diff --git a/.github/workflows/go.yml b/.github/workflows/go.yml
index 3c1f6cf..010d5f2 100644
--- a/.github/workflows/go.yml
+++ b/.github/workflows/go.yml
@@ -19,7 +19,7 @@ jobs:
     - name: Set up Go
       uses: actions/setup-go@v3
       with:
-        go-version: 1.21
+        go-version: 1.23
 
     - name: Build
       run: go build -v ./...
diff --git a/go.mod b/go.mod
index 74912df..fa95f7d 100644
--- a/go.mod
+++ b/go.mod
@@ -1,50 +1,68 @@
 module github.com/cockroachdb/cockroachdb-parser
 
-go 1.21.1
-
-toolchain go1.21.3
+go 1.23.8
 
 require (
 	github.com/bazelbuild/rules_go v0.46.0
 	github.com/biogo/store v0.0.0-20201120204734-aad293a2328f
 	github.com/blevesearch/snowballstem v0.9.0
 	github.com/cockroachdb/apd/v3 v3.1.0
-	github.com/cockroachdb/errors v1.9.0
+	github.com/cockroachdb/errors v1.11.3
 	github.com/cockroachdb/gostdlib v1.19.0
-	github.com/cockroachdb/redact v1.1.3
+	github.com/cockroachdb/logtags v0.0.0-20241215232642-bb51bb14a506
+	github.com/cockroachdb/redact v1.1.5
+	github.com/cockroachdb/version v0.0.0-20250314144055-3860cd14adf2
 	github.com/dave/dst v0.27.2
 	github.com/dustin/go-humanize v1.0.0
 	github.com/gogo/protobuf v1.3.2
 	github.com/golang/geo v0.0.0-20210211234256-740aa86cb551
-	github.com/google/go-cmp v0.5.8
+	github.com/google/go-cmp v0.7.0
 	github.com/grpc-ecosystem/grpc-gateway v1.16.0
+	github.com/jaegertracing/jaeger v1.18.1
 	github.com/lib/pq v1.10.6
+	github.com/petermattis/goid v0.0.0-20180202154549-b0b1615b78e5
 	github.com/pierrre/geohash v1.0.0
+	github.com/pmezard/go-difflib v1.0.0
 	github.com/sasha-s/go-deadlock v0.3.1
 	github.com/spf13/pflag v1.0.5
-	github.com/stretchr/testify v1.7.0
+	github.com/stretchr/testify v1.10.0
 	github.com/twpayne/go-geom v1.4.1
+	go.opentelemetry.io/otel v1.36.0
+	go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.36.0
+	go.opentelemetry.io/otel/exporters/zipkin v1.36.0
+	go.opentelemetry.io/otel/sdk v1.36.0
+	go.opentelemetry.io/otel/trace v1.36.0
 	golang.org/x/exp v0.0.0-20240205201215-2c58cdc269a3
-	golang.org/x/text v0.14.0
-	golang.org/x/tools v0.17.0
+	golang.org/x/net v0.40.0
+	golang.org/x/sys v0.33.0
+	golang.org/x/text v0.25.0
+	golang.org/x/tools v0.26.0
+	gonum.org/v1/gonum v0.16.0
+	google.golang.org/grpc v1.72.1
+	google.golang.org/protobuf v1.36.6
 )
 
 require (
-	github.com/cockroachdb/logtags v0.0.0-20211118104740-dabe8e521a4f // indirect
+	github.com/cenkalti/backoff/v5 v5.0.2 // indirect
 	github.com/davecgh/go-spew v1.1.1 // indirect
-	github.com/getsentry/sentry-go v0.12.0 // indirect
-	github.com/golang/protobuf v1.5.3 // indirect
-	github.com/kr/pretty v0.3.0 // indirect
+	github.com/getsentry/sentry-go v0.27.0 // indirect
+	github.com/go-logr/logr v1.4.2 // indirect
+	github.com/go-logr/stdr v1.2.2 // indirect
+	github.com/golang/protobuf v1.5.4 // indirect
+	github.com/google/uuid v1.6.0 // indirect
+	github.com/grpc-ecosystem/grpc-gateway/v2 v2.26.3 // indirect
+	github.com/kr/pretty v0.3.1 // indirect
 	github.com/kr/text v0.2.0 // indirect
-	github.com/petermattis/goid v0.0.0-20180202154549-b0b1615b78e5 // indirect
+	github.com/openzipkin/zipkin-go v0.4.3 // indirect
 	github.com/pkg/errors v0.9.1 // indirect
-	github.com/pmezard/go-difflib v1.0.0 // indirect
-	github.com/rogpeppe/go-internal v1.8.1 // indirect
+	github.com/rogpeppe/go-internal v1.13.1 // indirect
 	github.com/twpayne/go-kml v1.5.2 // indirect
-	golang.org/x/mod v0.14.0 // indirect
-	golang.org/x/sys v0.15.0 // indirect
-	google.golang.org/genproto v0.0.0-20210624195500-8bfb893ecb84 // indirect
-	google.golang.org/grpc v1.40.1 // indirect
-	google.golang.org/protobuf v1.31.0 // indirect
-	gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b // indirect
+	go.opentelemetry.io/auto/sdk v1.1.0 // indirect
+	go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.36.0 // indirect
+	go.opentelemetry.io/otel/metric v1.36.0 // indirect
+	go.opentelemetry.io/proto/otlp v1.6.0 // indirect
+	golang.org/x/mod v0.21.0 // indirect
+	golang.org/x/sync v0.14.0 // indirect
+	google.golang.org/genproto v0.0.0-20230410155749-daa745c078e1 // indirect
+	gopkg.in/yaml.v3 v3.0.1 // indirect
 )
diff --git a/go.sum b/go.sum
index e6655cb..5492e18 100644
--- a/go.sum
+++ b/go.sum
@@ -1,69 +1,86 @@
 cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
 cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
-github.com/AndreasBriese/bbloom v0.0.0-20190306092124-e2d15f34fcf9/go.mod h1:bOvUY6CB00SOBii9/FifXqc0awNKxLFCL/+pkDPuyl8=
+github.com/AndreasBriese/bbloom v0.0.0-20190825152654-46b345b51c96/go.mod h1:bOvUY6CB00SOBii9/FifXqc0awNKxLFCL/+pkDPuyl8=
 github.com/Azure/go-ansiterm v0.0.0-20170929234023-d6e3b3328b78/go.mod h1:LmzpDX56iTiv29bbRTIsUNlaFfuhWRQBWjQdVyAevI8=
 github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
-github.com/CloudyKit/fastprinter v0.0.0-20170127035650-74b38d55f37a/go.mod h1:EFZQ978U7x8IRnstaskI3IysnWY5Ao3QgZUKOXlsAdw=
-github.com/CloudyKit/fastprinter v0.0.0-20200109182630-33d98a066a53/go.mod h1:+3IMCy2vIlbG1XG/0ggNQv0SvxCAIpPM5b1nCz56Xno=
-github.com/CloudyKit/jet v2.1.3-0.20180809161101-62edd43e4f88+incompatible/go.mod h1:HPYO+50pSWkPoj9Q/eq0aRGByCL6ScRlUmiEX5Zgm+w=
-github.com/CloudyKit/jet/v3 v3.0.0/go.mod h1:HKQPgSJmdK8hdoAbKUUWajkHyHo4RaU5rMdUywE7VMo=
 github.com/Codefor/geohash v0.0.0-20140723084247-1b41c28e3a9d h1:iG9B49Q218F/XxXNRM7k/vWf7MKmLIS8AcJV9cGN4nA=
 github.com/Codefor/geohash v0.0.0-20140723084247-1b41c28e3a9d/go.mod h1:RVnhzAX71far8Kc3TQeA0k/dcaEKUnTDSOyet/JCmGI=
 github.com/DATA-DOG/go-sqlmock v1.3.2 h1:2L2f5t3kKnCLxnClDD/PrDfExFFa1wjESgxHG/B1ibo=
 github.com/DATA-DOG/go-sqlmock v1.3.2/go.mod h1:f/Ixk793poVmq4qj/V1dPUg2JEAKC73Q5eFN3EC/SaM=
-github.com/Joker/hpp v1.0.0/go.mod h1:8x5n+M1Hp5hC0g8okX3sR3vFQwynaX/UgSOM9MeBKzY=
-github.com/Joker/jade v1.0.1-0.20190614124447-d475f43051e7/go.mod h1:6E6s8o2AE4KhCrqr6GRJjdC/gNfTdxkIXvuGZZda2VM=
+github.com/DataDog/zstd v1.3.6-0.20190409195224-796139022798/go.mod h1:1jcaCB/ufaK+sKp1NBhlGmpz41jOoPQ35bpF36t7BBo=
+github.com/DataDog/zstd v1.4.4/go.mod h1:1jcaCB/ufaK+sKp1NBhlGmpz41jOoPQ35bpF36t7BBo=
 github.com/Masterminds/goutils v1.1.0/go.mod h1:8cTjp+g8YejhMuvIA5y2vz3BpJxksy863GQaJW2MFNU=
 github.com/Masterminds/semver v1.5.0/go.mod h1:MB6lktGJrhw8PrUyiEoblNEGEQ+RzHPF078ddwwvV3Y=
 github.com/Masterminds/sprig v2.22.0+incompatible/go.mod h1:y6hNFY5UBTIWBxnzTeuNhlNS5hqE0NB0E6fgfo2Br3o=
 github.com/Microsoft/go-winio v0.4.14/go.mod h1:qXqCSQ3Xa7+6tgxaGTIe4Kpcdsi+P8jBhyzoq1bpyYA=
 github.com/Nvveen/Gotty v0.0.0-20120604004816-cd527374f1e5/go.mod h1:lmUJ/7eu/Q8D7ML55dXQrVaamCz2vxCfdQBasLZfHKk=
 github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU=
-github.com/Shopify/goreferrer v0.0.0-20181106222321-ec9c9a553398/go.mod h1:a1uqRtAwp2Xwc6WNPJEufxJ7fx3npB4UV/JOLmbu5I0=
+github.com/PuerkitoBio/purell v1.1.0/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0=
+github.com/PuerkitoBio/purell v1.1.1/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0=
+github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578/go.mod h1:uGdkoq3SwY9Y+13GIhn11/XLaGBb4BfwItxLd5jeuXE=
+github.com/Shopify/sarama v1.22.2-0.20190604114437-cd910a683f9f/go.mod h1:XLH1GYJnLVE0XCr6KdJGVJRTwY30moWNJ4sERjXX6fs=
+github.com/Shopify/toxiproxy v2.1.4+incompatible/go.mod h1:OXgGpZ6Cli1/URJOF1DMxUHB2q5Ap20/P/eIdh4G0pI=
 github.com/TomiHiltunen/geohash-golang v0.0.0-20150112065804-b3e4e625abfb h1:wumPkzt4zaxO4rHPBrjDK8iZMR41C1qs7njNqlacwQg=
 github.com/TomiHiltunen/geohash-golang v0.0.0-20150112065804-b3e4e625abfb/go.mod h1:QiYsIBRQEO+Z4Rz7GoI+dsHVneZNONvhczuA+llOZNM=
-github.com/ajg/form v1.5.1/go.mod h1:uL1WgH+h2mgNtvBq0339dVnzXdBETtL2LeUXaIv25UY=
+github.com/VividCortex/gohistogram v1.0.0/go.mod h1:Pf5mBqqDxYaXu3hDrrU+w6nw50o/4+TcAqDqk/vUH7g=
+github.com/agnivade/levenshtein v1.0.1/go.mod h1:CURSv5d9Uaml+FovSIICkLbAUZ9S4RqaHDIsdSBg7lM=
+github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
+github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
+github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
+github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
+github.com/andreyvit/diff v0.0.0-20170406064948-c7f18ee00883/go.mod h1:rCTlJbsFo29Kk6CurOXKm700vrz8f0KW0JNfpkRJY/8=
+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-20151001171628-53dd39833a08/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb+bacwQ=
 github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8=
-github.com/aymerick/raymond v2.0.3-0.20180322193309-b565731e1464+incompatible/go.mod h1:osfaiScAUVup+UC9Nfq76eWqDhXlp+4UYaA8uhTBO6g=
+github.com/asaskevich/govalidator v0.0.0-20180720115003-f9ffefc3facf/go.mod h1:lB+ZfQJz7igIIfQNfa7Ml4HSf2uFQQRzpGGRXenZAgY=
+github.com/asaskevich/govalidator v0.0.0-20190424111038-f61b66f89f4a/go.mod h1:lB+ZfQJz7igIIfQNfa7Ml4HSf2uFQQRzpGGRXenZAgY=
+github.com/asaskevich/govalidator v0.0.0-20200108200545-475eaeb16496/go.mod h1:oGkLhpf+kjZl6xBf758TQhh5XrAeiJv/7FRz/2spLIg=
 github.com/bazelbuild/rules_go v0.46.0 h1:CTefzjN/D3Cdn3rkrM6qMWuQj59OBcuOjyIp3m4hZ7s=
 github.com/bazelbuild/rules_go v0.46.0/go.mod h1:Dhcz716Kqg1RHNWos+N6MlXNkjNP2EwZQ0LukRKJfMs=
+github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q=
+github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8=
+github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw=
 github.com/biogo/store v0.0.0-20201120204734-aad293a2328f h1:+6okTAeUsUrdQr/qN7fIODzowrjjCrnJDg/gkYqcSXY=
 github.com/biogo/store v0.0.0-20201120204734-aad293a2328f/go.mod h1:z52shMwD6SGwRg2iYFjjDwX5Ene4ENTw6HfXraUy/08=
+github.com/bitly/go-hostpool v0.0.0-20171023180738-a3a6125de932/go.mod h1:NOuUCSz6Q9T7+igc/hlvDOUdtWKryOrtFyIVABv/p7k=
 github.com/blevesearch/snowballstem v0.9.0 h1:lMQ189YspGP6sXvZQ4WZ+MLawfV8wOmPoD/iWeNXm8s=
 github.com/blevesearch/snowballstem v0.9.0/go.mod h1:PivSj3JMc8WuaFkTSRDW2SlrulNWPl4ABg1tC/hlgLs=
+github.com/bmizerany/assert v0.0.0-20160611221934-b7ed37b82869/go.mod h1:Ekp36dRnpXw/yCqJaO+ZrUyxD+3VXMFFr56k5XYrpB4=
+github.com/bmizerany/perks v0.0.0-20141205001514-d9a9656a3a4b/go.mod h1:ac9efd0D1fsDb3EJvhqgXRbFx7bs2wqZ10HQPeU8U/Q=
 github.com/broady/gogeohash v0.0.0-20120525094510-7b2c40d64042 h1:iEdmkrNMLXbM7ecffOAtZJQOQUTE4iMonxrb5opUgE4=
 github.com/broady/gogeohash v0.0.0-20120525094510-7b2c40d64042/go.mod h1:f1L9YvXvlt9JTa+A17trQjSMM6bV40f+tHjB+Pi+Fqk=
+github.com/bsm/sarama-cluster v2.1.13+incompatible/go.mod h1:r7ao+4tTNXvWm+VRpRJchr2kQhqxgmAp2iEX5W96gMM=
 github.com/cenkalti/backoff/v3 v3.0.0/go.mod h1:cIeZDE3IrqwwJl6VUwCN6trj1oXrTS4rc0ij+ULvLYs=
+github.com/cenkalti/backoff/v5 v5.0.2 h1:rIfFVxEf1QsI7E1ZHfp/B4DF/6QBAUhmgkxc0H7Zss8=
+github.com/cenkalti/backoff/v5 v5.0.2/go.mod h1:rkhZdG3JZukswDf7f0cwqPNk4K0sa+F97BxZthm/crw=
 github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
 github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc=
 github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
 github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc=
-github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk=
-github.com/cncf/xds/go v0.0.0-20210312221358-fbca930ec8ed/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs=
 github.com/cockroachdb/apd/v3 v3.1.0 h1:MK3Ow7LH0W8zkd5GMKA1PvS9qG3bWFI95WaVNfyZJ/w=
 github.com/cockroachdb/apd/v3 v3.1.0/go.mod h1:6qgPBMXjATAdD/VefbRP9NoSLKjbB4LCoA7gN4LpHs4=
-github.com/cockroachdb/datadriven v1.0.1-0.20211007161720-b558070c3be0/go.mod h1:5Ib8Meh+jk1RlHIXej6Pzevx/NLlNvQB9pmSBZErGA4=
-github.com/cockroachdb/datadriven v1.0.1-0.20220214170620-9913f5bc19b7/go.mod h1:hi0MtSY3AYDQNDi83kDkMH5/yqM/CsIrsOITkSoH7KI=
-github.com/cockroachdb/errors v1.6.1/go.mod h1:tm6FTP5G81vwJ5lC0SizQo374JNCOPrHyXGitRJoDqM=
-github.com/cockroachdb/errors v1.8.8/go.mod h1:z6VnEL3hZ/2ONZEvG7S5Ym0bU2AqPcEKnIiA1wbsSu0=
-github.com/cockroachdb/errors v1.9.0 h1:B48dYem5SlAY7iU8AKsgedb4gH6mo+bDkbtLIvM/a88=
-github.com/cockroachdb/errors v1.9.0/go.mod h1:vaNcEYYqbIqB5JhKBhFV9CneUqeuEbB2OYJBK4GBNYQ=
+github.com/cockroachdb/errors v1.11.3 h1:5bA+k2Y6r+oz/6Z/RFlNeVCesGARKuC6YymtcDrbC/I=
+github.com/cockroachdb/errors v1.11.3/go.mod h1:m4UIW4CDjx+R5cybPsNrRbreomiFqt8o1h1wUVazSd8=
 github.com/cockroachdb/gostdlib v1.19.0 h1:cSISxkVnTlWhTkyple/T6NXzOi5659FkhxvUgZv+Eb0=
 github.com/cockroachdb/gostdlib v1.19.0/go.mod h1:+dqqpARXbE/gRDEhCak6dm0l14AaTymPZUKMfURjBtY=
-github.com/cockroachdb/logtags v0.0.0-20190617123548-eb05cc24525f/go.mod h1:i/u985jwjWRlyHXQbwatDASoW0RMlZ/3i9yJHE2xLkI=
-github.com/cockroachdb/logtags v0.0.0-20211118104740-dabe8e521a4f h1:6jduT9Hfc0njg5jJ1DdKCFPdMBrp/mdZfCpa5h+WM74=
-github.com/cockroachdb/logtags v0.0.0-20211118104740-dabe8e521a4f/go.mod h1:Vz9DsVWQQhf3vs21MhPMZpMGSht7O/2vFW2xusFUVOs=
-github.com/cockroachdb/redact v1.1.3 h1:AKZds10rFSIj7qADf0g46UixK8NNLwWTNdCIGS5wfSQ=
-github.com/cockroachdb/redact v1.1.3/go.mod h1:BVNblN9mBWFyMyqK1k3AAiSxhvhfK2oOZZ2lK+dpvRg=
-github.com/cockroachdb/sentry-go v0.6.1-cockroachdb.2/go.mod h1:8BT+cPK6xvFOcRlk0R8eg+OTkcqI6baNH4xAkpiYVvQ=
-github.com/codegangsta/inject v0.0.0-20150114235600-33e0aa1cb7c0/go.mod h1:4Zcjuz89kmFXt9morQgcfYZAYZ5n8WHjt81YYWIwtTM=
+github.com/cockroachdb/logtags v0.0.0-20241215232642-bb51bb14a506 h1:ASDL+UJcILMqgNeV5jiqR4j+sTuvQNHdf2chuKj1M5k=
+github.com/cockroachdb/logtags v0.0.0-20241215232642-bb51bb14a506/go.mod h1:Mw7HqKr2kdtu6aYGn3tPmAftiP3QPX63LdK/zcariIo=
+github.com/cockroachdb/redact v1.1.5 h1:u1PMllDkdFfPWaNGMyLD1+so+aq3uUItthCFqzwPJ30=
+github.com/cockroachdb/redact v1.1.5/go.mod h1:BVNblN9mBWFyMyqK1k3AAiSxhvhfK2oOZZ2lK+dpvRg=
+github.com/cockroachdb/version v0.0.0-20250314144055-3860cd14adf2 h1:8Vfw2iNEpYIV6aLtMwT5UOGuPmp9MKlEKWKFTuB+MPU=
+github.com/cockroachdb/version v0.0.0-20250314144055-3860cd14adf2/go.mod h1:P9WiZOdQ1R/ZZDL0WzF5wlyRvrjtfhNOwMZymFpBwjE=
+github.com/codahale/hdrhistogram v0.0.0-20161010025455-3a0bb77429bd/go.mod h1:sE/e/2PUdi/liOCUjSTXgM1o87ZssimdTWN964YiIeI=
 github.com/containerd/continuity v0.0.0-20190827140505-75bee3e2ccb6/go.mod h1:GL3xCUCBDV3CZiTSEKksMWbLE66hEyuu9qyDOOqM47Y=
+github.com/coreos/bbolt v1.3.2/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk=
 github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE=
-github.com/coreos/go-etcd v2.0.0+incompatible/go.mod h1:Jez6KQU2B/sWsbdaef3ED8NzMklzPG4d5KIOhIy30Tk=
 github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk=
+github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4=
+github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA=
 github.com/cpuguy83/go-md2man v1.0.10/go.mod h1:SmD6nW6nTyfqj6ABTjUi3V3JVMnlJmwcJI5acqYI6dE=
+github.com/creack/pty v1.1.7/go.mod h1:lj5s0c3V2DBrqTV7llrYr5NG6My20zk30Fl46Y7DoTY=
 github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
+github.com/crossdock/crossdock-go v0.0.0-20160816171116-049aabb0122b/go.mod h1:v9FBN7gdVTpiD/+LZ7Po0UKvROyT87uLVxTHVky/dlQ=
 github.com/dave/dst v0.27.2 h1:4Y5VFTkhGLC1oddtNwuxxe36pnyLxMFXT51FOzH8Ekc=
 github.com/dave/dst v0.27.2/go.mod h1:jHh6EOibnHgcUW3WjKHisiooEkYwqpHLBSX1iOBhEyc=
 github.com/dave/jennifer v1.5.0 h1:HmgPN93bVDpkQyYbqhCHj5QlgvUkvEOzMyEvKLgCRrg=
@@ -71,188 +88,268 @@ github.com/dave/jennifer v1.5.0/go.mod h1:4MnyiFIlZS3l5tSDn8VnzE6ffAhYBMB2SZntBs
 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/dgraph-io/badger v1.6.0/go.mod h1:zwt7syl517jmP8s94KqSxTlM6IMsdhYy6psNgSztDR4=
+github.com/dgraph-io/badger v1.5.3/go.mod h1:VZxzAIRPHRVNRKRo6AXrX9BJegn6il06VMTZVJYCIjQ=
 github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ=
-github.com/dgryski/go-farm v0.0.0-20190423205320-6a90982ecee2/go.mod h1:SqUrOPUnsFjfmXRMNPybcSiG0BgUW2AuFH8PAnS2iTw=
+github.com/dgryski/go-farm v0.0.0-20200201041132-a6ae2369ad13/go.mod h1:SqUrOPUnsFjfmXRMNPybcSiG0BgUW2AuFH8PAnS2iTw=
+github.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954/go.mod h1:vAd38F8PWV+bWy6jNmig1y/TA+kYO4g3RSRF0IAv0no=
 github.com/docker/go-connections v0.4.0/go.mod h1:Gbd7IOopHjR8Iph03tsViu4nIes5XhDvyHbTtUxmeec=
+github.com/docker/go-units v0.3.3/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk=
 github.com/docker/go-units v0.4.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk=
 github.com/dustin/go-humanize v1.0.0 h1:VSnTsYCnlFHaM2/igO1h6X3HA71jcobQuxemgkq4zYo=
 github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk=
-github.com/eknkc/amber v0.0.0-20171010120322-cdade1c07385/go.mod h1:0vRUJqYpeSZifjYj7uP3BG/gKcuzL9xWVV/Y+cK33KM=
+github.com/eapache/go-resiliency v1.1.0/go.mod h1:kFI+JgMyC7bLPUVY133qvEBtVayf5mFgVsvEsIPBvNs=
+github.com/eapache/go-resiliency v1.2.0/go.mod h1:kFI+JgMyC7bLPUVY133qvEBtVayf5mFgVsvEsIPBvNs=
+github.com/eapache/go-xerial-snappy v0.0.0-20180814174437-776d5712da21/go.mod h1:+020luEh2TKB4/GOp8oxxtq0Daoen/Cii55CzbTV6DU=
+github.com/eapache/queue v1.1.0/go.mod h1:6eCeP0CKFpHLu8blIFXhExK/dRa7WDZfr6jVFPTqq+I=
 github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
 github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
 github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98=
-github.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk=
-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/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/fanixk/geohash v0.0.0-20150324002647-c1f9b5fa157a h1:Fyfh/dsHFrC6nkX7H7+nFdTd1wROlX/FxEIWVpKYf1U=
 github.com/fanixk/geohash v0.0.0-20150324002647-c1f9b5fa157a/go.mod h1:UgNw+PTmmGN8rV7RvjvnBMsoTU8ZXXnaT3hYsDTBlgQ=
-github.com/fasthttp-contrib/websocket v0.0.0-20160511215533-1f3b11f56072/go.mod h1:duJ4Jxv5lDcvg4QuQr0oowTf7dz4/CR8NtyCooz9HL8=
-github.com/fatih/structs v1.1.0/go.mod h1:9NiDSp5zOcgEDl+j00MP/WkGVPOlPRLejGD8Ga6PJ7M=
-github.com/flosch/pongo2 v0.0.0-20190707114632-bbf5a6c351f4/go.mod h1:T9YF2M40nIgbVgp3rreNmTged+9HrbNTIQf1PsaIiTA=
+github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4=
+github.com/fortytw2/leaktest v1.3.0/go.mod h1:jDsjWgpAGjm2CA7WthBh/CdZYEPF31XHquHwclZch5g=
+github.com/frankban/quicktest v1.7.3/go.mod h1:V1d2J5pfxYH6EjBAgSK7YNXcXlTWxUHdE1sVDXkjnig=
 github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
-github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ=
-github.com/gavv/httpexpect v2.0.0+incompatible/go.mod h1:x+9tiU1YnrOvnB725RkpoLv1M62hOWzwo5OXotisrKc=
-github.com/getsentry/sentry-go v0.12.0 h1:era7g0re5iY13bHSdN/xMkyV+5zZppjRVQhZrXCaEIk=
-github.com/getsentry/sentry-go v0.12.0/go.mod h1:NSap0JBYWzHND8oMbyi0+XZhUalc1TBdRL1M71JZW2c=
+github.com/getsentry/sentry-go v0.27.0 h1:Pv98CIbtB3LkMWmXi4Joa5OOcwbmnX88sF5qbK3r3Ps=
+github.com/getsentry/sentry-go v0.27.0/go.mod h1:lc76E2QywIyW8WuBnwl8Lc4bkmQH4+w1gwTf25trprY=
 github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
-github.com/gin-contrib/sse v0.0.0-20190301062529-5545eab6dad3/go.mod h1:VJ0WA2NBN22VlZ2dKZQPAPnyWw5XTlK1KymzLKsr59s=
-github.com/gin-gonic/gin v1.4.0/go.mod h1:OW2EZn3DO8Ln9oIKOvM++LBO+5UPHJJDH72/q/3rZdM=
-github.com/go-check/check v0.0.0-20180628173108-788fd7840127/go.mod h1:9ES+weclKsC9YodN5RgxqK/VD9HM9JsCSh7rNhMZE98=
-github.com/go-errors/errors v1.0.1 h1:LUHzmkK3GUKUrL/1gfBUxAHzcev3apQlezX/+O7ma6w=
-github.com/go-errors/errors v1.0.1/go.mod h1:f4zRHt4oKfwPJE5k8C9vpYG+aDHdBFUsgrm6/TyX73Q=
-github.com/go-martini/martini v0.0.0-20170121215854-22fa46961aab/go.mod h1:/P9AEU963A2AYjv4d1V5eVL1CQbEJq6aCNHDDjibzu8=
-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/gogo/googleapis v0.0.0-20180223154316-0cd9801be74a/go.mod h1:gf4bu3Q80BeJ6H1S1vYPm8/ELATdvryBaNFGgqEef3s=
-github.com/gogo/googleapis v1.4.1/go.mod h1:2lpHqI5OcWCtVElxXnPt+s8oJvMpySlOyM6xDCrzib4=
-github.com/gogo/protobuf v1.2.0/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=
-github.com/gogo/protobuf v1.3.1/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXPKa29o=
+github.com/globalsign/mgo v0.0.0-20180905125535-1ca0a4f7cbcb/go.mod h1:xkRDCp4j0OGD1HRkm4kmhM+pmpv3AKq5SU7GMg4oO/Q=
+github.com/globalsign/mgo v0.0.0-20181015135952-eeefdecb41b8/go.mod h1:xkRDCp4j0OGD1HRkm4kmhM+pmpv3AKq5SU7GMg4oO/Q=
+github.com/go-errors/errors v1.4.2 h1:J6MZopCL4uSllY1OfXM374weqZFFItUbrImctkmUxIA=
+github.com/go-errors/errors v1.4.2/go.mod h1:sIVyrIiJhuEF+Pj9Ebtd6P/rEYROXFi3BopGUQ5a5Og=
+github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
+github.com/go-kit/kit v0.9.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
+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-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=
+github.com/go-logr/logr v1.4.2 h1:6pFjapn8bFcIbiKo3XT4j/BhANplGihG6tvd+8rYgrY=
+github.com/go-logr/logr v1.4.2/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY=
+github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag=
+github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE=
+github.com/go-openapi/analysis v0.0.0-20180825180245-b006789cd277/go.mod h1:k70tL6pCuVxPJOHXQ+wIac1FUrvNkHolPie/cLEU6hI=
+github.com/go-openapi/analysis v0.17.0/go.mod h1:IowGgpVeD0vNm45So8nr+IcQ3pxVtpRoBWb8PVZO0ik=
+github.com/go-openapi/analysis v0.18.0/go.mod h1:IowGgpVeD0vNm45So8nr+IcQ3pxVtpRoBWb8PVZO0ik=
+github.com/go-openapi/analysis v0.19.2/go.mod h1:3P1osvZa9jKjb8ed2TPng3f0i/UY9snX6gxi44djMjk=
+github.com/go-openapi/analysis v0.19.4/go.mod h1:3P1osvZa9jKjb8ed2TPng3f0i/UY9snX6gxi44djMjk=
+github.com/go-openapi/analysis v0.19.5/go.mod h1:hkEAkxagaIvIP7VTn8ygJNkd4kAYON2rCu0v0ObL0AU=
+github.com/go-openapi/analysis v0.19.7/go.mod h1:hkEAkxagaIvIP7VTn8ygJNkd4kAYON2rCu0v0ObL0AU=
+github.com/go-openapi/errors v0.17.0/go.mod h1:LcZQpmvG4wyF5j4IhA73wkLFQg+QJXOQHVjmcZxhka0=
+github.com/go-openapi/errors v0.18.0/go.mod h1:LcZQpmvG4wyF5j4IhA73wkLFQg+QJXOQHVjmcZxhka0=
+github.com/go-openapi/errors v0.19.2/go.mod h1:qX0BLWsyaKfvhluLejVpVNwNRdXZhEbTA4kxxpKBC94=
+github.com/go-openapi/errors v0.19.3/go.mod h1:qX0BLWsyaKfvhluLejVpVNwNRdXZhEbTA4kxxpKBC94=
+github.com/go-openapi/jsonpointer v0.17.0/go.mod h1:cOnomiV+CVVwFLk0A/MExoFMjwdsUdVpsRhURCKh+3M=
+github.com/go-openapi/jsonpointer v0.18.0/go.mod h1:cOnomiV+CVVwFLk0A/MExoFMjwdsUdVpsRhURCKh+3M=
+github.com/go-openapi/jsonpointer v0.19.2/go.mod h1:3akKfEdA7DF1sugOqz1dVQHBcuDBPKZGEoHC/NkiQRg=
+github.com/go-openapi/jsonpointer v0.19.3/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg=
+github.com/go-openapi/jsonreference v0.17.0/go.mod h1:g4xxGn04lDIRh0GJb5QlpE3HfopLOL6uZrK/VgnsK9I=
+github.com/go-openapi/jsonreference v0.18.0/go.mod h1:g4xxGn04lDIRh0GJb5QlpE3HfopLOL6uZrK/VgnsK9I=
+github.com/go-openapi/jsonreference v0.19.2/go.mod h1:jMjeRr2HHw6nAVajTXJ4eiUwohSTlpa0o73RUL1owJc=
+github.com/go-openapi/jsonreference v0.19.3/go.mod h1:rjx6GuL8TTa9VaixXglHmQmIL98+wF9xc8zWvFonSJ8=
+github.com/go-openapi/loads v0.17.0/go.mod h1:72tmFy5wsWx89uEVddd0RjRWPZm92WRLhf7AC+0+OOU=
+github.com/go-openapi/loads v0.18.0/go.mod h1:72tmFy5wsWx89uEVddd0RjRWPZm92WRLhf7AC+0+OOU=
+github.com/go-openapi/loads v0.19.0/go.mod h1:72tmFy5wsWx89uEVddd0RjRWPZm92WRLhf7AC+0+OOU=
+github.com/go-openapi/loads v0.19.2/go.mod h1:QAskZPMX5V0C2gvfkGZzJlINuP7Hx/4+ix5jWFxsNPs=
+github.com/go-openapi/loads v0.19.3/go.mod h1:YVfqhUCdahYwR3f3iiwQLhicVRvLlU/WO5WPaZvcvSI=
+github.com/go-openapi/loads v0.19.4/go.mod h1:zZVHonKd8DXyxyw4yfnVjPzBjIQcLt0CCsn0N0ZrQsk=
+github.com/go-openapi/runtime v0.0.0-20180920151709-4f900dc2ade9/go.mod h1:6v9a6LTXWQCdL8k1AO3cvqx5OtZY/Y9wKTgaoP6YRfA=
+github.com/go-openapi/runtime v0.19.0/go.mod h1:OwNfisksmmaZse4+gpV3Ne9AyMOlP1lt4sK4FXt0O64=
+github.com/go-openapi/runtime v0.19.4/go.mod h1:X277bwSUBxVlCYR3r7xgZZGKVvBd/29gLDlFGtJ8NL4=
+github.com/go-openapi/runtime v0.19.11/go.mod h1:dhGWCTKRXlAfGnQG0ONViOZpjfg0m2gUt9nTQPQZuoo=
+github.com/go-openapi/spec v0.17.0/go.mod h1:XkF/MOi14NmjsfZ8VtAKf8pIlbZzyoTvZsdfssdxcBI=
+github.com/go-openapi/spec v0.18.0/go.mod h1:XkF/MOi14NmjsfZ8VtAKf8pIlbZzyoTvZsdfssdxcBI=
+github.com/go-openapi/spec v0.19.2/go.mod h1:sCxk3jxKgioEJikev4fgkNmwS+3kuYdJtcsZsD5zxMY=
+github.com/go-openapi/spec v0.19.3/go.mod h1:FpwSN1ksY1eteniUU7X0N/BgJ7a4WvBFVA8Lj9mJglo=
+github.com/go-openapi/spec v0.19.6/go.mod h1:Hm2Jr4jv8G1ciIAo+frC/Ft+rR2kQDh8JHKHb3gWUSk=
+github.com/go-openapi/strfmt v0.17.0/go.mod h1:P82hnJI0CXkErkXi8IKjPbNBM6lV6+5pLP5l494TcyU=
+github.com/go-openapi/strfmt v0.18.0/go.mod h1:P82hnJI0CXkErkXi8IKjPbNBM6lV6+5pLP5l494TcyU=
+github.com/go-openapi/strfmt v0.19.0/go.mod h1:+uW+93UVvGGq2qGaZxdDeJqSAqBqBdl+ZPMF/cC8nDY=
+github.com/go-openapi/strfmt v0.19.2/go.mod h1:0yX7dbo8mKIvc3XSKp7MNfxw4JytCfCD6+bY1AVL9LU=
+github.com/go-openapi/strfmt v0.19.3/go.mod h1:0yX7dbo8mKIvc3XSKp7MNfxw4JytCfCD6+bY1AVL9LU=
+github.com/go-openapi/strfmt v0.19.4/go.mod h1:eftuHTlB/dI8Uq8JJOyRlieZf+WkkxUuk0dgdHXr2Qk=
+github.com/go-openapi/swag v0.17.0/go.mod h1:AByQ+nYG6gQg71GINrmuDXCPWdL640yX49/kXLo40Tg=
+github.com/go-openapi/swag v0.18.0/go.mod h1:AByQ+nYG6gQg71GINrmuDXCPWdL640yX49/kXLo40Tg=
+github.com/go-openapi/swag v0.19.2/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk=
+github.com/go-openapi/swag v0.19.5/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk=
+github.com/go-openapi/swag v0.19.7/go.mod h1:ao+8BpOPyKdpQz3AOJfbeEVpLmWAvlT1IfTe5McPyhY=
+github.com/go-openapi/validate v0.18.0/go.mod h1:Uh4HdOzKt19xGIGm1qHf/ofbX1YQ4Y+MYsct2VUrAJ4=
+github.com/go-openapi/validate v0.19.2/go.mod h1:1tRCw7m3jtI8eNWEEliiAqUIcBztB2KDnRCRMUi7GTA=
+github.com/go-openapi/validate v0.19.3/go.mod h1:90Vh6jjkTn+OT1Eefm0ZixWNFjhtOH7vS9k0lo6zwJo=
+github.com/go-openapi/validate v0.19.6/go.mod h1:8DJv2CVJQ6kGNpFW6eV9N3JviE1C85nY1c2z52x1Gk4=
+github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=
+github.com/gobuffalo/attrs v0.0.0-20190224210810-a9411de4debd/go.mod h1:4duuawTqi2wkkpB4ePgWMaai6/Kc6WEz83bhFwpHzj0=
+github.com/gobuffalo/depgen v0.0.0-20190329151759-d478694a28d3/go.mod h1:3STtPUQYuzV0gBVOY3vy6CfMm/ljR4pABfrTeHNLHUY=
+github.com/gobuffalo/depgen v0.1.0/go.mod h1:+ifsuy7fhi15RWncXQQKjWS9JPkdah5sZvtHc2RXGlg=
+github.com/gobuffalo/envy v1.6.15/go.mod h1:n7DRkBerg/aorDM8kbduw5dN3oXGswK5liaSCx4T5NI=
+github.com/gobuffalo/envy v1.7.0/go.mod h1:n7DRkBerg/aorDM8kbduw5dN3oXGswK5liaSCx4T5NI=
+github.com/gobuffalo/flect v0.1.0/go.mod h1:d2ehjJqGOH/Kjqcoz+F7jHTBbmDb38yXA598Hb50EGs=
+github.com/gobuffalo/flect v0.1.1/go.mod h1:8JCgGVbRjJhVgD6399mQr4fx5rRfGKVzFjbj6RE/9UI=
+github.com/gobuffalo/flect v0.1.3/go.mod h1:8JCgGVbRjJhVgD6399mQr4fx5rRfGKVzFjbj6RE/9UI=
+github.com/gobuffalo/genny v0.0.0-20190329151137-27723ad26ef9/go.mod h1:rWs4Z12d1Zbf19rlsn0nurr75KqhYp52EAGGxTbBhNk=
+github.com/gobuffalo/genny v0.0.0-20190403191548-3ca520ef0d9e/go.mod h1:80lIj3kVJWwOrXWWMRzzdhW3DsrdjILVil/SFKBzF28=
+github.com/gobuffalo/genny v0.1.0/go.mod h1:XidbUqzak3lHdS//TPu2OgiFB+51Ur5f7CSnXZ/JDvo=
+github.com/gobuffalo/genny v0.1.1/go.mod h1:5TExbEyY48pfunL4QSXxlDOmdsD44RRq4mVZ0Ex28Xk=
+github.com/gobuffalo/gitgen v0.0.0-20190315122116-cc086187d211/go.mod h1:vEHJk/E9DmhejeLeNt7UVvlSGv3ziL+djtTr3yyzcOw=
+github.com/gobuffalo/gogen v0.0.0-20190315121717-8f38393713f5/go.mod h1:V9QVDIxsgKNZs6L2IYiGR8datgMhB577vzTDqypH360=
+github.com/gobuffalo/gogen v0.1.0/go.mod h1:8NTelM5qd8RZ15VjQTFkAW6qOMx5wBbW4dSCS3BY8gg=
+github.com/gobuffalo/gogen v0.1.1/go.mod h1:y8iBtmHmGc4qa3urIyo1shvOD8JftTtfcKi+71xfDNE=
+github.com/gobuffalo/logger v0.0.0-20190315122211-86e12af44bc2/go.mod h1:QdxcLw541hSGtBnhUc4gaNIXRjiDppFGaDqzbrBd3v8=
+github.com/gobuffalo/mapi v1.0.1/go.mod h1:4VAGh89y6rVOvm5A8fKFxYG+wIW6LO1FMTG9hnKStFc=
+github.com/gobuffalo/mapi v1.0.2/go.mod h1:4VAGh89y6rVOvm5A8fKFxYG+wIW6LO1FMTG9hnKStFc=
+github.com/gobuffalo/packd v0.0.0-20190315124812-a385830c7fc0/go.mod h1:M2Juc+hhDXf/PnmBANFCqx4DM3wRbgDvnVWeG2RIxq4=
+github.com/gobuffalo/packd v0.1.0/go.mod h1:M2Juc+hhDXf/PnmBANFCqx4DM3wRbgDvnVWeG2RIxq4=
+github.com/gobuffalo/packr/v2 v2.0.9/go.mod h1:emmyGweYTm6Kdper+iywB6YK5YzuKchGtJQZ0Odn4pQ=
+github.com/gobuffalo/packr/v2 v2.2.0/go.mod h1:CaAwI0GPIAv+5wKLtv8Afwl+Cm78K/I/VCm/3ptBN+0=
+github.com/gobuffalo/syncx v0.0.0-20190224160051-33c29581e754/go.mod h1:HhnNqWY95UYwwW3uSASeV7vtgYkT2t16hJgV3AEPUpw=
+github.com/gocql/gocql v0.0.0-20200228163523-cd4b606dd2fb/go.mod h1:DL0ekTmBSTdlNF25Orwt/JMzqIq3EJ4MVa/J/uK64OY=
+github.com/gogo/googleapis v1.0.1-0.20180501115203-b23578765ee5/go.mod h1:gf4bu3Q80BeJ6H1S1vYPm8/ELATdvryBaNFGgqEef3s=
+github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=
+github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4=
 github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q=
 github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q=
-github.com/gogo/status v1.1.0/go.mod h1:BFv9nrluPLmrS0EmGVvLaPNmRosr9KapBYd5/hpY1WM=
-github.com/golang-jwt/jwt v3.2.2+incompatible/go.mod h1:8pz2t5EyA70fFQQSrl6XZXzqecmYZeUEB8OUGHkxJ+I=
 github.com/golang/geo v0.0.0-20210211234256-740aa86cb551 h1:gtexQ/VGyN+VVFRXSFiguSNcXmS6rkKT+X7FdIrTtfo=
 github.com/golang/geo v0.0.0-20210211234256-740aa86cb551/go.mod h1:QZ0nwyI2jOfgRAoBvP+ab5aRr7c9x7lhGEJrKvBwjWI=
 github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
+github.com/golang/groupcache v0.0.0-20190129154638-5b532d6fd5ef/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
 github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
 github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
 github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
 github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
 github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw=
-github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8=
-github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA=
-github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs=
-github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w=
-github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0=
-github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8=
-github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
-github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
-github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk=
-github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY=
-github.com/golang/protobuf v1.5.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg=
-github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY=
-github.com/gomodule/redigo v1.7.1-0.20190724094224-574c33c3df38/go.mod h1:B4C85qUVwatsJoIUNIfCRsp7qO0iAmpGFZ4EELWSbC4=
+github.com/golang/protobuf v1.3.4/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw=
+github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek=
+github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps=
+github.com/golang/snappy v0.0.0-20170215233205-553a64147049/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
+github.com/golang/snappy v0.0.1/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
+github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
 github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=
 github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
 github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
 github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
-github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
-github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
-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-querystring v1.0.0/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck=
+github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8=
+github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU=
 github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
+github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI=
+github.com/google/uuid v1.0.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
 github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
 github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
+github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
+github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
 github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY=
+github.com/gorilla/handlers v1.4.2/go.mod h1:Qkdc/uu4tH4g6mTK6auzZ766c4CA0Ng8+o/OAirnOIQ=
+github.com/gorilla/mux v1.7.4/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So=
 github.com/gorilla/websocket v1.4.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ=
-github.com/gorilla/websocket v1.4.1/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
+github.com/grpc-ecosystem/go-grpc-middleware v1.0.0/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs=
+github.com/grpc-ecosystem/go-grpc-middleware v1.2.0/go.mod h1:mJzapYve32yjrKlk9GbyCZHuPgZsrbyIbyKhSzOpg6s=
+github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk=
+github.com/grpc-ecosystem/grpc-gateway v1.9.0/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY=
+github.com/grpc-ecosystem/grpc-gateway v1.13.0/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/hashicorp/go-version v1.2.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA=
+github.com/grpc-ecosystem/grpc-gateway/v2 v2.26.3 h1:5ZPtiqj0JL5oKWmcsq4VMaAW5ukBEgSGXEN89zeH1Jo=
+github.com/grpc-ecosystem/grpc-gateway/v2 v2.26.3/go.mod h1:ndYquD05frm2vACXE1nsccT4oJzjhw2arTS2cpUD1PI=
+github.com/hailocab/go-hostpool v0.0.0-20160125115350-e80d13ce29ed/go.mod h1:tMWxXQ9wFIaZeTI9F+hmhFiGpFmhOHzyShyFUhRm0H4=
+github.com/hashicorp/go-hclog v0.0.0-20180709165350-ff2cf002a8dd/go.mod h1:9bjs9uLqI8l75knNv3lV1kA55veR+WUPSiKIWcQHudI=
+github.com/hashicorp/go-hclog v0.14.0/go.mod h1:whpDNt7SSdeAju8AWKIWsul05p54N/39EeqMAyrmvFQ=
+github.com/hashicorp/go-plugin v1.3.0/go.mod h1:F9eH4LrE/ZsRdbwhfjs9k9HoDUwAHnYtXdgmf1AVNs0=
+github.com/hashicorp/go-uuid v1.0.1/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro=
+github.com/hashicorp/go-uuid v1.0.2/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro=
 github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ=
+github.com/hashicorp/yamux v0.0.0-20180604194846-3520598351bb/go.mod h1:+NfK9FKeTrX5uv1uIXGdwYDTeHna2qgaIlx54MXqjAM=
+github.com/hashicorp/yamux v0.0.0-20190923154419-df201c70410d/go.mod h1:+NfK9FKeTrX5uv1uIXGdwYDTeHna2qgaIlx54MXqjAM=
 github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
 github.com/huandu/xstrings v1.3.0/go.mod h1:y5/lhBue+AyNmUVz9RLU9xbLR0o4KIIExikq4ovT0aE=
-github.com/hydrogen18/memlistener v0.0.0-20141126152155-54553eb933fb/go.mod h1:qEIFzExnS6016fRpRfxrExeVn2gbClQA99gQhnIcdhE=
-github.com/hydrogen18/memlistener v0.0.0-20200120041712-dcc25e7acd91/go.mod h1:qEIFzExnS6016fRpRfxrExeVn2gbClQA99gQhnIcdhE=
 github.com/imdario/mergo v0.3.9/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA=
-github.com/imkira/go-interpol v1.1.0/go.mod h1:z0h2/2T3XF8kyEPpRgJ3kmNv+C43p+I/CoI+jC3w2iA=
 github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8=
-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=
-github.com/iris-contrib/i18n v0.0.0-20171121225848-987a633949d0/go.mod h1:pMCz62A0xJL6I+umB2YTlFRwWXaDFA0jy+5HzGiJjqI=
-github.com/iris-contrib/jade v1.1.3/go.mod h1:H/geBymxJhShH5kecoiOCSssPX7QWYH7UaeZTSWddIk=
-github.com/iris-contrib/pongo2 v0.0.1/go.mod h1:Ssh+00+3GAZqSQb30AvBRNxBx7rf0GqwkjqxNd0u65g=
-github.com/iris-contrib/schema v0.0.1/go.mod h1:urYA3uvUNG1TIIjOSCzHr9/LmbQo8LrOcOqfqxa4hXw=
+github.com/jaegertracing/jaeger v1.18.1 h1:eFqjEpTKq2FfiZ/YX53oxeCePdIZyWvDfXaTAGj0r5E=
+github.com/jaegertracing/jaeger v1.18.1/go.mod h1:WRzMFH62rje1VgbShlgk6UbWUNoo08uFFvs/x50aZKk=
+github.com/jcmturner/gofork v0.0.0-20190328161633-dc7c13fece03/go.mod h1:MK8+TM0La+2rjBD4jE12Kj1pCCxK7d2LK/UM3ncEo0o=
+github.com/jcmturner/gofork v1.0.0/go.mod h1:MK8+TM0La+2rjBD4jE12Kj1pCCxK7d2LK/UM3ncEo0o=
+github.com/jhump/protoreflect v1.6.0/go.mod h1:eaTn3RZAmMBcV0fifFvlm6VHNz3wSkYyXYWUh7ymB74=
+github.com/joho/godotenv v1.3.0/go.mod h1:7hK45KPybAkOC6peb+G5yklZfMxEjkZhHbwpqxOKXbg=
+github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo=
 github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU=
-github.com/json-iterator/go v1.1.9/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
+github.com/json-iterator/go v1.1.7/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
 github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU=
-github.com/juju/errors v0.0.0-20181118221551-089d3ea4e4d5/go.mod h1:W54LbzXuIE0boCoNJfwqpmkKJ1O4TCTZMetAt6jGk7Q=
-github.com/juju/loggo v0.0.0-20180524022052-584905176618/go.mod h1:vgyd7OREkbtVEN/8IXZe5Ooef3LQePvuBm9UWj6ZL8U=
-github.com/juju/testing v0.0.0-20180920084828-472a3e8b2073/go.mod h1:63prj8cnj0tU0S9OHjGJn+b1h0ZghCndfnbQolrYTwA=
-github.com/k0kubun/colorstring v0.0.0-20150214042306-9440f1994b88/go.mod h1:3w7q1U84EfirKl04SVQ/s7nPm1ZPhiXd34z40TNz36k=
-github.com/kataras/golog v0.0.9/go.mod h1:12HJgwBIZFNGL0EJnMRhmvGA0PQGx8VFwrZtM4CqbAk=
-github.com/kataras/golog v0.0.10/go.mod h1:yJ8YKCmyL+nWjERB90Qwn+bdyBZsaQwU3bTVFgkFIp8=
-github.com/kataras/iris/v12 v12.0.1/go.mod h1:udK4vLQKkdDqMGJJVd/msuMtN6hpYJhg/lSzuxjhO+U=
-github.com/kataras/iris/v12 v12.1.8/go.mod h1:LMYy4VlP67TQ3Zgriz8RE2h2kMZV2SgMYbq3UhfoFmE=
-github.com/kataras/neffos v0.0.10/go.mod h1:ZYmJC07hQPW67eKuzlfY7SO3bC0mw83A3j6im82hfqw=
-github.com/kataras/neffos v0.0.14/go.mod h1:8lqADm8PnbeFfL7CLXh1WHw53dG27MC3pgi2R1rmoTE=
-github.com/kataras/pio v0.0.0-20190103105442-ea782b38602d/go.mod h1:NV88laa9UiiDuX9AhMbDPkGYSPugBOV6yTZB1l2K9Z0=
-github.com/kataras/pio v0.0.2/go.mod h1:hAoW0t9UmXi4R5Oyq5Z4irTbaTsOemSrDGUtaTl7Dro=
-github.com/kataras/sitemap v0.0.5/go.mod h1:KY2eugMKiPwsJgx7+U103YZehfvNGOXURubcGyk0Bz8=
+github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w=
+github.com/karrick/godirwalk v1.8.0/go.mod h1:H5KPZjojv4lE+QYImBI8xVtrBRgYrIVsaRPx4tDPEn4=
+github.com/karrick/godirwalk v1.10.3/go.mod h1:RoGL9dQei4vP9ilrpETWE8CLOZ1kiN0LhBygSwrAsHA=
+github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q=
 github.com/kisielk/errcheck v1.2.0/go.mod h1:/BMXB+zMLi60iA8Vv6Ksmxu/1UDYcXs4uQLJ+jE2L00=
 github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8=
 github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
-github.com/klauspost/compress v1.8.2/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A=
-github.com/klauspost/compress v1.9.0/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A=
-github.com/klauspost/compress v1.9.7/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A=
-github.com/klauspost/cpuid v1.2.1/go.mod h1:Pj4uuM528wm8OyEC2QMXAi2YiTZ96dNQPGgoMS4s3ek=
+github.com/klauspost/compress v1.9.5/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A=
 github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
 github.com/konsorten/go-windows-terminal-sequences v1.0.2/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
+github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc=
 github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
 github.com/kr/pretty v0.2.0/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI=
-github.com/kr/pretty v0.3.0 h1:WgNl7dwNpEZ6jJ9k1snq4pZsg7DOEN8hP9Xw0Tsjwk0=
-github.com/kr/pretty v0.3.0/go.mod h1:640gp4NfQd8pI5XOwp5fnNeVWj67G7CFk/SaSQn7NBk=
+github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
+github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk=
 github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
+github.com/kr/pty v1.1.5/go.mod h1:9r2w37qlBe7rQ6e1fg1S/9xpWHSnaqNdHD3WcMdbPDA=
+github.com/kr/pty v1.1.8/go.mod h1:O1sed60cT9XZ5uDucP5qwvh+TE3NnUj51EiZO/lmSfw=
 github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
 github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
 github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
-github.com/labstack/echo/v4 v4.1.11/go.mod h1:i541M3Fj6f76NZtHSj7TXnyM8n2gaodfvfxNnFqi74g=
-github.com/labstack/echo/v4 v4.5.0/go.mod h1:czIriw4a0C1dFun+ObrXp7ok03xON0N1awStJ6ArI7Y=
-github.com/labstack/gommon v0.3.0/go.mod h1:MULnywXg0yavhxWKc+lOruYdAhDwPK9wf0OL7NoOu+k=
 github.com/lib/pq v0.0.0-20180327071824-d34b9ff171c2/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
+github.com/lib/pq v1.2.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
 github.com/lib/pq v1.8.0/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o=
 github.com/lib/pq v1.10.6 h1:jbk+ZieJ0D7EVGJYpL9QTz7/YW6UHbmdnZWYyK5cdBs=
 github.com/lib/pq v1.10.6/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o=
-github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ=
-github.com/mattn/go-colorable v0.1.2/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE=
-github.com/mattn/go-colorable v0.1.8/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc=
-github.com/mattn/go-colorable v0.1.11/go.mod h1:u5H1YNBxpqRaxsYJYSkiCWKzEfiAb1Gb520KVy5xxl4=
-github.com/mattn/go-isatty v0.0.7/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s=
+github.com/magiconair/properties v1.8.1/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ=
+github.com/mailru/easyjson v0.0.0-20180823135443-60711f1a8329/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
+github.com/mailru/easyjson v0.0.0-20190312143242-1de009706dbe/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
+github.com/mailru/easyjson v0.0.0-20190614124828-94de47d64c63/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
+github.com/mailru/easyjson v0.0.0-20190626092158-b2ccc519800e/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
+github.com/mailru/easyjson v0.7.0/go.mod h1:KAzv3t3aY1NaHWoQz1+4F1ccyAH66Jk7yos7ldAVICs=
+github.com/mailru/easyjson v0.7.1/go.mod h1:KAzv3t3aY1NaHWoQz1+4F1ccyAH66Jk7yos7ldAVICs=
+github.com/markbates/oncer v0.0.0-20181203154359-bf2de49a0be2/go.mod h1:Ld9puTsIW75CHf65OeIOkyKbteujpZVXDpWK6YGZbxE=
+github.com/markbates/safe v1.0.1/go.mod h1:nAqgmRi7cY2nqMc92/bSEeQA+R4OheNU2T1kNSCBdG0=
+github.com/mattn/go-colorable v0.1.4/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE=
 github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s=
-github.com/mattn/go-isatty v0.0.9/go.mod h1:YNRxwqDuOph6SZLI9vUUz6OYw3QyUt7WiY2yME+cCiQ=
-github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU=
-github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94=
-github.com/mattn/goveralls v0.0.2/go.mod h1:8d1ZMHsd7fW6IRPKQh46F2WRpyib5/X4FOpevwGNQEw=
-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=
-github.com/mediocregopher/radix/v3 v3.4.2/go.mod h1:8FL3F6UQRXHXIBSPUs5h0RybMF8i4n7wVopoX3x7Bv8=
-github.com/microcosm-cc/bluemonday v1.0.2/go.mod h1:iVP4YcDBq+n/5fb23BhYFvIMq/leAFZyRl6bYmGDlGc=
+github.com/mattn/go-isatty v0.0.10/go.mod h1:qgIWMr58cqv1PHHyhnkY9lrL7etaEgOFcMEpPG5Rm84=
+github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=
 github.com/mitchellh/copystructure v1.0.0/go.mod h1:SNtv71yrdKgLRyLFxmLdkAbkKEFWgYaq1OVrnRcwhnw=
-github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0=
+github.com/mitchellh/go-testing-interface v0.0.0-20171004221916-a61a99592b77/go.mod h1:kRemZodwjscx+RGhAo8eIhFbs2+BFgRtFPeD/KE+zxI=
+github.com/mitchellh/go-testing-interface v1.0.0/go.mod h1:kRemZodwjscx+RGhAo8eIhFbs2+BFgRtFPeD/KE+zxI=
 github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
 github.com/mitchellh/reflectwalk v1.0.0/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw=
+github.com/mjibson/esc v0.2.0/go.mod h1:9Hw9gxxfHulMF5OJKCyhYD7PzlSdhzXyaGEBRPH1OPs=
 github.com/mmcloughlin/geohash v0.9.0 h1:FihR004p/aE1Sju6gcVq5OLDqGcMnpBY+8moBqIsVOs=
 github.com/mmcloughlin/geohash v0.9.0/go.mod h1:oNZxQo5yWJh0eMQEP/8hwQuVx9Z9tjwFUqcTB1SmG0c=
 github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
 github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
 github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
 github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
-github.com/moul/http2curl v1.0.0/go.mod h1:8UbvGypXm98wA/IqH45anm5Y2Z6ep6O31QGOAZ3H0fQ=
-github.com/nats-io/jwt v0.3.0/go.mod h1:fRYCDE99xlTsqUzISS1Bi75UBJ6ljOJQOAAu5VglpSg=
-github.com/nats-io/nats.go v1.8.1/go.mod h1:BrFz9vVn0fU3AcH9Vn4Kd7W0NpJ651tD5omQ3M8LwxM=
-github.com/nats-io/nats.go v1.9.1/go.mod h1:ZjDU1L/7fJ09jvUSRVBR2e7+RnLiiIQyqyzEE/Zbp4w=
-github.com/nats-io/nkeys v0.0.2/go.mod h1:dab7URMsZm6Z/jp9Z5UGa87Uutgc2mVpXLC4B7TDb/4=
-github.com/nats-io/nkeys v0.1.0/go.mod h1:xpnFELMwJABBLVhffcfd1MZx6VsNRFpEugbxziKVo7w=
-github.com/nats-io/nuid v1.0.1/go.mod h1:19wcPz3Ph3q0Jbyiqsd0kePYG7A95tJPxeL+1OSON2c=
-github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A=
+github.com/montanaflynn/stats v0.0.0-20171201202039-1bf9dbcd8cbe/go.mod h1:wL8QJuTMNUDYhXwkmfOly8iTdp5TEcJFWZD2D7SIkUc=
+github.com/mozilla/tls-observatory v0.0.0-20190404164649-a3c1b6cfecfd/go.mod h1:SrKMQvPiws7F7iqYp8/TX+IhxCYhzr6N/1yb8cwHsGk=
+github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
+github.com/nbutton23/zxcvbn-go v0.0.0-20180912185939-ae427f1e4c1d/go.mod h1:o96djdrsSGy3AWPyBgZMAGfxZNfgntdJG+11KU4QvbU=
+github.com/oklog/run v1.0.0/go.mod h1:dlhp/R75TPv97u0XWUtDeV/lRKWPKSdTuV0TZvrmrQA=
+github.com/oklog/run v1.1.0/go.mod h1:sVPdnTZT1zYwAJeCMu2Th4T21pA3FPOQRfWjQlk7DVU=
+github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U=
+github.com/olivere/elastic v6.2.27+incompatible/go.mod h1:J+q1zQJTgAz9woqsbVRqGeB5G1iqDKVBWLNSYW8yfJ8=
 github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
-github.com/onsi/ginkgo v1.10.3/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
-github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk=
-github.com/onsi/ginkgo v1.13.0/go.mod h1:+REjRxOmWfHCjfv9TTWB1jD1Frx4XydAD3zm1lskyM0=
+github.com/onsi/ginkgo v1.12.0/go.mod h1:oUhWkIvk5aDxtKvDDuw8gItl8pKl42LzjC9KZE0HfGg=
 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.9.0/go.mod h1:Ho0h+IUsWyvy1OpqCwxlQ/21gkhVunqlU8fDGcoTdcA=
 github.com/opencontainers/go-digest v1.0.0-rc1/go.mod h1:cMLVZDEM3+U2I4VmLI6N8jQYUd2OVphdqWwCJHrFt2s=
 github.com/opencontainers/image-spec v1.0.1/go.mod h1:BtxoFyWECRxE4U/7sNtV5W15zMzWCbyJoFRP3s7yZA0=
 github.com/opencontainers/runc v1.0.0-rc9/go.mod h1:qT5XzbpPznkRYVz/mWwUaVBUv2rmF59PVA73FjuZG0U=
+github.com/opentracing-contrib/go-stdlib v0.0.0-20190519235532-cf7a6c988dc9/go.mod h1:PLldrQSroqzH70Xl+1DQcGnefIbqsKR7UDaiux3zV+w=
+github.com/opentracing/opentracing-go v1.1.0/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o=
+github.com/openzipkin/zipkin-go v0.4.3 h1:9EGwpqkgnwdEIJ+Od7QVSEIH+ocmm5nPat0G7sjsSdg=
+github.com/openzipkin/zipkin-go v0.4.3/go.mod h1:M9wCJZFWCo2RiY+o1eBCEMe0Dp2S5LDHcMZmk3RmK7c=
 github.com/ory/dockertest/v3 v3.6.0/go.mod h1:4ZOpj8qBUmh8fcBSVzkH2bws2s91JdGvHUqan4GHEuQ=
+github.com/pborman/uuid v1.2.0/go.mod h1:X/NO0urCmaxf9VXbdlT7C2Yzkj2IKimNn4k+gtPdI/k=
 github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic=
+github.com/pelletier/go-toml v1.4.0/go.mod h1:PN7xzY2wHTK0K9p34ErDQMlFxa51Fk0OUruD3k1mMwo=
+github.com/pelletier/go-toml v1.6.0/go.mod h1:5N711Q9dKgbdkxHL+MEfF31hpT7l0S0s/t2kKREewys=
 github.com/petermattis/goid v0.0.0-20180202154549-b0b1615b78e5 h1:q2e307iGHPdTGp0hoxKjt1H5pDo6utceo3dQVK3I5XQ=
 github.com/petermattis/goid v0.0.0-20180202154549-b0b1615b78e5/go.mod h1:jvVRKCrJTQWu0XVbaOlby/2lO20uSCHEMzzplHXte1o=
+github.com/pierrec/lz4 v0.0.0-20190327172049-315a67e90e41/go.mod h1:3/3N9NVKO0jef7pBehbT1qWhCMrIgbYNnFAZCqQ5LRc=
+github.com/pierrec/lz4 v2.4.1+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY=
 github.com/pierrre/compare v1.0.2 h1:k4IUsHgh+dbcAOIWCfxVa/7G6STjADH2qmhomv+1quc=
 github.com/pierrre/compare v1.0.2/go.mod h1:8UvyRHH+9HS8Pczdd2z5x/wvv67krDwVxoOndaIIDVU=
 github.com/pierrre/geohash v1.0.0 h1:f/zfjdV4rVofTCz1FhP07T+EMQAvcMM2ioGZVt+zqjI=
@@ -264,249 +361,323 @@ github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINE
 github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
 github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
 github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
+github.com/pkg/profile v1.2.1/go.mod h1:hJw3o1OdXxsrSjjVksARp5W95eeEaEfptyVZyv6JUPA=
 github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
 github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
+github.com/prashantv/protectmem v0.0.0-20171002184600-e20412882b3a/go.mod h1:lzZQ3Noex5pfAy7mkAeCjcBDteYU85uWWnJ/y6gKU8k=
+github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw=
+github.com/prometheus/client_golang v0.9.3/go.mod h1:/TN21ttK/J9q6uSwhBd54HahCDft0ttaMvbicHlPoso=
+github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo=
+github.com/prometheus/client_golang v1.1.0/go.mod h1:I1FGZT9+L76gKKOs5djB6ezCbFQP1xR9D75/vuwEF3g=
+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/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
+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.6.0/go.mod h1:eBmuwkDJBwy6iBfxCBob6t6dR6ENT/y+J+Zk0j9GMYc=
+github.com/prometheus/common v0.9.1/go.mod h1:yhUN8i9wzaXS3w1O07YhxHEBxD+W35wd8bs7vj7HSQ4=
+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.0.3/go.mod h1:4A/X28fw3Fc593LaREMrKMqOKvUAntwMDaekg4FpcdQ=
+github.com/prometheus/procfs v0.0.10/go.mod h1:7Qr8sr6344vo1JqZ6HhLceV9o3AJ1Ff+GxbHq6oeK9A=
+github.com/prometheus/tsdb v0.7.1/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40TwIPHuXU=
+github.com/rcrowley/go-metrics v0.0.0-20181016184325-3113b8401b8a/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4=
+github.com/rcrowley/go-metrics v0.0.0-20190826022208-cac0b30c2563/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4=
+github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg=
 github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ=
-github.com/rogpeppe/go-internal v1.6.1/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc=
-github.com/rogpeppe/go-internal v1.8.1 h1:geMPLpDpQOgVyCg5z5GoRwLHepNdb71NXb67XFkP+Eg=
-github.com/rogpeppe/go-internal v1.8.1/go.mod h1:JeRgkft04UBgHMgCIwADu4Pn6Mtm5d4nPKWu0nJ5d+o=
+github.com/rogpeppe/go-internal v1.1.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
+github.com/rogpeppe/go-internal v1.2.2/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
+github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
+github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs=
+github.com/rogpeppe/go-internal v1.13.1 h1:KvO1DLK/DRN07sQ1LQKScxyZJuNnedQ5/wKSR38lUII=
+github.com/rogpeppe/go-internal v1.13.1/go.mod h1:uMEvuHeurkdAXX61udpOXGD/AzZDWNMNyH2VO9fmH0o=
+github.com/rs/cors v1.7.0/go.mod h1:gFx+x8UowdsKA9AchylcLynDq+nNFfI8FkUZdN/jGCU=
 github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g=
-github.com/ryanuber/columnize v2.1.0+incompatible/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts=
 github.com/sasha-s/go-deadlock v0.3.1 h1:sqv7fDNShgjcaxkO0JNcOAlr8B9+cV5Ey/OB71efZx0=
 github.com/sasha-s/go-deadlock v0.3.1/go.mod h1:F73l+cr82YSh10GxyRI6qZiCgK64VaZjwesgfQ1/iLM=
-github.com/schollz/closestmatch v2.1.0+incompatible/go.mod h1:RtP1ddjLong6gTkbtmuhtR2uUrrJOpYzYRvbcPAid+g=
-github.com/sclevine/agouti v3.0.0+incompatible/go.mod h1:b4WX9W9L1sfQKXeJf1mUTLZKJ48R1S7H23Ji7oFO5Bw=
+github.com/sectioneight/md-to-godoc v0.0.0-20161108233149-55e43be6c335/go.mod h1:lPZq22klO8la1kyImIDhrGytugMV0TsrsZB55a+xxI0=
+github.com/securego/gosec v0.0.0-20200203094520-d13bb6d2420c/go.mod h1:gp0gaHj0WlmPh9BdsTmo1aq6C27yIPWdxCKGFGdVKBE=
 github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo=
-github.com/sergi/go-diff v1.1.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM=
 github.com/sergi/go-diff v1.2.0 h1:XU+rvMAioB0UC3q1MFrIQy4Vo5/4VsRDQQXHsEya6xQ=
 github.com/sergi/go-diff v1.2.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM=
-github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc=
+github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo=
+github.com/sirupsen/logrus v1.4.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo=
 github.com/sirupsen/logrus v1.4.1/go.mod h1:ni0Sbl8bgC9z8RoU9G6nDWqqs/fq4eDPysMBDgk/93Q=
 github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE=
 github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc=
 github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA=
+github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM=
 github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/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/cast v1.3.1/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE=
+github.com/spf13/cobra v0.0.3/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ=
 github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo=
+github.com/spf13/jwalterweatherman v1.1.0/go.mod h1:aNWZUN0dPAAO/Ljvb5BEdw96iTZ0EXowPYD95IqWIGo=
 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=
 github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
-github.com/spf13/viper v1.3.2/go.mod h1:ZiWeW+zYFKm7srdB9IoDzzZXaJaI5eL9QjNiN/DMA2s=
+github.com/spf13/viper v1.6.2/go.mod h1:t3iDnF5Jlj76alVNuyFBk5oUMCvsrkbvZK0WQdfDi5k=
+github.com/streadway/quantile v0.0.0-20150917103942-b0c588724d25/go.mod h1:lbP8tGiBjZ5YWIc2fzuRpTaz0b/53vT6PEs3QuAWzuU=
 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.2.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoHMkEqE=
 github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
 github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
 github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
-github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=
+github.com/stretchr/testify v1.5.0/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=
 github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
-github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY=
-github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
+github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA=
+github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
+github.com/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69rRypqCw=
 github.com/the42/cartconvert v0.0.0-20131203171324-aae784c392b8 h1:I4DY8wLxJXCrMYzDM6lKCGc3IQwJX0PlTLsd3nQqI3c=
 github.com/the42/cartconvert v0.0.0-20131203171324-aae784c392b8/go.mod h1:fWO/msnJVhHqN1yX6OBoxSyfj7TEj1hHiL8bJSQsK30=
+github.com/tidwall/pretty v1.0.0/go.mod h1:XNkn88O1ChpSDQmQeStsy+sBenx6DDtFZJxhVysOjyk=
+github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U=
 github.com/twpayne/go-geom v1.4.1 h1:LeivFqaGBRfyg0XJJ9pkudcptwhSSrYN9KZUW6HcgdA=
 github.com/twpayne/go-geom v1.4.1/go.mod h1:k/zktXdL+qnA6OgKsdEGUTA17jbQ2ZPTUa3CCySuGpE=
 github.com/twpayne/go-kml v1.5.2 h1:rFMw2/EwgkVssGS2MT6YfWSPZz6BgcJkLxQ53jnE8rQ=
 github.com/twpayne/go-kml v1.5.2/go.mod h1:kz8jAiIz6FIdU2Zjce9qGlVtgFYES9vt7BTPBHf5jl4=
 github.com/twpayne/go-polyline v1.0.0/go.mod h1:ICh24bcLYBX8CknfvNPKqoTbe+eg+MX1NPyJmSBo7pU=
 github.com/twpayne/go-waypoint v0.0.0-20200706203930-b263a7f6e4e8/go.mod h1:qj5pHncxKhu9gxtZEYWypA/z097sxhFlbTyOyt9gcnU=
+github.com/uber/jaeger-client-go v2.22.1+incompatible/go.mod h1:WVhlPFC8FDjOFMMWRy2pZqQJSXxYSwNYOkTr/Z6d3Kk=
+github.com/uber/jaeger-lib v2.2.0+incompatible/go.mod h1:ComeNDZlWwrWnDv8aPp0Ba6+uUTzImX/AauajbLI56U=
+github.com/uber/tchannel-go v1.16.0/go.mod h1:Rrgz1eL8kMjW/nEzZos0t+Heq0O4LhnUJVA32OvWKHo=
 github.com/ugorji/go v1.1.4/go.mod h1:uQMGLiO92mf5W77hV/PUCpI3pbzQx3CRekS0kk+RGrc=
-github.com/ugorji/go v1.1.7/go.mod h1:kZn38zHttfInRq0xu/PH0az30d+z6vm202qpg1oXVMw=
-github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0=
-github.com/ugorji/go/codec v1.1.7/go.mod h1:Ax+UKWsSmolVDwsd+7N3ZtXu+yMGCf907BLYF3GoBXY=
-github.com/urfave/negroni v1.0.0/go.mod h1:Meg73S6kFm/4PpbYdq35yYWoCZ9mS/YSx+lKnmiohz4=
-github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc=
-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/fasttemplate v1.2.1/go.mod h1:KHLXt3tVN2HBp8eijSv/kGJopbvo7S+qRAEEKiv+SiQ=
-github.com/valyala/tcplisten v0.0.0-20161114210144-ceec8f93295a/go.mod h1:v3UYOV9WzVtRmSR+PDvWpU/qWl4Wa5LApYYX4ZtKbio=
-github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU=
-github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415/go.mod h1:GwrjFmJcFw6At/Gs6z4yjiIwzuJ1/+UwLxMQDVQXShQ=
-github.com/xeipuuv/gojsonschema v1.2.0/go.mod h1:anYRn/JVcOK2ZgGU+IjEV4nwlhoK5sQluxsYJ78Id3Y=
+github.com/vektah/gqlparser v1.1.2/go.mod h1:1ycwN7Ij5njmMkPPAOaRFY4rET2Enx7IkVv3vaXspKw=
+github.com/vektra/mockery v0.0.0-20181123154057-e78b021dcbb5/go.mod h1:ppEjwdhyy7Y31EnHRDm1JkChoC7LXIJ7Ex0VYLWtZtQ=
+github.com/wadey/gocovmerge v0.0.0-20160331181800-b5bfa59ec0ad/go.mod h1:Hy8o65+MXnS6EwGElrSRjUzQDLXreJlzYLlWiHtt8hM=
+github.com/xdg/scram v0.0.0-20180814205039-7eeb5667e42c/go.mod h1:lB8K/P019DLNhemzwFU4jHLhdvlE6uDZjXFejJXr49I=
+github.com/xdg/stringprep v0.0.0-20180714160509-73f8eece6fdc/go.mod h1:Jhud4/sHMO4oL310DaZAKk9ZaJ08SJfe+sJh0HrGL1Y=
+github.com/xdg/stringprep v1.0.0/go.mod h1:Jhud4/sHMO4oL310DaZAKk9ZaJ08SJfe+sJh0HrGL1Y=
+github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU=
 github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q=
-github.com/yalp/jsonpath v0.0.0-20180802001716-5cc68e5049a0/go.mod h1:/LWChgwKmvncFJFHJ7Gvn9wZArjbV5/FppcK2fKk/tI=
-github.com/yudai/gojsondiff v1.0.0/go.mod h1:AY32+k2cwILAkW1fbgxQ5mUmMiZFgLIV+FBNExI05xg=
-github.com/yudai/golcs v0.0.0-20170316035057-ecda9a501e82/go.mod h1:lgjkn3NuSvDfVJdfcVVdX+jpBxNmX4rDAzaS45IcYoM=
-github.com/yudai/pp v2.0.1+incompatible/go.mod h1:PuxR/8QJ7cyCkFp/aUDS+JY727OFEZkTdatxwunjIkc=
 github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
 github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
-github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
-go.opentelemetry.io/proto/otlp v0.7.0/go.mod h1:PqfVotwruBrMGOCsRd/89rSnXhoiJIqeYNgFYFoEGnI=
-golang.org/x/crypto v0.0.0-20181203042331-505ab145d0a9/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
+go.etcd.io/bbolt v1.3.2/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU=
+go.mongodb.org/mongo-driver v1.0.3/go.mod h1:u7ryQJ+DOzQmeO7zB6MHyr8jkEQvC8vH7qLUO4lqsUM=
+go.mongodb.org/mongo-driver v1.1.1/go.mod h1:u7ryQJ+DOzQmeO7zB6MHyr8jkEQvC8vH7qLUO4lqsUM=
+go.mongodb.org/mongo-driver v1.1.2/go.mod h1:u7ryQJ+DOzQmeO7zB6MHyr8jkEQvC8vH7qLUO4lqsUM=
+go.mongodb.org/mongo-driver v1.3.0/go.mod h1:MSWZXKOynuguX+JSvwP8i+58jYCXxbia8HS3gZBapIE=
+go.opentelemetry.io/auto/sdk v1.1.0 h1:cH53jehLUN6UFLY71z+NDOiNJqDdPRaXzTel0sJySYA=
+go.opentelemetry.io/auto/sdk v1.1.0/go.mod h1:3wSPjt5PWp2RhlCcmmOial7AvC4DQqZb7a7wCow3W8A=
+go.opentelemetry.io/otel v1.36.0 h1:UumtzIklRBY6cI/lllNZlALOF5nNIzJVb16APdvgTXg=
+go.opentelemetry.io/otel v1.36.0/go.mod h1:/TcFMXYjyRNh8khOAO9ybYkqaDBb/70aVwkNML4pP8E=
+go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.36.0 h1:dNzwXjZKpMpE2JhmO+9HsPl42NIXFIFSUSSs0fiqra0=
+go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.36.0/go.mod h1:90PoxvaEB5n6AOdZvi+yWJQoE95U8Dhhw2bSyRqnTD0=
+go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.36.0 h1:JgtbA0xkWHnTmYk7YusopJFX6uleBmAuZ8n05NEh8nQ=
+go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.36.0/go.mod h1:179AK5aar5R3eS9FucPy6rggvU0g52cvKId8pv4+v0c=
+go.opentelemetry.io/otel/exporters/zipkin v1.36.0 h1:s0n95ya5tOG03exJ5JySOdJFtwGo4ZQ+KeY7Zro4CLI=
+go.opentelemetry.io/otel/exporters/zipkin v1.36.0/go.mod h1:m9wRxtKA2MZ1HcnNC4BKI+9aYe434qRZTCvI7QGUN7Y=
+go.opentelemetry.io/otel/metric v1.36.0 h1:MoWPKVhQvJ+eeXWHFBOPoBOi20jh6Iq2CcCREuTYufE=
+go.opentelemetry.io/otel/metric v1.36.0/go.mod h1:zC7Ks+yeyJt4xig9DEw9kuUFe5C3zLbVjV2PzT6qzbs=
+go.opentelemetry.io/otel/sdk v1.36.0 h1:b6SYIuLRs88ztox4EyrvRti80uXIFy+Sqzoh9kFULbs=
+go.opentelemetry.io/otel/sdk v1.36.0/go.mod h1:+lC+mTgD+MUWfjJubi2vvXWcVxyr9rmlshZni72pXeY=
+go.opentelemetry.io/otel/sdk/metric v1.34.0 h1:5CeK9ujjbFVL5c1PhLuStg1wxA7vQv7ce1EK0Gyvahk=
+go.opentelemetry.io/otel/sdk/metric v1.34.0/go.mod h1:jQ/r8Ze28zRKoNRdkjCZxfs6YvBTG1+YIqyFVFYec5w=
+go.opentelemetry.io/otel/trace v1.36.0 h1:ahxWNuqZjpdiFAyrIoQ4GIiAIhxAunQR6MUoKrsNd4w=
+go.opentelemetry.io/otel/trace v1.36.0/go.mod h1:gQ+OnDZzrybY4k4seLzPAWNwVBBVlF2szhehOBB/tGA=
+go.opentelemetry.io/proto/otlp v1.6.0 h1:jQjP+AQyTf+Fe7OKj/MfkDrmK4MNVtw2NpXsf9fefDI=
+go.opentelemetry.io/proto/otlp v1.6.0/go.mod h1:cicgGehlFuNdgZkcALOCh3VE6K/u2tAjzlRhDwmVpZc=
+go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE=
+go.uber.org/atomic v1.5.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ=
+go.uber.org/atomic v1.5.1/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ=
+go.uber.org/automaxprocs v1.3.0/go.mod h1:9CWT6lKIep8U41DDaPiH6eFscnTyjfTANNQNx6LrIcA=
+go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto=
+go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE=
+go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0=
+go.uber.org/multierr v1.3.0/go.mod h1:VgVr7evmIr6uPjLBxg28wmKNXyqE9akIJ5XnfpiKl+4=
+go.uber.org/multierr v1.4.0/go.mod h1:VgVr7evmIr6uPjLBxg28wmKNXyqE9akIJ5XnfpiKl+4=
+go.uber.org/tools v0.0.0-20190618225709-2cfd321de3ee/go.mod h1:vJERXedbb3MVM5f9Ejo0C68/HhF8uaILCdgjnY+goOA=
+go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q=
+go.uber.org/zap v1.13.0/go.mod h1:zwrFLgMcdUuIBviXEYEH1YKNaOBnKXsx2IPda5bBwHM=
+golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
 golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
-golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
+golang.org/x/crypto v0.0.0-20190320223903-b7391e95e576/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
+golang.org/x/crypto v0.0.0-20190404164418-38d8ce5564a5/go.mod h1:WFFai1msRO1wXaEeE5yQxYXgSfI8pQAWXbQop6sCtWE=
+golang.org/x/crypto v0.0.0-20190422162423-af44ce270edf/go.mod h1:WFFai1msRO1wXaEeE5yQxYXgSfI8pQAWXbQop6sCtWE=
+golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
+golang.org/x/crypto v0.0.0-20190530122614-20be4c3c3ed5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
+golang.org/x/crypto v0.0.0-20190611184440-5c40567a22f8/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
+golang.org/x/crypto v0.0.0-20190617133340-57b3e21c3d56/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
 golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
-golang.org/x/crypto v0.0.0-20191227163750-53104e6ec876/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
+golang.org/x/crypto v0.0.0-20200214034016-1d94cc7ab1c6/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
 golang.org/x/crypto v0.0.0-20200323165209-0ec3e9974c59/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
 golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
-golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4=
-golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
 golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
 golang.org/x/exp v0.0.0-20240205201215-2c58cdc269a3 h1:/RIbNt/Zr7rVhIkQhooTxCxFcdWLGIKnZA4IXNFSrvo=
 golang.org/x/exp v0.0.0-20240205201215-2c58cdc269a3/go.mod h1:idGWGoKP1toJGkd5/ig9ZLuPcZBC3ewk7SzmH0uou08=
 golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
 golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU=
 golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
-golang.org/x/lint v0.0.0-20210508222113-6edffad5e616/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
+golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
+golang.org/x/lint v0.0.0-20191125180803-fdd1cda4f05f/go.mod h1:5qLYkcX4OjUUV8bRuDixDT3tpyyb+LUpUlRWLxfhWrs=
+golang.org/x/lint v0.0.0-20200130185559-910be7a94367/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
+golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc=
 golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=
 golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
 golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
-golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
-golang.org/x/mod v0.14.0 h1:dGoOF9QVLYng8IHTm7BAyWqCqSheQ5pYWGhzW00YJr0=
-golang.org/x/mod v0.14.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c=
+golang.org/x/mod v0.21.0 h1:vvrHzRwRfVKSiLrG+d4FMl/Qi4ukBCE6kZlTUkDYRT0=
+golang.org/x/mod v0.21.0/go.mod h1:6SkKJ3Xj0I0BrPOZoBy3bdMptDDU9oJrpohJ3eWZ1fY=
+golang.org/x/net v0.0.0-20180530234432-1e491301e022/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
 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=
+golang.org/x/net v0.0.0-20181005035420-146acd28ed58/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
+golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
 golang.org/x/net v0.0.0-20181220203305-927f97764cc3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
 golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
 golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
 golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
-golang.org/x/net v0.0.0-20190327091125-710a502c58a2/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
+golang.org/x/net v0.0.0-20190320064053-1272bf9dcd53/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
 golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
-golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
+golang.org/x/net v0.0.0-20190522155817-f3200d17e092/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks=
+golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
 golang.org/x/net v0.0.0-20190620200207-3b0461eec859/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-20190923162816-aa69164e4478/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-20191003171128-d98b1b443823/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-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
 golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
-golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
 golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
 golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
-golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
-golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM=
-golang.org/x/net v0.0.0-20211008194852-3b03d305991f/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
-golang.org/x/net v0.20.0 h1:aCL9BSgETF1k+blQaYUBx9hJ9LOGP3gAVemcZlf1Kpo=
-golang.org/x/net v0.20.0/go.mod h1:z8BVo6PvndSri0LbOE3hAn0apkU+1YvI6E70E9jsnvY=
+golang.org/x/net v0.40.0 h1:79Xs7wF06Gbdcg4kdCCIQArK11Z1hr5POQ6+fIYHNuY=
+golang.org/x/net v0.40.0/go.mod h1:y0hY0exeL2Pku80/zKK7tpntoX23cqL3Oa6njdgRtds=
 golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
 golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
 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=
 golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
+golang.org/x/sync v0.0.0-20190412183630-56d357773e84/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
 golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
 golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
 golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/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.6.0 h1:5BMeUDZ7vkXGfEr1x9B4bRcTH4lpkTkpdh0T/J+qjbQ=
-golang.org/x/sync v0.6.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
+golang.org/x/sync v0.14.0 h1:woo0S4Yywslg6hp4eUFjTVOyKt0RookbpAHG4c1HmhQ=
+golang.org/x/sync v0.14.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA=
 golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
 golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
 golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
-golang.org/x/sys v0.0.0-20181205085412-a5c9d58dba9a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
+golang.org/x/sys v0.0.0-20181107165924-66b7b1311ac8/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
+golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
 golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
 golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
+golang.org/x/sys v0.0.0-20190321052220-f7bb7a8bee54/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20190403152447-81d4e9dc473e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20190419153524-e8e3143a4f4a/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20190626221950-04f50cda93cb/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20190813064441-fde4db37ae7a/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20190904154756-749cb33beabd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20190531175056-4c3a928424d2/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20190616124812-15dcb6c0061f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20190801041406-cbf593c0f2f3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20191008105621-543471e840be/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/sys v0.0.0-20200121082415-34d275377bf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20200217220822-9197077df867/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20200519105757-fe76b779f299/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20210403161142-5e06dd20ab57/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
-golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
-golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
-golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
-golang.org/x/sys v0.0.0-20211007075335-d3039528d8ac/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
-golang.org/x/sys v0.0.0-20220209214540-3681064d5158/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
-golang.org/x/sys v0.15.0 h1:h48lPFYpsTvQJZF4EKyI4aLHaev3CxivZmv7yZig9pc=
-golang.org/x/sys v0.15.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
-golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
+golang.org/x/sys v0.33.0 h1:q3i8TbbEz+JRD9ywIRlyRAQbM0qF7hu24q3teo2hbuw=
+golang.org/x/sys v0.33.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k=
 golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
 golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
 golang.org/x/text v0.3.3/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/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
-golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ=
-golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
-golang.org/x/time v0.0.0-20201208040808-7e3f01d25324/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
+golang.org/x/text v0.25.0 h1:qVyWApTSYLk/drJRO5mDlNYskwQznZmkpV2c8q9zls4=
+golang.org/x/text v0.25.0/go.mod h1:WEdwpYrmk1qmdHvhkSTNPm3app7v4rsT8F2UD6+VHIA=
+golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/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-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
 golang.org/x/tools v0.0.0-20181030221726-6c7e314b6563/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
-golang.org/x/tools v0.0.0-20181221001348-537d06c36207/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
+golang.org/x/tools v0.0.0-20181112210238-4b1f3b6b1646/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
 golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
+golang.org/x/tools v0.0.0-20190125232054-d66bd3c5d5a6/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
 golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY=
 golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
-golang.org/x/tools v0.0.0-20190327201419-c70d86f8b7cf/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
 golang.org/x/tools v0.0.0-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
+golang.org/x/tools v0.0.0-20190329151228-23e29df326fe/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
+golang.org/x/tools v0.0.0-20190416151739-9c9e1878f421/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
+golang.org/x/tools v0.0.0-20190420181800-aa740d480789/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
 golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
+golang.org/x/tools v0.0.0-20190531172133-b3315ee88b7d/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
+golang.org/x/tools v0.0.0-20190614205625-5aca471b1d59/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
+golang.org/x/tools v0.0.0-20190617190820-da514acc4774/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
+golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
 golang.org/x/tools v0.0.0-20190624222133-a101b041ded4/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
+golang.org/x/tools v0.0.0-20191029041327-9cc4af7d6b2c/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
+golang.org/x/tools v0.0.0-20191029190741-b9c20aec41a5/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
 golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
+golang.org/x/tools v0.0.0-20191125144606-a911d9008d1f/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
 golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
+golang.org/x/tools v0.0.0-20200203023011-6f24f261dadb/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
+golang.org/x/tools v0.0.0-20200227222343-706bc42d1f0d/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
 golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
 golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
-golang.org/x/tools v0.1.3/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
-golang.org/x/tools v0.17.0 h1:FvmRgNOcs3kOa+T20R1uhfP9F6HgG2mfxDv1vrx1Htc=
-golang.org/x/tools v0.17.0/go.mod h1:xsh6VxdV005rRVaS6SSAf9oiAqljS7UZUacMZ8Bnsps=
+golang.org/x/tools v0.26.0 h1:v/60pFQmzmT9ExmjDv2gGIfi3OqfKoEP6I5+umXlbnQ=
+golang.org/x/tools v0.26.0/go.mod h1:TPVVj70c7JJ3WCazhD8OdXcZg/og+b9+tH/KxylGwH0=
 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=
+gonum.org/v1/gonum v0.16.0 h1:5+ul4Swaf3ESvrOnidPp4GZbzf0mxVQpDCYUQE7OJfk=
+gonum.org/v1/gonum v0.16.0/go.mod h1:fef3am4MQ93R2HHpKnLk4/Tbh/s0+wqD5nfa6Pnwy4E=
 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/genproto v0.0.0-20180518175338-11a468237815/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
+google.golang.org/genproto v0.0.0-20170818010345-ee236bd376b0/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
 google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
 google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc=
+google.golang.org/genproto v0.0.0-20190927181202-20e1ac93f88c/go.mod h1:IbNlFCBrqXvoKpeg0TB2l7cyZUmoaFKYIwrEpbDKLA8=
+google.golang.org/genproto v0.0.0-20200218151345-dad8c97a84f5/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
 google.golang.org/genproto v0.0.0-20200513103714-09dca8ec2884/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
-google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo=
-google.golang.org/genproto v0.0.0-20210624195500-8bfb893ecb84 h1:R1r5J0u6Cx+RNl/6mezTw6oA14cmKC96FeUwL6A9bd4=
-google.golang.org/genproto v0.0.0-20210624195500-8bfb893ecb84/go.mod h1:SzzZ/N+nwJDaO1kznhnlzqS8ocJICar6hYhVyhi++24=
-google.golang.org/grpc v1.12.0/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw=
+google.golang.org/genproto v0.0.0-20230410155749-daa745c078e1 h1:KpwkzHKEF7B9Zxg18WzOa7djJ+Ha5DzthMyZYQfEn2A=
+google.golang.org/genproto v0.0.0-20230410155749-daa745c078e1/go.mod h1:nKE/iIaLqn2bQwXBg8f1g2Ylh6r5MN5CmZvuzZCgsCU=
+google.golang.org/grpc v1.8.0/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw=
 google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
+google.golang.org/grpc v1.21.0/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM=
 google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg=
+google.golang.org/grpc v1.24.0/go.mod h1:XDChyiUovWa60DnaeDeZmSW86xtLtjtZbwvSiRnRtcA=
 google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY=
 google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
-google.golang.org/grpc v1.29.1/go.mod h1:itym6AZVZYACWQqET3MqgPpjcuV5QH3BxFS3IjizoKk=
+google.golang.org/grpc v1.27.1/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
 google.golang.org/grpc v1.33.1/go.mod h1:fr5YgcSWrqhRRxogOsw7RzIpsmvOZ6IcH4kBYTpR3n0=
-google.golang.org/grpc v1.36.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU=
-google.golang.org/grpc v1.38.0/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM=
-google.golang.org/grpc v1.40.1 h1:pnP7OclFFFgFi4VHQDQDaoXUVauOFyktqTsqqgzFKbc=
-google.golang.org/grpc v1.40.1/go.mod h1:ogyxbiOoUXAkP+4+xa6PZSE9DZgIHtSpzjDTB9KAK34=
-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=
-google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM=
-google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE=
-google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo=
-google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
-google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
-google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
-google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c=
-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.31.0 h1:g0LDEJHgrBl9N9r17Ru3sqWhkIx2NB67okBHPwC7hs8=
-google.golang.org/protobuf v1.31.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
+google.golang.org/grpc v1.72.1 h1:HR03wO6eyZ7lknl75XlxABNVLLFc2PAb6mHlYh756mA=
+google.golang.org/grpc v1.72.1/go.mod h1:wH5Aktxcg25y1I3w7H69nHfXdOG3UiadoBtjh3izSDM=
+google.golang.org/protobuf v1.36.6 h1:z1NpPI8ku2WgiWnf+t9wTPsn6eP1L7ksHUlkfLvd9xY=
+google.golang.org/protobuf v1.36.6/go.mod h1:jduwjTPXsFjZGTmRluh+L6NjiWu7pchiJ2/5YcXBHnY=
+gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw=
 gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
 gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
-gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 h1:YR8cESwS4TdDjEe65xsg0ogRM/Nc3DYOhEAlW+xobZo=
 gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
+gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
+gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
 gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=
 gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys=
-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/ini.v1 v1.51.1/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
-gopkg.in/mgo.v2 v2.0.0-20180705113604-9856a29383ce/go.mod h1:yeKp02qBN3iKW1OzL3MGk2IdtZzaj7SFntXj72NppTA=
+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.52.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
+gopkg.in/jcmturner/aescts.v1 v1.0.1/go.mod h1:nsR8qBOg+OucoIW+WMhB3GspUQXq9XorLnQb9XtvcOo=
+gopkg.in/jcmturner/dnsutils.v1 v1.0.1/go.mod h1:m3v+5svpVOhtFAP/wSz+yzh4Mc0Fg7eRhxkJMWSIz9Q=
+gopkg.in/jcmturner/goidentity.v3 v3.0.0/go.mod h1:oG2kH0IvSYNIu80dVAyu/yoefjq1mNfM5bm88whjWx4=
+gopkg.in/jcmturner/gokrb5.v7 v7.2.3/go.mod h1:l8VISx+WGYp+Fp7KRbsiUuXTTOnxIc3Tuvyavf11/WM=
+gopkg.in/jcmturner/gokrb5.v7 v7.5.0/go.mod h1:l8VISx+WGYp+Fp7KRbsiUuXTTOnxIc3Tuvyavf11/WM=
+gopkg.in/jcmturner/rpc.v1 v1.1.0/go.mod h1:YIdkC4XfD6GXbzje11McwsDuOlZQSb9W4vfLvuNnlv8=
+gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo=
 gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw=
+gopkg.in/yaml.v2 v2.0.0-20170812160011-eb3733d160e7/go.mod h1:JAlM8MvJe8wmxCU4Bli9HhUf9+ttbYbLASfIpnQbh74=
+gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
 gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
 gopkg.in/yaml.v2 v2.2.3/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
 gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
 gopkg.in/yaml.v2 v2.2.7/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
-gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
-gopkg.in/yaml.v3 v3.0.0-20191120175047-4206685974f2/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
+gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
 gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
-gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b h1:h8qDotaEPuJATrMmW04NCwg7v22aHH28wwpauUhK9Oo=
-gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
+gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
+gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
 gotest.tools/v3 v3.0.2/go.mod h1:3SzNCllyD9/Y+b5r9JIKQ474KzkZyqLqEfYqMsX94Bk=
 honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
 honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
+honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg=
diff --git a/parser_test.go b/parser_test.go
index f742391..7534a3a 100644
--- a/parser_test.go
+++ b/parser_test.go
@@ -12,5 +12,5 @@ func TestParser(t *testing.T) {
 	p, err := parser.ParseOne("CREATE TABLE t (a TIMESTAMPTZ DEFAULT CURRENT_TIMESTAMP)")
 	require.NoError(t, err)
 	f := tree.DefaultPrettyCfg()
-	f.Pretty(p.AST)
+	t.Log(f.Pretty(p.AST))
 }
diff --git a/patches/0002-fix-quote-names.sql b/patches/0002-fix-quote-names.patch
similarity index 84%
rename from patches/0002-fix-quote-names.sql
rename to patches/0002-fix-quote-names.patch
index d972768..bb615c5 100644
--- a/patches/0002-fix-quote-names.sql
+++ b/patches/0002-fix-quote-names.patch
@@ -1,8 +1,8 @@
 diff --git a/pkg/sql/sem/tree/type_name.go b/pkg/sql/sem/tree/type_name.go
-index 898009a..5d4423a 100644
+index 10cd908..98daa0e 100644
 --- a/pkg/sql/sem/tree/type_name.go
 +++ b/pkg/sql/sem/tree/type_name.go
-@@ -56,8 +56,7 @@ func (t *TypeName) String() string {
+@@ -42,8 +42,7 @@ func (t *TypeName) Format(ctx *FmtCtx) {
  
  // SQLString implements the ResolvableTypeReference interface.
  func (t *TypeName) SQLString() string {
@@ -11,8 +11,8 @@ index 898009a..5d4423a 100644
 +	return AsStringWithFlags(t, FmtSimple)
  }
  
- // FQString renders the type name in full, not omitting the prefix
-@@ -250,14 +249,12 @@ func (node *ArrayTypeReference) Format(ctx *FmtCtx) {
+ func (t *TypeName) objectName() {}
+@@ -240,14 +239,12 @@ func (node *ArrayTypeReference) Format(ctx *FmtCtx) {
  
  // SQLString implements the ResolvableTypeReference interface.
  func (node *ArrayTypeReference) SQLString() string {
diff --git a/patches/0004-enc-always-quoted.patch b/patches/0004-enc-always-quoted.patch
new file mode 100644
index 0000000..0e29ddf
--- /dev/null
+++ b/patches/0004-enc-always-quoted.patch
@@ -0,0 +1,35 @@
+diff --git a/pkg/sql/lexbase/encode.go b/pkg/sql/lexbase/encode.go
+index 0083555..47b9a37 100644
+--- a/pkg/sql/lexbase/encode.go
++++ b/pkg/sql/lexbase/encode.go
+@@ -49,6 +49,11 @@ const (
+ 	// EncFirstFreeFlagBit needs to remain unused; it is used as base
+ 	// bit offset for tree.FmtFlags.
+ 	EncFirstFreeFlagBit
++
++	// EncAlwaysQuoted makes sure the string is always wrapped with quotes.
++	// This is used only to construct a statement against Oracle source,
++	// as Oracle is case insensitive if object name is not quoted.
++	EncAlwaysQuoted
+ )
+ 
+ // EncodeRestrictedSQLIdent writes the identifier in s to buf. The
+@@ -56,8 +61,7 @@ const (
+ // contains special characters, or the identifier is a reserved SQL
+ // keyword.
+ func EncodeRestrictedSQLIdent(buf *bytes.Buffer, s string, flags EncodeFlags) {
+-	if flags.HasFlags(EncBareIdentifiers) ||
+-		(IsBareIdentifier(s) && (flags.HasFlags(EncBareReservedKeywords) || !isReservedKeyword(s))) {
++	if !flags.HasFlags(EncAlwaysQuoted) && (flags.HasFlags(EncBareIdentifiers) || (!isReservedKeyword(s) && IsBareIdentifier(s))) {
+ 		buf.WriteString(s)
+ 		return
+ 	}
+@@ -68,7 +72,7 @@ func EncodeRestrictedSQLIdent(buf *bytes.Buffer, s string, flags EncodeFlags) {
+ // The identifier is only quoted if the flags don't tell otherwise and
+ // the identifier contains special characters.
+ func EncodeUnrestrictedSQLIdent(buf *bytes.Buffer, s string, flags EncodeFlags) {
+-	if flags.HasFlags(EncBareIdentifiers) || IsBareIdentifier(s) {
++	if !flags.HasFlags(EncAlwaysQuoted) && (flags.HasFlags(EncBareIdentifiers) || IsBareIdentifier(s)) {
+ 		buf.WriteString(s)
+ 		return
+ 	}
diff --git a/patches/0004-fix-bazel-compl.patch b/patches/0004-fix-bazel-compl.patch
deleted file mode 100644
index 5e9b3dc..0000000
--- a/patches/0004-fix-bazel-compl.patch
+++ /dev/null
@@ -1,64 +0,0 @@
-From d300afb062569278ff9e770b4f7e0ed0d84f6f82 Mon Sep 17 00:00:00 2001
-From: Oliver Tan <otan@cockroachlabs.com>
-Date: Mon, 15 May 2023 14:21:32 +1000
-Subject: [PATCH] fix bazel compilation for grunning
-
----
- pkg/util/grunning/disabled.go |  5 -----
- pkg/util/grunning/enabled.go  | 28 ----------------------------
- 2 files changed, 33 deletions(-)
- delete mode 100644 pkg/util/grunning/enabled.go
-
-diff --git a/pkg/util/grunning/disabled.go b/pkg/util/grunning/disabled.go
-index 7fdc2f0..89fcb2d 100644
---- a/pkg/util/grunning/disabled.go
-+++ b/pkg/util/grunning/disabled.go
-@@ -8,11 +8,6 @@
- // by the Apache License, Version 2.0, included in the file
- // licenses/APL.txt.
- 
--// See grunning.Supported() for an explanation behind this build tag.
--//
--//go:build freebsd || (linux && s390x) || !bazel
--// +build freebsd linux,s390x !bazel
--
- package grunning
- 
- func grunningnanos() int64 { return 0 }
-diff --git a/pkg/util/grunning/enabled.go b/pkg/util/grunning/enabled.go
-deleted file mode 100644
-index ab12aae..0000000
---- a/pkg/util/grunning/enabled.go
-+++ /dev/null
-@@ -1,28 +0,0 @@
--// Copyright 2022 The Cockroach Authors.
--//
--// Use of this software is governed by the Business Source License
--// included in the file licenses/BSL.txt.
--//
--// As of the Change Date specified in that file, in accordance with
--// the Business Source License, use of this software will be governed
--// by the Apache License, Version 2.0, included in the file
--// licenses/APL.txt.
--
--// See grunning.Supported() for an explanation behind this build tag.
--//
--//go:build !(freebsd || (linux && s390x) || !bazel)
--// +build !freebsd
--// +build !linux !s390x
--// +build bazel
--
--package grunning
--
--import _ "unsafe" // for go:linkname
--
--// grunningnanos returns the running time observed by the current goroutine by
--// linking to a private symbol in the (patched) runtime package.
--//
--//go:linkname grunningnanos runtime.grunningnanos
--func grunningnanos() int64
--
--func supported() bool { return true }
--- 
-2.39.2 (Apple Git-143)
-
diff --git a/patches/0005-delete-plpgsql-files.patch b/patches/0005-delete-plpgsql-files.patch
deleted file mode 100644
index 9dd47ae..0000000
--- a/patches/0005-delete-plpgsql-files.patch
+++ /dev/null
@@ -1,3099 +0,0 @@
-From 6f5dc3ecb62864562a1a715962e4c70d0e19c91e Mon Sep 17 00:00:00 2001
-From: Jeremy Yang <jyang@cockroachlabs.com>
-Date: Mon, 12 Feb 2024 13:19:27 -0800
-Subject: [PATCH] delete plpgsql files
-
----
- pkg/sql/plpgsql/parser/lexbase/keywords.go |  356 -----
- pkg/sql/plpgsql/parser/lexbase/tokens.go   |  134 --
- pkg/sql/plpgsql/parser/lexbase/utils.go    |   12 -
- pkg/sql/plpgsql/parser/lexer.go            |  501 ------
- pkg/sql/plpgsql/parser/parse.go            |  136 --
- pkg/sql/plpgsql/parser/plpgsql.y           | 1647 --------------------
- pkg/sql/scanner/plpgsql_scan.go            |  246 ---
- 7 files changed, 3032 deletions(-)
- delete mode 100644 pkg/sql/plpgsql/parser/lexbase/keywords.go
- delete mode 100644 pkg/sql/plpgsql/parser/lexbase/tokens.go
- delete mode 100644 pkg/sql/plpgsql/parser/lexbase/utils.go
- delete mode 100644 pkg/sql/plpgsql/parser/lexer.go
- delete mode 100644 pkg/sql/plpgsql/parser/parse.go
- delete mode 100644 pkg/sql/plpgsql/parser/plpgsql.y
- delete mode 100644 pkg/sql/scanner/plpgsql_scan.go
-
-diff --git a/pkg/sql/plpgsql/parser/lexbase/keywords.go b/pkg/sql/plpgsql/parser/lexbase/keywords.go
-deleted file mode 100644
-index 8cd3bc1..0000000
---- a/pkg/sql/plpgsql/parser/lexbase/keywords.go
-+++ /dev/null
-@@ -1,356 +0,0 @@
--// Code generated by pkg/sql/lexbase/allkeywords. DO NOT EDIT.
--
--package lexbase
--
--var KeywordsCategories = map[string]string{
--"absolute": "U",
--"alias": "U",
--"all": "R",
--"and": "U",
--"array": "U",
--"assert": "U",
--"backward": "U",
--"begin": "R",
--"by": "R",
--"call": "U",
--"case": "R",
--"chain": "U",
--"close": "U",
--"collate": "U",
--"column": "U",
--"column_name": "U",
--"commit": "U",
--"constant": "U",
--"constraint": "U",
--"constraint_name": "U",
--"continue": "U",
--"current": "U",
--"cursor": "U",
--"datatype": "U",
--"debug": "U",
--"declare": "R",
--"default": "U",
--"detail": "U",
--"diagnostics": "U",
--"do": "U",
--"dump": "U",
--"else": "R",
--"elsif": "U",
--"end": "R",
--"end_case": "R",
--"end_if": "R",
--"errcode": "U",
--"error": "U",
--"exception": "U",
--"execute": "R",
--"exit": "U",
--"fetch": "U",
--"first": "U",
--"for": "R",
--"foreach": "R",
--"forward": "U",
--"from": "R",
--"get": "U",
--"hint": "U",
--"if": "R",
--"import": "U",
--"in": "R",
--"info": "U",
--"insert": "U",
--"into": "R",
--"is": "U",
--"last": "U",
--"log": "U",
--"loop": "R",
--"merge": "U",
--"message": "U",
--"message_text": "U",
--"move": "U",
--"next": "U",
--"no": "U",
--"not": "R",
--"notice": "U",
--"no_scroll": "U",
--"null": "R",
--"open": "U",
--"option": "U",
--"or": "R",
--"perform": "U",
--"pg_context": "U",
--"pg_datatype_name": "U",
--"pg_exception_context": "U",
--"pg_exception_detail": "U",
--"pg_exception_hint": "U",
--"print_strict_params": "U",
--"prior": "U",
--"query": "U",
--"raise": "U",
--"relative": "U",
--"return": "U",
--"returned_sqlstate": "U",
--"return_next": "U",
--"return_query": "U",
--"reverse": "U",
--"rollback": "U",
--"rowtype": "U",
--"row_count": "U",
--"schema": "U",
--"schema_name": "U",
--"scroll": "U",
--"slice": "U",
--"sqlstate": "U",
--"stacked": "U",
--"strict": "R",
--"table": "U",
--"table_name": "U",
--"then": "R",
--"to": "R",
--"type": "U",
--"upsert": "U",
--"use_column": "U",
--"use_variable": "U",
--"using": "R",
--"variable_conflict": "U",
--"warning": "U",
--"when": "R",
--"while": "R",
--}
--
--// KeywordNames contains all keywords sorted, so that pg_get_keywords returns
--// deterministic results.
--var KeywordNames = []string{
--"absolute",
--"alias",
--"all",
--"and",
--"array",
--"assert",
--"backward",
--"begin",
--"by",
--"call",
--"case",
--"chain",
--"close",
--"collate",
--"column",
--"column_name",
--"commit",
--"constant",
--"constraint",
--"constraint_name",
--"continue",
--"current",
--"cursor",
--"datatype",
--"debug",
--"declare",
--"default",
--"detail",
--"diagnostics",
--"do",
--"dump",
--"else",
--"elsif",
--"end",
--"end_case",
--"end_if",
--"errcode",
--"error",
--"exception",
--"execute",
--"exit",
--"fetch",
--"first",
--"for",
--"foreach",
--"forward",
--"from",
--"get",
--"hint",
--"if",
--"import",
--"in",
--"info",
--"insert",
--"into",
--"is",
--"last",
--"log",
--"loop",
--"merge",
--"message",
--"message_text",
--"move",
--"next",
--"no",
--"not",
--"notice",
--"no_scroll",
--"null",
--"open",
--"option",
--"or",
--"perform",
--"pg_context",
--"pg_datatype_name",
--"pg_exception_context",
--"pg_exception_detail",
--"pg_exception_hint",
--"print_strict_params",
--"prior",
--"query",
--"raise",
--"relative",
--"return",
--"returned_sqlstate",
--"return_next",
--"return_query",
--"reverse",
--"rollback",
--"rowtype",
--"row_count",
--"schema",
--"schema_name",
--"scroll",
--"slice",
--"sqlstate",
--"stacked",
--"strict",
--"table",
--"table_name",
--"then",
--"to",
--"type",
--"upsert",
--"use_column",
--"use_variable",
--"using",
--"variable_conflict",
--"warning",
--"when",
--"while",
--}
--
--// GetKeywordID returns the lex id of the SQL keyword k or IDENT if k is
--// not a keyword.
--func GetKeywordID(k string) int32 {
--	// The previous implementation generated a map that did a string ->
--	// id lookup. Various ideas were benchmarked and the implementation below
--	// was the fastest of those, between 3% and 10% faster (at parsing, so the
--	// scanning speedup is even more) than the map implementation.
--	switch k {
--	case "absolute": return ABSOLUTE
--	case "alias": return ALIAS
--	case "all": return ALL
--	case "and": return AND
--	case "array": return ARRAY
--	case "assert": return ASSERT
--	case "backward": return BACKWARD
--	case "begin": return BEGIN
--	case "by": return BY
--	case "call": return CALL
--	case "case": return CASE
--	case "chain": return CHAIN
--	case "close": return CLOSE
--	case "collate": return COLLATE
--	case "column": return COLUMN
--	case "column_name": return COLUMN_NAME
--	case "commit": return COMMIT
--	case "constant": return CONSTANT
--	case "constraint": return CONSTRAINT
--	case "constraint_name": return CONSTRAINT_NAME
--	case "continue": return CONTINUE
--	case "current": return CURRENT
--	case "cursor": return CURSOR
--	case "datatype": return DATATYPE
--	case "debug": return DEBUG
--	case "declare": return DECLARE
--	case "default": return DEFAULT
--	case "detail": return DETAIL
--	case "diagnostics": return DIAGNOSTICS
--	case "do": return DO
--	case "dump": return DUMP
--	case "else": return ELSE
--	case "elsif": return ELSIF
--	case "end": return END
--	case "end_case": return END_CASE
--	case "end_if": return END_IF
--	case "errcode": return ERRCODE
--	case "error": return ERROR
--	case "exception": return EXCEPTION
--	case "execute": return EXECUTE
--	case "exit": return EXIT
--	case "fetch": return FETCH
--	case "first": return FIRST
--	case "for": return FOR
--	case "foreach": return FOREACH
--	case "forward": return FORWARD
--	case "from": return FROM
--	case "get": return GET
--	case "hint": return HINT
--	case "if": return IF
--	case "import": return IMPORT
--	case "in": return IN
--	case "info": return INFO
--	case "insert": return INSERT
--	case "into": return INTO
--	case "is": return IS
--	case "last": return LAST
--	case "log": return LOG
--	case "loop": return LOOP
--	case "merge": return MERGE
--	case "message": return MESSAGE
--	case "message_text": return MESSAGE_TEXT
--	case "move": return MOVE
--	case "next": return NEXT
--	case "no": return NO
--	case "not": return NOT
--	case "notice": return NOTICE
--	case "no_scroll": return NO_SCROLL
--	case "null": return NULL
--	case "open": return OPEN
--	case "option": return OPTION
--	case "or": return OR
--	case "perform": return PERFORM
--	case "pg_context": return PG_CONTEXT
--	case "pg_datatype_name": return PG_DATATYPE_NAME
--	case "pg_exception_context": return PG_EXCEPTION_CONTEXT
--	case "pg_exception_detail": return PG_EXCEPTION_DETAIL
--	case "pg_exception_hint": return PG_EXCEPTION_HINT
--	case "print_strict_params": return PRINT_STRICT_PARAMS
--	case "prior": return PRIOR
--	case "query": return QUERY
--	case "raise": return RAISE
--	case "relative": return RELATIVE
--	case "return": return RETURN
--	case "returned_sqlstate": return RETURNED_SQLSTATE
--	case "return_next": return RETURN_NEXT
--	case "return_query": return RETURN_QUERY
--	case "reverse": return REVERSE
--	case "rollback": return ROLLBACK
--	case "rowtype": return ROWTYPE
--	case "row_count": return ROW_COUNT
--	case "schema": return SCHEMA
--	case "schema_name": return SCHEMA_NAME
--	case "scroll": return SCROLL
--	case "slice": return SLICE
--	case "sqlstate": return SQLSTATE
--	case "stacked": return STACKED
--	case "strict": return STRICT
--	case "table": return TABLE
--	case "table_name": return TABLE_NAME
--	case "then": return THEN
--	case "to": return TO
--	case "type": return TYPE
--	case "upsert": return UPSERT
--	case "use_column": return USE_COLUMN
--	case "use_variable": return USE_VARIABLE
--	case "using": return USING
--	case "variable_conflict": return VARIABLE_CONFLICT
--	case "warning": return WARNING
--	case "when": return WHEN
--	case "while": return WHILE
--	default: return IDENT
--	}
--}
-diff --git a/pkg/sql/plpgsql/parser/lexbase/tokens.go b/pkg/sql/plpgsql/parser/lexbase/tokens.go
-deleted file mode 100644
-index 56ac04c..0000000
---- a/pkg/sql/plpgsql/parser/lexbase/tokens.go
-+++ /dev/null
-@@ -1,134 +0,0 @@
--// Code generated by make. DO NOT EDIT.
--// GENERATED FILE DO NOT EDIT
--
--package lexbase
--
--const IDENT = 57346
--const UIDENT = 57347
--const FCONST = 57348
--const SCONST = 57349
--const USCONST = 57350
--const BCONST = 57351
--const XCONST = 57352
--const ICONST = 57354
--const PARAM = 57355
--const TYPECAST = 57356
--const DOT_DOT = 57357
--const COLON_EQUALS = 57358
--const EQUALS_GREATER = 57359
--const LESS_EQUALS = 57360
--const GREATER_EQUALS = 57361
--const NOT_EQUALS = 57362
--const LESS_LESS = 57363
--const GREATER_GREATER = 57364
--const ABSOLUTE = 57365
--const ALIAS = 57366
--const ALL = 57367
--const AND = 57368
--const ARRAY = 57369
--const ASSERT = 57370
--const BACKWARD = 57371
--const BEGIN = 57372
--const BY = 57373
--const CALL = 57374
--const CASE = 57375
--const CHAIN = 57376
--const CLOSE = 57377
--const COLLATE = 57378
--const COLUMN = 57379
--const COLUMN_NAME = 57380
--const COMMIT = 57381
--const CONSTANT = 57382
--const CONSTRAINT = 57383
--const CONSTRAINT_NAME = 57384
--const CONTINUE = 57385
--const CURRENT = 57386
--const CURSOR = 57387
--const DATATYPE = 57388
--const DEBUG = 57389
--const DECLARE = 57390
--const DEFAULT = 57391
--const DETAIL = 57392
--const DIAGNOSTICS = 57393
--const DO = 57394
--const DUMP = 57395
--const ELSE = 57396
--const ELSIF = 57397
--const END = 57398
--const END_CASE = 57399
--const END_IF = 57400
--const ERRCODE = 57401
--const ERROR = 57402
--const EXCEPTION = 57403
--const EXECUTE = 57404
--const EXIT = 57405
--const FETCH = 57406
--const FIRST = 57407
--const FOR = 57408
--const FOREACH = 57409
--const FORWARD = 57410
--const FROM = 57411
--const GET = 57412
--const HINT = 57413
--const IF = 57414
--const IMPORT = 57415
--const IN = 57416
--const INFO = 57417
--const INSERT = 57418
--const INTO = 57419
--const IS = 57420
--const LAST = 57421
--const LOG = 57422
--const LOOP = 57423
--const MERGE = 57424
--const MESSAGE = 57425
--const MESSAGE_TEXT = 57426
--const MOVE = 57427
--const NEXT = 57428
--const NO = 57429
--const NO_SCROLL = 57430
--const NOT = 57431
--const NOTICE = 57432
--const NULL = 57433
--const OPEN = 57434
--const OPTION = 57435
--const OR = 57436
--const PERFORM = 57437
--const PG_CONTEXT = 57438
--const PG_DATATYPE_NAME = 57439
--const PG_EXCEPTION_CONTEXT = 57440
--const PG_EXCEPTION_DETAIL = 57441
--const PG_EXCEPTION_HINT = 57442
--const PRINT_STRICT_PARAMS = 57443
--const PRIOR = 57444
--const QUERY = 57445
--const RAISE = 57446
--const RELATIVE = 57447
--const RETURN = 57448
--const RETURN_NEXT = 57449
--const RETURN_QUERY = 57450
--const RETURNED_SQLSTATE = 57451
--const REVERSE = 57452
--const ROLLBACK = 57453
--const ROW_COUNT = 57454
--const ROWTYPE = 57455
--const SCHEMA = 57456
--const SCHEMA_NAME = 57457
--const SCROLL = 57458
--const SLICE = 57459
--const SQLSTATE = 57460
--const STACKED = 57461
--const STRICT = 57462
--const TABLE = 57463
--const TABLE_NAME = 57464
--const THEN = 57465
--const TO = 57466
--const TYPE = 57467
--const UPSERT = 57468
--const USE_COLUMN = 57469
--const USE_VARIABLE = 57470
--const USING = 57471
--const VARIABLE_CONFLICT = 57472
--const WARNING = 57473
--const WHEN = 57474
--const WHILE = 57475
-diff --git a/pkg/sql/plpgsql/parser/lexbase/utils.go b/pkg/sql/plpgsql/parser/lexbase/utils.go
-deleted file mode 100644
-index 66596bf..0000000
---- a/pkg/sql/plpgsql/parser/lexbase/utils.go
-+++ /dev/null
-@@ -1,12 +0,0 @@
--// Copyright 2023 The Cockroach Authors.
--//
--// Use of this software is governed by the Business Source License
--// included in the file licenses/BSL.txt.
--//
--// As of the Change Date specified in that file, in accordance with
--// the Business Source License, use of this software will be governed
--// by the Apache License, Version 2.0, included in the file
--// licenses/APL.txt.
--
--// Package lexbase contains utilities for lexing plpgsql.
--package lexbase
-diff --git a/pkg/sql/plpgsql/parser/lexer.go b/pkg/sql/plpgsql/parser/lexer.go
-deleted file mode 100644
-index 9201b03..0000000
---- a/pkg/sql/plpgsql/parser/lexer.go
-+++ /dev/null
-@@ -1,501 +0,0 @@
--// Copyright 2023 The Cockroach Authors.
--//
--// Use of this software is governed by the Business Source License
--// included in the file licenses/BSL.txt.
--//
--// As of the Change Date specified in that file, in accordance with
--// the Business Source License, use of this software will be governed
--// by the Apache License, Version 2.0, included in the file
--// licenses/APL.txt.
--
--package parser
--
--import (
--	"strings"
--
--	"github.com/cockroachdb/cockroachdb-parser/pkg/sql/parser"
--	"github.com/cockroachdb/cockroachdb-parser/pkg/sql/pgwire/pgcode"
--	"github.com/cockroachdb/cockroachdb-parser/pkg/sql/pgwire/pgerror"
--	"github.com/cockroachdb/cockroachdb-parser/pkg/sql/sem/plpgsqltree"
--	"github.com/cockroachdb/cockroachdb-parser/pkg/sql/sem/tree"
--	"github.com/cockroachdb/cockroachdb-parser/pkg/sql/types"
--	unimp "github.com/cockroachdb/cockroachdb-parser/pkg/util/errorutil/unimplemented"
--	"github.com/cockroachdb/errors"
--)
--
--type lexer struct {
--	in string
--	// tokens contains tokens generated by the scanner.
--	tokens []plpgsqlSymType
--
--	// The type that should be used when an INT or SERIAL is encountered.
--	nakedIntType *types.T
--
--	// lastPos is the position into the tokens slice of the last
--	// token returned by Lex().
--	lastPos int
--
--	stmt *plpgsqltree.Block
--
--	// numPlaceholders is 1 + the highest placeholder index encountered.
--	numPlaceholders int
--	numAnnotations  tree.AnnotationIdx
--
--	lastError error
--
--	parser plpgsqlParser
--}
--
--func (l *lexer) init(sql string, tokens []plpgsqlSymType, nakedIntType *types.T, p plpgsqlParser) {
--	l.in = sql
--	l.tokens = tokens
--	l.lastPos = -1
--	l.stmt = nil
--	l.numPlaceholders = 0
--	l.numAnnotations = 0
--	l.lastError = nil
--	l.nakedIntType = nakedIntType
--	l.parser = p
--}
--
--// cleanup is used to avoid holding on to memory unnecessarily (for the cases
--// where we reuse a scanner).
--func (l *lexer) cleanup() {
--	l.tokens = nil
--	l.stmt = nil
--	l.lastError = nil
--}
--
--// Lex lexes a token from input.
--// to push the tokens back (move l.pos back).
--func (l *lexer) Lex(lval *plpgsqlSymType) int {
--	l.lastPos++
--	// The core lexing takes place in the scanner. Here we do a small bit of post
--	// processing of the lexical tokens so that the grammar only requires
--	// one-token lookahead despite SQL requiring multi-token lookahead in some
--	// cases. These special cases are handled below and the returned tokens are
--	// adjusted to reflect the lookahead (LA) that occurred.
--	if l.lastPos >= len(l.tokens) {
--		lval.id = 0
--		lval.pos = int32(len(l.in))
--		lval.str = "EOF"
--		return 0
--	}
--	*lval = l.tokens[l.lastPos]
--
--	switch lval.id {
--	case RETURN:
--		nextToken := plpgsqlSymType{}
--		if l.lastPos+1 < len(l.tokens) {
--			nextToken = l.tokens[l.lastPos+1]
--		}
--		switch nextToken.id {
--		case NEXT:
--			lval.id = RETURN_NEXT
--		case QUERY:
--			lval.id = RETURN_QUERY
--		}
--	case END:
--		nextToken := plpgsqlSymType{}
--		if l.lastPos+1 < len(l.tokens) {
--			nextToken = l.tokens[l.lastPos+1]
--		}
--		switch nextToken.id {
--		case IF:
--			lval.id = END_IF
--		case CASE:
--			lval.id = END_CASE
--		}
--	case NO:
--		nextToken := plpgsqlSymType{}
--		if l.lastPos+1 < len(l.tokens) {
--			nextToken = l.tokens[l.lastPos+1]
--		}
--		switch nextToken.id {
--		case SCROLL:
--			lval.id = NO_SCROLL
--		}
--	}
--
--	return int(lval.id)
--}
--
--// MakeExecSqlStmt makes an Execute node.
--func (l *lexer) MakeExecSqlStmt() (*plpgsqltree.Execute, error) {
--	if l.parser.Lookahead() != -1 {
--		// Push back the lookahead token so that it can be included.
--		l.PushBack(1)
--	}
--	// Push back the first token so that it's included in the SQL string.
--	l.PushBack(1)
--	startPos, endPos, _, err := l.readSQLConstruct(false /* isExpr */, ';')
--	if err != nil {
--		return nil, err
--	}
--	// Move past the semicolon.
--	l.lastPos++
--
--	var haveInto, haveStrict bool
--	var intoStartPos, intoEndPos int
--	var target []plpgsqltree.Variable
--	firstTok := l.tokens[startPos]
--	tok := firstTok
--	for pos := startPos; pos < endPos; pos++ {
--		prevTok := tok
--		tok = l.tokens[pos]
--		if tok.id == INTO {
--			if prevTok.id == INSERT || prevTok.id == UPSERT ||
--				prevTok.id == MERGE || firstTok.id == IMPORT {
--				// INSERT INTO, UPSERT INTO, MERGE INTO, and IMPORT ... INTO are not
--				// INTO-targets.
--				continue
--			}
--			if haveInto {
--				return nil, errors.New("INTO specified more than once")
--			}
--			haveInto = true
--			intoStartPos = pos
--			pos++
--			if pos+1 < endPos && l.tokens[pos].id == STRICT {
--				haveStrict = true
--				pos++
--			}
--			// Read in one or more comma-separated variables as the INTO target.
--			for ; pos < endPos; pos += 2 {
--				tok = l.tokens[pos]
--				if tok.id != IDENT {
--					return nil, errors.Newf("\"%s\" is not a scalar variable", tok.str)
--				}
--				variable := plpgsqltree.Variable(strings.TrimSpace(l.getStr(pos, pos+1)))
--				target = append(target, variable)
--				if pos+1 == endPos || l.tokens[pos+1].id != ',' {
--					// This is the end of the target list.
--					break
--				}
--			}
--			intoEndPos = pos + 1
--		}
--	}
--
--	var sql string
--	if haveInto {
--		sql = l.getStr(startPos, intoStartPos) + l.getStr(intoEndPos, endPos)
--	} else {
--		sql = l.getStr(startPos, endPos)
--	}
--	sqlStmt, err := parser.ParseOne(sql)
--	if err != nil {
--		return nil, err
--	}
--
--	// Note: PG disallows directly writing SQL statements that return rows, like
--	// a SELECT or a mutation with RETURNING. It is difficult to determine this
--	// for all possible statements, and execution is able to handle it, so we
--	// allow SQL statements that return rows.
--	if target != nil && sqlStmt.AST.StatementReturnType() != tree.Rows {
--		return nil, pgerror.New(pgcode.Syntax, "INTO used with a command that cannot return data")
--	}
--	return &plpgsqltree.Execute{
--		SqlStmt: sqlStmt.AST,
--		Strict:  haveStrict,
--		Target:  target,
--	}, nil
--}
--
--func (l *lexer) MakeDynamicExecuteStmt() (*plpgsqltree.DynamicExecute, error) {
--	cmdStr, _, err := l.ReadSqlStatement(INTO, USING, ';')
--	if err != nil {
--		return nil, err
--	}
--	ret := &plpgsqltree.DynamicExecute{
--		Query: cmdStr,
--	}
--
--	var lval plpgsqlSymType
--	l.Lex(&lval)
--	for {
--		if lval.id == INTO {
--			if ret.Into {
--				return nil, errors.New("multiple INTO keywords")
--			}
--			ret.Into = true
--			nextTok := l.Peek()
--			if nextTok.id == int32(STRICT) {
--				l.Lex(&lval)
--				ret.Strict = true
--			}
--			// TODO we need to read each "INTO" variable name instead of just a
--			// string.
--			_, _, err = l.ReadSqlExpr(USING, ';')
--			if err != nil {
--				return nil, err
--			}
--			l.Lex(&lval)
--		} else if lval.id == USING {
--			if ret.Params != nil {
--				return nil, errors.New("multiple USING keywords")
--			}
--			ret.Params = make([]plpgsqltree.Expr, 0)
--			for {
--				_, _, err = l.ReadSqlExpr(',', ';', INTO)
--				if err != nil {
--					return nil, err
--				}
--				ret.Params = append(ret.Params, nil)
--				l.Lex(&lval)
--				if lval.id == ';' {
--					break
--				}
--			}
--		} else if lval.id == ';' {
--			break
--		} else {
--			return nil, errors.Newf("unexpected token: %s", lval.id)
--		}
--	}
--
--	return ret, nil
--}
--
--func (l *lexer) readSQLConstruct(
--	isExpr bool, terminator1 int, terminators ...int,
--) (startPos, endPos, terminatorMet int, err error) {
--	if l.parser.Lookahead() != -1 {
--		// Push back the lookahead token so that it can be included.
--		l.PushBack(1)
--	}
--	parenLevel := 0
--	startPos = l.lastPos + 1
--	for l.lastPos < len(l.tokens) {
--		tok := l.Peek()
--		if int(tok.id) == terminator1 && parenLevel == 0 {
--			terminatorMet = terminator1
--			break
--		}
--		for _, term := range terminators {
--			if int(tok.id) == term && parenLevel == 0 {
--				terminatorMet = term
--			}
--		}
--		if terminatorMet != 0 {
--			break
--		}
--		if tok.id == '(' || tok.id == '[' {
--			parenLevel++
--		} else if tok.id == ')' || tok.id == ']' {
--			parenLevel--
--			if parenLevel < 0 {
--				return 0, 0, 0, errors.New("mismatched parentheses")
--			}
--		}
--		l.lastPos++
--	}
--	if parenLevel != 0 {
--		return 0, 0, 0, errors.New("mismatched parentheses")
--	}
--	endPos = l.lastPos + 1
--	if endPos > len(l.tokens) {
--		endPos = len(l.tokens)
--	}
--	if endPos <= startPos {
--		if isExpr {
--			return 0, 0, 0, errors.New("missing expression")
--		} else {
--			return 0, 0, 0, errors.New("missing SQL statement")
--		}
--	}
--	return startPos, endPos, terminatorMet, nil
--}
--
--func (l *lexer) MakeFetchOrMoveStmt(isMove bool) (plpgsqltree.Statement, error) {
--	if l.parser.Lookahead() != -1 {
--		// Push back the lookahead token so that it can be included.
--		l.PushBack(1)
--	}
--	prefix := "FETCH "
--	if isMove {
--		prefix = "MOVE "
--	}
--	sqlStr, terminator, err := l.ReadSqlStatement(INTO, ';')
--	if err != nil {
--		return nil, err
--	}
--	sqlStr = prefix + sqlStr
--	sqlStmt, err := parser.ParseOne(sqlStr)
--	if err != nil {
--		return nil, err
--	}
--	var cursor tree.CursorStmt
--	switch t := sqlStmt.AST.(type) {
--	case *tree.FetchCursor:
--		cursor = t.CursorStmt
--	case *tree.MoveCursor:
--		cursor = t.CursorStmt
--	default:
--		return nil, errors.Newf("invalid FETCH or MOVE syntax")
--	}
--	var target []plpgsqltree.Variable
--	if !isMove {
--		if terminator != INTO {
--			return nil, errors.Newf("invalid syntax for FETCH")
--		}
--		// Read past the INTO.
--		l.lastPos++
--		startPos, endPos, _, err := l.readSQLConstruct(true /* isExpr */, ';')
--		if err != nil {
--			return nil, err
--		}
--		for pos := startPos; pos < endPos; pos += 2 {
--			tok := l.tokens[pos]
--			if tok.id != IDENT {
--				return nil, errors.Newf("\"%s\" is not a scalar variable", tok.str)
--			}
--			if pos+1 != endPos && l.tokens[pos+1].id != ',' {
--				return nil, errors.Newf("expected INTO target to be a comma-separated list")
--			}
--			variable := plpgsqltree.Variable(strings.TrimSpace(l.getStr(pos, pos+1)))
--			target = append(target, variable)
--		}
--		if len(target) == 0 {
--			return nil, errors.Newf("expected INTO target")
--		}
--	}
--	// Move past the semicolon.
--	l.lastPos++
--	return &plpgsqltree.Fetch{
--		Cursor: cursor,
--		Target: target,
--		IsMove: isMove,
--	}, nil
--}
--
--func (l *lexer) ReadSqlExpr(
--	terminator1 int, terminators ...int,
--) (sqlStr string, terminatorMet int, err error) {
--	var startPos, endPos int
--	startPos, endPos, terminatorMet, err = l.readSQLConstruct(
--		true /* isExpr */, terminator1, terminators...,
--	)
--	return l.getStr(startPos, endPos), terminatorMet, err
--}
--
--func (l *lexer) ReadSqlStatement(
--	terminator1 int, terminators ...int,
--) (sqlStr string, terminatorMet int, err error) {
--	var startPos, endPos int
--	startPos, endPos, terminatorMet, err = l.readSQLConstruct(
--		false /* isExpr */, terminator1, terminators...,
--	)
--	return l.getStr(startPos, endPos), terminatorMet, err
--}
--
--func (l *lexer) getStr(startPos, endPos int) string {
--	if endPos <= startPos {
--		return ""
--	}
--	end := len(l.in)
--	if endPos < len(l.tokens) {
--		end = int(l.tokens[endPos].Pos())
--	}
--	start := int(l.tokens[startPos].Pos())
--	return l.in[start:end]
--}
--
--// Peek peeks
--func (l *lexer) Peek() plpgsqlSymType {
--	if l.lastPos+1 < len(l.tokens) {
--		return l.tokens[l.lastPos+1]
--	}
--	return plpgsqlSymType{}
--}
--
--// PushBack rewinds the lexer by n tokens.
--func (l *lexer) PushBack(n int) {
--	if n < 0 {
--		panic(errors.AssertionFailedf("negative n provided to PushBack"))
--	}
--	l.lastPos -= n
--	if l.lastPos < -1 {
--		// Return to the initialized state.
--		l.lastPos = -1
--	}
--	if n >= 1 {
--		// Invalidate the parser lookahead token.
--		l.parser.(*plpgsqlParserImpl).char = -1
--	}
--}
--
--func (l *lexer) lastToken() plpgsqlSymType {
--	if l.lastPos < 0 {
--		return plpgsqlSymType{}
--	}
--
--	if l.lastPos >= len(l.tokens) {
--		return plpgsqlSymType{
--			id:  0,
--			pos: int32(len(l.in)),
--			str: "EOF",
--		}
--	}
--	return l.tokens[l.lastPos]
--}
--
--// SetStmt is called from the parser when the statement is constructed.
--func (l *lexer) SetStmt(stmt plpgsqltree.Statement) {
--	l.stmt = stmt.(*plpgsqltree.Block)
--}
--
--// setErr is called from parsing action rules to register an error observed
--// while running the action. That error becomes the actual "cause" of the
--// syntax error.
--func (l *lexer) setErr(err error) {
--	err = pgerror.WithCandidateCode(err, pgcode.Syntax)
--	l.lastError = err
--	lastTok := l.lastToken()
--	l.lastError = parser.PopulateErrorDetails(lastTok.id, lastTok.str, lastTok.pos, l.lastError, l.in)
--}
--
--func (l *lexer) Error(e string) {
--	e = strings.TrimPrefix(e, "syntax error: ") // we'll add it again below.
--	err := pgerror.WithCandidateCode(errors.Newf("%s", e), pgcode.Syntax)
--	lastTok := l.lastToken()
--	l.lastError = parser.PopulateErrorDetails(lastTok.id, lastTok.str, lastTok.pos, err, l.in)
--}
--
--// Unimplemented wraps Error, setting lastUnimplementedError.
--func (l *lexer) Unimplemented(feature string) {
--	l.lastError = unimp.New(feature, "this syntax")
--	lastTok := l.lastToken()
--	l.lastError = parser.PopulateErrorDetails(lastTok.id, lastTok.str, lastTok.pos, l.lastError, l.in)
--	l.lastError = &tree.UnsupportedError{
--		Err:         l.lastError,
--		FeatureName: feature,
--	}
--}
--
--func (l *lexer) GetTypeFromValidSQLSyntax(sqlStr string) (tree.ResolvableTypeReference, error) {
--	return parser.GetTypeFromValidSQLSyntax(sqlStr)
--}
--
--func (l *lexer) ParseExpr(sqlStr string) (plpgsqltree.Expr, error) {
--	// Use ParseExprs instead of ParseExpr in order to correctly handle the case
--	// when multiple expressions are incorrectly passed.
--	exprs, err := parser.ParseExprs([]string{sqlStr})
--	if err != nil {
--		return nil, err
--	}
--	if len(exprs) != 1 {
--		return nil, pgerror.Newf(pgcode.Syntax, "query returned %d columns", len(exprs))
--	}
--	return exprs[0], nil
--}
--
--func checkLoopLabels(start, end string) error {
--	if start == "" && end != "" {
--		return errors.Newf("end label \"%s\" specified for unlabeled block", end)
--	}
--	if end != "" && start != end {
--		return errors.Newf("end label \"%s\" differs from block's label \"%s\"", end, start)
--	}
--	return nil
--}
-diff --git a/pkg/sql/plpgsql/parser/parse.go b/pkg/sql/plpgsql/parser/parse.go
-deleted file mode 100644
-index 520830a..0000000
---- a/pkg/sql/plpgsql/parser/parse.go
-+++ /dev/null
-@@ -1,136 +0,0 @@
--// Copyright 2023 The Cockroach Authors.
--//
--// Use of this software is governed by the Business Source License
--// included in the file licenses/BSL.txt.
--//
--// As of the Change Date specified in that file, in accordance with
--// the Business Source License, use of this software will be governed
--// by the Apache License, Version 2.0, included in the file
--// licenses/APL.txt.
--
--// Package parser exposes a parser for plpgsql.
--package parser
--
--import (
--	"go/constant"
--
--	"github.com/cockroachdb/cockroachdb-parser/pkg/sql/parser/statements"
--	"github.com/cockroachdb/cockroachdb-parser/pkg/sql/scanner"
--	"github.com/cockroachdb/cockroachdb-parser/pkg/sql/sem/tree"
--	"github.com/cockroachdb/cockroachdb-parser/pkg/sql/types"
--	"github.com/cockroachdb/errors"
--)
--
--func init() {
--	scanner.NewNumValFn = func(a constant.Value, s string, b bool) interface{} { return tree.NewNumVal(a, s, b) }
--	scanner.NewPlaceholderFn = func(s string) (interface{}, error) { return tree.NewPlaceholder(s) }
--}
--
--// Parser wraps a scanner, parser and other utilities present in the parser
--// package.
--type Parser struct {
--	scanner    scanner.PLpgSQLScanner
--	lexer      lexer
--	parserImpl plpgsqlParserImpl
--	tokBuf     [8]plpgsqlSymType
--}
--
--// INT8 is the historical interpretation of INT. This should be left
--// alone in the future, since there are many sql fragments stored
--// in various descriptors. Any user input that was created after
--// INT := INT4 will simply use INT4 in any resulting code.
--var defaultNakedIntType = types.Int
--
--// Parse parses the sql and returns a list of statements.
--func (p *Parser) Parse(sql string) (statements.PLpgStatement, error) {
--	return p.parseWithDepth(1, sql, defaultNakedIntType)
--}
--
--func (p *Parser) scanFnBlock() (sql string, tokens []plpgsqlSymType, done bool) {
--	var lval plpgsqlSymType
--	tokens = p.tokBuf[:0]
--
--	// Scan the first token.
--	p.scanner.Scan(&lval)
--	if lval.id == 0 {
--		return "", nil, true
--	}
--
--	startPos := lval.pos
--	// We make the resulting token positions match the returned string.
--	lval.pos = 0
--	tokens = append(tokens, lval)
--	for {
--		if lval.id == ERROR {
--			return p.scanner.In()[startPos:], tokens, true
--		}
--		// Reset the plpgsqlSymType struct before scanning.
--		lval = plpgsqlSymType{}
--		posBeforeScan := p.scanner.Pos()
--		p.scanner.Scan(&lval)
--		if lval.id == 0 {
--			return p.scanner.In()[startPos:posBeforeScan], tokens, (lval.id == 0)
--		}
--		lval.pos -= startPos
--		tokens = append(tokens, lval)
--	}
--}
--
--func (p *Parser) parseWithDepth(
--	depth int, plpgsql string, nakedIntType *types.T,
--) (statements.PLpgStatement, error) {
--	p.scanner.Init(plpgsql)
--	defer p.scanner.Cleanup()
--	sql, tokens, done := p.scanFnBlock()
--	stmt, err := p.parse(depth+1, sql, tokens, nakedIntType)
--	if err != nil {
--		return statements.PLpgStatement{}, err
--	}
--	if !done {
--		return statements.PLpgStatement{}, errors.AssertionFailedf("invalid plpgsql function: %s", plpgsql)
--	}
--	return stmt, nil
--}
--
--// parse parses a statement from the given scanned tokens.
--func (p *Parser) parse(
--	depth int, sql string, tokens []plpgsqlSymType, nakedIntType *types.T,
--) (statements.PLpgStatement, error) {
--	p.lexer.init(sql, tokens, nakedIntType, &p.parserImpl)
--	defer p.lexer.cleanup()
--	if p.parserImpl.Parse(&p.lexer) != 0 {
--		if p.lexer.lastError == nil {
--			// This should never happen -- there should be an error object
--			// every time Parse() returns nonzero. We're just playing safe
--			// here.
--			p.lexer.Error("syntax error")
--		}
--		err := p.lexer.lastError
--
--		// Compatibility with 19.1 telemetry: prefix the telemetry keys
--		// with the "syntax." prefix.
--		// TODO(knz): move the auto-prefixing of feature names to a
--		// higher level in the call stack.
--		tkeys := errors.GetTelemetryKeys(err)
--		if len(tkeys) > 0 {
--			for i := range tkeys {
--				tkeys[i] = "syntax." + tkeys[i]
--			}
--			err = errors.WithTelemetry(err, tkeys...)
--		}
--
--		return statements.PLpgStatement{}, err
--	}
--	return statements.PLpgStatement{
--		AST:             p.lexer.stmt,
--		SQL:             sql,
--		NumPlaceholders: p.lexer.numPlaceholders,
--		NumAnnotations:  p.lexer.numAnnotations,
--	}, nil
--}
--
--// Parse parses a sql statement string and returns a list of Statements.
--func Parse(sql string) (statements.PLpgStatement, error) {
--	var p Parser
--	return p.parseWithDepth(1, sql, defaultNakedIntType)
--}
-diff --git a/pkg/sql/plpgsql/parser/plpgsql.y b/pkg/sql/plpgsql/parser/plpgsql.y
-deleted file mode 100644
-index 8ee4069..0000000
---- a/pkg/sql/plpgsql/parser/plpgsql.y
-+++ /dev/null
-@@ -1,1647 +0,0 @@
--%{
--package parser
--
--import (
--  "github.com/cockroachdb/cockroach/pkg/sql/parser"
--  "github.com/cockroachdb/cockroach/pkg/sql/scanner"
--  "github.com/cockroachdb/cockroach/pkg/sql/sem/tree"
--  "github.com/cockroachdb/cockroach/pkg/sql/sem/plpgsqltree"
--  "github.com/cockroachdb/errors"
--  "github.com/cockroachdb/redact"
--)
--%}
--
--%{
--func setErr(plpgsqllex plpgsqlLexer, err error) int {
--    plpgsqllex.(*lexer).setErr(err)
--    return 1
--}
--
--func unimplemented(plpgsqllex plpgsqlLexer, feature string) int {
--    plpgsqllex.(*lexer).Unimplemented(feature)
--    return 1
--}
--
--//functions to cast plpgsqlSymType/sqlSymUnion to other types.
--var _ scanner.ScanSymType = &plpgsqlSymType{}
--
--func (s *plpgsqlSymType) ID() int32 {
--  return s.id
--}
--
--func (s *plpgsqlSymType) SetID(id int32) {
--  s.id = id
--}
--
--func (s *plpgsqlSymType) Pos() int32 {
--  return s.pos
--}
--
--func (s *plpgsqlSymType) SetPos(pos int32) {
--  s.pos = pos
--}
--
--func (s *plpgsqlSymType) Str() string {
--  return s.str
--}
--
--func (s *plpgsqlSymType) SetStr(str string) {
--  s.str = str
--}
--
--func (s *plpgsqlSymType) UnionVal() interface{} {
--  return s.union.val
--}
--
--func (s *plpgsqlSymType) SetUnionVal(val interface{}) {
--  s.union.val = val
--}
--
--func (s *plpgsqlSymType) plpgsqlScanSymType() {}
--
--type plpgsqlSymUnion struct {
--    val interface{}
--}
--
--func (u *plpgsqlSymUnion) block() *plpgsqltree.Block {
--    return u.val.(*plpgsqltree.Block)
--}
--
--func (u *plpgsqlSymUnion) caseWhen() *plpgsqltree.CaseWhen {
--    return u.val.(*plpgsqltree.CaseWhen)
--}
--
--func (u *plpgsqlSymUnion) caseWhens() []*plpgsqltree.CaseWhen {
--    return u.val.([]*plpgsqltree.CaseWhen)
--}
--
--func (u *plpgsqlSymUnion) statement() plpgsqltree.Statement {
--    return u.val.(plpgsqltree.Statement)
--}
--
--func (u *plpgsqlSymUnion) statements() []plpgsqltree.Statement {
--    return u.val.([]plpgsqltree.Statement)
--}
--
--func (u *plpgsqlSymUnion) int32() int32 {
--    return u.val.(int32)
--}
--
--func (u *plpgsqlSymUnion) uint32() uint32 {
--    return u.val.(uint32)
--}
--
--func (u *plpgsqlSymUnion) bool() bool {
--    return u.val.(bool)
--}
--
--func (u *plpgsqlSymUnion) numVal() *tree.NumVal {
--    return u.val.(*tree.NumVal)
--}
--
--func (u *plpgsqlSymUnion) typ() tree.ResolvableTypeReference {
--    return u.val.(tree.ResolvableTypeReference)
--}
--
--func (u *plpgsqlSymUnion) getDiagnosticsKind() plpgsqltree.GetDiagnosticsKind {
--    return u.val.(plpgsqltree.GetDiagnosticsKind)
--}
--
--func (u *plpgsqlSymUnion) getDiagnosticsItem() *plpgsqltree.GetDiagnosticsItem {
--    return u.val.(*plpgsqltree.GetDiagnosticsItem)
--}
--
--func (u *plpgsqlSymUnion) getDiagnosticsItemList() plpgsqltree.GetDiagnosticsItemList {
--    return u.val.(plpgsqltree.GetDiagnosticsItemList)
--}
--
--func (u *plpgsqlSymUnion) elseIf() []plpgsqltree.ElseIf {
--    return u.val.([]plpgsqltree.ElseIf)
--}
--
--func (u *plpgsqlSymUnion) open() *plpgsqltree.Open {
--    return u.val.(*plpgsqltree.Open)
--}
--
--func (u *plpgsqlSymUnion) expr() plpgsqltree.Expr {
--    if u.val == nil {
--        return nil
--    }
--    return u.val.(plpgsqltree.Expr)
--}
--
--func (u *plpgsqlSymUnion) exprs() []plpgsqltree.Expr {
--    return u.val.([]plpgsqltree.Expr)
--}
--
--func (u *plpgsqlSymUnion) raiseOption() *plpgsqltree.RaiseOption {
--    return u.val.(*plpgsqltree.RaiseOption)
--}
--
--func (u *plpgsqlSymUnion) raiseOptions() []plpgsqltree.RaiseOption {
--    return u.val.([]plpgsqltree.RaiseOption)
--}
--
--
--func (u *plpgsqlSymUnion) exception() *plpgsqltree.Exception {
--    return u.val.(*plpgsqltree.Exception)
--}
--
--func (u *plpgsqlSymUnion) exceptions() []plpgsqltree.Exception {
--    return u.val.([]plpgsqltree.Exception)
--}
--
--func (u *plpgsqlSymUnion) condition() *plpgsqltree.Condition {
--    return u.val.(*plpgsqltree.Condition)
--}
--
--func (u *plpgsqlSymUnion) conditions() []plpgsqltree.Condition {
--    return u.val.([]plpgsqltree.Condition)
--}
--
--func (u *plpgsqlSymUnion) cursorScrollOption() tree.CursorScrollOption {
--    return u.val.(tree.CursorScrollOption)
--}
--
--func (u *plpgsqlSymUnion) sqlStatement() tree.Statement {
--    return u.val.(tree.Statement)
--}
--
--%}
--/*
-- * Basic non-keyword token types.  These are hard-wired into the core lexer.
-- * They must be listed first so that their numeric codes do not depend on
-- * the set of keywords.  Keep this list in sync with backend/parser/gram.y!
-- *
-- * Some of these are not directly referenced in this file, but they must be
-- * here anyway.
-- */
--%token <str> IDENT UIDENT FCONST SCONST USCONST BCONST XCONST Op
--%token <*tree.NumVal>	ICONST PARAM
--%token <str> TYPECAST DOT_DOT COLON_EQUALS EQUALS_GREATER
--%token <str> LESS_EQUALS GREATER_EQUALS NOT_EQUALS
--
--/*
-- * Other tokens recognized by plpgsql's lexer interface layer (pl_scanner.c).
-- */
--%token <str> LESS_LESS GREATER_GREATER
--
--/*
-- * Keyword tokens.  Some of these are reserved and some are not;
-- * see pl_scanner.c for info.  Be sure unreserved keywords are listed
-- * in the "unreserved_keyword" production below.
-- */
--%token <str>  ABSOLUTE
--%token <str>  ALIAS
--%token <str>  ALL
--%token <str>  AND
--%token <str>  ARRAY
--%token <str>  ASSERT
--%token <str>  BACKWARD
--%token <str>  BEGIN
--%token <str>  BY
--%token <str>  CALL
--%token <str>  CASE
--%token <str>  CHAIN
--%token <str>  CLOSE
--%token <str>  COLLATE
--%token <str>  COLUMN
--%token <str>  COLUMN_NAME
--%token <str>  COMMIT
--%token <str>  CONSTANT
--%token <str>  CONSTRAINT
--%token <str>  CONSTRAINT_NAME
--%token <str>  CONTINUE
--%token <str>  CURRENT
--%token <str>  CURSOR
--%token <str>  DATATYPE
--%token <str>  DEBUG
--%token <str>  DECLARE
--%token <str>  DEFAULT
--%token <str>  DETAIL
--%token <str>  DIAGNOSTICS
--%token <str>  DO
--%token <str>  DUMP
--%token <str>  ELSE
--%token <str>  ELSIF
--%token <str>  END
--%token <str>  END_CASE
--%token <str>  END_IF
--%token <str>  ERRCODE
--%token <str>  ERROR
--%token <str>  EXCEPTION
--%token <str>  EXECUTE
--%token <str>  EXIT
--%token <str>  FETCH
--%token <str>  FIRST
--%token <str>  FOR
--%token <str>  FOREACH
--%token <str>  FORWARD
--%token <str>  FROM
--%token <str>  GET
--%token <str>  HINT
--%token <str>  IF
--%token <str>  IMPORT
--%token <str>  IN
--%token <str>  INFO
--%token <str>  INSERT
--%token <str>  INTO
--%token <str>  IS
--%token <str>  LAST
--%token <str>  LOG
--%token <str>  LOOP
--%token <str>  MERGE
--%token <str>  MESSAGE
--%token <str>  MESSAGE_TEXT
--%token <str>  MOVE
--%token <str>  NEXT
--%token <str>  NO
--%token <str>  NO_SCROLL
--%token <str>  NOT
--%token <str>  NOTICE
--%token <str>  NULL
--%token <str>  OPEN
--%token <str>  OPTION
--%token <str>  OR
--%token <str>  PERFORM
--%token <str>  PG_CONTEXT
--%token <str>  PG_DATATYPE_NAME
--%token <str>  PG_EXCEPTION_CONTEXT
--%token <str>  PG_EXCEPTION_DETAIL
--%token <str>  PG_EXCEPTION_HINT
--%token <str>  PRINT_STRICT_PARAMS
--%token <str>  PRIOR
--%token <str>  QUERY
--%token <str>  RAISE
--%token <str>  RELATIVE
--%token <str>  RETURN
--%token <str>  RETURN_NEXT
--%token <str>  RETURN_QUERY
--%token <str>  RETURNED_SQLSTATE
--%token <str>  REVERSE
--%token <str>  ROLLBACK
--%token <str>  ROW_COUNT
--%token <str>  ROWTYPE
--%token <str>  SCHEMA
--%token <str>  SCHEMA_NAME
--%token <str>  SCROLL
--%token <str>  SLICE
--%token <str>  SQLSTATE
--%token <str>  STACKED
--%token <str>  STRICT
--%token <str>  TABLE
--%token <str>  TABLE_NAME
--%token <str>  THEN
--%token <str>  TO
--%token <str>  TYPE
--%token <str>  UPSERT
--%token <str>  USE_COLUMN
--%token <str>  USE_VARIABLE
--%token <str>  USING
--%token <str>  VARIABLE_CONFLICT
--%token <str>  WARNING
--%token <str>  WHEN
--%token <str>  WHILE
--
--
--%union {
--  id    int32
--  pos   int32
--  str   string
--  union plpgsqlSymUnion
--}
--
--%type <str> decl_varname decl_defkey
--%type <bool>	decl_const decl_notnull
--%type <plpgsqltree.Expr>	decl_defval decl_cursor_query
--%type <tree.ResolvableTypeReference>	decl_datatype
--%type <str>		decl_collate
--
--%type <str>	expr_until_semi expr_until_paren stmt_until_semi
--%type <str>	expr_until_then expr_until_loop opt_expr_until_when
--%type <plpgsqltree.Expr>	opt_exitcond
--
--%type <forvariable>	for_variable
--%type <plpgsqltree.Expr>	return_variable
--%type <*tree.NumVal>	foreach_slice
--%type <plpgsqltree.Statement>	for_control
--
--%type <str> any_identifier opt_block_label opt_loop_label opt_label query_options
--%type <str> opt_error_level option_type
--
--%type <[]plpgsqltree.Statement> proc_sect
--%type <[]plpgsqltree.ElseIf> stmt_elsifs
--%type <[]plpgsqltree.Statement> stmt_else loop_body // TODO is this a list of statement?
--%type <plpgsqltree.Statement>  pl_block
--%type <plpgsqltree.Statement>	proc_stmt
--%type <plpgsqltree.Statement>	stmt_assign stmt_if stmt_loop stmt_while stmt_exit stmt_continue
--%type <plpgsqltree.Statement>	stmt_return stmt_raise stmt_assert stmt_execsql
--%type <plpgsqltree.Statement>	stmt_dynexecute stmt_for stmt_perform stmt_call stmt_getdiag
--%type <plpgsqltree.Statement>	stmt_open stmt_fetch stmt_move stmt_close stmt_null
--%type <plpgsqltree.Statement>	stmt_commit stmt_rollback
--%type <plpgsqltree.Statement>	stmt_case stmt_foreach_a
--
--%type <plpgsqltree.Statement> decl_stmt decl_statement
--%type <[]plpgsqltree.Statement> decl_sect opt_decl_stmts decl_stmts
--
--%type <[]plpgsqltree.Exception> exception_sect proc_exceptions
--%type <*plpgsqltree.Exception>	proc_exception
--%type <[]plpgsqltree.Condition> proc_conditions
--%type <*plpgsqltree.Condition> proc_condition
--
--%type <*plpgsqltree.CaseWhen>	case_when
--%type <[]*plpgsqltree.CaseWhen>	case_when_list
--%type <[]plpgsqltree.Statement> opt_case_else
--
--%type <bool>	getdiag_area_opt
--%type <plpgsqltree.GetDiagnosticsItemList>	getdiag_list // TODO don't know what this is
--%type <*plpgsqltree.GetDiagnosticsItem> getdiag_list_item // TODO don't know what this is
--%type <int32> getdiag_item
--
--%type <*plpgsqltree.RaiseOption> option_expr
--%type <[]plpgsqltree.RaiseOption> option_exprs opt_option_exprs
--%type <plpgsqltree.Expr> format_expr
--%type <[]plpgsqltree.Expr> opt_format_exprs format_exprs
--
--%type <tree.CursorScrollOption>	opt_scrollable
--
--%type <*tree.NumVal>	opt_transaction_chain
--
--%type <str>	unreserved_keyword
--%%
--
--pl_function:
--  pl_block opt_semi
--  {
--    plpgsqllex.(*lexer).SetStmt($1.statement())
--  }
--
--opt_semi:
--| ';'
--;
--
--pl_block: opt_block_label decl_sect BEGIN proc_sect exception_sect END opt_label
--  {
--    $$.val = &plpgsqltree.Block{
--      Label: $1,
--      Decls: $2.statements(),
--      Body: $4.statements(),
--      Exceptions: $5.exceptions(),
--    }
--  }
--;
--
--decl_sect: DECLARE opt_decl_stmts
--  {
--    $$.val = $2.statements()
--  }
--| /* EMPTY */
--  {
--    // Use a nil slice to indicate DECLARE was not used.
--    $$.val = []plpgsqltree.Statement(nil)
--  }
--;
--
--opt_decl_stmts: decl_stmts
--  {
--    $$.val = $1.statements()
--  }
--| /* EMPTY */
--  {
--    $$.val = []plpgsqltree.Statement{}
--  }
--;
--
--decl_stmts: decl_stmts decl_stmt
--  {
--    decs := $1.statements()
--    dec := $2.statement()
--    $$.val = append(decs, dec)
--  }
--| decl_stmt
--  {
--    dec := $1.statement()
--    $$.val = []plpgsqltree.Statement{dec}
--	}
--;
--
--decl_stmt	: decl_statement
--  {
--    $$.val = $1.statement()
--  }
--| DECLARE
--  {
--    // This is to allow useless extra "DECLARE" keywords in the declare section.
--    $$.val = (plpgsqltree.Statement)(nil)
--  }
--// TODO(chengxiong): turn this block on and throw useful error if user
--// tries to put the block label just before BEGIN instead of before
--// DECLARE.
--//| LESS_LESS any_identifier GREATER_GREATER
--//  {
--//  }
--;
--
--decl_statement: decl_varname decl_const decl_datatype decl_collate decl_notnull decl_defval
--  {
--    $$.val = &plpgsqltree.Declaration{
--      Var: plpgsqltree.Variable($1),
--      Constant: $2.bool(),
--      Typ: $3.typ(),
--      Collate: $4,
--      NotNull: $5.bool(),
--      Expr: $6.expr(),
--    }
--  }
--| decl_varname ALIAS FOR decl_aliasitem ';'
--  {
--    return unimplemented(plpgsqllex, "alias for")
--  }
--| decl_varname opt_scrollable CURSOR decl_cursor_args decl_is_for decl_cursor_query
--  {
--    $$.val = &plpgsqltree.CursorDeclaration{
--      Name: plpgsqltree.Variable($1),
--      Scroll: $2.cursorScrollOption(),
--      Query: $6.sqlStatement(),
--    }
--  }
--;
--
--opt_scrollable:
--  {
--    $$.val = tree.UnspecifiedScroll
--  }
--| NO_SCROLL SCROLL
--  {
--    $$.val = tree.NoScroll
--  }
--| SCROLL
--  {
--    $$.val = tree.Scroll
--  }
--;
--
--decl_cursor_query: stmt_until_semi ';'
--  {
--    stmts, err := parser.Parse($1)
--    if err != nil {
--      return setErr(plpgsqllex, err)
--    }
--    if len(stmts) != 1 {
--      return setErr(plpgsqllex, errors.New("expected exactly one SQL statement for cursor"))
--    }
--    $$.val = stmts[0].AST
--  }
--;
--
--decl_cursor_args: '('
--  {
--    return unimplemented(plpgsqllex, "cursor arguments")
--  }
--| /* EMPTY */
--  {
--  }
--;
--
--decl_cursor_arglist: decl_cursor_arg
--  {
--  }
--| decl_cursor_arglist ',' decl_cursor_arg
--  {
--  }
--;
--
--decl_cursor_arg: decl_varname decl_datatype
--  {
--  }
--;
--
--decl_is_for:
--  IS   /* Oracle */
--| FOR  /* SQL standard */
--
--decl_aliasitem: IDENT
--  {
--  }
--| unreserved_keyword
--  {
--  }
--;
--
--decl_varname: IDENT
--| unreserved_keyword
--;
--
--decl_const:
--  {
--    $$.val = false
--  }
--| CONSTANT
--  {
--    $$.val = true
--  }
--;
--
--decl_datatype:
--  {
--    // Read until reaching one of the tokens that can follow a declaration
--    // data type.
--    sqlStr, _, err := plpgsqllex.(*lexer).ReadSqlExpr(
--      ';', COLLATE, NOT, '=', COLON_EQUALS, DECLARE,
--    )
--    if err != nil {
--      return setErr(plpgsqllex, err)
--    }
--    typ, err := plpgsqllex.(*lexer).GetTypeFromValidSQLSyntax(sqlStr)
--    if err != nil {
--      return setErr(plpgsqllex, err)
--    }
--    $$.val = typ
--  }
--;
--
--decl_collate:
--  {
--    $$ = ""
--  }
--| COLLATE IDENT
--  {
--    $$ = $2
--  }
--| COLLATE unreserved_keyword
--  {
--    $$ = $2
--  }
--;
--
--decl_notnull:
--  {
--    $$.val = false
--  }
--| NOT NULL
--  {
--    $$.val = true
--  }
--;
--
--decl_defval: ';'
--  {
--    $$.val = (plpgsqltree.Expr)(nil)
--  }
--| decl_defkey ';'
--  {
--    expr, err := plpgsqllex.(*lexer).ParseExpr($1)
--    if err != nil {
--      return setErr(plpgsqllex, err)
--    }
--    $$.val = expr
--  }
--;
--
--decl_defkey: assign_operator
--  {
--    sqlStr, _, err := plpgsqllex.(*lexer).ReadSqlExpr(';')
--    if err != nil {
--      return setErr(plpgsqllex, err)
--    }
--    $$ = sqlStr
--  }
--| DEFAULT
--  {
--    sqlStr, _, err := plpgsqllex.(*lexer).ReadSqlExpr(';')
--    if err != nil {
--      return setErr(plpgsqllex, err)
--    }
--    $$ = sqlStr
--  }
--;
--
--/*
-- * Ada-based PL/SQL uses := for assignment and variable defaults, while
-- * the SQL standard uses equals for these cases and for GET
-- * DIAGNOSTICS, so we support both.  FOR and OPEN only support :=.
-- */
--assign_operator: '='
--| COLON_EQUALS
--;
--
--proc_sect:
--  {
--    $$.val = []plpgsqltree.Statement{}
--  }
--| proc_sect proc_stmt
--  {
--    stmts := $1.statements()
--    stmts = append(stmts, $2.statement())
--    $$.val = stmts
--  }
--;
--
--proc_stmt:pl_block ';'
--  {
--    $$.val = $1.block()
--  }
--| stmt_assign
--  {
--    $$.val = $1.statement()
--  }
--| stmt_if
--  {
--    $$.val = $1.statement()
--  }
--| stmt_case
--  {
--    $$.val = $1.statement()
--  }
--| stmt_loop
--  {
--    $$.val = $1.statement()
--  }
--| stmt_while
--  { }
--| stmt_for
--  { }
--| stmt_foreach_a
--  { }
--| stmt_exit
--  {
--    $$.val = $1.statement()
--  }
--| stmt_continue
--  {
--    $$.val = $1.statement()
--  }
--| stmt_return
--  {
--    $$.val = $1.statement()
--  }
--| stmt_raise
--  {
--    $$.val = $1.statement()
--  }
--| stmt_assert
--  {
--    $$.val = $1.statement()
--  }
--| stmt_execsql
--  {
--    $$.val = $1.statement()
--  }
--| stmt_dynexecute
--  {
--    $$.val = $1.statement()
--  }
--| stmt_perform
--  { }
--| stmt_call
--  {
--    $$.val = $1.statement()
--  }
--| stmt_getdiag
--  { }
--| stmt_open
--  {
--    $$.val = $1.statement()
--  }
--| stmt_fetch
--  {
--    $$.val = $1.statement()
--  }
--| stmt_move
--  {
--    $$.val = $1.statement()
--  }
--| stmt_close
--  {
--    $$.val = $1.statement()
--  }
--| stmt_null
--  { }
--| stmt_commit
--  { }
--| stmt_rollback
--  { }
--;
--
--stmt_perform: PERFORM stmt_until_semi ';'
--  {
--    return unimplemented(plpgsqllex, "perform")
--  }
--;
--
--stmt_call: CALL call_cmd ';'
--  {
--    $$.val = &plpgsqltree.Call{IsCall: true}
--  }
--| DO call_cmd ';'
--  {
--    $$.val = &plpgsqltree.Call{IsCall: false}
--  }
--;
--
--call_cmd:
--  {
--    _, _, err := plpgsqllex.(*lexer).ReadSqlExpr(';')
--    if err != nil {
--      return setErr(plpgsqllex, err)
--    }
--  }
--;
--
--stmt_assign: IDENT assign_operator expr_until_semi ';'
--  {
--    expr, err := plpgsqllex.(*lexer).ParseExpr($3)
--    if err != nil {
--      return setErr(plpgsqllex, err)
--    }
--    $$.val = &plpgsqltree.Assignment{
--      Var: plpgsqltree.Variable($1),
--      Value: expr,
--    }
--  }
--;
--
--stmt_getdiag: GET getdiag_area_opt DIAGNOSTICS getdiag_list ';'
--  {
--  $$.val = &plpgsqltree.GetDiagnostics{
--    IsStacked: $2.bool(),
--    DiagItems: $4.getDiagnosticsItemList(),
--  }
--  // TODO(jane): Check information items are valid for area option.
--  }
--;
--
--getdiag_area_opt:
--  {
--    $$.val = false
--  }
--| CURRENT
--  {
--    $$.val = false
--  }
--| STACKED
--  {
--    $$.val = true
--  }
--;
--
--getdiag_list: getdiag_list ',' getdiag_list_item
--  {
--    $$.val = append($1.getDiagnosticsItemList(), $3.getDiagnosticsItem())
--  }
--| getdiag_list_item
--  {
--    $$.val = plpgsqltree.GetDiagnosticsItemList{$1.getDiagnosticsItem()}
--  }
--;
--
--getdiag_list_item: IDENT assign_operator getdiag_item
--  {
--    $$.val = &plpgsqltree.GetDiagnosticsItem{
--      Kind : $3.getDiagnosticsKind(),
--      TargetName: $1,
--      // TODO(jane): set the target from $1.
--    }
--  }
--;
--
--getdiag_item: unreserved_keyword {
--  switch $1 {
--    case "row_count":
--      $$.val = plpgsqltree.GetDiagnosticsRowCount;
--    case "pg_context":
--      $$.val = plpgsqltree.GetDiagnosticsContext;
--    case "pg_exception_detail":
--      $$.val = plpgsqltree.GetDiagnosticsErrorDetail;
--    case "pg_exception_hint":
--      $$.val = plpgsqltree.GetDiagnosticsErrorHint;
--    case "pg_exception_context":
--      $$.val = plpgsqltree.GetDiagnosticsErrorContext;
--    case "column_name":
--      $$.val = plpgsqltree.GetDiagnosticsColumnName;
--    case "constraint_name":
--      $$.val = plpgsqltree.GetDiagnosticsConstraintName;
--    case "pg_datatype_name":
--      $$.val = plpgsqltree.GetDiagnosticsDatatypeName;
--    case "message_text":
--      $$.val = plpgsqltree.GetDiagnosticsMessageText;
--    case "table_name":
--      $$.val = plpgsqltree.GetDiagnosticsTableName;
--    case "schema_name":
--      $$.val = plpgsqltree.GetDiagnosticsSchemaName;
--    case "returned_sqlstate":
--      $$.val = plpgsqltree.GetDiagnosticsReturnedSQLState;
--    default:
--      // TODO(jane): Should this use an unimplemented error instead?
--      return setErr(plpgsqllex, errors.Newf("unrecognized GET DIAGNOSTICS item: %s", redact.Safe($1)))
--  }
--}
--;
--
--getdiag_target:
--// TODO(jane): remove ident.
--IDENT
--  {
--  }
--;
--
--stmt_if: IF expr_until_then THEN proc_sect stmt_elsifs stmt_else END_IF IF ';'
--  {
--    cond, err := plpgsqllex.(*lexer).ParseExpr($2)
--    if err != nil {
--      return setErr(plpgsqllex, err)
--    }
--    $$.val = &plpgsqltree.If{
--      Condition: cond,
--      ThenBody: $4.statements(),
--      ElseIfList: $5.elseIf(),
--      ElseBody: $6.statements(),
--    }
--  }
--;
--
--stmt_elsifs:
--  {
--    $$.val = []plpgsqltree.ElseIf{};
--  }
--| stmt_elsifs ELSIF expr_until_then THEN proc_sect
--  {
--    cond, err := plpgsqllex.(*lexer).ParseExpr($3)
--    if err != nil {
--      return setErr(plpgsqllex, err)
--    }
--    newStmt := plpgsqltree.ElseIf{
--      Condition: cond,
--      Stmts: $5.statements(),
--    }
--    $$.val = append($1.elseIf() , newStmt)
--  }
--;
--
--stmt_else:
--  {
--    $$.val = []plpgsqltree.Statement{};
--  }
--| ELSE proc_sect
--  {
--    $$.val = $2.statements();
--  }
--;
--
--stmt_case: CASE opt_expr_until_when case_when_list opt_case_else END_CASE CASE ';'
--  {
--    expr := &plpgsqltree.Case {
--      TestExpr: $2,
--      CaseWhenList: $3.caseWhens(),
--    }
--    if $4.val != nil {
--       expr.HaveElse = true
--       expr.ElseStmts = $4.statements()
--    }
--    $$.val = expr
--  }
--;
--
--opt_expr_until_when:
--  {
--    if plpgsqllex.(*lexer).Peek().id != WHEN {
--      sqlStr, _, err := plpgsqllex.(*lexer).ReadSqlExpr(WHEN)
--      if err != nil {
--        return setErr(plpgsqllex, err)
--      }
--      $$ = sqlStr
--    } else {
--      $$ = ""
--    }
--  }
--;
--
--case_when_list: case_when_list case_when
--  {
--    stmts := $1.caseWhens()
--    stmts = append(stmts, $2.caseWhen())
--    $$.val = stmts
--  }
--| case_when
--  {
--    stmts := []*plpgsqltree.CaseWhen{}
--    stmts = append(stmts, $1.caseWhen())
--    $$.val = stmts
--  }
--;
--
--case_when: WHEN expr_until_then THEN proc_sect
--  {
--     expr := &plpgsqltree.CaseWhen{
--       Expr: $2,
--       Stmts: $4.statements(),
--     }
--     $$.val = expr
--  }
--;
--
--opt_case_else:
--  {
--    $$.val = nil
--  }
--| ELSE proc_sect
--  {
--    $$.val = $2.statements()
--  }
--;
--
--stmt_loop: opt_loop_label LOOP loop_body opt_label ';'
--  {
--    loopLabel, loopEndLabel := $1, $4
--    if err := checkLoopLabels(loopLabel, loopEndLabel); err != nil {
--      return setErr(plpgsqllex, err)
--    }
--    $$.val = &plpgsqltree.Loop{
--      Label: $1,
--      Body: $3.statements(),
--    }
--  }
--;
--
--stmt_while: opt_loop_label WHILE expr_until_loop LOOP loop_body opt_label ';'
--  {
--    loopLabel, loopEndLabel := $1, $6
--    if err := checkLoopLabels(loopLabel, loopEndLabel); err != nil {
--      return setErr(plpgsqllex, err)
--    }
--    cond, err := plpgsqllex.(*lexer).ParseExpr($3)
--    if err != nil {
--      return setErr(plpgsqllex, err)
--    }
--    $$.val = &plpgsqltree.While{
--      Label: $1,
--      Condition: cond,
--      Body: $5.statements(),
--    }
--  }
--;
--
--stmt_for: opt_loop_label FOR for_control loop_body
--  {
--    return unimplemented(plpgsqllex, "for loop")
--  }
--;
--
--for_control: for_variable IN
--  // TODO need to parse the sql expression here.
--  {
--    return unimplemented(plpgsqllex, "for loop")
--  }
--;
--
--/*
-- * Processing the for_variable is tricky because we don't yet know if the
-- * FOR is an integer FOR loop or a loop over query results.  In the former
-- * case, the variable is just a name that we must instantiate as a loop
-- * local variable, regardless of any other definition it might have.
-- * Therefore, we always save the actual identifier into $$.name where it
-- * can be used for that case.  We also save the outer-variable definition,
-- * if any, because that's what we need for the loop-over-query case.  Note
-- * that we must NOT apply check_assignable() or any other semantic check
-- * until we know what's what.
-- *
-- * However, if we see a comma-separated list of names, we know that it
-- * can't be an integer FOR loop and so it's OK to check the variables
-- * immediately.  In particular, for T_WORD followed by comma, we should
-- * complain that the name is not known rather than say it's a syntax error.
-- * Note that the non-error result of this case sets *both* $$.scalar and
-- * $$.row; see the for_control production.
-- */
--for_variable: any_identifier
--  {
--    return unimplemented(plpgsqllex, "for loop")
--  }
--;
--
--stmt_foreach_a: opt_loop_label FOREACH for_variable foreach_slice IN ARRAY expr_until_loop loop_body
--  {
--    return unimplemented(plpgsqllex, "for each loop")
--  }
--;
--
--foreach_slice:
--  {
--  }
--| SLICE ICONST
--  {
--  }
--;
--
--stmt_exit: EXIT opt_label opt_exitcond
--  {
--    $$.val = &plpgsqltree.Exit{
--      Label: $2,
--      Condition: $3.expr(),
--    }
--  }
--;
--
--stmt_continue: CONTINUE opt_label opt_exitcond
--  {
--    $$.val = &plpgsqltree.Continue{
--      Label: $2,
--      Condition: $3.expr(),
--    }
--  }
--;
--
--  // TODO handle variable names
--  // 1. verify if the first token is a variable (this means that we need to track variable scope during parsing)
--  // 2. if yes, check next token is ';'
--  // 3. if no, expecting a sql expression "read_sql_expression"
--  //    we can just read until a ';', then do the sql expression validation during compile time.
--
--stmt_return: RETURN return_variable ';'
--  {
--    $$.val = &plpgsqltree.Return{
--      Expr: $2.expr(),
--    }
--  }
--| RETURN_NEXT NEXT
--  {
--    return unimplemented(plpgsqllex, "return next")
--  }
--| RETURN_QUERY QUERY
-- {
--   return unimplemented (plpgsqllex, "return query")
-- }
--;
--
--
--query_options:
--  {
--    _, terminator, err := plpgsqllex.(*lexer).ReadSqlExpr(EXECUTE, ';')
--    if err != nil {
--      return setErr(plpgsqllex, err)
--    }
--    if terminator == EXECUTE {
--      return unimplemented (plpgsqllex, "return dynamic sql query")
--    }
--    _, _, err = plpgsqllex.(*lexer).ReadSqlExpr(';')
--    if err != nil {
--      return setErr(plpgsqllex, err)
--    }
--  }
--;
--
--
--return_variable: expr_until_semi
--  {
--    expr, err := plpgsqllex.(*lexer).ParseExpr($1)
--    if err != nil {
--      return setErr(plpgsqllex, err)
--    }
--    $$.val = expr
--  }
--;
--
--stmt_raise:
--  RAISE ';'
--  {
--    return unimplemented(plpgsqllex, "empty RAISE statement")
--  }
--| RAISE opt_error_level SCONST opt_format_exprs opt_option_exprs ';'
--  {
--    $$.val = &plpgsqltree.Raise{
--      LogLevel: $2,
--      Message: $3,
--      Params: $4.exprs(),
--      Options: $5.raiseOptions(),
--    }
--  }
--| RAISE opt_error_level IDENT opt_option_exprs ';'
--  {
--    $$.val = &plpgsqltree.Raise{
--      LogLevel: $2,
--      CodeName: $3,
--      Options: $4.raiseOptions(),
--    }
--  }
--| RAISE opt_error_level SQLSTATE SCONST opt_option_exprs ';'
--  {
--    $$.val = &plpgsqltree.Raise{
--      LogLevel: $2,
--      Code: $4,
--      Options: $5.raiseOptions(),
--    }
--  }
--| RAISE opt_error_level USING option_exprs ';'
--  {
--    $$.val = &plpgsqltree.Raise{
--      LogLevel: $2,
--      Options: $4.raiseOptions(),
--    }
--  }
--;
--
--opt_error_level:
--  DEBUG
--| LOG
--| INFO
--| NOTICE
--| WARNING
--| EXCEPTION
--| /* EMPTY */
--  {
--    $$ = ""
--  }
--;
--
--opt_option_exprs:
--  USING option_exprs
--  {
--    $$.val = $2.raiseOptions()
--  }
--| /* EMPTY */
--  {
--    $$.val = []plpgsqltree.RaiseOption{}
--  }
--;
--
--option_exprs:
--  option_exprs ',' option_expr
--  {
--    option := $3.raiseOption()
--    $$.val = append($1.raiseOptions(), *option)
--  }
--| option_expr
--  {
--    option := $1.raiseOption()
--    $$.val = []plpgsqltree.RaiseOption{*option}
--  }
--;
--
--option_expr:
--  option_type assign_operator
--  {
--    // Read until reaching one of the tokens that can follow a raise option.
--    sqlStr, _, err := plpgsqllex.(*lexer).ReadSqlExpr(',', ';')
--    if err != nil {
--      return setErr(plpgsqllex, err)
--    }
--    optionExpr, err := plpgsqllex.(*lexer).ParseExpr(sqlStr)
--    if err != nil {
--      return setErr(plpgsqllex, err)
--    }
--    $$.val = &plpgsqltree.RaiseOption{
--      OptType: $1,
--      Expr: optionExpr,
--    }
--  }
--;
--
--option_type:
--  MESSAGE
--| DETAIL
--| HINT
--| ERRCODE
--| COLUMN
--| CONSTRAINT
--| DATATYPE
--| TABLE
--| SCHEMA
--;
--
--opt_format_exprs:
--  format_exprs
--  {
--    $$.val = $1.exprs()
--  }
-- | /* EMPTY */
--  {
--    $$.val = []plpgsqltree.Expr{}
--  }
--;
--
--format_exprs:
--  format_expr
--  {
--    $$.val = []plpgsqltree.Expr{$1.expr()}
--  }
--| format_exprs format_expr
--  {
--    $$.val = append($1.exprs(), $2.expr())
--  }
--;
--
--format_expr: ','
--  {
--    // Read until reaching a token that can follow a raise format parameter.
--    sqlStr, _, err := plpgsqllex.(*lexer).ReadSqlExpr(',', ';', USING)
--    if err != nil {
--      return setErr(plpgsqllex, err)
--    }
--    param, err := plpgsqllex.(*lexer).ParseExpr(sqlStr)
--    if err != nil {
--      return setErr(plpgsqllex, err)
--    }
--    $$.val = param
--  }
--;
--
--stmt_assert: ASSERT assert_cond ';'
--  {
--    $$.val = &plpgsqltree.Assert{}
--  }
--;
--
--assert_cond:
--  {
--    _, terminator, err := plpgsqllex.(*lexer).ReadSqlExpr(',', ';')
--    if err != nil {
--      return setErr(plpgsqllex, err)
--    }
--    if terminator == ',' {
--      _, _, err = plpgsqllex.(*lexer).ReadSqlExpr(';')
--      if err != nil {
--        return setErr(plpgsqllex, err)
--      }
--    }
--  }
--;
--
--loop_body: proc_sect END LOOP
--  {
--    $$.val = $1.statements()
--  }
--;
--
--stmt_execsql: stmt_execsql_start
--  {
--    stmt, err := plpgsqllex.(*lexer).MakeExecSqlStmt()
--    if err != nil {
--      return setErr(plpgsqllex, err)
--    }
--    $$.val = stmt
--  }
--;
--
--stmt_execsql_start:
--  IMPORT
--| INSERT
--| UPSERT
--| MERGE
--| IDENT
--;
--
--stmt_dynexecute: EXECUTE
--  {
--    stmt, err := plpgsqllex.(*lexer).MakeDynamicExecuteStmt()
--    if err != nil {
--      return setErr(plpgsqllex, err)
--    }
--    $$.val = stmt
--  }
--;
--
--stmt_open: OPEN IDENT ';'
--  {
--    $$.val = &plpgsqltree.Open{CurVar: plpgsqltree.Variable($2)}
--  }
--| OPEN IDENT opt_scrollable FOR EXECUTE 
--  {
--    return unimplemented(plpgsqllex, "cursor for execute")
--  }
--| OPEN IDENT opt_scrollable FOR stmt_until_semi ';'
--  {
--    stmts, err := parser.Parse($5)
--    if err != nil {
--      return setErr(plpgsqllex, err)
--    }
--    if len(stmts) != 1 {
--      return setErr(plpgsqllex, errors.New("expected exactly one SQL statement for cursor"))
--    }
--    $$.val = &plpgsqltree.Open{
--      CurVar: plpgsqltree.Variable($2),
--      Scroll: $3.cursorScrollOption(),
--      Query: stmts[0].AST,
--    }
--  }
--;
--
--stmt_fetch: FETCH
--  {
--    fetch, err := plpgsqllex.(*lexer).MakeFetchOrMoveStmt(false)
--    if err != nil {
--      return setErr(plpgsqllex, err)
--    }
--    $$.val = fetch
--  }
--;
--
--stmt_move: MOVE
--  {
--    move, err := plpgsqllex.(*lexer).MakeFetchOrMoveStmt(true)
--    if err != nil {
--      return setErr(plpgsqllex, err)
--    }
--    $$.val = move
--  }
--;
--
--stmt_close: CLOSE IDENT ';'
--  {
--    $$.val = &plpgsqltree.Close{CurVar: plpgsqltree.Variable($2)}
--  }
--;
--
--stmt_null: NULL ';'
--  {
--  $$.val = &plpgsqltree.Null{};
--  }
--;
--
--stmt_commit: COMMIT opt_transaction_chain ';'
--  {
--    return unimplemented(plpgsqllex, "commit")
--  }
--;
--
--stmt_rollback: ROLLBACK opt_transaction_chain ';'
--  {
--    return unimplemented(plpgsqllex, "rollback")
--  }
--;
--
--opt_transaction_chain:
--AND CHAIN
--  { }
--| AND NO CHAIN
--  { }
--| /* EMPTY */
--  { }
--
--exception_sect: /* EMPTY */
--  {
--    $$.val = []plpgsqltree.Exception(nil)
--  }
--| EXCEPTION proc_exceptions
--  {
--    $$.val = $2.exceptions()
--  }
--;
--
--proc_exceptions: proc_exceptions proc_exception
--  {
--    e := $2.exception()
--    $$.val = append($1.exceptions(), *e)
--  }
--| proc_exception
--  {
--    e := $1.exception()
--    $$.val = []plpgsqltree.Exception{*e}
--  }
--;
--
--proc_exception: WHEN proc_conditions THEN proc_sect
--  {
--    $$.val = &plpgsqltree.Exception{
--      Conditions: $2.conditions(),
--      Action: $4.statements(),
--    }
--  }
--;
--
--proc_conditions: proc_conditions OR proc_condition
--  {
--    c := $3.condition()
--    $$.val = append($1.conditions(), *c)
--  }
--| proc_condition
--  {
--    c := $1.condition()
--    $$.val = []plpgsqltree.Condition{*c}
--  }
--;
--
--proc_condition: any_identifier
--  {
--    $$.val = &plpgsqltree.Condition{SqlErrName: $1}
--  }
--| SQLSTATE SCONST
--  {
--    $$.val = &plpgsqltree.Condition{SqlErrState: $2}
--  }
--;
--
--expr_until_semi:
--  {
--    sqlStr, _, err := plpgsqllex.(*lexer).ReadSqlExpr(';')
--    if err != nil {
--      return setErr(plpgsqllex, err)
--    }
--    $$ = sqlStr
--  }
--;
--
--stmt_until_semi:
--  {
--    sqlStr, _, err := plpgsqllex.(*lexer).ReadSqlStatement(';')
--    if err != nil {
--      return setErr(plpgsqllex, err)
--    }
--    $$ = sqlStr
--  }
--;
--
--expr_until_then:
--  {
--    sqlStr, _, err := plpgsqllex.(*lexer).ReadSqlExpr(THEN)
--    if err != nil {
--      return setErr(plpgsqllex, err)
--    }
--    $$ = sqlStr
--  }
--;
--
--expr_until_loop:
--  {
--    sqlStr, _, err := plpgsqllex.(*lexer).ReadSqlExpr(LOOP)
--    if err != nil {
--      return setErr(plpgsqllex, err)
--    }
--    $$ = sqlStr
--  }
--;
--
--expr_until_paren :
--  {
--    sqlStr, _, err := plpgsqllex.(*lexer).ReadSqlExpr(')')
--    if err != nil {
--      return setErr(plpgsqllex, err)
--    }
--    $$ = sqlStr
--  }
--;
--
--opt_block_label	:
--  {
--    $$ = ""
--  }
--| LESS_LESS any_identifier GREATER_GREATER
--  {
--    $$ = $2
--  }
--;
--
--opt_loop_label:
--  {
--    $$ = ""
--  }
--| LESS_LESS any_identifier GREATER_GREATER
--  {
--    $$ = $2
--  }
--;
--
--opt_label:
--  {
--    $$ = ""
--  }
--| any_identifier
--  {
--    $$ = $1
--  }
--;
--
--opt_exitcond: ';'
--  { }
--| WHEN expr_until_semi ';'
--  {
--    expr, err := plpgsqllex.(*lexer).ParseExpr($2)
--    if err != nil {
--      return setErr(plpgsqllex, err)
--    }
--    $$.val = expr
--  }
--;
--
--/*
-- * need to allow DATUM because scanner will have tried to resolve as variable
-- */
--any_identifier:
--IDENT
--| unreserved_keyword
--;
--
--unreserved_keyword:
--  ABSOLUTE
--| ALIAS
--| AND
--| ARRAY
--| ASSERT
--| BACKWARD
--| CALL
--| CHAIN
--| CLOSE
--| COLLATE
--| COLUMN
--| COLUMN_NAME
--| COMMIT
--| CONSTANT
--| CONSTRAINT
--| CONSTRAINT_NAME
--| CONTINUE
--| CURRENT
--| CURSOR
--| DATATYPE
--| DEBUG
--| DEFAULT
--| DETAIL
--| DIAGNOSTICS
--| DO
--| DUMP
--| ELSIF
--| ERRCODE
--| ERROR
--| EXCEPTION
--| EXIT
--| FETCH
--| FIRST
--| FORWARD
--| GET
--| HINT
--| IMPORT
--| INFO
--| INSERT
--| IS
--| LAST
--| LOG
--| MERGE
--| MESSAGE
--| MESSAGE_TEXT
--| MOVE
--| NEXT
--| NO
--| NO_SCROLL
--| NOTICE
--| OPEN
--| OPTION
--| PERFORM
--| PG_CONTEXT
--| PG_DATATYPE_NAME
--| PG_EXCEPTION_CONTEXT
--| PG_EXCEPTION_DETAIL
--| PG_EXCEPTION_HINT
--| PRINT_STRICT_PARAMS
--| PRIOR
--| QUERY
--| RAISE
--| RELATIVE
--| RETURN
--| RETURN_NEXT
--| RETURN_QUERY
--| RETURNED_SQLSTATE
--| REVERSE
--| ROLLBACK
--| ROW_COUNT
--| ROWTYPE
--| SCHEMA
--| SCHEMA_NAME
--| SCROLL
--| SLICE
--| SQLSTATE
--| STACKED
--| TABLE
--| TABLE_NAME
--| TYPE
--| UPSERT
--| USE_COLUMN
--| USE_VARIABLE
--| VARIABLE_CONFLICT
--| WARNING
--
--reserved_keyword:
--  ALL
--| BEGIN
--| BY
--| CASE
--| DECLARE
--| ELSE
--| END
--| END_CASE
--| END_IF
--| EXECUTE
--| FOR
--| FOREACH
--| FROM
--| IF
--| IN
--| INTO
--| LOOP
--| NOT
--| NULL
--| OR
--| STRICT
--| THEN
--| TO
--| USING
--| WHEN
--| WHILE
--
--%%
-diff --git a/pkg/sql/scanner/plpgsql_scan.go b/pkg/sql/scanner/plpgsql_scan.go
-deleted file mode 100644
-index 3dc5500..0000000
---- a/pkg/sql/scanner/plpgsql_scan.go
-+++ /dev/null
-@@ -1,246 +0,0 @@
--// Copyright 2023 The Cockroach Authors.
--//
--// Use of this software is governed by the Business Source License
--// included in the file licenses/BSL.txt.
--//
--// As of the Change Date specified in that file, in accordance with
--// the Business Source License, use of this software will be governed
--// by the Apache License, Version 2.0, included in the file
--// licenses/APL.txt.
--
--package scanner
--
--import (
--	"fmt"
--	"go/constant"
--	"go/token"
--
--	sqllex "github.com/cockroachdb/cockroachdb-parser/pkg/sql/lexbase"
--	"github.com/cockroachdb/cockroachdb-parser/pkg/sql/plpgsql/parser/lexbase"
--)
--
--// PLpgSQLScanner is a scanner with a PLPGSQL specific scan function
--type PLpgSQLScanner struct {
--	Scanner
--}
--
--// Scan scans the next token and populates its information into lval.
--// This scan function contains rules for plpgsql.
--func (s *PLpgSQLScanner) Scan(lval ScanSymType) {
--	ch, skipWhiteSpace := s.scanSetup(lval)
--
--	if skipWhiteSpace {
--		return
--	}
--
--	switch ch {
--	case '$':
--		if s.scanDollarQuotedString(lval) {
--			lval.SetID(lexbase.SCONST)
--			return
--		}
--		return
--
--	case identQuote:
--		// "[^"]"
--		if s.scanString(lval, identQuote, false /* allowEscapes */, true /* requireUTF8 */) {
--			lval.SetID(lexbase.IDENT)
--		}
--		return
--
--	case singleQuote:
--		// '[^']'
--		if s.scanString(lval, ch, false /* allowEscapes */, true /* requireUTF8 */) {
--			lval.SetID(lexbase.SCONST)
--		}
--		return
--
--	case 'b':
--		// Bytes?
--		if s.peek() == singleQuote {
--			// b'[^']'
--			s.pos++
--			if s.scanString(lval, singleQuote, true /* allowEscapes */, false /* requireUTF8 */) {
--				lval.SetID(lexbase.BCONST)
--			}
--			return
--		}
--		s.scanIdent(lval)
--		return
--
--	case '.':
--		switch t := s.peek(); {
--		case t == '.': // ..
--			s.pos++
--			lval.SetID(lexbase.DOT_DOT)
--			return
--		case sqllex.IsDigit(t):
--			s.scanNumber(lval, ch)
--			return
--		}
--		return
--
--	case '!':
--		switch s.peek() {
--		case '=': // !=
--			s.pos++
--			lval.SetID(lexbase.NOT_EQUALS)
--			return
--		}
--		return
--
--	case '<':
--		switch s.peek() {
--		case '<': // <<
--			s.pos++
--			lval.SetID(lexbase.LESS_LESS)
--			return
--		case '=': // <=
--			s.pos++
--			lval.SetID(lexbase.LESS_EQUALS)
--			return
--		}
--		return
--
--	case '>':
--		switch s.peek() {
--		case '>': // >>
--			s.pos++
--			lval.SetID(lexbase.GREATER_GREATER)
--			return
--		case '=': // >=
--			s.pos++
--			lval.SetID(lexbase.GREATER_EQUALS)
--			return
--		}
--		return
--
--	case ':':
--		switch s.peek() {
--		case ':':
--			s.pos++
--			lval.SetID(lexbase.TYPECAST)
--			return
--		case '=':
--			s.pos++
--			lval.SetID(lexbase.COLON_EQUALS)
--			return
--		}
--		return
--
--	default:
--		if sqllex.IsDigit(ch) {
--			s.scanNumber(lval, ch)
--			return
--		}
--		if sqllex.IsIdentStart(ch) {
--			s.scanIdent(lval)
--			return
--		}
--	}
--	// Everything else is a single character token which we already initialized
--	// lval for above.
--}
--
--func (s *PLpgSQLScanner) scanNumber(lval ScanSymType, ch int) {
--	start := s.pos - 1
--	isHex := false
--	hasDecimal := ch == '.'
--	hasExponent := false
--
--	for {
--		ch := s.peek()
--		if (isHex && sqllex.IsHexDigit(ch)) || sqllex.IsDigit(ch) {
--			s.pos++
--			continue
--		}
--		if ch == 'x' || ch == 'X' {
--			if isHex || s.in[start] != '0' || s.pos != start+1 {
--				lval.SetID(lexbase.ERROR)
--				lval.SetStr(errInvalidHexNumeric)
--				return
--			}
--			s.pos++
--			isHex = true
--			continue
--		}
--		if isHex {
--			break
--		}
--		if ch == '.' {
--			if hasDecimal || hasExponent {
--				break
--			}
--			s.pos++
--			if s.peek() == '.' {
--				// Found ".." while scanning a number: back up to the end of the
--				// integer.
--				s.pos--
--				break
--			}
--			hasDecimal = true
--			continue
--		}
--		if ch == 'e' || ch == 'E' {
--			if hasExponent {
--				break
--			}
--			hasExponent = true
--			s.pos++
--			ch = s.peek()
--			if ch == '-' || ch == '+' {
--				s.pos++
--			}
--			ch = s.peek()
--			if !sqllex.IsDigit(ch) {
--				lval.SetID(lexbase.ERROR)
--				lval.SetStr("invalid floating point literal")
--				return
--			}
--			continue
--		}
--		break
--	}
--
--	lval.SetStr(s.in[start:s.pos])
--	if hasDecimal || hasExponent {
--		lval.SetID(lexbase.FCONST)
--		floatConst := constant.MakeFromLiteral(lval.Str(), token.FLOAT, 0)
--		if floatConst.Kind() == constant.Unknown {
--			lval.SetID(lexbase.ERROR)
--			lval.SetStr(fmt.Sprintf("could not make constant float from literal %q", lval.Str()))
--			return
--		}
--		lval.SetUnionVal(NewNumValFn(floatConst, lval.Str(), false /* negative */))
--	} else {
--		if isHex && s.pos == start+2 {
--			lval.SetID(lexbase.ERROR)
--			lval.SetStr(errInvalidHexNumeric)
--			return
--		}
--
--		// Strip off leading zeros from non-hex (decimal) literals so that
--		// constant.MakeFromLiteral doesn't inappropriately interpret the
--		// string as an octal literal. Note: we can't use strings.TrimLeft
--		// here, because it will truncate '0' to ''.
--		if !isHex {
--			for len(lval.Str()) > 1 && lval.Str()[0] == '0' {
--				lval.SetStr(lval.Str()[1:])
--			}
--		}
--
--		lval.SetID(lexbase.ICONST)
--		intConst := constant.MakeFromLiteral(lval.Str(), token.INT, 0)
--		if intConst.Kind() == constant.Unknown {
--			lval.SetID(lexbase.ERROR)
--			lval.SetStr(fmt.Sprintf("could not make constant int from literal %q", lval.Str()))
--			return
--		}
--		lval.SetUnionVal(NewNumValFn(intConst, lval.Str(), false /* negative */))
--	}
--}
--
--func (s *PLpgSQLScanner) scanIdent(lval ScanSymType) {
--	s.lowerCaseAndNormalizeIdent(lval)
--	lval.SetID(lexbase.GetKeywordID(lval.Str()))
--}
--- 
-2.38.1
-
diff --git a/patches/0005-enc-first-free-flag.patch b/patches/0005-enc-first-free-flag.patch
new file mode 100644
index 0000000..877c149
--- /dev/null
+++ b/patches/0005-enc-first-free-flag.patch
@@ -0,0 +1,23 @@
+diff --git a/pkg/sql/lexbase/encode.go b/pkg/sql/lexbase/encode.go
+index 47b9a37..4f7bc03 100644
+--- a/pkg/sql/lexbase/encode.go
++++ b/pkg/sql/lexbase/encode.go
+@@ -46,14 +46,14 @@ const (
+ 	// without wrapping quotes.
+ 	EncBareReservedKeywords
+ 
+-	// EncFirstFreeFlagBit needs to remain unused; it is used as base
+-	// bit offset for tree.FmtFlags.
+-	EncFirstFreeFlagBit
+-
+ 	// EncAlwaysQuoted makes sure the string is always wrapped with quotes.
+ 	// This is used only to construct a statement against Oracle source,
+ 	// as Oracle is case insensitive if object name is not quoted.
+ 	EncAlwaysQuoted
++
++	// EncFirstFreeFlagBit needs to remain unused; it is used as base
++	// bit offset for tree.FmtFlags.
++	EncFirstFreeFlagBit
+ )
+ 
+ // EncodeRestrictedSQLIdent writes the identifier in s to buf. The
diff --git a/patches/0006-remove-gosigar.patch b/patches/0006-remove-gosigar.patch
new file mode 100644
index 0000000..10f3ad7
--- /dev/null
+++ b/patches/0006-remove-gosigar.patch
@@ -0,0 +1,47 @@
+diff --git a/pkg/util/debugutil/debugutil.go b/pkg/util/debugutil/debugutil.go
+index 4aedcb9..446868c 100644
+--- a/pkg/util/debugutil/debugutil.go
++++ b/pkg/util/debugutil/debugutil.go
+@@ -6,12 +6,8 @@
+ package debugutil
+ 
+ import (
+-	"os"
+-	"path/filepath"
+ 	"runtime/debug"
+ 	"sync/atomic"
+-
+-	"github.com/elastic/gosigar"
+ )
+ 
+ // IsLaunchedByDebugger returns true in cases where the delve debugger
+@@ -22,29 +18,6 @@ func IsLaunchedByDebugger() bool {
+ 
+ var isLaunchedByDebugger atomic.Bool
+ 
+-func init() {
+-	isLaunchedByDebugger.Store(func(maybeDelvePID int) bool {
+-		// We loop in case there were intermediary processes like the gopls
+-		// language server.
+-		for maybeDelvePID != 0 {
+-			var exe gosigar.ProcExe
+-			if err := exe.Get(maybeDelvePID); err != nil {
+-				break
+-			}
+-			switch filepath.Base(exe.Name) {
+-			case "dlv":
+-				return true
+-			}
+-			var state gosigar.ProcState
+-			if err := state.Get(maybeDelvePID); err != nil {
+-				break
+-			}
+-			maybeDelvePID = state.Ppid
+-		}
+-		return false
+-	}(os.Getppid()))
+-}
+-
+ // SafeStack is an alias for []byte that handles redaction. Use this type
+ // instead of []byte when you are sure that the stack trace does not contain
+ // sensitive information.
diff --git a/patches/0007-update-functions-parser.patch b/patches/0007-update-functions-parser.patch
new file mode 100644
index 0000000..b31a67e
--- /dev/null
+++ b/patches/0007-update-functions-parser.patch
@@ -0,0 +1,218 @@
+diff --git a/pkg/sql/lexbase/encode.go b/pkg/sql/lexbase/encode.go
+index 4f7bc03..5b31fd0 100644
+--- a/pkg/sql/lexbase/encode.go
++++ b/pkg/sql/lexbase/encode.go
+@@ -51,6 +51,13 @@ const (
+ 	// as Oracle is case insensitive if object name is not quoted.
+ 	EncAlwaysQuoted
+ 
++	// EncSkipEscapeString indicates that the string should not be escaped,
++	// and non-ASCII characters are allowed.
++	// More specifically, it means that the tree.DString won't be wrapped
++	// with e'text' as the prefix and suffix, and single quotes within
++	// the string will not be escaped with a backslash.
++	EncSkipEscapeString
++
+ 	// EncFirstFreeFlagBit needs to remain unused; it is used as base
+ 	// bit offset for tree.FmtFlags.
+ 	EncFirstFreeFlagBit
+@@ -147,6 +154,7 @@ func EscapeSQLString(in string) string {
+ func EncodeSQLStringWithFlags(buf *bytes.Buffer, in string, flags EncodeFlags) {
+ 	// See http://www.postgresql.org/docs/9.4/static/sql-syntax-lexical.html
+ 	start := 0
++	skipEscape := flags.HasFlags(EncSkipEscapeString)
+ 	escapedString := false
+ 	bareStrings := flags.HasFlags(EncBareStrings)
+ 	// Loop through each unicode code point.
+@@ -165,7 +173,13 @@ func EncodeSQLStringWithFlags(buf *bytes.Buffer, in string, flags EncodeFlags) {
+ 			}
+ 		}
+ 
+-		if !escapedString {
++		// If non-ASCII characters are allowed,
++		// skip escaping and write the original UTF-8 character.
++		if r > maxPrintableChar && skipEscape {
++			continue
++		}
++
++		if !skipEscape && !escapedString {
+ 			buf.WriteString("e'") // begin e'xxx' string
+ 			escapedString = true
+ 		}
+@@ -177,17 +191,19 @@ func EncodeSQLStringWithFlags(buf *bytes.Buffer, in string, flags EncodeFlags) {
+ 		} else {
+ 			start = i + ln
+ 		}
+-		stringencoding.EncodeEscapedChar(buf, in, r, ch, i, '\'')
++		// If we skip escaping, we don't write the slash char before the
++		// quote char, so we will  write the quote char directly.
++		stringencoding.EncodeEscapedChar(buf, in, r, ch, i, '\'', !skipEscape)
+ 	}
+ 
+-	quote := !escapedString && !bareStrings
++	quote := !escapedString && !bareStrings && !skipEscape
+ 	if quote {
+ 		buf.WriteByte('\'') // begin 'xxx' string if nothing was escaped
+ 	}
+ 	if start < len(in) {
+ 		buf.WriteString(in[start:])
+ 	}
+-	if escapedString || quote {
++	if !skipEscape && (escapedString || quote) {
+ 		buf.WriteByte('\'')
+ 	}
+ }
+diff --git a/pkg/sql/sem/tree/expr.go b/pkg/sql/sem/tree/expr.go
+index 05d64e1..dabff21 100644
+--- a/pkg/sql/sem/tree/expr.go
++++ b/pkg/sql/sem/tree/expr.go
+@@ -1364,6 +1364,19 @@ const (
+ 	OrderedSetAgg
+ )
+ 
++// onlyNameFunc is the list of function who can be compiled with only the
++// name. This is for PG compatibility, where examples such as `CURRENT_TIMESTAMP()`
++// is not allowed, but `CURRENT_TIMESTAMP` is allowed.
++var onlyNameFunc = map[string]bool{
++	"current_timestamp": true,
++}
++
++func isOnlyNameFunc(f *FuncExpr) bool {
++	funcStr := f.Func.String()
++	_, ok := onlyNameFunc[funcStr]
++	return ok
++}
++
+ // Format implements the NodeFormatter interface.
+ func (node *FuncExpr) Format(ctx *FmtCtx) {
+ 	var typ string
+@@ -1385,41 +1398,43 @@ func (node *FuncExpr) Format(ctx *FmtCtx) {
+ 		ctx.FormatNode(&node.Func)
+ 	})
+ 
+-	ctx.WriteByte('(')
+-	ctx.WriteString(typ)
+-	ctx.FormatNode(&node.Exprs)
+-	if node.AggType == GeneralAgg && len(node.OrderBy) > 0 {
+-		ctx.WriteByte(' ')
+-		ctx.FormatNode(&node.OrderBy)
+-	}
+-	ctx.WriteByte(')')
+-	if ctx.HasFlags(FmtParsable) && node.typ != nil {
+-		if node.fnProps.AmbiguousReturnType {
+-			// There's no type annotation available for tuples.
+-			// TODO(jordan,knz): clean this up. AmbiguousReturnType should be set only
+-			// when we should and can put an annotation here. #28579
+-			if node.typ.Family() != types.TupleFamily {
+-				ctx.WriteString(":::")
+-				ctx.Buffer.WriteString(node.typ.SQLString())
++	if !(ctx.HasFlags(FmtFuncOnlyName) && isOnlyNameFunc(node)) {
++		ctx.WriteByte('(')
++		ctx.WriteString(typ)
++		ctx.FormatNode(&node.Exprs)
++		if node.AggType == GeneralAgg && len(node.OrderBy) > 0 {
++			ctx.WriteByte(' ')
++			ctx.FormatNode(&node.OrderBy)
++		}
++		ctx.WriteByte(')')
++		if ctx.HasFlags(FmtParsable) && node.typ != nil {
++			if node.fnProps.AmbiguousReturnType {
++				// There's no type annotation available for tuples.
++				// TODO(jordan,knz): clean this up. AmbiguousReturnType should be set only
++				// when we should and can put an annotation here. #28579
++				if node.typ.Family() != types.TupleFamily {
++					ctx.WriteString(":::")
++					ctx.Buffer.WriteString(node.typ.SQLString())
++				}
+ 			}
+ 		}
+-	}
+-	if node.AggType == OrderedSetAgg && len(node.OrderBy) > 0 {
+-		ctx.WriteString(" WITHIN GROUP (")
+-		ctx.FormatNode(&node.OrderBy)
+-		ctx.WriteString(")")
+-	}
+-	if node.Filter != nil {
+-		ctx.WriteString(" FILTER (WHERE ")
+-		ctx.FormatNode(node.Filter)
+-		ctx.WriteString(")")
+-	}
+-	if window := node.WindowDef; window != nil {
+-		ctx.WriteString(" OVER ")
+-		if window.Name != "" {
+-			ctx.FormatNode(&window.Name)
+-		} else {
+-			ctx.FormatNode(window)
++		if node.AggType == OrderedSetAgg && len(node.OrderBy) > 0 {
++			ctx.WriteString(" WITHIN GROUP (")
++			ctx.FormatNode(&node.OrderBy)
++			ctx.WriteString(")")
++		}
++		if node.Filter != nil {
++			ctx.WriteString(" FILTER (WHERE ")
++			ctx.FormatNode(node.Filter)
++			ctx.WriteString(")")
++		}
++		if window := node.WindowDef; window != nil {
++			ctx.WriteString(" OVER ")
++			if window.Name != "" {
++				ctx.FormatNode(&window.Name)
++			} else {
++				ctx.FormatNode(window)
++			}
+ 		}
+ 	}
+ }
+diff --git a/pkg/sql/sem/tree/format.go b/pkg/sql/sem/tree/format.go
+index 6832c7e..df15c15 100644
+--- a/pkg/sql/sem/tree/format.go
++++ b/pkg/sql/sem/tree/format.go
+@@ -195,6 +195,10 @@ const (
+ 	// FmtSkipAsOfSystemTimeClauses prevents the formatter from printing AS OF
+ 	// SYSTEM TIME clauses.
+ 	FmtSkipAsOfSystemTimeClauses
++
++	// FmtFuncOnlyName instructs the formating for a function only print
++	// its name, without printing the body of the function nor with the brackets.
++	FmtFuncOnlyName
+ )
+ 
+ const genericArityIndicator = "__more__"
+diff --git a/pkg/util/stringencoding/string_encoding.go b/pkg/util/stringencoding/string_encoding.go
+index fcb7fac..afa0090 100644
+--- a/pkg/util/stringencoding/string_encoding.go
++++ b/pkg/util/stringencoding/string_encoding.go
+@@ -73,6 +73,7 @@ func init() {
+ 
+ // EncodeEscapedChar is used internally to write out a character from a larger
+ // string that needs to be escaped to a buffer.
++// If slashedQuoteChar is true, it will write a backslash before the quoteChar.
+ func EncodeEscapedChar(
+ 	buf *bytes.Buffer,
+ 	entireString string,
+@@ -80,6 +81,7 @@ func EncodeEscapedChar(
+ 	currentByte byte,
+ 	currentIdx int,
+ 	quoteChar byte,
++	slashedQuoteChar bool,
+ ) {
+ 	ln := utf8.RuneLen(currentRune)
+ 	if currentRune == utf8.RuneError {
+@@ -94,10 +96,15 @@ func EncodeEscapedChar(
+ 	} else if ln == 1 {
+ 		// For single-byte runes, do the same as encodeSQLBytes.
+ 		if encodedChar := EncodeMap[currentByte]; encodedChar != DontEscape {
+-			buf.WriteByte('\\')
++			if slashedQuoteChar {
++				buf.WriteByte('\\')
++			}
++
+ 			buf.WriteByte(encodedChar)
+ 		} else if currentByte == quoteChar {
+-			buf.WriteByte('\\')
++			if slashedQuoteChar {
++				buf.WriteByte('\\')
++			}
+ 			buf.WriteByte(quoteChar)
+ 		} else {
+ 			// Escape non-printable characters.
diff --git a/pkg/build/bazel/bazel.go b/pkg/build/bazel/bazel.go
index 2504468..5988dc0 100644
--- a/pkg/build/bazel/bazel.go
+++ b/pkg/build/bazel/bazel.go
@@ -1,15 +1,9 @@
 // Copyright 2015 The Cockroach Authors.
 //
-// Use of this software is governed by the Business Source License
-// included in the file licenses/BSL.txt.
-//
-// As of the Change Date specified in that file, in accordance with
-// the Business Source License, use of this software will be governed
-// by the Apache License, Version 2.0, included in the file
-// licenses/APL.txt.
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
 
 //go:build bazel
-// +build bazel
 
 package bazel
 
diff --git a/pkg/build/bazel/non_bazel.go b/pkg/build/bazel/non_bazel.go
index 17833fb..91ac847 100644
--- a/pkg/build/bazel/non_bazel.go
+++ b/pkg/build/bazel/non_bazel.go
@@ -1,15 +1,9 @@
 // Copyright 2015 The Cockroach Authors.
 //
-// Use of this software is governed by the Business Source License
-// included in the file licenses/BSL.txt.
-//
-// As of the Change Date specified in that file, in accordance with
-// the Business Source License, use of this software will be governed
-// by the Apache License, Version 2.0, included in the file
-// licenses/APL.txt.
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
 
 //go:build !bazel
-// +build !bazel
 
 package bazel
 
diff --git a/pkg/build/bazel/util/tinystringer/main.go b/pkg/build/bazel/util/tinystringer/main.go
index b0b260a..ec63f54 100644
--- a/pkg/build/bazel/util/tinystringer/main.go
+++ b/pkg/build/bazel/util/tinystringer/main.go
@@ -1,16 +1,12 @@
 // Copyright 2023 The Cockroach Authors.
 //
-// Use of this software is governed by the Business Source License
-// included in the file licenses/BSL.txt.
-//
-// As of the Change Date specified in that file, in accordance with
-// the Business Source License, use of this software will be governed
-// by the Apache License, Version 2.0, included in the file
-// licenses/APL.txt.
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
 
 package main
 
 import (
+	"cmp"
 	"errors"
 	"flag"
 	"fmt"
@@ -19,7 +15,7 @@ import (
 	"go/token"
 	"os"
 	"path/filepath"
-	"sort"
+	"slices"
 	"strconv"
 	"strings"
 )
@@ -126,7 +122,12 @@ func (s tinyStringer) stringify() error {
 	defer func() {
 		_ = outputFile.Close()
 	}()
-	fmt.Fprintf(outputFile, `// Code generated by "stringer"; DO NOT EDIT.
+	fmt.Fprintf(outputFile, `// Copyright 2023 The Cockroach Authors.
+//
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
+
+// Code generated by "stringer"; DO NOT EDIT.
 
 package %s
 
@@ -221,8 +222,8 @@ var %s = []%s{
 				seen[nameToInt[constName]] = struct{}{}
 			}
 		}
-		sort.Slice(inLexicographicOrder, func(i, j int) bool {
-			return nameToPrinted[inLexicographicOrder[i]] < nameToPrinted[inLexicographicOrder[j]]
+		slices.SortFunc(inLexicographicOrder, func(a, b string) int {
+			return cmp.Compare(nameToPrinted[a], nameToPrinted[b])
 		})
 		seen = make(map[int]struct{})
 		for _, constName := range inLexicographicOrder {
diff --git a/pkg/build/cgo_compiler.go b/pkg/build/cgo_compiler.go
index 09bc565..2411e36 100644
--- a/pkg/build/cgo_compiler.go
+++ b/pkg/build/cgo_compiler.go
@@ -1,12 +1,7 @@
 // Copyright 2015 The Cockroach Authors.
 //
-// Use of this software is governed by the Business Source License
-// included in the file licenses/BSL.txt.
-//
-// As of the Change Date specified in that file, in accordance with
-// the Business Source License, use of this software will be governed
-// by the Apache License, Version 2.0, included in the file
-// licenses/APL.txt.
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
 
 package build
 
diff --git a/pkg/build/cgo_compiler_nocgo.go b/pkg/build/cgo_compiler_nocgo.go
index a11bb78..2fe9f92 100644
--- a/pkg/build/cgo_compiler_nocgo.go
+++ b/pkg/build/cgo_compiler_nocgo.go
@@ -1,15 +1,9 @@
 // Copyright 2018 The Cockroach Authors.
 //
-// Use of this software is governed by the Business Source License
-// included in the file licenses/BSL.txt.
-//
-// As of the Change Date specified in that file, in accordance with
-// the Business Source License, use of this software will be governed
-// by the Apache License, Version 2.0, included in the file
-// licenses/APL.txt.
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
 
 //go:build !cgo
-// +build !cgo
 
 package build
 
diff --git a/pkg/build/info.go b/pkg/build/info.go
index b1e7c5c..ec7ede1 100644
--- a/pkg/build/info.go
+++ b/pkg/build/info.go
@@ -1,12 +1,7 @@
 // Copyright 2015 The Cockroach Authors.
 //
-// Use of this software is governed by the Business Source License
-// included in the file licenses/BSL.txt.
-//
-// As of the Change Date specified in that file, in accordance with
-// the Business Source License, use of this software will be governed
-// by the Apache License, Version 2.0, included in the file
-// licenses/APL.txt.
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
 
 package build
 
@@ -21,31 +16,42 @@ import (
 
 	"github.com/cockroachdb/cockroachdb-parser/pkg/util/buildutil"
 	"github.com/cockroachdb/cockroachdb-parser/pkg/util/envutil"
-	"github.com/cockroachdb/cockroachdb-parser/pkg/util/version"
+	"github.com/cockroachdb/redact"
+	"github.com/cockroachdb/version"
 )
 
 // TimeFormat is the reference format for build.Time. Make sure it stays in sync
 // with the string passed to the linker in the root Makefile.
 const TimeFormat = "2006/01/02 15:04:05"
 
+// These variables are initialized by Bazel via the linker -X flag
+// when compiling release binaries.
 var (
-	// These variables are initialized by Bazel via the linker -X flag
-	// when compiling release binaries.
 	utcTime          string // Build time in UTC (year/month/day hour:min:sec)
 	rev              string // SHA-1 of this build (git rev-parse)
 	buildTagOverride string
-	cgoCompiler      = cgoVersion()
 	cgoTargetTriple  string
-	platform         = fmt.Sprintf("%s %s", runtime.GOOS, runtime.GOARCH)
-	// Distribution is changed by the CCL init-time hook in non-APL builds.
-	Distribution      = "OSS"
-	typ               string // Type of this build: <empty>, "development", or "release"
-	channel           string
+	typ              string // Type of this build: <empty>, "development", or "release"
+	channel          string
+)
+
+// Distribution is changed by the CCL init-time hook in non-APL builds.
+var Distribution = "OSS"
+
+var (
+	cgoCompiler       = cgoVersion()
+	platform          = fmt.Sprintf("%s %s", runtime.GOOS, runtime.GOARCH)
 	envChannel        = envutil.EnvOrDefaultString("COCKROACH_CHANNEL", "unknown")
 	enabledAssertions = buildutil.CrdbTestBuild
+)
+
+var (
 	//go:embed version.txt
-	cockroachVersion string
-	binaryVersion    = computeBinaryVersion(cockroachVersion, rev)
+	versionTxt       string
+	parsedVersionTxt *version.Version = parseCockroachVersion(versionTxt)
+	binaryVersion    string           = computeBinaryVersion(buildTagOverride, parsedVersionTxt, rev)
+	// binaryVersionTestingOverride is modified by TestingOverrideVersion.
+	binaryVersionTestingOverride string
 )
 
 const (
@@ -64,36 +70,63 @@ func SeemsOfficial() bool {
 	return channel == DefaultTelemetryChannel || channel == FIPSTelemetryChannel
 }
 
-func computeBinaryVersion(versionTxt, revision string) string {
-	if buildTagOverride != "" {
-		return buildTagOverride
-	}
+func parseCockroachVersion(versionTxt string) *version.Version {
 	txt := strings.TrimSuffix(versionTxt, "\n")
 	v, err := version.Parse(txt)
 	if err != nil {
 		panic(fmt.Errorf("could not parse version.txt: %w", err))
 	}
+	return &v
+}
+
+func computeBinaryVersion(
+	buildTagOverride string, parsedVersionTxt *version.Version, revision string,
+) string {
+	if buildTagOverride != "" {
+		return buildTagOverride
+	}
 	if IsRelease() {
-		return v.String()
+		return parsedVersionTxt.String()
 	}
 	if revision != "" {
-		return fmt.Sprintf("%s-dev-%s", v.String(), revision)
+		return fmt.Sprintf("%s-dev-%s", parsedVersionTxt.String(), revision)
 	}
-	return fmt.Sprintf("%s-dev", v.String())
+	return fmt.Sprintf("%s-dev", parsedVersionTxt.String())
 }
 
-// BinaryVersion returns the version prefix, patch number and metadata of the current build.
+// BinaryVersion returns the version prefix, patch number and metadata of the
+// current build.
 func BinaryVersion() string {
+	if binaryVersionTestingOverride != "" {
+		return binaryVersionTestingOverride
+	}
 	return binaryVersion
 }
 
-// BinaryVersionPrefix returns the version prefix of the current build.
-func BinaryVersionPrefix() string {
-	v, err := version.Parse(binaryVersion)
-	if err != nil {
+// VersionForURLs is used to determine the version to use in public-facing doc URLs.
+// It returns "vX.Y" for all release versions, and all prerelease versions >= "alpha.1".
+// X and Y are the major and minor, respectively, of the version specified in version.txt.
+// For all other prerelease versions, it returns "dev".
+// N.B. new public-facing doc URLs are expected to be up beginning with the "alpha.1" prerelease. Otherwise, "dev" will
+// cause the url mapper to redirect to the latest stable release.
+func VersionForURLs() string {
+	if parsedVersionTxt.IsPrerelease() {
+		phaseAndOrdinal := parsedVersionTxt.Format("%P.%o")
+		// builds prior to "alpha.1" use 'dev' in their URLs
+		if phaseAndOrdinal < "alpha.1" {
+			return "dev"
+		}
+	} else if parsedVersionTxt.IsCustomOrNightlyBuild() {
 		return "dev"
 	}
-	return fmt.Sprintf("v%d.%d", v.Major(), v.Minor())
+	return parsedVersionTxt.Major().String()
+}
+
+// BranchReleaseSeries returns tha major and minor in version.txt, without
+// allowing for any overrides.
+func BranchReleaseSeries() (year, ordinal int) {
+	major := parsedVersionTxt.Major()
+	return major.Year, major.Ordinal
 }
 
 func init() {
@@ -105,13 +138,18 @@ func init() {
 }
 
 // Short returns a pretty printed build and version summary.
-func (b Info) Short() string {
+func (b Info) Short() redact.RedactableString {
 	plat := b.Platform
 	if b.CgoTargetTriple != "" {
 		plat = b.CgoTargetTriple
 	}
-	return fmt.Sprintf("CockroachDB %s %s (%s, built %s, %s)",
-		b.Distribution, b.Tag, plat, b.Time, b.GoVersion)
+	return redact.Sprintf("CockroachDB %s %s (%s, built %s, %s)",
+		redact.SafeString(b.Distribution),
+		redact.SafeString(b.Tag),
+		redact.SafeString(plat),
+		redact.SafeString(b.Time),
+		redact.SafeString(b.GoVersion),
+	)
 }
 
 // Long returns a pretty printed build summary
@@ -161,7 +199,7 @@ func GetInfo() Info {
 	}
 	return Info{
 		GoVersion:         runtime.Version(),
-		Tag:               binaryVersion,
+		Tag:               BinaryVersion(),
 		Time:              utcTime,
 		Revision:          rev,
 		CgoCompiler:       cgoCompiler,
@@ -178,12 +216,17 @@ func GetInfo() Info {
 // TestingOverrideVersion allows tests to override the binary version
 // reported by cockroach.
 func TestingOverrideVersion(v string) func() {
-	prevBinaryVersion := binaryVersion
-	binaryVersion = v
-	return func() { binaryVersion = prevBinaryVersion }
+	prevOverride := binaryVersionTestingOverride
+	binaryVersionTestingOverride = v
+	return func() { binaryVersionTestingOverride = prevOverride }
 }
 
 // MakeIssueURL produces a URL to a CockroachDB issue.
 func MakeIssueURL(issue int) string {
-	return fmt.Sprintf("https://go.crdb.dev/issue-v/%d/%s", issue, BinaryVersionPrefix())
+	return fmt.Sprintf("https://go.crdb.dev/issue-v/%d/%s", issue, VersionForURLs())
+}
+
+// ParsedVersion returns the parsed version.txt.
+func ParsedVersion() *version.Version {
+	return parsedVersionTxt
 }
diff --git a/pkg/build/info.pb.go b/pkg/build/info.pb.go
index fe5e53d..79a0de2 100644
--- a/pkg/build/info.pb.go
+++ b/pkg/build/info.pb.go
@@ -270,7 +270,7 @@ func (m *Info) Size() (n int) {
 }
 
 func sovInfo(x uint64) (n int) {
-	return (math_bits.Len64(x|1) + 6) / 7
+	return int((uint32(math_bits.Len64(x|1)+6) * 37) >> 8)
 }
 func sozInfo(x uint64) (n int) {
 	return sovInfo(uint64((x << 1) ^ uint64((int64(x) >> 63))))
diff --git a/pkg/build/info.proto b/pkg/build/info.proto
index 8e3e18a..8a2e988 100644
--- a/pkg/build/info.proto
+++ b/pkg/build/info.proto
@@ -1,12 +1,7 @@
 // Copyright 2016 The Cockroach Authors.
 //
-// Use of this software is governed by the Business Source License
-// included in the file licenses/BSL.txt.
-//
-// As of the Change Date specified in that file, in accordance with
-// the Business Source License, use of this software will be governed
-// by the Apache License, Version 2.0, included in the file
-// licenses/APL.txt.
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
 
 syntax = "proto2";
 package cockroach.build;
diff --git a/pkg/build/version.txt b/pkg/build/version.txt
index ae39fab..4367f90 100644
--- a/pkg/build/version.txt
+++ b/pkg/build/version.txt
@@ -1 +1 @@
-v0.0.0
+v1.2.3
diff --git a/pkg/cli/exit/codes.go b/pkg/cli/exit/codes.go
index 0fd9368..6734aab 100644
--- a/pkg/cli/exit/codes.go
+++ b/pkg/cli/exit/codes.go
@@ -1,12 +1,7 @@
 // Copyright 2020 The Cockroach Authors.
 //
-// Use of this software is governed by the Business Source License
-// included in the file licenses/BSL.txt.
-//
-// As of the Change Date specified in that file, in accordance with
-// the Business Source License, use of this software will be governed
-// by the Apache License, Version 2.0, included in the file
-// licenses/APL.txt.
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
 
 package exit
 
diff --git a/pkg/cli/exit/doc.go b/pkg/cli/exit/doc.go
index c76a112..b9f072f 100644
--- a/pkg/cli/exit/doc.go
+++ b/pkg/cli/exit/doc.go
@@ -1,12 +1,7 @@
 // Copyright 2020 The Cockroach Authors.
 //
-// Use of this software is governed by the Business Source License
-// included in the file licenses/BSL.txt.
-//
-// As of the Change Date specified in that file, in accordance with
-// the Business Source License, use of this software will be governed
-// by the Apache License, Version 2.0, included in the file
-// licenses/APL.txt.
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
 
 // Package exit encapsulates calls to os.Exit to control the
 // production of process exit status codes.
diff --git a/pkg/cli/exit/exit.go b/pkg/cli/exit/exit.go
index bc2ad11..d2252e9 100644
--- a/pkg/cli/exit/exit.go
+++ b/pkg/cli/exit/exit.go
@@ -1,12 +1,7 @@
 // Copyright 2020 The Cockroach Authors.
 //
-// Use of this software is governed by the Business Source License
-// included in the file licenses/BSL.txt.
-//
-// As of the Change Date specified in that file, in accordance with
-// the Business Source License, use of this software will be governed
-// by the Apache License, Version 2.0, included in the file
-// licenses/APL.txt.
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
 
 package exit
 
diff --git a/pkg/col/coldata/batch.go b/pkg/col/coldata/batch.go
index 03e0b4a..9ad01cc 100644
--- a/pkg/col/coldata/batch.go
+++ b/pkg/col/coldata/batch.go
@@ -1,12 +1,7 @@
 // Copyright 2018 The Cockroach Authors.
 //
-// Use of this software is governed by the Business Source License
-// included in the file licenses/BSL.txt.
-//
-// As of the Change Date specified in that file, in accordance with
-// the Business Source License, use of this software will be governed
-// by the Apache License, Version 2.0, included in the file
-// licenses/APL.txt.
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
 
 package coldata
 
@@ -16,8 +11,9 @@ import (
 	"strings"
 	"sync/atomic"
 
+	"github.com/cockroachdb/cockroachdb-parser/pkg/col/typeconv"
 	"github.com/cockroachdb/cockroachdb-parser/pkg/sql/types"
-	"github.com/cockroachdb/cockroachdb-parser/pkg/util"
+	"github.com/cockroachdb/cockroachdb-parser/pkg/util/metamorphic"
 	"github.com/cockroachdb/errors"
 )
 
@@ -40,23 +36,24 @@ type Batch interface {
 	// Width returns the number of columns in the batch.
 	Width() int
 	// ColVec returns the ith Vec in this batch.
-	ColVec(i int) Vec
+	ColVec(i int) *Vec
 	// ColVecs returns all of the underlying Vecs in this batch.
-	ColVecs() []Vec
-	// Selection, if not nil, returns the selection vector on this batch: a
+	ColVecs() []*Vec
+	// Selection - if not nil - returns the selection vector on this batch: a
 	// densely-packed list of the *increasing* indices in each column that have
 	// not been filtered out by a previous step.
 	// TODO(yuzefovich): consider ensuring that the length of the returned slice
 	// equals the length of the batch.
+	// TODO(yuzefovich): consider using []int16 to reduce memory footprint.
 	Selection() []int
 	// SetSelection sets whether this batch is using its selection vector or not.
 	SetSelection(bool)
 	// AppendCol appends the given Vec to this batch.
-	AppendCol(Vec)
+	AppendCol(*Vec)
 	// ReplaceCol replaces the current Vec at the provided index with the
 	// provided Vec. The original and the replacement vectors *must* be of the
 	// same type.
-	ReplaceCol(Vec, int)
+	ReplaceCol(*Vec, int)
 	// Reset modifies the caller in-place to have the given length and columns
 	// with the given types. If it's possible, Reset will reuse the existing
 	// columns and allocations, invalidating existing references to the Batch or
@@ -86,7 +83,7 @@ const DefaultColdataBatchSize = 1024
 // confirmed to be very good using tpchvec/bench benchmark on TPC-H queries
 // (the best number according to that benchmark was 1280, but it was negligibly
 // better, so we decided to keep 1024 as it is a power of 2).
-var defaultBatchSize = int64(util.ConstantWithMetamorphicTestRange(
+var defaultBatchSize = int64(metamorphic.ConstantWithTestRange(
 	"coldata-batch-size",
 	DefaultColdataBatchSize, /* defaultValue */
 	// min is set to 3 to match colexec's minBatchSize setting.
@@ -120,29 +117,173 @@ func NewMemBatch(typs []*types.T, factory ColumnFactory) Batch {
 	return NewMemBatchWithCapacity(typs, BatchSize(), factory)
 }
 
+const (
+	boolAllocIdx int = iota
+	bytesAllocIdx
+	int16AllocIdx
+	int32AllocIdx
+	int64AllocIdx
+	float64AllocIdx
+	decimalAllocIdx
+	timeAllocIdx
+	intervalAllocIdx
+	jsonAllocIdx
+	datumAllocIdx
+	numCanonicalTypes
+)
+
+//gcassert:inline
+func toAllocIdx(canonicalTypeFamily types.Family, width int32) int {
+	switch canonicalTypeFamily {
+	case types.BoolFamily:
+		return boolAllocIdx
+	case types.BytesFamily:
+		return bytesAllocIdx
+	case types.IntFamily:
+		switch width {
+		case 16:
+			return int16AllocIdx
+		case 32:
+			return int32AllocIdx
+		case 0, 64:
+			return int64AllocIdx
+		default:
+			return -1
+		}
+	case types.FloatFamily:
+		return float64AllocIdx
+	case types.DecimalFamily:
+		return decimalAllocIdx
+	case types.TimestampTZFamily:
+		return timeAllocIdx
+	case types.IntervalFamily:
+		return intervalAllocIdx
+	case types.JsonFamily:
+		return jsonAllocIdx
+	case typeconv.DatumVecCanonicalTypeFamily:
+		return datumAllocIdx
+	default:
+		// Return negative number which will cause index out of bounds error if
+		// a new natively-supported type is added and this switch is not
+		// updated.
+		return -1
+	}
+}
+
+var (
+	unexpectedAllocIdxErr = errors.New("unexpected allocIdx")
+	datumBackedType       = types.TSQuery
+)
+
+func init() {
+	if typeconv.TypeFamilyToCanonicalTypeFamily(datumBackedType.Family()) != typeconv.DatumVecCanonicalTypeFamily {
+		panic("update datumBackedType to be actually datum-backed")
+	}
+}
+
+//gcassert:inline
+func toCanonicalType(allocIdx int) *types.T {
+	switch allocIdx {
+	case boolAllocIdx:
+		return types.Bool
+	case bytesAllocIdx:
+		return types.Bytes
+	case int16AllocIdx:
+		return types.Int2
+	case int32AllocIdx:
+		return types.Int4
+	case int64AllocIdx:
+		return types.Int
+	case float64AllocIdx:
+		return types.Float
+	case decimalAllocIdx:
+		return types.Decimal
+	case timeAllocIdx:
+		return types.TimestampTZ
+	case intervalAllocIdx:
+		return types.Interval
+	case jsonAllocIdx:
+		return types.Json
+	case datumAllocIdx:
+		return datumBackedType
+	default:
+		panic(unexpectedAllocIdxErr)
+	}
+}
+
 // NewMemBatchWithCapacity allocates a new in-memory Batch with the given
 // column size. Use for operators that have a precisely-sized output batch.
 func NewMemBatchWithCapacity(typs []*types.T, capacity int, factory ColumnFactory) Batch {
 	b := NewMemBatchNoCols(typs, capacity).(*MemBatch)
-	cols := make([]memColumn, len(typs))
+	vecs := make([]Vec, len(typs))
+	// numForCanonicalType will track how many times a particular canonical type
+	// family appears in typs.
+	//
+	//gcassert:noescape
+	var numForCanonicalType [numCanonicalTypes]int
 	for i, t := range typs {
-		col := &cols[i]
-		col.init(t, capacity, factory)
-		b.b[i] = col
+		vecs[i].t = t
+		vecs[i].canonicalTypeFamily = typeconv.TypeFamilyToCanonicalTypeFamily(t.Family())
+		b.b[i] = &vecs[i]
+		allocIdx := toAllocIdx(vecs[i].canonicalTypeFamily, vecs[i].t.Width())
+		numForCanonicalType[allocIdx]++
+	}
+	var maxSame int
+	for _, numColumns := range numForCanonicalType {
+		maxSame = max(maxSame, numColumns)
+	}
+	// First, initialize columns that can be batch-allocated together for the
+	// same canonical type.
+	if maxSame > 1 {
+		scratchColumns := make([]Column, maxSame)
+		for allocIdx, numColumns := range numForCanonicalType {
+			if numColumns > 1 {
+				scratch := scratchColumns[:numColumns]
+				t := toCanonicalType(allocIdx)
+				factory.MakeColumns(scratch, t, capacity)
+				for i := range vecs {
+					if toAllocIdx(vecs[i].canonicalTypeFamily, vecs[i].t.Width()) == allocIdx {
+						vecs[i].col = scratch[0]
+						scratch = scratch[1:]
+					}
+				}
+			}
+		}
+		if numForCanonicalType[datumAllocIdx] > 1 {
+			// We need to set the correct type on each datum-backed vector.
+			for i := range vecs {
+				if vecs[i].canonicalTypeFamily == typeconv.DatumVecCanonicalTypeFamily {
+					vecs[i].Datum().SetType(vecs[i].t)
+				}
+			}
+		}
+	}
+	// Initialize all remaining columns while also initializing all Nulls
+	// bitmaps.
+	nullsCap := nullsStorageCap(capacity)
+	nullsAlloc := make([]byte, len(typs)*nullsCap)
+	for i := range vecs {
+		if vecs[i].col == nil {
+			vecs[i].col = factory.MakeColumn(vecs[i].t, capacity)
+		}
+		vecs[i].nulls = newNulls(nullsAlloc[:nullsCap:nullsCap])
+		nullsAlloc = nullsAlloc[nullsCap:]
 	}
 	return b
 }
 
+var batchCapacityTooLargeErr = errors.New("batches cannot have capacity larger than max uint16")
+
 // NewMemBatchNoCols creates a "skeleton" of new in-memory Batch. It allocates
 // memory for the selection vector but does *not* allocate any memory for the
 // column vectors - those will have to be added separately.
 func NewMemBatchNoCols(typs []*types.T, capacity int) Batch {
-	if max := math.MaxUint16; capacity > max {
-		panic(fmt.Sprintf(`batches cannot have capacity larger than %d; requested %d`, max, capacity))
+	if capacity > math.MaxUint16 {
+		panic(batchCapacityTooLargeErr)
 	}
 	b := &MemBatch{}
 	b.capacity = capacity
-	b.b = make([]Vec, len(typs))
+	b.b = make([]*Vec, len(typs))
 	b.sel = make([]int, capacity)
 	return b
 }
@@ -178,11 +319,11 @@ func (b *zeroBatch) SetSelection(bool) {
 	panic("selection should not be changed on zero batch")
 }
 
-func (b *zeroBatch) AppendCol(Vec) {
+func (b *zeroBatch) AppendCol(*Vec) {
 	panic("no columns should be appended to zero batch")
 }
 
-func (b *zeroBatch) ReplaceCol(Vec, int) {
+func (b *zeroBatch) ReplaceCol(*Vec, int) {
 	panic("no columns should be replaced in zero batch")
 }
 
@@ -198,7 +339,7 @@ type MemBatch struct {
 	// MemBatch.
 	capacity int
 	// b is the slice of columns in this batch.
-	b      []Vec
+	b      []*Vec
 	useSel bool
 	// sel is - if useSel is true - a selection vector from upstream. A
 	// selection vector is a list of selected tuple indices in this memBatch's
@@ -223,12 +364,12 @@ func (m *MemBatch) Width() int {
 }
 
 // ColVec implements the Batch interface.
-func (m *MemBatch) ColVec(i int) Vec {
+func (m *MemBatch) ColVec(i int) *Vec {
 	return m.b[i]
 }
 
 // ColVecs implements the Batch interface.
-func (m *MemBatch) ColVecs() []Vec {
+func (m *MemBatch) ColVecs() []*Vec {
 	return m.b
 }
 
@@ -251,13 +392,13 @@ func (m *MemBatch) SetLength(length int) {
 }
 
 // AppendCol implements the Batch interface.
-func (m *MemBatch) AppendCol(col Vec) {
+func (m *MemBatch) AppendCol(col *Vec) {
 	m.b = append(m.b, col)
 }
 
 // ReplaceCol implements the Batch interface.
-func (m *MemBatch) ReplaceCol(col Vec, colIdx int) {
-	if m.b[colIdx] != nil && !m.b[colIdx].Type().Identical(col.Type()) {
+func (m *MemBatch) ReplaceCol(col *Vec, colIdx int) {
+	if m.b[colIdx] != nil && m.b[colIdx].t != nil && !m.b[colIdx].Type().Identical(col.Type()) {
 		panic(fmt.Sprintf("unexpected replacement: original vector is %s "+
 			"whereas the replacement is %s", m.b[colIdx].Type(), col.Type()))
 	}
@@ -272,7 +413,7 @@ func (m *MemBatch) Reset(typs []*types.T, length int, factory ColumnFactory) {
 		// TODO(yuzefovich): requiring that types are "identical" might be an
 		// overkill - the vectors could have the same physical representation
 		// but non-identical types. Think through this more.
-		if !m.ColVec(i).Type().Identical(typs[i]) {
+		if v := m.ColVec(i); !v.Type().Identical(typs[i]) {
 			cannotReuse = true
 			break
 		}
@@ -324,7 +465,7 @@ func (m *MemBatch) String() string {
 //
 // The implementation lives in colconv package and is injected during the
 // initialization.
-var VecsToStringWithRowPrefix func(vecs []Vec, length int, sel []int, prefix string) []string
+var VecsToStringWithRowPrefix func(vecs []*Vec, length int, sel []int, prefix string) []string
 
 // GetBatchMemSize returns the total memory footprint of the batch.
 //
diff --git a/pkg/col/coldata/bytes.go b/pkg/col/coldata/bytes.go
index 03a5cb3..a67854a 100644
--- a/pkg/col/coldata/bytes.go
+++ b/pkg/col/coldata/bytes.go
@@ -1,12 +1,7 @@
 // Copyright 2019 The Cockroach Authors.
 //
-// Use of this software is governed by the Business Source License
-// included in the file licenses/BSL.txt.
-//
-// As of the Change Date specified in that file, in accordance with
-// the Business Source License, use of this software will be governed
-// by the Apache License, Version 2.0, included in the file
-// licenses/APL.txt.
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
 
 package coldata
 
@@ -276,7 +271,8 @@ func (b *Bytes) copyElements(srcElementsToCopy []element, src *Bytes, destIdx in
 			// append the new value to b.buffer.
 			*e = element{}
 			//gcassert:bce
-			e.setNonInlined(srcElementsToCopy[i].getNonInlined(src), b)
+			srcElement := srcElementsToCopy[i]
+			e.setNonInlined(srcElement.getNonInlined(src), b)
 		}
 	}
 }
@@ -645,7 +641,7 @@ func (b *Bytes) Deserialize(data []byte, offsets []int32) {
 
 // ProportionalSize calls the method of the same name on bytes-like vectors,
 // panicking if not bytes-like.
-func ProportionalSize(v Vec, length int64) int64 {
+func ProportionalSize(v *Vec, length int64) int64 {
 	family := v.CanonicalTypeFamily()
 	switch family {
 	case types.BytesFamily:
@@ -659,7 +655,7 @@ func ProportionalSize(v Vec, length int64) int64 {
 }
 
 // ResetIfBytesLike calls Reset on v if it is bytes-like, noop otherwise.
-func ResetIfBytesLike(v Vec) {
+func ResetIfBytesLike(v *Vec) {
 	switch v.CanonicalTypeFamily() {
 	case types.BytesFamily:
 		v.Bytes().Reset()
diff --git a/pkg/col/coldata/datum_vec.go b/pkg/col/coldata/datum_vec.go
index 6ca9ea5..cc02b8a 100644
--- a/pkg/col/coldata/datum_vec.go
+++ b/pkg/col/coldata/datum_vec.go
@@ -1,12 +1,7 @@
 // Copyright 2020 The Cockroach Authors.
 //
-// Use of this software is governed by the Business Source License
-// included in the file licenses/BSL.txt.
-//
-// As of the Change Date specified in that file, in accordance with
-// the Business Source License, use of this software will be governed
-// by the Apache License, Version 2.0, included in the file
-// licenses/APL.txt.
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
 
 package coldata
 
@@ -57,4 +52,6 @@ type DatumVec interface {
 	Size(startIdx int) int64
 	// SetEvalCtx updates the vector with the provided *eval.Context.
 	SetEvalCtx(evalCtx interface{})
+	// SetType updates the vector with its type.
+	SetType(t interface{})
 }
diff --git a/pkg/col/coldata/json.go b/pkg/col/coldata/json.go
index 54263ff..4cdd855 100644
--- a/pkg/col/coldata/json.go
+++ b/pkg/col/coldata/json.go
@@ -1,12 +1,7 @@
 // Copyright 2021 The Cockroach Authors.
 //
-// Use of this software is governed by the Business Source License
-// included in the file licenses/BSL.txt.
-//
-// As of the Change Date specified in that file, in accordance with
-// the Business Source License, use of this software will be governed
-// by the Apache License, Version 2.0, included in the file
-// licenses/APL.txt.
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
 
 package coldata
 
diff --git a/pkg/col/coldata/native_types.go b/pkg/col/coldata/native_types.go
index 4bac49c..e61bc34 100644
--- a/pkg/col/coldata/native_types.go
+++ b/pkg/col/coldata/native_types.go
@@ -1,12 +1,7 @@
 // Copyright 2020 The Cockroach Authors.
 //
-// Use of this software is governed by the Business Source License
-// included in the file licenses/BSL.txt.
-//
-// As of the Change Date specified in that file, in accordance with
-// the Business Source License, use of this software will be governed
-// by the Apache License, Version 2.0, included in the file
-// licenses/APL.txt.
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
 
 package coldata
 
@@ -215,7 +210,7 @@ func (c Float64s) CopySlice(src Float64s, destIdx, srcStartIdx, srcEndIdx int) {
 // destIdx.
 //
 // Note that this method is usually inlined, but it isn't in case of the
-// memColumn.Copy generated code (probably because of the size of that
+// Vec.Copy generated code (probably because of the size of that
 // function), so we don't assert the inlining with the GCAssert linter.
 func (c Decimals) CopySlice(src Decimals, destIdx, srcStartIdx, srcEndIdx int) {
 	srcSlice := src[srcStartIdx:srcEndIdx]
diff --git a/pkg/col/coldata/nulls.go b/pkg/col/coldata/nulls.go
index 417bd7b..061a1b3 100644
--- a/pkg/col/coldata/nulls.go
+++ b/pkg/col/coldata/nulls.go
@@ -1,12 +1,7 @@
 // Copyright 2018 The Cockroach Authors.
 //
-// Use of this software is governed by the Business Source License
-// included in the file licenses/BSL.txt.
-//
-// As of the Change Date specified in that file, in accordance with
-// the Business Source License, use of this software will be governed
-// by the Apache License, Version 2.0, included in the file
-// licenses/APL.txt.
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
 
 package coldata
 
@@ -47,16 +42,25 @@ type Nulls struct {
 
 // NewNulls returns a new nulls vector, initialized with a length.
 func NewNulls(len int) Nulls {
-	if len > 0 {
-		n := Nulls{
-			nulls: make([]byte, (len-1)/8+1),
-		}
-		n.UnsetNulls()
-		return n
-	}
-	return Nulls{
-		nulls: make([]byte, 0),
+	return newNulls(make([]byte, nullsStorageCap(len)))
+}
+
+//gcassert:inline
+func newNulls(nulls []byte) Nulls {
+	n := Nulls{nulls: nulls}
+	n.UnsetNulls()
+	return n
+}
+
+// nullsStorageCap returns the length of the byte slice that is needed to
+// maintain the Nulls bitmap for n elements.
+//
+//gcassert:inline
+func nullsStorageCap(n int) int {
+	if n <= 0 {
+		return 0
 	}
+	return (n-1)/8 + 1
 }
 
 // MaybeHasNulls returns true if the column possibly has any null values, and
diff --git a/pkg/col/coldata/testutils.go b/pkg/col/coldata/testutils.go
index 595a66f..f0e8143 100644
--- a/pkg/col/coldata/testutils.go
+++ b/pkg/col/coldata/testutils.go
@@ -1,12 +1,7 @@
 // Copyright 2020 The Cockroach Authors.
 //
-// Use of this software is governed by the Business Source License
-// included in the file licenses/BSL.txt.
-//
-// As of the Change Date specified in that file, in accordance with
-// the Business Source License, use of this software will be governed
-// by the Apache License, Version 2.0, included in the file
-// licenses/APL.txt.
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
 
 package coldata
 
@@ -65,9 +60,6 @@ func AssertEquivalentBatches(t testingT, expected, actual Batch) {
 		expectedNulls := expectedVec.Nulls()
 		actualNulls := actualVec.Nulls()
 		oldExpMaybeHasNulls, oldActMaybeHasNulls := expectedNulls.maybeHasNulls, actualNulls.maybeHasNulls
-		defer func() {
-			expectedNulls.maybeHasNulls, actualNulls.maybeHasNulls = oldExpMaybeHasNulls, oldActMaybeHasNulls
-		}()
 		expectedNulls.maybeHasNulls = expectedNulls.maybeHasNulls || actualNulls.maybeHasNulls
 		actualNulls.maybeHasNulls = expectedNulls.maybeHasNulls || actualNulls.maybeHasNulls
 		require.Equal(t, expectedNulls.Slice(0, expected.Length()), actualNulls.Slice(0, actual.Length()))
@@ -152,5 +144,6 @@ func AssertEquivalentBatches(t testingT, expected, actual Batch) {
 				actualVec.Window(0, actual.Length()),
 			)
 		}
+		expectedNulls.maybeHasNulls, actualNulls.maybeHasNulls = oldExpMaybeHasNulls, oldActMaybeHasNulls
 	}
 }
diff --git a/pkg/col/coldata/vec.eg.go b/pkg/col/coldata/vec.eg.go
index 478160d..d25095f 100644
--- a/pkg/col/coldata/vec.eg.go
+++ b/pkg/col/coldata/vec.eg.go
@@ -1,13 +1,8 @@
 // Code generated by execgen; DO NOT EDIT.
 // Copyright 2018 The Cockroach Authors.
 //
-// Use of this software is governed by the Business Source License
-// included in the file licenses/BSL.txt.
-//
-// As of the Change Date specified in that file, in accordance with
-// the Business Source License, use of this software will be governed
-// by the Apache License, Version 2.0, included in the file
-// licenses/APL.txt.
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
 
 package coldata
 
@@ -41,7 +36,7 @@ var (
 // they are working with can then access the typed column directly, avoiding
 // expensive type casts.
 type TypedVecs struct {
-	Vecs  []Vec
+	Vecs  []*Vec
 	Nulls []*Nulls
 
 	// Fields below need to be accessed by an index mapped via ColsMap.
@@ -212,14 +207,22 @@ func (v *TypedVecs) Reset() {
 	}
 }
 
-func (m *memColumn) Append(args SliceArgs) {
-	switch m.CanonicalTypeFamily() {
+// Append uses SliceArgs to append elements of a source Vec into this Vec.
+// It is logically equivalent to:
+// destVec = append(destVec[:args.DestIdx], args.Src[args.SrcStartIdx:args.SrcEndIdx])
+// An optional Sel slice can also be provided to apply a filter on the source
+// Vec.
+// Refer to the SliceArgs comment for specifics and TestAppend for examples.
+//
+// Note: Append()'ing from a Vector into itself is not supported.
+func (v *Vec) Append(args SliceArgs) {
+	switch v.CanonicalTypeFamily() {
 	case types.BoolFamily:
-		switch m.t.Width() {
+		switch v.t.Width() {
 		case -1:
 		default:
 			fromCol := args.Src.Bool()
-			toCol := m.Bool()
+			toCol := v.Bool()
 			// NOTE: it is unfortunate that we always append whole slice without paying
 			// attention to whether the values are NULL. However, if we do start paying
 			// attention, the performance suffers dramatically, so we choose to copy
@@ -234,15 +237,15 @@ func (m *memColumn) Append(args SliceArgs) {
 					toCol = append(toCol, val)
 				}
 			}
-			m.nulls.set(args)
-			m.col = toCol
+			v.nulls.set(args)
+			v.col = toCol
 		}
 	case types.BytesFamily:
-		switch m.t.Width() {
+		switch v.t.Width() {
 		case -1:
 		default:
 			fromCol := args.Src.Bytes()
-			toCol := m.Bytes()
+			toCol := v.Bytes()
 			// NOTE: it is unfortunate that we always append whole slice without paying
 			// attention to whether the values are NULL. However, if we do start paying
 			// attention, the performance suffers dramatically, so we choose to copy
@@ -253,15 +256,15 @@ func (m *memColumn) Append(args SliceArgs) {
 				sel := args.Sel[args.SrcStartIdx:args.SrcEndIdx]
 				toCol.appendSliceWithSel(fromCol, args.DestIdx, sel)
 			}
-			m.nulls.set(args)
-			m.col = toCol
+			v.nulls.set(args)
+			v.col = toCol
 		}
 	case types.DecimalFamily:
-		switch m.t.Width() {
+		switch v.t.Width() {
 		case -1:
 		default:
 			fromCol := args.Src.Decimal()
-			toCol := m.Decimal()
+			toCol := v.Decimal()
 			// NOTE: it is unfortunate that we always append whole slice without paying
 			// attention to whether the values are NULL. However, if we do start paying
 			// attention, the performance suffers dramatically, so we choose to copy
@@ -298,14 +301,14 @@ func (m *memColumn) Append(args SliceArgs) {
 					toCol[len(toCol)-1].Set(&val)
 				}
 			}
-			m.nulls.set(args)
-			m.col = toCol
+			v.nulls.set(args)
+			v.col = toCol
 		}
 	case types.IntFamily:
-		switch m.t.Width() {
+		switch v.t.Width() {
 		case 16:
 			fromCol := args.Src.Int16()
-			toCol := m.Int16()
+			toCol := v.Int16()
 			// NOTE: it is unfortunate that we always append whole slice without paying
 			// attention to whether the values are NULL. However, if we do start paying
 			// attention, the performance suffers dramatically, so we choose to copy
@@ -320,11 +323,11 @@ func (m *memColumn) Append(args SliceArgs) {
 					toCol = append(toCol, val)
 				}
 			}
-			m.nulls.set(args)
-			m.col = toCol
+			v.nulls.set(args)
+			v.col = toCol
 		case 32:
 			fromCol := args.Src.Int32()
-			toCol := m.Int32()
+			toCol := v.Int32()
 			// NOTE: it is unfortunate that we always append whole slice without paying
 			// attention to whether the values are NULL. However, if we do start paying
 			// attention, the performance suffers dramatically, so we choose to copy
@@ -339,12 +342,12 @@ func (m *memColumn) Append(args SliceArgs) {
 					toCol = append(toCol, val)
 				}
 			}
-			m.nulls.set(args)
-			m.col = toCol
+			v.nulls.set(args)
+			v.col = toCol
 		case -1:
 		default:
 			fromCol := args.Src.Int64()
-			toCol := m.Int64()
+			toCol := v.Int64()
 			// NOTE: it is unfortunate that we always append whole slice without paying
 			// attention to whether the values are NULL. However, if we do start paying
 			// attention, the performance suffers dramatically, so we choose to copy
@@ -359,15 +362,15 @@ func (m *memColumn) Append(args SliceArgs) {
 					toCol = append(toCol, val)
 				}
 			}
-			m.nulls.set(args)
-			m.col = toCol
+			v.nulls.set(args)
+			v.col = toCol
 		}
 	case types.FloatFamily:
-		switch m.t.Width() {
+		switch v.t.Width() {
 		case -1:
 		default:
 			fromCol := args.Src.Float64()
-			toCol := m.Float64()
+			toCol := v.Float64()
 			// NOTE: it is unfortunate that we always append whole slice without paying
 			// attention to whether the values are NULL. However, if we do start paying
 			// attention, the performance suffers dramatically, so we choose to copy
@@ -382,15 +385,15 @@ func (m *memColumn) Append(args SliceArgs) {
 					toCol = append(toCol, val)
 				}
 			}
-			m.nulls.set(args)
-			m.col = toCol
+			v.nulls.set(args)
+			v.col = toCol
 		}
 	case types.TimestampTZFamily:
-		switch m.t.Width() {
+		switch v.t.Width() {
 		case -1:
 		default:
 			fromCol := args.Src.Timestamp()
-			toCol := m.Timestamp()
+			toCol := v.Timestamp()
 			// NOTE: it is unfortunate that we always append whole slice without paying
 			// attention to whether the values are NULL. However, if we do start paying
 			// attention, the performance suffers dramatically, so we choose to copy
@@ -405,15 +408,15 @@ func (m *memColumn) Append(args SliceArgs) {
 					toCol = append(toCol, val)
 				}
 			}
-			m.nulls.set(args)
-			m.col = toCol
+			v.nulls.set(args)
+			v.col = toCol
 		}
 	case types.IntervalFamily:
-		switch m.t.Width() {
+		switch v.t.Width() {
 		case -1:
 		default:
 			fromCol := args.Src.Interval()
-			toCol := m.Interval()
+			toCol := v.Interval()
 			// NOTE: it is unfortunate that we always append whole slice without paying
 			// attention to whether the values are NULL. However, if we do start paying
 			// attention, the performance suffers dramatically, so we choose to copy
@@ -428,15 +431,15 @@ func (m *memColumn) Append(args SliceArgs) {
 					toCol = append(toCol, val)
 				}
 			}
-			m.nulls.set(args)
-			m.col = toCol
+			v.nulls.set(args)
+			v.col = toCol
 		}
 	case types.JsonFamily:
-		switch m.t.Width() {
+		switch v.t.Width() {
 		case -1:
 		default:
 			fromCol := args.Src.JSON()
-			toCol := m.JSON()
+			toCol := v.JSON()
 			// NOTE: it is unfortunate that we always append whole slice without paying
 			// attention to whether the values are NULL. However, if we do start paying
 			// attention, the performance suffers dramatically, so we choose to copy
@@ -447,15 +450,15 @@ func (m *memColumn) Append(args SliceArgs) {
 				sel := args.Sel[args.SrcStartIdx:args.SrcEndIdx]
 				toCol.appendSliceWithSel(fromCol, args.DestIdx, sel)
 			}
-			m.nulls.set(args)
-			m.col = toCol
+			v.nulls.set(args)
+			v.col = toCol
 		}
 	case typeconv.DatumVecCanonicalTypeFamily:
-		switch m.t.Width() {
+		switch v.t.Width() {
 		case -1:
 		default:
 			fromCol := args.Src.Datum()
-			toCol := m.Datum()
+			toCol := v.Datum()
 			// NOTE: it is unfortunate that we always append whole slice without paying
 			// attention to whether the values are NULL. However, if we do start paying
 			// attention, the performance suffers dramatically, so we choose to copy
@@ -470,31 +473,37 @@ func (m *memColumn) Append(args SliceArgs) {
 					toCol.AppendVal(val)
 				}
 			}
-			m.nulls.set(args)
-			m.col = toCol
+			v.nulls.set(args)
+			v.col = toCol
 		}
 	default:
-		panic(fmt.Sprintf("unhandled type %s", m.t))
+		panic(fmt.Sprintf("unhandled type %s", v.t))
 	}
 }
 
-func (m *memColumn) Copy(args SliceArgs) {
+// Copy uses SliceArgs to copy elements of a source Vec into this Vec. It is
+// logically equivalent to:
+// copy(destVec[args.DestIdx:], args.Src[args.SrcStartIdx:args.SrcEndIdx])
+// An optional Sel slice can also be provided to apply a filter on the source
+// Vec.
+// Refer to the SliceArgs comment for specifics and TestCopy for examples.
+func (v *Vec) Copy(args SliceArgs) {
 	if args.SrcStartIdx == args.SrcEndIdx {
 		// Nothing to copy, so return early.
 		return
 	}
-	if m.Nulls().MaybeHasNulls() {
+	if v.Nulls().MaybeHasNulls() {
 		// We're about to overwrite this entire range, so unset all the nulls.
-		m.Nulls().UnsetNullRange(args.DestIdx, args.DestIdx+(args.SrcEndIdx-args.SrcStartIdx))
+		v.Nulls().UnsetNullRange(args.DestIdx, args.DestIdx+(args.SrcEndIdx-args.SrcStartIdx))
 	}
 
-	switch m.CanonicalTypeFamily() {
+	switch v.CanonicalTypeFamily() {
 	case types.BoolFamily:
-		switch m.t.Width() {
+		switch v.t.Width() {
 		case -1:
 		default:
 			fromCol := args.Src.Bool()
-			toCol := m.Bool()
+			toCol := v.Bool()
 			if args.Sel != nil {
 				sel := args.Sel[args.SrcStartIdx:args.SrcEndIdx]
 				n := len(sel)
@@ -506,7 +515,7 @@ func (m *memColumn) Copy(args SliceArgs) {
 						//gcassert:bce
 						selIdx := sel[i]
 						if nulls.NullAt(selIdx) {
-							m.nulls.SetNull(i + args.DestIdx)
+							v.nulls.SetNull(i + args.DestIdx)
 						} else {
 							v := fromCol.Get(selIdx)
 							//gcassert:bce
@@ -527,14 +536,14 @@ func (m *memColumn) Copy(args SliceArgs) {
 			}
 			// No Sel.
 			toCol.CopySlice(fromCol, args.DestIdx, args.SrcStartIdx, args.SrcEndIdx)
-			m.nulls.set(args)
+			v.nulls.set(args)
 		}
 	case types.BytesFamily:
-		switch m.t.Width() {
+		switch v.t.Width() {
 		case -1:
 		default:
 			fromCol := args.Src.Bytes()
-			toCol := m.Bytes()
+			toCol := v.Bytes()
 			if args.Sel != nil {
 				sel := args.Sel[args.SrcStartIdx:args.SrcEndIdx]
 				n := len(sel)
@@ -544,7 +553,7 @@ func (m *memColumn) Copy(args SliceArgs) {
 						//gcassert:bce
 						selIdx := sel[i]
 						if nulls.NullAt(selIdx) {
-							m.nulls.SetNull(i + args.DestIdx)
+							v.nulls.SetNull(i + args.DestIdx)
 						} else {
 							toCol.Copy(fromCol, i+args.DestIdx, selIdx)
 						}
@@ -561,14 +570,14 @@ func (m *memColumn) Copy(args SliceArgs) {
 			}
 			// No Sel.
 			toCol.CopySlice(fromCol, args.DestIdx, args.SrcStartIdx, args.SrcEndIdx)
-			m.nulls.set(args)
+			v.nulls.set(args)
 		}
 	case types.DecimalFamily:
-		switch m.t.Width() {
+		switch v.t.Width() {
 		case -1:
 		default:
 			fromCol := args.Src.Decimal()
-			toCol := m.Decimal()
+			toCol := v.Decimal()
 			if args.Sel != nil {
 				sel := args.Sel[args.SrcStartIdx:args.SrcEndIdx]
 				n := len(sel)
@@ -580,7 +589,7 @@ func (m *memColumn) Copy(args SliceArgs) {
 						//gcassert:bce
 						selIdx := sel[i]
 						if nulls.NullAt(selIdx) {
-							m.nulls.SetNull(i + args.DestIdx)
+							v.nulls.SetNull(i + args.DestIdx)
 						} else {
 							v := fromCol.Get(selIdx)
 							//gcassert:bce
@@ -601,13 +610,13 @@ func (m *memColumn) Copy(args SliceArgs) {
 			}
 			// No Sel.
 			toCol.CopySlice(fromCol, args.DestIdx, args.SrcStartIdx, args.SrcEndIdx)
-			m.nulls.set(args)
+			v.nulls.set(args)
 		}
 	case types.IntFamily:
-		switch m.t.Width() {
+		switch v.t.Width() {
 		case 16:
 			fromCol := args.Src.Int16()
-			toCol := m.Int16()
+			toCol := v.Int16()
 			if args.Sel != nil {
 				sel := args.Sel[args.SrcStartIdx:args.SrcEndIdx]
 				n := len(sel)
@@ -619,7 +628,7 @@ func (m *memColumn) Copy(args SliceArgs) {
 						//gcassert:bce
 						selIdx := sel[i]
 						if nulls.NullAt(selIdx) {
-							m.nulls.SetNull(i + args.DestIdx)
+							v.nulls.SetNull(i + args.DestIdx)
 						} else {
 							v := fromCol.Get(selIdx)
 							//gcassert:bce
@@ -640,10 +649,10 @@ func (m *memColumn) Copy(args SliceArgs) {
 			}
 			// No Sel.
 			toCol.CopySlice(fromCol, args.DestIdx, args.SrcStartIdx, args.SrcEndIdx)
-			m.nulls.set(args)
+			v.nulls.set(args)
 		case 32:
 			fromCol := args.Src.Int32()
-			toCol := m.Int32()
+			toCol := v.Int32()
 			if args.Sel != nil {
 				sel := args.Sel[args.SrcStartIdx:args.SrcEndIdx]
 				n := len(sel)
@@ -655,7 +664,7 @@ func (m *memColumn) Copy(args SliceArgs) {
 						//gcassert:bce
 						selIdx := sel[i]
 						if nulls.NullAt(selIdx) {
-							m.nulls.SetNull(i + args.DestIdx)
+							v.nulls.SetNull(i + args.DestIdx)
 						} else {
 							v := fromCol.Get(selIdx)
 							//gcassert:bce
@@ -676,11 +685,11 @@ func (m *memColumn) Copy(args SliceArgs) {
 			}
 			// No Sel.
 			toCol.CopySlice(fromCol, args.DestIdx, args.SrcStartIdx, args.SrcEndIdx)
-			m.nulls.set(args)
+			v.nulls.set(args)
 		case -1:
 		default:
 			fromCol := args.Src.Int64()
-			toCol := m.Int64()
+			toCol := v.Int64()
 			if args.Sel != nil {
 				sel := args.Sel[args.SrcStartIdx:args.SrcEndIdx]
 				n := len(sel)
@@ -692,7 +701,7 @@ func (m *memColumn) Copy(args SliceArgs) {
 						//gcassert:bce
 						selIdx := sel[i]
 						if nulls.NullAt(selIdx) {
-							m.nulls.SetNull(i + args.DestIdx)
+							v.nulls.SetNull(i + args.DestIdx)
 						} else {
 							v := fromCol.Get(selIdx)
 							//gcassert:bce
@@ -713,14 +722,14 @@ func (m *memColumn) Copy(args SliceArgs) {
 			}
 			// No Sel.
 			toCol.CopySlice(fromCol, args.DestIdx, args.SrcStartIdx, args.SrcEndIdx)
-			m.nulls.set(args)
+			v.nulls.set(args)
 		}
 	case types.FloatFamily:
-		switch m.t.Width() {
+		switch v.t.Width() {
 		case -1:
 		default:
 			fromCol := args.Src.Float64()
-			toCol := m.Float64()
+			toCol := v.Float64()
 			if args.Sel != nil {
 				sel := args.Sel[args.SrcStartIdx:args.SrcEndIdx]
 				n := len(sel)
@@ -732,7 +741,7 @@ func (m *memColumn) Copy(args SliceArgs) {
 						//gcassert:bce
 						selIdx := sel[i]
 						if nulls.NullAt(selIdx) {
-							m.nulls.SetNull(i + args.DestIdx)
+							v.nulls.SetNull(i + args.DestIdx)
 						} else {
 							v := fromCol.Get(selIdx)
 							//gcassert:bce
@@ -753,14 +762,14 @@ func (m *memColumn) Copy(args SliceArgs) {
 			}
 			// No Sel.
 			toCol.CopySlice(fromCol, args.DestIdx, args.SrcStartIdx, args.SrcEndIdx)
-			m.nulls.set(args)
+			v.nulls.set(args)
 		}
 	case types.TimestampTZFamily:
-		switch m.t.Width() {
+		switch v.t.Width() {
 		case -1:
 		default:
 			fromCol := args.Src.Timestamp()
-			toCol := m.Timestamp()
+			toCol := v.Timestamp()
 			if args.Sel != nil {
 				sel := args.Sel[args.SrcStartIdx:args.SrcEndIdx]
 				n := len(sel)
@@ -772,7 +781,7 @@ func (m *memColumn) Copy(args SliceArgs) {
 						//gcassert:bce
 						selIdx := sel[i]
 						if nulls.NullAt(selIdx) {
-							m.nulls.SetNull(i + args.DestIdx)
+							v.nulls.SetNull(i + args.DestIdx)
 						} else {
 							v := fromCol.Get(selIdx)
 							//gcassert:bce
@@ -793,14 +802,14 @@ func (m *memColumn) Copy(args SliceArgs) {
 			}
 			// No Sel.
 			toCol.CopySlice(fromCol, args.DestIdx, args.SrcStartIdx, args.SrcEndIdx)
-			m.nulls.set(args)
+			v.nulls.set(args)
 		}
 	case types.IntervalFamily:
-		switch m.t.Width() {
+		switch v.t.Width() {
 		case -1:
 		default:
 			fromCol := args.Src.Interval()
-			toCol := m.Interval()
+			toCol := v.Interval()
 			if args.Sel != nil {
 				sel := args.Sel[args.SrcStartIdx:args.SrcEndIdx]
 				n := len(sel)
@@ -812,7 +821,7 @@ func (m *memColumn) Copy(args SliceArgs) {
 						//gcassert:bce
 						selIdx := sel[i]
 						if nulls.NullAt(selIdx) {
-							m.nulls.SetNull(i + args.DestIdx)
+							v.nulls.SetNull(i + args.DestIdx)
 						} else {
 							v := fromCol.Get(selIdx)
 							//gcassert:bce
@@ -833,14 +842,14 @@ func (m *memColumn) Copy(args SliceArgs) {
 			}
 			// No Sel.
 			toCol.CopySlice(fromCol, args.DestIdx, args.SrcStartIdx, args.SrcEndIdx)
-			m.nulls.set(args)
+			v.nulls.set(args)
 		}
 	case types.JsonFamily:
-		switch m.t.Width() {
+		switch v.t.Width() {
 		case -1:
 		default:
 			fromCol := args.Src.JSON()
-			toCol := m.JSON()
+			toCol := v.JSON()
 			if args.Sel != nil {
 				sel := args.Sel[args.SrcStartIdx:args.SrcEndIdx]
 				n := len(sel)
@@ -850,7 +859,7 @@ func (m *memColumn) Copy(args SliceArgs) {
 						//gcassert:bce
 						selIdx := sel[i]
 						if nulls.NullAt(selIdx) {
-							m.nulls.SetNull(i + args.DestIdx)
+							v.nulls.SetNull(i + args.DestIdx)
 						} else {
 							toCol.Copy(fromCol, i+args.DestIdx, selIdx)
 						}
@@ -867,14 +876,14 @@ func (m *memColumn) Copy(args SliceArgs) {
 			}
 			// No Sel.
 			toCol.CopySlice(fromCol, args.DestIdx, args.SrcStartIdx, args.SrcEndIdx)
-			m.nulls.set(args)
+			v.nulls.set(args)
 		}
 	case typeconv.DatumVecCanonicalTypeFamily:
-		switch m.t.Width() {
+		switch v.t.Width() {
 		case -1:
 		default:
 			fromCol := args.Src.Datum()
-			toCol := m.Datum()
+			toCol := v.Datum()
 			if args.Sel != nil {
 				sel := args.Sel[args.SrcStartIdx:args.SrcEndIdx]
 				n := len(sel)
@@ -884,7 +893,7 @@ func (m *memColumn) Copy(args SliceArgs) {
 						//gcassert:bce
 						selIdx := sel[i]
 						if nulls.NullAt(selIdx) {
-							m.nulls.SetNull(i + args.DestIdx)
+							v.nulls.SetNull(i + args.DestIdx)
 						} else {
 							v := fromCol.Get(selIdx)
 							toCol.Set(i+args.DestIdx, v)
@@ -903,27 +912,31 @@ func (m *memColumn) Copy(args SliceArgs) {
 			}
 			// No Sel.
 			toCol.CopySlice(fromCol, args.DestIdx, args.SrcStartIdx, args.SrcEndIdx)
-			m.nulls.set(args)
+			v.nulls.set(args)
 		}
 	default:
-		panic(fmt.Sprintf("unhandled type %s", m.t))
+		panic(fmt.Sprintf("unhandled type %s", v.t))
 	}
 }
 
-func (m *memColumn) CopyWithReorderedSource(src Vec, sel, order []int) {
+// CopyWithReorderedSource copies a value at position order[sel[i]] in src
+// into the receiver at position sel[i]. len(sel) elements are copied.
+// Resulting values of elements not mentioned in sel are undefined after
+// this function.
+func (v *Vec) CopyWithReorderedSource(src *Vec, sel, order []int) {
 	if len(sel) == 0 {
 		return
 	}
-	if m.nulls.MaybeHasNulls() {
-		m.nulls.UnsetNulls()
+	if v.nulls.MaybeHasNulls() {
+		v.nulls.UnsetNulls()
 	}
-	switch m.CanonicalTypeFamily() {
+	switch v.CanonicalTypeFamily() {
 	case types.BoolFamily:
-		switch m.t.Width() {
+		switch v.t.Width() {
 		case -1:
 		default:
 			fromCol := src.Bool()
-			toCol := m.Bool()
+			toCol := v.Bool()
 			n := len(sel)
 			_ = sel[n-1]
 			if src.MaybeHasNulls() {
@@ -933,7 +946,7 @@ func (m *memColumn) CopyWithReorderedSource(src Vec, sel, order []int) {
 					destIdx := sel[i]
 					srcIdx := order[destIdx]
 					if nulls.NullAt(srcIdx) {
-						m.nulls.SetNull(destIdx)
+						v.nulls.SetNull(destIdx)
 					} else {
 						v := fromCol.Get(srcIdx)
 						toCol.Set(destIdx, v)
@@ -952,11 +965,11 @@ func (m *memColumn) CopyWithReorderedSource(src Vec, sel, order []int) {
 			}
 		}
 	case types.BytesFamily:
-		switch m.t.Width() {
+		switch v.t.Width() {
 		case -1:
 		default:
 			fromCol := src.Bytes()
-			toCol := m.Bytes()
+			toCol := v.Bytes()
 			n := len(sel)
 			_ = sel[n-1]
 			if src.MaybeHasNulls() {
@@ -966,7 +979,7 @@ func (m *memColumn) CopyWithReorderedSource(src Vec, sel, order []int) {
 					destIdx := sel[i]
 					srcIdx := order[destIdx]
 					if nulls.NullAt(srcIdx) {
-						m.nulls.SetNull(destIdx)
+						v.nulls.SetNull(destIdx)
 					} else {
 						toCol.Copy(fromCol, destIdx, srcIdx)
 					}
@@ -983,11 +996,11 @@ func (m *memColumn) CopyWithReorderedSource(src Vec, sel, order []int) {
 			}
 		}
 	case types.DecimalFamily:
-		switch m.t.Width() {
+		switch v.t.Width() {
 		case -1:
 		default:
 			fromCol := src.Decimal()
-			toCol := m.Decimal()
+			toCol := v.Decimal()
 			n := len(sel)
 			_ = sel[n-1]
 			if src.MaybeHasNulls() {
@@ -997,7 +1010,7 @@ func (m *memColumn) CopyWithReorderedSource(src Vec, sel, order []int) {
 					destIdx := sel[i]
 					srcIdx := order[destIdx]
 					if nulls.NullAt(srcIdx) {
-						m.nulls.SetNull(destIdx)
+						v.nulls.SetNull(destIdx)
 					} else {
 						v := fromCol.Get(srcIdx)
 						toCol.Set(destIdx, v)
@@ -1016,10 +1029,10 @@ func (m *memColumn) CopyWithReorderedSource(src Vec, sel, order []int) {
 			}
 		}
 	case types.IntFamily:
-		switch m.t.Width() {
+		switch v.t.Width() {
 		case 16:
 			fromCol := src.Int16()
-			toCol := m.Int16()
+			toCol := v.Int16()
 			n := len(sel)
 			_ = sel[n-1]
 			if src.MaybeHasNulls() {
@@ -1029,7 +1042,7 @@ func (m *memColumn) CopyWithReorderedSource(src Vec, sel, order []int) {
 					destIdx := sel[i]
 					srcIdx := order[destIdx]
 					if nulls.NullAt(srcIdx) {
-						m.nulls.SetNull(destIdx)
+						v.nulls.SetNull(destIdx)
 					} else {
 						v := fromCol.Get(srcIdx)
 						toCol.Set(destIdx, v)
@@ -1048,7 +1061,7 @@ func (m *memColumn) CopyWithReorderedSource(src Vec, sel, order []int) {
 			}
 		case 32:
 			fromCol := src.Int32()
-			toCol := m.Int32()
+			toCol := v.Int32()
 			n := len(sel)
 			_ = sel[n-1]
 			if src.MaybeHasNulls() {
@@ -1058,7 +1071,7 @@ func (m *memColumn) CopyWithReorderedSource(src Vec, sel, order []int) {
 					destIdx := sel[i]
 					srcIdx := order[destIdx]
 					if nulls.NullAt(srcIdx) {
-						m.nulls.SetNull(destIdx)
+						v.nulls.SetNull(destIdx)
 					} else {
 						v := fromCol.Get(srcIdx)
 						toCol.Set(destIdx, v)
@@ -1078,7 +1091,7 @@ func (m *memColumn) CopyWithReorderedSource(src Vec, sel, order []int) {
 		case -1:
 		default:
 			fromCol := src.Int64()
-			toCol := m.Int64()
+			toCol := v.Int64()
 			n := len(sel)
 			_ = sel[n-1]
 			if src.MaybeHasNulls() {
@@ -1088,7 +1101,7 @@ func (m *memColumn) CopyWithReorderedSource(src Vec, sel, order []int) {
 					destIdx := sel[i]
 					srcIdx := order[destIdx]
 					if nulls.NullAt(srcIdx) {
-						m.nulls.SetNull(destIdx)
+						v.nulls.SetNull(destIdx)
 					} else {
 						v := fromCol.Get(srcIdx)
 						toCol.Set(destIdx, v)
@@ -1107,11 +1120,11 @@ func (m *memColumn) CopyWithReorderedSource(src Vec, sel, order []int) {
 			}
 		}
 	case types.FloatFamily:
-		switch m.t.Width() {
+		switch v.t.Width() {
 		case -1:
 		default:
 			fromCol := src.Float64()
-			toCol := m.Float64()
+			toCol := v.Float64()
 			n := len(sel)
 			_ = sel[n-1]
 			if src.MaybeHasNulls() {
@@ -1121,7 +1134,7 @@ func (m *memColumn) CopyWithReorderedSource(src Vec, sel, order []int) {
 					destIdx := sel[i]
 					srcIdx := order[destIdx]
 					if nulls.NullAt(srcIdx) {
-						m.nulls.SetNull(destIdx)
+						v.nulls.SetNull(destIdx)
 					} else {
 						v := fromCol.Get(srcIdx)
 						toCol.Set(destIdx, v)
@@ -1140,11 +1153,11 @@ func (m *memColumn) CopyWithReorderedSource(src Vec, sel, order []int) {
 			}
 		}
 	case types.TimestampTZFamily:
-		switch m.t.Width() {
+		switch v.t.Width() {
 		case -1:
 		default:
 			fromCol := src.Timestamp()
-			toCol := m.Timestamp()
+			toCol := v.Timestamp()
 			n := len(sel)
 			_ = sel[n-1]
 			if src.MaybeHasNulls() {
@@ -1154,7 +1167,7 @@ func (m *memColumn) CopyWithReorderedSource(src Vec, sel, order []int) {
 					destIdx := sel[i]
 					srcIdx := order[destIdx]
 					if nulls.NullAt(srcIdx) {
-						m.nulls.SetNull(destIdx)
+						v.nulls.SetNull(destIdx)
 					} else {
 						v := fromCol.Get(srcIdx)
 						toCol.Set(destIdx, v)
@@ -1173,11 +1186,11 @@ func (m *memColumn) CopyWithReorderedSource(src Vec, sel, order []int) {
 			}
 		}
 	case types.IntervalFamily:
-		switch m.t.Width() {
+		switch v.t.Width() {
 		case -1:
 		default:
 			fromCol := src.Interval()
-			toCol := m.Interval()
+			toCol := v.Interval()
 			n := len(sel)
 			_ = sel[n-1]
 			if src.MaybeHasNulls() {
@@ -1187,7 +1200,7 @@ func (m *memColumn) CopyWithReorderedSource(src Vec, sel, order []int) {
 					destIdx := sel[i]
 					srcIdx := order[destIdx]
 					if nulls.NullAt(srcIdx) {
-						m.nulls.SetNull(destIdx)
+						v.nulls.SetNull(destIdx)
 					} else {
 						v := fromCol.Get(srcIdx)
 						toCol.Set(destIdx, v)
@@ -1206,11 +1219,11 @@ func (m *memColumn) CopyWithReorderedSource(src Vec, sel, order []int) {
 			}
 		}
 	case types.JsonFamily:
-		switch m.t.Width() {
+		switch v.t.Width() {
 		case -1:
 		default:
 			fromCol := src.JSON()
-			toCol := m.JSON()
+			toCol := v.JSON()
 			n := len(sel)
 			_ = sel[n-1]
 			if src.MaybeHasNulls() {
@@ -1220,7 +1233,7 @@ func (m *memColumn) CopyWithReorderedSource(src Vec, sel, order []int) {
 					destIdx := sel[i]
 					srcIdx := order[destIdx]
 					if nulls.NullAt(srcIdx) {
-						m.nulls.SetNull(destIdx)
+						v.nulls.SetNull(destIdx)
 					} else {
 						toCol.Copy(fromCol, destIdx, srcIdx)
 					}
@@ -1237,11 +1250,11 @@ func (m *memColumn) CopyWithReorderedSource(src Vec, sel, order []int) {
 			}
 		}
 	case typeconv.DatumVecCanonicalTypeFamily:
-		switch m.t.Width() {
+		switch v.t.Width() {
 		case -1:
 		default:
 			fromCol := src.Datum()
-			toCol := m.Datum()
+			toCol := v.Datum()
 			n := len(sel)
 			_ = sel[n-1]
 			if src.MaybeHasNulls() {
@@ -1251,7 +1264,7 @@ func (m *memColumn) CopyWithReorderedSource(src Vec, sel, order []int) {
 					destIdx := sel[i]
 					srcIdx := order[destIdx]
 					if nulls.NullAt(srcIdx) {
-						m.nulls.SetNull(destIdx)
+						v.nulls.SetNull(destIdx)
 					} else {
 						v := fromCol.Get(srcIdx)
 						toCol.Set(destIdx, v)
@@ -1270,143 +1283,147 @@ func (m *memColumn) CopyWithReorderedSource(src Vec, sel, order []int) {
 			}
 		}
 	default:
-		panic(fmt.Sprintf("unhandled type %s", m.t))
+		panic(fmt.Sprintf("unhandled type %s", v.t))
 	}
 }
 
-func (m *memColumn) Window(start int, end int) Vec {
-	switch m.CanonicalTypeFamily() {
+// Window returns a "window" into the Vec. A "window" is similar to Golang's
+// slice of the current Vec from [start, end), but the returned object is NOT
+// allowed to be modified (the modification might result in an undefined
+// behavior).
+func (v *Vec) Window(start int, end int) *Vec {
+	switch v.CanonicalTypeFamily() {
 	case types.BoolFamily:
-		switch m.t.Width() {
+		switch v.t.Width() {
 		case -1:
 		default:
-			col := m.Bool()
-			return &memColumn{
-				t:                   m.t,
-				canonicalTypeFamily: m.canonicalTypeFamily,
+			col := v.Bool()
+			return &Vec{
+				t:                   v.t,
+				canonicalTypeFamily: v.canonicalTypeFamily,
 				col:                 col.Window(start, end),
-				nulls:               m.nulls.Slice(start, end),
+				nulls:               v.nulls.Slice(start, end),
 			}
 		}
 	case types.BytesFamily:
-		switch m.t.Width() {
+		switch v.t.Width() {
 		case -1:
 		default:
-			col := m.Bytes()
-			return &memColumn{
-				t:                   m.t,
-				canonicalTypeFamily: m.canonicalTypeFamily,
+			col := v.Bytes()
+			return &Vec{
+				t:                   v.t,
+				canonicalTypeFamily: v.canonicalTypeFamily,
 				col:                 col.Window(start, end),
-				nulls:               m.nulls.Slice(start, end),
+				nulls:               v.nulls.Slice(start, end),
 			}
 		}
 	case types.DecimalFamily:
-		switch m.t.Width() {
+		switch v.t.Width() {
 		case -1:
 		default:
-			col := m.Decimal()
-			return &memColumn{
-				t:                   m.t,
-				canonicalTypeFamily: m.canonicalTypeFamily,
+			col := v.Decimal()
+			return &Vec{
+				t:                   v.t,
+				canonicalTypeFamily: v.canonicalTypeFamily,
 				col:                 col.Window(start, end),
-				nulls:               m.nulls.Slice(start, end),
+				nulls:               v.nulls.Slice(start, end),
 			}
 		}
 	case types.IntFamily:
-		switch m.t.Width() {
+		switch v.t.Width() {
 		case 16:
-			col := m.Int16()
-			return &memColumn{
-				t:                   m.t,
-				canonicalTypeFamily: m.canonicalTypeFamily,
+			col := v.Int16()
+			return &Vec{
+				t:                   v.t,
+				canonicalTypeFamily: v.canonicalTypeFamily,
 				col:                 col.Window(start, end),
-				nulls:               m.nulls.Slice(start, end),
+				nulls:               v.nulls.Slice(start, end),
 			}
 		case 32:
-			col := m.Int32()
-			return &memColumn{
-				t:                   m.t,
-				canonicalTypeFamily: m.canonicalTypeFamily,
+			col := v.Int32()
+			return &Vec{
+				t:                   v.t,
+				canonicalTypeFamily: v.canonicalTypeFamily,
 				col:                 col.Window(start, end),
-				nulls:               m.nulls.Slice(start, end),
+				nulls:               v.nulls.Slice(start, end),
 			}
 		case -1:
 		default:
-			col := m.Int64()
-			return &memColumn{
-				t:                   m.t,
-				canonicalTypeFamily: m.canonicalTypeFamily,
+			col := v.Int64()
+			return &Vec{
+				t:                   v.t,
+				canonicalTypeFamily: v.canonicalTypeFamily,
 				col:                 col.Window(start, end),
-				nulls:               m.nulls.Slice(start, end),
+				nulls:               v.nulls.Slice(start, end),
 			}
 		}
 	case types.FloatFamily:
-		switch m.t.Width() {
+		switch v.t.Width() {
 		case -1:
 		default:
-			col := m.Float64()
-			return &memColumn{
-				t:                   m.t,
-				canonicalTypeFamily: m.canonicalTypeFamily,
+			col := v.Float64()
+			return &Vec{
+				t:                   v.t,
+				canonicalTypeFamily: v.canonicalTypeFamily,
 				col:                 col.Window(start, end),
-				nulls:               m.nulls.Slice(start, end),
+				nulls:               v.nulls.Slice(start, end),
 			}
 		}
 	case types.TimestampTZFamily:
-		switch m.t.Width() {
+		switch v.t.Width() {
 		case -1:
 		default:
-			col := m.Timestamp()
-			return &memColumn{
-				t:                   m.t,
-				canonicalTypeFamily: m.canonicalTypeFamily,
+			col := v.Timestamp()
+			return &Vec{
+				t:                   v.t,
+				canonicalTypeFamily: v.canonicalTypeFamily,
 				col:                 col.Window(start, end),
-				nulls:               m.nulls.Slice(start, end),
+				nulls:               v.nulls.Slice(start, end),
 			}
 		}
 	case types.IntervalFamily:
-		switch m.t.Width() {
+		switch v.t.Width() {
 		case -1:
 		default:
-			col := m.Interval()
-			return &memColumn{
-				t:                   m.t,
-				canonicalTypeFamily: m.canonicalTypeFamily,
+			col := v.Interval()
+			return &Vec{
+				t:                   v.t,
+				canonicalTypeFamily: v.canonicalTypeFamily,
 				col:                 col.Window(start, end),
-				nulls:               m.nulls.Slice(start, end),
+				nulls:               v.nulls.Slice(start, end),
 			}
 		}
 	case types.JsonFamily:
-		switch m.t.Width() {
+		switch v.t.Width() {
 		case -1:
 		default:
-			col := m.JSON()
-			return &memColumn{
-				t:                   m.t,
-				canonicalTypeFamily: m.canonicalTypeFamily,
+			col := v.JSON()
+			return &Vec{
+				t:                   v.t,
+				canonicalTypeFamily: v.canonicalTypeFamily,
 				col:                 col.Window(start, end),
-				nulls:               m.nulls.Slice(start, end),
+				nulls:               v.nulls.Slice(start, end),
 			}
 		}
 	case typeconv.DatumVecCanonicalTypeFamily:
-		switch m.t.Width() {
+		switch v.t.Width() {
 		case -1:
 		default:
-			col := m.Datum()
-			return &memColumn{
-				t:                   m.t,
-				canonicalTypeFamily: m.canonicalTypeFamily,
+			col := v.Datum()
+			return &Vec{
+				t:                   v.t,
+				canonicalTypeFamily: v.canonicalTypeFamily,
 				col:                 col.Window(start, end),
-				nulls:               m.nulls.Slice(start, end),
+				nulls:               v.nulls.Slice(start, end),
 			}
 		}
 	}
-	panic(fmt.Sprintf("unhandled type %s", m.t))
+	panic(fmt.Sprintf("unhandled type %s", v.t))
 }
 
 // SetValueAt is an inefficient helper to set the value in a Vec when the type
 // is unknown.
-func SetValueAt(v Vec, elem interface{}, rowIdx int) {
+func SetValueAt(v *Vec, elem interface{}, rowIdx int) {
 	switch t := v.Type(); v.CanonicalTypeFamily() {
 	case types.BoolFamily:
 		switch t.Width() {
@@ -1495,7 +1512,7 @@ func SetValueAt(v Vec, elem interface{}, rowIdx int) {
 
 // GetValueAt is an inefficient helper to get the value in a Vec when the type
 // is unknown.
-func GetValueAt(v Vec, rowIdx int) interface{} {
+func GetValueAt(v *Vec, rowIdx int) interface{} {
 	if v.Nulls().NullAt(rowIdx) {
 		return nil
 	}
diff --git a/pkg/col/coldata/vec.go b/pkg/col/coldata/vec.go
index 25d0aab..3e21f45 100644
--- a/pkg/col/coldata/vec.go
+++ b/pkg/col/coldata/vec.go
@@ -1,12 +1,7 @@
 // Copyright 2018 The Cockroach Authors.
 //
-// Use of this software is governed by the Business Source License
-// included in the file licenses/BSL.txt.
-//
-// As of the Change Date specified in that file, in accordance with
-// the Business Source License, use of this software will be governed
-// by the Apache License, Version 2.0, included in the file
-// licenses/APL.txt.
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
 
 // Package coldata exposes utilities for handling columnarized data.
 package coldata
@@ -27,7 +22,7 @@ type Column interface {
 // SliceArgs represents the arguments passed in to Vec.Append and Nulls.set.
 type SliceArgs struct {
 	// Src is the data being appended.
-	Src Vec
+	Src *Vec
 	// Sel is an optional slice specifying indices to append to the destination
 	// slice. Note that Src{Start,End}Idx apply to Sel.
 	Sel []int
@@ -42,103 +37,10 @@ type SliceArgs struct {
 	SrcEndIdx int
 }
 
-// Vec is an interface that represents a column vector that's accessible by
-// Go native types.
-type Vec interface {
-	// Type returns the type of data stored in this Vec. Consider whether
-	// CanonicalTypeFamily() should be used instead.
-	Type() *types.T
-	// CanonicalTypeFamily returns the canonical type family of data stored in
-	// this Vec.
-	CanonicalTypeFamily() types.Family
-
-	// Bool returns a bool list.
-	Bool() Bools
-	// Int16 returns an int16 slice.
-	Int16() Int16s
-	// Int32 returns an int32 slice.
-	Int32() Int32s
-	// Int64 returns an int64 slice.
-	Int64() Int64s
-	// Float64 returns a float64 slice.
-	Float64() Float64s
-	// Bytes returns a flat Bytes representation.
-	Bytes() *Bytes
-	// Decimal returns an apd.Decimal slice.
-	Decimal() Decimals
-	// Timestamp returns a time.Time slice.
-	Timestamp() Times
-	// Interval returns a duration.Duration slice.
-	Interval() Durations
-	// JSON returns a vector of JSONs.
-	JSON() *JSONs
-	// Datum returns a vector of Datums.
-	Datum() DatumVec
-
-	// Col returns the raw, typeless backing storage for this Vec.
-	Col() Column
-
-	// SetCol sets the member column (in the case of mutable columns).
-	SetCol(Column)
-
-	// TemplateType returns an []interface{} and is used for operator templates.
-	// Do not call this from normal code - it'll always panic.
-	TemplateType() []interface{}
-
-	// Append uses SliceArgs to append elements of a source Vec into this Vec.
-	// It is logically equivalent to:
-	// destVec = append(destVec[:args.DestIdx], args.Src[args.SrcStartIdx:args.SrcEndIdx])
-	// An optional Sel slice can also be provided to apply a filter on the source
-	// Vec.
-	// Refer to the SliceArgs comment for specifics and TestAppend for examples.
-	//
-	// Note: Append()'ing from a Vector into itself is not supported.
-	Append(SliceArgs)
-
-	// Copy uses SliceArgs to copy elements of a source Vec into this Vec. It is
-	// logically equivalent to:
-	// copy(destVec[args.DestIdx:], args.Src[args.SrcStartIdx:args.SrcEndIdx])
-	// An optional Sel slice can also be provided to apply a filter on the source
-	// Vec.
-	// Refer to the SliceArgs comment for specifics and TestCopy for examples.
-	Copy(SliceArgs)
-
-	// CopyWithReorderedSource copies a value at position order[sel[i]] in src
-	// into the receiver at position sel[i]. len(sel) elements are copied.
-	// Resulting values of elements not mentioned in sel are undefined after
-	// this function.
-	CopyWithReorderedSource(src Vec, sel, order []int)
-
-	// Window returns a "window" into the Vec. A "window" is similar to Golang's
-	// slice of the current Vec from [start, end), but the returned object is NOT
-	// allowed to be modified (the modification might result in an undefined
-	// behavior).
-	Window(start int, end int) Vec
-
-	// MaybeHasNulls returns true if the column possibly has any null values, and
-	// returns false if the column definitely has no null values.
-	MaybeHasNulls() bool
-
-	// Nulls returns the nulls vector for the column.
-	Nulls() *Nulls
-
-	// SetNulls sets the nulls vector for this column.
-	SetNulls(Nulls)
-
-	// Length returns the length of the slice that is underlying this Vec.
-	Length() int
-
-	// Capacity returns the capacity of the Golang's slice that is underlying
-	// this Vec. Note that if there is no "slice" (like in case of flat bytes),
-	// then "capacity" of such object is equal to the number of elements.
-	Capacity() int
-}
-
-var _ Vec = &memColumn{}
-
-// memColumn is a simple pass-through implementation of Vec that just casts
-// a generic interface{} to the proper type when requested.
-type memColumn struct {
+// Vec is a column vector that's accessible by Go native types.
+// TODO(yuzefovich): consider storing / passing vectors by value rather than
+// pointer.
+type Vec struct {
 	t                   *types.T
 	canonicalTypeFamily types.Family
 	col                 Column
@@ -148,6 +50,10 @@ type memColumn struct {
 // ColumnFactory is an interface that can construct columns for Batches.
 type ColumnFactory interface {
 	MakeColumn(t *types.T, length int) Column
+	// MakeColumns batch-allocates columns of the given type and the given
+	// length. Note that datum-backed vectors will be incomplete - the caller
+	// must set the correct type on each one.
+	MakeColumns(columns []Column, t *types.T, length int)
 }
 
 type defaultColumnFactory struct{}
@@ -188,17 +94,87 @@ func (cf *defaultColumnFactory) MakeColumn(t *types.T, length int) Column {
 	}
 }
 
-// NewMemColumn returns a new memColumn, initialized with a length using the
-// given column factory.
-func NewMemColumn(t *types.T, length int, factory ColumnFactory) Vec {
-	var m memColumn
-	m.init(t, length, factory)
-	return &m
+func (cf *defaultColumnFactory) MakeColumns(columns []Column, t *types.T, length int) {
+	allocLength := len(columns) * length
+	switch canonicalTypeFamily := typeconv.TypeFamilyToCanonicalTypeFamily(t.Family()); canonicalTypeFamily {
+	case types.BoolFamily:
+		alloc := make(Bools, allocLength)
+		for i := range columns {
+			columns[i] = alloc[:length:length]
+			alloc = alloc[length:]
+		}
+	case types.BytesFamily:
+		alloc := make([]element, allocLength)
+		wrapperAlloc := make([]Bytes, len(columns))
+		for i := range columns {
+			wrapperAlloc[i].elements = alloc[:length:length]
+			columns[i] = &wrapperAlloc[i]
+			alloc = alloc[length:]
+		}
+	case types.IntFamily:
+		switch t.Width() {
+		case 16:
+			alloc := make(Int16s, allocLength)
+			for i := range columns {
+				columns[i] = alloc[:length:length]
+				alloc = alloc[length:]
+			}
+		case 32:
+			alloc := make(Int32s, allocLength)
+			for i := range columns {
+				columns[i] = alloc[:length:length]
+				alloc = alloc[length:]
+			}
+		case 0, 64:
+			alloc := make(Int64s, allocLength)
+			for i := range columns {
+				columns[i] = alloc[:length:length]
+				alloc = alloc[length:]
+			}
+		default:
+			panic(fmt.Sprintf("unexpected integer width: %d", t.Width()))
+		}
+	case types.FloatFamily:
+		alloc := make(Float64s, allocLength)
+		for i := range columns {
+			columns[i] = alloc[:length:length]
+			alloc = alloc[length:]
+		}
+	case types.DecimalFamily:
+		alloc := make(Decimals, allocLength)
+		for i := range columns {
+			columns[i] = alloc[:length:length]
+			alloc = alloc[length:]
+		}
+	case types.TimestampTZFamily:
+		alloc := make(Times, allocLength)
+		for i := range columns {
+			columns[i] = alloc[:length:length]
+			alloc = alloc[length:]
+		}
+	case types.IntervalFamily:
+		alloc := make(Durations, allocLength)
+		for i := range columns {
+			columns[i] = alloc[:length:length]
+			alloc = alloc[length:]
+		}
+	case types.JsonFamily:
+		alloc := make([]element, allocLength)
+		wrapperAlloc := make([]JSONs, len(columns))
+		for i := range columns {
+			wrapperAlloc[i].elements = alloc[:length:length]
+			columns[i] = &wrapperAlloc[i]
+			alloc = alloc[length:]
+		}
+	default:
+		panic(fmt.Sprintf("StandardColumnFactory doesn't support %s", t))
+	}
 }
 
-// init initializes the receiver with a length using the given column factory.
-func (m *memColumn) init(t *types.T, length int, factory ColumnFactory) {
-	*m = memColumn{
+// NewVec returns a new Vec, initialized with a length using the given column
+// factory.
+func NewVec(t *types.T, length int, factory ColumnFactory) *Vec {
+	return &Vec{
 		t:                   t,
 		canonicalTypeFamily: typeconv.TypeFamilyToCanonicalTypeFamily(t.Family()),
 		col:                 factory.MakeColumn(t, length),
@@ -206,116 +182,143 @@ func (m *memColumn) init(t *types.T, length int, factory ColumnFactory) {
 	}
 }
 
-func (m *memColumn) Type() *types.T {
-	return m.t
+// Type returns the type of data stored in this Vec. Consider whether
+// CanonicalTypeFamily() should be used instead.
+func (v *Vec) Type() *types.T {
+	return v.t
 }
 
-func (m *memColumn) CanonicalTypeFamily() types.Family {
-	return m.canonicalTypeFamily
+// CanonicalTypeFamily returns the canonical type family of data stored in this
+// Vec.
+func (v *Vec) CanonicalTypeFamily() types.Family {
+	return v.canonicalTypeFamily
 }
 
-func (m *memColumn) SetCol(col Column) {
-	m.col = col
+// SetCol sets the member column (in the case of mutable columns).
+func (v *Vec) SetCol(col Column) {
+	v.col = col
 }
 
-func (m *memColumn) Bool() Bools {
-	return m.col.(Bools)
+// Bool returns a bool list.
+func (v *Vec) Bool() Bools {
+	return v.col.(Bools)
 }
 
-func (m *memColumn) Int16() Int16s {
-	return m.col.(Int16s)
+// Int16 returns an int16 slice.
+func (v *Vec) Int16() Int16s {
+	return v.col.(Int16s)
 }
 
-func (m *memColumn) Int32() Int32s {
-	return m.col.(Int32s)
+// Int32 returns an int32 slice.
+func (v *Vec) Int32() Int32s {
+	return v.col.(Int32s)
 }
 
-func (m *memColumn) Int64() Int64s {
-	return m.col.(Int64s)
+// Int64 returns an int64 slice.
+func (v *Vec) Int64() Int64s {
+	return v.col.(Int64s)
 }
 
-func (m *memColumn) Float64() Float64s {
-	return m.col.(Float64s)
+// Float64 returns a float64 slice.
+func (v *Vec) Float64() Float64s {
+	return v.col.(Float64s)
 }
 
-func (m *memColumn) Bytes() *Bytes {
-	return m.col.(*Bytes)
+// Bytes returns a flat Bytes representation.
+func (v *Vec) Bytes() *Bytes {
+	return v.col.(*Bytes)
 }
 
-func (m *memColumn) Decimal() Decimals {
-	return m.col.(Decimals)
+// Decimal returns an apd.Decimal slice.
+func (v *Vec) Decimal() Decimals {
+	return v.col.(Decimals)
 }
 
-func (m *memColumn) Timestamp() Times {
-	return m.col.(Times)
+// Timestamp returns a time.Time slice.
+func (v *Vec) Timestamp() Times {
+	return v.col.(Times)
 }
 
-func (m *memColumn) Interval() Durations {
-	return m.col.(Durations)
+// Interval returns a duration.Duration slice.
+func (v *Vec) Interval() Durations {
+	return v.col.(Durations)
 }
 
-func (m *memColumn) JSON() *JSONs {
-	return m.col.(*JSONs)
+// JSON returns a vector of JSONs.
+func (v *Vec) JSON() *JSONs {
+	return v.col.(*JSONs)
 }
 
-func (m *memColumn) Datum() DatumVec {
-	return m.col.(DatumVec)
+// Datum returns a vector of Datums.
+func (v *Vec) Datum() DatumVec {
+	return v.col.(DatumVec)
 }
 
-func (m *memColumn) Col() Column {
-	return m.col
+// Col returns the raw, typeless backing storage for this Vec.
+func (v *Vec) Col() Column {
+	return v.col
 }
 
-func (m *memColumn) TemplateType() []interface{} {
+// TemplateType returns an []interface{} and is used for operator templates.
+// Do not call this from normal code - it'll always panic.
+func (v *Vec) TemplateType() []interface{} {
 	panic("don't call this from non template code")
 }
 
-func (m *memColumn) MaybeHasNulls() bool {
-	return m.nulls.maybeHasNulls
+// MaybeHasNulls returns true if the column possibly has any null values, and
+// returns false if the column definitely has no null values.
+func (v *Vec) MaybeHasNulls() bool {
+	return v.nulls.maybeHasNulls
 }
 
-func (m *memColumn) Nulls() *Nulls {
-	return &m.nulls
+// Nulls returns the nulls vector for the column.
+func (v *Vec) Nulls() *Nulls {
+	return &v.nulls
 }
 
-func (m *memColumn) SetNulls(n Nulls) {
-	m.nulls = n
+// SetNulls sets the nulls vector for this column.
+func (v *Vec) SetNulls(n Nulls) {
+	v.nulls = n
 }
 
-func (m *memColumn) Length() int {
-	return m.col.Len()
+// Length returns the length of the slice that is underlying this Vec.
+func (v *Vec) Length() int {
+	return v.col.Len()
 }
 
-func (m *memColumn) Capacity() int {
-	switch m.CanonicalTypeFamily() {
+// Capacity returns the capacity of the Golang's slice that is underlying
+// this Vec. Note that if there is no "slice" (like in case of flat bytes),
+// then "capacity" of such object is equal to the number of elements.
+func (v *Vec) Capacity() int {
+	switch v.CanonicalTypeFamily() {
 	case types.BoolFamily:
-		return cap(m.col.(Bools))
+		return cap(v.col.(Bools))
 	case types.BytesFamily:
-		return m.Bytes().Len()
+		return v.Bytes().Len()
 	case types.IntFamily:
-		switch m.t.Width() {
+		switch v.t.Width() {
 		case 16:
-			return cap(m.col.(Int16s))
+			return cap(v.col.(Int16s))
 		case 32:
-			return cap(m.col.(Int32s))
+			return cap(v.col.(Int32s))
 		case 0, 64:
-			return cap(m.col.(Int64s))
+			return cap(v.col.(Int64s))
 		default:
-			panic(fmt.Sprintf("unexpected int width: %d", m.t.Width()))
+			panic(fmt.Sprintf("unexpected int width: %d", v.t.Width()))
 		}
 	case types.FloatFamily:
-		return cap(m.col.(Float64s))
+		return cap(v.col.(Float64s))
 	case types.DecimalFamily:
-		return cap(m.col.(Decimals))
+		return cap(v.col.(Decimals))
 	case types.TimestampTZFamily:
-		return cap(m.col.(Times))
+		return cap(v.col.(Times))
 	case types.IntervalFamily:
-		return cap(m.col.(Durations))
+		return cap(v.col.(Durations))
 	case types.JsonFamily:
-		return m.JSON().Len()
+		return v.JSON().Len()
 	case typeconv.DatumVecCanonicalTypeFamily:
-		return m.col.(DatumVec).Cap()
+		return v.col.(DatumVec).Cap()
 	default:
-		panic(fmt.Sprintf("unhandled type %s", m.t))
+		panic(fmt.Sprintf("unhandled type %s", v.t))
 	}
 }
diff --git a/pkg/col/coldata/vec_tmpl.go b/pkg/col/coldata/vec_tmpl.go
index 23c9f41..9f2a72f 100644
--- a/pkg/col/coldata/vec_tmpl.go
+++ b/pkg/col/coldata/vec_tmpl.go
@@ -1,16 +1,10 @@
 // Copyright 2018 The Cockroach Authors.
 //
-// Use of this software is governed by the Business Source License
-// included in the file licenses/BSL.txt.
-//
-// As of the Change Date specified in that file, in accordance with
-// the Business Source License, use of this software will be governed
-// by the Apache License, Version 2.0, included in the file
-// licenses/APL.txt.
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
 
 // {{/*
 //go:build execgen_template
-// +build execgen_template
 
 //
 // This file is the execgen template for vec.eg.go. It's formatted in a
@@ -64,7 +58,7 @@ const _TYPE_WIDTH = 0
 // they are working with can then access the typed column directly, avoiding
 // expensive type casts.
 type TypedVecs struct {
-	Vecs  []Vec
+	Vecs  []*Vec
 	Nulls []*Nulls
 
 	// Fields below need to be accessed by an index mapped via ColsMap.
@@ -138,15 +132,23 @@ func (v *TypedVecs) Reset() {
 	// {{end}}
 }
 
-func (m *memColumn) Append(args SliceArgs) {
-	switch m.CanonicalTypeFamily() {
+// Append uses SliceArgs to append elements of a source Vec into this Vec.
+// It is logically equivalent to:
+// destVec = append(destVec[:args.DestIdx], args.Src[args.SrcStartIdx:args.SrcEndIdx])
+// An optional Sel slice can also be provided to apply a filter on the source
+// Vec.
+// Refer to the SliceArgs comment for specifics and TestAppend for examples.
+//
+// Note: Append()'ing from a Vector into itself is not supported.
+func (v *Vec) Append(args SliceArgs) {
+	switch v.CanonicalTypeFamily() {
 	// {{range .}}
 	case _CANONICAL_TYPE_FAMILY:
-		switch m.t.Width() {
+		switch v.t.Width() {
 		// {{range .WidthOverloads}}
 		case _TYPE_WIDTH:
 			fromCol := args.Src.TemplateType()
-			toCol := m.TemplateType()
+			toCol := v.TemplateType()
 			// NOTE: it is unfortunate that we always append whole slice without paying
 			// attention to whether the values are NULL. However, if we do start paying
 			// attention, the performance suffers dramatically, so we choose to copy
@@ -166,34 +168,40 @@ func (m *memColumn) Append(args SliceArgs) {
 				}
 				// {{end}}
 			}
-			m.nulls.set(args)
-			m.col = toCol
+			v.nulls.set(args)
+			v.col = toCol
 			// {{end}}
 		}
 		// {{end}}
 	default:
-		panic(fmt.Sprintf("unhandled type %s", m.t))
+		panic(fmt.Sprintf("unhandled type %s", v.t))
 	}
 }
 
-func (m *memColumn) Copy(args SliceArgs) {
+// Copy uses SliceArgs to copy elements of a source Vec into this Vec. It is
+// logically equivalent to:
+// copy(destVec[args.DestIdx:], args.Src[args.SrcStartIdx:args.SrcEndIdx])
+// An optional Sel slice can also be provided to apply a filter on the source
+// Vec.
+// Refer to the SliceArgs comment for specifics and TestCopy for examples.
+func (v *Vec) Copy(args SliceArgs) {
 	if args.SrcStartIdx == args.SrcEndIdx {
 		// Nothing to copy, so return early.
 		return
 	}
-	if m.Nulls().MaybeHasNulls() {
+	if v.Nulls().MaybeHasNulls() {
 		// We're about to overwrite this entire range, so unset all the nulls.
-		m.Nulls().UnsetNullRange(args.DestIdx, args.DestIdx+(args.SrcEndIdx-args.SrcStartIdx))
+		v.Nulls().UnsetNullRange(args.DestIdx, args.DestIdx+(args.SrcEndIdx-args.SrcStartIdx))
 	}
 
-	switch m.CanonicalTypeFamily() {
+	switch v.CanonicalTypeFamily() {
 	// {{range .}}
 	case _CANONICAL_TYPE_FAMILY:
-		switch m.t.Width() {
+		switch v.t.Width() {
 		// {{range .WidthOverloads}}
 		case _TYPE_WIDTH:
 			fromCol := args.Src.TemplateType()
-			toCol := m.TemplateType()
+			toCol := v.TemplateType()
 			if args.Sel != nil {
 				sel := args.Sel[args.SrcStartIdx:args.SrcEndIdx]
 				n := len(sel)
@@ -207,7 +215,7 @@ func (m *memColumn) Copy(args SliceArgs) {
 						//gcassert:bce
 						selIdx := sel[i]
 						if nulls.NullAt(selIdx) {
-							m.nulls.SetNull(i + args.DestIdx)
+							v.nulls.SetNull(i + args.DestIdx)
 						} else {
 							// {{if .IsBytesLike}}
 							toCol.Copy(fromCol, i+args.DestIdx, selIdx)
@@ -262,12 +270,12 @@ func (m *memColumn) Copy(args SliceArgs) {
 			}
 			// No Sel.
 			toCol.CopySlice(fromCol, args.DestIdx, args.SrcStartIdx, args.SrcEndIdx)
-			m.nulls.set(args)
+			v.nulls.set(args)
 			// {{end}}
 		}
 		// {{end}}
 	default:
-		panic(fmt.Sprintf("unhandled type %s", m.t))
+		panic(fmt.Sprintf("unhandled type %s", v.t))
 	}
 }
 
@@ -280,7 +288,7 @@ func _COPY_WITH_REORDERED_SOURCE(_SRC_HAS_NULLS bool) { // */}}
 		srcIdx := order[destIdx]
 		// {{if .SrcHasNulls}}
 		if nulls.NullAt(srcIdx) {
-			m.nulls.SetNull(destIdx)
+			v.nulls.SetNull(destIdx)
 		} else
 		// {{end}}
 		{
@@ -298,21 +306,25 @@ func _COPY_WITH_REORDERED_SOURCE(_SRC_HAS_NULLS bool) { // */}}
 
 // */}}
 
-func (m *memColumn) CopyWithReorderedSource(src Vec, sel, order []int) {
+// CopyWithReorderedSource copies a value at position order[sel[i]] in src
+// into the receiver at position sel[i]. len(sel) elements are copied.
+// Resulting values of elements not mentioned in sel are undefined after
+// this function.
+func (v *Vec) CopyWithReorderedSource(src *Vec, sel, order []int) {
 	if len(sel) == 0 {
 		return
 	}
-	if m.nulls.MaybeHasNulls() {
-		m.nulls.UnsetNulls()
+	if v.nulls.MaybeHasNulls() {
+		v.nulls.UnsetNulls()
 	}
-	switch m.CanonicalTypeFamily() {
+	switch v.CanonicalTypeFamily() {
 	// {{range .}}
 	case _CANONICAL_TYPE_FAMILY:
-		switch m.t.Width() {
+		switch v.t.Width() {
 		// {{range .WidthOverloads}}
 		case _TYPE_WIDTH:
 			fromCol := src.TemplateType()
-			toCol := m.TemplateType()
+			toCol := v.TemplateType()
 			n := len(sel)
 			_ = sel[n-1]
 			if src.MaybeHasNulls() {
@@ -325,34 +337,38 @@ func (m *memColumn) CopyWithReorderedSource(src Vec, sel, order []int) {
 		}
 		// {{end}}
 	default:
-		panic(fmt.Sprintf("unhandled type %s", m.t))
+		panic(fmt.Sprintf("unhandled type %s", v.t))
 	}
 }
 
-func (m *memColumn) Window(start int, end int) Vec {
-	switch m.CanonicalTypeFamily() {
+// Window returns a "window" into the Vec. A "window" is similar to Golang's
+// slice of the current Vec from [start, end), but the returned object is NOT
+// allowed to be modified (the modification might result in an undefined
+// behavior).
+func (v *Vec) Window(start int, end int) *Vec {
+	switch v.CanonicalTypeFamily() {
 	// {{range .}}
 	case _CANONICAL_TYPE_FAMILY:
-		switch m.t.Width() {
+		switch v.t.Width() {
 		// {{range .WidthOverloads}}
 		case _TYPE_WIDTH:
-			col := m.TemplateType()
-			return &memColumn{
-				t:                   m.t,
-				canonicalTypeFamily: m.canonicalTypeFamily,
+			col := v.TemplateType()
+			return &Vec{
+				t:                   v.t,
+				canonicalTypeFamily: v.canonicalTypeFamily,
 				col:                 col.Window(start, end),
-				nulls:               m.nulls.Slice(start, end),
+				nulls:               v.nulls.Slice(start, end),
 			}
 			// {{end}}
 		}
 		// {{end}}
 	}
-	panic(fmt.Sprintf("unhandled type %s", m.t))
+	panic(fmt.Sprintf("unhandled type %s", v.t))
 }
 
 // SetValueAt is an inefficient helper to set the value in a Vec when the type
 // is unknown.
-func SetValueAt(v Vec, elem interface{}, rowIdx int) {
+func SetValueAt(v *Vec, elem interface{}, rowIdx int) {
 	switch t := v.Type(); v.CanonicalTypeFamily() {
 	// {{range .}}
 	case _CANONICAL_TYPE_FAMILY:
@@ -372,7 +388,7 @@ func SetValueAt(v Vec, elem interface{}, rowIdx int) {
 
 // GetValueAt is an inefficient helper to get the value in a Vec when the type
 // is unknown.
-func GetValueAt(v Vec, rowIdx int) interface{} {
+func GetValueAt(v *Vec, rowIdx int) interface{} {
 	if v.Nulls().NullAt(rowIdx) {
 		return nil
 	}
diff --git a/pkg/col/typeconv/typeconv.go b/pkg/col/typeconv/typeconv.go
index 7900d3c..2ecf195 100644
--- a/pkg/col/typeconv/typeconv.go
+++ b/pkg/col/typeconv/typeconv.go
@@ -1,12 +1,7 @@
 // Copyright 2020 The Cockroach Authors.
 //
-// Use of this software is governed by the Business Source License
-// included in the file licenses/BSL.txt.
-//
-// As of the Change Date specified in that file, in accordance with
-// the Business Source License, use of this software will be governed
-// by the Apache License, Version 2.0, included in the file
-// licenses/APL.txt.
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
 
 package typeconv
 
diff --git a/pkg/docs/docs.go b/pkg/docs/docs.go
index da30f60..e719bf6 100644
--- a/pkg/docs/docs.go
+++ b/pkg/docs/docs.go
@@ -1,12 +1,7 @@
 // Copyright 2020 The Cockroach Authors.
 //
-// Use of this software is governed by the Business Source License
-// included in the file licenses/BSL.txt.
-//
-// As of the Change Date specified in that file, in accordance with
-// the Business Source License, use of this software will be governed
-// by the Apache License, Version 2.0, included in the file
-// licenses/APL.txt.
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
 
 package docs
 
@@ -18,12 +13,12 @@ import (
 
 // URLBase is the root URL for the version of the docs associated with this
 // binary.
-var URLBase = "https://www.cockroachlabs.com/docs/" + build.BinaryVersionPrefix()
+var URLBase = "https://www.cockroachlabs.com/docs/" + build.VersionForURLs()
 
 // URLReleaseNotesBase is the root URL for the release notes for the .0 patch
 // release associated with this binary.
 var URLReleaseNotesBase = fmt.Sprintf("https://www.cockroachlabs.com/docs/releases/%s.0.html",
-	build.BinaryVersionPrefix())
+	build.VersionForURLs())
 
 // URL generates the URL to pageName in the version of the docs associated
 // with this binary.
diff --git a/pkg/geo/bbox.go b/pkg/geo/bbox.go
index 8719018..e3bf48b 100644
--- a/pkg/geo/bbox.go
+++ b/pkg/geo/bbox.go
@@ -1,12 +1,7 @@
 // Copyright 2020 The Cockroach Authors.
 //
-// Use of this software is governed by the Business Source License
-// included in the file licenses/BSL.txt.
-//
-// As of the Change Date specified in that file, in accordance with
-// the Business Source License, use of this software will be governed
-// by the Apache License, Version 2.0, included in the file
-// licenses/APL.txt.
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
 
 package geo
 
diff --git a/pkg/geo/encode.go b/pkg/geo/encode.go
index 6f6a2f1..e328f06 100644
--- a/pkg/geo/encode.go
+++ b/pkg/geo/encode.go
@@ -1,12 +1,7 @@
 // Copyright 2020 The Cockroach Authors.
 //
-// Use of this software is governed by the Business Source License
-// included in the file licenses/BSL.txt.
-//
-// As of the Change Date specified in that file, in accordance with
-// the Business Source License, use of this software will be governed
-// by the Apache License, Version 2.0, included in the file
-// licenses/APL.txt.
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
 
 package geo
 
@@ -32,8 +27,10 @@ import (
 	"github.com/twpayne/go-geom/encoding/wkt"
 )
 
-// DefaultGeoJSONDecimalDigits is the default number of digits coordinates in GeoJSON.
-const DefaultGeoJSONDecimalDigits = 9
+// FullPrecisionGeoJSON, when used in place of max decimal digits in
+// GeoJSON functions, indicates to GeoJSON that it should use full
+// precision when encoding JSON.
+const FullPrecisionGeoJSON = -1
 
 // SpatialObjectToWKT transforms a given SpatialObject to WKT.
 func SpatialObjectToWKT(so geopb.SpatialObject, maxDecimalDigits int) (geopb.WKT, error) {
diff --git a/pkg/geo/errors.go b/pkg/geo/errors.go
index b0f73f6..0c1b1b2 100644
--- a/pkg/geo/errors.go
+++ b/pkg/geo/errors.go
@@ -1,12 +1,7 @@
 // Copyright 2020 The Cockroach Authors.
 //
-// Use of this software is governed by the Business Source License
-// included in the file licenses/BSL.txt.
-//
-// As of the Change Date specified in that file, in accordance with
-// the Business Source License, use of this software will be governed
-// by the Apache License, Version 2.0, included in the file
-// licenses/APL.txt.
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
 
 package geo
 
diff --git a/pkg/geo/geo.go b/pkg/geo/geo.go
index ececb73..b548eac 100644
--- a/pkg/geo/geo.go
+++ b/pkg/geo/geo.go
@@ -1,12 +1,7 @@
 // Copyright 2020 The Cockroach Authors.
 //
-// Use of this software is governed by the Business Source License
-// included in the file licenses/BSL.txt.
-//
-// As of the Change Date specified in that file, in accordance with
-// the Business Source License, use of this software will be governed
-// by the Apache License, Version 2.0, included in the file
-// licenses/APL.txt.
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
 
 // Package geo contains the base types for spatial data type operations.
 package geo
diff --git a/pkg/geo/geodist/geodist.go b/pkg/geo/geodist/geodist.go
new file mode 100644
index 0000000..e2cd2aa
--- /dev/null
+++ b/pkg/geo/geodist/geodist.go
@@ -0,0 +1,428 @@
+// Copyright 2020 The Cockroach Authors.
+//
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
+
+// Package geodist finds distances between two geospatial shapes.
+package geodist
+
+import (
+	"github.com/cockroachdb/cockroachdb-parser/pkg/sql/pgwire/pgcode"
+	"github.com/cockroachdb/cockroachdb-parser/pkg/sql/pgwire/pgerror"
+	"github.com/golang/geo/s2"
+	"github.com/twpayne/go-geom"
+)
+
+// Point is a union of the point types used in geometry and geography representation.
+// The interfaces for distance calculation defined below are shared for both representations,
+// and this union helps us avoid heap allocations by doing cheap copy-by-value of points. The
+// code that peers inside a Point knows which of the two fields is populated.
+type Point struct {
+	GeomPoint geom.Coord
+	GeogPoint s2.Point
+}
+
+// IsShape implements the geodist.Shape interface.
+func (p *Point) IsShape() {}
+
+// Edge is a struct that represents a connection between two points.
+type Edge struct {
+	V0, V1 Point
+}
+
+// LineString is an interface that represents a geospatial LineString.
+type LineString interface {
+	Edge(i int) Edge
+	NumEdges() int
+	Vertex(i int) Point
+	NumVertexes() int
+	IsShape()
+	IsLineString()
+}
+
+// LinearRing is an interface that represents a geospatial LinearRing.
+type LinearRing interface {
+	Edge(i int) Edge
+	NumEdges() int
+	Vertex(i int) Point
+	NumVertexes() int
+	IsShape()
+	IsLinearRing()
+}
+
+// shapeWithEdges represents any shape that contains edges.
+type shapeWithEdges interface {
+	Edge(i int) Edge
+	NumEdges() int
+}
+
+// Polygon is an interface that represents a geospatial Polygon.
+type Polygon interface {
+	LinearRing(i int) LinearRing
+	NumLinearRings() int
+	IsShape()
+	IsPolygon()
+}
+
+// Shape is an interface that represents any Geospatial shape.
+type Shape interface {
+	IsShape()
+}
+
+var _ Shape = (*Point)(nil)
+var _ Shape = (LineString)(nil)
+var _ Shape = (LinearRing)(nil)
+var _ Shape = (Polygon)(nil)
+
+// DistanceUpdater is a provided hook that has a series of functions that allows
+// the caller to maintain the distance value desired.
+type DistanceUpdater interface {
+	// Update updates the distance based on two provided points,
+	// returning if the function should return early.
+	Update(a Point, b Point) bool
+	// OnIntersects is called when two shapes intersects.
+	OnIntersects(p Point) bool
+	// Distance returns the distance to return so far.
+	Distance() float64
+	// IsMaxDistance returns whether the updater is looking for maximum distance.
+	IsMaxDistance() bool
+	// FlipGeometries is called to flip the order of geometries.
+	FlipGeometries()
+}
+
+// EdgeCrosser is a provided hook that calculates whether edges intersect.
+type EdgeCrosser interface {
+	// ChainCrossing assumes there is an edge to compare against, and the previous
+	// point `p0` is the start of the next edge. It will then returns whether (p0, p)
+	// intersects with the edge and point of intersection if they intersect.
+	// When complete, point p will become p0.
+	// Desired usage examples:
+	//   crosser := NewEdgeCrosser(edge.V0, edge.V1, startingP0)
+	//   intersects, _ := crosser.ChainCrossing(p1)
+	//   laterIntersects, _ := crosser.ChainCrossing(p2)
+	//   intersects |= laterIntersects ....
+	ChainCrossing(p Point) (bool, Point)
+}
+
+// DistanceCalculator contains calculations which allow ShapeDistance to calculate
+// the distance between two shapes.
+type DistanceCalculator interface {
+	// DistanceUpdater returns the DistanceUpdater for the current set of calculations.
+	DistanceUpdater() DistanceUpdater
+	// NewEdgeCrosser returns a new EdgeCrosser with the given edge initialized to be
+	// the edge to compare against, and the start point to be the start of the first
+	// edge to compare against.
+	NewEdgeCrosser(edge Edge, startPoint Point) EdgeCrosser
+	// PointIntersectsLinearRing returns whether the point intersects the given linearRing.
+	PointIntersectsLinearRing(point Point, linearRing LinearRing) bool
+	// ClosestPointToEdge returns the closest point to the infinite line denoted by
+	// the edge, and a bool on whether this point lies on the edge segment.
+	ClosestPointToEdge(edge Edge, point Point) (Point, bool)
+	// BoundingBoxIntersects returns whether the bounding boxes of the shapes in
+	// question intersect.
+	BoundingBoxIntersects() bool
+}
+
+// ShapeDistance returns the distance between two given shapes.
+// Distance is defined by the DistanceUpdater provided by the interface.
+// It returns whether the function above should return early.
+func ShapeDistance(c DistanceCalculator, a Shape, b Shape) (bool, error) {
+	switch a := a.(type) {
+	case *Point:
+		switch b := b.(type) {
+		case *Point:
+			return c.DistanceUpdater().Update(*a, *b), nil
+		case LineString:
+			return onPointToLineString(c, *a, b), nil
+		case Polygon:
+			return onPointToPolygon(c, *a, b), nil
+		default:
+			return false, pgerror.Newf(pgcode.InvalidParameterValue, "unknown shape: %T", b)
+		}
+	case LineString:
+		switch b := b.(type) {
+		case *Point:
+			c.DistanceUpdater().FlipGeometries()
+			// defer to restore the order of geometries at the end of the function call.
+			defer c.DistanceUpdater().FlipGeometries()
+			return onPointToLineString(c, *b, a), nil
+		case LineString:
+			return onShapeEdgesToShapeEdges(c, a, b), nil
+		case Polygon:
+			return onLineStringToPolygon(c, a, b), nil
+		default:
+			return false, pgerror.Newf(pgcode.InvalidParameterValue, "unknown shape: %T", b)
+		}
+	case Polygon:
+		switch b := b.(type) {
+		case *Point:
+			c.DistanceUpdater().FlipGeometries()
+			// defer to restore the order of geometries at the end of the function call.
+			defer c.DistanceUpdater().FlipGeometries()
+			return onPointToPolygon(c, *b, a), nil
+		case LineString:
+			c.DistanceUpdater().FlipGeometries()
+			// defer to restore the order of geometries at the end of the function call.
+			defer c.DistanceUpdater().FlipGeometries()
+			return onLineStringToPolygon(c, b, a), nil
+		case Polygon:
+			return onPolygonToPolygon(c, a, b), nil
+		default:
+			return false, pgerror.Newf(pgcode.InvalidParameterValue, "unknown shape: %T", b)
+		}
+	}
+	return false, pgerror.Newf(pgcode.InvalidParameterValue, "unknown shape: %T", a)
+}
+
+// onPointToEdgesExceptFirstEdgeStart updates the distance against the edges of a shape and a point.
+// It will only check the V1 of each edge and assumes the first edge start does not need the distance
+// to be computed.
+func onPointToEdgesExceptFirstEdgeStart(c DistanceCalculator, a Point, b shapeWithEdges) bool {
+	for edgeIdx, bNumEdges := 0, b.NumEdges(); edgeIdx < bNumEdges; edgeIdx++ {
+		edge := b.Edge(edgeIdx)
+		// Check against all V1 of every edge.
+		if c.DistanceUpdater().Update(a, edge.V1) {
+			return true
+		}
+		// The max distance between a point and the set of points representing an edge is the
+		// maximum distance from the point and the pair of end-points of the edge, so we don't
+		// need to update the distance using the projected point.
+		if !c.DistanceUpdater().IsMaxDistance() {
+			// Also project the point to the infinite line of the edge, and compare if the closestPoint
+			// lies on the edge.
+			if closestPoint, ok := c.ClosestPointToEdge(edge, a); ok {
+				if c.DistanceUpdater().Update(a, closestPoint) {
+					return true
+				}
+			}
+		}
+	}
+	return false
+}
+
+// onPointToLineString updates the distance between a point and a polyline.
+// Returns true if the calling function should early exit.
+func onPointToLineString(c DistanceCalculator, a Point, b LineString) bool {
+	// Compare the first point, to avoid checking each V0 in the chain afterwards.
+	if c.DistanceUpdater().Update(a, b.Vertex(0)) {
+		return true
+	}
+	return onPointToEdgesExceptFirstEdgeStart(c, a, b)
+}
+
+// onPointToPolygon updates the distance between a point and a polygon.
+// Returns true if the calling function should early exit.
+func onPointToPolygon(c DistanceCalculator, a Point, b Polygon) bool {
+	// MaxDistance: When computing the maximum distance, the cases are:
+	//   - The point P is not contained in the exterior of the polygon G.
+	//     Say vertex V is the vertex of the exterior of the polygon that is
+	//     furthest away from point P (among all the exterior vertices).
+	//   - One can prove that any vertex of the holes will be closer to point P than vertex V.
+	//     Similarly we can prove that any point in the interior of the polygon is closer to P than vertex V.
+	//     Therefore we only need to compare with the exterior.
+	//   - The point P is contained in the exterior and inside a hole of polygon G.
+	//     One can again prove that the furthest point in the polygon from P is one of the vertices of the exterior.
+	//   - The point P is contained in the polygon. One can again prove the same property.
+	//   So we only need to compare with the exterior ring.
+	// MinDistance: If the exterior ring does not contain the point, we just need to calculate the distance to
+	//   the exterior ring.
+	// BoundingBoxIntersects: if the bounding box of the shape being calculated does not intersect,
+	//   then we only need to compare the outer loop.
+	if c.DistanceUpdater().IsMaxDistance() || !c.BoundingBoxIntersects() ||
+		!c.PointIntersectsLinearRing(a, b.LinearRing(0)) {
+		return onPointToEdgesExceptFirstEdgeStart(c, a, b.LinearRing(0))
+	}
+	// At this point it may be inside a hole.
+	// If it is in a hole, return the distance to the hole.
+	for ringIdx := 1; ringIdx < b.NumLinearRings(); ringIdx++ {
+		ring := b.LinearRing(ringIdx)
+		if c.PointIntersectsLinearRing(a, ring) {
+			return onPointToEdgesExceptFirstEdgeStart(c, a, ring)
+		}
+	}
+
+	// Otherwise, we are inside the polygon.
+	return c.DistanceUpdater().OnIntersects(a)
+}
+
+// onShapeEdgesToShapeEdges updates the distance between two shapes by
+// only looking at the edges.
+// Returns true if the calling function should early exit.
+func onShapeEdgesToShapeEdges(c DistanceCalculator, a shapeWithEdges, b shapeWithEdges) bool {
+	for aEdgeIdx, aNumEdges := 0, a.NumEdges(); aEdgeIdx < aNumEdges; aEdgeIdx++ {
+		aEdge := a.Edge(aEdgeIdx)
+		var crosser EdgeCrosser
+		// MaxDistance: the max distance between 2 edges is the maximum of the distance across
+		//   pairs of vertices chosen from each edge.
+		//   It does not matter whether the edges cross, so we skip this check.
+		// BoundingBoxIntersects: if the bounding box of the two shapes do not intersect,
+		//   then we don't need to check whether edges intersect either.
+		if !c.DistanceUpdater().IsMaxDistance() && c.BoundingBoxIntersects() {
+			crosser = c.NewEdgeCrosser(aEdge, b.Edge(0).V0)
+		}
+		for bEdgeIdx, bNumEdges := 0, b.NumEdges(); bEdgeIdx < bNumEdges; bEdgeIdx++ {
+			bEdge := b.Edge(bEdgeIdx)
+			if crosser != nil {
+				// If the edges cross, the distance is 0.
+				intersects, intersectionPoint := crosser.ChainCrossing(bEdge.V1)
+				if intersects {
+					return c.DistanceUpdater().OnIntersects(intersectionPoint)
+				}
+			}
+
+			// Check the vertex against the ends of the edges.
+			if c.DistanceUpdater().Update(aEdge.V0, bEdge.V0) ||
+				c.DistanceUpdater().Update(aEdge.V0, bEdge.V1) ||
+				c.DistanceUpdater().Update(aEdge.V1, bEdge.V0) ||
+				c.DistanceUpdater().Update(aEdge.V1, bEdge.V1) {
+				return true
+			}
+			// Only project vertexes to edges if we are looking at the edges.
+			if !c.DistanceUpdater().IsMaxDistance() {
+				if projectVertexToEdge(c, aEdge.V0, bEdge) ||
+					projectVertexToEdge(c, aEdge.V1, bEdge) {
+					return true
+				}
+				c.DistanceUpdater().FlipGeometries()
+				if projectVertexToEdge(c, bEdge.V0, aEdge) ||
+					projectVertexToEdge(c, bEdge.V1, aEdge) {
+					// Restore the order of geometries.
+					c.DistanceUpdater().FlipGeometries()
+					return true
+				}
+				// Restore the order of geometries.
+				c.DistanceUpdater().FlipGeometries()
+			}
+		}
+	}
+	return false
+}
+
+// projectVertexToEdge attempts to project the point onto the given edge.
+// Returns true if the calling function should early exit.
+func projectVertexToEdge(c DistanceCalculator, vertex Point, edge Edge) bool {
+	// Also check the projection of the vertex onto the edge.
+	if closestPoint, ok := c.ClosestPointToEdge(edge, vertex); ok {
+		if c.DistanceUpdater().Update(vertex, closestPoint) {
+			return true
+		}
+	}
+	return false
+}
+
+// onLineStringToPolygon updates the distance between a polyline and a polygon.
+// Returns true if the calling function should early exit.
+func onLineStringToPolygon(c DistanceCalculator, a LineString, b Polygon) bool {
+	// MinDistance: If we know at least one point is outside the exterior ring, then there are two cases:
+	//   * the line is always outside the exterior ring. We only need to compare the line
+	//     against the exterior ring.
+	//   * the line intersects with the exterior ring.
+	//   In both these cases, we can defer to the edge to edge comparison between the line
+	//   and the exterior ring.
+	//   We use the first point of the linestring for this check.
+	// MaxDistance: the furthest distance from a LineString to a Polygon is always against the
+	//   exterior ring. This follows the reasoning under "onPointToPolygon", but we must now
+	//   check each point in the LineString.
+	// BoundingBoxIntersects: if the bounding box of the two shapes do not intersect,
+	//   then the distance is always from the LineString to the exterior ring.
+	if c.DistanceUpdater().IsMaxDistance() ||
+		!c.BoundingBoxIntersects() ||
+		!c.PointIntersectsLinearRing(a.Vertex(0), b.LinearRing(0)) {
+		return onShapeEdgesToShapeEdges(c, a, b.LinearRing(0))
+	}
+
+	// Now we are guaranteed that there is at least one point inside the exterior ring.
+	//
+	// For a polygon with no holes, the fact that there is a point inside the exterior
+	// ring would imply that the distance is zero.
+	//
+	// However, when there are holes, it is possible that the distance is non-zero if
+	// polyline A is completely contained inside a hole. We iterate over the holes and
+	// compute the distance between the hole and polyline A.
+	// * If polyline A is within the given distance, we can immediately return.
+	// * If polyline A does not intersect the hole but there is at least one point inside
+	//   the hole, must be inside that hole and so the distance of this polyline to this hole
+	//   is the distance of this polyline to this polygon.
+	for ringIdx := 1; ringIdx < b.NumLinearRings(); ringIdx++ {
+		hole := b.LinearRing(ringIdx)
+		if onShapeEdgesToShapeEdges(c, a, hole) {
+			return true
+		}
+		for pointIdx := 0; pointIdx < a.NumVertexes(); pointIdx++ {
+			if c.PointIntersectsLinearRing(a.Vertex(pointIdx), hole) {
+				return false
+			}
+		}
+	}
+
+	// This means we are inside the exterior ring, and no points are inside a hole.
+	// This means the point is inside the polygon.
+	return c.DistanceUpdater().OnIntersects(a.Vertex(0))
+}
+
+// onPolygonToPolygon updates the distance between two polygons.
+// Returns true if the calling function should early exit.
+func onPolygonToPolygon(c DistanceCalculator, a Polygon, b Polygon) bool {
+	aFirstPoint := a.LinearRing(0).Vertex(0)
+	bFirstPoint := b.LinearRing(0).Vertex(0)
+
+	// MinDistance:
+	// If there is at least one point on the exterior ring of B that is outside the exterior ring
+	// of A, then we have one of these two cases:
+	// * The exterior rings of A and B intersect. The distance can always be found by comparing
+	//   the exterior rings.
+	// * The exterior rings of A and B never meet. This distance can always be found
+	//   by only comparing the exterior rings.
+	// If we find the point is inside the exterior ring, A could contain B, so this reasoning
+	// does not apply.
+	//
+	// The same reasoning applies if there is at least one point on the exterior ring of A
+	// that is outside the exterior ring of B.
+	//
+	// As such, we only need to compare the exterior rings if we detect this.
+	//
+	// MaxDistance:
+	//   The furthest distance between two polygons is always against the exterior rings of each other.
+	//   This closely follows the reasoning pointed out in "onPointToPolygon". Holes are always located
+	//   inside the exterior ring of a polygon, so the exterior ring will always contain a point
+	//   with a larger max distance.
+	// BoundingBoxIntersects: if the bounding box of the two shapes do not intersect,
+	//   then the distance is always between the two exterior rings.
+	if c.DistanceUpdater().IsMaxDistance() ||
+		!c.BoundingBoxIntersects() ||
+		(!c.PointIntersectsLinearRing(bFirstPoint, a.LinearRing(0)) &&
+			!c.PointIntersectsLinearRing(aFirstPoint, b.LinearRing(0))) {
+		return onShapeEdgesToShapeEdges(c, a.LinearRing(0), b.LinearRing(0))
+	}
+
+	// If any point of polygon A is inside a hole of polygon B, then either:
+	// * A is inside the hole and the closest point can be found by comparing A's outer
+	//   linearRing and the hole in B, or
+	// * A intersects this hole and the distance is zero, which can also be found by comparing
+	//   A's outer linearRing and the hole in B.
+	// In this case, we only need to compare the holes of B to contain a single point A.
+	for ringIdx := 1; ringIdx < b.NumLinearRings(); ringIdx++ {
+		bHole := b.LinearRing(ringIdx)
+		if c.PointIntersectsLinearRing(aFirstPoint, bHole) {
+			return onShapeEdgesToShapeEdges(c, a.LinearRing(0), bHole)
+		}
+	}
+
+	// Do the same check for the polygons the other way around.
+	c.DistanceUpdater().FlipGeometries()
+	// defer to restore the order of geometries at the end of the function call.
+	defer c.DistanceUpdater().FlipGeometries()
+	for ringIdx := 1; ringIdx < a.NumLinearRings(); ringIdx++ {
+		aHole := a.LinearRing(ringIdx)
+		if c.PointIntersectsLinearRing(bFirstPoint, aHole) {
+			return onShapeEdgesToShapeEdges(c, b.LinearRing(0), aHole)
+		}
+	}
+
+	// Now we know either a point of the exterior ring A is definitely inside polygon B
+	// or vice versa. This is an intersection.
+	if c.PointIntersectsLinearRing(aFirstPoint, b.LinearRing(0)) {
+		return c.DistanceUpdater().OnIntersects(aFirstPoint)
+	}
+	return c.DistanceUpdater().OnIntersects(bFirstPoint)
+}
diff --git a/pkg/geo/geogen/geogen.go b/pkg/geo/geogen/geogen.go
new file mode 100644
index 0000000..2245fe3
--- /dev/null
+++ b/pkg/geo/geogen/geogen.go
@@ -0,0 +1,355 @@
+// Copyright 2020 The Cockroach Authors.
+//
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
+
+// Package geogen provides utilities for generating various geospatial types.
+package geogen
+
+import (
+	"math"
+	"math/rand"
+	"sort"
+
+	"github.com/cockroachdb/cockroachdb-parser/pkg/geo"
+	"github.com/cockroachdb/cockroachdb-parser/pkg/geo/geopb"
+	"github.com/cockroachdb/cockroachdb-parser/pkg/geo/geoprojbase"
+	"github.com/cockroachdb/errors"
+	"github.com/twpayne/go-geom"
+)
+
+var validShapeTypes = []geopb.ShapeType{
+	geopb.ShapeType_Point,
+	geopb.ShapeType_LineString,
+	geopb.ShapeType_Polygon,
+	geopb.ShapeType_MultiPoint,
+	geopb.ShapeType_MultiLineString,
+	geopb.ShapeType_MultiPolygon,
+	geopb.ShapeType_GeometryCollection,
+}
+
+// RandomShapeType returns a random geometry type.
+func RandomShapeType(rng *rand.Rand) geopb.ShapeType {
+	return validShapeTypes[rng.Intn(len(validShapeTypes))]
+}
+
+var validLayouts = []geom.Layout{
+	geom.XY,
+	geom.XYM,
+	geom.XYZ,
+	geom.XYZM,
+}
+
+// RandomLayout randomly chooses a layout if no layout is provided.
+func RandomLayout(rng *rand.Rand, layout geom.Layout) geom.Layout {
+	if layout != geom.NoLayout {
+		return layout
+	}
+	return validLayouts[rng.Intn(len(validLayouts))]
+}
+
+// RandomGeomBounds is a struct for storing the random bounds for each dimension.
+type RandomGeomBounds struct {
+	minX, maxX float64
+	minY, maxY float64
+	minZ, maxZ float64
+	minM, maxM float64
+}
+
+// MakeRandomGeomBoundsForGeography creates a RandomGeomBounds struct with
+// bounds corresponding to a geography.
+func MakeRandomGeomBoundsForGeography() RandomGeomBounds {
+	randomBounds := MakeRandomGeomBounds()
+	randomBounds.minX, randomBounds.maxX = -180.0, 180.0
+	randomBounds.minY, randomBounds.maxY = -90.0, 90.0
+	return randomBounds
+}
+
+// MakeRandomGeomBounds creates a RandomGeomBounds struct with
+// bounds corresponding to a geometry.
+func MakeRandomGeomBounds() RandomGeomBounds {
+	return RandomGeomBounds{
+		minX: -10e9, maxX: 10e9,
+		minY: -10e9, maxY: 10e9,
+		minZ: -10e9, maxZ: 10e9,
+		minM: -10e9, maxM: 10e9,
+	}
+}
+
+// RandomCoordSlice generates a slice of random coords of length corresponding
+// to the given layout.
+func RandomCoordSlice(rng *rand.Rand, randomBounds RandomGeomBounds, layout geom.Layout) []float64 {
+	if layout == geom.NoLayout {
+		panic(errors.Newf("must specify a layout for RandomCoordSlice"))
+	}
+	var coords []float64
+	coords = append(coords, RandomCoord(rng, randomBounds.minX, randomBounds.maxX))
+	coords = append(coords, RandomCoord(rng, randomBounds.minY, randomBounds.maxY))
+
+	if layout.ZIndex() != -1 {
+		coords = append(coords, RandomCoord(rng, randomBounds.minZ, randomBounds.maxZ))
+	}
+	if layout.MIndex() != -1 {
+		coords = append(coords, RandomCoord(rng, randomBounds.minM, randomBounds.maxM))
+	}
+
+	return coords
+}
+
+// RandomCoord generates a random coord in the given bounds.
+func RandomCoord(rng *rand.Rand, min float64, max float64) float64 {
+	return rng.Float64()*(max-min) + min
+}
+
+// RandomValidLinearRingCoords generates a flat float64 array of coordinates that represents
+// a completely closed shape that can represent a simple LinearRing. This shape is always valid.
+// A LinearRing must have at least 3 points. A point is added at the end to close the ring.
+// Implements the algorithm in https://observablehq.com/@tarte0/generate-random-simple-polygon.
+func RandomValidLinearRingCoords(
+	rng *rand.Rand, numPoints int, randomBounds RandomGeomBounds, layout geom.Layout,
+) []geom.Coord {
+	layout = RandomLayout(rng, layout)
+	if numPoints < 3 {
+		panic(errors.Newf("need at least 3 points, got %d", numPoints))
+	}
+	// Generate N random points, and find the center.
+	coords := make([]geom.Coord, numPoints+1)
+	var centerX, centerY float64
+	for i := 0; i < numPoints; i++ {
+		coords[i] = RandomCoordSlice(rng, randomBounds, layout)
+		centerX += coords[i].X()
+		centerY += coords[i].Y()
+	}
+
+	centerX /= float64(numPoints)
+	centerY /= float64(numPoints)
+
+	// Sort by the angle of all the points relative to the center.
+	// Use ascending order of angle to get a CCW loop.
+	sort.Slice(coords[:numPoints], func(i, j int) bool {
+		angleI := math.Atan2(coords[i].Y()-centerY, coords[i].X()-centerX)
+		angleJ := math.Atan2(coords[j].Y()-centerY, coords[j].X()-centerX)
+		return angleI < angleJ
+	})
+
+	// Append the first coordinate to the end.
+	coords[numPoints] = coords[0]
+	return coords
+}
+
+// RandomPoint generates a random Point.
+func RandomPoint(
+	rng *rand.Rand, randomBounds RandomGeomBounds, srid geopb.SRID, layout geom.Layout,
+) *geom.Point {
+	layout = RandomLayout(rng, layout)
+	// 10% chance to generate an empty point.
+	if rng.Intn(10) == 0 {
+		return geom.NewPointEmpty(layout).SetSRID(int(srid))
+	}
+	return geom.NewPointFlat(layout, RandomCoordSlice(rng, randomBounds, layout)).SetSRID(int(srid))
+}
+
+// RandomLineString generates a random LineString.
+func RandomLineString(
+	rng *rand.Rand, randomBounds RandomGeomBounds, srid geopb.SRID, layout geom.Layout,
+) *geom.LineString {
+	layout = RandomLayout(rng, layout)
+	// 10% chance to generate an empty linestring.
+	if rng.Intn(10) == 0 {
+		return geom.NewLineString(layout).SetSRID(int(srid))
+	}
+	numCoords := 3 + rng.Intn(10)
+	randCoords := RandomValidLinearRingCoords(rng, numCoords, randomBounds, layout)
+
+	// Extract a random substring from the LineString by truncating at the ends.
+	var minTrunc, maxTrunc int
+	// Ensure we always have at least two points.
+	for maxTrunc-minTrunc < 2 {
+		minTrunc, maxTrunc = rng.Intn(numCoords+1), rng.Intn(numCoords+1)
+		// Ensure maxTrunc >= minTrunc.
+		if minTrunc > maxTrunc {
+			minTrunc, maxTrunc = maxTrunc, minTrunc
+		}
+	}
+	return geom.NewLineString(layout).MustSetCoords(randCoords[minTrunc:maxTrunc]).SetSRID(int(srid))
+}
+
+// RandomPolygon generates a random Polygon.
+func RandomPolygon(
+	rng *rand.Rand, randomBounds RandomGeomBounds, srid geopb.SRID, layout geom.Layout,
+) *geom.Polygon {
+	layout = RandomLayout(rng, layout)
+	// 10% chance to generate an empty polygon.
+	if rng.Intn(10) == 0 {
+		return geom.NewPolygon(layout).SetSRID(int(srid))
+	}
+	// TODO(otan): generate random holes inside the Polygon.
+	// Ideas:
+	// * We can do something like use 4 arbitrary points in the LinearRing to generate a BoundingBox,
+	//   and re-use "PointIntersectsLinearRing" to generate N random points inside the 4 points to form
+	//   a "sub" linear ring inside.
+	// * Generate a random set of polygons, see which ones they fully cover and use that.
+	return geom.NewPolygon(layout).MustSetCoords([][]geom.Coord{
+		RandomValidLinearRingCoords(rng, 3+rng.Intn(10), randomBounds, layout),
+	}).SetSRID(int(srid))
+}
+
+// RandomMultiPoint generates a random MultiPoint.
+func RandomMultiPoint(
+	rng *rand.Rand, randomBounds RandomGeomBounds, srid geopb.SRID, layout geom.Layout,
+) *geom.MultiPoint {
+	layout = RandomLayout(rng, layout)
+	ret := geom.NewMultiPoint(layout).SetSRID(int(srid))
+	// 10% chance to generate an empty multipoint (when num is 0).
+	num := rng.Intn(10)
+	for i := 0; i < num; i++ {
+		// TODO(#62184): permit EMPTY collection item once GEOS is patched
+		var point *geom.Point
+		for point == nil || point.Empty() {
+			point = RandomPoint(rng, randomBounds, srid, layout)
+		}
+		if err := ret.Push(point); err != nil {
+			panic(err)
+		}
+	}
+	return ret
+}
+
+// RandomMultiLineString generates a random MultiLineString.
+func RandomMultiLineString(
+	rng *rand.Rand, randomBounds RandomGeomBounds, srid geopb.SRID, layout geom.Layout,
+) *geom.MultiLineString {
+	layout = RandomLayout(rng, layout)
+	ret := geom.NewMultiLineString(layout).SetSRID(int(srid))
+	// 10% chance to generate an empty multilinestring (when num is 0).
+	num := rng.Intn(10)
+	for i := 0; i < num; i++ {
+		// TODO(#62184): permit EMPTY collection item once GEOS is patched
+		var lineString *geom.LineString
+		for lineString == nil || lineString.Empty() {
+			lineString = RandomLineString(rng, randomBounds, srid, layout)
+		}
+		if err := ret.Push(lineString); err != nil {
+			panic(err)
+		}
+	}
+	return ret
+}
+
+// RandomMultiPolygon generates a random MultiPolygon.
+func RandomMultiPolygon(
+	rng *rand.Rand, randomBounds RandomGeomBounds, srid geopb.SRID, layout geom.Layout,
+) *geom.MultiPolygon {
+	layout = RandomLayout(rng, layout)
+	ret := geom.NewMultiPolygon(layout).SetSRID(int(srid))
+	// 10% chance to generate an empty multipolygon (when num is 0).
+	num := rng.Intn(10)
+	for i := 0; i < num; i++ {
+		// TODO(#62184): permit EMPTY collection item once GEOS is patched
+		var polygon *geom.Polygon
+		for polygon == nil || polygon.Empty() {
+			polygon = RandomPolygon(rng, randomBounds, srid, layout)
+		}
+		if err := ret.Push(polygon); err != nil {
+			panic(err)
+		}
+	}
+	return ret
+}
+
+// RandomGeometryCollection generates a random GeometryCollection.
+func RandomGeometryCollection(
+	rng *rand.Rand, randomBounds RandomGeomBounds, srid geopb.SRID, layout geom.Layout,
+) *geom.GeometryCollection {
+	layout = RandomLayout(rng, layout)
+	ret := geom.NewGeometryCollection().SetSRID(int(srid))
+	if err := ret.SetLayout(layout); err != nil {
+		panic(err)
+	}
+	// 10% chance to generate an empty geometrycollection (when num is 0).
+	num := rng.Intn(10)
+	for i := 0; i < num; i++ {
+		var shape geom.T
+		needShape := true
+		// Keep searching for a non GeometryCollection.
+		for needShape {
+			shape = RandomGeomT(rng, randomBounds, srid, layout)
+			_, needShape = shape.(*geom.GeometryCollection)
+			// TODO(#62184): permit EMPTY collection item once GEOS is patched
+			if shape.Empty() {
+				needShape = true
+			}
+		}
+		if err := ret.Push(shape); err != nil {
+			panic(err)
+		}
+	}
+	return ret
+}
+
+// RandomGeomT generates a random geom.T object with the given layout within the
+// given bounds and SRID.
+func RandomGeomT(
+	rng *rand.Rand, randomBounds RandomGeomBounds, srid geopb.SRID, layout geom.Layout,
+) geom.T {
+	layout = RandomLayout(rng, layout)
+	shapeType := RandomShapeType(rng)
+	switch shapeType {
+	case geopb.ShapeType_Point:
+		return RandomPoint(rng, randomBounds, srid, layout)
+	case geopb.ShapeType_LineString:
+		return RandomLineString(rng, randomBounds, srid, layout)
+	case geopb.ShapeType_Polygon:
+		return RandomPolygon(rng, randomBounds, srid, layout)
+	case geopb.ShapeType_MultiPoint:
+		return RandomMultiPoint(rng, randomBounds, srid, layout)
+	case geopb.ShapeType_MultiLineString:
+		return RandomMultiLineString(rng, randomBounds, srid, layout)
+	case geopb.ShapeType_MultiPolygon:
+		return RandomMultiPolygon(rng, randomBounds, srid, layout)
+	case geopb.ShapeType_GeometryCollection:
+		return RandomGeometryCollection(rng, randomBounds, srid, layout)
+	}
+	panic(errors.Newf("unknown shape type: %v", shapeType))
+}
+
+// RandomGeometry generates a random Geometry with the given SRID.
+func RandomGeometry(rng *rand.Rand, srid geopb.SRID) geo.Geometry {
+	return RandomGeometryWithLayout(rng, srid, geom.NoLayout)
+}
+
+// RandomGeometryWithLayout generates a random Geometry of a given layout with
+// the given SRID.
+func RandomGeometryWithLayout(rng *rand.Rand, srid geopb.SRID, layout geom.Layout) geo.Geometry {
+	randomBounds := MakeRandomGeomBounds()
+	if srid != 0 {
+		proj, err := geoprojbase.Projection(srid)
+		if err != nil {
+			panic(err)
+		}
+		randomBounds.minX, randomBounds.maxX = proj.Bounds.MinX, proj.Bounds.MaxX
+		randomBounds.minY, randomBounds.maxY = proj.Bounds.MinY, proj.Bounds.MaxY
+	}
+	ret, err := geo.MakeGeometryFromGeomT(RandomGeomT(rng, randomBounds, srid, layout))
+	if err != nil {
+		panic(err)
+	}
+	return ret
+}
+
+// RandomGeography generates a random Geometry with the given SRID.
+func RandomGeography(rng *rand.Rand, srid geopb.SRID) geo.Geography {
+	return RandomGeographyWithLayout(rng, srid, geom.NoLayout)
+}
+
+// RandomGeographyWithLayout generates a random Geometry of a given layout with
+// the given SRID.
+func RandomGeographyWithLayout(rng *rand.Rand, srid geopb.SRID, layout geom.Layout) geo.Geography {
+	// TODO(otan): generate geographies that traverse latitude/longitude boundaries.
+	randomBoundsGeography := MakeRandomGeomBoundsForGeography()
+	ret, err := geo.MakeGeographyFromGeomT(RandomGeomT(rng, randomBoundsGeography, srid, layout))
+	if err != nil {
+		panic(err)
+	}
+	return ret
+}
diff --git a/pkg/geo/geogfn/azimuth.go b/pkg/geo/geogfn/azimuth.go
new file mode 100644
index 0000000..4bd6806
--- /dev/null
+++ b/pkg/geo/geogfn/azimuth.go
@@ -0,0 +1,68 @@
+// Copyright 2020 The Cockroach Authors.
+//
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
+
+package geogfn
+
+import (
+	"math"
+
+	"github.com/cockroachdb/cockroachdb-parser/pkg/geo"
+	"github.com/cockroachdb/cockroachdb-parser/pkg/sql/pgwire/pgcode"
+	"github.com/cockroachdb/cockroachdb-parser/pkg/sql/pgwire/pgerror"
+	"github.com/golang/geo/s2"
+	"github.com/twpayne/go-geom"
+)
+
+// Azimuth returns the azimuth in radians of the segment defined by the given point geometries.
+// The azimuth is angle is referenced from north, and is positive clockwise.
+// North = 0; East = π/2; South = π; West = 3π/2.
+// Returns nil if the two points are the same.
+// Returns an error if any of the two Geography items are not points.
+func Azimuth(a geo.Geography, b geo.Geography) (*float64, error) {
+	if a.SRID() != b.SRID() {
+		return nil, geo.NewMismatchingSRIDsError(a.SpatialObject(), b.SpatialObject())
+	}
+
+	aGeomT, err := a.AsGeomT()
+	if err != nil {
+		return nil, err
+	}
+
+	aPoint, ok := aGeomT.(*geom.Point)
+	if !ok {
+		return nil, pgerror.Newf(pgcode.InvalidParameterValue, "arguments must be POINT geometries")
+	}
+
+	bGeomT, err := b.AsGeomT()
+	if err != nil {
+		return nil, err
+	}
+
+	bPoint, ok := bGeomT.(*geom.Point)
+	if !ok {
+		return nil, pgerror.Newf(pgcode.InvalidParameterValue, "arguments must be POINT geometries")
+	}
+
+	if aPoint.Empty() || bPoint.Empty() {
+		return nil, pgerror.Newf(pgcode.InvalidParameterValue, "cannot call ST_Azimuth with POINT EMPTY")
+	}
+
+	if aPoint.X() == bPoint.X() && aPoint.Y() == bPoint.Y() {
+		return nil, nil
+	}
+
+	s, err := spheroidFromGeography(a)
+	if err != nil {
+		return nil, err
+	}
+
+	_, az1, _ := s.Inverse(
+		s2.LatLngFromDegrees(aPoint.Y(), aPoint.X()),
+		s2.LatLngFromDegrees(bPoint.Y(), bPoint.X()),
+	)
+	// Convert to radians.
+	az1 = az1 * math.Pi / 180
+	return &az1, nil
+}
diff --git a/pkg/geo/geogfn/best_projection.go b/pkg/geo/geogfn/best_projection.go
new file mode 100644
index 0000000..21b7c7a
--- /dev/null
+++ b/pkg/geo/geogfn/best_projection.go
@@ -0,0 +1,134 @@
+// Copyright 2020 The Cockroach Authors.
+//
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
+
+package geogfn
+
+import (
+	"fmt"
+	"math"
+
+	"github.com/cockroachdb/cockroachdb-parser/pkg/geo/geopb"
+	"github.com/cockroachdb/cockroachdb-parser/pkg/geo/geoprojbase"
+	"github.com/golang/geo/s1"
+	"github.com/golang/geo/s2"
+)
+
+// BestGeomProjection translates roughly to the ST_BestSRID function in PostGIS.
+// It attempts to find the best projection for a bounding box into an accurate
+// geometry-type projection.
+//
+// The algorithm is described by ST_Buffer/ST_Intersection documentation (paraphrased):
+//
+//	It first determines the best SRID that fits the bounding box of the 2 geography objects (ST_Intersection only).
+//	It favors a north/south pole projection, then UTM, then LAEA for smaller zones, otherwise falling back
+//	to web mercator.
+//	If geography objects are within one half zone UTM but not the same UTM it will pick one of those.
+//	After the calculation is complete, it will fall back to WGS84 Geography.
+func BestGeomProjection(boundingRect s2.Rect) (geoprojbase.Proj4Text, error) {
+	center := boundingRect.Center()
+
+	latWidth := s1.Angle(boundingRect.Lat.Length())
+	lngWidth := s1.Angle(boundingRect.Lng.Length())
+
+	// Check if these fit either the North Pole or South Pole areas.
+	// If the center has latitude greater than 70 (an arbitrary polar threshold), and it is
+	// within the polar ranges, return that.
+	if center.Lat.Degrees() > 70 && boundingRect.Lo().Lat.Degrees() > 45 {
+		// See: https://epsg.io/3574.
+		return getGeomProjection(3574)
+	}
+	// Same for south pole.
+	if center.Lat.Degrees() < -70 && boundingRect.Hi().Lat.Degrees() < -45 {
+		// See: https://epsg.io/3409
+		return getGeomProjection(3409)
+	}
+
+	// Each UTM zone is 6 degrees wide and distortion is low for geometries that fit within the zone. We use
+	// UTM if the width is lower than the UTM zone width, even though the geometry may span 2 zones -- using
+	// the geometry center to pick the UTM zone should result in most of the geometry being in the picked zone.
+	if lngWidth.Degrees() < 6 {
+		// Determine the offset of the projection.
+		// Offset longitude -180 to 0 and divide by 6 to get the zone.
+		// Note that we treat 180 degree longitudes as offset 59.
+		// TODO(#geo): do we care about https://en.wikipedia.org/wiki/Universal_Transverse_Mercator_coordinate_system#Exceptions?
+		// PostGIS's _ST_BestSRID function doesn't seem to care: .
+		sridOffset := geopb.SRID(math.Min(math.Floor((center.Lng.Degrees()+180)/6), 59))
+		if center.Lat.Degrees() >= 0 {
+			// Start at the north UTM SRID.
+			return getGeomProjection(32601 + sridOffset)
+		}
+		// Start at the south UTM SRID.
+		// This should make no difference in end result compared to using the north UTMs,
+		// but for completeness we do it.
+		return getGeomProjection(32701 + sridOffset)
+	}
+
+	// Attempt to fit into LAEA areas if the width is less than 25 degrees (we can go up to 30
+	// but want to leave some room for precision issues).
+	//
+	// LAEA areas are separated into 3 latitude zones between 0 and 90 and 3 latitude zones
+	// between -90 and 0. Within each latitude zones, they have different longitude bands:
+	// * The bands closest to the equator have 12x30 degree longitude zones.
+	// * The bands in the temperate area 8x45 degree longitude zones.
+	// * The bands near the poles have 4x90 degree longitude zones.
+	//
+	// For each of these bands, we custom define a LAEA area with the center of the LAEA area
+	// as the lat/lon offset.
+	//
+	// See also: https://en.wikipedia.org/wiki/Lambert_azimuthal_equal-area_projection.
+	if latWidth.Degrees() < 25 {
+		// Convert lat to a known 30 degree zone..
+		// -3 represents [-90, -60), -2 represents [-60, -30) ... and 2 represents [60, 90].
+		// (note: 90 is inclusive at the end).
+		// Treat a 90 degree latitude as band 2.
+		latZone := math.Min(math.Floor(center.Lat.Degrees()/30), 2)
+		latZoneCenterDegrees := (latZone * 30) + 15
+		// Equator bands - 30 degree zones.
+		if (latZone == 0 || latZone == -1) && lngWidth.Degrees() <= 30 {
+			lngZone := math.Floor(center.Lng.Degrees() / 30)
+			return geoprojbase.MakeProj4Text(
+				fmt.Sprintf(
+					"+proj=laea +ellps=WGS84 +datum=WGS84 +lat_0=%g +lon_0=%g +units=m +no_defs",
+					latZoneCenterDegrees,
+					(lngZone*30)+15,
+				),
+			), nil
+		}
+		// Temperate bands - 45 degree zones.
+		if (latZone == -2 || latZone == 1) && lngWidth.Degrees() <= 45 {
+			lngZone := math.Floor(center.Lng.Degrees() / 45)
+			return geoprojbase.MakeProj4Text(
+				fmt.Sprintf(
+					"+proj=laea +ellps=WGS84 +datum=WGS84 +lat_0=%g +lon_0=%g +units=m +no_defs",
+					latZoneCenterDegrees,
+					(lngZone*45)+22.5,
+				),
+			), nil
+		}
+		// Polar bands -- 90 degree zones.
+		if (latZone == -3 || latZone == 2) && lngWidth.Degrees() <= 90 {
+			lngZone := math.Floor(center.Lng.Degrees() / 90)
+			return geoprojbase.MakeProj4Text(
+				fmt.Sprintf(
+					"+proj=laea +ellps=WGS84 +datum=WGS84 +lat_0=%g +lon_0=%g +units=m +no_defs",
+					latZoneCenterDegrees,
+					(lngZone*90)+45,
+				),
+			), nil
+		}
+	}
+
+	// Default to Web Mercator.
+	return getGeomProjection(3857)
+}
+
+// getGeomProjection returns the Proj4Text associated with an SRID.
+func getGeomProjection(srid geopb.SRID) (geoprojbase.Proj4Text, error) {
+	proj, err := geoprojbase.Projection(srid)
+	if err != nil {
+		return geoprojbase.Proj4Text{}, err
+	}
+	return proj.Proj4Text, nil
+}
diff --git a/pkg/geo/geogfn/covers.go b/pkg/geo/geogfn/covers.go
new file mode 100644
index 0000000..1de0397
--- /dev/null
+++ b/pkg/geo/geogfn/covers.go
@@ -0,0 +1,300 @@
+// Copyright 2020 The Cockroach Authors.
+//
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
+
+package geogfn
+
+import (
+	"github.com/cockroachdb/cockroachdb-parser/pkg/geo"
+	"github.com/cockroachdb/cockroachdb-parser/pkg/sql/pgwire/pgcode"
+	"github.com/cockroachdb/cockroachdb-parser/pkg/sql/pgwire/pgerror"
+	"github.com/golang/geo/s2"
+)
+
+// Covers returns whether geography A covers geography B.
+//
+// This calculation is done on the sphere.
+//
+// Due to minor inaccuracies and lack of certain primitives in S2,
+// precision for Covers will be for up to 1cm.
+//
+// Current limitations (which are also limitations in PostGIS):
+//
+//   - POLYGON/LINESTRING only works as "contains" - if any point of the LINESTRING
+//     touches the boundary of the polygon, we will return false but should be true - e.g.
+//     SELECT st_covers(
+//     'multipolygon(((0.0 0.0, 1.0 0.0, 1.0 1.0, 0.0 1.0, 0.0 0.0)), ((1.0 0.0, 2.0 0.0, 2.0 1.0, 1.0 1.0, 1.0 0.0)))',
+//     'linestring(0.0 0.0, 1.0 0.0)'::geography
+//     );
+//
+//   - Furthermore, LINESTRINGS that are covered in multiple POLYGONs inside
+//     MULTIPOLYGON but NOT within a single POLYGON in the MULTIPOLYGON
+//     currently return false but should be true, e.g.
+//     SELECT st_covers(
+//     'multipolygon(((0.0 0.0, 1.0 0.0, 1.0 1.0, 0.0 1.0, 0.0 0.0)), ((1.0 0.0, 2.0 0.0, 2.0 1.0, 1.0 1.0, 1.0 0.0)))',
+//     'linestring(0.0 0.0, 2.0 0.0)'::geography
+//     );
+func Covers(a geo.Geography, b geo.Geography) (bool, error) {
+	if a.SRID() != b.SRID() {
+		return false, geo.NewMismatchingSRIDsError(a.SpatialObject(), b.SpatialObject())
+	}
+	return covers(a, b)
+}
+
+// covers is the internal calculation for Covers.
+func covers(a geo.Geography, b geo.Geography) (bool, error) {
+	// Rect "contains" is a version of covers.
+	if !a.BoundingRect().Contains(b.BoundingRect()) {
+		return false, nil
+	}
+
+	// Ignore EMPTY regions in a.
+	aRegions, err := a.AsS2(geo.EmptyBehaviorOmit)
+	if err != nil {
+		return false, err
+	}
+	// If any of b is empty, we cannot cover it. Error and catch to return false.
+	bRegions, err := b.AsS2(geo.EmptyBehaviorError)
+	if err != nil {
+		if geo.IsEmptyGeometryError(err) {
+			return false, nil
+		}
+		return false, err
+	}
+
+	// We need to check each region in B is covered by at least
+	// one region of A.
+	bRegionsRemaining := make(map[int]struct{}, len(bRegions))
+	for i := range bRegions {
+		bRegionsRemaining[i] = struct{}{}
+	}
+	for _, aRegion := range aRegions {
+		for bRegionIdx := range bRegionsRemaining {
+			regionCovers, err := regionCovers(aRegion, bRegions[bRegionIdx])
+			if err != nil {
+				return false, err
+			}
+			if regionCovers {
+				delete(bRegionsRemaining, bRegionIdx)
+			}
+		}
+		if len(bRegionsRemaining) == 0 {
+			return true, nil
+		}
+	}
+	return false, nil
+}
+
+// CoveredBy returns whether geography A is covered by geography B.
+// See Covers for limitations.
+func CoveredBy(a geo.Geography, b geo.Geography) (bool, error) {
+	if a.SRID() != b.SRID() {
+		return false, geo.NewMismatchingSRIDsError(a.SpatialObject(), b.SpatialObject())
+	}
+	return covers(b, a)
+}
+
+// regionCovers returns whether aRegion completely covers bRegion.
+func regionCovers(aRegion s2.Region, bRegion s2.Region) (bool, error) {
+	switch aRegion := aRegion.(type) {
+	case s2.Point:
+		switch bRegion := bRegion.(type) {
+		case s2.Point:
+			return aRegion.ContainsPoint(bRegion), nil
+		case *s2.Polyline:
+			return false, nil
+		case *s2.Polygon:
+			return false, nil
+		default:
+			return false, pgerror.Newf(pgcode.InvalidParameterValue, "unknown s2 type of b: %#v", bRegion)
+		}
+	case *s2.Polyline:
+		switch bRegion := bRegion.(type) {
+		case s2.Point:
+			return polylineCoversPoint(aRegion, bRegion), nil
+		case *s2.Polyline:
+			return polylineCoversPolyline(aRegion, bRegion), nil
+		case *s2.Polygon:
+			return false, nil
+		default:
+			return false, pgerror.Newf(pgcode.InvalidParameterValue, "unknown s2 type of b: %#v", bRegion)
+		}
+	case *s2.Polygon:
+		switch bRegion := bRegion.(type) {
+		case s2.Point:
+			return polygonCoversPoint(aRegion, bRegion), nil
+		case *s2.Polyline:
+			return polygonCoversPolyline(aRegion, bRegion), nil
+		case *s2.Polygon:
+			return polygonCoversPolygon(aRegion, bRegion), nil
+		default:
+			return false, pgerror.Newf(pgcode.InvalidParameterValue, "unknown s2 type of b: %#v", bRegion)
+		}
+	}
+	return false, pgerror.Newf(pgcode.InvalidParameterValue, "unknown s2 type of a: %#v", aRegion)
+}
+
+// polylineCoversPoints returns whether a polyline covers a given point.
+func polylineCoversPoint(a *s2.Polyline, b s2.Point) bool {
+	return a.IntersectsCell(s2.CellFromPoint(b))
+}
+
+// polylineCoversPointsWithIdx returns whether a polyline covers a given point.
+// If true, it will also return an index of the start of the edge where there
+// was an intersection.
+func polylineCoversPointWithIdx(a *s2.Polyline, b s2.Point) (bool, int) {
+	for edgeIdx, aNumEdges := 0, a.NumEdges(); edgeIdx < aNumEdges; edgeIdx++ {
+		if edgeCoversPoint(a.Edge(edgeIdx), b) {
+			return true, edgeIdx
+		}
+	}
+	return false, -1
+}
+
+// polygonCoversPoints returns whether a polygon covers a given point.
+func polygonCoversPoint(a *s2.Polygon, b s2.Point) bool {
+	return a.IntersectsCell(s2.CellFromPoint(b))
+}
+
+// edgeCoversPoint determines whether a given edge contains a point.
+func edgeCoversPoint(e s2.Edge, p s2.Point) bool {
+	return (&s2.Polyline{e.V0, e.V1}).IntersectsCell(s2.CellFromPoint(p))
+}
+
+// polylineCoversPolyline returns whether polyline a covers polyline b.
+func polylineCoversPolyline(a *s2.Polyline, b *s2.Polyline) bool {
+	if polylineCoversPolylineOrdered(a, b) {
+		return true
+	}
+	// Check reverse ordering works as well.
+	reversedB := make([]s2.Point, len(*b))
+	for i, point := range *b {
+		reversedB[len(reversedB)-1-i] = point
+	}
+	newBAsPolyline := s2.Polyline(reversedB)
+	return polylineCoversPolylineOrdered(a, &newBAsPolyline)
+}
+
+// polylineCoversPolylineOrdered returns whether a polyline covers a polyline
+// in the same ordering.
+func polylineCoversPolylineOrdered(a *s2.Polyline, b *s2.Polyline) bool {
+	aCoversStartOfB, aCoverBStart := polylineCoversPointWithIdx(a, (*b)[0])
+	// We must first check that the start of B is contained by A.
+	if !aCoversStartOfB {
+		return false
+	}
+
+	aPoints := *a
+	bPoints := *b
+	// We have found "aIdx" which is the first edge in polyline A
+	// that includes the starting vertex of polyline "B".
+	// Start checking the covering from this edge.
+	aIdx := aCoverBStart
+	bIdx := 0
+
+	aEdge := s2.Edge{V0: aPoints[aIdx], V1: aPoints[aIdx+1]}
+	bEdge := s2.Edge{V0: bPoints[bIdx], V1: bPoints[bIdx+1]}
+	for {
+		aEdgeCoversBStart := edgeCoversPoint(aEdge, bEdge.V0)
+		aEdgeCoversBEnd := edgeCoversPoint(aEdge, bEdge.V1)
+		bEdgeCoversAEnd := edgeCoversPoint(bEdge, aEdge.V1)
+		if aEdgeCoversBStart && aEdgeCoversBEnd {
+			// If the edge A fully covers edge B, check the next edge.
+			bIdx++
+			// We are out of edges in B, and A keeps going or stops at the same point.
+			// This is a covering.
+			if bIdx == len(bPoints)-1 {
+				return true
+			}
+			bEdge = s2.Edge{V0: bPoints[bIdx], V1: bPoints[bIdx+1]}
+			// If A and B end at the same place, we need to move A forward.
+			if bEdgeCoversAEnd {
+				aIdx++
+				if aIdx == len(aPoints)-1 {
+					// At this point, B extends past A. return false.
+					return false
+				}
+				aEdge = s2.Edge{V0: aPoints[aIdx], V1: aPoints[aIdx+1]}
+			}
+			continue
+		}
+
+		if aEdgeCoversBStart {
+			// Edge A doesn't cover the end of B, but it does cover the start.
+			// If B doesn't cover the end of A, we're done.
+			if !bEdgeCoversAEnd {
+				return false
+			}
+			// If the end of edge B covers the end of A, that means that
+			// B is possibly longer than A. If that's the case, truncate B
+			// to be the end of A, and move A forward.
+			bEdge.V0 = aEdge.V1
+			aIdx++
+			if aIdx == len(aPoints)-1 {
+				// At this point, B extends past A. return false.
+				return false
+			}
+			aEdge = s2.Edge{V0: aPoints[aIdx], V1: aPoints[aIdx+1]}
+			continue
+		}
+
+		// Otherwise, we're doomed.
+		// Edge A does not contain edge B.
+		return false
+	}
+}
+
+// polygonCoversPolyline returns whether polygon a covers polyline b.
+func polygonCoversPolyline(a *s2.Polygon, b *s2.Polyline) bool {
+	// Check everything of polyline B is in the interior of polygon A.
+	for _, vertex := range *b {
+		if !polygonCoversPoint(a, vertex) {
+			return false
+		}
+	}
+	// Even if every point of polyline B is inside polygon A, they
+	// may form an edge which goes outside of polygon A and back in
+	// due to holes and concavities.
+	//
+	// As such, check if there are any intersections - if so,
+	// we do not consider it a covering.
+	//
+	// NOTE: this implementation has a limitation where a vertex of the line could
+	// be on the boundary and still technically be "covered" (using GEOS).
+	//
+	// However, PostGIS seems to consider this as non-covering so we can go
+	// with this for now.
+	// i.e. `
+	//   select st_covers(
+	//    'POLYGON((0.0 0.0, 1.0 0.0, 1.0 1.0, 0.0 1.0, 0.0 0.0))'::geography,
+	//    'LINESTRING(0.0 0.0, 1.0 1.0)'::geography);
+	// ` returns false, but should be true. This requires some more math to resolve.
+	return !polygonIntersectsPolylineEdge(a, b)
+}
+
+// polygonIntersectsPolylineEdge returns whether polygon a intersects with
+// polyline b by edge. It does not return true if the polyline is completely
+// within the polygon.
+func polygonIntersectsPolylineEdge(a *s2.Polygon, b *s2.Polyline) bool {
+	// Avoid using NumEdges / Edge of the Polygon type as it is not O(1).
+	for _, loop := range a.Loops() {
+		for loopEdgeIdx, loopNumEdges := 0, loop.NumEdges(); loopEdgeIdx < loopNumEdges; loopEdgeIdx++ {
+			loopEdge := loop.Edge(loopEdgeIdx)
+			crosser := s2.NewChainEdgeCrosser(loopEdge.V0, loopEdge.V1, (*b)[0])
+			for _, nextVertex := range (*b)[1:] {
+				if crosser.ChainCrossingSign(nextVertex) != s2.DoNotCross {
+					return true
+				}
+			}
+		}
+	}
+	return false
+}
+
+// polygonCoversPolygon returns whether polygon a intersects with polygon b.
+func polygonCoversPolygon(a *s2.Polygon, b *s2.Polygon) bool {
+	// We can rely on Contains here, as if the boundaries of A and B are on top
+	// of each other, it is still considered a containment as well as a covering.
+	return a.Contains(b)
+}
diff --git a/pkg/geo/geogfn/distance.go b/pkg/geo/geogfn/distance.go
new file mode 100644
index 0000000..99c846f
--- /dev/null
+++ b/pkg/geo/geogfn/distance.go
@@ -0,0 +1,413 @@
+// Copyright 2020 The Cockroach Authors.
+//
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
+
+package geogfn
+
+import (
+	"math"
+
+	"github.com/cockroachdb/cockroachdb-parser/pkg/geo"
+	"github.com/cockroachdb/cockroachdb-parser/pkg/geo/geodist"
+	"github.com/cockroachdb/cockroachdb-parser/pkg/geo/geoprojbase"
+	"github.com/cockroachdb/cockroachdb-parser/pkg/sql/pgwire/pgcode"
+	"github.com/cockroachdb/cockroachdb-parser/pkg/sql/pgwire/pgerror"
+	"github.com/golang/geo/s1"
+	"github.com/golang/geo/s2"
+)
+
+// SpheroidErrorFraction is an error fraction to compensate for using a sphere
+// to calculate the distance for what is actually a spheroid. The distance
+// calculation has an error that is bounded by (2 * spheroid.flattening)%.
+// This 5% margin is pretty safe.
+const SpheroidErrorFraction = 0.05
+
+// Distance returns the distance between geographies a and b on a sphere or spheroid.
+// Returns a geo.EmptyGeometryError if any of the Geographies are EMPTY.
+func Distance(
+	a geo.Geography, b geo.Geography, useSphereOrSpheroid UseSphereOrSpheroid,
+) (float64, error) {
+	if a.SRID() != b.SRID() {
+		return 0, geo.NewMismatchingSRIDsError(a.SpatialObject(), b.SpatialObject())
+	}
+
+	aRegions, err := a.AsS2(geo.EmptyBehaviorError)
+	if err != nil {
+		return 0, err
+	}
+	bRegions, err := b.AsS2(geo.EmptyBehaviorError)
+	if err != nil {
+		return 0, err
+	}
+	if BoundingBoxHasNaNCoordinates(a) {
+		return 0, geo.OutOfRangeError()
+	}
+	if BoundingBoxHasNaNCoordinates(b) {
+		return 0, geo.OutOfRangeError()
+	}
+	spheroid, err := spheroidFromGeography(a)
+	if err != nil {
+		return 0, err
+	}
+	return distanceGeographyRegions(
+		spheroid,
+		useSphereOrSpheroid,
+		aRegions,
+		bRegions,
+		a.BoundingRect().Intersects(b.BoundingRect()),
+		0, /* stopAfter */
+		geo.FnInclusive,
+	)
+}
+
+//
+// Spheroids
+//
+
+// s2GeodistLineString implements geodist.LineString.
+type s2GeodistLineString struct {
+	*s2.Polyline
+}
+
+var _ geodist.LineString = (*s2GeodistLineString)(nil)
+
+// IsShape implements the geodist.LineString interface.
+func (*s2GeodistLineString) IsShape() {}
+
+// LineString implements the geodist.LineString interface.
+func (*s2GeodistLineString) IsLineString() {}
+
+// Edge implements the geodist.LineString interface.
+func (g *s2GeodistLineString) Edge(i int) geodist.Edge {
+	return geodist.Edge{
+		V0: geodist.Point{GeogPoint: (*g.Polyline)[i]},
+		V1: geodist.Point{GeogPoint: (*g.Polyline)[i+1]},
+	}
+}
+
+// NumEdges implements the geodist.LineString interface.
+func (g *s2GeodistLineString) NumEdges() int {
+	return len(*g.Polyline) - 1
+}
+
+// Vertex implements the geodist.LineString interface.
+func (g *s2GeodistLineString) Vertex(i int) geodist.Point {
+	return geodist.Point{
+		GeogPoint: (*g.Polyline)[i],
+	}
+}
+
+// NumVertexes implements the geodist.LineString interface.
+func (g *s2GeodistLineString) NumVertexes() int {
+	return len(*g.Polyline)
+}
+
+// s2GeodistLinearRing implements geodist.LinearRing.
+type s2GeodistLinearRing struct {
+	*s2.Loop
+}
+
+var _ geodist.LinearRing = (*s2GeodistLinearRing)(nil)
+
+// IsShape implements the geodist.LinearRing interface.
+func (*s2GeodistLinearRing) IsShape() {}
+
+// LinearRing implements the geodist.LinearRing interface.
+func (*s2GeodistLinearRing) IsLinearRing() {}
+
+// Edge implements the geodist.LinearRing interface.
+func (g *s2GeodistLinearRing) Edge(i int) geodist.Edge {
+	return geodist.Edge{
+		V0: geodist.Point{GeogPoint: g.Loop.Vertex(i)},
+		V1: geodist.Point{GeogPoint: g.Loop.Vertex(i + 1)},
+	}
+}
+
+// NumEdges implements the geodist.LinearRing interface.
+func (g *s2GeodistLinearRing) NumEdges() int {
+	return g.Loop.NumEdges()
+}
+
+// Vertex implements the geodist.LinearRing interface.
+func (g *s2GeodistLinearRing) Vertex(i int) geodist.Point {
+	return geodist.Point{
+		GeogPoint: g.Loop.Vertex(i),
+	}
+}
+
+// NumVertexes implements the geodist.LinearRing interface.
+func (g *s2GeodistLinearRing) NumVertexes() int {
+	return g.Loop.NumVertices()
+}
+
+// s2GeodistPolygon implements geodist.Polygon.
+type s2GeodistPolygon struct {
+	*s2.Polygon
+}
+
+var _ geodist.Polygon = (*s2GeodistPolygon)(nil)
+
+// IsShape implements the geodist.Polygon interface.
+func (*s2GeodistPolygon) IsShape() {}
+
+// Polygon implements the geodist.Polygon interface.
+func (*s2GeodistPolygon) IsPolygon() {}
+
+// LinearRing implements the geodist.Polygon interface.
+func (g *s2GeodistPolygon) LinearRing(i int) geodist.LinearRing {
+	return &s2GeodistLinearRing{Loop: g.Polygon.Loop(i)}
+}
+
+// NumLinearRings implements the geodist.Polygon interface.
+func (g *s2GeodistPolygon) NumLinearRings() int {
+	return g.Polygon.NumLoops()
+}
+
+// s2GeodistEdgeCrosser implements geodist.EdgeCrosser.
+type s2GeodistEdgeCrosser struct {
+	*s2.EdgeCrosser
+}
+
+var _ geodist.EdgeCrosser = (*s2GeodistEdgeCrosser)(nil)
+
+// ChainCrossing implements geodist.EdgeCrosser.
+func (c *s2GeodistEdgeCrosser) ChainCrossing(p geodist.Point) (bool, geodist.Point) {
+	// Returns nil for the intersection point as we don't require the intersection
+	// point as we do not have to implement ShortestLine in geography.
+	return c.EdgeCrosser.ChainCrossingSign(p.GeogPoint) != s2.DoNotCross, geodist.Point{}
+}
+
+// distanceGeographyRegions calculates the distance between two sets of regions.
+// If inclusive, it will quit if it finds a distance that is less than or equal
+// to stopAfter. Otherwise, it will quit if a distance less than stopAfter is
+// found. It is not guaranteed to find the absolute minimum distance if
+// stopAfter > 0.
+//
+// !!! SURPRISING BEHAVIOR WARNING FOR SPHEROIDS !!!
+// PostGIS evaluates the distance between spheroid regions by computing the min of
+// the pair-wise distance between the cross-product of the regions in A and the regions
+// in B, where the pair-wise distance is computed as:
+//   - Find the two closest points between the pairs of regions using the sphere
+//     for distance calculations.
+//   - Compute the spheroid distance between the two closest points.
+//
+// This is technically incorrect, since it is possible that the two closest points on
+// the spheroid are different than the two closest points on the sphere.
+// See distance_test.go for examples of the "truer" distance values.
+// Since we aim to be compatible with PostGIS, we adopt the same approach.
+func distanceGeographyRegions(
+	spheroid geoprojbase.Spheroid,
+	useSphereOrSpheroid UseSphereOrSpheroid,
+	aRegions []s2.Region,
+	bRegions []s2.Region,
+	boundingBoxIntersects bool,
+	stopAfter float64,
+	exclusivity geo.FnExclusivity,
+) (float64, error) {
+	minDistance := math.MaxFloat64
+	for _, aRegion := range aRegions {
+		aGeodist, err := regionToGeodistShape(aRegion)
+		if err != nil {
+			return 0, err
+		}
+		for _, bRegion := range bRegions {
+			minDistanceUpdater := newGeographyMinDistanceUpdater(
+				spheroid,
+				useSphereOrSpheroid,
+				stopAfter,
+				exclusivity,
+			)
+			bGeodist, err := regionToGeodistShape(bRegion)
+			if err != nil {
+				return 0, err
+			}
+			earlyExit, err := geodist.ShapeDistance(
+				&geographyDistanceCalculator{
+					updater:               minDistanceUpdater,
+					boundingBoxIntersects: boundingBoxIntersects,
+				},
+				aGeodist,
+				bGeodist,
+			)
+			if err != nil {
+				return 0, err
+			}
+			minDistance = math.Min(minDistance, minDistanceUpdater.Distance())
+			if earlyExit {
+				return minDistance, nil
+			}
+		}
+	}
+	return minDistance, nil
+}
+
+// geographyMinDistanceUpdater finds the minimum distance using a sphere.
+// Methods will return early if it finds a minimum distance <= stopAfterLE.
+type geographyMinDistanceUpdater struct {
+	spheroid            geoprojbase.Spheroid
+	useSphereOrSpheroid UseSphereOrSpheroid
+	minEdge             s2.Edge
+	minD                s1.ChordAngle
+	stopAfter           s1.ChordAngle
+	exclusivity         geo.FnExclusivity
+}
+
+var _ geodist.DistanceUpdater = (*geographyMinDistanceUpdater)(nil)
+
+// newGeographyMinDistanceUpdater returns a new geographyMinDistanceUpdater with the
+// correct arguments set up.
+func newGeographyMinDistanceUpdater(
+	spheroid geoprojbase.Spheroid,
+	useSphereOrSpheroid UseSphereOrSpheroid,
+	stopAfter float64,
+	exclusivity geo.FnExclusivity,
+) *geographyMinDistanceUpdater {
+	multiplier := 1.0
+	if useSphereOrSpheroid == UseSpheroid {
+		// Modify the stopAfterLE distance to be less by the error fraction, since
+		// we use the sphere to calculate the distance and we want to leave a
+		// buffer for spheroid distances being slightly off.
+		multiplier -= SpheroidErrorFraction
+	}
+	stopAfterChordAngle := s1.ChordAngleFromAngle(s1.Angle(stopAfter * multiplier / spheroid.SphereRadius()))
+	return &geographyMinDistanceUpdater{
+		spheroid:            spheroid,
+		minD:                math.MaxFloat64,
+		useSphereOrSpheroid: useSphereOrSpheroid,
+		stopAfter:           stopAfterChordAngle,
+		exclusivity:         exclusivity,
+	}
+}
+
+// Distance implements the DistanceUpdater interface.
+func (u *geographyMinDistanceUpdater) Distance() float64 {
+	// If the distance is zero, avoid the call to spheroidDistance and return early.
+	if u.minD == 0 {
+		return 0
+	}
+	if u.useSphereOrSpheroid == UseSpheroid {
+		return spheroidDistance(u.spheroid, u.minEdge.V0, u.minEdge.V1)
+	}
+	return u.minD.Angle().Radians() * u.spheroid.SphereRadius()
+}
+
+// Update implements the geodist.DistanceUpdater interface.
+func (u *geographyMinDistanceUpdater) Update(aPoint geodist.Point, bPoint geodist.Point) bool {
+	a := aPoint.GeogPoint
+	b := bPoint.GeogPoint
+
+	sphereDistance := s2.ChordAngleBetweenPoints(a, b)
+	if sphereDistance < u.minD {
+		u.minD = sphereDistance
+		u.minEdge = s2.Edge{V0: a, V1: b}
+		// If we have a threshold, determine if we can stop early.
+		// If the sphere distance is within range of the stopAfter, we can
+		// definitively say we've reach the close enough point.
+		if (u.exclusivity == geo.FnInclusive && u.minD <= u.stopAfter) ||
+			(u.exclusivity == geo.FnExclusive && u.minD < u.stopAfter) {
+			return true
+		}
+	}
+	return false
+}
+
+// OnIntersects implements the geodist.DistanceUpdater interface.
+func (u *geographyMinDistanceUpdater) OnIntersects(p geodist.Point) bool {
+	u.minD = 0
+	return true
+}
+
+// IsMaxDistance implements the geodist.DistanceUpdater interface.
+func (u *geographyMinDistanceUpdater) IsMaxDistance() bool {
+	return false
+}
+
+// FlipGeometries implements the geodist.DistanceUpdater interface.
+func (u *geographyMinDistanceUpdater) FlipGeometries() {
+	// FlipGeometries is unimplemented for geographyMinDistanceUpdater as we don't
+	// require the order of geometries for calculation of minimum distance.
+}
+
+// geographyDistanceCalculator implements geodist.DistanceCalculator
+type geographyDistanceCalculator struct {
+	updater               *geographyMinDistanceUpdater
+	boundingBoxIntersects bool
+}
+
+var _ geodist.DistanceCalculator = (*geographyDistanceCalculator)(nil)
+
+// DistanceUpdater implements geodist.DistanceCalculator.
+func (c *geographyDistanceCalculator) DistanceUpdater() geodist.DistanceUpdater {
+	return c.updater
+}
+
+// BoundingBoxIntersects implements geodist.DistanceCalculator.
+func (c *geographyDistanceCalculator) BoundingBoxIntersects() bool {
+	return c.boundingBoxIntersects
+}
+
+// NewEdgeCrosser implements geodist.DistanceCalculator.
+func (c *geographyDistanceCalculator) NewEdgeCrosser(
+	edge geodist.Edge, startPoint geodist.Point,
+) geodist.EdgeCrosser {
+	return &s2GeodistEdgeCrosser{
+		EdgeCrosser: s2.NewChainEdgeCrosser(
+			edge.V0.GeogPoint,
+			edge.V1.GeogPoint,
+			startPoint.GeogPoint,
+		),
+	}
+}
+
+// PointIntersectsLinearRing implements geodist.DistanceCalculator.
+func (c *geographyDistanceCalculator) PointIntersectsLinearRing(
+	point geodist.Point, polygon geodist.LinearRing,
+) bool {
+	return polygon.(*s2GeodistLinearRing).ContainsPoint(point.GeogPoint)
+}
+
+// ClosestPointToEdge implements geodist.DistanceCalculator.
+//
+// ClosestPointToEdge projects the point onto the infinite line represented
+// by the edge. This will return the point on the line closest to the edge.
+// It will return the closest point on the line, as well as a bool representing
+// whether the point that is projected lies directly on the edge as a segment.
+//
+// For visualization and more, see: Section 6 / Figure 4 of
+// "Projective configuration theorems: old wine into new wineskins", Tabachnikov, Serge, 2016/07/16
+func (c *geographyDistanceCalculator) ClosestPointToEdge(
+	edge geodist.Edge, point geodist.Point,
+) (geodist.Point, bool) {
+	eV0 := edge.V0.GeogPoint
+	eV1 := edge.V1.GeogPoint
+
+	// Project the point onto the normal of the edge. A great circle passing through
+	// the normal and the point will intersect with the great circle represented
+	// by the given edge.
+	normal := eV0.Vector.Cross(eV1.Vector).Normalize()
+	// To find the point where the great circle represented by the edge and the
+	// great circle represented by (normal, point), we project the point
+	// onto the normal.
+	normalScaledToPoint := normal.Mul(normal.Dot(point.GeogPoint.Vector))
+	// The difference between the point and the projection of the normal when normalized
+	// should give us a point on the great circle which contains the vertexes of the edge.
+	closestPoint := s2.Point{Vector: point.GeogPoint.Vector.Sub(normalScaledToPoint).Normalize()}
+	// We then check whether the given point lies on the geodesic of the edge,
+	// as the above algorithm only generates a point on the great circle
+	// represented by the edge.
+	return geodist.Point{GeogPoint: closestPoint}, (&s2.Polyline{eV0, eV1}).IntersectsCell(s2.CellFromPoint(closestPoint))
+}
+
+// regionToGeodistShape converts the s2 Region to a geodist object.
+func regionToGeodistShape(r s2.Region) (geodist.Shape, error) {
+	switch r := r.(type) {
+	case s2.Point:
+		return &geodist.Point{GeogPoint: r}, nil
+	case *s2.Polyline:
+		return &s2GeodistLineString{Polyline: r}, nil
+	case *s2.Polygon:
+		return &s2GeodistPolygon{Polygon: r}, nil
+	}
+	return nil, pgerror.Newf(pgcode.InvalidParameterValue, "unknown region: %T", r)
+}
diff --git a/pkg/geo/geogfn/dwithin.go b/pkg/geo/geogfn/dwithin.go
new file mode 100644
index 0000000..509b486
--- /dev/null
+++ b/pkg/geo/geogfn/dwithin.go
@@ -0,0 +1,75 @@
+// Copyright 2020 The Cockroach Authors.
+//
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
+
+package geogfn
+
+import (
+	"github.com/cockroachdb/cockroachdb-parser/pkg/geo"
+	"github.com/cockroachdb/cockroachdb-parser/pkg/sql/pgwire/pgcode"
+	"github.com/cockroachdb/cockroachdb-parser/pkg/sql/pgwire/pgerror"
+	"github.com/golang/geo/s1"
+)
+
+// DWithin returns whether a is within distance d of b. If A or B contains empty
+// Geography objects, this will return false. If inclusive, DWithin is
+// equivalent to Distance(a, b) <= d. Otherwise, DWithin is instead equivalent
+// to Distance(a, b) < d.
+func DWithin(
+	a geo.Geography,
+	b geo.Geography,
+	distance float64,
+	useSphereOrSpheroid UseSphereOrSpheroid,
+	exclusivity geo.FnExclusivity,
+) (bool, error) {
+	if a.SRID() != b.SRID() {
+		return false, geo.NewMismatchingSRIDsError(a.SpatialObject(), b.SpatialObject())
+	}
+	if distance < 0 {
+		return false, pgerror.Newf(pgcode.InvalidParameterValue, "dwithin distance cannot be less than zero")
+	}
+	spheroid, err := spheroidFromGeography(a)
+	if err != nil {
+		return false, err
+	}
+
+	angleToExpand := s1.Angle(distance / spheroid.SphereRadius())
+	if useSphereOrSpheroid == UseSpheroid {
+		angleToExpand *= (1 + SpheroidErrorFraction)
+	}
+	if !a.BoundingCap().Expanded(angleToExpand).Intersects(b.BoundingCap()) {
+		return false, nil
+	}
+
+	aRegions, err := a.AsS2(geo.EmptyBehaviorError)
+	if err != nil {
+		if geo.IsEmptyGeometryError(err) {
+			return false, nil
+		}
+		return false, err
+	}
+	bRegions, err := b.AsS2(geo.EmptyBehaviorError)
+	if err != nil {
+		if geo.IsEmptyGeometryError(err) {
+			return false, nil
+		}
+		return false, err
+	}
+	maybeClosestDistance, err := distanceGeographyRegions(
+		spheroid,
+		useSphereOrSpheroid,
+		aRegions,
+		bRegions,
+		a.BoundingRect().Intersects(b.BoundingRect()),
+		distance,
+		exclusivity,
+	)
+	if err != nil {
+		return false, err
+	}
+	if exclusivity == geo.FnExclusive {
+		return maybeClosestDistance < distance, nil
+	}
+	return maybeClosestDistance <= distance, nil
+}
diff --git a/pkg/geo/geogfn/geogfn.go b/pkg/geo/geogfn/geogfn.go
new file mode 100644
index 0000000..6934e56
--- /dev/null
+++ b/pkg/geo/geogfn/geogfn.go
@@ -0,0 +1,17 @@
+// Copyright 2020 The Cockroach Authors.
+//
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
+
+package geogfn
+
+// UseSphereOrSpheroid indicates whether to use a Sphere or Spheroid
+// for certain calculations.
+type UseSphereOrSpheroid bool
+
+const (
+	// UseSpheroid indicates to use the spheroid for calculations.
+	UseSpheroid UseSphereOrSpheroid = true
+	// UseSphere indicates to use the sphere for calculations.
+	UseSphere UseSphereOrSpheroid = false
+)
diff --git a/pkg/geo/geogfn/intersects.go b/pkg/geo/geogfn/intersects.go
new file mode 100644
index 0000000..ad71adb
--- /dev/null
+++ b/pkg/geo/geogfn/intersects.go
@@ -0,0 +1,132 @@
+// Copyright 2020 The Cockroach Authors.
+//
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
+
+package geogfn
+
+import (
+	"github.com/cockroachdb/cockroachdb-parser/pkg/geo"
+	"github.com/cockroachdb/cockroachdb-parser/pkg/sql/pgwire/pgcode"
+	"github.com/cockroachdb/cockroachdb-parser/pkg/sql/pgwire/pgerror"
+	"github.com/golang/geo/s2"
+)
+
+// Intersects returns whether geography A intersects geography B.
+// This calculation is done on the sphere.
+// Precision of intersect measurements is up to 1cm.
+func Intersects(a geo.Geography, b geo.Geography) (bool, error) {
+	if !a.BoundingRect().Intersects(b.BoundingRect()) {
+		return false, nil
+	}
+	if a.SRID() != b.SRID() {
+		return false, geo.NewMismatchingSRIDsError(a.SpatialObject(), b.SpatialObject())
+	}
+
+	aRegions, err := a.AsS2(geo.EmptyBehaviorOmit)
+	if err != nil {
+		return false, err
+	}
+	bRegions, err := b.AsS2(geo.EmptyBehaviorOmit)
+	if err != nil {
+		return false, err
+	}
+	// If any of aRegions intersects any of bRegions, return true.
+	for _, aRegion := range aRegions {
+		for _, bRegion := range bRegions {
+			intersects, err := singleRegionIntersects(aRegion, bRegion)
+			if err != nil {
+				return false, err
+			}
+			if intersects {
+				return true, nil
+			}
+		}
+	}
+	return false, nil
+}
+
+// singleRegionIntersects returns true if aRegion intersects bRegion.
+func singleRegionIntersects(aRegion s2.Region, bRegion s2.Region) (bool, error) {
+	switch aRegion := aRegion.(type) {
+	case s2.Point:
+		switch bRegion := bRegion.(type) {
+		case s2.Point:
+			return aRegion.IntersectsCell(s2.CellFromPoint(bRegion)), nil
+		case *s2.Polyline:
+			return bRegion.IntersectsCell(s2.CellFromPoint(aRegion)), nil
+		case *s2.Polygon:
+			return bRegion.IntersectsCell(s2.CellFromPoint(aRegion)), nil
+		default:
+			return false, pgerror.Newf(pgcode.InvalidParameterValue, "unknown s2 type of b: %#v", bRegion)
+		}
+	case *s2.Polyline:
+		switch bRegion := bRegion.(type) {
+		case s2.Point:
+			return aRegion.IntersectsCell(s2.CellFromPoint(bRegion)), nil
+		case *s2.Polyline:
+			return polylineIntersectsPolyline(aRegion, bRegion), nil
+		case *s2.Polygon:
+			return polygonIntersectsPolyline(bRegion, aRegion), nil
+		default:
+			return false, pgerror.Newf(pgcode.InvalidParameterValue, "unknown s2 type of b: %#v", bRegion)
+		}
+	case *s2.Polygon:
+		switch bRegion := bRegion.(type) {
+		case s2.Point:
+			return aRegion.IntersectsCell(s2.CellFromPoint(bRegion)), nil
+		case *s2.Polyline:
+			return polygonIntersectsPolyline(aRegion, bRegion), nil
+		case *s2.Polygon:
+			return aRegion.Intersects(bRegion), nil
+		default:
+			return false, pgerror.Newf(pgcode.InvalidParameterValue, "unknown s2 type of b: %#v", bRegion)
+		}
+	}
+	return false, pgerror.Newf(pgcode.InvalidParameterValue, "unknown s2 type of a: %#v", aRegion)
+}
+
+// polylineIntersectsPolyline returns whether polyline a intersects with
+// polyline b.
+func polylineIntersectsPolyline(a *s2.Polyline, b *s2.Polyline) bool {
+	for aEdgeIdx, aNumEdges := 0, a.NumEdges(); aEdgeIdx < aNumEdges; aEdgeIdx++ {
+		edge := a.Edge(aEdgeIdx)
+		crosser := s2.NewChainEdgeCrosser(edge.V0, edge.V1, (*b)[0])
+		for _, nextVertex := range (*b)[1:] {
+			crossing := crosser.ChainCrossingSign(nextVertex)
+			if crossing != s2.DoNotCross {
+				return true
+			}
+		}
+	}
+	return false
+}
+
+// polygonIntersectsPolyline returns whether polygon a intersects with
+// polyline b.
+func polygonIntersectsPolyline(a *s2.Polygon, b *s2.Polyline) bool {
+	// Check if the polygon contains any vertex of the line b.
+	for _, vertex := range *b {
+		if a.IntersectsCell(s2.CellFromPoint(vertex)) {
+			return true
+		}
+	}
+	// Here the polygon does not contain any vertex of the polyline.
+	// The polyline can intersect the polygon if a line goes through the polygon
+	// with both vertexes that are not in the interior of the polygon.
+	// This technique works for holes touching, or holes touching the exterior
+	// as the point in which the holes touch is considered an intersection.
+	for _, loop := range a.Loops() {
+		for loopEdgeIdx, loopNumEdges := 0, loop.NumEdges(); loopEdgeIdx < loopNumEdges; loopEdgeIdx++ {
+			loopEdge := loop.Edge(loopEdgeIdx)
+			crosser := s2.NewChainEdgeCrosser(loopEdge.V0, loopEdge.V1, (*b)[0])
+			for _, nextVertex := range (*b)[1:] {
+				crossing := crosser.ChainCrossingSign(nextVertex)
+				if crossing != s2.DoNotCross {
+					return true
+				}
+			}
+		}
+	}
+	return false
+}
diff --git a/pkg/geo/geogfn/segmentize.go b/pkg/geo/geogfn/segmentize.go
new file mode 100644
index 0000000..52f5f4f
--- /dev/null
+++ b/pkg/geo/geogfn/segmentize.go
@@ -0,0 +1,107 @@
+// Copyright 2020 The Cockroach Authors.
+//
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
+
+package geogfn
+
+import (
+	"math"
+
+	"github.com/cockroachdb/cockroachdb-parser/pkg/geo"
+	"github.com/cockroachdb/cockroachdb-parser/pkg/geo/geosegmentize"
+	"github.com/cockroachdb/cockroachdb-parser/pkg/sql/pgwire/pgcode"
+	"github.com/cockroachdb/cockroachdb-parser/pkg/sql/pgwire/pgerror"
+	"github.com/golang/geo/s2"
+	"github.com/twpayne/go-geom"
+)
+
+// Segmentize return modified Geography having no segment longer
+// that given maximum segment length.
+// This works by dividing each segment by a power of 2 to find the
+// smallest power less than or equal to the segmentMaxLength.
+func Segmentize(geography geo.Geography, segmentMaxLength float64) (geo.Geography, error) {
+	if math.IsNaN(segmentMaxLength) || math.IsInf(segmentMaxLength, 1 /* sign */) {
+		return geography, nil
+	}
+	geometry, err := geography.AsGeomT()
+	if err != nil {
+		return geo.Geography{}, err
+	}
+	switch geometry := geometry.(type) {
+	case *geom.Point, *geom.MultiPoint:
+		return geography, nil
+	default:
+		if segmentMaxLength <= 0 {
+			return geo.Geography{}, pgerror.Newf(pgcode.InvalidParameterValue, "maximum segment length must be positive")
+		}
+		spheroid, err := spheroidFromGeography(geography)
+		if err != nil {
+			return geo.Geography{}, err
+		}
+		// Convert segmentMaxLength to Angle with respect to earth sphere as
+		// further calculation is done considering segmentMaxLength as Angle.
+		segmentMaxAngle := segmentMaxLength / spheroid.SphereRadius()
+		ret, err := geosegmentize.Segmentize(geometry, segmentMaxAngle, segmentizeCoords)
+		if err != nil {
+			return geo.Geography{}, err
+		}
+		return geo.MakeGeographyFromGeomT(ret)
+	}
+}
+
+// segmentizeCoords inserts multiple points between given two coordinates and
+// return resultant point as flat []float64. Such that distance between any two
+// points is less than given maximum segment's length, the total number of
+// segments is the power of 2, and all the segments are of the same length.
+// Note: List of points does not consist of end point.
+func segmentizeCoords(a geom.Coord, b geom.Coord, segmentMaxAngle float64) ([]float64, error) {
+	if len(a) != len(b) {
+		return nil, pgerror.Newf(pgcode.InvalidParameterValue, "cannot segmentize two coordinates of different dimensions")
+	}
+	if segmentMaxAngle <= 0 {
+		return nil, pgerror.Newf(pgcode.InvalidParameterValue, "maximum segment angle must be positive")
+	}
+
+	// Converted geom.Coord into s2.Point so we can segmentize the coordinates.
+	pointA := s2.PointFromLatLng(s2.LatLngFromDegrees(a.Y(), a.X()))
+	pointB := s2.PointFromLatLng(s2.LatLngFromDegrees(b.Y(), b.X()))
+
+	chordAngleBetweenPoints := s2.ChordAngleBetweenPoints(pointA, pointB).Angle().Radians()
+	// PostGIS' behavior appears to involve cutting this down into segments divisible
+	// by a power of two. As such, we do not use ceil(chordAngleBetweenPoints/segmentMaxAngle).
+	//
+	// This calculation determines the smallest power of 2 that is greater
+	// than ceil(chordAngleBetweenPoints/segmentMaxAngle).
+	//
+	// We can write that power as 2^n in the following inequality
+	// 2^n >= ceil(chordAngleBetweenPoints/segmentMaxLength) > 2^(n-1).
+	// We can drop the ceil since 2^n must be an int
+	// 2^n >= chordAngleBetweenPoints/segmentMaxLength > 2^(n-1).
+	// Then n = ceil(log2(chordAngleBetweenPoints/segmentMaxLength)).
+	// Hence numberOfSegmentsToCreate = 2^(ceil(log2(chordAngleBetweenPoints/segmentMaxLength))).
+	doubleNumberOfSegmentsToCreate := math.Pow(2, math.Ceil(math.Log2(chordAngleBetweenPoints/segmentMaxAngle)))
+	doubleNumPoints := float64(len(a)) * (1 + doubleNumberOfSegmentsToCreate)
+	if err := geosegmentize.CheckSegmentizeValidNumPoints(doubleNumPoints, a, b); err != nil {
+		return nil, err
+	}
+	numberOfSegmentsToCreate := int(doubleNumberOfSegmentsToCreate)
+	numPoints := int(doubleNumPoints)
+
+	allSegmentizedCoordinates := make([]float64, 0, numPoints)
+	allSegmentizedCoordinates = append(allSegmentizedCoordinates, a.Clone()...)
+	segmentFraction := 1.0 / float64(numberOfSegmentsToCreate)
+	for pointInserted := 1; pointInserted < numberOfSegmentsToCreate; pointInserted++ {
+		newPoint := s2.Interpolate(float64(pointInserted)/float64(numberOfSegmentsToCreate), pointA, pointB)
+		latLng := s2.LatLngFromPoint(newPoint)
+		allSegmentizedCoordinates = append(allSegmentizedCoordinates, latLng.Lng.Degrees(), latLng.Lat.Degrees())
+		// Linearly interpolate Z and/or M coordinates.
+		for i := 2; i < len(a); i++ {
+			allSegmentizedCoordinates = append(
+				allSegmentizedCoordinates,
+				a[i]*(1-float64(pointInserted)*segmentFraction)+b[i]*(float64(pointInserted)*segmentFraction),
+			)
+		}
+	}
+	return allSegmentizedCoordinates, nil
+}
diff --git a/pkg/geo/geogfn/spheroid.go b/pkg/geo/geogfn/spheroid.go
new file mode 100644
index 0000000..c80bef3
--- /dev/null
+++ b/pkg/geo/geogfn/spheroid.go
@@ -0,0 +1,29 @@
+// Copyright 2020 The Cockroach Authors.
+//
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
+
+package geogfn
+
+import (
+	"github.com/cockroachdb/cockroachdb-parser/pkg/geo"
+	// Blank import so projections are initialized correctly.
+	_ "github.com/cockroachdb/cockroachdb-parser/pkg/geo/geographiclib"
+	"github.com/cockroachdb/cockroachdb-parser/pkg/geo/geoprojbase"
+	"github.com/golang/geo/s2"
+)
+
+// spheroidDistance returns the s12 (meter) component of spheroid.Inverse from s2 Points.
+func spheroidDistance(s geoprojbase.Spheroid, a s2.Point, b s2.Point) float64 {
+	inv, _, _ := s.Inverse(s2.LatLngFromPoint(a), s2.LatLngFromPoint(b))
+	return inv
+}
+
+// spheroid returns the spheroid represented by the given Geography.
+func spheroidFromGeography(g geo.Geography) (geoprojbase.Spheroid, error) {
+	proj, err := geoprojbase.Projection(g.SRID())
+	if err != nil {
+		return nil, err
+	}
+	return proj.Spheroid, nil
+}
diff --git a/pkg/geo/geogfn/topology_operations.go b/pkg/geo/geogfn/topology_operations.go
new file mode 100644
index 0000000..b0bdc7c
--- /dev/null
+++ b/pkg/geo/geogfn/topology_operations.go
@@ -0,0 +1,137 @@
+// Copyright 2020 The Cockroach Authors.
+//
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
+
+package geogfn
+
+import (
+	"math"
+
+	"github.com/cockroachdb/cockroachdb-parser/pkg/geo"
+	"github.com/cockroachdb/cockroachdb-parser/pkg/sql/pgwire/pgcode"
+	"github.com/cockroachdb/cockroachdb-parser/pkg/sql/pgwire/pgerror"
+	"github.com/golang/geo/r3"
+	"github.com/golang/geo/s2"
+	"github.com/twpayne/go-geom"
+)
+
+// Centroid returns the Centroid of a given Geography.
+//
+// NOTE: In the case of (Multi)Polygon Centroid result, it doesn't mirror with
+// PostGIS's result. We are using the same algorithm of dividing into triangles.
+// However, The PostGIS implementation differs as it cuts triangles in a different
+// way - namely, it fixes the first point in the exterior ring as the first point
+// of the triangle, whereas we always update the reference point to be
+// the first point of the ring when moving from one ring to another.
+//
+// See: http://jennessent.com/downloads/Graphics_Shapes_Manual_A4.pdf#page=49
+// for more details.
+//
+// Ideally, both implementations should provide the same result. However, the
+// centroid of the triangles is the vectorized mean of all the points, not the
+// actual projection in the Spherical surface, which causes a small inaccuracies.
+// This inaccuracy will eventually grow if there is a substantial
+// number of a triangle with a larger area.
+func Centroid(g geo.Geography, useSphereOrSpheroid UseSphereOrSpheroid) (geo.Geography, error) {
+	geomRepr, err := g.AsGeomT()
+	if err != nil {
+		return geo.Geography{}, err
+	}
+	if geomRepr.Empty() {
+		return geo.MakeGeographyFromGeomT(geom.NewGeometryCollection().SetSRID(geomRepr.SRID()))
+	}
+	switch geomRepr.(type) {
+	case *geom.Point, *geom.LineString, *geom.Polygon, *geom.MultiPoint, *geom.MultiLineString, *geom.MultiPolygon:
+	default:
+		return geo.Geography{}, pgerror.Newf(pgcode.InvalidParameterValue, "unhandled geography type %s", g.ShapeType().String())
+	}
+
+	regions, err := geo.S2RegionsFromGeomT(geomRepr, geo.EmptyBehaviorOmit)
+	if err != nil {
+		return geo.Geography{}, err
+	}
+	spheroid, err := spheroidFromGeography(g)
+	if err != nil {
+		return geo.Geography{}, err
+	}
+
+	// localWeightedCentroids is the collection of all the centroid corresponds to
+	// various small regions in which we divide the given region for calculation
+	// of centroid. The magnitude of each s2.Point.Vector represents
+	// the weight corresponding to its region.
+	var localWeightedCentroids []s2.Point
+	for _, region := range regions {
+		switch region := region.(type) {
+		case s2.Point:
+			localWeightedCentroids = append(localWeightedCentroids, region)
+		case *s2.Polyline:
+			// The algorithm used for the calculation of centroid for (Multi)LineString:
+			//  * Split (Multi)LineString in the set of individual edges.
+			//  * Calculate the mid-points and length/angle for all the edges.
+			//  * The centroid of (Multi)LineString will be a weighted average of mid-points
+			//    of all the edges, where each mid-points is weighted by its length/angle.
+			for edgeIdx, regionNumEdges := 0, region.NumEdges(); edgeIdx < regionNumEdges; edgeIdx++ {
+				var edgeWeight float64
+				eV0 := region.Edge(edgeIdx).V0
+				eV1 := region.Edge(edgeIdx).V1
+				if useSphereOrSpheroid == UseSpheroid {
+					edgeWeight = spheroidDistance(spheroid, eV0, eV1)
+				} else {
+					edgeWeight = float64(s2.ChordAngleBetweenPoints(eV0, eV1).Angle())
+				}
+				localWeightedCentroids = append(localWeightedCentroids, s2.Point{Vector: eV0.Add(eV1.Vector).Mul(edgeWeight)})
+			}
+		case *s2.Polygon:
+			// The algorithm used for the calculation of centroid for (Multi)Polygon:
+			//  * Split (Multi)Polygon in the set of individual triangles.
+			//  * Calculate the centroid and signed area (negative area for triangle inside
+			//    the hole) for all the triangle.
+			//  * The centroid of (Multi)Polygon will be a weighted average of the centroid
+			//    of all the triangle, where each centroid is weighted by its area.
+			for _, loop := range region.Loops() {
+				triangleVertices := make([]s2.Point, 4)
+				triangleVertices[0] = loop.Vertex(0)
+				triangleVertices[3] = loop.Vertex(0)
+
+				for pointIdx := 1; pointIdx+2 < loop.NumVertices(); pointIdx++ {
+					triangleVertices[1] = loop.Vertex(pointIdx)
+					triangleVertices[2] = loop.Vertex(pointIdx + 1)
+					triangleCentroid := s2.PlanarCentroid(triangleVertices[0], triangleVertices[1], triangleVertices[2])
+					var area float64
+					if useSphereOrSpheroid == UseSpheroid {
+						area, _ = spheroid.AreaAndPerimeter(triangleVertices[:3])
+					} else {
+						area = s2.LoopFromPoints(triangleVertices).Area()
+					}
+					area = area * float64(loop.Sign())
+					localWeightedCentroids = append(localWeightedCentroids, s2.Point{Vector: triangleCentroid.Mul(area)})
+				}
+			}
+		}
+	}
+	var centroidVector r3.Vector
+	for _, point := range localWeightedCentroids {
+		centroidVector = centroidVector.Add(point.Vector)
+	}
+	latLng := s2.LatLngFromPoint(s2.Point{Vector: centroidVector.Normalize()})
+	centroid := geom.NewPointFlat(geom.XY, []float64{latLng.Lng.Degrees(), latLng.Lat.Degrees()}).SetSRID(int(g.SRID()))
+	return geo.MakeGeographyFromGeomT(centroid)
+}
+
+// BoundingBoxHasNaNCoordinates checks if the bounding box of a Geography
+// has a NaN coordinate.
+func BoundingBoxHasNaNCoordinates(g geo.Geography) bool {
+	boundingBox := g.BoundingBoxRef()
+	if boundingBox == nil {
+		return false
+	}
+	// Don't use `:= range []float64{...}` to avoid memory allocation.
+	isNaN := func(ord float64) bool {
+		return math.IsNaN(ord)
+	}
+	if isNaN(boundingBox.LoX) || isNaN(boundingBox.LoY) || isNaN(boundingBox.HiX) || isNaN(boundingBox.HiY) {
+		return true
+	}
+	return false
+}
diff --git a/pkg/geo/geogfn/unary_operators.go b/pkg/geo/geogfn/unary_operators.go
new file mode 100644
index 0000000..d7fc544
--- /dev/null
+++ b/pkg/geo/geogfn/unary_operators.go
@@ -0,0 +1,195 @@
+// Copyright 2020 The Cockroach Authors.
+//
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
+
+package geogfn
+
+import (
+	"math"
+
+	"github.com/cockroachdb/cockroachdb-parser/pkg/geo"
+	"github.com/cockroachdb/cockroachdb-parser/pkg/geo/geoprojbase"
+	"github.com/cockroachdb/cockroachdb-parser/pkg/sql/pgwire/pgcode"
+	"github.com/cockroachdb/cockroachdb-parser/pkg/sql/pgwire/pgerror"
+	"github.com/golang/geo/s1"
+	"github.com/golang/geo/s2"
+	"github.com/twpayne/go-geom"
+)
+
+// Area returns the area of a given Geography.
+func Area(g geo.Geography, useSphereOrSpheroid UseSphereOrSpheroid) (float64, error) {
+	regions, err := g.AsS2(geo.EmptyBehaviorOmit)
+	if err != nil {
+		return 0, err
+	}
+	spheroid, err := spheroidFromGeography(g)
+	if err != nil {
+		return 0, err
+	}
+
+	var totalArea float64
+	for _, region := range regions {
+		switch region := region.(type) {
+		case s2.Point, *s2.Polyline:
+		case *s2.Polygon:
+			if useSphereOrSpheroid == UseSpheroid {
+				for _, loop := range region.Loops() {
+					points := loop.Vertices()
+					area, _ := spheroid.AreaAndPerimeter(points[:len(points)-1])
+					totalArea += float64(loop.Sign()) * area
+				}
+			} else {
+				totalArea += region.Area()
+			}
+		default:
+			return 0, pgerror.Newf(pgcode.InvalidParameterValue, "unknown type: %T", region)
+		}
+	}
+	if useSphereOrSpheroid == UseSphere {
+		totalArea *= spheroid.SphereRadius() * spheroid.SphereRadius()
+	}
+	return totalArea, nil
+}
+
+// Perimeter returns the perimeter of a given Geography.
+func Perimeter(g geo.Geography, useSphereOrSpheroid UseSphereOrSpheroid) (float64, error) {
+	gt, err := g.AsGeomT()
+	if err != nil {
+		return 0, err
+	}
+	// This check mirrors PostGIS behavior, where GeometryCollections
+	// of LineStrings include the length for perimeters.
+	switch gt.(type) {
+	case *geom.Polygon, *geom.MultiPolygon, *geom.GeometryCollection:
+	default:
+		return 0, nil
+	}
+	regions, err := geo.S2RegionsFromGeomT(gt, geo.EmptyBehaviorOmit)
+	if err != nil {
+		return 0, err
+	}
+	spheroid, err := spheroidFromGeography(g)
+	if err != nil {
+		return 0, err
+	}
+	return length(regions, spheroid, useSphereOrSpheroid)
+}
+
+// Length returns length of a given Geography.
+func Length(g geo.Geography, useSphereOrSpheroid UseSphereOrSpheroid) (float64, error) {
+	gt, err := g.AsGeomT()
+	if err != nil {
+		return 0, err
+	}
+	// This check mirrors PostGIS behavior, where GeometryCollections
+	// of Polygons include the perimeters for polygons.
+	switch gt.(type) {
+	case *geom.LineString, *geom.MultiLineString, *geom.GeometryCollection:
+	default:
+		return 0, nil
+	}
+	regions, err := geo.S2RegionsFromGeomT(gt, geo.EmptyBehaviorOmit)
+	if err != nil {
+		return 0, err
+	}
+	spheroid, err := spheroidFromGeography(g)
+	if err != nil {
+		return 0, err
+	}
+	return length(regions, spheroid, useSphereOrSpheroid)
+}
+
+// Project returns calculate a projected point given a source point, a distance and a azimuth.
+func Project(g geo.Geography, distance float64, azimuth s1.Angle) (geo.Geography, error) {
+	geomT, err := g.AsGeomT()
+	if err != nil {
+		return geo.Geography{}, err
+	}
+
+	point, ok := geomT.(*geom.Point)
+	if !ok {
+		return geo.Geography{}, pgerror.Newf(pgcode.InvalidParameterValue, "ST_Project(geography) is only valid for point inputs")
+	}
+
+	spheroid, err := spheroidFromGeography(g)
+	if err != nil {
+		return geo.Geography{}, err
+	}
+
+	// Normalize distance to be positive.
+	if distance < 0.0 {
+		distance = -distance
+		azimuth += math.Pi
+	}
+
+	// Normalize azimuth
+	azimuth = azimuth.Normalized()
+
+	// Check the distance validity.
+	if distance > (math.Pi * spheroid.Radius()) {
+		return geo.Geography{}, pgerror.Newf(pgcode.InvalidParameterValue, "distance must not be greater than %f", math.Pi*spheroid.Radius())
+	}
+
+	if point.Empty() {
+		return geo.Geography{}, pgerror.Newf(pgcode.InvalidParameterValue, "cannot project POINT EMPTY")
+	}
+
+	// Convert to ta geodetic point.
+	x := point.X()
+	y := point.Y()
+
+	projected := spheroid.Project(
+		s2.LatLngFromDegrees(x, y),
+		distance,
+		azimuth,
+	)
+
+	ret := geom.NewPointFlat(
+		geom.XY,
+		[]float64{
+			geo.NormalizeLongitudeDegrees(projected.Lng.Degrees()),
+			geo.NormalizeLatitudeDegrees(projected.Lat.Degrees()),
+		},
+	).SetSRID(point.SRID())
+	return geo.MakeGeographyFromGeomT(ret)
+}
+
+// length returns the sum of the lengths and perimeters in the shapes of the Geography.
+// In OGC parlance, length returns both LineString lengths _and_ Polygon perimeters.
+func length(
+	regions []s2.Region, spheroid geoprojbase.Spheroid, useSphereOrSpheroid UseSphereOrSpheroid,
+) (float64, error) {
+	var totalLength float64
+	for _, region := range regions {
+		switch region := region.(type) {
+		case s2.Point:
+		case *s2.Polyline:
+			if useSphereOrSpheroid == UseSpheroid {
+				totalLength += spheroid.InverseBatch((*region))
+			} else {
+				for edgeIdx, regionNumEdges := 0, region.NumEdges(); edgeIdx < regionNumEdges; edgeIdx++ {
+					edge := region.Edge(edgeIdx)
+					totalLength += s2.ChordAngleBetweenPoints(edge.V0, edge.V1).Angle().Radians()
+				}
+			}
+		case *s2.Polygon:
+			for _, loop := range region.Loops() {
+				if useSphereOrSpheroid == UseSpheroid {
+					totalLength += spheroid.InverseBatch(loop.Vertices())
+				} else {
+					for edgeIdx, loopNumEdges := 0, loop.NumEdges(); edgeIdx < loopNumEdges; edgeIdx++ {
+						edge := loop.Edge(edgeIdx)
+						totalLength += s2.ChordAngleBetweenPoints(edge.V0, edge.V1).Angle().Radians()
+					}
+				}
+			}
+		default:
+			return 0, pgerror.Newf(pgcode.InvalidParameterValue, "unknown type: %T", region)
+		}
+	}
+	if useSphereOrSpheroid == UseSphere {
+		totalLength *= spheroid.SphereRadius()
+	}
+	return totalLength, nil
+}
diff --git a/pkg/geo/geographiclib/geodesic.c b/pkg/geo/geographiclib/geodesic.c
new file mode 100644
index 0000000..02887e1
--- /dev/null
+++ b/pkg/geo/geographiclib/geodesic.c
@@ -0,0 +1,2114 @@
+/**
+ * \file geodesic.c
+ * \brief Implementation of the geodesic routines in C
+ *
+ * For the full documentation see geodesic.h.
+ **********************************************************************/
+
+/** @cond SKIP */
+
+/*
+ * This is a C implementation of the geodesic algorithms described in
+ *
+ *   C. F. F. Karney,
+ *   Algorithms for geodesics,
+ *   J. Geodesy <b>87</b>, 43--55 (2013);
+ *   https://doi.org/10.1007/s00190-012-0578-z
+ *   Addenda: https://geographiclib.sourceforge.io/geod-addenda.html
+ *
+ * See the comments in geodesic.h for documentation.
+ *
+ * Copyright (c) Charles Karney (2012-2019) <charles@karney.com> and licensed
+ * under the MIT/X11 License.  For more information, see
+ * https://geographiclib.sourceforge.io/
+ */
+
+#include "geodesic.h"
+#include <math.h>
+#include <limits.h>
+#include <float.h>
+
+#if !defined(HAVE_C99_MATH)
+#if defined(PROJ_LIB)
+/* PROJ requires C99 so HAVE_C99_MATH is implicit */
+#define HAVE_C99_MATH 1
+#else
+#define HAVE_C99_MATH 0
+#endif
+#endif
+
+#if !defined(__cplusplus)
+#define nullptr 0
+#endif
+
+#define GEOGRAPHICLIB_GEODESIC_ORDER 6
+#define nA1   GEOGRAPHICLIB_GEODESIC_ORDER
+#define nC1   GEOGRAPHICLIB_GEODESIC_ORDER
+#define nC1p  GEOGRAPHICLIB_GEODESIC_ORDER
+#define nA2   GEOGRAPHICLIB_GEODESIC_ORDER
+#define nC2   GEOGRAPHICLIB_GEODESIC_ORDER
+#define nA3   GEOGRAPHICLIB_GEODESIC_ORDER
+#define nA3x  nA3
+#define nC3   GEOGRAPHICLIB_GEODESIC_ORDER
+#define nC3x  ((nC3 * (nC3 - 1)) / 2)
+#define nC4   GEOGRAPHICLIB_GEODESIC_ORDER
+#define nC4x  ((nC4 * (nC4 + 1)) / 2)
+#define nC    (GEOGRAPHICLIB_GEODESIC_ORDER + 1)
+
+typedef double real;
+typedef int boolx;
+
+static unsigned init = 0;
+static const int FALSE = 0;
+static const int TRUE = 1;
+static unsigned digits, maxit1, maxit2;
+static real epsilon, realmin, pi, degree, NaN,
+  tiny, tol0, tol1, tol2, tolb, xthresh;
+
+static void Init() {
+  if (!init) {
+    digits = DBL_MANT_DIG;
+    epsilon = DBL_EPSILON;
+    realmin = DBL_MIN;
+#if defined(M_PI)
+    pi = M_PI;
+#else
+    pi = atan2(0.0, -1.0);
+#endif
+    maxit1 = 20;
+    maxit2 = maxit1 + digits + 10;
+    tiny = sqrt(realmin);
+    tol0 = epsilon;
+    /* Increase multiplier in defn of tol1 from 100 to 200 to fix inverse case
+     * 52.784459512564 0 -52.784459512563990912 179.634407464943777557
+     * which otherwise failed for Visual Studio 10 (Release and Debug) */
+    tol1 = 200 * tol0;
+    tol2 = sqrt(tol0);
+    /* Check on bisection interval */
+    tolb = tol0 * tol2;
+    xthresh = 1000 * tol2;
+    degree = pi/180;
+#if defined(NAN)
+    NaN = NAN;                  /* NAN is defined in C99 */
+#else
+    {
+      real minus1 = -1;
+      /* cppcheck-suppress wrongmathcall */
+      NaN = sqrt(minus1);
+    }
+#endif
+    init = 1;
+  }
+}
+
+enum captype {
+  CAP_NONE = 0U,
+  CAP_C1   = 1U<<0,
+  CAP_C1p  = 1U<<1,
+  CAP_C2   = 1U<<2,
+  CAP_C3   = 1U<<3,
+  CAP_C4   = 1U<<4,
+  CAP_ALL  = 0x1FU,
+  OUT_ALL  = 0x7F80U
+};
+
+#if HAVE_C99_MATH
+#define hypotx hypot
+/* no need to redirect log1px, since it's only used by atanhx */
+#define atanhx atanh
+#define copysignx copysign
+#define cbrtx cbrt
+#define remainderx remainder
+#define remquox remquo
+#else
+/* Replacements for C99 math functions */
+
+static real hypotx(real x, real y) {
+  x = fabs(x); y = fabs(y);
+  if (x < y) {
+    x /= y;                     /* y is nonzero */
+    return y * sqrt(1 + x * x);
+  } else {
+    y /= (x != 0 ? x : 1);
+    return x * sqrt(1 + y * y);
+  }
+}
+
+static real log1px(real x) {
+  volatile real
+    y = 1 + x,
+    z = y - 1;
+  /* Here's the explanation for this magic: y = 1 + z, exactly, and z
+   * approx x, thus log(y)/z (which is nearly constant near z = 0) returns
+   * a good approximation to the true log(1 + x)/x.  The multiplication x *
+   * (log(y)/z) introduces little additional error. */
+  return z == 0 ? x : x * log(y) / z;
+}
+
+static real atanhx(real x) {
+  real y = fabs(x);             /* Enforce odd parity */
+  y = log1px(2 * y/(1 - y))/2;
+  return x > 0 ? y : (x < 0 ? -y : x); /* atanh(-0.0) = -0.0 */
+}
+
+static real copysignx(real x, real y) {
+  /* 1/y trick to get the sign of -0.0 */
+  return fabs(x) * (y < 0 || (y == 0 && 1/y < 0) ? -1 : 1);
+}
+
+static real cbrtx(real x) {
+  real y = pow(fabs(x), 1/(real)(3));  /* Return the real cube root */
+  return x > 0 ? y : (x < 0 ? -y : x); /* cbrt(-0.0) = -0.0 */
+}
+
+static real remainderx(real x, real y) {
+  real z;
+  y = fabs(y);                 /* The result doesn't depend on the sign of y */
+  z = fmod(x, y);
+  if (z == 0)
+    /* This shouldn't be necessary.  However, before version 14 (2015),
+     * Visual Studio had problems dealing with -0.0.  Specifically
+     *   VC 10,11,12 and 32-bit compile: fmod(-0.0, 360.0) -> +0.0
+     * python 2.7 on Windows 32-bit machines has the same problem. */
+    z = copysignx(z, x);
+  else if (2 * fabs(z) == y)
+    z -= fmod(x, 2 * y) - z;    /* Implement ties to even */
+  else if (2 * fabs(z) > y)
+    z += (z < 0 ? y : -y);      /* Fold remaining cases to (-y/2, y/2) */
+  return z;
+}
+
+static real remquox(real x, real y, int* n) {
+  real z = remainderx(x, y);
+  if (n) {
+    real
+      a = remainderx(x, 2 * y),
+      b = remainderx(x, 4 * y),
+      c = remainderx(x, 8 * y);
+    *n  = (a > z ? 1 : (a < z ? -1 : 0));
+    *n += (b > a ? 2 : (b < a ? -2 : 0));
+    *n += (c > b ? 4 : (c < b ? -4 : 0));
+    if (y < 0) *n *= -1;
+    if (y != 0) {
+      if (x/y > 0 && *n <= 0)
+        *n += 8;
+      else if (x/y < 0 && *n >= 0)
+        *n -= 8;
+    }
+  }
+  return z;
+}
+
+#endif
+
+static real sq(real x) { return x * x; }
+
+static real sumx(real u, real v, real* t) {
+  volatile real s = u + v;
+  volatile real up = s - v;
+  volatile real vpp = s - up;
+  up -= u;
+  vpp -= v;
+  if (t) *t = -(up + vpp);
+  /* error-free sum:
+   * u + v =       s      + t
+   *       = round(u + v) + t */
+  return s;
+}
+
+static real polyval(int N, const real p[], real x) {
+  real y = N < 0 ? 0 : *p++;
+  while (--N >= 0) y = y * x + *p++;
+  return y;
+}
+
+/* mimic C++ std::min and std::max */
+static real minx(real a, real b)
+{ return (b < a) ? b : a; }
+
+static real maxx(real a, real b)
+{ return (a < b) ? b : a; }
+
+static void swapx(real* x, real* y)
+{ real t = *x; *x = *y; *y = t; }
+
+static void norm2(real* sinx, real* cosx) {
+  real r = hypotx(*sinx, *cosx);
+  *sinx /= r;
+  *cosx /= r;
+}
+
+static real AngNormalize(real x) {
+  x = remainderx(x, (real)(360));
+  return x != -180 ? x : 180;
+}
+
+static real LatFix(real x)
+{ return fabs(x) > 90 ? NaN : x; }
+
+static real AngDiff(real x, real y, real* e) {
+  real t, d = AngNormalize(sumx(AngNormalize(-x), AngNormalize(y), &t));
+  /* Here y - x = d + t (mod 360), exactly, where d is in (-180,180] and
+   * abs(t) <= eps (eps = 2^-45 for doubles).  The only case where the
+   * addition of t takes the result outside the range (-180,180] is d = 180
+   * and t > 0.  The case, d = -180 + eps, t = -eps, can't happen, since
+   * sum would have returned the exact result in such a case (i.e., given t
+   * = 0). */
+  return sumx(d == 180 && t > 0 ? -180 : d, t, e);
+}
+
+static real AngRound(real x) {
+  const real z = 1/(real)(16);
+  volatile real y;
+  if (x == 0) return 0;
+  y = fabs(x);
+  /* The compiler mustn't "simplify" z - (z - y) to y */
+  y = y < z ? z - (z - y) : y;
+  return x < 0 ? -y : y;
+}
+
+static void sincosdx(real x, real* sinx, real* cosx) {
+  /* In order to minimize round-off errors, this function exactly reduces
+   * the argument to the range [-45, 45] before converting it to radians. */
+  real r, s, c; int q;
+  r = remquox(x, (real)(90), &q);
+  /* now abs(r) <= 45 */
+  r *= degree;
+  /* Possibly could call the gnu extension sincos */
+  s = sin(r); c = cos(r);
+#if defined(_MSC_VER) && _MSC_VER < 1900
+  /*
+   * Before version 14 (2015), Visual Studio had problems dealing
+   * with -0.0.  Specifically
+   *   VC 10,11,12 and 32-bit compile: fmod(-0.0, 360.0) -> +0.0
+   *   VC 12       and 64-bit compile:  sin(-0.0)        -> +0.0
+   * AngNormalize has a similar fix.
+   * python 2.7 on Windows 32-bit machines has the same problem.
+   */
+  if (x == 0) s = x;
+#endif
+  switch ((unsigned)q & 3U) {
+  case 0U: *sinx =  s; *cosx =  c; break;
+  case 1U: *sinx =  c; *cosx = -s; break;
+  case 2U: *sinx = -s; *cosx = -c; break;
+  default: *sinx = -c; *cosx =  s; break; /* case 3U */
+  }
+  if (x != 0) { *sinx += (real)(0); *cosx += (real)(0); }
+}
+
+static real atan2dx(real y, real x) {
+  /* In order to minimize round-off errors, this function rearranges the
+   * arguments so that result of atan2 is in the range [-pi/4, pi/4] before
+   * converting it to degrees and mapping the result to the correct
+   * quadrant. */
+  int q = 0; real ang;
+  if (fabs(y) > fabs(x)) { swapx(&x, &y); q = 2; }
+  if (x < 0) { x = -x; ++q; }
+  /* here x >= 0 and x >= abs(y), so angle is in [-pi/4, pi/4] */
+  ang = atan2(y, x) / degree;
+  switch (q) {
+    /* Note that atan2d(-0.0, 1.0) will return -0.  However, we expect that
+     * atan2d will not be called with y = -0.  If need be, include
+     *
+     *   case 0: ang = 0 + ang; break;
+     */
+  case 1: ang = (y >= 0 ? 180 : -180) - ang; break;
+  case 2: ang =  90 - ang; break;
+  case 3: ang = -90 + ang; break;
+  }
+  return ang;
+}
+
+static void A3coeff(struct geod_geodesic* g);
+static void C3coeff(struct geod_geodesic* g);
+static void C4coeff(struct geod_geodesic* g);
+static real SinCosSeries(boolx sinp,
+                         real sinx, real cosx,
+                         const real c[], int n);
+static void Lengths(const struct geod_geodesic* g,
+                    real eps, real sig12,
+                    real ssig1, real csig1, real dn1,
+                    real ssig2, real csig2, real dn2,
+                    real cbet1, real cbet2,
+                    real* ps12b, real* pm12b, real* pm0,
+                    real* pM12, real* pM21,
+                    /* Scratch area of the right size */
+                    real Ca[]);
+static real Astroid(real x, real y);
+static real InverseStart(const struct geod_geodesic* g,
+                         real sbet1, real cbet1, real dn1,
+                         real sbet2, real cbet2, real dn2,
+                         real lam12, real slam12, real clam12,
+                         real* psalp1, real* pcalp1,
+                         /* Only updated if return val >= 0 */
+                         real* psalp2, real* pcalp2,
+                         /* Only updated for short lines */
+                         real* pdnm,
+                         /* Scratch area of the right size */
+                         real Ca[]);
+static real Lambda12(const struct geod_geodesic* g,
+                     real sbet1, real cbet1, real dn1,
+                     real sbet2, real cbet2, real dn2,
+                     real salp1, real calp1,
+                     real slam120, real clam120,
+                     real* psalp2, real* pcalp2,
+                     real* psig12,
+                     real* pssig1, real* pcsig1,
+                     real* pssig2, real* pcsig2,
+                     real* peps,
+                     real* pdomg12,
+                     boolx diffp, real* pdlam12,
+                     /* Scratch area of the right size */
+                     real Ca[]);
+static real A3f(const struct geod_geodesic* g, real eps);
+static void C3f(const struct geod_geodesic* g, real eps, real c[]);
+static void C4f(const struct geod_geodesic* g, real eps, real c[]);
+static real A1m1f(real eps);
+static void C1f(real eps, real c[]);
+static void C1pf(real eps, real c[]);
+static real A2m1f(real eps);
+static void C2f(real eps, real c[]);
+static int transit(real lon1, real lon2);
+static int transitdirect(real lon1, real lon2);
+static void accini(real s[]);
+static void acccopy(const real s[], real t[]);
+static void accadd(real s[], real y);
+static real accsum(const real s[], real y);
+static void accneg(real s[]);
+static void accrem(real s[], real y);
+static real areareduceA(real area[], real area0,
+                        int crossings, boolx reverse, boolx sign);
+static real areareduceB(real area, real area0,
+                        int crossings, boolx reverse, boolx sign);
+
+void geod_init(struct geod_geodesic* g, real a, real f) {
+  if (!init) Init();
+  g->a = a;
+  g->f = f;
+  g->f1 = 1 - g->f;
+  g->e2 = g->f * (2 - g->f);
+  g->ep2 = g->e2 / sq(g->f1);   /* e2 / (1 - e2) */
+  g->n = g->f / ( 2 - g->f);
+  g->b = g->a * g->f1;
+  g->c2 = (sq(g->a) + sq(g->b) *
+           (g->e2 == 0 ? 1 :
+            (g->e2 > 0 ? atanhx(sqrt(g->e2)) : atan(sqrt(-g->e2))) /
+            sqrt(fabs(g->e2))))/2; /* authalic radius squared */
+  /* The sig12 threshold for "really short".  Using the auxiliary sphere
+   * solution with dnm computed at (bet1 + bet2) / 2, the relative error in the
+   * azimuth consistency check is sig12^2 * abs(f) * min(1, 1-f/2) / 2.  (Error
+   * measured for 1/100 < b/a < 100 and abs(f) >= 1/1000.  For a given f and
+   * sig12, the max error occurs for lines near the pole.  If the old rule for
+   * computing dnm = (dn1 + dn2)/2 is used, then the error increases by a
+   * factor of 2.)  Setting this equal to epsilon gives sig12 = etol2.  Here
+   * 0.1 is a safety factor (error decreased by 100) and max(0.001, abs(f))
+   * stops etol2 getting too large in the nearly spherical case. */
+  g->etol2 = 0.1 * tol2 /
+    sqrt( maxx((real)(0.001), fabs(g->f)) * minx((real)(1), 1 - g->f/2) / 2 );
+
+  A3coeff(g);
+  C3coeff(g);
+  C4coeff(g);
+}
+
+static void geod_lineinit_int(struct geod_geodesicline* l,
+                              const struct geod_geodesic* g,
+                              real lat1, real lon1,
+                              real azi1, real salp1, real calp1,
+                              unsigned caps) {
+  real cbet1, sbet1, eps;
+  l->a = g->a;
+  l->f = g->f;
+  l->b = g->b;
+  l->c2 = g->c2;
+  l->f1 = g->f1;
+  /* If caps is 0 assume the standard direct calculation */
+  l->caps = (caps ? caps : GEOD_DISTANCE_IN | GEOD_LONGITUDE) |
+    /* always allow latitude and azimuth and unrolling of longitude */
+    GEOD_LATITUDE | GEOD_AZIMUTH | GEOD_LONG_UNROLL;
+
+  l->lat1 = LatFix(lat1);
+  l->lon1 = lon1;
+  l->azi1 = azi1;
+  l->salp1 = salp1;
+  l->calp1 = calp1;
+
+  sincosdx(AngRound(l->lat1), &sbet1, &cbet1); sbet1 *= l->f1;
+  /* Ensure cbet1 = +epsilon at poles */
+  norm2(&sbet1, &cbet1); cbet1 = maxx(tiny, cbet1);
+  l->dn1 = sqrt(1 + g->ep2 * sq(sbet1));
+
+  /* Evaluate alp0 from sin(alp1) * cos(bet1) = sin(alp0), */
+  l->salp0 = l->salp1 * cbet1; /* alp0 in [0, pi/2 - |bet1|] */
+  /* Alt: calp0 = hypot(sbet1, calp1 * cbet1).  The following
+   * is slightly better (consider the case salp1 = 0). */
+  l->calp0 = hypotx(l->calp1, l->salp1 * sbet1);
+  /* Evaluate sig with tan(bet1) = tan(sig1) * cos(alp1).
+   * sig = 0 is nearest northward crossing of equator.
+   * With bet1 = 0, alp1 = pi/2, we have sig1 = 0 (equatorial line).
+   * With bet1 =  pi/2, alp1 = -pi, sig1 =  pi/2
+   * With bet1 = -pi/2, alp1 =  0 , sig1 = -pi/2
+   * Evaluate omg1 with tan(omg1) = sin(alp0) * tan(sig1).
+   * With alp0 in (0, pi/2], quadrants for sig and omg coincide.
+   * No atan2(0,0) ambiguity at poles since cbet1 = +epsilon.
+   * With alp0 = 0, omg1 = 0 for alp1 = 0, omg1 = pi for alp1 = pi. */
+  l->ssig1 = sbet1; l->somg1 = l->salp0 * sbet1;
+  l->csig1 = l->comg1 = sbet1 != 0 || l->calp1 != 0 ? cbet1 * l->calp1 : 1;
+  norm2(&l->ssig1, &l->csig1); /* sig1 in (-pi, pi] */
+  /* norm2(somg1, comg1); -- don't need to normalize! */
+
+  l->k2 = sq(l->calp0) * g->ep2;
+  eps = l->k2 / (2 * (1 + sqrt(1 + l->k2)) + l->k2);
+
+  if (l->caps & CAP_C1) {
+    real s, c;
+    l->A1m1 = A1m1f(eps);
+    C1f(eps, l->C1a);
+    l->B11 = SinCosSeries(TRUE, l->ssig1, l->csig1, l->C1a, nC1);
+    s = sin(l->B11); c = cos(l->B11);
+    /* tau1 = sig1 + B11 */
+    l->stau1 = l->ssig1 * c + l->csig1 * s;
+    l->ctau1 = l->csig1 * c - l->ssig1 * s;
+    /* Not necessary because C1pa reverts C1a
+     *    B11 = -SinCosSeries(TRUE, stau1, ctau1, C1pa, nC1p); */
+  }
+
+  if (l->caps & CAP_C1p)
+    C1pf(eps, l->C1pa);
+
+  if (l->caps & CAP_C2) {
+    l->A2m1 = A2m1f(eps);
+    C2f(eps, l->C2a);
+    l->B21 = SinCosSeries(TRUE, l->ssig1, l->csig1, l->C2a, nC2);
+  }
+
+  if (l->caps & CAP_C3) {
+    C3f(g, eps, l->C3a);
+    l->A3c = -l->f * l->salp0 * A3f(g, eps);
+    l->B31 = SinCosSeries(TRUE, l->ssig1, l->csig1, l->C3a, nC3-1);
+  }
+
+  if (l->caps & CAP_C4) {
+    C4f(g, eps, l->C4a);
+    /* Multiplier = a^2 * e^2 * cos(alpha0) * sin(alpha0) */
+    l->A4 = sq(l->a) * l->calp0 * l->salp0 * g->e2;
+    l->B41 = SinCosSeries(FALSE, l->ssig1, l->csig1, l->C4a, nC4);
+  }
+
+  l->a13 = l->s13 = NaN;
+}
+
+void geod_lineinit(struct geod_geodesicline* l,
+                   const struct geod_geodesic* g,
+                   real lat1, real lon1, real azi1, unsigned caps) {
+  real salp1, calp1;
+  azi1 = AngNormalize(azi1);
+  /* Guard against underflow in salp0 */
+  sincosdx(AngRound(azi1), &salp1, &calp1);
+  geod_lineinit_int(l, g, lat1, lon1, azi1, salp1, calp1, caps);
+}
+
+void geod_gendirectline(struct geod_geodesicline* l,
+                        const struct geod_geodesic* g,
+                        real lat1, real lon1, real azi1,
+                        unsigned flags, real s12_a12,
+                        unsigned caps) {
+  geod_lineinit(l, g, lat1, lon1, azi1, caps);
+  geod_gensetdistance(l, flags, s12_a12);
+}
+
+void geod_directline(struct geod_geodesicline* l,
+                        const struct geod_geodesic* g,
+                        real lat1, real lon1, real azi1,
+                        real s12, unsigned caps) {
+  geod_gendirectline(l, g, lat1, lon1, azi1, GEOD_NOFLAGS, s12, caps);
+}
+
+real geod_genposition(const struct geod_geodesicline* l,
+                      unsigned flags, real s12_a12,
+                      real* plat2, real* plon2, real* pazi2,
+                      real* ps12, real* pm12,
+                      real* pM12, real* pM21,
+                      real* pS12) {
+  real lat2 = 0, lon2 = 0, azi2 = 0, s12 = 0,
+    m12 = 0, M12 = 0, M21 = 0, S12 = 0;
+  /* Avoid warning about uninitialized B12. */
+  real sig12, ssig12, csig12, B12 = 0, AB1 = 0;
+  real omg12, lam12, lon12;
+  real ssig2, csig2, sbet2, cbet2, somg2, comg2, salp2, calp2, dn2;
+  unsigned outmask =
+    (plat2 ? GEOD_LATITUDE : GEOD_NONE) |
+    (plon2 ? GEOD_LONGITUDE : GEOD_NONE) |
+    (pazi2 ? GEOD_AZIMUTH : GEOD_NONE) |
+    (ps12 ? GEOD_DISTANCE : GEOD_NONE) |
+    (pm12 ? GEOD_REDUCEDLENGTH : GEOD_NONE) |
+    (pM12 || pM21 ? GEOD_GEODESICSCALE : GEOD_NONE) |
+    (pS12 ? GEOD_AREA : GEOD_NONE);
+
+  outmask &= l->caps & OUT_ALL;
+  if (!( TRUE /*Init()*/ &&
+         (flags & GEOD_ARCMODE || (l->caps & (GEOD_DISTANCE_IN & OUT_ALL))) ))
+    /* Uninitialized or impossible distance calculation requested */
+    return NaN;
+
+  if (flags & GEOD_ARCMODE) {
+    /* Interpret s12_a12 as spherical arc length */
+    sig12 = s12_a12 * degree;
+    sincosdx(s12_a12, &ssig12, &csig12);
+  } else {
+    /* Interpret s12_a12 as distance */
+    real
+      tau12 = s12_a12 / (l->b * (1 + l->A1m1)),
+      s = sin(tau12),
+      c = cos(tau12);
+    /* tau2 = tau1 + tau12 */
+    B12 = - SinCosSeries(TRUE,
+                         l->stau1 * c + l->ctau1 * s,
+                         l->ctau1 * c - l->stau1 * s,
+                         l->C1pa, nC1p);
+    sig12 = tau12 - (B12 - l->B11);
+    ssig12 = sin(sig12); csig12 = cos(sig12);
+    if (fabs(l->f) > 0.01) {
+      /* Reverted distance series is inaccurate for |f| > 1/100, so correct
+       * sig12 with 1 Newton iteration.  The following table shows the
+       * approximate maximum error for a = WGS_a() and various f relative to
+       * GeodesicExact.
+       *     erri = the error in the inverse solution (nm)
+       *     errd = the error in the direct solution (series only) (nm)
+       *     errda = the error in the direct solution (series + 1 Newton) (nm)
+       *
+       *       f     erri  errd errda
+       *     -1/5    12e6 1.2e9  69e6
+       *     -1/10  123e3  12e6 765e3
+       *     -1/20   1110 108e3  7155
+       *     -1/50  18.63 200.9 27.12
+       *     -1/100 18.63 23.78 23.37
+       *     -1/150 18.63 21.05 20.26
+       *      1/150 22.35 24.73 25.83
+       *      1/100 22.35 25.03 25.31
+       *      1/50  29.80 231.9 30.44
+       *      1/20   5376 146e3  10e3
+       *      1/10  829e3  22e6 1.5e6
+       *      1/5   157e6 3.8e9 280e6 */
+      real serr;
+      ssig2 = l->ssig1 * csig12 + l->csig1 * ssig12;
+      csig2 = l->csig1 * csig12 - l->ssig1 * ssig12;
+      B12 = SinCosSeries(TRUE, ssig2, csig2, l->C1a, nC1);
+      serr = (1 + l->A1m1) * (sig12 + (B12 - l->B11)) - s12_a12 / l->b;
+      sig12 = sig12 - serr / sqrt(1 + l->k2 * sq(ssig2));
+      ssig12 = sin(sig12); csig12 = cos(sig12);
+      /* Update B12 below */
+    }
+  }
+
+  /* sig2 = sig1 + sig12 */
+  ssig2 = l->ssig1 * csig12 + l->csig1 * ssig12;
+  csig2 = l->csig1 * csig12 - l->ssig1 * ssig12;
+  dn2 = sqrt(1 + l->k2 * sq(ssig2));
+  if (outmask & (GEOD_DISTANCE | GEOD_REDUCEDLENGTH | GEOD_GEODESICSCALE)) {
+    if (flags & GEOD_ARCMODE || fabs(l->f) > 0.01)
+      B12 = SinCosSeries(TRUE, ssig2, csig2, l->C1a, nC1);
+    AB1 = (1 + l->A1m1) * (B12 - l->B11);
+  }
+  /* sin(bet2) = cos(alp0) * sin(sig2) */
+  sbet2 = l->calp0 * ssig2;
+  /* Alt: cbet2 = hypot(csig2, salp0 * ssig2); */
+  cbet2 = hypotx(l->salp0, l->calp0 * csig2);
+  if (cbet2 == 0)
+    /* I.e., salp0 = 0, csig2 = 0.  Break the degeneracy in this case */
+    cbet2 = csig2 = tiny;
+  /* tan(alp0) = cos(sig2)*tan(alp2) */
+  salp2 = l->salp0; calp2 = l->calp0 * csig2; /* No need to normalize */
+
+  if (outmask & GEOD_DISTANCE)
+    s12 = (flags & GEOD_ARCMODE) ?
+      l->b * ((1 + l->A1m1) * sig12 + AB1) :
+      s12_a12;
+
+  if (outmask & GEOD_LONGITUDE) {
+    real E = copysignx(1, l->salp0); /* east or west going? */
+    /* tan(omg2) = sin(alp0) * tan(sig2) */
+    somg2 = l->salp0 * ssig2; comg2 = csig2;  /* No need to normalize */
+    /* omg12 = omg2 - omg1 */
+    omg12 = (flags & GEOD_LONG_UNROLL)
+      ? E * (sig12
+             - (atan2(    ssig2, csig2) - atan2(    l->ssig1, l->csig1))
+             + (atan2(E * somg2, comg2) - atan2(E * l->somg1, l->comg1)))
+      : atan2(somg2 * l->comg1 - comg2 * l->somg1,
+              comg2 * l->comg1 + somg2 * l->somg1);
+    lam12 = omg12 + l->A3c *
+      ( sig12 + (SinCosSeries(TRUE, ssig2, csig2, l->C3a, nC3-1)
+                 - l->B31));
+    lon12 = lam12 / degree;
+    lon2 = (flags & GEOD_LONG_UNROLL) ? l->lon1 + lon12 :
+      AngNormalize(AngNormalize(l->lon1) + AngNormalize(lon12));
+  }
+
+  if (outmask & GEOD_LATITUDE)
+    lat2 = atan2dx(sbet2, l->f1 * cbet2);
+
+  if (outmask & GEOD_AZIMUTH)
+    azi2 = atan2dx(salp2, calp2);
+
+  if (outmask & (GEOD_REDUCEDLENGTH | GEOD_GEODESICSCALE)) {
+    real
+      B22 = SinCosSeries(TRUE, ssig2, csig2, l->C2a, nC2),
+      AB2 = (1 + l->A2m1) * (B22 - l->B21),
+      J12 = (l->A1m1 - l->A2m1) * sig12 + (AB1 - AB2);
+    if (outmask & GEOD_REDUCEDLENGTH)
+      /* Add parens around (csig1 * ssig2) and (ssig1 * csig2) to ensure
+       * accurate cancellation in the case of coincident points. */
+      m12 = l->b * ((dn2 * (l->csig1 * ssig2) - l->dn1 * (l->ssig1 * csig2))
+                    - l->csig1 * csig2 * J12);
+    if (outmask & GEOD_GEODESICSCALE) {
+      real t = l->k2 * (ssig2 - l->ssig1) * (ssig2 + l->ssig1) /
+        (l->dn1 + dn2);
+      M12 = csig12 + (t *  ssig2 -  csig2 * J12) * l->ssig1 / l->dn1;
+      M21 = csig12 - (t * l->ssig1 - l->csig1 * J12) *  ssig2 /  dn2;
+    }
+  }
+
+  if (outmask & GEOD_AREA) {
+    real
+      B42 = SinCosSeries(FALSE, ssig2, csig2, l->C4a, nC4);
+    real salp12, calp12;
+    if (l->calp0 == 0 || l->salp0 == 0) {
+      /* alp12 = alp2 - alp1, used in atan2 so no need to normalize */
+      salp12 = salp2 * l->calp1 - calp2 * l->salp1;
+      calp12 = calp2 * l->calp1 + salp2 * l->salp1;
+    } else {
+      /* tan(alp) = tan(alp0) * sec(sig)
+       * tan(alp2-alp1) = (tan(alp2) -tan(alp1)) / (tan(alp2)*tan(alp1)+1)
+       * = calp0 * salp0 * (csig1-csig2) / (salp0^2 + calp0^2 * csig1*csig2)
+       * If csig12 > 0, write
+       *   csig1 - csig2 = ssig12 * (csig1 * ssig12 / (1 + csig12) + ssig1)
+       * else
+       *   csig1 - csig2 = csig1 * (1 - csig12) + ssig12 * ssig1
+       * No need to normalize */
+      salp12 = l->calp0 * l->salp0 *
+        (csig12 <= 0 ? l->csig1 * (1 - csig12) + ssig12 * l->ssig1 :
+         ssig12 * (l->csig1 * ssig12 / (1 + csig12) + l->ssig1));
+      calp12 = sq(l->salp0) + sq(l->calp0) * l->csig1 * csig2;
+    }
+    S12 = l->c2 * atan2(salp12, calp12) + l->A4 * (B42 - l->B41);
+  }
+
+  /* In the pattern
+   *
+   *   if ((outmask & GEOD_XX) && pYY)
+   *     *pYY = YY;
+   *
+   * the second check "&& pYY" is redundant.  It's there to make the CLang
+   * static analyzer happy.
+   */
+  if ((outmask & GEOD_LATITUDE) && plat2)
+    *plat2 = lat2;
+  if ((outmask & GEOD_LONGITUDE) && plon2)
+    *plon2 = lon2;
+  if ((outmask & GEOD_AZIMUTH) && pazi2)
+    *pazi2 = azi2;
+  if ((outmask & GEOD_DISTANCE) && ps12)
+    *ps12 = s12;
+  if ((outmask & GEOD_REDUCEDLENGTH) && pm12)
+    *pm12 = m12;
+  if (outmask & GEOD_GEODESICSCALE) {
+    if (pM12) *pM12 = M12;
+    if (pM21) *pM21 = M21;
+  }
+  if ((outmask & GEOD_AREA) && pS12)
+    *pS12 = S12;
+
+  return (flags & GEOD_ARCMODE) ? s12_a12 : sig12 / degree;
+}
+
+void geod_setdistance(struct geod_geodesicline* l, real s13) {
+  l->s13 = s13;
+  l->a13 = geod_genposition(l, GEOD_NOFLAGS, l->s13, nullptr, nullptr, nullptr,
+                            nullptr, nullptr, nullptr, nullptr, nullptr);
+}
+
+static void geod_setarc(struct geod_geodesicline* l, real a13) {
+  l->a13 = a13; l->s13 = NaN;
+  geod_genposition(l, GEOD_ARCMODE, l->a13, nullptr, nullptr, nullptr, &l->s13,
+                   nullptr, nullptr, nullptr, nullptr);
+}
+
+void geod_gensetdistance(struct geod_geodesicline* l,
+ unsigned flags, real s13_a13) {
+  (flags & GEOD_ARCMODE) ?
+    geod_setarc(l, s13_a13) :
+    geod_setdistance(l, s13_a13);
+}
+
+void geod_position(const struct geod_geodesicline* l, real s12,
+                   real* plat2, real* plon2, real* pazi2) {
+  geod_genposition(l, FALSE, s12, plat2, plon2, pazi2,
+                   nullptr, nullptr, nullptr, nullptr, nullptr);
+}
+
+real geod_gendirect(const struct geod_geodesic* g,
+                    real lat1, real lon1, real azi1,
+                    unsigned flags, real s12_a12,
+                    real* plat2, real* plon2, real* pazi2,
+                    real* ps12, real* pm12, real* pM12, real* pM21,
+                    real* pS12) {
+  struct geod_geodesicline l;
+  unsigned outmask =
+    (plat2 ? GEOD_LATITUDE : GEOD_NONE) |
+    (plon2 ? GEOD_LONGITUDE : GEOD_NONE) |
+    (pazi2 ? GEOD_AZIMUTH : GEOD_NONE) |
+    (ps12 ? GEOD_DISTANCE : GEOD_NONE) |
+    (pm12 ? GEOD_REDUCEDLENGTH : GEOD_NONE) |
+    (pM12 || pM21 ? GEOD_GEODESICSCALE : GEOD_NONE) |
+    (pS12 ? GEOD_AREA : GEOD_NONE);
+
+  geod_lineinit(&l, g, lat1, lon1, azi1,
+                /* Automatically supply GEOD_DISTANCE_IN if necessary */
+                outmask |
+                ((flags & GEOD_ARCMODE) ? GEOD_NONE : GEOD_DISTANCE_IN));
+  return geod_genposition(&l, flags, s12_a12,
+                          plat2, plon2, pazi2, ps12, pm12, pM12, pM21, pS12);
+}
+
+void geod_direct(const struct geod_geodesic* g,
+                 real lat1, real lon1, real azi1,
+                 real s12,
+                 real* plat2, real* plon2, real* pazi2) {
+  geod_gendirect(g, lat1, lon1, azi1, GEOD_NOFLAGS, s12, plat2, plon2, pazi2,
+                 nullptr, nullptr, nullptr, nullptr, nullptr);
+}
+
+static real geod_geninverse_int(const struct geod_geodesic* g,
+                                real lat1, real lon1, real lat2, real lon2,
+                                real* ps12,
+                                real* psalp1, real* pcalp1,
+                                real* psalp2, real* pcalp2,
+                                real* pm12, real* pM12, real* pM21,
+                                real* pS12) {
+  real s12 = 0, m12 = 0, M12 = 0, M21 = 0, S12 = 0;
+  real lon12, lon12s;
+  int latsign, lonsign, swapp;
+  real sbet1, cbet1, sbet2, cbet2, s12x = 0, m12x = 0;
+  real dn1, dn2, lam12, slam12, clam12;
+  real a12 = 0, sig12, calp1 = 0, salp1 = 0, calp2 = 0, salp2 = 0;
+  real Ca[nC];
+  boolx meridian;
+  /* somg12 > 1 marks that it needs to be calculated */
+  real omg12 = 0, somg12 = 2, comg12 = 0;
+
+  unsigned outmask =
+    (ps12 ? GEOD_DISTANCE : GEOD_NONE) |
+    (pm12 ? GEOD_REDUCEDLENGTH : GEOD_NONE) |
+    (pM12 || pM21 ? GEOD_GEODESICSCALE : GEOD_NONE) |
+    (pS12 ? GEOD_AREA : GEOD_NONE);
+
+  outmask &= OUT_ALL;
+  /* Compute longitude difference (AngDiff does this carefully).  Result is
+   * in [-180, 180] but -180 is only for west-going geodesics.  180 is for
+   * east-going and meridional geodesics. */
+  lon12 = AngDiff(lon1, lon2, &lon12s);
+  /* Make longitude difference positive. */
+  lonsign = lon12 >= 0 ? 1 : -1;
+  /* If very close to being on the same half-meridian, then make it so. */
+  lon12 = lonsign * AngRound(lon12);
+  lon12s = AngRound((180 - lon12) - lonsign * lon12s);
+  lam12 = lon12 * degree;
+  if (lon12 > 90) {
+    sincosdx(lon12s, &slam12, &clam12);
+    clam12 = -clam12;
+  } else
+    sincosdx(lon12, &slam12, &clam12);
+
+  /* If really close to the equator, treat as on equator. */
+  lat1 = AngRound(LatFix(lat1));
+  lat2 = AngRound(LatFix(lat2));
+  /* Swap points so that point with higher (abs) latitude is point 1
+   * If one latitude is a nan, then it becomes lat1. */
+  swapp = fabs(lat1) < fabs(lat2) ? -1 : 1;
+  if (swapp < 0) {
+    lonsign *= -1;
+    swapx(&lat1, &lat2);
+  }
+  /* Make lat1 <= 0 */
+  latsign = lat1 < 0 ? 1 : -1;
+  lat1 *= latsign;
+  lat2 *= latsign;
+  /* Now we have
+   *
+   *     0 <= lon12 <= 180
+   *     -90 <= lat1 <= 0
+   *     lat1 <= lat2 <= -lat1
+   *
+   * longsign, swapp, latsign register the transformation to bring the
+   * coordinates to this canonical form.  In all cases, 1 means no change was
+   * made.  We make these transformations so that there are few cases to
+   * check, e.g., on verifying quadrants in atan2.  In addition, this
+   * enforces some symmetries in the results returned. */
+
+  sincosdx(lat1, &sbet1, &cbet1); sbet1 *= g->f1;
+  /* Ensure cbet1 = +epsilon at poles */
+  norm2(&sbet1, &cbet1); cbet1 = maxx(tiny, cbet1);
+
+  sincosdx(lat2, &sbet2, &cbet2); sbet2 *= g->f1;
+  /* Ensure cbet2 = +epsilon at poles */
+  norm2(&sbet2, &cbet2); cbet2 = maxx(tiny, cbet2);
+
+  /* If cbet1 < -sbet1, then cbet2 - cbet1 is a sensitive measure of the
+   * |bet1| - |bet2|.  Alternatively (cbet1 >= -sbet1), abs(sbet2) + sbet1 is
+   * a better measure.  This logic is used in assigning calp2 in Lambda12.
+   * Sometimes these quantities vanish and in that case we force bet2 = +/-
+   * bet1 exactly.  An example where is is necessary is the inverse problem
+   * 48.522876735459 0 -48.52287673545898293 179.599720456223079643
+   * which failed with Visual Studio 10 (Release and Debug) */
+
+  if (cbet1 < -sbet1) {
+    if (cbet2 == cbet1)
+      sbet2 = sbet2 < 0 ? sbet1 : -sbet1;
+  } else {
+    if (fabs(sbet2) == -sbet1)
+      cbet2 = cbet1;
+  }
+
+  dn1 = sqrt(1 + g->ep2 * sq(sbet1));
+  dn2 = sqrt(1 + g->ep2 * sq(sbet2));
+
+  meridian = lat1 == -90 || slam12 == 0;
+
+  if (meridian) {
+
+    /* Endpoints are on a single full meridian, so the geodesic might lie on
+     * a meridian. */
+
+    real ssig1, csig1, ssig2, csig2;
+    calp1 = clam12; salp1 = slam12; /* Head to the target longitude */
+    calp2 = 1; salp2 = 0;           /* At the target we're heading north */
+
+    /* tan(bet) = tan(sig) * cos(alp) */
+    ssig1 = sbet1; csig1 = calp1 * cbet1;
+    ssig2 = sbet2; csig2 = calp2 * cbet2;
+
+    /* sig12 = sig2 - sig1 */
+    sig12 = atan2(maxx((real)(0), csig1 * ssig2 - ssig1 * csig2),
+                                  csig1 * csig2 + ssig1 * ssig2);
+    Lengths(g, g->n, sig12, ssig1, csig1, dn1, ssig2, csig2, dn2,
+            cbet1, cbet2, &s12x, &m12x, nullptr,
+            (outmask & GEOD_GEODESICSCALE) ? &M12 : nullptr,
+            (outmask & GEOD_GEODESICSCALE) ? &M21 : nullptr,
+            Ca);
+    /* Add the check for sig12 since zero length geodesics might yield m12 <
+     * 0.  Test case was
+     *
+     *    echo 20.001 0 20.001 0 | GeodSolve -i
+     *
+     * In fact, we will have sig12 > pi/2 for meridional geodesic which is
+     * not a shortest path. */
+    if (sig12 < 1 || m12x >= 0) {
+      /* Need at least 2, to handle 90 0 90 180 */
+      if (sig12 < 3 * tiny)
+        sig12 = m12x = s12x = 0;
+      m12x *= g->b;
+      s12x *= g->b;
+      a12 = sig12 / degree;
+    } else
+      /* m12 < 0, i.e., prolate and too close to anti-podal */
+      meridian = FALSE;
+  }
+
+  if (!meridian &&
+      sbet1 == 0 &&           /* and sbet2 == 0 */
+      /* Mimic the way Lambda12 works with calp1 = 0 */
+      (g->f <= 0 || lon12s >= g->f * 180)) {
+
+    /* Geodesic runs along equator */
+    calp1 = calp2 = 0; salp1 = salp2 = 1;
+    s12x = g->a * lam12;
+    sig12 = omg12 = lam12 / g->f1;
+    m12x = g->b * sin(sig12);
+    if (outmask & GEOD_GEODESICSCALE)
+      M12 = M21 = cos(sig12);
+    a12 = lon12 / g->f1;
+
+  } else if (!meridian) {
+
+    /* Now point1 and point2 belong within a hemisphere bounded by a
+     * meridian and geodesic is neither meridional or equatorial. */
+
+    /* Figure a starting point for Newton's method */
+    real dnm = 0;
+    sig12 = InverseStart(g, sbet1, cbet1, dn1, sbet2, cbet2, dn2,
+                         lam12, slam12, clam12,
+                         &salp1, &calp1, &salp2, &calp2, &dnm,
+                         Ca);
+
+    if (sig12 >= 0) {
+      /* Short lines (InverseStart sets salp2, calp2, dnm) */
+      s12x = sig12 * g->b * dnm;
+      m12x = sq(dnm) * g->b * sin(sig12 / dnm);
+      if (outmask & GEOD_GEODESICSCALE)
+        M12 = M21 = cos(sig12 / dnm);
+      a12 = sig12 / degree;
+      omg12 = lam12 / (g->f1 * dnm);
+    } else {
+
+      /* Newton's method.  This is a straightforward solution of f(alp1) =
+       * lambda12(alp1) - lam12 = 0 with one wrinkle.  f(alp) has exactly one
+       * root in the interval (0, pi) and its derivative is positive at the
+       * root.  Thus f(alp) is positive for alp > alp1 and negative for alp <
+       * alp1.  During the course of the iteration, a range (alp1a, alp1b) is
+       * maintained which brackets the root and with each evaluation of
+       * f(alp) the range is shrunk, if possible.  Newton's method is
+       * restarted whenever the derivative of f is negative (because the new
+       * value of alp1 is then further from the solution) or if the new
+       * estimate of alp1 lies outside (0,pi); in this case, the new starting
+       * guess is taken to be (alp1a + alp1b) / 2. */
+      real ssig1 = 0, csig1 = 0, ssig2 = 0, csig2 = 0, eps = 0, domg12 = 0;
+      unsigned numit = 0;
+      /* Bracketing range */
+      real salp1a = tiny, calp1a = 1, salp1b = tiny, calp1b = -1;
+      boolx tripn = FALSE;
+      boolx tripb = FALSE;
+      for (; numit < maxit2; ++numit) {
+        /* the WGS84 test set: mean = 1.47, sd = 1.25, max = 16
+         * WGS84 and random input: mean = 2.85, sd = 0.60 */
+        real dv = 0,
+          v = Lambda12(g, sbet1, cbet1, dn1, sbet2, cbet2, dn2, salp1, calp1,
+                        slam12, clam12,
+                        &salp2, &calp2, &sig12, &ssig1, &csig1, &ssig2, &csig2,
+                        &eps, &domg12, numit < maxit1, &dv, Ca);
+        /* 2 * tol0 is approximately 1 ulp for a number in [0, pi]. */
+        /* Reversed test to allow escape with NaNs */
+        if (tripb || !(fabs(v) >= (tripn ? 8 : 1) * tol0)) break;
+        /* Update bracketing values */
+        if (v > 0 && (numit > maxit1 || calp1/salp1 > calp1b/salp1b))
+          { salp1b = salp1; calp1b = calp1; }
+        else if (v < 0 && (numit > maxit1 || calp1/salp1 < calp1a/salp1a))
+          { salp1a = salp1; calp1a = calp1; }
+        if (numit < maxit1 && dv > 0) {
+          real
+            dalp1 = -v/dv;
+          real
+            sdalp1 = sin(dalp1), cdalp1 = cos(dalp1),
+            nsalp1 = salp1 * cdalp1 + calp1 * sdalp1;
+          if (nsalp1 > 0 && fabs(dalp1) < pi) {
+            calp1 = calp1 * cdalp1 - salp1 * sdalp1;
+            salp1 = nsalp1;
+            norm2(&salp1, &calp1);
+            /* In some regimes we don't get quadratic convergence because
+             * slope -> 0.  So use convergence conditions based on epsilon
+             * instead of sqrt(epsilon). */
+            tripn = fabs(v) <= 16 * tol0;
+            continue;
+          }
+        }
+        /* Either dv was not positive or updated value was outside legal
+         * range.  Use the midpoint of the bracket as the next estimate.
+         * This mechanism is not needed for the WGS84 ellipsoid, but it does
+         * catch problems with more eccentric ellipsoids.  Its efficacy is
+         * such for the WGS84 test set with the starting guess set to alp1 =
+         * 90deg:
+         * the WGS84 test set: mean = 5.21, sd = 3.93, max = 24
+         * WGS84 and random input: mean = 4.74, sd = 0.99 */
+        salp1 = (salp1a + salp1b)/2;
+        calp1 = (calp1a + calp1b)/2;
+        norm2(&salp1, &calp1);
+        tripn = FALSE;
+        tripb = (fabs(salp1a - salp1) + (calp1a - calp1) < tolb ||
+                 fabs(salp1 - salp1b) + (calp1 - calp1b) < tolb);
+      }
+      Lengths(g, eps, sig12, ssig1, csig1, dn1, ssig2, csig2, dn2,
+              cbet1, cbet2, &s12x, &m12x, nullptr,
+              (outmask & GEOD_GEODESICSCALE) ? &M12 : nullptr,
+              (outmask & GEOD_GEODESICSCALE) ? &M21 : nullptr, Ca);
+      m12x *= g->b;
+      s12x *= g->b;
+      a12 = sig12 / degree;
+      if (outmask & GEOD_AREA) {
+        /* omg12 = lam12 - domg12 */
+        real sdomg12 = sin(domg12), cdomg12 = cos(domg12);
+        somg12 = slam12 * cdomg12 - clam12 * sdomg12;
+        comg12 = clam12 * cdomg12 + slam12 * sdomg12;
+      }
+    }
+  }
+
+  if (outmask & GEOD_DISTANCE)
+    s12 = 0 + s12x;             /* Convert -0 to 0 */
+
+  if (outmask & GEOD_REDUCEDLENGTH)
+    m12 = 0 + m12x;             /* Convert -0 to 0 */
+
+  if (outmask & GEOD_AREA) {
+    real
+      /* From Lambda12: sin(alp1) * cos(bet1) = sin(alp0) */
+      salp0 = salp1 * cbet1,
+      calp0 = hypotx(calp1, salp1 * sbet1); /* calp0 > 0 */
+    real alp12;
+    if (calp0 != 0 && salp0 != 0) {
+      real
+        /* From Lambda12: tan(bet) = tan(sig) * cos(alp) */
+        ssig1 = sbet1, csig1 = calp1 * cbet1,
+        ssig2 = sbet2, csig2 = calp2 * cbet2,
+        k2 = sq(calp0) * g->ep2,
+        eps = k2 / (2 * (1 + sqrt(1 + k2)) + k2),
+        /* Multiplier = a^2 * e^2 * cos(alpha0) * sin(alpha0). */
+        A4 = sq(g->a) * calp0 * salp0 * g->e2;
+      real B41, B42;
+      norm2(&ssig1, &csig1);
+      norm2(&ssig2, &csig2);
+      C4f(g, eps, Ca);
+      B41 = SinCosSeries(FALSE, ssig1, csig1, Ca, nC4);
+      B42 = SinCosSeries(FALSE, ssig2, csig2, Ca, nC4);
+      S12 = A4 * (B42 - B41);
+    } else
+      /* Avoid problems with indeterminate sig1, sig2 on equator */
+      S12 = 0;
+
+    if (!meridian && somg12 > 1) {
+      somg12 = sin(omg12); comg12 = cos(omg12);
+    }
+
+    if (!meridian &&
+        /* omg12 < 3/4 * pi */
+        comg12 > -(real)(0.7071) &&     /* Long difference not too big */
+        sbet2 - sbet1 < (real)(1.75)) { /* Lat difference not too big */
+      /* Use tan(Gamma/2) = tan(omg12/2)
+       * * (tan(bet1/2)+tan(bet2/2))/(1+tan(bet1/2)*tan(bet2/2))
+       * with tan(x/2) = sin(x)/(1+cos(x)) */
+      real
+        domg12 = 1 + comg12, dbet1 = 1 + cbet1, dbet2 = 1 + cbet2;
+      alp12 = 2 * atan2( somg12 * ( sbet1 * dbet2 + sbet2 * dbet1 ),
+                         domg12 * ( sbet1 * sbet2 + dbet1 * dbet2 ) );
+    } else {
+      /* alp12 = alp2 - alp1, used in atan2 so no need to normalize */
+      real
+        salp12 = salp2 * calp1 - calp2 * salp1,
+        calp12 = calp2 * calp1 + salp2 * salp1;
+      /* The right thing appears to happen if alp1 = +/-180 and alp2 = 0, viz
+       * salp12 = -0 and alp12 = -180.  However this depends on the sign
+       * being attached to 0 correctly.  The following ensures the correct
+       * behavior. */
+      if (salp12 == 0 && calp12 < 0) {
+        salp12 = tiny * calp1;
+        calp12 = -1;
+      }
+      alp12 = atan2(salp12, calp12);
+    }
+    S12 += g->c2 * alp12;
+    S12 *= swapp * lonsign * latsign;
+    /* Convert -0 to 0 */
+    S12 += 0;
+  }
+
+  /* Convert calp, salp to azimuth accounting for lonsign, swapp, latsign. */
+  if (swapp < 0) {
+    swapx(&salp1, &salp2);
+    swapx(&calp1, &calp2);
+    if (outmask & GEOD_GEODESICSCALE)
+      swapx(&M12, &M21);
+  }
+
+  salp1 *= swapp * lonsign; calp1 *= swapp * latsign;
+  salp2 *= swapp * lonsign; calp2 *= swapp * latsign;
+
+  if (psalp1) *psalp1 = salp1;
+  if (pcalp1) *pcalp1 = calp1;
+  if (psalp2) *psalp2 = salp2;
+  if (pcalp2) *pcalp2 = calp2;
+
+  if (outmask & GEOD_DISTANCE)
+    *ps12 = s12;
+  if (outmask & GEOD_REDUCEDLENGTH)
+    *pm12 = m12;
+  if (outmask & GEOD_GEODESICSCALE) {
+    if (pM12) *pM12 = M12;
+    if (pM21) *pM21 = M21;
+  }
+  if (outmask & GEOD_AREA)
+    *pS12 = S12;
+
+  /* Returned value in [0, 180] */
+  return a12;
+}
+
+real geod_geninverse(const struct geod_geodesic* g,
+                     real lat1, real lon1, real lat2, real lon2,
+                     real* ps12, real* pazi1, real* pazi2,
+                     real* pm12, real* pM12, real* pM21, real* pS12) {
+  real salp1, calp1, salp2, calp2,
+    a12 = geod_geninverse_int(g, lat1, lon1, lat2, lon2, ps12,
+                              &salp1, &calp1, &salp2, &calp2,
+                              pm12, pM12, pM21, pS12);
+  if (pazi1) *pazi1 = atan2dx(salp1, calp1);
+  if (pazi2) *pazi2 = atan2dx(salp2, calp2);
+  return a12;
+}
+
+void geod_inverseline(struct geod_geodesicline* l,
+                      const struct geod_geodesic* g,
+                      real lat1, real lon1, real lat2, real lon2,
+                      unsigned caps) {
+  real salp1, calp1,
+    a12 = geod_geninverse_int(g, lat1, lon1, lat2, lon2, nullptr,
+                              &salp1, &calp1, nullptr, nullptr,
+                              nullptr, nullptr, nullptr, nullptr),
+    azi1 = atan2dx(salp1, calp1);
+  caps = caps ? caps : GEOD_DISTANCE_IN | GEOD_LONGITUDE;
+  /* Ensure that a12 can be converted to a distance */
+  if (caps & (OUT_ALL & GEOD_DISTANCE_IN)) caps |= GEOD_DISTANCE;
+  geod_lineinit_int(l, g, lat1, lon1, azi1, salp1, calp1, caps);
+  geod_setarc(l, a12);
+}
+
+void geod_inverse(const struct geod_geodesic* g,
+                  real lat1, real lon1, real lat2, real lon2,
+                  real* ps12, real* pazi1, real* pazi2) {
+  geod_geninverse(g, lat1, lon1, lat2, lon2, ps12, pazi1, pazi2,
+                  nullptr, nullptr, nullptr, nullptr);
+}
+
+real SinCosSeries(boolx sinp, real sinx, real cosx, const real c[], int n) {
+  /* Evaluate
+   * y = sinp ? sum(c[i] * sin( 2*i    * x), i, 1, n) :
+   *            sum(c[i] * cos((2*i+1) * x), i, 0, n-1)
+   * using Clenshaw summation.  N.B. c[0] is unused for sin series
+   * Approx operation count = (n + 5) mult and (2 * n + 2) add */
+  real ar, y0, y1;
+  c += (n + sinp);              /* Point to one beyond last element */
+  ar = 2 * (cosx - sinx) * (cosx + sinx); /* 2 * cos(2 * x) */
+  y0 = (n & 1) ? *--c : 0; y1 = 0;        /* accumulators for sum */
+  /* Now n is even */
+  n /= 2;
+  while (n--) {
+    /* Unroll loop x 2, so accumulators return to their original role */
+    y1 = ar * y0 - y1 + *--c;
+    y0 = ar * y1 - y0 + *--c;
+  }
+  return sinp
+    ? 2 * sinx * cosx * y0      /* sin(2 * x) * y0 */
+    : cosx * (y0 - y1);         /* cos(x) * (y0 - y1) */
+}
+
+void Lengths(const struct geod_geodesic* g,
+             real eps, real sig12,
+             real ssig1, real csig1, real dn1,
+             real ssig2, real csig2, real dn2,
+             real cbet1, real cbet2,
+             real* ps12b, real* pm12b, real* pm0,
+             real* pM12, real* pM21,
+             /* Scratch area of the right size */
+             real Ca[]) {
+  real m0 = 0, J12 = 0, A1 = 0, A2 = 0;
+  real Cb[nC];
+
+  /* Return m12b = (reduced length)/b; also calculate s12b = distance/b,
+   * and m0 = coefficient of secular term in expression for reduced length. */
+  boolx redlp = pm12b || pm0 || pM12 || pM21;
+  if (ps12b || redlp) {
+    A1 = A1m1f(eps);
+    C1f(eps, Ca);
+    if (redlp) {
+      A2 = A2m1f(eps);
+      C2f(eps, Cb);
+      m0 = A1 - A2;
+      A2 = 1 + A2;
+    }
+    A1 = 1 + A1;
+  }
+  if (ps12b) {
+    real B1 = SinCosSeries(TRUE, ssig2, csig2, Ca, nC1) -
+      SinCosSeries(TRUE, ssig1, csig1, Ca, nC1);
+    /* Missing a factor of b */
+    *ps12b = A1 * (sig12 + B1);
+    if (redlp) {
+      real B2 = SinCosSeries(TRUE, ssig2, csig2, Cb, nC2) -
+        SinCosSeries(TRUE, ssig1, csig1, Cb, nC2);
+      J12 = m0 * sig12 + (A1 * B1 - A2 * B2);
+    }
+  } else if (redlp) {
+    /* Assume here that nC1 >= nC2 */
+    int l;
+    for (l = 1; l <= nC2; ++l)
+      Cb[l] = A1 * Ca[l] - A2 * Cb[l];
+    J12 = m0 * sig12 + (SinCosSeries(TRUE, ssig2, csig2, Cb, nC2) -
+                        SinCosSeries(TRUE, ssig1, csig1, Cb, nC2));
+  }
+  if (pm0) *pm0 = m0;
+  if (pm12b)
+    /* Missing a factor of b.
+     * Add parens around (csig1 * ssig2) and (ssig1 * csig2) to ensure
+     * accurate cancellation in the case of coincident points. */
+    *pm12b = dn2 * (csig1 * ssig2) - dn1 * (ssig1 * csig2) -
+      csig1 * csig2 * J12;
+  if (pM12 || pM21) {
+    real csig12 = csig1 * csig2 + ssig1 * ssig2;
+    real t = g->ep2 * (cbet1 - cbet2) * (cbet1 + cbet2) / (dn1 + dn2);
+    if (pM12)
+      *pM12 = csig12 + (t * ssig2 - csig2 * J12) * ssig1 / dn1;
+    if (pM21)
+      *pM21 = csig12 - (t * ssig1 - csig1 * J12) * ssig2 / dn2;
+  }
+}
+
+real Astroid(real x, real y) {
+  /* Solve k^4+2*k^3-(x^2+y^2-1)*k^2-2*y^2*k-y^2 = 0 for positive root k.
+   * This solution is adapted from Geocentric::Reverse. */
+  real k;
+  real
+    p = sq(x),
+    q = sq(y),
+    r = (p + q - 1) / 6;
+  if ( !(q == 0 && r <= 0) ) {
+    real
+      /* Avoid possible division by zero when r = 0 by multiplying equations
+       * for s and t by r^3 and r, resp. */
+      S = p * q / 4,            /* S = r^3 * s */
+      r2 = sq(r),
+      r3 = r * r2,
+      /* The discriminant of the quadratic equation for T3.  This is zero on
+       * the evolute curve p^(1/3)+q^(1/3) = 1 */
+      disc = S * (S + 2 * r3);
+    real u = r;
+    real v, uv, w;
+    if (disc >= 0) {
+      real T3 = S + r3, T;
+      /* Pick the sign on the sqrt to maximize abs(T3).  This minimizes loss
+       * of precision due to cancellation.  The result is unchanged because
+       * of the way the T is used in definition of u. */
+      T3 += T3 < 0 ? -sqrt(disc) : sqrt(disc); /* T3 = (r * t)^3 */
+      /* N.B. cbrtx always returns the real root.  cbrtx(-8) = -2. */
+      T = cbrtx(T3);            /* T = r * t */
+      /* T can be zero; but then r2 / T -> 0. */
+      u += T + (T != 0 ? r2 / T : 0);
+    } else {
+      /* T is complex, but the way u is defined the result is real. */
+      real ang = atan2(sqrt(-disc), -(S + r3));
+      /* There are three possible cube roots.  We choose the root which
+       * avoids cancellation.  Note that disc < 0 implies that r < 0. */
+      u += 2 * r * cos(ang / 3);
+    }
+    v = sqrt(sq(u) + q);              /* guaranteed positive */
+    /* Avoid loss of accuracy when u < 0. */
+    uv = u < 0 ? q / (v - u) : u + v; /* u+v, guaranteed positive */
+    w = (uv - q) / (2 * v);           /* positive? */
+    /* Rearrange expression for k to avoid loss of accuracy due to
+     * subtraction.  Division by 0 not possible because uv > 0, w >= 0. */
+    k = uv / (sqrt(uv + sq(w)) + w);   /* guaranteed positive */
+  } else {               /* q == 0 && r <= 0 */
+    /* y = 0 with |x| <= 1.  Handle this case directly.
+     * for y small, positive root is k = abs(y)/sqrt(1-x^2) */
+    k = 0;
+  }
+  return k;
+}
+
+real InverseStart(const struct geod_geodesic* g,
+                  real sbet1, real cbet1, real dn1,
+                  real sbet2, real cbet2, real dn2,
+                  real lam12, real slam12, real clam12,
+                  real* psalp1, real* pcalp1,
+                  /* Only updated if return val >= 0 */
+                  real* psalp2, real* pcalp2,
+                  /* Only updated for short lines */
+                  real* pdnm,
+                  /* Scratch area of the right size */
+                  real Ca[]) {
+  real salp1 = 0, calp1 = 0, salp2 = 0, calp2 = 0, dnm = 0;
+
+  /* Return a starting point for Newton's method in salp1 and calp1 (function
+   * value is -1).  If Newton's method doesn't need to be used, return also
+   * salp2 and calp2 and function value is sig12. */
+  real
+    sig12 = -1,               /* Return value */
+    /* bet12 = bet2 - bet1 in [0, pi); bet12a = bet2 + bet1 in (-pi, 0] */
+    sbet12 = sbet2 * cbet1 - cbet2 * sbet1,
+    cbet12 = cbet2 * cbet1 + sbet2 * sbet1;
+  real sbet12a;
+  boolx shortline = cbet12 >= 0 && sbet12 < (real)(0.5) &&
+    cbet2 * lam12 < (real)(0.5);
+  real somg12, comg12, ssig12, csig12;
+  sbet12a = sbet2 * cbet1 + cbet2 * sbet1;
+  if (shortline) {
+    real sbetm2 = sq(sbet1 + sbet2), omg12;
+    /* sin((bet1+bet2)/2)^2
+     * =  (sbet1 + sbet2)^2 / ((sbet1 + sbet2)^2 + (cbet1 + cbet2)^2) */
+    sbetm2 /= sbetm2 + sq(cbet1 + cbet2);
+    dnm = sqrt(1 + g->ep2 * sbetm2);
+    omg12 = lam12 / (g->f1 * dnm);
+    somg12 = sin(omg12); comg12 = cos(omg12);
+  } else {
+    somg12 = slam12; comg12 = clam12;
+  }
+
+  salp1 = cbet2 * somg12;
+  calp1 = comg12 >= 0 ?
+    sbet12 + cbet2 * sbet1 * sq(somg12) / (1 + comg12) :
+    sbet12a - cbet2 * sbet1 * sq(somg12) / (1 - comg12);
+
+  ssig12 = hypotx(salp1, calp1);
+  csig12 = sbet1 * sbet2 + cbet1 * cbet2 * comg12;
+
+  if (shortline && ssig12 < g->etol2) {
+    /* really short lines */
+    salp2 = cbet1 * somg12;
+    calp2 = sbet12 - cbet1 * sbet2 *
+      (comg12 >= 0 ? sq(somg12) / (1 + comg12) : 1 - comg12);
+    norm2(&salp2, &calp2);
+    /* Set return value */
+    sig12 = atan2(ssig12, csig12);
+  } else if (fabs(g->n) > (real)(0.1) || /* No astroid calc if too eccentric */
+             csig12 >= 0 ||
+             ssig12 >= 6 * fabs(g->n) * pi * sq(cbet1)) {
+    /* Nothing to do, zeroth order spherical approximation is OK */
+  } else {
+    /* Scale lam12 and bet2 to x, y coordinate system where antipodal point
+     * is at origin and singular point is at y = 0, x = -1. */
+    real y, lamscale, betscale;
+    /* Volatile declaration needed to fix inverse case
+     * 56.320923501171 0 -56.320923501171 179.664747671772880215
+     * which otherwise fails with g++ 4.4.4 x86 -O3 */
+    volatile real x;
+    real lam12x = atan2(-slam12, -clam12); /* lam12 - pi */
+    if (g->f >= 0) {            /* In fact f == 0 does not get here */
+      /* x = dlong, y = dlat */
+      {
+        real
+          k2 = sq(sbet1) * g->ep2,
+          eps = k2 / (2 * (1 + sqrt(1 + k2)) + k2);
+        lamscale = g->f * cbet1 * A3f(g, eps) * pi;
+      }
+      betscale = lamscale * cbet1;
+
+      x = lam12x / lamscale;
+      y = sbet12a / betscale;
+    } else {                    /* f < 0 */
+      /* x = dlat, y = dlong */
+      real
+        cbet12a = cbet2 * cbet1 - sbet2 * sbet1,
+        bet12a = atan2(sbet12a, cbet12a);
+      real m12b, m0;
+      /* In the case of lon12 = 180, this repeats a calculation made in
+       * Inverse. */
+      Lengths(g, g->n, pi + bet12a,
+              sbet1, -cbet1, dn1, sbet2, cbet2, dn2,
+              cbet1, cbet2, nullptr, &m12b, &m0, nullptr, nullptr, Ca);
+      x = -1 + m12b / (cbet1 * cbet2 * m0 * pi);
+      betscale = x < -(real)(0.01) ? sbet12a / x :
+        -g->f * sq(cbet1) * pi;
+      lamscale = betscale / cbet1;
+      y = lam12x / lamscale;
+    }
+
+    if (y > -tol1 && x > -1 - xthresh) {
+      /* strip near cut */
+      if (g->f >= 0) {
+        salp1 = minx((real)(1), -(real)(x)); calp1 = - sqrt(1 - sq(salp1));
+      } else {
+        calp1 = maxx((real)(x > -tol1 ? 0 : -1), (real)(x));
+        salp1 = sqrt(1 - sq(calp1));
+      }
+    } else {
+      /* Estimate alp1, by solving the astroid problem.
+       *
+       * Could estimate alpha1 = theta + pi/2, directly, i.e.,
+       *   calp1 = y/k; salp1 = -x/(1+k);  for f >= 0
+       *   calp1 = x/(1+k); salp1 = -y/k;  for f < 0 (need to check)
+       *
+       * However, it's better to estimate omg12 from astroid and use
+       * spherical formula to compute alp1.  This reduces the mean number of
+       * Newton iterations for astroid cases from 2.24 (min 0, max 6) to 2.12
+       * (min 0 max 5).  The changes in the number of iterations are as
+       * follows:
+       *
+       * change percent
+       *    1       5
+       *    0      78
+       *   -1      16
+       *   -2       0.6
+       *   -3       0.04
+       *   -4       0.002
+       *
+       * The histogram of iterations is (m = number of iterations estimating
+       * alp1 directly, n = number of iterations estimating via omg12, total
+       * number of trials = 148605):
+       *
+       *  iter    m      n
+       *    0   148    186
+       *    1 13046  13845
+       *    2 93315 102225
+       *    3 36189  32341
+       *    4  5396      7
+       *    5   455      1
+       *    6    56      0
+       *
+       * Because omg12 is near pi, estimate work with omg12a = pi - omg12 */
+      real k = Astroid(x, y);
+      real
+        omg12a = lamscale * ( g->f >= 0 ? -x * k/(1 + k) : -y * (1 + k)/k );
+      somg12 = sin(omg12a); comg12 = -cos(omg12a);
+      /* Update spherical estimate of alp1 using omg12 instead of lam12 */
+      salp1 = cbet2 * somg12;
+      calp1 = sbet12a - cbet2 * sbet1 * sq(somg12) / (1 - comg12);
+    }
+  }
+  /* Sanity check on starting guess.  Backwards check allows NaN through. */
+  if (!(salp1 <= 0))
+    norm2(&salp1, &calp1);
+  else {
+    salp1 = 1; calp1 = 0;
+  }
+
+  *psalp1 = salp1;
+  *pcalp1 = calp1;
+  if (shortline)
+    *pdnm = dnm;
+  if (sig12 >= 0) {
+    *psalp2 = salp2;
+    *pcalp2 = calp2;
+  }
+  return sig12;
+}
+
+real Lambda12(const struct geod_geodesic* g,
+              real sbet1, real cbet1, real dn1,
+              real sbet2, real cbet2, real dn2,
+              real salp1, real calp1,
+              real slam120, real clam120,
+              real* psalp2, real* pcalp2,
+              real* psig12,
+              real* pssig1, real* pcsig1,
+              real* pssig2, real* pcsig2,
+              real* peps,
+              real* pdomg12,
+              boolx diffp, real* pdlam12,
+              /* Scratch area of the right size */
+              real Ca[]) {
+  real salp2 = 0, calp2 = 0, sig12 = 0,
+    ssig1 = 0, csig1 = 0, ssig2 = 0, csig2 = 0, eps = 0,
+    domg12 = 0, dlam12 = 0;
+  real salp0, calp0;
+  real somg1, comg1, somg2, comg2, somg12, comg12, lam12;
+  real B312, eta, k2;
+
+  if (sbet1 == 0 && calp1 == 0)
+    /* Break degeneracy of equatorial line.  This case has already been
+     * handled. */
+    calp1 = -tiny;
+
+  /* sin(alp1) * cos(bet1) = sin(alp0) */
+  salp0 = salp1 * cbet1;
+  calp0 = hypotx(calp1, salp1 * sbet1); /* calp0 > 0 */
+
+  /* tan(bet1) = tan(sig1) * cos(alp1)
+   * tan(omg1) = sin(alp0) * tan(sig1) = tan(omg1)=tan(alp1)*sin(bet1) */
+  ssig1 = sbet1; somg1 = salp0 * sbet1;
+  csig1 = comg1 = calp1 * cbet1;
+  norm2(&ssig1, &csig1);
+  /* norm2(&somg1, &comg1); -- don't need to normalize! */
+
+  /* Enforce symmetries in the case abs(bet2) = -bet1.  Need to be careful
+   * about this case, since this can yield singularities in the Newton
+   * iteration.
+   * sin(alp2) * cos(bet2) = sin(alp0) */
+  salp2 = cbet2 != cbet1 ? salp0 / cbet2 : salp1;
+  /* calp2 = sqrt(1 - sq(salp2))
+   *       = sqrt(sq(calp0) - sq(sbet2)) / cbet2
+   * and subst for calp0 and rearrange to give (choose positive sqrt
+   * to give alp2 in [0, pi/2]). */
+  calp2 = cbet2 != cbet1 || fabs(sbet2) != -sbet1 ?
+    sqrt(sq(calp1 * cbet1) +
+         (cbet1 < -sbet1 ?
+          (cbet2 - cbet1) * (cbet1 + cbet2) :
+          (sbet1 - sbet2) * (sbet1 + sbet2))) / cbet2 :
+    fabs(calp1);
+  /* tan(bet2) = tan(sig2) * cos(alp2)
+   * tan(omg2) = sin(alp0) * tan(sig2). */
+  ssig2 = sbet2; somg2 = salp0 * sbet2;
+  csig2 = comg2 = calp2 * cbet2;
+  norm2(&ssig2, &csig2);
+  /* norm2(&somg2, &comg2); -- don't need to normalize! */
+
+  /* sig12 = sig2 - sig1, limit to [0, pi] */
+  sig12 = atan2(maxx((real)(0), csig1 * ssig2 - ssig1 * csig2),
+                                csig1 * csig2 + ssig1 * ssig2);
+
+  /* omg12 = omg2 - omg1, limit to [0, pi] */
+  somg12 = maxx((real)(0), comg1 * somg2 - somg1 * comg2);
+  comg12 =                 comg1 * comg2 + somg1 * somg2;
+  /* eta = omg12 - lam120 */
+  eta = atan2(somg12 * clam120 - comg12 * slam120,
+              comg12 * clam120 + somg12 * slam120);
+  k2 = sq(calp0) * g->ep2;
+  eps = k2 / (2 * (1 + sqrt(1 + k2)) + k2);
+  C3f(g, eps, Ca);
+  B312 = (SinCosSeries(TRUE, ssig2, csig2, Ca, nC3-1) -
+          SinCosSeries(TRUE, ssig1, csig1, Ca, nC3-1));
+  domg12 = -g->f * A3f(g, eps) * salp0 * (sig12 + B312);
+  lam12 = eta + domg12;
+
+  if (diffp) {
+    if (calp2 == 0)
+      dlam12 = - 2 * g->f1 * dn1 / sbet1;
+    else {
+      Lengths(g, eps, sig12, ssig1, csig1, dn1, ssig2, csig2, dn2,
+              cbet1, cbet2, nullptr, &dlam12, nullptr, nullptr, nullptr, Ca);
+      dlam12 *= g->f1 / (calp2 * cbet2);
+    }
+  }
+
+  *psalp2 = salp2;
+  *pcalp2 = calp2;
+  *psig12 = sig12;
+  *pssig1 = ssig1;
+  *pcsig1 = csig1;
+  *pssig2 = ssig2;
+  *pcsig2 = csig2;
+  *peps = eps;
+  *pdomg12 = domg12;
+  if (diffp)
+    *pdlam12 = dlam12;
+
+  return lam12;
+}
+
+real A3f(const struct geod_geodesic* g, real eps) {
+  /* Evaluate A3 */
+  return polyval(nA3 - 1, g->A3x, eps);
+}
+
+void C3f(const struct geod_geodesic* g, real eps, real c[]) {
+  /* Evaluate C3 coeffs
+   * Elements c[1] through c[nC3 - 1] are set */
+  real mult = 1;
+  int o = 0, l;
+  for (l = 1; l < nC3; ++l) {   /* l is index of C3[l] */
+    int m = nC3 - l - 1;        /* order of polynomial in eps */
+    mult *= eps;
+    c[l] = mult * polyval(m, g->C3x + o, eps);
+    o += m + 1;
+  }
+}
+
+void C4f(const struct geod_geodesic* g, real eps, real c[]) {
+  /* Evaluate C4 coeffs
+   * Elements c[0] through c[nC4 - 1] are set */
+  real mult = 1;
+  int o = 0, l;
+  for (l = 0; l < nC4; ++l) {   /* l is index of C4[l] */
+    int m = nC4 - l - 1;        /* order of polynomial in eps */
+    c[l] = mult * polyval(m, g->C4x + o, eps);
+    o += m + 1;
+    mult *= eps;
+  }
+}
+
+/* The scale factor A1-1 = mean value of (d/dsigma)I1 - 1 */
+real A1m1f(real eps)  {
+  static const real coeff[] = {
+    /* (1-eps)*A1-1, polynomial in eps2 of order 3 */
+    1, 4, 64, 0, 256,
+  };
+  int m = nA1/2;
+  real t = polyval(m, coeff, sq(eps)) / coeff[m + 1];
+  return (t + eps) / (1 - eps);
+}
+
+/* The coefficients C1[l] in the Fourier expansion of B1 */
+void C1f(real eps, real c[])  {
+  static const real coeff[] = {
+    /* C1[1]/eps^1, polynomial in eps2 of order 2 */
+    -1, 6, -16, 32,
+    /* C1[2]/eps^2, polynomial in eps2 of order 2 */
+    -9, 64, -128, 2048,
+    /* C1[3]/eps^3, polynomial in eps2 of order 1 */
+    9, -16, 768,
+    /* C1[4]/eps^4, polynomial in eps2 of order 1 */
+    3, -5, 512,
+    /* C1[5]/eps^5, polynomial in eps2 of order 0 */
+    -7, 1280,
+    /* C1[6]/eps^6, polynomial in eps2 of order 0 */
+    -7, 2048,
+  };
+  real
+    eps2 = sq(eps),
+    d = eps;
+  int o = 0, l;
+  for (l = 1; l <= nC1; ++l) {  /* l is index of C1p[l] */
+    int m = (nC1 - l) / 2;      /* order of polynomial in eps^2 */
+    c[l] = d * polyval(m, coeff + o, eps2) / coeff[o + m + 1];
+    o += m + 2;
+    d *= eps;
+  }
+}
+
+/* The coefficients C1p[l] in the Fourier expansion of B1p */
+void C1pf(real eps, real c[])  {
+  static const real coeff[] = {
+    /* C1p[1]/eps^1, polynomial in eps2 of order 2 */
+    205, -432, 768, 1536,
+    /* C1p[2]/eps^2, polynomial in eps2 of order 2 */
+    4005, -4736, 3840, 12288,
+    /* C1p[3]/eps^3, polynomial in eps2 of order 1 */
+    -225, 116, 384,
+    /* C1p[4]/eps^4, polynomial in eps2 of order 1 */
+    -7173, 2695, 7680,
+    /* C1p[5]/eps^5, polynomial in eps2 of order 0 */
+    3467, 7680,
+    /* C1p[6]/eps^6, polynomial in eps2 of order 0 */
+    38081, 61440,
+  };
+  real
+    eps2 = sq(eps),
+    d = eps;
+  int o = 0, l;
+  for (l = 1; l <= nC1p; ++l) { /* l is index of C1p[l] */
+    int m = (nC1p - l) / 2;     /* order of polynomial in eps^2 */
+    c[l] = d * polyval(m, coeff + o, eps2) / coeff[o + m + 1];
+    o += m + 2;
+    d *= eps;
+  }
+}
+
+/* The scale factor A2-1 = mean value of (d/dsigma)I2 - 1 */
+real A2m1f(real eps)  {
+  static const real coeff[] = {
+    /* (eps+1)*A2-1, polynomial in eps2 of order 3 */
+    -11, -28, -192, 0, 256,
+  };
+  int m = nA2/2;
+  real t = polyval(m, coeff, sq(eps)) / coeff[m + 1];
+  return (t - eps) / (1 + eps);
+}
+
+/* The coefficients C2[l] in the Fourier expansion of B2 */
+void C2f(real eps, real c[])  {
+  static const real coeff[] = {
+    /* C2[1]/eps^1, polynomial in eps2 of order 2 */
+    1, 2, 16, 32,
+    /* C2[2]/eps^2, polynomial in eps2 of order 2 */
+    35, 64, 384, 2048,
+    /* C2[3]/eps^3, polynomial in eps2 of order 1 */
+    15, 80, 768,
+    /* C2[4]/eps^4, polynomial in eps2 of order 1 */
+    7, 35, 512,
+    /* C2[5]/eps^5, polynomial in eps2 of order 0 */
+    63, 1280,
+    /* C2[6]/eps^6, polynomial in eps2 of order 0 */
+    77, 2048,
+  };
+  real
+    eps2 = sq(eps),
+    d = eps;
+  int o = 0, l;
+  for (l = 1; l <= nC2; ++l) { /* l is index of C2[l] */
+    int m = (nC2 - l) / 2;     /* order of polynomial in eps^2 */
+    c[l] = d * polyval(m, coeff + o, eps2) / coeff[o + m + 1];
+    o += m + 2;
+    d *= eps;
+  }
+}
+
+/* The scale factor A3 = mean value of (d/dsigma)I3 */
+void A3coeff(struct geod_geodesic* g) {
+  static const real coeff[] = {
+    /* A3, coeff of eps^5, polynomial in n of order 0 */
+    -3, 128,
+    /* A3, coeff of eps^4, polynomial in n of order 1 */
+    -2, -3, 64,
+    /* A3, coeff of eps^3, polynomial in n of order 2 */
+    -1, -3, -1, 16,
+    /* A3, coeff of eps^2, polynomial in n of order 2 */
+    3, -1, -2, 8,
+    /* A3, coeff of eps^1, polynomial in n of order 1 */
+    1, -1, 2,
+    /* A3, coeff of eps^0, polynomial in n of order 0 */
+    1, 1,
+  };
+  int o = 0, k = 0, j;
+  for (j = nA3 - 1; j >= 0; --j) {             /* coeff of eps^j */
+    int m = nA3 - j - 1 < j ? nA3 - j - 1 : j; /* order of polynomial in n */
+    g->A3x[k++] = polyval(m, coeff + o, g->n) / coeff[o + m + 1];
+    o += m + 2;
+  }
+}
+
+/* The coefficients C3[l] in the Fourier expansion of B3 */
+void C3coeff(struct geod_geodesic* g) {
+  static const real coeff[] = {
+    /* C3[1], coeff of eps^5, polynomial in n of order 0 */
+    3, 128,
+    /* C3[1], coeff of eps^4, polynomial in n of order 1 */
+    2, 5, 128,
+    /* C3[1], coeff of eps^3, polynomial in n of order 2 */
+    -1, 3, 3, 64,
+    /* C3[1], coeff of eps^2, polynomial in n of order 2 */
+    -1, 0, 1, 8,
+    /* C3[1], coeff of eps^1, polynomial in n of order 1 */
+    -1, 1, 4,
+    /* C3[2], coeff of eps^5, polynomial in n of order 0 */
+    5, 256,
+    /* C3[2], coeff of eps^4, polynomial in n of order 1 */
+    1, 3, 128,
+    /* C3[2], coeff of eps^3, polynomial in n of order 2 */
+    -3, -2, 3, 64,
+    /* C3[2], coeff of eps^2, polynomial in n of order 2 */
+    1, -3, 2, 32,
+    /* C3[3], coeff of eps^5, polynomial in n of order 0 */
+    7, 512,
+    /* C3[3], coeff of eps^4, polynomial in n of order 1 */
+    -10, 9, 384,
+    /* C3[3], coeff of eps^3, polynomial in n of order 2 */
+    5, -9, 5, 192,
+    /* C3[4], coeff of eps^5, polynomial in n of order 0 */
+    7, 512,
+    /* C3[4], coeff of eps^4, polynomial in n of order 1 */
+    -14, 7, 512,
+    /* C3[5], coeff of eps^5, polynomial in n of order 0 */
+    21, 2560,
+  };
+  int o = 0, k = 0, l, j;
+  for (l = 1; l < nC3; ++l) {                    /* l is index of C3[l] */
+    for (j = nC3 - 1; j >= l; --j) {             /* coeff of eps^j */
+      int m = nC3 - j - 1 < j ? nC3 - j - 1 : j; /* order of polynomial in n */
+      g->C3x[k++] = polyval(m, coeff + o, g->n) / coeff[o + m + 1];
+      o += m + 2;
+    }
+  }
+}
+
+/* The coefficients C4[l] in the Fourier expansion of I4 */
+void C4coeff(struct geod_geodesic* g) {
+  static const real coeff[] = {
+    /* C4[0], coeff of eps^5, polynomial in n of order 0 */
+    97, 15015,
+    /* C4[0], coeff of eps^4, polynomial in n of order 1 */
+    1088, 156, 45045,
+    /* C4[0], coeff of eps^3, polynomial in n of order 2 */
+    -224, -4784, 1573, 45045,
+    /* C4[0], coeff of eps^2, polynomial in n of order 3 */
+    -10656, 14144, -4576, -858, 45045,
+    /* C4[0], coeff of eps^1, polynomial in n of order 4 */
+    64, 624, -4576, 6864, -3003, 15015,
+    /* C4[0], coeff of eps^0, polynomial in n of order 5 */
+    100, 208, 572, 3432, -12012, 30030, 45045,
+    /* C4[1], coeff of eps^5, polynomial in n of order 0 */
+    1, 9009,
+    /* C4[1], coeff of eps^4, polynomial in n of order 1 */
+    -2944, 468, 135135,
+    /* C4[1], coeff of eps^3, polynomial in n of order 2 */
+    5792, 1040, -1287, 135135,
+    /* C4[1], coeff of eps^2, polynomial in n of order 3 */
+    5952, -11648, 9152, -2574, 135135,
+    /* C4[1], coeff of eps^1, polynomial in n of order 4 */
+    -64, -624, 4576, -6864, 3003, 135135,
+    /* C4[2], coeff of eps^5, polynomial in n of order 0 */
+    8, 10725,
+    /* C4[2], coeff of eps^4, polynomial in n of order 1 */
+    1856, -936, 225225,
+    /* C4[2], coeff of eps^3, polynomial in n of order 2 */
+    -8448, 4992, -1144, 225225,
+    /* C4[2], coeff of eps^2, polynomial in n of order 3 */
+    -1440, 4160, -4576, 1716, 225225,
+    /* C4[3], coeff of eps^5, polynomial in n of order 0 */
+    -136, 63063,
+    /* C4[3], coeff of eps^4, polynomial in n of order 1 */
+    1024, -208, 105105,
+    /* C4[3], coeff of eps^3, polynomial in n of order 2 */
+    3584, -3328, 1144, 315315,
+    /* C4[4], coeff of eps^5, polynomial in n of order 0 */
+    -128, 135135,
+    /* C4[4], coeff of eps^4, polynomial in n of order 1 */
+    -2560, 832, 405405,
+    /* C4[5], coeff of eps^5, polynomial in n of order 0 */
+    128, 99099,
+  };
+  int o = 0, k = 0, l, j;
+  for (l = 0; l < nC4; ++l) {        /* l is index of C4[l] */
+    for (j = nC4 - 1; j >= l; --j) { /* coeff of eps^j */
+      int m = nC4 - j - 1;           /* order of polynomial in n */
+      g->C4x[k++] = polyval(m, coeff + o, g->n) / coeff[o + m + 1];
+      o += m + 2;
+    }
+  }
+}
+
+int transit(real lon1, real lon2) {
+  real lon12;
+  /* Return 1 or -1 if crossing prime meridian in east or west direction.
+   * Otherwise return zero. */
+  /* Compute lon12 the same way as Geodesic::Inverse. */
+  lon1 = AngNormalize(lon1);
+  lon2 = AngNormalize(lon2);
+  lon12 = AngDiff(lon1, lon2, nullptr);
+  return lon1 <= 0 && lon2 > 0 && lon12 > 0 ? 1 :
+    (lon2 <= 0 && lon1 > 0 && lon12 < 0 ? -1 : 0);
+}
+
+int transitdirect(real lon1, real lon2) {
+  /* Compute exactly the parity of
+     int(ceil(lon2 / 360)) - int(ceil(lon1 / 360)) */
+  lon1 = remainderx(lon1, (real)(720));
+  lon2 = remainderx(lon2, (real)(720));
+  return ( (lon2 <= 0 && lon2 > -360 ? 1 : 0) -
+           (lon1 <= 0 && lon1 > -360 ? 1 : 0) );
+}
+
+void accini(real s[]) {
+  /* Initialize an accumulator; this is an array with two elements. */
+  s[0] = s[1] = 0;
+}
+
+void acccopy(const real s[], real t[]) {
+  /* Copy an accumulator; t = s. */
+  t[0] = s[0]; t[1] = s[1];
+}
+
+void accadd(real s[], real y) {
+  /* Add y to an accumulator. */
+  real u, z = sumx(y, s[1], &u);
+  s[0] = sumx(z, s[0], &s[1]);
+  if (s[0] == 0)
+    s[0] = u;
+  else
+    s[1] = s[1] + u;
+}
+
+real accsum(const real s[], real y) {
+  /* Return accumulator + y (but don't add to accumulator). */
+  real t[2];
+  acccopy(s, t);
+  accadd(t, y);
+  return t[0];
+}
+
+void accneg(real s[]) {
+  /* Negate an accumulator. */
+  s[0] = -s[0]; s[1] = -s[1];
+}
+
+void accrem(real s[], real y) {
+  /* Reduce to [-y/2, y/2]. */
+  s[0] = remainderx(s[0], y);
+  accadd(s, (real)(0));
+}
+
+void geod_polygon_init(struct geod_polygon* p, boolx polylinep) {
+  p->polyline = (polylinep != 0);
+  geod_polygon_clear(p);
+}
+
+void geod_polygon_clear(struct geod_polygon* p) {
+  p->lat0 = p->lon0 = p->lat = p->lon = NaN;
+  accini(p->P);
+  accini(p->A);
+  p->num = p->crossings = 0;
+}
+
+void geod_polygon_addpoint(const struct geod_geodesic* g,
+                           struct geod_polygon* p,
+                           real lat, real lon) {
+  lon = AngNormalize(lon);
+  if (p->num == 0) {
+    p->lat0 = p->lat = lat;
+    p->lon0 = p->lon = lon;
+  } else {
+    real s12, S12 = 0;       /* Initialize S12 to stop Visual Studio warning */
+    geod_geninverse(g, p->lat, p->lon, lat, lon,
+                    &s12, nullptr, nullptr, nullptr, nullptr, nullptr,
+                    p->polyline ? nullptr : &S12);
+    accadd(p->P, s12);
+    if (!p->polyline) {
+      accadd(p->A, S12);
+      p->crossings += transit(p->lon, lon);
+    }
+    p->lat = lat; p->lon = lon;
+  }
+  ++p->num;
+}
+
+void geod_polygon_addedge(const struct geod_geodesic* g,
+                          struct geod_polygon* p,
+                          real azi, real s) {
+  if (p->num) {              /* Do nothing is num is zero */
+    /* Initialize S12 to stop Visual Studio warning.  Initialization of lat and
+     * lon is to make CLang static analyzer happy. */
+    real lat = 0, lon = 0, S12 = 0;
+    geod_gendirect(g, p->lat, p->lon, azi, GEOD_LONG_UNROLL, s,
+                   &lat, &lon, nullptr,
+                   nullptr, nullptr, nullptr, nullptr,
+                   p->polyline ? nullptr : &S12);
+    accadd(p->P, s);
+    if (!p->polyline) {
+      accadd(p->A, S12);
+      p->crossings += transitdirect(p->lon, lon);
+    }
+    p->lat = lat; p->lon = lon;
+    ++p->num;
+  }
+}
+
+unsigned geod_polygon_compute(const struct geod_geodesic* g,
+                              const struct geod_polygon* p,
+                              boolx reverse, boolx sign,
+                              real* pA, real* pP) {
+  real s12, S12, t[2];
+  if (p->num < 2) {
+    if (pP) *pP = 0;
+    if (!p->polyline && pA) *pA = 0;
+    return p->num;
+  }
+  if (p->polyline) {
+    if (pP) *pP = p->P[0];
+    return p->num;
+  }
+  geod_geninverse(g, p->lat, p->lon, p->lat0, p->lon0,
+                  &s12, nullptr, nullptr, nullptr, nullptr, nullptr, &S12);
+  if (pP) *pP = accsum(p->P, s12);
+  acccopy(p->A, t);
+  accadd(t, S12);
+  if (pA) *pA = areareduceA(t, 4 * pi * g->c2,
+                            p->crossings + transit(p->lon, p->lon0),
+                            reverse, sign);
+  return p->num;
+}
+
+unsigned geod_polygon_testpoint(const struct geod_geodesic* g,
+                                const struct geod_polygon* p,
+                                real lat, real lon,
+                                boolx reverse, boolx sign,
+                                real* pA, real* pP) {
+  real perimeter, tempsum;
+  int crossings, i;
+  unsigned num = p->num + 1;
+  if (num == 1) {
+    if (pP) *pP = 0;
+    if (!p->polyline && pA) *pA = 0;
+    return num;
+  }
+  perimeter = p->P[0];
+  tempsum = p->polyline ? 0 : p->A[0];
+  crossings = p->crossings;
+  for (i = 0; i < (p->polyline ? 1 : 2); ++i) {
+    real s12, S12 = 0;       /* Initialize S12 to stop Visual Studio warning */
+    geod_geninverse(g,
+                    i == 0 ? p->lat  : lat, i == 0 ? p->lon  : lon,
+                    i != 0 ? p->lat0 : lat, i != 0 ? p->lon0 : lon,
+                    &s12, nullptr, nullptr, nullptr, nullptr, nullptr,
+                    p->polyline ? nullptr : &S12);
+    perimeter += s12;
+    if (!p->polyline) {
+      tempsum += S12;
+      crossings += transit(i == 0 ? p->lon  : lon,
+                           i != 0 ? p->lon0 : lon);
+    }
+  }
+
+  if (pP) *pP = perimeter;
+  if (p->polyline)
+    return num;
+
+  if (pA) *pA = areareduceB(tempsum, 4 * pi * g->c2, crossings, reverse, sign);
+  return num;
+}
+
+unsigned geod_polygon_testedge(const struct geod_geodesic* g,
+                               const struct geod_polygon* p,
+                               real azi, real s,
+                               boolx reverse, boolx sign,
+                               real* pA, real* pP) {
+  real perimeter, tempsum;
+  int crossings;
+  unsigned num = p->num + 1;
+  if (num == 1) {               /* we don't have a starting point! */
+    if (pP) *pP = NaN;
+    if (!p->polyline && pA) *pA = NaN;
+    return 0;
+  }
+  perimeter = p->P[0] + s;
+  if (p->polyline) {
+    if (pP) *pP = perimeter;
+    return num;
+  }
+
+  tempsum = p->A[0];
+  crossings = p->crossings;
+  {
+    /* Initialization of lat, lon, and S12 is to make CLang static analyzer
+     * happy. */
+    real lat = 0, lon = 0, s12, S12 = 0;
+    geod_gendirect(g, p->lat, p->lon, azi, GEOD_LONG_UNROLL, s,
+                   &lat, &lon, nullptr,
+                   nullptr, nullptr, nullptr, nullptr, &S12);
+    tempsum += S12;
+    crossings += transitdirect(p->lon, lon);
+    geod_geninverse(g, lat,  lon, p->lat0,  p->lon0,
+                    &s12, nullptr, nullptr, nullptr, nullptr, nullptr, &S12);
+    perimeter += s12;
+    tempsum += S12;
+    crossings += transit(lon, p->lon0);
+  }
+
+  if (pP) *pP = perimeter;
+  if (pA) *pA = areareduceB(tempsum, 4 * pi * g->c2, crossings, reverse, sign);
+  return num;
+}
+
+void geod_polygonarea(const struct geod_geodesic* g,
+                      real lats[], real lons[], int n,
+                      real* pA, real* pP) {
+  int i;
+  struct geod_polygon p;
+  geod_polygon_init(&p, FALSE);
+  for (i = 0; i < n; ++i)
+    geod_polygon_addpoint(g, &p, lats[i], lons[i]);
+  geod_polygon_compute(g, &p, FALSE, TRUE, pA, pP);
+}
+
+real areareduceA(real area[], real area0,
+                 int crossings, boolx reverse, boolx sign) {
+  accrem(area, area0);
+  if (crossings & 1)
+    accadd(area, (area[0] < 0 ? 1 : -1) * area0/2);
+  /* area is with the clockwise sense.  If !reverse convert to
+   * counter-clockwise convention. */
+  if (!reverse)
+    accneg(area);
+  /* If sign put area in (-area0/2, area0/2], else put area in [0, area0) */
+  if (sign) {
+    if (area[0] > area0/2)
+      accadd(area, -area0);
+    else if (area[0] <= -area0/2)
+      accadd(area, +area0);
+  } else {
+    if (area[0] >= area0)
+      accadd(area, -area0);
+    else if (area[0] < 0)
+      accadd(area, +area0);
+  }
+  return 0 + area[0];
+}
+
+real areareduceB(real area, real area0,
+                 int crossings, boolx reverse, boolx sign) {
+  area = remainderx(area, area0);
+    if (crossings & 1)
+    area += (area < 0 ? 1 : -1) * area0/2;
+  /* area is with the clockwise sense.  If !reverse convert to
+   * counter-clockwise convention. */
+  if (!reverse)
+    area *= -1;
+  /* If sign put area in (-area0/2, area0/2], else put area in [0, area0) */
+  if (sign) {
+    if (area > area0/2)
+      area -= area0;
+    else if (area <= -area0/2)
+      area += area0;
+  } else {
+    if (area >= area0)
+      area -= area0;
+    else if (area < 0)
+      area += area0;
+  }
+  return 0 + area;
+}
+
+/** @endcond */
diff --git a/pkg/geo/geographiclib/geodesic.h b/pkg/geo/geographiclib/geodesic.h
new file mode 100644
index 0000000..5d23053
--- /dev/null
+++ b/pkg/geo/geographiclib/geodesic.h
@@ -0,0 +1,933 @@
+/**
+ * \file geodesic.h
+ * \brief API for the geodesic routines in C
+ *
+ * This an implementation in C of the geodesic algorithms described in
+ * - C. F. F. Karney,
+ *   <a href="https://doi.org/10.1007/s00190-012-0578-z">
+ *   Algorithms for geodesics</a>,
+ *   J. Geodesy <b>87</b>, 43--55 (2013);
+ *   DOI: <a href="https://doi.org/10.1007/s00190-012-0578-z">
+ *   10.1007/s00190-012-0578-z</a>;
+ *   addenda: <a href="https://geographiclib.sourceforge.io/geod-addenda.html">
+ *   geod-addenda.html</a>.
+ * .
+ * The principal advantages of these algorithms over previous ones (e.g.,
+ * Vincenty, 1975) are
+ * - accurate to round off for |<i>f</i>| &lt; 1/50;
+ * - the solution of the inverse problem is always found;
+ * - differential and integral properties of geodesics are computed.
+ *
+ * The shortest path between two points on the ellipsoid at (\e lat1, \e
+ * lon1) and (\e lat2, \e lon2) is called the geodesic.  Its length is
+ * \e s12 and the geodesic from point 1 to point 2 has forward azimuths
+ * \e azi1 and \e azi2 at the two end points.
+ *
+ * Traditionally two geodesic problems are considered:
+ * - the direct problem -- given \e lat1, \e lon1, \e s12, and \e azi1,
+ *   determine \e lat2, \e lon2, and \e azi2.  This is solved by the function
+ *   geod_direct().
+ * - the inverse problem -- given \e lat1, \e lon1, and \e lat2, \e lon2,
+ *   determine \e s12, \e azi1, and \e azi2.  This is solved by the function
+ *   geod_inverse().
+ *
+ * The ellipsoid is specified by its equatorial radius \e a (typically in
+ * meters) and flattening \e f.  The routines are accurate to round off with
+ * double precision arithmetic provided that |<i>f</i>| &lt; 1/50; for the
+ * WGS84 ellipsoid, the errors are less than 15 nanometers.  (Reasonably
+ * accurate results are obtained for |<i>f</i>| &lt; 1/5.)  For a prolate
+ * ellipsoid, specify \e f &lt; 0.
+ *
+ * The routines also calculate several other quantities of interest
+ * - \e S12 is the area between the geodesic from point 1 to point 2 and the
+ *   equator; i.e., it is the area, measured counter-clockwise, of the
+ *   quadrilateral with corners (\e lat1,\e lon1), (0,\e lon1), (0,\e lon2),
+ *   and (\e lat2,\e lon2).
+ * - \e m12, the reduced length of the geodesic is defined such that if
+ *   the initial azimuth is perturbed by \e dazi1 (radians) then the
+ *   second point is displaced by \e m12 \e dazi1 in the direction
+ *   perpendicular to the geodesic.  On a curved surface the reduced
+ *   length obeys a symmetry relation, \e m12 + \e m21 = 0.  On a flat
+ *   surface, we have \e m12 = \e s12.
+ * - \e M12 and \e M21 are geodesic scales.  If two geodesics are
+ *   parallel at point 1 and separated by a small distance \e dt, then
+ *   they are separated by a distance \e M12 \e dt at point 2.  \e M21
+ *   is defined similarly (with the geodesics being parallel to one
+ *   another at point 2).  On a flat surface, we have \e M12 = \e M21
+ *   = 1.
+ * - \e a12 is the arc length on the auxiliary sphere.  This is a
+ *   construct for converting the problem to one in spherical
+ *   trigonometry.  \e a12 is measured in degrees.  The spherical arc
+ *   length from one equator crossing to the next is always 180&deg;.
+ *
+ * If points 1, 2, and 3 lie on a single geodesic, then the following
+ * addition rules hold:
+ * - \e s13 = \e s12 + \e s23
+ * - \e a13 = \e a12 + \e a23
+ * - \e S13 = \e S12 + \e S23
+ * - \e m13 = \e m12 \e M23 + \e m23 \e M21
+ * - \e M13 = \e M12 \e M23 &minus; (1 &minus; \e M12 \e M21) \e
+ *   m23 / \e m12
+ * - \e M31 = \e M32 \e M21 &minus; (1 &minus; \e M23 \e M32) \e
+ *   m12 / \e m23
+ *
+ * The shortest distance returned by the solution of the inverse problem is
+ * (obviously) uniquely defined.  However, in a few special cases there are
+ * multiple azimuths which yield the same shortest distance.  Here is a
+ * catalog of those cases:
+ * - \e lat1 = &minus;\e lat2 (with neither point at a pole).  If \e azi1 = \e
+ *   azi2, the geodesic is unique.  Otherwise there are two geodesics and the
+ *   second one is obtained by setting [\e azi1, \e azi2] &rarr; [\e azi2, \e
+ *   azi1], [\e M12, \e M21] &rarr; [\e M21, \e M12], \e S12 &rarr; &minus;\e
+ *   S12.  (This occurs when the longitude difference is near &plusmn;180&deg;
+ *   for oblate ellipsoids.)
+ * - \e lon2 = \e lon1 &plusmn; 180&deg; (with neither point at a pole).  If \e
+ *   azi1 = 0&deg; or &plusmn;180&deg;, the geodesic is unique.  Otherwise
+ *   there are two geodesics and the second one is obtained by setting [\e
+ *   azi1, \e azi2] &rarr; [&minus;\e azi1, &minus;\e azi2], \e S12 &rarr;
+ *   &minus;\e S12.  (This occurs when \e lat2 is near &minus;\e lat1 for
+ *   prolate ellipsoids.)
+ * - Points 1 and 2 at opposite poles.  There are infinitely many geodesics
+ *   which can be generated by setting [\e azi1, \e azi2] &rarr; [\e azi1, \e
+ *   azi2] + [\e d, &minus;\e d], for arbitrary \e d.  (For spheres, this
+ *   prescription applies when points 1 and 2 are antipodal.)
+ * - \e s12 = 0 (coincident points).  There are infinitely many geodesics which
+ *   can be generated by setting [\e azi1, \e azi2] &rarr; [\e azi1, \e azi2] +
+ *   [\e d, \e d], for arbitrary \e d.
+ *
+ * These routines are a simple transcription of the corresponding C++ classes
+ * in <a href="https://geographiclib.sourceforge.io"> GeographicLib</a>.  The
+ * "class data" is represented by the structs geod_geodesic, geod_geodesicline,
+ * geod_polygon and pointers to these objects are passed as initial arguments
+ * to the member functions.  Most of the internal comments have been retained.
+ * However, in the process of transcription some documentation has been lost
+ * and the documentation for the C++ classes, GeographicLib::Geodesic,
+ * GeographicLib::GeodesicLine, and GeographicLib::PolygonAreaT, should be
+ * consulted.  The C++ code remains the "reference implementation".  Think
+ * twice about restructuring the internals of the C code since this may make
+ * porting fixes from the C++ code more difficult.
+ *
+ * Copyright (c) Charles Karney (2012-2019) <charles@karney.com> and licensed
+ * under the MIT/X11 License.  For more information, see
+ * https://geographiclib.sourceforge.io/
+ *
+ * This library was distributed with
+ * <a href="../index.html">GeographicLib</a> 1.50.
+ **********************************************************************/
+
+#if !defined(GEODESIC_H)
+#define GEODESIC_H 1
+
+/**
+ * The major version of the geodesic library.  (This tracks the version of
+ * GeographicLib.)
+ **********************************************************************/
+#define GEODESIC_VERSION_MAJOR 1
+/**
+ * The minor version of the geodesic library.  (This tracks the version of
+ * GeographicLib.)
+ **********************************************************************/
+#define GEODESIC_VERSION_MINOR 50
+/**
+ * The patch level of the geodesic library.  (This tracks the version of
+ * GeographicLib.)
+ **********************************************************************/
+#define GEODESIC_VERSION_PATCH 0
+
+/**
+ * Pack the version components into a single integer.  Users should not rely on
+ * this particular packing of the components of the version number; see the
+ * documentation for GEODESIC_VERSION, below.
+ **********************************************************************/
+#define GEODESIC_VERSION_NUM(a,b,c) ((((a) * 10000 + (b)) * 100) + (c))
+
+/**
+ * The version of the geodesic library as a single integer, packed as MMmmmmpp
+ * where MM is the major version, mmmm is the minor version, and pp is the
+ * patch level.  Users should not rely on this particular packing of the
+ * components of the version number.  Instead they should use a test such as
+ * @code{.c}
+   #if GEODESIC_VERSION >= GEODESIC_VERSION_NUM(1,40,0)
+   ...
+   #endif
+ * @endcode
+ **********************************************************************/
+#define GEODESIC_VERSION \
+ GEODESIC_VERSION_NUM(GEODESIC_VERSION_MAJOR, \
+                      GEODESIC_VERSION_MINOR, \
+                      GEODESIC_VERSION_PATCH)
+
+#if !defined(GEOD_DLL)
+#if defined(_MSC_VER)
+#define GEOD_DLL __declspec(dllexport)
+#elif defined(__GNUC__)
+#define GEOD_DLL __attribute__ ((visibility("default")))
+#else
+#define GEOD_DLL
+#endif
+#endif
+
+#if defined(PROJ_RENAME_SYMBOLS)
+#include "proj_symbol_rename.h"
+#endif
+
+#if defined(__cplusplus)
+extern "C" {
+#endif
+
+  /**
+   * The struct containing information about the ellipsoid.  This must be
+   * initialized by geod_init() before use.
+   **********************************************************************/
+  struct geod_geodesic {
+    double a;                   /**< the equatorial radius */
+    double f;                   /**< the flattening */
+    /**< @cond SKIP */
+    double f1, e2, ep2, n, b, c2, etol2;
+    double A3x[6], C3x[15], C4x[21];
+    /**< @endcond */
+  };
+
+  /**
+   * The struct containing information about a single geodesic.  This must be
+   * initialized by geod_lineinit(), geod_directline(), geod_gendirectline(),
+   * or geod_inverseline() before use.
+   **********************************************************************/
+  struct geod_geodesicline {
+    double lat1;                /**< the starting latitude */
+    double lon1;                /**< the starting longitude */
+    double azi1;                /**< the starting azimuth */
+    double a;                   /**< the equatorial radius */
+    double f;                   /**< the flattening */
+    double salp1;               /**< sine of \e azi1 */
+    double calp1;               /**< cosine of \e azi1 */
+    double a13;                 /**< arc length to reference point */
+    double s13;                 /**< distance to reference point */
+    /**< @cond SKIP */
+    double b, c2, f1, salp0, calp0, k2,
+      ssig1, csig1, dn1, stau1, ctau1, somg1, comg1,
+      A1m1, A2m1, A3c, B11, B21, B31, A4, B41;
+    double C1a[6+1], C1pa[6+1], C2a[6+1], C3a[6], C4a[6];
+    /**< @endcond */
+    unsigned caps;              /**< the capabilities */
+  };
+
+  /**
+   * The struct for accumulating information about a geodesic polygon.  This is
+   * used for computing the perimeter and area of a polygon.  This must be
+   * initialized by geod_polygon_init() before use.
+   **********************************************************************/
+  struct geod_polygon {
+    double lat;                 /**< the current latitude */
+    double lon;                 /**< the current longitude */
+    /**< @cond SKIP */
+    double lat0;
+    double lon0;
+    double A[2];
+    double P[2];
+    int polyline;
+    int crossings;
+    /**< @endcond */
+    unsigned num;               /**< the number of points so far */
+  };
+
+  /**
+   * Initialize a geod_geodesic object.
+   *
+   * @param[out] g a pointer to the object to be initialized.
+   * @param[in] a the equatorial radius (meters).
+   * @param[in] f the flattening.
+   **********************************************************************/
+  void GEOD_DLL geod_init(struct geod_geodesic* g, double a, double f);
+
+  /**
+   * Solve the direct geodesic problem.
+   *
+   * @param[in] g a pointer to the geod_geodesic object specifying the
+   *   ellipsoid.
+   * @param[in] lat1 latitude of point 1 (degrees).
+   * @param[in] lon1 longitude of point 1 (degrees).
+   * @param[in] azi1 azimuth at point 1 (degrees).
+   * @param[in] s12 distance from point 1 to point 2 (meters); it can be
+   *   negative.
+   * @param[out] plat2 pointer to the latitude of point 2 (degrees).
+   * @param[out] plon2 pointer to the longitude of point 2 (degrees).
+   * @param[out] pazi2 pointer to the (forward) azimuth at point 2 (degrees).
+   *
+   * \e g must have been initialized with a call to geod_init().  \e lat1
+   * should be in the range [&minus;90&deg;, 90&deg;].  The values of \e lon2
+   * and \e azi2 returned are in the range [&minus;180&deg;, 180&deg;].  Any of
+   * the "return" arguments \e plat2, etc., may be replaced by 0, if you do not
+   * need some quantities computed.
+   *
+   * If either point is at a pole, the azimuth is defined by keeping the
+   * longitude fixed, writing \e lat = &plusmn;(90&deg; &minus; &epsilon;), and
+   * taking the limit &epsilon; &rarr; 0+.  An arc length greater that 180&deg;
+   * signifies a geodesic which is not a shortest path.  (For a prolate
+   * ellipsoid, an additional condition is necessary for a shortest path: the
+   * longitudinal extent must not exceed of 180&deg;.)
+   *
+   * Example, determine the point 10000 km NE of JFK:
+   @code{.c}
+   struct geod_geodesic g;
+   double lat, lon;
+   geod_init(&g, 6378137, 1/298.257223563);
+   geod_direct(&g, 40.64, -73.78, 45.0, 10e6, &lat, &lon, 0);
+   printf("%.5f %.5f\n", lat, lon);
+   @endcode
+   **********************************************************************/
+  void GEOD_DLL geod_direct(const struct geod_geodesic* g,
+                            double lat1, double lon1, double azi1, double s12,
+                            double* plat2, double* plon2, double* pazi2);
+
+  /**
+   * The general direct geodesic problem.
+   *
+   * @param[in] g a pointer to the geod_geodesic object specifying the
+   *   ellipsoid.
+   * @param[in] lat1 latitude of point 1 (degrees).
+   * @param[in] lon1 longitude of point 1 (degrees).
+   * @param[in] azi1 azimuth at point 1 (degrees).
+   * @param[in] flags bitor'ed combination of geod_flags(); \e flags &
+   *   GEOD_ARCMODE determines the meaning of \e s12_a12 and \e flags &
+   *   GEOD_LONG_UNROLL "unrolls" \e lon2.
+   * @param[in] s12_a12 if \e flags & GEOD_ARCMODE is 0, this is the distance
+   *   from point 1 to point 2 (meters); otherwise it is the arc length
+   *   from point 1 to point 2 (degrees); it can be negative.
+   * @param[out] plat2 pointer to the latitude of point 2 (degrees).
+   * @param[out] plon2 pointer to the longitude of point 2 (degrees).
+   * @param[out] pazi2 pointer to the (forward) azimuth at point 2 (degrees).
+   * @param[out] ps12 pointer to the distance from point 1 to point 2
+   *   (meters).
+   * @param[out] pm12 pointer to the reduced length of geodesic (meters).
+   * @param[out] pM12 pointer to the geodesic scale of point 2 relative to
+   *   point 1 (dimensionless).
+   * @param[out] pM21 pointer to the geodesic scale of point 1 relative to
+   *   point 2 (dimensionless).
+   * @param[out] pS12 pointer to the area under the geodesic
+   *   (meters<sup>2</sup>).
+   * @return \e a12 arc length from point 1 to point 2 (degrees).
+   *
+   * \e g must have been initialized with a call to geod_init().  \e lat1
+   * should be in the range [&minus;90&deg;, 90&deg;].  The function value \e
+   * a12 equals \e s12_a12 if \e flags & GEOD_ARCMODE.  Any of the "return"
+   * arguments, \e plat2, etc., may be replaced by 0, if you do not need some
+   * quantities computed.
+   *
+   * With \e flags & GEOD_LONG_UNROLL bit set, the longitude is "unrolled" so
+   * that the quantity \e lon2 &minus; \e lon1 indicates how many times and in
+   * what sense the geodesic encircles the ellipsoid.
+   **********************************************************************/
+  double GEOD_DLL geod_gendirect(const struct geod_geodesic* g,
+                                 double lat1, double lon1, double azi1,
+                                 unsigned flags, double s12_a12,
+                                 double* plat2, double* plon2, double* pazi2,
+                                 double* ps12, double* pm12,
+                                 double* pM12, double* pM21,
+                                 double* pS12);
+
+  /**
+   * Solve the inverse geodesic problem.
+   *
+   * @param[in] g a pointer to the geod_geodesic object specifying the
+   *   ellipsoid.
+   * @param[in] lat1 latitude of point 1 (degrees).
+   * @param[in] lon1 longitude of point 1 (degrees).
+   * @param[in] lat2 latitude of point 2 (degrees).
+   * @param[in] lon2 longitude of point 2 (degrees).
+   * @param[out] ps12 pointer to the distance from point 1 to point 2
+   *   (meters).
+   * @param[out] pazi1 pointer to the azimuth at point 1 (degrees).
+   * @param[out] pazi2 pointer to the (forward) azimuth at point 2 (degrees).
+   *
+   * \e g must have been initialized with a call to geod_init().  \e lat1 and
+   * \e lat2 should be in the range [&minus;90&deg;, 90&deg;].  The values of
+   * \e azi1 and \e azi2 returned are in the range [&minus;180&deg;, 180&deg;].
+   * Any of the "return" arguments, \e ps12, etc., may be replaced by 0, if you
+   * do not need some quantities computed.
+   *
+   * If either point is at a pole, the azimuth is defined by keeping the
+   * longitude fixed, writing \e lat = &plusmn;(90&deg; &minus; &epsilon;), and
+   * taking the limit &epsilon; &rarr; 0+.
+   *
+   * The solution to the inverse problem is found using Newton's method.  If
+   * this fails to converge (this is very unlikely in geodetic applications
+   * but does occur for very eccentric ellipsoids), then the bisection method
+   * is used to refine the solution.
+   *
+   * Example, determine the distance between JFK and Singapore Changi Airport:
+   @code{.c}
+   struct geod_geodesic g;
+   double s12;
+   geod_init(&g, 6378137, 1/298.257223563);
+   geod_inverse(&g, 40.64, -73.78, 1.36, 103.99, &s12, 0, 0);
+   printf("%.3f\n", s12);
+   @endcode
+   **********************************************************************/
+  void GEOD_DLL geod_inverse(const struct geod_geodesic* g,
+                             double lat1, double lon1,
+                             double lat2, double lon2,
+                             double* ps12, double* pazi1, double* pazi2);
+
+  /**
+   * The general inverse geodesic calculation.
+   *
+   * @param[in] g a pointer to the geod_geodesic object specifying the
+   *   ellipsoid.
+   * @param[in] lat1 latitude of point 1 (degrees).
+   * @param[in] lon1 longitude of point 1 (degrees).
+   * @param[in] lat2 latitude of point 2 (degrees).
+   * @param[in] lon2 longitude of point 2 (degrees).
+   * @param[out] ps12 pointer to the distance from point 1 to point 2
+   *  (meters).
+   * @param[out] pazi1 pointer to the azimuth at point 1 (degrees).
+   * @param[out] pazi2 pointer to the (forward) azimuth at point 2 (degrees).
+   * @param[out] pm12 pointer to the reduced length of geodesic (meters).
+   * @param[out] pM12 pointer to the geodesic scale of point 2 relative to
+   *   point 1 (dimensionless).
+   * @param[out] pM21 pointer to the geodesic scale of point 1 relative to
+   *   point 2 (dimensionless).
+   * @param[out] pS12 pointer to the area under the geodesic
+   *   (meters<sup>2</sup>).
+   * @return \e a12 arc length from point 1 to point 2 (degrees).
+   *
+   * \e g must have been initialized with a call to geod_init().  \e lat1 and
+   * \e lat2 should be in the range [&minus;90&deg;, 90&deg;].  Any of the
+   * "return" arguments \e ps12, etc., may be replaced by 0, if you do not need
+   * some quantities computed.
+   **********************************************************************/
+  double GEOD_DLL geod_geninverse(const struct geod_geodesic* g,
+                                  double lat1, double lon1,
+                                  double lat2, double lon2,
+                                  double* ps12, double* pazi1, double* pazi2,
+                                  double* pm12, double* pM12, double* pM21,
+                                  double* pS12);
+
+  /**
+   * Initialize a geod_geodesicline object.
+   *
+   * @param[out] l a pointer to the object to be initialized.
+   * @param[in] g a pointer to the geod_geodesic object specifying the
+   *   ellipsoid.
+   * @param[in] lat1 latitude of point 1 (degrees).
+   * @param[in] lon1 longitude of point 1 (degrees).
+   * @param[in] azi1 azimuth at point 1 (degrees).
+   * @param[in] caps bitor'ed combination of geod_mask() values specifying the
+   *   capabilities the geod_geodesicline object should possess, i.e., which
+   *   quantities can be returned in calls to geod_position() and
+   *   geod_genposition().
+   *
+   * \e g must have been initialized with a call to geod_init().  \e lat1
+   * should be in the range [&minus;90&deg;, 90&deg;].
+   *
+   * The geod_mask values are [see geod_mask()]:
+   * - \e caps |= GEOD_LATITUDE for the latitude \e lat2; this is
+   *   added automatically,
+   * - \e caps |= GEOD_LONGITUDE for the latitude \e lon2,
+   * - \e caps |= GEOD_AZIMUTH for the latitude \e azi2; this is
+   *   added automatically,
+   * - \e caps |= GEOD_DISTANCE for the distance \e s12,
+   * - \e caps |= GEOD_REDUCEDLENGTH for the reduced length \e m12,
+   * - \e caps |= GEOD_GEODESICSCALE for the geodesic scales \e M12
+   *   and \e M21,
+   * - \e caps |= GEOD_AREA for the area \e S12,
+   * - \e caps |= GEOD_DISTANCE_IN permits the length of the
+   *   geodesic to be given in terms of \e s12; without this capability the
+   *   length can only be specified in terms of arc length.
+   * .
+   * A value of \e caps = 0 is treated as GEOD_LATITUDE | GEOD_LONGITUDE |
+   * GEOD_AZIMUTH | GEOD_DISTANCE_IN (to support the solution of the "standard"
+   * direct problem).
+   *
+   * When initialized by this function, point 3 is undefined (l->s13 = l->a13 =
+   * NaN).
+   **********************************************************************/
+  void GEOD_DLL geod_lineinit(struct geod_geodesicline* l,
+                              const struct geod_geodesic* g,
+                              double lat1, double lon1, double azi1,
+                              unsigned caps);
+
+  /**
+   * Initialize a geod_geodesicline object in terms of the direct geodesic
+   * problem.
+   *
+   * @param[out] l a pointer to the object to be initialized.
+   * @param[in] g a pointer to the geod_geodesic object specifying the
+   *   ellipsoid.
+   * @param[in] lat1 latitude of point 1 (degrees).
+   * @param[in] lon1 longitude of point 1 (degrees).
+   * @param[in] azi1 azimuth at point 1 (degrees).
+   * @param[in] s12 distance from point 1 to point 2 (meters); it can be
+   *   negative.
+   * @param[in] caps bitor'ed combination of geod_mask() values specifying the
+   *   capabilities the geod_geodesicline object should possess, i.e., which
+   *   quantities can be returned in calls to geod_position() and
+   *   geod_genposition().
+   *
+   * This function sets point 3 of the geod_geodesicline to correspond to point
+   * 2 of the direct geodesic problem.  See geod_lineinit() for more
+   * information.
+   **********************************************************************/
+  void GEOD_DLL geod_directline(struct geod_geodesicline* l,
+                                const struct geod_geodesic* g,
+                                double lat1, double lon1,
+                                double azi1, double s12,
+                                unsigned caps);
+
+  /**
+   * Initialize a geod_geodesicline object in terms of the direct geodesic
+   * problem spacified in terms of either distance or arc length.
+   *
+   * @param[out] l a pointer to the object to be initialized.
+   * @param[in] g a pointer to the geod_geodesic object specifying the
+   *   ellipsoid.
+   * @param[in] lat1 latitude of point 1 (degrees).
+   * @param[in] lon1 longitude of point 1 (degrees).
+   * @param[in] azi1 azimuth at point 1 (degrees).
+   * @param[in] flags either GEOD_NOFLAGS or GEOD_ARCMODE to determining the
+   *   meaning of the \e s12_a12.
+   * @param[in] s12_a12 if \e flags = GEOD_NOFLAGS, this is the distance
+   *   from point 1 to point 2 (meters); if \e flags = GEOD_ARCMODE, it is
+   *   the arc length from point 1 to point 2 (degrees); it can be
+   *   negative.
+   * @param[in] caps bitor'ed combination of geod_mask() values specifying the
+   *   capabilities the geod_geodesicline object should possess, i.e., which
+   *   quantities can be returned in calls to geod_position() and
+   *   geod_genposition().
+   *
+   * This function sets point 3 of the geod_geodesicline to correspond to point
+   * 2 of the direct geodesic problem.  See geod_lineinit() for more
+   * information.
+   **********************************************************************/
+  void GEOD_DLL geod_gendirectline(struct geod_geodesicline* l,
+                                   const struct geod_geodesic* g,
+                                   double lat1, double lon1, double azi1,
+                                   unsigned flags, double s12_a12,
+                                   unsigned caps);
+
+  /**
+   * Initialize a geod_geodesicline object in terms of the inverse geodesic
+   * problem.
+   *
+   * @param[out] l a pointer to the object to be initialized.
+   * @param[in] g a pointer to the geod_geodesic object specifying the
+   *   ellipsoid.
+   * @param[in] lat1 latitude of point 1 (degrees).
+   * @param[in] lon1 longitude of point 1 (degrees).
+   * @param[in] lat2 latitude of point 2 (degrees).
+   * @param[in] lon2 longitude of point 2 (degrees).
+   * @param[in] caps bitor'ed combination of geod_mask() values specifying the
+   *   capabilities the geod_geodesicline object should possess, i.e., which
+   *   quantities can be returned in calls to geod_position() and
+   *   geod_genposition().
+   *
+   * This function sets point 3 of the geod_geodesicline to correspond to point
+   * 2 of the inverse geodesic problem.  See geod_lineinit() for more
+   * information.
+   **********************************************************************/
+  void GEOD_DLL geod_inverseline(struct geod_geodesicline* l,
+                                 const struct geod_geodesic* g,
+                                 double lat1, double lon1,
+                                 double lat2, double lon2,
+                                 unsigned caps);
+
+  /**
+   * Compute the position along a geod_geodesicline.
+   *
+   * @param[in] l a pointer to the geod_geodesicline object specifying the
+   *   geodesic line.
+   * @param[in] s12 distance from point 1 to point 2 (meters); it can be
+   *   negative.
+   * @param[out] plat2 pointer to the latitude of point 2 (degrees).
+   * @param[out] plon2 pointer to the longitude of point 2 (degrees); requires
+   *   that \e l was initialized with \e caps |= GEOD_LONGITUDE.
+   * @param[out] pazi2 pointer to the (forward) azimuth at point 2 (degrees).
+   *
+   * \e l must have been initialized with a call, e.g., to geod_lineinit(),
+   * with \e caps |= GEOD_DISTANCE_IN (or \e caps = 0).  The values of \e lon2
+   * and \e azi2 returned are in the range [&minus;180&deg;, 180&deg;].  Any of
+   * the "return" arguments \e plat2, etc., may be replaced by 0, if you do not
+   * need some quantities computed.
+   *
+   * Example, compute way points between JFK and Singapore Changi Airport
+   * the "obvious" way using geod_direct():
+   @code{.c}
+   struct geod_geodesic g;
+   double s12, azi1, lat[101],lon[101];
+   int i;
+   geod_init(&g, 6378137, 1/298.257223563);
+   geod_inverse(&g, 40.64, -73.78, 1.36, 103.99, &s12, &azi1, 0);
+   for (i = 0; i < 101; ++i) {
+     geod_direct(&g, 40.64, -73.78, azi1, i * s12 * 0.01, lat + i, lon + i, 0);
+     printf("%.5f %.5f\n", lat[i], lon[i]);
+   }
+   @endcode
+   * A faster way using geod_position():
+   @code{.c}
+   struct geod_geodesic g;
+   struct geod_geodesicline l;
+   double lat[101],lon[101];
+   int i;
+   geod_init(&g, 6378137, 1/298.257223563);
+   geod_inverseline(&l, &g, 40.64, -73.78, 1.36, 103.99, 0);
+   for (i = 0; i <= 100; ++i) {
+     geod_position(&l, i * l.s13 * 0.01, lat + i, lon + i, 0);
+     printf("%.5f %.5f\n", lat[i], lon[i]);
+   }
+   @endcode
+   **********************************************************************/
+  void GEOD_DLL geod_position(const struct geod_geodesicline* l, double s12,
+                              double* plat2, double* plon2, double* pazi2);
+
+  /**
+   * The general position function.
+   *
+   * @param[in] l a pointer to the geod_geodesicline object specifying the
+   *   geodesic line.
+   * @param[in] flags bitor'ed combination of geod_flags(); \e flags &
+   *   GEOD_ARCMODE determines the meaning of \e s12_a12 and \e flags &
+   *   GEOD_LONG_UNROLL "unrolls" \e lon2; if \e flags & GEOD_ARCMODE is 0,
+   *   then \e l must have been initialized with \e caps |= GEOD_DISTANCE_IN.
+   * @param[in] s12_a12 if \e flags & GEOD_ARCMODE is 0, this is the
+   *   distance from point 1 to point 2 (meters); otherwise it is the
+   *   arc length from point 1 to point 2 (degrees); it can be
+   *   negative.
+   * @param[out] plat2 pointer to the latitude of point 2 (degrees).
+   * @param[out] plon2 pointer to the longitude of point 2 (degrees); requires
+   *   that \e l was initialized with \e caps |= GEOD_LONGITUDE.
+   * @param[out] pazi2 pointer to the (forward) azimuth at point 2 (degrees).
+   * @param[out] ps12 pointer to the distance from point 1 to point 2
+   *   (meters); requires that \e l was initialized with \e caps |=
+   *   GEOD_DISTANCE.
+   * @param[out] pm12 pointer to the reduced length of geodesic (meters);
+   *   requires that \e l was initialized with \e caps |= GEOD_REDUCEDLENGTH.
+   * @param[out] pM12 pointer to the geodesic scale of point 2 relative to
+   *   point 1 (dimensionless); requires that \e l was initialized with \e caps
+   *   |= GEOD_GEODESICSCALE.
+   * @param[out] pM21 pointer to the geodesic scale of point 1 relative to
+   *   point 2 (dimensionless); requires that \e l was initialized with \e caps
+   *   |= GEOD_GEODESICSCALE.
+   * @param[out] pS12 pointer to the area under the geodesic
+   *   (meters<sup>2</sup>); requires that \e l was initialized with \e caps |=
+   *   GEOD_AREA.
+   * @return \e a12 arc length from point 1 to point 2 (degrees).
+   *
+   * \e l must have been initialized with a call to geod_lineinit() with \e
+   * caps |= GEOD_DISTANCE_IN.  The value \e azi2 returned is in the range
+   * [&minus;180&deg;, 180&deg;].  Any of the "return" arguments \e plat2,
+   * etc., may be replaced by 0, if you do not need some quantities
+   * computed.  Requesting a value which \e l is not capable of computing
+   * is not an error; the corresponding argument will not be altered.
+   *
+   * With \e flags & GEOD_LONG_UNROLL bit set, the longitude is "unrolled" so
+   * that the quantity \e lon2 &minus; \e lon1 indicates how many times and in
+   * what sense the geodesic encircles the ellipsoid.
+   *
+   * Example, compute way points between JFK and Singapore Changi Airport using
+   * geod_genposition().  In this example, the points are evenly space in arc
+   * length (and so only approximately equally spaced in distance).  This is
+   * faster than using geod_position() and would be appropriate if drawing the
+   * path on a map.
+   @code{.c}
+   struct geod_geodesic g;
+   struct geod_geodesicline l;
+   double lat[101], lon[101];
+   int i;
+   geod_init(&g, 6378137, 1/298.257223563);
+   geod_inverseline(&l, &g, 40.64, -73.78, 1.36, 103.99,
+                    GEOD_LATITUDE | GEOD_LONGITUDE);
+   for (i = 0; i <= 100; ++i) {
+     geod_genposition(&l, GEOD_ARCMODE, i * l.a13 * 0.01,
+                      lat + i, lon + i, 0, 0, 0, 0, 0, 0);
+     printf("%.5f %.5f\n", lat[i], lon[i]);
+   }
+   @endcode
+   **********************************************************************/
+  double GEOD_DLL geod_genposition(const struct geod_geodesicline* l,
+                                   unsigned flags, double s12_a12,
+                                   double* plat2, double* plon2, double* pazi2,
+                                   double* ps12, double* pm12,
+                                   double* pM12, double* pM21,
+                                   double* pS12);
+
+  /**
+   * Specify position of point 3 in terms of distance.
+   *
+   * @param[in,out] l a pointer to the geod_geodesicline object.
+   * @param[in] s13 the distance from point 1 to point 3 (meters); it
+   *   can be negative.
+   *
+   * This is only useful if the geod_geodesicline object has been constructed
+   * with \e caps |= GEOD_DISTANCE_IN.
+   **********************************************************************/
+  void GEOD_DLL geod_setdistance(struct geod_geodesicline* l, double s13);
+
+  /**
+   * Specify position of point 3 in terms of either distance or arc length.
+   *
+   * @param[in,out] l a pointer to the geod_geodesicline object.
+   * @param[in] flags either GEOD_NOFLAGS or GEOD_ARCMODE to determining the
+   *   meaning of the \e s13_a13.
+   * @param[in] s13_a13 if \e flags = GEOD_NOFLAGS, this is the distance
+   *   from point 1 to point 3 (meters); if \e flags = GEOD_ARCMODE, it is
+   *   the arc length from point 1 to point 3 (degrees); it can be
+   *   negative.
+   *
+   * If flags = GEOD_NOFLAGS, this calls geod_setdistance().  If flags =
+   * GEOD_ARCMODE, the \e s13 is only set if the geod_geodesicline object has
+   * been constructed with \e caps |= GEOD_DISTANCE.
+   **********************************************************************/
+  void GEOD_DLL geod_gensetdistance(struct geod_geodesicline* l,
+                                    unsigned flags, double s13_a13);
+
+  /**
+   * Initialize a geod_polygon object.
+   *
+   * @param[out] p a pointer to the object to be initialized.
+   * @param[in] polylinep non-zero if a polyline instead of a polygon.
+   *
+   * If \e polylinep is zero, then the sequence of vertices and edges added by
+   * geod_polygon_addpoint() and geod_polygon_addedge() define a polygon and
+   * the perimeter and area are returned by geod_polygon_compute().  If \e
+   * polylinep is non-zero, then the vertices and edges define a polyline and
+   * only the perimeter is returned by geod_polygon_compute().
+   *
+   * The area and perimeter are accumulated at two times the standard floating
+   * point precision to guard against the loss of accuracy with many-sided
+   * polygons.  At any point you can ask for the perimeter and area so far.
+   *
+   * An example of the use of this function is given in the documentation for
+   * geod_polygon_compute().
+   **********************************************************************/
+  void GEOD_DLL geod_polygon_init(struct geod_polygon* p, int polylinep);
+
+  /**
+   * Clear the polygon, allowing a new polygon to be started.
+   *
+   * @param[in,out] p a pointer to the object to be cleared.
+   **********************************************************************/
+  void GEOD_DLL geod_polygon_clear(struct geod_polygon* p);
+
+  /**
+   * Add a point to the polygon or polyline.
+   *
+   * @param[in] g a pointer to the geod_geodesic object specifying the
+   *   ellipsoid.
+   * @param[in,out] p a pointer to the geod_polygon object specifying the
+   *   polygon.
+   * @param[in] lat the latitude of the point (degrees).
+   * @param[in] lon the longitude of the point (degrees).
+   *
+   * \e g and \e p must have been initialized with calls to geod_init() and
+   * geod_polygon_init(), respectively.  The same \e g must be used for all the
+   * points and edges in a polygon.  \e lat should be in the range
+   * [&minus;90&deg;, 90&deg;].
+   *
+   * An example of the use of this function is given in the documentation for
+   * geod_polygon_compute().
+   **********************************************************************/
+  void GEOD_DLL geod_polygon_addpoint(const struct geod_geodesic* g,
+                                      struct geod_polygon* p,
+                                      double lat, double lon);
+
+  /**
+   * Add an edge to the polygon or polyline.
+   *
+   * @param[in] g a pointer to the geod_geodesic object specifying the
+   *   ellipsoid.
+   * @param[in,out] p a pointer to the geod_polygon object specifying the
+   *   polygon.
+   * @param[in] azi azimuth at current point (degrees).
+   * @param[in] s distance from current point to next point (meters).
+   *
+   * \e g and \e p must have been initialized with calls to geod_init() and
+   * geod_polygon_init(), respectively.  The same \e g must be used for all the
+   * points and edges in a polygon.  This does nothing if no points have been
+   * added yet.  The \e lat and \e lon fields of \e p give the location of the
+   * new vertex.
+   **********************************************************************/
+  void GEOD_DLL geod_polygon_addedge(const struct geod_geodesic* g,
+                                     struct geod_polygon* p,
+                                     double azi, double s);
+
+  /**
+   * Return the results for a polygon.
+   *
+   * @param[in] g a pointer to the geod_geodesic object specifying the
+   *   ellipsoid.
+   * @param[in] p a pointer to the geod_polygon object specifying the polygon.
+   * @param[in] reverse if non-zero then clockwise (instead of
+   *   counter-clockwise) traversal counts as a positive area.
+   * @param[in] sign if non-zero then return a signed result for the area if
+   *   the polygon is traversed in the "wrong" direction instead of returning
+   *   the area for the rest of the earth.
+   * @param[out] pA pointer to the area of the polygon (meters<sup>2</sup>);
+   *   only set if \e polyline is non-zero in the call to geod_polygon_init().
+   * @param[out] pP pointer to the perimeter of the polygon or length of the
+   *   polyline (meters).
+   * @return the number of points.
+   *
+   * The area and perimeter are accumulated at two times the standard floating
+   * point precision to guard against the loss of accuracy with many-sided
+   * polygons.  Arbitrarily complex polygons are allowed.  In the case of
+   * self-intersecting polygons the area is accumulated "algebraically", e.g.,
+   * the areas of the 2 loops in a figure-8 polygon will partially cancel.
+   * There's no need to "close" the polygon by repeating the first vertex.  Set
+   * \e pA or \e pP to zero, if you do not want the corresponding quantity
+   * returned.
+   *
+   * More points can be added to the polygon after this call.
+   *
+   * Example, compute the perimeter and area of the geodesic triangle with
+   * vertices (0&deg;N,0&deg;E), (0&deg;N,90&deg;E), (90&deg;N,0&deg;E).
+   @code{.c}
+   double A, P;
+   int n;
+   struct geod_geodesic g;
+   struct geod_polygon p;
+   geod_init(&g, 6378137, 1/298.257223563);
+   geod_polygon_init(&p, 0);
+
+   geod_polygon_addpoint(&g, &p,  0,  0);
+   geod_polygon_addpoint(&g, &p,  0, 90);
+   geod_polygon_addpoint(&g, &p, 90,  0);
+   n = geod_polygon_compute(&g, &p, 0, 1, &A, &P);
+   printf("%d %.8f %.3f\n", n, P, A);
+   @endcode
+   **********************************************************************/
+  unsigned GEOD_DLL geod_polygon_compute(const struct geod_geodesic* g,
+                                         const struct geod_polygon* p,
+                                         int reverse, int sign,
+                                         double* pA, double* pP);
+
+  /**
+   * Return the results assuming a tentative final test point is added;
+   * however, the data for the test point is not saved.  This lets you report a
+   * running result for the perimeter and area as the user moves the mouse
+   * cursor.  Ordinary floating point arithmetic is used to accumulate the data
+   * for the test point; thus the area and perimeter returned are less accurate
+   * than if geod_polygon_addpoint() and geod_polygon_compute() are used.
+   *
+   * @param[in] g a pointer to the geod_geodesic object specifying the
+   *   ellipsoid.
+   * @param[in] p a pointer to the geod_polygon object specifying the polygon.
+   * @param[in] lat the latitude of the test point (degrees).
+   * @param[in] lon the longitude of the test point (degrees).
+   * @param[in] reverse if non-zero then clockwise (instead of
+   *   counter-clockwise) traversal counts as a positive area.
+   * @param[in] sign if non-zero then return a signed result for the area if
+   *   the polygon is traversed in the "wrong" direction instead of returning
+   *   the area for the rest of the earth.
+   * @param[out] pA pointer to the area of the polygon (meters<sup>2</sup>);
+   *   only set if \e polyline is non-zero in the call to geod_polygon_init().
+   * @param[out] pP pointer to the perimeter of the polygon or length of the
+   *   polyline (meters).
+   * @return the number of points.
+   *
+   * \e lat should be in the range [&minus;90&deg;, 90&deg;].
+   **********************************************************************/
+  unsigned GEOD_DLL geod_polygon_testpoint(const struct geod_geodesic* g,
+                                           const struct geod_polygon* p,
+                                           double lat, double lon,
+                                           int reverse, int sign,
+                                           double* pA, double* pP);
+
+  /**
+   * Return the results assuming a tentative final test point is added via an
+   * azimuth and distance; however, the data for the test point is not saved.
+   * This lets you report a running result for the perimeter and area as the
+   * user moves the mouse cursor.  Ordinary floating point arithmetic is used
+   * to accumulate the data for the test point; thus the area and perimeter
+   * returned are less accurate than if geod_polygon_addedge() and
+   * geod_polygon_compute() are used.
+   *
+   * @param[in] g a pointer to the geod_geodesic object specifying the
+   *   ellipsoid.
+   * @param[in] p a pointer to the geod_polygon object specifying the polygon.
+   * @param[in] azi azimuth at current point (degrees).
+   * @param[in] s distance from current point to final test point (meters).
+   * @param[in] reverse if non-zero then clockwise (instead of
+   *   counter-clockwise) traversal counts as a positive area.
+   * @param[in] sign if non-zero then return a signed result for the area if
+   *   the polygon is traversed in the "wrong" direction instead of returning
+   *   the area for the rest of the earth.
+   * @param[out] pA pointer to the area of the polygon (meters<sup>2</sup>);
+   *   only set if \e polyline is non-zero in the call to geod_polygon_init().
+   * @param[out] pP pointer to the perimeter of the polygon or length of the
+   *   polyline (meters).
+   * @return the number of points.
+   **********************************************************************/
+  unsigned GEOD_DLL geod_polygon_testedge(const struct geod_geodesic* g,
+                                          const struct geod_polygon* p,
+                                          double azi, double s,
+                                          int reverse, int sign,
+                                          double* pA, double* pP);
+
+  /**
+   * A simple interface for computing the area of a geodesic polygon.
+   *
+   * @param[in] g a pointer to the geod_geodesic object specifying the
+   *   ellipsoid.
+   * @param[in] lats an array of latitudes of the polygon vertices (degrees).
+   * @param[in] lons an array of longitudes of the polygon vertices (degrees).
+   * @param[in] n the number of vertices.
+   * @param[out] pA pointer to the area of the polygon (meters<sup>2</sup>).
+   * @param[out] pP pointer to the perimeter of the polygon (meters).
+   *
+   * \e lats should be in the range [&minus;90&deg;, 90&deg;].
+   *
+   * Arbitrarily complex polygons are allowed.  In the case self-intersecting
+   * of polygons the area is accumulated "algebraically", e.g., the areas of
+   * the 2 loops in a figure-8 polygon will partially cancel.  There's no need
+   * to "close" the polygon by repeating the first vertex.  The area returned
+   * is signed with counter-clockwise traversal being treated as positive.
+   *
+   * Example, compute the area of Antarctica:
+   @code{.c}
+   double
+     lats[] = {-72.9, -71.9, -74.9, -74.3, -77.5, -77.4, -71.7, -65.9, -65.7,
+               -66.6, -66.9, -69.8, -70.0, -71.0, -77.3, -77.9, -74.7},
+     lons[] = {-74, -102, -102, -131, -163, 163, 172, 140, 113,
+                88, 59, 25, -4, -14, -33, -46, -61};
+   struct geod_geodesic g;
+   double A, P;
+   geod_init(&g, 6378137, 1/298.257223563);
+   geod_polygonarea(&g, lats, lons, (sizeof lats) / (sizeof lats[0]), &A, &P);
+   printf("%.0f %.2f\n", A, P);
+   @endcode
+   **********************************************************************/
+  void GEOD_DLL geod_polygonarea(const struct geod_geodesic* g,
+                                 double lats[], double lons[], int n,
+                                 double* pA, double* pP);
+
+  /**
+   * mask values for the \e caps argument to geod_lineinit().
+   **********************************************************************/
+  enum geod_mask {
+    GEOD_NONE         = 0U,                    /**< Calculate nothing */
+    GEOD_LATITUDE     = 1U<<7  | 0U,           /**< Calculate latitude */
+    GEOD_LONGITUDE    = 1U<<8  | 1U<<3,        /**< Calculate longitude */
+    GEOD_AZIMUTH      = 1U<<9  | 0U,           /**< Calculate azimuth */
+    GEOD_DISTANCE     = 1U<<10 | 1U<<0,        /**< Calculate distance */
+    GEOD_DISTANCE_IN  = 1U<<11 | 1U<<0 | 1U<<1,/**< Allow distance as input  */
+    GEOD_REDUCEDLENGTH= 1U<<12 | 1U<<0 | 1U<<2,/**< Calculate reduced length */
+    GEOD_GEODESICSCALE= 1U<<13 | 1U<<0 | 1U<<2,/**< Calculate geodesic scale */
+    GEOD_AREA         = 1U<<14 | 1U<<4,        /**< Calculate reduced length */
+    GEOD_ALL          = 0x7F80U| 0x1FU         /**< Calculate everything */
+  };
+
+  /**
+   * flag values for the \e flags argument to geod_gendirect() and
+   * geod_genposition()
+   **********************************************************************/
+  enum geod_flags {
+    GEOD_NOFLAGS      = 0U,     /**< No flags */
+    GEOD_ARCMODE      = 1U<<0,  /**< Position given in terms of arc distance */
+    GEOD_LONG_UNROLL  = 1U<<15  /**< Unroll the longitude */
+  };
+
+#if defined(__cplusplus)
+}
+#endif
+
+#endif
diff --git a/pkg/geo/geographiclib/geographiclib.cc b/pkg/geo/geographiclib/geographiclib.cc
new file mode 100644
index 0000000..140c33e
--- /dev/null
+++ b/pkg/geo/geographiclib/geographiclib.cc
@@ -0,0 +1,22 @@
+// Copyright 2020 The Cockroach Authors.
+//
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
+
+#include "geodesic.h"
+#include "geographiclib.h"
+
+void CR_GEOGRAPHICLIB_InverseBatch(
+  struct geod_geodesic* spheroid,
+  double lats[],
+  double lngs[],
+  int len,
+  double *result
+) {
+  *result = 0;
+  for (int i = 0; i < len - 1; i++) {
+    double s12, az1, az2;
+    geod_inverse(spheroid, lats[i], lngs[i], lats[i+1], lngs[i+1], &s12, &az1, &az2);
+    *result += s12;
+  }
+}
diff --git a/pkg/geo/geographiclib/geographiclib.go b/pkg/geo/geographiclib/geographiclib.go
new file mode 100644
index 0000000..f5c250e
--- /dev/null
+++ b/pkg/geo/geographiclib/geographiclib.go
@@ -0,0 +1,153 @@
+// Copyright 2020 The Cockroach Authors.
+//
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
+
+// Package geographiclib is a wrapper around the GeographicLib library.
+package geographiclib
+
+// #cgo CXXFLAGS: -std=c++14
+// #cgo LDFLAGS: -lm
+//
+// #include "geodesic.h"
+// #include "geographiclib.h"
+import "C"
+
+import (
+	"math"
+
+	"github.com/cockroachdb/cockroachdb-parser/pkg/geo/geoprojbase"
+	"github.com/golang/geo/s1"
+	"github.com/golang/geo/s2"
+)
+
+func init() {
+	geoprojbase.MakeSpheroid = func(radius, flattening float64) (geoprojbase.Spheroid, error) {
+		return NewSpheroid(radius, flattening), nil
+	}
+}
+
+var (
+	// WGS84Spheroid represents the default WGS84 ellipsoid.
+	WGS84Spheroid = NewSpheroid(6378137, 1/298.257223563)
+)
+
+// Spheroid is an object that can perform geodesic operations
+// on a given spheroid.
+type Spheroid struct {
+	cRepr        C.struct_geod_geodesic
+	radius       float64
+	flattening   float64
+	sphereRadius float64
+}
+
+// NewSpheroid creates a spheroid from a radius and flattening.
+func NewSpheroid(radius float64, flattening float64) *Spheroid {
+	minorAxis := radius - radius*flattening
+	s := &Spheroid{
+		radius:       radius,
+		flattening:   flattening,
+		sphereRadius: (radius*2 + minorAxis) / 3,
+	}
+	C.geod_init(&s.cRepr, C.double(radius), C.double(flattening))
+	return s
+}
+
+// Radius returns the radius of the spheroid.
+func (s *Spheroid) Radius() float64 {
+	return s.radius
+}
+
+// Flattening returns the flattening factor of the spheroid.
+func (s *Spheroid) Flattening() float64 {
+	return s.flattening
+}
+
+// SphereRadius returns the radius of a sphere that fits inside the spheroid.
+func (s *Spheroid) SphereRadius() float64 {
+	return s.sphereRadius
+}
+
+// Inverse solves the geodetic inverse problem on the given spheroid
+// (https://en.wikipedia.org/wiki/Geodesy#Geodetic_problems).
+// Returns s12 (distance in meters), az1 (azimuth at point 1) and az2 (azimuth at point 2).
+func (s *Spheroid) Inverse(a, b s2.LatLng) (s12, az1, az2 float64) {
+	var retS12, retAZ1, retAZ2 C.double
+	C.geod_inverse(
+		&s.cRepr,
+		C.double(a.Lat.Degrees()),
+		C.double(a.Lng.Degrees()),
+		C.double(b.Lat.Degrees()),
+		C.double(b.Lng.Degrees()),
+		&retS12,
+		&retAZ1,
+		&retAZ2,
+	)
+	return float64(retS12), float64(retAZ1), float64(retAZ2)
+}
+
+// InverseBatch computes the sum of the length of the lines represented
+// by the line of points.
+// This is intended for use for LineStrings. LinearRings/Polygons should use "AreaAndPerimeter".
+// Returns the sum of the s12 (distance in meters) units.
+func (s *Spheroid) InverseBatch(points []s2.Point) float64 {
+	lats := make([]C.double, len(points))
+	lngs := make([]C.double, len(points))
+	for i, p := range points {
+		latlng := s2.LatLngFromPoint(p)
+		lats[i] = C.double(latlng.Lat.Degrees())
+		lngs[i] = C.double(latlng.Lng.Degrees())
+	}
+	var result C.double
+	C.CR_GEOGRAPHICLIB_InverseBatch(
+		&s.cRepr,
+		&lats[0],
+		&lngs[0],
+		C.int(len(points)),
+		&result,
+	)
+	return float64(result)
+}
+
+// AreaAndPerimeter computes the area and perimeter of a polygon on a given spheroid.
+// The points must never be duplicated (i.e. do not include the "final" point of a Polygon LinearRing).
+// Area is in meter^2, Perimeter is in meters.
+func (s *Spheroid) AreaAndPerimeter(points []s2.Point) (area float64, perimeter float64) {
+	lats := make([]C.double, len(points))
+	lngs := make([]C.double, len(points))
+	for i, p := range points {
+		latlng := s2.LatLngFromPoint(p)
+		lats[i] = C.double(latlng.Lat.Degrees())
+		lngs[i] = C.double(latlng.Lng.Degrees())
+	}
+	var areaDouble, perimeterDouble C.double
+	C.geod_polygonarea(
+		&s.cRepr,
+		&lats[0],
+		&lngs[0],
+		C.int(len(points)),
+		&areaDouble,
+		&perimeterDouble,
+	)
+	return float64(areaDouble), float64(perimeterDouble)
+}
+
+// Project returns computes the location of the projected point.
+//
+// Using the direct geodesic problem from GeographicLib (Karney 2013).
+func (s *Spheroid) Project(point s2.LatLng, distance float64, azimuth s1.Angle) s2.LatLng {
+	var lat, lng C.double
+
+	C.geod_direct(
+		&s.cRepr,
+		C.double(point.Lat.Degrees()),
+		C.double(point.Lng.Degrees()),
+		C.double(azimuth*180.0/math.Pi),
+		C.double(distance),
+		&lat,
+		&lng,
+		nil,
+	)
+
+	return s2.LatLngFromDegrees(float64(lat), float64(lng))
+}
diff --git a/pkg/geo/geographiclib/geographiclib.h b/pkg/geo/geographiclib/geographiclib.h
new file mode 100644
index 0000000..6fbe660
--- /dev/null
+++ b/pkg/geo/geographiclib/geographiclib.h
@@ -0,0 +1,25 @@
+// Copyright 2020 The Cockroach Authors.
+//
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
+
+#include "geodesic.h"
+
+#if defined(__cplusplus)
+extern "C" {
+#endif
+
+// CR_GEOGRAPHICLIB_InverseBatch computes the sum of the length of the lines
+// represented by an array of lat/lngs using Inverse from GeographicLib.
+// It is batched in C++ to reduce the cgo overheads.
+void CR_GEOGRAPHICLIB_InverseBatch(
+  struct geod_geodesic* spheroid,
+  double lats[],
+  double lngs[],
+  int len,
+  double *result
+);
+
+#if defined(__cplusplus)
+}
+#endif
diff --git a/pkg/geo/geoindex/geoindex.go b/pkg/geo/geoindex/geoindex.go
new file mode 100644
index 0000000..f9350cc
--- /dev/null
+++ b/pkg/geo/geoindex/geoindex.go
@@ -0,0 +1,714 @@
+// Copyright 2020 The Cockroach Authors.
+//
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
+
+package geoindex
+
+import (
+	"context"
+	"fmt"
+	"math"
+	"sort"
+	"strings"
+
+	"github.com/cockroachdb/cockroachdb-parser/pkg/geo"
+	"github.com/cockroachdb/cockroachdb-parser/pkg/geo/geogfn"
+	// Blank import so projections are initialized correctly.
+	_ "github.com/cockroachdb/cockroachdb-parser/pkg/geo/geographiclib"
+	"github.com/cockroachdb/cockroachdb-parser/pkg/geo/geopb"
+	"github.com/golang/geo/s2"
+	"github.com/twpayne/go-geom"
+)
+
+// RelationshipMap contains all the geospatial functions that can be index-
+// accelerated. Each function implies a certain type of geospatial relationship,
+// which affects how the index is queried as part of a constrained scan or
+// geospatial lookup join. RelationshipMap maps the function name to its
+// corresponding relationship (Covers, CoveredBy, DFullyWithin, DWithin or Intersects).
+//
+// Note that for all of these functions, a geospatial lookup join or constrained
+// index scan may produce false positives. Therefore, the original function must
+// be called on the output of the index operation to filter the results.
+var RelationshipMap = map[string]RelationshipType{
+	"st_covers":                Covers,
+	"st_coveredby":             CoveredBy,
+	"st_contains":              Covers,
+	"st_containsproperly":      Covers,
+	"st_crosses":               Intersects,
+	"st_dwithin":               DWithin,
+	"st_dfullywithin":          DFullyWithin,
+	"st_equals":                Intersects,
+	"st_intersects":            Intersects,
+	"st_overlaps":              Intersects,
+	"st_touches":               Intersects,
+	"st_within":                CoveredBy,
+	"st_dwithinexclusive":      DWithin,
+	"st_dfullywithinexclusive": DFullyWithin,
+}
+
+// RelationshipReverseMap contains a default function for each of the
+// possible geospatial relationships.
+var RelationshipReverseMap = map[RelationshipType]string{
+	Covers:       "st_covers",
+	CoveredBy:    "st_coveredby",
+	DWithin:      "st_dwithin",
+	DFullyWithin: "st_dfullywithin",
+	Intersects:   "st_intersects",
+}
+
+// CommuteRelationshipMap is used to determine how the geospatial
+// relationship changes if the arguments to the index-accelerated function are
+// commuted.
+//
+// The relationships in the RelationshipMap map above only apply when the
+// second argument to the function is the indexed column. If the arguments are
+// commuted so that the first argument is the indexed column, the relationship
+// may change.
+var CommuteRelationshipMap = map[RelationshipType]RelationshipType{
+	Covers:       CoveredBy,
+	CoveredBy:    Covers,
+	DWithin:      DWithin,
+	DFullyWithin: DFullyWithin,
+	Intersects:   Intersects,
+}
+
+// Interfaces for accelerating certain spatial operations, by allowing the
+// caller to use an externally stored index.
+//
+// An index interface has methods that specify what to write or read from the
+// stored index. It is the caller's responsibility to do the actual writes and
+// reads. Index keys are represented using uint64 which implies that the index
+// is transforming the 2D space (spherical or planar) to 1D space, say using a
+// space-filling curve. The index can return false positives so query
+// execution must use an exact filtering step after using the index. The
+// current implementations use the S2 geometry library.
+//
+// The externally stored index must support key-value semantics and range
+// queries over keys. The return values from Covers/CoveredBy/Intersects are
+// specialized to the computation that needs to be performed:
+// - Intersects needs to union (a) all the ranges corresponding to subtrees
+//   rooted at the covering of g, (b) all the parent nodes of the covering
+//   of g. The individual entries in (b) are representable as ranges of
+//   length 1. All of this is represented as UnionKeySpans. Covers, which
+//   is the shape that g covers, currently delegates to Intersects so
+//   returns the same.
+//
+// - CoveredBy, which are the shapes that g is covered-by, needs to compute
+//   on the paths from each covering node to the root. For example, consider
+//   a quad-tree approach to dividing the space, where the nodes/cells
+//   covering g are c53, c61, c64. The corresponding ancestor path sets are
+//   {c53, c13, c3, c0}, {c61, c15, c3, c0}, {c64, c15, c3, c0}. Let I(c53)
+//   represent the index entries for c53. Then,
+//   I(c53) \union I(c13) \union I(c3) \union I(c0)
+//   represents all the shapes that cover cell c53. Similar union expressions
+//   can be constructed for all these paths. The computation needs to
+//   intersect these unions since all these cells need to be covered by a
+//   shape that covers g. One can extract the common sub-expressions to give
+//   I(c0) \union I(c3) \union
+//    ((I(c13) \union I(c53)) \intersection
+//     (I(c15) \union (I(c61) \intersection I(c64)))
+//   CoveredBy returns this factored expression in Reverse Polish notation.
+
+// GeographyIndex is an index over the unit sphere.
+type GeographyIndex interface {
+	// InvertedIndexKeys returns the keys to store this object under when adding
+	// it to the index. Additionally returns a bounding box, which is non-empty
+	// iff the key slice is non-empty.
+	InvertedIndexKeys(c context.Context, g geo.Geography) ([]Key, geopb.BoundingBox, error)
+
+	// Acceleration for topological relationships (see
+	// https://postgis.net/docs/reference.html#Spatial_Relationships). Distance
+	// relationships can be accelerated by adjusting g before calling these
+	// functions. Bounding box operators are not accelerated since we do not
+	// index the bounding box -- bounding box queries are an implementation
+	// detail of a particular indexing approach in PostGIS and are not part of
+	// the OGC or SQL/MM specs.
+
+	// Covers returns the index spans to read and union for the relationship
+	// ST_Covers(g, x), where x are the indexed geometries.
+	Covers(c context.Context, g geo.Geography) (UnionKeySpans, error)
+
+	// CoveredBy returns the index entries to read and the expression to compute
+	// for ST_CoveredBy(g, x), where x are the indexed geometries.
+	CoveredBy(c context.Context, g geo.Geography) (RPKeyExpr, error)
+
+	// Intersects returns the index spans to read and union for the relationship
+	// ST_Intersects(g, x), where x are the indexed geometries.
+	Intersects(c context.Context, g geo.Geography) (UnionKeySpans, error)
+
+	// DWithin returns the index spans to read and union for the relationship
+	// ST_DWithin(g, x, distanceMeters). That is, there exists a part of
+	// geometry g that is within distanceMeters of x, where x is an indexed
+	// geometry. This function assumes a sphere.
+	DWithin(
+		c context.Context, g geo.Geography, distanceMeters float64,
+		useSphereOrSpheroid geogfn.UseSphereOrSpheroid,
+	) (UnionKeySpans, error)
+
+	// TestingInnerCovering returns an inner covering of g.
+	TestingInnerCovering(g geo.Geography) s2.CellUnion
+	// CoveringGeography returns a Geography which represents the covering of g
+	// using the index configuration.
+	CoveringGeography(c context.Context, g geo.Geography) (geo.Geography, error)
+}
+
+// GeometryIndex is an index over 2D cartesian coordinates.
+type GeometryIndex interface {
+	// InvertedIndexKeys returns the keys to store this object under when adding
+	// it to the index. Additionally returns a bounding box, which is non-empty
+	// iff the key slice is non-empty.
+	InvertedIndexKeys(c context.Context, g geo.Geometry) ([]Key, geopb.BoundingBox, error)
+
+	// Acceleration for topological relationships (see
+	// https://postgis.net/docs/reference.html#Spatial_Relationships). Distance
+	// relationships can be accelerated by adjusting g before calling these
+	// functions. Bounding box operators are not accelerated since we do not
+	// index the bounding box -- bounding box queries are an implementation
+	// detail of a particular indexing approach in PostGIS and are not part of
+	// the OGC or SQL/MM specs.
+
+	// Covers returns the index spans to read and union for the relationship
+	// ST_Covers(g, x), where x are the indexed geometries.
+	Covers(c context.Context, g geo.Geometry) (UnionKeySpans, error)
+
+	// CoveredBy returns the index entries to read and the expression to compute
+	// for ST_CoveredBy(g, x), where x are the indexed geometries.
+	CoveredBy(c context.Context, g geo.Geometry) (RPKeyExpr, error)
+
+	// Intersects returns the index spans to read and union for the relationship
+	// ST_Intersects(g, x), where x are the indexed geometries.
+	Intersects(c context.Context, g geo.Geometry) (UnionKeySpans, error)
+
+	// DWithin returns the index spans to read and union for the relationship
+	// ST_DWithin(g, x, distance). That is, there exists a part of geometry g
+	// that is within distance units of x, where x is an indexed geometry.
+	DWithin(c context.Context, g geo.Geometry, distance float64) (UnionKeySpans, error)
+
+	// DFullyWithin returns the index spans to read and union for the
+	// relationship ST_DFullyWithin(g, x, distance). That is, the maximum distance
+	// across every pair of points comprising geometries g and x is within distance
+	// units, where x is an indexed geometry.
+	DFullyWithin(c context.Context, g geo.Geometry, distance float64) (UnionKeySpans, error)
+
+	// TestingInnerCovering returns an inner covering of g.
+	TestingInnerCovering(g geo.Geometry) s2.CellUnion
+	// CoveringGeometry returns a Geometry which represents the covering of g
+	// using the index configuration.
+	CoveringGeometry(c context.Context, g geo.Geometry) (geo.Geometry, error)
+}
+
+// RelationshipType stores a type of geospatial relationship query that can
+// be accelerated using an index.
+type RelationshipType uint8
+
+const (
+	// Covers corresponds to the relationship in which one geospatial object
+	// covers another geospatial object.
+	Covers RelationshipType = (1 << iota)
+
+	// CoveredBy corresponds to the relationship in which one geospatial object
+	// is covered by another geospatial object.
+	CoveredBy
+
+	// Intersects corresponds to the relationship in which one geospatial object
+	// intersects another geospatial object.
+	Intersects
+
+	// DWithin corresponds to a relationship where there exists a part of one
+	// geometry within d distance units of the other geometry.
+	DWithin
+
+	// DFullyWithin corresponds to a relationship where every pair of points in
+	// two geometries are within d distance units.
+	DFullyWithin
+)
+
+var geoRelationshipTypeStr = map[RelationshipType]string{
+	Covers:       "covers",
+	CoveredBy:    "covered by",
+	Intersects:   "intersects",
+	DWithin:      "dwithin",
+	DFullyWithin: "dfullywithin",
+}
+
+func (gr RelationshipType) String() string {
+	return geoRelationshipTypeStr[gr]
+}
+
+// Key is one entry under which a geospatial shape is stored on behalf of an
+// Index. The index is of the form (Key, Primary Key).
+type Key uint64
+
+// rpExprElement implements the RPExprElement interface.
+func (k Key) rpExprElement() {}
+
+func (k Key) String() string {
+	c := s2.CellID(k)
+	if !c.IsValid() {
+		return "spilled"
+	}
+	var b strings.Builder
+	b.WriteByte('F')
+	b.WriteByte("012345"[c.Face()])
+	fmt.Fprintf(&b, "/L%d/", c.Level())
+	for level := 1; level <= c.Level(); level++ {
+		b.WriteByte("0123"[c.ChildPosition(level)])
+	}
+	return b.String()
+}
+
+// S2CellID transforms the given key into the S2 CellID.
+func (k Key) S2CellID() s2.CellID {
+	return s2.CellID(k)
+}
+
+// KeySpan represents a range of Keys.
+type KeySpan struct {
+	// Both Start and End are inclusive, i.e., [Start, End].
+	Start, End Key
+}
+
+// UnionKeySpans is the set of indexed spans to retrieve and combine via set
+// union. The spans are guaranteed to be non-overlapping and sorted in
+// increasing order. Duplicate primary keys will not be retrieved by any
+// individual key, but they may be present if more than one key is retrieved
+// (including duplicates in a single span where End - Start > 1).
+type UnionKeySpans []KeySpan
+
+func (s UnionKeySpans) String() string {
+	return s.toString(math.MaxInt32)
+}
+
+func (s UnionKeySpans) toString(wrap int) string {
+	b := newStringBuilderWithWrap(&strings.Builder{}, wrap)
+	for i, span := range s {
+		if span.Start == span.End {
+			fmt.Fprintf(b, "%s", span.Start)
+		} else {
+			fmt.Fprintf(b, "[%s, %s]", span.Start, span.End)
+		}
+		if i != len(s)-1 {
+			b.WriteString(", ")
+		}
+		b.tryWrap()
+	}
+	return b.String()
+}
+
+// RPExprElement is an element in the Reverse Polish notation expression.
+// It is implemented by Key and RPSetOperator.
+type RPExprElement interface {
+	rpExprElement()
+}
+
+// RPSetOperator is a set operator in the Reverse Polish notation expression.
+type RPSetOperator int
+
+const (
+	// RPSetUnion is the union operator.
+	RPSetUnion RPSetOperator = iota + 1
+
+	// RPSetIntersection is the intersection operator.
+	RPSetIntersection
+)
+
+// rpExprElement implements the RPExprElement interface.
+func (o RPSetOperator) rpExprElement() {}
+
+// RPKeyExpr is an expression to evaluate over primary keys retrieved for
+// index keys. If we view each index key as a posting list of primary keys,
+// the expression involves union and intersection over the sets represented by
+// each posting list. For S2, this expression represents an intersection of
+// ancestors of different keys (cell ids) and is likely to contain many common
+// keys. This special structure allows us to efficiently and easily eliminate
+// common sub-expressions, hence the interface presents the factored
+// expression. The expression is represented in Reverse Polish notation.
+type RPKeyExpr []RPExprElement
+
+func (x RPKeyExpr) String() string {
+	var elements []string
+	for _, e := range x {
+		switch elem := e.(type) {
+		case Key:
+			elements = append(elements, elem.String())
+		case RPSetOperator:
+			switch elem {
+			case RPSetUnion:
+				elements = append(elements, `\U`)
+			case RPSetIntersection:
+				elements = append(elements, `\I`)
+			}
+		}
+	}
+	return strings.Join(elements, " ")
+}
+
+// Helper functions for index implementations that use the S2 geometry
+// library.
+
+// covererInterface provides a covering for a set of regions.
+type covererInterface interface {
+	// covering returns a normalized CellUnion, i.e., it is sorted, and does not
+	// contain redundancy.
+	covering(regions []s2.Region) s2.CellUnion
+}
+
+// simpleCovererImpl is an implementation of covererInterface that delegates
+// to s2.RegionCoverer.
+type simpleCovererImpl struct {
+	rc *s2.RegionCoverer
+}
+
+var _ covererInterface = simpleCovererImpl{}
+
+func (rc simpleCovererImpl) covering(regions []s2.Region) s2.CellUnion {
+	// TODO(sumeer): Add a max cells constraint for the whole covering,
+	// to respect the index configuration.
+	var u s2.CellUnion
+	for _, r := range regions {
+		u = append(u, rc.rc.Covering(r)...)
+	}
+	// Ensure the cells are non-overlapping.
+	u.Normalize()
+	return u
+}
+
+// The "inner covering", for shape s, represented by the regions parameter, is
+// used to find shapes that contain shape s. A regular covering that includes
+// a cell c not completely covered by shape s could result in false negatives,
+// since shape x that covers shape s could use a finer cell covering (using
+// cells below c). For example, consider a portion of the cell quad-tree
+// below:
+//
+//	     c0
+//	     |
+//	     c3
+//	     |
+//	 +---+---+
+//	 |       |
+//	c13      c15
+//	 |       |
+//	c53   +--+--+
+//	      |     |
+//	     c61    c64
+//
+// Shape s could have a regular covering c15, c53, where c15 has 4 child cells
+// c61..c64, and shape s only intersects wit c61, c64. A different shape x
+// that covers shape s may have a covering c61, c64, c53. That is, it has used
+// the finer cells c61, c64. If we used both regular coverings it is hard to
+// know that x covers g. Hence, we compute the "inner covering" of g (defined
+// below).
+//
+// The interior covering of shape s includes only cells covered by s. This is
+// computed by RegionCoverer.InteriorCovering() and is intuitively what we
+// need. But the interior covering is naturally empty for points and lines
+// (and can be empty for polygons too), and an empty covering is not useful
+// for constraining index lookups. We observe that leaf cells that intersect
+// shape s can be used in the covering, since the covering of shape x must
+// also cover these cells. This allows us to compute non-empty coverings for
+// all shapes. Since this is not technically the interior covering, we use the
+// term "inner covering".
+func innerCovering(rc *s2.RegionCoverer, regions []s2.Region) s2.CellUnion {
+	var u s2.CellUnion
+	for _, r := range regions {
+		switch region := r.(type) {
+		case s2.Point:
+			cellID := cellIDCoveringPoint(region, rc.MaxLevel)
+			u = append(u, cellID)
+		case *s2.Polyline:
+			// TODO(sumeer): for long lines could also pick some intermediate
+			// points along the line. Decide based on experiments.
+			for _, p := range *region {
+				cellID := cellIDCoveringPoint(p, rc.MaxLevel)
+				u = append(u, cellID)
+			}
+		case *s2.Polygon:
+			// Iterate over all exterior points
+			if region.NumLoops() > 0 {
+				loop := region.Loop(0)
+				for _, p := range loop.Vertices() {
+					cellID := cellIDCoveringPoint(p, rc.MaxLevel)
+					u = append(u, cellID)
+				}
+				// Arbitrary threshold value. This is to avoid computing an expensive
+				// region covering for regions with small area.
+				// TODO(sumeer): Improve this heuristic:
+				// - Area() may be expensive.
+				// - For large area regions, put an upper bound on the
+				//   level used for cells.
+				// Decide based on experiments.
+				const smallPolygonLevelThreshold = 25
+				if region.Area() > s2.AvgAreaMetric.Value(smallPolygonLevelThreshold) {
+					u = append(u, rc.InteriorCovering(region)...)
+				}
+			}
+		default:
+			panic("bug: code should not be producing unhandled Region type")
+		}
+	}
+	// Ensure the cells are non-overlapping.
+	u.Normalize()
+
+	// TODO(sumeer): if the number of cells is too many, make the list sparser.
+	// u[len(u)-1] - u[0] / len(u) is the mean distance between cells. Pick a
+	// target distance based on the goal to reduce to k cells: target_distance
+	// := mean_distance * k / len(u) Then iterate over u and for every sequence
+	// of cells that are within target_distance, replace by median cell or by
+	// largest cell. Decide based on experiments.
+
+	return u
+}
+
+func cellIDCoveringPoint(point s2.Point, level int) s2.CellID {
+	cellID := s2.CellFromPoint(point).ID()
+	if !cellID.IsLeaf() {
+		panic("bug in S2")
+	}
+	return cellID.Parent(level)
+}
+
+// ancestorCells returns the set of cells containing these cells, not
+// including the given cells.
+//
+// TODO(sumeer): use the MinLevel and LevelMod of the RegionCoverer used
+// for the index to constrain the ancestors set.
+func ancestorCells(cells []s2.CellID) []s2.CellID {
+	var ancestors []s2.CellID
+	var seen map[s2.CellID]struct{}
+	if len(cells) > 1 {
+		seen = make(map[s2.CellID]struct{})
+	}
+	for _, c := range cells {
+		for l := c.Level() - 1; l >= 0; l-- {
+			p := c.Parent(l)
+			if seen != nil {
+				if _, ok := seen[p]; ok {
+					break
+				}
+				seen[p] = struct{}{}
+			}
+			ancestors = append(ancestors, p)
+		}
+	}
+	return ancestors
+}
+
+// Helper for InvertedIndexKeys.
+func invertedIndexKeys(_ context.Context, rc covererInterface, r []s2.Region) []Key {
+	covering := rc.covering(r)
+	keys := make([]Key, len(covering))
+	for i, cid := range covering {
+		keys[i] = Key(cid)
+	}
+	return keys
+}
+
+// TODO(sumeer): examine RegionCoverer carefully to see if we can strengthen
+// the covering invariant, which would increase the efficiency of covers() and
+// remove the need for TestingInnerCovering().
+//
+// Helper for Covers.
+func covers(c context.Context, rc covererInterface, r []s2.Region) UnionKeySpans {
+	// We use intersects since geometries covered by r may have been indexed
+	// using cells that are ancestors of the covering of r. We could avoid
+	// reading ancestors if we had a stronger covering invariant, such as by
+	// indexing inner coverings.
+	return intersects(c, rc, r)
+}
+
+// Helper for Intersects. Returns spans in sorted order for convenience of
+// scans.
+func intersects(_ context.Context, rc covererInterface, r []s2.Region) UnionKeySpans {
+	covering := rc.covering(r)
+	return intersectsUsingCovering(covering)
+}
+
+func intersectsUsingCovering(covering s2.CellUnion) UnionKeySpans {
+	querySpans := make([]KeySpan, len(covering))
+	for i, cid := range covering {
+		querySpans[i] = KeySpan{Start: Key(cid.RangeMin()), End: Key(cid.RangeMax())}
+	}
+	for _, cid := range ancestorCells(covering) {
+		querySpans = append(querySpans, KeySpan{Start: Key(cid), End: Key(cid)})
+	}
+	sort.Slice(querySpans, func(i, j int) bool { return querySpans[i].Start < querySpans[j].Start })
+	return querySpans
+}
+
+// Helper for CoveredBy.
+func coveredBy(_ context.Context, rc *s2.RegionCoverer, r []s2.Region) RPKeyExpr {
+	covering := innerCovering(rc, r)
+	ancestors := ancestorCells(covering)
+
+	// The covering is normalized so no 2 cells are such that one is an ancestor
+	// of another. Arrange these cells and their ancestors in a quad-tree. Any cell
+	// with more than one child needs to be unioned with the intersection of the
+	// expressions corresponding to each child. See the detailed comment in
+	// generateRPExprForTree().
+
+	// It is sufficient to represent the tree(s) using presentCells since the ids
+	// of all possible 4 children of a cell can be computed and checked for
+	// presence in the map.
+	presentCells := make(map[s2.CellID]struct{}, len(covering)+len(ancestors))
+	for _, c := range covering {
+		presentCells[c] = struct{}{}
+	}
+	for _, c := range ancestors {
+		presentCells[c] = struct{}{}
+	}
+
+	// Construct the reverse polish expression. Note that there are up to 6
+	// trees corresponding to the 6 faces in S2. The expressions for the
+	// trees need to be intersected with each other.
+	expr := make([]RPExprElement, 0, len(presentCells)*2)
+	numFaces := 0
+	for face := 0; face < 6; face++ {
+		rootID := s2.CellIDFromFace(face)
+		if _, ok := presentCells[rootID]; !ok {
+			continue
+		}
+		expr = generateRPExprForTree(rootID, presentCells, expr)
+		numFaces++
+		if numFaces > 1 {
+			expr = append(expr, RPSetIntersection)
+		}
+	}
+	return expr
+}
+
+// The quad-trees stored in presentCells together represent a set expression.
+// This expression specifies:
+//   - the path for each leaf to the root of that quad-tree. The index entries
+//     on each such path represent the shapes that cover that leaf. Hence these
+//     index entries for a single path need to be unioned to give the shapes
+//     that cover the leaf.
+//   - The full expression specifies the shapes that cover all the leaves, so
+//     the union expressions for the paths must be intersected with each other.
+//
+// Reusing an example from earlier in this file, say the quad-tree is:
+//
+//	     c0
+//	     |
+//	     c3
+//	     |
+//	 +---+---+
+//	 |       |
+//	c13      c15
+//	 |       |
+//	c53   +--+--+
+//	      |     |
+//	     c61    c64
+//
+// This tree represents the following expression (where I(c) are the index
+// entries stored at cell c):
+//
+//	(I(c64) \union I(c15) \union I(c3) \union I(c0)) \intersection
+//	(I(c61) \union I(c15) \union I(c3) \union I(c0)) \intersection
+//	(I(c53) \union I(c13) \union I(c3) \union I(c0))
+//
+// In this example all the union sub-expressions have the same number of terms
+// but that does not need to be true.
+//
+// The above expression can be factored to eliminate repetition of the
+// same cell. The factored expression for this example is:
+//
+//	I(c0) \union I(c3) \union
+//	 ((I(c13) \union I(c53)) \intersection
+//	  (I(c15) \union (I(c61) \intersection I(c64)))
+//
+// This function generates this factored expression represented in reverse
+// polish notation.
+//
+// One can generate the factored expression in reverse polish notation using
+// a post-order traversal of this tree:
+// Step A. append the expression for the subtree rooted at c3
+// Step B. append c0 and the union operator
+// For Step A:
+// - append the expression for the subtree rooted at c13
+// - append the expression for the subtree rooted at c15
+// - append the intersection operator
+// - append c13
+// - append the union operator
+func generateRPExprForTree(
+	rootID s2.CellID, presentCells map[s2.CellID]struct{}, expr []RPExprElement,
+) []RPExprElement {
+	expr = append(expr, Key(rootID))
+	if rootID.IsLeaf() {
+		return expr
+	}
+	numChildren := 0
+	for _, childCellID := range rootID.Children() {
+		if _, ok := presentCells[childCellID]; !ok {
+			continue
+		}
+		expr = generateRPExprForTree(childCellID, presentCells, expr)
+		numChildren++
+		if numChildren > 1 {
+			expr = append(expr, RPSetIntersection)
+		}
+	}
+	if numChildren > 0 {
+		expr = append(expr, RPSetUnion)
+	}
+	return expr
+}
+
+// stringBuilderWithWrap is a strings.Builder that approximately wraps at a
+// certain number of characters. Newline characters should only be
+// written using tryWrap and doWrap.
+type stringBuilderWithWrap struct {
+	*strings.Builder
+	wrap     int
+	lastWrap int
+}
+
+func newStringBuilderWithWrap(b *strings.Builder, wrap int) *stringBuilderWithWrap {
+	return &stringBuilderWithWrap{
+		Builder:  b,
+		wrap:     wrap,
+		lastWrap: b.Len(),
+	}
+}
+
+func (b *stringBuilderWithWrap) tryWrap() {
+	if b.Len()-b.lastWrap > b.wrap {
+		b.doWrap()
+	}
+}
+
+func (b *stringBuilderWithWrap) doWrap() {
+	fmt.Fprintln(b)
+	b.lastWrap = b.Len()
+}
+
+// DefaultS2Config returns the default S2Config to initialize.
+func DefaultS2Config() *geopb.S2Config {
+	return &geopb.S2Config{
+		MinLevel: 0,
+		MaxLevel: 30,
+		LevelMod: 1,
+		MaxCells: 4,
+	}
+}
+
+func makeGeomTFromKeys(
+	keys []Key, srid geopb.SRID, xyFromS2Point func(s2.Point) (float64, float64),
+) (geom.T, error) {
+	t := geom.NewMultiPolygon(geom.XY).SetSRID(int(srid))
+	for _, key := range keys {
+		cell := s2.CellFromCellID(key.S2CellID())
+		flatCoords := make([]float64, 0, 10)
+		for i := 0; i < 4; i++ {
+			x, y := xyFromS2Point(cell.Vertex(i))
+			flatCoords = append(flatCoords, x, y)
+		}
+		// The last point is the same as the first point.
+		flatCoords = append(flatCoords, flatCoords[0:2]...)
+		err := t.Push(geom.NewPolygonFlat(geom.XY, flatCoords, []int{10}))
+		if err != nil {
+			return nil, err
+		}
+	}
+	return t, nil
+}
diff --git a/pkg/geo/geoindex/s2_geography_index.go b/pkg/geo/geoindex/s2_geography_index.go
new file mode 100644
index 0000000..67f0cce
--- /dev/null
+++ b/pkg/geo/geoindex/s2_geography_index.go
@@ -0,0 +1,226 @@
+// Copyright 2020 The Cockroach Authors.
+//
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
+
+package geoindex
+
+import (
+	"context"
+
+	"github.com/cockroachdb/cockroachdb-parser/pkg/geo"
+	"github.com/cockroachdb/cockroachdb-parser/pkg/geo/geogfn"
+	"github.com/cockroachdb/cockroachdb-parser/pkg/geo/geopb"
+	"github.com/cockroachdb/cockroachdb-parser/pkg/geo/geoprojbase"
+	"github.com/cockroachdb/errors"
+	"github.com/golang/geo/s1"
+	"github.com/golang/geo/s2"
+	"github.com/twpayne/go-geom"
+)
+
+// s2GeographyIndex is an implementation of GeographyIndex that uses the S2 geometry
+// library.
+type s2GeographyIndex struct {
+	rc *s2.RegionCoverer
+}
+
+var _ GeographyIndex = (*s2GeographyIndex)(nil)
+
+// NewS2GeographyIndex returns an index with the given configuration. The
+// configuration of an index cannot be changed without rewriting the index
+// since deletes could miss some index entries. Currently, reads could use a
+// different configuration, but that is subject to change if we manage to
+// strengthen the covering invariants (see the todo in covers() in index.go).
+func NewS2GeographyIndex(cfg geopb.S2GeographyConfig) GeographyIndex {
+	// TODO(sumeer): Sanity check cfg.
+	return &s2GeographyIndex{
+		rc: &s2.RegionCoverer{
+			MinLevel: int(cfg.S2Config.MinLevel),
+			MaxLevel: int(cfg.S2Config.MaxLevel),
+			LevelMod: int(cfg.S2Config.LevelMod),
+			MaxCells: int(cfg.S2Config.MaxCells),
+		},
+	}
+}
+
+// DefaultGeographyIndexConfig returns a default config for a geography index.
+func DefaultGeographyIndexConfig() *geopb.Config {
+	return &geopb.Config{
+		S2Geography: &geopb.S2GeographyConfig{S2Config: DefaultS2Config()},
+	}
+}
+
+// geogCovererWithBBoxFallback first computes the covering for the provided
+// regions (which were computed using g), and if the covering is too broad
+// (contains top-level cells from all faces), falls back to using the bounding
+// box of g to compute the covering.
+type geogCovererWithBBoxFallback struct {
+	rc *s2.RegionCoverer
+	g  geo.Geography
+}
+
+var _ covererInterface = geogCovererWithBBoxFallback{}
+
+func toDeg(radians float64) float64 {
+	return s1.Angle(radians).Degrees()
+}
+
+func (rc geogCovererWithBBoxFallback) covering(regions []s2.Region) s2.CellUnion {
+	cu := simpleCovererImpl{rc: rc.rc}.covering(regions)
+	if isBadGeogCovering(cu) {
+		bbox := rc.g.SpatialObject().BoundingBox
+		if bbox == nil {
+			return cu
+		}
+		flatCoords := []float64{
+			toDeg(bbox.LoX), toDeg(bbox.LoY), toDeg(bbox.HiX), toDeg(bbox.LoY),
+			toDeg(bbox.HiX), toDeg(bbox.HiY), toDeg(bbox.LoX), toDeg(bbox.HiY),
+			toDeg(bbox.LoX), toDeg(bbox.LoY)}
+		bboxT := geom.NewPolygonFlat(geom.XY, flatCoords, []int{len(flatCoords)})
+		bboxRegions, err := geo.S2RegionsFromGeomT(bboxT, geo.EmptyBehaviorOmit)
+		if err != nil {
+			return cu
+		}
+		bboxCU := simpleCovererImpl{rc: rc.rc}.covering(bboxRegions)
+		if !isBadGeogCovering(bboxCU) {
+			cu = bboxCU
+		}
+	}
+	return cu
+}
+
+func isBadGeogCovering(cu s2.CellUnion) bool {
+	const numFaces = 6
+	if len(cu) != numFaces {
+		return false
+	}
+	numFaceCells := 0
+	for _, c := range cu {
+		if c.Level() == 0 {
+			numFaceCells++
+		}
+	}
+	return numFaces == numFaceCells
+}
+
+// InvertedIndexKeys implements the GeographyIndex interface.
+func (i *s2GeographyIndex) InvertedIndexKeys(
+	c context.Context, g geo.Geography,
+) ([]Key, geopb.BoundingBox, error) {
+	r, err := g.AsS2(geo.EmptyBehaviorOmit)
+	if err != nil {
+		return nil, geopb.BoundingBox{}, err
+	}
+	rect := g.BoundingRect()
+	bbox := geopb.BoundingBox{
+		LoX: rect.Lng.Lo,
+		HiX: rect.Lng.Hi,
+		LoY: rect.Lat.Lo,
+		HiY: rect.Lat.Hi,
+	}
+	return invertedIndexKeys(c, geogCovererWithBBoxFallback{rc: i.rc, g: g}, r), bbox, nil
+}
+
+// Covers implements the GeographyIndex interface.
+func (i *s2GeographyIndex) Covers(c context.Context, g geo.Geography) (UnionKeySpans, error) {
+	r, err := g.AsS2(geo.EmptyBehaviorOmit)
+	if err != nil {
+		return nil, err
+	}
+	return covers(c, geogCovererWithBBoxFallback{rc: i.rc, g: g}, r), nil
+}
+
+// CoveredBy implements the GeographyIndex interface.
+func (i *s2GeographyIndex) CoveredBy(c context.Context, g geo.Geography) (RPKeyExpr, error) {
+	r, err := g.AsS2(geo.EmptyBehaviorOmit)
+	if err != nil {
+		return nil, err
+	}
+	return coveredBy(c, i.rc, r), nil
+}
+
+// Intersects implements the GeographyIndex interface.
+func (i *s2GeographyIndex) Intersects(c context.Context, g geo.Geography) (UnionKeySpans, error) {
+	r, err := g.AsS2(geo.EmptyBehaviorOmit)
+	if err != nil {
+		return nil, err
+	}
+	return intersects(c, geogCovererWithBBoxFallback{rc: i.rc, g: g}, r), nil
+}
+
+func (i *s2GeographyIndex) DWithin(
+	_ context.Context,
+	g geo.Geography,
+	distanceMeters float64,
+	useSphereOrSpheroid geogfn.UseSphereOrSpheroid,
+) (UnionKeySpans, error) {
+	projInfo, err := geoprojbase.Projection(g.SRID())
+	if err != nil {
+		return nil, err
+	}
+	if projInfo.Spheroid == nil {
+		return nil, errors.Errorf("projection %d does not have spheroid", g.SRID())
+	}
+	r, err := g.AsS2(geo.EmptyBehaviorOmit)
+	if err != nil {
+		return nil, err
+	}
+	// The following approach of constructing the covering and then expanding by
+	// an angle is worse than first expanding the original shape and then
+	// constructing a covering. However the s2 golang library lacks the c++
+	// S2ShapeIndexBufferedRegion, whose GetCellUnionBound() method is what we
+	// desire.
+	//
+	// Construct the cell covering for the shape.
+	gCovering := geogCovererWithBBoxFallback{rc: i.rc, g: g}.covering(r)
+	// Convert the distanceMeters to an angle, in order to expand the cell covering
+	// on the sphere by the angle.
+	multiplier := 1.0
+	if useSphereOrSpheroid == geogfn.UseSpheroid {
+		// We are using a sphere to calculate an angle on a spheroid, so adjust by the
+		// error.
+		multiplier += geogfn.SpheroidErrorFraction
+	}
+	angle := s1.Angle(multiplier * distanceMeters / projInfo.Spheroid.SphereRadius())
+	// maxLevelDiff puts a bound on the number of cells used after the expansion.
+	// For example, we do not want expanding a large country by 1km to generate too
+	// many cells.
+	const maxLevelDiff = 2
+	gCovering.ExpandByRadius(angle, maxLevelDiff)
+	// Finally, make the expanded covering obey the configuration of the index, which
+	// is used in the RegionCoverer.
+	var covering s2.CellUnion
+	for _, c := range gCovering {
+		if c.Level() > i.rc.MaxLevel {
+			c = c.Parent(i.rc.MaxLevel)
+		}
+		covering = append(covering, c)
+	}
+	covering.Normalize()
+	return intersectsUsingCovering(covering), nil
+}
+
+func (i *s2GeographyIndex) TestingInnerCovering(g geo.Geography) s2.CellUnion {
+	r, _ := g.AsS2(geo.EmptyBehaviorOmit)
+	if r == nil {
+		return nil
+	}
+	return innerCovering(i.rc, r)
+}
+
+func (i *s2GeographyIndex) CoveringGeography(
+	c context.Context, g geo.Geography,
+) (geo.Geography, error) {
+	keys, _, err := i.InvertedIndexKeys(c, g)
+	if err != nil {
+		return geo.Geography{}, err
+	}
+	t, err := makeGeomTFromKeys(keys, g.SRID(), func(p s2.Point) (float64, float64) {
+		latlng := s2.LatLngFromPoint(p)
+		return latlng.Lng.Degrees(), latlng.Lat.Degrees()
+	})
+	if err != nil {
+		return geo.Geography{}, err
+	}
+	return geo.MakeGeographyFromGeomT(t)
+}
diff --git a/pkg/geo/geoindex/s2_geometry_index.go b/pkg/geo/geoindex/s2_geometry_index.go
new file mode 100644
index 0000000..babdce1
--- /dev/null
+++ b/pkg/geo/geoindex/s2_geometry_index.go
@@ -0,0 +1,519 @@
+// Copyright 2020 The Cockroach Authors.
+//
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
+
+package geoindex
+
+import (
+	"context"
+	"math"
+
+	"github.com/cockroachdb/cockroachdb-parser/pkg/geo"
+	"github.com/cockroachdb/cockroachdb-parser/pkg/geo/geomfn"
+	"github.com/cockroachdb/cockroachdb-parser/pkg/geo/geopb"
+	"github.com/cockroachdb/cockroachdb-parser/pkg/geo/geoprojbase"
+	"github.com/cockroachdb/cockroachdb-parser/pkg/geo/geos"
+	"github.com/cockroachdb/cockroachdb-parser/pkg/sql/pgwire/pgcode"
+	"github.com/cockroachdb/cockroachdb-parser/pkg/sql/pgwire/pgerror"
+	"github.com/cockroachdb/errors"
+	"github.com/golang/geo/r3"
+	"github.com/golang/geo/s2"
+	"github.com/twpayne/go-geom"
+)
+
+// s2GeometryIndex is an implementation of GeometryIndex that uses the S2 geometry
+// library.
+type s2GeometryIndex struct {
+	rc                     *s2.RegionCoverer
+	minX, maxX, minY, maxY float64
+	deltaX, deltaY         float64
+}
+
+var _ GeometryIndex = (*s2GeometryIndex)(nil)
+
+// We adjust the clipping bounds to be smaller by this fraction, since using
+// the endpoints of face 0 in S2 causes coverings to spill out of that face.
+const clippingBoundsDelta = 0.01
+
+// NewS2GeometryIndex returns an index with the given configuration. All reads and
+// writes on this index must use the same config. Writes must use the same
+// config to correctly process deletions. Reads must use the same config since
+// the bounds affect when a read needs to look at the exceedsBoundsCellID.
+func NewS2GeometryIndex(cfg geopb.S2GeometryConfig) GeometryIndex {
+	// TODO(sumeer): Sanity check cfg.
+	return &s2GeometryIndex{
+		rc: &s2.RegionCoverer{
+			MinLevel: int(cfg.S2Config.MinLevel),
+			MaxLevel: int(cfg.S2Config.MaxLevel),
+			LevelMod: int(cfg.S2Config.LevelMod),
+			MaxCells: int(cfg.S2Config.MaxCells),
+		},
+		minX:   cfg.MinX,
+		maxX:   cfg.MaxX,
+		minY:   cfg.MinY,
+		maxY:   cfg.MaxY,
+		deltaX: clippingBoundsDelta * (cfg.MaxX - cfg.MinX),
+		deltaY: clippingBoundsDelta * (cfg.MaxY - cfg.MinY),
+	}
+}
+
+// TODO(sumeer): also support index config with parameters specified by CREATE
+// INDEX.
+
+// DefaultGeometryIndexConfig returns a default config for a geometry index.
+func DefaultGeometryIndexConfig() *geopb.Config {
+	return &geopb.Config{
+		S2Geometry: &geopb.S2GeometryConfig{
+			// Bounding box similar to the circumference of the earth (~2B meters)
+			MinX:     -(1 << 31),
+			MaxX:     (1 << 31) - 1,
+			MinY:     -(1 << 31),
+			MaxY:     (1 << 31) - 1,
+			S2Config: DefaultS2Config(),
+		},
+	}
+}
+
+// GeometryIndexConfigForSRID returns a geometry index config for srid.
+func GeometryIndexConfigForSRID(srid geopb.SRID) (*geopb.Config, error) {
+	if srid == 0 {
+		return DefaultGeometryIndexConfig(), nil
+	}
+	p, err := geoprojbase.Projection(srid)
+	if err != nil {
+		return nil, err
+	}
+	b := p.Bounds
+	minX, maxX, minY, maxY := b.MinX, b.MaxX, b.MinY, b.MaxY
+	// There are projections where the min and max are equal e.g. 3571.
+	// We need to have a valid rectangle as the geometry index bounds.
+	if maxX-minX < 1 {
+		maxX++
+	}
+	if maxY-minY < 1 {
+		maxY++
+	}
+	// We are covering shapes using cells that are square. If we have shapes
+	// that start off as well-behaved wrt square cells, we do not wish to
+	// distort them significantly. Hence, we equalize MaxX-MinX and MaxY-MinY
+	// in the index bounds.
+	diffX := maxX - minX
+	diffY := maxY - minY
+	if diffX > diffY {
+		adjustment := (diffX - diffY) / 2
+		minY -= adjustment
+		maxY += adjustment
+	} else {
+		adjustment := (diffY - diffX) / 2
+		minX -= adjustment
+		maxX += adjustment
+	}
+	// Expand the bounds by 2x the clippingBoundsDelta, to
+	// ensure that shapes touching the bounds don't get
+	// clipped.
+	boundsExpansion := 2 * clippingBoundsDelta
+	deltaX := (maxX - minX) * boundsExpansion
+	deltaY := (maxY - minY) * boundsExpansion
+	return &geopb.Config{
+		S2Geometry: &geopb.S2GeometryConfig{
+			MinX:     minX - deltaX,
+			MaxX:     maxX + deltaX,
+			MinY:     minY - deltaY,
+			MaxY:     maxY + deltaY,
+			S2Config: DefaultS2Config()},
+	}, nil
+}
+
+// A cell id unused by S2. We use it to index geometries that exceed the
+// configured bounds.
+const exceedsBoundsCellID = s2.CellID(^uint64(0))
+
+// TODO(sumeer): adjust code to handle precision issues with floating point
+// arithmetic.
+
+// geomCovererWithBBoxFallback first computes the covering for the provided
+// regions (which were computed using geom), and if the covering is too
+// broad (contains faces other than 0), falls back to using the bounding
+// box of geom to compute the covering.
+type geomCovererWithBBoxFallback struct {
+	s    *s2GeometryIndex
+	geom geom.T
+}
+
+var _ covererInterface = geomCovererWithBBoxFallback{}
+
+func (rc geomCovererWithBBoxFallback) covering(regions []s2.Region) s2.CellUnion {
+	cu := simpleCovererImpl{rc: rc.s.rc}.covering(regions)
+	if isBadGeomCovering(cu) {
+		bbox := geo.BoundingBoxFromGeomTGeometryType(rc.geom)
+		flatCoords := []float64{
+			bbox.LoX, bbox.LoY, bbox.HiX, bbox.LoY, bbox.HiX, bbox.HiY, bbox.LoX, bbox.HiY,
+			bbox.LoX, bbox.LoY}
+		bboxT := geom.NewPolygonFlat(geom.XY, flatCoords, []int{len(flatCoords)})
+		bboxRegions := rc.s.s2RegionsFromPlanarGeomT(bboxT)
+		bboxCU := simpleCovererImpl{rc: rc.s.rc}.covering(bboxRegions)
+		if !isBadGeomCovering(bboxCU) {
+			cu = bboxCU
+		}
+	}
+	return cu
+}
+
+func isBadGeomCovering(cu s2.CellUnion) bool {
+	for _, c := range cu {
+		if c.Face() != 0 {
+			// Good coverings should not see a face other than 0.
+			return true
+		}
+	}
+	return false
+}
+
+// InvertedIndexKeys implements the GeometryIndex interface.
+func (s *s2GeometryIndex) InvertedIndexKeys(
+	c context.Context, g geo.Geometry,
+) ([]Key, geopb.BoundingBox, error) {
+	// If the geometry exceeds the bounds, we index the clipped geometry in
+	// addition to the special cell, so that queries for geometries that don't
+	// exceed the bounds don't need to query the special cell (which would
+	// become a hotspot in the key space).
+	gt, clipped, err := s.convertToGeomTAndTryClip(g)
+	if err != nil {
+		return nil, geopb.BoundingBox{}, err
+	}
+	var keys []Key
+	if gt != nil {
+		r := s.s2RegionsFromPlanarGeomT(gt)
+		keys = invertedIndexKeys(c, geomCovererWithBBoxFallback{s: s, geom: gt}, r)
+	}
+	if clipped {
+		keys = append(keys, Key(exceedsBoundsCellID))
+	}
+	bbox := geopb.BoundingBox{}
+	bboxRef := g.BoundingBoxRef()
+	if bboxRef == nil && len(keys) > 0 {
+		return keys, bbox, errors.AssertionFailedf("non-empty geometry should have bounding box")
+	}
+	if bboxRef != nil {
+		bbox = *bboxRef
+	}
+	return keys, bbox, nil
+}
+
+// Covers implements the GeometryIndex interface.
+func (s *s2GeometryIndex) Covers(c context.Context, g geo.Geometry) (UnionKeySpans, error) {
+	return s.Intersects(c, g)
+}
+
+// CoveredBy implements the GeometryIndex interface.
+func (s *s2GeometryIndex) CoveredBy(c context.Context, g geo.Geometry) (RPKeyExpr, error) {
+	// If the geometry exceeds the bounds, we use the clipped geometry to
+	// restrict the search within the bounds.
+	gt, clipped, err := s.convertToGeomTAndTryClip(g)
+	if err != nil {
+		return nil, err
+	}
+	var expr RPKeyExpr
+	if gt != nil {
+		r := s.s2RegionsFromPlanarGeomT(gt)
+		expr = coveredBy(c, s.rc, r)
+	}
+	if clipped {
+		// Intersect with the shapes that exceed the bounds.
+		expr = append(expr, Key(exceedsBoundsCellID))
+		if len(expr) > 1 {
+			expr = append(expr, RPSetIntersection)
+		}
+	}
+	return expr, nil
+}
+
+// Intersects implements the GeometryIndex interface.
+func (s *s2GeometryIndex) Intersects(c context.Context, g geo.Geometry) (UnionKeySpans, error) {
+	// If the geometry exceeds the bounds, we use the clipped geometry to
+	// restrict the search within the bounds.
+	gt, clipped, err := s.convertToGeomTAndTryClip(g)
+	if err != nil {
+		return nil, err
+	}
+	var spans UnionKeySpans
+	if gt != nil {
+		r := s.s2RegionsFromPlanarGeomT(gt)
+		spans = intersects(c, geomCovererWithBBoxFallback{s: s, geom: gt}, r)
+	}
+	if clipped {
+		// And lookup all shapes that exceed the bounds. The exceedsBoundsCellID is the largest
+		// possible key, so appending it maintains the sorted order of spans.
+		spans = append(spans, KeySpan{Start: Key(exceedsBoundsCellID), End: Key(exceedsBoundsCellID)})
+	}
+	return spans, nil
+}
+
+func (s *s2GeometryIndex) DWithin(
+	c context.Context, g geo.Geometry, distance float64,
+) (UnionKeySpans, error) {
+	// TODO(sumeer): are the default params the correct thing to use here?
+	g, err := geomfn.Buffer(g, geomfn.MakeDefaultBufferParams(), distance)
+	if err != nil {
+		return nil, err
+	}
+	return s.Intersects(c, g)
+}
+
+func (s *s2GeometryIndex) DFullyWithin(
+	c context.Context, g geo.Geometry, distance float64,
+) (UnionKeySpans, error) {
+	// TODO(sumeer): are the default params the correct thing to use here?
+	g, err := geomfn.Buffer(g, geomfn.MakeDefaultBufferParams(), distance)
+	if err != nil {
+		return nil, err
+	}
+	return s.Covers(c, g)
+}
+
+// Converts to geom.T and clips to the rectangle bounds of the index.
+func (s *s2GeometryIndex) convertToGeomTAndTryClip(g geo.Geometry) (geom.T, bool, error) {
+	// Anything with a NaN coordinate should be marked as clipped.
+	if bbox := g.BoundingBoxRef(); bbox != nil && (math.IsNaN(bbox.LoX) || math.IsNaN(bbox.HiX) ||
+		math.IsNaN(bbox.LoY) || math.IsNaN(bbox.HiY)) {
+		return nil, false, pgerror.Newf(
+			pgcode.InvalidParameterValue,
+			"cannot index a geometry with NaN coordinates",
+		)
+	}
+	gt, err := g.AsGeomT()
+	if err != nil {
+		return nil, false, err
+	}
+	if gt.Empty() {
+		return gt, false, nil
+	}
+	clipped := false
+	if s.geomExceedsBounds(gt) {
+		// TODO(#63126): Replace workaround for bug in geos.ClipByRect.
+		g, err = geomfn.ForceLayout(g, geom.XY)
+		if err != nil {
+			return nil, false, err
+		}
+		clipped = true
+		clippedEWKB, err :=
+			geos.ClipByRect(g.EWKB(), s.minX+s.deltaX, s.minY+s.deltaY, s.maxX-s.deltaX, s.maxY-s.deltaY)
+		if err != nil {
+			return nil, false, err
+		}
+		gt = nil
+		if clippedEWKB != nil {
+			g, err = geo.ParseGeometryFromEWKBUnsafe(clippedEWKB)
+			if err != nil {
+				return nil, false, err
+			}
+			gt, err = g.AsGeomT()
+			if err != nil {
+				return nil, false, err
+			}
+		}
+	}
+	return gt, clipped, nil
+}
+
+// Returns true if the point represented by (x, y) exceeds the rectangle
+// bounds of the index.
+func (s *s2GeometryIndex) xyExceedsBounds(x float64, y float64) bool {
+	if x < (s.minX+s.deltaX) || x > (s.maxX-s.deltaX) {
+		return true
+	}
+	if y < (s.minY+s.deltaY) || y > (s.maxY-s.deltaY) {
+		return true
+	}
+	return false
+}
+
+// Returns true if g exceeds the rectangle bounds of the index.
+func (s *s2GeometryIndex) geomExceedsBounds(g geom.T) bool {
+	switch repr := g.(type) {
+	case *geom.Point:
+		return s.xyExceedsBounds(repr.X(), repr.Y())
+	case *geom.LineString:
+		for i := 0; i < repr.NumCoords(); i++ {
+			p := repr.Coord(i)
+			if s.xyExceedsBounds(p.X(), p.Y()) {
+				return true
+			}
+		}
+	case *geom.Polygon:
+		if repr.NumLinearRings() > 0 {
+			lr := repr.LinearRing(0)
+			for i := 0; i < lr.NumCoords(); i++ {
+				if s.xyExceedsBounds(lr.Coord(i).X(), lr.Coord(i).Y()) {
+					return true
+				}
+			}
+		}
+	case *geom.GeometryCollection:
+		for _, geom := range repr.Geoms() {
+			if s.geomExceedsBounds(geom) {
+				return true
+			}
+		}
+	case *geom.MultiPoint:
+		for i := 0; i < repr.NumPoints(); i++ {
+			if s.geomExceedsBounds(repr.Point(i)) {
+				return true
+			}
+		}
+	case *geom.MultiLineString:
+		for i := 0; i < repr.NumLineStrings(); i++ {
+			if s.geomExceedsBounds(repr.LineString(i)) {
+				return true
+			}
+		}
+	case *geom.MultiPolygon:
+		for i := 0; i < repr.NumPolygons(); i++ {
+			if s.geomExceedsBounds(repr.Polygon(i)) {
+				return true
+			}
+		}
+	}
+	return false
+}
+
+// stToUV, uvToST, xyzToFace0UV and face0UVToXYZPoint are adapted
+// from unexported methods in github.com/golang/geo/s2/stuv.go
+
+// stToUV converts an s or t value to the corresponding u or v value.
+// This is a non-linear transformation from [-1,1] to [-1,1] that
+// attempts to make the cell sizes more uniform.
+// This uses what the C++ version calls 'the quadratic transform'.
+func stToUV(s float64) float64 {
+	if s >= 0.5 {
+		return (1 / 3.) * (4*s*s - 1)
+	}
+	return (1 / 3.) * (1 - 4*(1-s)*(1-s))
+}
+
+// uvToST is the inverse of the stToUV transformation. Note that it
+// is not always true that uvToST(stToUV(x)) == x due to numerical
+// errors.
+func uvToST(u float64) float64 {
+	if u >= 0 {
+		return 0.5 * math.Sqrt(1+3*u)
+	}
+	return 1 - 0.5*math.Sqrt(1-3*u)
+}
+
+// Specialized version of faceUVToXYZ() for face 0
+func face0UVToXYZPoint(u, v float64) s2.Point {
+	return s2.Point{Vector: r3.Vector{X: 1, Y: u, Z: v}}
+}
+
+// xyzToFace0UV converts a direction vector (not necessarily unit length) to
+// (u, v) coordinates on face 0.
+func xyzToFace0UV(r s2.Point) (u, v float64) {
+	return r.Y / r.X, r.Z / r.X
+}
+
+// planarPointToS2Point converts a planar point to an s2.Point.
+func (s *s2GeometryIndex) planarPointToS2Point(x float64, y float64) s2.Point {
+	ss := (x - s.minX) / (s.maxX - s.minX)
+	tt := (y - s.minY) / (s.maxY - s.minY)
+	u := stToUV(ss)
+	v := stToUV(tt)
+	return face0UVToXYZPoint(u, v)
+}
+
+// s2PointToPlanarPoints converts an s2.Point to a planar point.
+func (s *s2GeometryIndex) s2PointToPlanarPoint(p s2.Point) (x, y float64) {
+	u, v := xyzToFace0UV(p)
+	ss := uvToST(u)
+	tt := uvToST(v)
+	return ss*(s.maxX-s.minX) + s.minX, tt*(s.maxY-s.minY) + s.minY
+}
+
+// TODO(sumeer): this is similar to S2RegionsFromGeomT() but needs to do
+// a different point conversion. If these functions do not diverge further,
+// and turn out not to be performance critical, merge the two implementations.
+func (s *s2GeometryIndex) s2RegionsFromPlanarGeomT(geomRepr geom.T) []s2.Region {
+	if geomRepr.Empty() {
+		return nil
+	}
+	var regions []s2.Region
+	switch repr := geomRepr.(type) {
+	case *geom.Point:
+		regions = []s2.Region{
+			s.planarPointToS2Point(repr.X(), repr.Y()),
+		}
+	case *geom.LineString:
+		points := make([]s2.Point, repr.NumCoords())
+		for i := 0; i < repr.NumCoords(); i++ {
+			p := repr.Coord(i)
+			points[i] = s.planarPointToS2Point(p.X(), p.Y())
+		}
+		pl := s2.Polyline(points)
+		regions = []s2.Region{&pl}
+	case *geom.Polygon:
+		loops := make([]*s2.Loop, repr.NumLinearRings())
+		// The first ring is a "shell". Following rings are "holes".
+		// All loops must be oriented CCW for S2.
+		for ringIdx := 0; ringIdx < repr.NumLinearRings(); ringIdx++ {
+			linearRing := repr.LinearRing(ringIdx)
+			points := make([]s2.Point, linearRing.NumCoords())
+			isCCW := geo.IsLinearRingCCW(linearRing)
+			for pointIdx := 0; pointIdx < linearRing.NumCoords(); pointIdx++ {
+				p := linearRing.Coord(pointIdx)
+				pt := s.planarPointToS2Point(p.X(), p.Y())
+				if isCCW {
+					points[pointIdx] = pt
+				} else {
+					points[len(points)-pointIdx-1] = pt
+				}
+			}
+			loops[ringIdx] = s2.LoopFromPoints(points)
+		}
+		regions = []s2.Region{
+			s2.PolygonFromLoops(loops),
+		}
+	case *geom.GeometryCollection:
+		for _, geom := range repr.Geoms() {
+			regions = append(regions, s.s2RegionsFromPlanarGeomT(geom)...)
+		}
+	case *geom.MultiPoint:
+		for i := 0; i < repr.NumPoints(); i++ {
+			regions = append(regions, s.s2RegionsFromPlanarGeomT(repr.Point(i))...)
+		}
+	case *geom.MultiLineString:
+		for i := 0; i < repr.NumLineStrings(); i++ {
+			regions = append(regions, s.s2RegionsFromPlanarGeomT(repr.LineString(i))...)
+		}
+	case *geom.MultiPolygon:
+		for i := 0; i < repr.NumPolygons(); i++ {
+			regions = append(regions, s.s2RegionsFromPlanarGeomT(repr.Polygon(i))...)
+		}
+	}
+	return regions
+}
+
+func (s *s2GeometryIndex) TestingInnerCovering(g geo.Geometry) s2.CellUnion {
+	gt, _, err := s.convertToGeomTAndTryClip(g)
+	if err != nil || gt == nil {
+		return nil
+	}
+	r := s.s2RegionsFromPlanarGeomT(gt)
+	return innerCovering(s.rc, r)
+}
+
+func (s *s2GeometryIndex) CoveringGeometry(
+	c context.Context, g geo.Geometry,
+) (geo.Geometry, error) {
+	keys, _, err := s.InvertedIndexKeys(c, g)
+	if err != nil {
+		return geo.Geometry{}, err
+	}
+	t, err := makeGeomTFromKeys(keys, g.SRID(), func(p s2.Point) (float64, float64) {
+		return s.s2PointToPlanarPoint(p)
+	})
+	if err != nil {
+		return geo.Geometry{}, err
+	}
+	return geo.MakeGeometryFromGeomT(t)
+}
diff --git a/pkg/geo/geoindex/testdata/clip b/pkg/geo/geoindex/testdata/clip
new file mode 100644
index 0000000..11743d1
--- /dev/null
+++ b/pkg/geo/geoindex/testdata/clip
@@ -0,0 +1,28 @@
+geometry
+SRID=4004;MULTIPOINT((1.0 5.0), (3.0 4.0))
+----
+
+clip xmin=10 ymin=10 xmax=20 ymax=20
+----
+55 => 13 (srid: 4004)
+
+clip xmin=0 ymin=0 xmax=10 ymax=10
+----
+55 => 55 (srid: 4004)
+
+geometry
+MULTIPOINT((1.0 5.0), (3.0 4.0))
+----
+
+clip xmin=10 ymin=10 xmax=20 ymax=20
+----
+51 => 9 (srid: 0)
+
+clip xmin=0 ymin=0 xmax=10 ymax=10
+----
+51 => 51 (srid: 0)
+
+
+clip xmin=10 ymin=0 xmax=0 ymax=10
+----
+geos error: IllegalArgumentException: Clipping rectangle must be non-empty
diff --git a/pkg/geo/geoindex/testdata/s2_geography b/pkg/geo/geoindex/testdata/s2_geography
new file mode 100644
index 0000000..cde1f85
--- /dev/null
+++ b/pkg/geo/geoindex/testdata/s2_geography
@@ -0,0 +1,440 @@
+geometry name=point1
+MULTIPOINT((1.0 5.0), (3.0 4.0))
+----
+
+geometry name=shortline1
+LINESTRING (-86.609955 32.703682,-86.609836 32.703659)
+----
+
+geometry name=nystate
+POLYGON((-79.7624 42.5142,-79.0672 42.7783,-78.9313 42.8508,-78.9024 42.9061,-78.9313 42.9554,-78.9656 42.9584,-79.0219 42.9886,-79.0027 43.0568,-79.0727 43.0769,-79.0713 43.1220,-79.0302 43.1441,-79.0576 43.1801,-79.0604 43.2482,-79.0837 43.2812,-79.2004 43.4509,-78.6909 43.6311,-76.7958 43.6321,-76.4978 43.9987,-76.4388 44.0965,-76.3536 44.1349,-76.3124 44.1989,-76.2437 44.2049,-76.1655 44.2413,-76.1353 44.2973,-76.0474 44.3327,-75.9856 44.3553,-75.9196 44.3749,-75.8730 44.3994,-75.8221 44.4308,-75.8098 44.4740,-75.7288 44.5425,-75.5585 44.6647,-75.4088 44.7672,-75.3442 44.8101,-75.3058 44.8383,-75.2399 44.8676,-75.1204 44.9211,-74.9995 44.9609,-74.9899 44.9803,-74.9103 44.9852,-74.8856 45.0017,-74.8306 45.0153,-74.7633 45.0046,-74.7070 45.0027,-74.5642 45.0007,-74.1467 44.9920,-73.7306 45.0037,-73.4203 45.0085,-73.3430 45.0109,-73.3547 44.9874,-73.3379 44.9648,-73.3396 44.9160,-73.3739 44.8354,-73.3324 44.8013,-73.3667 44.7419,-73.3873 44.6139,-73.3736 44.5787,-73.3049 44.4916,-73.2953 44.4289,-73.3365 44.3513,-73.3118 44.2757,-73.3818 44.1980,-73.4079 44.1142,-73.4367 44.0511,-73.4065 44.0165,-73.4079 43.9375,-73.3749 43.8771,-73.3914 43.8167,-73.3557 43.7790,-73.4244 43.6460,-73.4340 43.5893,-73.3969 43.5655,-73.3818 43.6112,-73.3049 43.6271,-73.3063 43.5764,-73.2582 43.5675,-73.2445 43.5227,-73.2582 43.2582,-73.2733 42.9715,-73.2898 42.8004,-73.2664 42.7460,-73.3708 42.4630,-73.5095 42.0840,-73.4903 42.0218,-73.4999 41.8808,-73.5535 41.2953,-73.4834 41.2128,-73.7275 41.1011,-73.6644 41.0237,-73.6578 40.9851,-73.6132 40.9509,-72.4823 41.1869,-72.0950 41.2551,-71.9714 41.3005,-71.9193 41.3108,-71.7915 41.1838,-71.7929 41.1249,-71.7517 41.0462,-72.9465 40.6306,-73.4628 40.5368,-73.8885 40.4887,-73.9490 40.5232,-74.2271 40.4772,-74.2532 40.4861,-74.1866 40.6468,-74.0547 40.6556,-74.0156 40.7618,-73.9421 40.8699,-73.8934 40.9980,-73.9854 41.0343,-74.6274 41.3268,-74.7084 41.3583,-74.7101 41.3811,-74.8265 41.4386,-74.9913 41.5075,-75.0668 41.6000,-75.0366 41.6719,-75.0545 41.7672,-75.1945 41.8808,-75.3552 42.0013,-75.4266 42.0003,-77.0306 42.0013,-79.7250 41.9993,-79.7621 42.0003,-79.7621 42.1827,-79.7621 42.5146,-79.7624 42.5142))
+----
+
+geometry name=nys-approx1
+POLYGON((-79 42,-77 44,-78 41,-79 42))
+----
+
+geometry name=nys-approx2
+POLYGON((-79 42,-78 41,-77 44,-79 42))
+----
+
+geometry name=red-hook-nyc
+MULTIPOLYGON(((-74.0126927094665 40.6600480732464,-74.0127064547618 40.6600447465578,-74.0141319802258 40.6609147092529,-74.0145335611922 40.6611344232761,-74.0145358849763 40.6611361779097,-74.0145399285567 40.6611402822267,-74.014541648353 40.6611426319101,-74.0145797021934 40.6612147162775,-74.0145806405216 40.6612173067132,-74.0145817746666 40.661222645325,-74.0145819704835 40.6612253935011,-74.0145789529984 40.6612703205022,-74.0145775882448 40.6612747317321,-74.0145730223663 40.6612824707693,-74.0145698212414 40.6612857985766,-74.0144997485308 40.6613308932157,-74.0144993922351 40.6613311121095,-74.0144986708037 40.6613315348099,-74.014498305668 40.6613317386166,-74.0136647221644 40.6617744175344,-74.0134542384902 40.6618992353571,-74.0134540575192 40.6618993401319,-74.0134536934255 40.6618995458745,-74.013453510303 40.6618996468423,-74.0128195031462 40.6622406226638,-74.012816235274 40.6622417071219,-74.0128095254169 40.6622427033898,-74.0128060834319 40.6622426151996,-74.0127019801943 40.6622216604417,-74.012700315079 40.6622211716785,-74.0126970944194 40.6622199136429,-74.012695538875 40.6622191443704,-74.011062576148 40.6612266089193,-74.0110624213581 40.6612218066015,-74.0127057329214 40.6600718294846,-74.0127094072378 40.6600602461869,-74.0127040330277 40.6600453326751,-74.0126927094665 40.6600480732464)))
+----
+
+init minlevel=0 maxlevel=30 maxcells=2
+----
+
+# NB: Bounding boxes use radian units for longitude and latitude.
+index-keys name=nys-approx1
+----
+F4/L5/10321, F4/L5/10322
+BoundingBox: lo_x:-1.378810 hi_x:-1.343904 lo_y:0.715585 hi_y:0.767945
+
+index-keys name=nys-approx2
+----
+F4/L5/10321, F4/L5/10322
+BoundingBox: lo_x:-1.378810 hi_x:-1.343904 lo_y:0.715585 hi_y:0.767945
+
+index-keys name=point1
+----
+F0/L30/200023210133112000102232313101, F0/L30/200033223021330130001101002333
+BoundingBox: lo_x:0.017453 hi_x:0.052360 lo_y:0.069813 hi_y:0.087266
+
+covers name=point1
+----
+F0/L0/, F0/L4/2000, F0/L5/20002, F0/L6/200023, F0/L10/2000232101, 
+F0/L11/20002321013, F0/L14/20002321013311, F0/L20/20002321013311200010, 
+F0/L21/200023210133112000102, F0/L22/2000232101331120001022, 
+F0/L23/20002321013311200010223, F0/L24/200023210133112000102232, 
+F0/L26/20002321013311200010223231, F0/L30/200023210133112000102232313101, 
+F0/L29/20002321013311200010223231310, F0/L28/2000232101331120001022323131, 
+F0/L27/200023210133112000102232313, F0/L25/2000232101331120001022323, 
+F0/L19/2000232101331120001, F0/L18/200023210133112000, F0/L17/20002321013311200, 
+F0/L16/2000232101331120, F0/L15/200023210133112, F0/L13/2000232101331, 
+F0/L12/200023210133, F0/L9/200023210, F0/L8/20002321, F0/L7/2000232, 
+F0/L5/20003, F0/L6/200033, F0/L7/2000332, F0/L8/20003322, F0/L10/2000332230, 
+F0/L12/200033223021, F0/L13/2000332230213, F0/L16/2000332230213301, 
+F0/L26/20003322302133013000110100, F0/L27/200033223021330130001101002, 
+F0/L28/2000332230213301300011010023, F0/L29/20003322302133013000110100233, 
+F0/L30/200033223021330130001101002333, F0/L25/2000332230213301300011010, 
+F0/L24/200033223021330130001101, F0/L23/20003322302133013000110, 
+F0/L22/2000332230213301300011, F0/L21/200033223021330130001, 
+F0/L20/20003322302133013000, F0/L19/2000332230213301300, F0/L18/200033223021330130, 
+F0/L17/20003322302133013, F0/L15/200033223021330, F0/L14/20003322302133, 
+F0/L11/20003322302, F0/L9/200033223, F0/L3/200, F0/L2/20, F0/L1/2
+
+intersects name=point1
+----
+F0/L0/, F0/L4/2000, F0/L5/20002, F0/L6/200023, F0/L10/2000232101, 
+F0/L11/20002321013, F0/L14/20002321013311, F0/L20/20002321013311200010, 
+F0/L21/200023210133112000102, F0/L22/2000232101331120001022, 
+F0/L23/20002321013311200010223, F0/L24/200023210133112000102232, 
+F0/L26/20002321013311200010223231, F0/L30/200023210133112000102232313101, 
+F0/L29/20002321013311200010223231310, F0/L28/2000232101331120001022323131, 
+F0/L27/200023210133112000102232313, F0/L25/2000232101331120001022323, 
+F0/L19/2000232101331120001, F0/L18/200023210133112000, F0/L17/20002321013311200, 
+F0/L16/2000232101331120, F0/L15/200023210133112, F0/L13/2000232101331, 
+F0/L12/200023210133, F0/L9/200023210, F0/L8/20002321, F0/L7/2000232, 
+F0/L5/20003, F0/L6/200033, F0/L7/2000332, F0/L8/20003322, F0/L10/2000332230, 
+F0/L12/200033223021, F0/L13/2000332230213, F0/L16/2000332230213301, 
+F0/L26/20003322302133013000110100, F0/L27/200033223021330130001101002, 
+F0/L28/2000332230213301300011010023, F0/L29/20003322302133013000110100233, 
+F0/L30/200033223021330130001101002333, F0/L25/2000332230213301300011010, 
+F0/L24/200033223021330130001101, F0/L23/20003322302133013000110, 
+F0/L22/2000332230213301300011, F0/L21/200033223021330130001, 
+F0/L20/20003322302133013000, F0/L19/2000332230213301300, F0/L18/200033223021330130, 
+F0/L17/20003322302133013, F0/L15/200033223021330, F0/L14/20003322302133, 
+F0/L11/20003322302, F0/L9/200033223, F0/L3/200, F0/L2/20, F0/L1/2
+
+inner-covering name=point1
+----
+F0/L30/200023210133112000102232313101, F0/L30/200033223021330130001101002333
+
+covered-by name=point1
+----
+0: F0/L30/200033223021330130001101002333, F0/L29/20003322302133013000110100233, 
+F0/L28/2000332230213301300011010023, F0/L27/200033223021330130001101002, 
+F0/L26/20003322302133013000110100, F0/L25/2000332230213301300011010, 
+F0/L24/200033223021330130001101, F0/L23/20003322302133013000110, 
+F0/L22/2000332230213301300011, F0/L21/200033223021330130001, 
+F0/L20/20003322302133013000, F0/L19/2000332230213301300, F0/L18/200033223021330130, 
+F0/L17/20003322302133013, F0/L16/2000332230213301, F0/L15/200033223021330, 
+F0/L14/20003322302133, F0/L13/2000332230213, F0/L12/200033223021, 
+F0/L11/20003322302, F0/L10/2000332230, F0/L9/200033223, F0/L8/20003322, 
+F0/L7/2000332, F0/L6/200033, F0/L5/20003, F0/L4/2000, F0/L3/200, 
+F0/L2/20, F0/L1/2, F0/L0/
+1: F0/L30/200023210133112000102232313101, F0/L29/20002321013311200010223231310, 
+F0/L28/2000232101331120001022323131, F0/L27/200023210133112000102232313, 
+F0/L26/20002321013311200010223231, F0/L25/2000232101331120001022323, 
+F0/L24/200023210133112000102232, F0/L23/20002321013311200010223, 
+F0/L22/2000232101331120001022, F0/L21/200023210133112000102, 
+F0/L20/20002321013311200010, F0/L19/2000232101331120001, F0/L18/200023210133112000, 
+F0/L17/20002321013311200, F0/L16/2000232101331120, F0/L15/200023210133112, 
+F0/L14/20002321013311, F0/L13/2000232101331, F0/L12/200023210133, 
+F0/L11/20002321013, F0/L10/2000232101, F0/L9/200023210, F0/L8/20002321, 
+F0/L7/2000232, F0/L6/200023, F0/L5/20002, F0/L4/2000, F0/L3/200, 
+F0/L2/20, F0/L1/2, F0/L0/
+
+index-keys name=shortline1
+----
+F4/L19/1010131200020223230, F4/L21/101013120002022323312
+BoundingBox: lo_x:-1.511629 hi_x:-1.511627 lo_y:0.570787 hi_y:0.570787
+
+covers name=shortline1
+----
+F4/L5/10101, F4/L7/1010131, F4/L11/10101312000, F4/L13/1010131200020, 
+F4/L14/10101312000202, F4/L15/101013120002022, F4/L16/1010131200020223, 
+F4/L17/10101312000202232, [F4/L30/101013120002022323000000000000, F4/L30/101013120002022323033333333333], 
+F4/L18/101013120002022323, F4/L20/10101312000202232331, [F4/L30/101013120002022323312000000000, F4/L30/101013120002022323312333333333], 
+F4/L19/1010131200020223233, F4/L12/101013120002, F4/L10/1010131200, 
+F4/L9/101013120, F4/L8/10101312, F4/L6/101013, F4/L4/1010, F4/L3/101, 
+F4/L2/10, F4/L1/1, F4/L0/
+
+intersects name=shortline1
+----
+F4/L5/10101, F4/L7/1010131, F4/L11/10101312000, F4/L13/1010131200020, 
+F4/L14/10101312000202, F4/L15/101013120002022, F4/L16/1010131200020223, 
+F4/L17/10101312000202232, [F4/L30/101013120002022323000000000000, F4/L30/101013120002022323033333333333], 
+F4/L18/101013120002022323, F4/L20/10101312000202232331, [F4/L30/101013120002022323312000000000, F4/L30/101013120002022323312333333333], 
+F4/L19/1010131200020223233, F4/L12/101013120002, F4/L10/1010131200, 
+F4/L9/101013120, F4/L8/10101312, F4/L6/101013, F4/L4/1010, F4/L3/101, 
+F4/L2/10, F4/L1/1, F4/L0/
+
+inner-covering name=shortline1
+----
+F4/L30/101013120002022323031030033032, F4/L30/101013120002022323312001023033
+
+covered-by name=shortline1
+----
+0: F4/L30/101013120002022323312001023033, F4/L29/10101312000202232331200102303, 
+F4/L28/1010131200020223233120010230, F4/L27/101013120002022323312001023, 
+F4/L26/10101312000202232331200102, F4/L25/1010131200020223233120010, 
+F4/L24/101013120002022323312001, F4/L23/10101312000202232331200, 
+F4/L22/1010131200020223233120, F4/L21/101013120002022323312, 
+F4/L20/10101312000202232331, F4/L19/1010131200020223233, F4/L18/101013120002022323, 
+F4/L17/10101312000202232, F4/L16/1010131200020223, F4/L15/101013120002022, 
+F4/L14/10101312000202, F4/L13/1010131200020, F4/L12/101013120002, 
+F4/L11/10101312000, F4/L10/1010131200, F4/L9/101013120, F4/L8/10101312, 
+F4/L7/1010131, F4/L6/101013, F4/L5/10101, F4/L4/1010, F4/L3/101, 
+F4/L2/10, F4/L1/1, F4/L0/
+1: F4/L30/101013120002022323031030033032, F4/L29/10101312000202232303103003303, 
+F4/L28/1010131200020223230310300330, F4/L27/101013120002022323031030033, 
+F4/L26/10101312000202232303103003, F4/L25/1010131200020223230310300, 
+F4/L24/101013120002022323031030, F4/L23/10101312000202232303103, 
+F4/L22/1010131200020223230310, F4/L21/101013120002022323031, 
+F4/L20/10101312000202232303, F4/L19/1010131200020223230, F4/L18/101013120002022323, 
+F4/L17/10101312000202232, F4/L16/1010131200020223, F4/L15/101013120002022, 
+F4/L14/10101312000202, F4/L13/1010131200020, F4/L12/101013120002, 
+F4/L11/10101312000, F4/L10/1010131200, F4/L9/101013120, F4/L8/10101312, 
+F4/L7/1010131, F4/L6/101013, F4/L5/10101, F4/L4/1010, F4/L3/101, 
+F4/L2/10, F4/L1/1, F4/L0/
+
+index-keys name=nystate
+----
+F2/L2/12, F4/L2/10
+BoundingBox: lo_x:-1.392116 hi_x:-1.252303 lo_y:0.706460 hi_y:0.785665
+
+covers name=nystate
+----
+F2/L1/1, [F2/L30/120000000000000000000000000000, F2/L30/123333333333333333333333333333], 
+F2/L0/, [F4/L30/100000000000000000000000000000, F4/L30/103333333333333333333333333333], 
+F4/L1/1, F4/L0/
+
+intersects name=nystate
+----
+F2/L1/1, [F2/L30/120000000000000000000000000000, F2/L30/123333333333333333333333333333], 
+F2/L0/, [F4/L30/100000000000000000000000000000, F4/L30/103333333333333333333333333333], 
+F4/L1/1, F4/L0/
+
+index-keys name=red-hook-nyc
+----
+F4/L13/1032010231102, F4/L13/1032010231113
+BoundingBox: lo_x:-1.291798 hi_x:-1.291737 lo_y:0.709652 hi_y:0.709690
+
+init minlevel=0 maxlevel=30 maxcells=8
+----
+
+index-keys name=nystate
+----
+F2/L5/12112, F2/L5/12121, F2/L5/12122, F2/L7/1221111, F4/L4/1001, F4/L4/1032, F4/L5/10330, F4/L5/10331
+BoundingBox: lo_x:-1.392116 hi_x:-1.252303 lo_y:0.706460 hi_y:0.785665
+
+index-keys name=red-hook-nyc
+----
+F4/L16/1032010231102232, F4/L16/1032010231102233, F4/L15/103201023110230, F4/L17/10320102311132301, F4/L18/103201023111323020, F4/L16/1032010231113233, F4/L17/10320102311133000, F4/L17/10320102311133003
+BoundingBox: lo_x:-1.291798 hi_x:-1.291737 lo_y:0.709652 hi_y:0.709690
+
+init minlevel=0 maxlevel=30 maxcells=1
+----
+
+index-keys name=point1
+----
+F0/L30/200023210133112000102232313101, F0/L30/200033223021330130001101002333
+BoundingBox: lo_x:0.017453 hi_x:0.052360 lo_y:0.069813 hi_y:0.087266
+
+covers name=point1
+----
+F0/L0/, F0/L4/2000, F0/L5/20002, F0/L6/200023, F0/L10/2000232101, 
+F0/L11/20002321013, F0/L14/20002321013311, F0/L20/20002321013311200010, 
+F0/L21/200023210133112000102, F0/L22/2000232101331120001022, 
+F0/L23/20002321013311200010223, F0/L24/200023210133112000102232, 
+F0/L26/20002321013311200010223231, F0/L30/200023210133112000102232313101, 
+F0/L29/20002321013311200010223231310, F0/L28/2000232101331120001022323131, 
+F0/L27/200023210133112000102232313, F0/L25/2000232101331120001022323, 
+F0/L19/2000232101331120001, F0/L18/200023210133112000, F0/L17/20002321013311200, 
+F0/L16/2000232101331120, F0/L15/200023210133112, F0/L13/2000232101331, 
+F0/L12/200023210133, F0/L9/200023210, F0/L8/20002321, F0/L7/2000232, 
+F0/L5/20003, F0/L6/200033, F0/L7/2000332, F0/L8/20003322, F0/L10/2000332230, 
+F0/L12/200033223021, F0/L13/2000332230213, F0/L16/2000332230213301, 
+F0/L26/20003322302133013000110100, F0/L27/200033223021330130001101002, 
+F0/L28/2000332230213301300011010023, F0/L29/20003322302133013000110100233, 
+F0/L30/200033223021330130001101002333, F0/L25/2000332230213301300011010, 
+F0/L24/200033223021330130001101, F0/L23/20003322302133013000110, 
+F0/L22/2000332230213301300011, F0/L21/200033223021330130001, 
+F0/L20/20003322302133013000, F0/L19/2000332230213301300, F0/L18/200033223021330130, 
+F0/L17/20003322302133013, F0/L15/200033223021330, F0/L14/20003322302133, 
+F0/L11/20003322302, F0/L9/200033223, F0/L3/200, F0/L2/20, F0/L1/2
+
+intersects name=point1
+----
+F0/L0/, F0/L4/2000, F0/L5/20002, F0/L6/200023, F0/L10/2000232101, 
+F0/L11/20002321013, F0/L14/20002321013311, F0/L20/20002321013311200010, 
+F0/L21/200023210133112000102, F0/L22/2000232101331120001022, 
+F0/L23/20002321013311200010223, F0/L24/200023210133112000102232, 
+F0/L26/20002321013311200010223231, F0/L30/200023210133112000102232313101, 
+F0/L29/20002321013311200010223231310, F0/L28/2000232101331120001022323131, 
+F0/L27/200023210133112000102232313, F0/L25/2000232101331120001022323, 
+F0/L19/2000232101331120001, F0/L18/200023210133112000, F0/L17/20002321013311200, 
+F0/L16/2000232101331120, F0/L15/200023210133112, F0/L13/2000232101331, 
+F0/L12/200023210133, F0/L9/200023210, F0/L8/20002321, F0/L7/2000232, 
+F0/L5/20003, F0/L6/200033, F0/L7/2000332, F0/L8/20003322, F0/L10/2000332230, 
+F0/L12/200033223021, F0/L13/2000332230213, F0/L16/2000332230213301, 
+F0/L26/20003322302133013000110100, F0/L27/200033223021330130001101002, 
+F0/L28/2000332230213301300011010023, F0/L29/20003322302133013000110100233, 
+F0/L30/200033223021330130001101002333, F0/L25/2000332230213301300011010, 
+F0/L24/200033223021330130001101, F0/L23/20003322302133013000110, 
+F0/L22/2000332230213301300011, F0/L21/200033223021330130001, 
+F0/L20/20003322302133013000, F0/L19/2000332230213301300, F0/L18/200033223021330130, 
+F0/L17/20003322302133013, F0/L15/200033223021330, F0/L14/20003322302133, 
+F0/L11/20003322302, F0/L9/200033223, F0/L3/200, F0/L2/20, F0/L1/2
+
+inner-covering name=point1
+----
+F0/L30/200023210133112000102232313101, F0/L30/200033223021330130001101002333
+
+covered-by name=point1
+----
+0: F0/L30/200033223021330130001101002333, F0/L29/20003322302133013000110100233, 
+F0/L28/2000332230213301300011010023, F0/L27/200033223021330130001101002, 
+F0/L26/20003322302133013000110100, F0/L25/2000332230213301300011010, 
+F0/L24/200033223021330130001101, F0/L23/20003322302133013000110, 
+F0/L22/2000332230213301300011, F0/L21/200033223021330130001, 
+F0/L20/20003322302133013000, F0/L19/2000332230213301300, F0/L18/200033223021330130, 
+F0/L17/20003322302133013, F0/L16/2000332230213301, F0/L15/200033223021330, 
+F0/L14/20003322302133, F0/L13/2000332230213, F0/L12/200033223021, 
+F0/L11/20003322302, F0/L10/2000332230, F0/L9/200033223, F0/L8/20003322, 
+F0/L7/2000332, F0/L6/200033, F0/L5/20003, F0/L4/2000, F0/L3/200, 
+F0/L2/20, F0/L1/2, F0/L0/
+1: F0/L30/200023210133112000102232313101, F0/L29/20002321013311200010223231310, 
+F0/L28/2000232101331120001022323131, F0/L27/200023210133112000102232313, 
+F0/L26/20002321013311200010223231, F0/L25/2000232101331120001022323, 
+F0/L24/200023210133112000102232, F0/L23/20002321013311200010223, 
+F0/L22/2000232101331120001022, F0/L21/200023210133112000102, 
+F0/L20/20002321013311200010, F0/L19/2000232101331120001, F0/L18/200023210133112000, 
+F0/L17/20002321013311200, F0/L16/2000232101331120, F0/L15/200023210133112, 
+F0/L14/20002321013311, F0/L13/2000232101331, F0/L12/200023210133, 
+F0/L11/20002321013, F0/L10/2000232101, F0/L9/200023210, F0/L8/20002321, 
+F0/L7/2000232, F0/L6/200023, F0/L5/20002, F0/L4/2000, F0/L3/200, 
+F0/L2/20, F0/L1/2, F0/L0/
+
+index-keys name=shortline1
+----
+F4/L18/101013120002022323
+BoundingBox: lo_x:-1.511629 hi_x:-1.511627 lo_y:0.570787 hi_y:0.570787
+
+covers name=shortline1
+----
+F4/L5/10101, F4/L7/1010131, F4/L11/10101312000, F4/L13/1010131200020, 
+F4/L14/10101312000202, F4/L15/101013120002022, F4/L16/1010131200020223, 
+F4/L17/10101312000202232, [F4/L30/101013120002022323000000000000, F4/L30/101013120002022323333333333333], 
+F4/L12/101013120002, F4/L10/1010131200, F4/L9/101013120, F4/L8/10101312, 
+F4/L6/101013, F4/L4/1010, F4/L3/101, F4/L2/10, F4/L1/1, F4/L0/
+
+intersects name=shortline1
+----
+F4/L5/10101, F4/L7/1010131, F4/L11/10101312000, F4/L13/1010131200020, 
+F4/L14/10101312000202, F4/L15/101013120002022, F4/L16/1010131200020223, 
+F4/L17/10101312000202232, [F4/L30/101013120002022323000000000000, F4/L30/101013120002022323333333333333], 
+F4/L12/101013120002, F4/L10/1010131200, F4/L9/101013120, F4/L8/10101312, 
+F4/L6/101013, F4/L4/1010, F4/L3/101, F4/L2/10, F4/L1/1, F4/L0/
+
+inner-covering name=shortline1
+----
+F4/L30/101013120002022323031030033032, F4/L30/101013120002022323312001023033
+
+covered-by name=shortline1
+----
+0: F4/L30/101013120002022323312001023033, F4/L29/10101312000202232331200102303, 
+F4/L28/1010131200020223233120010230, F4/L27/101013120002022323312001023, 
+F4/L26/10101312000202232331200102, F4/L25/1010131200020223233120010, 
+F4/L24/101013120002022323312001, F4/L23/10101312000202232331200, 
+F4/L22/1010131200020223233120, F4/L21/101013120002022323312, 
+F4/L20/10101312000202232331, F4/L19/1010131200020223233, F4/L18/101013120002022323, 
+F4/L17/10101312000202232, F4/L16/1010131200020223, F4/L15/101013120002022, 
+F4/L14/10101312000202, F4/L13/1010131200020, F4/L12/101013120002, 
+F4/L11/10101312000, F4/L10/1010131200, F4/L9/101013120, F4/L8/10101312, 
+F4/L7/1010131, F4/L6/101013, F4/L5/10101, F4/L4/1010, F4/L3/101, 
+F4/L2/10, F4/L1/1, F4/L0/
+1: F4/L30/101013120002022323031030033032, F4/L29/10101312000202232303103003303, 
+F4/L28/1010131200020223230310300330, F4/L27/101013120002022323031030033, 
+F4/L26/10101312000202232303103003, F4/L25/1010131200020223230310300, 
+F4/L24/101013120002022323031030, F4/L23/10101312000202232303103, 
+F4/L22/1010131200020223230310, F4/L21/101013120002022323031, 
+F4/L20/10101312000202232303, F4/L19/1010131200020223230, F4/L18/101013120002022323, 
+F4/L17/10101312000202232, F4/L16/1010131200020223, F4/L15/101013120002022, 
+F4/L14/10101312000202, F4/L13/1010131200020, F4/L12/101013120002, 
+F4/L11/10101312000, F4/L10/1010131200, F4/L9/101013120, F4/L8/10101312, 
+F4/L7/1010131, F4/L6/101013, F4/L5/10101, F4/L4/1010, F4/L3/101, 
+F4/L2/10, F4/L1/1, F4/L0/
+
+init minlevel=0 maxlevel=4 maxcells=1
+----
+
+inner-covering name=point1
+----
+F0/L4/2000
+
+inner-covering name=shortline1
+----
+F4/L4/1010
+
+init minlevel=0 maxlevel=16 maxcells=2
+----
+
+index-keys name=point1
+----
+F0/L16/2000232101331120, F0/L16/2000332230213301
+BoundingBox: lo_x:0.017453 hi_x:0.052360 lo_y:0.069813 hi_y:0.087266
+
+d-within distance=2000 name=point1
+----
+F0/L0/, F0/L4/2000, F0/L5/20002, F0/L6/200023, F0/L10/2000232100, 
+[F0/L30/200023210020000000000000000000, F0/L30/200023210023333333333333333333], 
+[F0/L30/200023210030000000000000000000, F0/L30/200023210033333333333333333333], 
+[F0/L30/200023210100000000000000000000, F0/L30/200023210133333333333333333333], 
+F0/L9/200023210, [F0/L30/200023210200000000000000000000, F0/L30/200023210203333333333333333333], 
+[F0/L30/200023210210000000000000000000, F0/L30/200023210213333333333333333333], 
+F0/L10/2000232102, [F0/L30/200023210310000000000000000000, F0/L30/200023210313333333333333333333], 
+F0/L10/2000232103, F0/L8/20002321, F0/L7/2000232, F0/L5/20003, 
+F0/L6/200033, F0/L7/2000332, F0/L8/20003322, [F0/L30/200033223000000000000000000000, F0/L30/200033223033333333333333333333], 
+[F0/L30/200033223100000000000000000000, F0/L30/200033223103333333333333333333], 
+F0/L10/2000332231, [F0/L30/200033223130000000000000000000, F0/L30/200033223133333333333333333333], 
+F0/L9/200033223, [F0/L30/200033223200000000000000000000, F0/L30/200033223203333333333333333333], 
+F0/L10/2000332232, [F0/L30/200033223310000000000000000000, F0/L30/200033223313333333333333333333], 
+F0/L10/2000332233, [F0/L30/200033223320000000000000000000, F0/L30/200033223323333333333333333333], 
+F0/L3/200, F0/L2/20, F0/L1/2
+
+d-within distance=20000 name=point1
+----
+F0/L0/, F0/L4/2000, [F0/L30/200020110000000000000000000000, F0/L30/200020113333333333333333333333], 
+F0/L7/2000201, [F0/L30/200020120000000000000000000000, F0/L30/200020123333333333333333333333], 
+F0/L6/200020, [F0/L30/200020210000000000000000000000, F0/L30/200020213333333333333333333333], 
+F0/L7/2000202, F0/L5/20002, F0/L7/2000231, [F0/L30/200023120000000000000000000000, F0/L30/200023123333333333333333333333], 
+[F0/L30/200023130000000000000000000000, F0/L30/200023133333333333333333333333], 
+F0/L6/200023, [F0/L30/200023200000000000000000000000, F0/L30/200023233333333333333333333333], 
+[F0/L30/200030110000000000000000000000, F0/L30/200030113333333333333333333333], 
+F0/L7/2000301, [F0/L30/200030120000000000000000000000, F0/L30/200030123333333333333333333333], 
+F0/L6/200030, F0/L5/20003, F0/L6/200033, [F0/L30/200033200000000000000000000000, F0/L30/200033233333333333333333333333], 
+F0/L6/200100, F0/L7/2001003, [F0/L30/200100320000000000000000000000, F0/L30/200100323333333333333333333333], 
+[F0/L30/200100330000000000000000000000, F0/L30/200100333333333333333333333333], 
+[F0/L30/200101000000000000000000000000, F0/L30/200101003333333333333333333333], 
+F0/L7/2001010, F0/L6/200101, F0/L5/20010, F0/L4/2001, F0/L3/200, 
+F0/L2/20, F0/L1/2
+
+index-keys name=nys-approx1
+----
+F4/L5/10321, F4/L5/10322
+BoundingBox: lo_x:-1.378810 hi_x:-1.343904 lo_y:0.715585 hi_y:0.767945
+
+intersects name=nys-approx1
+----
+F4/L2/10, F4/L3/103, [F4/L30/103210000000000000000000000000, F4/L30/103213333333333333333333333333], 
+F4/L4/1032, [F4/L30/103220000000000000000000000000, F4/L30/103223333333333333333333333333], 
+F4/L1/1, F4/L0/
+
+d-within distance=2000 name=nys-approx1
+----
+F2/L1/1, F2/L3/121, F2/L5/12121, F2/L6/121212, [F2/L30/121212200000000000000000000000, F2/L30/121212233333333333333333333333], 
+F2/L4/1212, [F2/L30/121221100000000000000000000000, F2/L30/121221133333333333333333333333], 
+F2/L6/121221, [F2/L30/121221200000000000000000000000, F2/L30/121221233333333333333333333333], 
+F2/L5/12122, [F2/L30/121222100000000000000000000000, F2/L30/121222133333333333333333333333], 
+F2/L6/121222, [F2/L30/121222200000000000000000000000, F2/L30/121222233333333333333333333333], 
+F2/L2/12, [F2/L30/122111100000000000000000000000, F2/L30/122111133333333333333333333333], 
+F2/L6/122111, F2/L5/12211, F2/L4/1221, F2/L3/122, F2/L0/, [F4/L30/100111100000000000000000000000, F4/L30/100111133333333333333333333333], 
+F4/L6/100111, [F4/L30/100111200000000000000000000000, F4/L30/100111233333333333333333333333], 
+F4/L5/10011, [F4/L30/100112100000000000000000000000, F4/L30/100112133333333333333333333333], 
+F4/L6/100112, [F4/L30/100112200000000000000000000000, F4/L30/100112233333333333333333333333], 
+F4/L4/1001, [F4/L30/100121100000000000000000000000, F4/L30/100121133333333333333333333333], 
+F4/L6/100121, [F4/L30/100121200000000000000000000000, F4/L30/100121233333333333333333333333], 
+F4/L5/10012, [F4/L30/100122100000000000000000000000, F4/L30/100122133333333333333333333333], 
+F4/L6/100122, [F4/L30/100122200000000000000000000000, F4/L30/100122233333333333333333333333], 
+F4/L3/100, [F4/L30/100211100000000000000000000000, F4/L30/100211133333333333333333333333], 
+F4/L6/100211, F4/L5/10021, F4/L4/1002, F4/L2/10, F4/L4/1031, 
+F4/L5/10312, F4/L6/103122, [F4/L30/103122200000000000000000000000, F4/L30/103122233333333333333333333333], 
+[F4/L30/103122300000000000000000000000, F4/L30/103122333333333333333333333333], 
+[F4/L30/103123000000000000000000000000, F4/L30/103123033333333333333333333333], 
+F4/L6/103123, [F4/L30/103123300000000000000000000000, F4/L30/103123333333333333333333333333], 
+[F4/L30/103130000000000000000000000000, F4/L30/103130033333333333333333333333], 
+F4/L6/103130, F4/L5/10313, F4/L3/103, F4/L5/10320, F4/L6/103202, 
+[F4/L30/103202200000000000000000000000, F4/L30/103202233333333333333333333333], 
+[F4/L30/103202300000000000000000000000, F4/L30/103202333333333333333333333333], 
+[F4/L30/103203000000000000000000000000, F4/L30/103203033333333333333333333333], 
+F4/L6/103203, [F4/L30/103203300000000000000000000000, F4/L30/103203333333333333333333333333], 
+[F4/L30/103210000000000000000000000000, F4/L30/103213333333333333333333333333], 
+F4/L4/1032, [F4/L30/103220000000000000000000000000, F4/L30/103223333333333333333333333333], 
+[F4/L30/103230000000000000000000000000, F4/L30/103230033333333333333333333333], 
+F4/L6/103230, [F4/L30/103230300000000000000000000000, F4/L30/103230333333333333333333333333], 
+[F4/L30/103231000000000000000000000000, F4/L30/103231033333333333333333333333], 
+[F4/L30/103231100000000000000000000000, F4/L30/103231133333333333333333333333], 
+F4/L6/103231, F4/L5/10323, F4/L1/1, F4/L0/
diff --git a/pkg/geo/geoindex/testdata/s2_geometry b/pkg/geo/geoindex/testdata/s2_geometry
new file mode 100644
index 0000000..affb9c2
--- /dev/null
+++ b/pkg/geo/geoindex/testdata/s2_geometry
@@ -0,0 +1,401 @@
+# TODO(sumeer): add more test cases
+
+geometry name=point1
+MULTIPOINT((12 12), (21 21))
+----
+
+geometry name=shortline1
+LINESTRING (11 11,12 12)
+----
+
+geometry name=line-exceeds-bound
+LINESTRING (12 15, 22 23)
+----
+
+geometry name=poly1
+POLYGON((15 15,16 15.5,15.5 17,15 15))
+----
+
+geometry name=nan
+0105000000060000000102000000020000002CF565DB1790F041010000000000F87F1C1E119D614AE7C1010000000000F87F010200000003000000809745B2972CF841010000000000F87FE0D03302F1C6D641010000000000F87FF83C7FD5C4ACD641010000000000F87F010200000004000000C4A695BE1FC2FD41010000000000F87F42F59F55FD780042010000000000F87FA07574B08DC0D941010000000000F87FD843A641FF49E741010000000000F87F010200000004000000781D60294113F241010000000000F87F100451CE196BED41010000000000F87F1430818C69A2EF41010000000000F87F00E4B02D00CB9341010000000000F87F01020000000400000040B0B6B74C96A0C1010000000000F87F1CD943F294E9E5C1010000000000F87F709F7E29F32AC4C1010000000000F87F607737DC4662E941010000000000F87F010200000004000000F097AF975517F441010000000000F87F5442BA391710F841010000000000F87FE01C9C5F7602B641010000000000F87F40E714D68300E2C1010000000000F87F
+----
+
+geometry name=poly1-different-orientation
+POLYGON((15 15,15.5 17,16 15.5,15 15))
+----
+
+init minlevel=0 maxlevel=30 maxcells=4 minx=10 miny=10 maxx=20 maxy=20
+----
+
+# NaN
+covers name=nan
+----
+cannot index a geometry with NaN coordinates
+
+index-keys name=nan
+----
+cannot index a geometry with NaN coordinates
+
+intersects name=nan
+----
+cannot index a geometry with NaN coordinates
+
+# The orientation difference between the polygons has no effect on the
+# index keys.
+
+index-keys name=poly1
+----
+F0/L30/022222222222222222222222222222, F0/L30/133333333333333333333333333333, F0/L2/20, F0/L30/311111111111111111111111111111
+BoundingBox: lo_x:15.000000 hi_x:16.000000 lo_y:15.000000 hi_y:17.000000
+
+index-keys name=poly1-different-orientation
+----
+F0/L30/022222222222222222222222222222, F0/L30/133333333333333333333333333333, F0/L2/20, F0/L30/311111111111111111111111111111
+BoundingBox: lo_x:15.000000 hi_x:16.000000 lo_y:15.000000 hi_y:17.000000
+
+# Point exceeds the defined bounds.
+
+index-keys name=point1
+----
+F0/L30/002200220022002200220022002200, spilled
+BoundingBox: lo_x:12.000000 hi_x:21.000000 lo_y:12.000000 hi_y:21.000000
+
+covers name=point1
+----
+F0/L2/00, F0/L3/002, F0/L6/002200, F0/L7/0022002, F0/L10/0022002200, 
+F0/L11/00220022002, F0/L14/00220022002200, F0/L15/002200220022002, 
+F0/L18/002200220022002200, F0/L19/0022002200220022002, F0/L22/0022002200220022002200, 
+F0/L23/00220022002200220022002, F0/L26/00220022002200220022002200, 
+F0/L27/002200220022002200220022002, F0/L30/002200220022002200220022002200, 
+F0/L29/00220022002200220022002200220, F0/L28/0022002200220022002200220022, 
+F0/L25/0022002200220022002200220, F0/L24/002200220022002200220022, 
+F0/L21/002200220022002200220, F0/L20/00220022002200220022, F0/L17/00220022002200220, 
+F0/L16/0022002200220022, F0/L13/0022002200220, F0/L12/002200220022, 
+F0/L9/002200220, F0/L8/00220022, F0/L5/00220, F0/L4/0022, F0/L1/0, 
+F0/L0/, spilled
+
+intersects name=point1
+----
+F0/L2/00, F0/L3/002, F0/L6/002200, F0/L7/0022002, F0/L10/0022002200, 
+F0/L11/00220022002, F0/L14/00220022002200, F0/L15/002200220022002, 
+F0/L18/002200220022002200, F0/L19/0022002200220022002, F0/L22/0022002200220022002200, 
+F0/L23/00220022002200220022002, F0/L26/00220022002200220022002200, 
+F0/L27/002200220022002200220022002, F0/L30/002200220022002200220022002200, 
+F0/L29/00220022002200220022002200220, F0/L28/0022002200220022002200220022, 
+F0/L25/0022002200220022002200220, F0/L24/002200220022002200220022, 
+F0/L21/002200220022002200220, F0/L20/00220022002200220022, F0/L17/00220022002200220, 
+F0/L16/0022002200220022, F0/L13/0022002200220, F0/L12/002200220022, 
+F0/L9/002200220, F0/L8/00220022, F0/L5/00220, F0/L4/0022, F0/L1/0, 
+F0/L0/, spilled
+
+inner-covering name=point1
+----
+F0/L30/002200220022002200220022002200
+
+covered-by name=point1
+----
+0: spilled
+1: F0/L30/002200220022002200220022002200, F0/L29/00220022002200220022002200220, 
+F0/L28/0022002200220022002200220022, F0/L27/002200220022002200220022002, 
+F0/L26/00220022002200220022002200, F0/L25/0022002200220022002200220, 
+F0/L24/002200220022002200220022, F0/L23/00220022002200220022002, 
+F0/L22/0022002200220022002200, F0/L21/002200220022002200220, 
+F0/L20/00220022002200220022, F0/L19/0022002200220022002, F0/L18/002200220022002200, 
+F0/L17/00220022002200220, F0/L16/0022002200220022, F0/L15/002200220022002, 
+F0/L14/00220022002200, F0/L13/0022002200220, F0/L12/002200220022, 
+F0/L11/00220022002, F0/L10/0022002200, F0/L9/002200220, F0/L8/00220022, 
+F0/L7/0022002, F0/L6/002200, F0/L5/00220, F0/L4/0022, F0/L3/002, 
+F0/L2/00, F0/L1/0, F0/L0/
+
+index-keys name=shortline1
+----
+F0/L5/00022, F0/L3/002, F0/L30/003111111111111111111111111111
+BoundingBox: lo_x:11.000000 hi_x:12.000000 lo_y:11.000000 hi_y:12.000000
+
+covers name=shortline1
+----
+F0/L3/000, F0/L4/0002, [F0/L30/000220000000000000000000000000, F0/L30/000223333333333333333333333333], 
+F0/L2/00, [F0/L30/002000000000000000000000000000, F0/L30/002333333333333333333333333333], 
+F0/L30/003111111111111111111111111111, F0/L29/00311111111111111111111111111, 
+F0/L28/0031111111111111111111111111, F0/L27/003111111111111111111111111, 
+F0/L26/00311111111111111111111111, F0/L25/0031111111111111111111111, 
+F0/L24/003111111111111111111111, F0/L23/00311111111111111111111, 
+F0/L22/0031111111111111111111, F0/L21/003111111111111111111, 
+F0/L20/00311111111111111111, F0/L19/0031111111111111111, F0/L18/003111111111111111, 
+F0/L17/00311111111111111, F0/L16/0031111111111111, F0/L15/003111111111111, 
+F0/L14/00311111111111, F0/L13/0031111111111, F0/L12/003111111111, 
+F0/L11/00311111111, F0/L10/0031111111, F0/L9/003111111, F0/L8/00311111, 
+F0/L7/0031111, F0/L6/003111, F0/L5/00311, F0/L4/0031, F0/L3/003, 
+F0/L1/0, F0/L0/
+
+intersects name=shortline1
+----
+F0/L3/000, F0/L4/0002, [F0/L30/000220000000000000000000000000, F0/L30/000223333333333333333333333333], 
+F0/L2/00, [F0/L30/002000000000000000000000000000, F0/L30/002333333333333333333333333333], 
+F0/L30/003111111111111111111111111111, F0/L29/00311111111111111111111111111, 
+F0/L28/0031111111111111111111111111, F0/L27/003111111111111111111111111, 
+F0/L26/00311111111111111111111111, F0/L25/0031111111111111111111111, 
+F0/L24/003111111111111111111111, F0/L23/00311111111111111111111, 
+F0/L22/0031111111111111111111, F0/L21/003111111111111111111, 
+F0/L20/00311111111111111111, F0/L19/0031111111111111111, F0/L18/003111111111111111, 
+F0/L17/00311111111111111, F0/L16/0031111111111111, F0/L15/003111111111111, 
+F0/L14/00311111111111, F0/L13/0031111111111, F0/L12/003111111111, 
+F0/L11/00311111111, F0/L10/0031111111, F0/L9/003111111, F0/L8/00311111, 
+F0/L7/0031111, F0/L6/003111, F0/L5/00311, F0/L4/0031, F0/L3/003, 
+F0/L1/0, F0/L0/
+
+inner-covering name=shortline1
+----
+F0/L30/000220022002200220022002200220, F0/L30/002200220022002200220022002200
+
+covered-by name=shortline1
+----
+0: F0/L30/002200220022002200220022002200, F0/L29/00220022002200220022002200220, 
+F0/L28/0022002200220022002200220022, F0/L27/002200220022002200220022002, 
+F0/L26/00220022002200220022002200, F0/L25/0022002200220022002200220, 
+F0/L24/002200220022002200220022, F0/L23/00220022002200220022002, 
+F0/L22/0022002200220022002200, F0/L21/002200220022002200220, 
+F0/L20/00220022002200220022, F0/L19/0022002200220022002, F0/L18/002200220022002200, 
+F0/L17/00220022002200220, F0/L16/0022002200220022, F0/L15/002200220022002, 
+F0/L14/00220022002200, F0/L13/0022002200220, F0/L12/002200220022, 
+F0/L11/00220022002, F0/L10/0022002200, F0/L9/002200220, F0/L8/00220022, 
+F0/L7/0022002, F0/L6/002200, F0/L5/00220, F0/L4/0022, F0/L3/002, 
+F0/L2/00, F0/L1/0, F0/L0/
+1: F0/L30/000220022002200220022002200220, F0/L29/00022002200220022002200220022, 
+F0/L28/0002200220022002200220022002, F0/L27/000220022002200220022002200, 
+F0/L26/00022002200220022002200220, F0/L25/0002200220022002200220022, 
+F0/L24/000220022002200220022002, F0/L23/00022002200220022002200, 
+F0/L22/0002200220022002200220, F0/L21/000220022002200220022, 
+F0/L20/00022002200220022002, F0/L19/0002200220022002200, F0/L18/000220022002200220, 
+F0/L17/00022002200220022, F0/L16/0002200220022002, F0/L15/000220022002200, 
+F0/L14/00022002200220, F0/L13/0002200220022, F0/L12/000220022002, 
+F0/L11/00022002200, F0/L10/0002200220, F0/L9/000220022, F0/L8/00022002, 
+F0/L7/0002200, F0/L6/000220, F0/L5/00022, F0/L4/0002, F0/L3/000, 
+F0/L2/00, F0/L1/0, F0/L0/
+
+index-keys name=line-exceeds-bound
+----
+F0/L30/030033003300330033003300330033, F0/L1/1, F0/L2/21, F0/L4/2211, spilled
+BoundingBox: lo_x:12.000000 hi_x:22.000000 lo_y:15.000000 hi_y:23.000000
+
+covers name=line-exceeds-bound
+----
+F0/L1/0, F0/L4/0300, F0/L5/03003, F0/L8/03003300, F0/L9/030033003, 
+F0/L12/030033003300, F0/L13/0300330033003, F0/L16/0300330033003300, 
+F0/L17/03003300330033003, F0/L20/03003300330033003300, F0/L21/030033003300330033003, 
+F0/L24/030033003300330033003300, F0/L25/0300330033003300330033003, 
+F0/L28/0300330033003300330033003300, F0/L29/03003300330033003300330033003, 
+F0/L30/030033003300330033003300330033, F0/L27/030033003300330033003300330, 
+F0/L26/03003300330033003300330033, F0/L23/03003300330033003300330, 
+F0/L22/0300330033003300330033, F0/L19/0300330033003300330, F0/L18/030033003300330033, 
+F0/L15/030033003300330, F0/L14/03003300330033, F0/L11/03003300330, 
+F0/L10/0300330033, F0/L7/0300330, F0/L6/030033, F0/L3/030, F0/L2/03, 
+[F0/L30/100000000000000000000000000000, F0/L30/133333333333333333333333333333], 
+F0/L0/, [F0/L30/210000000000000000000000000000, F0/L30/213333333333333333333333333333], 
+F0/L1/2, [F0/L30/221100000000000000000000000000, F0/L30/221133333333333333333333333333], 
+F0/L3/221, F0/L2/22, spilled
+
+intersects name=line-exceeds-bound
+----
+F0/L1/0, F0/L4/0300, F0/L5/03003, F0/L8/03003300, F0/L9/030033003, 
+F0/L12/030033003300, F0/L13/0300330033003, F0/L16/0300330033003300, 
+F0/L17/03003300330033003, F0/L20/03003300330033003300, F0/L21/030033003300330033003, 
+F0/L24/030033003300330033003300, F0/L25/0300330033003300330033003, 
+F0/L28/0300330033003300330033003300, F0/L29/03003300330033003300330033003, 
+F0/L30/030033003300330033003300330033, F0/L27/030033003300330033003300330, 
+F0/L26/03003300330033003300330033, F0/L23/03003300330033003300330, 
+F0/L22/0300330033003300330033, F0/L19/0300330033003300330, F0/L18/030033003300330033, 
+F0/L15/030033003300330, F0/L14/03003300330033, F0/L11/03003300330, 
+F0/L10/0300330033, F0/L7/0300330, F0/L6/030033, F0/L3/030, F0/L2/03, 
+[F0/L30/100000000000000000000000000000, F0/L30/133333333333333333333333333333], 
+F0/L0/, [F0/L30/210000000000000000000000000000, F0/L30/213333333333333333333333333333], 
+F0/L1/2, [F0/L30/221100000000000000000000000000, F0/L30/221133333333333333333333333333], 
+F0/L3/221, F0/L2/22, spilled
+
+inner-covering name=line-exceeds-bound
+----
+F0/L30/101100110011001100110011001100, F0/L30/221122301000333301033322223010
+
+covered-by name=line-exceeds-bound
+----
+0: spilled
+1: F0/L30/221122301000333301033322223010, F0/L29/22112230100033330103332222301, 
+F0/L28/2211223010003333010333222230, F0/L27/221122301000333301033322223, 
+F0/L26/22112230100033330103332222, F0/L25/2211223010003333010333222, 
+F0/L24/221122301000333301033322, F0/L23/22112230100033330103332, 
+F0/L22/2211223010003333010333, F0/L21/221122301000333301033, 
+F0/L20/22112230100033330103, F0/L19/2211223010003333010, F0/L18/221122301000333301, 
+F0/L17/22112230100033330, F0/L16/2211223010003333, F0/L15/221122301000333, 
+F0/L14/22112230100033, F0/L13/2211223010003, F0/L12/221122301000, 
+F0/L11/22112230100, F0/L10/2211223010, F0/L9/221122301, F0/L8/22112230, 
+F0/L7/2211223, F0/L6/221122, F0/L5/22112, F0/L4/2211, F0/L3/221, 
+F0/L2/22, F0/L1/2, F0/L0/
+2: F0/L30/101100110011001100110011001100, F0/L29/10110011001100110011001100110, 
+F0/L28/1011001100110011001100110011, F0/L27/101100110011001100110011001, 
+F0/L26/10110011001100110011001100, F0/L25/1011001100110011001100110, 
+F0/L24/101100110011001100110011, F0/L23/10110011001100110011001, 
+F0/L22/1011001100110011001100, F0/L21/101100110011001100110, 
+F0/L20/10110011001100110011, F0/L19/1011001100110011001, F0/L18/101100110011001100, 
+F0/L17/10110011001100110, F0/L16/1011001100110011, F0/L15/101100110011001, 
+F0/L14/10110011001100, F0/L13/1011001100110, F0/L12/101100110011, 
+F0/L11/10110011001, F0/L10/1011001100, F0/L9/101100110, F0/L8/10110011, 
+F0/L7/1011001, F0/L6/101100, F0/L5/10110, F0/L4/1011, F0/L3/101, 
+F0/L2/10, F0/L1/1, F0/L0/
+
+init minlevel=0 maxlevel=4 maxcells=1 minx=10 miny=10 maxx=20 maxy=20
+----
+
+inner-covering name=point1
+----
+F0/L4/0022
+
+inner-covering name=shortline1
+----
+F0/L4/0002, F0/L4/0022
+
+inner-covering name=line-exceeds-bound
+----
+F0/L4/1011, F0/L4/2211
+
+init minlevel=0 maxlevel=2 maxcells=1 minx=10 miny=10 maxx=20 maxy=20
+----
+
+inner-covering name=point1
+----
+F0/L2/00
+
+inner-covering name=shortline1
+----
+F0/L2/00
+
+inner-covering name=line-exceeds-bound
+----
+F0/L2/10, F0/L2/22
+
+init minlevel=0 maxlevel=4 maxcells=2 minx=10 miny=10 maxx=20 maxy=20
+----
+
+index-keys name=point1
+----
+F0/L4/0022, spilled
+BoundingBox: lo_x:12.000000 hi_x:21.000000 lo_y:12.000000 hi_y:21.000000
+
+covers name=point1
+----
+F0/L2/00, F0/L3/002, [F0/L30/002200000000000000000000000000, F0/L30/002233333333333333333333333333], 
+F0/L1/0, F0/L0/, spilled
+
+d-within distance=1 name=point1
+----
+[F0/L30/000000000000000000000000000000, F0/L30/033333333333333333333333333333], 
+F0/L0/, spilled
+
+# See https://github.com/cockroachdb/cockroach/issues/106954 for skip-arm64.
+d-within distance=2 name=point1 skip-arm64
+----
+[F0/L30/000000000000000000000000000000, F0/L30/033333333333333333333333333333], 
+F0/L0/, F0/L1/2, F0/L2/22, [F0/L30/222000000000000000000000000000, F0/L30/222333333333333333333333333333], 
+spilled
+
+# Since s2GeometryIndex.{Covers,Intersects} currently have the same implementation,
+# the output of d-fully-within is the same as dwithin.
+
+d-fully-within distance=1 name=point1
+----
+[F0/L30/000000000000000000000000000000, F0/L30/033333333333333333333333333333], 
+F0/L0/, spilled
+
+# See https://github.com/cockroachdb/cockroach/issues/106954 for skip-arm64.
+d-fully-within distance=2 name=point1 skip-arm64
+----
+[F0/L30/000000000000000000000000000000, F0/L30/033333333333333333333333333333], 
+F0/L0/, F0/L1/2, F0/L2/22, [F0/L30/222000000000000000000000000000, F0/L30/222333333333333333333333333333], 
+spilled
+
+# Empty shapes
+
+geometry name=point-empty
+POINT EMPTY
+----
+
+index-keys name=point-empty
+----
+
+covered-by name=point-empty
+----
+
+covers name=point-empty
+----
+
+inner-covering name=point-empty
+----
+
+geometry name=polygon-empty
+POLYGON EMPTY
+----
+
+index-keys name=polygon-empty
+----
+
+covered-by name=polygon-empty
+----
+
+covers name=polygon-empty
+----
+
+inner-covering name=polygon-empty
+----
+
+geometry name=coll-empty
+GEOMETRYCOLLECTION EMPTY
+----
+
+index-keys name=coll-empty
+----
+
+covered-by name=coll-empty
+----
+
+covers name=coll-empty
+----
+
+inner-covering name=coll-empty
+----
+
+# Rough bounds for SRID 26918, used in a data set with geometries that triggered
+# bad coverings. If we did not fallback to using the bounding box, these coverings
+# would be F0/L0/, F1/L0/, F2/L0/, F3/L0/, F4/L0/, F5/L0/.
+init minlevel=0 maxlevel=30 maxcells=4 minx=-9102387 miny=680961 maxx=11819889 maxy=9646533
+----
+
+geometry name=troubled-poly1
+MULTIPOLYGON (((586857.9475235254503786563873 4500244.4056084547191858291626, 586890.2225210913456976413727 4500184.1842294149100780487061, 586836.4119185773888602852821 4500155.4893597159534692764282, 586828.247425784822553396225 4500149.819862429983913898468, 586828.2344921003095805644989 4500149.8106948612257838249207, 586828.219571095774881541729 4500149.8045549383386969566345, 586818.8969909736188128590584 4500145.6565522141754627227783, 586818.8891138497274369001389 4500145.6525010699406266212463, 586818.8811029464704915881157 4500145.6504012979567050933838, 586808.8418830885784700512886 4500143.3347355769947171211243, 586808.8288800554582849144936 4500143.3316676989197731018066, 586808.8138911846326664090157 4500143.3314972892403602600098, 586798.6254629108589142560959 4500142.9746762989088892936707, 586798.606457170913927257061 4500142.9744602208957076072693, 586798.5874725470785051584244 4500142.9772946210578083992004, 586788.7675613947212696075439 4500144.4972309721633791923523, 586773.9053534916602075099945 4500232.9436314916238188743591, 586843.7861474975943565368652 4500270.3302134787663817405701, 586857.9475235254503786563873 4500244.4056084547191858291626)))
+----
+
+geometry name=troubled-poly2
+MULTIPOLYGON (((592585.8247029320336878299713 4527600.0504941008985042572021, 592570.350101865711621940136 4527506.2746569896116852760315, 592565.788726658443920314312 4527515.0605620192363858222961, 592559.4958810925018042325974 4527523.4817722812294960021973, 592551.4831399817485362291336 4527531.0544084021821618080139, 592541.9410741194151341915131 4527537.281961767934262752533, 592531.242556162993423640728 4527541.7387133436277508735657, 592519.9064861471997573971748 4527544.1516027571633458137512, 592508.5146641617175191640854 4527544.4512635143473744392395, 592497.6182677873875945806503 4527542.7740788338705897331238, 592487.654849782935343682766 4527539.4209095872938632965088, 592478.9087759252870455384254 4527534.7839743737131357192993, 592426.5560151999816298484802 4527507.3111610254272818565369, 592391.1302773362258449196815 4527487.8251397302374243736267, 592380.5234924985561519861221 4527483.903793333098292350769, 592380.5135518473107367753983 4527483.8996622655540704727173, 592380.503569008316844701767 4527483.8975952444598078727722, 592369.0481809278717264533043 4527481.7931765085086226463318, 592369.0362646455178037285805 4527481.7910315934568643569946, 592369.0252366602653637528419 4527481.7909055659547448158264, 592357.2036226189229637384415 4527481.7277858173474669456482, 592357.1816224402282387018204 4527481.7275343947112560272217, 592357.1595949504990130662918 4527481.7313001239672303199768, 592345.5120095876045525074005 4527483.7616681559011340141296, 592345.5029671189840883016586 4527483.7635735515505075454712, 592345.4939884119667112827301 4527483.7664096402004361152649, 592334.5448844350175932049751 4527487.7513697473332285881042, 592334.5358300651423633098602 4527487.7543165665119886398315, 592334.5267987564438953995705 4527487.760127955116331577301, 592324.7216157623333856463432 4527493.3917804230004549026489, 592327.3960505314171314239502 4527512.0222137765958905220032, 592331.7675609502475708723068 4527530.52607412729412317276, 592337.8227386228973045945168 4527548.6721113082021474838257, 592345.5072859587380662560463 4527566.2330158911645412445068, 592354.7286294148070737719536 4527582.9927399819716811180115, 592365.3550374577753245830536 4527598.7585767218843102455139, 592377.2264194176532328128815 4527613.3650593571364879608154, 592387.9781726722139865159988 4527629.3583310637623071670532, 592452.8652935600839555263519 4527675.0458535477519035339355, 592492.8839034214615821838379 4527688.4662118805572390556335, 592592.2261793565703555941582 4527693.3977307192981243133545, 592585.8247029320336878299713 4527600.0504941008985042572021)))
+----
+
+index-keys name=troubled-poly1
+----
+F0/L17/02213031322200022, F0/L18/022130313222001333, F0/L16/0221303132220020, F0/L16/0221303132220031
+BoundingBox: lo_x:586773.905353 hi_x:586890.222521 lo_y:4500142.974460 hi_y:4500270.330213
+
+index-keys name=troubled-poly2
+----
+F0/L16/0221303121021212, F0/L16/0221303121021221, F0/L16/0221303121312112, F0/L16/0221303121312121
+BoundingBox: lo_x:592324.721616 hi_x:592592.226179 lo_y:4527481.727534 hi_y:4527693.397731
+
+# Index tests for geometries with Z/M coordinates.
+
+geometry name=3d-line-exceeds-bounds
+LINESTRING Z (-1126040592.69383 164687857.663771 -4874040605.86647,-1096532142.92787 -5330670539.80611 7585243782.68975,9489439383.13689 6909804458.78381 8297630805.37724,-6339483118.5989 1323767903.77216 -7534611690.78481)
+----
+
+init minlevel=0 maxlevel=30 maxcells=4 minx=-2104533975 miny=-2104533975 maxx=2104533975 maxy=2104533975
+----
+
+index-keys name=3d-line-exceeds-bounds
+----
+F0/L2/00, F0/L3/030, F0/L3/031, F0/L4/1011, F0/L4/3330, F0/L7/3332011, F0/L5/33323, F0/L5/33331, spilled
+BoundingBox: lo_x:-6339483118.598900 hi_x:9489439383.136890 lo_y:-5330670539.806110 hi_y:6909804458.783810
diff --git a/pkg/geo/geomfn/add_measure.go b/pkg/geo/geomfn/add_measure.go
new file mode 100644
index 0000000..a2380cb
--- /dev/null
+++ b/pkg/geo/geomfn/add_measure.go
@@ -0,0 +1,127 @@
+// Copyright 2021 The Cockroach Authors.
+//
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
+
+package geomfn
+
+import (
+	"github.com/cockroachdb/cockroachdb-parser/pkg/geo"
+	"github.com/cockroachdb/cockroachdb-parser/pkg/sql/pgwire/pgcode"
+	"github.com/cockroachdb/cockroachdb-parser/pkg/sql/pgwire/pgerror"
+	"github.com/twpayne/go-geom"
+)
+
+// AddMeasure takes a LineString or MultiLineString and linearly interpolates measure values for each line.
+func AddMeasure(geometry geo.Geometry, start float64, end float64) (geo.Geometry, error) {
+	t, err := geometry.AsGeomT()
+	if err != nil {
+		return geometry, err
+	}
+
+	switch t := t.(type) {
+	case *geom.LineString:
+		newLineString, err := addMeasureToLineString(t, start, end)
+		if err != nil {
+			return geometry, err
+		}
+		return geo.MakeGeometryFromGeomT(newLineString)
+	case *geom.MultiLineString:
+		newMultiLineString, err := addMeasureToMultiLineString(t, start, end)
+		if err != nil {
+			return geometry, err
+		}
+		return geo.MakeGeometryFromGeomT(newMultiLineString)
+	default:
+		// Ideally we should return NULL here, but following PostGIS on this.
+		return geometry, pgerror.Newf(pgcode.InvalidParameterValue, "input geometry must be LINESTRING or MULTILINESTRING")
+	}
+}
+
+// addMeasureToMultiLineString takes a MultiLineString and linearly interpolates measure values for each component line.
+func addMeasureToMultiLineString(
+	multiLineString *geom.MultiLineString, start float64, end float64,
+) (*geom.MultiLineString, error) {
+	newMultiLineString :=
+		geom.NewMultiLineString(augmentLayoutWithM(multiLineString.Layout())).SetSRID(multiLineString.SRID())
+
+	// Create a copy of the MultiLineString with measures added to each component LineString.
+	for i := 0; i < multiLineString.NumLineStrings(); i++ {
+		newLineString, err := addMeasureToLineString(multiLineString.LineString(i), start, end)
+		if err != nil {
+			return multiLineString, err
+		}
+		err = newMultiLineString.Push(newLineString)
+		if err != nil {
+			return multiLineString, err
+		}
+	}
+
+	return newMultiLineString, nil
+}
+
+// addMeasureToLineString takes a LineString and linearly interpolates measure values.
+func addMeasureToLineString(
+	lineString *geom.LineString, start float64, end float64,
+) (*geom.LineString, error) {
+	newLineString := geom.NewLineString(augmentLayoutWithM(lineString.Layout())).SetSRID(lineString.SRID())
+
+	if lineString.Empty() {
+		return newLineString, nil
+	}
+
+	// Extract the line's current points.
+	lineCoords := lineString.Coords()
+
+	// Compute the length of the line as the sum of the distances between each pair of points.
+	// Also, fill in pointMeasures with the partial sums.
+	prevPoint := lineCoords[0]
+	lineLength := float64(0)
+	pointMeasures := make([]float64, lineString.NumCoords())
+	for i := 0; i < lineString.NumCoords(); i++ {
+		curPoint := lineCoords[i]
+		distBetweenPoints := coordNorm(coordSub(prevPoint, curPoint))
+		lineLength += distBetweenPoints
+		pointMeasures[i] = lineLength
+		prevPoint = curPoint
+	}
+
+	// Compute the measures for each point.
+	for i := 0; i < lineString.NumCoords(); i++ {
+		// Handle special case where line is zero length.
+		if lineLength == 0 {
+			pointMeasures[i] = start + (end-start)*(float64(i)/float64(lineString.NumCoords()-1))
+		} else {
+			pointMeasures[i] = start + (end-start)*(pointMeasures[i]/lineLength)
+		}
+	}
+
+	// Replace M value if it exists, otherwise append it to each Coord.
+	for i := 0; i < lineString.NumCoords(); i++ {
+		if lineString.Layout().MIndex() == -1 {
+			lineCoords[i] = append(lineCoords[i], pointMeasures[i])
+		} else {
+			lineCoords[i][lineString.Layout().MIndex()] = pointMeasures[i]
+		}
+	}
+
+	// Create a new LineString with the measures tacked on.
+	_, err := newLineString.SetCoords(lineCoords)
+	if err != nil {
+		return lineString, err
+	}
+
+	return newLineString, nil
+}
+
+// augmentLayoutWithM takes a layout and returns a layout with the M dimension added.
+func augmentLayoutWithM(layout geom.Layout) geom.Layout {
+	switch layout {
+	case geom.XY, geom.XYM:
+		return geom.XYM
+	case geom.XYZ, geom.XYZM:
+		return geom.XYZM
+	default:
+		return layout
+	}
+}
diff --git a/pkg/geo/geomfn/affine_transforms.go b/pkg/geo/geomfn/affine_transforms.go
new file mode 100644
index 0000000..fe6cbb1
--- /dev/null
+++ b/pkg/geo/geomfn/affine_transforms.go
@@ -0,0 +1,347 @@
+// Copyright 2020 The Cockroach Authors.
+//
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
+
+package geomfn
+
+import (
+	"math"
+
+	"github.com/cockroachdb/cockroachdb-parser/pkg/geo"
+	"github.com/cockroachdb/cockroachdb-parser/pkg/geo/geopb"
+	"github.com/cockroachdb/cockroachdb-parser/pkg/sql/pgwire/pgcode"
+	"github.com/cockroachdb/cockroachdb-parser/pkg/sql/pgwire/pgerror"
+	"github.com/cockroachdb/errors"
+	"github.com/twpayne/go-geom"
+)
+
+// AffineMatrix defines an affine transformation matrix for a geom object.
+// It is expected to be of the form:
+//
+//	a  b  c  x_off
+//	d  e  f  y_off
+//	g  h  i  z_off
+//	0  0  0  1
+//
+// Which gets applies onto a coordinate of form:
+//
+//	(x y z 0)^T
+//
+// With the following transformation:
+//
+//	x' = a*x + b*y + c*z + x_off
+//	y' = d*x + e*y + f*z + y_off
+//	z' = g*x + h*y + i*z + z_off
+type AffineMatrix [][]float64
+
+// Affine applies a 3D affine transformation onto the given geometry.
+// See: https://en.wikipedia.org/wiki/Affine_transformation.
+func Affine(g geo.Geometry, m AffineMatrix) (geo.Geometry, error) {
+	if g.Empty() {
+		return g, nil
+	}
+
+	t, err := g.AsGeomT()
+	if err != nil {
+		return geo.Geometry{}, err
+	}
+
+	newT, err := affine(t, m)
+	if err != nil {
+		return geo.Geometry{}, err
+	}
+	return geo.MakeGeometryFromGeomT(newT)
+}
+
+func affine(t geom.T, m AffineMatrix) (geom.T, error) {
+	return applyOnCoordsForGeomT(t, func(l geom.Layout, dst, src []float64) error {
+		var z float64
+		if l.ZIndex() != -1 {
+			z = src[l.ZIndex()]
+		}
+		newX := m[0][0]*src[0] + m[0][1]*src[1] + m[0][2]*z + m[0][3]
+		newY := m[1][0]*src[0] + m[1][1]*src[1] + m[1][2]*z + m[1][3]
+		newZ := m[2][0]*src[0] + m[2][1]*src[1] + m[2][2]*z + m[2][3]
+
+		dst[0] = newX
+		dst[1] = newY
+		if l.ZIndex() != -1 {
+			dst[2] = newZ
+		}
+		if l.MIndex() != -1 {
+			dst[l.MIndex()] = src[l.MIndex()]
+		}
+		return nil
+	})
+}
+
+// Translate returns a modified Geometry whose coordinates are incremented
+// or decremented by the deltas.
+func Translate(g geo.Geometry, deltas []float64) (geo.Geometry, error) {
+	if g.Empty() {
+		return g, nil
+	}
+
+	t, err := g.AsGeomT()
+	if err != nil {
+		return geo.Geometry{}, err
+	}
+
+	newT, err := translate(t, deltas)
+	if err != nil {
+		return geo.Geometry{}, err
+	}
+	return geo.MakeGeometryFromGeomT(newT)
+}
+
+func translate(t geom.T, deltas []float64) (geom.T, error) {
+	if t.Layout().Stride() != len(deltas) {
+		err := geom.ErrStrideMismatch{
+			Got:  len(deltas),
+			Want: t.Layout().Stride(),
+		}
+		return nil, pgerror.WithCandidateCode(
+			errors.Wrap(err, "translating coordinates"),
+			pgcode.InvalidParameterValue,
+		)
+	}
+	var zOff float64
+	if t.Layout().ZIndex() != -1 {
+		zOff = deltas[t.Layout().ZIndex()]
+	}
+	return affine(
+		t,
+		AffineMatrix([][]float64{
+			{1, 0, 0, deltas[0]},
+			{0, 1, 0, deltas[1]},
+			{0, 0, 1, zOff},
+			{0, 0, 0, 1},
+		}),
+	)
+}
+
+// Scale returns a modified Geometry whose coordinates are multiplied by the factors.
+// REQUIRES: len(factors) >= 2.
+func Scale(g geo.Geometry, factors []float64) (geo.Geometry, error) {
+	var zFactor float64
+	if len(factors) > 2 {
+		zFactor = factors[2]
+	}
+	return Affine(
+		g,
+		AffineMatrix([][]float64{
+			{factors[0], 0, 0, 0},
+			{0, factors[1], 0, 0},
+			{0, 0, zFactor, 0},
+			{0, 0, 0, 1},
+		}),
+	)
+}
+
+// ScaleRelativeToOrigin returns a modified Geometry whose coordinates are
+// multiplied by the factors relative to the origin.
+func ScaleRelativeToOrigin(
+	g geo.Geometry, factor geo.Geometry, origin geo.Geometry,
+) (geo.Geometry, error) {
+	if g.Empty() {
+		return g, nil
+	}
+
+	t, err := g.AsGeomT()
+	if err != nil {
+		return geo.Geometry{}, err
+	}
+
+	factorG, err := factor.AsGeomT()
+	if err != nil {
+		return geo.Geometry{}, err
+	}
+
+	factorPointG, ok := factorG.(*geom.Point)
+	if !ok {
+		return geo.Geometry{}, pgerror.Newf(pgcode.InvalidParameterValue, "the scaling factor must be a Point")
+	}
+
+	originG, err := origin.AsGeomT()
+	if err != nil {
+		return geo.Geometry{}, err
+	}
+
+	originPointG, ok := originG.(*geom.Point)
+	if !ok {
+		return geo.Geometry{}, pgerror.Newf(pgcode.InvalidParameterValue, "the false origin must be a Point")
+	}
+
+	if factorG.Stride() != originG.Stride() {
+		err := geom.ErrStrideMismatch{
+			Got:  factorG.Stride(),
+			Want: originG.Stride(),
+		}
+		return geo.Geometry{}, pgerror.WithCandidateCode(
+			errors.Wrap(err, "number of dimensions for the scaling factor and origin must be equal"),
+			pgcode.InvalidParameterValue,
+		)
+	}
+
+	// This is inconsistent with PostGIS, which allows a POINT EMPTY, but whose
+	// behavior seems to depend on previous queries in the session, and not
+	// desirable to reproduce.
+	if len(originPointG.FlatCoords()) < 2 {
+		return geo.Geometry{}, pgerror.Newf(pgcode.InvalidParameterValue, "the origin must have at least 2 coordinates")
+	}
+
+	// Offset by the origin, scale, and translate it back to the origin.
+	offsetDeltas := make([]float64, 0, 3)
+	offsetDeltas = append(offsetDeltas, -originPointG.X(), -originPointG.Y())
+	if originG.Layout().ZIndex() != -1 {
+		offsetDeltas = append(offsetDeltas, -originPointG.Z())
+	}
+	retT, err := translate(t, offsetDeltas)
+	if err != nil {
+		return geo.Geometry{}, err
+	}
+
+	var xFactor, yFactor, zFactor float64
+	zFactor = 1
+	if len(factorPointG.FlatCoords()) < 2 {
+		// POINT EMPTY results in factors of 0, similar to PostGIS.
+		xFactor, yFactor = 0, 0
+	} else {
+		xFactor, yFactor = factorPointG.X(), factorPointG.Y()
+		if factorPointG.Layout().ZIndex() != -1 {
+			zFactor = factorPointG.Z()
+		}
+	}
+
+	retT, err = affine(
+		retT,
+		AffineMatrix([][]float64{
+			{xFactor, 0, 0, 0},
+			{0, yFactor, 0, 0},
+			{0, 0, zFactor, 0},
+			{0, 0, 0, 1},
+		}),
+	)
+	if err != nil {
+		return geo.Geometry{}, err
+	}
+
+	for i := range offsetDeltas {
+		offsetDeltas[i] = -offsetDeltas[i]
+	}
+	retT, err = translate(retT, offsetDeltas)
+	if err != nil {
+		return geo.Geometry{}, err
+	}
+
+	return geo.MakeGeometryFromGeomT(retT)
+}
+
+// Rotate returns a modified Geometry whose coordinates are rotated
+// around the origin by a rotation angle.
+func Rotate(g geo.Geometry, rotRadians float64) (geo.Geometry, error) {
+	return Affine(
+		g,
+		AffineMatrix([][]float64{
+			{math.Cos(rotRadians), -math.Sin(rotRadians), 0, 0},
+			{math.Sin(rotRadians), math.Cos(rotRadians), 0, 0},
+			{0, 0, 1, 0},
+			{0, 0, 0, 1},
+		}),
+	)
+}
+
+// ErrPointOriginEmpty is an error to compare point origin is empty.
+var ErrPointOriginEmpty = pgerror.Newf(pgcode.InvalidParameterValue, "origin is an empty point")
+
+// RotateWithPointOrigin returns a modified Geometry whose coordinates are rotated
+// around the pointOrigin by a rotRadians.
+func RotateWithPointOrigin(
+	g geo.Geometry, rotRadians float64, pointOrigin geo.Geometry,
+) (geo.Geometry, error) {
+	if pointOrigin.ShapeType() != geopb.ShapeType_Point {
+		return g, pgerror.Newf(pgcode.InvalidParameterValue, "origin is not a POINT")
+	}
+	t, err := pointOrigin.AsGeomT()
+	if err != nil {
+		return g, err
+	}
+	if t.Empty() {
+		return g, ErrPointOriginEmpty
+	}
+
+	return RotateWithXY(g, rotRadians, t.FlatCoords()[0], t.FlatCoords()[1])
+}
+
+// RotateWithXY returns a modified Geometry whose coordinates are rotated
+// around the X and Y by a rotRadians.
+func RotateWithXY(g geo.Geometry, rotRadians, x, y float64) (geo.Geometry, error) {
+	cos, sin := math.Cos(rotRadians), math.Sin(rotRadians)
+	return Affine(
+		g,
+		AffineMatrix{
+			{cos, -sin, 0, x - x*cos + y*sin},
+			{sin, cos, 0, y - x*sin - y*cos},
+			{0, 0, 1, 0},
+			{0, 0, 0, 1},
+		},
+	)
+}
+
+// RotateX returns a modified Geometry whose coordinates are rotated about
+// the X axis by rotRadians
+func RotateX(g geo.Geometry, rotRadians float64) (geo.Geometry, error) {
+	cos, sin := math.Cos(rotRadians), math.Sin(rotRadians)
+	return Affine(
+		g,
+		AffineMatrix{
+			{1, 0, 0, 0},
+			{0, cos, -sin, 0},
+			{0, sin, cos, 0},
+			{0, 0, 0, 1},
+		},
+	)
+}
+
+// RotateY returns a modified Geometry whose coordinates are rotated about
+// the Y axis by rotRadians
+func RotateY(g geo.Geometry, rotRadians float64) (geo.Geometry, error) {
+	cos, sin := math.Cos(rotRadians), math.Sin(rotRadians)
+	return Affine(
+		g,
+		AffineMatrix{
+			{cos, 0, sin, 0},
+			{0, 1, 0, 0},
+			{-sin, 0, cos, 0},
+			{0, 0, 0, 1},
+		},
+	)
+}
+
+// RotateZ returns a modified Geometry whose coordinates are rotated about
+// the Z axis by rotRadians
+func RotateZ(g geo.Geometry, rotRadians float64) (geo.Geometry, error) {
+	cos, sin := math.Cos(rotRadians), math.Sin(rotRadians)
+	return Affine(
+		g,
+		AffineMatrix{
+			{cos, -sin, 0, 0},
+			{sin, cos, 0, 0},
+			{0, 0, 1, 0},
+			{0, 0, 0, 1},
+		},
+	)
+}
+
+// TransScale returns a modified Geometry whose coordinates are
+// translate by deltaX and deltaY and scale by xFactor and yFactor
+func TransScale(g geo.Geometry, deltaX, deltaY, xFactor, yFactor float64) (geo.Geometry, error) {
+	return Affine(g,
+		AffineMatrix([][]float64{
+			{xFactor, 0, 0, xFactor * deltaX},
+			{0, yFactor, 0, yFactor * deltaY},
+			{0, 0, 1, 0},
+			{0, 0, 0, 1},
+		}))
+}
diff --git a/pkg/geo/geomfn/angle.go b/pkg/geo/geomfn/angle.go
new file mode 100644
index 0000000..1b230ce
--- /dev/null
+++ b/pkg/geo/geomfn/angle.go
@@ -0,0 +1,116 @@
+// Copyright 2020 The Cockroach Authors.
+//
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
+
+package geomfn
+
+import (
+	"math"
+
+	"github.com/cockroachdb/cockroachdb-parser/pkg/geo"
+	"github.com/cockroachdb/cockroachdb-parser/pkg/sql/pgwire/pgcode"
+	"github.com/cockroachdb/cockroachdb-parser/pkg/sql/pgwire/pgerror"
+	"github.com/twpayne/go-geom"
+)
+
+// Angle calculates the clockwise angle between two vectors given by points
+// p1,p2 and p3,p4. If p4 is an empty geometry (of any type, to follow PostGIS
+// behavior), it instead calculates the clockwise angle between p2,p1 and p2,p3.
+func Angle(g1, g2, g3, g4 geo.Geometry) (*float64, error) {
+	if g4.Empty() {
+		g1, g2, g3, g4 = g2, g1, g2, g3
+	}
+
+	if g1.SRID() != g2.SRID() {
+		return nil, geo.NewMismatchingSRIDsError(g1.SpatialObject(), g2.SpatialObject())
+	}
+	if g1.SRID() != g3.SRID() {
+		return nil, geo.NewMismatchingSRIDsError(g1.SpatialObject(), g3.SpatialObject())
+	}
+	if g1.SRID() != g4.SRID() {
+		return nil, geo.NewMismatchingSRIDsError(g1.SpatialObject(), g4.SpatialObject())
+	}
+
+	t1, err := g1.AsGeomT()
+	if err != nil {
+		return nil, err
+	}
+	t2, err := g2.AsGeomT()
+	if err != nil {
+		return nil, err
+	}
+	t3, err := g3.AsGeomT()
+	if err != nil {
+		return nil, err
+	}
+	t4, err := g4.AsGeomT()
+	if err != nil {
+		return nil, err
+	}
+
+	p1, p1ok := t1.(*geom.Point)
+	p2, p2ok := t2.(*geom.Point)
+	p3, p3ok := t3.(*geom.Point)
+	p4, p4ok := t4.(*geom.Point)
+
+	if !p1ok || !p2ok || !p3ok || !p4ok {
+		return nil, pgerror.Newf(pgcode.InvalidParameterValue, "arguments must be POINT geometries")
+	}
+	if p1.Empty() || p2.Empty() || p3.Empty() || p4.Empty() {
+		return nil, pgerror.Newf(pgcode.InvalidParameterValue, "received EMPTY geometry")
+	}
+
+	return angleFromCoords(p1.Coords(), p2.Coords(), p3.Coords(), p4.Coords()), nil
+}
+
+// AngleLineString calculates the clockwise angle between two linestrings,
+// treating them as vectors between the start- and endpoints. Type conflicts
+// or empty geometries return nil (as opposed to Angle which errors), to
+// follow PostGIS behavior.
+func AngleLineString(g1, g2 geo.Geometry) (*float64, error) {
+	if g1.SRID() != g2.SRID() {
+		return nil, geo.NewMismatchingSRIDsError(g1.SpatialObject(), g2.SpatialObject())
+	}
+	t1, err := g1.AsGeomT()
+	if err != nil {
+		return nil, err
+	}
+	t2, err := g2.AsGeomT()
+	if err != nil {
+		return nil, err
+	}
+	l1, l1ok := t1.(*geom.LineString)
+	l2, l2ok := t2.(*geom.LineString)
+	if !l1ok || !l2ok || l1.Empty() || l2.Empty() {
+		return nil, nil // follow PostGIS behavior
+	}
+	return angleFromCoords(
+		l1.Coord(0), l1.Coord(l1.NumCoords()-1), l2.Coord(0), l2.Coord(l2.NumCoords()-1)), nil
+}
+
+// angleFromCoords returns the clockwise angle between the vectors c1,c2 and
+// c3,c4. For compatibility with PostGIS, it returns nil if any vectors have
+// length 0.
+func angleFromCoords(c1, c2, c3, c4 geom.Coord) *float64 {
+	a := coordSub(c2, c1)
+	b := coordSub(c4, c3)
+	if (a.X() == 0 && a.Y() == 0) || (b.X() == 0 && b.Y() == 0) {
+		return nil
+	}
+	// We want the clockwise angle, not the smallest interior angle, so can't use cosine formula.
+	angle := math.Atan2(-coordDet(a, b), coordDot(a, b))
+	// We want the angle in the interval [0,2π), while Atan2 returns [-π,π]
+	//
+	// NB: In Go, the literal -0.0 does not produce negative
+	// zero. However, since IEEE 754 requires that -0.0 == 0.0,
+	// this code is still correct and we use -0.0 here for
+	// semantic clarity.
+	//lint:ignore SA4026 -0.0 used here for clarity
+	if angle == -0.0 {
+		angle = 0.0
+	} else if angle < 0 {
+		angle += 2 * math.Pi
+	}
+	return &angle
+}
diff --git a/pkg/geo/geomfn/azimuth.go b/pkg/geo/geomfn/azimuth.go
new file mode 100644
index 0000000..a8ea6b3
--- /dev/null
+++ b/pkg/geo/geomfn/azimuth.go
@@ -0,0 +1,63 @@
+// Copyright 2020 The Cockroach Authors.
+//
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
+
+package geomfn
+
+import (
+	"math"
+
+	"github.com/cockroachdb/cockroachdb-parser/pkg/geo"
+	"github.com/cockroachdb/cockroachdb-parser/pkg/sql/pgwire/pgcode"
+	"github.com/cockroachdb/cockroachdb-parser/pkg/sql/pgwire/pgerror"
+	"github.com/twpayne/go-geom"
+)
+
+// Azimuth returns the azimuth in radians of the segment defined by the given point geometries,
+// where point a is the reference point.
+// The reference direction from which the azimuth is calculated is north, and is positive clockwise.
+// i.e. North = 0; East = π/2; South = π; West = 3π/2.
+// See https://en.wikipedia.org/wiki/Polar_coordinate_system.
+// Returns nil if the two points are the same.
+// Returns an error if any of the two Geometry items are not points.
+func Azimuth(a geo.Geometry, b geo.Geometry) (*float64, error) {
+	if a.SRID() != b.SRID() {
+		return nil, geo.NewMismatchingSRIDsError(a.SpatialObject(), b.SpatialObject())
+	}
+
+	aGeomT, err := a.AsGeomT()
+	if err != nil {
+		return nil, err
+	}
+
+	aPoint, ok := aGeomT.(*geom.Point)
+	if !ok {
+		return nil, pgerror.Newf(pgcode.InvalidParameterValue, "arguments must be POINT geometries")
+	}
+
+	bGeomT, err := b.AsGeomT()
+	if err != nil {
+		return nil, err
+	}
+
+	bPoint, ok := bGeomT.(*geom.Point)
+	if !ok {
+		return nil, pgerror.Newf(pgcode.InvalidParameterValue, "arguments must be POINT geometries")
+	}
+
+	if aPoint.Empty() || bPoint.Empty() {
+		return nil, pgerror.Newf(pgcode.InvalidParameterValue, "cannot call ST_Azimuth with POINT EMPTY")
+	}
+
+	if aPoint.X() == bPoint.X() && aPoint.Y() == bPoint.Y() {
+		return nil, nil
+	}
+
+	atan := math.Atan2(bPoint.Y()-aPoint.Y(), bPoint.X()-aPoint.X())
+	// math.Pi / 2 is North from the atan calculation this is a CCW direction.
+	// We want to return a CW direction, so subtract atan from math.Pi / 2 to get it into a CW direction.
+	// Then add 2*math.Pi to ensure a positive azimuth.
+	azimuth := math.Mod(math.Pi/2-atan+2*math.Pi, 2*math.Pi)
+	return &azimuth, nil
+}
diff --git a/pkg/geo/geomfn/bench.sh b/pkg/geo/geomfn/bench.sh
new file mode 100755
index 0000000..c1bf87c
--- /dev/null
+++ b/pkg/geo/geomfn/bench.sh
@@ -0,0 +1,23 @@
+#!/bin/sh
+
+# Copyright 2021 The Cockroach Authors.
+#
+# Use of this software is governed by the CockroachDB Software License
+# included in the /LICENSE file.
+
+set -eux
+
+if [ $# -eq 0 ] || [ "$1" == "" ]; then
+  echo "Usage: ./bench.sh [output-name]"
+  exit 1
+fi
+
+echo "output file: $1.txt"
+
+for i in {1..10}
+do
+  go test -bench=. >> $1.txt.tmp
+done
+
+sed -n '/^Benchmark/p' $1.txt.tmp > $1.txt
+rm $1.txt.tmp
diff --git a/pkg/geo/geomfn/binary_predicates.go b/pkg/geo/geomfn/binary_predicates.go
new file mode 100644
index 0000000..36b00d1
--- /dev/null
+++ b/pkg/geo/geomfn/binary_predicates.go
@@ -0,0 +1,337 @@
+// Copyright 2020 The Cockroach Authors.
+//
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
+
+package geomfn
+
+import (
+	"github.com/cockroachdb/cockroachdb-parser/pkg/geo"
+	"github.com/cockroachdb/cockroachdb-parser/pkg/geo/geopb"
+	"github.com/cockroachdb/cockroachdb-parser/pkg/geo/geos"
+	"github.com/cockroachdb/errors"
+	"github.com/twpayne/go-geom"
+)
+
+// Covers returns whether geometry A covers geometry B.
+func Covers(a geo.Geometry, b geo.Geometry) (bool, error) {
+	if a.SRID() != b.SRID() {
+		return false, geo.NewMismatchingSRIDsError(a.SpatialObject(), b.SpatialObject())
+	}
+	if !a.CartesianBoundingBox().Covers(b.CartesianBoundingBox()) {
+		return false, nil
+	}
+
+	// Optimization for point in polygon calculations.
+	pointPolygonPair, pointKind, polygonKind := PointKindAndPolygonKind(a, b)
+	switch pointPolygonPair {
+	case PointAndPolygon:
+		// A point cannot cover a polygon.
+		return false, nil
+	case PolygonAndPoint:
+		// Computing whether a polygon covers a point is equivalent
+		// to computing whether the point is covered by the polygon.
+		return PointKindCoveredByPolygonKind(pointKind, polygonKind)
+	}
+
+	return geos.Covers(a.EWKB(), b.EWKB())
+}
+
+// CoveredBy returns whether geometry A is covered by geometry B.
+func CoveredBy(a geo.Geometry, b geo.Geometry) (bool, error) {
+	if a.SRID() != b.SRID() {
+		return false, geo.NewMismatchingSRIDsError(a.SpatialObject(), b.SpatialObject())
+	}
+	if !b.CartesianBoundingBox().Covers(a.CartesianBoundingBox()) {
+		return false, nil
+	}
+
+	// Optimization for point in polygon calculations.
+	pointPolygonPair, pointKind, polygonKind := PointKindAndPolygonKind(a, b)
+	switch pointPolygonPair {
+	case PolygonAndPoint:
+		// A polygon cannot be covered by a point.
+		return false, nil
+	case PointAndPolygon:
+		return PointKindCoveredByPolygonKind(pointKind, polygonKind)
+	}
+
+	return geos.CoveredBy(a.EWKB(), b.EWKB())
+}
+
+// Contains returns whether geometry A contains geometry B.
+func Contains(a geo.Geometry, b geo.Geometry) (bool, error) {
+	if a.SRID() != b.SRID() {
+		return false, geo.NewMismatchingSRIDsError(a.SpatialObject(), b.SpatialObject())
+	}
+	if !a.CartesianBoundingBox().Covers(b.CartesianBoundingBox()) {
+		return false, nil
+	}
+
+	// Optimization for point in polygon calculations.
+	pointPolygonPair, pointKind, polygonKind := PointKindAndPolygonKind(a, b)
+	switch pointPolygonPair {
+	case PointAndPolygon:
+		// A point cannot contain a polygon.
+		return false, nil
+	case PolygonAndPoint:
+		// Computing whether a polygon contains a point is equivalent
+		// to computing whether the point is contained within the polygon.
+		return PointKindWithinPolygonKind(pointKind, polygonKind)
+	}
+
+	return geos.Contains(a.EWKB(), b.EWKB())
+}
+
+// ContainsProperly returns whether geometry A properly contains geometry B.
+func ContainsProperly(a geo.Geometry, b geo.Geometry) (bool, error) {
+	if a.SRID() != b.SRID() {
+		return false, geo.NewMismatchingSRIDsError(a.SpatialObject(), b.SpatialObject())
+	}
+	if !a.CartesianBoundingBox().Covers(b.CartesianBoundingBox()) {
+		return false, nil
+	}
+	return geos.RelatePattern(a.EWKB(), b.EWKB(), "T**FF*FF*")
+}
+
+// Crosses returns whether geometry A crosses geometry B.
+func Crosses(a geo.Geometry, b geo.Geometry) (bool, error) {
+	if a.SRID() != b.SRID() {
+		return false, geo.NewMismatchingSRIDsError(a.SpatialObject(), b.SpatialObject())
+	}
+	if !a.CartesianBoundingBox().Intersects(b.CartesianBoundingBox()) {
+		return false, nil
+	}
+	return geos.Crosses(a.EWKB(), b.EWKB())
+}
+
+// Disjoint returns whether geometry A is disjoint from geometry B.
+func Disjoint(a geo.Geometry, b geo.Geometry) (bool, error) {
+	if a.SRID() != b.SRID() {
+		return false, geo.NewMismatchingSRIDsError(a.SpatialObject(), b.SpatialObject())
+	}
+	return geos.Disjoint(a.EWKB(), b.EWKB())
+}
+
+// Equals returns whether geometry A equals geometry B.
+func Equals(a geo.Geometry, b geo.Geometry) (bool, error) {
+	if a.SRID() != b.SRID() {
+		return false, geo.NewMismatchingSRIDsError(a.SpatialObject(), b.SpatialObject())
+	}
+	// Empty items are equal to each other.
+	// Do this check before the BoundingBoxIntersects check, as we would otherwise
+	// return false.
+	if a.Empty() && b.Empty() {
+		return true, nil
+	}
+	if !a.CartesianBoundingBox().Covers(b.CartesianBoundingBox()) {
+		return false, nil
+	}
+	return geos.Equals(a.EWKB(), b.EWKB())
+}
+
+// Intersects returns whether geometry A intersects geometry B.
+func Intersects(a geo.Geometry, b geo.Geometry) (bool, error) {
+	if a.SRID() != b.SRID() {
+		return false, geo.NewMismatchingSRIDsError(a.SpatialObject(), b.SpatialObject())
+	}
+	if !a.CartesianBoundingBox().Intersects(b.CartesianBoundingBox()) {
+		return false, nil
+	}
+
+	// Optimization for point in polygon calculations.
+	pointPolygonPair, pointKind, polygonKind := PointKindAndPolygonKind(a, b)
+	switch pointPolygonPair {
+	case PointAndPolygon, PolygonAndPoint:
+		return PointKindIntersectsPolygonKind(pointKind, polygonKind)
+	}
+
+	return geos.Intersects(a.EWKB(), b.EWKB())
+}
+
+// OrderingEquals returns whether geometry A is equal to B, with all constituents
+// and coordinates in the same order.
+func OrderingEquals(a, b geo.Geometry) (bool, error) {
+	if a.SRID() != b.SRID() {
+		return false, nil
+	}
+	aBox, bBox := a.CartesianBoundingBox(), b.CartesianBoundingBox()
+	switch {
+	case aBox == nil && bBox == nil:
+	case aBox == nil || bBox == nil:
+		return false, nil
+	case aBox.Compare(bBox) != 0:
+		return false, nil
+	}
+
+	geomA, err := a.AsGeomT()
+	if err != nil {
+		return false, err
+	}
+	geomB, err := b.AsGeomT()
+	if err != nil {
+		return false, err
+	}
+	return orderingEqualsFromGeomT(geomA, geomB)
+}
+
+// orderingEqualsFromGeomT returns whether geometry A is equal to B.
+func orderingEqualsFromGeomT(a, b geom.T) (bool, error) {
+	if a.Layout() != b.Layout() {
+		return false, nil
+	}
+	switch a := a.(type) {
+	case *geom.Point:
+		if b, ok := b.(*geom.Point); ok {
+			// Point.Coords() panics on empty points
+			switch {
+			case a.Empty() && b.Empty():
+				return true, nil
+			case a.Empty() || b.Empty():
+				return false, nil
+			default:
+				return a.Coords().Equal(b.Layout(), b.Coords()), nil
+			}
+		}
+	case *geom.LineString:
+		if b, ok := b.(*geom.LineString); ok && a.NumCoords() == b.NumCoords() {
+			for i := 0; i < a.NumCoords(); i++ {
+				if !a.Coord(i).Equal(b.Layout(), b.Coord(i)) {
+					return false, nil
+				}
+			}
+			return true, nil
+		}
+	case *geom.Polygon:
+		if b, ok := b.(*geom.Polygon); ok && a.NumLinearRings() == b.NumLinearRings() {
+			for i := 0; i < a.NumLinearRings(); i++ {
+				for j := 0; j < a.LinearRing(i).NumCoords(); j++ {
+					if !a.LinearRing(i).Coord(j).Equal(b.Layout(), b.LinearRing(i).Coord(j)) {
+						return false, nil
+					}
+				}
+			}
+			return true, nil
+		}
+	case *geom.MultiPoint:
+		if b, ok := b.(*geom.MultiPoint); ok && a.NumPoints() == b.NumPoints() {
+			for i := 0; i < a.NumPoints(); i++ {
+				if eq, err := orderingEqualsFromGeomT(a.Point(i), b.Point(i)); err != nil || !eq {
+					return false, err
+				}
+			}
+			return true, nil
+		}
+	case *geom.MultiLineString:
+		if b, ok := b.(*geom.MultiLineString); ok && a.NumLineStrings() == b.NumLineStrings() {
+			for i := 0; i < a.NumLineStrings(); i++ {
+				if eq, err := orderingEqualsFromGeomT(a.LineString(i), b.LineString(i)); err != nil || !eq {
+					return false, err
+				}
+			}
+			return true, nil
+		}
+	case *geom.MultiPolygon:
+		if b, ok := b.(*geom.MultiPolygon); ok && a.NumPolygons() == b.NumPolygons() {
+			for i := 0; i < a.NumPolygons(); i++ {
+				if eq, err := orderingEqualsFromGeomT(a.Polygon(i), b.Polygon(i)); err != nil || !eq {
+					return false, err
+				}
+			}
+			return true, nil
+		}
+	case *geom.GeometryCollection:
+		if b, ok := b.(*geom.GeometryCollection); ok && a.NumGeoms() == b.NumGeoms() {
+			for i := 0; i < a.NumGeoms(); i++ {
+				if eq, err := orderingEqualsFromGeomT(a.Geom(i), b.Geom(i)); err != nil || !eq {
+					return false, err
+				}
+			}
+			return true, nil
+		}
+	default:
+		return false, errors.AssertionFailedf("unknown geometry type: %T", a)
+	}
+	return false, nil
+}
+
+// Overlaps returns whether geometry A overlaps geometry B.
+func Overlaps(a geo.Geometry, b geo.Geometry) (bool, error) {
+	if a.SRID() != b.SRID() {
+		return false, geo.NewMismatchingSRIDsError(a.SpatialObject(), b.SpatialObject())
+	}
+	if !a.CartesianBoundingBox().Intersects(b.CartesianBoundingBox()) {
+		return false, nil
+	}
+	return geos.Overlaps(a.EWKB(), b.EWKB())
+}
+
+// PointPolygonOrder represents the order of a point and a polygon
+// in an ordered pair of geometries.
+type PointPolygonOrder int
+
+const (
+	// NotPointAndPolygon signifies that a pair of geometries is
+	// not a point and a polygon.
+	NotPointAndPolygon PointPolygonOrder = iota
+	// PointAndPolygon signifies that the point appears first
+	// in an ordered pair of a point and a polygon.
+	PointAndPolygon
+	// PolygonAndPoint signifies that the polygon appears first
+	// in an ordered pair of a point and a polygon.
+	PolygonAndPoint
+)
+
+// PointKindAndPolygonKind returns whether a pair of geometries contains
+// a (multi)point and a (multi)polygon. It is used to determine if the
+// point in polygon optimization can be applied.
+func PointKindAndPolygonKind(
+	a geo.Geometry, b geo.Geometry,
+) (PointPolygonOrder, geo.Geometry, geo.Geometry) {
+	switch a.ShapeType2D() {
+	case geopb.ShapeType_Point, geopb.ShapeType_MultiPoint:
+		switch b.ShapeType2D() {
+		case geopb.ShapeType_Polygon, geopb.ShapeType_MultiPolygon:
+			return PointAndPolygon, a, b
+		}
+	case geopb.ShapeType_Polygon, geopb.ShapeType_MultiPolygon:
+		switch b.ShapeType2D() {
+		case geopb.ShapeType_Point, geopb.ShapeType_MultiPoint:
+			return PolygonAndPoint, b, a
+		}
+	}
+	return NotPointAndPolygon, a, b
+}
+
+// Touches returns whether geometry A touches geometry B.
+func Touches(a geo.Geometry, b geo.Geometry) (bool, error) {
+	if a.SRID() != b.SRID() {
+		return false, geo.NewMismatchingSRIDsError(a.SpatialObject(), b.SpatialObject())
+	}
+	if !a.CartesianBoundingBox().Intersects(b.CartesianBoundingBox()) {
+		return false, nil
+	}
+	return geos.Touches(a.EWKB(), b.EWKB())
+}
+
+// Within returns whether geometry A is within geometry B.
+func Within(a geo.Geometry, b geo.Geometry) (bool, error) {
+	if a.SRID() != b.SRID() {
+		return false, geo.NewMismatchingSRIDsError(a.SpatialObject(), b.SpatialObject())
+	}
+	if !b.CartesianBoundingBox().Covers(a.CartesianBoundingBox()) {
+		return false, nil
+	}
+
+	// Optimization for point in polygon calculations.
+	pointPolygonPair, pointKind, polygonKind := PointKindAndPolygonKind(a, b)
+	switch pointPolygonPair {
+	case PolygonAndPoint:
+		// A polygon cannot be contained within a point.
+		return false, nil
+	case PointAndPolygon:
+		return PointKindWithinPolygonKind(pointKind, polygonKind)
+	}
+
+	return geos.Within(a.EWKB(), b.EWKB())
+}
diff --git a/pkg/geo/geomfn/buffer.go b/pkg/geo/geomfn/buffer.go
new file mode 100644
index 0000000..20e77be
--- /dev/null
+++ b/pkg/geo/geomfn/buffer.go
@@ -0,0 +1,148 @@
+// Copyright 2020 The Cockroach Authors.
+//
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
+
+package geomfn
+
+import (
+	"strconv"
+	"strings"
+
+	"github.com/cockroachdb/cockroachdb-parser/pkg/geo"
+	"github.com/cockroachdb/cockroachdb-parser/pkg/geo/geos"
+	"github.com/cockroachdb/cockroachdb-parser/pkg/sql/pgwire/pgcode"
+	"github.com/cockroachdb/cockroachdb-parser/pkg/sql/pgwire/pgerror"
+	"github.com/cockroachdb/errors"
+)
+
+// BufferParams is a wrapper around the geos.BufferParams.
+type BufferParams struct {
+	p geos.BufferParams
+}
+
+// MakeDefaultBufferParams returns the default BufferParams/
+func MakeDefaultBufferParams() BufferParams {
+	return BufferParams{
+		p: geos.BufferParams{
+			EndCapStyle:      geos.BufferParamsEndCapStyleRound,
+			JoinStyle:        geos.BufferParamsJoinStyleRound,
+			SingleSided:      false,
+			QuadrantSegments: 8,
+			MitreLimit:       5.0,
+		},
+	}
+}
+
+// WithQuadrantSegments returns a copy of the BufferParams with the quadrantSegments set.
+func (b BufferParams) WithQuadrantSegments(quadrantSegments int) BufferParams {
+	ret := b
+	ret.p.QuadrantSegments = quadrantSegments
+	return ret
+}
+
+// ParseBufferParams parses the given buffer params from a SQL string into
+// the BufferParams form.
+// The string must be of the same format as specified by https://postgis.net/docs/ST_Buffer.html.
+// Returns the BufferParams, as well as the modified distance.
+func ParseBufferParams(s string, distance float64) (BufferParams, float64, error) {
+	p := MakeDefaultBufferParams()
+	fields := strings.Fields(s)
+	for _, field := range fields {
+		fParams := strings.Split(field, "=")
+		if len(fParams) != 2 {
+			return BufferParams{}, 0, pgerror.Newf(pgcode.InvalidParameterValue, "unknown buffer parameter: %s", fParams)
+		}
+		f, val := fParams[0], fParams[1]
+		switch strings.ToLower(f) {
+		case "quad_segs":
+			valInt, err := strconv.ParseInt(val, 10, 64)
+			if err != nil {
+				return BufferParams{}, 0, pgerror.WithCandidateCode(
+					errors.Wrapf(err, "invalid int for %s: %s", f, val),
+					pgcode.InvalidParameterValue,
+				)
+			}
+			p.p.QuadrantSegments = int(valInt)
+		case "endcap":
+			switch strings.ToLower(val) {
+			case "round":
+				p.p.EndCapStyle = geos.BufferParamsEndCapStyleRound
+			case "flat", "butt":
+				p.p.EndCapStyle = geos.BufferParamsEndCapStyleFlat
+			case "square":
+				p.p.EndCapStyle = geos.BufferParamsEndCapStyleSquare
+			default:
+				return BufferParams{}, 0, pgerror.Newf(
+					pgcode.InvalidParameterValue,
+					"unknown endcap: %s (accepted: round, flat, square)",
+					val,
+				)
+			}
+		case "join":
+			switch strings.ToLower(val) {
+			case "round":
+				p.p.JoinStyle = geos.BufferParamsJoinStyleRound
+			case "mitre", "miter":
+				p.p.JoinStyle = geos.BufferParamsJoinStyleMitre
+			case "bevel":
+				p.p.JoinStyle = geos.BufferParamsJoinStyleBevel
+			default:
+				return BufferParams{}, 0, pgerror.Newf(
+					pgcode.InvalidParameterValue,
+					"unknown join: %s (accepted: round, mitre, bevel)",
+					val,
+				)
+			}
+		case "mitre_limit", "miter_limit":
+			valFloat, err := strconv.ParseFloat(val, 64)
+			if err != nil {
+				return BufferParams{}, 0, pgerror.WithCandidateCode(
+					errors.Wrapf(err, "invalid float for %s: %s", f, val),
+					pgcode.InvalidParameterValue,
+				)
+			}
+			p.p.MitreLimit = valFloat
+		case "side":
+			switch strings.ToLower(val) {
+			case "both":
+				p.p.SingleSided = false
+			case "left":
+				p.p.SingleSided = true
+			case "right":
+				p.p.SingleSided = true
+				distance *= -1
+			default:
+				return BufferParams{}, 0, pgerror.Newf(pgcode.InvalidParameterValue, "unknown side: %s (accepted: both, left, right)", val)
+			}
+		default:
+			return BufferParams{}, 0, pgerror.Newf(pgcode.InvalidParameterValue, "unknown field: %s (accepted fields: quad_segs, endcap, join, mitre_limit, side)", f)
+		}
+	}
+	return p, distance, nil
+}
+
+// Buffer buffers a given Geometry by the supplied parameters.
+func Buffer(g geo.Geometry, params BufferParams, distance float64) (geo.Geometry, error) {
+	if params.p.QuadrantSegments < 1 {
+		return geo.Geometry{}, pgerror.Newf(
+			pgcode.InvalidParameterValue,
+			"must request at least 1 quadrant segment, requested %d quadrant segments",
+			params.p.QuadrantSegments,
+		)
+
+	}
+	if params.p.QuadrantSegments > geo.MaxAllowedSplitPoints {
+		return geo.Geometry{}, pgerror.Newf(
+			pgcode.InvalidParameterValue,
+			"attempting to split buffered geometry into too many quadrant segments; requested %d quadrant segments, max %d",
+			params.p.QuadrantSegments,
+			geo.MaxAllowedSplitPoints,
+		)
+	}
+	bufferedGeom, err := geos.Buffer(g.EWKB(), params.p, distance)
+	if err != nil {
+		return geo.Geometry{}, err
+	}
+	return geo.ParseGeometryFromEWKB(bufferedGeom)
+}
diff --git a/pkg/geo/geomfn/collections.go b/pkg/geo/geomfn/collections.go
new file mode 100644
index 0000000..021cb7b
--- /dev/null
+++ b/pkg/geo/geomfn/collections.go
@@ -0,0 +1,433 @@
+// Copyright 2020 The Cockroach Authors.
+//
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
+
+package geomfn
+
+import (
+	"github.com/cockroachdb/cockroachdb-parser/pkg/geo"
+	"github.com/cockroachdb/cockroachdb-parser/pkg/geo/geopb"
+	"github.com/cockroachdb/cockroachdb-parser/pkg/sql/pgwire/pgcode"
+	"github.com/cockroachdb/cockroachdb-parser/pkg/sql/pgwire/pgerror"
+	"github.com/cockroachdb/errors"
+	"github.com/twpayne/go-geom"
+)
+
+// Collect collects two geometries into a GeometryCollection or multi-type.
+//
+// This is the binary version of `ST_Collect()`, but since it's not possible to
+// have an aggregate and non-aggregate function with the same name (different
+// args), this is not used. Code is left behind for when we add support for
+// this. Be sure to handle NULL args when adding the builtin for this, where it
+// should return the non-NULL arg unused like PostGIS.
+func Collect(g1 geo.Geometry, g2 geo.Geometry) (geo.Geometry, error) {
+	t1, err := g1.AsGeomT()
+	if err != nil {
+		return geo.Geometry{}, err
+	}
+	t2, err := g2.AsGeomT()
+	if err != nil {
+		return geo.Geometry{}, err
+	}
+
+	// First, try to generate multi-types
+	switch t1 := t1.(type) {
+	case *geom.Point:
+		if t2, ok := t2.(*geom.Point); ok {
+			multi := geom.NewMultiPoint(t1.Layout()).SetSRID(t1.SRID())
+			if err := multi.Push(t1); err != nil {
+				return geo.Geometry{}, err
+			}
+			if err := multi.Push(t2); err != nil {
+				return geo.Geometry{}, err
+			}
+			return geo.MakeGeometryFromGeomT(multi)
+		}
+	case *geom.LineString:
+		if t2, ok := t2.(*geom.LineString); ok {
+			multi := geom.NewMultiLineString(t1.Layout()).SetSRID(t1.SRID())
+			if err := multi.Push(t1); err != nil {
+				return geo.Geometry{}, err
+			}
+			if err := multi.Push(t2); err != nil {
+				return geo.Geometry{}, err
+			}
+			return geo.MakeGeometryFromGeomT(multi)
+		}
+	case *geom.Polygon:
+		if t2, ok := t2.(*geom.Polygon); ok {
+			multi := geom.NewMultiPolygon(t1.Layout()).SetSRID(t1.SRID())
+			if err := multi.Push(t1); err != nil {
+				return geo.Geometry{}, err
+			}
+			if err := multi.Push(t2); err != nil {
+				return geo.Geometry{}, err
+			}
+			return geo.MakeGeometryFromGeomT(multi)
+		}
+	}
+
+	// Otherwise, just put them in a collection
+	gc := geom.NewGeometryCollection().SetSRID(t1.SRID())
+	if err := gc.Push(t1); err != nil {
+		return geo.Geometry{}, err
+	}
+	if err := gc.Push(t2); err != nil {
+		return geo.Geometry{}, err
+	}
+	return geo.MakeGeometryFromGeomT(gc)
+}
+
+// CollectionExtract returns a (multi-)geometry consisting only of the specified type.
+// The type can only be point, line, or polygon.
+func CollectionExtract(g geo.Geometry, shapeType geopb.ShapeType) (geo.Geometry, error) {
+	switch shapeType {
+	case geopb.ShapeType_Point, geopb.ShapeType_LineString, geopb.ShapeType_Polygon:
+	default:
+		return geo.Geometry{}, pgerror.Newf(
+			pgcode.InvalidParameterValue,
+			"only point, linestring and polygon may be extracted (got %s)",
+			shapeType,
+		)
+	}
+
+	// If the input is already of the correct (multi-)type, just return it before
+	// decoding the geom.T below.
+	if g.ShapeType() == shapeType || g.ShapeType() == shapeType.MultiType() {
+		return g, nil
+	}
+
+	t, err := g.AsGeomT()
+	if err != nil {
+		return geo.Geometry{}, err
+	}
+
+	switch t := t.(type) {
+	// If the input is not a collection then return an empty geometry of the expected type.
+	case *geom.Point, *geom.LineString, *geom.Polygon:
+		switch shapeType {
+		case geopb.ShapeType_Point:
+			return geo.MakeGeometryFromGeomT(geom.NewPointEmpty(t.Layout()).SetSRID(t.SRID()))
+		case geopb.ShapeType_LineString:
+			return geo.MakeGeometryFromGeomT(geom.NewLineString(t.Layout()).SetSRID(t.SRID()))
+		case geopb.ShapeType_Polygon:
+			return geo.MakeGeometryFromGeomT(geom.NewPolygon(t.Layout()).SetSRID(t.SRID()))
+		default:
+			return geo.Geometry{}, pgerror.Newf(
+				pgcode.InvalidParameterValue,
+				"unexpected shape type %v",
+				shapeType.String(),
+			)
+		}
+
+	// If the input is a multitype then return an empty multi-geometry of the expected type.
+	case *geom.MultiPoint, *geom.MultiLineString, *geom.MultiPolygon:
+		switch shapeType.MultiType() {
+		case geopb.ShapeType_MultiPoint:
+			return geo.MakeGeometryFromGeomT(geom.NewMultiPoint(t.Layout()).SetSRID(t.SRID()))
+		case geopb.ShapeType_MultiLineString:
+			return geo.MakeGeometryFromGeomT(geom.NewMultiLineString(t.Layout()).SetSRID(t.SRID()))
+		case geopb.ShapeType_MultiPolygon:
+			return geo.MakeGeometryFromGeomT(geom.NewMultiPolygon(t.Layout()).SetSRID(t.SRID()))
+		default:
+			return geo.Geometry{}, pgerror.Newf(
+				pgcode.InvalidParameterValue,
+				"unexpected shape type %v",
+				shapeType.MultiType().String(),
+			)
+		}
+
+	// If the input is a collection, recursively gather geometries of the right type.
+	case *geom.GeometryCollection:
+		// Empty geos.GeometryCollection has NoLayout, while PostGIS uses XY. Returned
+		// multi-geometries cannot have NoLayout.
+		layout := t.Layout()
+		if layout == geom.NoLayout && t.Empty() {
+			layout = geom.XY
+		}
+		iter := geo.NewGeomTIterator(t, geo.EmptyBehaviorOmit)
+		srid := t.SRID()
+
+		var (
+			multi geom.T
+			err   error
+		)
+		switch shapeType {
+		case geopb.ShapeType_Point:
+			multi, err = collectionExtractPoints(iter, layout, srid)
+		case geopb.ShapeType_LineString:
+			multi, err = collectionExtractLineStrings(iter, layout, srid)
+		case geopb.ShapeType_Polygon:
+			multi, err = collectionExtractPolygons(iter, layout, srid)
+		default:
+			return geo.Geometry{}, errors.AssertionFailedf("unexpected shape type %v", shapeType.String())
+		}
+		if err != nil {
+			return geo.Geometry{}, err
+		}
+		return geo.MakeGeometryFromGeomT(multi)
+
+	default:
+		return geo.Geometry{}, errors.AssertionFailedf("unexpected shape type: %T", t)
+	}
+}
+
+// collectionExtractPoints extracts points from an iterator.
+func collectionExtractPoints(
+	iter geo.GeomTIterator, layout geom.Layout, srid int,
+) (*geom.MultiPoint, error) {
+	points := geom.NewMultiPoint(layout).SetSRID(srid)
+	for {
+		if next, hasNext, err := iter.Next(); err != nil {
+			return nil, err
+		} else if !hasNext {
+			break
+		} else if point, ok := next.(*geom.Point); ok {
+			if err = points.Push(point); err != nil {
+				return nil, err
+			}
+		}
+	}
+	return points, nil
+}
+
+// collectionExtractLineStrings extracts line strings from an iterator.
+func collectionExtractLineStrings(
+	iter geo.GeomTIterator, layout geom.Layout, srid int,
+) (*geom.MultiLineString, error) {
+	lineStrings := geom.NewMultiLineString(layout).SetSRID(srid)
+	for {
+		if next, hasNext, err := iter.Next(); err != nil {
+			return nil, err
+		} else if !hasNext {
+			break
+		} else if lineString, ok := next.(*geom.LineString); ok {
+			if err = lineStrings.Push(lineString); err != nil {
+				return nil, err
+			}
+		}
+	}
+	return lineStrings, nil
+}
+
+// collectionExtractPolygons extracts polygons from an iterator.
+func collectionExtractPolygons(
+	iter geo.GeomTIterator, layout geom.Layout, srid int,
+) (*geom.MultiPolygon, error) {
+	polygons := geom.NewMultiPolygon(layout).SetSRID(srid)
+	for {
+		if next, hasNext, err := iter.Next(); err != nil {
+			return nil, err
+		} else if !hasNext {
+			break
+		} else if polygon, ok := next.(*geom.Polygon); ok {
+			if err = polygons.Push(polygon); err != nil {
+				return nil, err
+			}
+		}
+	}
+	return polygons, nil
+}
+
+// CollectionHomogenize returns the simplest representation of a collection.
+func CollectionHomogenize(g geo.Geometry) (geo.Geometry, error) {
+	t, err := g.AsGeomT()
+	if err != nil {
+		return geo.Geometry{}, err
+	}
+	srid := t.SRID()
+	t, err = collectionHomogenizeGeomT(t)
+	if err != nil {
+		return geo.Geometry{}, err
+	}
+	if srid != 0 {
+		geo.AdjustGeomTSRID(t, geopb.SRID(srid))
+	}
+	return geo.MakeGeometryFromGeomT(t)
+}
+
+// collectionHomogenizeGeomT homogenizes a geom.T collection.
+func collectionHomogenizeGeomT(t geom.T) (geom.T, error) {
+	switch t := t.(type) {
+	case *geom.Point, *geom.LineString, *geom.Polygon:
+		return t, nil
+
+	case *geom.MultiPoint:
+		if t.NumPoints() == 1 {
+			return t.Point(0), nil
+		}
+		return t, nil
+
+	case *geom.MultiLineString:
+		if t.NumLineStrings() == 1 {
+			return t.LineString(0), nil
+		}
+		return t, nil
+
+	case *geom.MultiPolygon:
+		if t.NumPolygons() == 1 {
+			return t.Polygon(0), nil
+		}
+		return t, nil
+
+	case *geom.GeometryCollection:
+		layout := t.Layout()
+		if layout == geom.NoLayout && t.Empty() {
+			layout = geom.XY
+		}
+		points := geom.NewMultiPoint(layout)
+		linestrings := geom.NewMultiLineString(layout)
+		polygons := geom.NewMultiPolygon(layout)
+		iter := geo.NewGeomTIterator(t, geo.EmptyBehaviorOmit)
+		for {
+			next, hasNext, err := iter.Next()
+			if err != nil {
+				return nil, err
+			}
+			if !hasNext {
+				break
+			}
+			switch next := next.(type) {
+			case *geom.Point:
+				err = points.Push(next)
+			case *geom.LineString:
+				err = linestrings.Push(next)
+			case *geom.Polygon:
+				err = polygons.Push(next)
+			default:
+				err = errors.AssertionFailedf("encountered unexpected geometry type: %T", next)
+			}
+			if err != nil {
+				return nil, err
+			}
+		}
+		homog := geom.NewGeometryCollection()
+		switch points.NumPoints() {
+		case 0:
+		case 1:
+			if err := homog.Push(points.Point(0)); err != nil {
+				return nil, err
+			}
+		default:
+			if err := homog.Push(points); err != nil {
+				return nil, err
+			}
+		}
+		switch linestrings.NumLineStrings() {
+		case 0:
+		case 1:
+			if err := homog.Push(linestrings.LineString(0)); err != nil {
+				return nil, err
+			}
+		default:
+			if err := homog.Push(linestrings); err != nil {
+				return nil, err
+			}
+		}
+		switch polygons.NumPolygons() {
+		case 0:
+		case 1:
+			if err := homog.Push(polygons.Polygon(0)); err != nil {
+				return nil, err
+			}
+		default:
+			if err := homog.Push(polygons); err != nil {
+				return nil, err
+			}
+		}
+
+		if homog.NumGeoms() == 1 {
+			return homog.Geom(0), nil
+		}
+		return homog, nil
+
+	default:
+		return nil, errors.AssertionFailedf("unknown geometry type: %T", t)
+	}
+}
+
+// ForceCollection converts the input into a GeometryCollection.
+func ForceCollection(g geo.Geometry) (geo.Geometry, error) {
+	t, err := g.AsGeomT()
+	if err != nil {
+		return geo.Geometry{}, err
+	}
+	t, err = forceCollectionFromGeomT(t)
+	if err != nil {
+		return geo.Geometry{}, err
+	}
+	return geo.MakeGeometryFromGeomT(t)
+}
+
+// forceCollectionFromGeomT converts a geom.T into a geom.GeometryCollection.
+func forceCollectionFromGeomT(t geom.T) (geom.T, error) {
+	gc := geom.NewGeometryCollection().SetSRID(t.SRID())
+	switch t := t.(type) {
+	case *geom.Point, *geom.LineString, *geom.Polygon:
+		if err := gc.Push(t); err != nil {
+			return nil, err
+		}
+	case *geom.MultiPoint:
+		for i := 0; i < t.NumPoints(); i++ {
+			if err := gc.Push(t.Point(i)); err != nil {
+				return nil, err
+			}
+		}
+	case *geom.MultiLineString:
+		for i := 0; i < t.NumLineStrings(); i++ {
+			if err := gc.Push(t.LineString(i)); err != nil {
+				return nil, err
+			}
+		}
+	case *geom.MultiPolygon:
+		for i := 0; i < t.NumPolygons(); i++ {
+			if err := gc.Push(t.Polygon(i)); err != nil {
+				return nil, err
+			}
+		}
+	case *geom.GeometryCollection:
+		gc = t
+	default:
+		return nil, errors.AssertionFailedf("unknown geometry type: %T", t)
+	}
+	return gc, nil
+}
+
+// Multi converts the given geometry into a new multi-geometry.
+func Multi(g geo.Geometry) (geo.Geometry, error) {
+	t, err := g.AsGeomT() // implicitly clones the input
+	if err != nil {
+		return geo.Geometry{}, err
+	}
+	switch t := t.(type) {
+	case *geom.MultiPoint, *geom.MultiLineString, *geom.MultiPolygon, *geom.GeometryCollection:
+		return geo.MakeGeometryFromGeomT(t)
+	case *geom.Point:
+		multi := geom.NewMultiPoint(t.Layout()).SetSRID(t.SRID())
+		if !t.Empty() {
+			if err = multi.Push(t); err != nil {
+				return geo.Geometry{}, err
+			}
+		}
+		return geo.MakeGeometryFromGeomT(multi)
+	case *geom.LineString:
+		multi := geom.NewMultiLineString(t.Layout()).SetSRID(t.SRID())
+		if !t.Empty() {
+			if err = multi.Push(t); err != nil {
+				return geo.Geometry{}, err
+			}
+		}
+		return geo.MakeGeometryFromGeomT(multi)
+	case *geom.Polygon:
+		multi := geom.NewMultiPolygon(t.Layout()).SetSRID(t.SRID())
+		if !t.Empty() {
+			if err = multi.Push(t); err != nil {
+				return geo.Geometry{}, err
+			}
+		}
+		return geo.MakeGeometryFromGeomT(multi)
+	default:
+		return geo.Geometry{}, errors.AssertionFailedf("unknown geometry type: %T", t)
+	}
+}
diff --git a/pkg/geo/geomfn/coord.go b/pkg/geo/geomfn/coord.go
new file mode 100644
index 0000000..76d810b
--- /dev/null
+++ b/pkg/geo/geomfn/coord.go
@@ -0,0 +1,62 @@
+// Copyright 2020 The Cockroach Authors.
+//
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
+
+package geomfn
+
+import (
+	"math"
+
+	"github.com/twpayne/go-geom"
+)
+
+// coordAdd adds two coordinates and returns a new result.
+func coordAdd(a geom.Coord, b geom.Coord) geom.Coord {
+	return geom.Coord{a.X() + b.X(), a.Y() + b.Y()}
+}
+
+// coordSub subtracts two coordinates and returns a new result.
+func coordSub(a geom.Coord, b geom.Coord) geom.Coord {
+	return geom.Coord{a.X() - b.X(), a.Y() - b.Y()}
+}
+
+// coordMul multiplies a coord by a scalar and returns the new result.
+func coordMul(a geom.Coord, s float64) geom.Coord {
+	return geom.Coord{a.X() * s, a.Y() * s}
+}
+
+// coordDet returns the determinant of the 2x2 matrix formed by the vectors a and b.
+func coordDet(a geom.Coord, b geom.Coord) float64 {
+	return a.X()*b.Y() - b.X()*a.Y()
+}
+
+// coordDot returns the dot product of two coords if the coord was a vector.
+func coordDot(a geom.Coord, b geom.Coord) float64 {
+	return a.X()*b.X() + a.Y()*b.Y()
+}
+
+// coordCross returns the cross product of two coords if the coord was a vector.
+func coordCross(a geom.Coord, b geom.Coord) float64 {
+	return a.X()*b.Y() - a.Y()*b.X()
+}
+
+// coordNorm2 returns the normalization^2 of a coordinate if the coord was a vector.
+func coordNorm2(c geom.Coord) float64 {
+	return coordDot(c, c)
+}
+
+// coordNorm returns the normalization of a coordinate if the coord was a vector.
+func coordNorm(c geom.Coord) float64 {
+	return math.Sqrt(coordNorm2(c))
+}
+
+// coordEqual returns whether two coordinates are equal.
+func coordEqual(a geom.Coord, b geom.Coord) bool {
+	return a.X() == b.X() && a.Y() == b.Y()
+}
+
+// coordMag2 returns the magnitude^2 of a coordinate if the coord was a vector.
+func coordMag2(c geom.Coord) float64 {
+	return coordDot(c, c)
+}
diff --git a/pkg/geo/geomfn/de9im.go b/pkg/geo/geomfn/de9im.go
new file mode 100644
index 0000000..7864600
--- /dev/null
+++ b/pkg/geo/geomfn/de9im.go
@@ -0,0 +1,90 @@
+// Copyright 2020 The Cockroach Authors.
+//
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
+
+package geomfn
+
+import (
+	"github.com/cockroachdb/cockroachdb-parser/pkg/geo"
+	"github.com/cockroachdb/cockroachdb-parser/pkg/geo/geos"
+	"github.com/cockroachdb/cockroachdb-parser/pkg/sql/pgwire/pgcode"
+	"github.com/cockroachdb/cockroachdb-parser/pkg/sql/pgwire/pgerror"
+	"github.com/cockroachdb/cockroachdb-parser/pkg/util"
+)
+
+// Relate returns the DE-9IM relation between A and B.
+func Relate(a geo.Geometry, b geo.Geometry) (string, error) {
+	if a.SRID() != b.SRID() {
+		return "", geo.NewMismatchingSRIDsError(a.SpatialObject(), b.SpatialObject())
+	}
+	return geos.Relate(a.EWKB(), b.EWKB())
+}
+
+// RelateBoundaryNodeRule returns the DE-9IM relation between A and B using
+// the given boundary node rule (as specified by GEOS).
+func RelateBoundaryNodeRule(a, b geo.Geometry, bnr int) (string, error) {
+	if a.SRID() != b.SRID() {
+		return "", geo.NewMismatchingSRIDsError(a.SpatialObject(), b.SpatialObject())
+	}
+	return geos.RelateBoundaryNodeRule(a.EWKB(), b.EWKB(), bnr)
+}
+
+// RelatePattern returns whether the DE-9IM relation between A and B matches.
+func RelatePattern(a geo.Geometry, b geo.Geometry, pattern string) (bool, error) {
+	if a.SRID() != b.SRID() {
+		return false, geo.NewMismatchingSRIDsError(a.SpatialObject(), b.SpatialObject())
+	}
+	return geos.RelatePattern(a.EWKB(), b.EWKB(), pattern)
+}
+
+// MatchesDE9IM checks whether the given DE-9IM relation matches the DE-91M pattern.
+// Assumes the relation has been computed, and such has no 'T' and '*' characters.
+// See: https://en.wikipedia.org/wiki/DE-9IM.
+func MatchesDE9IM(relation string, pattern string) (bool, error) {
+	if len(relation) != 9 {
+		return false, pgerror.Newf(pgcode.InvalidParameterValue, "relation %q should be of length 9", relation)
+	}
+	if len(pattern) != 9 {
+		return false, pgerror.Newf(pgcode.InvalidParameterValue, "pattern %q should be of length 9", pattern)
+	}
+	for i := 0; i < len(relation); i++ {
+		matches, err := relationByteMatchesPatternByte(relation[i], pattern[i])
+		if err != nil {
+			return false, err
+		}
+		if !matches {
+			return false, nil
+		}
+	}
+	return true, nil
+}
+
+// relationByteMatchesPatternByte matches a single byte of a DE-9IM relation
+// against the DE-9IM pattern.
+// Pattern matches are as follows:
+//   - '*': allow anything.
+//   - '0' / '1' / '2': match exactly.
+//   - 't'/'T': allow only if the relation is true. This means the relation must be
+//     '0' (point), '1' (line) or '2' (area) - which is the dimensionality of the
+//     intersection.
+//   - 'f'/'F': allow only if relation is also false, which is of the form 'f'/'F'.
+func relationByteMatchesPatternByte(r byte, p byte) (bool, error) {
+	switch util.ToLowerSingleByte(p) {
+	case '*':
+		return true, nil
+	case 't':
+		if r < '0' || r > '2' {
+			return false, nil
+		}
+	case 'f':
+		if util.ToLowerSingleByte(r) != 'f' {
+			return false, nil
+		}
+	case '0', '1', '2':
+		return r == p, nil
+	default:
+		return false, pgerror.Newf(pgcode.InvalidParameterValue, "unrecognized pattern character: %s", string(p))
+	}
+	return true, nil
+}
diff --git a/pkg/geo/geomfn/distance.go b/pkg/geo/geomfn/distance.go
new file mode 100644
index 0000000..324ea21
--- /dev/null
+++ b/pkg/geo/geomfn/distance.go
@@ -0,0 +1,904 @@
+// Copyright 2020 The Cockroach Authors.
+//
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
+
+package geomfn
+
+import (
+	"math"
+
+	"github.com/cockroachdb/cockroachdb-parser/pkg/geo"
+	"github.com/cockroachdb/cockroachdb-parser/pkg/geo/geodist"
+	"github.com/cockroachdb/cockroachdb-parser/pkg/geo/geos"
+	"github.com/cockroachdb/cockroachdb-parser/pkg/sql/pgwire/pgcode"
+	"github.com/cockroachdb/cockroachdb-parser/pkg/sql/pgwire/pgerror"
+	"github.com/cockroachdb/errors"
+	"github.com/twpayne/go-geom"
+	"github.com/twpayne/go-geom/xy/lineintersector"
+)
+
+// geometricalObjectsOrder allows us to preserve the order of geometrical objects to
+// match the start and endpoint in the shortest and longest LineString.
+type geometricalObjectsOrder int
+
+const (
+	// geometricalObjectsFlipped represents that the given order of two geometrical
+	// objects has been flipped.
+	geometricalObjectsFlipped geometricalObjectsOrder = -1
+	// geometricalObjectsNotFlipped represents that the given order of two geometrical
+	// objects has not been flipped.
+	geometricalObjectsNotFlipped geometricalObjectsOrder = 1
+)
+
+// MinDistance returns the minimum distance between geometries A and B.
+// This returns a geo.EmptyGeometryError if either A or B is EMPTY.
+func MinDistance(a geo.Geometry, b geo.Geometry) (float64, error) {
+	if a.SRID() != b.SRID() {
+		return 0, geo.NewMismatchingSRIDsError(a.SpatialObject(), b.SpatialObject())
+	}
+	return minDistanceInternal(a, b, 0, geo.EmptyBehaviorOmit, geo.FnInclusive)
+}
+
+// MaxDistance returns the maximum distance across every pair of points comprising
+// geometries A and B.
+func MaxDistance(a geo.Geometry, b geo.Geometry) (float64, error) {
+	if a.SRID() != b.SRID() {
+		return 0, geo.NewMismatchingSRIDsError(a.SpatialObject(), b.SpatialObject())
+	}
+	return maxDistanceInternal(a, b, math.MaxFloat64, geo.EmptyBehaviorOmit, geo.FnInclusive)
+}
+
+// DWithin determines if any part of geometry A is within D units of geometry B.
+// If exclusive, DWithin is equivalent to Distance(a, b) < d. Otherwise, DWithin
+// is equivalent to Distance(a, b) <= d.
+func DWithin(
+	a geo.Geometry, b geo.Geometry, d float64, exclusivity geo.FnExclusivity,
+) (bool, error) {
+	if a.SRID() != b.SRID() {
+		return false, geo.NewMismatchingSRIDsError(a.SpatialObject(), b.SpatialObject())
+	}
+	if d < 0 {
+		return false, pgerror.Newf(pgcode.InvalidParameterValue, "dwithin distance cannot be less than zero")
+	}
+	if !a.CartesianBoundingBox().Buffer(d, d).Intersects(b.CartesianBoundingBox()) {
+		return false, nil
+	}
+	dist, err := minDistanceInternal(a, b, d, geo.EmptyBehaviorError, exclusivity)
+	if err != nil {
+		// In case of any empty geometries return false.
+		if geo.IsEmptyGeometryError(err) {
+			return false, nil
+		}
+		return false, err
+	}
+	if exclusivity == geo.FnExclusive {
+		return dist < d, nil
+	}
+	return dist <= d, nil
+}
+
+// DFullyWithin determines whether the maximum distance across every pair of
+// points comprising geometries A and B is within D units. If exclusive,
+// DFullyWithin is equivalent to MaxDistance(a, b) < d. Otherwise, DFullyWithin
+// is equivalent to MaxDistance(a, b) <= d.
+func DFullyWithin(
+	a geo.Geometry, b geo.Geometry, d float64, exclusivity geo.FnExclusivity,
+) (bool, error) {
+	if a.SRID() != b.SRID() {
+		return false, geo.NewMismatchingSRIDsError(a.SpatialObject(), b.SpatialObject())
+	}
+	if d < 0 {
+		return false, pgerror.Newf(pgcode.InvalidParameterValue, "dwithin distance cannot be less than zero")
+	}
+	if !a.CartesianBoundingBox().Buffer(d, d).Covers(b.CartesianBoundingBox()) {
+		return false, nil
+	}
+	dist, err := maxDistanceInternal(a, b, d, geo.EmptyBehaviorError, exclusivity)
+	if err != nil {
+		// In case of any empty geometries return false.
+		if geo.IsEmptyGeometryError(err) {
+			return false, nil
+		}
+		return false, err
+	}
+	if exclusivity == geo.FnExclusive {
+		return dist < d, nil
+	}
+	return dist <= d, nil
+}
+
+// LongestLineString returns the LineString corresponds to maximum distance across
+// every pair of points comprising geometries A and B.
+func LongestLineString(a geo.Geometry, b geo.Geometry) (geo.Geometry, error) {
+	if a.SRID() != b.SRID() {
+		return geo.Geometry{}, geo.NewMismatchingSRIDsError(a.SpatialObject(), b.SpatialObject())
+	}
+	u := newGeomMaxDistanceUpdater(math.MaxFloat64, geo.FnInclusive)
+	return distanceLineStringInternal(a, b, u, geo.EmptyBehaviorOmit)
+}
+
+// ShortestLineString returns the LineString corresponds to minimum distance across
+// every pair of points comprising geometries A and B.
+func ShortestLineString(a geo.Geometry, b geo.Geometry) (geo.Geometry, error) {
+	if a.SRID() != b.SRID() {
+		return geo.Geometry{}, geo.NewMismatchingSRIDsError(a.SpatialObject(), b.SpatialObject())
+	}
+	u := newGeomMinDistanceUpdater(0 /*stopAfter */, geo.FnInclusive)
+	return distanceLineStringInternal(a, b, u, geo.EmptyBehaviorOmit)
+}
+
+// distanceLineStringInternal calculates the LineString between two geometries using
+// the DistanceCalculator operator.
+// If there are any EMPTY Geometry objects, they will be ignored. It will return an
+// EmptyGeometryError if A or B contains only EMPTY geometries, even if emptyBehavior
+// is set to EmptyBehaviorOmit.
+func distanceLineStringInternal(
+	a geo.Geometry, b geo.Geometry, u geodist.DistanceUpdater, emptyBehavior geo.EmptyBehavior,
+) (geo.Geometry, error) {
+	c := &geomDistanceCalculator{updater: u, boundingBoxIntersects: a.CartesianBoundingBox().Intersects(b.CartesianBoundingBox())}
+	_, err := distanceInternal(a, b, c, emptyBehavior)
+	if err != nil {
+		return geo.Geometry{}, err
+	}
+	var coordA, coordB geom.Coord
+	switch u := u.(type) {
+	case *geomMaxDistanceUpdater:
+		coordA = u.coordA
+		coordB = u.coordB
+	case *geomMinDistanceUpdater:
+		coordA = u.coordA
+		coordB = u.coordB
+	default:
+		return geo.Geometry{}, errors.AssertionFailedf("programmer error: unknown behavior")
+	}
+	lineCoords := []float64{coordA.X(), coordA.Y(), coordB.X(), coordB.Y()}
+	lineString := geom.NewLineStringFlat(geom.XY, lineCoords).SetSRID(int(a.SRID()))
+	return geo.MakeGeometryFromGeomT(lineString)
+}
+
+// maxDistanceInternal finds the maximum distance between two geometries.
+// We can re-use the same algorithm as min-distance, allowing skips of checks that involve
+// the interiors or intersections as those will always be less then the maximum min-distance.
+func maxDistanceInternal(
+	a geo.Geometry,
+	b geo.Geometry,
+	stopAfter float64,
+	emptyBehavior geo.EmptyBehavior,
+	exclusivity geo.FnExclusivity,
+) (float64, error) {
+	u := newGeomMaxDistanceUpdater(stopAfter, exclusivity)
+	c := &geomDistanceCalculator{updater: u, boundingBoxIntersects: a.CartesianBoundingBox().Intersects(b.CartesianBoundingBox())}
+	return distanceInternal(a, b, c, emptyBehavior)
+}
+
+// minDistanceInternal finds the minimum distance between two geometries.
+// This implementation is done in-house, as compared to using GEOS.
+func minDistanceInternal(
+	a geo.Geometry,
+	b geo.Geometry,
+	stopAfter float64,
+	emptyBehavior geo.EmptyBehavior,
+	exclusivity geo.FnExclusivity,
+) (float64, error) {
+	u := newGeomMinDistanceUpdater(stopAfter, exclusivity)
+	c := &geomDistanceCalculator{updater: u, boundingBoxIntersects: a.CartesianBoundingBox().Intersects(b.CartesianBoundingBox())}
+	return distanceInternal(a, b, c, emptyBehavior)
+}
+
+// distanceInternal calculates the distance between two geometries using
+// the DistanceCalculator operator.
+// If there are any EMPTY Geometry objects, they will be ignored. It will return an
+// EmptyGeometryError if A or B contains only EMPTY geometries, even if emptyBehavior
+// is set to EmptyBehaviorOmit.
+func distanceInternal(
+	a geo.Geometry, b geo.Geometry, c geodist.DistanceCalculator, emptyBehavior geo.EmptyBehavior,
+) (float64, error) {
+	// If either side has no geoms, then we error out regardless of emptyBehavior.
+	if a.Empty() || b.Empty() {
+		return 0, geo.NewEmptyGeometryError()
+	}
+
+	aGeomT, err := a.AsGeomT()
+	if err != nil {
+		return 0, err
+	}
+	bGeomT, err := b.AsGeomT()
+	if err != nil {
+		return 0, err
+	}
+
+	// If we early exit, we have to check empty behavior upfront to return
+	// the appropriate error message.
+	// This matches PostGIS's behavior for DWithin, which is always false
+	// if at least one element is empty.
+	if emptyBehavior == geo.EmptyBehaviorError &&
+		(geo.GeomTContainsEmpty(aGeomT) || geo.GeomTContainsEmpty(bGeomT)) {
+		return 0, geo.NewEmptyGeometryError()
+	}
+
+	aIt := geo.NewGeomTIterator(aGeomT, emptyBehavior)
+	aGeom, aNext, aErr := aIt.Next()
+	if aErr != nil {
+		return 0, err
+	}
+	for aNext {
+		aGeodist, err := geomToGeodist(aGeom)
+		if err != nil {
+			return 0, err
+		}
+
+		bIt := geo.NewGeomTIterator(bGeomT, emptyBehavior)
+		bGeom, bNext, bErr := bIt.Next()
+		if bErr != nil {
+			return 0, err
+		}
+		for bNext {
+			bGeodist, err := geomToGeodist(bGeom)
+			if err != nil {
+				return 0, err
+			}
+			earlyExit, err := geodist.ShapeDistance(c, aGeodist, bGeodist)
+			if err != nil {
+				return 0, err
+			}
+			if earlyExit {
+				return c.DistanceUpdater().Distance(), nil
+			}
+
+			bGeom, bNext, bErr = bIt.Next()
+			if bErr != nil {
+				return 0, err
+			}
+		}
+
+		aGeom, aNext, aErr = aIt.Next()
+		if aErr != nil {
+			return 0, err
+		}
+	}
+	return c.DistanceUpdater().Distance(), nil
+}
+
+// geomToGeodist converts a given geom object to a geodist shape.
+func geomToGeodist(g geom.T) (geodist.Shape, error) {
+	switch g := g.(type) {
+	case *geom.Point:
+		return &geodist.Point{GeomPoint: g.Coords()}, nil
+	case *geom.LineString:
+		return &geomGeodistLineString{LineString: g}, nil
+	case *geom.Polygon:
+		return &geomGeodistPolygon{Polygon: g}, nil
+	}
+	return nil, pgerror.Newf(pgcode.InvalidParameterValue, "could not find shape: %T", g)
+}
+
+// geomGeodistLineString implements geodist.LineString.
+type geomGeodistLineString struct {
+	*geom.LineString
+}
+
+var _ geodist.LineString = (*geomGeodistLineString)(nil)
+
+// IsShape implements the geodist.LineString interface.
+func (*geomGeodistLineString) IsShape() {}
+
+// LineString implements the geodist.LineString interface.
+func (*geomGeodistLineString) IsLineString() {}
+
+// Edge implements the geodist.LineString interface.
+func (g *geomGeodistLineString) Edge(i int) geodist.Edge {
+	return geodist.Edge{
+		V0: geodist.Point{GeomPoint: g.LineString.Coord(i)},
+		V1: geodist.Point{GeomPoint: g.LineString.Coord(i + 1)},
+	}
+}
+
+// NumEdges implements the geodist.LineString interface.
+func (g *geomGeodistLineString) NumEdges() int {
+	return g.LineString.NumCoords() - 1
+}
+
+// Vertex implements the geodist.LineString interface.
+func (g *geomGeodistLineString) Vertex(i int) geodist.Point {
+	return geodist.Point{GeomPoint: g.LineString.Coord(i)}
+}
+
+// NumVertexes implements the geodist.LineString interface.
+func (g *geomGeodistLineString) NumVertexes() int {
+	return g.LineString.NumCoords()
+}
+
+// geomGeodistLinearRing implements geodist.LinearRing.
+type geomGeodistLinearRing struct {
+	*geom.LinearRing
+}
+
+var _ geodist.LinearRing = (*geomGeodistLinearRing)(nil)
+
+// IsShape implements the geodist.LinearRing interface.
+func (*geomGeodistLinearRing) IsShape() {}
+
+// LinearRing implements the geodist.LinearRing interface.
+func (*geomGeodistLinearRing) IsLinearRing() {}
+
+// Edge implements the geodist.LinearRing interface.
+func (g *geomGeodistLinearRing) Edge(i int) geodist.Edge {
+	return geodist.Edge{
+		V0: geodist.Point{GeomPoint: g.LinearRing.Coord(i)},
+		V1: geodist.Point{GeomPoint: g.LinearRing.Coord(i + 1)},
+	}
+}
+
+// NumEdges implements the geodist.LinearRing interface.
+func (g *geomGeodistLinearRing) NumEdges() int {
+	return g.LinearRing.NumCoords() - 1
+}
+
+// Vertex implements the geodist.LinearRing interface.
+func (g *geomGeodistLinearRing) Vertex(i int) geodist.Point {
+	return geodist.Point{GeomPoint: g.LinearRing.Coord(i)}
+}
+
+// NumVertexes implements the geodist.LinearRing interface.
+func (g *geomGeodistLinearRing) NumVertexes() int {
+	return g.LinearRing.NumCoords()
+}
+
+// geomGeodistPolygon implements geodist.Polygon.
+type geomGeodistPolygon struct {
+	*geom.Polygon
+}
+
+var _ geodist.Polygon = (*geomGeodistPolygon)(nil)
+
+// IsShape implements the geodist.Polygon interface.
+func (*geomGeodistPolygon) IsShape() {}
+
+// Polygon implements the geodist.Polygon interface.
+func (*geomGeodistPolygon) IsPolygon() {}
+
+// LinearRing implements the geodist.Polygon interface.
+func (g *geomGeodistPolygon) LinearRing(i int) geodist.LinearRing {
+	return &geomGeodistLinearRing{LinearRing: g.Polygon.LinearRing(i)}
+}
+
+// NumLinearRings implements the geodist.Polygon interface.
+func (g *geomGeodistPolygon) NumLinearRings() int {
+	return g.Polygon.NumLinearRings()
+}
+
+// geomGeodistEdgeCrosser implements geodist.EdgeCrosser.
+type geomGeodistEdgeCrosser struct {
+	strategy   lineintersector.Strategy
+	edgeV0     geom.Coord
+	edgeV1     geom.Coord
+	nextEdgeV0 geom.Coord
+}
+
+var _ geodist.EdgeCrosser = (*geomGeodistEdgeCrosser)(nil)
+
+// ChainCrossing implements geodist.EdgeCrosser.
+func (c *geomGeodistEdgeCrosser) ChainCrossing(p geodist.Point) (bool, geodist.Point) {
+	nextEdgeV1 := p.GeomPoint
+	result := lineintersector.LineIntersectsLine(
+		c.strategy,
+		c.edgeV0,
+		c.edgeV1,
+		c.nextEdgeV0,
+		nextEdgeV1,
+	)
+	c.nextEdgeV0 = nextEdgeV1
+	if result.HasIntersection() {
+		return true, geodist.Point{GeomPoint: result.Intersection()[0]}
+	}
+	return false, geodist.Point{}
+}
+
+// geomMinDistanceUpdater finds the minimum distance using geom calculations.
+// And preserve the line's endpoints as geom.Coord which corresponds to minimum
+// distance. If inclusive, methods will return early if it finds a minimum
+// distance <= stopAfter. Otherwise, methods will return early if it finds a
+// minimum distance < stopAfter.
+type geomMinDistanceUpdater struct {
+	currentValue float64
+	stopAfter    float64
+	exclusivity  geo.FnExclusivity
+	// coordA represents the first vertex of the edge that holds the maximum distance.
+	coordA geom.Coord
+	// coordB represents the second vertex of the edge that holds the maximum distance.
+	coordB geom.Coord
+
+	geometricalObjOrder geometricalObjectsOrder
+}
+
+var _ geodist.DistanceUpdater = (*geomMinDistanceUpdater)(nil)
+
+// newGeomMinDistanceUpdater returns a new geomMinDistanceUpdater with the
+// correct arguments set up.
+func newGeomMinDistanceUpdater(
+	stopAfter float64, exclusivity geo.FnExclusivity,
+) *geomMinDistanceUpdater {
+	return &geomMinDistanceUpdater{
+		currentValue:        math.MaxFloat64,
+		stopAfter:           stopAfter,
+		exclusivity:         exclusivity,
+		coordA:              nil,
+		coordB:              nil,
+		geometricalObjOrder: geometricalObjectsNotFlipped,
+	}
+}
+
+// Distance implements the geodist.DistanceUpdater interface.
+func (u *geomMinDistanceUpdater) Distance() float64 {
+	return u.currentValue
+}
+
+// Update implements the geodist.DistanceUpdater interface.
+func (u *geomMinDistanceUpdater) Update(aPoint geodist.Point, bPoint geodist.Point) bool {
+	a := aPoint.GeomPoint
+	b := bPoint.GeomPoint
+
+	dist := coordNorm(coordSub(a, b))
+	if dist < u.currentValue || u.coordA == nil {
+		u.currentValue = dist
+		if u.geometricalObjOrder == geometricalObjectsFlipped {
+			u.coordA = b
+			u.coordB = a
+		} else {
+			u.coordA = a
+			u.coordB = b
+		}
+		if u.exclusivity == geo.FnExclusive {
+			return dist < u.stopAfter
+		}
+		return dist <= u.stopAfter
+	}
+	return false
+}
+
+// OnIntersects implements the geodist.DistanceUpdater interface.
+func (u *geomMinDistanceUpdater) OnIntersects(p geodist.Point) bool {
+	u.coordA = p.GeomPoint
+	u.coordB = p.GeomPoint
+	u.currentValue = 0
+	return true
+}
+
+// IsMaxDistance implements the geodist.DistanceUpdater interface.
+func (u *geomMinDistanceUpdater) IsMaxDistance() bool {
+	return false
+}
+
+// FlipGeometries implements the geodist.DistanceUpdater interface.
+func (u *geomMinDistanceUpdater) FlipGeometries() {
+	u.geometricalObjOrder = -u.geometricalObjOrder
+}
+
+// geomMaxDistanceUpdater finds the maximum distance using geom calculations.
+// And preserve the line's endpoints as geom.Coord which corresponds to maximum
+// distance. If exclusive, methods will return early if it finds that
+// distance >= stopAfter. Otherwise, methods will return early if distance >
+// stopAfter.
+type geomMaxDistanceUpdater struct {
+	currentValue float64
+	stopAfter    float64
+	exclusivity  geo.FnExclusivity
+
+	// coordA represents the first vertex of the edge that holds the maximum distance.
+	coordA geom.Coord
+	// coordB represents the second vertex of the edge that holds the maximum distance.
+	coordB geom.Coord
+
+	geometricalObjOrder geometricalObjectsOrder
+}
+
+var _ geodist.DistanceUpdater = (*geomMaxDistanceUpdater)(nil)
+
+// newGeomMaxDistanceUpdater returns a new geomMaxDistanceUpdater with the
+// correct arguments set up. currentValue is initially populated with least
+// possible value instead of 0 because there may be the case where maximum
+// distance is 0 and we may require to find the line for 0 maximum distance.
+func newGeomMaxDistanceUpdater(
+	stopAfter float64, exclusivity geo.FnExclusivity,
+) *geomMaxDistanceUpdater {
+	return &geomMaxDistanceUpdater{
+		currentValue:        -math.MaxFloat64,
+		stopAfter:           stopAfter,
+		exclusivity:         exclusivity,
+		coordA:              nil,
+		coordB:              nil,
+		geometricalObjOrder: geometricalObjectsNotFlipped,
+	}
+}
+
+// Distance implements the geodist.DistanceUpdater interface.
+func (u *geomMaxDistanceUpdater) Distance() float64 {
+	return u.currentValue
+}
+
+// Update implements the geodist.DistanceUpdater interface.
+func (u *geomMaxDistanceUpdater) Update(aPoint geodist.Point, bPoint geodist.Point) bool {
+	a := aPoint.GeomPoint
+	b := bPoint.GeomPoint
+
+	dist := coordNorm(coordSub(a, b))
+	if dist > u.currentValue || u.coordA == nil {
+		u.currentValue = dist
+		if u.geometricalObjOrder == geometricalObjectsFlipped {
+			u.coordA = b
+			u.coordB = a
+		} else {
+			u.coordA = a
+			u.coordB = b
+		}
+		if u.exclusivity == geo.FnExclusive {
+			return dist >= u.stopAfter
+		}
+		return dist > u.stopAfter
+	}
+	return false
+}
+
+// OnIntersects implements the geodist.DistanceUpdater interface.
+func (u *geomMaxDistanceUpdater) OnIntersects(p geodist.Point) bool {
+	return false
+}
+
+// IsMaxDistance implements the geodist.DistanceUpdater interface.
+func (u *geomMaxDistanceUpdater) IsMaxDistance() bool {
+	return true
+}
+
+// FlipGeometries implements the geodist.DistanceUpdater interface.
+func (u *geomMaxDistanceUpdater) FlipGeometries() {
+	u.geometricalObjOrder = -u.geometricalObjOrder
+}
+
+// geomDistanceCalculator implements geodist.DistanceCalculator
+type geomDistanceCalculator struct {
+	updater               geodist.DistanceUpdater
+	boundingBoxIntersects bool
+}
+
+var _ geodist.DistanceCalculator = (*geomDistanceCalculator)(nil)
+
+// DistanceUpdater implements geodist.DistanceCalculator.
+func (c *geomDistanceCalculator) DistanceUpdater() geodist.DistanceUpdater {
+	return c.updater
+}
+
+// BoundingBoxIntersects implements geodist.DistanceCalculator.
+func (c *geomDistanceCalculator) BoundingBoxIntersects() bool {
+	return c.boundingBoxIntersects
+}
+
+// NewEdgeCrosser implements geodist.DistanceCalculator.
+func (c *geomDistanceCalculator) NewEdgeCrosser(
+	edge geodist.Edge, startPoint geodist.Point,
+) geodist.EdgeCrosser {
+	return &geomGeodistEdgeCrosser{
+		strategy:   &lineintersector.NonRobustLineIntersector{},
+		edgeV0:     edge.V0.GeomPoint,
+		edgeV1:     edge.V1.GeomPoint,
+		nextEdgeV0: startPoint.GeomPoint,
+	}
+}
+
+// side corresponds to the side in which a point is relative to a line.
+type pointSide int
+
+const (
+	pointSideLeft  pointSide = -1
+	pointSideOn    pointSide = 0
+	pointSideRight pointSide = 1
+)
+
+// findPointSide finds which side a point is relative to the infinite line
+// given by the edge.
+// Note this side is relative to the orientation of the line.
+func findPointSide(p geom.Coord, eV0 geom.Coord, eV1 geom.Coord) pointSide {
+	// This is the equivalent of using the point-gradient formula
+	// and determining the sign, i.e. the sign of
+	// d = (x-x1)(y2-y1) - (y-y1)(x2-x1)
+	// where (x1,y1) and (x2,y2) is the edge and (x,y) is the point
+	sign := (p.X()-eV0.X())*(eV1.Y()-eV0.Y()) - (eV1.X()-eV0.X())*(p.Y()-eV0.Y())
+	switch {
+	case sign == 0:
+		return pointSideOn
+	case sign > 0:
+		return pointSideRight
+	default:
+		return pointSideLeft
+	}
+}
+
+type linearRingSide int
+
+const (
+	outsideLinearRing linearRingSide = -1
+	onLinearRing      linearRingSide = 0
+	insideLinearRing  linearRingSide = 1
+)
+
+// findPointSideOfLinearRing returns whether a point is outside, on, or inside a
+// linear ring.
+func findPointSideOfLinearRing(point geodist.Point, linearRing geodist.LinearRing) linearRingSide {
+	// This is done using the winding number algorithm, also known as the
+	// "non-zero rule".
+	// See: https://en.wikipedia.org/wiki/Point_in_polygon for intro.
+	// See: http://geomalgorithms.com/a03-_inclusion.html for algorithm.
+	// See also: https://en.wikipedia.org/wiki/Winding_number
+	// See also: https://en.wikipedia.org/wiki/Nonzero-rule
+	windingNumber := 0
+	p := point.GeomPoint
+	for edgeIdx, numEdges := 0, linearRing.NumEdges(); edgeIdx < numEdges; edgeIdx++ {
+		e := linearRing.Edge(edgeIdx)
+		eV0 := e.V0.GeomPoint
+		eV1 := e.V1.GeomPoint
+		// Same vertex; none of these checks will pass.
+		if coordEqual(eV0, eV1) {
+			continue
+		}
+		yMin := math.Min(eV0.Y(), eV1.Y())
+		yMax := math.Max(eV0.Y(), eV1.Y())
+		// If the edge isn't on the same level as Y, this edge isn't worth considering.
+		if p.Y() > yMax || p.Y() < yMin {
+			continue
+		}
+		side := findPointSide(p, eV0, eV1)
+		// If the point is on the line if the edge was infinite, and the point is within the bounds
+		// of the line segment denoted by the edge, there is a covering.
+		if side == pointSideOn && (eV0.X() <= p.X() && p.X() <= eV1.X()) {
+			return onLinearRing
+		}
+		// If the point is left of the segment and the line is rising
+		// we have a circle going CCW, so increment.
+		// Note we only compare [start, end) as we do not want to double count points
+		// which are on the same X / Y axis as an edge vertex.
+		if side == pointSideLeft && eV0.Y() <= p.Y() && p.Y() < eV1.Y() {
+			windingNumber++
+		}
+		// If the line is to the right of the segment and the
+		// line is falling, we a have a circle going CW so decrement.
+		// Note we only compare [start, end) as we do not want to double count points
+		// which are on the same X / Y axis as an edge vertex.
+		if side == pointSideRight && eV1.Y() <= p.Y() && p.Y() < eV0.Y() {
+			windingNumber--
+		}
+	}
+	if windingNumber != 0 {
+		return insideLinearRing
+	}
+	return outsideLinearRing
+}
+
+// PointIntersectsLinearRing implements geodist.DistanceCalculator.
+func (c *geomDistanceCalculator) PointIntersectsLinearRing(
+	point geodist.Point, linearRing geodist.LinearRing,
+) bool {
+	switch findPointSideOfLinearRing(point, linearRing) {
+	case insideLinearRing, onLinearRing:
+		return true
+	default:
+		return false
+	}
+}
+
+// ClosestPointToEdge implements geodist.DistanceCalculator.
+func (c *geomDistanceCalculator) ClosestPointToEdge(
+	e geodist.Edge, p geodist.Point,
+) (geodist.Point, bool) {
+	// Edge is a single point. Closest point must be any edge vertex.
+	if coordEqual(e.V0.GeomPoint, e.V1.GeomPoint) {
+		return e.V0, coordEqual(e.V0.GeomPoint, p.GeomPoint)
+	}
+
+	// From http://www.faqs.org/faqs/graphics/algorithms-faq/, section 1.02
+	//
+	//  Let the point be C (Cx,Cy) and the line be AB (Ax,Ay) to (Bx,By).
+	//  Let P be the point of perpendicular projection of C on AB.  The parameter
+	//  r, which indicates P's position along AB, is computed by the dot product
+	//  of AC and AB divided by the square of the length of AB:
+	//
+	//  (1)     AC dot AB
+	//      r = ---------
+	//          ||AB||^2
+	//
+	//  r has the following meaning:
+	//
+	//      r=0      P = A
+	//      r=1      P = B
+	//      r<0      P is on the backward extension of AB
+	//      r>1      P is on the forward extension of AB
+	//      0<r<1    P is interior to AB
+	if coordEqual(p.GeomPoint, e.V0.GeomPoint) {
+		return p, true
+	}
+	if coordEqual(p.GeomPoint, e.V1.GeomPoint) {
+		return p, true
+	}
+
+	ac := coordSub(p.GeomPoint, e.V0.GeomPoint)
+	ab := coordSub(e.V1.GeomPoint, e.V0.GeomPoint)
+
+	r := coordDot(ac, ab) / coordNorm2(ab)
+	if r < 0 || r > 1 {
+		return p, false
+	}
+	return geodist.Point{GeomPoint: coordAdd(e.V0.GeomPoint, coordMul(ab, r))}, true
+}
+
+// FrechetDistance calculates the Frechet distance between two geometries.
+func FrechetDistance(a, b geo.Geometry) (*float64, error) {
+	if a.Empty() || b.Empty() {
+		return nil, nil
+	}
+	if a.SRID() != b.SRID() {
+		return nil, geo.NewMismatchingSRIDsError(a.SpatialObject(), b.SpatialObject())
+	}
+	distance, err := geos.FrechetDistance(a.EWKB(), b.EWKB())
+	if err != nil {
+		return nil, err
+	}
+	return &distance, nil
+}
+
+// FrechetDistanceDensify calculates the Frechet distance between two geometries.
+func FrechetDistanceDensify(a, b geo.Geometry, densifyFrac float64) (*float64, error) {
+	// For Frechet distance, we take <= 0 to disable the densifyFrac parameter.
+	// This differs from HausdorffDistance, but follows PostGIS behavior.
+	if densifyFrac <= 0 {
+		return FrechetDistance(a, b)
+	}
+	if a.Empty() || b.Empty() {
+		return nil, nil
+	}
+	if a.SRID() != b.SRID() {
+		return nil, geo.NewMismatchingSRIDsError(a.SpatialObject(), b.SpatialObject())
+	}
+	if err := verifyDensifyFrac(densifyFrac); err != nil {
+		return nil, err
+	}
+	distance, err := geos.FrechetDistanceDensify(a.EWKB(), b.EWKB(), densifyFrac)
+	if err != nil {
+		return nil, err
+	}
+	return &distance, nil
+}
+
+// HausdorffDistance calculates the Hausdorff distance between two geometries.
+func HausdorffDistance(a, b geo.Geometry) (*float64, error) {
+	if a.Empty() || b.Empty() {
+		return nil, nil
+	}
+	if a.SRID() != b.SRID() {
+		return nil, geo.NewMismatchingSRIDsError(a.SpatialObject(), b.SpatialObject())
+	}
+	distance, err := geos.HausdorffDistance(a.EWKB(), b.EWKB())
+	if err != nil {
+		return nil, err
+	}
+	return &distance, nil
+}
+
+// HausdorffDistanceDensify calculates the Hausdorff distance between two geometries.
+func HausdorffDistanceDensify(a, b geo.Geometry, densifyFrac float64) (*float64, error) {
+	if a.Empty() || b.Empty() {
+		return nil, nil
+	}
+	if a.SRID() != b.SRID() {
+		return nil, geo.NewMismatchingSRIDsError(a.SpatialObject(), b.SpatialObject())
+	}
+	if err := verifyDensifyFrac(densifyFrac); err != nil {
+		return nil, err
+	}
+
+	distance, err := geos.HausdorffDistanceDensify(a.EWKB(), b.EWKB(), densifyFrac)
+	if err != nil {
+		return nil, err
+	}
+	return &distance, nil
+}
+
+// ClosestPoint returns the first point located on geometry A on the shortest line between the geometries.
+func ClosestPoint(a, b geo.Geometry) (geo.Geometry, error) {
+	shortestLine, err := ShortestLineString(a, b)
+	if err != nil {
+		return geo.Geometry{}, err
+	}
+	shortestLineT, err := shortestLine.AsGeomT()
+	if err != nil {
+		return geo.Geometry{}, err
+	}
+	closestPoint, err := geo.MakeGeometryFromPointCoords(
+		shortestLineT.(*geom.LineString).Coord(0).X(),
+		shortestLineT.(*geom.LineString).Coord(0).Y(),
+	)
+	if err != nil {
+		return geo.Geometry{}, err
+	}
+	return closestPoint.CloneWithSRID(a.SRID())
+}
+
+func verifyDensifyFrac(f float64) error {
+	if f < 0 || f > 1 {
+		return pgerror.Newf(pgcode.InvalidParameterValue, "fraction must be in range [0, 1], got %f", f)
+	}
+	// Very small densifyFrac potentially causes a SIGFPE or generate a large
+	// amount of memory. Guard against this.
+	const fracTooSmall = 1e-6
+	if f > 0 && f < fracTooSmall {
+		return pgerror.Newf(pgcode.InvalidParameterValue, "fraction %f is too small, must be at least %f", f, fracTooSmall)
+	}
+	return nil
+}
+
+// findPointSideOfPolygon returns whether a point intersects with a polygon.
+func findPointSideOfPolygon(point geom.T, polygon geom.T) (linearRingSide, error) {
+	// Convert point from a geom.T to a *geodist.Point.
+	_, ok := point.(*geom.Point)
+	if !ok {
+		return outsideLinearRing, pgerror.Newf(pgcode.InvalidParameterValue, "first geometry passed to findPointSideOfPolygon must be a point")
+	}
+	pointGeodistShape, err := geomToGeodist(point)
+	if err != nil {
+		return outsideLinearRing, err
+	}
+	pointGeodistPoint, ok := pointGeodistShape.(*geodist.Point)
+	if !ok {
+		return outsideLinearRing, pgerror.Newf(pgcode.InvalidParameterValue, "geomToGeodist failed to convert a *geom.Point to a *geodist.Point")
+	}
+
+	// Convert polygon from a geom.T to a geodist.Polygon.
+	_, ok = polygon.(*geom.Polygon)
+	if !ok {
+		return outsideLinearRing, pgerror.Newf(pgcode.InvalidParameterValue, "second geometry passed to findPointSideOfPolygon must be a polygon")
+	}
+	polygonGeodistShape, err := geomToGeodist(polygon)
+	if err != nil {
+		return outsideLinearRing, err
+	}
+	polygonGeodistPolygon, ok := polygonGeodistShape.(geodist.Polygon)
+	if !ok {
+		return outsideLinearRing, pgerror.Newf(pgcode.InvalidParameterValue, "geomToGeodist failed to convert a *geom.Polygon to a geodist.Polygon")
+	}
+
+	// Point cannot be inside an empty polygon.
+	if polygonGeodistPolygon.NumLinearRings() == 0 {
+		return outsideLinearRing, nil
+	}
+
+	// Find which side the point is relative to the main outer boundary of
+	// the polygon. If it outside or on the boundary, we can conclude
+	// that the point is on that side of the overall polygon as well.
+	mainRing := polygonGeodistPolygon.LinearRing(0)
+	switch pointSide := findPointSideOfLinearRing(*pointGeodistPoint, mainRing); pointSide {
+	case insideLinearRing:
+	case outsideLinearRing, onLinearRing:
+		return pointSide, nil
+	default:
+		return outsideLinearRing, pgerror.Newf(pgcode.InvalidParameterValue, "unknown linearRingSide %d", pointSide)
+	}
+
+	// If the point is inside the main outer boundary of the polygon, we must
+	// determine which side it is relative to every hole in the polygon.
+	// If it is inside any hole, it is outside the polygon. If it is on the
+	// ring of any hole, it is on the boundary of the polygon. Otherwise,
+	// it is inside the polygon.
+	for ringNum := 1; ringNum < polygonGeodistPolygon.NumLinearRings(); ringNum++ {
+		polygonHole := polygonGeodistPolygon.LinearRing(ringNum)
+		switch pointSide := findPointSideOfLinearRing(*pointGeodistPoint, polygonHole); pointSide {
+		case insideLinearRing:
+			return outsideLinearRing, nil
+		case onLinearRing:
+			return onLinearRing, nil
+		case outsideLinearRing:
+			continue
+		default:
+			return outsideLinearRing, pgerror.Newf(pgcode.InvalidParameterValue, "unknown linearRingSide %d", pointSide)
+		}
+	}
+
+	return insideLinearRing, nil
+}
diff --git a/pkg/geo/geomfn/envelope.go b/pkg/geo/geomfn/envelope.go
new file mode 100644
index 0000000..cbfaa5d
--- /dev/null
+++ b/pkg/geo/geomfn/envelope.go
@@ -0,0 +1,18 @@
+// Copyright 2020 The Cockroach Authors.
+//
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
+
+package geomfn
+
+import "github.com/cockroachdb/cockroachdb-parser/pkg/geo"
+
+// Envelope forms an envelope (compliant with the OGC spec) of the given Geometry.
+// It uses the bounding box to return a Polygon, but can return a Point or
+// Line if the bounding box is degenerate and not a box.
+func Envelope(g geo.Geometry) (geo.Geometry, error) {
+	if g.Empty() {
+		return g, nil
+	}
+	return geo.MakeGeometryFromGeomT(g.CartesianBoundingBox().ToGeomT(g.SRID()))
+}
diff --git a/pkg/geo/geomfn/flip_coordinates.go b/pkg/geo/geomfn/flip_coordinates.go
new file mode 100644
index 0000000..0bade6a
--- /dev/null
+++ b/pkg/geo/geomfn/flip_coordinates.go
@@ -0,0 +1,39 @@
+// Copyright 2020 The Cockroach Authors.
+//
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
+
+package geomfn
+
+import (
+	"github.com/cockroachdb/cockroachdb-parser/pkg/geo"
+	"github.com/twpayne/go-geom"
+)
+
+// FlipCoordinates returns a modified g whose X, Y coordinates are flipped.
+func FlipCoordinates(g geo.Geometry) (geo.Geometry, error) {
+	if g.Empty() {
+		return g, nil
+	}
+
+	t, err := g.AsGeomT()
+	if err != nil {
+		return geo.Geometry{}, err
+	}
+
+	newT, err := applyOnCoordsForGeomT(t, func(l geom.Layout, dst, src []float64) error {
+		dst[0], dst[1] = src[1], src[0]
+		if l.ZIndex() != -1 {
+			dst[l.ZIndex()] = src[l.ZIndex()]
+		}
+		if l.MIndex() != -1 {
+			dst[l.MIndex()] = src[l.MIndex()]
+		}
+		return nil
+	})
+	if err != nil {
+		return geo.Geometry{}, err
+	}
+
+	return geo.MakeGeometryFromGeomT(newT)
+}
diff --git a/pkg/geo/geomfn/force_layout.go b/pkg/geo/geomfn/force_layout.go
new file mode 100644
index 0000000..8f1cf6b
--- /dev/null
+++ b/pkg/geo/geomfn/force_layout.go
@@ -0,0 +1,156 @@
+// Copyright 2020 The Cockroach Authors.
+//
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
+
+package geomfn
+
+import (
+	"github.com/cockroachdb/cockroachdb-parser/pkg/geo"
+	"github.com/cockroachdb/cockroachdb-parser/pkg/sql/pgwire/pgcode"
+	"github.com/cockroachdb/cockroachdb-parser/pkg/sql/pgwire/pgerror"
+	"github.com/twpayne/go-geom"
+)
+
+// ForceLayout forces a geometry into the given layout.
+// If a Z dimension is added, 0 is added as the Z value.
+// If an M dimension is added, 0 is added as the M value.
+func ForceLayout(g geo.Geometry, layout geom.Layout) (geo.Geometry, error) {
+	return ForceLayoutWithDefaultZM(g, layout, 0, 0)
+}
+
+// ForceLayoutWithDefaultZ forces a geometry into the given layout.
+// If a Z dimension is added, defaultZ is added as the Z value.
+// If an M dimension is added, 0 is added as the M value.
+func ForceLayoutWithDefaultZ(
+	g geo.Geometry, layout geom.Layout, defaultZ float64,
+) (geo.Geometry, error) {
+	return ForceLayoutWithDefaultZM(g, layout, defaultZ, 0)
+}
+
+// ForceLayoutWithDefaultM forces a geometry into the given layout.
+// If a Z dimension is added, 0 is added as the Z value.
+// If an M dimension is added, defaultM is added as the M value.
+func ForceLayoutWithDefaultM(
+	g geo.Geometry, layout geom.Layout, defaultM float64,
+) (geo.Geometry, error) {
+	return ForceLayoutWithDefaultZM(g, layout, 0, defaultM)
+}
+
+// ForceLayoutWithDefaultZM forces a geometry into the given layout.
+// If a Z dimension is added, defaultZ is added as the Z value.
+// If an M dimension is added, defaultM is added as the M value.
+func ForceLayoutWithDefaultZM(
+	g geo.Geometry, layout geom.Layout, defaultZ float64, defaultM float64,
+) (geo.Geometry, error) {
+	geomT, err := g.AsGeomT()
+	if err != nil {
+		return geo.Geometry{}, err
+	}
+	retGeomT, err := forceLayout(geomT, layout, defaultZ, defaultM)
+	if err != nil {
+		return geo.Geometry{}, err
+	}
+	return geo.MakeGeometryFromGeomT(retGeomT)
+}
+
+// forceLayout forces a geom.T into the given layout and uses
+// the specified default Z and M values as needed.
+func forceLayout(t geom.T, layout geom.Layout, defaultZ float64, defaultM float64) (geom.T, error) {
+	if t.Layout() == layout {
+		return t, nil
+	}
+	switch t := t.(type) {
+	case *geom.GeometryCollection:
+		ret := geom.NewGeometryCollection().SetSRID(t.SRID())
+		if err := ret.SetLayout(layout); err != nil {
+			return nil, err
+		}
+		for i := 0; i < t.NumGeoms(); i++ {
+			toPush, err := forceLayout(t.Geom(i), layout, defaultZ, defaultM)
+			if err != nil {
+				return nil, err
+			}
+			if err := ret.Push(toPush); err != nil {
+				return nil, err
+			}
+		}
+		return ret, nil
+	case *geom.Point:
+		return geom.NewPointFlat(
+			layout, forceFlatCoordsLayout(t, layout, defaultZ, defaultM)).SetSRID(t.SRID()), nil
+	case *geom.LineString:
+		return geom.NewLineStringFlat(
+			layout, forceFlatCoordsLayout(t, layout, defaultZ, defaultM)).SetSRID(t.SRID()), nil
+	case *geom.Polygon:
+		return geom.NewPolygonFlat(
+			layout,
+			forceFlatCoordsLayout(t, layout, defaultZ, defaultM),
+			forceEnds(t.Ends(), t.Layout(), layout),
+		).SetSRID(t.SRID()), nil
+	case *geom.MultiPoint:
+		return geom.NewMultiPointFlat(
+			layout,
+			forceFlatCoordsLayout(t, layout, defaultZ, defaultM),
+			geom.NewMultiPointFlatOptionWithEnds(forceEnds(t.Ends(), t.Layout(), layout)),
+		).SetSRID(t.SRID()), nil
+	case *geom.MultiLineString:
+		return geom.NewMultiLineStringFlat(
+			layout,
+			forceFlatCoordsLayout(t, layout, defaultZ, defaultM),
+			forceEnds(t.Ends(), t.Layout(), layout),
+		).SetSRID(t.SRID()), nil
+	case *geom.MultiPolygon:
+		endss := make([][]int, len(t.Endss()))
+		for i := range t.Endss() {
+			endss[i] = forceEnds(t.Endss()[i], t.Layout(), layout)
+		}
+		return geom.NewMultiPolygonFlat(
+			layout,
+			forceFlatCoordsLayout(t, layout, defaultZ, defaultM),
+			endss,
+		).SetSRID(t.SRID()), nil
+	default:
+		return nil, pgerror.Newf(pgcode.InvalidParameterValue, "unknown geom.T type: %T", t)
+	}
+}
+
+// forceEnds forces the Endss layout of a geometry into the new layout.
+func forceEnds(ends []int, oldLayout geom.Layout, newLayout geom.Layout) []int {
+	if oldLayout.Stride() == newLayout.Stride() {
+		return ends
+	}
+	newEnds := make([]int, len(ends))
+	for i := range ends {
+		newEnds[i] = (ends[i] / oldLayout.Stride()) * newLayout.Stride()
+	}
+	return newEnds
+}
+
+// forceFlatCoordsLayout forces the flatCoords layout of a geometry into the new layout
+// and uses the specified default Z and M values as needed.
+func forceFlatCoordsLayout(
+	t geom.T, layout geom.Layout, defaultZ float64, defaultM float64,
+) []float64 {
+	oldFlatCoords := t.FlatCoords()
+	newFlatCoords := make([]float64, (len(oldFlatCoords)/t.Stride())*layout.Stride())
+	for coordIdx := 0; coordIdx < len(oldFlatCoords)/t.Stride(); coordIdx++ {
+		newFlatCoords[coordIdx*layout.Stride()] = oldFlatCoords[coordIdx*t.Stride()]
+		newFlatCoords[coordIdx*layout.Stride()+1] = oldFlatCoords[coordIdx*t.Stride()+1]
+		if layout.ZIndex() != -1 {
+			z := defaultZ
+			if t.Layout().ZIndex() != -1 {
+				z = oldFlatCoords[coordIdx*t.Stride()+t.Layout().ZIndex()]
+			}
+			newFlatCoords[coordIdx*layout.Stride()+layout.ZIndex()] = z
+		}
+		if layout.MIndex() != -1 {
+			m := defaultM
+			if t.Layout().MIndex() != -1 {
+				m = oldFlatCoords[coordIdx*t.Stride()+t.Layout().MIndex()]
+			}
+			newFlatCoords[coordIdx*layout.Stride()+layout.MIndex()] = m
+		}
+	}
+	return newFlatCoords
+}
diff --git a/pkg/geo/geomfn/generate_points.go b/pkg/geo/geomfn/generate_points.go
new file mode 100644
index 0000000..3549a51
--- /dev/null
+++ b/pkg/geo/geomfn/generate_points.go
@@ -0,0 +1,221 @@
+// Copyright 2020 The Cockroach Authors.
+//
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
+
+package geomfn
+
+import (
+	"math"
+	"math/rand"
+
+	"github.com/cockroachdb/cockroachdb-parser/pkg/geo"
+	"github.com/cockroachdb/cockroachdb-parser/pkg/geo/geopb"
+	"github.com/cockroachdb/cockroachdb-parser/pkg/geo/geos"
+	"github.com/cockroachdb/cockroachdb-parser/pkg/sql/pgwire/pgcode"
+	"github.com/cockroachdb/cockroachdb-parser/pkg/sql/pgwire/pgerror"
+	"github.com/cockroachdb/errors"
+	"github.com/twpayne/go-geom"
+)
+
+// maxAllowedGridSize is the upper bound limit for a generated grid size.
+const maxAllowedGridSize = 100 * geo.MaxAllowedSplitPoints
+
+// ErrGenerateRandomPointsInvalidPoints is returned if we have a negative number of points
+// or an empty geometry.
+var ErrGenerateRandomPointsInvalidPoints = pgerror.Newf(
+	pgcode.InvalidParameterValue,
+	"points must be positive and geometry must not be empty",
+)
+
+// GenerateRandomPoints generates provided number of pseudo-random points for the input area.
+func GenerateRandomPoints(g geo.Geometry, nPoints int, rng *rand.Rand) (geo.Geometry, error) {
+	var generateRandomPointsFunction func(g geo.Geometry, nPoints int, rng *rand.Rand) (*geom.MultiPoint, error)
+	switch g.ShapeType() {
+	case geopb.ShapeType_Polygon:
+		generateRandomPointsFunction = generateRandomPointsFromPolygon
+	case geopb.ShapeType_MultiPolygon:
+		generateRandomPointsFunction = generateRandomPointsFromMultiPolygon
+	default:
+		return geo.Geometry{}, pgerror.Newf(pgcode.InvalidParameterValue, "unsupported type: %v", g.ShapeType().String())
+	}
+	if nPoints <= 0 {
+		return geo.Geometry{}, ErrGenerateRandomPointsInvalidPoints
+	}
+	if nPoints > geo.MaxAllowedSplitPoints {
+		return geo.Geometry{}, pgerror.Newf(
+			pgcode.InvalidParameterValue,
+			"failed to generate random points, too many points to generate: requires %d points, max %d",
+			nPoints,
+			geo.MaxAllowedSplitPoints,
+		)
+	}
+	empty, err := IsEmpty(g)
+	if err != nil {
+		return geo.Geometry{}, errors.Wrap(err, "could not check if geometry is empty")
+	}
+	if empty {
+		return geo.Geometry{}, ErrGenerateRandomPointsInvalidPoints
+	}
+	mpt, err := generateRandomPointsFunction(g, nPoints, rng)
+	if err != nil {
+		return geo.Geometry{}, err
+	}
+	srid := g.SRID()
+	mpt.SetSRID(int(srid))
+	out, err := geo.MakeGeometryFromGeomT(mpt)
+	if err != nil {
+		return geo.Geometry{}, errors.Wrap(err, "could not transform geom.T into geometry")
+	}
+	return out, nil
+}
+
+// generateRandomPointsFromPolygon returns a given number of randomly generated points that are within the Polygon provided.
+// In order to get more uniformed number of points, it's generating a grid, and then generating a random point within each grid cell.
+// Read more: http://lin-ear-th-inking.blogspot.com/2010/05/more-random-points-in-jts.html.
+// Rough description of the algorithm:
+// 1. Generate the grid cells. The higher number of points to generate and bounding box area/polygon area ratio, the smaller cell size.
+// 2. Shuffle the array of grid cells indexes. This way the order in which grid cells are chosen for point generation is random.
+// 3. For each grid cell, generate a random point within it. If the point intersects with our geometry, add it to the results.
+// 4. When there are enough points in the results, stop. Otherwise go to step 3.
+func generateRandomPointsFromPolygon(
+	g geo.Geometry, nPoints int, rng *rand.Rand,
+) (*geom.MultiPoint, error) {
+	area, err := Area(g)
+	if err != nil {
+		return nil, errors.Wrap(err, "could not calculate Polygon area")
+	}
+	if area == 0.0 {
+		return nil, pgerror.Newf(pgcode.InvalidParameterValue, "zero area input Polygon")
+	}
+	bbox := g.CartesianBoundingBox()
+	bboxWidth := bbox.HiX - bbox.LoX
+	bboxHeight := bbox.HiY - bbox.LoY
+	bboxArea := bboxHeight * bboxWidth
+	// Gross up our test set a bit to increase odds of getting coverage in one pass.
+	sampleNPoints := float64(nPoints) * bboxArea / area
+
+	sampleSqrt := math.Round(math.Sqrt(sampleNPoints))
+	if sampleSqrt == 0 {
+		sampleSqrt = 1
+	}
+	var sampleHeight, sampleWidth int
+	var sampleCellSize float64
+	// Calculate the grids we're going to randomize within.
+	if bboxWidth > bboxHeight {
+		sampleWidth = int(sampleSqrt)
+		sampleHeight = int(math.Ceil(sampleNPoints / float64(sampleWidth)))
+		sampleCellSize = bboxWidth / float64(sampleWidth)
+	} else {
+		sampleHeight = int(sampleSqrt)
+		sampleWidth = int(math.Ceil(sampleNPoints / float64(sampleHeight)))
+		sampleCellSize = bboxHeight / float64(sampleHeight)
+	}
+	n := sampleHeight * sampleWidth
+	if n > maxAllowedGridSize {
+		return nil, pgerror.Newf(
+			pgcode.InvalidParameterValue,
+			"generated area is too large: %d, max %d",
+			n,
+			maxAllowedGridSize,
+		)
+	}
+
+	// Prepare the polygon for fast true/false testing.
+	gPrep, err := geos.PrepareGeometry(g.EWKB())
+	if err != nil {
+		return nil, errors.Wrap(err, "could not prepare geometry")
+	}
+	defer geos.PreparedGeomDestroy(gPrep)
+
+	// Generate a slice of points - for every cell on a grid store coordinates.
+	cells := make([]geom.Coord, n)
+	for i := 0; i < sampleWidth; i++ {
+		for j := 0; j < sampleHeight; j++ {
+			cells[i*sampleHeight+j] = geom.Coord{float64(i), float64(j)}
+		}
+	}
+	// Shuffle the points. Without shuffling, the generated point will
+	// always be adjacent to the previous one (in terms of grid cells).
+	if n > 1 {
+		rng.Shuffle(n, func(i int, j int) {
+			temp := cells[j]
+			cells[j] = cells[i]
+			cells[i] = temp
+		})
+	}
+	results := geom.NewMultiPoint(geom.XY)
+	// Generate points and test them.
+	for nPointsGenerated, iterations := 0, 0; nPointsGenerated < nPoints && iterations <= 100; iterations++ {
+		for _, cell := range cells {
+			y := bbox.LoY + cell.X()*sampleCellSize
+			x := bbox.LoX + cell.Y()*sampleCellSize
+			x += rng.Float64() * sampleCellSize
+			y += rng.Float64() * sampleCellSize
+			if x > bbox.HiX || y > bbox.HiY {
+				continue
+			}
+			gpt, err := geo.MakeGeometryFromPointCoords(x, y)
+			if err != nil {
+				return nil, errors.Wrap(err, "could not create geometry Point")
+			}
+			intersects, err := geos.PreparedIntersects(gPrep, gpt.EWKB())
+			if err != nil {
+				return nil, errors.Wrap(err, "could not check prepared intersection")
+			}
+			if intersects {
+				nPointsGenerated++
+				p := geom.NewPointFlat(geom.XY, []float64{x, y})
+				srid := g.SRID()
+				p.SetSRID(int(srid))
+				err = results.Push(p)
+				if err != nil {
+					return nil, errors.Wrap(err, "could not add point to the results")
+				}
+				if nPointsGenerated == nPoints {
+					return results, nil
+				}
+			}
+		}
+	}
+	return results, nil
+}
+
+func generateRandomPointsFromMultiPolygon(
+	g geo.Geometry, nPoints int, rng *rand.Rand,
+) (*geom.MultiPoint, error) {
+	results := geom.NewMultiPoint(geom.XY)
+
+	area, err := Area(g)
+	if err != nil {
+		return nil, errors.Wrap(err, "could not calculate MultiPolygon area")
+	}
+
+	gt, err := g.AsGeomT()
+	if err != nil {
+		return nil, errors.Wrap(err, "could not transform MultiPolygon into geom.T")
+	}
+
+	gmp := gt.(*geom.MultiPolygon)
+	for i := 0; i < gmp.NumPolygons(); i++ {
+		poly := gmp.Polygon(i)
+		subarea := poly.Area()
+		subNPoints := int(math.Round(float64(nPoints) * subarea / area))
+		if subNPoints > 0 {
+			g, err := geo.MakeGeometryFromGeomT(poly)
+			if err != nil {
+				return nil, errors.Wrap(err, "could not transform geom.T into Geometry")
+			}
+			subMPT, err := generateRandomPointsFromPolygon(g, subNPoints, rng)
+			if err != nil {
+				return nil, errors.Wrap(err, "error generating points for Polygon")
+			}
+			for j := 0; j < subMPT.NumPoints(); j++ {
+				if err := results.Push(subMPT.Point(j)); err != nil {
+					return nil, errors.Wrap(err, "could not push point to the results")
+				}
+			}
+		}
+	}
+	return results, nil
+}
diff --git a/pkg/geo/geomfn/geomfn.go b/pkg/geo/geomfn/geomfn.go
new file mode 100644
index 0000000..03fdea2
--- /dev/null
+++ b/pkg/geo/geomfn/geomfn.go
@@ -0,0 +1,174 @@
+// Copyright 2020 The Cockroach Authors.
+//
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
+
+// Package geomfn contains functions that are used for geometry-based builtins.
+package geomfn
+
+import (
+	// Blank import so projections are initialized correctly.
+	_ "github.com/cockroachdb/cockroachdb-parser/pkg/geo/geographiclib"
+	"github.com/twpayne/go-geom"
+)
+
+// applyCoordFunc applies a function on src to copy onto dst.
+// Both slices represent a single Coord within the FlatCoord array.
+type applyCoordFunc func(l geom.Layout, dst []float64, src []float64) error
+
+// applyOnCoords applies the applyCoordFunc on each coordinate, returning
+// a new array for the coordinates.
+func applyOnCoords(flatCoords []float64, l geom.Layout, f applyCoordFunc) ([]float64, error) {
+	newCoords := make([]float64, len(flatCoords))
+	for i := 0; i < len(flatCoords); i += l.Stride() {
+		if err := f(l, newCoords[i:i+l.Stride()], flatCoords[i:i+l.Stride()]); err != nil {
+			return nil, err
+		}
+	}
+	return newCoords, nil
+}
+
+// applyOnCoordsForGeomT applies the applyCoordFunc on each coordinate in the geom.T,
+// returning a copied over geom.T.
+func applyOnCoordsForGeomT(g geom.T, f applyCoordFunc) (geom.T, error) {
+	if geomCollection, ok := g.(*geom.GeometryCollection); ok {
+		return applyOnCoordsForGeometryCollection(geomCollection, f)
+	}
+
+	newCoords, err := applyOnCoords(g.FlatCoords(), g.Layout(), f)
+	if err != nil {
+		return nil, err
+	}
+
+	switch t := g.(type) {
+	case *geom.Point:
+		g = geom.NewPointFlat(t.Layout(), newCoords).SetSRID(g.SRID())
+	case *geom.LineString:
+		g = geom.NewLineStringFlat(t.Layout(), newCoords).SetSRID(g.SRID())
+	case *geom.Polygon:
+		g = geom.NewPolygonFlat(t.Layout(), newCoords, t.Ends()).SetSRID(g.SRID())
+	case *geom.MultiPoint:
+		g = geom.NewMultiPointFlat(t.Layout(), newCoords, geom.NewMultiPointFlatOptionWithEnds(t.Ends())).SetSRID(g.SRID())
+	case *geom.MultiLineString:
+		g = geom.NewMultiLineStringFlat(t.Layout(), newCoords, t.Ends()).SetSRID(g.SRID())
+	case *geom.MultiPolygon:
+		g = geom.NewMultiPolygonFlat(t.Layout(), newCoords, t.Endss()).SetSRID(g.SRID())
+	default:
+		return nil, geom.ErrUnsupportedType{Value: g}
+	}
+
+	return g, nil
+}
+
+// applyOnCoordsForGeometryCollection applies the applyCoordFunc on each coordinate
+// inside a geometry collection, returning a copied over geom.T.
+func applyOnCoordsForGeometryCollection(
+	geomCollection *geom.GeometryCollection, f applyCoordFunc,
+) (*geom.GeometryCollection, error) {
+	res := geom.NewGeometryCollection()
+	for _, subG := range geomCollection.Geoms() {
+		subGeom, err := applyOnCoordsForGeomT(subG, f)
+		if err != nil {
+			return nil, err
+		}
+
+		if err := res.Push(subGeom); err != nil {
+			return nil, err
+		}
+	}
+	return res, nil
+}
+
+// removeConsecutivePointsFromGeomT removes duplicate consecutive points from a given geom.T.
+// If the resultant geometry is invalid, it will be EMPTY.
+func removeConsecutivePointsFromGeomT(t geom.T) (geom.T, error) {
+	if t.Empty() {
+		return t, nil
+	}
+	switch t := t.(type) {
+	case *geom.Point, *geom.MultiPoint:
+		return t, nil
+	case *geom.LineString:
+		newCoords := make([]float64, 0, len(t.FlatCoords()))
+		newCoords = append(newCoords, t.Coord(0)...)
+		for i := 1; i < t.NumCoords(); i++ {
+			if !t.Coord(i).Equal(t.Layout(), t.Coord(i-1)) {
+				newCoords = append(newCoords, t.Coord(i)...)
+			}
+		}
+		if len(newCoords) < t.Stride()*2 {
+			newCoords = newCoords[:0]
+		}
+		return geom.NewLineStringFlat(t.Layout(), newCoords).SetSRID(t.SRID()), nil
+	case *geom.Polygon:
+		ret := geom.NewPolygon(t.Layout()).SetSRID(t.SRID())
+		for ringIdx := 0; ringIdx < t.NumLinearRings(); ringIdx++ {
+			ring := t.LinearRing(ringIdx)
+			newCoords := make([]float64, 0, len(ring.FlatCoords()))
+			newCoords = append(newCoords, ring.Coord(0)...)
+			for i := 1; i < ring.NumCoords(); i++ {
+				if !ring.Coord(i).Equal(ring.Layout(), ring.Coord(i-1)) {
+					newCoords = append(newCoords, ring.Coord(i)...)
+				}
+			}
+			if len(newCoords) < t.Stride()*4 {
+				// If the outer ring is invalid, the polygon should be entirely empty.
+				if ringIdx == 0 {
+					return ret, nil
+				}
+				// Ignore any holes.
+				continue
+			}
+			if err := ret.Push(geom.NewLinearRingFlat(t.Layout(), newCoords)); err != nil {
+				return nil, err
+			}
+		}
+		return ret, nil
+	case *geom.MultiLineString:
+		ret := geom.NewMultiLineString(t.Layout()).SetSRID(t.SRID())
+		for i := 0; i < t.NumLineStrings(); i++ {
+			ls, err := removeConsecutivePointsFromGeomT(t.LineString(i))
+			if err != nil {
+				return nil, err
+			}
+			if ls.Empty() {
+				continue
+			}
+			if err := ret.Push(ls.(*geom.LineString)); err != nil {
+				return nil, err
+			}
+		}
+		return ret, nil
+	case *geom.MultiPolygon:
+		ret := geom.NewMultiPolygon(t.Layout()).SetSRID(t.SRID())
+		for i := 0; i < t.NumPolygons(); i++ {
+			p, err := removeConsecutivePointsFromGeomT(t.Polygon(i))
+			if err != nil {
+				return nil, err
+			}
+			if p.Empty() {
+				continue
+			}
+			if err := ret.Push(p.(*geom.Polygon)); err != nil {
+				return nil, err
+			}
+		}
+		return ret, nil
+	case *geom.GeometryCollection:
+		ret := geom.NewGeometryCollection().SetSRID(t.SRID())
+		for i := 0; i < t.NumGeoms(); i++ {
+			g, err := removeConsecutivePointsFromGeomT(t.Geom(i))
+			if err != nil {
+				return nil, err
+			}
+			if g.Empty() {
+				continue
+			}
+			if err := ret.Push(g); err != nil {
+				return nil, err
+			}
+		}
+		return ret, nil
+	}
+	return nil, geom.ErrUnsupportedType{Value: t}
+}
diff --git a/pkg/geo/geomfn/line_crossing_direction.go b/pkg/geo/geomfn/line_crossing_direction.go
new file mode 100644
index 0000000..69e759f
--- /dev/null
+++ b/pkg/geo/geomfn/line_crossing_direction.go
@@ -0,0 +1,156 @@
+// Copyright 2021 The Cockroach Authors.
+//
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
+
+package geomfn
+
+import (
+	"github.com/cockroachdb/cockroachdb-parser/pkg/geo"
+	"github.com/cockroachdb/cockroachdb-parser/pkg/sql/pgwire/pgcode"
+	"github.com/cockroachdb/cockroachdb-parser/pkg/sql/pgwire/pgerror"
+	"github.com/twpayne/go-geom"
+)
+
+// lineCrossingDirection corresponds to integer defining particular direction.
+type lineCrossingDirection int
+
+// LineCrossingDirectionValue maps to the return value of
+// ST_LineCrossingDirection from PostGIS.
+type LineCrossingDirectionValue int
+
+// Assigning constant integer values to variables for different crossing behavior and directions
+// throughout the functions.
+const (
+	LineNoCross                    LineCrossingDirectionValue = 0
+	LineCrossLeft                  LineCrossingDirectionValue = -1
+	LineCrossRight                 LineCrossingDirectionValue = 1
+	LineMultiCrossToLeft           LineCrossingDirectionValue = -2
+	LineMultiCrossToRight          LineCrossingDirectionValue = 2
+	LineMultiCrossToSameFirstLeft  LineCrossingDirectionValue = -3
+	LineMultiCrossToSameFirstRight LineCrossingDirectionValue = 3
+
+	leftDir            lineCrossingDirection = -1
+	noCrossOrCollinear lineCrossingDirection = 0
+	rightDir           lineCrossingDirection = 1
+
+	inLeft      lineCrossingDirection = -1
+	isCollinear lineCrossingDirection = 0
+	inRight     lineCrossingDirection = 1
+)
+
+// getPosition takes 3 points and returns the direction of third point from segment formed by first point and second point.
+func getPosition(fromSeg, toSeg, givenPoint geom.Coord) lineCrossingDirection {
+
+	// crossProductValueInZ is value of Cross Product of two vectors in z axis direction where
+	// first vector is from givenPoint to toSeg and second vector is from givenPoint to fromSeg.
+	crossProductValueInZ := (toSeg.X()-givenPoint.X())*(fromSeg.Y()-givenPoint.Y()) - (toSeg.Y()-givenPoint.Y())*(fromSeg.X()-givenPoint.X())
+
+	if crossProductValueInZ < 0 {
+		return inLeft
+	}
+	if crossProductValueInZ > 0 {
+		return inRight
+	}
+	return isCollinear
+}
+
+// getSegCrossDirection takes 4 points and returns the crossing direction of second segment over first segment
+// first segment is formed by first 2 points whereas second segment is formed by next 2 points.
+func getSegCrossDirection(fromSeg1, toSeg1, fromSeg2, toSeg2 geom.Coord) lineCrossingDirection {
+	posF1FromSeg2 := getPosition(fromSeg2, toSeg2, fromSeg1)
+	posT1FromSeg2 := getPosition(fromSeg2, toSeg2, toSeg1)
+
+	posF2FromSeg1 := getPosition(fromSeg1, toSeg1, fromSeg2)
+	posT2FromSeg1 := getPosition(fromSeg1, toSeg1, toSeg2)
+
+	// If both point of any segment is on same side of other segment
+	// or second point of any segment is collinear with other segment
+	// then return the value as noCrossOrCollinear else return the direction of segment2 over segment1.
+	// To avoid double counting, collinearity condition is used with second points only.
+	if posF1FromSeg2 == posT1FromSeg2 || posF2FromSeg1 == posT2FromSeg1 ||
+		posT1FromSeg2 == isCollinear || posT2FromSeg1 == isCollinear {
+		return noCrossOrCollinear
+	}
+	return posT2FromSeg1
+}
+
+// LineCrossingDirection takes two lines and returns an integer value defining behavior of crossing of lines:
+// 0: lines do not cross,
+// -1: line2 crosses line1 from right to left,
+// 1: line2 crosses line1 from left to right,
+// -2: line2 crosses line1 multiple times from right to left,
+// 2: line2 crosses line1 multiple times from left to right,
+// -3: line2 crosses line1 multiple times from left to left,
+// 3: line2 crosses line1 multiple times from right to Right.
+// Note that the top vertex of the segment touching another line does not count as a crossing,
+// but the bottom vertex of segment touching another line is considered a crossing.
+func LineCrossingDirection(geometry1, geometry2 geo.Geometry) (LineCrossingDirectionValue, error) {
+
+	t1, err1 := geometry1.AsGeomT()
+	if err1 != nil {
+		return 0, err1
+	}
+
+	t2, err2 := geometry2.AsGeomT()
+	if err2 != nil {
+		return 0, err2
+	}
+
+	g1, ok1 := t1.(*geom.LineString)
+	g2, ok2 := t2.(*geom.LineString)
+
+	if !ok1 || !ok2 {
+		return 0, pgerror.Newf(pgcode.InvalidParameterValue, "arguments must be LINESTRING")
+	}
+
+	line1, line2 := g1.Coords(), g2.Coords()
+
+	firstSegCrossDirection := noCrossOrCollinear
+	countDirection := make(map[lineCrossingDirection]int)
+
+	// Iterating segment2 over line2 from tail to head.
+	for idx2 := 1; idx2 < len(line2); idx2++ {
+		fromSeg2, toSeg2 := line2[idx2-1], line2[idx2]
+
+		// Iterating segment1 over line1 from tail to head.
+		for idx1 := 1; idx1 < len(line1); idx1++ {
+			fromSeg1, toSeg1 := line1[idx1-1], line1[idx1]
+
+			// segCrossDirection is current crossing direction of segment2 over segment1.
+			segCrossDirection := getSegCrossDirection(fromSeg1, toSeg1, fromSeg2, toSeg2)
+			// update count of current crossing direction.
+			countDirection[segCrossDirection]++
+
+			// firstSegCrossDirection keeps direction of first segment2 which cross over segment1.
+			if firstSegCrossDirection == noCrossOrCollinear {
+				firstSegCrossDirection = segCrossDirection
+			}
+		}
+	}
+
+	if countDirection[leftDir] == 0 && countDirection[rightDir] == 0 {
+		return LineNoCross, nil
+	}
+	if countDirection[leftDir] == 1 && countDirection[rightDir] == 0 {
+		return LineCrossLeft, nil
+	}
+	if countDirection[leftDir] == 0 && countDirection[rightDir] == 1 {
+		return LineCrossRight, nil
+	}
+	if countDirection[leftDir]-countDirection[rightDir] == 1 {
+		return LineMultiCrossToLeft, nil
+	}
+	if countDirection[rightDir]-countDirection[leftDir] == 1 {
+		return LineMultiCrossToRight, nil
+	}
+	if countDirection[leftDir] == countDirection[rightDir] {
+
+		if firstSegCrossDirection == leftDir {
+			return LineMultiCrossToSameFirstLeft, nil
+		}
+		return LineMultiCrossToSameFirstRight, nil
+	}
+
+	return LineNoCross, nil
+}
diff --git a/pkg/geo/geomfn/linear_reference.go b/pkg/geo/geomfn/linear_reference.go
new file mode 100644
index 0000000..b195138
--- /dev/null
+++ b/pkg/geo/geomfn/linear_reference.go
@@ -0,0 +1,69 @@
+// Copyright 2020 The Cockroach Authors.
+//
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
+
+package geomfn
+
+import (
+	"github.com/cockroachdb/cockroachdb-parser/pkg/geo"
+	"github.com/cockroachdb/cockroachdb-parser/pkg/geo/geos"
+	"github.com/cockroachdb/cockroachdb-parser/pkg/sql/pgwire/pgcode"
+	"github.com/cockroachdb/cockroachdb-parser/pkg/sql/pgwire/pgerror"
+	"github.com/twpayne/go-geom"
+	"github.com/twpayne/go-geom/encoding/ewkb"
+)
+
+// LineInterpolatePoints returns one or more points along the given
+// LineString which are at an integral multiples of given fraction of
+// LineString's total length. When repeat is set to false, it returns
+// the first point.
+func LineInterpolatePoints(g geo.Geometry, fraction float64, repeat bool) (geo.Geometry, error) {
+	if fraction < 0 || fraction > 1 {
+		return geo.Geometry{}, pgerror.Newf(pgcode.InvalidParameterValue, "fraction %f should be within [0 1] range", fraction)
+	}
+	geomRepr, err := g.AsGeomT()
+	if err != nil {
+		return geo.Geometry{}, err
+	}
+	switch geomRepr := geomRepr.(type) {
+	case *geom.LineString:
+		// In case fraction is greater than 0.5 or equal to 0 or repeat is false,
+		// then we will have only one interpolated point.
+		lengthOfLineString := geomRepr.Length()
+		if repeat && fraction <= 0.5 && fraction != 0 {
+			numberOfInterpolatedPoints := int(1 / fraction)
+			if numberOfInterpolatedPoints > geo.MaxAllowedSplitPoints {
+				return geo.Geometry{}, pgerror.Newf(
+					pgcode.InvalidParameterValue,
+					"attempting to interpolate into too many points; requires %d points, max %d",
+					numberOfInterpolatedPoints,
+					geo.MaxAllowedSplitPoints,
+				)
+			}
+			interpolatedPoints := geom.NewMultiPoint(geom.XY).SetSRID(geomRepr.SRID())
+			for pointInserted := 1; pointInserted <= numberOfInterpolatedPoints; pointInserted++ {
+				pointEWKB, err := geos.InterpolateLine(g.EWKB(), float64(pointInserted)*fraction*lengthOfLineString)
+				if err != nil {
+					return geo.Geometry{}, err
+				}
+				point, err := ewkb.Unmarshal(pointEWKB)
+				if err != nil {
+					return geo.Geometry{}, err
+				}
+				err = interpolatedPoints.Push(point.(*geom.Point))
+				if err != nil {
+					return geo.Geometry{}, err
+				}
+			}
+			return geo.MakeGeometryFromGeomT(interpolatedPoints)
+		}
+		interpolatedPointEWKB, err := geos.InterpolateLine(g.EWKB(), fraction*lengthOfLineString)
+		if err != nil {
+			return geo.Geometry{}, err
+		}
+		return geo.ParseGeometryFromEWKB(interpolatedPointEWKB)
+	default:
+		return geo.Geometry{}, pgerror.Newf(pgcode.InvalidParameterValue, "geometry %s should be LineString", g.ShapeType())
+	}
+}
diff --git a/pkg/geo/geomfn/linestring.go b/pkg/geo/geomfn/linestring.go
new file mode 100644
index 0000000..b4978c2
--- /dev/null
+++ b/pkg/geo/geomfn/linestring.go
@@ -0,0 +1,360 @@
+// Copyright 2020 The Cockroach Authors.
+//
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
+
+package geomfn
+
+import (
+	"github.com/cockroachdb/cockroachdb-parser/pkg/geo"
+	"github.com/cockroachdb/cockroachdb-parser/pkg/geo/geos"
+	"github.com/cockroachdb/cockroachdb-parser/pkg/sql/pgwire/pgcode"
+	"github.com/cockroachdb/cockroachdb-parser/pkg/sql/pgwire/pgerror"
+	"github.com/cockroachdb/errors"
+	"github.com/twpayne/go-geom"
+	"github.com/twpayne/go-geom/encoding/ewkb"
+)
+
+// LineStringFromMultiPoint generates a linestring from a multipoint.
+func LineStringFromMultiPoint(g geo.Geometry) (geo.Geometry, error) {
+	t, err := g.AsGeomT()
+	if err != nil {
+		return geo.Geometry{}, err
+	}
+	mp, ok := t.(*geom.MultiPoint)
+	if !ok {
+		return geo.Geometry{}, errors.Wrap(geom.ErrUnsupportedType{Value: t},
+			"geometry must be a MultiPoint")
+	}
+	if mp.NumPoints() == 1 {
+		return geo.Geometry{}, pgerror.Newf(pgcode.InvalidParameterValue, "a LineString must have at least 2 points")
+	}
+	flatCoords := make([]float64, 0, mp.NumCoords()*mp.Stride())
+	var prevPoint *geom.Point
+	for i := 0; i < mp.NumPoints(); i++ {
+		p := mp.Point(i)
+		// Empty points in multipoints are replaced by the previous point.
+		// If the previous point does not exist, we append (0, 0, ...) coordinates.
+		if p.Empty() {
+			if prevPoint == nil {
+				prevPoint = geom.NewPointFlat(mp.Layout(), make([]float64, mp.Stride()))
+			}
+			flatCoords = append(flatCoords, prevPoint.FlatCoords()...)
+			continue
+		}
+		flatCoords = append(flatCoords, p.FlatCoords()...)
+		prevPoint = p
+	}
+	lineString := geom.NewLineStringFlat(mp.Layout(), flatCoords).SetSRID(mp.SRID())
+	return geo.MakeGeometryFromGeomT(lineString)
+}
+
+// LineMerge merges multilinestring constituents.
+func LineMerge(g geo.Geometry) (geo.Geometry, error) {
+	// Mirrors PostGIS behavior
+	if g.Empty() {
+		return g, nil
+	}
+	if BoundingBoxHasInfiniteCoordinates(g) {
+		return geo.Geometry{}, pgerror.Newf(pgcode.InvalidParameterValue, "value out of range: overflow")
+	}
+	ret, err := geos.LineMerge(g.EWKB())
+	if err != nil {
+		return geo.Geometry{}, err
+	}
+	return geo.ParseGeometryFromEWKB(ret)
+}
+
+// LineLocatePoint returns a float between 0 and 1 representing the location of the
+// closest point on LineString to the given Point, as a fraction of total 2d line length.
+func LineLocatePoint(line geo.Geometry, point geo.Geometry) (float64, error) {
+	lineT, err := line.AsGeomT()
+	if err != nil {
+		return 0, err
+	}
+	lineString, ok := lineT.(*geom.LineString)
+	if !ok {
+		return 0, pgerror.Newf(pgcode.InvalidParameterValue,
+			"first parameter has to be of type LineString")
+	}
+
+	// compute closest point on line to the given point
+	closestPoint, err := ClosestPoint(line, point)
+	if err != nil {
+		return 0, err
+	}
+	closestT, err := closestPoint.AsGeomT()
+	if err != nil {
+		return 0, err
+	}
+
+	p := closestT.(*geom.Point)
+	lineStart := geom.Coord{lineString.Coord(0).X(), lineString.Coord(0).Y()}
+	// build new line segment to the closest point we found
+	lineSegment := geom.NewLineString(geom.XY).MustSetCoords([]geom.Coord{lineStart, p.Coords()})
+
+	// compute fraction of new line segment compared to total line length
+	return lineSegment.Length() / lineString.Length(), nil
+}
+
+// AddPoint adds a point to a LineString at the given 0-based index. -1 appends.
+func AddPoint(lineString geo.Geometry, index int, point geo.Geometry) (geo.Geometry, error) {
+	g, err := lineString.AsGeomT()
+	if err != nil {
+		return geo.Geometry{}, err
+	}
+	lineStringG, ok := g.(*geom.LineString)
+	if !ok {
+		e := geom.ErrUnsupportedType{Value: g}
+		return geo.Geometry{}, errors.Wrap(e, "geometry to be modified must be a LineString")
+	}
+
+	g, err = point.AsGeomT()
+	if err != nil {
+		return geo.Geometry{}, err
+	}
+
+	pointG, ok := g.(*geom.Point)
+	if !ok {
+		e := geom.ErrUnsupportedType{Value: g}
+		return geo.Geometry{}, errors.Wrapf(e, "invalid geometry used to add a Point to a LineString")
+	}
+
+	g, err = addPoint(lineStringG, index, pointG)
+	if err != nil {
+		return geo.Geometry{}, err
+	}
+
+	return geo.MakeGeometryFromGeomT(g)
+}
+
+func addPoint(lineString *geom.LineString, index int, point *geom.Point) (*geom.LineString, error) {
+	if lineString.Layout() != point.Layout() {
+		return nil, pgerror.WithCandidateCode(
+			geom.ErrLayoutMismatch{Got: point.Layout(), Want: lineString.Layout()},
+			pgcode.InvalidParameterValue,
+		)
+	}
+	if point.Empty() {
+		point = geom.NewPointFlat(point.Layout(), make([]float64, point.Stride()))
+	}
+
+	coords := lineString.Coords()
+
+	if index > len(coords) {
+		return nil, pgerror.Newf(pgcode.InvalidParameterValue, "index %d out of range of LineString with %d coordinates",
+			index, len(coords))
+	} else if index == -1 {
+		index = len(coords)
+	} else if index < 0 {
+		return nil, pgerror.Newf(pgcode.InvalidParameterValue, "invalid index %v", index)
+	}
+
+	// Shift the slice right by one element, then replace the element at the index, to avoid
+	// allocating an additional slice.
+	coords = append(coords, geom.Coord{})
+	copy(coords[index+1:], coords[index:])
+	coords[index] = point.Coords()
+
+	return lineString.SetCoords(coords)
+}
+
+// SetPoint sets the point at the given index of lineString; index is 0-based.
+func SetPoint(lineString geo.Geometry, index int, point geo.Geometry) (geo.Geometry, error) {
+	g, err := lineString.AsGeomT()
+	if err != nil {
+		return geo.Geometry{}, err
+	}
+
+	lineStringG, ok := g.(*geom.LineString)
+	if !ok {
+		e := geom.ErrUnsupportedType{Value: g}
+		return geo.Geometry{}, errors.Wrap(e, "geometry to be modified must be a LineString")
+	}
+
+	g, err = point.AsGeomT()
+	if err != nil {
+		return geo.Geometry{}, err
+	}
+
+	pointG, ok := g.(*geom.Point)
+	if !ok {
+		e := geom.ErrUnsupportedType{Value: g}
+		return geo.Geometry{}, errors.Wrapf(e, "invalid geometry used to replace a Point on a LineString")
+	}
+
+	g, err = setPoint(lineStringG, index, pointG)
+	if err != nil {
+		return geo.Geometry{}, err
+	}
+
+	return geo.MakeGeometryFromGeomT(g)
+}
+
+func setPoint(lineString *geom.LineString, index int, point *geom.Point) (*geom.LineString, error) {
+	if lineString.Layout() != point.Layout() {
+		return nil, geom.ErrLayoutMismatch{Got: point.Layout(), Want: lineString.Layout()}
+	}
+	if point.Empty() {
+		point = geom.NewPointFlat(point.Layout(), make([]float64, point.Stride()))
+	}
+
+	coords := lineString.Coords()
+	hasNegIndex := index < 0
+
+	if index >= len(coords) || (hasNegIndex && index*-1 > len(coords)) {
+		return nil, pgerror.Newf(pgcode.InvalidParameterValue, "index %d out of range of LineString with %d coordinates", index, len(coords))
+	}
+
+	if hasNegIndex {
+		index = len(coords) + index
+	}
+
+	coords[index].Set(point.Coords())
+
+	return lineString.SetCoords(coords)
+}
+
+// RemovePoint removes the point at the given index of lineString; index is 0-based.
+func RemovePoint(lineString geo.Geometry, index int) (geo.Geometry, error) {
+	g, err := lineString.AsGeomT()
+	if err != nil {
+		return geo.Geometry{}, err
+	}
+
+	lineStringG, ok := g.(*geom.LineString)
+	if !ok {
+		e := geom.ErrUnsupportedType{Value: g}
+		return geo.Geometry{}, errors.Wrap(e, "geometry to be modified must be a LineString")
+	}
+
+	if lineStringG.NumCoords() == 2 {
+		return geo.Geometry{}, pgerror.Newf(pgcode.InvalidParameterValue, "cannot remove a point from a LineString with only two Points")
+	}
+
+	g, err = removePoint(lineStringG, index)
+	if err != nil {
+		return geo.Geometry{}, err
+	}
+
+	return geo.MakeGeometryFromGeomT(g)
+}
+
+func removePoint(lineString *geom.LineString, index int) (*geom.LineString, error) {
+	coords := lineString.Coords()
+
+	if index >= len(coords) || index < 0 {
+		return nil, pgerror.Newf(pgcode.InvalidParameterValue, "index %d out of range of LineString with %d coordinates", index, len(coords))
+	}
+
+	coords = append(coords[:index], coords[index+1:]...)
+
+	return lineString.SetCoords(coords)
+}
+
+// LineSubstring returns a LineString being a substring by start and end
+func LineSubstring(g geo.Geometry, start, end float64) (geo.Geometry, error) {
+	if start < 0 || start > 1 || end < 0 || end > 1 {
+		return g, pgerror.Newf(pgcode.InvalidParameterValue,
+			"start and and must be within 0 and 1")
+	}
+	if start > end {
+		return g, pgerror.Newf(pgcode.InvalidParameterValue,
+			"end must be greater or equal to the start")
+	}
+
+	lineT, err := g.AsGeomT()
+	if err != nil {
+		return g, err
+	}
+	lineString, ok := lineT.(*geom.LineString)
+	if !ok {
+		return g, pgerror.Newf(pgcode.InvalidParameterValue,
+			"geometry has to be of type LineString")
+	}
+	if lineString.Empty() {
+		return geo.MakeGeometryFromGeomT(
+			geom.NewLineString(geom.XY).SetSRID(lineString.SRID()),
+		)
+	}
+	if start == end {
+		return LineInterpolatePoints(g, start, false)
+	}
+
+	lsLength := lineString.Length()
+	// A LineString which entirely consistent of the same point has length 0
+	// and should return the single point that represents it.
+	if lsLength == 0 {
+		return geo.MakeGeometryFromGeomT(
+			geom.NewPointFlat(geom.XY, lineString.FlatCoords()[0:2]).SetSRID(lineString.SRID()),
+		)
+	}
+
+	var newFlatCoords []float64
+	// The algorithm roughly as follows.
+	// * For each line segment, first find whether we have exceeded the start distance.
+	//   If we have, interpolate the point on that LineString that represents the start point.
+	// * Keep adding points until we have we reach the segment where the entire LineString
+	//   exceeds the max distance.
+	//   We then interpolate the end point on the last segment of the LineString.
+	startDistance, endDistance := start*lsLength, end*lsLength
+	for i := range lineString.Coords() {
+		currentLineString, err := geom.NewLineString(geom.XY).SetCoords(lineString.Coords()[0 : i+1])
+		if err != nil {
+			return geo.Geometry{}, err
+		}
+		// If the current distance exceeds the end distance, find the last point and
+		// terminate the loop early.
+		if currentLineString.Length() >= endDistance {
+			// If we have not added coordinates to the LineString, it means the
+			// current segment starts and ends on the current line segment.
+			// Interpolate the start position.
+			if len(newFlatCoords) == 0 {
+				coords, err := interpolateFlatCoordsFromDistance(g, startDistance)
+				if err != nil {
+					return geo.Geometry{}, err
+				}
+				newFlatCoords = append(newFlatCoords, coords...)
+			}
+
+			coords, err := interpolateFlatCoordsFromDistance(g, endDistance)
+			if err != nil {
+				return geo.Geometry{}, err
+			}
+			newFlatCoords = append(newFlatCoords, coords...)
+			break
+		}
+		// If we are past the start distance, check if we already have points
+		// in the LineString.
+		if currentLineString.Length() >= startDistance {
+			if len(newFlatCoords) == 0 {
+				// If this is our first point, interpolate the first point.
+				coords, err := interpolateFlatCoordsFromDistance(g, startDistance)
+				if err != nil {
+					return geo.Geometry{}, err
+				}
+				newFlatCoords = append(newFlatCoords, coords...)
+			}
+
+			// Add the current point if it is not the same as the previous point.
+			prevCoords := geom.Coord(newFlatCoords[len(newFlatCoords)-2:])
+			if !currentLineString.Coord(i).Equal(geom.XY, prevCoords) {
+				newFlatCoords = append(newFlatCoords, currentLineString.Coord(i)...)
+			}
+		}
+	}
+	return geo.MakeGeometryFromGeomT(geom.NewLineStringFlat(geom.XY, newFlatCoords).SetSRID(lineString.SRID()))
+}
+
+// interpolateFlatCoordsFromDistance interpolates the geometry at a given distance and returns its flat coordinates.
+func interpolateFlatCoordsFromDistance(g geo.Geometry, distance float64) ([]float64, error) {
+	pointEWKB, err := geos.InterpolateLine(g.EWKB(), distance)
+	if err != nil {
+		return []float64{}, err
+	}
+	point, err := ewkb.Unmarshal(pointEWKB)
+	if err != nil {
+		return []float64{}, err
+	}
+	return point.FlatCoords(), nil
+}
diff --git a/pkg/geo/geomfn/make_geometry.go b/pkg/geo/geomfn/make_geometry.go
new file mode 100644
index 0000000..2ece269
--- /dev/null
+++ b/pkg/geo/geomfn/make_geometry.go
@@ -0,0 +1,95 @@
+// Copyright 2020 The Cockroach Authors.
+//
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
+
+package geomfn
+
+import (
+	"github.com/cockroachdb/cockroachdb-parser/pkg/geo"
+	"github.com/cockroachdb/cockroachdb-parser/pkg/geo/geopb"
+	"github.com/cockroachdb/cockroachdb-parser/pkg/sql/pgwire/pgcode"
+	"github.com/cockroachdb/cockroachdb-parser/pkg/sql/pgwire/pgerror"
+	"github.com/twpayne/go-geom"
+)
+
+// MakePolygon creates a Polygon geometry from linestring and optional inner linestrings.
+// Returns errors if geometries are not linestrings.
+func MakePolygon(outer geo.Geometry, interior ...geo.Geometry) (geo.Geometry, error) {
+	layout := geom.XY
+	outerGeomT, err := outer.AsGeomT()
+	if err != nil {
+		return geo.Geometry{}, err
+	}
+	outerRing, ok := outerGeomT.(*geom.LineString)
+	if !ok {
+		return geo.Geometry{}, pgerror.Newf(pgcode.InvalidParameterValue, "argument must be LINESTRING geometries")
+	}
+	if outerRing.Empty() {
+		return geo.Geometry{}, pgerror.Newf(pgcode.InvalidParameterValue, "polygon shell must not be empty")
+	}
+	srid := outerRing.SRID()
+	coords := make([][]geom.Coord, len(interior)+1)
+	coords[0] = outerRing.Coords()
+	for i, g := range interior {
+		interiorRingGeomT, err := g.AsGeomT()
+		if err != nil {
+			return geo.Geometry{}, err
+		}
+		interiorRing, ok := interiorRingGeomT.(*geom.LineString)
+		if !ok {
+			return geo.Geometry{}, pgerror.Newf(pgcode.InvalidParameterValue, "argument must be LINESTRING geometries")
+		}
+		if interiorRing.SRID() != srid {
+			return geo.Geometry{}, pgerror.Newf(pgcode.InvalidParameterValue, "mixed SRIDs are not allowed")
+		}
+		if outerRing.Layout() != interiorRing.Layout() {
+			return geo.Geometry{}, pgerror.Newf(pgcode.InvalidParameterValue, "mixed dimension rings")
+		}
+		coords[i+1] = interiorRing.Coords()
+	}
+
+	polygon, err := geom.NewPolygon(layout).SetSRID(srid).SetCoords(coords)
+	if err != nil {
+		return geo.Geometry{}, err
+	}
+	return geo.MakeGeometryFromGeomT(polygon)
+}
+
+// MakePolygonWithSRID is like MakePolygon but also sets the SRID, like ST_Polygon.
+func MakePolygonWithSRID(g geo.Geometry, srid int) (geo.Geometry, error) {
+	polygon, err := MakePolygon(g)
+	if err != nil {
+		return geo.Geometry{}, err
+	}
+	t, err := polygon.AsGeomT()
+	if err != nil {
+		return geo.Geometry{}, err
+	}
+	geo.AdjustGeomTSRID(t, geopb.SRID(srid))
+	return geo.MakeGeometryFromGeomT(t)
+}
+
+// Takes a multilinestring input and converts it to a slice of linestrings to call MakePolygon.
+// Returns error if input is not a single multilinestring.
+func MakePolygonFromMultiLineString(g geo.Geometry, srid geopb.SRID) (geo.Geometry, error) {
+	geomT, err := g.AsGeomT()
+	if err != nil {
+		return geo.Geometry{}, err
+	}
+	lsCollection, ok := geomT.(*geom.MultiLineString)
+	if !ok {
+		return geo.Geometry{}, pgerror.Newf(pgcode.InvalidParameterValue, "argument must be MULTILINESTRING geometry")
+	}
+	linestrings := make([]geo.Geometry, lsCollection.NumLineStrings())
+	for i := 0; i < lsCollection.NumLineStrings(); i++ {
+		lineStringT := lsCollection.LineString(i)
+		geo.AdjustGeomTSRID(lineStringT, srid)
+		ls, err := geo.MakeGeometryFromGeomT(lineStringT)
+		if err != nil {
+			return geo.Geometry{}, err
+		}
+		linestrings[i] = ls
+	}
+	return MakePolygon(linestrings[0], linestrings[1:]...)
+}
diff --git a/pkg/geo/geomfn/mvtgeom.go b/pkg/geo/geomfn/mvtgeom.go
new file mode 100644
index 0000000..d2c6149
--- /dev/null
+++ b/pkg/geo/geomfn/mvtgeom.go
@@ -0,0 +1,309 @@
+// Copyright 2023 The Cockroach Authors.
+//
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
+
+package geomfn
+
+import (
+	"github.com/cockroachdb/cockroachdb-parser/pkg/geo"
+	"github.com/cockroachdb/cockroachdb-parser/pkg/geo/geopb"
+	"github.com/cockroachdb/cockroachdb-parser/pkg/sql/pgwire/pgcode"
+	"github.com/cockroachdb/cockroachdb-parser/pkg/sql/pgwire/pgerror"
+	"github.com/cockroachdb/errors"
+	"github.com/twpayne/go-geom"
+)
+
+// AsMVTGeometry returns a geometry converted into Mapbox Vector Tile coordinate
+// space.
+func AsMVTGeometry(
+	g geo.Geometry, bounds geo.CartesianBoundingBox, extent int, buffer int, clipGeometry bool,
+) (geo.Geometry, error) {
+	bbox := bounds.BoundingBox
+	err := validateInputParams(bbox, extent, buffer)
+	if err != nil {
+		return geo.Geometry{}, err
+	}
+	gt, err := g.AsGeomT()
+	if err != nil {
+		return geo.Geometry{}, errors.Wrap(err, "failed to convert geometry to geom.T")
+	}
+	if geometrySmallerThanHalfBoundingBox(gt, bbox, extent) {
+		return geo.Geometry{}, nil
+	}
+
+	return transformToMVTGeom(gt, g, bbox, extent, buffer, clipGeometry)
+}
+
+func validateInputParams(bbox geopb.BoundingBox, extent int, buffer int) error {
+	if bbox.HiX-bbox.LoX <= 0 || bbox.HiY-bbox.LoY <= 0 {
+		return pgerror.New(pgcode.InvalidParameterValue, "geometric bounds are too small")
+	}
+	if extent <= 0 {
+		return pgerror.New(pgcode.InvalidParameterValue, "extent must be greater than 0")
+	}
+	if buffer < 0 {
+		return pgerror.New(pgcode.InvalidParameterValue, "buffer value cannot be negative")
+	}
+	return nil
+}
+
+func geometrySmallerThanHalfBoundingBox(gt geom.T, bbox geopb.BoundingBox, extent int) bool {
+	switch gt := gt.(type) {
+	// Don't check GeometryCollection so that we don't discard a collection of points.
+	case *geom.LineString, *geom.MultiLineString, *geom.Polygon, *geom.MultiPolygon:
+		geometryBoundingBox := gt.Bounds()
+		geomWidth := geometryBoundingBox.Max(0) - geometryBoundingBox.Min(0)
+		geomHeight := geometryBoundingBox.Max(1) - geometryBoundingBox.Min(1)
+		// We use half of the square height and width as limit instead of area so it works properly with lines.
+		halfBoundsWidth := ((bbox.HiX - bbox.LoX) / float64(extent)) / 2
+		halfBoundsHeight := ((bbox.HiY - bbox.LoY) / float64(extent)) / 2
+		if geomWidth < halfBoundsWidth && geomHeight < halfBoundsHeight {
+			return true
+		}
+	}
+	return false
+}
+
+// transformToMVTGeom transforms a geometry into vector tile coordinate space.
+func transformToMVTGeom(
+	gt geom.T, g geo.Geometry, bbox geopb.BoundingBox, extent int, buffer int, clipGeometry bool,
+) (geo.Geometry, error) {
+	basicType, err := getBasicType(gt)
+	if err != nil {
+		return geo.Geometry{}, errors.Wrap(err, "failed to get geom.T basic type")
+	}
+	basicTypeGeometry, err := convertToBasicType(g, basicType)
+	if err != nil {
+		return geo.Geometry{}, errors.Wrap(err, "failed to convert geometry to basic type")
+	}
+	if basicTypeGeometry.Empty() {
+		return geo.Geometry{}, nil
+	}
+
+	removeRepeatedPointsGeometry, err := RemoveRepeatedPoints(basicTypeGeometry, 0)
+	if err != nil {
+		return geo.Geometry{}, errors.Wrap(err, "failed to remove repeated points")
+	}
+	// Remove points on straight lines
+	simplifiedGeometry, empty, err := Simplify(removeRepeatedPointsGeometry, 0, false)
+	if err != nil {
+		return geo.Geometry{}, errors.Wrap(err, "failed to simplify geometry")
+	}
+	if empty {
+		return geo.Geometry{}, nil
+	}
+
+	affinedGeometry, err := transformToTileCoordinateSpace(simplifiedGeometry, bbox, extent)
+	if err != nil {
+		return geo.Geometry{}, err
+	}
+
+	snappedGeometry, err := snapToIntegersGrid(affinedGeometry)
+	if err != nil {
+		return geo.Geometry{}, err
+	}
+
+	out, err := clipAndValidateMVTOutput(snappedGeometry, basicType, extent, buffer, clipGeometry)
+	if err != nil {
+		return geo.Geometry{}, errors.Wrap(err, "failed to clip and validate")
+	}
+	if out.Empty() {
+		return geo.Geometry{}, nil
+	}
+	return out, nil
+}
+
+func transformToTileCoordinateSpace(
+	g geo.Geometry, bbox geopb.BoundingBox, extent int,
+) (geo.Geometry, error) {
+	width := bbox.HiX - bbox.LoX
+	height := bbox.HiY - bbox.LoY
+	fx := float64(extent) / width
+	fy := -float64(extent) / height
+	affineMatrix := AffineMatrix{
+		{fx, 0, 0, -bbox.LoX * fx},
+		{0, fy, 0, -bbox.HiY * fy},
+		{0, 0, 1, 0},
+		{0, 0, 0, 1},
+	}
+	affinedGeometry, err := Affine(g, affineMatrix)
+	if err != nil {
+		return geo.Geometry{}, errors.Wrap(err, "failed to affine geometry")
+	}
+	return affinedGeometry, nil
+}
+
+// clipAndValidateMVTOutput prepares the geometry so that it's clipped (if needed), valid, snapped to grid and it's basic type is the same as the input geometry.
+func clipAndValidateMVTOutput(
+	g geo.Geometry, inputBasicType geopb.ShapeType, extent int, buffer int, clipGeometry bool,
+) (geo.Geometry, error) {
+	var err error
+	if clipGeometry && !g.Empty() {
+		bbox := *g.CartesianBoundingBox()
+		bbox.HiX = overwriteMinusZero(float64(extent) + float64(buffer))
+		bbox.HiY = overwriteMinusZero(float64(extent) + float64(buffer))
+		bbox.LoX = overwriteMinusZero(-float64(buffer))
+		bbox.LoY = overwriteMinusZero(-float64(buffer))
+		g, err = ClipByRect(g, bbox)
+		if err != nil {
+			return geo.Geometry{}, errors.Wrap(err, "failed to clip geometry")
+		}
+	}
+	g, err = snapToGridAndValidate(g, inputBasicType)
+	if err != nil {
+		return geo.Geometry{}, errors.Wrap(err, "failed to grid and validate")
+	}
+	outputGt, err := g.AsGeomT()
+	if err != nil {
+		return geo.Geometry{}, errors.Wrap(err, "failed to convert geometry into geom.T")
+	}
+	outputBasicType, err := getBasicType(outputGt)
+	if err != nil {
+		return geo.Geometry{}, err
+	}
+	if inputBasicType != outputBasicType {
+		return geo.Geometry{}, errors.New("geometry dropped because of output type change")
+	}
+	return g, nil
+}
+
+func snapToGridAndValidate(g geo.Geometry, basicType geopb.ShapeType) (geo.Geometry, error) {
+	var err error
+	g, err = convertToBasicType(g, basicType)
+	if err != nil {
+		return geo.Geometry{}, errors.Wrap(err, "failed to convert to basic type")
+	}
+	if basicType != geopb.ShapeType_Polygon {
+		snappedGeometry, err := snapToIntegersGrid(g)
+		if err != nil {
+			return geo.Geometry{}, err
+		}
+		return snappedGeometry, nil
+	}
+	return snapToGridAndValidateBasicPolygon(g, basicType)
+}
+
+// snapToGridAndValidateBasicPolygon snaps to the integer grid and force validation.
+// Since snapping to the grid can create an invalid geometry and making it valid can create float values,
+// we iterate up to 3 times to generate a valid geometry with integer coordinates.
+func snapToGridAndValidateBasicPolygon(
+	g geo.Geometry, basicType geopb.ShapeType,
+) (geo.Geometry, error) {
+	iterations := 0
+	const maxIterations = 3
+	valid := false
+
+	var err error
+	g, err = snapToIntegersGrid(g)
+	if err != nil {
+		return geo.Geometry{}, err
+	}
+	valid, err = IsValid(g)
+	if err != nil {
+		return geo.Geometry{}, errors.Wrap(err, "failed to check validity")
+	}
+	for !valid && iterations < maxIterations {
+		g, err = MakeValid(g)
+		if err != nil {
+			return geo.Geometry{}, errors.Wrap(err, "failed to make valid")
+		}
+
+		g, err = snapToIntegersGrid(g)
+		if err != nil {
+			return geo.Geometry{}, err
+		}
+		converted, err := convertToBasicType(g, basicType)
+		if err != nil {
+			return geo.Geometry{}, errors.Wrap(err, "failed to convert to basic type")
+		}
+		g = converted
+		valid, err = IsValid(g)
+		if err != nil {
+			return geo.Geometry{}, errors.Wrap(err, "failed to check validity")
+		}
+		iterations++
+	}
+	if !valid {
+		return geo.Geometry{}, nil
+	}
+
+	gt, err := g.AsGeomT()
+	if err != nil {
+		return geo.Geometry{}, errors.Wrap(err, "failed to convert to geom.T")
+	}
+	err = forcePolygonOrientation(gt, OrientationCCW)
+	if err != nil {
+		return geo.Geometry{}, errors.Wrap(err, "failed to force polygon orientation")
+	}
+	g, err = geo.MakeGeometryFromGeomT(gt)
+	if err != nil {
+		return geo.Geometry{}, errors.Wrap(err, "failed to make geometry from geom.T")
+	}
+	return g, nil
+}
+
+func snapToIntegersGrid(g geo.Geometry) (geo.Geometry, error) {
+	offset := geom.Coord{0, 0, 0, 0}
+	grid := geom.Coord{1, 1, 0, 0}
+	g, err := SnapToGrid(g, offset, grid)
+	if err != nil {
+		return geo.Geometry{}, errors.Wrap(err, "failed to snap to grid")
+	}
+	return g, nil
+}
+
+func overwriteMinusZero(val float64) float64 {
+	if val == -0 {
+		return 0
+	}
+	return val
+}
+
+// For a given geometry, look for the highest dimensional basic type: point, line or polygon.
+func getBasicType(gt geom.T) (geopb.ShapeType, error) {
+	switch gt := gt.(type) {
+	case *geom.Point:
+		return geopb.ShapeType_Point, nil
+	case *geom.LineString:
+		return geopb.ShapeType_LineString, nil
+	case *geom.Polygon:
+		return geopb.ShapeType_Polygon, nil
+	case *geom.MultiPoint:
+		return geopb.ShapeType_Point, nil
+	case *geom.MultiLineString:
+		return geopb.ShapeType_LineString, nil
+	case *geom.MultiPolygon:
+		return geopb.ShapeType_Polygon, nil
+	case *geom.GeometryCollection:
+		maxShape := geopb.ShapeType_Unset
+		for _, subGt := range gt.Geoms() {
+			shapeType, err := getBasicType(subGt)
+			if err != nil {
+				return geopb.ShapeType_Unset, err
+			}
+			if shapeType > maxShape {
+				maxShape = shapeType
+			}
+		}
+		return maxShape, nil
+	default:
+		return geopb.ShapeType_Unset, geom.ErrUnsupportedType{Value: gt}
+	}
+}
+
+func convertToBasicType(g geo.Geometry, basicType geopb.ShapeType) (geo.Geometry, error) {
+	var err error
+	if g.ShapeType() == geopb.ShapeType_GeometryCollection {
+		g, err = CollectionExtract(g, basicType)
+		if err != nil {
+			return geo.Geometry{}, errors.Wrap(err, "failed to extract collection")
+		}
+	}
+	// If the extracted geometry is a MultiPoint, MultiLineString or MultiPolygon but includes only one sub geometry, we want to return that subgeometry.
+	out, err := CollectionHomogenize(g)
+	if err != nil {
+		return geo.Geometry{}, errors.Wrap(err, "failed to homogenize collection")
+	}
+	return out, nil
+}
diff --git a/pkg/geo/geomfn/node.go b/pkg/geo/geomfn/node.go
new file mode 100644
index 0000000..74ab2f2
--- /dev/null
+++ b/pkg/geo/geomfn/node.go
@@ -0,0 +1,223 @@
+// Copyright 2020 The Cockroach Authors.
+//
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
+
+package geomfn
+
+import (
+	"github.com/cockroachdb/cockroachdb-parser/pkg/geo"
+	"github.com/cockroachdb/cockroachdb-parser/pkg/geo/geopb"
+	"github.com/cockroachdb/cockroachdb-parser/pkg/geo/geos"
+	"github.com/cockroachdb/cockroachdb-parser/pkg/sql/pgwire/pgcode"
+	"github.com/cockroachdb/cockroachdb-parser/pkg/sql/pgwire/pgerror"
+	"github.com/cockroachdb/errors"
+	geom "github.com/twpayne/go-geom"
+	"github.com/twpayne/go-geom/xy"
+)
+
+// Node returns a geometry containing a set of LineStrings using the least
+// possible number of nodes while preserving all of the input ones.
+func Node(g geo.Geometry) (geo.Geometry, error) {
+	if g.ShapeType() != geopb.ShapeType_LineString && g.ShapeType() != geopb.ShapeType_MultiLineString {
+		return geo.Geometry{}, pgerror.Newf(
+			pgcode.InvalidParameterValue,
+			"geometry type is unsupported. Please pass a LineString or a MultiLineString",
+		)
+	}
+
+	// Return GEOMETRYCOLLECTION EMPTY if it is empty.
+	if g.Empty() {
+		return geo.MakeGeometryFromGeomT(geom.NewGeometryCollection().SetSRID(int(g.SRID())))
+	}
+
+	res, err := geos.Node(g.EWKB())
+	if err != nil {
+		return geo.Geometry{}, err
+	}
+	node, err := geo.ParseGeometryFromEWKB(res)
+	if err != nil {
+		return geo.Geometry{}, err
+	}
+
+	res, err = geos.LineMerge(node.EWKB())
+	if err != nil {
+		return geo.Geometry{}, err
+	}
+	lines, err := geo.ParseGeometryFromEWKB(res)
+	if err != nil {
+		return geo.Geometry{}, err
+	}
+	if lines.ShapeType() == geopb.ShapeType_LineString {
+		// No nodes found, return a MultiLineString.
+		return node, nil
+	}
+
+	glines, err := lines.AsGeomT()
+	if err != nil {
+		return geo.Geometry{}, errors.Wrap(err, "error transforming lines")
+	}
+	ep, err := extractEndpoints(g)
+	if err != nil {
+		return geo.Geometry{}, errors.Wrap(err, "error extracting endpoints")
+	}
+	var mllines *geom.MultiLineString
+	switch t := glines.(type) {
+	case *geom.MultiLineString:
+		mllines = t
+	case *geom.GeometryCollection:
+		if t.Empty() {
+			t.SetSRID(int(g.SRID()))
+			return geo.MakeGeometryFromGeomT(t)
+		}
+		return geo.Geometry{}, errors.AssertionFailedf("unknown GEOMETRYCOLLECTION: %T", t)
+	default:
+		return geo.Geometry{}, errors.AssertionFailedf("unknown LineMerge result type: %T", t)
+	}
+
+	gep, err := ep.AsGeomT()
+	if err != nil {
+		return geo.Geometry{}, errors.Wrap(err, "error transforming endpoints")
+	}
+	mpep := gep.(*geom.MultiPoint)
+	mlout, err := splitLinesByPoints(mllines, mpep)
+	if err != nil {
+		return geo.Geometry{}, err
+	}
+	mlout.SetSRID(int(g.SRID()))
+	out, err := geo.MakeGeometryFromGeomT(mlout)
+	if err != nil {
+		return geo.Geometry{}, errors.Wrap(err, "could not transform output into geometry")
+	}
+	return out, nil
+}
+
+// splitLinesByPoints goes through every LineString and tries to split that LineString by any
+// of the Points provided. Does not split LineString if the Point is an endpoint for that line.
+// Returns MultiLineString consisting of splitted, as well as not splitted provided LineStrings.
+func splitLinesByPoints(
+	mllines *geom.MultiLineString, mpep *geom.MultiPoint,
+) (*geom.MultiLineString, error) {
+	mlout := geom.NewMultiLineString(geom.XY)
+	splitted := false
+	var err error
+	var splitLines []*geom.LineString
+	for i := 0; i < mllines.NumLineStrings(); i++ {
+		l := mllines.LineString(i)
+		for j := 0; j < mpep.NumPoints(); j++ {
+			p := mpep.Point(j)
+			splitted, splitLines, err = splitLineByPoint(l, p.Coords())
+			if err != nil {
+				return nil, errors.Wrap(err, "could not split line")
+			}
+			if splitted {
+				err = mlout.Push(splitLines[0])
+				if err != nil {
+					return nil, errors.Wrap(err, "could not construct output geometry")
+				}
+				err = mlout.Push(splitLines[1])
+				if err != nil {
+					return nil, errors.Wrap(err, "could not construct output geometry")
+				}
+				break
+			}
+		}
+		if !splitted {
+			err = mlout.Push(l)
+			if err != nil {
+				return nil, errors.Wrap(err, "could not construct output geometry")
+			}
+		}
+	}
+	return mlout, nil
+}
+
+// extractEndpoints extracts the endpoints from geometry provided and returns them as a MultiPoint geometry.
+func extractEndpoints(g geo.Geometry) (geo.Geometry, error) {
+	mp := geom.NewMultiPoint(geom.XY)
+
+	gt, err := g.AsGeomT()
+	if err != nil {
+		return geo.Geometry{}, errors.Wrap(err, "error transforming geometry")
+	}
+
+	switch gt := gt.(type) {
+	case *geom.LineString:
+		endpoints := collectEndpoints(gt)
+		for _, endpoint := range endpoints {
+			err := mp.Push(endpoint)
+			if err != nil {
+				return geo.Geometry{}, errors.Wrap(err, "error creating output geometry")
+			}
+		}
+	case *geom.MultiLineString:
+		for i := 0; i < gt.NumLineStrings(); i++ {
+			ls := gt.LineString(i)
+			endpoints := collectEndpoints(ls)
+			for _, endpoint := range endpoints {
+				err := mp.Push(endpoint)
+				if err != nil {
+					return geo.Geometry{}, errors.Wrap(err, "error creating output geometry")
+				}
+			}
+		}
+	default:
+		return geo.Geometry{}, pgerror.Newf(pgcode.InvalidParameterValue, "unsupported type: %T", gt)
+	}
+
+	result, err := geo.MakeGeometryFromGeomT(mp)
+	if err != nil {
+		return geo.Geometry{}, errors.Wrap(err, "error creating output geometry")
+	}
+	return result, nil
+}
+
+// collectEndpoints returns endpoints of the line provided as a slice of Points.
+func collectEndpoints(ls *geom.LineString) []*geom.Point {
+	coord := ls.Coord(0)
+	startPoint := geom.NewPointFlat(geom.XY, []float64{coord.X(), coord.Y()})
+	coord = ls.Coord(ls.NumCoords() - 1)
+	endPoint := geom.NewPointFlat(geom.XY, []float64{coord.X(), coord.Y()})
+	return []*geom.Point{startPoint, endPoint}
+}
+
+// splitLineByPoint splits the line using the Point provided.
+// Returns a bool representing whether the line was splitted or not, and a slice of output LineStrings.
+// The Point must be on provided line and not an endpoint, otherwise false is returned along with unsplit line.
+func splitLineByPoint(l *geom.LineString, p geom.Coord) (bool, []*geom.LineString, error) {
+	// Do not split if Point is not on line.
+	if !xy.IsOnLine(l.Layout(), p, l.FlatCoords()) {
+		return false, []*geom.LineString{l}, nil
+	}
+	// Do not split if Point is the endpoint of the line.
+	startCoord := l.Coord(0)
+	endCoord := l.Coord(l.NumCoords() - 1)
+	if p.Equal(l.Layout(), startCoord) || p.Equal(l.Layout(), endCoord) {
+		return false, []*geom.LineString{l}, nil
+	}
+	// Find where to split the line and group coords.
+	coordsA := []geom.Coord{}
+	coordsB := []geom.Coord{}
+	for i := 1; i < l.NumCoords(); i++ {
+		if xy.IsPointWithinLineBounds(p, l.Coord(i-1), l.Coord(i)) {
+			coordsA = append(l.Coords()[0:i], p)
+			if p.Equal(l.Layout(), l.Coord(i)) {
+				coordsB = l.Coords()[i:]
+			} else {
+				coordsB = append([]geom.Coord{p}, l.Coords()[i:]...)
+			}
+			break
+		}
+	}
+	l1 := geom.NewLineString(l.Layout())
+	_, err := l1.SetCoords(coordsA)
+	if err != nil {
+		return false, []*geom.LineString{}, errors.Wrap(err, "could not set coords")
+	}
+	l2 := geom.NewLineString(l.Layout())
+	_, err = l2.SetCoords(coordsB)
+	if err != nil {
+		return false, []*geom.LineString{}, errors.Wrap(err, "could not set coords")
+	}
+	return true, []*geom.LineString{l1, l2}, nil
+}
diff --git a/pkg/geo/geomfn/orientation.go b/pkg/geo/geomfn/orientation.go
new file mode 100644
index 0000000..c6bc7d7
--- /dev/null
+++ b/pkg/geo/geomfn/orientation.go
@@ -0,0 +1,150 @@
+// Copyright 2020 The Cockroach Authors.
+//
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
+
+package geomfn
+
+import (
+	"github.com/cockroachdb/cockroachdb-parser/pkg/geo"
+	"github.com/cockroachdb/cockroachdb-parser/pkg/sql/pgwire/pgcode"
+	"github.com/cockroachdb/cockroachdb-parser/pkg/sql/pgwire/pgerror"
+	"github.com/twpayne/go-geom"
+)
+
+// Orientation defines an orientation of a shape.
+type Orientation int
+
+const (
+	// OrientationCW denotes a clockwise orientation.
+	OrientationCW Orientation = iota
+	// OrientationCCW denotes a counter-clockwise orientation
+	OrientationCCW
+)
+
+// HasPolygonOrientation checks whether a given Geometry have polygons
+// that matches the given Orientation.
+// Non-Polygon objects
+func HasPolygonOrientation(g geo.Geometry, o Orientation) (bool, error) {
+	t, err := g.AsGeomT()
+	if err != nil {
+		return false, err
+	}
+	return hasPolygonOrientation(t, o)
+}
+
+func hasPolygonOrientation(g geom.T, o Orientation) (bool, error) {
+	switch g := g.(type) {
+	case *geom.Polygon:
+		for i := 0; i < g.NumLinearRings(); i++ {
+			isCCW := geo.IsLinearRingCCW(g.LinearRing(i))
+			// Interior rings should be the reverse orientation of the exterior ring.
+			if i > 0 {
+				isCCW = !isCCW
+			}
+			switch o {
+			case OrientationCW:
+				if isCCW {
+					return false, nil
+				}
+			case OrientationCCW:
+				if !isCCW {
+					return false, nil
+				}
+			default:
+				return false, pgerror.Newf(pgcode.InvalidParameterValue, "unexpected orientation: %v", o)
+			}
+		}
+		return true, nil
+	case *geom.MultiPolygon:
+		for i := 0; i < g.NumPolygons(); i++ {
+			if ret, err := hasPolygonOrientation(g.Polygon(i), o); !ret || err != nil {
+				return ret, err
+			}
+		}
+		return true, nil
+	case *geom.GeometryCollection:
+		for i := 0; i < g.NumGeoms(); i++ {
+			if ret, err := hasPolygonOrientation(g.Geom(i), o); !ret || err != nil {
+				return ret, err
+			}
+		}
+		return true, nil
+	case *geom.Point, *geom.MultiPoint, *geom.LineString, *geom.MultiLineString:
+		return true, nil
+	default:
+		return false, pgerror.Newf(pgcode.InvalidParameterValue, "unhandled geometry type: %T", g)
+	}
+}
+
+// ForcePolygonOrientation forces orientations within polygons
+// to be oriented the prescribed way.
+func ForcePolygonOrientation(g geo.Geometry, o Orientation) (geo.Geometry, error) {
+	t, err := g.AsGeomT()
+	if err != nil {
+		return geo.Geometry{}, err
+	}
+
+	if err := forcePolygonOrientation(t, o); err != nil {
+		return geo.Geometry{}, err
+	}
+	return geo.MakeGeometryFromGeomT(t)
+}
+
+func forcePolygonOrientation(g geom.T, o Orientation) error {
+	switch g := g.(type) {
+	case *geom.Polygon:
+		for i := 0; i < g.NumLinearRings(); i++ {
+			isCCW := geo.IsLinearRingCCW(g.LinearRing(i))
+			// Interior rings should be the reverse orientation of the exterior ring.
+			if i > 0 {
+				isCCW = !isCCW
+			}
+			reverse := false
+			switch o {
+			case OrientationCW:
+				if isCCW {
+					reverse = true
+				}
+			case OrientationCCW:
+				if !isCCW {
+					reverse = true
+				}
+			default:
+				return pgerror.Newf(pgcode.InvalidParameterValue, "unexpected orientation: %v", o)
+			}
+
+			if reverse {
+				// Reverse coordinates from both ends.
+				// Do this by swapping up to the middle of the array of elements, which guarantees
+				// each end get swapped. This works for an odd number of elements as well as
+				// the middle element ends swapping with itself, which is ok.
+				coords := g.LinearRing(i).FlatCoords()
+				for cIdx := 0; cIdx < len(coords)/2; cIdx += g.Stride() {
+					for sIdx := 0; sIdx < g.Stride(); sIdx++ {
+						coords[cIdx+sIdx], coords[len(coords)-cIdx-g.Stride()+sIdx] = coords[len(coords)-cIdx-g.Stride()+sIdx], coords[cIdx+sIdx]
+					}
+				}
+			}
+		}
+		return nil
+	case *geom.MultiPolygon:
+		for i := 0; i < g.NumPolygons(); i++ {
+			if err := forcePolygonOrientation(g.Polygon(i), o); err != nil {
+				return err
+			}
+		}
+		return nil
+	case *geom.GeometryCollection:
+		for i := 0; i < g.NumGeoms(); i++ {
+			if err := forcePolygonOrientation(g.Geom(i), o); err != nil {
+				return err
+			}
+		}
+		return nil
+	case *geom.Point, *geom.MultiPoint, *geom.LineString, *geom.MultiLineString:
+		return nil
+	default:
+		return pgerror.Newf(pgcode.InvalidParameterValue, "unhandled geometry type: %T", g)
+	}
+}
diff --git a/pkg/geo/geomfn/point_polygon_optimization.go b/pkg/geo/geomfn/point_polygon_optimization.go
new file mode 100644
index 0000000..cb0d63d
--- /dev/null
+++ b/pkg/geo/geomfn/point_polygon_optimization.go
@@ -0,0 +1,221 @@
+// Copyright 2021 The Cockroach Authors.
+//
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
+
+package geomfn
+
+import (
+	"github.com/cockroachdb/cockroachdb-parser/pkg/geo"
+	"github.com/cockroachdb/errors"
+)
+
+// PointPolygonControlFlowType signals what control flow to follow.
+type PointPolygonControlFlowType int
+
+const (
+	// PPCFCheckNextPolygon signals that the current point should be checked
+	// against the next polygon.
+	PPCFCheckNextPolygon PointPolygonControlFlowType = iota
+	// PPCFSkipToNextPoint signals that the rest of the checking for the current
+	// point can be skipped.
+	PPCFSkipToNextPoint
+	// PPCFReturnTrue signals that the function should exit early and return true.
+	PPCFReturnTrue
+)
+
+// PointInPolygonEventListener is an interface implemented for each
+// binary predicate making use of the point in polygon optimization
+// to specify the behavior in pointKindRelatesToPolygonKind.
+type PointInPolygonEventListener interface {
+	// OnPointIntersectsPolygon returns whether the function should exit and
+	// return true, skip to the next point, or check the current point against
+	// the next polygon in the case where a point intersects with a polygon.
+	// The strictlyInside param signifies whether the point is strictly inside
+	// or on the boundary of the polygon.
+	OnPointIntersectsPolygon(strictlyInside bool) PointPolygonControlFlowType
+	// OnPointDoesNotIntersect returns whether the function should early exit and
+	// return false in the case where a point does not intersect any polygon.
+	ExitIfPointDoesNotIntersect() bool
+	// AfterPointPolygonLoops returns the bool to return after the point-polygon
+	// loops have finished.
+	AfterPointPolygonLoops() bool
+}
+
+// For Intersects, at least one point must intersect with at least one polygon.
+type intersectsPIPEventListener struct{}
+
+func (el *intersectsPIPEventListener) OnPointIntersectsPolygon(
+	strictlyInside bool,
+) PointPolygonControlFlowType {
+	// A single intersection is sufficient.
+	return PPCFReturnTrue
+}
+
+func (el *intersectsPIPEventListener) ExitIfPointDoesNotIntersect() bool {
+	return false
+}
+
+func (el *intersectsPIPEventListener) AfterPointPolygonLoops() bool {
+	return false
+}
+
+var _ PointInPolygonEventListener = (*intersectsPIPEventListener)(nil)
+
+func newIntersectsPIPEventListener() *intersectsPIPEventListener {
+	return &intersectsPIPEventListener{}
+}
+
+// For CoveredBy, every point must intersect with at least one polygon.
+type coveredByPIPEventListener struct {
+	intersectsOnce bool
+}
+
+func (el *coveredByPIPEventListener) OnPointIntersectsPolygon(
+	strictlyInside bool,
+) PointPolygonControlFlowType {
+	// If the current point intersects, check the next point.
+	el.intersectsOnce = true
+	return PPCFSkipToNextPoint
+}
+
+func (el *coveredByPIPEventListener) ExitIfPointDoesNotIntersect() bool {
+	// Each point in a (multi)point must intersect a polygon in the
+	// (multi)point to be covered by it.
+	return true
+}
+
+func (el *coveredByPIPEventListener) AfterPointPolygonLoops() bool {
+	return el.intersectsOnce
+}
+
+var _ PointInPolygonEventListener = (*coveredByPIPEventListener)(nil)
+
+func newCoveredByPIPEventListener() *coveredByPIPEventListener {
+	return &coveredByPIPEventListener{intersectsOnce: false}
+}
+
+// For Within, every point must intersect with at least one polygon.
+type withinPIPEventListener struct {
+	insideOnce bool
+}
+
+func (el *withinPIPEventListener) OnPointIntersectsPolygon(
+	strictlyInside bool,
+) PointPolygonControlFlowType {
+	// We can only skip to the next point if we have already seen a point
+	// that is inside the (multi)polygon.
+	if el.insideOnce {
+		return PPCFSkipToNextPoint
+	}
+	if strictlyInside {
+		el.insideOnce = true
+		return PPCFSkipToNextPoint
+	}
+	return PPCFCheckNextPolygon
+}
+
+func (el *withinPIPEventListener) ExitIfPointDoesNotIntersect() bool {
+	// Each point in a (multi)point must intersect a polygon in the
+	// (multi)polygon to be contained within it.
+	return true
+}
+
+func (el *withinPIPEventListener) AfterPointPolygonLoops() bool {
+	return el.insideOnce
+}
+
+var _ PointInPolygonEventListener = (*withinPIPEventListener)(nil)
+
+func newWithinPIPEventListener() *withinPIPEventListener {
+	return &withinPIPEventListener{insideOnce: false}
+}
+
+// PointKindIntersectsPolygonKind returns whether a (multi)point
+// and a (multi)polygon intersect.
+func PointKindIntersectsPolygonKind(
+	pointKind geo.Geometry, polygonKind geo.Geometry,
+) (bool, error) {
+	return pointKindRelatesToPolygonKind(pointKind, polygonKind, newIntersectsPIPEventListener())
+}
+
+// PointKindCoveredByPolygonKind returns whether a (multi)point
+// is covered by a (multi)polygon.
+func PointKindCoveredByPolygonKind(pointKind geo.Geometry, polygonKind geo.Geometry) (bool, error) {
+	return pointKindRelatesToPolygonKind(pointKind, polygonKind, newCoveredByPIPEventListener())
+}
+
+// PointKindWithinPolygonKind returns whether a (multi)point
+// is contained within a (multi)polygon.
+func PointKindWithinPolygonKind(pointKind geo.Geometry, polygonKind geo.Geometry) (bool, error) {
+	return pointKindRelatesToPolygonKind(pointKind, polygonKind, newWithinPIPEventListener())
+}
+
+// pointKindRelatesToPolygonKind returns whether a (multi)point
+// and a (multi)polygon have the given relationship.
+func pointKindRelatesToPolygonKind(
+	pointKind geo.Geometry, polygonKind geo.Geometry, eventListener PointInPolygonEventListener,
+) (bool, error) {
+	// Nothing can relate to a NaN coordinate.
+	if BoundingBoxHasNaNCoordinates(pointKind) || BoundingBoxHasNaNCoordinates(polygonKind) {
+		return false, nil
+	}
+	pointKindBaseT, err := pointKind.AsGeomT()
+	if err != nil {
+		return false, err
+	}
+	polygonKindBaseT, err := polygonKind.AsGeomT()
+	if err != nil {
+		return false, err
+	}
+	pointKindIterator := geo.NewGeomTIterator(pointKindBaseT, geo.EmptyBehaviorOmit)
+	polygonKindIterator := geo.NewGeomTIterator(polygonKindBaseT, geo.EmptyBehaviorOmit)
+
+	// Check whether each point intersects with at least one polygon.
+	// The behavior for each predicate is dictated by eventListener.
+pointOuterLoop:
+	for {
+		point, hasPoint, err := pointKindIterator.Next()
+		if err != nil {
+			return false, err
+		}
+		if !hasPoint {
+			break
+		}
+		// Reset the polygon iterator on each iteration of the point iterator.
+		polygonKindIterator.Reset()
+		curIntersects := false
+		for {
+			polygon, hasPolygon, err := polygonKindIterator.Next()
+			if err != nil {
+				return false, err
+			}
+			if !hasPolygon {
+				break
+			}
+			pointSide, err := findPointSideOfPolygon(point, polygon)
+			if err != nil {
+				return false, err
+			}
+			switch pointSide {
+			case insideLinearRing, onLinearRing:
+				curIntersects = true
+				strictlyInside := pointSide == insideLinearRing
+				switch eventListener.OnPointIntersectsPolygon(strictlyInside) {
+				case PPCFCheckNextPolygon:
+				case PPCFSkipToNextPoint:
+					continue pointOuterLoop
+				case PPCFReturnTrue:
+					return true, nil
+				}
+			case outsideLinearRing:
+			default:
+				return false, errors.AssertionFailedf("findPointSideOfPolygon returned unknown linearRingSide %d", pointSide)
+			}
+		}
+		if !curIntersects && eventListener.ExitIfPointDoesNotIntersect() {
+			return false, nil
+		}
+	}
+	return eventListener.AfterPointPolygonLoops(), nil
+}
diff --git a/pkg/geo/geomfn/remove_repeated_points.go b/pkg/geo/geomfn/remove_repeated_points.go
new file mode 100644
index 0000000..fad5d5e
--- /dev/null
+++ b/pkg/geo/geomfn/remove_repeated_points.go
@@ -0,0 +1,114 @@
+// Copyright 2020 The Cockroach Authors.
+//
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
+
+package geomfn
+
+import (
+	"github.com/cockroachdb/cockroachdb-parser/pkg/geo"
+	"github.com/cockroachdb/errors"
+	"github.com/twpayne/go-geom"
+)
+
+// RemoveRepeatedPoints returns the geometry with repeated points removed.
+func RemoveRepeatedPoints(g geo.Geometry, tolerance float64) (geo.Geometry, error) {
+	t, err := g.AsGeomT()
+	if err != nil {
+		return geo.Geometry{}, err
+	}
+	// Use the square of the tolerance to avoid taking the square root of distance results.
+	t, err = removeRepeatedPointsFromGeomT(t, tolerance*tolerance)
+	if err != nil {
+		return geo.Geometry{}, err
+	}
+	return geo.MakeGeometryFromGeomT(t)
+}
+
+func removeRepeatedPointsFromGeomT(t geom.T, tolerance2 float64) (geom.T, error) {
+	switch t := t.(type) {
+	case *geom.Point:
+	case *geom.LineString:
+		if coords, modified := removeRepeatedCoords(t.Layout(), t.Coords(), tolerance2, 2); modified {
+			return t.SetCoords(coords)
+		}
+	case *geom.Polygon:
+		if coords, modified := removeRepeatedCoords2(t.Layout(), t.Coords(), tolerance2, 4); modified {
+			return t.SetCoords(coords)
+		}
+	case *geom.MultiPoint:
+		if coords, modified := removeRepeatedCoords(t.Layout(), t.Coords(), tolerance2, 0); modified {
+			return t.SetCoords(coords)
+		}
+	case *geom.MultiLineString:
+		if coords, modified := removeRepeatedCoords2(t.Layout(), t.Coords(), tolerance2, 2); modified {
+			return t.SetCoords(coords)
+		}
+	case *geom.MultiPolygon:
+		if coords, modified := removeRepeatedCoords3(t.Layout(), t.Coords(), tolerance2, 4); modified {
+			return t.SetCoords(coords)
+		}
+	case *geom.GeometryCollection:
+		for _, g := range t.Geoms() {
+			if _, err := removeRepeatedPointsFromGeomT(g, tolerance2); err != nil {
+				return nil, err
+			}
+		}
+	default:
+		return nil, errors.AssertionFailedf("unknown geometry type: %T", t)
+	}
+	return t, nil
+}
+
+func removeRepeatedCoords(
+	layout geom.Layout, coords []geom.Coord, tolerance2 float64, minCoords int,
+) ([]geom.Coord, bool) {
+	modified := false
+	switch tolerance2 {
+	case 0:
+		for i := 1; i < len(coords) && len(coords) > minCoords; i++ {
+			if coords[i].Equal(layout, coords[i-1]) {
+				coords = append(coords[:i], coords[i+1:]...)
+				modified = true
+				i--
+			}
+		}
+	default:
+		for i := 1; i < len(coords) && len(coords) > minCoords; i++ {
+			if coordMag2(coordSub(coords[i], coords[i-1])) <= tolerance2 {
+				coords = append(coords[:i], coords[i+1:]...)
+				modified = true
+				i--
+			}
+		}
+	}
+	return coords, modified
+}
+
+func removeRepeatedCoords2(
+	layout geom.Layout, coords2 [][]geom.Coord, tolerance2 float64, minCoords int,
+) ([][]geom.Coord, bool) {
+	modified := false
+	for i, coords := range coords2 {
+		if c, m := removeRepeatedCoords(layout, coords, tolerance2, minCoords); m {
+			coords2[i] = c
+			modified = true
+		}
+	}
+	return coords2, modified
+}
+
+func removeRepeatedCoords3(
+	layout geom.Layout, coords3 [][][]geom.Coord, tolerance2 float64, minCoords int,
+) ([][][]geom.Coord, bool) {
+	modified := false
+	for i, coords2 := range coords3 {
+		for j, coords := range coords2 {
+			if c, m := removeRepeatedCoords(layout, coords, tolerance2, minCoords); m {
+				coords3[i][j] = c
+				modified = true
+			}
+		}
+	}
+	return coords3, modified
+}
diff --git a/pkg/geo/geomfn/reverse.go b/pkg/geo/geomfn/reverse.go
new file mode 100644
index 0000000..5ec26ab
--- /dev/null
+++ b/pkg/geo/geomfn/reverse.go
@@ -0,0 +1,96 @@
+// Copyright 2020 The Cockroach Authors.
+//
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
+
+package geomfn
+
+import (
+	"github.com/cockroachdb/cockroachdb-parser/pkg/geo"
+	"github.com/twpayne/go-geom"
+)
+
+// Reverse returns a modified geometry by reversing the order of its vertexes
+func Reverse(geometry geo.Geometry) (geo.Geometry, error) {
+	g, err := geometry.AsGeomT()
+	if err != nil {
+		return geo.Geometry{}, err
+	}
+
+	g, err = reverse(g)
+	if err != nil {
+		return geo.Geometry{}, err
+	}
+
+	return geo.MakeGeometryFromGeomT(g)
+}
+
+func reverse(g geom.T) (geom.T, error) {
+	if geomCollection, ok := g.(*geom.GeometryCollection); ok {
+		return reverseCollection(geomCollection)
+	}
+
+	switch t := g.(type) {
+	case *geom.Point, *geom.MultiPoint: // cases where reverse does change the order
+		return g, nil
+	case *geom.LineString:
+		g = geom.NewLineStringFlat(t.Layout(), reverseCoords(g.FlatCoords(), g.Stride())).SetSRID(g.SRID())
+	case *geom.Polygon:
+		g = geom.NewPolygonFlat(t.Layout(), reverseCoords(g.FlatCoords(), g.Stride()), t.Ends()).SetSRID(g.SRID())
+	case *geom.MultiLineString:
+		g = geom.NewMultiLineStringFlat(t.Layout(), reverseMulti(g, t.Ends()), t.Ends()).SetSRID(g.SRID())
+	case *geom.MultiPolygon:
+		var ends []int
+		for _, e := range t.Endss() {
+			ends = append(ends, e...)
+		}
+		g = geom.NewMultiPolygonFlat(t.Layout(), reverseMulti(g, ends), t.Endss()).SetSRID(g.SRID())
+
+	default:
+		return nil, geom.ErrUnsupportedType{Value: g}
+	}
+
+	return g, nil
+}
+
+func reverseCoords(coords []float64, stride int) []float64 {
+	for i := 0; i < len(coords)/2; i += stride {
+		for j := 0; j < stride; j++ {
+			coords[i+j], coords[len(coords)-stride-i+j] = coords[len(coords)-stride-i+j], coords[i+j]
+		}
+	}
+
+	return coords
+}
+
+// reverseMulti handles reversing coordinates of MULTI* geometries with nested sub-structures
+func reverseMulti(g geom.T, ends []int) []float64 {
+	coords := g.FlatCoords()
+	prevEnd := 0
+
+	for _, end := range ends {
+		copy(
+			coords[prevEnd:end],
+			reverseCoords(coords[prevEnd:end], g.Stride()),
+		)
+		prevEnd = end
+	}
+
+	return coords
+}
+
+// reverseCollection iterates through a GeometryCollection and calls reverse() on each geometry.
+func reverseCollection(geomCollection *geom.GeometryCollection) (*geom.GeometryCollection, error) {
+	res := geom.NewGeometryCollection()
+	for _, subG := range geomCollection.Geoms() {
+		subGeom, err := reverse(subG)
+		if err != nil {
+			return nil, err
+		}
+
+		if err := res.Push(subGeom); err != nil {
+			return nil, err
+		}
+	}
+	return res, nil
+}
diff --git a/pkg/geo/geomfn/segmentize.go b/pkg/geo/geomfn/segmentize.go
new file mode 100644
index 0000000..d84e66d
--- /dev/null
+++ b/pkg/geo/geomfn/segmentize.go
@@ -0,0 +1,93 @@
+// Copyright 2020 The Cockroach Authors.
+//
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
+
+package geomfn
+
+import (
+	"math"
+
+	"github.com/cockroachdb/cockroachdb-parser/pkg/geo"
+	"github.com/cockroachdb/cockroachdb-parser/pkg/geo/geosegmentize"
+	"github.com/cockroachdb/cockroachdb-parser/pkg/sql/pgwire/pgcode"
+	"github.com/cockroachdb/cockroachdb-parser/pkg/sql/pgwire/pgerror"
+	"github.com/twpayne/go-geom"
+)
+
+// Segmentize return modified Geometry having no segment longer
+// that given maximum segment length.
+// This works by inserting the extra points in such a manner that
+// minimum number of new segments with equal length is created,
+// between given two-points such that each segment has length less
+// than or equal to given maximum segment length.
+func Segmentize(g geo.Geometry, segmentMaxLength float64) (geo.Geometry, error) {
+	if math.IsNaN(segmentMaxLength) || math.IsInf(segmentMaxLength, 1 /* sign */) {
+		return g, nil
+	}
+	geometry, err := g.AsGeomT()
+	if err != nil {
+		return geo.Geometry{}, err
+	}
+	switch geometry := geometry.(type) {
+	case *geom.Point, *geom.MultiPoint:
+		return g, nil
+	default:
+		if segmentMaxLength <= 0 {
+			return geo.Geometry{}, pgerror.Newf(pgcode.InvalidParameterValue, "maximum segment length must be positive")
+		}
+		segGeometry, err := geosegmentize.Segmentize(geometry, segmentMaxLength, segmentizeCoords)
+		if err != nil {
+			return geo.Geometry{}, err
+		}
+		return geo.MakeGeometryFromGeomT(segGeometry)
+	}
+}
+
+// segmentizeCoords inserts multiple points between given two coordinates and
+// return resultant point as flat []float64. Points are inserted in such a
+// way that they create minimum number segments of equal length such that each
+// segment has a length less than or equal to given maximum segment length.
+// Note: List of points does not consist of end point.
+func segmentizeCoords(a geom.Coord, b geom.Coord, maxSegmentLength float64) ([]float64, error) {
+	if len(a) != len(b) {
+		return nil, pgerror.Newf(pgcode.InvalidParameterValue, "cannot segmentize two coordinates of different dimensions")
+	}
+	if maxSegmentLength <= 0 {
+		return nil, pgerror.Newf(pgcode.InvalidParameterValue, "maximum segment length must be positive")
+	}
+
+	// Only 2D distance is considered for determining number of segments.
+	distanceBetweenPoints := math.Sqrt(math.Pow(a.X()-b.X(), 2) + math.Pow(b.Y()-a.Y(), 2))
+
+	doubleNumberOfSegmentsToCreate := math.Ceil(distanceBetweenPoints / maxSegmentLength)
+	doubleNumPoints := float64(len(a)) * (1 + doubleNumberOfSegmentsToCreate)
+	if err := geosegmentize.CheckSegmentizeValidNumPoints(doubleNumPoints, a, b); err != nil {
+		return nil, err
+	}
+
+	// numberOfSegmentsToCreate represent the total number of segments
+	// in which given two coordinates will be divided.
+	numberOfSegmentsToCreate := int(doubleNumberOfSegmentsToCreate)
+	numPoints := int(doubleNumPoints)
+	// segmentFraction represent the fraction of length each segment
+	// has with respect to total length between two coordinates.
+	allSegmentizedCoordinates := make([]float64, 0, numPoints)
+	allSegmentizedCoordinates = append(allSegmentizedCoordinates, a.Clone()...)
+	segmentFraction := 1.0 / float64(numberOfSegmentsToCreate)
+	for pointInserted := 1; pointInserted < numberOfSegmentsToCreate; pointInserted++ {
+		segmentPoint := make([]float64, 0, len(a))
+		for i := 0; i < len(a); i++ {
+			segmentPoint = append(
+				segmentPoint,
+				a[i]*(1-float64(pointInserted)*segmentFraction)+b[i]*(float64(pointInserted)*segmentFraction),
+			)
+		}
+		allSegmentizedCoordinates = append(
+			allSegmentizedCoordinates,
+			segmentPoint...,
+		)
+	}
+
+	return allSegmentizedCoordinates, nil
+}
diff --git a/pkg/geo/geomfn/shift_longitude.go b/pkg/geo/geomfn/shift_longitude.go
new file mode 100644
index 0000000..d9c766c
--- /dev/null
+++ b/pkg/geo/geomfn/shift_longitude.go
@@ -0,0 +1,37 @@
+// Copyright 2021 The Cockroach Authors.
+//
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
+
+package geomfn
+
+import (
+	"github.com/cockroachdb/cockroachdb-parser/pkg/geo"
+	"github.com/twpayne/go-geom"
+)
+
+// ShiftLongitude returns a modified version of a geometry in which the longitude (X coordinate)
+// of each point is incremented by 360 if it is <0 and decremented by 360 if it is >180.
+// The result is only meaningful if the coordinates are in longitude/latitude.
+func ShiftLongitude(geometry geo.Geometry) (geo.Geometry, error) {
+	t, err := geometry.AsGeomT()
+	if err != nil {
+		return geometry, err
+	}
+
+	newT, err := applyOnCoordsForGeomT(t, func(l geom.Layout, dst []float64, src []float64) error {
+		copy(dst, src)
+		if src[0] < 0 {
+			dst[0] += 360
+		} else if src[0] > 180 {
+			dst[0] -= 360
+		}
+		return nil
+	})
+
+	if err != nil {
+		return geometry, err
+	}
+
+	return geo.MakeGeometryFromGeomT(newT)
+}
diff --git a/pkg/geo/geomfn/simplify.go b/pkg/geo/geomfn/simplify.go
new file mode 100644
index 0000000..caab762
--- /dev/null
+++ b/pkg/geo/geomfn/simplify.go
@@ -0,0 +1,344 @@
+// Copyright 2021 The Cockroach Authors.
+//
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
+
+package geomfn
+
+import (
+	"github.com/cockroachdb/cockroachdb-parser/pkg/geo"
+	"github.com/cockroachdb/cockroachdb-parser/pkg/geo/geopb"
+	"github.com/cockroachdb/cockroachdb-parser/pkg/sql/pgwire/pgcode"
+	"github.com/cockroachdb/cockroachdb-parser/pkg/sql/pgwire/pgerror"
+	"github.com/cockroachdb/errors"
+	"github.com/twpayne/go-geom"
+)
+
+// Simplify simplifies the given Geometry using the Douglas-Pecker algorithm.
+// If preserveCollapsed is specified, we will always return a partial LineString
+// or Polygon if the entire shape is collapsed.
+// Returns a bool if the geometry should be NULL.
+func Simplify(
+	g geo.Geometry, tolerance float64, preserveCollapsed bool,
+) (geo.Geometry, bool, error) {
+	if g.ShapeType2D() == geopb.ShapeType_Point ||
+		g.ShapeType2D() == geopb.ShapeType_MultiPoint ||
+		g.Empty() {
+		return g, false, nil
+	}
+	// Negative tolerances round to zero, similar to PostGIS.
+	if tolerance < 0 {
+		tolerance = 0
+	}
+	t, err := g.AsGeomT()
+	if err != nil {
+		return geo.Geometry{}, false, err
+	}
+	simplifiedT, err := simplify(t, tolerance, preserveCollapsed)
+	if err != nil {
+		return geo.Geometry{}, false, err
+	}
+	if simplifiedT == nil {
+		return geo.Geometry{}, true, nil
+	}
+
+	ret, err := geo.MakeGeometryFromGeomT(simplifiedT)
+	return ret, false, err
+}
+
+func simplify(t geom.T, tolerance float64, preserveCollapsed bool) (geom.T, error) {
+	if t.Empty() {
+		return t, nil
+	}
+	switch t := t.(type) {
+	case *geom.Point, *geom.MultiPoint:
+		// Though handled by the callee, GeometryCollections can have points/multipoints.
+		return t, nil
+	case *geom.LineString:
+		return simplifySimplifiableShape(t, tolerance, preserveCollapsed)
+	case *geom.MultiLineString:
+		ret := geom.NewMultiLineString(t.Layout()).SetSRID(t.SRID())
+		for i := 0; i < t.NumLineStrings(); i++ {
+			appendT, err := simplify(t.LineString(i), tolerance, preserveCollapsed)
+			if err != nil {
+				return nil, err
+			}
+			if appendT != nil {
+				if err := ret.Push(appendT.(*geom.LineString)); err != nil {
+					return nil, err
+				}
+			}
+		}
+		return ret, nil
+	case *geom.Polygon:
+		p := geom.NewPolygon(t.Layout()).SetSRID(t.SRID())
+		for i := 0; i < t.NumLinearRings(); i++ {
+			lrT, err := simplifySimplifiableShape(
+				t.LinearRing(i),
+				tolerance,
+				// We only want to preserve the outer ring.
+				preserveCollapsed && i == 0,
+			)
+			if err != nil {
+				return nil, err
+			}
+			lr := lrT.(*geom.LinearRing)
+			if lr.NumCoords() < 4 {
+				// If we are the exterior ring without at least 4 points, return nil.
+				if i == 0 {
+					return nil, nil
+				}
+				// Otherwise, ignore this inner ring.
+				continue
+			}
+			// Note it is possible for an inner ring to extend outside of the outer ring.
+			if err := p.Push(lr); err != nil {
+				return nil, err
+			}
+		}
+		return p, nil
+	case *geom.MultiPolygon:
+		ret := geom.NewMultiPolygon(t.Layout()).SetSRID(t.SRID())
+		for i := 0; i < t.NumPolygons(); i++ {
+			appendT, err := simplify(t.Polygon(i), tolerance, preserveCollapsed)
+			if err != nil {
+				return nil, err
+			}
+			if appendT != nil {
+				if err := ret.Push(appendT.(*geom.Polygon)); err != nil {
+					return nil, err
+				}
+			}
+		}
+		return ret, nil
+	case *geom.GeometryCollection:
+		ret := geom.NewGeometryCollection().SetSRID(t.SRID())
+		for _, gcT := range t.Geoms() {
+			appendT, err := simplify(gcT, tolerance, preserveCollapsed)
+			if err != nil {
+				return nil, err
+			}
+			if appendT != nil {
+				if err := ret.Push(appendT); err != nil {
+					return nil, err
+				}
+			}
+		}
+		return ret, nil
+	default:
+		return nil, pgerror.Newf(pgcode.InvalidParameterValue, "unknown shape type: %T", t)
+	}
+}
+
+type simplifiableShape interface {
+	geom.T
+
+	Coord(i int) geom.Coord
+	NumCoords() int
+}
+
+// simplifySimplifiableShape wraps simplifySimplifiableShapeInternal, performing extra
+// processing for preserveCollapsed.
+func simplifySimplifiableShape(
+	t simplifiableShape, tolerance float64, preserveCollapsed bool,
+) (geom.T, error) {
+	minPoints := 0
+	if preserveCollapsed {
+		switch t.(type) {
+		case *geom.LinearRing:
+			minPoints = 4
+		case *geom.LineString:
+			minPoints = 2
+		}
+	}
+
+	ret, err := simplifySimplifiableShapeInternal(t, tolerance, minPoints)
+	if err != nil {
+		return nil, err
+	}
+	switch ret := ret.(type) {
+	case *geom.LineString:
+		// If we have a LineString with the same first and last point, we should
+		// collapse the geometry entirely.
+		if !preserveCollapsed && ret.NumCoords() == 2 && coordEqual(ret.Coord(0), ret.Coord(1)) {
+			return nil, nil
+		}
+	}
+	return ret, nil
+}
+
+// simplifySimplifiableShapeInternal applies the Douglas-Peucker algorithm to the given
+// shape, returning the shape which is simplified.
+// Algorithm at https://en.wikipedia.org/wiki/Ramer%E2%80%93Douglas%E2%80%93Peucker_algorithm#Algorithm.
+func simplifySimplifiableShapeInternal(
+	t simplifiableShape, tolerance float64, minPoints int,
+) (geom.T, error) {
+	numCoords := t.NumCoords()
+	// If we already have the minimum number of points, return early.
+	if numCoords <= 2 || numCoords <= minPoints {
+		return t, nil
+	}
+
+	// Keep a track of points to keep. Always keep the first and last point.
+	keepPoints := make([]bool, numCoords)
+	keepPoints[0] = true
+	keepPoints[numCoords-1] = true
+	numKeepPoints := 2
+
+	if tolerance == 0 {
+		// We can special case tolerance 0 to be O(n) by only through
+		// the list of coordinates once and determining whether a given
+		// intermediate point lies on the edge of the previous and next
+		// point.
+		prevCoord := t.Coord(0)
+		for i := 1; i < t.NumCoords()-1; i++ {
+			currCoord := t.Coord(i)
+			nextCoord := t.Coord(i + 1)
+
+			// Let AB by the line from the prev coord to the current coord.
+			// Let AC be the line from the prev coord to the coord one ahead.
+			ab := coordSub(currCoord, prevCoord)
+			ac := coordSub(nextCoord, prevCoord)
+
+			// If AB and AC have a cross product of 0, they are parallel.
+			// If these are parallel, then we need to determine whether B
+			// is on the line segment AC.
+			if coordCross(ab, ac) == 0 {
+				// Project AB onto line AC. If the projection lies on the edge bounded by
+				// AC, we should skip the current point.
+				// See `findSplitIndexForSimplifiableShape` for description of the logic.
+				r := coordDot(ab, ac) / coordNorm2(ac)
+				if r >= 0 && r <= 1 {
+					continue
+				}
+			}
+
+			// Since B does not lie on line AC, we should keep the point.
+			prevCoord = currCoord
+			keepPoints[i] = true
+			numKeepPoints++
+		}
+	} else {
+		// Apply the algorithm, noting points to keep in the keepPoints array.
+		var recurse func(startIdx, endIdx int)
+		recurse = func(startIdx, endIdx int) {
+			// Find the index to split at.
+			splitIdx := findSplitIndexForSimplifiableShape(t, startIdx, endIdx, tolerance, minPoints > numKeepPoints)
+			// Return if there are no points to split at.
+			if splitIdx == startIdx {
+				return
+			}
+			keepPoints[splitIdx] = true
+			numKeepPoints++
+			recurse(startIdx, splitIdx)
+			recurse(splitIdx, endIdx)
+		}
+		recurse(0, numCoords-1)
+	}
+
+	// If we keep every point, return the existing shape.
+	if numKeepPoints == numCoords {
+		return t, nil
+	}
+
+	// Copy the flat coordinates over in the order they came in.
+	newFlatCoords := make([]float64, 0, numKeepPoints*t.Layout().Stride())
+	for i, keep := range keepPoints {
+		shouldAdd := keep
+		// We need to add enough points to satisfy minPoints. If we have not marked
+		// enough points to keep, add the first points we initially marked as not to
+		// keep until we hit minPoints. This is safe as we will still create a shape
+		// resembling the original shape.
+		// This is required for cases where polygons may simplify into a 2 or 3 point
+		// linestring, in which simplification may result in an invalid outer ring.
+		if !shouldAdd && numKeepPoints < minPoints {
+			shouldAdd = true
+			numKeepPoints++
+		}
+		if shouldAdd {
+			newFlatCoords = append(newFlatCoords, []float64(t.Coord(i))...)
+		}
+	}
+
+	switch t.(type) {
+	case *geom.LineString:
+		return geom.NewLineStringFlat(t.Layout(), newFlatCoords).SetSRID(t.SRID()), nil
+	case *geom.LinearRing:
+		return geom.NewLinearRingFlat(t.Layout(), newFlatCoords), nil
+	}
+	return nil, errors.AssertionFailedf("unknown shape: %T", t)
+}
+
+// findSplitIndexForSimplifiableShape finds the perpendicular distance for all
+// points between the coordinates of the start and end index exclusive to the edge
+// formed by coordinates of the start and end index.
+// Returns the startIdx if there is no further points to split.
+func findSplitIndexForSimplifiableShape(
+	t simplifiableShape, startIdx int, endIdx int, tolerance float64, forceSplit bool,
+) int {
+	// If there are no points between, then we have no more points to split.
+	if endIdx-startIdx < 2 {
+		return startIdx
+	}
+
+	edgeV0 := t.Coord(startIdx)
+	edgeV1 := t.Coord(endIdx)
+
+	edgeIsSamePoint := coordEqual(edgeV0, edgeV1)
+	splitIdx := startIdx
+	var maxDistance float64
+
+	for i := startIdx + 1; i < endIdx; i++ {
+		curr := t.Coord(i)
+		var dist float64
+		// If we are not equal any of the edges, we have to find the closest
+		// perpendicular distance from the point to the edge.
+		if !coordEqual(curr, edgeV0) && !coordEqual(curr, edgeV1) {
+			// Project the point onto the edge. If the point lies on the edge,
+			// use that projection. Otherwise, the distance is the minimum distance
+			// to one vertex of the edge. We use the math below.
+			//
+			// From http://www.faqs.org/faqs/graphics/algorithms-faq/, section 1.02
+			//
+			//  Let the point be C (Cx,Cy) and the line be AB (Ax,Ay) to (Bx,By).
+			//  Let P be the point of perpendicular projection of C on AB.  The parameter
+			//  r, which indicates P's position along AB, is computed by the dot product
+			//  of AC and AB divided by the square of the length of AB:
+			//
+			//  (1)     AC dot AB
+			//      r = ---------
+			//          ||AB||^2
+			//
+			//  r has the following meaning:
+			//
+			//      r=0      P = A
+			//      r=1      P = B
+			//      r<0      P is on the backward extension of AB
+			//      r>1      P is on the forward extension of AB
+			//      0<r<1    P is interior to AB
+			closestPointToEdge := edgeV0
+			if !edgeIsSamePoint {
+				ac := coordSub(curr, edgeV0)
+				ab := coordSub(edgeV1, edgeV0)
+
+				r := coordDot(ac, ab) / coordNorm2(ab)
+				if r >= 1 {
+					// Closest to V1.
+					closestPointToEdge = edgeV1
+				} else if r > 0 {
+					// Use the projection as the closest point.
+					closestPointToEdge = coordAdd(edgeV0, coordMul(ab, r))
+				}
+			}
+
+			// Now find the distance.
+			dist = coordNorm(coordSub(closestPointToEdge, curr))
+		}
+		if (dist > tolerance && dist > maxDistance) || forceSplit {
+			forceSplit = false
+			splitIdx = i
+			maxDistance = dist
+		}
+	}
+	return splitIdx
+}
diff --git a/pkg/geo/geomfn/snap.go b/pkg/geo/geomfn/snap.go
new file mode 100644
index 0000000..75c3ba8
--- /dev/null
+++ b/pkg/geo/geomfn/snap.go
@@ -0,0 +1,22 @@
+// Copyright 2021 The Cockroach Authors.
+//
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
+
+package geomfn
+
+import (
+	"github.com/cockroachdb/cockroachdb-parser/pkg/geo"
+	"github.com/cockroachdb/cockroachdb-parser/pkg/geo/geos"
+)
+
+// Snap returns the input geometry with the vertices snapped to the target
+// geometry. Tolerance is used to control where snapping is performed.
+// If no snapping occurs then the input geometry is returned unchanged.
+func Snap(input, target geo.Geometry, tolerance float64) (geo.Geometry, error) {
+	snappedEWKB, err := geos.Snap(input.EWKB(), target.EWKB(), tolerance)
+	if err != nil {
+		return geo.Geometry{}, err
+	}
+	return geo.ParseGeometryFromEWKB(snappedEWKB)
+}
diff --git a/pkg/geo/geomfn/snap_to_grid.go b/pkg/geo/geomfn/snap_to_grid.go
new file mode 100644
index 0000000..ad5a5eb
--- /dev/null
+++ b/pkg/geo/geomfn/snap_to_grid.go
@@ -0,0 +1,78 @@
+// Copyright 2020 The Cockroach Authors.
+//
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
+
+package geomfn
+
+import (
+	"math"
+
+	"github.com/cockroachdb/cockroachdb-parser/pkg/geo"
+	"github.com/cockroachdb/cockroachdb-parser/pkg/sql/pgwire/pgcode"
+	"github.com/cockroachdb/cockroachdb-parser/pkg/sql/pgwire/pgerror"
+	"github.com/twpayne/go-geom"
+)
+
+// SnapToGrid snaps all coordinates in the Geometry to the given grid size,
+// offset by the given origin. It will remove duplicate points from the results.
+// If the resulting geometry is invalid, it will be converted to it's EMPTY form.
+func SnapToGrid(g geo.Geometry, origin geom.Coord, gridSize geom.Coord) (geo.Geometry, error) {
+	if len(origin) != 4 {
+		return geo.Geometry{}, pgerror.Newf(pgcode.InvalidParameterValue, "origin must be 4D")
+	}
+	if len(gridSize) != 4 {
+		return geo.Geometry{}, pgerror.Newf(pgcode.InvalidParameterValue, "gridSize must be 4D")
+	}
+	if g.Empty() {
+		return g, nil
+	}
+	geomT, err := g.AsGeomT()
+	if err != nil {
+		return geo.Geometry{}, err
+	}
+	retGeomT, err := snapToGrid(geomT, origin, gridSize)
+	if err != nil {
+		return geo.Geometry{}, err
+	}
+	return geo.MakeGeometryFromGeomT(retGeomT)
+}
+
+func snapCoordinateToGrid(
+	l geom.Layout, dst []float64, src []float64, origin geom.Coord, gridSize geom.Coord,
+) {
+	dst[0] = snapOrdinateToGrid(src[0], origin[0], gridSize[0])
+	dst[1] = snapOrdinateToGrid(src[1], origin[1], gridSize[1])
+	if l.ZIndex() != -1 {
+		dst[l.ZIndex()] = snapOrdinateToGrid(src[l.ZIndex()], origin[l.ZIndex()], gridSize[l.ZIndex()])
+	}
+	if l.MIndex() != -1 {
+		dst[l.MIndex()] = snapOrdinateToGrid(src[l.MIndex()], origin[l.MIndex()], gridSize[l.MIndex()])
+	}
+}
+
+func snapOrdinateToGrid(
+	ordinate float64, originOrdinate float64, gridSizeOrdinate float64,
+) float64 {
+	// A zero grid size ordinate indicates a dimension should not be snapped.
+	// For PostGIS compatibility, a negative grid size ordinate also results
+	// in a dimension not being snapped.
+	if gridSizeOrdinate <= 0 {
+		return ordinate
+	}
+	return math.RoundToEven((ordinate-originOrdinate)/gridSizeOrdinate)*gridSizeOrdinate + originOrdinate
+}
+
+func snapToGrid(t geom.T, origin geom.Coord, gridSize geom.Coord) (geom.T, error) {
+	if t.Empty() {
+		return t, nil
+	}
+	t, err := applyOnCoordsForGeomT(t, func(l geom.Layout, dst []float64, src []float64) error {
+		snapCoordinateToGrid(l, dst, src, origin, gridSize)
+		return nil
+	})
+	if err != nil {
+		return nil, err
+	}
+	return removeConsecutivePointsFromGeomT(t)
+}
diff --git a/pkg/geo/geomfn/subdivide.go b/pkg/geo/geomfn/subdivide.go
new file mode 100644
index 0000000..406a1d7
--- /dev/null
+++ b/pkg/geo/geomfn/subdivide.go
@@ -0,0 +1,299 @@
+// Copyright 2020 The Cockroach Authors.
+//
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
+
+package geomfn
+
+import (
+	"math"
+
+	"github.com/cockroachdb/cockroachdb-parser/pkg/geo"
+	"github.com/cockroachdb/cockroachdb-parser/pkg/sql/pgwire/pgcode"
+	"github.com/cockroachdb/cockroachdb-parser/pkg/sql/pgwire/pgerror"
+	"github.com/cockroachdb/errors"
+	geom "github.com/twpayne/go-geom"
+)
+
+// Subdivide returns a geometry divided into parts, where each part contains no more than the number of vertices provided.
+func Subdivide(g geo.Geometry, maxVertices int) ([]geo.Geometry, error) {
+	if g.Empty() {
+		return []geo.Geometry{g}, nil
+	}
+	const minMaxVertices = 5
+	if maxVertices < minMaxVertices {
+		return nil, pgerror.Newf(pgcode.InvalidParameterValue, "max_vertices number cannot be less than %v", minMaxVertices)
+	}
+
+	gt, err := g.AsGeomT()
+	if err != nil {
+		return nil, errors.Wrap(err, "could not transform input geometry into geom.T")
+	}
+	dim, err := dimensionFromGeomT(gt)
+	if err != nil {
+		return nil, errors.Wrap(err, "could not calculate geometry dimension")
+	}
+	// maxDepth 50 => 2^50 ~= 10^15 subdivisions.
+	const maxDepth = 50
+	const startDepth = 0
+	geomTs, err := subdivideRecursive(gt, maxVertices, startDepth, dim, maxDepth)
+	if err != nil {
+		return nil, err
+	}
+
+	output := []geo.Geometry{}
+	for _, cg := range geomTs {
+		geo.AdjustGeomTSRID(cg, g.SRID())
+		g, err := geo.MakeGeometryFromGeomT(cg)
+		if err != nil {
+			return []geo.Geometry{}, errors.Wrap(err, "could not transform output geom.T into geometry")
+		}
+		output = append(output, g)
+	}
+	return output, nil
+}
+
+// subdivideRecursive performs the recursive subdivision on the gt provided.
+// Subdivided geom.T's that have less vertices than maxVertices are added to the results.
+// depth is compared with maxDepth, so that maximum number of subdivisions is never exceeded.
+// If gt passed is a GeometryCollection, some of the types may be shallower than the others.
+// We need dim to make sure that those geometries are ignored.
+func subdivideRecursive(
+	gt geom.T, maxVertices int, depth int, dim int, maxDepth int,
+) ([]geom.T, error) {
+	var results []geom.T
+	clip := geo.BoundingBoxFromGeomTGeometryType(gt)
+	width := clip.HiX - clip.LoX
+	height := clip.HiY - clip.LoY
+	if width == 0 && height == 0 {
+		// Point is a special case, because actual dimension is checked later in the code.
+		if gt, ok := gt.(*geom.Point); ok && dim == 0 {
+			results = append(results, gt)
+		}
+		return results, nil
+	}
+	// Boundaries needs to be widen slightly for intersection to work properly.
+	const tolerance = 1e-12
+	if width == 0 {
+		clip.HiX += tolerance
+		clip.LoX -= tolerance
+		width = 2 * tolerance
+	}
+	if height == 0 {
+		clip.HiY += tolerance
+		clip.LoY -= tolerance
+		height = 2 * tolerance
+	}
+	// Recurse into collections other than MultiPoint.
+	switch gt.(type) {
+	case *geom.MultiLineString, *geom.MultiPolygon, *geom.GeometryCollection:
+		err := forEachGeomTInCollectionForSubdivide(gt, func(gi geom.T) error {
+			// It's not a subdivision yet, so depth stays the same.
+			subdivisions, err := subdivideRecursive(gi, maxVertices, depth, dim, maxDepth)
+			if err != nil {
+				return err
+			}
+			results = append(results, subdivisions...)
+			return nil
+		})
+		if err != nil {
+			return nil, err
+		}
+		return results, nil
+	}
+	currDim, err := dimensionFromGeomT(gt)
+	if err != nil {
+		return nil, errors.Wrap(err, "error checking geom.T dimension")
+	}
+	if currDim < dim {
+		// Ignore lower dimension object produced by clipping at a shallower recursion level.
+		return results, nil
+	}
+	if depth > maxDepth {
+		results = append(results, gt)
+		return results, nil
+	}
+	nVertices := CountVertices(gt)
+	if nVertices == 0 {
+		return results, nil
+	}
+	if nVertices <= maxVertices {
+		results = append(results, gt)
+		return results, nil
+	}
+
+	splitHorizontally := width > height
+	splitPoint, err := calculateSplitPointCoordForSubdivide(gt, nVertices, splitHorizontally, *clip)
+	if err != nil {
+		return nil, err
+	}
+	subBox1 := *clip
+	subBox2 := *clip
+	if splitHorizontally {
+		subBox1.HiX = splitPoint
+		subBox2.LoX = splitPoint
+	} else {
+		subBox1.HiY = splitPoint
+		subBox2.LoY = splitPoint
+	}
+
+	clipped1, err := clipGeomTByBoundingBoxForSubdivide(gt, &subBox1)
+	if err != nil {
+		return nil, errors.Wrap(err, "error clipping geom.T")
+	}
+	clipped2, err := clipGeomTByBoundingBoxForSubdivide(gt, &subBox2)
+	if err != nil {
+		return nil, errors.Wrap(err, "error clipping geom.T")
+	}
+	depth++
+	subdivisions1, err := subdivideRecursive(clipped1, maxVertices, depth, dim, maxDepth)
+	if err != nil {
+		return nil, err
+	}
+	subdivisions2, err := subdivideRecursive(clipped2, maxVertices, depth, dim, maxDepth)
+	if err != nil {
+		return nil, err
+	}
+	results = append(results, subdivisions1...)
+	results = append(results, subdivisions2...)
+	return results, nil
+}
+
+// forEachGeomTInCollectionForSubdivide calls the provided function for each geometry in the passed in collection.
+// Ignores MultiPoint input.
+func forEachGeomTInCollectionForSubdivide(gt geom.T, fn func(geom.T) error) error {
+	switch gt := gt.(type) {
+	case *geom.GeometryCollection:
+		for i := 0; i < gt.NumGeoms(); i++ {
+			err := fn(gt.Geom(i))
+			if err != nil {
+				return err
+			}
+		}
+		return nil
+	case *geom.MultiPolygon:
+		for i := 0; i < gt.NumPolygons(); i++ {
+			err := fn(gt.Polygon(i))
+			if err != nil {
+				return err
+			}
+		}
+	case *geom.MultiLineString:
+		for i := 0; i < gt.NumLineStrings(); i++ {
+			err := fn(gt.LineString(i))
+			if err != nil {
+				return err
+			}
+		}
+	}
+	return nil
+}
+
+// calculateSplitPointCoordForSubdivide calculates the coords that can be used for splitting
+// the geom.T provided and returns their X or Y value, depending on the splitHorizontally argument.
+// These coords will be coords of the closest point to the center in case of a Polygon
+// and simply the center coords in case of any other geometry type or
+// closest point to the center being on the boundaries.
+// Specialized to be used by the Subdivide function.
+func calculateSplitPointCoordForSubdivide(
+	gt geom.T, nVertices int, splitHorizontally bool, clip geo.CartesianBoundingBox,
+) (float64, error) {
+	var pivot float64
+	switch gt := gt.(type) {
+	case *geom.Polygon:
+		var err error
+		pivot, err = findMostCentralPointValueForPolygon(gt, nVertices, splitHorizontally, &clip)
+		if err != nil {
+			return 0, errors.Wrap(err, "error finding most central point for polygon")
+		}
+		if splitHorizontally {
+			// Ignore point on the boundaries
+			if clip.LoX == pivot || clip.HiX == pivot {
+				pivot = (clip.LoX + clip.HiX) / 2
+			}
+		} else {
+			// Ignore point on the boundaries
+			if clip.LoY == pivot || clip.HiY == pivot {
+				pivot = (clip.LoY + clip.HiY) / 2
+			}
+		}
+	default:
+		if splitHorizontally {
+			pivot = (clip.LoX + clip.HiX) / 2
+		} else {
+			pivot = (clip.LoY + clip.HiY) / 2
+		}
+	}
+	return pivot, nil
+}
+
+// findMostCentralPointValueForPolygon finds the value of the most central point for a geom.Polygon.
+// Can be X or Y value, depending on the splitHorizontally argument.
+func findMostCentralPointValueForPolygon(
+	poly *geom.Polygon, nVertices int, splitHorizontally bool, clip *geo.CartesianBoundingBox,
+) (float64, error) {
+	pivot := math.MaxFloat64
+	ringToTrimIndex := 0
+	ringArea := float64(0)
+	pivotEps := math.MaxFloat64
+	var ptEps float64
+	nVerticesOuterRing := CountVertices(poly.LinearRing(0))
+	if nVertices >= 2*nVerticesOuterRing {
+		// When there are more points in holes than in outer ring, trim holes starting from biggest.
+		for i := 1; i < poly.NumLinearRings(); i++ {
+			currentRingArea := poly.LinearRing(i).Area()
+			if currentRingArea >= ringArea {
+				ringArea = currentRingArea
+				ringToTrimIndex = i
+			}
+		}
+	}
+	pa := poly.LinearRing(ringToTrimIndex)
+	// Find the most central point in the chosen ring.
+	for j := 0; j < pa.NumCoords(); j++ {
+		var pt float64
+		if splitHorizontally {
+			pt = pa.Coord(j).X()
+			xHalf := (clip.LoX + clip.HiX) / 2
+			ptEps = math.Abs(pt - xHalf)
+		} else {
+			pt = pa.Coord(j).Y()
+			yHalf := (clip.LoY + clip.HiY) / 2
+			ptEps = math.Abs(pt - yHalf)
+		}
+		if ptEps < pivotEps {
+			pivot = pt
+			pivotEps = ptEps
+		}
+	}
+	return pivot, nil
+}
+
+// clipGeomTByBoundingBoxForSubdivide returns a result of intersection and simplification of the geom.T and bounding box provided.
+// The result is also a geom.T.
+// Specialized to be used in the Subdivide function.
+func clipGeomTByBoundingBoxForSubdivide(gt geom.T, clip *geo.CartesianBoundingBox) (geom.T, error) {
+	g, err := geo.MakeGeometryFromGeomT(gt)
+	if err != nil {
+		return nil, errors.Wrap(err, "error transforming geom.T to geometry")
+	}
+	clipgt := clip.ToGeomT(g.SRID())
+	clipg, err := geo.MakeGeometryFromGeomT(clipgt)
+	if err != nil {
+		return nil, errors.Wrap(err, "error transforming geom.T to geometry")
+	}
+	out, err := Intersection(g, clipg)
+	if err != nil {
+		return nil, errors.Wrap(err, "error applying intersection")
+	}
+	// Simplify is required to remove the unnecessary points. Otherwise vertices count is altered and too many subdivision may be returned.
+	out, err = SimplifyGEOS(out, 0)
+	if err != nil {
+		return nil, errors.Wrap(err, "simplifying error")
+	}
+	gt, err = out.AsGeomT()
+	if err != nil {
+		return nil, errors.Wrap(err, "error transforming geometry to geom.T")
+	}
+	return gt, nil
+}
diff --git a/pkg/geo/geomfn/swap_ordinates.go b/pkg/geo/geomfn/swap_ordinates.go
new file mode 100644
index 0000000..f215238
--- /dev/null
+++ b/pkg/geo/geomfn/swap_ordinates.go
@@ -0,0 +1,79 @@
+// Copyright 2020 The Cockroach Authors.
+//
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
+
+package geomfn
+
+import (
+	"strings"
+
+	"github.com/cockroachdb/cockroachdb-parser/pkg/geo"
+	"github.com/cockroachdb/cockroachdb-parser/pkg/sql/pgwire/pgcode"
+	"github.com/cockroachdb/cockroachdb-parser/pkg/sql/pgwire/pgerror"
+	"github.com/twpayne/go-geom"
+)
+
+// SwapOrdinates returns a version of the given geometry with given ordinates swapped.
+// The ords parameter is a 2-characters string naming the ordinates to swap. Valid names are: x,y,z and m.
+func SwapOrdinates(geometry geo.Geometry, ords string) (geo.Geometry, error) {
+	if geometry.Empty() {
+		return geometry, nil
+	}
+
+	t, err := geometry.AsGeomT()
+	if err != nil {
+		return geometry, err
+	}
+
+	newT, err := applyOnCoordsForGeomT(t, func(l geom.Layout, dst, src []float64) error {
+		if len(ords) != 2 {
+			return pgerror.Newf(pgcode.InvalidParameterValue, "invalid ordinate specification. need two letters from the set (x, y, z and m)")
+		}
+		ordsIndices, err := getOrdsIndices(l, ords)
+		if err != nil {
+			return err
+		}
+
+		dst[ordsIndices[0]], dst[ordsIndices[1]] = src[ordsIndices[1]], src[ordsIndices[0]]
+		return nil
+	})
+	if err != nil {
+		return geometry, err
+	}
+
+	return geo.MakeGeometryFromGeomT(newT)
+}
+
+// getOrdsIndices get the indices position of ordinates string
+func getOrdsIndices(l geom.Layout, ords string) ([2]int, error) {
+	ords = strings.ToUpper(ords)
+	var ordIndices [2]int
+	for i := 0; i < len(ords); i++ {
+		oi := findOrdIndex(ords[i], l)
+		if oi == -2 {
+			return ordIndices, pgerror.Newf(pgcode.InvalidParameterValue, "invalid ordinate specification. need two letters from the set (x, y, z and m)")
+		}
+		if oi == -1 {
+			return ordIndices, pgerror.Newf(pgcode.InvalidParameterValue, "geometry does not have a %s ordinate", string(ords[i]))
+		}
+		ordIndices[i] = oi
+	}
+
+	return ordIndices, nil
+}
+
+func findOrdIndex(ordString uint8, l geom.Layout) int {
+	switch ordString {
+	case 'X':
+		return 0
+	case 'Y':
+		return 1
+	case 'Z':
+		return l.ZIndex()
+	case 'M':
+		return l.MIndex()
+	default:
+		return -2
+	}
+}
diff --git a/pkg/geo/geomfn/tile_envelope.go b/pkg/geo/geomfn/tile_envelope.go
new file mode 100644
index 0000000..e0f61ee
--- /dev/null
+++ b/pkg/geo/geomfn/tile_envelope.go
@@ -0,0 +1,112 @@
+// Copyright 2020 The Cockroach Authors.
+//
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
+
+package geomfn
+
+import (
+	"github.com/cockroachdb/cockroachdb-parser/pkg/geo"
+	"github.com/cockroachdb/cockroachdb-parser/pkg/geo/geopb"
+	"github.com/cockroachdb/cockroachdb-parser/pkg/sql/pgwire/pgcode"
+	"github.com/cockroachdb/cockroachdb-parser/pkg/sql/pgwire/pgerror"
+)
+
+// TileEnvelope returns a geometry as a rectangular Polygon giving the
+// extent of a tile in the XYZ tile system
+func TileEnvelope(
+	tileZoom int, tileX int, tileY int, bounds geo.Geometry, margin float64,
+) (geo.Geometry, error) {
+	bbox := bounds.BoundingBoxRef()
+	if bbox == nil {
+		return geo.Geometry{}, pgerror.Newf(
+			pgcode.InvalidParameterValue,
+			"Unable to compute bbox")
+	}
+	srid := bounds.SRID()
+
+	if tileZoom < 0 || tileZoom >= 32 {
+		return geo.Geometry{}, pgerror.Newf(
+			pgcode.InvalidParameterValue,
+			"Invalid tile zoom value, %d",
+			tileZoom,
+		)
+	}
+
+	if bbox.HiX-bbox.LoX <= 0 || bbox.HiY-bbox.LoY <= 0 {
+		return geo.Geometry{}, pgerror.New(
+			pgcode.InvalidParameterValue,
+			"Geometric bounds are too small",
+		)
+	}
+
+	if margin < -0.5 {
+		return geo.Geometry{}, pgerror.Newf(
+			pgcode.InvalidParameterValue,
+			"Margin value must not be less than -50%%, %d",
+			margin,
+		)
+	}
+
+	tileZoomu := uint32(tileZoom)
+	if tileZoomu > 31 {
+		tileZoomu = 31
+	}
+
+	worldTileSize := uint32(0x01) << tileZoomu
+
+	if tileX < 0 || uint32(tileX) >= worldTileSize {
+		return geo.Geometry{}, pgerror.Newf(
+			pgcode.InvalidParameterValue,
+			"Invalid tile x value, %d",
+			tileX,
+		)
+	}
+
+	if tileY < 0 || uint32(tileY) >= worldTileSize {
+		return geo.Geometry{}, pgerror.Newf(
+			pgcode.InvalidParameterValue,
+			"Invalid tile y value, %d",
+			tileY,
+		)
+	}
+
+	tileGeoSizeX := (bbox.HiX - bbox.LoX) / float64(worldTileSize)
+	tileGeoSizeY := (bbox.HiY - bbox.LoY) / float64(worldTileSize)
+
+	var x1 float64
+	var x2 float64
+
+	// 1 margin (100%) is the same as a single tile width
+	// if the size of the tile with margins span more than the total number of tiles,
+	// reset x1/x2 to the bounds
+	if 1+margin*2 > float64(worldTileSize) {
+		x1 = bbox.LoX
+		x2 = bbox.HiX
+	} else {
+		x1 = bbox.LoX + tileGeoSizeX*(float64(tileX)-margin)
+		x2 = bbox.LoX + tileGeoSizeX*(float64(tileX)+1+margin)
+	}
+
+	y1 := bbox.HiY - tileGeoSizeY*(float64(tileY)+1+margin)
+	y2 := bbox.HiY - tileGeoSizeY*(float64(tileY)-margin)
+
+	// Clip y-axis to the given bounds
+	if y1 < bbox.LoY {
+		y1 = bbox.LoY
+	}
+	if y2 > bbox.HiY {
+		y2 = bbox.HiY
+	}
+
+	envelope := &geo.CartesianBoundingBox{
+		BoundingBox: geopb.BoundingBox{
+			LoX: x1,
+			LoY: y1,
+			HiX: x2,
+			HiY: y2,
+		},
+	}
+
+	return geo.MakeGeometryFromGeomT(envelope.ToGeomT(srid))
+}
diff --git a/pkg/geo/geomfn/topology_operations.go b/pkg/geo/geomfn/topology_operations.go
new file mode 100644
index 0000000..a8b69e2
--- /dev/null
+++ b/pkg/geo/geomfn/topology_operations.go
@@ -0,0 +1,244 @@
+// Copyright 2020 The Cockroach Authors.
+//
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
+
+package geomfn
+
+import (
+	"math"
+
+	"github.com/cockroachdb/cockroachdb-parser/pkg/geo"
+	"github.com/cockroachdb/cockroachdb-parser/pkg/geo/geopb"
+	"github.com/cockroachdb/cockroachdb-parser/pkg/geo/geos"
+	"github.com/cockroachdb/cockroachdb-parser/pkg/sql/pgwire/pgcode"
+	"github.com/cockroachdb/cockroachdb-parser/pkg/sql/pgwire/pgerror"
+)
+
+// Boundary returns the boundary of a given Geometry.
+func Boundary(g geo.Geometry) (geo.Geometry, error) {
+	// follow PostGIS behavior
+	if g.Empty() {
+		return g, nil
+	}
+	boundaryEWKB, err := geos.Boundary(g.EWKB())
+	if err != nil {
+		return geo.Geometry{}, err
+	}
+	return geo.ParseGeometryFromEWKB(boundaryEWKB)
+}
+
+// Centroid returns the Centroid of a given Geometry.
+func Centroid(g geo.Geometry) (geo.Geometry, error) {
+	centroidEWKB, err := geos.Centroid(g.EWKB())
+	if err != nil {
+		return geo.Geometry{}, err
+	}
+	return geo.ParseGeometryFromEWKB(centroidEWKB)
+}
+
+// MinimumBoundingCircle returns minimum bounding circle of an EWKB
+func MinimumBoundingCircle(g geo.Geometry) (geo.Geometry, geo.Geometry, float64, error) {
+	if BoundingBoxHasInfiniteCoordinates(g) || BoundingBoxHasNaNCoordinates(g) {
+		return geo.Geometry{}, geo.Geometry{}, 0, pgerror.Newf(pgcode.InvalidParameterValue, "value out of range: overflow")
+	}
+
+	polygonEWKB, centroidEWKB, radius, err := geos.MinimumBoundingCircle(g.EWKB())
+	if err != nil {
+		return geo.Geometry{}, geo.Geometry{}, 0, err
+	}
+
+	polygon, err := geo.ParseGeometryFromEWKB(polygonEWKB)
+	if err != nil {
+		return geo.Geometry{}, geo.Geometry{}, 0, err
+	}
+
+	centroid, err := geo.ParseGeometryFromEWKB(centroidEWKB)
+	if err != nil {
+		return geo.Geometry{}, geo.Geometry{}, 0, err
+	}
+
+	return polygon, centroid, radius, nil
+}
+
+// ClipByRect clips a given Geometry by the given BoundingBox.
+func ClipByRect(g geo.Geometry, b geo.CartesianBoundingBox) (geo.Geometry, error) {
+	if g.Empty() {
+		return g, nil
+	}
+	clipByRectEWKB, err := geos.ClipByRect(g.EWKB(), b.LoX, b.LoY, b.HiX, b.HiY)
+	if err != nil {
+		return geo.Geometry{}, err
+	}
+	return geo.ParseGeometryFromEWKB(clipByRectEWKB)
+}
+
+// ConvexHull returns the convex hull of a given Geometry.
+func ConvexHull(g geo.Geometry) (geo.Geometry, error) {
+	convexHullEWKB, err := geos.ConvexHull(g.EWKB())
+	if err != nil {
+		return geo.Geometry{}, err
+	}
+	return geo.ParseGeometryFromEWKB(convexHullEWKB)
+}
+
+// Difference returns the difference between two given Geometries.
+func Difference(a, b geo.Geometry) (geo.Geometry, error) {
+	// follow PostGIS behavior
+	if a.Empty() || b.Empty() {
+		return a, nil
+	}
+	if a.SRID() != b.SRID() {
+		return geo.Geometry{}, geo.NewMismatchingSRIDsError(a.SpatialObject(), b.SpatialObject())
+	}
+	diffEWKB, err := geos.Difference(a.EWKB(), b.EWKB())
+	if err != nil {
+		return geo.Geometry{}, err
+	}
+	return geo.ParseGeometryFromEWKB(diffEWKB)
+}
+
+// SimplifyGEOS returns a simplified Geometry with GEOS.
+func SimplifyGEOS(g geo.Geometry, tolerance float64) (geo.Geometry, error) {
+	if math.IsNaN(tolerance) || g.ShapeType2D() == geopb.ShapeType_Point || g.ShapeType2D() == geopb.ShapeType_MultiPoint {
+		return g, nil
+	}
+	simplifiedEWKB, err := geos.Simplify(g.EWKB(), tolerance)
+	if err != nil {
+		return geo.Geometry{}, err
+	}
+	return geo.ParseGeometryFromEWKB(simplifiedEWKB)
+}
+
+// SimplifyPreserveTopology returns a simplified Geometry with topology preserved.
+func SimplifyPreserveTopology(g geo.Geometry, tolerance float64) (geo.Geometry, error) {
+	simplifiedEWKB, err := geos.TopologyPreserveSimplify(g.EWKB(), tolerance)
+	if err != nil {
+		return geo.Geometry{}, err
+	}
+	return geo.ParseGeometryFromEWKB(simplifiedEWKB)
+}
+
+// PointOnSurface returns the PointOnSurface of a given Geometry.
+func PointOnSurface(g geo.Geometry) (geo.Geometry, error) {
+	pointOnSurfaceEWKB, err := geos.PointOnSurface(g.EWKB())
+	if err != nil {
+		return geo.Geometry{}, err
+	}
+	return geo.ParseGeometryFromEWKB(pointOnSurfaceEWKB)
+}
+
+// Intersection returns the geometries of intersection between A and B.
+func Intersection(a geo.Geometry, b geo.Geometry) (geo.Geometry, error) {
+	if a.SRID() != b.SRID() {
+		return geo.Geometry{}, geo.NewMismatchingSRIDsError(a.SpatialObject(), b.SpatialObject())
+	}
+	// Match PostGIS.
+	if a.Empty() {
+		return a, nil
+	}
+	if b.Empty() {
+		return b, nil
+	}
+	retEWKB, err := geos.Intersection(a.EWKB(), b.EWKB())
+	if err != nil {
+		return geo.Geometry{}, err
+	}
+	return geo.ParseGeometryFromEWKB(retEWKB)
+}
+
+// UnaryUnion returns the geometry of union between input geometry components
+func UnaryUnion(g geo.Geometry) (geo.Geometry, error) {
+	retEWKB, err := geos.UnaryUnion(g.EWKB())
+	if err != nil {
+		return geo.Geometry{}, err
+	}
+	return geo.ParseGeometryFromEWKB(retEWKB)
+}
+
+// Union returns the geometries of union between A and B.
+func Union(a geo.Geometry, b geo.Geometry) (geo.Geometry, error) {
+	if a.SRID() != b.SRID() {
+		return geo.Geometry{}, geo.NewMismatchingSRIDsError(a.SpatialObject(), b.SpatialObject())
+	}
+	retEWKB, err := geos.Union(a.EWKB(), b.EWKB())
+	if err != nil {
+		return geo.Geometry{}, err
+	}
+	return geo.ParseGeometryFromEWKB(retEWKB)
+}
+
+// SymDifference returns the geometries of symmetric difference between A and B.
+func SymDifference(a geo.Geometry, b geo.Geometry) (geo.Geometry, error) {
+	if a.SRID() != b.SRID() {
+		return geo.Geometry{}, geo.NewMismatchingSRIDsError(a.SpatialObject(), b.SpatialObject())
+	}
+	retEWKB, err := geos.SymDifference(a.EWKB(), b.EWKB())
+	if err != nil {
+		return geo.Geometry{}, err
+	}
+	return geo.ParseGeometryFromEWKB(retEWKB)
+}
+
+// SharedPaths Returns a geometry collection containing paths shared by the two input geometries.
+func SharedPaths(a geo.Geometry, b geo.Geometry) (geo.Geometry, error) {
+	if a.SRID() != b.SRID() {
+		return geo.Geometry{}, geo.NewMismatchingSRIDsError(a.SpatialObject(), b.SpatialObject())
+	}
+	paths, err := geos.SharedPaths(a.EWKB(), b.EWKB())
+	if err != nil {
+		return geo.Geometry{}, err
+	}
+	gm, err := geo.ParseGeometryFromEWKB(paths)
+	if err != nil {
+		return geo.Geometry{}, err
+	}
+	return gm, nil
+}
+
+// MinimumRotatedRectangle Returns a minimum rotated rectangle enclosing a geometry
+func MinimumRotatedRectangle(g geo.Geometry) (geo.Geometry, error) {
+	paths, err := geos.MinimumRotatedRectangle(g.EWKB())
+	if err != nil {
+		return geo.Geometry{}, err
+	}
+	gm, err := geo.ParseGeometryFromEWKB(paths)
+	if err != nil {
+		return geo.Geometry{}, err
+	}
+	return gm, nil
+}
+
+// BoundingBoxHasInfiniteCoordinates checks if the bounding box of a Geometry
+// has an infinite coordinate.
+func BoundingBoxHasInfiniteCoordinates(g geo.Geometry) bool {
+	boundingBox := g.BoundingBoxRef()
+	if boundingBox == nil {
+		return false
+	}
+	// Don't use `:= range []float64{...}` to avoid memory allocation.
+	isInf := func(ord float64) bool {
+		return math.IsInf(ord, 0)
+	}
+	if isInf(boundingBox.LoX) || isInf(boundingBox.LoY) || isInf(boundingBox.HiX) || isInf(boundingBox.HiY) {
+		return true
+	}
+	return false
+}
+
+// BoundingBoxHasNaNCoordinates checks if the bounding box of a Geometry
+// has a NaN coordinate.
+func BoundingBoxHasNaNCoordinates(g geo.Geometry) bool {
+	boundingBox := g.BoundingBoxRef()
+	if boundingBox == nil {
+		return false
+	}
+	// Don't use `:= range []float64{...}` to avoid memory allocation.
+	isNaN := func(ord float64) bool {
+		return math.IsNaN(ord)
+	}
+	if isNaN(boundingBox.LoX) || isNaN(boundingBox.LoY) || isNaN(boundingBox.HiX) || isNaN(boundingBox.HiY) {
+		return true
+	}
+	return false
+}
diff --git a/pkg/geo/geomfn/unary_operators.go b/pkg/geo/geomfn/unary_operators.go
new file mode 100644
index 0000000..571d5d2
--- /dev/null
+++ b/pkg/geo/geomfn/unary_operators.go
@@ -0,0 +1,244 @@
+// Copyright 2020 The Cockroach Authors.
+//
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
+
+package geomfn
+
+import (
+	"github.com/cockroachdb/cockroachdb-parser/pkg/geo"
+	"github.com/cockroachdb/cockroachdb-parser/pkg/geo/geos"
+	"github.com/cockroachdb/errors"
+	"github.com/twpayne/go-geom"
+	"github.com/twpayne/go-geom/encoding/ewkb"
+)
+
+// Length returns the length of a given Geometry.
+// Note only (MULTI)LINESTRING objects have a length.
+// (MULTI)POLYGON objects should use Perimeter.
+func Length(g geo.Geometry) (float64, error) {
+	geomRepr, err := g.AsGeomT()
+	if err != nil {
+		return 0, err
+	}
+	// Fast path.
+	switch geomRepr.(type) {
+	case *geom.LineString, *geom.MultiLineString:
+		return geos.Length(g.EWKB())
+	}
+	return lengthFromGeomT(geomRepr)
+}
+
+// lengthFromGeomT returns the length from a geom.T, recursing down
+// GeometryCollections if required.
+func lengthFromGeomT(geomRepr geom.T) (float64, error) {
+	// Length in GEOS will also include polygon "perimeters".
+	// As such, gate based on on shape underneath.
+	switch geomRepr := geomRepr.(type) {
+	case *geom.Point, *geom.MultiPoint, *geom.Polygon, *geom.MultiPolygon:
+		return 0, nil
+	case *geom.LineString, *geom.MultiLineString:
+		ewkb, err := ewkb.Marshal(geomRepr, geo.DefaultEWKBEncodingFormat)
+		if err != nil {
+			return 0, err
+		}
+		return geos.Length(ewkb)
+	case *geom.GeometryCollection:
+		total := float64(0)
+		for _, subG := range geomRepr.Geoms() {
+			subLength, err := lengthFromGeomT(subG)
+			if err != nil {
+				return 0, err
+			}
+			total += subLength
+		}
+		return total, nil
+	default:
+		return 0, errors.AssertionFailedf("unknown geometry type: %T", geomRepr)
+	}
+}
+
+// Perimeter returns the perimeter of a given Geometry.
+// Note only (MULTI)POLYGON objects have a perimeter.
+// (MULTI)LineString objects should use Length.
+func Perimeter(g geo.Geometry) (float64, error) {
+	geomRepr, err := g.AsGeomT()
+	if err != nil {
+		return 0, err
+	}
+	// Fast path.
+	switch geomRepr.(type) {
+	case *geom.Polygon, *geom.MultiPolygon:
+		return geos.Length(g.EWKB())
+	}
+	return perimeterFromGeomT(geomRepr)
+}
+
+// perimeterFromGeomT returns the perimeter from a geom.T, recursing down
+// GeometryCollections if required.
+func perimeterFromGeomT(geomRepr geom.T) (float64, error) {
+	// Length in GEOS will also include polygon "perimeters".
+	// As such, gate based on on shape underneath.
+	switch geomRepr := geomRepr.(type) {
+	case *geom.Point, *geom.MultiPoint, *geom.LineString, *geom.MultiLineString:
+		return 0, nil
+	case *geom.Polygon, *geom.MultiPolygon:
+		ewkb, err := ewkb.Marshal(geomRepr, geo.DefaultEWKBEncodingFormat)
+		if err != nil {
+			return 0, err
+		}
+		return geos.Length(ewkb)
+	case *geom.GeometryCollection:
+		total := float64(0)
+		for _, subG := range geomRepr.Geoms() {
+			subLength, err := perimeterFromGeomT(subG)
+			if err != nil {
+				return 0, err
+			}
+			total += subLength
+		}
+		return total, nil
+	default:
+		return 0, errors.AssertionFailedf("unknown geometry type: %T", geomRepr)
+	}
+}
+
+// Area returns the area of a given Geometry.
+func Area(g geo.Geometry) (float64, error) {
+	return geos.Area(g.EWKB())
+}
+
+// Dimension returns the topological dimension of a given Geometry.
+func Dimension(g geo.Geometry) (int, error) {
+	t, err := g.AsGeomT()
+	if err != nil {
+		return 0, err
+	}
+	return dimensionFromGeomT(t)
+}
+
+// dimensionFromGeomT returns the dimension from a geom.T, recursing down
+// GeometryCollections if required.
+func dimensionFromGeomT(geomRepr geom.T) (int, error) {
+	switch geomRepr := geomRepr.(type) {
+	case *geom.Point, *geom.MultiPoint:
+		return 0, nil
+	case *geom.LineString, *geom.MultiLineString:
+		return 1, nil
+	case *geom.Polygon, *geom.MultiPolygon:
+		return 2, nil
+	case *geom.GeometryCollection:
+		maxDim := 0
+		for _, g := range geomRepr.Geoms() {
+			dim, err := dimensionFromGeomT(g)
+			if err != nil {
+				return 0, err
+			}
+			if dim > maxDim {
+				maxDim = dim
+			}
+		}
+		return maxDim, nil
+	default:
+		return 0, errors.AssertionFailedf("unknown geometry type: %T", geomRepr)
+	}
+}
+
+// Points returns the points of all coordinates in a geometry as a multipoint.
+func Points(g geo.Geometry) (geo.Geometry, error) {
+	t, err := g.AsGeomT()
+	if err != nil {
+		return geo.Geometry{}, err
+	}
+	layout := t.Layout()
+	if gc, ok := t.(*geom.GeometryCollection); ok && gc.Empty() {
+		layout = geom.XY
+	}
+	points := geom.NewMultiPoint(layout).SetSRID(t.SRID())
+	iter := geo.NewGeomTIterator(t, geo.EmptyBehaviorOmit)
+	for {
+		geomRepr, hasNext, err := iter.Next()
+		if err != nil {
+			return geo.Geometry{}, err
+		} else if !hasNext {
+			break
+		} else if geomRepr.Empty() {
+			continue
+		}
+		switch geomRepr := geomRepr.(type) {
+		case *geom.Point:
+			if err = pushCoord(points, geomRepr.Coords()); err != nil {
+				return geo.Geometry{}, err
+			}
+		case *geom.LineString:
+			for i := 0; i < geomRepr.NumCoords(); i++ {
+				if err = pushCoord(points, geomRepr.Coord(i)); err != nil {
+					return geo.Geometry{}, err
+				}
+			}
+		case *geom.Polygon:
+			for i := 0; i < geomRepr.NumLinearRings(); i++ {
+				linearRing := geomRepr.LinearRing(i)
+				for j := 0; j < linearRing.NumCoords(); j++ {
+					if err = pushCoord(points, linearRing.Coord(j)); err != nil {
+						return geo.Geometry{}, err
+					}
+				}
+			}
+		default:
+			return geo.Geometry{}, errors.AssertionFailedf("unexpected type: %T", geomRepr)
+		}
+	}
+	return geo.MakeGeometryFromGeomT(points)
+}
+
+// pushCoord is a helper function for PointsFromGeomT that appends
+// a coordinate to a multipoint as a point.
+func pushCoord(points *geom.MultiPoint, coord geom.Coord) error {
+	point, err := geom.NewPoint(points.Layout()).SetCoords(coord)
+	if err != nil {
+		return err
+	}
+	return points.Push(point)
+}
+
+// Normalize returns the geometry in its normalized form.
+func Normalize(g geo.Geometry) (geo.Geometry, error) {
+	retEWKB, err := geos.Normalize(g.EWKB())
+	if err != nil {
+		return geo.Geometry{}, err
+	}
+	return geo.ParseGeometryFromEWKB(retEWKB)
+}
+
+// MinimumClearance returns the minimum distance a vertex can move to produce
+// an invalid geometry, or infinity if no clearance was found.
+func MinimumClearance(g geo.Geometry) (float64, error) {
+	return geos.MinimumClearance(g.EWKB())
+}
+
+// MinimumClearanceLine returns the line spanning the minimum distance a vertex
+// can move to produce an invalid geometry, or an empty line if no clearance was
+// found.
+func MinimumClearanceLine(g geo.Geometry) (geo.Geometry, error) {
+	retEWKB, err := geos.MinimumClearanceLine(g.EWKB())
+	if err != nil {
+		return geo.Geometry{}, err
+	}
+	return geo.ParseGeometryFromEWKB(retEWKB)
+}
+
+// CountVertices returns a number of vertices (points) for the geom.T provided.
+func CountVertices(t geom.T) int {
+	switch t := t.(type) {
+	case *geom.GeometryCollection:
+		// FlatCoords() does not work on GeometryCollection.
+		numPoints := 0
+		for _, g := range t.Geoms() {
+			numPoints += CountVertices(g)
+		}
+		return numPoints
+	default:
+		return len(t.FlatCoords()) / t.Stride()
+	}
+}
diff --git a/pkg/geo/geomfn/unary_predicates.go b/pkg/geo/geomfn/unary_predicates.go
new file mode 100644
index 0000000..5dfa2a2
--- /dev/null
+++ b/pkg/geo/geomfn/unary_predicates.go
@@ -0,0 +1,118 @@
+// Copyright 2020 The Cockroach Authors.
+//
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
+
+package geomfn
+
+import (
+	"github.com/cockroachdb/cockroachdb-parser/pkg/geo"
+	"github.com/cockroachdb/cockroachdb-parser/pkg/geo/geopb"
+	"github.com/cockroachdb/cockroachdb-parser/pkg/geo/geos"
+	"github.com/cockroachdb/errors"
+	"github.com/twpayne/go-geom"
+)
+
+// IsClosed returns whether the given geometry has equal start and end points.
+// Collections and multi-types must contain all-closed geometries. Empty
+// geometries are not closed.
+func IsClosed(g geo.Geometry) (bool, error) {
+	t, err := g.AsGeomT()
+	if err != nil {
+		return false, err
+	}
+	return isClosedFromGeomT(t)
+}
+
+// isClosedFromGeomT returns whether the given geom.T is closed, recursing
+// into collections.
+func isClosedFromGeomT(t geom.T) (bool, error) {
+	if t.Empty() {
+		return false, nil
+	}
+	switch t := t.(type) {
+	case *geom.Point, *geom.MultiPoint:
+		return true, nil
+	case *geom.LinearRing:
+		return t.Coord(0).Equal(t.Layout(), t.Coord(t.NumCoords()-1)), nil
+	case *geom.LineString:
+		return t.Coord(0).Equal(t.Layout(), t.Coord(t.NumCoords()-1)), nil
+	case *geom.MultiLineString:
+		for i := 0; i < t.NumLineStrings(); i++ {
+			if closed, err := isClosedFromGeomT(t.LineString(i)); err != nil || !closed {
+				return false, err
+			}
+		}
+		return true, nil
+	case *geom.Polygon:
+		for i := 0; i < t.NumLinearRings(); i++ {
+			if closed, err := isClosedFromGeomT(t.LinearRing(i)); err != nil || !closed {
+				return false, err
+			}
+		}
+		return true, nil
+	case *geom.MultiPolygon:
+		for i := 0; i < t.NumPolygons(); i++ {
+			if closed, err := isClosedFromGeomT(t.Polygon(i)); err != nil || !closed {
+				return false, err
+			}
+		}
+		return true, nil
+	case *geom.GeometryCollection:
+		for _, g := range t.Geoms() {
+			if closed, err := isClosedFromGeomT(g); err != nil || !closed {
+				return false, err
+			}
+		}
+		return true, nil
+	default:
+		return false, errors.AssertionFailedf("unknown geometry type: %T", t)
+	}
+}
+
+// IsCollection returns whether the given geometry is of a collection type.
+func IsCollection(g geo.Geometry) (bool, error) {
+	switch g.ShapeType() {
+	case geopb.ShapeType_MultiPoint, geopb.ShapeType_MultiLineString, geopb.ShapeType_MultiPolygon,
+		geopb.ShapeType_GeometryCollection:
+		return true, nil
+	default:
+		return false, nil
+	}
+}
+
+// IsEmpty returns whether the given geometry is empty.
+func IsEmpty(g geo.Geometry) (bool, error) {
+	return g.Empty(), nil
+}
+
+// IsRing returns whether the given geometry is a ring, i.e. that it is a
+// simple and closed line.
+func IsRing(g geo.Geometry) (bool, error) {
+	// We explicitly check for empty geometries before checking the type,
+	// to follow PostGIS behavior where all empty geometries return false.
+	if g.Empty() {
+		return false, nil
+	}
+	if g.ShapeType() != geopb.ShapeType_LineString {
+		t, err := g.AsGeomT()
+		if err != nil {
+			return false, err
+		}
+		e := geom.ErrUnsupportedType{Value: t}
+		return false, errors.Wrap(e, "should only be called on a linear feature")
+	}
+	if closed, err := IsClosed(g); err != nil || !closed {
+		return false, err
+	}
+	if simple, err := IsSimple(g); err != nil || !simple {
+		return false, err
+	}
+	return true, nil
+}
+
+// IsSimple returns whether the given geometry is simple, i.e. that it does not
+// intersect or lie tangent to itself.
+func IsSimple(g geo.Geometry) (bool, error) {
+	return geos.IsSimple(g.EWKB())
+}
diff --git a/pkg/geo/geomfn/validity_check.go b/pkg/geo/geomfn/validity_check.go
new file mode 100644
index 0000000..9d08d65
--- /dev/null
+++ b/pkg/geo/geomfn/validity_check.go
@@ -0,0 +1,105 @@
+// Copyright 2020 The Cockroach Authors.
+//
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
+
+package geomfn
+
+import (
+	"github.com/cockroachdb/cockroachdb-parser/pkg/geo"
+	"github.com/cockroachdb/cockroachdb-parser/pkg/geo/geos"
+	"github.com/cockroachdb/cockroachdb-parser/pkg/sql/pgwire/pgcode"
+	"github.com/cockroachdb/cockroachdb-parser/pkg/sql/pgwire/pgerror"
+	"github.com/twpayne/go-geom"
+)
+
+// ValidDetail contains information about the validity of a geometry.
+type ValidDetail struct {
+	IsValid bool
+	// Reason is only populated if IsValid = false.
+	Reason string
+	// InvalidLocation is only populated if IsValid = false.
+	InvalidLocation geo.Geometry
+}
+
+// IsValid returns whether the given Geometry is valid.
+func IsValid(g geo.Geometry) (bool, error) {
+	isValid, err := geos.IsValid(g.EWKB())
+	if err != nil {
+		return false, err
+	}
+	return isValid, nil
+}
+
+// IsValidReason returns the reasoning for whether the Geometry is valid or invalid.
+func IsValidReason(g geo.Geometry) (string, error) {
+	reason, err := geos.IsValidReason(g.EWKB())
+	if err != nil {
+		return "", err
+	}
+	return reason, nil
+}
+
+// IsValidDetail returns information about the validity of a Geometry.
+// It takes in a flag parameter which behaves the same as the GEOS module, where 1
+// means that self-intersecting rings forming holes are considered valid.
+func IsValidDetail(g geo.Geometry, flags int) (ValidDetail, error) {
+	isValid, reason, locEWKB, err := geos.IsValidDetail(g.EWKB(), flags)
+	if err != nil {
+		return ValidDetail{}, err
+	}
+	var loc geo.Geometry
+	if len(locEWKB) > 0 {
+		loc, err = geo.ParseGeometryFromEWKB(locEWKB)
+		if err != nil {
+			return ValidDetail{}, err
+		}
+	}
+	return ValidDetail{
+		IsValid:         isValid,
+		Reason:          reason,
+		InvalidLocation: loc,
+	}, nil
+}
+
+// IsValidTrajectory returns whether a geometry encodes a valid trajectory
+func IsValidTrajectory(line geo.Geometry) (bool, error) {
+	t, err := line.AsGeomT()
+	if err != nil {
+		return false, err
+	}
+	lineString, ok := t.(*geom.LineString)
+	if !ok {
+		return false, pgerror.Newf(pgcode.InvalidParameterValue, "expected LineString, got %s", line.ShapeType().String())
+	}
+	mIndex := t.Layout().MIndex()
+	if mIndex < 0 {
+		return false, pgerror.Newf(pgcode.InvalidParameterValue, "LineString does not have M coordinates")
+	}
+
+	coords := lineString.Coords()
+	for i := 1; i < len(coords); i++ {
+		if coords[i][mIndex] <= coords[i-1][mIndex] {
+			return false, nil
+		}
+	}
+	return true, nil
+}
+
+// MakeValid returns a valid form of the given Geometry.
+func MakeValid(g geo.Geometry) (geo.Geometry, error) {
+	validEWKB, err := geos.MakeValid(g.EWKB())
+	if err != nil {
+		return geo.Geometry{}, err
+	}
+	return geo.ParseGeometryFromEWKB(validEWKB)
+}
+
+// EqualsExact validates if two geometry objects are exact equal under some epsilon
+func EqualsExact(lhs, rhs geo.Geometry, epsilon float64) bool {
+	equalsExact, err := geos.EqualsExact(lhs.EWKB(), rhs.EWKB(), epsilon)
+	if err != nil {
+		return false
+	}
+	return equalsExact
+}
diff --git a/pkg/geo/geomfn/voronoi.go b/pkg/geo/geomfn/voronoi.go
new file mode 100644
index 0000000..e6892bb
--- /dev/null
+++ b/pkg/geo/geomfn/voronoi.go
@@ -0,0 +1,34 @@
+// Copyright 2020 The Cockroach Authors.
+//
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
+
+package geomfn
+
+import (
+	"github.com/cockroachdb/cockroachdb-parser/pkg/geo"
+	"github.com/cockroachdb/cockroachdb-parser/pkg/geo/geopb"
+	"github.com/cockroachdb/cockroachdb-parser/pkg/geo/geos"
+)
+
+// VoronoiDiagram Computes the Voronoi Diagram from the vertices of the supplied geometry.
+func VoronoiDiagram(
+	g geo.Geometry, env *geo.Geometry, tolerance float64, onlyEdges bool,
+) (geo.Geometry, error) {
+	var envEWKB geopb.EWKB
+	if !(env == nil) {
+		if g.SRID() != env.SRID() {
+			return geo.Geometry{}, geo.NewMismatchingSRIDsError(g.SpatialObject(), env.SpatialObject())
+		}
+		envEWKB = env.EWKB()
+	}
+	paths, err := geos.VoronoiDiagram(g.EWKB(), envEWKB, tolerance, onlyEdges)
+	if err != nil {
+		return geo.Geometry{}, err
+	}
+	gm, err := geo.ParseGeometryFromEWKB(paths)
+	if err != nil {
+		return geo.Geometry{}, err
+	}
+	return gm, nil
+}
diff --git a/pkg/geo/geopb/config.go b/pkg/geo/geopb/config.go
new file mode 100644
index 0000000..8a280ed
--- /dev/null
+++ b/pkg/geo/geopb/config.go
@@ -0,0 +1,24 @@
+// Copyright 2022 The Cockroach Authors.
+//
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
+
+package geopb
+
+// IsEmpty returns whether the config contains a geospatial index
+// configuration.
+func (cfg Config) IsEmpty() bool {
+	return cfg.S2Geography == nil && cfg.S2Geometry == nil
+}
+
+// IsGeography returns whether the config is a geography geospatial index
+// configuration.
+func (cfg Config) IsGeography() bool {
+	return cfg.S2Geography != nil
+}
+
+// IsGeometry returns whether the config is a geometry geospatial index
+// configuration.
+func (cfg Config) IsGeometry() bool {
+	return cfg.S2Geometry != nil
+}
diff --git a/pkg/geo/geopb/config.pb.go b/pkg/geo/geopb/config.pb.go
new file mode 100644
index 0000000..fe25911
--- /dev/null
+++ b/pkg/geo/geopb/config.pb.go
@@ -0,0 +1,1191 @@
+// Code generated by protoc-gen-gogo. DO NOT EDIT.
+// source: geo/geopb/config.proto
+
+package geopb
+
+import (
+	encoding_binary "encoding/binary"
+	fmt "fmt"
+	_ "github.com/gogo/protobuf/gogoproto"
+	proto "github.com/gogo/protobuf/proto"
+	io "io"
+	math "math"
+	math_bits "math/bits"
+)
+
+// Reference imports to suppress errors if they are not otherwise used.
+var _ = proto.Marshal
+var _ = fmt.Errorf
+var _ = math.Inf
+
+// This is a compile-time assertion to ensure that this generated file
+// is compatible with the proto package it is being compiled against.
+// A compilation error at this line likely means your copy of the
+// proto package needs to be updated.
+const _ = proto.GoGoProtoPackageIsVersion3 // please upgrade the proto package
+
+// Config is the information used to tune one instance of a geospatial index.
+// Each SQL index will have its own config.
+//
+// At the moment, only one major indexing strategy is implemented (S2 cells).
+type Config struct {
+	S2Geography *S2GeographyConfig `protobuf:"bytes,1,opt,name=s2_geography,json=s2Geography,proto3" json:"s2_geography,omitempty"`
+	S2Geometry  *S2GeometryConfig  `protobuf:"bytes,2,opt,name=s2_geometry,json=s2Geometry,proto3" json:"s2_geometry,omitempty"`
+}
+
+func (m *Config) Reset()         { *m = Config{} }
+func (m *Config) String() string { return proto.CompactTextString(m) }
+func (*Config) ProtoMessage()    {}
+func (*Config) Descriptor() ([]byte, []int) {
+	return fileDescriptor_6c5614d57d337886, []int{0}
+}
+func (m *Config) XXX_Unmarshal(b []byte) error {
+	return m.Unmarshal(b)
+}
+func (m *Config) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+	b = b[:cap(b)]
+	n, err := m.MarshalToSizedBuffer(b)
+	if err != nil {
+		return nil, err
+	}
+	return b[:n], nil
+}
+func (m *Config) XXX_Merge(src proto.Message) {
+	xxx_messageInfo_Config.Merge(m, src)
+}
+func (m *Config) XXX_Size() int {
+	return m.Size()
+}
+func (m *Config) XXX_DiscardUnknown() {
+	xxx_messageInfo_Config.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_Config proto.InternalMessageInfo
+
+// S2Config is the required information to tune one instance of an S2 cell
+// backed geospatial index. For advanced users only -- the defaults should be
+// good enough.
+//
+// TODO(sumeer): Based on experiments, reduce the knobs below by making the
+// covering self-tuning.
+type S2Config struct {
+	// MinLevel is the minimum cell level stored in the index. If left unset, it
+	// defaults to 0.
+	MinLevel int32 `protobuf:"varint,1,opt,name=min_level,json=minLevel,proto3" json:"min_level,omitempty"`
+	// MaxLevel is the maximum cell level stored in the index. If left unset, it
+	// defaults to 30.
+	MaxLevel int32 `protobuf:"varint,2,opt,name=max_level,json=maxLevel,proto3" json:"max_level,omitempty"`
+	// `MaxLevel-MinLevel` must be an exact multiple of LevelMod. If left unset,
+	// it defaults to 1.
+	LevelMod int32 `protobuf:"varint,3,opt,name=level_mod,json=levelMod,proto3" json:"level_mod,omitempty"`
+	// MaxCells is a soft hint for the maximum number of entries used to store a
+	// single geospatial object. If left unset, it defaults to 4.
+	MaxCells int32 `protobuf:"varint,4,opt,name=max_cells,json=maxCells,proto3" json:"max_cells,omitempty"`
+}
+
+func (m *S2Config) Reset()         { *m = S2Config{} }
+func (m *S2Config) String() string { return proto.CompactTextString(m) }
+func (*S2Config) ProtoMessage()    {}
+func (*S2Config) Descriptor() ([]byte, []int) {
+	return fileDescriptor_6c5614d57d337886, []int{1}
+}
+func (m *S2Config) XXX_Unmarshal(b []byte) error {
+	return m.Unmarshal(b)
+}
+func (m *S2Config) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+	b = b[:cap(b)]
+	n, err := m.MarshalToSizedBuffer(b)
+	if err != nil {
+		return nil, err
+	}
+	return b[:n], nil
+}
+func (m *S2Config) XXX_Merge(src proto.Message) {
+	xxx_messageInfo_S2Config.Merge(m, src)
+}
+func (m *S2Config) XXX_Size() int {
+	return m.Size()
+}
+func (m *S2Config) XXX_DiscardUnknown() {
+	xxx_messageInfo_S2Config.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_S2Config proto.InternalMessageInfo
+
+type S2GeographyConfig struct {
+	S2Config *S2Config `protobuf:"bytes,1,opt,name=s2_config,json=s2Config,proto3" json:"s2_config,omitempty"`
+}
+
+func (m *S2GeographyConfig) Reset()         { *m = S2GeographyConfig{} }
+func (m *S2GeographyConfig) String() string { return proto.CompactTextString(m) }
+func (*S2GeographyConfig) ProtoMessage()    {}
+func (*S2GeographyConfig) Descriptor() ([]byte, []int) {
+	return fileDescriptor_6c5614d57d337886, []int{2}
+}
+func (m *S2GeographyConfig) XXX_Unmarshal(b []byte) error {
+	return m.Unmarshal(b)
+}
+func (m *S2GeographyConfig) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+	b = b[:cap(b)]
+	n, err := m.MarshalToSizedBuffer(b)
+	if err != nil {
+		return nil, err
+	}
+	return b[:n], nil
+}
+func (m *S2GeographyConfig) XXX_Merge(src proto.Message) {
+	xxx_messageInfo_S2GeographyConfig.Merge(m, src)
+}
+func (m *S2GeographyConfig) XXX_Size() int {
+	return m.Size()
+}
+func (m *S2GeographyConfig) XXX_DiscardUnknown() {
+	xxx_messageInfo_S2GeographyConfig.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_S2GeographyConfig proto.InternalMessageInfo
+
+type S2GeometryConfig struct {
+	// The rectangle bounds of the plane that will be efficiently indexed. Shapes
+	// should rarely exceed these bounds.
+	MinX     float64   `protobuf:"fixed64,1,opt,name=min_x,json=minX,proto3" json:"min_x,omitempty"`
+	MaxX     float64   `protobuf:"fixed64,2,opt,name=max_x,json=maxX,proto3" json:"max_x,omitempty"`
+	MinY     float64   `protobuf:"fixed64,3,opt,name=min_y,json=minY,proto3" json:"min_y,omitempty"`
+	MaxY     float64   `protobuf:"fixed64,4,opt,name=max_y,json=maxY,proto3" json:"max_y,omitempty"`
+	S2Config *S2Config `protobuf:"bytes,5,opt,name=s2_config,json=s2Config,proto3" json:"s2_config,omitempty"`
+}
+
+func (m *S2GeometryConfig) Reset()         { *m = S2GeometryConfig{} }
+func (m *S2GeometryConfig) String() string { return proto.CompactTextString(m) }
+func (*S2GeometryConfig) ProtoMessage()    {}
+func (*S2GeometryConfig) Descriptor() ([]byte, []int) {
+	return fileDescriptor_6c5614d57d337886, []int{3}
+}
+func (m *S2GeometryConfig) XXX_Unmarshal(b []byte) error {
+	return m.Unmarshal(b)
+}
+func (m *S2GeometryConfig) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+	b = b[:cap(b)]
+	n, err := m.MarshalToSizedBuffer(b)
+	if err != nil {
+		return nil, err
+	}
+	return b[:n], nil
+}
+func (m *S2GeometryConfig) XXX_Merge(src proto.Message) {
+	xxx_messageInfo_S2GeometryConfig.Merge(m, src)
+}
+func (m *S2GeometryConfig) XXX_Size() int {
+	return m.Size()
+}
+func (m *S2GeometryConfig) XXX_DiscardUnknown() {
+	xxx_messageInfo_S2GeometryConfig.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_S2GeometryConfig proto.InternalMessageInfo
+
+func init() {
+	proto.RegisterType((*Config)(nil), "cockroach.parser.geo.geoindex.Config")
+	proto.RegisterType((*S2Config)(nil), "cockroach.parser.geo.geoindex.S2Config")
+	proto.RegisterType((*S2GeographyConfig)(nil), "cockroach.parser.geo.geoindex.S2GeographyConfig")
+	proto.RegisterType((*S2GeometryConfig)(nil), "cockroach.parser.geo.geoindex.S2GeometryConfig")
+}
+
+func init() { proto.RegisterFile("geo/geopb/config.proto", fileDescriptor_6c5614d57d337886) }
+
+var fileDescriptor_6c5614d57d337886 = []byte{
+	// 394 bytes of a gzipped FileDescriptorProto
+	0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x9c, 0x52, 0xbd, 0x6e, 0xfa, 0x30,
+	0x1c, 0x8c, 0xf9, 0x03, 0x0a, 0xe6, 0x3f, 0xb4, 0x69, 0x85, 0xa2, 0x56, 0x32, 0x88, 0x89, 0x2e,
+	0x89, 0x94, 0x6e, 0x48, 0x5d, 0xca, 0x50, 0x55, 0xa2, 0x52, 0x05, 0x0b, 0x74, 0x89, 0xf2, 0xe1,
+	0x9a, 0x88, 0x24, 0x8e, 0x12, 0x5a, 0x25, 0x7b, 0x1f, 0xa0, 0x8f, 0xc0, 0xce, 0x8b, 0x30, 0x32,
+	0x32, 0xb6, 0x61, 0xe9, 0x63, 0x54, 0x71, 0x9c, 0xa0, 0x7e, 0x0e, 0x1d, 0x22, 0xfd, 0x7c, 0x77,
+	0xbf, 0xd3, 0x9d, 0x63, 0xd8, 0x22, 0x98, 0xaa, 0x04, 0xd3, 0xc0, 0x54, 0x2d, 0xea, 0xdf, 0x3b,
+	0x44, 0x09, 0x42, 0xba, 0xa0, 0x52, 0xcb, 0xa2, 0xd6, 0x3c, 0xa4, 0x86, 0x35, 0x53, 0x08, 0xa6,
+	0xd9, 0xe7, 0xf8, 0x36, 0x8e, 0x4f, 0x8e, 0x09, 0x25, 0x94, 0x49, 0xd4, 0x6c, 0xca, 0xd5, 0xdd,
+	0x15, 0x80, 0xf5, 0x01, 0x5b, 0x97, 0x86, 0xf0, 0x7f, 0xa4, 0xe9, 0x04, 0x53, 0x12, 0x1a, 0xc1,
+	0x2c, 0x91, 0x41, 0x07, 0xf4, 0x9a, 0xda, 0x99, 0xf2, 0xbd, 0x9f, 0x32, 0xd6, 0xae, 0x0a, 0x69,
+	0x6e, 0x30, 0x6a, 0x46, 0x7b, 0x48, 0xba, 0x86, 0xcd, 0xdc, 0xcd, 0xc3, 0x8b, 0x30, 0x91, 0x2b,
+	0xcc, 0xac, 0xf7, 0xab, 0x19, 0x53, 0x72, 0x2f, 0x18, 0x95, 0x48, 0x5f, 0x5c, 0x2f, 0xdb, 0xe0,
+	0x6d, 0xd9, 0x06, 0xdd, 0x27, 0x00, 0xc5, 0xb1, 0xc6, 0xf3, 0x9e, 0xc2, 0x86, 0xe7, 0xf8, 0xba,
+	0x8b, 0x1f, 0xb1, 0xcb, 0xc2, 0xd6, 0x46, 0xa2, 0xe7, 0xf8, 0xc3, 0xec, 0xcc, 0x48, 0x23, 0xe6,
+	0x64, 0x85, 0x93, 0x46, 0x5c, 0x92, 0x8c, 0xd0, 0x3d, 0x6a, 0xcb, 0xff, 0x72, 0x92, 0x01, 0x37,
+	0xd4, 0x2e, 0x36, 0x2d, 0xec, 0xba, 0x91, 0x5c, 0x2d, 0x37, 0x07, 0xd9, 0xb9, 0x5f, 0x65, 0x31,
+	0x26, 0xf0, 0xf0, 0x4b, 0x7b, 0xe9, 0x02, 0x36, 0x22, 0x4d, 0xcf, 0x7f, 0x05, 0xbf, 0xbb, 0xce,
+	0xcf, 0x75, 0x79, 0x4d, 0x31, 0xe2, 0x13, 0x77, 0x5e, 0x01, 0x78, 0xf0, 0xf9, 0x2e, 0xa4, 0x23,
+	0x58, 0xcb, 0x8a, 0xc6, 0xcc, 0x15, 0x8c, 0xaa, 0x9e, 0xe3, 0x4f, 0x18, 0x68, 0xc4, 0x7a, 0xcc,
+	0xca, 0x65, 0xa0, 0x11, 0x4f, 0x0a, 0x65, 0xc2, 0x4a, 0xe5, 0xca, 0x69, 0xa1, 0x4c, 0x58, 0x99,
+	0x5c, 0x39, 0xfd, 0x98, 0xb6, 0xf6, 0xb7, 0xb4, 0x97, 0xb7, 0xeb, 0x57, 0x24, 0xac, 0x53, 0x04,
+	0x36, 0x29, 0x02, 0xdb, 0x14, 0x81, 0x97, 0x14, 0x81, 0xe7, 0x1d, 0x12, 0x36, 0x3b, 0x24, 0x6c,
+	0x77, 0x48, 0xb8, 0x53, 0x88, 0xb3, 0x98, 0x3d, 0x98, 0x8a, 0x45, 0x3d, 0xb5, 0x74, 0xb7, 0xcd,
+	0xfd, 0xac, 0x06, 0x73, 0xa2, 0x96, 0x2f, 0xd9, 0xac, 0xb3, 0x57, 0x79, 0xfe, 0x1e, 0x00, 0x00,
+	0xff, 0xff, 0x1e, 0xdc, 0x45, 0x29, 0xdd, 0x02, 0x00, 0x00,
+}
+
+func (this *Config) Equal(that interface{}) bool {
+	if that == nil {
+		return this == nil
+	}
+
+	that1, ok := that.(*Config)
+	if !ok {
+		that2, ok := that.(Config)
+		if ok {
+			that1 = &that2
+		} else {
+			return false
+		}
+	}
+	if that1 == nil {
+		return this == nil
+	} else if this == nil {
+		return false
+	}
+	if !this.S2Geography.Equal(that1.S2Geography) {
+		return false
+	}
+	if !this.S2Geometry.Equal(that1.S2Geometry) {
+		return false
+	}
+	return true
+}
+func (this *S2Config) Equal(that interface{}) bool {
+	if that == nil {
+		return this == nil
+	}
+
+	that1, ok := that.(*S2Config)
+	if !ok {
+		that2, ok := that.(S2Config)
+		if ok {
+			that1 = &that2
+		} else {
+			return false
+		}
+	}
+	if that1 == nil {
+		return this == nil
+	} else if this == nil {
+		return false
+	}
+	if this.MinLevel != that1.MinLevel {
+		return false
+	}
+	if this.MaxLevel != that1.MaxLevel {
+		return false
+	}
+	if this.LevelMod != that1.LevelMod {
+		return false
+	}
+	if this.MaxCells != that1.MaxCells {
+		return false
+	}
+	return true
+}
+func (this *S2GeographyConfig) Equal(that interface{}) bool {
+	if that == nil {
+		return this == nil
+	}
+
+	that1, ok := that.(*S2GeographyConfig)
+	if !ok {
+		that2, ok := that.(S2GeographyConfig)
+		if ok {
+			that1 = &that2
+		} else {
+			return false
+		}
+	}
+	if that1 == nil {
+		return this == nil
+	} else if this == nil {
+		return false
+	}
+	if !this.S2Config.Equal(that1.S2Config) {
+		return false
+	}
+	return true
+}
+func (this *S2GeometryConfig) Equal(that interface{}) bool {
+	if that == nil {
+		return this == nil
+	}
+
+	that1, ok := that.(*S2GeometryConfig)
+	if !ok {
+		that2, ok := that.(S2GeometryConfig)
+		if ok {
+			that1 = &that2
+		} else {
+			return false
+		}
+	}
+	if that1 == nil {
+		return this == nil
+	} else if this == nil {
+		return false
+	}
+	if this.MinX != that1.MinX {
+		return false
+	}
+	if this.MaxX != that1.MaxX {
+		return false
+	}
+	if this.MinY != that1.MinY {
+		return false
+	}
+	if this.MaxY != that1.MaxY {
+		return false
+	}
+	if !this.S2Config.Equal(that1.S2Config) {
+		return false
+	}
+	return true
+}
+func (m *Config) Marshal() (dAtA []byte, err error) {
+	size := m.Size()
+	dAtA = make([]byte, size)
+	n, err := m.MarshalToSizedBuffer(dAtA[:size])
+	if err != nil {
+		return nil, err
+	}
+	return dAtA[:n], nil
+}
+
+func (m *Config) MarshalTo(dAtA []byte) (int, error) {
+	size := m.Size()
+	return m.MarshalToSizedBuffer(dAtA[:size])
+}
+
+func (m *Config) MarshalToSizedBuffer(dAtA []byte) (int, error) {
+	i := len(dAtA)
+	_ = i
+	var l int
+	_ = l
+	if m.S2Geometry != nil {
+		{
+			size, err := m.S2Geometry.MarshalToSizedBuffer(dAtA[:i])
+			if err != nil {
+				return 0, err
+			}
+			i -= size
+			i = encodeVarintConfig(dAtA, i, uint64(size))
+		}
+		i--
+		dAtA[i] = 0x12
+	}
+	if m.S2Geography != nil {
+		{
+			size, err := m.S2Geography.MarshalToSizedBuffer(dAtA[:i])
+			if err != nil {
+				return 0, err
+			}
+			i -= size
+			i = encodeVarintConfig(dAtA, i, uint64(size))
+		}
+		i--
+		dAtA[i] = 0xa
+	}
+	return len(dAtA) - i, nil
+}
+
+func (m *S2Config) Marshal() (dAtA []byte, err error) {
+	size := m.Size()
+	dAtA = make([]byte, size)
+	n, err := m.MarshalToSizedBuffer(dAtA[:size])
+	if err != nil {
+		return nil, err
+	}
+	return dAtA[:n], nil
+}
+
+func (m *S2Config) MarshalTo(dAtA []byte) (int, error) {
+	size := m.Size()
+	return m.MarshalToSizedBuffer(dAtA[:size])
+}
+
+func (m *S2Config) MarshalToSizedBuffer(dAtA []byte) (int, error) {
+	i := len(dAtA)
+	_ = i
+	var l int
+	_ = l
+	if m.MaxCells != 0 {
+		i = encodeVarintConfig(dAtA, i, uint64(m.MaxCells))
+		i--
+		dAtA[i] = 0x20
+	}
+	if m.LevelMod != 0 {
+		i = encodeVarintConfig(dAtA, i, uint64(m.LevelMod))
+		i--
+		dAtA[i] = 0x18
+	}
+	if m.MaxLevel != 0 {
+		i = encodeVarintConfig(dAtA, i, uint64(m.MaxLevel))
+		i--
+		dAtA[i] = 0x10
+	}
+	if m.MinLevel != 0 {
+		i = encodeVarintConfig(dAtA, i, uint64(m.MinLevel))
+		i--
+		dAtA[i] = 0x8
+	}
+	return len(dAtA) - i, nil
+}
+
+func (m *S2GeographyConfig) Marshal() (dAtA []byte, err error) {
+	size := m.Size()
+	dAtA = make([]byte, size)
+	n, err := m.MarshalToSizedBuffer(dAtA[:size])
+	if err != nil {
+		return nil, err
+	}
+	return dAtA[:n], nil
+}
+
+func (m *S2GeographyConfig) MarshalTo(dAtA []byte) (int, error) {
+	size := m.Size()
+	return m.MarshalToSizedBuffer(dAtA[:size])
+}
+
+func (m *S2GeographyConfig) MarshalToSizedBuffer(dAtA []byte) (int, error) {
+	i := len(dAtA)
+	_ = i
+	var l int
+	_ = l
+	if m.S2Config != nil {
+		{
+			size, err := m.S2Config.MarshalToSizedBuffer(dAtA[:i])
+			if err != nil {
+				return 0, err
+			}
+			i -= size
+			i = encodeVarintConfig(dAtA, i, uint64(size))
+		}
+		i--
+		dAtA[i] = 0xa
+	}
+	return len(dAtA) - i, nil
+}
+
+func (m *S2GeometryConfig) Marshal() (dAtA []byte, err error) {
+	size := m.Size()
+	dAtA = make([]byte, size)
+	n, err := m.MarshalToSizedBuffer(dAtA[:size])
+	if err != nil {
+		return nil, err
+	}
+	return dAtA[:n], nil
+}
+
+func (m *S2GeometryConfig) MarshalTo(dAtA []byte) (int, error) {
+	size := m.Size()
+	return m.MarshalToSizedBuffer(dAtA[:size])
+}
+
+func (m *S2GeometryConfig) MarshalToSizedBuffer(dAtA []byte) (int, error) {
+	i := len(dAtA)
+	_ = i
+	var l int
+	_ = l
+	if m.S2Config != nil {
+		{
+			size, err := m.S2Config.MarshalToSizedBuffer(dAtA[:i])
+			if err != nil {
+				return 0, err
+			}
+			i -= size
+			i = encodeVarintConfig(dAtA, i, uint64(size))
+		}
+		i--
+		dAtA[i] = 0x2a
+	}
+	if m.MaxY != 0 {
+		i -= 8
+		encoding_binary.LittleEndian.PutUint64(dAtA[i:], uint64(math.Float64bits(float64(m.MaxY))))
+		i--
+		dAtA[i] = 0x21
+	}
+	if m.MinY != 0 {
+		i -= 8
+		encoding_binary.LittleEndian.PutUint64(dAtA[i:], uint64(math.Float64bits(float64(m.MinY))))
+		i--
+		dAtA[i] = 0x19
+	}
+	if m.MaxX != 0 {
+		i -= 8
+		encoding_binary.LittleEndian.PutUint64(dAtA[i:], uint64(math.Float64bits(float64(m.MaxX))))
+		i--
+		dAtA[i] = 0x11
+	}
+	if m.MinX != 0 {
+		i -= 8
+		encoding_binary.LittleEndian.PutUint64(dAtA[i:], uint64(math.Float64bits(float64(m.MinX))))
+		i--
+		dAtA[i] = 0x9
+	}
+	return len(dAtA) - i, nil
+}
+
+func encodeVarintConfig(dAtA []byte, offset int, v uint64) int {
+	offset -= sovConfig(v)
+	base := offset
+	for v >= 1<<7 {
+		dAtA[offset] = uint8(v&0x7f | 0x80)
+		v >>= 7
+		offset++
+	}
+	dAtA[offset] = uint8(v)
+	return base
+}
+func (m *Config) Size() (n int) {
+	if m == nil {
+		return 0
+	}
+	var l int
+	_ = l
+	if m.S2Geography != nil {
+		l = m.S2Geography.Size()
+		n += 1 + l + sovConfig(uint64(l))
+	}
+	if m.S2Geometry != nil {
+		l = m.S2Geometry.Size()
+		n += 1 + l + sovConfig(uint64(l))
+	}
+	return n
+}
+
+func (m *S2Config) Size() (n int) {
+	if m == nil {
+		return 0
+	}
+	var l int
+	_ = l
+	if m.MinLevel != 0 {
+		n += 1 + sovConfig(uint64(m.MinLevel))
+	}
+	if m.MaxLevel != 0 {
+		n += 1 + sovConfig(uint64(m.MaxLevel))
+	}
+	if m.LevelMod != 0 {
+		n += 1 + sovConfig(uint64(m.LevelMod))
+	}
+	if m.MaxCells != 0 {
+		n += 1 + sovConfig(uint64(m.MaxCells))
+	}
+	return n
+}
+
+func (m *S2GeographyConfig) Size() (n int) {
+	if m == nil {
+		return 0
+	}
+	var l int
+	_ = l
+	if m.S2Config != nil {
+		l = m.S2Config.Size()
+		n += 1 + l + sovConfig(uint64(l))
+	}
+	return n
+}
+
+func (m *S2GeometryConfig) Size() (n int) {
+	if m == nil {
+		return 0
+	}
+	var l int
+	_ = l
+	if m.MinX != 0 {
+		n += 9
+	}
+	if m.MaxX != 0 {
+		n += 9
+	}
+	if m.MinY != 0 {
+		n += 9
+	}
+	if m.MaxY != 0 {
+		n += 9
+	}
+	if m.S2Config != nil {
+		l = m.S2Config.Size()
+		n += 1 + l + sovConfig(uint64(l))
+	}
+	return n
+}
+
+func sovConfig(x uint64) (n int) {
+	return int((uint32(math_bits.Len64(x|1)+6) * 37) >> 8)
+}
+func sozConfig(x uint64) (n int) {
+	return sovConfig(uint64((x << 1) ^ uint64((int64(x) >> 63))))
+}
+func (this *Config) GetValue() interface{} {
+	if this.S2Geography != nil {
+		return this.S2Geography
+	}
+	if this.S2Geometry != nil {
+		return this.S2Geometry
+	}
+	return nil
+}
+
+func (this *Config) SetValue(value interface{}) bool {
+	switch vt := value.(type) {
+	case *S2GeographyConfig:
+		this.S2Geography = vt
+	case *S2GeometryConfig:
+		this.S2Geometry = vt
+	default:
+		return false
+	}
+	return true
+}
+func (m *Config) Unmarshal(dAtA []byte) error {
+	l := len(dAtA)
+	iNdEx := 0
+	for iNdEx < l {
+		preIndex := iNdEx
+		var wire uint64
+		for shift := uint(0); ; shift += 7 {
+			if shift >= 64 {
+				return ErrIntOverflowConfig
+			}
+			if iNdEx >= l {
+				return io.ErrUnexpectedEOF
+			}
+			b := dAtA[iNdEx]
+			iNdEx++
+			wire |= uint64(b&0x7F) << shift
+			if b < 0x80 {
+				break
+			}
+		}
+		fieldNum := int32(wire >> 3)
+		wireType := int(wire & 0x7)
+		if wireType == 4 {
+			return fmt.Errorf("proto: Config: wiretype end group for non-group")
+		}
+		if fieldNum <= 0 {
+			return fmt.Errorf("proto: Config: illegal tag %d (wire type %d)", fieldNum, wire)
+		}
+		switch fieldNum {
+		case 1:
+			if wireType != 2 {
+				return fmt.Errorf("proto: wrong wireType = %d for field S2Geography", wireType)
+			}
+			var msglen int
+			for shift := uint(0); ; shift += 7 {
+				if shift >= 64 {
+					return ErrIntOverflowConfig
+				}
+				if iNdEx >= l {
+					return io.ErrUnexpectedEOF
+				}
+				b := dAtA[iNdEx]
+				iNdEx++
+				msglen |= int(b&0x7F) << shift
+				if b < 0x80 {
+					break
+				}
+			}
+			if msglen < 0 {
+				return ErrInvalidLengthConfig
+			}
+			postIndex := iNdEx + msglen
+			if postIndex < 0 {
+				return ErrInvalidLengthConfig
+			}
+			if postIndex > l {
+				return io.ErrUnexpectedEOF
+			}
+			if m.S2Geography == nil {
+				m.S2Geography = &S2GeographyConfig{}
+			}
+			if err := m.S2Geography.Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
+				return err
+			}
+			iNdEx = postIndex
+		case 2:
+			if wireType != 2 {
+				return fmt.Errorf("proto: wrong wireType = %d for field S2Geometry", wireType)
+			}
+			var msglen int
+			for shift := uint(0); ; shift += 7 {
+				if shift >= 64 {
+					return ErrIntOverflowConfig
+				}
+				if iNdEx >= l {
+					return io.ErrUnexpectedEOF
+				}
+				b := dAtA[iNdEx]
+				iNdEx++
+				msglen |= int(b&0x7F) << shift
+				if b < 0x80 {
+					break
+				}
+			}
+			if msglen < 0 {
+				return ErrInvalidLengthConfig
+			}
+			postIndex := iNdEx + msglen
+			if postIndex < 0 {
+				return ErrInvalidLengthConfig
+			}
+			if postIndex > l {
+				return io.ErrUnexpectedEOF
+			}
+			if m.S2Geometry == nil {
+				m.S2Geometry = &S2GeometryConfig{}
+			}
+			if err := m.S2Geometry.Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
+				return err
+			}
+			iNdEx = postIndex
+		default:
+			iNdEx = preIndex
+			skippy, err := skipConfig(dAtA[iNdEx:])
+			if err != nil {
+				return err
+			}
+			if (skippy < 0) || (iNdEx+skippy) < 0 {
+				return ErrInvalidLengthConfig
+			}
+			if (iNdEx + skippy) > l {
+				return io.ErrUnexpectedEOF
+			}
+			iNdEx += skippy
+		}
+	}
+
+	if iNdEx > l {
+		return io.ErrUnexpectedEOF
+	}
+	return nil
+}
+func (m *S2Config) Unmarshal(dAtA []byte) error {
+	l := len(dAtA)
+	iNdEx := 0
+	for iNdEx < l {
+		preIndex := iNdEx
+		var wire uint64
+		for shift := uint(0); ; shift += 7 {
+			if shift >= 64 {
+				return ErrIntOverflowConfig
+			}
+			if iNdEx >= l {
+				return io.ErrUnexpectedEOF
+			}
+			b := dAtA[iNdEx]
+			iNdEx++
+			wire |= uint64(b&0x7F) << shift
+			if b < 0x80 {
+				break
+			}
+		}
+		fieldNum := int32(wire >> 3)
+		wireType := int(wire & 0x7)
+		if wireType == 4 {
+			return fmt.Errorf("proto: S2Config: wiretype end group for non-group")
+		}
+		if fieldNum <= 0 {
+			return fmt.Errorf("proto: S2Config: illegal tag %d (wire type %d)", fieldNum, wire)
+		}
+		switch fieldNum {
+		case 1:
+			if wireType != 0 {
+				return fmt.Errorf("proto: wrong wireType = %d for field MinLevel", wireType)
+			}
+			m.MinLevel = 0
+			for shift := uint(0); ; shift += 7 {
+				if shift >= 64 {
+					return ErrIntOverflowConfig
+				}
+				if iNdEx >= l {
+					return io.ErrUnexpectedEOF
+				}
+				b := dAtA[iNdEx]
+				iNdEx++
+				m.MinLevel |= int32(b&0x7F) << shift
+				if b < 0x80 {
+					break
+				}
+			}
+		case 2:
+			if wireType != 0 {
+				return fmt.Errorf("proto: wrong wireType = %d for field MaxLevel", wireType)
+			}
+			m.MaxLevel = 0
+			for shift := uint(0); ; shift += 7 {
+				if shift >= 64 {
+					return ErrIntOverflowConfig
+				}
+				if iNdEx >= l {
+					return io.ErrUnexpectedEOF
+				}
+				b := dAtA[iNdEx]
+				iNdEx++
+				m.MaxLevel |= int32(b&0x7F) << shift
+				if b < 0x80 {
+					break
+				}
+			}
+		case 3:
+			if wireType != 0 {
+				return fmt.Errorf("proto: wrong wireType = %d for field LevelMod", wireType)
+			}
+			m.LevelMod = 0
+			for shift := uint(0); ; shift += 7 {
+				if shift >= 64 {
+					return ErrIntOverflowConfig
+				}
+				if iNdEx >= l {
+					return io.ErrUnexpectedEOF
+				}
+				b := dAtA[iNdEx]
+				iNdEx++
+				m.LevelMod |= int32(b&0x7F) << shift
+				if b < 0x80 {
+					break
+				}
+			}
+		case 4:
+			if wireType != 0 {
+				return fmt.Errorf("proto: wrong wireType = %d for field MaxCells", wireType)
+			}
+			m.MaxCells = 0
+			for shift := uint(0); ; shift += 7 {
+				if shift >= 64 {
+					return ErrIntOverflowConfig
+				}
+				if iNdEx >= l {
+					return io.ErrUnexpectedEOF
+				}
+				b := dAtA[iNdEx]
+				iNdEx++
+				m.MaxCells |= int32(b&0x7F) << shift
+				if b < 0x80 {
+					break
+				}
+			}
+		default:
+			iNdEx = preIndex
+			skippy, err := skipConfig(dAtA[iNdEx:])
+			if err != nil {
+				return err
+			}
+			if (skippy < 0) || (iNdEx+skippy) < 0 {
+				return ErrInvalidLengthConfig
+			}
+			if (iNdEx + skippy) > l {
+				return io.ErrUnexpectedEOF
+			}
+			iNdEx += skippy
+		}
+	}
+
+	if iNdEx > l {
+		return io.ErrUnexpectedEOF
+	}
+	return nil
+}
+func (m *S2GeographyConfig) Unmarshal(dAtA []byte) error {
+	l := len(dAtA)
+	iNdEx := 0
+	for iNdEx < l {
+		preIndex := iNdEx
+		var wire uint64
+		for shift := uint(0); ; shift += 7 {
+			if shift >= 64 {
+				return ErrIntOverflowConfig
+			}
+			if iNdEx >= l {
+				return io.ErrUnexpectedEOF
+			}
+			b := dAtA[iNdEx]
+			iNdEx++
+			wire |= uint64(b&0x7F) << shift
+			if b < 0x80 {
+				break
+			}
+		}
+		fieldNum := int32(wire >> 3)
+		wireType := int(wire & 0x7)
+		if wireType == 4 {
+			return fmt.Errorf("proto: S2GeographyConfig: wiretype end group for non-group")
+		}
+		if fieldNum <= 0 {
+			return fmt.Errorf("proto: S2GeographyConfig: illegal tag %d (wire type %d)", fieldNum, wire)
+		}
+		switch fieldNum {
+		case 1:
+			if wireType != 2 {
+				return fmt.Errorf("proto: wrong wireType = %d for field S2Config", wireType)
+			}
+			var msglen int
+			for shift := uint(0); ; shift += 7 {
+				if shift >= 64 {
+					return ErrIntOverflowConfig
+				}
+				if iNdEx >= l {
+					return io.ErrUnexpectedEOF
+				}
+				b := dAtA[iNdEx]
+				iNdEx++
+				msglen |= int(b&0x7F) << shift
+				if b < 0x80 {
+					break
+				}
+			}
+			if msglen < 0 {
+				return ErrInvalidLengthConfig
+			}
+			postIndex := iNdEx + msglen
+			if postIndex < 0 {
+				return ErrInvalidLengthConfig
+			}
+			if postIndex > l {
+				return io.ErrUnexpectedEOF
+			}
+			if m.S2Config == nil {
+				m.S2Config = &S2Config{}
+			}
+			if err := m.S2Config.Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
+				return err
+			}
+			iNdEx = postIndex
+		default:
+			iNdEx = preIndex
+			skippy, err := skipConfig(dAtA[iNdEx:])
+			if err != nil {
+				return err
+			}
+			if (skippy < 0) || (iNdEx+skippy) < 0 {
+				return ErrInvalidLengthConfig
+			}
+			if (iNdEx + skippy) > l {
+				return io.ErrUnexpectedEOF
+			}
+			iNdEx += skippy
+		}
+	}
+
+	if iNdEx > l {
+		return io.ErrUnexpectedEOF
+	}
+	return nil
+}
+func (m *S2GeometryConfig) Unmarshal(dAtA []byte) error {
+	l := len(dAtA)
+	iNdEx := 0
+	for iNdEx < l {
+		preIndex := iNdEx
+		var wire uint64
+		for shift := uint(0); ; shift += 7 {
+			if shift >= 64 {
+				return ErrIntOverflowConfig
+			}
+			if iNdEx >= l {
+				return io.ErrUnexpectedEOF
+			}
+			b := dAtA[iNdEx]
+			iNdEx++
+			wire |= uint64(b&0x7F) << shift
+			if b < 0x80 {
+				break
+			}
+		}
+		fieldNum := int32(wire >> 3)
+		wireType := int(wire & 0x7)
+		if wireType == 4 {
+			return fmt.Errorf("proto: S2GeometryConfig: wiretype end group for non-group")
+		}
+		if fieldNum <= 0 {
+			return fmt.Errorf("proto: S2GeometryConfig: illegal tag %d (wire type %d)", fieldNum, wire)
+		}
+		switch fieldNum {
+		case 1:
+			if wireType != 1 {
+				return fmt.Errorf("proto: wrong wireType = %d for field MinX", wireType)
+			}
+			var v uint64
+			if (iNdEx + 8) > l {
+				return io.ErrUnexpectedEOF
+			}
+			v = uint64(encoding_binary.LittleEndian.Uint64(dAtA[iNdEx:]))
+			iNdEx += 8
+			m.MinX = float64(math.Float64frombits(v))
+		case 2:
+			if wireType != 1 {
+				return fmt.Errorf("proto: wrong wireType = %d for field MaxX", wireType)
+			}
+			var v uint64
+			if (iNdEx + 8) > l {
+				return io.ErrUnexpectedEOF
+			}
+			v = uint64(encoding_binary.LittleEndian.Uint64(dAtA[iNdEx:]))
+			iNdEx += 8
+			m.MaxX = float64(math.Float64frombits(v))
+		case 3:
+			if wireType != 1 {
+				return fmt.Errorf("proto: wrong wireType = %d for field MinY", wireType)
+			}
+			var v uint64
+			if (iNdEx + 8) > l {
+				return io.ErrUnexpectedEOF
+			}
+			v = uint64(encoding_binary.LittleEndian.Uint64(dAtA[iNdEx:]))
+			iNdEx += 8
+			m.MinY = float64(math.Float64frombits(v))
+		case 4:
+			if wireType != 1 {
+				return fmt.Errorf("proto: wrong wireType = %d for field MaxY", wireType)
+			}
+			var v uint64
+			if (iNdEx + 8) > l {
+				return io.ErrUnexpectedEOF
+			}
+			v = uint64(encoding_binary.LittleEndian.Uint64(dAtA[iNdEx:]))
+			iNdEx += 8
+			m.MaxY = float64(math.Float64frombits(v))
+		case 5:
+			if wireType != 2 {
+				return fmt.Errorf("proto: wrong wireType = %d for field S2Config", wireType)
+			}
+			var msglen int
+			for shift := uint(0); ; shift += 7 {
+				if shift >= 64 {
+					return ErrIntOverflowConfig
+				}
+				if iNdEx >= l {
+					return io.ErrUnexpectedEOF
+				}
+				b := dAtA[iNdEx]
+				iNdEx++
+				msglen |= int(b&0x7F) << shift
+				if b < 0x80 {
+					break
+				}
+			}
+			if msglen < 0 {
+				return ErrInvalidLengthConfig
+			}
+			postIndex := iNdEx + msglen
+			if postIndex < 0 {
+				return ErrInvalidLengthConfig
+			}
+			if postIndex > l {
+				return io.ErrUnexpectedEOF
+			}
+			if m.S2Config == nil {
+				m.S2Config = &S2Config{}
+			}
+			if err := m.S2Config.Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
+				return err
+			}
+			iNdEx = postIndex
+		default:
+			iNdEx = preIndex
+			skippy, err := skipConfig(dAtA[iNdEx:])
+			if err != nil {
+				return err
+			}
+			if (skippy < 0) || (iNdEx+skippy) < 0 {
+				return ErrInvalidLengthConfig
+			}
+			if (iNdEx + skippy) > l {
+				return io.ErrUnexpectedEOF
+			}
+			iNdEx += skippy
+		}
+	}
+
+	if iNdEx > l {
+		return io.ErrUnexpectedEOF
+	}
+	return nil
+}
+func skipConfig(dAtA []byte) (n int, err error) {
+	l := len(dAtA)
+	iNdEx := 0
+	depth := 0
+	for iNdEx < l {
+		var wire uint64
+		for shift := uint(0); ; shift += 7 {
+			if shift >= 64 {
+				return 0, ErrIntOverflowConfig
+			}
+			if iNdEx >= l {
+				return 0, io.ErrUnexpectedEOF
+			}
+			b := dAtA[iNdEx]
+			iNdEx++
+			wire |= (uint64(b) & 0x7F) << shift
+			if b < 0x80 {
+				break
+			}
+		}
+		wireType := int(wire & 0x7)
+		switch wireType {
+		case 0:
+			for shift := uint(0); ; shift += 7 {
+				if shift >= 64 {
+					return 0, ErrIntOverflowConfig
+				}
+				if iNdEx >= l {
+					return 0, io.ErrUnexpectedEOF
+				}
+				iNdEx++
+				if dAtA[iNdEx-1] < 0x80 {
+					break
+				}
+			}
+		case 1:
+			iNdEx += 8
+		case 2:
+			var length int
+			for shift := uint(0); ; shift += 7 {
+				if shift >= 64 {
+					return 0, ErrIntOverflowConfig
+				}
+				if iNdEx >= l {
+					return 0, io.ErrUnexpectedEOF
+				}
+				b := dAtA[iNdEx]
+				iNdEx++
+				length |= (int(b) & 0x7F) << shift
+				if b < 0x80 {
+					break
+				}
+			}
+			if length < 0 {
+				return 0, ErrInvalidLengthConfig
+			}
+			iNdEx += length
+		case 3:
+			depth++
+		case 4:
+			if depth == 0 {
+				return 0, ErrUnexpectedEndOfGroupConfig
+			}
+			depth--
+		case 5:
+			iNdEx += 4
+		default:
+			return 0, fmt.Errorf("proto: illegal wireType %d", wireType)
+		}
+		if iNdEx < 0 {
+			return 0, ErrInvalidLengthConfig
+		}
+		if depth == 0 {
+			return iNdEx, nil
+		}
+	}
+	return 0, io.ErrUnexpectedEOF
+}
+
+var (
+	ErrInvalidLengthConfig        = fmt.Errorf("proto: negative length found during unmarshaling")
+	ErrIntOverflowConfig          = fmt.Errorf("proto: integer overflow")
+	ErrUnexpectedEndOfGroupConfig = fmt.Errorf("proto: unexpected end of group")
+)
+
diff --git a/pkg/geo/geopb/config.proto b/pkg/geo/geopb/config.proto
new file mode 100644
index 0000000..ababb1e
--- /dev/null
+++ b/pkg/geo/geopb/config.proto
@@ -0,0 +1,60 @@
+// Copyright 2020 The Cockroach Authors.
+//
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
+
+syntax = "proto3";
+package cockroach.geo.geoindex;
+option go_package = "github.com/cockroachdb/cockroach/pkg/geo/geopb";
+
+import "gogoproto/gogo.proto";
+
+// Config is the information used to tune one instance of a geospatial index.
+// Each SQL index will have its own config.
+//
+// At the moment, only one major indexing strategy is implemented (S2 cells).
+message Config {
+  option (gogoproto.equal) = true;
+  option (gogoproto.onlyone) = true;
+  S2GeographyConfig s2_geography = 1;
+  S2GeometryConfig s2_geometry = 2;
+}
+
+// S2Config is the required information to tune one instance of an S2 cell
+// backed geospatial index. For advanced users only -- the defaults should be
+// good enough.
+//
+// TODO(sumeer): Based on experiments, reduce the knobs below by making the
+// covering self-tuning.
+message S2Config {
+  option (gogoproto.equal) = true;
+  // MinLevel is the minimum cell level stored in the index. If left unset, it
+  // defaults to 0.
+  int32 min_level = 1;
+  // MaxLevel is the maximum cell level stored in the index. If left unset, it
+  // defaults to 30.
+  int32 max_level = 2;
+  // `MaxLevel-MinLevel` must be an exact multiple of LevelMod. If left unset,
+  // it defaults to 1.
+  int32 level_mod = 3;
+  // MaxCells is a soft hint for the maximum number of entries used to store a
+  // single geospatial object. If left unset, it defaults to 4.
+  int32 max_cells = 4;
+}
+
+message S2GeographyConfig {
+  option (gogoproto.equal) = true;
+  S2Config s2_config = 1;
+}
+
+message S2GeometryConfig {
+  option (gogoproto.equal) = true;
+  // The rectangle bounds of the plane that will be efficiently indexed. Shapes
+  // should rarely exceed these bounds.
+  double min_x = 1;
+  double max_x = 2;
+  double min_y = 3;
+  double max_y = 4;
+
+  S2Config s2_config = 5;
+}
diff --git a/pkg/geo/geopb/geopb.go b/pkg/geo/geopb/geopb.go
index 3c70bd6..319d88b 100644
--- a/pkg/geo/geopb/geopb.go
+++ b/pkg/geo/geopb/geopb.go
@@ -1,12 +1,7 @@
 // Copyright 2020 The Cockroach Authors.
 //
-// Use of this software is governed by the Business Source License
-// included in the file licenses/BSL.txt.
-//
-// As of the Change Date specified in that file, in accordance with
-// the Business Source License, use of this software will be governed
-// by the Apache License, Version 2.0, included in the file
-// licenses/APL.txt.
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
 
 package geopb
 
@@ -20,13 +15,19 @@ func (b *SpatialObject) EWKBHex() string {
 	return fmt.Sprintf("%X", b.EWKB)
 }
 
-// MemSize returns the size of the spatial object in memory.
-func (b *SpatialObject) MemSize() uintptr {
+// MemSize returns the size of the spatial object in memory. If deterministic is
+// true, then only length of EWKB slice is included - this option should only be
+// used when determinism is favored over precision.
+func (b *SpatialObject) MemSize(deterministic bool) uintptr {
 	var bboxSize uintptr
 	if bbox := b.BoundingBox; bbox != nil {
 		bboxSize = unsafe.Sizeof(*bbox)
 	}
-	return unsafe.Sizeof(*b) + bboxSize + uintptr(len(b.EWKB))
+	ewkbSize := uintptr(cap(b.EWKB))
+	if deterministic {
+		ewkbSize = uintptr(len(b.EWKB))
+	}
+	return unsafe.Sizeof(*b) + bboxSize + ewkbSize
 }
 
 // MultiType returns the corresponding multi-type for a shape type, or unset
diff --git a/pkg/geo/geopb/geopb.pb.go b/pkg/geo/geopb/geopb.pb.go
index 0d22387..3e55211 100644
--- a/pkg/geo/geopb/geopb.pb.go
+++ b/pkg/geo/geopb/geopb.pb.go
@@ -480,7 +480,7 @@ func (m *BoundingBox) Size() (n int) {
 }
 
 func sovGeopb(x uint64) (n int) {
-	return (math_bits.Len64(x|1) + 6) / 7
+	return int((uint32(math_bits.Len64(x|1)+6) * 37) >> 8)
 }
 func sozGeopb(x uint64) (n int) {
 	return sovGeopb(uint64((x << 1) ^ uint64((int64(x) >> 63))))
diff --git a/pkg/geo/geopb/geopb.proto b/pkg/geo/geopb/geopb.proto
index 7e04df7..d98f41d 100644
--- a/pkg/geo/geopb/geopb.proto
+++ b/pkg/geo/geopb/geopb.proto
@@ -1,12 +1,7 @@
 // Copyright 2020 The Cockroach Authors.
 //
-// Use of this software is governed by the Business Source License
-// included in the file licenses/BSL.txt.
-//
-// As of the Change Date specified in that file, in accordance with
-// the Business Source License, use of this software will be governed
-// by the Apache License, Version 2.0, included in the file
-// licenses/APL.txt.
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
 
 syntax = "proto3";
 package cockroach.geopb;
diff --git a/pkg/geo/geopb/types.go b/pkg/geo/geopb/types.go
index f9f0f41..33b3718 100644
--- a/pkg/geo/geopb/types.go
+++ b/pkg/geo/geopb/types.go
@@ -1,12 +1,7 @@
 // Copyright 2020 The Cockroach Authors.
 //
-// Use of this software is governed by the Business Source License
-// included in the file licenses/BSL.txt.
-//
-// As of the Change Date specified in that file, in accordance with
-// the Business Source License, use of this software will be governed
-// by the Apache License, Version 2.0, included in the file
-// licenses/APL.txt.
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
 
 package geopb
 
diff --git a/pkg/geo/geoproj/.clang-format b/pkg/geo/geoproj/.clang-format
new file mode 100644
index 0000000..ad6a09e
--- /dev/null
+++ b/pkg/geo/geoproj/.clang-format
@@ -0,0 +1,109 @@
+---
+Language:        Cpp
+AccessModifierOffset: -1
+AlignAfterOpenBracket: Align
+AlignConsecutiveAssignments: false
+AlignConsecutiveDeclarations: false
+AlignEscapedNewlines: Right
+AlignOperands:   true
+AlignTrailingComments: true
+AllowAllParametersOfDeclarationOnNextLine: true
+AllowShortBlocksOnASingleLine: false
+AllowShortCaseLabelsOnASingleLine: false
+AllowShortFunctionsOnASingleLine: All
+AllowShortIfStatementsOnASingleLine: false
+AllowShortLoopsOnASingleLine: false
+AlwaysBreakAfterDefinitionReturnType: None
+AlwaysBreakAfterReturnType: None
+AlwaysBreakBeforeMultilineStrings: false
+AlwaysBreakTemplateDeclarations: false
+BinPackArguments: true
+BinPackParameters: true
+BraceWrapping:
+  AfterClass:      false
+  AfterControlStatement: false
+  AfterEnum:       false
+  AfterFunction:   false
+  AfterNamespace:  false
+  AfterObjCDeclaration: false
+  AfterStruct:     false
+  AfterUnion:      false
+  BeforeCatch:     false
+  BeforeElse:      false
+  IndentBraces:    false
+  SplitEmptyFunction: true
+  SplitEmptyRecord: true
+  SplitEmptyNamespace: true
+BreakBeforeBinaryOperators: None
+BreakBeforeBraces: Attach
+BreakBeforeInheritanceComma: false
+BreakBeforeTernaryOperators: true
+BreakConstructorInitializersBeforeComma: false
+BreakConstructorInitializers: BeforeColon
+BreakAfterJavaFieldAnnotations: false
+BreakStringLiterals: true
+ColumnLimit:     100
+CommentPragmas:  '^ IWYU pragma:'
+CompactNamespaces: false
+ConstructorInitializerAllOnOneLineOrOnePerLine: true
+ConstructorInitializerIndentWidth: 4
+ContinuationIndentWidth: 4
+Cpp11BracedListStyle: true
+DerivePointerAlignment: false
+DisableFormat:   false
+ExperimentalAutoDetectBinPacking: false
+FixNamespaceComments: true
+ForEachMacros:
+  - foreach
+  - Q_FOREACH
+  - BOOST_FOREACH
+IncludeCategories:
+  - Regex:           '^"(llvm|llvm-c|clang|clang-c)/'
+    Priority:        2
+  - Regex:           '^(<|"(gtest|isl|json)/)'
+    Priority:        3
+  - Regex:           '^".*"$'
+    Priority:        4
+  - Regex:           '.*'
+    Priority:        5
+IncludeIsMainRegex: '(Test)?$'
+IndentCaseLabels: false
+IndentWidth:     2
+IndentWrappedFunctionNames: false
+JavaScriptQuotes: Leave
+JavaScriptWrapImports: true
+KeepEmptyLinesAtTheStartOfBlocks: true
+MacroBlockBegin: ''
+MacroBlockEnd:   ''
+MaxEmptyLinesToKeep: 1
+NamespaceIndentation: None
+ObjCBlockIndentWidth: 2
+ObjCSpaceAfterProperty: false
+ObjCSpaceBeforeProtocolList: true
+PenaltyBreakAssignment: 2
+PenaltyBreakBeforeFirstCallParameter: 19
+PenaltyBreakComment: 300
+PenaltyBreakFirstLessLess: 120
+PenaltyBreakString: 1000
+PenaltyExcessCharacter: 1000000
+PenaltyReturnTypeOnItsOwnLine: 60
+PointerAlignment: Left
+ReflowComments:  true
+SortIncludes:    true
+SortUsingDeclarations: true
+SpaceAfterCStyleCast: false
+SpaceAfterTemplateKeyword: true
+SpaceBeforeAssignmentOperators: true
+SpaceBeforeParens: ControlStatements
+SpaceInEmptyParentheses: false
+SpacesBeforeTrailingComments: 2
+SpacesInAngles:  false
+SpacesInContainerLiterals: true
+SpacesInCStyleCastParentheses: false
+SpacesInParentheses: false
+SpacesInSquareBrackets: false
+Standard:        Cpp11
+TabWidth:        8
+UseTab:          Never
+...
+
diff --git a/pkg/geo/geoproj/geoproj.go b/pkg/geo/geoproj/geoproj.go
new file mode 100644
index 0000000..bfd3f7f
--- /dev/null
+++ b/pkg/geo/geoproj/geoproj.go
@@ -0,0 +1,94 @@
+// Copyright 2020 The Cockroach Authors.
+//
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
+
+// Package geoproj contains functions that interface with the PROJ library.
+package geoproj
+
+// #cgo CXXFLAGS: -std=c++14
+// #cgo CPPFLAGS: -I../../../c-deps/proj/src
+// #cgo !windows LDFLAGS: -lproj
+// #cgo linux LDFLAGS: -lrt -lm -lpthread
+// #cgo windows LDFLAGS: -lproj_4_9 -lshlwapi -lrpcrt4
+//
+// #include "proj.h"
+import "C"
+import (
+	"math"
+	"unsafe"
+
+	"github.com/cockroachdb/cockroachdb-parser/pkg/geo/geographiclib"
+	"github.com/cockroachdb/cockroachdb-parser/pkg/geo/geoprojbase"
+	"github.com/cockroachdb/cockroachdb-parser/pkg/sql/pgwire/pgcode"
+	"github.com/cockroachdb/cockroachdb-parser/pkg/sql/pgwire/pgerror"
+)
+
+// maxArrayLen is the maximum safe length for this architecture.
+const maxArrayLen = 1<<31 - 1
+
+func cStatusToUnsafeGoBytes(s C.CR_PROJ_Status) []byte {
+	if s.data == nil {
+		return nil
+	}
+	// Interpret the C pointer as a pointer to a Go array, then slice.
+	return (*[maxArrayLen]byte)(unsafe.Pointer(s.data))[:s.len:s.len]
+}
+
+// GetProjMetadata returns metadata about the given projection.
+// The return arguments are a bool representing whether it is a latlng, a spheroid
+// object and an error if anything was erroneous was found.
+func GetProjMetadata(b geoprojbase.Proj4Text) (bool, *geographiclib.Spheroid, error) {
+	var majorAxis, eccentricitySquared C.double
+	var isLatLng C.int
+	if err := cStatusToUnsafeGoBytes(
+		C.CR_PROJ_GetProjMetadata(
+			(*C.char)(unsafe.Pointer(&b.Bytes()[0])),
+			(*C.int)(unsafe.Pointer(&isLatLng)),
+			(*C.double)(unsafe.Pointer(&majorAxis)),
+			(*C.double)(unsafe.Pointer(&eccentricitySquared)),
+		),
+	); err != nil {
+		return false, nil, pgerror.Newf(pgcode.InvalidParameterValue, "error from PROJ: %s", string(err))
+	}
+	// flattening = e^2 / 1 + sqrt(1-e^2).
+	// See: https://en.wikipedia.org/wiki/Eccentricity_(mathematics), derived from
+	// e = sqrt(f(2-f))
+	flattening := float64(eccentricitySquared) / (1 + math.Sqrt(1-float64(eccentricitySquared)))
+	return isLatLng != 0, geographiclib.NewSpheroid(float64(majorAxis), flattening), nil
+}
+
+// Project projects the given xCoords, yCoords and zCoords from one
+// coordinate system to another using proj4text.
+// Array elements are edited in place.
+func Project(
+	from geoprojbase.Proj4Text,
+	to geoprojbase.Proj4Text,
+	xCoords []float64,
+	yCoords []float64,
+	zCoords []float64,
+) error {
+	if len(xCoords) != len(yCoords) || len(xCoords) != len(zCoords) {
+		return pgerror.Newf(
+			pgcode.InvalidParameterValue,
+			"len(xCoords) != len(yCoords) != len(zCoords): %d != %d != %d",
+			len(xCoords),
+			len(yCoords),
+			len(zCoords),
+		)
+	}
+	if len(xCoords) == 0 {
+		return nil
+	}
+	if err := cStatusToUnsafeGoBytes(C.CR_PROJ_Transform(
+		(*C.char)(unsafe.Pointer(&from.Bytes()[0])),
+		(*C.char)(unsafe.Pointer(&to.Bytes()[0])),
+		C.long(len(xCoords)),
+		(*C.double)(unsafe.Pointer(&xCoords[0])),
+		(*C.double)(unsafe.Pointer(&yCoords[0])),
+		(*C.double)(unsafe.Pointer(&zCoords[0])),
+	)); err != nil {
+		return pgerror.Newf(pgcode.InvalidParameterValue, "error from PROJ: %s", string(err))
+	}
+	return nil
+}
diff --git a/pkg/geo/geoproj/proj.cc b/pkg/geo/geoproj/proj.cc
new file mode 100644
index 0000000..6ad73ef
--- /dev/null
+++ b/pkg/geo/geoproj/proj.cc
@@ -0,0 +1,89 @@
+// Copyright 2020 The Cockroach Authors.
+//
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
+
+#include "proj.h"
+#include <cstring>
+#include <proj_api.h>
+#include <stdlib.h>
+#include <string>
+
+const char* DEFAULT_ERROR_MSG = "PROJ could not parse proj4text";
+
+namespace {
+CR_PROJ_Status CR_PROJ_ErrorFromErrorCode(int code) {
+  char* err = pj_strerrno(code);
+  if (err == nullptr) {
+    err = (char*)DEFAULT_ERROR_MSG;
+  }
+  return {.data = err, .len = strlen(err)};
+}
+
+}  // namespace
+
+CR_PROJ_Status CR_PROJ_Transform(char* fromSpec, char* toSpec, long point_count, double* x,
+                                 double* y, double* z) {
+  CR_PROJ_Status err = {.data = NULL, .len = 0};
+  auto ctx = pj_ctx_alloc();
+  auto fromPJ = pj_init_plus_ctx(ctx, fromSpec);
+  if (fromPJ == nullptr) {
+    err = CR_PROJ_ErrorFromErrorCode(pj_ctx_get_errno(ctx));
+    pj_ctx_free(ctx);
+    return err;
+  }
+  auto toPJ = pj_init_plus_ctx(ctx, toSpec);
+  if (toPJ == nullptr) {
+    err = CR_PROJ_ErrorFromErrorCode(pj_ctx_get_errno(ctx));
+    pj_free(fromPJ);
+    pj_ctx_free(ctx);
+    return err;
+  }
+  // If we have a latlng from, transform to radians.
+  if (pj_is_latlong(fromPJ)) {
+    for (auto i = 0; i < point_count; i++) {
+      x[i] = x[i] * DEG_TO_RAD;
+      y[i] = y[i] * DEG_TO_RAD;
+    }
+  }
+  pj_transform(fromPJ, toPJ, point_count, 0, x, y, z);
+  int errCode = pj_ctx_get_errno(ctx);
+  if (errCode != 0) {
+    err = CR_PROJ_ErrorFromErrorCode(errCode);
+    pj_free(toPJ);
+    pj_free(fromPJ);
+    pj_ctx_free(ctx);
+    return err;
+  }
+
+  // If we have a latlng to, transform to degrees.
+  if (pj_is_latlong(toPJ)) {
+    for (auto i = 0; i < point_count; i++) {
+      x[i] = x[i] * RAD_TO_DEG;
+      y[i] = y[i] * RAD_TO_DEG;
+    }
+  }
+  pj_free(toPJ);
+  pj_free(fromPJ);
+  pj_ctx_free(ctx);
+  return err;
+}
+
+CR_PROJ_Status CR_PROJ_GetProjMetadata(char* spec, int* retIsLatLng, double* retMajorAxis,
+                                       double* retEccentricitySquared) {
+  CR_PROJ_Status err = {.data = NULL, .len = 0};
+  auto ctx = pj_ctx_alloc();
+  auto pj = pj_init_plus_ctx(ctx, spec);
+  if (pj == nullptr) {
+    err = CR_PROJ_ErrorFromErrorCode(pj_ctx_get_errno(ctx));
+    pj_ctx_free(ctx);
+    return err;
+  }
+
+  *retIsLatLng = pj_is_latlong(pj);
+  pj_get_spheroid_defn(pj, retMajorAxis, retEccentricitySquared);
+
+  pj_free(pj);
+  pj_ctx_free(ctx);
+  return err;
+}
diff --git a/pkg/geo/geoproj/proj.h b/pkg/geo/geoproj/proj.h
new file mode 100644
index 0000000..5ad14cb
--- /dev/null
+++ b/pkg/geo/geoproj/proj.h
@@ -0,0 +1,33 @@
+// Copyright 2020 The Cockroach Authors.
+//
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
+
+#include <stdlib.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+// CR_PROJ_Slice contains data that does not need to be freed.
+// It can be either a Go or C pointer (which indicates who allocated the
+// memory).
+typedef struct {
+  char* data;
+  size_t len;
+} CR_PROJ_Slice;
+
+typedef CR_PROJ_Slice CR_PROJ_Status;
+
+// CR_PROJ_Transform converts the given x/y/z coordinates to a new project specification.
+// Note points (x[i], y[i], z[i]) are in the range 0 <= i < point_coint.
+CR_PROJ_Status CR_PROJ_Transform(char* fromSpec, char* toSpec, long point_count, double* x,
+                                 double* y, double* z);
+
+// CR_PROJ_GetProjMetadata gets the metadata for a given spec in relation to
+// the spheroid it represents.
+CR_PROJ_Status CR_PROJ_GetProjMetadata(char* spec, int* retIsLatLng, double* retMajorAxis,
+                                       double* retEccentricitySquared);
+#ifdef __cplusplus
+}  // extern "C"
+#endif
diff --git a/pkg/geo/geoproj/proj_api.h b/pkg/geo/geoproj/proj_api.h
new file mode 100644
index 0000000..24a6f05
--- /dev/null
+++ b/pkg/geo/geoproj/proj_api.h
@@ -0,0 +1,184 @@
+/******************************************************************************
+ * Project:  PROJ.4
+ * Purpose:  Public (application) include file for PROJ.4 API, and constants.
+ * Author:   Frank Warmerdam, <warmerdam@pobox.com>
+ *
+ ******************************************************************************
+ * Copyright (c) 2001, Frank Warmerdam <warmerdam@pobox.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *****************************************************************************/
+
+/* General projections header file */
+#ifndef PROJ_API_H
+#define PROJ_API_H
+
+/* standard inclusions */
+#include <math.h>
+#include <stdlib.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * This version number should be updated with every release!  The format of
+ * PJ_VERSION is
+ *
+ * * Before version 4.10.0: PJ_VERSION=MNP where M, N, and P are the major,
+ *   minor, and patch numbers; e.g., PJ_VERSION=493 for version 4.9.3.
+ *
+ * * Version 4.10.0 and later: PJ_VERSION=MMMNNNPP later where MMM, NNN, PP
+ *   are the major, minor, and patch numbers (the minor and patch numbers
+ *   are padded with leading zeros if necessary); e.g., PJ_VERSION=401000
+ *   for version 4.10.0.
+ */
+#define PJ_VERSION 493
+
+/* pj_init() and similar functions can be used with a non-C locale */
+/* Can be detected too at runtime if the symbol pj_atof exists */
+#define PJ_LOCALE_SAFE 1
+
+extern char const pj_release[]; /* global release id string */
+
+#define RAD_TO_DEG	57.295779513082321
+#define DEG_TO_RAD	.017453292519943296
+
+
+extern int pj_errno;	/* global error return code */
+
+#if !defined(PROJECTS_H)
+    typedef struct { double u, v; } projUV;
+    typedef struct { double u, v, w; } projUVW;
+    typedef void *projPJ;
+    #define projXY projUV
+    #define projLP projUV
+    #define projXYZ projUVW
+    #define projLPZ projUVW
+    typedef void *projCtx;
+#else
+    typedef PJ *projPJ;
+    typedef projCtx_t *projCtx;
+#   define projXY	XY
+#   define projLP       LP
+#   define projXYZ      XYZ
+#   define projLPZ      LPZ
+#endif
+
+/* file reading api, like stdio */
+typedef int *PAFile;
+typedef struct projFileAPI_t {
+    PAFile  (*FOpen)(projCtx ctx, const char *filename, const char *access);
+    size_t  (*FRead)(void *buffer, size_t size, size_t nmemb, PAFile file);
+    int     (*FSeek)(PAFile file, long offset, int whence);
+    long    (*FTell)(PAFile file);
+    void    (*FClose)(PAFile);
+} projFileAPI;
+
+/* procedure prototypes */
+
+projXY pj_fwd(projLP, projPJ);
+projLP pj_inv(projXY, projPJ);
+
+projXYZ pj_fwd3d(projLPZ, projPJ);
+projLPZ pj_inv3d(projXYZ, projPJ);
+
+int pj_transform( projPJ src, projPJ dst, long point_count, int point_offset,
+                  double *x, double *y, double *z );
+int pj_datum_transform( projPJ src, projPJ dst, long point_count, int point_offset,
+                        double *x, double *y, double *z );
+int pj_geocentric_to_geodetic( double a, double es,
+                               long point_count, int point_offset,
+                               double *x, double *y, double *z );
+int pj_geodetic_to_geocentric( double a, double es,
+                               long point_count, int point_offset,
+                               double *x, double *y, double *z );
+int pj_compare_datums( projPJ srcdefn, projPJ dstdefn );
+int pj_apply_gridshift( projCtx, const char *, int,
+                        long point_count, int point_offset,
+                        double *x, double *y, double *z );
+void pj_deallocate_grids(void);
+void pj_clear_initcache(void);
+int pj_is_latlong(projPJ);
+int pj_is_geocent(projPJ);
+void pj_get_spheroid_defn(projPJ defn, double *major_axis, double *eccentricity_squared);
+void pj_pr_list(projPJ);
+void pj_free(projPJ);
+void pj_set_finder( const char *(*)(const char *) );
+void pj_set_searchpath ( int count, const char **path );
+projPJ pj_init(int, char **);
+projPJ pj_init_plus(const char *);
+projPJ pj_init_ctx( projCtx, int, char ** );
+projPJ pj_init_plus_ctx( projCtx, const char * );
+char *pj_get_def(projPJ, int);
+projPJ pj_latlong_from_proj( projPJ );
+void *pj_malloc(size_t);
+void pj_dalloc(void *);
+void *pj_calloc (size_t n, size_t size);
+void *pj_dealloc (void *ptr);
+char *pj_strerrno(int);
+int *pj_get_errno_ref(void);
+const char *pj_get_release(void);
+void pj_acquire_lock(void);
+void pj_release_lock(void);
+void pj_cleanup_lock(void);
+
+projCtx pj_get_default_ctx(void);
+projCtx pj_get_ctx( projPJ );
+void pj_set_ctx( projPJ, projCtx );
+projCtx pj_ctx_alloc(void);
+void    pj_ctx_free( projCtx );
+int pj_ctx_get_errno( projCtx );
+void pj_ctx_set_errno( projCtx, int );
+void pj_ctx_set_debug( projCtx, int );
+void pj_ctx_set_logger( projCtx, void (*)(void *, int, const char *) );
+void pj_ctx_set_app_data( projCtx, void * );
+void *pj_ctx_get_app_data( projCtx );
+void pj_ctx_set_fileapi( projCtx, projFileAPI *);
+projFileAPI *pj_ctx_get_fileapi( projCtx );
+
+void pj_log( projCtx ctx, int level, const char *fmt, ... );
+void pj_stderr_logger( void *, int, const char * );
+
+/* file api */
+projFileAPI *pj_get_default_fileapi();
+
+PAFile pj_ctx_fopen(projCtx ctx, const char *filename, const char *access);
+size_t pj_ctx_fread(projCtx ctx, void *buffer, size_t size, size_t nmemb, PAFile file);
+int    pj_ctx_fseek(projCtx ctx, PAFile file, long offset, int whence);
+long   pj_ctx_ftell(projCtx ctx, PAFile file);
+void   pj_ctx_fclose(projCtx ctx, PAFile file);
+char  *pj_ctx_fgets(projCtx ctx, char *line, int size, PAFile file);
+
+PAFile pj_open_lib(projCtx, const char *, const char *);
+
+int pj_run_selftests (int verbosity);
+
+
+#define PJ_LOG_NONE        0
+#define PJ_LOG_ERROR       1
+#define PJ_LOG_DEBUG_MAJOR 2
+#define PJ_LOG_DEBUG_MINOR 3
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* ndef PROJ_API_H */
+
diff --git a/pkg/geo/geoproj/zcgo_flags.go b/pkg/geo/geoproj/zcgo_flags.go
new file mode 100644
index 0000000..5e06e73
--- /dev/null
+++ b/pkg/geo/geoproj/zcgo_flags.go
@@ -0,0 +1,7 @@
+// GENERATED FILE DO NOT EDIT
+
+package geoproj
+
+// #cgo CPPFLAGS: -I/Users/jeremyyang/go/src/github.com/cockroachdb/cockroachdb-parser/bin/c-deps/archived_cdep_libjemalloc_macosarm/include
+// #cgo LDFLAGS: -L/Users/jeremyyang/go/src/github.com/cockroachdb/cockroachdb-parser/bin/c-deps/archived_cdep_libjemalloc_macosarm/lib -L/Users/jeremyyang/go/src/github.com/cockroachdb/cockroachdb-parser/bin/c-deps/archived_cdep_libproj_macosarm/lib
+import "C"
diff --git a/pkg/geo/geoprojbase/embeddedproj/embedded_proj.go b/pkg/geo/geoprojbase/embeddedproj/embedded_proj.go
index 172b28f..77a3d19 100644
--- a/pkg/geo/geoprojbase/embeddedproj/embedded_proj.go
+++ b/pkg/geo/geoprojbase/embeddedproj/embedded_proj.go
@@ -1,12 +1,7 @@
 // Copyright 2021 The Cockroach Authors.
 //
-// Use of this software is governed by the Business Source License
-// included in the file licenses/BSL.txt.
-//
-// As of the Change Date specified in that file, in accordance with
-// the Business Source License, use of this software will be governed
-// by the Apache License, Version 2.0, included in the file
-// licenses/APL.txt.
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
 
 // Package embeddedproj defines the format used to embed static projection data
 // in the Cockroach binary. Is is used to load the data as well as to generate
diff --git a/pkg/geo/geoprojbase/embeddedproj/embeddedproj/embedded_proj.go b/pkg/geo/geoprojbase/embeddedproj/embeddedproj/embedded_proj.go
new file mode 100644
index 0000000..77a3d19
--- /dev/null
+++ b/pkg/geo/geoprojbase/embeddedproj/embeddedproj/embedded_proj.go
@@ -0,0 +1,81 @@
+// Copyright 2021 The Cockroach Authors.
+//
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
+
+// Package embeddedproj defines the format used to embed static projection data
+// in the Cockroach binary. Is is used to load the data as well as to generate
+// the data file (from cmd/generate-spatial-ref-sys).
+package embeddedproj
+
+import (
+	"compress/gzip"
+	"encoding/json"
+	"io"
+)
+
+// Spheroid stores the metadata for a spheroid. Each spheroid is referenced by
+// its unique hash.
+type Spheroid struct {
+	Hash       int64
+	Radius     float64
+	Flattening float64
+}
+
+// Projection stores the metadata for a projection; it mirrors the fields in
+// geoprojbase.ProjInfo but with modifications that allow serialization and
+// deserialization.
+type Projection struct {
+	SRID      int
+	AuthName  string
+	AuthSRID  int
+	SRText    string
+	Proj4Text string
+	Bounds    Bounds
+	IsLatLng  bool
+	// The hash of the spheroid represented by the SRID.
+	Spheroid int64
+}
+
+// Bounds stores the bounds of a projection.
+type Bounds struct {
+	MinX float64
+	MaxX float64
+	MinY float64
+	MaxY float64
+}
+
+// Data stores all the spheroid and projection data.
+type Data struct {
+	Spheroids   []Spheroid
+	Projections []Projection
+}
+
+// Encode writes serializes Data as a gzip-compressed json.
+func Encode(d Data, w io.Writer) error {
+	data, err := json.MarshalIndent(d, "", " ")
+	if err != nil {
+		return err
+	}
+	zw, err := gzip.NewWriterLevel(w, gzip.BestCompression)
+	if err != nil {
+		return err
+	}
+	if _, err := zw.Write(data); err != nil {
+		return err
+	}
+	return zw.Close()
+}
+
+// Decode deserializes Data from a gzip-compressed json generated by Encode().
+func Decode(r io.Reader) (Data, error) {
+	zr, err := gzip.NewReader(r)
+	if err != nil {
+		return Data{}, err
+	}
+	var result Data
+	if err := json.NewDecoder(zr).Decode(&result); err != nil {
+		return Data{}, err
+	}
+	return result, nil
+}
diff --git a/pkg/geo/geoprojbase/geoprojbase.go b/pkg/geo/geoprojbase/geoprojbase.go
index 5219fdc..1bc59ad 100644
--- a/pkg/geo/geoprojbase/geoprojbase.go
+++ b/pkg/geo/geoprojbase/geoprojbase.go
@@ -1,12 +1,7 @@
 // Copyright 2020 The Cockroach Authors.
 //
-// Use of this software is governed by the Business Source License
-// included in the file licenses/BSL.txt.
-//
-// As of the Change Date specified in that file, in accordance with
-// the Business Source License, use of this software will be governed
-// by the Apache License, Version 2.0, included in the file
-// licenses/APL.txt.
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
 
 // Package geoprojbase is a minimal dependency package that contains
 // basic metadata and data structures for SRIDs and their CRS
diff --git a/pkg/geo/geoprojbase/projections.go b/pkg/geo/geoprojbase/projections.go
index bb9b182..db6442f 100644
--- a/pkg/geo/geoprojbase/projections.go
+++ b/pkg/geo/geoprojbase/projections.go
@@ -1,12 +1,7 @@
 // Copyright 2020 The Cockroach Authors.
 //
-// Use of this software is governed by the Business Source License
-// included in the file licenses/BSL.txt.
-//
-// As of the Change Date specified in that file, in accordance with
-// the Business Source License, use of this software will be governed
-// by the Apache License, Version 2.0, included in the file
-// licenses/APL.txt.
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
 
 // This file was generated from `./pkg/cmd/generate-spatial-ref-sys`.
 
diff --git a/pkg/geo/geos/.clang-format b/pkg/geo/geos/.clang-format
new file mode 100644
index 0000000..ad6a09e
--- /dev/null
+++ b/pkg/geo/geos/.clang-format
@@ -0,0 +1,109 @@
+---
+Language:        Cpp
+AccessModifierOffset: -1
+AlignAfterOpenBracket: Align
+AlignConsecutiveAssignments: false
+AlignConsecutiveDeclarations: false
+AlignEscapedNewlines: Right
+AlignOperands:   true
+AlignTrailingComments: true
+AllowAllParametersOfDeclarationOnNextLine: true
+AllowShortBlocksOnASingleLine: false
+AllowShortCaseLabelsOnASingleLine: false
+AllowShortFunctionsOnASingleLine: All
+AllowShortIfStatementsOnASingleLine: false
+AllowShortLoopsOnASingleLine: false
+AlwaysBreakAfterDefinitionReturnType: None
+AlwaysBreakAfterReturnType: None
+AlwaysBreakBeforeMultilineStrings: false
+AlwaysBreakTemplateDeclarations: false
+BinPackArguments: true
+BinPackParameters: true
+BraceWrapping:
+  AfterClass:      false
+  AfterControlStatement: false
+  AfterEnum:       false
+  AfterFunction:   false
+  AfterNamespace:  false
+  AfterObjCDeclaration: false
+  AfterStruct:     false
+  AfterUnion:      false
+  BeforeCatch:     false
+  BeforeElse:      false
+  IndentBraces:    false
+  SplitEmptyFunction: true
+  SplitEmptyRecord: true
+  SplitEmptyNamespace: true
+BreakBeforeBinaryOperators: None
+BreakBeforeBraces: Attach
+BreakBeforeInheritanceComma: false
+BreakBeforeTernaryOperators: true
+BreakConstructorInitializersBeforeComma: false
+BreakConstructorInitializers: BeforeColon
+BreakAfterJavaFieldAnnotations: false
+BreakStringLiterals: true
+ColumnLimit:     100
+CommentPragmas:  '^ IWYU pragma:'
+CompactNamespaces: false
+ConstructorInitializerAllOnOneLineOrOnePerLine: true
+ConstructorInitializerIndentWidth: 4
+ContinuationIndentWidth: 4
+Cpp11BracedListStyle: true
+DerivePointerAlignment: false
+DisableFormat:   false
+ExperimentalAutoDetectBinPacking: false
+FixNamespaceComments: true
+ForEachMacros:
+  - foreach
+  - Q_FOREACH
+  - BOOST_FOREACH
+IncludeCategories:
+  - Regex:           '^"(llvm|llvm-c|clang|clang-c)/'
+    Priority:        2
+  - Regex:           '^(<|"(gtest|isl|json)/)'
+    Priority:        3
+  - Regex:           '^".*"$'
+    Priority:        4
+  - Regex:           '.*'
+    Priority:        5
+IncludeIsMainRegex: '(Test)?$'
+IndentCaseLabels: false
+IndentWidth:     2
+IndentWrappedFunctionNames: false
+JavaScriptQuotes: Leave
+JavaScriptWrapImports: true
+KeepEmptyLinesAtTheStartOfBlocks: true
+MacroBlockBegin: ''
+MacroBlockEnd:   ''
+MaxEmptyLinesToKeep: 1
+NamespaceIndentation: None
+ObjCBlockIndentWidth: 2
+ObjCSpaceAfterProperty: false
+ObjCSpaceBeforeProtocolList: true
+PenaltyBreakAssignment: 2
+PenaltyBreakBeforeFirstCallParameter: 19
+PenaltyBreakComment: 300
+PenaltyBreakFirstLessLess: 120
+PenaltyBreakString: 1000
+PenaltyExcessCharacter: 1000000
+PenaltyReturnTypeOnItsOwnLine: 60
+PointerAlignment: Left
+ReflowComments:  true
+SortIncludes:    true
+SortUsingDeclarations: true
+SpaceAfterCStyleCast: false
+SpaceAfterTemplateKeyword: true
+SpaceBeforeAssignmentOperators: true
+SpaceBeforeParens: ControlStatements
+SpaceInEmptyParentheses: false
+SpacesBeforeTrailingComments: 2
+SpacesInAngles:  false
+SpacesInContainerLiterals: true
+SpacesInCStyleCastParentheses: false
+SpacesInParentheses: false
+SpacesInSquareBrackets: false
+Standard:        Cpp11
+TabWidth:        8
+UseTab:          Never
+...
+
diff --git a/pkg/geo/geos/geos.cc b/pkg/geo/geos/geos.cc
new file mode 100644
index 0000000..628151a
--- /dev/null
+++ b/pkg/geo/geos/geos.cc
@@ -0,0 +1,1558 @@
+// Copyright 2020 The Cockroach Authors.
+//
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
+
+#include <cstdarg>
+#include <cstring>
+#if _WIN32
+#include <windows.h>
+#else
+#include <dlfcn.h>
+#endif  // #if _WIN32
+#include <memory>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string>
+#include <vector>
+
+#include "geos.h"
+
+#if _WIN32
+#define dlopen(x, y) LoadLibrary(x)
+#define dlsym GetProcAddress
+#define dlclose FreeLibrary
+#define dlerror() ((char*)"failed to execute dlsym")
+typedef HMODULE dlhandle;
+#else
+typedef void* dlhandle;
+#endif  // #if _WIN32
+
+#define CR_GEOS_NO_ERROR_DEFINED_MESSAGE "geos: returned invalid result but error not populated"
+
+namespace {
+
+// Data Types adapted from `capi/geos_c.h.in` in GEOS.
+typedef void* CR_GEOS_Handle;
+typedef void (*CR_GEOS_MessageHandler)(const char*, void*);
+typedef void* CR_GEOS_WKTReader;
+typedef void* CR_GEOS_WKBReader;
+typedef void* CR_GEOS_WKBWriter;
+typedef void* CR_GEOS_BufferParams;
+
+// Function declarations from `capi/geos_c.h.in` in GEOS.
+typedef CR_GEOS_Handle (*CR_GEOS_init_r)();
+typedef void (*CR_GEOS_finish_r)(CR_GEOS_Handle);
+typedef CR_GEOS_MessageHandler (*CR_GEOS_Context_setErrorMessageHandler_r)(CR_GEOS_Handle,
+                                                                           CR_GEOS_MessageHandler,
+                                                                           void*);
+typedef void (*CR_GEOS_Free_r)(CR_GEOS_Handle, void* buffer);
+typedef void (*CR_GEOS_SetSRID_r)(CR_GEOS_Handle, CR_GEOS_Geometry, int);
+typedef int (*CR_GEOS_GetSRID_r)(CR_GEOS_Handle, CR_GEOS_Geometry);
+typedef void (*CR_GEOS_GeomDestroy_r)(CR_GEOS_Handle, CR_GEOS_Geometry);
+
+typedef char (*CR_GEOS_HasZ_r)(CR_GEOS_Handle, CR_GEOS_Geometry);
+typedef char (*CR_GEOS_IsEmpty_r)(CR_GEOS_Handle, CR_GEOS_Geometry);
+typedef char (*CR_GEOS_IsSimple_r)(CR_GEOS_Handle, CR_GEOS_Geometry);
+typedef int (*CR_GEOS_GeomTypeId_r)(CR_GEOS_Handle, CR_GEOS_Geometry);
+
+typedef CR_GEOS_WKTReader (*CR_GEOS_WKTReader_create_r)(CR_GEOS_Handle);
+typedef CR_GEOS_Geometry (*CR_GEOS_WKTReader_read_r)(CR_GEOS_Handle, CR_GEOS_WKTReader,
+                                                     const char*);
+typedef void (*CR_GEOS_WKTReader_destroy_r)(CR_GEOS_Handle, CR_GEOS_WKTReader);
+
+typedef CR_GEOS_WKBReader (*CR_GEOS_WKBReader_create_r)(CR_GEOS_Handle);
+typedef CR_GEOS_Geometry (*CR_GEOS_WKBReader_read_r)(CR_GEOS_Handle, CR_GEOS_WKBReader, const char*,
+                                                     size_t);
+typedef void (*CR_GEOS_WKBReader_destroy_r)(CR_GEOS_Handle, CR_GEOS_WKBReader);
+
+typedef CR_GEOS_BufferParams (*CR_GEOS_BufferParams_create_r)(CR_GEOS_Handle);
+typedef void (*CR_GEOS_GEOSBufferParams_destroy_r)(CR_GEOS_Handle, CR_GEOS_BufferParams);
+typedef int (*CR_GEOS_BufferParams_setEndCapStyle_r)(CR_GEOS_Handle, CR_GEOS_BufferParams,
+                                                     int endCapStyle);
+typedef int (*CR_GEOS_BufferParams_setJoinStyle_r)(CR_GEOS_Handle, CR_GEOS_BufferParams,
+                                                   int joinStyle);
+typedef int (*CR_GEOS_BufferParams_setMitreLimit_r)(CR_GEOS_Handle, CR_GEOS_BufferParams,
+                                                    double mitreLimit);
+typedef int (*CR_GEOS_BufferParams_setQuadrantSegments_r)(CR_GEOS_Handle, CR_GEOS_BufferParams,
+                                                          int quadrantSegments);
+typedef int (*CR_GEOS_BufferParams_setSingleSided_r)(CR_GEOS_Handle, CR_GEOS_BufferParams,
+                                                     int singleSided);
+typedef CR_GEOS_Geometry (*CR_GEOS_BufferWithParams_r)(CR_GEOS_Handle, CR_GEOS_Geometry,
+                                                       CR_GEOS_BufferParams, double width);
+
+typedef char (*CR_GEOS_isValid_r)(CR_GEOS_Handle, CR_GEOS_Geometry);
+typedef char* (*CR_GEOS_isValidReason_r)(CR_GEOS_Handle, CR_GEOS_Geometry);
+typedef char (*CR_GEOS_isValidDetail_r)(CR_GEOS_Handle, CR_GEOS_Geometry, int flags, char** reason,
+                                        CR_GEOS_Geometry* loc);
+typedef CR_GEOS_Geometry (*CR_GEOS_MakeValid_r)(CR_GEOS_Handle, CR_GEOS_Geometry);
+
+typedef int (*CR_GEOS_Area_r)(CR_GEOS_Handle, CR_GEOS_Geometry, double*);
+typedef int (*CR_GEOS_Length_r)(CR_GEOS_Handle, CR_GEOS_Geometry, double*);
+typedef int (*CR_GEOS_MinimumClearance_r)(CR_GEOS_Handle, CR_GEOS_Geometry, double*);
+typedef CR_GEOS_Geometry (*CR_GEOS_MinimumClearanceLine_r)(CR_GEOS_Handle, CR_GEOS_Geometry);
+typedef int (*CR_GEOS_Normalize_r)(CR_GEOS_Handle, CR_GEOS_Geometry);
+typedef CR_GEOS_Geometry (*CR_GEOS_LineMerge_r)(CR_GEOS_Handle, CR_GEOS_Geometry);
+
+typedef CR_GEOS_Geometry (*CR_GEOS_Boundary_r)(CR_GEOS_Handle, CR_GEOS_Geometry);
+typedef CR_GEOS_Geometry (*CR_GEOS_Centroid_r)(CR_GEOS_Handle, CR_GEOS_Geometry);
+typedef CR_GEOS_Geometry (*CR_GEOS_ConvexHull_r)(CR_GEOS_Handle, CR_GEOS_Geometry);
+typedef CR_GEOS_Geometry (*CR_GEOS_Difference_r)(CR_GEOS_Handle, CR_GEOS_Geometry,
+                                                 CR_GEOS_Geometry);
+typedef CR_GEOS_Geometry (*CR_GEOS_Simplify_r)(CR_GEOS_Handle, CR_GEOS_Geometry, double);
+typedef CR_GEOS_Geometry (*CR_GEOS_TopologyPreserveSimplify_r)(CR_GEOS_Handle, CR_GEOS_Geometry,
+                                                               double);
+typedef CR_GEOS_Geometry (*CR_GEOS_UnaryUnion_r)(CR_GEOS_Handle, CR_GEOS_Geometry);
+typedef CR_GEOS_Geometry (*CR_GEOS_Union_r)(CR_GEOS_Handle, CR_GEOS_Geometry, CR_GEOS_Geometry);
+typedef CR_GEOS_Geometry (*CR_GEOS_Intersection_r)(CR_GEOS_Handle, CR_GEOS_Geometry,
+                                                   CR_GEOS_Geometry);
+typedef CR_GEOS_Geometry (*CR_GEOS_SymDifference_r)(CR_GEOS_Handle, CR_GEOS_Geometry,
+                                                    CR_GEOS_Geometry);
+typedef CR_GEOS_Geometry (*CR_GEOS_PointOnSurface_r)(CR_GEOS_Handle, CR_GEOS_Geometry);
+
+typedef CR_GEOS_Geometry (*CR_GEOS_Interpolate_r)(CR_GEOS_Handle, CR_GEOS_Geometry, double);
+
+typedef CR_GEOS_Geometry (*CR_GEOS_MinimumBoundingCircle_r)(CR_GEOS_Handle, CR_GEOS_Geometry, double*, CR_GEOS_Geometry**);
+
+typedef int (*CR_GEOS_Distance_r)(CR_GEOS_Handle, CR_GEOS_Geometry, CR_GEOS_Geometry, double*);
+typedef int (*CR_GEOS_FrechetDistance_r)(CR_GEOS_Handle, CR_GEOS_Geometry, CR_GEOS_Geometry,
+                                         double*);
+typedef int (*CR_GEOS_FrechetDistanceDensify_r)(CR_GEOS_Handle, CR_GEOS_Geometry, CR_GEOS_Geometry,
+                                                double, double*);
+typedef int (*CR_GEOS_HausdorffDistance_r)(CR_GEOS_Handle, CR_GEOS_Geometry, CR_GEOS_Geometry,
+                                           double*);
+typedef int (*CR_GEOS_HausdorffDistanceDensify_r)(CR_GEOS_Handle, CR_GEOS_Geometry,
+                                                  CR_GEOS_Geometry, double, double*);
+
+typedef CR_GEOS_PreparedInternalGeometry (*CR_GEOS_Prepare_r)(CR_GEOS_Handle, CR_GEOS_Geometry);
+typedef void (*CR_GEOS_PreparedGeom_destroy_r)(CR_GEOS_Handle, CR_GEOS_PreparedInternalGeometry);
+
+typedef char (*CR_GEOS_PreparedIntersects_r)(CR_GEOS_Handle, CR_GEOS_PreparedInternalGeometry, CR_GEOS_Geometry);
+
+typedef char (*CR_GEOS_Covers_r)(CR_GEOS_Handle, CR_GEOS_Geometry, CR_GEOS_Geometry);
+typedef char (*CR_GEOS_CoveredBy_r)(CR_GEOS_Handle, CR_GEOS_Geometry, CR_GEOS_Geometry);
+typedef char (*CR_GEOS_Contains_r)(CR_GEOS_Handle, CR_GEOS_Geometry, CR_GEOS_Geometry);
+typedef char (*CR_GEOS_Crosses_r)(CR_GEOS_Handle, CR_GEOS_Geometry, CR_GEOS_Geometry);
+typedef char (*CR_GEOS_Disjoint_r)(CR_GEOS_Handle, CR_GEOS_Geometry, CR_GEOS_Geometry);
+typedef char (*CR_GEOS_Equals_r)(CR_GEOS_Handle, CR_GEOS_Geometry, CR_GEOS_Geometry);
+typedef char (*CR_GEOS_Intersects_r)(CR_GEOS_Handle, CR_GEOS_Geometry, CR_GEOS_Geometry);
+typedef char (*CR_GEOS_Overlaps_r)(CR_GEOS_Handle, CR_GEOS_Geometry, CR_GEOS_Geometry);
+typedef char (*CR_GEOS_Touches_r)(CR_GEOS_Handle, CR_GEOS_Geometry, CR_GEOS_Geometry);
+typedef char (*CR_GEOS_Within_r)(CR_GEOS_Handle, CR_GEOS_Geometry, CR_GEOS_Geometry);
+
+typedef char* (*CR_GEOS_Relate_r)(CR_GEOS_Handle, CR_GEOS_Geometry, CR_GEOS_Geometry);
+typedef char* (*CR_GEOS_RelateBoundaryNodeRule_r)(CR_GEOS_Handle, CR_GEOS_Geometry,
+                                                  CR_GEOS_Geometry, int);
+typedef char (*CR_GEOS_RelatePattern_r)(CR_GEOS_Handle, CR_GEOS_Geometry, CR_GEOS_Geometry,
+                                        const char*);
+
+typedef CR_GEOS_WKBWriter (*CR_GEOS_WKBWriter_create_r)(CR_GEOS_Handle);
+typedef char* (*CR_GEOS_WKBWriter_write_r)(CR_GEOS_Handle, CR_GEOS_WKBWriter, CR_GEOS_Geometry,
+                                           size_t*);
+typedef void (*CR_GEOS_WKBWriter_setByteOrder_r)(CR_GEOS_Handle, CR_GEOS_WKBWriter, int);
+typedef void (*CR_GEOS_WKBWriter_setOutputDimension_r)(CR_GEOS_Handle, CR_GEOS_WKBWriter, int);
+typedef void (*CR_GEOS_WKBWriter_destroy_r)(CR_GEOS_Handle, CR_GEOS_WKBWriter);
+typedef void (*CR_GEOS_WKBWriter_setIncludeSRID_r)(CR_GEOS_Handle, CR_GEOS_WKBWriter, const char);
+typedef CR_GEOS_Geometry (*CR_GEOS_ClipByRect_r)(CR_GEOS_Handle, CR_GEOS_Geometry, double, double,
+                                                 double, double);
+
+typedef CR_GEOS_Geometry (*CR_GEOS_SharedPaths_r)(CR_GEOS_Handle, CR_GEOS_Geometry,
+                                                  CR_GEOS_Geometry);
+
+typedef CR_GEOS_Geometry (*CR_GEOS_Node_r)(CR_GEOS_Handle, CR_GEOS_Geometry);
+
+typedef CR_GEOS_Geometry (*CR_GEOS_VoronoiDiagram_r)(CR_GEOS_Handle, CR_GEOS_Geometry,
+                                                  CR_GEOS_Geometry, double, int);
+
+typedef char (*CR_GEOS_EqualsExact_r)(CR_GEOS_Handle, CR_GEOS_Geometry,
+                                                  CR_GEOS_Geometry, double);
+
+typedef CR_GEOS_Geometry (*CR_GEOS_MinimumRotatedRectangle_r)(CR_GEOS_Handle, CR_GEOS_Geometry);
+
+typedef CR_GEOS_Geometry (*CR_GEOS_Snap_r)(CR_GEOS_Handle, CR_GEOS_Geometry, CR_GEOS_Geometry, double);
+typedef const char* (*CR_GEOS_Version_r)();
+
+std::string ToString(CR_GEOS_Slice slice) { return std::string(slice.data, slice.len); }
+
+}  // namespace
+
+struct CR_GEOS {
+  dlhandle geoscHandle;
+  dlhandle geosHandle;
+
+  CR_GEOS_init_r GEOS_init_r;
+  CR_GEOS_finish_r GEOS_finish_r;
+  CR_GEOS_Context_setErrorMessageHandler_r GEOSContext_setErrorMessageHandler_r;
+  CR_GEOS_Free_r GEOSFree_r;
+
+  CR_GEOS_HasZ_r GEOSHasZ_r;
+  CR_GEOS_IsEmpty_r GEOSisEmpty_r;
+  CR_GEOS_IsSimple_r GEOSisSimple_r;
+  CR_GEOS_GeomTypeId_r GEOSGeomTypeId_r;
+
+  CR_GEOS_BufferParams_create_r GEOSBufferParams_create_r;
+  CR_GEOS_GEOSBufferParams_destroy_r GEOSBufferParams_destroy_r;
+  CR_GEOS_BufferParams_setEndCapStyle_r GEOSBufferParams_setEndCapStyle_r;
+  CR_GEOS_BufferParams_setJoinStyle_r GEOSBufferParams_setJoinStyle_r;
+  CR_GEOS_BufferParams_setMitreLimit_r GEOSBufferParams_setMitreLimit_r;
+  CR_GEOS_BufferParams_setQuadrantSegments_r GEOSBufferParams_setQuadrantSegments_r;
+  CR_GEOS_BufferParams_setSingleSided_r GEOSBufferParams_setSingleSided_r;
+  CR_GEOS_BufferWithParams_r GEOSBufferWithParams_r;
+
+  CR_GEOS_SetSRID_r GEOSSetSRID_r;
+  CR_GEOS_GetSRID_r GEOSGetSRID_r;
+  CR_GEOS_GeomDestroy_r GEOSGeom_destroy_r;
+
+  CR_GEOS_WKTReader_create_r GEOSWKTReader_create_r;
+  CR_GEOS_WKTReader_destroy_r GEOSWKTReader_destroy_r;
+  CR_GEOS_WKTReader_read_r GEOSWKTReader_read_r;
+
+  CR_GEOS_WKBReader_create_r GEOSWKBReader_create_r;
+  CR_GEOS_WKBReader_destroy_r GEOSWKBReader_destroy_r;
+  CR_GEOS_WKBReader_read_r GEOSWKBReader_read_r;
+
+  CR_GEOS_isValid_r GEOSisValid_r;
+  CR_GEOS_isValidReason_r GEOSisValidReason_r;
+  CR_GEOS_isValidDetail_r GEOSisValidDetail_r;
+  CR_GEOS_MakeValid_r GEOSMakeValid_r;
+
+  CR_GEOS_Area_r GEOSArea_r;
+  CR_GEOS_Length_r GEOSLength_r;
+  CR_GEOS_MinimumClearance_r GEOSMinimumClearance_r;
+  CR_GEOS_MinimumClearanceLine_r GEOSMinimumClearanceLine_r;
+  CR_GEOS_Normalize_r GEOSNormalize_r;
+  CR_GEOS_LineMerge_r GEOSLineMerge_r;
+
+  CR_GEOS_Boundary_r GEOSBoundary_r;
+  CR_GEOS_Centroid_r GEOSGetCentroid_r;
+  CR_GEOS_ConvexHull_r GEOSConvexHull_r;
+  CR_GEOS_Difference_r GEOSDifference_r;
+  CR_GEOS_Simplify_r GEOSSimplify_r;
+  CR_GEOS_TopologyPreserveSimplify_r GEOSTopologyPreserveSimplify_r;
+  CR_GEOS_UnaryUnion_r GEOSUnaryUnion_r;
+  CR_GEOS_Union_r GEOSUnion_r;
+  CR_GEOS_PointOnSurface_r GEOSPointOnSurface_r;
+  CR_GEOS_Intersection_r GEOSIntersection_r;
+  CR_GEOS_SymDifference_r GEOSSymDifference_r;
+
+  CR_GEOS_MinimumBoundingCircle_r GEOSMinimumBoundingCircle_r;
+
+  CR_GEOS_Interpolate_r GEOSInterpolate_r;
+
+  CR_GEOS_Distance_r GEOSDistance_r;
+  CR_GEOS_FrechetDistance_r GEOSFrechetDistance_r;
+  CR_GEOS_FrechetDistanceDensify_r GEOSFrechetDistanceDensify_r;
+  CR_GEOS_HausdorffDistance_r GEOSHausdorffDistance_r;
+  CR_GEOS_HausdorffDistanceDensify_r GEOSHausdorffDistanceDensify_r;
+
+  CR_GEOS_Prepare_r GEOSPrepare_r;
+  CR_GEOS_PreparedGeom_destroy_r GEOSPreparedGeom_destroy_r;
+
+  CR_GEOS_PreparedIntersects_r GEOSPreparedIntersects_r;
+
+  CR_GEOS_Covers_r GEOSCovers_r;
+  CR_GEOS_CoveredBy_r GEOSCoveredBy_r;
+  CR_GEOS_Contains_r GEOSContains_r;
+  CR_GEOS_Crosses_r GEOSCrosses_r;
+  CR_GEOS_Disjoint_r GEOSDisjoint_r;
+  CR_GEOS_Equals_r GEOSEquals_r;
+  CR_GEOS_Intersects_r GEOSIntersects_r;
+  CR_GEOS_Overlaps_r GEOSOverlaps_r;
+  CR_GEOS_Touches_r GEOSTouches_r;
+  CR_GEOS_Within_r GEOSWithin_r;
+
+  CR_GEOS_Relate_r GEOSRelate_r;
+  CR_GEOS_RelateBoundaryNodeRule_r GEOSRelateBoundaryNodeRule_r;
+  CR_GEOS_RelatePattern_r GEOSRelatePattern_r;
+
+  CR_GEOS_WKBWriter_create_r GEOSWKBWriter_create_r;
+  CR_GEOS_WKBWriter_destroy_r GEOSWKBWriter_destroy_r;
+  CR_GEOS_WKBWriter_setByteOrder_r GEOSWKBWriter_setByteOrder_r;
+  CR_GEOS_WKBWriter_setOutputDimension_r GEOSWKBWriter_setOutputDimension_r;
+  CR_GEOS_WKBWriter_setIncludeSRID_r GEOSWKBWriter_setIncludeSRID_r;
+  CR_GEOS_WKBWriter_write_r GEOSWKBWriter_write_r;
+
+  CR_GEOS_ClipByRect_r GEOSClipByRect_r;
+
+  CR_GEOS_SharedPaths_r GEOSSharedPaths_r;
+  CR_GEOS_VoronoiDiagram_r GEOSVoronoiDiagram_r;
+  CR_GEOS_EqualsExact_r GEOSEqualsExact_r;
+  CR_GEOS_MinimumRotatedRectangle_r GEOSMinimumRotatedRectangle_r;
+
+  CR_GEOS_Node_r GEOSNode_r;
+
+  CR_GEOS_Snap_r GEOSSnap_r;
+
+  CR_GEOS_Version_r GEOSversion;
+
+  CR_GEOS(dlhandle geoscHandle, dlhandle geosHandle)
+      : geoscHandle(geoscHandle), geosHandle(geosHandle) {}
+
+  ~CR_GEOS() {
+    if (geoscHandle != NULL) {
+      dlclose(geoscHandle);
+    }
+    if (geosHandle != NULL) {
+      dlclose(geosHandle);
+    }
+  }
+
+  char* Init() {
+#define INIT(x)                                                                                    \
+  do {                                                                                             \
+    auto error = InitSym(&x, #x);                                                                  \
+    if (error != nullptr) {                                                                        \
+      return error;                                                                                \
+    }                                                                                              \
+  } while (0)
+
+    INIT(GEOS_init_r);
+    INIT(GEOS_finish_r);
+    INIT(GEOSFree_r);
+    INIT(GEOSContext_setErrorMessageHandler_r);
+    INIT(GEOSGeom_destroy_r);
+    INIT(GEOSBufferParams_create_r);
+    INIT(GEOSBufferParams_destroy_r);
+    INIT(GEOSBufferParams_setEndCapStyle_r);
+    INIT(GEOSBufferParams_setJoinStyle_r);
+    INIT(GEOSBufferParams_setMitreLimit_r);
+    INIT(GEOSBufferParams_setQuadrantSegments_r);
+    INIT(GEOSBufferParams_setSingleSided_r);
+    INIT(GEOSBufferWithParams_r);
+    INIT(GEOSHasZ_r);
+    INIT(GEOSisEmpty_r);
+    INIT(GEOSGeomTypeId_r);
+    INIT(GEOSSetSRID_r);
+    INIT(GEOSGetSRID_r);
+    INIT(GEOSisValid_r);
+    INIT(GEOSisValidReason_r);
+    INIT(GEOSisValidDetail_r);
+    INIT(GEOSMakeValid_r);
+    INIT(GEOSArea_r);
+    INIT(GEOSLength_r);
+    INIT(GEOSMinimumClearance_r);
+    INIT(GEOSMinimumClearanceLine_r);
+    INIT(GEOSNormalize_r);
+    INIT(GEOSLineMerge_r);
+    INIT(GEOSisSimple_r);
+    INIT(GEOSBoundary_r);
+    INIT(GEOSDifference_r);
+    INIT(GEOSGetCentroid_r);
+    INIT(GEOSMinimumBoundingCircle_r);
+    INIT(GEOSConvexHull_r);
+    INIT(GEOSSimplify_r);
+    INIT(GEOSTopologyPreserveSimplify_r);
+    INIT(GEOSUnaryUnion_r);
+    INIT(GEOSUnion_r);
+    INIT(GEOSPointOnSurface_r);
+    INIT(GEOSIntersection_r);
+    INIT(GEOSSymDifference_r);
+    INIT(GEOSInterpolate_r);
+    INIT(GEOSDistance_r);
+    INIT(GEOSFrechetDistance_r);
+    INIT(GEOSFrechetDistanceDensify_r);
+    INIT(GEOSHausdorffDistance_r);
+    INIT(GEOSHausdorffDistanceDensify_r);
+    INIT(GEOSPrepare_r);
+    INIT(GEOSPreparedGeom_destroy_r);
+    INIT(GEOSPreparedIntersects_r);
+    INIT(GEOSCovers_r);
+    INIT(GEOSCoveredBy_r);
+    INIT(GEOSContains_r);
+    INIT(GEOSCrosses_r);
+    INIT(GEOSDisjoint_r);
+    INIT(GEOSEquals_r);
+    INIT(GEOSIntersects_r);
+    INIT(GEOSOverlaps_r);
+    INIT(GEOSTouches_r);
+    INIT(GEOSWithin_r);
+    INIT(GEOSRelate_r);
+    INIT(GEOSVoronoiDiagram_r);
+    INIT(GEOSEqualsExact_r);
+    INIT(GEOSMinimumRotatedRectangle_r);
+    INIT(GEOSRelateBoundaryNodeRule_r);
+    INIT(GEOSRelatePattern_r);
+    INIT(GEOSSharedPaths_r);
+    INIT(GEOSWKTReader_create_r);
+    INIT(GEOSWKTReader_destroy_r);
+    INIT(GEOSWKTReader_read_r);
+    INIT(GEOSWKBReader_create_r);
+    INIT(GEOSWKBReader_destroy_r);
+    INIT(GEOSWKBReader_read_r);
+    INIT(GEOSWKBWriter_create_r);
+    INIT(GEOSWKBWriter_destroy_r);
+    INIT(GEOSWKBWriter_setByteOrder_r);
+    INIT(GEOSWKBWriter_setOutputDimension_r);
+    INIT(GEOSWKBWriter_setIncludeSRID_r);
+    INIT(GEOSWKBWriter_write_r);
+    INIT(GEOSClipByRect_r);
+    INIT(GEOSNode_r);
+    INIT(GEOSSnap_r);
+    INIT(GEOSversion);
+    return nullptr;
+
+#undef INIT
+  }
+
+  template <typename T> char* InitSym(T* ptr, const char* symbol) {
+    *ptr = reinterpret_cast<T>(dlsym(geoscHandle, symbol));
+    if (ptr == nullptr) {
+      return dlerror();
+    }
+    return nullptr;
+  }
+};
+
+CR_GEOS_Slice cStringToSlice(char* cstr) {
+  CR_GEOS_Slice slice = {.data = cstr, .len = strlen(cstr)};
+  return slice;
+}
+
+// Given data that will be deallocated on return, with length
+// equal to len, returns a CR_GEOS_String to return to Go.
+CR_GEOS_String toGEOSString(const char* data, size_t len) {
+  CR_GEOS_String result = {.data = nullptr, .len = len};
+  if (len == 0) {
+    return result;
+  }
+  result.data = static_cast<char*>(malloc(len));
+  memcpy(result.data, data, len);
+  return result;
+}
+
+void errorHandler(const char* msg, void* buffer) {
+  std::string* str = static_cast<std::string*>(buffer);
+  *str = std::string("geos error: ") + msg;
+}
+
+CR_GEOS_Status CR_GEOS_Init(CR_GEOS_Slice geoscLoc, CR_GEOS_Slice geosLoc, CR_GEOS** lib) {
+  // Open the libgeos.$(EXT) first, so that libgeos_c.$(EXT) can read it.
+  std::string error;
+  auto geosLocStr = ToString(geosLoc);
+  dlhandle geosHandle = dlopen(geosLocStr.c_str(), RTLD_LAZY);
+  if (!geosHandle) {
+    errorHandler(dlerror(), &error);
+    return toGEOSString(error.data(), error.length());
+  }
+
+  auto geoscLocStr = ToString(geoscLoc);
+  dlhandle geoscHandle = dlopen(geoscLocStr.c_str(), RTLD_LAZY);
+  if (!geoscHandle) {
+    errorHandler(dlerror(), &error);
+    dlclose(geosHandle);
+    return toGEOSString(error.data(), error.length());
+  }
+
+  std::unique_ptr<CR_GEOS> ret(new CR_GEOS(geoscHandle, geosHandle));
+  auto initError = ret->Init();
+  if (initError != nullptr) {
+    errorHandler(initError, &error);
+    dlclose(geosHandle);
+    dlclose(geoscHandle);
+    return toGEOSString(error.data(), error.length());
+  }
+
+  *lib = ret.release();
+  return toGEOSString(error.data(), error.length());
+}
+
+CR_GEOS_Handle initHandleWithErrorBuffer(CR_GEOS* lib, std::string* buffer) {
+  auto handle = lib->GEOS_init_r();
+  lib->GEOSContext_setErrorMessageHandler_r(handle, errorHandler, buffer);
+  return handle;
+}
+
+CR_GEOS_Geometry CR_GEOS_GeometryFromSlice(CR_GEOS* lib, CR_GEOS_Handle handle,
+                                           CR_GEOS_Slice slice) {
+  auto wkbReader = lib->GEOSWKBReader_create_r(handle);
+  auto geom = lib->GEOSWKBReader_read_r(handle, wkbReader, slice.data, slice.len);
+  lib->GEOSWKBReader_destroy_r(handle, wkbReader);
+  return geom;
+}
+
+void CR_GEOS_Version(CR_GEOS* lib, CR_GEOS_String* ret) {
+  auto version = lib->GEOSversion();
+  *ret = toGEOSString(version, strlen(version));
+}
+
+void CR_GEOS_writeGeomToEWKB(CR_GEOS* lib, CR_GEOS_Handle handle, CR_GEOS_Geometry geom,
+                             CR_GEOS_String* ewkb, int srid) {
+  auto hasZ = lib->GEOSHasZ_r(handle, geom);
+  auto wkbWriter = lib->GEOSWKBWriter_create_r(handle);
+  lib->GEOSWKBWriter_setByteOrder_r(handle, wkbWriter, 1);
+  if (hasZ) {
+    lib->GEOSWKBWriter_setOutputDimension_r(handle, wkbWriter, 3);
+  }
+  if (srid != 0) {
+    lib->GEOSSetSRID_r(handle, geom, srid);
+  }
+  lib->GEOSWKBWriter_setIncludeSRID_r(handle, wkbWriter, true);
+  ewkb->data = lib->GEOSWKBWriter_write_r(handle, wkbWriter, geom, &ewkb->len);
+  lib->GEOSWKBWriter_destroy_r(handle, wkbWriter);
+}
+
+CR_GEOS_Status CR_GEOS_WKTToEWKB(CR_GEOS* lib, CR_GEOS_Slice wkt, int srid, CR_GEOS_String* ewkb) {
+  std::string error;
+  auto handle = initHandleWithErrorBuffer(lib, &error);
+
+  auto wktReader = lib->GEOSWKTReader_create_r(handle);
+  auto wktStr = ToString(wkt);
+  auto geom = lib->GEOSWKTReader_read_r(handle, wktReader, wktStr.c_str());
+  lib->GEOSWKTReader_destroy_r(handle, wktReader);
+
+  if (geom != NULL) {
+    CR_GEOS_writeGeomToEWKB(lib, handle, geom, ewkb, srid);
+    lib->GEOSGeom_destroy_r(handle, geom);
+  }
+
+  lib->GEOS_finish_r(handle);
+  return toGEOSString(error.data(), error.length());
+}
+
+CR_GEOS_Status CR_GEOS_ClipByRect(CR_GEOS* lib, CR_GEOS_Slice ewkb, double xmin, double ymin,
+                                  double xmax, double ymax, CR_GEOS_String* clippedEWKB) {
+  std::string error;
+  auto handle = initHandleWithErrorBuffer(lib, &error);
+  *clippedEWKB = {.data = NULL, .len = 0};
+
+  auto geom = CR_GEOS_GeometryFromSlice(lib, handle, ewkb);
+  if (geom != nullptr) {
+    auto clippedGeom = lib->GEOSClipByRect_r(handle, geom, xmin, ymin, xmax, ymax);
+    if (clippedGeom != nullptr) {
+      auto srid = lib->GEOSGetSRID_r(handle, geom);
+      CR_GEOS_writeGeomToEWKB(lib, handle, clippedGeom, clippedEWKB, srid);
+      lib->GEOSGeom_destroy_r(handle, clippedGeom);
+    }
+    lib->GEOSGeom_destroy_r(handle, geom);
+  }
+
+  lib->GEOS_finish_r(handle);
+  return toGEOSString(error.data(), error.length());
+}
+
+CR_GEOS_Status CR_GEOS_Buffer(CR_GEOS* lib, CR_GEOS_Slice ewkb, CR_GEOS_BufferParamsInput params,
+                              double distance, CR_GEOS_String* ret) {
+  std::string error;
+  auto handle = initHandleWithErrorBuffer(lib, &error);
+  *ret = {.data = NULL, .len = 0};
+
+  auto geom = CR_GEOS_GeometryFromSlice(lib, handle, ewkb);
+  if (geom != nullptr) {
+    auto gParams = lib->GEOSBufferParams_create_r(handle);
+    if (gParams != nullptr) {
+      if (lib->GEOSBufferParams_setEndCapStyle_r(handle, gParams, params.endCapStyle) &&
+          lib->GEOSBufferParams_setJoinStyle_r(handle, gParams, params.joinStyle) &&
+          lib->GEOSBufferParams_setMitreLimit_r(handle, gParams, params.mitreLimit) &&
+          lib->GEOSBufferParams_setQuadrantSegments_r(handle, gParams, params.quadrantSegments) &&
+          lib->GEOSBufferParams_setSingleSided_r(handle, gParams, params.singleSided)) {
+        auto bufferedGeom = lib->GEOSBufferWithParams_r(handle, geom, gParams, distance);
+        if (bufferedGeom != nullptr) {
+          auto srid = lib->GEOSGetSRID_r(handle, geom);
+          CR_GEOS_writeGeomToEWKB(lib, handle, bufferedGeom, ret, srid);
+          lib->GEOSGeom_destroy_r(handle, bufferedGeom);
+        }
+      }
+      lib->GEOSBufferParams_destroy_r(handle, gParams);
+    }
+    lib->GEOSGeom_destroy_r(handle, geom);
+  }
+
+  lib->GEOS_finish_r(handle);
+  return toGEOSString(error.data(), error.length());
+}
+
+//
+// Unary operators
+//
+
+template <typename T, typename R>
+CR_GEOS_Status CR_GEOS_UnaryOperator(CR_GEOS* lib, T fn, CR_GEOS_Slice a, R* ret) {
+  std::string error;
+  auto handle = initHandleWithErrorBuffer(lib, &error);
+  auto geom = CR_GEOS_GeometryFromSlice(lib, handle, a);
+  if (geom != nullptr) {
+    auto r = fn(handle, geom, ret);
+    // ret == 0 indicates an exception.
+    if (r == 0) {
+      if (error.length() == 0) {
+        error.assign(CR_GEOS_NO_ERROR_DEFINED_MESSAGE);
+      }
+    }
+    lib->GEOSGeom_destroy_r(handle, geom);
+  }
+  lib->GEOS_finish_r(handle);
+  return toGEOSString(error.data(), error.length());
+}
+
+template <typename T, typename R>
+CR_GEOS_Status CR_GEOS_BinaryOperator(CR_GEOS* lib, T fn, CR_GEOS_Slice a, CR_GEOS_Slice b,
+                                      R* ret) {
+  std::string error;
+  auto handle = initHandleWithErrorBuffer(lib, &error);
+  auto wkbReader = lib->GEOSWKBReader_create_r(handle);
+  auto geomA = lib->GEOSWKBReader_read_r(handle, wkbReader, a.data, a.len);
+  auto geomB = lib->GEOSWKBReader_read_r(handle, wkbReader, b.data, b.len);
+  lib->GEOSWKBReader_destroy_r(handle, wkbReader);
+  if (geomA != nullptr && geomB != nullptr) {
+    auto r = fn(handle, geomA, geomB, ret);
+    // ret == 0 indicates an exception.
+    if (r == 0) {
+      if (error.length() == 0) {
+        error.assign(CR_GEOS_NO_ERROR_DEFINED_MESSAGE);
+      }
+    }
+  }
+  if (geomA != nullptr) {
+    lib->GEOSGeom_destroy_r(handle, geomA);
+  }
+  if (geomB != nullptr) {
+    lib->GEOSGeom_destroy_r(handle, geomB);
+  }
+  lib->GEOS_finish_r(handle);
+  return toGEOSString(error.data(), error.length());
+}
+
+CR_GEOS_Status CR_GEOS_Area(CR_GEOS* lib, CR_GEOS_Slice a, double* ret) {
+  return CR_GEOS_UnaryOperator(lib, lib->GEOSArea_r, a, ret);
+}
+
+CR_GEOS_Status CR_GEOS_Length(CR_GEOS* lib, CR_GEOS_Slice a, double* ret) {
+  return CR_GEOS_UnaryOperator(lib, lib->GEOSLength_r, a, ret);
+}
+
+CR_GEOS_Status CR_GEOS_MinimumClearance(CR_GEOS* lib, CR_GEOS_Slice g, double* ret) {
+  std::string error;
+  auto handle = initHandleWithErrorBuffer(lib, &error);
+  auto geom = CR_GEOS_GeometryFromSlice(lib, handle, g);
+  *ret = 0;
+  if (geom != nullptr) {
+    auto r = lib->GEOSMinimumClearance_r(handle, geom, ret);
+    if (r == 2) {
+      if (error.length() == 0) {
+        error.assign(CR_GEOS_NO_ERROR_DEFINED_MESSAGE);
+      }
+    }
+    lib->GEOSGeom_destroy_r(handle, geom);
+  }
+  lib->GEOS_finish_r(handle);
+  return toGEOSString(error.data(), error.length());
+}
+
+CR_GEOS_Status CR_GEOS_MinimumClearanceLine(CR_GEOS* lib, CR_GEOS_Slice g,
+                                            CR_GEOS_String* clearanceEWKB) {
+  std::string error;
+  auto handle = initHandleWithErrorBuffer(lib, &error);
+  *clearanceEWKB = {.data = NULL, .len = 0};
+
+  auto geom = CR_GEOS_GeometryFromSlice(lib, handle, g);
+  if (geom != nullptr) {
+    auto clearance = lib->GEOSMinimumClearanceLine_r(handle, geom);
+    auto srid = lib->GEOSGetSRID_r(handle, clearance);
+    CR_GEOS_writeGeomToEWKB(lib, handle, clearance, clearanceEWKB, srid);
+    lib->GEOSGeom_destroy_r(handle, geom);
+  }
+
+  lib->GEOS_finish_r(handle);
+  return toGEOSString(error.data(), error.length());
+}
+
+CR_GEOS_Status CR_GEOS_Normalize(CR_GEOS* lib, CR_GEOS_Slice a, CR_GEOS_String* normalizedEWKB) {
+  std::string error;
+  auto handle = initHandleWithErrorBuffer(lib, &error);
+  *normalizedEWKB = {.data = NULL, .len = 0};
+
+  auto geomA = CR_GEOS_GeometryFromSlice(lib, handle, a);
+  if (geomA != nullptr) {
+    auto exceptionStatus = lib->GEOSNormalize_r(handle, geomA);
+    if (exceptionStatus != -1) {
+      auto srid = lib->GEOSGetSRID_r(handle, geomA);
+      CR_GEOS_writeGeomToEWKB(lib, handle, geomA, normalizedEWKB, srid);
+    } else {
+      error.assign(CR_GEOS_NO_ERROR_DEFINED_MESSAGE);
+    }
+    lib->GEOSGeom_destroy_r(handle, geomA);
+  }
+
+  lib->GEOS_finish_r(handle);
+  return toGEOSString(error.data(), error.length());
+}
+
+CR_GEOS_Status CR_GEOS_LineMerge(CR_GEOS* lib, CR_GEOS_Slice a, CR_GEOS_String* ewkb) {
+  std::string error;
+  auto handle = initHandleWithErrorBuffer(lib, &error);
+  *ewkb = {.data = NULL, .len = 0};
+
+  auto geomA = CR_GEOS_GeometryFromSlice(lib, handle, a);
+  if (geomA != nullptr) {
+    auto merged = lib->GEOSLineMerge_r(handle, geomA);
+    auto srid = lib->GEOSGetSRID_r(handle, merged);
+    CR_GEOS_writeGeomToEWKB(lib, handle, merged, ewkb, srid);
+    lib->GEOSGeom_destroy_r(handle, geomA);
+  }
+
+  lib->GEOS_finish_r(handle);
+  return toGEOSString(error.data(), error.length());
+}
+
+//
+// Unary predicates.
+//
+
+template <typename T>
+CR_GEOS_Status CR_GEOS_UnaryPredicate(CR_GEOS* lib, T fn, CR_GEOS_Slice a, char* ret) {
+  std::string error;
+  auto handle = initHandleWithErrorBuffer(lib, &error);
+  auto geom = CR_GEOS_GeometryFromSlice(lib, handle, a);
+  if (geom != nullptr) {
+    auto r = fn(handle, geom);
+    // r == 2 indicates an exception.
+    if (r == 2) {
+      if (error.length() == 0) {
+        error.assign(CR_GEOS_NO_ERROR_DEFINED_MESSAGE);
+      }
+    } else {
+      *ret = r;
+    }
+    lib->GEOSGeom_destroy_r(handle, geom);
+  }
+  lib->GEOS_finish_r(handle);
+  return toGEOSString(error.data(), error.length());
+}
+
+CR_GEOS_Status CR_GEOS_IsSimple(CR_GEOS* lib, CR_GEOS_Slice a, char* ret) {
+  return CR_GEOS_UnaryPredicate(lib, lib->GEOSisSimple_r, a, ret);
+}
+
+//
+// Validity checking.
+//
+
+CR_GEOS_Status CR_GEOS_IsValid(CR_GEOS* lib, CR_GEOS_Slice g, char* ret) {
+  std::string error;
+  auto handle = initHandleWithErrorBuffer(lib, &error);
+  auto geom = CR_GEOS_GeometryFromSlice(lib, handle, g);
+  *ret = 0;
+  if (geom != nullptr) {
+    auto r = lib->GEOSisValid_r(handle, geom);
+    if (r == 2) {
+      if (error.length() == 0) {
+        error.assign(CR_GEOS_NO_ERROR_DEFINED_MESSAGE);
+      }
+    } else {
+      *ret = r;
+    }
+    lib->GEOSGeom_destroy_r(handle, geom);
+  }
+  lib->GEOS_finish_r(handle);
+  return toGEOSString(error.data(), error.length());
+}
+
+CR_GEOS_Status CR_GEOS_IsValidReason(CR_GEOS* lib, CR_GEOS_Slice g, CR_GEOS_String* ret) {
+  std::string error;
+  auto handle = initHandleWithErrorBuffer(lib, &error);
+  auto geom = CR_GEOS_GeometryFromSlice(lib, handle, g);
+  *ret = {.data = NULL, .len = 0};
+  if (geom != nullptr) {
+    auto r = lib->GEOSisValidReason_r(handle, geom);
+    if (r != NULL) {
+      *ret = toGEOSString(r, strlen(r));
+      lib->GEOSFree_r(handle, r);
+    }
+    lib->GEOSGeom_destroy_r(handle, geom);
+  }
+  lib->GEOS_finish_r(handle);
+  return toGEOSString(error.data(), error.length());
+}
+
+CR_GEOS_Status CR_GEOS_IsValidDetail(CR_GEOS* lib, CR_GEOS_Slice g, int flags, char* retIsValid,
+                                     CR_GEOS_String* retReason, CR_GEOS_String* retLocationEWKB) {
+  std::string error;
+  auto handle = initHandleWithErrorBuffer(lib, &error);
+  auto geom = CR_GEOS_GeometryFromSlice(lib, handle, g);
+  *retReason = {.data = NULL, .len = 0};
+  *retLocationEWKB = {.data = NULL, .len = 0};
+  if (geom != nullptr) {
+    char* reason = NULL;
+    CR_GEOS_Geometry loc = NULL;
+    auto r = lib->GEOSisValidDetail_r(handle, geom, flags, &reason, &loc);
+
+    if (r == 2) {
+      if (error.length() == 0) {
+        error.assign(CR_GEOS_NO_ERROR_DEFINED_MESSAGE);
+      }
+    } else {
+      *retIsValid = r;
+    }
+
+    if (reason != NULL) {
+      *retReason = toGEOSString(reason, strlen(reason));
+      lib->GEOSFree_r(handle, reason);
+    }
+
+    if (loc != NULL) {
+      auto srid = lib->GEOSGetSRID_r(handle, geom);
+      CR_GEOS_writeGeomToEWKB(lib, handle, loc, retLocationEWKB, srid);
+      lib->GEOSGeom_destroy_r(handle, loc);
+    }
+
+    lib->GEOSGeom_destroy_r(handle, geom);
+  }
+  lib->GEOS_finish_r(handle);
+  return toGEOSString(error.data(), error.length());
+}
+
+CR_GEOS_Status CR_GEOS_MakeValid(CR_GEOS* lib, CR_GEOS_Slice g, CR_GEOS_String* validEWKB) {
+  std::string error;
+  auto handle = initHandleWithErrorBuffer(lib, &error);
+  auto geom = CR_GEOS_GeometryFromSlice(lib, handle, g);
+  *validEWKB = {.data = NULL, .len = 0};
+  if (geom != nullptr) {
+    auto validGeom = lib->GEOSMakeValid_r(handle, geom);
+    if (validGeom != nullptr) {
+      auto srid = lib->GEOSGetSRID_r(handle, geom);
+      CR_GEOS_writeGeomToEWKB(lib, handle, validGeom, validEWKB, srid);
+      lib->GEOSGeom_destroy_r(handle, validGeom);
+    }
+    lib->GEOSGeom_destroy_r(handle, geom);
+  }
+  lib->GEOS_finish_r(handle);
+  return toGEOSString(error.data(), error.length());
+}
+
+//
+// Topology operators.
+//
+
+CR_GEOS_Status CR_GEOS_Boundary(CR_GEOS* lib, CR_GEOS_Slice a, CR_GEOS_String* boundaryEWKB) {
+  std::string error;
+  auto handle = initHandleWithErrorBuffer(lib, &error);
+  auto geom = CR_GEOS_GeometryFromSlice(lib, handle, a);
+  *boundaryEWKB = {.data = NULL, .len = 0};
+  if (geom != nullptr) {
+    auto boundaryGeom = lib->GEOSBoundary_r(handle, geom);
+    if (boundaryGeom != nullptr) {
+      auto srid = lib->GEOSGetSRID_r(handle, geom);
+      CR_GEOS_writeGeomToEWKB(lib, handle, boundaryGeom, boundaryEWKB, srid);
+      lib->GEOSGeom_destroy_r(handle, boundaryGeom);
+    }
+    lib->GEOSGeom_destroy_r(handle, geom);
+  }
+  lib->GEOS_finish_r(handle);
+  return toGEOSString(error.data(), error.length());
+}
+
+CR_GEOS_Status CR_GEOS_Centroid(CR_GEOS* lib, CR_GEOS_Slice a, CR_GEOS_String* centroidEWKB) {
+  std::string error;
+  auto handle = initHandleWithErrorBuffer(lib, &error);
+  auto geom = CR_GEOS_GeometryFromSlice(lib, handle, a);
+  *centroidEWKB = {.data = NULL, .len = 0};
+  if (geom != nullptr) {
+    auto centroidGeom = lib->GEOSGetCentroid_r(handle, geom);
+    if (centroidGeom != nullptr) {
+      auto srid = lib->GEOSGetSRID_r(handle, geom);
+      CR_GEOS_writeGeomToEWKB(lib, handle, centroidGeom, centroidEWKB, srid);
+      lib->GEOSGeom_destroy_r(handle, centroidGeom);
+    }
+    lib->GEOSGeom_destroy_r(handle, geom);
+  }
+  lib->GEOS_finish_r(handle);
+  return toGEOSString(error.data(), error.length());
+}
+
+CR_GEOS_Status CR_GEOS_MinimumBoundingCircle(CR_GEOS* lib, CR_GEOS_Slice a, double* radius,
+                                              CR_GEOS_String* centerEWKB, CR_GEOS_String* polygonEWKB) {
+  std::string error;
+  auto handle = initHandleWithErrorBuffer(lib, &error);
+  auto geom = CR_GEOS_GeometryFromSlice(lib, handle, a);
+  CR_GEOS_Geometry* centerGeom;
+  *polygonEWKB = {.data = NULL, .len = 0};
+  if (geom != nullptr) {
+    auto circlePolygonGeom = lib->GEOSMinimumBoundingCircle_r(handle, geom, radius, &centerGeom);
+    if (circlePolygonGeom != nullptr) {
+      auto srid = lib->GEOSGetSRID_r(handle, geom);
+      CR_GEOS_writeGeomToEWKB(lib, handle, circlePolygonGeom, polygonEWKB, srid);
+      lib->GEOSGeom_destroy_r(handle, circlePolygonGeom);
+    }
+    if (centerGeom != nullptr) {
+      auto srid = lib->GEOSGetSRID_r(handle, geom);
+      CR_GEOS_writeGeomToEWKB(lib, handle, centerGeom, centerEWKB, srid);
+      lib->GEOSGeom_destroy_r(handle, centerGeom);
+    }
+    lib->GEOSGeom_destroy_r(handle, geom);
+  }
+  lib->GEOS_finish_r(handle);
+  return toGEOSString(error.data(), error.length());
+}
+
+CR_GEOS_Status CR_GEOS_ConvexHull(CR_GEOS* lib, CR_GEOS_Slice a, CR_GEOS_String* convexHullEWKB) {
+  std::string error;
+  auto handle = initHandleWithErrorBuffer(lib, &error);
+  auto geom = CR_GEOS_GeometryFromSlice(lib, handle, a);
+  *convexHullEWKB = {.data = NULL, .len = 0};
+  if (geom != nullptr) {
+    auto convexHullGeom = lib->GEOSConvexHull_r(handle, geom);
+    if (convexHullGeom != nullptr) {
+      auto srid = lib->GEOSGetSRID_r(handle, geom);
+      CR_GEOS_writeGeomToEWKB(lib, handle, convexHullGeom, convexHullEWKB, srid);
+      lib->GEOSGeom_destroy_r(handle, convexHullGeom);
+    }
+    lib->GEOSGeom_destroy_r(handle, geom);
+  }
+  lib->GEOS_finish_r(handle);
+  return toGEOSString(error.data(), error.length());
+}
+
+CR_GEOS_Status CR_GEOS_Difference(CR_GEOS* lib, CR_GEOS_Slice a, CR_GEOS_Slice b,
+                                  CR_GEOS_String* diffEWKB) {
+  std::string error;
+  auto handle = initHandleWithErrorBuffer(lib, &error);
+  auto geomA = CR_GEOS_GeometryFromSlice(lib, handle, a);
+  auto geomB = CR_GEOS_GeometryFromSlice(lib, handle, b);
+  *diffEWKB = {.data = NULL, .len = 0};
+  if (geomA != nullptr && geomB != nullptr) {
+    auto diffGeom = lib->GEOSDifference_r(handle, geomA, geomB);
+    if (diffGeom != nullptr) {
+      auto srid = lib->GEOSGetSRID_r(handle, geomA);
+      CR_GEOS_writeGeomToEWKB(lib, handle, diffGeom, diffEWKB, srid);
+      lib->GEOSGeom_destroy_r(handle, diffGeom);
+    }
+  }
+  if (geomA != nullptr) {
+    lib->GEOSGeom_destroy_r(handle, geomA);
+  }
+  if (geomB != nullptr) {
+    lib->GEOSGeom_destroy_r(handle, geomB);
+  }
+  lib->GEOS_finish_r(handle);
+  return toGEOSString(error.data(), error.length());
+}
+
+CR_GEOS_Status CR_GEOS_Simplify(CR_GEOS* lib, CR_GEOS_Slice a, CR_GEOS_String* simplifyEWKB,
+                                double tolerance) {
+  std::string error;
+  auto handle = initHandleWithErrorBuffer(lib, &error);
+  auto geom = CR_GEOS_GeometryFromSlice(lib, handle, a);
+  *simplifyEWKB = {.data = NULL, .len = 0};
+  if (geom != nullptr) {
+    auto simplifyGeom = lib->GEOSSimplify_r(handle, geom, tolerance);
+    if (simplifyGeom != nullptr) {
+      auto srid = lib->GEOSGetSRID_r(handle, geom);
+      CR_GEOS_writeGeomToEWKB(lib, handle, simplifyGeom, simplifyEWKB, srid);
+      lib->GEOSGeom_destroy_r(handle, simplifyGeom);
+    }
+    lib->GEOSGeom_destroy_r(handle, geom);
+  }
+  lib->GEOS_finish_r(handle);
+  return toGEOSString(error.data(), error.length());
+}
+
+CR_GEOS_Status CR_GEOS_TopologyPreserveSimplify(CR_GEOS* lib, CR_GEOS_Slice a,
+                                                CR_GEOS_String* simplifyEWKB, double tolerance) {
+  std::string error;
+  auto handle = initHandleWithErrorBuffer(lib, &error);
+  auto geom = CR_GEOS_GeometryFromSlice(lib, handle, a);
+  *simplifyEWKB = {.data = NULL, .len = 0};
+  if (geom != nullptr) {
+    auto simplifyGeom = lib->GEOSTopologyPreserveSimplify_r(handle, geom, tolerance);
+    if (simplifyGeom != nullptr) {
+      auto srid = lib->GEOSGetSRID_r(handle, geom);
+      CR_GEOS_writeGeomToEWKB(lib, handle, simplifyGeom, simplifyEWKB, srid);
+      lib->GEOSGeom_destroy_r(handle, simplifyGeom);
+    }
+    lib->GEOSGeom_destroy_r(handle, geom);
+  }
+  lib->GEOS_finish_r(handle);
+  return toGEOSString(error.data(), error.length());
+}
+
+CR_GEOS_Status CR_GEOS_UnaryUnion(CR_GEOS* lib, CR_GEOS_Slice a, CR_GEOS_String* unionEWKB) {
+  std::string error;
+  auto handle = initHandleWithErrorBuffer(lib, &error);
+
+  auto geomA = CR_GEOS_GeometryFromSlice(lib, handle, a);
+  *unionEWKB = {.data = NULL, .len = 0};
+  if (geomA != nullptr) {
+    auto r = lib->GEOSUnaryUnion_r(handle, geomA);
+    if (r != NULL) {
+      auto srid = lib->GEOSGetSRID_r(handle, r);
+      CR_GEOS_writeGeomToEWKB(lib, handle, r, unionEWKB, srid);
+      lib->GEOSGeom_destroy_r(handle, r);
+    }
+    lib->GEOSGeom_destroy_r(handle, geomA);
+  }
+  lib->GEOS_finish_r(handle);
+  return toGEOSString(error.data(), error.length());
+}
+
+CR_GEOS_Status CR_GEOS_Union(CR_GEOS* lib, CR_GEOS_Slice a, CR_GEOS_Slice b,
+                             CR_GEOS_String* unionEWKB) {
+  std::string error;
+  auto handle = initHandleWithErrorBuffer(lib, &error);
+  *unionEWKB = {.data = NULL, .len = 0};
+
+  auto geomA = CR_GEOS_GeometryFromSlice(lib, handle, a);
+  auto geomB = CR_GEOS_GeometryFromSlice(lib, handle, b);
+  if (geomA != nullptr && geomB != nullptr) {
+    auto unionGeom = lib->GEOSUnion_r(handle, geomA, geomB);
+    if (unionGeom != nullptr) {
+      auto srid = lib->GEOSGetSRID_r(handle, geomA);
+      CR_GEOS_writeGeomToEWKB(lib, handle, unionGeom, unionEWKB, srid);
+      lib->GEOSGeom_destroy_r(handle, unionGeom);
+    }
+  }
+  if (geomA != nullptr) {
+    lib->GEOSGeom_destroy_r(handle, geomA);
+  }
+  if (geomB != nullptr) {
+    lib->GEOSGeom_destroy_r(handle, geomB);
+  }
+
+  lib->GEOS_finish_r(handle);
+  return toGEOSString(error.data(), error.length());
+}
+
+CR_GEOS_Status CR_GEOS_PointOnSurface(CR_GEOS* lib, CR_GEOS_Slice a,
+                                      CR_GEOS_String* pointOnSurfaceEWKB) {
+  std::string error;
+  auto handle = initHandleWithErrorBuffer(lib, &error);
+  auto geom = CR_GEOS_GeometryFromSlice(lib, handle, a);
+  *pointOnSurfaceEWKB = {.data = NULL, .len = 0};
+  if (geom != nullptr) {
+    auto pointOnSurfaceGeom = lib->GEOSPointOnSurface_r(handle, geom);
+    if (pointOnSurfaceGeom != nullptr) {
+      auto srid = lib->GEOSGetSRID_r(handle, geom);
+      CR_GEOS_writeGeomToEWKB(lib, handle, pointOnSurfaceGeom, pointOnSurfaceEWKB, srid);
+      lib->GEOSGeom_destroy_r(handle, pointOnSurfaceGeom);
+    }
+    lib->GEOSGeom_destroy_r(handle, geom);
+  }
+  lib->GEOS_finish_r(handle);
+  return toGEOSString(error.data(), error.length());
+}
+
+CR_GEOS_Status CR_GEOS_Intersection(CR_GEOS* lib, CR_GEOS_Slice a, CR_GEOS_Slice b,
+                                    CR_GEOS_String* intersectionEWKB) {
+  std::string error;
+  auto handle = initHandleWithErrorBuffer(lib, &error);
+  *intersectionEWKB = {.data = NULL, .len = 0};
+
+  auto geomA = CR_GEOS_GeometryFromSlice(lib, handle, a);
+  auto geomB = CR_GEOS_GeometryFromSlice(lib, handle, b);
+  if (geomA != nullptr && geomB != nullptr) {
+    auto intersectionGeom = lib->GEOSIntersection_r(handle, geomA, geomB);
+    if (intersectionGeom != nullptr) {
+      auto srid = lib->GEOSGetSRID_r(handle, geomA);
+      CR_GEOS_writeGeomToEWKB(lib, handle, intersectionGeom, intersectionEWKB, srid);
+      lib->GEOSGeom_destroy_r(handle, intersectionGeom);
+    }
+  }
+  if (geomA != nullptr) {
+    lib->GEOSGeom_destroy_r(handle, geomA);
+  }
+  if (geomB != nullptr) {
+    lib->GEOSGeom_destroy_r(handle, geomB);
+  }
+
+  lib->GEOS_finish_r(handle);
+  return toGEOSString(error.data(), error.length());
+}
+
+CR_GEOS_Status CR_GEOS_SymDifference(CR_GEOS* lib, CR_GEOS_Slice a, CR_GEOS_Slice b,
+                                     CR_GEOS_String* symdifferenceEWKB) {
+  std::string error;
+  auto handle = initHandleWithErrorBuffer(lib, &error);
+  *symdifferenceEWKB = {.data = NULL, .len = 0};
+
+  auto geomA = CR_GEOS_GeometryFromSlice(lib, handle, a);
+  auto geomB = CR_GEOS_GeometryFromSlice(lib, handle, b);
+  if (geomA != nullptr && geomB != nullptr) {
+    auto symdifferenceGeom = lib->GEOSSymDifference_r(handle, geomA, geomB);
+    if (symdifferenceGeom != nullptr) {
+      auto srid = lib->GEOSGetSRID_r(handle, geomA);
+      CR_GEOS_writeGeomToEWKB(lib, handle, symdifferenceGeom, symdifferenceEWKB, srid);
+      lib->GEOSGeom_destroy_r(handle, symdifferenceGeom);
+    }
+  }
+  if (geomA != nullptr) {
+    lib->GEOSGeom_destroy_r(handle, geomA);
+  }
+  if (geomB != nullptr) {
+    lib->GEOSGeom_destroy_r(handle, geomB);
+  }
+
+  lib->GEOS_finish_r(handle);
+  return toGEOSString(error.data(), error.length());
+}
+
+//
+// Linear Reference
+//
+
+CR_GEOS_Status CR_GEOS_Interpolate(CR_GEOS* lib, CR_GEOS_Slice a, double distance,
+                                   CR_GEOS_String* interpolatedPointEWKB) {
+  std::string error;
+  auto handle = initHandleWithErrorBuffer(lib, &error);
+  auto geom = CR_GEOS_GeometryFromSlice(lib, handle, a);
+  *interpolatedPointEWKB = {.data = NULL, .len = 0};
+  if (geom != nullptr) {
+    auto interpolatedPoint = lib->GEOSInterpolate_r(handle, geom, distance);
+    if (interpolatedPoint != nullptr) {
+      auto srid = lib->GEOSGetSRID_r(handle, geom);
+      CR_GEOS_writeGeomToEWKB(lib, handle, interpolatedPoint, interpolatedPointEWKB, srid);
+      lib->GEOSGeom_destroy_r(handle, interpolatedPoint);
+    }
+    lib->GEOSGeom_destroy_r(handle, geom);
+  }
+  lib->GEOS_finish_r(handle);
+  return toGEOSString(error.data(), error.length());
+}
+
+//
+// Binary operators
+//
+
+CR_GEOS_Status CR_GEOS_Distance(CR_GEOS* lib, CR_GEOS_Slice a, CR_GEOS_Slice b, double* ret) {
+  return CR_GEOS_BinaryOperator(lib, lib->GEOSDistance_r, a, b, ret);
+}
+CR_GEOS_Status CR_GEOS_FrechetDistance(CR_GEOS* lib, CR_GEOS_Slice a, CR_GEOS_Slice b,
+                                       double* ret) {
+  return CR_GEOS_BinaryOperator(lib, lib->GEOSFrechetDistance_r, a, b, ret);
+}
+
+CR_GEOS_Status CR_GEOS_FrechetDistanceDensify(CR_GEOS* lib, CR_GEOS_Slice a, CR_GEOS_Slice b,
+                                              double densifyFrac, double* ret) {
+  std::string error;
+  auto handle = initHandleWithErrorBuffer(lib, &error);
+
+  auto wkbReader = lib->GEOSWKBReader_create_r(handle);
+  auto geomA = lib->GEOSWKBReader_read_r(handle, wkbReader, a.data, a.len);
+  auto geomB = lib->GEOSWKBReader_read_r(handle, wkbReader, b.data, b.len);
+  lib->GEOSWKBReader_destroy_r(handle, wkbReader);
+
+  if (geomA != nullptr && geomB != nullptr) {
+    auto r = lib->GEOSFrechetDistanceDensify_r(handle, geomA, geomB, densifyFrac, ret);
+    // ret == 0 indicates an exception.
+    if (r == 0) {
+      if (error.length() == 0) {
+        error.assign(CR_GEOS_NO_ERROR_DEFINED_MESSAGE);
+      }
+    }
+  }
+  if (geomA != nullptr) {
+    lib->GEOSGeom_destroy_r(handle, geomA);
+  }
+  if (geomB != nullptr) {
+    lib->GEOSGeom_destroy_r(handle, geomB);
+  }
+  lib->GEOS_finish_r(handle);
+  return toGEOSString(error.data(), error.length());
+}
+
+CR_GEOS_Status CR_GEOS_HausdorffDistance(CR_GEOS* lib, CR_GEOS_Slice a, CR_GEOS_Slice b,
+                                         double* ret) {
+  return CR_GEOS_BinaryOperator(lib, lib->GEOSHausdorffDistance_r, a, b, ret);
+}
+
+CR_GEOS_Status CR_GEOS_HausdorffDistanceDensify(CR_GEOS* lib, CR_GEOS_Slice a, CR_GEOS_Slice b,
+                                                double densifyFrac, double* ret) {
+  std::string error;
+  auto handle = initHandleWithErrorBuffer(lib, &error);
+
+  auto wkbReader = lib->GEOSWKBReader_create_r(handle);
+  auto geomA = lib->GEOSWKBReader_read_r(handle, wkbReader, a.data, a.len);
+  auto geomB = lib->GEOSWKBReader_read_r(handle, wkbReader, b.data, b.len);
+  lib->GEOSWKBReader_destroy_r(handle, wkbReader);
+
+  if (geomA != nullptr && geomB != nullptr) {
+    auto r = lib->GEOSHausdorffDistanceDensify_r(handle, geomA, geomB, densifyFrac, ret);
+    // ret == 0 indicates an exception.
+    if (r == 0) {
+      if (error.length() == 0) {
+        error.assign(CR_GEOS_NO_ERROR_DEFINED_MESSAGE);
+      }
+    }
+  }
+  if (geomA != nullptr) {
+    lib->GEOSGeom_destroy_r(handle, geomA);
+  }
+  if (geomB != nullptr) {
+    lib->GEOSGeom_destroy_r(handle, geomB);
+  }
+  lib->GEOS_finish_r(handle);
+  return toGEOSString(error.data(), error.length());
+}
+
+//
+// PreparedGeometry
+//
+
+CR_GEOS_Status CR_GEOS_Prepare(CR_GEOS* lib, CR_GEOS_Slice a, CR_GEOS_PreparedGeometry** ret) {
+  std::string error;
+  auto handle = initHandleWithErrorBuffer(lib, &error);
+
+  auto wkbReader = lib->GEOSWKBReader_create_r(handle);
+  auto geom = lib->GEOSWKBReader_read_r(handle, wkbReader, a.data, a.len);
+  lib->GEOSWKBReader_destroy_r(handle, wkbReader);
+  if (geom != nullptr) {
+    auto preparedGeom = lib->GEOSPrepare_r(handle, geom);
+    auto tmp = new CR_GEOS_PreparedGeometry();
+    tmp->g = geom;
+    tmp->p = preparedGeom;
+    *ret = tmp;
+  }
+  lib->GEOS_finish_r(handle);
+  return toGEOSString(error.data(), error.length());
+}
+
+CR_GEOS_Status CR_GEOS_PreparedGeometryDestroy(CR_GEOS* lib, CR_GEOS_PreparedGeometry* a) {
+  std::string error;
+  auto handle = initHandleWithErrorBuffer(lib, &error);
+  lib->GEOSPreparedGeom_destroy_r(handle, a->p);
+  lib->GEOSGeom_destroy_r(handle, a->g);
+  lib->GEOS_finish_r(handle);
+  delete a;
+  return toGEOSString(error.data(), error.length());
+}
+
+template <typename T>
+CR_GEOS_Status CR_GEOS_PreparedBinaryPredicate(CR_GEOS* lib, T fn, CR_GEOS_PreparedInternalGeometry a, CR_GEOS_Slice b,
+                                       char* ret) {
+  std::string error;
+  auto handle = initHandleWithErrorBuffer(lib, &error);
+
+  auto wkbReader = lib->GEOSWKBReader_create_r(handle);
+  auto geomB = lib->GEOSWKBReader_read_r(handle, wkbReader, b.data, b.len);
+  lib->GEOSWKBReader_destroy_r(handle, wkbReader);
+
+  if (geomB != nullptr) {
+    auto r = fn(handle, a, geomB);
+    // ret == 2 indicates an exception.
+    if (r == 2) {
+      if (error.length() == 0) {
+        error.assign(CR_GEOS_NO_ERROR_DEFINED_MESSAGE);
+      }
+    } else {
+      *ret = r;
+    }
+  }
+  if (geomB != nullptr) {
+    lib->GEOSGeom_destroy_r(handle, geomB);
+  }
+  lib->GEOS_finish_r(handle);
+  return toGEOSString(error.data(), error.length());
+}
+
+CR_GEOS_Status CR_GEOS_PreparedIntersects(CR_GEOS* lib, CR_GEOS_PreparedGeometry* a, CR_GEOS_Slice b, char* ret) {
+  return CR_GEOS_PreparedBinaryPredicate(lib, lib->GEOSPreparedIntersects_r, a->p, b, ret);
+}
+
+//
+// Binary predicates
+//
+
+template <typename T>
+CR_GEOS_Status CR_GEOS_BinaryPredicate(CR_GEOS* lib, T fn, CR_GEOS_Slice a, CR_GEOS_Slice b,
+                                       char* ret) {
+  std::string error;
+  auto handle = initHandleWithErrorBuffer(lib, &error);
+
+  auto wkbReader = lib->GEOSWKBReader_create_r(handle);
+  auto geomA = lib->GEOSWKBReader_read_r(handle, wkbReader, a.data, a.len);
+  auto geomB = lib->GEOSWKBReader_read_r(handle, wkbReader, b.data, b.len);
+  lib->GEOSWKBReader_destroy_r(handle, wkbReader);
+
+  if (geomA != nullptr && geomB != nullptr) {
+    auto r = fn(handle, geomA, geomB);
+    // ret == 2 indicates an exception.
+    if (r == 2) {
+      if (error.length() == 0) {
+        error.assign(CR_GEOS_NO_ERROR_DEFINED_MESSAGE);
+      }
+    } else {
+      *ret = r;
+    }
+  }
+  if (geomA != nullptr) {
+    lib->GEOSGeom_destroy_r(handle, geomA);
+  }
+  if (geomB != nullptr) {
+    lib->GEOSGeom_destroy_r(handle, geomB);
+  }
+  lib->GEOS_finish_r(handle);
+  return toGEOSString(error.data(), error.length());
+}
+
+CR_GEOS_Status CR_GEOS_Covers(CR_GEOS* lib, CR_GEOS_Slice a, CR_GEOS_Slice b, char* ret) {
+  return CR_GEOS_BinaryPredicate(lib, lib->GEOSCovers_r, a, b, ret);
+}
+
+CR_GEOS_Status CR_GEOS_CoveredBy(CR_GEOS* lib, CR_GEOS_Slice a, CR_GEOS_Slice b, char* ret) {
+  return CR_GEOS_BinaryPredicate(lib, lib->GEOSCoveredBy_r, a, b, ret);
+}
+
+CR_GEOS_Status CR_GEOS_Contains(CR_GEOS* lib, CR_GEOS_Slice a, CR_GEOS_Slice b, char* ret) {
+  return CR_GEOS_BinaryPredicate(lib, lib->GEOSContains_r, a, b, ret);
+}
+
+CR_GEOS_Status CR_GEOS_Crosses(CR_GEOS* lib, CR_GEOS_Slice a, CR_GEOS_Slice b, char* ret) {
+  return CR_GEOS_BinaryPredicate(lib, lib->GEOSCrosses_r, a, b, ret);
+}
+
+CR_GEOS_Status CR_GEOS_Disjoint(CR_GEOS* lib, CR_GEOS_Slice a, CR_GEOS_Slice b, char* ret) {
+  return CR_GEOS_BinaryPredicate(lib, lib->GEOSDisjoint_r, a, b, ret);
+}
+
+CR_GEOS_Status CR_GEOS_Equals(CR_GEOS* lib, CR_GEOS_Slice a, CR_GEOS_Slice b, char* ret) {
+  return CR_GEOS_BinaryPredicate(lib, lib->GEOSEquals_r, a, b, ret);
+}
+
+CR_GEOS_Status CR_GEOS_Intersects(CR_GEOS* lib, CR_GEOS_Slice a, CR_GEOS_Slice b, char* ret) {
+  return CR_GEOS_BinaryPredicate(lib, lib->GEOSIntersects_r, a, b, ret);
+}
+
+CR_GEOS_Status CR_GEOS_Overlaps(CR_GEOS* lib, CR_GEOS_Slice a, CR_GEOS_Slice b, char* ret) {
+  return CR_GEOS_BinaryPredicate(lib, lib->GEOSOverlaps_r, a, b, ret);
+}
+
+CR_GEOS_Status CR_GEOS_PreparedIntersects(CR_GEOS* lib, CR_GEOS_Slice a, CR_GEOS_Slice b, char* ret) {
+  return CR_GEOS_BinaryPredicate(lib, lib->GEOSPreparedIntersects_r, a, b, ret);
+}
+
+CR_GEOS_Status CR_GEOS_Touches(CR_GEOS* lib, CR_GEOS_Slice a, CR_GEOS_Slice b, char* ret) {
+  return CR_GEOS_BinaryPredicate(lib, lib->GEOSTouches_r, a, b, ret);
+}
+
+CR_GEOS_Status CR_GEOS_Within(CR_GEOS* lib, CR_GEOS_Slice a, CR_GEOS_Slice b, char* ret) {
+  return CR_GEOS_BinaryPredicate(lib, lib->GEOSWithin_r, a, b, ret);
+}
+
+//
+// DE-9IM related
+// See: https://en.wikipedia.org/wiki/DE-9IM.
+//
+
+CR_GEOS_Status CR_GEOS_Relate(CR_GEOS* lib, CR_GEOS_Slice a, CR_GEOS_Slice b, CR_GEOS_String* ret) {
+  std::string error;
+  auto handle = initHandleWithErrorBuffer(lib, &error);
+
+  auto wkbReader = lib->GEOSWKBReader_create_r(handle);
+  auto geomA = lib->GEOSWKBReader_read_r(handle, wkbReader, a.data, a.len);
+  auto geomB = lib->GEOSWKBReader_read_r(handle, wkbReader, b.data, b.len);
+  lib->GEOSWKBReader_destroy_r(handle, wkbReader);
+
+  if (geomA != nullptr && geomB != nullptr) {
+    auto r = lib->GEOSRelate_r(handle, geomA, geomB);
+    if (r != NULL) {
+      *ret = toGEOSString(r, strlen(r));
+      lib->GEOSFree_r(handle, r);
+    }
+  }
+  if (geomA != nullptr) {
+    lib->GEOSGeom_destroy_r(handle, geomA);
+  }
+  if (geomB != nullptr) {
+    lib->GEOSGeom_destroy_r(handle, geomB);
+  }
+  lib->GEOS_finish_r(handle);
+  return toGEOSString(error.data(), error.length());
+}
+
+CR_GEOS_Status CR_GEOS_RelateBoundaryNodeRule(CR_GEOS* lib, CR_GEOS_Slice a, CR_GEOS_Slice b,
+                                              int bnr, CR_GEOS_String* ret) {
+  std::string error;
+  auto handle = initHandleWithErrorBuffer(lib, &error);
+
+  auto wkbReader = lib->GEOSWKBReader_create_r(handle);
+  auto geomA = lib->GEOSWKBReader_read_r(handle, wkbReader, a.data, a.len);
+  auto geomB = lib->GEOSWKBReader_read_r(handle, wkbReader, b.data, b.len);
+  lib->GEOSWKBReader_destroy_r(handle, wkbReader);
+
+  if (geomA != nullptr && geomB != nullptr) {
+    auto r = lib->GEOSRelateBoundaryNodeRule_r(handle, geomA, geomB, bnr);
+    if (r != NULL) {
+      *ret = toGEOSString(r, strlen(r));
+      lib->GEOSFree_r(handle, r);
+    }
+  }
+  if (geomA != nullptr) {
+    lib->GEOSGeom_destroy_r(handle, geomA);
+  }
+  if (geomB != nullptr) {
+    lib->GEOSGeom_destroy_r(handle, geomB);
+  }
+  lib->GEOS_finish_r(handle);
+  return toGEOSString(error.data(), error.length());
+}
+
+CR_GEOS_Status CR_GEOS_RelatePattern(CR_GEOS* lib, CR_GEOS_Slice a, CR_GEOS_Slice b,
+                                     CR_GEOS_Slice pattern, char* ret) {
+  std::string error;
+  auto handle = initHandleWithErrorBuffer(lib, &error);
+
+  auto wkbReader = lib->GEOSWKBReader_create_r(handle);
+  auto geomA = lib->GEOSWKBReader_read_r(handle, wkbReader, a.data, a.len);
+  auto geomB = lib->GEOSWKBReader_read_r(handle, wkbReader, b.data, b.len);
+  auto p = std::string(pattern.data, pattern.len);
+  lib->GEOSWKBReader_destroy_r(handle, wkbReader);
+
+  if (geomA != nullptr && geomB != nullptr) {
+    auto r = lib->GEOSRelatePattern_r(handle, geomA, geomB, p.c_str());
+    // ret == 2 indicates an exception.
+    if (r == 2) {
+      if (error.length() == 0) {
+        error.assign(CR_GEOS_NO_ERROR_DEFINED_MESSAGE);
+      }
+    } else {
+      *ret = r;
+    }
+  }
+  if (geomA != nullptr) {
+    lib->GEOSGeom_destroy_r(handle, geomA);
+  }
+  if (geomB != nullptr) {
+    lib->GEOSGeom_destroy_r(handle, geomB);
+  }
+  lib->GEOS_finish_r(handle);
+  return toGEOSString(error.data(), error.length());
+}
+
+CR_GEOS_Status CR_GEOS_SharedPaths(CR_GEOS* lib, CR_GEOS_Slice a, CR_GEOS_Slice b,
+                                   CR_GEOS_String* ret) {
+  std::string error;
+  auto handle = initHandleWithErrorBuffer(lib, &error);
+
+  auto wkbReader = lib->GEOSWKBReader_create_r(handle);
+  auto geomA = lib->GEOSWKBReader_read_r(handle, wkbReader, a.data, a.len);
+  auto geomB = lib->GEOSWKBReader_read_r(handle, wkbReader, b.data, b.len);
+  lib->GEOSWKBReader_destroy_r(handle, wkbReader);
+  *ret = {.data = NULL, .len = 0};
+  if (geomA != nullptr && geomB != nullptr) {
+    auto r = lib->GEOSSharedPaths_r(handle, geomA, geomB);
+    if (r != NULL) {
+      auto srid = lib->GEOSGetSRID_r(handle, r);
+      CR_GEOS_writeGeomToEWKB(lib, handle, r, ret, srid);
+      lib->GEOSGeom_destroy_r(handle, r);
+    }
+  }
+  if (geomA != nullptr) {
+    lib->GEOSGeom_destroy_r(handle, geomA);
+  }
+  if (geomB != nullptr) {
+    lib->GEOSGeom_destroy_r(handle, geomB);
+  }
+  lib->GEOS_finish_r(handle);
+  return toGEOSString(error.data(), error.length());
+}
+
+CR_GEOS_Status CR_GEOS_Node(CR_GEOS* lib, CR_GEOS_Slice a, CR_GEOS_String* nodeEWKB) {
+  std::string error;
+  auto handle = initHandleWithErrorBuffer(lib, &error);
+  *nodeEWKB = {.data = NULL, .len = 0};
+
+  auto geom = CR_GEOS_GeometryFromSlice(lib, handle, a);
+  if (geom != nullptr) {
+    auto r = lib->GEOSNode_r(handle, geom);
+    if (r != NULL) {
+      auto srid = lib->GEOSGetSRID_r(handle, r);
+      CR_GEOS_writeGeomToEWKB(lib,handle,r,nodeEWKB, srid);
+      lib->GEOSGeom_destroy_r(handle, r);
+    }
+    lib->GEOSGeom_destroy_r(handle, geom);
+  }
+
+  lib->GEOS_finish_r(handle);
+  return toGEOSString(error.data(), error.length());
+}
+
+CR_GEOS_Status CR_GEOS_VoronoiDiagram(CR_GEOS* lib, CR_GEOS_Slice g, CR_GEOS_Slice env,
+                                      double tolerance, int onlyEdges, CR_GEOS_String* ret) {
+  std::string error;
+  auto handle = initHandleWithErrorBuffer(lib, &error);
+
+  auto geomG = CR_GEOS_GeometryFromSlice(lib, handle, g);
+  CR_GEOS_Geometry geomEnv = nullptr;
+  if (env.data != nullptr) {
+   geomEnv = CR_GEOS_GeometryFromSlice(lib, handle, env);
+  }
+  *ret = {.data = NULL, .len = 0};
+
+  if (geomG != nullptr) {
+    auto r = lib->GEOSVoronoiDiagram_r(handle, geomG, geomEnv, tolerance, onlyEdges);
+    if (r != NULL) {
+      auto srid = lib->GEOSGetSRID_r(handle, r);
+      CR_GEOS_writeGeomToEWKB(lib, handle, r, ret, srid);
+      lib->GEOSGeom_destroy_r(handle, r);
+    }
+    lib->GEOSGeom_destroy_r(handle, geomG);
+  }
+  if (geomEnv != nullptr) {
+    lib->GEOSGeom_destroy_r(handle, geomEnv);
+  }
+
+  lib->GEOS_finish_r(handle);
+  return toGEOSString(error.data(), error.length());
+}
+
+CR_GEOS_Status CR_GEOS_EqualsExact(CR_GEOS* lib, CR_GEOS_Slice lhs, CR_GEOS_Slice rhs,
+                                      double tolerance, char* ret) {
+  std::string error;
+  auto handle = initHandleWithErrorBuffer(lib, &error);
+  auto lhsGeom = CR_GEOS_GeometryFromSlice(lib, handle, lhs);
+  auto rhsGeom = CR_GEOS_GeometryFromSlice(lib, handle, rhs);
+  *ret = 0;
+  if (lhsGeom != nullptr && rhsGeom != nullptr) {
+    auto r = lib->GEOSEqualsExact_r(handle, lhsGeom, rhsGeom, tolerance);
+    *ret = r;
+  }
+  if (lhsGeom != nullptr) {
+    lib->GEOSGeom_destroy_r(handle, lhsGeom);
+  }
+  if (rhsGeom != nullptr) {
+    lib->GEOSGeom_destroy_r(handle, rhsGeom);
+  }
+  lib->GEOS_finish_r(handle);
+  return toGEOSString(error.data(), error.length());
+}
+
+CR_GEOS_Status CR_GEOS_MinimumRotatedRectangle(CR_GEOS* lib, CR_GEOS_Slice g, CR_GEOS_String* ret) {
+  std::string error;
+  auto handle = initHandleWithErrorBuffer(lib, &error);
+  auto gGeom = CR_GEOS_GeometryFromSlice(lib, handle, g);
+  *ret = {.data = NULL, .len = 0};
+  if (gGeom != nullptr) {
+    auto r = lib->GEOSMinimumRotatedRectangle_r(handle, gGeom);
+    if (r != NULL) {
+      auto srid = lib->GEOSGetSRID_r(handle, r);
+      CR_GEOS_writeGeomToEWKB(lib, handle, r, ret, srid);
+      lib->GEOSGeom_destroy_r(handle, r);
+    }
+    lib->GEOSGeom_destroy_r(handle, gGeom);
+  }
+
+  lib->GEOS_finish_r(handle);
+  return toGEOSString(error.data(), error.length());
+}
+
+CR_GEOS_Status CR_GEOS_Snap(CR_GEOS* lib, CR_GEOS_Slice input, CR_GEOS_Slice target, double tolerance, CR_GEOS_String* snappedEWKB) {
+  std::string error;
+  auto handle = initHandleWithErrorBuffer(lib, &error);
+  auto gGeomInput = CR_GEOS_GeometryFromSlice(lib, handle, input);
+  auto gGeomTarget = CR_GEOS_GeometryFromSlice(lib, handle, target);
+  *snappedEWKB = {.data = NULL, .len = 0};
+  if (gGeomInput != nullptr && gGeomTarget != nullptr) {
+    auto r = lib->GEOSSnap_r(handle, gGeomInput, gGeomTarget, tolerance);
+    if (r != NULL) {
+      auto srid = lib->GEOSGetSRID_r(handle, r);
+      CR_GEOS_writeGeomToEWKB(lib, handle, r, snappedEWKB, srid);
+      lib->GEOSGeom_destroy_r(handle, r);
+    }
+  }
+  if (gGeomInput != nullptr) {
+    lib->GEOSGeom_destroy_r(handle, gGeomInput);
+  }
+  if (gGeomTarget != nullptr) {
+    lib->GEOSGeom_destroy_r(handle, gGeomTarget);
+  }
+  lib->GEOS_finish_r(handle);
+  return toGEOSString(error.data(), error.length());
+}
diff --git a/pkg/geo/geos/geos.go b/pkg/geo/geos/geos.go
new file mode 100644
index 0000000..d1b3076
--- /dev/null
+++ b/pkg/geo/geos/geos.go
@@ -0,0 +1,1125 @@
+// Copyright 2020 The Cockroach Authors.
+//
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
+
+// Package geos is a wrapper around the spatial data types between the geo
+// package and the GEOS C library. The GEOS library is dynamically loaded
+// at init time.
+// Operations will error if the GEOS library was not found.
+package geos
+
+import (
+	"fmt"
+	"os"
+	"path"
+	"path/filepath"
+	"runtime"
+	"sync"
+	"unsafe"
+
+	"github.com/cockroachdb/cockroachdb-parser/pkg/build/bazel"
+	"github.com/cockroachdb/cockroachdb-parser/pkg/docs"
+	"github.com/cockroachdb/cockroachdb-parser/pkg/geo/geopb"
+	"github.com/cockroachdb/cockroachdb-parser/pkg/sql/pgwire/pgcode"
+	"github.com/cockroachdb/cockroachdb-parser/pkg/sql/pgwire/pgerror"
+	"github.com/cockroachdb/errors"
+)
+
+// #cgo CXXFLAGS: -std=c++14
+// #cgo !windows LDFLAGS: -ldl -lm
+//
+// #include "geos.h"
+import "C"
+
+// EnsureInitErrorDisplay is used to control the error message displayed by
+// EnsureInit.
+type EnsureInitErrorDisplay int
+
+const (
+	// EnsureInitErrorDisplayPrivate displays the full error message, including
+	// path info. It is intended for log messages.
+	EnsureInitErrorDisplayPrivate EnsureInitErrorDisplay = iota
+	// EnsureInitErrorDisplayPublic displays a redacted error message, excluding
+	// path info. It is intended for errors to display for the client.
+	EnsureInitErrorDisplayPublic
+)
+
+// maxArrayLen is the maximum safe length for this architecture.
+const maxArrayLen = 1<<31 - 1
+
+// geosOnce contains the global instance of CR_GEOS, to be initialized
+// during at a maximum of once.
+// If it has failed to open, the error will be populated in "err".
+// This should only be touched by "fetchGEOSOrError".
+var geosOnce struct {
+	geos *C.CR_GEOS
+	loc  string
+	err  error
+	once sync.Once
+}
+
+// PreparedGeometry is an instance of a GEOS PreparedGeometry.
+type PreparedGeometry *C.CR_GEOS_PreparedGeometry
+
+// EnsureInit attempts to start GEOS if it has not been opened already
+// and returns the location if found, and an error if the CR_GEOS is not valid.
+func EnsureInit(
+	errDisplay EnsureInitErrorDisplay, flagLibraryDirectoryValue string,
+) (string, error) {
+	crdbBinaryLoc := ""
+	if len(os.Args) > 0 {
+		crdbBinaryLoc = os.Args[0]
+	}
+	_, err := ensureInit(errDisplay, flagLibraryDirectoryValue, crdbBinaryLoc)
+	return geosOnce.loc, err
+}
+
+// ensureInitInternal ensures initialization has been done, always displaying
+// errors privately and not assuming a flag has been set if initialized
+// for the first time.
+func ensureInitInternal() (*C.CR_GEOS, error) {
+	return ensureInit(EnsureInitErrorDisplayPrivate, "", "")
+}
+
+// ensureInits behaves as described in EnsureInit, but also returns the GEOS
+// C object which should be hidden from the public eye.
+func ensureInit(
+	errDisplay EnsureInitErrorDisplay, flagLibraryDirectoryValue string, crdbBinaryLoc string,
+) (*C.CR_GEOS, error) {
+	geosOnce.once.Do(func() {
+		geosOnce.geos, geosOnce.loc, geosOnce.err = initGEOS(
+			findLibraryDirectories(flagLibraryDirectoryValue, crdbBinaryLoc),
+		)
+	})
+	if geosOnce.err != nil && errDisplay == EnsureInitErrorDisplayPublic {
+		return nil, pgerror.Newf(pgcode.System, "geos: this operation is not available")
+	}
+	return geosOnce.geos, geosOnce.err
+}
+
+// appendLibraryExt appends the extension expected for the running OS.
+func getLibraryExt(base string) string {
+	switch runtime.GOOS {
+	case "darwin":
+		return base + ".dylib"
+	case "windows":
+		return base + ".dll"
+	default:
+		return base + ".so"
+	}
+}
+
+const (
+	libgeosFileName  = "libgeos"
+	libgeoscFileName = "libgeos_c"
+)
+
+// findLibraryDirectories returns the default locations where GEOS is installed.
+func findLibraryDirectories(flagLibraryDirectoryValue string, crdbBinaryLoc string) []string {
+	// Try path by trying to find all parenting paths and appending
+	// `lib/libgeos_c.<ext>` to the current working directory, as well
+	// as the directory in which the cockroach binary is initialized.
+	locs := []string{}
+	if flagLibraryDirectoryValue != "" {
+		locs = append(locs, flagLibraryDirectoryValue)
+	}
+	// Account for the libraries to be in a bazel runfile path.
+	if bazel.BuiltWithBazel() {
+		pathsToCheck := []string{
+			path.Join("c-deps", "libgeos_foreign", "lib"),
+			path.Join("external", "archived_cdep_libgeos_linux", "lib"),
+			path.Join("external", "archived_cdep_libgeos_linuxarm", "lib"),
+			path.Join("external", "archived_cdep_libgeos_macos", "lib"),
+			path.Join("external", "archived_cdep_libgeos_macosarm", "lib"),
+			path.Join("external", "archived_cdep_libgeos_windows", "bin"),
+		}
+		for _, path := range pathsToCheck {
+			if p, err := bazel.Runfile(path); err == nil {
+				locs = append(locs, p)
+			}
+		}
+	}
+	locs = append(
+		locs,
+		findLibraryDirectoriesInParentingDirectories(crdbBinaryLoc)...,
+	)
+	cwd, err := os.Getwd()
+	if err != nil {
+		fmt.Fprintf(os.Stderr, "warning: cannot retrieve cwd: %v", err)
+	} else {
+		locs = append(
+			locs,
+			findLibraryDirectoriesInParentingDirectories(cwd)...,
+		)
+	}
+	return locs
+}
+
+// findLibraryDirectoriesInParentingDirectories attempts to find GEOS by looking at
+// parenting folders and looking inside `lib/libgeos_c.*`.
+// This is basically only useful for CI runs.
+func findLibraryDirectoriesInParentingDirectories(dir string) []string {
+	locs := []string{}
+
+	for {
+		checkDir := filepath.Join(dir, "lib")
+		found := true
+		for _, file := range []string{
+			filepath.Join(checkDir, getLibraryExt(libgeoscFileName)),
+			filepath.Join(checkDir, getLibraryExt(libgeosFileName)),
+		} {
+			if _, err := os.Stat(file); err != nil {
+				found = false
+				break
+			}
+		}
+		if found {
+			locs = append(locs, checkDir)
+		}
+		parentDir := filepath.Dir(dir)
+		if parentDir == dir {
+			break
+		}
+		dir = parentDir
+	}
+	return locs
+}
+
+// initGEOS initializes the CR_GEOS by attempting to dlopen all
+// the paths as parsed in by locs.
+func initGEOS(dirs []string) (*C.CR_GEOS, string, error) {
+	var err error
+	for _, dir := range dirs {
+		var ret *C.CR_GEOS
+		newErr := statusToError(
+			C.CR_GEOS_Init(
+				goToCSlice([]byte(filepath.Join(dir, getLibraryExt(libgeoscFileName)))),
+				goToCSlice([]byte(filepath.Join(dir, getLibraryExt(libgeosFileName)))),
+				&ret,
+			),
+		)
+		if newErr == nil {
+			return ret, dir, nil
+		}
+		err = errors.CombineErrors(
+			err,
+			errors.Wrapf(
+				newErr,
+				"geos: cannot load GEOS from dir %q",
+				dir,
+			),
+		)
+	}
+	if err != nil {
+		return nil, "", wrapGEOSInitError(errors.Wrap(err, "geos: error during GEOS init"))
+	}
+	return nil, "", wrapGEOSInitError(errors.Newf("geos: no locations to init GEOS"))
+}
+
+func wrapGEOSInitError(err error) error {
+	page := "linux"
+	switch runtime.GOOS {
+	case "darwin":
+		page = "mac"
+	case "windows":
+		page = "windows"
+	}
+	return pgerror.WithCandidateCode(
+		errors.WithHintf(
+			err,
+			"Ensure you have the spatial libraries installed as per the instructions in %s",
+			docs.URL("install-cockroachdb-"+page),
+		),
+		pgcode.ConfigFile,
+	)
+}
+
+// goToCSlice returns a CR_GEOS_Slice from a given Go byte slice.
+func goToCSlice(b []byte) C.CR_GEOS_Slice {
+	if len(b) == 0 {
+		return C.CR_GEOS_Slice{data: nil, len: 0}
+	}
+	return C.CR_GEOS_Slice{
+		data: (*C.char)(unsafe.Pointer(&b[0])),
+		len:  C.size_t(len(b)),
+	}
+}
+
+// cStringToUnsafeGoBytes convert a CR_GEOS_String to a Go
+// byte slice that refer to the underlying C memory.
+func cStringToUnsafeGoBytes(s C.CR_GEOS_String) []byte {
+	return cToUnsafeGoBytes(s.data, s.len)
+}
+
+func cToUnsafeGoBytes(data *C.char, len C.size_t) []byte {
+	if data == nil {
+		return nil
+	}
+	// Interpret the C pointer as a pointer to a Go array, then slice.
+	return (*[maxArrayLen]byte)(unsafe.Pointer(data))[:len:len]
+}
+
+// cStringToSafeGoBytes converts a CR_GEOS_String to a Go byte slice.
+// Additionally, it frees the C memory.
+func cStringToSafeGoBytes(s C.CR_GEOS_String) []byte {
+	unsafeBytes := cStringToUnsafeGoBytes(s)
+	b := make([]byte, len(unsafeBytes))
+	copy(b, unsafeBytes)
+	C.free(unsafe.Pointer(s.data))
+	return b
+}
+
+// A Error wraps an error returned from a GEOS operation.
+type Error struct {
+	msg string
+}
+
+// Error implements the error interface.
+func (err *Error) Error() string {
+	return err.msg
+}
+
+func statusToError(s C.CR_GEOS_Status) error {
+	if s.data == nil {
+		return nil
+	}
+	return &Error{msg: string(cStringToSafeGoBytes(s))}
+}
+
+// Version returns the GEOS version used.
+func Version() (string, error) {
+	g, err := ensureInitInternal()
+	if err != nil {
+		return "", err
+	}
+	var version C.CR_GEOS_String
+	C.CR_GEOS_Version(g, &version)
+	// Returns a `const char*`, so we don't have to free anything.
+	return string(cStringToUnsafeGoBytes(version)), nil
+}
+
+// BufferParamsJoinStyle maps to the GEOSBufJoinStyles enum in geos_c.h.in.
+type BufferParamsJoinStyle int
+
+// These should be kept in sync with the geos_c.h.in corresponding enum definition.
+const (
+	BufferParamsJoinStyleRound = 1
+	BufferParamsJoinStyleMitre = 2
+	BufferParamsJoinStyleBevel = 3
+)
+
+// BufferParamsEndCapStyle maps to the GEOSBufCapStyles enum in geos_c.h.in.
+type BufferParamsEndCapStyle int
+
+// These should be kept in sync with the geos_c.h.in corresponding enum definition.
+const (
+	BufferParamsEndCapStyleRound  = 1
+	BufferParamsEndCapStyleFlat   = 2
+	BufferParamsEndCapStyleSquare = 3
+)
+
+// BufferParams are parameters to provide into the GEOS buffer function.
+type BufferParams struct {
+	JoinStyle        BufferParamsJoinStyle
+	EndCapStyle      BufferParamsEndCapStyle
+	SingleSided      bool
+	QuadrantSegments int
+	MitreLimit       float64
+}
+
+// Buffer buffers the given geometry by the given distance and params.
+func Buffer(ewkb geopb.EWKB, params BufferParams, distance float64) (geopb.EWKB, error) {
+	g, err := ensureInitInternal()
+	if err != nil {
+		return nil, err
+	}
+	singleSided := 0
+	if params.SingleSided {
+		singleSided = 1
+	}
+	cParams := C.CR_GEOS_BufferParamsInput{
+		endCapStyle:      C.int(params.EndCapStyle),
+		joinStyle:        C.int(params.JoinStyle),
+		singleSided:      C.int(singleSided),
+		quadrantSegments: C.int(params.QuadrantSegments),
+		mitreLimit:       C.double(params.MitreLimit),
+	}
+	var cEWKB C.CR_GEOS_String
+	if err := statusToError(C.CR_GEOS_Buffer(g, goToCSlice(ewkb), cParams, C.double(distance), &cEWKB)); err != nil {
+		return nil, err
+	}
+	return cStringToSafeGoBytes(cEWKB), nil
+}
+
+// Area returns the area of an EWKB.
+func Area(ewkb geopb.EWKB) (float64, error) {
+	g, err := ensureInitInternal()
+	if err != nil {
+		return 0, err
+	}
+	var area C.double
+	if err := statusToError(C.CR_GEOS_Area(g, goToCSlice(ewkb), &area)); err != nil {
+		return 0, err
+	}
+	return float64(area), nil
+}
+
+// Boundary returns the boundary of an EWKB.
+func Boundary(ewkb geopb.EWKB) (geopb.EWKB, error) {
+	g, err := ensureInitInternal()
+	if err != nil {
+		return nil, err
+	}
+	var cEWKB C.CR_GEOS_String
+	if err := statusToError(C.CR_GEOS_Boundary(g, goToCSlice(ewkb), &cEWKB)); err != nil {
+		return nil, err
+	}
+	return cStringToSafeGoBytes(cEWKB), nil
+}
+
+// Difference returns the difference between two EWKB.
+func Difference(ewkb1 geopb.EWKB, ewkb2 geopb.EWKB) (geopb.EWKB, error) {
+	g, err := ensureInitInternal()
+	if err != nil {
+		return nil, err
+	}
+	var diffEWKB C.CR_GEOS_String
+	if err := statusToError(C.CR_GEOS_Difference(g, goToCSlice(ewkb1), goToCSlice(ewkb2), &diffEWKB)); err != nil {
+		return nil, err
+	}
+	return cStringToSafeGoBytes(diffEWKB), nil
+}
+
+// Length returns the length of an EWKB.
+func Length(ewkb geopb.EWKB) (float64, error) {
+	g, err := ensureInitInternal()
+	if err != nil {
+		return 0, err
+	}
+	var length C.double
+	if err := statusToError(C.CR_GEOS_Length(g, goToCSlice(ewkb), &length)); err != nil {
+		return 0, err
+	}
+	return float64(length), nil
+}
+
+// Normalize returns the geometry in its normalized form.
+func Normalize(a geopb.EWKB) (geopb.EWKB, error) {
+	g, err := ensureInitInternal()
+	if err != nil {
+		return nil, err
+	}
+	var cEWKB C.CR_GEOS_String
+	if err := statusToError(C.CR_GEOS_Normalize(g, goToCSlice(a), &cEWKB)); err != nil {
+		return nil, err
+	}
+	return cStringToSafeGoBytes(cEWKB), nil
+}
+
+// LineMerge merges multilinestring constituents.
+func LineMerge(a geopb.EWKB) (geopb.EWKB, error) {
+	g, err := ensureInitInternal()
+	if err != nil {
+		return nil, err
+	}
+	var cEWKB C.CR_GEOS_String
+	if err := statusToError(C.CR_GEOS_LineMerge(g, goToCSlice(a), &cEWKB)); err != nil {
+		return nil, err
+	}
+	return cStringToSafeGoBytes(cEWKB), nil
+}
+
+// IsSimple returns whether the EWKB is simple.
+func IsSimple(ewkb geopb.EWKB) (bool, error) {
+	g, err := ensureInitInternal()
+	if err != nil {
+		return false, err
+	}
+	var ret C.char
+	if err := statusToError(C.CR_GEOS_IsSimple(g, goToCSlice(ewkb), &ret)); err != nil {
+		return false, err
+	}
+	return ret == 1, nil
+}
+
+// Centroid returns the centroid of an EWKB.
+func Centroid(ewkb geopb.EWKB) (geopb.EWKB, error) {
+	g, err := ensureInitInternal()
+	if err != nil {
+		return nil, err
+	}
+	var cEWKB C.CR_GEOS_String
+	if err := statusToError(C.CR_GEOS_Centroid(g, goToCSlice(ewkb), &cEWKB)); err != nil {
+		return nil, err
+	}
+	return cStringToSafeGoBytes(cEWKB), nil
+}
+
+// MinimumBoundingCircle returns minimum bounding circle of an EWKB
+func MinimumBoundingCircle(ewkb geopb.EWKB) (geopb.EWKB, geopb.EWKB, float64, error) {
+	g, err := ensureInitInternal()
+	if err != nil {
+		return nil, nil, 0, err
+	}
+	var centerEWKB C.CR_GEOS_String
+	var polygonEWKB C.CR_GEOS_String
+	var radius C.double
+
+	if err := statusToError(C.CR_GEOS_MinimumBoundingCircle(g, goToCSlice(ewkb), &radius, &centerEWKB, &polygonEWKB)); err != nil {
+		return nil, nil, 0, err
+	}
+	return cStringToSafeGoBytes(polygonEWKB), cStringToSafeGoBytes(centerEWKB), float64(radius), nil
+
+}
+
+// ConvexHull returns an EWKB which returns the convex hull of the given EWKB.
+func ConvexHull(ewkb geopb.EWKB) (geopb.EWKB, error) {
+	g, err := ensureInitInternal()
+	if err != nil {
+		return nil, err
+	}
+	var cEWKB C.CR_GEOS_String
+	if err := statusToError(C.CR_GEOS_ConvexHull(g, goToCSlice(ewkb), &cEWKB)); err != nil {
+		return nil, err
+	}
+	return cStringToSafeGoBytes(cEWKB), nil
+}
+
+// Simplify returns an EWKB which returns the simplified EWKB.
+func Simplify(ewkb geopb.EWKB, tolerance float64) (geopb.EWKB, error) {
+	g, err := ensureInitInternal()
+	if err != nil {
+		return nil, err
+	}
+	var cEWKB C.CR_GEOS_String
+	if err := statusToError(
+		C.CR_GEOS_Simplify(g, goToCSlice(ewkb), &cEWKB, C.double(tolerance)),
+	); err != nil {
+		return nil, err
+	}
+	return cStringToSafeGoBytes(cEWKB), nil
+}
+
+// TopologyPreserveSimplify returns an EWKB which returns the simplified EWKB
+// with the topology preserved.
+func TopologyPreserveSimplify(ewkb geopb.EWKB, tolerance float64) (geopb.EWKB, error) {
+	g, err := ensureInitInternal()
+	if err != nil {
+		return nil, err
+	}
+	var cEWKB C.CR_GEOS_String
+	if err := statusToError(
+		C.CR_GEOS_TopologyPreserveSimplify(g, goToCSlice(ewkb), &cEWKB, C.double(tolerance)),
+	); err != nil {
+		return nil, err
+	}
+	return cStringToSafeGoBytes(cEWKB), nil
+}
+
+// PointOnSurface returns an EWKB with a point that is on the surface of the given EWKB.
+func PointOnSurface(ewkb geopb.EWKB) (geopb.EWKB, error) {
+	g, err := ensureInitInternal()
+	if err != nil {
+		return nil, err
+	}
+	var cEWKB C.CR_GEOS_String
+	if err := statusToError(C.CR_GEOS_PointOnSurface(g, goToCSlice(ewkb), &cEWKB)); err != nil {
+		return nil, err
+	}
+	return cStringToSafeGoBytes(cEWKB), nil
+}
+
+// Intersection returns an EWKB which contains the geometries of intersection between A and B.
+func Intersection(a geopb.EWKB, b geopb.EWKB) (geopb.EWKB, error) {
+	g, err := ensureInitInternal()
+	if err != nil {
+		return nil, err
+	}
+	var cEWKB C.CR_GEOS_String
+	if err := statusToError(C.CR_GEOS_Intersection(g, goToCSlice(a), goToCSlice(b), &cEWKB)); err != nil {
+		return nil, err
+	}
+	return cStringToSafeGoBytes(cEWKB), nil
+}
+
+// UnaryUnion Returns an EWKB which is a union of input geometry components.
+func UnaryUnion(a geopb.EWKB) (geopb.EWKB, error) {
+	g, err := ensureInitInternal()
+	if err != nil {
+		return nil, err
+	}
+	var unionEWKB C.CR_GEOS_String
+	if err := statusToError(C.CR_GEOS_UnaryUnion(g, goToCSlice(a), &unionEWKB)); err != nil {
+		return nil, err
+	}
+	return cStringToSafeGoBytes(unionEWKB), nil
+}
+
+// Union returns an EWKB which is a union of shapes A and B.
+func Union(a geopb.EWKB, b geopb.EWKB) (geopb.EWKB, error) {
+	g, err := ensureInitInternal()
+	if err != nil {
+		return nil, err
+	}
+	var cEWKB C.CR_GEOS_String
+	if err := statusToError(C.CR_GEOS_Union(g, goToCSlice(a), goToCSlice(b), &cEWKB)); err != nil {
+		return nil, err
+	}
+	return cStringToSafeGoBytes(cEWKB), nil
+}
+
+// SymDifference returns an EWKB which is the symmetric difference of shapes A and B.
+func SymDifference(a geopb.EWKB, b geopb.EWKB) (geopb.EWKB, error) {
+	g, err := ensureInitInternal()
+	if err != nil {
+		return nil, err
+	}
+	var cEWKB C.CR_GEOS_String
+	if err := statusToError(C.CR_GEOS_SymDifference(g, goToCSlice(a), goToCSlice(b), &cEWKB)); err != nil {
+		return nil, err
+	}
+	return cStringToSafeGoBytes(cEWKB), nil
+}
+
+// InterpolateLine returns the point along the given LineString which is at
+// a given distance from starting point.
+// Note: For distance less than 0 it returns start point similarly for distance
+// greater LineString's length.
+// InterpolateLine also works with (Multi)LineString. However, the result is
+// not appropriate as it combines all the LineString present in (MULTI)LineString,
+// considering all the corner points of LineString overlaps each other.
+func InterpolateLine(ewkb geopb.EWKB, distance float64) (geopb.EWKB, error) {
+	g, err := ensureInitInternal()
+	if err != nil {
+		return nil, err
+	}
+	var cEWKB C.CR_GEOS_String
+	if err := statusToError(C.CR_GEOS_Interpolate(g, goToCSlice(ewkb), C.double(distance), &cEWKB)); err != nil {
+		return nil, err
+	}
+	return cStringToSafeGoBytes(cEWKB), nil
+}
+
+// MinDistance returns the minimum distance between two EWKBs.
+func MinDistance(a geopb.EWKB, b geopb.EWKB) (float64, error) {
+	g, err := ensureInitInternal()
+	if err != nil {
+		return 0, err
+	}
+	var distance C.double
+	if err := statusToError(C.CR_GEOS_Distance(g, goToCSlice(a), goToCSlice(b), &distance)); err != nil {
+		return 0, err
+	}
+	return float64(distance), nil
+}
+
+// MinimumClearance returns the minimum distance a vertex can move to result in an
+// invalid geometry.
+func MinimumClearance(ewkb geopb.EWKB) (float64, error) {
+	g, err := ensureInitInternal()
+	if err != nil {
+		return 0, err
+	}
+	var distance C.double
+	if err := statusToError(C.CR_GEOS_MinimumClearance(g, goToCSlice(ewkb), &distance)); err != nil {
+		return 0, err
+	}
+	return float64(distance), nil
+}
+
+// MinimumClearanceLine returns the line spanning the minimum clearance a vertex can
+// move before producing an invalid geometry.
+func MinimumClearanceLine(ewkb geopb.EWKB) (geopb.EWKB, error) {
+	g, err := ensureInitInternal()
+	if err != nil {
+		return nil, err
+	}
+	var clearanceEWKB C.CR_GEOS_String
+	if err := statusToError(C.CR_GEOS_MinimumClearanceLine(g, goToCSlice(ewkb), &clearanceEWKB)); err != nil {
+		return nil, err
+	}
+	return cStringToSafeGoBytes(clearanceEWKB), nil
+}
+
+// ClipByRect clips a EWKB to the specified rectangle.
+func ClipByRect(
+	ewkb geopb.EWKB, xMin float64, yMin float64, xMax float64, yMax float64,
+) (geopb.EWKB, error) {
+	g, err := ensureInitInternal()
+	if err != nil {
+		return nil, err
+	}
+	var cEWKB C.CR_GEOS_String
+	if err := statusToError(C.CR_GEOS_ClipByRect(g, goToCSlice(ewkb), C.double(xMin),
+		C.double(yMin), C.double(xMax), C.double(yMax), &cEWKB)); err != nil {
+		return nil, err
+	}
+	return cStringToSafeGoBytes(cEWKB), nil
+}
+
+//
+// PreparedGeometry
+//
+
+// PrepareGeometry prepares a geometry in GEOS.
+func PrepareGeometry(a geopb.EWKB) (PreparedGeometry, error) {
+	g, err := ensureInitInternal()
+	if err != nil {
+		return nil, err
+	}
+	var ret *C.CR_GEOS_PreparedGeometry
+	if err := statusToError(C.CR_GEOS_Prepare(g, goToCSlice(a), &ret)); err != nil {
+		return nil, err
+	}
+	return PreparedGeometry(ret), nil
+}
+
+// PreparedGeomDestroy destroys a prepared geometry.
+func PreparedGeomDestroy(a PreparedGeometry) {
+	g, err := ensureInitInternal()
+	if err != nil {
+		panic(errors.NewAssertionErrorWithWrappedErrf(err, "trying to destroy PreparedGeometry with no GEOS"))
+	}
+	ap := (*C.CR_GEOS_PreparedGeometry)(unsafe.Pointer(a))
+	if err := statusToError(C.CR_GEOS_PreparedGeometryDestroy(g, ap)); err != nil {
+		panic(errors.NewAssertionErrorWithWrappedErrf(err, "PreparedGeometryDestroy returned an error"))
+	}
+}
+
+//
+// Binary predicates.
+//
+
+// Covers returns whether the EWKB provided by A covers the EWKB provided by B.
+func Covers(a geopb.EWKB, b geopb.EWKB) (bool, error) {
+	g, err := ensureInitInternal()
+	if err != nil {
+		return false, err
+	}
+	var ret C.char
+	if err := statusToError(C.CR_GEOS_Covers(g, goToCSlice(a), goToCSlice(b), &ret)); err != nil {
+		return false, err
+	}
+	return ret == 1, nil
+}
+
+// CoveredBy returns whether the EWKB provided by A is covered by the EWKB provided by B.
+func CoveredBy(a geopb.EWKB, b geopb.EWKB) (bool, error) {
+	g, err := ensureInitInternal()
+	if err != nil {
+		return false, err
+	}
+	var ret C.char
+	if err := statusToError(C.CR_GEOS_CoveredBy(g, goToCSlice(a), goToCSlice(b), &ret)); err != nil {
+		return false, err
+	}
+	return ret == 1, nil
+}
+
+// Contains returns whether the EWKB provided by A contains the EWKB provided by B.
+func Contains(a geopb.EWKB, b geopb.EWKB) (bool, error) {
+	g, err := ensureInitInternal()
+	if err != nil {
+		return false, err
+	}
+	var ret C.char
+	if err := statusToError(C.CR_GEOS_Contains(g, goToCSlice(a), goToCSlice(b), &ret)); err != nil {
+		return false, err
+	}
+	return ret == 1, nil
+}
+
+// Crosses returns whether the EWKB provided by A crosses the EWKB provided by B.
+func Crosses(a geopb.EWKB, b geopb.EWKB) (bool, error) {
+	g, err := ensureInitInternal()
+	if err != nil {
+		return false, err
+	}
+	var ret C.char
+	if err := statusToError(C.CR_GEOS_Crosses(g, goToCSlice(a), goToCSlice(b), &ret)); err != nil {
+		return false, err
+	}
+	return ret == 1, nil
+}
+
+// Disjoint returns whether the EWKB provided by A is disjoint from the EWKB provided by B.
+func Disjoint(a geopb.EWKB, b geopb.EWKB) (bool, error) {
+	g, err := ensureInitInternal()
+	if err != nil {
+		return false, err
+	}
+	var ret C.char
+	if err := statusToError(C.CR_GEOS_Disjoint(g, goToCSlice(a), goToCSlice(b), &ret)); err != nil {
+		return false, err
+	}
+	return ret == 1, nil
+}
+
+// Equals returns whether the EWKB provided by A equals the EWKB provided by B.
+func Equals(a geopb.EWKB, b geopb.EWKB) (bool, error) {
+	g, err := ensureInitInternal()
+	if err != nil {
+		return false, err
+	}
+	var ret C.char
+	if err := statusToError(C.CR_GEOS_Equals(g, goToCSlice(a), goToCSlice(b), &ret)); err != nil {
+		return false, err
+	}
+	return ret == 1, nil
+}
+
+// PreparedIntersects returns whether the EWKB provided by A intersects the EWKB provided by B.
+func PreparedIntersects(a PreparedGeometry, b geopb.EWKB) (bool, error) {
+	// Double check - since PreparedGeometry is actually a pointer to C type.
+	if a == nil {
+		return false, errors.New("provided PreparedGeometry is nil")
+	}
+	g, err := ensureInitInternal()
+	if err != nil {
+		return false, err
+	}
+	var ret C.char
+	ap := (*C.CR_GEOS_PreparedGeometry)(unsafe.Pointer(a))
+	if err := statusToError(C.CR_GEOS_PreparedIntersects(g, ap, goToCSlice(b), &ret)); err != nil {
+		return false, err
+	}
+	return ret == 1, nil
+}
+
+// Intersects returns whether the EWKB provided by A intersects the EWKB provided by B.
+func Intersects(a geopb.EWKB, b geopb.EWKB) (bool, error) {
+	g, err := ensureInitInternal()
+	if err != nil {
+		return false, err
+	}
+	var ret C.char
+	if err := statusToError(C.CR_GEOS_Intersects(g, goToCSlice(a), goToCSlice(b), &ret)); err != nil {
+		return false, err
+	}
+	return ret == 1, nil
+}
+
+// Overlaps returns whether the EWKB provided by A overlaps the EWKB provided by B.
+func Overlaps(a geopb.EWKB, b geopb.EWKB) (bool, error) {
+	g, err := ensureInitInternal()
+	if err != nil {
+		return false, err
+	}
+	var ret C.char
+	if err := statusToError(C.CR_GEOS_Overlaps(g, goToCSlice(a), goToCSlice(b), &ret)); err != nil {
+		return false, err
+	}
+	return ret == 1, nil
+}
+
+// Touches returns whether the EWKB provided by A touches the EWKB provided by B.
+func Touches(a geopb.EWKB, b geopb.EWKB) (bool, error) {
+	g, err := ensureInitInternal()
+	if err != nil {
+		return false, err
+	}
+	var ret C.char
+	if err := statusToError(C.CR_GEOS_Touches(g, goToCSlice(a), goToCSlice(b), &ret)); err != nil {
+		return false, err
+	}
+	return ret == 1, nil
+}
+
+// Within returns whether the EWKB provided by A is within the EWKB provided by B.
+func Within(a geopb.EWKB, b geopb.EWKB) (bool, error) {
+	g, err := ensureInitInternal()
+	if err != nil {
+		return false, err
+	}
+	var ret C.char
+	if err := statusToError(C.CR_GEOS_Within(g, goToCSlice(a), goToCSlice(b), &ret)); err != nil {
+		return false, err
+	}
+	return ret == 1, nil
+}
+
+// FrechetDistance returns the Frechet distance between the geometries.
+func FrechetDistance(a, b geopb.EWKB) (float64, error) {
+	g, err := ensureInitInternal()
+	if err != nil {
+		return 0, err
+	}
+	var distance C.double
+	if err := statusToError(
+		C.CR_GEOS_FrechetDistance(g, goToCSlice(a), goToCSlice(b), &distance),
+	); err != nil {
+		return 0, err
+	}
+	return float64(distance), nil
+}
+
+// FrechetDistanceDensify returns the Frechet distance between the geometries.
+func FrechetDistanceDensify(a, b geopb.EWKB, densifyFrac float64) (float64, error) {
+	g, err := ensureInitInternal()
+	if err != nil {
+		return 0, err
+	}
+	var distance C.double
+	if err := statusToError(
+		C.CR_GEOS_FrechetDistanceDensify(g, goToCSlice(a), goToCSlice(b), C.double(densifyFrac), &distance),
+	); err != nil {
+		return 0, err
+	}
+	return float64(distance), nil
+}
+
+// HausdorffDistance returns the Hausdorff distance between the geometries.
+func HausdorffDistance(a, b geopb.EWKB) (float64, error) {
+	g, err := ensureInitInternal()
+	if err != nil {
+		return 0, err
+	}
+	var distance C.double
+	if err := statusToError(
+		C.CR_GEOS_HausdorffDistance(g, goToCSlice(a), goToCSlice(b), &distance),
+	); err != nil {
+		return 0, err
+	}
+	return float64(distance), nil
+}
+
+// HausdorffDistanceDensify returns the Hausdorff distance between the geometries.
+func HausdorffDistanceDensify(a, b geopb.EWKB, densifyFrac float64) (float64, error) {
+	g, err := ensureInitInternal()
+	if err != nil {
+		return 0, err
+	}
+	var distance C.double
+	if err := statusToError(
+		C.CR_GEOS_HausdorffDistanceDensify(g, goToCSlice(a), goToCSlice(b), C.double(densifyFrac), &distance),
+	); err != nil {
+		return 0, err
+	}
+	return float64(distance), nil
+}
+
+// EqualsExact returns whether two geometry objects are equal with some epsilon
+func EqualsExact(lhs, rhs geopb.EWKB, epsilon float64) (bool, error) {
+	g, err := ensureInitInternal()
+	if err != nil {
+		return false, err
+	}
+	var ret C.char
+	if err := statusToError(
+		C.CR_GEOS_EqualsExact(g, goToCSlice(lhs), goToCSlice(rhs), C.double(epsilon), &ret),
+	); err != nil {
+		return false, err
+	}
+	return ret == 1, nil
+}
+
+//
+// DE-9IM related
+//
+
+// Relate returns the DE-9IM relation between A and B.
+func Relate(a geopb.EWKB, b geopb.EWKB) (string, error) {
+	g, err := ensureInitInternal()
+	if err != nil {
+		return "", err
+	}
+	var ret C.CR_GEOS_String
+	if err := statusToError(C.CR_GEOS_Relate(g, goToCSlice(a), goToCSlice(b), &ret)); err != nil {
+		return "", err
+	}
+	if ret.data == nil {
+		return "", errors.Newf("expected DE-9IM string but found nothing")
+	}
+	return string(cStringToSafeGoBytes(ret)), nil
+}
+
+// RelateBoundaryNodeRule returns the DE-9IM relation between A and B given a boundary node rule.
+func RelateBoundaryNodeRule(a geopb.EWKB, b geopb.EWKB, bnr int) (string, error) {
+	g, err := ensureInitInternal()
+	if err != nil {
+		return "", err
+	}
+	var ret C.CR_GEOS_String
+	if err := statusToError(C.CR_GEOS_RelateBoundaryNodeRule(g, goToCSlice(a), goToCSlice(b), C.int(bnr), &ret)); err != nil {
+		return "", err
+	}
+	if ret.data == nil {
+		return "", errors.Newf("expected DE-9IM string but found nothing")
+	}
+	return string(cStringToSafeGoBytes(ret)), nil
+}
+
+// RelatePattern whether A and B have a DE-9IM relation matching the given pattern.
+func RelatePattern(a geopb.EWKB, b geopb.EWKB, pattern string) (bool, error) {
+	g, err := ensureInitInternal()
+	if err != nil {
+		return false, err
+	}
+	var ret C.char
+	if err := statusToError(
+		C.CR_GEOS_RelatePattern(g, goToCSlice(a), goToCSlice(b), goToCSlice([]byte(pattern)), &ret),
+	); err != nil {
+		return false, err
+	}
+	return ret == 1, nil
+}
+
+//
+// Validity checking.
+//
+
+// IsValid returns whether the given geometry is valid.
+func IsValid(ewkb geopb.EWKB) (bool, error) {
+	g, err := ensureInitInternal()
+	if err != nil {
+		return false, err
+	}
+	var ret C.char
+	if err := statusToError(
+		C.CR_GEOS_IsValid(g, goToCSlice(ewkb), &ret),
+	); err != nil {
+		return false, err
+	}
+	return ret == 1, nil
+}
+
+// IsValidReason the reasoning for whether the Geometry is valid or invalid.
+func IsValidReason(ewkb geopb.EWKB) (string, error) {
+	g, err := ensureInitInternal()
+	if err != nil {
+		return "", err
+	}
+	var ret C.CR_GEOS_String
+	if err := statusToError(
+		C.CR_GEOS_IsValidReason(g, goToCSlice(ewkb), &ret),
+	); err != nil {
+		return "", err
+	}
+
+	return string(cStringToSafeGoBytes(ret)), nil
+}
+
+// IsValidDetail returns information regarding whether a geometry is valid or invalid.
+// It takes in a flag parameter which behaves the same as the GEOS module, where 1
+// means that self-intersecting rings forming holes are considered valid.
+// It returns a bool representing whether it is valid, a string giving a reason for
+// invalidity and an EWKB representing the location things are invalid at.
+func IsValidDetail(ewkb geopb.EWKB, flags int) (bool, string, geopb.EWKB, error) {
+	g, err := ensureInitInternal()
+	if err != nil {
+		return false, "", nil, err
+	}
+	var retIsValid C.char
+	var retReason C.CR_GEOS_String
+	var retLocationEWKB C.CR_GEOS_String
+	if err := statusToError(
+		C.CR_GEOS_IsValidDetail(
+			g,
+			goToCSlice(ewkb),
+			C.int(flags),
+			&retIsValid,
+			&retReason,
+			&retLocationEWKB,
+		),
+	); err != nil {
+		return false, "", nil, err
+	}
+	return retIsValid == 1,
+		string(cStringToSafeGoBytes(retReason)),
+		cStringToSafeGoBytes(retLocationEWKB),
+		nil
+}
+
+// MakeValid returns a valid form of the EWKB.
+func MakeValid(ewkb geopb.EWKB) (geopb.EWKB, error) {
+	g, err := ensureInitInternal()
+	if err != nil {
+		return nil, err
+	}
+	var cEWKB C.CR_GEOS_String
+	if err := statusToError(C.CR_GEOS_MakeValid(g, goToCSlice(ewkb), &cEWKB)); err != nil {
+		return nil, err
+	}
+	return cStringToSafeGoBytes(cEWKB), nil
+}
+
+// SharedPaths Returns a EWKB containing paths shared by the two given EWKBs.
+func SharedPaths(a geopb.EWKB, b geopb.EWKB) (geopb.EWKB, error) {
+	g, err := ensureInitInternal()
+	if err != nil {
+		return nil, err
+	}
+	var cEWKB C.CR_GEOS_String
+	if err := statusToError(
+		C.CR_GEOS_SharedPaths(g, goToCSlice(a), goToCSlice(b), &cEWKB),
+	); err != nil {
+		return nil, err
+	}
+	return cStringToSafeGoBytes(cEWKB), nil
+}
+
+// Node returns a EWKB containing a set of linestrings using the least possible number of nodes while preserving all of the input ones.
+func Node(a geopb.EWKB) (geopb.EWKB, error) {
+	g, err := ensureInitInternal()
+	if err != nil {
+		return nil, err
+	}
+	var cEWKB C.CR_GEOS_String
+	err = statusToError(C.CR_GEOS_Node(g, goToCSlice(a), &cEWKB))
+	if err != nil {
+		return nil, err
+	}
+	return cStringToSafeGoBytes(cEWKB), nil
+}
+
+// VoronoiDiagram Computes the Voronoi Diagram from the vertices of the supplied EWKBs.
+func VoronoiDiagram(a, env geopb.EWKB, tolerance float64, onlyEdges bool) (geopb.EWKB, error) {
+	g, err := ensureInitInternal()
+	if err != nil {
+		return nil, err
+	}
+	var cEWKB C.CR_GEOS_String
+	flag := 0
+	if onlyEdges {
+		flag = 1
+	}
+	if err := statusToError(
+		C.CR_GEOS_VoronoiDiagram(g, goToCSlice(a), goToCSlice(env), C.double(tolerance), C.int(flag), &cEWKB),
+	); err != nil {
+		return nil, err
+	}
+	return cStringToSafeGoBytes(cEWKB), nil
+}
+
+// MinimumRotatedRectangle Returns a minimum rotated rectangle enclosing a geometry
+func MinimumRotatedRectangle(ewkb geopb.EWKB) (geopb.EWKB, error) {
+	g, err := ensureInitInternal()
+	if err != nil {
+		return nil, err
+	}
+	var cEWKB C.CR_GEOS_String
+	if err := statusToError(
+		C.CR_GEOS_MinimumRotatedRectangle(g, goToCSlice(ewkb), &cEWKB),
+	); err != nil {
+		return nil, err
+	}
+	return cStringToSafeGoBytes(cEWKB), nil
+}
+
+// Snap returns the input EWKB with the vertices snapped to the target
+// EWKB. Tolerance is used to control where snapping is performed.
+// If no snapping occurs then the input geometry is returned unchanged.
+func Snap(input, target geopb.EWKB, tolerance float64) (geopb.EWKB, error) {
+	g, err := ensureInitInternal()
+	if err != nil {
+		return nil, err
+	}
+	var cEWKB C.CR_GEOS_String
+	if err := statusToError(
+		C.CR_GEOS_Snap(g, goToCSlice(input), goToCSlice(target), C.double(tolerance), &cEWKB),
+	); err != nil {
+		return nil, err
+	}
+	return cStringToSafeGoBytes(cEWKB), nil
+}
diff --git a/pkg/geo/geos/geos.h b/pkg/geo/geos/geos.h
new file mode 100644
index 0000000..8cf9a2e
--- /dev/null
+++ b/pkg/geo/geos/geos.h
@@ -0,0 +1,195 @@
+// Copyright 2020 The Cockroach Authors.
+//
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
+
+#include <stdlib.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+// Data Types adapted from `capi/geos_c.h.in` in GEOS.
+typedef void* CR_GEOS_Geometry;
+typedef void* CR_GEOS_PreparedInternalGeometry;
+
+// NB: Both CR_GEOS_Slice and CR_GEOS_String can contain non-printable
+// data, so neither is necessarily compatible with a NUL character
+// terminated C string. Functions that need data that does not contain
+// the NUL character, so that they can convert to a NUL terminated C
+// string, must document that additional constraint in their interface.
+
+// CR_GEOS_Slice contains data that does not need to be freed. It
+// can be either a Go or C pointer (which indicates who allocated the
+// memory).
+typedef struct {
+  char* data;
+  size_t len;
+} CR_GEOS_Slice;
+
+// CR_GEOS_String contains a C pointer that needs to be freed.
+typedef struct {
+  char* data;
+  size_t len;
+} CR_GEOS_String;
+
+// CR_GEOS_PreparedGeometry is a wrapper containing GEOS PreparedGeometry and it's source Geometry.
+// This allows us to free the memory for both at the same time.
+typedef struct {
+  CR_GEOS_Geometry g;
+  CR_GEOS_PreparedInternalGeometry p;
+} CR_GEOS_PreparedGeometry;
+
+// CR_GEOS_BufferParams are parameters that will be passed to buffer.
+typedef struct {
+  int endCapStyle;
+  int joinStyle;
+  int singleSided;
+  int quadrantSegments;
+  double mitreLimit;
+} CR_GEOS_BufferParamsInput;
+
+typedef CR_GEOS_String CR_GEOS_Status;
+
+// CR_GEOS contains all the functions loaded by GEOS.
+typedef struct CR_GEOS CR_GEOS;
+
+// CR_GEOS_Init initializes the provided GEOSLib with GEOS using dlopen/dlsym.
+// Returns a string containing an error if an error was found. The loc slice
+// must be convertible to a NUL character terminated C string.
+// The CR_GEOS object will be stored in lib.
+CR_GEOS_Status CR_GEOS_Init(CR_GEOS_Slice geoscLoc, CR_GEOS_Slice geosLoc, CR_GEOS** lib);
+
+// CR_GEOS_WKTToWKB converts a given WKT into it's EWKB form. The wkt slice must be
+// convertible to a NUL character terminated C string.
+CR_GEOS_Status CR_GEOS_WKTToEWKB(CR_GEOS* lib, CR_GEOS_Slice wkt, int srid, CR_GEOS_String* ewkb);
+
+// CR_GEOS_ClipByRect clips a given EWKB by the given rectangle.
+CR_GEOS_Status CR_GEOS_ClipByRect(CR_GEOS* lib, CR_GEOS_Slice ewkb, double xmin, double ymin,
+                                  double xmax, double ymax, CR_GEOS_String* clippedEWKB);
+// CR_GEOS_Buffer buffers a given EWKB by the given distance and params.
+CR_GEOS_Status CR_GEOS_Buffer(CR_GEOS* lib, CR_GEOS_Slice ewkb, CR_GEOS_BufferParamsInput params,
+                              double distance, CR_GEOS_String* ret);
+void CR_GEOS_Version(CR_GEOS* lib, CR_GEOS_String* ret);
+
+//
+// Validity checking.
+//
+
+CR_GEOS_Status CR_GEOS_IsValid(CR_GEOS* lib, CR_GEOS_Slice g, char* ret);
+CR_GEOS_Status CR_GEOS_IsValidReason(CR_GEOS* lib, CR_GEOS_Slice g, CR_GEOS_String* ret);
+CR_GEOS_Status CR_GEOS_IsValidDetail(CR_GEOS* lib, CR_GEOS_Slice g, int flags, char* retIsValid,
+                                     CR_GEOS_String* retReason, CR_GEOS_String* retLocationEWKB);
+CR_GEOS_Status CR_GEOS_MakeValid(CR_GEOS* lib, CR_GEOS_Slice g, CR_GEOS_String* validEWKB);
+
+//
+// Unary operators.
+//
+
+CR_GEOS_Status CR_GEOS_Area(CR_GEOS* lib, CR_GEOS_Slice a, double* ret);
+CR_GEOS_Status CR_GEOS_Length(CR_GEOS* lib, CR_GEOS_Slice a, double* ret);
+CR_GEOS_Status CR_GEOS_Normalize(CR_GEOS* lib, CR_GEOS_Slice a, CR_GEOS_String* normalizedEWKB);
+CR_GEOS_Status CR_GEOS_LineMerge(CR_GEOS* lib, CR_GEOS_Slice a, CR_GEOS_String* ewkb);
+CR_GEOS_Status CR_GEOS_MinimumClearance(CR_GEOS* lib, CR_GEOS_Slice a, double* ret);
+CR_GEOS_Status CR_GEOS_MinimumClearanceLine(CR_GEOS* lib, CR_GEOS_Slice a,
+                                            CR_GEOS_String* clearanceEWKB);
+
+//
+// Unary predicates.
+//
+
+CR_GEOS_Status CR_GEOS_IsSimple(CR_GEOS* lib, CR_GEOS_Slice a, char* ret);
+
+//
+// Topology operators.
+//
+
+CR_GEOS_Status CR_GEOS_Boundary(CR_GEOS* lib, CR_GEOS_Slice a, CR_GEOS_String* boundaryEWKB);
+CR_GEOS_Status CR_GEOS_Centroid(CR_GEOS* lib, CR_GEOS_Slice a, CR_GEOS_String* centroidEWKB);
+CR_GEOS_Status CR_GEOS_ConvexHull(CR_GEOS* lib, CR_GEOS_Slice a, CR_GEOS_String* convexHullEWKB);
+CR_GEOS_Status CR_GEOS_Difference(CR_GEOS* lib, CR_GEOS_Slice a, CR_GEOS_Slice b,
+                                  CR_GEOS_String* diffEWKB);
+CR_GEOS_Status CR_GEOS_Simplify(CR_GEOS* lib, CR_GEOS_Slice a, CR_GEOS_String* simplifyEWKB,
+                                double tolerance);
+CR_GEOS_Status CR_GEOS_TopologyPreserveSimplify(CR_GEOS* lib, CR_GEOS_Slice a,
+                                                CR_GEOS_String* simplifyEWKB, double tolerance);
+CR_GEOS_Status CR_GEOS_UnaryUnion(CR_GEOS* lib, CR_GEOS_Slice a, CR_GEOS_String* unionEWKB);
+CR_GEOS_Status CR_GEOS_Union(CR_GEOS* lib, CR_GEOS_Slice a, CR_GEOS_Slice b,
+                             CR_GEOS_String* unionEWKB);
+CR_GEOS_Status CR_GEOS_PointOnSurface(CR_GEOS* lib, CR_GEOS_Slice a,
+                                      CR_GEOS_String* pointOnSurfaceEWKB);
+CR_GEOS_Status CR_GEOS_Intersection(CR_GEOS* lib, CR_GEOS_Slice a, CR_GEOS_Slice b,
+                                    CR_GEOS_String* intersectionEWKB);
+CR_GEOS_Status CR_GEOS_SymDifference(CR_GEOS* lib, CR_GEOS_Slice a, CR_GEOS_Slice b,
+                                     CR_GEOS_String* symdifferenceEWKB);
+CR_GEOS_Status CR_GEOS_SharedPaths(CR_GEOS* lib, CR_GEOS_Slice a, CR_GEOS_Slice b,
+                                   CR_GEOS_String* ret);
+CR_GEOS_Status CR_GEOS_Node(CR_GEOS* lib, CR_GEOS_Slice a, CR_GEOS_String* ret);
+
+CR_GEOS_Status CR_GEOS_MinimumBoundingCircle(CR_GEOS* lib, CR_GEOS_Slice a, double* radius,
+                                              CR_GEOS_String* centerEWKB, CR_GEOS_String* polygonEWKB);
+
+CR_GEOS_Status CR_GEOS_MinimumRotatedRectangle(CR_GEOS* lib, CR_GEOS_Slice g, CR_GEOS_String* ret);
+//
+// Linear reference.
+//
+CR_GEOS_Status CR_GEOS_Interpolate(CR_GEOS* lib, CR_GEOS_Slice a, double distance,
+                                   CR_GEOS_String* interpolatedPoint);
+
+//
+// Binary operators.
+//
+
+CR_GEOS_Status CR_GEOS_Distance(CR_GEOS* lib, CR_GEOS_Slice a, CR_GEOS_Slice b, double* ret);
+CR_GEOS_Status CR_GEOS_FrechetDistance(CR_GEOS* lib, CR_GEOS_Slice a, CR_GEOS_Slice b, double* ret);
+CR_GEOS_Status CR_GEOS_FrechetDistanceDensify(CR_GEOS* lib, CR_GEOS_Slice a, CR_GEOS_Slice b,
+                                              double densifyFrac, double* ret);
+CR_GEOS_Status CR_GEOS_HausdorffDistance(CR_GEOS* lib, CR_GEOS_Slice a, CR_GEOS_Slice b,
+                                         double* ret);
+CR_GEOS_Status CR_GEOS_HausdorffDistanceDensify(CR_GEOS* lib, CR_GEOS_Slice a, CR_GEOS_Slice b,
+                                                double densifyFrac, double* ret);
+CR_GEOS_Status CR_GEOS_EqualsExact(CR_GEOS* lib, CR_GEOS_Slice lhs, CR_GEOS_Slice rhs,
+                                      double tolerance, char* ret);
+
+//
+// PreparedGeometry
+//
+
+CR_GEOS_Status CR_GEOS_Prepare(CR_GEOS* lib, CR_GEOS_Slice a, CR_GEOS_PreparedGeometry** ret);
+CR_GEOS_Status CR_GEOS_PreparedGeometryDestroy(CR_GEOS* lib, CR_GEOS_PreparedGeometry* g);
+
+CR_GEOS_Status CR_GEOS_PreparedIntersects(CR_GEOS* lib, CR_GEOS_PreparedGeometry* a, CR_GEOS_Slice b, char* ret);
+
+//
+// Binary predicates.
+//
+
+CR_GEOS_Status CR_GEOS_Covers(CR_GEOS* lib, CR_GEOS_Slice a, CR_GEOS_Slice b, char* ret);
+CR_GEOS_Status CR_GEOS_CoveredBy(CR_GEOS* lib, CR_GEOS_Slice a, CR_GEOS_Slice b, char* ret);
+CR_GEOS_Status CR_GEOS_Contains(CR_GEOS* lib, CR_GEOS_Slice a, CR_GEOS_Slice b, char* ret);
+CR_GEOS_Status CR_GEOS_Crosses(CR_GEOS* lib, CR_GEOS_Slice a, CR_GEOS_Slice b, char* ret);
+CR_GEOS_Status CR_GEOS_Disjoint(CR_GEOS* lib, CR_GEOS_Slice a, CR_GEOS_Slice b, char* ret);
+CR_GEOS_Status CR_GEOS_Equals(CR_GEOS* lib, CR_GEOS_Slice a, CR_GEOS_Slice b, char* ret);
+CR_GEOS_Status CR_GEOS_Intersects(CR_GEOS* lib, CR_GEOS_Slice a, CR_GEOS_Slice b, char* ret);
+CR_GEOS_Status CR_GEOS_Overlaps(CR_GEOS* lib, CR_GEOS_Slice a, CR_GEOS_Slice b, char* ret);
+CR_GEOS_Status CR_GEOS_Touches(CR_GEOS* lib, CR_GEOS_Slice a, CR_GEOS_Slice b, char* ret);
+CR_GEOS_Status CR_GEOS_Within(CR_GEOS* lib, CR_GEOS_Slice a, CR_GEOS_Slice b, char* ret);
+
+//
+// DE-9IM related
+//
+
+CR_GEOS_Status CR_GEOS_Relate(CR_GEOS* lib, CR_GEOS_Slice a, CR_GEOS_Slice b, CR_GEOS_String* ret);
+CR_GEOS_Status CR_GEOS_RelateBoundaryNodeRule(CR_GEOS* lib, CR_GEOS_Slice a, CR_GEOS_Slice b,
+                                              int bnr, CR_GEOS_String* ret);
+CR_GEOS_Status CR_GEOS_RelatePattern(CR_GEOS* lib, CR_GEOS_Slice a, CR_GEOS_Slice b,
+                                     CR_GEOS_Slice pattern, char* ret);
+
+CR_GEOS_Status CR_GEOS_VoronoiDiagram(CR_GEOS* lib, CR_GEOS_Slice g, CR_GEOS_Slice env,
+                                      double tolerance, int onlyEdges, CR_GEOS_String* ret);
+
+CR_GEOS_Status CR_GEOS_Snap(CR_GEOS* lib, CR_GEOS_Slice input, CR_GEOS_Slice target, double tolerance, CR_GEOS_String* ret);
+
+#ifdef __cplusplus
+}  // extern "C"
+#endif
diff --git a/pkg/geo/geosegmentize/geosegmentize.go b/pkg/geo/geosegmentize/geosegmentize.go
new file mode 100644
index 0000000..0ee0287
--- /dev/null
+++ b/pkg/geo/geosegmentize/geosegmentize.go
@@ -0,0 +1,148 @@
+// Copyright 2020 The Cockroach Authors.
+//
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
+
+package geosegmentize
+
+import (
+	"math"
+	"strconv"
+	"strings"
+
+	"github.com/cockroachdb/cockroachdb-parser/pkg/geo"
+	"github.com/cockroachdb/cockroachdb-parser/pkg/sql/pgwire/pgcode"
+	"github.com/cockroachdb/cockroachdb-parser/pkg/sql/pgwire/pgerror"
+	"github.com/twpayne/go-geom"
+)
+
+// Segmentize returns a modified geom.T having no segment longer
+// than the given maximum segment length.
+// segmentMaxAngleOrLength represents two different things depending
+// on the object, which is about to segmentize as in case of geography
+// it represents maximum segment angle whereas, in case of geometry it
+// represents maximum segment distance.
+// segmentizeCoords represents the function's definition which allows
+// us to segmentize given two-points. We have to specify segmentizeCoords
+// explicitly, as the algorithm for segmentation is significantly
+// different for geometry and geography.
+func Segmentize(
+	geometry geom.T,
+	segmentMaxAngleOrLength float64,
+	segmentizeCoords func(geom.Coord, geom.Coord, float64) ([]float64, error),
+) (geom.T, error) {
+	if geometry.Empty() {
+		return geometry, nil
+	}
+	layout := geometry.Layout()
+	switch geometry := geometry.(type) {
+	case *geom.Point, *geom.MultiPoint:
+		return geometry, nil
+	case *geom.LineString:
+		var allFlatCoordinates []float64
+		for pointIdx := 1; pointIdx < geometry.NumCoords(); pointIdx++ {
+			coords, err := segmentizeCoords(geometry.Coord(pointIdx-1), geometry.Coord(pointIdx), segmentMaxAngleOrLength)
+			if err != nil {
+				return nil, err
+			}
+			allFlatCoordinates = append(
+				allFlatCoordinates,
+				coords...,
+			)
+		}
+		// Appending end point as it wasn't included in the iteration of coordinates.
+		allFlatCoordinates = append(allFlatCoordinates, geometry.Coord(geometry.NumCoords()-1)...)
+		return geom.NewLineStringFlat(layout, allFlatCoordinates).SetSRID(geometry.SRID()), nil
+	case *geom.MultiLineString:
+		segMultiLine := geom.NewMultiLineString(layout).SetSRID(geometry.SRID())
+		for lineIdx := 0; lineIdx < geometry.NumLineStrings(); lineIdx++ {
+			l, err := Segmentize(geometry.LineString(lineIdx), segmentMaxAngleOrLength, segmentizeCoords)
+			if err != nil {
+				return nil, err
+			}
+			err = segMultiLine.Push(l.(*geom.LineString))
+			if err != nil {
+				return nil, err
+			}
+		}
+		return segMultiLine, nil
+	case *geom.LinearRing:
+		var allFlatCoordinates []float64
+		for pointIdx := 1; pointIdx < geometry.NumCoords(); pointIdx++ {
+			coords, err := segmentizeCoords(geometry.Coord(pointIdx-1), geometry.Coord(pointIdx), segmentMaxAngleOrLength)
+			if err != nil {
+				return nil, err
+			}
+			allFlatCoordinates = append(
+				allFlatCoordinates,
+				coords...,
+			)
+		}
+		// Appending end point as it wasn't included in the iteration of coordinates.
+		allFlatCoordinates = append(allFlatCoordinates, geometry.Coord(geometry.NumCoords()-1)...)
+		return geom.NewLinearRingFlat(layout, allFlatCoordinates).SetSRID(geometry.SRID()), nil
+	case *geom.Polygon:
+		segPolygon := geom.NewPolygon(layout).SetSRID(geometry.SRID())
+		for loopIdx := 0; loopIdx < geometry.NumLinearRings(); loopIdx++ {
+			l, err := Segmentize(geometry.LinearRing(loopIdx), segmentMaxAngleOrLength, segmentizeCoords)
+			if err != nil {
+				return nil, err
+			}
+			err = segPolygon.Push(l.(*geom.LinearRing))
+			if err != nil {
+				return nil, err
+			}
+		}
+		return segPolygon, nil
+	case *geom.MultiPolygon:
+		segMultiPolygon := geom.NewMultiPolygon(layout).SetSRID(geometry.SRID())
+		for polygonIdx := 0; polygonIdx < geometry.NumPolygons(); polygonIdx++ {
+			p, err := Segmentize(geometry.Polygon(polygonIdx), segmentMaxAngleOrLength, segmentizeCoords)
+			if err != nil {
+				return nil, err
+			}
+			err = segMultiPolygon.Push(p.(*geom.Polygon))
+			if err != nil {
+				return nil, err
+			}
+		}
+		return segMultiPolygon, nil
+	case *geom.GeometryCollection:
+		segGeomCollection := geom.NewGeometryCollection().SetSRID(geometry.SRID())
+		err := segGeomCollection.SetLayout(layout)
+		if err != nil {
+			return nil, err
+		}
+		for geoIdx := 0; geoIdx < geometry.NumGeoms(); geoIdx++ {
+			g, err := Segmentize(geometry.Geom(geoIdx), segmentMaxAngleOrLength, segmentizeCoords)
+			if err != nil {
+				return nil, err
+			}
+			err = segGeomCollection.Push(g)
+			if err != nil {
+				return nil, err
+			}
+		}
+		return segGeomCollection, nil
+	}
+	return nil, pgerror.Newf(pgcode.InvalidParameterValue, "unknown type: %T", geometry)
+}
+
+// CheckSegmentizeValidNumPoints checks whether segmentize would break down into
+// too many points or NaN points.
+func CheckSegmentizeValidNumPoints(numPoints float64, a geom.Coord, b geom.Coord) error {
+	if math.IsNaN(numPoints) {
+		return pgerror.Newf(pgcode.InvalidParameterValue, "cannot segmentize into %f points", numPoints)
+	}
+	if numPoints > float64(geo.MaxAllowedSplitPoints) {
+		return pgerror.Newf(
+			pgcode.InvalidParameterValue,
+			"attempting to segmentize into too many coordinates; need %s points between %v and %v, max %d",
+			strings.TrimRight(strconv.FormatFloat(numPoints, 'f', -1, 64), "."),
+			a,
+			b,
+			geo.MaxAllowedSplitPoints,
+		)
+	}
+	return nil
+}
diff --git a/pkg/geo/geotest/geotest.go b/pkg/geo/geotest/geotest.go
new file mode 100644
index 0000000..bddc9e9
--- /dev/null
+++ b/pkg/geo/geotest/geotest.go
@@ -0,0 +1,81 @@
+// Copyright 2022 The Cockroach Authors.
+//
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
+
+package geotest
+
+import (
+	"math"
+	"testing"
+
+	"github.com/cockroachdb/cockroachdb-parser/pkg/geo"
+	"github.com/cockroachdb/errors"
+	"github.com/stretchr/testify/require"
+	"github.com/twpayne/go-geom"
+)
+
+// Epsilon is the default epsilon to use in spatial tests.
+// This corresponds to ~1cm in lat/lng.
+const Epsilon = 0.000001
+
+// RequireGeographyInEpsilon and ensures the geometry shape and SRID are equal,
+// and that each coordinate is within the provided epsilon.
+func RequireGeographyInEpsilon(t *testing.T, expected, got geo.Geography, epsilon float64) {
+	expectedT, err := expected.AsGeomT()
+	require.NoError(t, err)
+	gotT, err := got.AsGeomT()
+	require.NoError(t, err)
+	RequireGeomTInEpsilon(t, expectedT, gotT, epsilon)
+}
+
+// RequireGeometryInEpsilon and ensures the geometry shape and SRID are equal,
+// and that each coordinate is within the provided epsilon.
+func RequireGeometryInEpsilon(t *testing.T, expected, got geo.Geometry, epsilon float64) {
+	expectedT, err := expected.AsGeomT()
+	require.NoError(t, err)
+	gotT, err := got.AsGeomT()
+	require.NoError(t, err)
+	RequireGeomTInEpsilon(t, expectedT, gotT, epsilon)
+}
+
+// FlatCoordsInEpsilon ensures the flat coords are within the expected epsilon.
+func FlatCoordsInEpsilon(t *testing.T, expected []float64, actual []float64, epsilon float64) {
+	require.Equal(t, len(expected), len(actual), "expected %#v, got %#v", expected, actual)
+	for i := range expected {
+		require.True(t, math.Abs(expected[i]-actual[i]) < epsilon, "expected %#v, got %#v (mismatching at position %d)", expected, actual, i)
+	}
+}
+
+// RequireGeomTInEpsilon ensures that the geom.T are equal, except for
+// coords which should be within the given epsilon.
+func RequireGeomTInEpsilon(t *testing.T, expectedT, gotT geom.T, epsilon float64) {
+	require.Equal(t, expectedT.SRID(), gotT.SRID())
+	require.Equal(t, expectedT.Layout(), gotT.Layout())
+	require.IsType(t, expectedT, gotT)
+	switch lhs := expectedT.(type) {
+	case *geom.Point, *geom.LineString:
+		FlatCoordsInEpsilon(t, expectedT.FlatCoords(), gotT.FlatCoords(), epsilon)
+	case *geom.MultiPoint, *geom.Polygon, *geom.MultiLineString:
+		require.Equal(t, expectedT.Ends(), gotT.Ends())
+		FlatCoordsInEpsilon(t, expectedT.FlatCoords(), gotT.FlatCoords(), epsilon)
+	case *geom.MultiPolygon:
+		require.Equal(t, expectedT.Ends(), gotT.Ends())
+		require.Equal(t, expectedT.Endss(), gotT.Endss())
+		FlatCoordsInEpsilon(t, expectedT.FlatCoords(), gotT.FlatCoords(), epsilon)
+	case *geom.GeometryCollection:
+		rhs, ok := gotT.(*geom.GeometryCollection)
+		require.True(t, ok)
+		require.Len(t, rhs.Geoms(), len(lhs.Geoms()))
+		for i := range lhs.Geoms() {
+			RequireGeomTInEpsilon(
+				t,
+				lhs.Geom(i),
+				rhs.Geom(i),
+				epsilon,
+			)
+		}
+	default:
+		panic(errors.AssertionFailedf("unknown geometry type: %T", expectedT))
+	}
+}
diff --git a/pkg/geo/geotransform/geotransform.go b/pkg/geo/geotransform/geotransform.go
new file mode 100644
index 0000000..3a7d819
--- /dev/null
+++ b/pkg/geo/geotransform/geotransform.go
@@ -0,0 +1,136 @@
+// Copyright 2020 The Cockroach Authors.
+//
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
+
+package geotransform
+
+import (
+	"github.com/cockroachdb/cockroachdb-parser/pkg/geo"
+	"github.com/cockroachdb/cockroachdb-parser/pkg/geo/geopb"
+	"github.com/cockroachdb/cockroachdb-parser/pkg/geo/geoproj"
+	"github.com/cockroachdb/cockroachdb-parser/pkg/geo/geoprojbase"
+	"github.com/cockroachdb/cockroachdb-parser/pkg/sql/pgwire/pgcode"
+	"github.com/cockroachdb/cockroachdb-parser/pkg/sql/pgwire/pgerror"
+	"github.com/twpayne/go-geom"
+)
+
+// Transform projects a given Geometry from a given Proj4Text to another Proj4Text.
+func Transform(
+	g geo.Geometry, from geoprojbase.Proj4Text, to geoprojbase.Proj4Text, newSRID geopb.SRID,
+) (geo.Geometry, error) {
+	if from.Equal(to) {
+		return g.CloneWithSRID(newSRID)
+	}
+
+	t, err := g.AsGeomT()
+	if err != nil {
+		return geo.Geometry{}, err
+	}
+
+	newT, err := transform(t, from, to, newSRID)
+	if err != nil {
+		return geo.Geometry{}, err
+	}
+	return geo.MakeGeometryFromGeomT(newT)
+}
+
+// transform performs the projection operation on a geom.T object.
+func transform(
+	t geom.T, from geoprojbase.Proj4Text, to geoprojbase.Proj4Text, newSRID geopb.SRID,
+) (geom.T, error) {
+	switch t := t.(type) {
+	case *geom.Point:
+		newCoords, err := projectFlatCoords(t.FlatCoords(), t.Layout(), from, to)
+		if err != nil {
+			return nil, err
+		}
+		return geom.NewPointFlat(t.Layout(), newCoords).SetSRID(int(newSRID)), nil
+	case *geom.LineString:
+		newCoords, err := projectFlatCoords(t.FlatCoords(), t.Layout(), from, to)
+		if err != nil {
+			return nil, err
+		}
+		return geom.NewLineStringFlat(t.Layout(), newCoords).SetSRID(int(newSRID)), nil
+	case *geom.Polygon:
+		newCoords, err := projectFlatCoords(t.FlatCoords(), t.Layout(), from, to)
+		if err != nil {
+			return nil, err
+		}
+		return geom.NewPolygonFlat(t.Layout(), newCoords, t.Ends()).SetSRID(int(newSRID)), nil
+	case *geom.MultiPoint:
+		newCoords, err := projectFlatCoords(t.FlatCoords(), t.Layout(), from, to)
+		if err != nil {
+			return nil, err
+		}
+		return geom.NewMultiPointFlat(t.Layout(), newCoords).SetSRID(int(newSRID)), nil
+	case *geom.MultiLineString:
+		newCoords, err := projectFlatCoords(t.FlatCoords(), t.Layout(), from, to)
+		if err != nil {
+			return nil, err
+		}
+		return geom.NewMultiLineStringFlat(t.Layout(), newCoords, t.Ends()).SetSRID(int(newSRID)), nil
+	case *geom.MultiPolygon:
+		newCoords, err := projectFlatCoords(t.FlatCoords(), t.Layout(), from, to)
+		if err != nil {
+			return nil, err
+		}
+		return geom.NewMultiPolygonFlat(t.Layout(), newCoords, t.Endss()).SetSRID(int(newSRID)), nil
+	case *geom.GeometryCollection:
+		g := geom.NewGeometryCollection().SetSRID(int(newSRID))
+		for _, subG := range t.Geoms() {
+			subGeom, err := transform(subG, from, to, 0)
+			if err != nil {
+				return nil, err
+			}
+			if err := g.Push(subGeom); err != nil {
+				return nil, err
+			}
+		}
+		return g, nil
+	default:
+		return nil, pgerror.Newf(pgcode.InvalidParameterValue, "unhandled type: %T", t)
+	}
+}
+
+// projectFlatCoords projects a given flatCoords array and returns an array with the projected
+// coordinates.
+// Note M coordinates are not touched.
+func projectFlatCoords(
+	flatCoords []float64, layout geom.Layout, from geoprojbase.Proj4Text, to geoprojbase.Proj4Text,
+) ([]float64, error) {
+	numCoords := len(flatCoords) / layout.Stride()
+	// Allocate the map once and partition the arrays to store xCoords, yCoords and zCoords in order.
+	coords := make([]float64, numCoords*3)
+	xCoords := coords[numCoords*0 : numCoords*1]
+	yCoords := coords[numCoords*1 : numCoords*2]
+	zCoords := coords[numCoords*2 : numCoords*3]
+	for i := 0; i < numCoords; i++ {
+		base := i * layout.Stride()
+		xCoords[i] = flatCoords[base+0]
+		yCoords[i] = flatCoords[base+1]
+		// If ZIndex is != -1, it is 2 and forms part of our z coords.
+		if layout.ZIndex() != -1 {
+			zCoords[i] = flatCoords[base+layout.ZIndex()]
+		}
+	}
+
+	if err := geoproj.Project(from, to, xCoords, yCoords, zCoords); err != nil {
+		return nil, err
+	}
+	newCoords := make([]float64, numCoords*layout.Stride())
+	for i := 0; i < numCoords; i++ {
+		base := i * layout.Stride()
+		newCoords[base+0] = xCoords[i]
+		newCoords[base+1] = yCoords[i]
+
+		if layout.ZIndex() != -1 {
+			newCoords[base+layout.ZIndex()] = zCoords[i]
+		}
+		if layout.MIndex() != -1 {
+			newCoords[base+layout.MIndex()] = flatCoords[i*layout.Stride()+layout.MIndex()]
+		}
+	}
+
+	return newCoords, nil
+}
diff --git a/pkg/geo/hilbert.go b/pkg/geo/hilbert.go
index 1c4d015..1cf8f32d 100644
--- a/pkg/geo/hilbert.go
+++ b/pkg/geo/hilbert.go
@@ -1,12 +1,7 @@
 // Copyright 2020 The Cockroach Authors.
 //
-// Use of this software is governed by the Business Source License
-// included in the file licenses/BSL.txt.
-//
-// As of the Change Date specified in that file, in accordance with
-// the Business Source License, use of this software will be governed
-// by the Apache License, Version 2.0, included in the file
-// licenses/APL.txt.
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
 
 package geo
 
diff --git a/pkg/geo/iterator.go b/pkg/geo/iterator.go
index 65a06db..37411cb 100644
--- a/pkg/geo/iterator.go
+++ b/pkg/geo/iterator.go
@@ -1,12 +1,7 @@
 // Copyright 2020 The Cockroach Authors.
 //
-// Use of this software is governed by the Business Source License
-// included in the file licenses/BSL.txt.
-//
-// As of the Change Date specified in that file, in accordance with
-// the Business Source License, use of this software will be governed
-// by the Apache License, Version 2.0, included in the file
-// licenses/APL.txt.
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
 
 package geo
 
diff --git a/pkg/geo/latlng.go b/pkg/geo/latlng.go
index d71e0d8..5ac4d22 100644
--- a/pkg/geo/latlng.go
+++ b/pkg/geo/latlng.go
@@ -1,12 +1,7 @@
 // Copyright 2020 The Cockroach Authors.
 //
-// Use of this software is governed by the Business Source License
-// included in the file licenses/BSL.txt.
-//
-// As of the Change Date specified in that file, in accordance with
-// the Business Source License, use of this software will be governed
-// by the Apache License, Version 2.0, included in the file
-// licenses/APL.txt.
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
 
 package geo
 
diff --git a/pkg/geo/parse.go b/pkg/geo/parse.go
index 041ff44..66105d0 100644
--- a/pkg/geo/parse.go
+++ b/pkg/geo/parse.go
@@ -1,12 +1,7 @@
 // Copyright 2020 The Cockroach Authors.
 //
-// Use of this software is governed by the Business Source License
-// included in the file licenses/BSL.txt.
-//
-// As of the Change Date specified in that file, in accordance with
-// the Business Source License, use of this software will be governed
-// by the Apache License, Version 2.0, included in the file
-// licenses/APL.txt.
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
 
 package geo
 
diff --git a/pkg/geo/polyline.go b/pkg/geo/polyline.go
index c5bd243..212c1c9 100644
--- a/pkg/geo/polyline.go
+++ b/pkg/geo/polyline.go
@@ -1,12 +1,7 @@
 // Copyright 2020 The Cockroach Authors.
 //
-// Use of this software is governed by the Business Source License
-// included in the file licenses/BSL.txt.
-//
-// As of the Change Date specified in that file, in accordance with
-// the Business Source License, use of this software will be governed
-// by the Apache License, Version 2.0, included in the file
-// licenses/APL.txt.
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
 
 package geo
 
diff --git a/pkg/geo/summary.go b/pkg/geo/summary.go
index 5265b7b..e0c234d 100644
--- a/pkg/geo/summary.go
+++ b/pkg/geo/summary.go
@@ -1,12 +1,7 @@
 // Copyright 2020 The Cockroach Authors.
 //
-// Use of this software is governed by the Business Source License
-// included in the file licenses/BSL.txt.
-//
-// As of the Change Date specified in that file, in accordance with
-// the Business Source License, use of this software will be governed
-// by the Apache License, Version 2.0, included in the file
-// licenses/APL.txt.
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
 
 package geo
 
diff --git a/pkg/geo/twkb/twkb.go b/pkg/geo/twkb/twkb.go
new file mode 100644
index 0000000..de2861a
--- /dev/null
+++ b/pkg/geo/twkb/twkb.go
@@ -0,0 +1,359 @@
+// Copyright 2021 The Cockroach Authors.
+//
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
+
+// Package twkb implements the Tiny Well-known Binary (TWKB) encoding
+// as described in https://github.com/TWKB/Specification/blob/master/twkb.md.
+package twkb
+
+import (
+	"bytes"
+	"math"
+
+	"github.com/cockroachdb/cockroachdb-parser/pkg/sql/pgwire/pgcode"
+	"github.com/cockroachdb/cockroachdb-parser/pkg/sql/pgwire/pgerror"
+	"github.com/twpayne/go-geom"
+)
+
+// twkbType is represents a TWKB byte.
+type twkbType uint8
+
+const (
+	twkbTypePoint              twkbType = 1
+	twkbTypeLineString         twkbType = 2
+	twkbTypePolygon            twkbType = 3
+	twkbTypeMultiPoint         twkbType = 4
+	twkbTypeMultiLineString    twkbType = 5
+	twkbTypeMultiPolygon       twkbType = 6
+	twkbTypeGeometryCollection twkbType = 7
+)
+
+type marshalOptions struct {
+	precisionXY int8
+	precisionZ  int8
+	precisionM  int8
+}
+
+type marshaller struct {
+	bytes.Buffer
+	o marshalOptions
+	// prevCoords keeps track of the previously written coordinates.
+	// This is needed as for Polygons, MultiLineString and MultiPolygons, the
+	// deltas written can be based off the previous ring/linestring/polygon.
+	prevCoords []int64
+}
+
+// MarshalOption is an option to pass into Marshal.
+type MarshalOption func(o *marshalOptions) error
+
+// MarshalOptionPrecisionXY sets the XY precision for the TWKB.
+func MarshalOptionPrecisionXY(p int64) MarshalOption {
+	return func(o *marshalOptions) error {
+		if p < -7 || p > 7 {
+			return pgerror.Newf(
+				pgcode.InvalidParameterValue,
+				"XY precision must be between -7 and 7 inclusive",
+			)
+		}
+		o.precisionXY = int8(p)
+		return nil
+	}
+}
+
+// MarshalOptionPrecisionZ sets the Z precision for the TWKB.
+func MarshalOptionPrecisionZ(p int64) MarshalOption {
+	return func(o *marshalOptions) error {
+		if p < 0 || p > 7 {
+			return pgerror.Newf(
+				pgcode.InvalidParameterValue,
+				"Z precision must not be negative or greater than 7",
+			)
+		}
+
+		o.precisionZ = int8(p)
+		return nil
+	}
+}
+
+// MarshalOptionPrecisionM sets the M precision for the TWKB.
+func MarshalOptionPrecisionM(p int64) MarshalOption {
+	return func(o *marshalOptions) error {
+		if p < 0 || p > 7 {
+			return pgerror.Newf(
+				pgcode.InvalidParameterValue,
+				"M precision must not be negative or greater than 7",
+			)
+		}
+
+		o.precisionM = int8(p)
+		return nil
+	}
+}
+
+// Marshal converts a geom.T into a TWKB encoded byte array.
+func Marshal(t geom.T, opts ...MarshalOption) ([]byte, error) {
+	var o marshalOptions
+	for _, opt := range opts {
+		if err := opt(&o); err != nil {
+			return nil, err
+		}
+	}
+	// TODO(#48886): PostGIS increases the precision by 5
+	// for all lat/lng SRIDs in certain cases.
+	m := marshaller{
+		o:          o,
+		prevCoords: make([]int64, t.Layout().Stride()),
+	}
+	if err := (&m).marshal(t); err != nil {
+		return nil, err
+	}
+	return m.Bytes(), nil
+}
+
+func (m *marshaller) marshal(t geom.T) error {
+	// Write metadata byte.
+	typeAndPrecisionHeader, err := typeAndPrecisionHeaderByte(t, m.o)
+	if err != nil {
+		return err
+	}
+	if err := m.WriteByte(typeAndPrecisionHeader); err != nil {
+		return err
+	}
+	if err := m.WriteByte(metadataByte(t, m.o)); err != nil {
+		return err
+	}
+	if t.Layout().Stride() > 2 {
+		if err := m.WriteByte(extendedDimensionsByte(t, m.o)); err != nil {
+			return err
+		}
+	}
+	if !t.Empty() {
+		// TODO(#48886): write bounding box if we support writing bounding boxes.
+		switch t := t.(type) {
+		case *geom.Point:
+			if err := m.writeFlatCoords(
+				t.FlatCoords(),
+				t.Layout(),
+				false, /* writeLen */
+			); err != nil {
+				return err
+			}
+		case *geom.LineString:
+			if err := m.writeFlatCoords(
+				t.FlatCoords(),
+				t.Layout(),
+				true, /* writeLen */
+			); err != nil {
+				return err
+			}
+		case *geom.Polygon:
+			if err := m.writeGeomWithEnds(
+				t.FlatCoords(),
+				t.Ends(),
+				t.Layout(),
+				0, /* startOffset */
+			); err != nil {
+				return err
+			}
+		case *geom.MultiPoint:
+			// TODO(#48886): write out the id list for MultiPoint.
+			if err := m.writeFlatCoords(
+				t.FlatCoords(),
+				t.Layout(),
+				true, /* writeLen */
+			); err != nil {
+				return err
+			}
+		case *geom.MultiLineString:
+			// TODO(#48886): write out the id list for MultiLineString.
+			if err := m.writeGeomWithEnds(
+				t.FlatCoords(),
+				t.Ends(),
+				t.Layout(),
+				0, /* startOffset */
+			); err != nil {
+				return err
+			}
+		case *geom.MultiPolygon:
+			// TODO(#48886): write out the id list for MultiPolygon.
+			flatCoords := t.FlatCoords()
+			endss := t.Endss()
+			// Write the number of MultiPolygons.
+			if err := m.putUvarint(uint64(len(endss))); err != nil {
+				return err
+			}
+			startOffset := 0
+			for _, ends := range endss {
+				// Write out each polygon.
+				if err := m.writeGeomWithEnds(
+					flatCoords,
+					ends,
+					t.Layout(),
+					startOffset,
+				); err != nil {
+					return err
+				}
+				// Update the start offset to be the last end we encountered.
+				if len(ends) > 0 {
+					startOffset = ends[len(ends)-1]
+				}
+			}
+		case *geom.GeometryCollection:
+			// Write the number of geometries.
+			if err := m.putUvarint(uint64(t.NumGeoms())); err != nil {
+				return err
+			}
+			for _, gcT := range t.Geoms() {
+				// Reset prev coords each time.
+				for i := range m.prevCoords {
+					m.prevCoords[i] = 0
+				}
+				if err := m.marshal(gcT); err != nil {
+					return err
+				}
+			}
+		default:
+			return pgerror.Newf(pgcode.InvalidParameterValue, "unknown TWKB type: %T", t)
+		}
+	}
+	return nil
+}
+
+func (m *marshaller) writeGeomWithEnds(
+	flatCoords []float64, ends []int, layout geom.Layout, startOffset int,
+) error {
+	// Write the number of elements.
+	if err := m.putUvarint(uint64(len(ends))); err != nil {
+		return err
+	}
+	start := startOffset
+	// Write each segment with the length of each ring at the beginning.
+	for _, end := range ends {
+		if err := m.writeFlatCoords(
+			flatCoords[start:end],
+			layout,
+			true, /* writeLen */
+		); err != nil {
+			return err
+		}
+		start = end
+	}
+	return nil
+}
+
+// writeFlatCoords writes the flat coordinates into the buffer.
+func (m *marshaller) writeFlatCoords(
+	flatCoords []float64, layout geom.Layout, writeLen bool,
+) error {
+	stride := layout.Stride()
+	if writeLen {
+		if err := m.putUvarint(uint64(len(flatCoords) / stride)); err != nil {
+			return err
+		}
+	}
+
+	zIndex := layout.ZIndex()
+	mIndex := layout.MIndex()
+	for i, coord := range flatCoords {
+		// Precision varies by coordinate.
+		precision := m.o.precisionXY
+		if i%stride == zIndex {
+			precision = m.o.precisionZ
+		}
+		if i%stride == mIndex {
+			precision = m.o.precisionM
+		}
+		curr := int64(math.Round(coord * math.Pow(10, float64(precision))))
+		prev := m.prevCoords[i%stride]
+
+		// The value written is the int version of the delta multiplied
+		// by 10^precision.
+		if err := m.putVarint(curr - prev); err != nil {
+			return err
+		}
+		m.prevCoords[i%stride] = curr
+	}
+	return nil
+}
+
+// putVarint encodes an int64 into buf and returns the number of bytes written.
+func (m *marshaller) putVarint(x int64) error {
+	ux := uint64(x) << 1
+	if x < 0 {
+		ux = ^ux
+	}
+	return m.putUvarint(ux)
+}
+
+// putUvarint encodes a uint64 into buf and returns the number of bytes written.
+func (m *marshaller) putUvarint(x uint64) error {
+	for x >= 0x80 {
+		if err := m.WriteByte(byte(x) | 0x80); err != nil {
+			return err
+		}
+		x >>= 7
+	}
+	return m.WriteByte(byte(x))
+}
+
+func typeAndPrecisionHeaderByte(t geom.T, o marshalOptions) (byte, error) {
+	var typ twkbType
+	switch t.(type) {
+	case *geom.Point:
+		typ = twkbTypePoint
+	case *geom.LineString:
+		typ = twkbTypeLineString
+	case *geom.Polygon:
+		typ = twkbTypePolygon
+	case *geom.MultiPoint:
+		typ = twkbTypeMultiPoint
+	case *geom.MultiLineString:
+		typ = twkbTypeMultiLineString
+	case *geom.MultiPolygon:
+		typ = twkbTypeMultiPolygon
+	case *geom.GeometryCollection:
+		typ = twkbTypeGeometryCollection
+	default:
+		return 0, pgerror.Newf(pgcode.InvalidParameterValue, "unknown TWKB type: %T", t)
+	}
+
+	precisionZigZagged := zigzagInt8(o.precisionXY)
+	return (uint8(typ) & 0x0F) | ((precisionZigZagged & 0x0F) << 4), nil
+}
+
+func metadataByte(t geom.T, o marshalOptions) byte {
+	var b byte
+	if t.Empty() {
+		b |= 0b10000
+	}
+	if t.Layout().Stride() > 2 {
+		b |= 0b1000
+	}
+	return b
+}
+
+func extendedDimensionsByte(t geom.T, o marshalOptions) byte {
+	var extDimByte byte
+	// Follow PostGIS and do no bounds checking for precision under/overflow.
+	switch t.Layout() {
+	case geom.XYZ:
+		extDimByte |= 0b1
+		extDimByte |= (byte(o.precisionZ) & 0b111) << 2
+	case geom.XYM:
+		extDimByte |= 0b10
+		extDimByte |= (byte(o.precisionM) & 0b111) << 5
+	case geom.XYZM:
+		extDimByte |= 0b11
+		extDimByte |= (byte(o.precisionZ) & 0b111) << 2
+		extDimByte |= (byte(o.precisionM) & 0b111) << 5
+	}
+	return extDimByte
+}
+
+func zigzagInt8(x int8) byte {
+	if x < 0 {
+		return (uint8(-1-x) << 1) | 0x01
+	}
+	return uint8(x) << 1
+}
diff --git a/pkg/keysbase/data.go b/pkg/keysbase/data.go
index f7f2de9..dc5fa7e 100644
--- a/pkg/keysbase/data.go
+++ b/pkg/keysbase/data.go
@@ -1,12 +1,7 @@
 // Copyright 2022 The Cockroach Authors.
 //
-// Use of this software is governed by the Business Source License
-// included in the file licenses/BSL.txt.
-//
-// As of the Change Date specified in that file, in accordance with
-// the Business Source License, use of this software will be governed
-// by the Apache License, Version 2.0, included in the file
-// licenses/APL.txt.
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
 
 package keysbase
 
diff --git a/pkg/kv/kvserver/concurrency/isolation/levels.go b/pkg/kv/kvserver/concurrency/isolation/levels.go
index 8c43c28..d563890 100644
--- a/pkg/kv/kvserver/concurrency/isolation/levels.go
+++ b/pkg/kv/kvserver/concurrency/isolation/levels.go
@@ -1,12 +1,7 @@
 // Copyright 2023 The Cockroach Authors.
 //
-// Use of this software is governed by the Business Source License
-// included in the file licenses/BSL.txt.
-//
-// As of the Change Date specified in that file, in accordance with
-// the Business Source License, use of this software will be governed
-// by the Apache License, Version 2.0, included in the file
-// licenses/APL.txt.
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
 
 // Package isolation provides type definitions for isolation level-related
 // concepts used by concurrency control in the key-value layer.
diff --git a/pkg/kv/kvserver/concurrency/isolation/levels.proto b/pkg/kv/kvserver/concurrency/isolation/levels.proto
index cfc6eb7..a6e49cc 100644
--- a/pkg/kv/kvserver/concurrency/isolation/levels.proto
+++ b/pkg/kv/kvserver/concurrency/isolation/levels.proto
@@ -1,12 +1,7 @@
 // Copyright 2023 The Cockroach Authors.
 //
-// Use of this software is governed by the Business Source License
-// included in the file licenses/BSL.txt.
-//
-// As of the Change Date specified in that file, in accordance with
-// the Business Source License, use of this software will be governed
-// by the Apache License, Version 2.0, included in the file
-// licenses/APL.txt.
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
 
 syntax = "proto3";
 package cockroach.kv.kvserver.concurrency.isolation;
diff --git a/pkg/security/username/username.go b/pkg/security/username/username.go
index 8584296..0edcdba 100644
--- a/pkg/security/username/username.go
+++ b/pkg/security/username/username.go
@@ -1,12 +1,7 @@
 // Copyright 2020 The Cockroach Authors.
 //
-// Use of this software is governed by the Business Source License
-// included in the file licenses/BSL.txt.
-//
-// As of the Change Date specified in that file, in accordance with
-// the Business Source License, use of this software will be governed
-// by the Apache License, Version 2.0, included in the file
-// licenses/APL.txt.
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
 
 package username
 
diff --git a/pkg/settings/bool.go b/pkg/settings/bool.go
new file mode 100644
index 0000000..83ab3fd
--- /dev/null
+++ b/pkg/settings/bool.go
@@ -0,0 +1,160 @@
+// Copyright 2017 The Cockroach Authors.
+//
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
+
+package settings
+
+import (
+	"context"
+	"strconv"
+
+	"github.com/cockroachdb/errors"
+)
+
+// BoolSetting is the interface of a setting variable that will be
+// updated automatically when the corresponding cluster-wide setting
+// of type "bool" is updated.
+type BoolSetting struct {
+	common
+	defaultValue bool
+	validateFn   func(*Values, bool) error
+}
+
+var _ internalSetting = &BoolSetting{}
+
+// Get retrieves the bool value in the setting.
+func (b *BoolSetting) Get(sv *Values) bool {
+	return sv.getInt64(b.slot) != 0
+}
+
+func (b *BoolSetting) String(sv *Values) string {
+	return EncodeBool(b.Get(sv))
+}
+
+// DefaultString returns the default value for the setting as a string.
+func (b *BoolSetting) DefaultString() string {
+	return EncodeBool(b.defaultValue)
+}
+
+// Encoded returns the encoded value of the current value of the setting.
+func (b *BoolSetting) Encoded(sv *Values) string {
+	return b.String(sv)
+}
+
+// EncodedDefault returns the encoded value of the default value of the setting.
+func (b *BoolSetting) EncodedDefault() string {
+	return EncodeBool(b.defaultValue)
+}
+
+// DecodeToString decodes and renders an encoded value.
+func (b *BoolSetting) DecodeToString(encoded string) (string, error) {
+	bv, err := b.DecodeValue(encoded)
+	if err != nil {
+		return "", err
+	}
+	return EncodeBool(bv), nil
+}
+
+// DecodeValue decodes the value into a float.
+func (b *BoolSetting) DecodeValue(encoded string) (bool, error) {
+	return strconv.ParseBool(encoded)
+}
+
+// Typ returns the short (1 char) string denoting the type of setting.
+func (*BoolSetting) Typ() string {
+	return "b"
+}
+
+// Default returns default value for setting.
+func (b *BoolSetting) Default() bool {
+	return b.defaultValue
+}
+
+// Defeat the linter.
+var _ = (*BoolSetting).Default
+
+// Override changes the setting without validation and also overrides the
+// default value.
+//
+// For testing usage only.
+func (b *BoolSetting) Override(ctx context.Context, sv *Values, v bool) {
+	sv.setValueOrigin(ctx, b.slot, OriginOverride)
+	b.set(ctx, sv, v)
+	sv.setDefaultOverride(b.slot, v)
+}
+
+// Validate that a value conforms with the validation function.
+func (b *BoolSetting) Validate(sv *Values, v bool) error {
+	if b.validateFn != nil {
+		if err := b.validateFn(sv, v); err != nil {
+			return err
+		}
+	}
+	return nil
+}
+
+func (b *BoolSetting) set(ctx context.Context, sv *Values, v bool) {
+	vInt := int64(0)
+	if v {
+		vInt = 1
+	}
+	sv.setInt64(ctx, b.slot, vInt)
+}
+
+func (b *BoolSetting) decodeAndSet(ctx context.Context, sv *Values, encoded string) error {
+	v, err := strconv.ParseBool(encoded)
+	if err := b.Validate(sv, v); err != nil {
+		return err
+	}
+	if err != nil {
+		return err
+	}
+	b.set(ctx, sv, v)
+	return nil
+}
+
+func (b *BoolSetting) decodeAndSetDefaultOverride(
+	ctx context.Context, sv *Values, encoded string,
+) error {
+	v, err := strconv.ParseBool(encoded)
+	if err != nil {
+		return err
+	}
+	sv.setDefaultOverride(b.slot, v)
+	return nil
+}
+
+func (b *BoolSetting) setToDefault(ctx context.Context, sv *Values) {
+	// See if the default value was overridden.
+	if val := sv.getDefaultOverride(b.slot); val != nil {
+		b.set(ctx, sv, val.(bool))
+		return
+	}
+	b.set(ctx, sv, b.defaultValue)
+}
+
+// RegisterBoolSetting defines a new setting with type bool.
+func RegisterBoolSetting(
+	class Class, key InternalKey, desc string, defaultValue bool, opts ...SettingOption,
+) *BoolSetting {
+	validateFn := func(sv *Values, val bool) error {
+		for _, opt := range opts {
+			switch {
+			case opt.commonOpt != nil:
+				continue
+			case opt.validateBoolFn != nil:
+			default:
+				panic(errors.AssertionFailedf("wrong validator type"))
+			}
+			if err := opt.validateBoolFn(sv, val); err != nil {
+				return err
+			}
+		}
+		return nil
+	}
+	setting := &BoolSetting{defaultValue: defaultValue, validateFn: validateFn}
+	register(class, key, desc, setting)
+	setting.apply(opts)
+	return setting
+}
diff --git a/pkg/settings/byte_size.go b/pkg/settings/byte_size.go
new file mode 100644
index 0000000..093e6e3
--- /dev/null
+++ b/pkg/settings/byte_size.go
@@ -0,0 +1,94 @@
+// Copyright 2017 The Cockroach Authors.
+//
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
+
+package settings
+
+import (
+	"github.com/cockroachdb/cockroachdb-parser/pkg/util/humanizeutil"
+	"github.com/cockroachdb/errors"
+)
+
+// ByteSizeSetting is the interface of a setting variable that will be
+// updated automatically when the corresponding cluster-wide setting
+// of type "bytesize" is updated.
+type ByteSizeSetting struct {
+	IntSetting
+}
+
+var _ internalSetting = &ByteSizeSetting{}
+
+// Typ returns the short (1 char) string denoting the type of setting.
+func (*ByteSizeSetting) Typ() string {
+	return "z"
+}
+
+func (b *ByteSizeSetting) String(sv *Values) string {
+	return string(humanizeutil.IBytes(b.Get(sv)))
+}
+
+// DefaultString returns the default value for the setting as a string.
+func (b *ByteSizeSetting) DefaultString() string {
+	return string(humanizeutil.IBytes(b.defaultValue))
+}
+
+// DecodeToString decodes and renders an encoded value.
+func (b *ByteSizeSetting) DecodeToString(encoded string) (string, error) {
+	iv, err := b.DecodeNumericValue(encoded)
+	if err != nil {
+		return "", err
+	}
+	return string(humanizeutil.IBytes(iv)), nil
+}
+
+// RegisterByteSizeSetting defines a new setting with type bytesize and any
+// supplied validation function(s). If no validation functions are given, then
+// the non-negative int validation is performed.
+func RegisterByteSizeSetting(
+	class Class, key InternalKey, desc string, defaultValue int64, opts ...SettingOption,
+) *ByteSizeSetting {
+	validateFn := func(v int64) error {
+		hasExplicitValidationFn := false
+		for _, opt := range opts {
+			switch {
+			case opt.commonOpt != nil:
+				continue
+			case opt.validateInt64Fn != nil:
+			default:
+				panic(errors.AssertionFailedf("wrong validator type"))
+			}
+			hasExplicitValidationFn = true
+			if err := opt.validateInt64Fn(v); err != nil {
+				return errors.Wrapf(err, "invalid value for %s", key)
+			}
+		}
+		if !hasExplicitValidationFn {
+			// Default validation.
+			return nonNegativeIntInternal(v)
+		}
+		return nil
+	}
+
+	if err := validateFn(defaultValue); err != nil {
+		panic(errors.Wrap(err, "invalid default"))
+	}
+	setting := &ByteSizeSetting{IntSetting{
+		defaultValue: defaultValue,
+		validateFn:   validateFn,
+	}}
+	register(class, key, desc, setting)
+	setting.apply(opts)
+	return setting
+}
+
+// ByteSizeWithMinimum can be passed to RegisterByteSizeSetting.
+func ByteSizeWithMinimum(minVal int64) SettingOption {
+	return WithValidateInt(func(v int64) error {
+		if v < minVal {
+			return errors.Errorf("cannot be set to a value lower than %v",
+				humanizeutil.IBytes(minVal))
+		}
+		return nil
+	})
+}
diff --git a/pkg/settings/common.go b/pkg/settings/common.go
new file mode 100644
index 0000000..52343a6
--- /dev/null
+++ b/pkg/settings/common.go
@@ -0,0 +1,193 @@
+// Copyright 2021 The Cockroach Authors.
+//
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
+
+package settings
+
+import (
+	"context"
+	"fmt"
+
+	"github.com/cockroachdb/errors"
+)
+
+// common implements basic functionality used by all setting types.
+type common struct {
+	class         Class
+	key           InternalKey
+	name          SettingName
+	description   string
+	visibility    Visibility
+	unsafe        bool
+	slot          slotIdx
+	nonReportable bool
+	retired       bool
+	sensitive     bool
+}
+
+// slotIdx is an integer in the range [0, MaxSetting) which is uniquely
+// associated with a registered setting. Slot indexes are used as "handles" for
+// manipulating the setting values. They are generated sequentially, in the
+// order of registration.
+type slotIdx int32
+
+// init must be called to initialize the fields that don't have defaults.
+func (c *common) init(class Class, key InternalKey, description string, slot slotIdx) {
+	c.class = class
+	c.key = key
+	c.name = SettingName(key) // until overridden
+	c.description = description
+	if slot < 0 {
+		panic(fmt.Sprintf("Invalid slot index %d", slot))
+	}
+	if slot >= MaxSettings {
+		panic("too many settings; increase MaxSettings")
+	}
+	c.slot = slot
+}
+
+func (c common) Class() Class {
+	return c.class
+}
+
+func (c common) InternalKey() InternalKey {
+	return c.key
+}
+
+func (c common) Name() SettingName {
+	return c.name
+}
+
+func (c common) Description() string {
+	return c.description
+}
+
+func (c common) Visibility() Visibility {
+	return c.visibility
+}
+
+func (c common) isReportable() bool {
+	return !c.nonReportable
+}
+
+func (c *common) isRetired() bool {
+	return c.retired
+}
+
+func (c *common) isSensitive() bool {
+	return c.sensitive
+}
+
+func (c *common) ErrorHint() (bool, string) {
+	return false, ""
+}
+
+func (c *common) getSlot() slotIdx {
+	return c.slot
+}
+
+// ValueOrigin returns the origin of the current value of the setting.
+func (c *common) ValueOrigin(ctx context.Context, sv *Values) ValueOrigin {
+	return sv.getValueOrigin(ctx, c.slot)
+}
+
+// setReportable configures the reportability.
+// Refer to the WithReportable option for details.
+func (c *common) setReportable(reportable bool) {
+	c.nonReportable = !reportable
+}
+
+// setVisibility customizes the visibility of a setting.
+// Refer to the WithVisibility option for details.
+func (c *common) setVisibility(v Visibility) {
+	c.visibility = v
+}
+
+// setRetired marks the setting as obsolete. It also hides
+// it from the output of SHOW CLUSTER SETTINGS.
+func (c *common) setRetired() {
+	c.description = "do not use - " + c.description
+	c.retired = true
+}
+
+// setSensitive marks the setting as sensitive, which means that it will always
+// be redacted in any output. It also makes the setting non-reportable.
+func (c *common) setSensitive() {
+	c.sensitive = true
+	c.nonReportable = true
+}
+
+// setName is used to override the name of the setting.
+// Refer to the WithName option for details.
+func (c *common) setName(name SettingName) {
+	if c.name != SettingName(c.key) {
+		panic(errors.AssertionFailedf("duplicate use of WithName"))
+	}
+	c.name = name
+}
+
+// setUnsafe is used to override the unsafe status of the setting.
+// Refer to the WithUnsafe option for details.
+func (c *common) setUnsafe() {
+	c.unsafe = true
+}
+
+// IsUnsafe indicates whether the setting is unsafe.
+func (c *common) IsUnsafe() bool {
+	return c.unsafe
+}
+
+// SetOnChange installs a callback to be called when a setting's value changes.
+// `fn` should avoid doing long-running or blocking work as it is called on the
+// goroutine which handles all settings updates.
+func (c *common) SetOnChange(sv *Values, fn func(ctx context.Context)) {
+	sv.setOnChange(c.slot, fn)
+}
+
+type internalSetting interface {
+	NonMaskedSetting
+
+	init(class Class, key InternalKey, description string, slot slotIdx)
+	isRetired() bool
+	isSensitive() bool
+	getSlot() slotIdx
+
+	// isReportable indicates whether the value of the setting can be
+	// included in user-facing reports such as that produced by SHOW ALL
+	// CLUSTER SETTINGS.
+	// This only affects reports though; direct access is unconstrained.
+	// For example, `enterprise.license` is non-reportable:
+	// it cannot be listed, but can be accessed with `SHOW CLUSTER
+	// SETTING enterprise.license` or SET CLUSTER SETTING.
+	isReportable() bool
+
+	setToDefault(ctx context.Context, sv *Values)
+
+	// decodeAndSet sets the setting after decoding the encoded value.
+	decodeAndSet(ctx context.Context, sv *Values, encoded string) error
+
+	// decodeAndOverrideDefault overrides the default value for the respective
+	// setting to newVal. It does not change the current value. Validation checks
+	// are not run against the decoded value.
+	decodeAndSetDefaultOverride(ctx context.Context, sv *Values, encoded string) error
+}
+
+// TestingIsReportable is used in testing for reportability.
+func TestingIsReportable(s Setting) bool {
+	if _, ok := s.(*MaskedSetting); ok {
+		return false
+	}
+	if e, ok := s.(internalSetting); ok {
+		return e.isReportable()
+	}
+	return true
+}
+
+// TestingIsSensitive is used in testing for sensitivity.
+func TestingIsSensitive(s Setting) bool {
+	if e, ok := s.(internalSetting); ok {
+		return e.isSensitive()
+	}
+	return false
+}
diff --git a/pkg/settings/doc.go b/pkg/settings/doc.go
new file mode 100644
index 0000000..807770c
--- /dev/null
+++ b/pkg/settings/doc.go
@@ -0,0 +1,110 @@
+// Copyright 2017 The Cockroach Authors.
+//
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
+
+/*
+Package settings provides a central registry of runtime editable settings and
+accompanying helper functions for retrieving their current values.
+
+# Overview
+
+Settings values are stored in the system.settings table. A
+rangefeed-driven worker updates the cached value when the table
+changes (see package 'settingswatcher').
+
+To add a new setting, call one of the `Register` methods in `registry.go` and
+save the accessor created by the register function in the package where the
+setting is to be used. For example, to add an "enterprise" flag, adding into
+license_check.go:
+
+	var enterpriseEnabled = settings.RegisterBoolSetting(
+		settings.ApplicationLevel,
+		"enterprise.enabled",
+		"some doc for the setting",
+		false,
+	)
+
+Then use with `if enterpriseEnabled.Get(...) ...`
+
+# Setting names
+
+Settings have both a "key" and a "name".
+
+The key is what is used to persist the value and synchronize it across
+nodes. The key should remain immutable through the lifetime of the
+setting. This is the main argument passed through the Register() calls.
+
+The name is what end-users see in docs and can use via the SQL
+statements SET/SHOW CLUSTER SETTING. It can change over time. It is
+also subject to a linter; for example boolean settings should have a
+name ending with '.enabled'.
+
+When no name is specified, it defaults to the key. Another name
+can be specified using `WithName()`, for example:
+
+	var mySetting = settings.RegisterBoolSetting(
+		"mykey", ...,
+		settings.WithName("descriptive.name.enabled"),
+	)
+
+For convenience, users can also refer to a setting using its key
+in the SET/SHOW CLUSTER SETTING statements. Because of this,
+the keys and names are in the same namespace and cannot overlap.
+
+# Careful choice of default values, value propagation delay
+
+Settings should always be defined with "safe" default values -- until a node
+receives values asynchronously, or even after that, if it cannot read them for some
+reason, it will use the default values, so define defaults that "fail safe".
+
+In cases where the "safe" default doesn't actually match the desired default,
+like respecting an opt-*out* setting, we can default to `false` (opted out) and
+then use a migration to write an explicit `true`: in practice you'd still expect
+to read `true` unless a preference is expressed, but in the rare cases where you
+read a default, you don't risk ignoring an expressed opt-out.
+
+Ideally, when passing configuration into some structure or subsystem, e.g. a
+rate limit into a client or something, passing a `*FooSetting` rather than a
+`Foo` and waiting to call `.Get()` until the value is actually used ensures
+observing the latest value.
+
+# Changing names of settings
+
+Sometimes for UX or documentation purposes it is useful to rename a setting.
+However, to preserve backward-compatibility, its key cannot change.
+
+There are two situations possible:
+
+  - The setting currently has the same name as its key. To rename the setting,
+    use the `WithName()` option.
+
+  - The setting already has another name than its key. In this case,
+    modify the name in the `WithName()` option and also add a
+    `WithRetiredName()` option with the previous name. A SQL notice
+    will redirect users to the new name.
+
+# Retiring settings
+
+Settings may become irrelevant over time, especially when introduced to provide
+a workaround to a system limitation which is later corrected. There are two
+possible scenarios:
+
+  - The setting may still be referred to from automation (e.g. external
+    scripts). In this case, use the option `settings.Retired` at the
+    registration point.
+
+  - The setting will not ever be reused anywhere and can be deleted.
+    When deleting a setting's registration from the codebase, add its
+    name to the list of `retiredSettings` in settings/registry.go --
+    this ensures the name cannot be accidentally reused, and suppresses
+    log spam about the existing value.
+
+The list of deleted+retired settings can periodically (i.e. in major versions) be
+"flushed" by adding a migration that deletes all stored values for those keys
+at which point the key would be available for reuse in a later version. Is is
+only safe to run such a migration after the cluster upgrade process ensures no
+older nodes are still using the values for those old settings though, so such a
+migration needs to be version gated.
+*/
+package settings
diff --git a/pkg/settings/duration.go b/pkg/settings/duration.go
new file mode 100644
index 0000000..4c5e1d8
--- /dev/null
+++ b/pkg/settings/duration.go
@@ -0,0 +1,286 @@
+// Copyright 2017 The Cockroach Authors.
+//
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
+
+package settings
+
+import (
+	"context"
+	"time"
+
+	"github.com/cockroachdb/errors"
+)
+
+// DurationSetting is the interface of a setting variable that will be
+// updated automatically when the corresponding cluster-wide setting
+// of type "duration" is updated.
+type DurationSetting struct {
+	common
+	defaultValue time.Duration
+	validateFn   func(time.Duration) error
+}
+
+// DurationSettingWithExplicitUnit is like DurationSetting except it requires an
+// explicit unit when being set. (eg. 1s works, but 1 does not).
+type DurationSettingWithExplicitUnit struct {
+	DurationSetting
+}
+
+var _ internalSetting = &DurationSetting{}
+
+var _ internalSetting = &DurationSettingWithExplicitUnit{}
+
+// ErrorHint returns a hint message to be displayed on error to the user.
+func (d *DurationSettingWithExplicitUnit) ErrorHint() (bool, string) {
+	return true, "try using an interval value with explicit units, e.g 500ms or 1h2m"
+}
+
+// Get retrieves the duration value in the setting.
+func (d *DurationSetting) Get(sv *Values) time.Duration {
+	return time.Duration(sv.getInt64(d.slot))
+}
+
+func (d *DurationSetting) String(sv *Values) string {
+	return EncodeDuration(d.Get(sv))
+}
+
+// DefaultString returns the default value for the setting as a string.
+func (d *DurationSetting) DefaultString() string {
+	return EncodeDuration(d.defaultValue)
+}
+
+// Encoded returns the encoded value of the current value of the setting.
+func (d *DurationSetting) Encoded(sv *Values) string {
+	return d.String(sv)
+}
+
+// EncodedDefault returns the encoded value of the default value of the setting.
+func (d *DurationSetting) EncodedDefault() string {
+	return EncodeDuration(d.defaultValue)
+}
+
+// DecodeToString decodes and renders an encoded value.
+func (d *DurationSetting) DecodeToString(encoded string) (string, error) {
+	v, err := d.DecodeValue(encoded)
+	if err != nil {
+		return "", err
+	}
+	return v.String(), nil
+}
+
+// DecodeValue decodes the value into a float.
+func (d *DurationSetting) DecodeValue(encoded string) (time.Duration, error) {
+	return time.ParseDuration(encoded)
+}
+
+// Typ returns the short (1 char) string denoting the type of setting.
+func (*DurationSetting) Typ() string {
+	return "d"
+}
+
+// Default returns default value for setting.
+func (d *DurationSetting) Default() time.Duration {
+	return d.defaultValue
+}
+
+// Defeat the linter.
+var _ = (*DurationSetting).Default
+
+// Validate that a value conforms with the validation function.
+func (d *DurationSetting) Validate(v time.Duration) error {
+	if d.validateFn != nil {
+		if err := d.validateFn(v); err != nil {
+			return err
+		}
+	}
+	return nil
+}
+
+// Override changes the setting without validation and also overrides the
+// default value.
+//
+// For testing usage only.
+func (d *DurationSetting) Override(ctx context.Context, sv *Values, v time.Duration) {
+	sv.setValueOrigin(ctx, d.slot, OriginOverride)
+	sv.setInt64(ctx, d.slot, int64(v))
+	sv.setDefaultOverride(d.slot, v)
+}
+
+func (d *DurationSetting) set(ctx context.Context, sv *Values, v time.Duration) error {
+	if err := d.Validate(v); err != nil {
+		return err
+	}
+	sv.setInt64(ctx, d.slot, int64(v))
+	return nil
+}
+
+func (d *DurationSetting) decodeAndSet(ctx context.Context, sv *Values, encoded string) error {
+	v, err := d.DecodeValue(encoded)
+	if err != nil {
+		return err
+	}
+	return d.set(ctx, sv, v)
+}
+
+func (d *DurationSetting) decodeAndSetDefaultOverride(
+	ctx context.Context, sv *Values, encoded string,
+) error {
+	v, err := d.DecodeValue(encoded)
+	if err != nil {
+		return err
+	}
+	sv.setDefaultOverride(d.slot, v)
+	return nil
+}
+
+func (d *DurationSetting) setToDefault(ctx context.Context, sv *Values) {
+	// See if the default value was overridden.
+	if val := sv.getDefaultOverride(d.slot); val != nil {
+		// As per the semantics of override, these values don't go through
+		// validation.
+		_ = d.set(ctx, sv, val.(time.Duration))
+		return
+	}
+	if err := d.set(ctx, sv, d.defaultValue); err != nil {
+		panic(err)
+	}
+}
+
+// RegisterDurationSetting defines a new setting with type duration.
+func RegisterDurationSetting(
+	class Class, key InternalKey, desc string, defaultValue time.Duration, opts ...SettingOption,
+) *DurationSetting {
+	validateFn := func(val time.Duration) error {
+		for _, opt := range opts {
+			switch {
+			case opt.commonOpt != nil:
+				continue
+			case opt.validateDurationFn != nil:
+			default:
+				panic(errors.AssertionFailedf("wrong validator type"))
+			}
+			if err := opt.validateDurationFn(val); err != nil {
+				return errors.Wrapf(err, "invalid value for %s", key)
+			}
+		}
+		return nil
+	}
+
+	if err := validateFn(defaultValue); err != nil {
+		panic(errors.Wrap(err, "invalid default"))
+	}
+	setting := &DurationSetting{
+		defaultValue: defaultValue,
+		validateFn:   validateFn,
+	}
+	register(class, key, desc, setting)
+	setting.apply(opts)
+	return setting
+}
+
+// RegisterPublicDurationSettingWithExplicitUnit defines a new
+// public setting with type duration which requires an explicit unit when being
+// set.
+func RegisterDurationSettingWithExplicitUnit(
+	class Class, key InternalKey, desc string, defaultValue time.Duration, opts ...SettingOption,
+) *DurationSettingWithExplicitUnit {
+	validateFn := func(val time.Duration) error {
+		for _, opt := range opts {
+			switch {
+			case opt.commonOpt != nil:
+				continue
+			case opt.validateDurationFn != nil:
+			default:
+				panic(errors.AssertionFailedf("wrong validator type"))
+			}
+			if err := opt.validateDurationFn(val); err != nil {
+				return errors.Wrapf(err, "invalid value for %s", key)
+			}
+		}
+		return nil
+	}
+	if err := validateFn(defaultValue); err != nil {
+		panic(errors.Wrap(err, "invalid default"))
+	}
+	setting := &DurationSettingWithExplicitUnit{
+		DurationSetting{
+			defaultValue: defaultValue,
+			validateFn:   validateFn,
+		},
+	}
+	register(class, key, desc, setting)
+	setting.apply(opts)
+	return setting
+}
+
+// NonNegativeDuration checks that the duration is greater or equal to
+// zero. It can be passed to RegisterDurationSetting.
+var NonNegativeDuration SettingOption = WithValidateDuration(nonNegativeDurationInternal)
+
+func nonNegativeDurationInternal(v time.Duration) error {
+	if v < 0 {
+		return errors.Errorf("cannot be set to a negative duration: %s", v)
+	}
+	return nil
+}
+
+// DurationInRange returns a validation option that checks the value
+// is within the given bounds (inclusive).
+func DurationInRange(minVal, maxVal time.Duration) SettingOption {
+	return WithValidateDuration(func(v time.Duration) error {
+		if v < minVal || v > maxVal {
+			return errors.Errorf("expected value in range [%v, %v], got: %v", minVal, maxVal, v)
+		}
+		return nil
+	})
+}
+
+// NonNegativeDurationWithMaximum returns a validation option that
+// checks the duration is in the range [0, maxValue]. It can be passed
+// to RegisterDurationSetting.
+func NonNegativeDurationWithMaximum(maxValue time.Duration) SettingOption {
+	return DurationInRange(0, maxValue)
+}
+
+// DurationWithMinimum returns a validation option that checks the
+// duration is greater or equal to the given minimum. It can be passed
+// to RegisterDurationSetting.
+func DurationWithMinimum(minValue time.Duration) SettingOption {
+	return WithValidateDuration(func(v time.Duration) error {
+		if minValue >= 0 {
+			if err := nonNegativeDurationInternal(v); err != nil {
+				return err
+			}
+		}
+		if v < minValue {
+			return errors.Errorf("cannot be set to a value smaller than %s", minValue)
+		}
+		return nil
+	})
+}
+
+// DurationWithMinimumOrZeroDisable returns a validation option that
+// checks the value is at least the given minimum, or zero to disable.
+// It can be passed to RegisterDurationSetting.
+func DurationWithMinimumOrZeroDisable(minValue time.Duration) SettingOption {
+	return WithValidateDuration(func(v time.Duration) error {
+		if minValue >= 0 && v < 0 {
+			return errors.Errorf("cannot be set to a negative duration: %s", v)
+		}
+		if v != 0 && v < minValue {
+			return errors.Errorf("cannot be set to a value smaller than %s",
+				minValue)
+		}
+		return nil
+	})
+}
+
+// PositiveDuration checks that the value is strictly positive. It can
+// be passed to RegisterDurationSetting.
+var PositiveDuration SettingOption = WithValidateDuration(func(v time.Duration) error {
+	if v <= 0 {
+		return errors.Errorf("cannot be set to a non-positive duration: %s", v)
+	}
+	return nil
+})
diff --git a/pkg/settings/encoding.go b/pkg/settings/encoding.go
new file mode 100644
index 0000000..34b0608
--- /dev/null
+++ b/pkg/settings/encoding.go
@@ -0,0 +1,23 @@
+// Copyright 2022 The Cockroach Authors.
+//
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
+
+package settings
+
+import (
+	"github.com/cockroachdb/redact"
+	"github.com/cockroachdb/redact/interfaces"
+)
+
+// String is part of fmt.Stringer.
+func (v EncodedValue) String() string {
+	return redact.Sprint(v).StripMarkers()
+}
+
+// SafeFormat is part of redact.SafeFormatter.
+func (v EncodedValue) SafeFormat(s interfaces.SafePrinter, verb rune) {
+	s.Printf("%q (%s)", v.Value, redact.SafeString(v.Type))
+}
+
+var _ redact.SafeFormatter = EncodedValue{}
diff --git a/pkg/settings/encoding.pb.go b/pkg/settings/encoding.pb.go
new file mode 100644
index 0000000..0948350
--- /dev/null
+++ b/pkg/settings/encoding.pb.go
@@ -0,0 +1,381 @@
+// Code generated by protoc-gen-gogo. DO NOT EDIT.
+// source: settings/encoding.proto
+
+package settings
+
+import (
+	fmt "fmt"
+	_ "github.com/gogo/protobuf/gogoproto"
+	proto "github.com/gogo/protobuf/proto"
+	io "io"
+	math "math"
+	math_bits "math/bits"
+)
+
+// Reference imports to suppress errors if they are not otherwise used.
+var _ = proto.Marshal
+var _ = fmt.Errorf
+var _ = math.Inf
+
+// This is a compile-time assertion to ensure that this generated file
+// is compatible with the proto package it is being compiled against.
+// A compilation error at this line likely means your copy of the
+// proto package needs to be updated.
+const _ = proto.GoGoProtoPackageIsVersion3 // please upgrade the proto package
+
+// EncodedValue contains the value of a cluster setting serialized as an opaque
+// string, along with a type identifier. Used when storing setting values on
+// disk or passing them over the wire.
+type EncodedValue struct {
+	Value string `protobuf:"bytes,1,opt,name=value,proto3" json:"value,omitempty"`
+	Type  string `protobuf:"bytes,2,opt,name=type,proto3" json:"type,omitempty"`
+}
+
+func (m *EncodedValue) Reset()      { *m = EncodedValue{} }
+func (*EncodedValue) ProtoMessage() {}
+func (*EncodedValue) Descriptor() ([]byte, []int) {
+	return fileDescriptor_714f9b2611bd3e0b, []int{0}
+}
+func (m *EncodedValue) XXX_Unmarshal(b []byte) error {
+	return m.Unmarshal(b)
+}
+func (m *EncodedValue) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+	b = b[:cap(b)]
+	n, err := m.MarshalToSizedBuffer(b)
+	if err != nil {
+		return nil, err
+	}
+	return b[:n], nil
+}
+func (m *EncodedValue) XXX_Merge(src proto.Message) {
+	xxx_messageInfo_EncodedValue.Merge(m, src)
+}
+func (m *EncodedValue) XXX_Size() int {
+	return m.Size()
+}
+func (m *EncodedValue) XXX_DiscardUnknown() {
+	xxx_messageInfo_EncodedValue.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_EncodedValue proto.InternalMessageInfo
+
+func init() {
+	proto.RegisterType((*EncodedValue)(nil), "cockroach.parser.settings.EncodedValue")
+}
+
+func init() { proto.RegisterFile("settings/encoding.proto", fileDescriptor_714f9b2611bd3e0b) }
+
+var fileDescriptor_714f9b2611bd3e0b = []byte{
+	// 197 bytes of a gzipped FileDescriptorProto
+	0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0x12, 0x2f, 0x4e, 0x2d, 0x29,
+	0xc9, 0xcc, 0x4b, 0x2f, 0xd6, 0x4f, 0xcd, 0x4b, 0xce, 0x4f, 0xc9, 0xcc, 0x4b, 0xd7, 0x2b, 0x28,
+	0xca, 0x2f, 0xc9, 0x17, 0x12, 0x4a, 0xce, 0x4f, 0xce, 0x2e, 0xca, 0x4f, 0x4c, 0xce, 0xd0, 0x83,
+	0x29, 0x91, 0x12, 0x49, 0xcf, 0x4f, 0xcf, 0x07, 0x4b, 0xeb, 0x83, 0x58, 0x10, 0x95, 0x4a, 0x4e,
+	0x5c, 0x3c, 0xae, 0x20, 0xbd, 0xa9, 0x29, 0x61, 0x89, 0x39, 0xa5, 0xa9, 0x42, 0x22, 0x5c, 0xac,
+	0x65, 0x20, 0x86, 0x04, 0xa3, 0x02, 0xa3, 0x06, 0x67, 0x10, 0x84, 0x23, 0x24, 0xc4, 0xc5, 0x52,
+	0x52, 0x59, 0x90, 0x2a, 0xc1, 0x04, 0x16, 0x04, 0xb3, 0xad, 0x38, 0x66, 0x2c, 0x90, 0x67, 0x78,
+	0xb1, 0x40, 0x9e, 0xd1, 0xc9, 0xff, 0xc4, 0x43, 0x39, 0x86, 0x13, 0x8f, 0xe4, 0x18, 0x2f, 0x3c,
+	0x92, 0x63, 0xbc, 0xf1, 0x48, 0x8e, 0xf1, 0xc1, 0x23, 0x39, 0xc6, 0x09, 0x8f, 0xe5, 0x18, 0x2e,
+	0x3c, 0x96, 0x63, 0xb8, 0xf1, 0x58, 0x8e, 0x21, 0x4a, 0x37, 0x3d, 0xb3, 0x24, 0xa3, 0x34, 0x49,
+	0x2f, 0x39, 0x3f, 0x57, 0x1f, 0xee, 0xb4, 0x94, 0x24, 0x04, 0x5b, 0xbf, 0x20, 0x3b, 0x5d, 0x1f,
+	0xe6, 0xd4, 0x24, 0x36, 0xb0, 0xdb, 0x8c, 0x01, 0x01, 0x00, 0x00, 0xff, 0xff, 0xb9, 0xd8, 0x95,
+	0x49, 0xe0, 0x00, 0x00, 0x00,
+}
+
+func (this *EncodedValue) Equal(that interface{}) bool {
+	if that == nil {
+		return this == nil
+	}
+
+	that1, ok := that.(*EncodedValue)
+	if !ok {
+		that2, ok := that.(EncodedValue)
+		if ok {
+			that1 = &that2
+		} else {
+			return false
+		}
+	}
+	if that1 == nil {
+		return this == nil
+	} else if this == nil {
+		return false
+	}
+	if this.Value != that1.Value {
+		return false
+	}
+	if this.Type != that1.Type {
+		return false
+	}
+	return true
+}
+func (m *EncodedValue) Marshal() (dAtA []byte, err error) {
+	size := m.Size()
+	dAtA = make([]byte, size)
+	n, err := m.MarshalToSizedBuffer(dAtA[:size])
+	if err != nil {
+		return nil, err
+	}
+	return dAtA[:n], nil
+}
+
+func (m *EncodedValue) MarshalTo(dAtA []byte) (int, error) {
+	size := m.Size()
+	return m.MarshalToSizedBuffer(dAtA[:size])
+}
+
+func (m *EncodedValue) MarshalToSizedBuffer(dAtA []byte) (int, error) {
+	i := len(dAtA)
+	_ = i
+	var l int
+	_ = l
+	if len(m.Type) > 0 {
+		i -= len(m.Type)
+		copy(dAtA[i:], m.Type)
+		i = encodeVarintEncoding(dAtA, i, uint64(len(m.Type)))
+		i--
+		dAtA[i] = 0x12
+	}
+	if len(m.Value) > 0 {
+		i -= len(m.Value)
+		copy(dAtA[i:], m.Value)
+		i = encodeVarintEncoding(dAtA, i, uint64(len(m.Value)))
+		i--
+		dAtA[i] = 0xa
+	}
+	return len(dAtA) - i, nil
+}
+
+func encodeVarintEncoding(dAtA []byte, offset int, v uint64) int {
+	offset -= sovEncoding(v)
+	base := offset
+	for v >= 1<<7 {
+		dAtA[offset] = uint8(v&0x7f | 0x80)
+		v >>= 7
+		offset++
+	}
+	dAtA[offset] = uint8(v)
+	return base
+}
+func (m *EncodedValue) Size() (n int) {
+	if m == nil {
+		return 0
+	}
+	var l int
+	_ = l
+	l = len(m.Value)
+	if l > 0 {
+		n += 1 + l + sovEncoding(uint64(l))
+	}
+	l = len(m.Type)
+	if l > 0 {
+		n += 1 + l + sovEncoding(uint64(l))
+	}
+	return n
+}
+
+func sovEncoding(x uint64) (n int) {
+	return int((uint32(math_bits.Len64(x|1)+6) * 37) >> 8)
+}
+func sozEncoding(x uint64) (n int) {
+	return sovEncoding(uint64((x << 1) ^ uint64((int64(x) >> 63))))
+}
+func (m *EncodedValue) Unmarshal(dAtA []byte) error {
+	l := len(dAtA)
+	iNdEx := 0
+	for iNdEx < l {
+		preIndex := iNdEx
+		var wire uint64
+		for shift := uint(0); ; shift += 7 {
+			if shift >= 64 {
+				return ErrIntOverflowEncoding
+			}
+			if iNdEx >= l {
+				return io.ErrUnexpectedEOF
+			}
+			b := dAtA[iNdEx]
+			iNdEx++
+			wire |= uint64(b&0x7F) << shift
+			if b < 0x80 {
+				break
+			}
+		}
+		fieldNum := int32(wire >> 3)
+		wireType := int(wire & 0x7)
+		if wireType == 4 {
+			return fmt.Errorf("proto: EncodedValue: wiretype end group for non-group")
+		}
+		if fieldNum <= 0 {
+			return fmt.Errorf("proto: EncodedValue: illegal tag %d (wire type %d)", fieldNum, wire)
+		}
+		switch fieldNum {
+		case 1:
+			if wireType != 2 {
+				return fmt.Errorf("proto: wrong wireType = %d for field Value", wireType)
+			}
+			var stringLen uint64
+			for shift := uint(0); ; shift += 7 {
+				if shift >= 64 {
+					return ErrIntOverflowEncoding
+				}
+				if iNdEx >= l {
+					return io.ErrUnexpectedEOF
+				}
+				b := dAtA[iNdEx]
+				iNdEx++
+				stringLen |= uint64(b&0x7F) << shift
+				if b < 0x80 {
+					break
+				}
+			}
+			intStringLen := int(stringLen)
+			if intStringLen < 0 {
+				return ErrInvalidLengthEncoding
+			}
+			postIndex := iNdEx + intStringLen
+			if postIndex < 0 {
+				return ErrInvalidLengthEncoding
+			}
+			if postIndex > l {
+				return io.ErrUnexpectedEOF
+			}
+			m.Value = string(dAtA[iNdEx:postIndex])
+			iNdEx = postIndex
+		case 2:
+			if wireType != 2 {
+				return fmt.Errorf("proto: wrong wireType = %d for field Type", wireType)
+			}
+			var stringLen uint64
+			for shift := uint(0); ; shift += 7 {
+				if shift >= 64 {
+					return ErrIntOverflowEncoding
+				}
+				if iNdEx >= l {
+					return io.ErrUnexpectedEOF
+				}
+				b := dAtA[iNdEx]
+				iNdEx++
+				stringLen |= uint64(b&0x7F) << shift
+				if b < 0x80 {
+					break
+				}
+			}
+			intStringLen := int(stringLen)
+			if intStringLen < 0 {
+				return ErrInvalidLengthEncoding
+			}
+			postIndex := iNdEx + intStringLen
+			if postIndex < 0 {
+				return ErrInvalidLengthEncoding
+			}
+			if postIndex > l {
+				return io.ErrUnexpectedEOF
+			}
+			m.Type = string(dAtA[iNdEx:postIndex])
+			iNdEx = postIndex
+		default:
+			iNdEx = preIndex
+			skippy, err := skipEncoding(dAtA[iNdEx:])
+			if err != nil {
+				return err
+			}
+			if (skippy < 0) || (iNdEx+skippy) < 0 {
+				return ErrInvalidLengthEncoding
+			}
+			if (iNdEx + skippy) > l {
+				return io.ErrUnexpectedEOF
+			}
+			iNdEx += skippy
+		}
+	}
+
+	if iNdEx > l {
+		return io.ErrUnexpectedEOF
+	}
+	return nil
+}
+func skipEncoding(dAtA []byte) (n int, err error) {
+	l := len(dAtA)
+	iNdEx := 0
+	depth := 0
+	for iNdEx < l {
+		var wire uint64
+		for shift := uint(0); ; shift += 7 {
+			if shift >= 64 {
+				return 0, ErrIntOverflowEncoding
+			}
+			if iNdEx >= l {
+				return 0, io.ErrUnexpectedEOF
+			}
+			b := dAtA[iNdEx]
+			iNdEx++
+			wire |= (uint64(b) & 0x7F) << shift
+			if b < 0x80 {
+				break
+			}
+		}
+		wireType := int(wire & 0x7)
+		switch wireType {
+		case 0:
+			for shift := uint(0); ; shift += 7 {
+				if shift >= 64 {
+					return 0, ErrIntOverflowEncoding
+				}
+				if iNdEx >= l {
+					return 0, io.ErrUnexpectedEOF
+				}
+				iNdEx++
+				if dAtA[iNdEx-1] < 0x80 {
+					break
+				}
+			}
+		case 1:
+			iNdEx += 8
+		case 2:
+			var length int
+			for shift := uint(0); ; shift += 7 {
+				if shift >= 64 {
+					return 0, ErrIntOverflowEncoding
+				}
+				if iNdEx >= l {
+					return 0, io.ErrUnexpectedEOF
+				}
+				b := dAtA[iNdEx]
+				iNdEx++
+				length |= (int(b) & 0x7F) << shift
+				if b < 0x80 {
+					break
+				}
+			}
+			if length < 0 {
+				return 0, ErrInvalidLengthEncoding
+			}
+			iNdEx += length
+		case 3:
+			depth++
+		case 4:
+			if depth == 0 {
+				return 0, ErrUnexpectedEndOfGroupEncoding
+			}
+			depth--
+		case 5:
+			iNdEx += 4
+		default:
+			return 0, fmt.Errorf("proto: illegal wireType %d", wireType)
+		}
+		if iNdEx < 0 {
+			return 0, ErrInvalidLengthEncoding
+		}
+		if depth == 0 {
+			return iNdEx, nil
+		}
+	}
+	return 0, io.ErrUnexpectedEOF
+}
+
+var (
+	ErrInvalidLengthEncoding        = fmt.Errorf("proto: negative length found during unmarshaling")
+	ErrIntOverflowEncoding          = fmt.Errorf("proto: integer overflow")
+	ErrUnexpectedEndOfGroupEncoding = fmt.Errorf("proto: unexpected end of group")
+)
+
diff --git a/pkg/settings/encoding.proto b/pkg/settings/encoding.proto
new file mode 100644
index 0000000..4d9fea8
--- /dev/null
+++ b/pkg/settings/encoding.proto
@@ -0,0 +1,21 @@
+// Copyright 2022 The Cockroach Authors.
+//
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
+
+syntax = "proto3";
+package cockroach.settings;
+option go_package = "github.com/cockroachdb/cockroach/pkg/settings";
+
+import "gogoproto/gogo.proto";
+
+// EncodedValue contains the value of a cluster setting serialized as an opaque
+// string, along with a type identifier. Used when storing setting values on
+// disk or passing them over the wire.
+message EncodedValue {
+  option (gogoproto.equal) = true;
+  option (gogoproto.goproto_stringer) = false;
+
+  string value = 1;
+  string type = 2;
+}
diff --git a/pkg/settings/enum.go b/pkg/settings/enum.go
new file mode 100644
index 0000000..14ca86c
--- /dev/null
+++ b/pkg/settings/enum.go
@@ -0,0 +1,232 @@
+// Copyright 2017 The Cockroach Authors.
+//
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
+
+package settings
+
+import (
+	"bytes"
+	"context"
+	"fmt"
+	"sort"
+	"strconv"
+	"strings"
+
+	"golang.org/x/exp/constraints"
+)
+
+// EnumSetting is a StringSetting that restricts the values to be one of the `enumValues`
+type EnumSetting[T constraints.Integer] struct {
+	common
+	defaultValue T
+	// enumValues maps each valid value of T to a lowercase string.
+	enumValues map[T]string
+}
+
+// AnyEnumSetting is an interface that is used when the specific enum type T is
+// not known.
+type AnyEnumSetting interface {
+	internalSetting
+
+	// ParseEnum parses a string that is either a string in enumValues or an
+	// integer and returns the enum value as an int64 (and a boolean that
+	// indicates if it was parseable).
+	ParseEnum(raw string) (int64, bool)
+
+	// GetAvailableValuesAsHint returns the possible enum settings as a string that
+	// can be provided as an error hint to a user.
+	GetAvailableValuesAsHint() string
+}
+
+var _ AnyEnumSetting = &EnumSetting[int]{}
+
+// Typ returns the short (1 char) string denoting the type of setting.
+func (e *EnumSetting[T]) Typ() string {
+	return "e"
+}
+
+// Get retrieves the int value in the setting.
+func (e *EnumSetting[T]) Get(sv *Values) T {
+	return T(sv.container.getInt64(e.slot))
+}
+
+// Override changes the setting without validation and also overrides the
+// default value.
+func (e *EnumSetting[T]) Override(ctx context.Context, sv *Values, v T) {
+	sv.setValueOrigin(ctx, e.slot, OriginOverride)
+	sv.setInt64(ctx, e.slot, int64(v))
+	sv.setDefaultOverride(e.slot, int64(v))
+}
+
+// String returns the enum's string value.
+func (e *EnumSetting[T]) String(sv *Values) string {
+	enumID := e.Get(sv)
+	if str, ok := e.enumValues[enumID]; ok {
+		return str
+	}
+	return fmt.Sprintf("unknown(%d)", enumID)
+}
+
+// DefaultString returns the default value for the setting as a string.
+func (e *EnumSetting[T]) DefaultString() string {
+	return e.enumValues[e.defaultValue]
+}
+
+func (e *EnumSetting[T]) Encoded(sv *Values) string {
+	return EncodeInt(int64(e.Get(sv)))
+}
+
+func (e *EnumSetting[T]) EncodedDefault() string {
+	return EncodeInt(int64(e.defaultValue))
+}
+
+func (e *EnumSetting[T]) setToDefault(ctx context.Context, sv *Values) {
+	// See if the default value was overridden.
+	if val := sv.getDefaultOverride(e.slot); val != nil {
+		// As per the semantics of override, these values don't go through
+		// validation.
+		sv.setInt64(ctx, e.slot, val.(int64))
+		return
+	}
+	sv.setInt64(ctx, e.slot, int64(e.defaultValue))
+}
+
+func (e *EnumSetting[T]) decodeAndSet(ctx context.Context, sv *Values, encoded string) error {
+	v, err := strconv.ParseInt(encoded, 10, 64)
+	if err != nil {
+		return err
+	}
+	sv.setInt64(ctx, e.slot, v)
+	return nil
+}
+
+func (e *EnumSetting[T]) decodeAndSetDefaultOverride(
+	ctx context.Context, sv *Values, encoded string,
+) error {
+	v, err := strconv.ParseInt(encoded, 10, 64)
+	if err != nil {
+		return err
+	}
+	sv.setDefaultOverride(e.slot, v)
+	return nil
+}
+
+// DecodeToString decodes and renders an encoded value.
+func (e *EnumSetting[T]) DecodeToString(encoded string) (string, error) {
+	v, err := strconv.ParseInt(encoded, 10, 64)
+	if err != nil {
+		return "", err
+	}
+	if str, ok := e.enumValues[T(v)]; ok {
+		return str, nil
+	}
+	return encoded, nil
+}
+
+// ParseEnum parses a string that is either a string in enumValues or an integer
+// and returns the enum value as an int64 (and a boolean that indicates if it
+// was parseable).
+func (e *EnumSetting[T]) ParseEnum(raw string) (int64, bool) {
+	rawLower := strings.ToLower(raw)
+	for k, v := range e.enumValues {
+		if v == rawLower {
+			return int64(k), true
+		}
+	}
+	// Attempt to parse the string as an integer since it isn't a valid enum string.
+	v, err := strconv.ParseInt(raw, 10, 64)
+	if err != nil {
+		return 0, false
+	}
+	_, ok := e.enumValues[T(v)]
+	return v, ok
+}
+
+// GetAvailableValuesAsHint returns the possible enum settings as a string that
+// can be provided as an error hint to a user.
+func (e *EnumSetting[T]) GetAvailableValuesAsHint() string {
+	// First stabilize output by sorting by key.
+	valIdxs := make([]int, 0, len(e.enumValues))
+	for i := range e.enumValues {
+		valIdxs = append(valIdxs, int(i))
+	}
+	sort.Ints(valIdxs)
+
+	// Now use those indices
+	vals := make([]string, 0, len(e.enumValues))
+	for _, enumIdx := range valIdxs {
+		vals = append(vals, fmt.Sprintf("%d: %s", enumIdx, e.enumValues[T(enumIdx)]))
+	}
+	return "Available values: " + strings.Join(vals, ", ")
+}
+
+// GetAvailableValues returns the possible enum settings as a string
+// slice.
+func (e *EnumSetting[T]) GetAvailableValues() []string {
+	// First stabilize output by sorting by key.
+	valIdxs := make([]int, 0, len(e.enumValues))
+	for i := range e.enumValues {
+		valIdxs = append(valIdxs, int(i))
+	}
+	sort.Ints(valIdxs)
+
+	// Now use those indices
+	vals := make([]string, 0, len(e.enumValues))
+	for _, enumIdx := range valIdxs {
+		vals = append(vals, e.enumValues[T(enumIdx)])
+	}
+	return vals
+}
+
+func enumValuesToDesc[T constraints.Integer](enumValues map[T]string) string {
+	var buffer bytes.Buffer
+	values := make([]T, 0, len(enumValues))
+	for k := range enumValues {
+		values = append(values, k)
+	}
+	sort.Slice(values, func(i, j int) bool { return values[i] < values[j] })
+
+	buffer.WriteString("[")
+	for i, k := range values {
+		if i > 0 {
+			buffer.WriteString(", ")
+		}
+		fmt.Fprintf(&buffer, "%s = %d", strings.ToLower(enumValues[k]), k)
+	}
+	buffer.WriteString("]")
+	return buffer.String()
+}
+
+// RegisterEnumSetting defines a new setting with type int.
+func RegisterEnumSetting[T constraints.Integer](
+	class Class,
+	key InternalKey,
+	desc string,
+	defaultValue string,
+	enumValues map[T]string,
+	opts ...SettingOption,
+) *EnumSetting[T] {
+	enumValuesLower := make(map[T]string, len(enumValues))
+	for k, v := range enumValues {
+		enumValuesLower[k] = strings.ToLower(v)
+	}
+
+	defaultVal := func() T {
+		for k, v := range enumValues {
+			if v == defaultValue {
+				return k
+			}
+		}
+		panic(fmt.Sprintf("enum registered with default value %s not in map %s", defaultValue, enumValuesToDesc(enumValuesLower)))
+	}()
+
+	setting := &EnumSetting[T]{
+		defaultValue: defaultVal,
+		enumValues:   enumValuesLower,
+	}
+
+	register(class, key, fmt.Sprintf("%s %s", desc, enumValuesToDesc(enumValues)), setting)
+	setting.apply(opts)
+	return setting
+}
diff --git a/pkg/settings/float.go b/pkg/settings/float.go
new file mode 100644
index 0000000..2450bad
--- /dev/null
+++ b/pkg/settings/float.go
@@ -0,0 +1,260 @@
+// Copyright 2017 The Cockroach Authors.
+//
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
+
+package settings
+
+import (
+	"context"
+	"math"
+	"strconv"
+
+	"github.com/cockroachdb/errors"
+)
+
+// FloatSetting is the interface of a setting variable that will be
+// updated automatically when the corresponding cluster-wide setting
+// of type "float" is updated.
+type FloatSetting struct {
+	common
+	defaultValue float64
+	validateFn   func(float64) error
+}
+
+var _ internalSetting = &FloatSetting{}
+
+// Get retrieves the float value in the setting.
+func (f *FloatSetting) Get(sv *Values) float64 {
+	return math.Float64frombits(uint64(sv.getInt64(f.slot)))
+}
+
+func (f *FloatSetting) String(sv *Values) string {
+	return EncodeFloat(f.Get(sv))
+}
+
+// DefaultString returns the default value for the setting as a string.
+func (f *FloatSetting) DefaultString() string {
+	return EncodeFloat(f.defaultValue)
+}
+
+// Encoded returns the encoded value of the current value of the setting.
+func (f *FloatSetting) Encoded(sv *Values) string {
+	return f.String(sv)
+}
+
+// EncodedDefault returns the encoded value of the default value of the setting.
+func (f *FloatSetting) EncodedDefault() string {
+	return EncodeFloat(f.defaultValue)
+}
+
+// DecodeToString decodes and renders an encoded value.
+func (f *FloatSetting) DecodeToString(encoded string) (string, error) {
+	fv, err := f.DecodeValue(encoded)
+	if err != nil {
+		return "", err
+	}
+	return EncodeFloat(fv), nil
+}
+
+// DecodeValue decodes the value into a float.
+func (f *FloatSetting) DecodeValue(encoded string) (float64, error) {
+	return strconv.ParseFloat(encoded, 64)
+}
+
+// Typ returns the short (1 char) string denoting the type of setting.
+func (*FloatSetting) Typ() string {
+	return "f"
+}
+
+// Default returns default value for setting.
+func (f *FloatSetting) Default() float64 {
+	return f.defaultValue
+}
+
+// Defeat the linter.
+var _ = (*FloatSetting).Default
+
+// Override changes the setting panicking if validation fails and also overrides
+// the default value.
+//
+// For testing usage only.
+func (f *FloatSetting) Override(ctx context.Context, sv *Values, v float64) {
+	sv.setValueOrigin(ctx, f.slot, OriginOverride)
+	if err := f.set(ctx, sv, v); err != nil {
+		panic(err)
+	}
+	sv.setDefaultOverride(f.slot, v)
+}
+
+// Validate that a value conforms with the validation function.
+func (f *FloatSetting) Validate(v float64) error {
+	if f.validateFn != nil {
+		if err := f.validateFn(v); err != nil {
+			return err
+		}
+	}
+	return nil
+}
+
+func (f *FloatSetting) set(ctx context.Context, sv *Values, v float64) error {
+	if err := f.Validate(v); err != nil {
+		return err
+	}
+	sv.setInt64(ctx, f.slot, int64(math.Float64bits(v)))
+	return nil
+}
+
+func (f *FloatSetting) decodeAndSet(ctx context.Context, sv *Values, encoded string) error {
+	v, err := f.DecodeValue(encoded)
+	if err != nil {
+		return err
+	}
+	return f.set(ctx, sv, v)
+}
+
+func (f *FloatSetting) decodeAndSetDefaultOverride(
+	ctx context.Context, sv *Values, encoded string,
+) error {
+	v, err := f.DecodeValue(encoded)
+	if err != nil {
+		return err
+	}
+	sv.setDefaultOverride(f.slot, v)
+	return nil
+}
+
+func (f *FloatSetting) setToDefault(ctx context.Context, sv *Values) {
+	// See if the default value was overridden.
+	if val := sv.getDefaultOverride(f.slot); val != nil {
+		// As per the semantics of override, these values don't go through
+		// validation.
+		_ = f.set(ctx, sv, val.(float64))
+		return
+	}
+	if err := f.set(ctx, sv, f.defaultValue); err != nil {
+		panic(err)
+	}
+}
+
+// RegisterFloatSetting defines a new setting with type float.
+func RegisterFloatSetting(
+	class Class, key InternalKey, desc string, defaultValue float64, opts ...SettingOption,
+) *FloatSetting {
+	validateFn := func(v float64) error {
+		for _, opt := range opts {
+			switch {
+			case opt.commonOpt != nil:
+				continue
+			case opt.validateFloat64Fn != nil:
+			default:
+				panic(errors.AssertionFailedf("wrong validator type"))
+			}
+			if err := opt.validateFloat64Fn(v); err != nil {
+				return err
+			}
+		}
+		return nil
+	}
+
+	if err := validateFn(defaultValue); err != nil {
+		panic(errors.Wrap(err, "invalid default"))
+	}
+	setting := &FloatSetting{
+		defaultValue: defaultValue,
+		validateFn:   validateFn,
+	}
+	register(class, key, desc, setting)
+	setting.apply(opts)
+	return setting
+}
+
+// NonNegativeFloat checks the value is greater or equal to zero. It
+// can be passed to RegisterFloatSetting.
+var NonNegativeFloat SettingOption = FloatWithMinimum(0)
+
+// FloatWithMinimum returns a validation option that checks that the
+// value is at least the given minimum. It can be passed to
+// RegisterFloatSetting.
+func FloatWithMinimum(minVal float64) SettingOption {
+	return WithValidateFloat(func(v float64) error {
+		if minVal >= 0 && v < 0 {
+			return errors.Errorf("cannot set to a negative value: %f", v)
+		}
+		if v < minVal {
+			return errors.Errorf("cannot set to a value lower than %f: %f", minVal, v)
+		}
+		return nil
+	})
+}
+
+// FloatWithMinimumOrZeroDisable returns a validation option that
+// verifies the value is at least the given minimum, or zero to
+// disable. It can be passed to RegisterFloatSetting.
+func FloatWithMinimumOrZeroDisable(minVal float64) SettingOption {
+	return WithValidateFloat(func(v float64) error {
+		if minVal >= 0 && v < 0 {
+			return errors.Errorf("cannot set to a negative value: %f", v)
+		}
+		if v != 0 && v < minVal {
+			return errors.Errorf("cannot set to a value lower than %f: %f", minVal, v)
+		}
+		return nil
+	})
+}
+
+// NonNegativeFloatWithMaximum returns a validation option that checks
+// that the value is in the range [0, maxValue]. It can be passed to
+// RegisterFloatSetting.
+func NonNegativeFloatWithMaximum(maxValue float64) SettingOption {
+	return FloatInRange(0, maxValue)
+}
+
+// PositiveFloat checks that the value is strictly greater than zero.
+// It can be passed to RegisterFloatSetting.
+var PositiveFloat SettingOption = WithValidateFloat(func(v float64) error {
+	if v <= 0 {
+		return errors.Errorf("cannot set to a non-positive value: %f", v)
+	}
+	return nil
+})
+
+// NonZeroFloat checks that the value is non-zero. It can be passed to
+// RegisterFloatSetting.
+var NonZeroFloat SettingOption = WithValidateFloat(func(v float64) error {
+	if v == 0 {
+		return errors.New("cannot set to zero value")
+	}
+	return nil
+})
+
+// Fraction requires the setting to be in the interval [0, 1]. It can
+// be passed to RegisterFloatSetting.
+var Fraction SettingOption = FloatInRange(0, 1)
+
+// FloatInRange returns a validation option that checks the value is
+// within the given bounds (inclusive).
+func FloatInRange(minVal, maxVal float64) SettingOption {
+	return WithValidateFloat(func(v float64) error {
+		if v < minVal || v > maxVal {
+			return errors.Errorf("expected value in range [%f, %f], got: %f", minVal, maxVal, v)
+		}
+		return nil
+	})
+}
+
+// FractionUpperExclusive requires the setting to be in the interval
+// [0, 1). It can be passed to RegisterFloatSetting.
+var FractionUpperExclusive SettingOption = FloatInRangeUpperExclusive(0, 1)
+
+// FloatInRangeUpperExclusive returns a validation option that checks
+// the value is within the given bounds (inclusive lower, exclusive
+// upper).
+func FloatInRangeUpperExclusive(minVal, maxVal float64) SettingOption {
+	return WithValidateFloat(func(v float64) error {
+		if v < minVal || v >= maxVal {
+			return errors.Errorf("expected value in range [%f, %f), got: %f", minVal, maxVal, v)
+		}
+		return nil
+	})
+}
diff --git a/pkg/settings/int.go b/pkg/settings/int.go
new file mode 100644
index 0000000..2e0c890
--- /dev/null
+++ b/pkg/settings/int.go
@@ -0,0 +1,238 @@
+// Copyright 2017 The Cockroach Authors.
+//
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
+
+package settings
+
+import (
+	"context"
+	"strconv"
+
+	"github.com/cockroachdb/errors"
+)
+
+// IntSetting is the interface of a setting variable that will be
+// updated automatically when the corresponding cluster-wide setting
+// of type "int" is updated.
+type IntSetting struct {
+	common
+	defaultValue int64
+	validateFn   func(int64) error
+}
+
+var _ internalSetting = &IntSetting{}
+
+// Get retrieves the int value in the setting.
+func (i *IntSetting) Get(sv *Values) int64 {
+	return sv.container.getInt64(i.slot)
+}
+
+func (i *IntSetting) String(sv *Values) string {
+	return EncodeInt(i.Get(sv))
+}
+
+// DefaultString returns the default value for the setting as a string.
+func (i *IntSetting) DefaultString() string {
+	return EncodeInt(i.defaultValue)
+}
+
+// Encoded returns the encoded value of the current value of the setting.
+func (i *IntSetting) Encoded(sv *Values) string {
+	return i.String(sv)
+}
+
+// EncodedDefault returns the encoded value of the default value of the setting.
+func (i *IntSetting) EncodedDefault() string {
+	return EncodeInt(i.defaultValue)
+}
+
+// DecodeToString decodes and renders an encoded value.
+func (i *IntSetting) DecodeToString(encoded string) (string, error) {
+	iv, err := i.DecodeNumericValue(encoded)
+	if err != nil {
+		return "", err
+	}
+	return EncodeInt(iv), nil
+}
+
+// DecodeValue decodes the value into an integer.
+func (i *IntSetting) DecodeNumericValue(value string) (int64, error) {
+	return strconv.ParseInt(value, 10, 64)
+}
+
+// Typ returns the short (1 char) string denoting the type of setting.
+func (*IntSetting) Typ() string {
+	return "i"
+}
+
+// Default returns default value for setting.
+func (i *IntSetting) Default() int64 {
+	return i.defaultValue
+}
+
+// Defeat the linter.
+var _ = (*IntSetting).Default
+
+// Validate that a value conforms with the validation function.
+func (i *IntSetting) Validate(v int64) error {
+	if i.validateFn != nil {
+		if err := i.validateFn(v); err != nil {
+			return err
+		}
+	}
+	return nil
+}
+
+// Override changes the setting without validation and also overrides the
+// default value.
+//
+// For testing usage only.
+func (i *IntSetting) Override(ctx context.Context, sv *Values, v int64) {
+	sv.setValueOrigin(ctx, i.slot, OriginOverride)
+	sv.setInt64(ctx, i.slot, v)
+	sv.setDefaultOverride(i.slot, v)
+}
+
+func (i *IntSetting) decodeAndSet(ctx context.Context, sv *Values, encoded string) error {
+	v, err := strconv.ParseInt(encoded, 10, 64)
+	if err != nil {
+		return err
+	}
+	if err := i.Validate(v); err != nil {
+		return err
+	}
+	sv.setInt64(ctx, i.slot, v)
+	return nil
+}
+
+func (i *IntSetting) decodeAndSetDefaultOverride(
+	ctx context.Context, sv *Values, encoded string,
+) error {
+	v, err := strconv.ParseInt(encoded, 10, 64)
+	if err != nil {
+		return err
+	}
+	sv.setDefaultOverride(i.slot, v)
+	return nil
+}
+
+func (i *IntSetting) set(ctx context.Context, sv *Values, v int64) error {
+	if err := i.Validate(v); err != nil {
+		return err
+	}
+	sv.setInt64(ctx, i.slot, v)
+	return nil
+}
+
+func (i *IntSetting) setToDefault(ctx context.Context, sv *Values) {
+	// See if the default value was overridden.
+	if val := sv.getDefaultOverride(i.slot); val != nil {
+		// As per the semantics of override, these values don't go through
+		// validation.
+		_ = i.set(ctx, sv, val.(int64))
+		return
+	}
+	if err := i.set(ctx, sv, i.defaultValue); err != nil {
+		panic(err)
+	}
+}
+
+// RegisterIntSetting defines a new setting with type int with a
+// validation function.
+func RegisterIntSetting(
+	class Class, key InternalKey, desc string, defaultValue int64, opts ...SettingOption,
+) *IntSetting {
+	validateFn := func(val int64) error {
+		for _, opt := range opts {
+			switch {
+			case opt.commonOpt != nil:
+				continue
+			case opt.validateInt64Fn != nil:
+			default:
+				panic(errors.AssertionFailedf("wrong validator type"))
+			}
+			if err := opt.validateInt64Fn(val); err != nil {
+				return err
+			}
+		}
+		return nil
+	}
+	if err := validateFn(defaultValue); err != nil {
+		panic(errors.Wrap(err, "invalid default"))
+	}
+	setting := &IntSetting{
+		defaultValue: defaultValue,
+		validateFn:   validateFn,
+	}
+	register(class, key, desc, setting)
+	setting.apply(opts)
+	return setting
+}
+
+// PositiveInt can be passed to RegisterIntSetting.
+var PositiveInt SettingOption = WithValidateInt(func(v int64) error {
+	if v <= 0 {
+		return errors.Errorf("cannot be set to a non-positive value: %d", v)
+	}
+	return nil
+})
+
+// NonNegativeInt checks the value is zero or positive. It can be
+// passed to RegisterIntSetting.
+var NonNegativeInt SettingOption = WithValidateInt(nonNegativeIntInternal)
+
+func nonNegativeIntInternal(v int64) error {
+	if v < 0 {
+		return errors.Errorf("cannot be set to a negative value: %d", v)
+	}
+	return nil
+}
+
+// IntWithMinimum returns a validation option that checks
+// that the value is greater or equal to the given minimum. It can be
+// passed to RegisterIntSetting.
+func IntWithMinimum(minVal int64) SettingOption {
+	return WithValidateInt(func(v int64) error {
+		if minVal >= 0 {
+			if err := nonNegativeIntInternal(v); err != nil {
+				return err
+			}
+		}
+		if v < minVal {
+			return errors.Errorf("cannot be set to a value lower than %d: %d", minVal, v)
+		}
+		return nil
+	})
+}
+
+// NonNegativeIntWithMaximum returns a validation option that checks
+// that the value is in the range [0, maxValue]. It can be passed to
+// RegisterIntSetting.
+func NonNegativeIntWithMaximum(maxValue int64) SettingOption {
+	return IntInRange(0, maxValue)
+}
+
+// IntInRange returns a validation option that checks the value is
+// within the given bounds (inclusive). It can be passed to
+// RegisterIntSetting.
+func IntInRange(minVal, maxVal int64) SettingOption {
+	return WithValidateInt(func(v int64) error {
+		if v < minVal || v > maxVal {
+			return errors.Errorf("expected value in range [%d, %d], got: %d", minVal, maxVal, v)
+		}
+		return nil
+	})
+}
+
+// IntInRangeOrZeroDisable returns a validation option that checks the
+// value is within the given bounds (inclusive) or is zero (disabled).
+// It can be passed to RegisterIntSetting.
+func IntInRangeOrZeroDisable(minVal, maxVal int64) SettingOption {
+	return WithValidateInt(func(v int64) error {
+		if v != 0 && (v < minVal || v > maxVal) {
+			return errors.Errorf("expected value in range [%d, %d] or 0 to disable, got: %d", minVal, maxVal, v)
+		}
+		return nil
+	})
+}
diff --git a/pkg/settings/masked.go b/pkg/settings/masked.go
new file mode 100644
index 0000000..8776cdb
--- /dev/null
+++ b/pkg/settings/masked.go
@@ -0,0 +1,92 @@
+// Copyright 2019 The Cockroach Authors.
+//
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
+
+package settings
+
+import "context"
+
+// MaskedSetting is a wrapper for non-reportable settings that were retrieved
+// for reporting (see SetReportable and LookupForReportingByKey).
+type MaskedSetting struct {
+	setting NonMaskedSetting
+}
+
+var _ Setting = &MaskedSetting{}
+
+// redactSensitiveSettingsEnabled enables or disables the redaction of sensitive
+// cluster settings.
+var redactSensitiveSettingsEnabled = RegisterBoolSetting(
+	ApplicationLevel,
+	"server.redact_sensitive_settings.enabled",
+	"enables or disables the redaction of sensitive settings in the output of SHOW CLUSTER SETTINGS and "+
+		"SHOW ALL CLUSTER SETTINGS for users without the MODIFYCLUSTERSETTING privilege",
+	false,
+	WithPublic,
+)
+
+// String hides the underlying value.
+func (s *MaskedSetting) String(sv *Values) string {
+	// Special case for non-reportable/sensitive strings: we still want
+	// to distinguish empty from non-empty (= customized).
+	if st, ok := s.setting.(*StringSetting); ok && st.String(sv) == "" {
+		return ""
+	}
+	isSensitive := false
+	if st, ok := s.setting.(internalSetting); ok {
+		isSensitive = st.isSensitive()
+	}
+	sensitiveRedactionEnabled := redactSensitiveSettingsEnabled.Get(sv)
+	// Non-reportable settings are always redacted. Sensitive settings are
+	// redacted if the redaction cluster setting is enabled.
+	if !isSensitive || sensitiveRedactionEnabled {
+		return "<redacted>"
+	}
+	return s.setting.String(sv)
+}
+
+// DefaultString returns the default value for the setting as a string.
+func (s *MaskedSetting) DefaultString() string {
+	return s.setting.DefaultString()
+}
+
+// Visibility returns the visibility setting for the underlying setting.
+func (s *MaskedSetting) Visibility() Visibility {
+	return s.setting.Visibility()
+}
+
+// InternalKey returns the key string for the underlying setting.
+func (s *MaskedSetting) InternalKey() InternalKey {
+	return s.setting.InternalKey()
+}
+
+// Name returns the name string for the underlying setting.
+func (s *MaskedSetting) Name() SettingName {
+	return s.setting.Name()
+}
+
+// Description returns the description string for the underlying setting.
+func (s *MaskedSetting) Description() string {
+	return s.setting.Description()
+}
+
+// Typ returns the short (1 char) string denoting the type of setting.
+func (s *MaskedSetting) Typ() string {
+	return s.setting.Typ()
+}
+
+// Class returns the class for the underlying setting.
+func (s *MaskedSetting) Class() Class {
+	return s.setting.Class()
+}
+
+// ValueOrigin returns the origin of the current value of the setting.
+func (s *MaskedSetting) ValueOrigin(ctx context.Context, sv *Values) ValueOrigin {
+	return s.setting.ValueOrigin(ctx, sv)
+}
+
+// IsUnsafe returns whether the underlying setting is unsafe.
+func (s *MaskedSetting) IsUnsafe() bool {
+	return s.setting.IsUnsafe()
+}
diff --git a/pkg/settings/options.go b/pkg/settings/options.go
new file mode 100644
index 0000000..e030b93
--- /dev/null
+++ b/pkg/settings/options.go
@@ -0,0 +1,128 @@
+// Copyright 2023 The Cockroach Authors.
+//
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
+
+package settings
+
+import (
+	"time"
+
+	"github.com/cockroachdb/cockroachdb-parser/pkg/util/protoutil"
+)
+
+// SettingOption is the type of an option that can be passed to Register.
+type SettingOption struct {
+	commonOpt          func(*common)
+	validateBoolFn     func(*Values, bool) error
+	validateDurationFn func(time.Duration) error
+	validateInt64Fn    func(int64) error
+	validateFloat64Fn  func(float64) error
+	validateStringFn   func(*Values, string) error
+	validateProtoFn    func(*Values, protoutil.Message) error
+}
+
+// NameStatus indicates the status of a setting name.
+type NameStatus bool
+
+const (
+	// NameActive indicates that the name is currently in use.
+	NameActive NameStatus = true
+	// NameRetired indicates that the name is no longer in use.
+	NameRetired NameStatus = false
+)
+
+// WithName configures the user-visible name of the setting.
+func WithName(name SettingName) SettingOption {
+	return SettingOption{commonOpt: func(c *common) {
+		c.setName(name)
+		registerAlias(c.key, name, NameActive)
+	}}
+}
+
+// WithRetiredName configures a previous user-visible name of the setting,
+// when that name was different from the key and is not in use any more.
+func WithRetiredName(name SettingName) SettingOption {
+	return SettingOption{commonOpt: func(c *common) {
+		registerAlias(c.key, name, NameRetired)
+	}}
+}
+
+// WithVisibility customizes the visibility of a setting.
+func WithVisibility(v Visibility) SettingOption {
+	return SettingOption{commonOpt: func(c *common) {
+		c.setVisibility(v)
+	}}
+}
+
+// WithUnsafe indicates that the setting is unsafe.
+// Unsafe settings need an interlock to be updated. They also cannot be public.
+var WithUnsafe SettingOption = SettingOption{commonOpt: func(c *common) {
+	c.setUnsafe()
+}}
+
+// WithPublic sets public visibility.
+var WithPublic SettingOption = WithVisibility(Public)
+
+// WithReportable indicates whether a setting's value can show up in SHOW ALL
+// CLUSTER SETTINGS and telemetry reports.
+func WithReportable(reportable bool) SettingOption {
+	return SettingOption{commonOpt: func(c *common) {
+		c.setReportable(reportable)
+	}}
+}
+
+// Retired marks the setting as obsolete. It also hides it from the
+// output of SHOW CLUSTER SETTINGS. Note: in many case the setting
+// definition can be removed outright, and its name added to the
+// retiredSettings map (in settings/registry.go). The Retired option
+// exists for cases where there is a need to maintain compatibility
+// with automation.
+var Retired SettingOption = SettingOption{commonOpt: func(c *common) {
+	c.setRetired()
+}}
+
+// Sensitive marks the setting as sensitive, which means that it will always
+// be redacted in any output. It also makes the setting non-reportable. It can
+// only be used for string settings.
+var Sensitive SettingOption = SettingOption{commonOpt: func(c *common) {
+	c.setSensitive()
+}}
+
+// WithValidateDuration adds a validation function for a duration setting.
+func WithValidateDuration(fn func(time.Duration) error) SettingOption {
+	return SettingOption{validateDurationFn: fn}
+}
+
+// WithValidateInt adds a validation function for an int64 setting.
+func WithValidateInt(fn func(int64) error) SettingOption {
+	return SettingOption{validateInt64Fn: fn}
+}
+
+// WithValidateFloat adds a validation function for a float64 setting.
+func WithValidateFloat(fn func(float64) error) SettingOption {
+	return SettingOption{validateFloat64Fn: fn}
+}
+
+// WithValidateBool adds a validation function for a boolean setting.
+func WithValidateBool(fn func(*Values, bool) error) SettingOption {
+	return SettingOption{validateBoolFn: fn}
+}
+
+// WithValidateString adds a validation function for a string setting.
+func WithValidateString(fn func(*Values, string) error) SettingOption {
+	return SettingOption{validateStringFn: fn}
+}
+
+// WithValidateProto adds a validation function for a proto setting.
+func WithValidateProto(fn func(*Values, protoutil.Message) error) SettingOption {
+	return SettingOption{validateProtoFn: fn}
+}
+
+func (c *common) apply(opts []SettingOption) {
+	for _, opt := range opts {
+		if opt.commonOpt != nil {
+			opt.commonOpt(c)
+		}
+	}
+}
diff --git a/pkg/settings/protobuf.go b/pkg/settings/protobuf.go
new file mode 100644
index 0000000..c38f572
--- /dev/null
+++ b/pkg/settings/protobuf.go
@@ -0,0 +1,241 @@
+// Copyright 2022 The Cockroach Authors.
+//
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
+
+package settings
+
+import (
+	"context"
+	"reflect"
+	"strings"
+
+	"github.com/cockroachdb/cockroachdb-parser/pkg/util/protoutil"
+	"github.com/cockroachdb/errors"
+	"github.com/gogo/protobuf/jsonpb"
+	"github.com/gogo/protobuf/proto"
+)
+
+// ProtobufSetting is the interface of a setting variable that will be updated
+// automatically when the corresponding cluster-wide setting of type "protobuf"
+// is updated. The proto message is held in memory, the byte representation
+// stored in system.settings, and JSON presentation used when accepting input
+// and rendering (just through SHOW CLUSTER SETTING <setting-name>, the raw form
+// is visible when looking directly at system.settings).
+type ProtobufSetting struct {
+	defaultValue protoutil.Message
+	validateFn   func(*Values, protoutil.Message) error
+	common
+}
+
+var _ internalSetting = &ProtobufSetting{}
+
+// String returns the string representation of the setting's current value.
+func (s *ProtobufSetting) String(sv *Values) string {
+	p := s.Get(sv)
+	json, err := s.MarshalToJSON(p)
+	if err != nil {
+		panic(errors.Wrapf(err, "marshaling %s: %+v", proto.MessageName(p), p))
+	}
+	return json
+}
+
+// DefaultString returns the default value for the setting as a string.
+func (s *ProtobufSetting) DefaultString() string {
+	json, err := s.MarshalToJSON(s.defaultValue)
+	if err != nil {
+		panic(errors.Wrapf(err, "marshaling %s: %+v", proto.MessageName(s.defaultValue), s.defaultValue))
+	}
+	return json
+}
+
+// Encoded returns the encoded value of the current value of the setting.
+func (s *ProtobufSetting) Encoded(sv *Values) string {
+	p := s.Get(sv)
+	return EncodeProtobuf(p)
+}
+
+// EncodedDefault returns the encoded value of the default value of the setting.
+func (s *ProtobufSetting) EncodedDefault() string {
+	return EncodeProtobuf(s.defaultValue)
+}
+
+// DecodeToString decodes and renders an encoded value.
+func (s *ProtobufSetting) DecodeToString(encoded string) (string, error) {
+	message, err := s.DecodeValue(encoded)
+	if err != nil {
+		return "", err
+	}
+	return s.MarshalToJSON(message)
+}
+
+// Typ returns the short (1 char) string denoting the type of setting.
+func (*ProtobufSetting) Typ() string {
+	return "p"
+}
+
+// DecodeValue decodes the value into a protobuf.
+func (s *ProtobufSetting) DecodeValue(encoded string) (protoutil.Message, error) {
+	p, err := newProtoMessage(proto.MessageName(s.defaultValue))
+	if err != nil {
+		return nil, err
+	}
+
+	if err := protoutil.Unmarshal([]byte(encoded), p); err != nil {
+		return nil, err
+	}
+	return p, nil
+}
+
+// Default returns default value for setting.
+func (s *ProtobufSetting) Default() protoutil.Message {
+	return s.defaultValue
+}
+
+// Get retrieves the protobuf value in the setting.
+func (s *ProtobufSetting) Get(sv *Values) protoutil.Message {
+	loaded := sv.getGeneric(s.slot)
+	if loaded == nil {
+		return s.defaultValue
+	}
+	return loaded.(protoutil.Message)
+}
+
+// Validate that a value conforms with the validation function.
+func (s *ProtobufSetting) Validate(sv *Values, p protoutil.Message) error {
+	if s.validateFn == nil {
+		return nil // nothing to do
+	}
+	return s.validateFn(sv, p)
+}
+
+// Override sets the setting to the given value, assuming it passes validation.
+func (s *ProtobufSetting) Override(ctx context.Context, sv *Values, p protoutil.Message) {
+	sv.setValueOrigin(ctx, s.slot, OriginOverride)
+	_ = s.set(ctx, sv, p)
+	sv.setDefaultOverride(s.slot, p)
+}
+
+func (s *ProtobufSetting) decodeAndSet(ctx context.Context, sv *Values, encoded string) error {
+	p, err := s.DecodeValue(encoded)
+	if err != nil {
+		return err
+	}
+	return s.set(ctx, sv, p)
+}
+
+func (s *ProtobufSetting) decodeAndSetDefaultOverride(
+	ctx context.Context, sv *Values, encoded string,
+) error {
+	p, err := s.DecodeValue(encoded)
+	if err != nil {
+		return err
+	}
+	sv.setDefaultOverride(s.slot, p)
+	return nil
+}
+
+func (s *ProtobufSetting) set(ctx context.Context, sv *Values, p protoutil.Message) error {
+	if err := s.Validate(sv, p); err != nil {
+		return err
+	}
+	if s.Get(sv) != p {
+		sv.setGeneric(ctx, s.slot, p)
+	}
+	return nil
+}
+
+func (s *ProtobufSetting) setToDefault(ctx context.Context, sv *Values) {
+	// See if the default value was overridden.
+	if val := sv.getDefaultOverride(s.slot); val != nil {
+		// As per the semantics of override, these values don't go through
+		// validation.
+		_ = s.set(ctx, sv, val.(protoutil.Message))
+		return
+	}
+	if err := s.set(ctx, sv, s.defaultValue); err != nil {
+		panic(err)
+	}
+}
+
+// MarshalToJSON returns a JSON representation of the protobuf.
+func (s *ProtobufSetting) MarshalToJSON(p protoutil.Message) (string, error) {
+	jsonEncoder := jsonpb.Marshaler{EmitDefaults: false}
+	return jsonEncoder.MarshalToString(p)
+}
+
+// UnmarshalFromJSON unmarshals a protobuf from a json representation.
+func (s *ProtobufSetting) UnmarshalFromJSON(jsonEncoded string) (protoutil.Message, error) {
+	p, err := newProtoMessage(proto.MessageName(s.defaultValue))
+	if err != nil {
+		return nil, err
+	}
+
+	json := &jsonpb.Unmarshaler{}
+	if err := json.Unmarshal(strings.NewReader(jsonEncoded), p); err != nil {
+		return nil, errors.Wrapf(err, "unmarshaling json to %s", proto.MessageName(p))
+	}
+	return p, nil
+}
+
+// RegisterProtobufSetting defines a new setting with type protobuf.
+func RegisterProtobufSetting(
+	class Class, key InternalKey, desc string, defaultValue protoutil.Message, opts ...SettingOption,
+) *ProtobufSetting {
+	validateFn := func(sv *Values, p protoutil.Message) error {
+		for _, opt := range opts {
+			switch {
+			case opt.commonOpt != nil:
+				continue
+			case opt.validateProtoFn != nil:
+			default:
+				panic(errors.AssertionFailedf("wrong validator type"))
+			}
+			if err := opt.validateProtoFn(sv, p); err != nil {
+				return err
+			}
+		}
+		return nil
+	}
+	setting := &ProtobufSetting{
+		defaultValue: defaultValue,
+		validateFn:   validateFn,
+	}
+
+	// By default, all protobuf settings are considered to contain PII and are
+	// thus non-reportable (to exclude them from telemetry reports).
+	setting.setReportable(false)
+	register(class, key, desc, setting)
+	setting.apply(opts)
+	return setting
+}
+
+// Defeat the unused linter.
+var _ = (*ProtobufSetting).Default
+
+// newProtoMessage creates a new protocol message object, given its fully
+// qualified name.
+func newProtoMessage(name string) (protoutil.Message, error) {
+	// Get the reflected type of the protocol message.
+	rt := proto.MessageType(name)
+	if rt == nil {
+		return nil, errors.Newf("unknown proto message type %s", name)
+	}
+
+	// If the message is known, we should get the pointer to our message.
+	if rt.Kind() != reflect.Ptr {
+		return nil, errors.AssertionFailedf(
+			"expected ptr to message, got %s instead", rt.Kind().String())
+	}
+
+	// Construct message of appropriate type, through reflection.
+	rv := reflect.New(rt.Elem())
+	msg, ok := rv.Interface().(protoutil.Message)
+	if !ok {
+		// Just to be safe.
+		return nil, errors.AssertionFailedf(
+			"unexpected proto type for %s; expected protoutil.Message, got %T",
+			name, rv.Interface())
+	}
+	return msg, nil
+}
diff --git a/pkg/settings/registry.go b/pkg/settings/registry.go
new file mode 100644
index 0000000..e6e2321
--- /dev/null
+++ b/pkg/settings/registry.go
@@ -0,0 +1,574 @@
+// Copyright 2017 The Cockroach Authors.
+//
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
+
+package settings
+
+import (
+	"fmt"
+	"sort"
+	"strings"
+)
+
+// registry contains all defined settings, their types and default values.
+//
+// The registry does not store the current values of the settings; those are
+// stored separately in Values, allowing multiple independent instances
+// of each setting in the registry.
+//
+// registry should never be mutated after creation (except in tests), as it is
+// read concurrently by different callers.
+var registry = make(map[InternalKey]internalSetting)
+
+// tenantReadOnlyKeys contains the keys of settings that have the
+// class SystemVisible. This is used to initialize defaults in the
+// tenant settings watcher.
+var tenantReadOnlyKeys []InternalKey
+
+// aliasRegistry contains the mapping of names to keys, for names
+// different from the keys.
+var aliasRegistry = make(map[SettingName]aliasEntry)
+
+type aliasEntry struct {
+	// key is the setting this name is referring to.
+	key InternalKey
+	// active indicates whether this name is currently in use.
+	active NameStatus
+}
+
+// slotTable stores the same settings as the registry, but accessible by the
+// slot index.
+var slotTable [MaxSettings]internalSetting
+
+// TestingSaveRegistry can be used in tests to save/restore the current
+// contents of the registry.
+func TestingSaveRegistry() func() {
+	var origRegistry = make(map[InternalKey]internalSetting)
+	for k, v := range registry {
+		origRegistry[k] = v
+	}
+	var origAliases = make(map[SettingName]aliasEntry)
+	for k, v := range aliasRegistry {
+		origAliases[k] = v
+	}
+	var origSystemVisibleKeys = make([]InternalKey, len(tenantReadOnlyKeys))
+	copy(origSystemVisibleKeys, tenantReadOnlyKeys)
+	return func() {
+		registry = origRegistry
+		aliasRegistry = origAliases
+		tenantReadOnlyKeys = origSystemVisibleKeys
+	}
+}
+
+// When a setting class changes from ApplicationLevel to System, it should
+// be added to this list so that we can offer graceful degradation to
+// users of previous versions.
+var systemSettingsWithPreviousApplicationClass = map[InternalKey]struct{}{
+	// Changed in v23.2.
+	"cluster.organization":                        {},
+	"enterprise.license":                          {},
+	"kv.bulk_io_write.concurrent_export_requests": {},
+	"kv.closed_timestamp.propagation_slack":       {},
+	"kv.closed_timestamp.side_transport_interval": {},
+	"kv.closed_timestamp.target_duration":         {},
+	"kv.raft.command.max_size":                    {},
+	"kv.rangefeed.enabled":                        {},
+	"server.rangelog.ttl":                         {},
+	"timeseries.storage.enabled":                  {},
+	"timeseries.storage.resolution_10s.ttl":       {},
+	"timeseries.storage.resolution_30m.ttl":       {},
+}
+
+// SettingPreviouslyHadApplicationClass returns true if the setting
+// used to have the ApplicationLevel class.
+func SettingPreviouslyHadApplicationClass(key InternalKey) bool {
+	_, ok := systemSettingsWithPreviousApplicationClass[key]
+	return ok
+}
+
+// When a setting is removed, it should be added to this list so that we cannot
+// accidentally reuse its name, potentially mis-handling older values.
+var retiredSettings = map[InternalKey]struct{}{
+	// removed as of 2.0.
+	"kv.gc.batch_size":                     {},
+	"kv.transaction.max_intents":           {},
+	"diagnostics.reporting.report_metrics": {},
+	// removed as of 2.1.
+	"kv.allocator.stat_based_rebalancing.enabled": {},
+	"kv.allocator.stat_rebalance_threshold":       {},
+	// removed as of 19.1.
+	"kv.raft_log.synchronize": {},
+	// removed as of 19.2.
+	"schemachanger.bulk_index_backfill.enabled":            {},
+	"rocksdb.ingest_backpressure.delay_l0_file":            {}, // never used
+	"server.heap_profile.system_memory_threshold_fraction": {},
+	"timeseries.storage.10s_resolution_ttl":                {},
+	"changefeed.push.enabled":                              {},
+	"sql.defaults.optimizer":                               {},
+	"kv.bulk_io_write.addsstable_max_rate":                 {},
+	// removed as of 20.1.
+	"schemachanger.lease.duration":           {},
+	"schemachanger.lease.renew_fraction":     {},
+	"diagnostics.forced_stat_reset.interval": {},
+	// removed as of 20.2.
+	"rocksdb.ingest_backpressure.pending_compaction_threshold":         {},
+	"sql.distsql.temp_storage.joins":                                   {},
+	"sql.distsql.temp_storage.sorts":                                   {},
+	"sql.distsql.distribute_index_joins":                               {},
+	"sql.distsql.merge_joins.enabled":                                  {},
+	"sql.defaults.optimizer_foreign_keys.enabled":                      {},
+	"sql.defaults.experimental_optimizer_foreign_key_cascades.enabled": {},
+	"sql.parallel_scans.enabled":                                       {},
+	"backup.table_statistics.enabled":                                  {},
+	// removed as of 21.1.
+	"sql.distsql.interleaved_joins.enabled": {},
+	"sql.testing.vectorize.batch_size":      {},
+	"sql.testing.mutations.max_batch_size":  {},
+	"sql.testing.mock_contention.enabled":   {},
+	"kv.atomic_replication_changes.enabled": {},
+	// removed as of 21.1.2.
+	"kv.tenant_rate_limiter.read_requests.rate_limit":   {},
+	"kv.tenant_rate_limiter.read_requests.burst_limit":  {},
+	"kv.tenant_rate_limiter.write_requests.rate_limit":  {},
+	"kv.tenant_rate_limiter.write_requests.burst_limit": {},
+	"kv.tenant_rate_limiter.read_bytes.rate_limit":      {},
+	"kv.tenant_rate_limiter.read_bytes.burst_limit":     {},
+	"kv.tenant_rate_limiter.write_bytes.rate_limit":     {},
+	"kv.tenant_rate_limiter.write_bytes.burst_limit":    {},
+
+	// removed as of 21.2.
+	"sql.defaults.vectorize_row_count_threshold":                     {},
+	"cloudstorage.gs.default.key":                                    {},
+	"storage.sst_export.max_intents_per_error":                       {},
+	"jobs.registry.leniency":                                         {},
+	"sql.defaults.experimental_expression_based_indexes.enabled":     {},
+	"kv.transaction.write_pipelining_max_outstanding_size":           {},
+	"sql.defaults.optimizer_improve_disjunction_selectivity.enabled": {},
+	"bulkio.backup.proxy_file_writes.enabled":                        {},
+	"sql.distsql.prefer_local_execution.enabled":                     {},
+	"kv.follower_read.target_multiple":                               {},
+	"kv.closed_timestamp.close_fraction":                             {},
+	"sql.telemetry.query_sampling.qps_threshold":                     {},
+	"sql.telemetry.query_sampling.sample_rate":                       {},
+	"diagnostics.sql_stat_reset.interval":                            {},
+	"changefeed.mem.pushback_enabled":                                {},
+	"sql.distsql.index_join_limit_hint.enabled":                      {},
+
+	// removed as of 22.1.
+	"sql.defaults.drop_enum_value.enabled":                             {},
+	"trace.lightstep.token":                                            {},
+	"trace.datadog.agent":                                              {},
+	"trace.datadog.project":                                            {},
+	"sql.defaults.interleaved_tables.enabled":                          {},
+	"sql.defaults.copy_partitioning_when_deinterleaving_table.enabled": {},
+	"server.declined_reservation_timeout":                              {},
+	"bulkio.backup.resolve_destination_in_job.enabled":                 {},
+	"sql.defaults.experimental_hash_sharded_indexes.enabled":           {},
+	"schemachanger.backfiller.max_sst_size":                            {},
+	"kv.bulk_ingest.buffer_increment":                                  {},
+	"schemachanger.backfiller.buffer_increment":                        {},
+	"kv.rangefeed.separated_intent_scan.enabled":                       {},
+
+	// removed as of 22.1.2.
+	"tenant_cost_model.kv_read_request_cost":            {},
+	"tenant_cost_model.kv_read_cost_per_megabyte":       {},
+	"tenant_cost_model.kv_write_request_cost":           {},
+	"tenant_cost_model.kv_write_cost_per_megabyte":      {},
+	"tenant_cost_model.pod_cpu_second_cost":             {},
+	"tenant_cost_model.pgwire_egress_cost_per_megabyte": {},
+	"sql.ttl.range_batch_size":                          {},
+
+	// removed as of 22.2.
+	"bulkio.restore_at_current_time.enabled":                    {},
+	"bulkio.import_at_current_time.enabled":                     {},
+	"kv.bulk_io_write.experimental_incremental_export_enabled":  {},
+	"kv.bulk_io_write.revert_range_time_bound_iterator.enabled": {},
+	"kv.rangefeed.catchup_scan_iterator_optimization.enabled":   {},
+	"kv.refresh_range.time_bound_iterators.enabled":             {},
+	"sql.defaults.datestyle.enabled":                            {},
+	"sql.defaults.intervalstyle.enabled":                        {},
+
+	// removed as of 22.2.1
+	"sql.ttl.default_range_concurrency":                {},
+	"server.web_session.purge.period":                  {},
+	"server.web_session.purge.max_deletions_per_cycle": {},
+	"server.web_session.auto_logout.timeout":           {},
+
+	// removed as of 23.1.
+	"sql.auth.modify_cluster_setting_applies_to_all.enabled": {},
+	"sql.catalog.descs.validate_on_write.enabled":            {},
+	"sql.distsql.max_running_flows":                          {},
+	"sql.distsql.flow_scheduler_queueing.enabled":            {},
+	"sql.distsql.drain.cancel_after_wait.enabled":            {},
+	"changefeed.active_protected_timestamps.enabled":         {},
+	"jobs.scheduler.single_node_scheduler.enabled":           {},
+	"tenant_capabilities.authorizer.enabled":                 {},
+	// renamed.
+	"spanconfig.host_coalesce_adjacent.enabled":            {},
+	"sql.defaults.experimental_stream_replication.enabled": {},
+	"sql.drop_tenant.enabled":                              {},
+
+	// removed as of 23.2.
+	"sql.log.unstructured_entries.enabled":                     {},
+	"sql.auth.createrole_allows_grant_role_membership.enabled": {},
+	"changefeed.replan_flow_frequency":                         {},
+	"changefeed.replan_flow_threshold":                         {},
+	"jobs.trace.force_dump_mode":                               {},
+	"timeseries.storage.30m_resolution_ttl":                    {},
+	"server.cpu_profile.enabled":                               {},
+	"changefeed.lagging_ranges_threshold":                      {},
+	"changefeed.lagging_ranges_polling_rate":                   {},
+	"trace.jaeger.agent":                                       {},
+	"bulkio.restore.use_simple_import_spans":                   {},
+	"bulkio.restore.remove_regions.enabled":                    {},
+
+	// removed as of 24.1
+	"storage.mvcc.range_tombstones.enabled":                  {},
+	"changefeed.balance_range_distribution.enable":           {},
+	"changefeed.mux_rangefeed.enabled":                       {},
+	"kv.rangefeed.catchup_scan_concurrency":                  {},
+	"physical_replication.producer.mux_rangefeeds.enabled":   {},
+	"kv.rangefeed.use_dedicated_connection_class.enabled":    {},
+	"sql.trace.session_eventlog.enabled":                     {},
+	"sql.show_ranges_deprecated_behavior.enabled":            {},
+	"sql.drop_virtual_cluster.enabled":                       {},
+	"cross_cluster_replication.enabled":                      {},
+	"server.controller.default_tenant.check_service.enabled": {},
+
+	// removed as of 24.2
+	"storage.value_blocks.enabled":       {},
+	"kv.gc.sticky_hint.enabled":          {},
+	"kv.rangefeed.range_stuck_threshold": {},
+
+	// removed as of 24.3
+	"bulkio.backup.split_keys_on_timestamps":           {},
+	"sql.create_tenant.default_template":               {},
+	"kvadmission.low_pri_read_elastic_control.enabled": {},
+
+	// removed as of 25.1
+	"sql.auth.resolve_membership_single_scan.enabled":            {},
+	"storage.single_delete.crash_on_invariant_violation.enabled": {},
+	"storage.single_delete.crash_on_ineffectual.enabled":         {},
+	"bulkio.backup.elide_common_prefix.enabled":                  {},
+	"kv.bulkio.write_metadata_sst.enabled":                       {},
+	"jobs.execution_errors.max_entries":                          {},
+	"jobs.execution_errors.max_entry_size":                       {},
+	"sql.metrics.statement_details.plan_collection.enabled":      {},
+	"sql.metrics.statement_details.plan_collection.period":       {},
+
+	// removed as of 25.2
+	"kv.snapshot_receiver.excise.enabled":                    {},
+	"kv.mvcc_gc.queue_kv_admission_control.enabled":          {},
+	"sql.catalog.experimental_use_session_based_leasing":     {},
+	"bulkio.backup.merge_file_buffer_size":                   {},
+	"changefeed.new_webhook_sink_enabled":                    {},
+	"changefeed.new_webhook_sink.enabled":                    {},
+	"changefeed.new_pubsub_sink_enabled":                     {},
+	"changefeed.new_pubsub_sink.enabled":                     {},
+	"logical_replication.consumer.use_implicit_txns.enabled": {},
+}
+
+// grandfatheredDefaultSettings is the list of "grandfathered" existing sql.defaults
+// cluster settings. In 22.2 and later, new session settings do not need an
+// associated sql.defaults cluster setting (see the `vector_search_beam_size`
+// setting in vars.go for an example). A session setting can have its default
+// changed with ALTER ROLE ... SET, similar to this (the example assumes that
+// all roles should use the new default):
+//
+//	ALTER ROLE ALL SET vector_search_beam_size=128;
+//
+// Caveat: in some cases, we may still add new sql.defaults cluster settings,
+// but the new ones *must* be marked as non-public. Undocumented settings are
+// excluded from the check that prevents new sql.defaults settings. The
+// reason for this is that the rollout automation framework used in
+// CockroachCloud works by using cluster settings. If we want to slowly roll out
+// a feature that is gated behind a session setting, using a non-public
+// sql.defaults cluster setting is the recommended way to do so.
+var grandfatheredDefaultSettings = map[InternalKey]struct{}{
+	// PLEASE DO NOT ADD NEW SETTINGS TO THIS MAP. THANK YOU.
+	"sql.defaults.cost_scans_with_default_col_size.enabled":                     {},
+	"sql.defaults.datestyle":                                                    {},
+	"sql.defaults.datestyle.enabled":                                            {},
+	"sql.defaults.deadlock_timeout":                                             {},
+	"sql.defaults.default_hash_sharded_index_bucket_count":                      {},
+	"sql.defaults.default_int_size":                                             {},
+	"sql.defaults.disallow_full_table_scans.enabled":                            {},
+	"sql.defaults.distsql":                                                      {},
+	"sql.defaults.experimental_alter_column_type.enabled":                       {},
+	"sql.defaults.experimental_auto_rehoming.enabled":                           {},
+	"sql.defaults.experimental_computed_column_rewrites":                        {},
+	"sql.defaults.experimental_distsql_planning":                                {},
+	"sql.defaults.experimental_enable_unique_without_index_constraints.enabled": {},
+	"sql.defaults.experimental_implicit_column_partitioning.enabled":            {},
+	"sql.defaults.experimental_temporary_tables.enabled":                        {},
+	"sql.defaults.foreign_key_cascades_limit":                                   {},
+	"sql.defaults.idle_in_session_timeout":                                      {},
+	"sql.defaults.idle_in_transaction_session_timeout":                          {},
+	"sql.defaults.implicit_select_for_update.enabled":                           {},
+	"sql.defaults.insert_fast_path.enabled":                                     {},
+	"sql.defaults.intervalstyle":                                                {},
+	"sql.defaults.intervalstyle.enabled":                                        {},
+	"sql.defaults.large_full_scan_rows":                                         {},
+	"sql.defaults.locality_optimized_partitioned_index_scan.enabled":            {},
+	"sql.defaults.lock_timeout":                                                 {},
+	"sql.defaults.multiregion_placement_policy.enabled":                         {},
+	"sql.defaults.on_update_rehome_row.enabled":                                 {},
+	"sql.defaults.optimizer_use_histograms.enabled":                             {},
+	"sql.defaults.optimizer_use_multicol_stats.enabled":                         {},
+	"sql.defaults.override_alter_primary_region_in_super_region.enabled":        {},
+	"sql.defaults.override_multi_region_zone_config.enabled":                    {},
+	"sql.defaults.prefer_lookup_joins_for_fks.enabled":                          {},
+	"sql.defaults.primary_region":                                               {},
+	"sql.defaults.propagate_input_ordering.enabled":                             {},
+	"sql.defaults.reorder_joins_limit":                                          {},
+	"sql.defaults.require_explicit_primary_keys.enabled":                        {},
+	"sql.defaults.results_buffer.size":                                          {},
+	"sql.defaults.serial_normalization":                                         {},
+	"sql.defaults.serial_sequences_cache_size":                                  {},
+	"sql.defaults.statement_timeout":                                            {},
+	"sql.defaults.stub_catalog_tables.enabled":                                  {},
+	"sql.defaults.super_regions.enabled":                                        {},
+	"sql.defaults.transaction_rows_read_err":                                    {},
+	"sql.defaults.transaction_rows_read_log":                                    {},
+	"sql.defaults.transaction_rows_written_err":                                 {},
+	"sql.defaults.transaction_rows_written_log":                                 {},
+	"sql.defaults.use_declarative_schema_changer":                               {},
+	"sql.defaults.vectorize":                                                    {},
+	"sql.defaults.zigzag_join.enabled":                                          {},
+}
+
+// checkNameFound verifies whether the given string is known as key or name.
+func checkNameFound(keyOrName string) {
+	if _, ok := retiredSettings[InternalKey(keyOrName)]; ok {
+		panic(fmt.Sprintf("cannot reuse previously defined setting key: %s", InternalKey(keyOrName)))
+	}
+	if _, ok := registry[InternalKey(keyOrName)]; ok {
+		panic(fmt.Sprintf("setting already defined: %s", keyOrName))
+	}
+	if a, ok := aliasRegistry[SettingName(keyOrName)]; ok {
+		panic(fmt.Sprintf("setting already defined: %s (with key %s)", keyOrName, a.key))
+	}
+}
+
+// register adds a setting to the registry.
+func register(class Class, key InternalKey, desc string, s internalSetting) {
+	checkNameFound(string(key))
+	if strings.Contains(string(key), "sql.defaults") {
+		_, grandfathered := grandfatheredDefaultSettings[key]
+		if !grandfathered && s.Visibility() != Reserved {
+			panic(fmt.Sprintf(
+				"new sql.defaults cluster settings: %s is not needed now that `ALTER ROLE ... SET` syntax "+
+					"is supported; please remove the new sql.defaults cluster setting or make it non-public", key))
+		}
+	}
+
+	slot := slotIdx(len(registry))
+	s.init(class, key, desc, slot)
+	registry[key] = s
+	slotTable[slot] = s
+	if class == SystemVisible {
+		tenantReadOnlyKeys = append(tenantReadOnlyKeys, key)
+	}
+}
+
+func registerAlias(key InternalKey, name SettingName, nameStatus NameStatus) {
+	checkNameFound(string(name))
+	aliasRegistry[name] = aliasEntry{key: key, active: nameStatus}
+}
+
+// NumRegisteredSettings returns the number of registered settings.
+func NumRegisteredSettings() int { return len(registry) }
+
+// Keys returns a sorted string array with all the known keys.
+func Keys(forSystemTenant bool) (res []InternalKey) {
+	res = make([]InternalKey, 0, len(registry))
+	for k, v := range registry {
+		if v.isRetired() {
+			continue
+		}
+		if !forSystemTenant && v.Class() == SystemOnly {
+			continue
+		}
+		res = append(res, k)
+	}
+	sort.Slice(res, func(i, j int) bool { return res[i] < res[j] })
+	return res
+}
+
+// SystemVisibleKeys returns a array with all the known keys that
+// have the class SystemVisible. It might not be sorted.
+// The caller must refrain from modifying the return value.
+func SystemVisibleKeys() []InternalKey {
+	return tenantReadOnlyKeys
+}
+
+// ConsoleKeys return an array with all cluster settings keys
+// used by the UI Console.
+// This list should only contain settings that have no sensitive
+// information, because it will be returned on `settings` endpoint for
+// users without VIEWCLUSTERSETTING or MODIFYCLUSTERSETTING permission,
+// but that have VIEWACTIVITY or VIEWACTIVITYREDACTED permissions.
+func ConsoleKeys() (res []InternalKey) {
+	return allConsoleKeys
+}
+
+var allConsoleKeys = []InternalKey{
+	"keyvisualizer.enabled",
+	"keyvisualizer.sample_interval",
+	"sql.index_recommendation.drop_unused_duration",
+	"sql.insights.anomaly_detection.latency_threshold",
+	"sql.insights.high_retry_count.threshold",
+	"sql.insights.latency_threshold",
+	"sql.stats.automatic_collection.enabled",
+	"timeseries.storage.resolution_10s.ttl",
+	"timeseries.storage.resolution_30m.ttl",
+	"ui.display_timezone",
+	"version",
+}
+
+// NameToKey returns the key associated with a setting name.
+func NameToKey(name SettingName) (key InternalKey, found bool, nameStatus NameStatus) {
+	// First check the alias registry.
+	if alias, ok := aliasRegistry[name]; ok {
+		return alias.key, true, alias.active
+	}
+	// No alias: did they perhaps use the key directly?
+	maybeKey := InternalKey(name)
+	if s, ok := registry[maybeKey]; ok {
+		nameStatus := NameActive
+		if s.Name() != SettingName(maybeKey) {
+			// The user is invited to use the new name instead of the key.
+			nameStatus = NameRetired
+		}
+		return maybeKey, true, nameStatus
+	}
+	return "", false, NameActive
+}
+
+// LookupForLocalAccess returns a NonMaskedSetting by name. Used when a setting
+// is being retrieved for local processing within the cluster and not for
+// reporting; sensitive values are accessible.
+func LookupForLocalAccess(
+	name SettingName, forSystemTenant bool,
+) (NonMaskedSetting, bool, NameStatus) {
+	key, ok, nameStatus := NameToKey(name)
+	if !ok {
+		return nil, ok, nameStatus
+	}
+	s, ok := LookupForLocalAccessByKey(key, forSystemTenant)
+	return s, ok, nameStatus
+}
+
+// LookupForLocalAccessByKey returns a NonMaskedSetting by key. Used when a
+// setting is being retrieved for local processing within the cluster and not
+// for reporting; sensitive values are accessible.
+func LookupForLocalAccessByKey(key InternalKey, forSystemTenant bool) (NonMaskedSetting, bool) {
+	s, ok := registry[key]
+	if !ok {
+		return nil, false
+	}
+	if !forSystemTenant && s.Class() == SystemOnly {
+		return nil, false
+	}
+	return s, true
+}
+
+// LookupForReportingByKey returns a Setting by key. Used when a setting is being
+// retrieved for reporting.
+//
+// For settings that are non-reportable, the returned Setting hides the current
+// value (see Setting.String).
+func LookupForReportingByKey(key InternalKey, forSystemTenant bool) (Setting, bool) {
+	s, ok := registry[key]
+	if !ok {
+		return nil, false
+	}
+	if !forSystemTenant && s.Class() == SystemOnly {
+		return nil, false
+	}
+	if !s.isReportable() {
+		return &MaskedSetting{setting: s}, true
+	}
+	return s, true
+}
+
+// LookupForDisplay returns a Setting by key. Used when a setting is being
+// retrieved for display in SHOW commands or crdb_internal tables.
+//
+// For settings that are sensitive, the returned Setting hides the current
+// value (see Setting.String) if canViewSensitive is false.
+func LookupForDisplay(
+	name SettingName, forSystemTenant, canViewSensitive bool,
+) (Setting, bool, NameStatus) {
+	key, ok, nameStatus := NameToKey(name)
+	if !ok {
+		return nil, ok, nameStatus
+	}
+	s, ok := LookupForDisplayByKey(key, forSystemTenant, canViewSensitive)
+	return s, ok, nameStatus
+}
+
+// LookupForDisplayByKey returns a Setting by key. Used when a setting is being
+// retrieved for display in SHOW commands or crdb_internal tables.
+//
+// For settings that are sensitive, the returned Setting hides the current
+// value (see Setting.String) if canViewSensitive is false.
+func LookupForDisplayByKey(
+	key InternalKey, forSystemTenant, canViewSensitive bool,
+) (Setting, bool) {
+	s, ok := registry[key]
+	if !ok {
+		return nil, false
+	}
+	if !forSystemTenant && s.Class() == SystemOnly {
+		return nil, false
+	}
+	if s.isSensitive() && !canViewSensitive {
+		return &MaskedSetting{setting: s}, true
+	}
+	return s, true
+}
+
+// ForSystemTenant can be passed to Lookup for code that runs only on the system
+// tenant.
+const ForSystemTenant = true
+
+// ForVirtualCluster can be passed to Lookup for code that runs on
+// virtual clusters.
+const ForVirtualCluster = false
+
+// ReadableTypes maps our short type identifiers to friendlier names.
+var ReadableTypes = map[string]string{
+	"s": "string",
+	"i": "integer",
+	"f": "float",
+	"b": "boolean",
+	"z": "byte size",
+	"d": "duration",
+	"e": "enumeration",
+	// This is named "m" (instead of "v") for backwards compatibility reasons.
+	"m": "version",
+	"p": "protobuf",
+}
+
+// RedactedValue returns:
+//   - a string representation of the value, if the setting is reportable;
+//   - "<redacted>" if the setting is not reportable, sensitive, or a string;
+//   - "<unknown>" if there is no setting with this name.
+func RedactedValue(key InternalKey, values *Values, forSystemTenant bool) string {
+	if k, ok := registry[key]; ok {
+		if k.Typ() == "s" || k.isSensitive() || !k.isReportable() {
+			return "<redacted>"
+		}
+	}
+	if setting, ok := LookupForReportingByKey(key, forSystemTenant); ok {
+		return setting.String(values)
+	}
+	return "<unknown>"
+}
+
+// TestingListPrevAppSettings is exported for testing only.
+func TestingListPrevAppSettings() map[InternalKey]struct{} {
+	return systemSettingsWithPreviousApplicationClass
+}
diff --git a/pkg/settings/setting.go b/pkg/settings/setting.go
new file mode 100644
index 0000000..43763e4
--- /dev/null
+++ b/pkg/settings/setting.go
@@ -0,0 +1,333 @@
+// Copyright 2017 The Cockroach Authors.
+//
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
+
+package settings
+
+import (
+	"context"
+	"fmt"
+)
+
+// SettingName represents the user-visible name of a cluster setting.
+// The name is suitable for:
+// - SHOW/SET CLUSTER SETTING.
+// - inclusion in error messages.
+//
+// For internal storage, use the InternalKey type instead.
+type SettingName string
+
+// InternalKey is the internal (storage) key for a cluster setting.
+// The internal key is suitable for use with:
+// - direct accesses to system.settings.
+// - rangefeed logic associated with system.settings.
+// - (in unit tests only) interchangeably with the name for SET CLUSTER SETTING.
+//
+// For user-visible displays, use the SettingName type instead.
+type InternalKey string
+
+// Setting is the interface exposing the metadata for a cluster setting.
+//
+// The values for the settings are stored separately in Values. This allows
+// having a global (singleton) settings registry while allowing potentially
+// multiple "instances" (values) for each setting (e.g. for multiple test
+// servers in the same process).
+type Setting interface {
+	// Class returns the scope of the setting in multi-tenant scenarios.
+	Class() Class
+
+	// InternalKey returns the internal key used to store the setting.
+	// To display the name of the setting (eg. in errors etc) or the
+	// SET/SHOW CLUSTER SETTING statements, use the Name() method instead.
+	//
+	// The internal key is suitable for use with:
+	// - direct accesses to system.settings.
+	// - rangefeed logic associated with system.settings.
+	// - (in unit tests only) interchangeably with the name for SET CLUSTER SETTING.
+	InternalKey() InternalKey
+
+	// Name is the user-visible (display) name of the setting.
+	// The name is suitable for:
+	// - SHOW/SET CLUSTER SETTING.
+	// - inclusion in error messages.
+	Name() SettingName
+
+	// Typ returns the short (1 char) string denoting the type of setting.
+	Typ() string
+
+	// String returns the string representation of the setting's current value.
+	// It's used when materializing results for `SHOW CLUSTER SETTINGS` or `SHOW
+	// CLUSTER SETTING <setting-name>`.
+	//
+	// If this object implements a non-reportable setting that was retrieved for
+	// reporting (see LookupForReportingByKey), String hides the actual value.
+	String(sv *Values) string
+
+	// DefaultString returns the default value for the setting as a string. This
+	// is the same as calling String on the setting when it was never set.
+	DefaultString() string
+
+	// Description contains a helpful text explaining what the specific cluster
+	// setting is for.
+	Description() string
+
+	// Visibility returns whether the setting is made publicly visible. Reserved
+	// settings are still accessible to users, but they don't get listed out when
+	// retrieving all settings.
+	Visibility() Visibility
+
+	// IsUnsafe returns whether the setting is unsafe, and thus requires
+	// a special interlock to set.
+	IsUnsafe() bool
+
+	// ValueOrigin returns the origin of the current value.
+	ValueOrigin(ctx context.Context, sv *Values) ValueOrigin
+}
+
+// NonMaskedSetting is the exported interface of non-masked settings. A
+// non-masked setting provides access to the current value (even if the setting
+// is not reportable).
+//
+// A non-masked setting must not be used in the context of reporting values (see
+// LookupForReportingByKey).
+type NonMaskedSetting interface {
+	Setting
+
+	// Encoded returns the encoded representation of the current value of the
+	// setting.
+	Encoded(sv *Values) string
+
+	// EncodedDefault returns the encoded representation of the default value of
+	// the setting.
+	EncodedDefault() string
+
+	// DecodeToString returns the string representation of the provided
+	// encoded value.
+	// This is analogous to loading the setting from storage and
+	// then calling String() on it, however the setting is not modified.
+	// The string representation of the default value can be obtained
+	// by calling EncodedDefault() and then DecodeToString().
+	DecodeToString(encoded string) (repr string, err error)
+
+	// SetOnChange installs a callback to be called when a setting's value
+	// changes. `fn` should avoid doing long-running or blocking work as it is
+	// called on the goroutine which handles all settings updates.
+	SetOnChange(sv *Values, fn func(ctx context.Context))
+
+	// ErrorHint returns a hint message to be displayed to the user when there's
+	// an error.
+	ErrorHint() (bool, string)
+}
+
+// Class describes the scope of a setting under cluster
+// virtualization.
+//
+// Guidelines for choosing a class:
+//
+//   - Make sure to read the descriptions below carefully to
+//     understand the differences in semantics.
+//
+//   - Rules of thumb:
+//
+//     1. if an end-user may benefit from modifying the setting
+//     through a SQL connection to a secondary tenant / virtual
+//     cluster, AND different virtual clusters should be able to use
+//     different values, the setting should have class
+//     ApplicationLevel.
+//
+//     2. if a setting should only be controlled by SREs in a
+//     multi-tenant deployment or in an organization that wishes to
+//     shield DB operations from application development, OR the
+//     behavior of CockroachDB is not well-defined if multiple tenants
+//     (virtual clusters) use different values concurrently, the
+//     setting must *not* use class ApplicationLevel.
+//
+//     3. if and only if a setting relevant to the KV/storage layer
+//     and whose value is shared across all virtual clusters is ever
+//     accessed by code in the application layer (SQL execution or
+//     HTTP handlers), use SystemVisible.
+//
+//     4. in other cases, use SystemOnly.
+type Class int8
+
+const (
+	// SystemOnly settings are specific to the KV/storage layer and
+	// cannot be accessed from application layer code (in particular not
+	// from SQL layer nor HTTP handlers).
+	//
+	// As a rule of thumb, use this class if:
+	//
+	//   - the setting may be accessed from the shared KV/storage layer;
+	//
+	//   - AND, the setting should only be controllable by SREs (not
+	//     end-users) in a multi-tenant environment, AND the behavior
+	//     of CockroachDB is not well-defined if different virtual
+	//     clusters were to use different values concurrently.
+	//
+	//     (If this part of the condition does not hold, consider
+	//     ApplicationLevel instead.)
+	//
+	//   - AND, its value is never needed in the application layer (i.e.
+	//     it is not read from SQL code, HTTP handlers or other code
+	//     that would run in SQL pods in a multi-tenant environment).
+	//
+	//     (If this part of the condition does not hold, consider
+	//     SystemVisible instead.)
+	//
+	//     Note: if a setting is only ever accessed in the SQL code
+	//     after it has ascertained that it was running for the system
+	//     interface; and we do not wish to display this setting in the
+	//     list displayed by `SHOW ALL CLUSTER SETTINGS` in virtual
+	//     clusters, the class SystemOnly is suitable. Hence the emphasis
+	//     on "would run in SQL pods" above.
+	SystemOnly Class = iota
+
+	// SystemVisible settings are specific to the KV/storage layer and
+	// are also visible to virtual clusters.
+	//
+	// As a rule of thumb, use this class if:
+	//
+	//   - the setting may be accessed from the shared KV/storage layer;
+	//
+	//   - AND the setting should only be controllable by operators of
+	//     the storage cluster (e.g. SREs in the case of a multi-tenant
+	//     environment) but having the storage cluster's value be
+	//     observable by virtual clusters is desirable.
+	//
+	//     (If this part of the condition does not hold, consider
+	//     ApplicationLevel instead.)
+	//
+	//   - AND, its value is sometimes needed in the application layer
+	//     (i.e. it may be read from SQL code, HTTP handlers or other
+	//     code that could run in SQL pods in a multi-tenant environment).
+	//
+	//     (If this part of the condition does not hold, consider
+	//     SystemOnly instead.)
+	//
+	// One use cases is to enable optimizations in the KV client side of
+	// virtual cluster RPCs. For example, if the storage layer uses a
+	// setting to decide the size of a response, making the setting
+	// visible enables the client in virtual cluster code to
+	// pre-allocate response buffers to match the size they expect to
+	// receive.
+	//
+	// Another use case is KV/storage feature flags, to enable a UX
+	// improvement in virtual clusters by avoiding requesting
+	// storage-level functionality when it is not enabled, such as
+	// rangefeeds and provide a better error message.
+	// (Without this extra logic, the error reported by KV/storage
+	// might be hard to read by end-users.)
+	//
+	// As a reminder, the setting values observed by a virtual cluster,
+	// both for its own application settings and those it observes for
+	// system-visible settings, can be overridden using ALTER VIRTUAL
+	// CLUSTER SET CLUSTER SETTING. This can be used during e.g.
+	// troubleshooting, to allow changing the observed value for a
+	// virtual cluster without a code change.
+	//
+	// A setting that is expected to be overridden in regular operation
+	// to to control application-level behavior is still an application
+	// setting, and should use the application class; system-visible is
+	// for use by settings that control the storage layer but need to be
+	// visible, rather than for settings that control the application
+	// layer but are intended to be read-only. This latter case should
+	// use ApplicationLayer, because it controls application behavior,
+	// and then rely on an override to prevent modification from within
+	// the virtual cluster.
+	SystemVisible
+
+	// ApplicationLevel settings are readable and can optionally be
+	// modified by virtual clusters.
+	//
+	// As a rule of thumb, use this class if:
+	//
+	//   - the setting is never accessed by the shared KV/storage layer;
+	//
+	//   - AND, any of the following holds:
+	//
+	//     - end-users may benefit from modifying the setting
+	//       through a SQL connection to a secondary tenant / virtual
+	//       cluster.
+	//
+	//       (If this part of the condition does not hold, but the other
+	//       part of the condition below does hold, consider still using
+	//       ApplicationLevel and force an override using ALTER VIRTUAL
+	//       CLUSTER SET CLUSTER SETTING. This makes the
+	//       ApplicationLevel setting effectively read-only from the
+	//       virtual cluster's perspective, because system overrides
+	//       cannot be modified by the virtual cluster.)
+	//
+	//     - OR, different virtual clusters should be able to
+	//       use different values for the setting.
+	//
+	//       (If this part of the condition does not hold, consider
+	//       SystemOnly or SystemVisible instead.)
+	//
+	// Note that each SQL layer has its own copy of ApplicationLevel
+	// settings; including the system tenant/interface. However, they
+	// are neatly partitioned such that a given virtual cluster can
+	// never observe the value set for another virtual cluster nor that
+	// set for the system tenant/interface.
+	//
+	// As a reminder, the setting values observed by a virtual cluster,
+	// both for its own application settings and those it observes for
+	// system-visible settings, can be overridden using ALTER VIRTUAL
+	// CLUSTER SET CLUSTER SETTING. This can be used during e.g.
+	// troubleshooting, to allow changing the observed value for a
+	// virtual cluster without a code change.
+	ApplicationLevel
+)
+
+// Visibility describes how a user should feel confident that they can customize
+// the setting.
+//
+// See the constant definitions below for details.
+type Visibility int8
+
+const (
+	// Reserved - which is the default - indicates that a setting is
+	// not documented and the CockroachDB team has not developed
+	// internal experience about the impact of customizing it to other
+	// values.
+	// In short: "Use at your own risk."
+	Reserved Visibility = iota
+	// Public indicates that a setting is documented, the range of
+	// possible values yields predictable results, and the CockroachDB
+	// team is there to assist if issues occur as a result of the
+	// customization.
+	// In short: "Go ahead but be careful."
+	Public
+)
+
+// ValueOrigin indicates the origin of the current value of a setting, e.g. if
+// it is coming from the in-code default or an explicit override.
+type ValueOrigin uint32
+
+const (
+	// OriginDefault indicates the value in use is the default value.
+	OriginDefault ValueOrigin = iota
+	// OriginExplicitlySet indicates the value is has been set explicitly.
+	OriginExplicitlySet
+	// OriginExternallySet indicates the value has been set externally, such as
+	// via a host-cluster override for this or all tenant(s).
+	OriginExternallySet
+	// OriginOverride indicates the value has been set via a test override.
+	OriginOverride
+)
+
+func (v ValueOrigin) String() string {
+	if v > OriginOverride {
+		return fmt.Sprintf("invalid (%d)", v)
+	}
+	return [...]string{"default", "override", "external-override", "test-override"}[v]
+}
+
+// SafeValue implements the redact.SafeValue interface.
+func (ValueOrigin) SafeValue() {}
+
+// SafeValue implements the redact.SafeValue interface.
+func (SettingName) SafeValue() {}
+
+// SafeValue implements the redact.SafeValue interface.
+func (InternalKey) SafeValue() {}
diff --git a/pkg/settings/string.go b/pkg/settings/string.go
new file mode 100644
index 0000000..58ae1be
--- /dev/null
+++ b/pkg/settings/string.go
@@ -0,0 +1,149 @@
+// Copyright 2017 The Cockroach Authors.
+//
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
+
+package settings
+
+import (
+	"context"
+
+	"github.com/cockroachdb/errors"
+)
+
+// StringSetting is the interface of a setting variable that will be
+// updated automatically when the corresponding cluster-wide setting
+// of type "string" is updated.
+type StringSetting struct {
+	defaultValue string
+	validateFn   func(*Values, string) error
+	common
+}
+
+var _ internalSetting = &StringSetting{}
+
+func (s *StringSetting) String(sv *Values) string {
+	return s.Get(sv)
+}
+
+// Encoded returns the encoded value of the current value of the setting.
+func (s *StringSetting) Encoded(sv *Values) string {
+	return s.String(sv)
+}
+
+// EncodedDefault returns the encoded value of the default value of the setting.
+func (s *StringSetting) EncodedDefault() string {
+	return s.defaultValue
+}
+
+// DecodeToString decodes and renders an encoded value.
+func (s *StringSetting) DecodeToString(encoded string) (string, error) {
+	return encoded, nil
+}
+
+// Typ returns the short (1 char) string denoting the type of setting.
+func (*StringSetting) Typ() string {
+	return "s"
+}
+
+// Default returns default value for setting.
+func (s *StringSetting) Default() string {
+	return s.defaultValue
+}
+
+// DefaultString returns the default value for the setting as a string.
+func (s *StringSetting) DefaultString() string {
+	return s.defaultValue
+}
+
+// Defeat the linter.
+var _ = (*StringSetting).Default
+
+// Get retrieves the string value in the setting.
+func (s *StringSetting) Get(sv *Values) string {
+	loaded := sv.getGeneric(s.slot)
+	if loaded == nil {
+		return ""
+	}
+	return loaded.(string)
+}
+
+// Validate that a value conforms with the validation function.
+func (s *StringSetting) Validate(sv *Values, v string) error {
+	if s.validateFn != nil {
+		if err := s.validateFn(sv, v); err != nil {
+			return err
+		}
+	}
+	return nil
+}
+
+// Override sets the setting to the given value, assuming
+// it passes validation.
+func (s *StringSetting) Override(ctx context.Context, sv *Values, v string) {
+	sv.setValueOrigin(ctx, s.slot, OriginOverride)
+	_ = s.decodeAndSet(ctx, sv, v)
+	sv.setDefaultOverride(s.slot, v)
+}
+
+func (s *StringSetting) decodeAndSet(ctx context.Context, sv *Values, v string) error {
+	if err := s.Validate(sv, v); err != nil {
+		return err
+	}
+	if s.Get(sv) != v {
+		sv.setGeneric(ctx, s.slot, v)
+	}
+	return nil
+}
+
+func (s *StringSetting) decodeAndSetDefaultOverride(
+	ctx context.Context, sv *Values, v string,
+) error {
+	sv.setDefaultOverride(s.slot, v)
+	return nil
+}
+
+func (s *StringSetting) setToDefault(ctx context.Context, sv *Values) {
+	// See if the default value was overridden.
+	if val := sv.getDefaultOverride(s.slot); val != nil {
+		// As per the semantics of override, these values don't go through
+		// validation.
+		_ = s.decodeAndSet(ctx, sv, val.(string))
+		return
+	}
+	if err := s.decodeAndSet(ctx, sv, s.defaultValue); err != nil {
+		panic(err)
+	}
+}
+
+// RegisterStringSetting defines a new setting with type string.
+func RegisterStringSetting(
+	class Class, key InternalKey, desc string, defaultValue string, opts ...SettingOption,
+) *StringSetting {
+	validateFn := func(sv *Values, val string) error {
+		for _, opt := range opts {
+			switch {
+			case opt.commonOpt != nil:
+				continue
+			case opt.validateStringFn != nil:
+			default:
+				panic(errors.AssertionFailedf("wrong validator type"))
+			}
+			if err := opt.validateStringFn(sv, val); err != nil {
+				return err
+			}
+		}
+		return nil
+	}
+	setting := &StringSetting{
+		defaultValue: defaultValue,
+		validateFn:   validateFn,
+	}
+	// By default all string settings are considered to perhaps contain
+	// PII and are thus non-reportable (to exclude them from telemetry
+	// reports).
+	setting.setReportable(false)
+	register(class, key, desc, setting)
+	setting.apply(opts)
+	return setting
+}
diff --git a/pkg/settings/updater.go b/pkg/settings/updater.go
new file mode 100644
index 0000000..9a5824a
--- /dev/null
+++ b/pkg/settings/updater.go
@@ -0,0 +1,246 @@
+// Copyright 2017 The Cockroach Authors.
+//
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
+
+package settings
+
+import (
+	"context"
+	"strconv"
+	"time"
+
+	"github.com/cockroachdb/cockroachdb-parser/pkg/util/envutil"
+	"github.com/cockroachdb/cockroachdb-parser/pkg/util/protoutil"
+	"github.com/cockroachdb/errors"
+	"github.com/gogo/protobuf/proto"
+)
+
+var ignoreAllUpdates = envutil.EnvOrDefaultBool("COCKROACH_IGNORE_CLUSTER_SETTINGS", false)
+
+// IsIgnoringAllUpdates returns true if Updaters returned by NewUpdater will
+// discard all updates due to the COCKROACH_IGNORE_CLUSTER_SETTINGS var.
+func IsIgnoringAllUpdates() bool {
+	return ignoreAllUpdates
+}
+
+// EncodeDuration encodes a duration in the format of EncodedValue.Value.
+func EncodeDuration(d time.Duration) string {
+	return d.String()
+}
+
+// EncodeBool encodes a bool in the format of EncodedValue.Value.
+func EncodeBool(b bool) string {
+	return strconv.FormatBool(b)
+}
+
+// EncodeInt encodes an int in the format of EncodedValue.Value.
+func EncodeInt(i int64) string {
+	return strconv.FormatInt(i, 10)
+}
+
+// EncodeFloat encodes a float in the format of EncodedValue.Value.
+func EncodeFloat(f float64) string {
+	return strconv.FormatFloat(f, 'G', -1, 64)
+}
+
+// EncodeProtobuf encodes a protobuf in the format of EncodedValue.Value.
+func EncodeProtobuf(p protoutil.Message) string {
+	data := make([]byte, p.Size())
+	if _, err := p.MarshalTo(data); err != nil {
+		panic(errors.Wrapf(err, "encoding %s: %+v", proto.MessageName(p), p))
+	}
+	return string(data)
+}
+
+type updater struct {
+	sv *Values
+	m  map[InternalKey]struct{}
+}
+
+// Updater is a helper for updating the in-memory settings.
+//
+// RefreshSettings passes the serialized representations of all individual
+// settings -- e.g. the rows read from the system.settings table. We update the
+// wrapped atomic settings values as we go and note which settings were updated,
+// then set the rest to default in ResetRemaining().
+type Updater interface {
+	// Set is used by tests to configure overrides in a generic fashion.
+	Set(ctx context.Context, key InternalKey, value EncodedValue) error
+	// SetToDefault resets the setting to its default value.
+	SetToDefault(ctx context.Context, key InternalKey) error
+
+	// ResetRemaining loads the values from build-time defaults for all
+	// settings that were not updated by Set() and SetFromStorage().
+	ResetRemaining(ctx context.Context)
+
+	// SetFromStorage is called by the settings watcher to update the
+	// settings from either the rangefeed over system.settings, or
+	// overrides coming in over the network from the system tenant.
+	SetFromStorage(ctx context.Context, key InternalKey, value EncodedValue, origin ValueOrigin) error
+}
+
+// A NoopUpdater ignores all updates.
+type NoopUpdater struct{}
+
+// Set implements Updater. It is a no-op.
+func (u NoopUpdater) Set(ctx context.Context, key InternalKey, value EncodedValue) error { return nil }
+
+// ResetRemaining implements Updater. It is a no-op.
+func (u NoopUpdater) ResetRemaining(context.Context) {}
+
+// SetToDefault implements Updater. It is a no-op.
+func (u NoopUpdater) SetToDefault(ctx context.Context, key InternalKey) error { return nil }
+
+// SetFromStorage implements Updater. It is a no-op.
+func (u NoopUpdater) SetFromStorage(
+	ctx context.Context, key InternalKey, value EncodedValue, origin ValueOrigin,
+) error {
+	return nil
+}
+
+// NewUpdater makes an Updater.
+func NewUpdater(sv *Values) Updater {
+	if ignoreAllUpdates {
+		return NoopUpdater{}
+	}
+	return updater{
+		sv: sv,
+		m:  make(map[InternalKey]struct{}),
+	}
+}
+
+// getSetting determines whether the target setting can be set or
+// overridden.
+func (u updater) getSetting(key InternalKey, value EncodedValue) (internalSetting, error) {
+	d, ok := registry[key]
+	if !ok {
+		if _, ok := retiredSettings[key]; ok {
+			return nil, nil
+		}
+		// Likely a new setting this old node doesn't know about.
+		return nil, errors.Errorf("unknown setting '%s'", key)
+	}
+	return d, nil
+}
+
+func checkType(d internalSetting, value EncodedValue) error {
+	if expected := d.Typ(); value.Type != expected {
+		return errors.Errorf("setting '%s' defined as type %s, not %s", d.Name(), expected, value.Type)
+	}
+	return nil
+}
+
+// Set attempts update a setting and notes that it was updated.
+func (u updater) Set(ctx context.Context, key InternalKey, value EncodedValue) error {
+	d, err := u.getSetting(key, value)
+	if err != nil || d == nil {
+		return err
+	}
+
+	return u.setInternal(ctx, key, value, d, OriginExplicitlySet)
+}
+
+// setInternal is the shared code between Set() and SetFromStorage().
+// It propagates the given value to the in-RAM store and keeps track
+// of the origin of the value.
+func (u updater) setInternal(
+	ctx context.Context, key InternalKey, value EncodedValue, d internalSetting, origin ValueOrigin,
+) error {
+	// Mark the setting as modified, such that
+	// (updater).ResetRemaining() does not touch it.
+	u.m[key] = struct{}{}
+
+	if err := checkType(d, value); err != nil {
+		return err
+	}
+	u.sv.setValueOrigin(ctx, d.getSlot(), origin)
+	return d.decodeAndSet(ctx, u.sv, value.Value)
+}
+
+func (u updater) SetToDefault(ctx context.Context, key InternalKey) error {
+	d, ok := registry[key]
+	if !ok {
+		if _, ok := retiredSettings[key]; ok {
+			return nil
+		}
+		// Likely a new setting this old node doesn't know about.
+		return errors.Errorf("unknown setting '%s'", key)
+	}
+
+	u.m[key] = struct{}{}
+	u.sv.setValueOrigin(ctx, d.getSlot(), OriginDefault)
+	d.setToDefault(ctx, u.sv)
+	return nil
+}
+
+// ResetRemaining sets all settings not explicitly set via this
+// updater to their default values.
+func (u updater) ResetRemaining(ctx context.Context) {
+	for _, v := range registry {
+		if u.sv.SpecializedToVirtualCluster() && v.Class() == SystemOnly {
+			// Don't try to reset system settings on a non-system tenant.
+			continue
+		}
+		if _, setInThisUpdater := u.m[v.InternalKey()]; !setInThisUpdater &&
+			// We need to preserve test overrides.
+			u.sv.getValueOrigin(ctx, v.getSlot()) != OriginOverride {
+			u.sv.setValueOrigin(ctx, v.getSlot(), OriginDefault)
+			v.setToDefault(ctx, u.sv)
+		}
+	}
+}
+
+// SetFromStorage loads the stored value into the setting.
+func (u updater) SetFromStorage(
+	ctx context.Context, key InternalKey, value EncodedValue, origin ValueOrigin,
+) error {
+	d, err := u.getSetting(key, value)
+	if err != nil || d == nil {
+		return err
+	}
+
+	if !u.sv.SpecializedToVirtualCluster() /* system tenant */ ||
+		d.Class() == ApplicationLevel {
+		// The value is being loaded from the current virtual cluster's
+		// system.settings. Load it as an active value.
+		return u.setInternal(ctx, key, value, d, origin)
+	}
+
+	// Here we are looking at a SystemVisible or SystemOnly setting
+	// from within a virtual cluster.
+
+	if d.Class() == SystemOnly {
+		// Attempting to load a SystemOnly setting from a virtual
+		// cluster's system.settings table.
+		//
+		// This is always invalid. The caller should have prevented this
+		// point from being reached, so this is really protection against
+		// API misuse.
+		return errors.AssertionFailedf("programming error: cannot set SystemOnly %q", key)
+	}
+
+	if d.Class() != SystemVisible {
+		return errors.AssertionFailedf("unhandled class %v", d.Class())
+	}
+
+	if err := checkType(d, value); err != nil {
+		return err
+	}
+
+	defer func() {
+		// After the code below sets the default value, we ensure that the
+		// new default is also copied to the in-RAM store for all settings
+		// that didn't have an active value in the virtual cluster yet.
+		if u.sv.getValueOrigin(ctx, d.getSlot()) == OriginDefault {
+			d.setToDefault(ctx, u.sv)
+		}
+	}()
+
+	// We are receiving an alternate default for a SystemVisible
+	// setting. Here we do not configure the main setting value (via
+	// setInternal or .set on the setting itself): many tests use
+	// .Override earlier and we do not want to change the override.
+	// Instead, we update the default.
+	return d.decodeAndSetDefaultOverride(ctx, u.sv, value.Value)
+}
diff --git a/pkg/settings/values.go b/pkg/settings/values.go
new file mode 100644
index 0000000..59b681a
--- /dev/null
+++ b/pkg/settings/values.go
@@ -0,0 +1,307 @@
+// Copyright 2021 The Cockroach Authors.
+//
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
+
+package settings
+
+import (
+	"context"
+	"sync/atomic"
+
+	"github.com/cockroachdb/cockroachdb-parser/pkg/util/buildutil"
+	"github.com/cockroachdb/cockroachdb-parser/pkg/util/syncutil"
+	"github.com/cockroachdb/errors"
+)
+
+// MaxSettings is the maximum number of settings that the system supports.
+// Exported for tests.
+const MaxSettings = 1023
+
+// Values is a container that stores values for all registered settings.
+// Each setting is assigned a unique slot (up to MaxSettings).
+// Note that slot indices are 1-based (this is to trigger panics if an
+// uninitialized slot index is used).
+type Values struct {
+	container valuesContainer
+
+	classCheck classCheck
+
+	defaultOverridesMu struct {
+		syncutil.Mutex
+
+		// defaultOverrides maintains the set of overridden default values (see
+		// Override()).
+		defaultOverrides map[slotIdx]interface{}
+	}
+
+	changeMu struct {
+		syncutil.Mutex
+		// NB: any in place modification to individual slices must also hold the
+		// lock, e.g. if we ever add RemoveOnChange or something.
+		onChange [MaxSettings][]func(ctx context.Context)
+	}
+	// opaque is an arbitrary object that can be set by a higher layer to make it
+	// accessible from certain callbacks (like state machine transformers).
+	opaque interface{}
+}
+
+type classCheck uint32
+
+const (
+	// classCheckUndefined is used when the settings.Values hasn't been
+	// specialized yet.
+	classCheckUndefined classCheck = iota
+	// classCheckSystemInterface is used when the settings.Values is
+	// specialized for the system interface and SystemOnly settings can
+	// be used.
+	classCheckSystemInterface
+	// classCheckVirtualCluster is used when the settings.Values is
+	// specialized for a virtual cluster and SystemOnly settings cannot
+	// be used.
+	classCheckVirtualCluster
+)
+
+func (ck *classCheck) get() classCheck {
+	return classCheck(atomic.LoadUint32((*uint32)(ck)))
+}
+
+func (ck *classCheck) set(nv classCheck) {
+	atomic.StoreUint32((*uint32)(ck), uint32(nv))
+}
+
+const numSlots = MaxSettings + 1
+
+type valuesContainer struct {
+	intVals     [numSlots]int64
+	genericVals [numSlots]atomic.Value
+
+	// If forbidden[slot] is true, that setting is not allowed to be used from the
+	// current context (i.e. it is a SystemOnly setting and the container is for a
+	// tenant). Reading or writing such a setting causes panics in test builds.
+	forbidden [numSlots]bool
+
+	// hasValue contains the origin of the current value of the setting.
+	hasValue [numSlots]uint32
+}
+
+func (c *valuesContainer) setGenericVal(slot slotIdx, newVal interface{}) {
+	if !c.checkForbidden(slot) {
+		return
+	}
+	c.genericVals[slot].Store(newVal)
+}
+
+func (c *valuesContainer) setInt64Val(slot slotIdx, newVal int64) (changed bool) {
+	if !c.checkForbidden(slot) {
+		return false
+	}
+	return atomic.SwapInt64(&c.intVals[slot], newVal) != newVal
+}
+
+func (c *valuesContainer) getInt64(slot slotIdx) int64 {
+	c.checkForbidden(slot)
+	return atomic.LoadInt64(&c.intVals[slot])
+}
+
+func (c *valuesContainer) getGeneric(slot slotIdx) interface{} {
+	c.checkForbidden(slot)
+	return c.genericVals[slot].Load()
+}
+
+// checkForbidden checks if the setting in the given slot is allowed to be used
+// from the current context. If not, it panics in test builds and returns false
+// in non-test builds.
+func (c *valuesContainer) checkForbidden(slot slotIdx) bool {
+	if c.forbidden[slot] {
+		if buildutil.CrdbTestBuild {
+			const msg = `programming error: invalid access to SystemOnly setting %s from a virtual cluster!
+
+TIP: use class ApplicationLevel for settings that configure just 1
+virtual cluster; SystemOnly for settings that affect only the shared
+storage layer; and SystemVisible for settings that affect the storage
+layer and also must be visible to all virtual clusters.
+`
+			panic(errors.AssertionFailedf(msg, slotTable[slot].Name()))
+		}
+		return false
+	}
+	return true
+}
+
+type testOpaqueType struct{}
+
+// TestOpaque can be passed to Values.Init when we are testing the settings
+// infrastructure.
+var TestOpaque interface{} = testOpaqueType{}
+
+// Init must be called before using a Values instance; it initializes all
+// variables to their defaults.
+//
+// The opaque argument can be retrieved later via Opaque().
+func (sv *Values) Init(ctx context.Context, opaque interface{}) {
+	sv.opaque = opaque
+	for _, s := range registry {
+		s.setToDefault(ctx, sv)
+	}
+}
+
+const alreadySpecializedError = `programming error: setting value container is already specialized!
+
+TIP: avoid using the same cluster.Settings or settings.Value object across multiple servers.
+`
+
+// SpecializeForSystemInterface marks the values container as
+// pertaining to the system interface.
+func (sv *Values) SpecializeForSystemInterface() {
+	if ck := sv.classCheck.get(); ck != classCheckUndefined && ck != classCheckSystemInterface {
+		panic(errors.AssertionFailedf(alreadySpecializedError))
+	}
+	sv.classCheck.set(classCheckSystemInterface)
+}
+
+// SpecializeForVirtualCluster marks this container as pertaining to
+// a virtual cluster, after which use of SystemOnly values is
+// disallowed.
+func (sv *Values) SpecializeForVirtualCluster() {
+	if ck := sv.classCheck.get(); ck != classCheckUndefined && ck != classCheckVirtualCluster {
+		panic(errors.AssertionFailedf(alreadySpecializedError))
+	}
+	sv.classCheck.set(classCheckVirtualCluster)
+	for slot, setting := range slotTable {
+		if setting != nil && setting.Class() == SystemOnly {
+			sv.container.forbidden[slot] = true
+		}
+	}
+}
+
+// SpecializedToVirtualCluster returns true if this container is for a
+// virtual cluster (i.e. SpecializeToVirtualCluster() was called).
+func (sv *Values) SpecializedToVirtualCluster() bool {
+	return sv.classCheck.get() == classCheckVirtualCluster
+}
+
+// Opaque returns the argument passed to Init.
+func (sv *Values) Opaque() interface{} {
+	return sv.opaque
+}
+
+func (sv *Values) settingChanged(ctx context.Context, slot slotIdx) {
+	sv.changeMu.Lock()
+	funcs := sv.changeMu.onChange[slot]
+	sv.changeMu.Unlock()
+	for _, fn := range funcs {
+		fn(ctx)
+	}
+}
+
+func (sv *Values) setInt64(ctx context.Context, slot slotIdx, newVal int64) {
+	if sv.container.setInt64Val(slot, newVal) {
+		sv.settingChanged(ctx, slot)
+	}
+}
+
+func (sv *Values) setValueOrigin(ctx context.Context, slot slotIdx, origin ValueOrigin) {
+	atomic.StoreUint32(&sv.container.hasValue[slot], uint32(origin))
+}
+
+func (sv *Values) getValueOrigin(ctx context.Context, slot slotIdx) ValueOrigin {
+	return ValueOrigin(atomic.LoadUint32(&sv.container.hasValue[slot]))
+}
+
+// setDefaultOverride overrides the default value for the respective setting to
+// newVal.
+func (sv *Values) setDefaultOverride(slot slotIdx, newVal interface{}) {
+	sv.defaultOverridesMu.Lock()
+	defer sv.defaultOverridesMu.Unlock()
+	if sv.defaultOverridesMu.defaultOverrides == nil {
+		sv.defaultOverridesMu.defaultOverrides = make(map[slotIdx]interface{})
+	}
+	sv.defaultOverridesMu.defaultOverrides[slot] = newVal
+}
+
+// getDefaultOverrides checks whether there's a default override for slotIdx-1
+// and returns it (or nil if there is no override).
+func (sv *Values) getDefaultOverride(slot slotIdx) interface{} {
+	sv.defaultOverridesMu.Lock()
+	defer sv.defaultOverridesMu.Unlock()
+	return sv.defaultOverridesMu.defaultOverrides[slot]
+}
+
+func (sv *Values) setGeneric(ctx context.Context, slot slotIdx, newVal interface{}) {
+	sv.container.setGenericVal(slot, newVal)
+	sv.settingChanged(ctx, slot)
+}
+
+func (sv *Values) getInt64(slot slotIdx) int64 {
+	return sv.container.getInt64(slot)
+}
+
+func (sv *Values) getGeneric(slot slotIdx) interface{} {
+	return sv.container.getGeneric(slot)
+}
+
+// setOnChange installs a callback to be called when a setting's value changes.
+// `fn` should avoid doing long-running or blocking work as it is called on the
+// goroutine which handles all settings updates.
+func (sv *Values) setOnChange(slot slotIdx, fn func(ctx context.Context)) {
+	sv.changeMu.Lock()
+	sv.changeMu.onChange[slot] = append(sv.changeMu.onChange[slot], fn)
+	sv.changeMu.Unlock()
+}
+
+// TestingCopyForVirtualCluster makes a copy of the input Values in
+// the target Values for use when initializing a server for a virtual
+// cluster in tests. This is meant to propagate overrides
+// to ApplicationLevel settings.
+func (sv *Values) TestingCopyForVirtualCluster(input *Values) {
+	for slot := slotIdx(0); slot < slotIdx(len(registry)); slot++ {
+		s := slotTable[slot]
+		if s.Class() != ApplicationLevel && s.Class() != SystemVisible {
+			continue
+		}
+		// This test-only method is used when creating new virtual clusters which
+		// initialize their own version and thus do not want an existing version.
+		if s.Typ() == VersionSettingValueType {
+			continue
+		}
+
+		// Copy the value.
+		sv.container.intVals[slot] = atomic.LoadInt64(&input.container.intVals[slot])
+		if v := input.container.genericVals[slot].Load(); v != nil {
+			sv.container.genericVals[slot].Store(v)
+		}
+
+		// Copy the default.
+		input.defaultOverridesMu.Lock()
+		v, hasVal := input.defaultOverridesMu.defaultOverrides[slot]
+		input.defaultOverridesMu.Unlock()
+		if !hasVal {
+			continue
+		}
+		sv.setDefaultOverride(slot, v)
+	}
+}
+
+// TestingCopyForServer makes a copy of the input Values in the target Values
+// for use when initializing a server in a test cluster. This is meant to
+// propagate initial values and overrides.
+func (sv *Values) TestingCopyForServer(input *Values, newOpaque interface{}) {
+	sv.opaque = newOpaque
+	for slot := slotIdx(0); slot < slotIdx(len(registry)); slot++ {
+		// Copy the value.
+		sv.container.intVals[slot] = atomic.LoadInt64(&input.container.intVals[slot])
+		if v := input.container.genericVals[slot].Load(); v != nil {
+			sv.container.genericVals[slot].Store(v)
+		}
+
+		// Copy the default.
+		input.defaultOverridesMu.Lock()
+		v, hasVal := input.defaultOverridesMu.defaultOverrides[slot]
+		input.defaultOverridesMu.Unlock()
+		if !hasVal {
+			continue
+		}
+		sv.setDefaultOverride(slot, v)
+	}
+}
diff --git a/pkg/settings/version.go b/pkg/settings/version.go
new file mode 100644
index 0000000..10d3b3d
--- /dev/null
+++ b/pkg/settings/version.go
@@ -0,0 +1,190 @@
+// Copyright 2020 The Cockroach Authors.
+//
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
+
+package settings
+
+import (
+	"context"
+	"fmt"
+)
+
+// VersionSetting is the setting type that allows users to control the cluster
+// version. It starts off at an initial version and takes into account the
+// current version to validate proposed updates. This is (necessarily) tightly
+// coupled with the setting implementation in pkg/clusterversion, and it's done
+// through the VersionSettingImpl interface. We rely on the implementation to
+// decode to and from raw bytes, and to perform the validation itself. The
+// VersionSetting itself is then just the tiny shim that lets us hook into the
+// rest of the settings machinery (by interfacing with Values, to load and store
+// cluster versions).
+//
+// TODO(irfansharif): If the cluster version is no longer backed by gossip,
+// maybe we should stop pretending it's a regular gossip-backed cluster setting.
+// We could introduce new syntax here to motivate this shift.
+type VersionSetting struct {
+	impl VersionSettingImpl
+	common
+}
+
+var _ internalSetting = &VersionSetting{}
+
+// VersionSettingImpl is the interface bridging pkg/settings and
+// pkg/clusterversion. See VersionSetting for additional commentary.
+type VersionSettingImpl interface {
+	// Decode takes in an encoded cluster version and returns it as the native
+	// type (the clusterVersion proto). Except it does it through the
+	// ClusterVersionImpl to avoid circular dependencies.
+	Decode(val []byte) (ClusterVersionImpl, error)
+
+	// Validate checks whether an version update is permitted. It takes in the
+	// old and the proposed new value (both in encoded form). This is called by
+	// SET CLUSTER SETTING.
+	ValidateVersionUpgrade(ctx context.Context, sv *Values, oldV, newV []byte) error
+
+	// ValidateBinaryVersions is a subset of Validate. It only checks that the
+	// current binary supports the proposed version. This is called when the
+	// version is being communicated to us by a different node (currently
+	// through gossip).
+	//
+	// TODO(irfansharif): Update this comment when we stop relying on gossip to
+	// propagate version bumps.
+	ValidateBinaryVersions(ctx context.Context, sv *Values, newV []byte) error
+
+	// SettingsListDefault returns the value that should be presented by
+	// `./cockroach gen settings-list`
+	SettingsListDefault() string
+}
+
+// ClusterVersionImpl is used to stub out the dependency on the ClusterVersion
+// type (in pkg/clusterversion). The VersionSetting below is used to set
+// ClusterVersion values, but we can't import the type directly due to the
+// cyclical dependency structure.
+type ClusterVersionImpl interface {
+	fmt.Stringer
+
+	// Encode encodes the ClusterVersion (using the protobuf encoding).
+	Encode() []byte
+}
+
+// MakeVersionSetting instantiates a version setting instance. See
+// VersionSetting for additional commentary.
+func MakeVersionSetting(impl VersionSettingImpl) VersionSetting {
+	return VersionSetting{impl: impl}
+}
+
+// Validate checks whether an version update is permitted. It takes in the
+// old and the proposed new value (both in encoded form). This is called by
+// SET CLUSTER SETTING.
+func (v *VersionSetting) Validate(ctx context.Context, sv *Values, oldV, newV []byte) error {
+	return v.impl.ValidateVersionUpgrade(ctx, sv, oldV, newV)
+}
+
+// SettingsListDefault returns the value that should be presented by
+// `./cockroach gen settings-list`.
+func (v *VersionSetting) SettingsListDefault() string {
+	return v.impl.SettingsListDefault()
+}
+
+// Typ is part of the Setting interface.
+func (*VersionSetting) Typ() string {
+	// This is named "m" (instead of "v") for backwards compatibility reasons.
+	return VersionSettingValueType
+}
+
+// VersionSettingValueType is the value type string (m originally for
+// "migration") used in the system.settings table.
+const VersionSettingValueType = "m"
+
+// String is part of the Setting interface.
+func (v *VersionSetting) String(sv *Values) string {
+	cv := v.GetInternal(sv)
+	if cv == nil {
+		panic("unexpected nil value")
+	}
+	return cv.String()
+}
+
+// DefaultString returns the default value for the setting as a string.
+func (v *VersionSetting) DefaultString() string {
+	return encodedDefaultVersion
+}
+
+// Encoded is part of the NonMaskedSetting interface.
+func (v *VersionSetting) Encoded(sv *Values) string {
+	cv := v.GetInternal(sv)
+	if cv == nil {
+		panic("unexpected nil value")
+	}
+	return string(cv.Encode())
+}
+
+// EncodedDefault is part of the NonMaskedSetting interface.
+func (v *VersionSetting) EncodedDefault() string {
+	return encodedDefaultVersion
+}
+
+const encodedDefaultVersion = "unsupported"
+
+// DecodeToString decodes and renders an encoded value.
+func (v *VersionSetting) DecodeToString(encoded string) (string, error) {
+	if encoded == encodedDefaultVersion {
+		return encodedDefaultVersion, nil
+	}
+	cv, err := v.impl.Decode([]byte(encoded))
+	if err != nil {
+		return "", err
+	}
+	return cv.String(), nil
+}
+
+// GetInternal returns the setting's current value.
+func (v *VersionSetting) GetInternal(sv *Values) ClusterVersionImpl {
+	val := sv.getGeneric(v.slot)
+	if val == nil {
+		return nil
+	}
+	return val.(ClusterVersionImpl)
+}
+
+// SetInternal updates the setting's value in the provided Values container.
+func (v *VersionSetting) SetInternal(ctx context.Context, sv *Values, newVal ClusterVersionImpl) {
+	sv.setGeneric(ctx, v.slot, newVal)
+}
+
+// setToDefault is part of the internalSetting interface. This is a no-op for
+// VersionSetting. They don't have defaults that they can go back to at any
+// time.
+func (v *VersionSetting) setToDefault(ctx context.Context, sv *Values) {}
+
+// decodeAndSet is part of the internalSetting interface. We intentionally avoid
+//
+// We intentionally avoid updating the setting through this code path. The
+// specific setting backed by VersionSetting is the cluster version setting,
+// changes to which are propagated through direct RPCs to each node in the
+// cluster instead of gossip. This is done using the BumpClusterVersion RPC.
+func (v *VersionSetting) decodeAndSet(ctx context.Context, sv *Values, encoded string) error {
+	return nil
+}
+
+// decodeAndSetDefaultOverride is part of the internalSetting interface.
+//
+// We intentionally avoid updating the setting through this code path. The
+// specific setting backed by VersionSetting is the cluster version setting,
+// changes to which are propagated through direct RPCs to each node in the
+// cluster instead of gossip. This is done using the BumpClusterVersion RPC.
+func (v *VersionSetting) decodeAndSetDefaultOverride(
+	ctx context.Context, sv *Values, encoded string,
+) error {
+	return nil
+}
+
+// RegisterVersionSetting adds the provided version setting to the global
+// registry.
+func RegisterVersionSetting(
+	class Class, key InternalKey, desc string, setting *VersionSetting, opts ...SettingOption,
+) {
+	register(class, key, desc, setting)
+	setting.apply(opts)
+}
diff --git a/pkg/sql/colexec/execgen/cmd/execgen/agg_gen_util.go b/pkg/sql/colexec/execgen/cmd/execgen/agg_gen_util.go
index aa380d2..d0bb631 100644
--- a/pkg/sql/colexec/execgen/cmd/execgen/agg_gen_util.go
+++ b/pkg/sql/colexec/execgen/cmd/execgen/agg_gen_util.go
@@ -1,12 +1,7 @@
 // Copyright 2020 The Cockroach Authors.
 //
-// Use of this software is governed by the Business Source License
-// included in the file licenses/BSL.txt.
-//
-// As of the Change Date specified in that file, in accordance with
-// the Business Source License, use of this software will be governed
-// by the Apache License, Version 2.0, included in the file
-// licenses/APL.txt.
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
 
 package main
 
@@ -23,15 +18,63 @@ const (
 	// of aggregator using an aggregate function. It is replaced with "Hash",
 	// "Ordered", or "Window" before executing the template.
 	aggKindTmplVar = "_AGGKIND"
+	aggNameTmplVar = "_AGGNAME"
 	hashAggKind    = "Hash"
 	orderedAggKind = "Ordered"
 	windowAggKind  = "Window"
 )
 
-func registerAggGenerator(aggGen generator, filenameSuffix, dep string, genWindowVariant bool) {
+func registerAggGenerator(
+	aggGen generator, filenameSuffix, dep, aggName string, genWindowVariant bool,
+) {
 	aggGeneratorAdapter := func(aggKind string) generator {
 		return func(inputFileContents string, wr io.Writer) error {
+			inputFileContents = strings.ReplaceAll(inputFileContents, "var _ = _ALLOC_CODE", `
+// {{if eq "_AGGKIND" "Ordered"}}
+
+func init() {
+	// Sanity check the hard-coded number of overloads.
+	var numOverloads int
+	// {{range .}}
+	// {{range .WidthOverloads}}
+	numOverloads++
+	// {{end}}
+	// {{end}}
+	if numOverloads != _AGGNAMENumOverloads {
+		colexecerror.InternalError(errors.AssertionFailedf(
+			"_AGGNAMENumOverloads should be updated: expected %d, found %d", numOverloads, _AGGNAMENumOverloads,
+		))
+	}
+}
+
+// _AGGNAMEOverloadOffset returns the offset for this particular type overload
+// within contiguous slice of allocators for this aggregate function. 
+func _AGGNAMEOverloadOffset(t *types.T) int {
+	var offset int
+	canonicalTypeFamily := typeconv.TypeFamilyToCanonicalTypeFamily(t.Family())
+	// {{range .}}
+	if canonicalTypeFamily == _CANONICAL_TYPE_FAMILY {
+		// {{range .WidthOverloads}}
+		// {{if eq .Width -1}}
+		return offset
+		// {{else}}
+		if t.Width() == {{.Width}} {
+			return offset
+		}
+		offset++
+		// {{end}}
+		// {{end}}
+	}
+	offset += {{len .WidthOverloads}}
+	// {{end}}
+	colexecerror.InternalError(errors.AssertionFailedf("didn't find overload offset for %s", t.SQLStringForError()))
+	return 0
+}
+
+// {{end}}
+`)
 			inputFileContents = strings.ReplaceAll(inputFileContents, aggKindTmplVar, aggKind)
+			inputFileContents = strings.ReplaceAll(inputFileContents, aggNameTmplVar, aggName)
 			return aggGen(inputFileContents, wr)
 		}
 	}
diff --git a/pkg/sql/colexec/execgen/cmd/execgen/and_or_projection_gen.go b/pkg/sql/colexec/execgen/cmd/execgen/and_or_projection_gen.go
index 3d9cfdc..55ebcce 100644
--- a/pkg/sql/colexec/execgen/cmd/execgen/and_or_projection_gen.go
+++ b/pkg/sql/colexec/execgen/cmd/execgen/and_or_projection_gen.go
@@ -1,12 +1,7 @@
 // Copyright 2019 The Cockroach Authors.
 //
-// Use of this software is governed by the Business Source License
-// included in the file licenses/BSL.txt.
-//
-// As of the Change Date specified in that file, in accordance with
-// the Business Source License, use of this software will be governed
-// by the Apache License, Version 2.0, included in the file
-// licenses/APL.txt.
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
 
 package main
 
diff --git a/pkg/sql/colexec/execgen/cmd/execgen/any_not_null_agg_gen.go b/pkg/sql/colexec/execgen/cmd/execgen/any_not_null_agg_gen.go
index 714c971..d97ea92 100644
--- a/pkg/sql/colexec/execgen/cmd/execgen/any_not_null_agg_gen.go
+++ b/pkg/sql/colexec/execgen/cmd/execgen/any_not_null_agg_gen.go
@@ -1,12 +1,7 @@
 // Copyright 2018 The Cockroach Authors.
 //
-// Use of this software is governed by the Business Source License
-// included in the file licenses/BSL.txt.
-//
-// As of the Change Date specified in that file, in accordance with
-// the Business Source License, use of this software will be governed
-// by the Apache License, Version 2.0, included in the file
-// licenses/APL.txt.
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
 
 package main
 
@@ -46,5 +41,7 @@ func genAnyNotNullAgg(inputFileContents string, wr io.Writer) error {
 
 func init() {
 	registerAggGenerator(
-		genAnyNotNullAgg, "any_not_null_agg.eg.go", anyNotNullAggTmpl, false /* genWindowVariant */)
+		genAnyNotNullAgg, "any_not_null_agg.eg.go", /* filenameSuffix */
+		anyNotNullAggTmpl, "anyNotNull" /* aggName */, false, /* genWindowVariant */
+	)
 }
diff --git a/pkg/sql/colexec/execgen/cmd/execgen/avg_agg_gen.go b/pkg/sql/colexec/execgen/cmd/execgen/avg_agg_gen.go
index 9220566..fe470a5 100644
--- a/pkg/sql/colexec/execgen/cmd/execgen/avg_agg_gen.go
+++ b/pkg/sql/colexec/execgen/cmd/execgen/avg_agg_gen.go
@@ -1,12 +1,7 @@
 // Copyright 2018 The Cockroach Authors.
 //
-// Use of this software is governed by the Business Source License
-// included in the file licenses/BSL.txt.
-//
-// As of the Change Date specified in that file, in accordance with
-// the Business Source License, use of this software will be governed
-// by the Apache License, Version 2.0, included in the file
-// licenses/APL.txt.
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
 
 package main
 
@@ -107,7 +102,7 @@ const avgAggTmpl = "pkg/sql/colexec/colexecagg/avg_agg_tmpl.go"
 
 func genAvgAgg(inputFileContents string, wr io.Writer) error {
 	r := strings.NewReplacer(
-		"_TYPE_FAMILY", "{{.TypeFamily}}",
+		"_CANONICAL_TYPE_FAMILY", "{{.TypeFamily}}",
 		"_TYPE_WIDTH", typeWidthReplacement,
 		"_RET_GOTYPESLICE", `{{.RetGoTypeSlice}}`,
 		"_RET_GOTYPE", `{{.RetGoType}}`,
@@ -147,9 +142,10 @@ func genAvgAgg(inputFileContents string, wr io.Writer) error {
 	for _, inputTypeFamily := range []types.Family{types.IntFamily, types.DecimalFamily, types.FloatFamily, types.IntervalFamily} {
 		tmplInfo := avgAggTypeTmplInfo{TypeFamily: familyToString(inputTypeFamily)}
 		for _, inputTypeWidth := range supportedWidthsByCanonicalTypeFamily[inputTypeFamily] {
-			// Note that we don't use execinfrapb.GetAggregateInfo because we don't
-			// want to bring in a dependency on that package to reduce the burden
-			// of regenerating execgen code when the protobufs get generated.
+			// Note that we don't use execinfrapb.GetAggregateOutputType because
+			// we don't want to bring in a dependency on that package to reduce
+			// the burden of regenerating execgen code when the protobufs get
+			// generated.
 			retTypeFamily, retTypeWidth := inputTypeFamily, inputTypeWidth
 			if inputTypeFamily == types.IntFamily {
 				// Average of integers is a decimal.
@@ -174,5 +170,8 @@ func genAvgAgg(inputFileContents string, wr io.Writer) error {
 }
 
 func init() {
-	registerAggGenerator(genAvgAgg, "avg_agg.eg.go", avgAggTmpl, true /* genWindowVariant */)
+	registerAggGenerator(
+		genAvgAgg, "avg_agg.eg.go", /* filenameSuffix */
+		avgAggTmpl, "avg" /* aggName */, true, /* genWindowVariant */
+	)
 }
diff --git a/pkg/sql/colexec/execgen/cmd/execgen/bool_and_or_agg_gen.go b/pkg/sql/colexec/execgen/cmd/execgen/bool_and_or_agg_gen.go
index e5a3790..b12b2e3 100644
--- a/pkg/sql/colexec/execgen/cmd/execgen/bool_and_or_agg_gen.go
+++ b/pkg/sql/colexec/execgen/cmd/execgen/bool_and_or_agg_gen.go
@@ -1,12 +1,7 @@
 // Copyright 2020 The Cockroach Authors.
 //
-// Use of this software is governed by the Business Source License
-// included in the file licenses/BSL.txt.
-//
-// As of the Change Date specified in that file, in accordance with
-// the Business Source License, use of this software will be governed
-// by the Apache License, Version 2.0, included in the file
-// licenses/APL.txt.
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
 
 package main
 
@@ -96,5 +91,7 @@ func genBooleanAgg(inputFileContents string, wr io.Writer) error {
 
 func init() {
 	registerAggGenerator(
-		genBooleanAgg, "bool_and_or_agg.eg.go", boolAggTmpl, true /* genWindowVariant */)
+		genBooleanAgg, "bool_and_or_agg.eg.go", /* filenameSuffix */
+		boolAggTmpl, "boolAndOr", true, /* genWindowVariant */
+	)
 }
diff --git a/pkg/sql/colexec/execgen/cmd/execgen/cast_gen.go b/pkg/sql/colexec/execgen/cmd/execgen/cast_gen.go
index 8384089..afc7f3a 100644
--- a/pkg/sql/colexec/execgen/cmd/execgen/cast_gen.go
+++ b/pkg/sql/colexec/execgen/cmd/execgen/cast_gen.go
@@ -1,12 +1,7 @@
 // Copyright 2019 The Cockroach Authors.
 //
-// Use of this software is governed by the Business Source License
-// included in the file licenses/BSL.txt.
-//
-// As of the Change Date specified in that file, in accordance with
-// the Business Source License, use of this software will be governed
-// by the Apache License, Version 2.0, included in the file
-// licenses/APL.txt.
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
 
 package main
 
diff --git a/pkg/sql/colexec/execgen/cmd/execgen/cast_gen_util.go b/pkg/sql/colexec/execgen/cmd/execgen/cast_gen_util.go
index 757d1db..916e911 100644
--- a/pkg/sql/colexec/execgen/cmd/execgen/cast_gen_util.go
+++ b/pkg/sql/colexec/execgen/cmd/execgen/cast_gen_util.go
@@ -1,12 +1,7 @@
 // Copyright 2021 The Cockroach Authors.
 //
-// Use of this software is governed by the Business Source License
-// included in the file licenses/BSL.txt.
-//
-// As of the Change Date specified in that file, in accordance with
-// the Business Source License, use of this software will be governed
-// by the Apache License, Version 2.0, included in the file
-// licenses/APL.txt.
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
 
 package main
 
@@ -271,7 +266,7 @@ func floatToInt(intWidth, floatWidth int32) castFunc {
 			if math.IsNaN(float64(%[2]s)) || %[2]s <= float%[4]d(math.MinInt%[3]d) || %[2]s >= float%[4]d(math.MaxInt%[3]d) {
 				colexecerror.ExpectedError(tree.ErrIntOutOfRange)
 			}
-			%[1]s = int%[3]d(%[2]s)
+			%[1]s = int%[3]d(math.RoundToEven(%[2]s))
 		`
 		if intWidth == anyWidth {
 			intWidth = 64
@@ -589,7 +584,8 @@ func getStringToTimestampCastFunc(withoutTimezone bool) castFunc {
 		_roundTo := tree.TimeFamilyPrecisionToRoundDuration(%[4]s.Precision())
 		_now := %[3]s.GetRelativeParseTime()
 		_dateStyle := %[3]s.GetDateStyle()
-		_t, _, err := pgdate.ParseTimestamp%[5]s(_now, _dateStyle, string(%[2]s))
+		_h := %[3]s.GetDateHelper()
+		_t, _, err := pgdate.ParseTimestamp%[5]s(_now, _dateStyle, string(%[2]s), _h)
 		if err != nil {
 			colexecerror.ExpectedError(err)
 		}
diff --git a/pkg/sql/colexec/execgen/cmd/execgen/concat_agg_gen.go b/pkg/sql/colexec/execgen/cmd/execgen/concat_agg_gen.go
index 5b9db05..34da925 100644
--- a/pkg/sql/colexec/execgen/cmd/execgen/concat_agg_gen.go
+++ b/pkg/sql/colexec/execgen/cmd/execgen/concat_agg_gen.go
@@ -1,12 +1,7 @@
 // Copyright 2020 The Cockroach Authors.
 //
-// Use of this software is governed by the Business Source License
-// included in the file licenses/BSL.txt.
-//
-// As of the Change Date specified in that file, in accordance with
-// the Business Source License, use of this software will be governed
-// by the Apache License, Version 2.0, included in the file
-// licenses/APL.txt.
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
 
 package main
 
@@ -34,5 +29,7 @@ func genConcatAgg(inputFileContents string, wr io.Writer) error {
 
 func init() {
 	registerAggGenerator(
-		genConcatAgg, "concat_agg.eg.go", concatAggTmpl, true /* genWindowVariant */)
+		genConcatAgg, "concat_agg.eg.go", /* filenameSuffix */
+		concatAggTmpl, "concat" /* aggName */, true, /* genWindowVariant */
+	)
 }
diff --git a/pkg/sql/colexec/execgen/cmd/execgen/const_gen.go b/pkg/sql/colexec/execgen/cmd/execgen/const_gen.go
index e408539..7354575 100644
--- a/pkg/sql/colexec/execgen/cmd/execgen/const_gen.go
+++ b/pkg/sql/colexec/execgen/cmd/execgen/const_gen.go
@@ -1,12 +1,7 @@
 // Copyright 2019 The Cockroach Authors.
 //
-// Use of this software is governed by the Business Source License
-// included in the file licenses/BSL.txt.
-//
-// As of the Change Date specified in that file, in accordance with
-// the Business Source License, use of this software will be governed
-// by the Apache License, Version 2.0, included in the file
-// licenses/APL.txt.
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
 
 package main
 
diff --git a/pkg/sql/colexec/execgen/cmd/execgen/count_agg_gen.go b/pkg/sql/colexec/execgen/cmd/execgen/count_agg_gen.go
index c52a67a..155d538 100644
--- a/pkg/sql/colexec/execgen/cmd/execgen/count_agg_gen.go
+++ b/pkg/sql/colexec/execgen/cmd/execgen/count_agg_gen.go
@@ -1,12 +1,7 @@
 // Copyright 2019 The Cockroach Authors.
 //
-// Use of this software is governed by the Business Source License
-// included in the file licenses/BSL.txt.
-//
-// As of the Change Date specified in that file, in accordance with
-// the Business Source License, use of this software will be governed
-// by the Apache License, Version 2.0, included in the file
-// licenses/APL.txt.
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
 
 package main
 
@@ -56,5 +51,8 @@ func genCountAgg(inputFileContents string, wr io.Writer) error {
 }
 
 func init() {
-	registerAggGenerator(genCountAgg, "count_agg.eg.go", countAggTmpl, true /* genWindowVariant */)
+	registerAggGenerator(
+		genCountAgg, "count_agg.eg.go", /* filenameSuffix */
+		countAggTmpl, "count" /* aggName */, true, /* genWindowVariant */
+	)
 }
diff --git a/pkg/sql/colexec/execgen/cmd/execgen/crossjoiner_gen.go b/pkg/sql/colexec/execgen/cmd/execgen/crossjoiner_gen.go
index 152b609..103b611 100644
--- a/pkg/sql/colexec/execgen/cmd/execgen/crossjoiner_gen.go
+++ b/pkg/sql/colexec/execgen/cmd/execgen/crossjoiner_gen.go
@@ -1,12 +1,7 @@
 // Copyright 2020 The Cockroach Authors.
 //
-// Use of this software is governed by the Business Source License
-// included in the file licenses/BSL.txt.
-//
-// As of the Change Date specified in that file, in accordance with
-// the Business Source License, use of this software will be governed
-// by the Apache License, Version 2.0, included in the file
-// licenses/APL.txt.
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
 
 package main
 
diff --git a/pkg/sql/colexec/execgen/cmd/execgen/data_manipulation_gen.go b/pkg/sql/colexec/execgen/cmd/execgen/data_manipulation_gen.go
index f08a57d..ff167a1 100644
--- a/pkg/sql/colexec/execgen/cmd/execgen/data_manipulation_gen.go
+++ b/pkg/sql/colexec/execgen/cmd/execgen/data_manipulation_gen.go
@@ -1,12 +1,7 @@
 // Copyright 2019 The Cockroach Authors.
 //
-// Use of this software is governed by the Business Source License
-// included in the file licenses/BSL.txt.
-//
-// As of the Change Date specified in that file, in accordance with
-// the Business Source License, use of this software will be governed
-// by the Apache License, Version 2.0, included in the file
-// licenses/APL.txt.
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
 
 package main
 
diff --git a/pkg/sql/colexec/execgen/cmd/execgen/datum_to_vec_gen.go b/pkg/sql/colexec/execgen/cmd/execgen/datum_to_vec_gen.go
index a346b25..e121619 100644
--- a/pkg/sql/colexec/execgen/cmd/execgen/datum_to_vec_gen.go
+++ b/pkg/sql/colexec/execgen/cmd/execgen/datum_to_vec_gen.go
@@ -1,12 +1,7 @@
 // Copyright 2020 The Cockroach Authors.
 //
-// Use of this software is governed by the Business Source License
-// included in the file licenses/BSL.txt.
-//
-// As of the Change Date specified in that file, in accordance with
-// the Business Source License, use of this software will be governed
-// by the Apache License, Version 2.0, included in the file
-// licenses/APL.txt.
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
 
 package main
 
diff --git a/pkg/sql/colexec/execgen/cmd/execgen/default_agg_gen.go b/pkg/sql/colexec/execgen/cmd/execgen/default_agg_gen.go
index ac6126b..40cdc9e 100644
--- a/pkg/sql/colexec/execgen/cmd/execgen/default_agg_gen.go
+++ b/pkg/sql/colexec/execgen/cmd/execgen/default_agg_gen.go
@@ -1,12 +1,7 @@
 // Copyright 2020 The Cockroach Authors.
 //
-// Use of this software is governed by the Business Source License
-// included in the file licenses/BSL.txt.
-//
-// As of the Change Date specified in that file, in accordance with
-// the Business Source License, use of this software will be governed
-// by the Apache License, Version 2.0, included in the file
-// licenses/APL.txt.
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
 
 package main
 
@@ -35,5 +30,7 @@ func genDefaultAgg(inputFileContents string, wr io.Writer) error {
 
 func init() {
 	registerAggGenerator(
-		genDefaultAgg, "default_agg.eg.go", defaultAggTmpl, false /* genWindowVariant */)
+		genDefaultAgg, "default_agg.eg.go", /* filenameSuffix */
+		defaultAggTmpl, "defaultAgg" /* aggName */, false, /* genWindowVariant */
+	)
 }
diff --git a/pkg/sql/colexec/execgen/cmd/execgen/default_cmp_expr_gen.go b/pkg/sql/colexec/execgen/cmd/execgen/default_cmp_expr_gen.go
index b7b6c9f..1f488b5 100644
--- a/pkg/sql/colexec/execgen/cmd/execgen/default_cmp_expr_gen.go
+++ b/pkg/sql/colexec/execgen/cmd/execgen/default_cmp_expr_gen.go
@@ -1,12 +1,7 @@
 // Copyright 2020 The Cockroach Authors.
 //
-// Use of this software is governed by the Business Source License
-// included in the file licenses/BSL.txt.
-//
-// As of the Change Date specified in that file, in accordance with
-// the Business Source License, use of this software will be governed
-// by the Apache License, Version 2.0, included in the file
-// licenses/APL.txt.
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
 
 package main
 
diff --git a/pkg/sql/colexec/execgen/cmd/execgen/default_cmp_proj_ops_gen.go b/pkg/sql/colexec/execgen/cmd/execgen/default_cmp_proj_ops_gen.go
index ccc2cb4..f4e3155 100644
--- a/pkg/sql/colexec/execgen/cmd/execgen/default_cmp_proj_ops_gen.go
+++ b/pkg/sql/colexec/execgen/cmd/execgen/default_cmp_proj_ops_gen.go
@@ -1,12 +1,7 @@
 // Copyright 2020 The Cockroach Authors.
 //
-// Use of this software is governed by the Business Source License
-// included in the file licenses/BSL.txt.
-//
-// As of the Change Date specified in that file, in accordance with
-// the Business Source License, use of this software will be governed
-// by the Apache License, Version 2.0, included in the file
-// licenses/APL.txt.
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
 
 package main
 
@@ -23,13 +18,8 @@ import (
 const defaultCmpProjTemplate = `
 // Copyright 2020 The Cockroach Authors.
 //
-// Use of this software is governed by the Business Source License
-// included in the file licenses/BSL.txt.
-//
-// As of the Change Date specified in that file, in accordance with
-// the Business Source License, use of this software will be governed
-// by the Apache License, Version 2.0, included in the file
-// licenses/APL.txt.
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
 
 package {{.TargetPkg}}
 
diff --git a/pkg/sql/colexec/execgen/cmd/execgen/default_cmp_sel_ops_gen.go b/pkg/sql/colexec/execgen/cmd/execgen/default_cmp_sel_ops_gen.go
index dce1843..96e0b9d 100644
--- a/pkg/sql/colexec/execgen/cmd/execgen/default_cmp_sel_ops_gen.go
+++ b/pkg/sql/colexec/execgen/cmd/execgen/default_cmp_sel_ops_gen.go
@@ -1,12 +1,7 @@
 // Copyright 2020 The Cockroach Authors.
 //
-// Use of this software is governed by the Business Source License
-// included in the file licenses/BSL.txt.
-//
-// As of the Change Date specified in that file, in accordance with
-// the Business Source License, use of this software will be governed
-// by the Apache License, Version 2.0, included in the file
-// licenses/APL.txt.
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
 
 package main
 
diff --git a/pkg/sql/colexec/execgen/cmd/execgen/distinct_gen.go b/pkg/sql/colexec/execgen/cmd/execgen/distinct_gen.go
index 8bbe3b6..c59a08d 100644
--- a/pkg/sql/colexec/execgen/cmd/execgen/distinct_gen.go
+++ b/pkg/sql/colexec/execgen/cmd/execgen/distinct_gen.go
@@ -1,12 +1,7 @@
 // Copyright 2018 The Cockroach Authors.
 //
-// Use of this software is governed by the Business Source License
-// included in the file licenses/BSL.txt.
-//
-// As of the Change Date specified in that file, in accordance with
-// the Business Source License, use of this software will be governed
-// by the Apache License, Version 2.0, included in the file
-// licenses/APL.txt.
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
 
 package main
 
@@ -28,13 +23,8 @@ import (
 const distinctTmpl = `
 // Copyright 2018 The Cockroach Authors.
 //
-// Use of this software is governed by the Business Source License
-// included in the file licenses/BSL.txt.
-//
-// As of the Change Date specified in that file, in accordance with
-// the Business Source License, use of this software will be governed
-// by the Apache License, Version 2.0, included in the file
-// licenses/APL.txt.
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
 
 package %s
 
diff --git a/pkg/sql/colexec/execgen/cmd/execgen/first_last_nth_value_gen.go b/pkg/sql/colexec/execgen/cmd/execgen/first_last_nth_value_gen.go
index c0c4b3e..8df525d 100644
--- a/pkg/sql/colexec/execgen/cmd/execgen/first_last_nth_value_gen.go
+++ b/pkg/sql/colexec/execgen/cmd/execgen/first_last_nth_value_gen.go
@@ -1,12 +1,7 @@
 // Copyright 2021 The Cockroach Authors.
 //
-// Use of this software is governed by the Business Source License
-// included in the file licenses/BSL.txt.
-//
-// As of the Change Date specified in that file, in accordance with
-// the Business Source License, use of this software will be governed
-// by the Apache License, Version 2.0, included in the file
-// licenses/APL.txt.
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
 
 package main
 
diff --git a/pkg/sql/colexec/execgen/cmd/execgen/hash_aggregator_gen.go b/pkg/sql/colexec/execgen/cmd/execgen/hash_aggregator_gen.go
index 9c466e2..669a42f 100644
--- a/pkg/sql/colexec/execgen/cmd/execgen/hash_aggregator_gen.go
+++ b/pkg/sql/colexec/execgen/cmd/execgen/hash_aggregator_gen.go
@@ -1,12 +1,7 @@
 // Copyright 2020 The Cockroach Authors.
 //
-// Use of this software is governed by the Business Source License
-// included in the file licenses/BSL.txt.
-//
-// As of the Change Date specified in that file, in accordance with
-// the Business Source License, use of this software will be governed
-// by the Apache License, Version 2.0, included in the file
-// licenses/APL.txt.
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
 
 package main
 
diff --git a/pkg/sql/colexec/execgen/cmd/execgen/hash_utils_gen.go b/pkg/sql/colexec/execgen/cmd/execgen/hash_utils_gen.go
index fff2916..84f4d2e 100644
--- a/pkg/sql/colexec/execgen/cmd/execgen/hash_utils_gen.go
+++ b/pkg/sql/colexec/execgen/cmd/execgen/hash_utils_gen.go
@@ -1,12 +1,7 @@
 // Copyright 2020 The Cockroach Authors.
 //
-// Use of this software is governed by the Business Source License
-// included in the file licenses/BSL.txt.
-//
-// As of the Change Date specified in that file, in accordance with
-// the Business Source License, use of this software will be governed
-// by the Apache License, Version 2.0, included in the file
-// licenses/APL.txt.
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
 
 package main
 
@@ -25,14 +20,18 @@ func genHashUtils(inputFileContents string, wr io.Writer) error {
 		"_TYPE_WIDTH", typeWidthReplacement,
 		"_TYPE", "{{.VecMethod}}",
 		"TemplateType", "{{.VecMethod}}",
+		// Currently, github.com/dave/dst library used by execgen doesn't
+		// support the generics well, so we need to put the generic type clause
+		// manually.
+		"func rehash(", "func rehash[T uint32 | uint64](",
 	)
 	s := r.Replace(inputFileContents)
 
 	assignHash := makeFunctionRegex("_ASSIGN_HASH", 4)
 	s = assignHash.ReplaceAllString(s, makeTemplateFunctionCall("Global.AssignHash", 4))
 
-	rehash := makeFunctionRegex("_REHASH_BODY", 8)
-	s = rehash.ReplaceAllString(s, `{{template "rehashBody" buildDict "Global" . "HasSel" $6 "HasNulls" $7 "Uint64" $8}}`)
+	rehash := makeFunctionRegex("_REHASH_BODY", 7)
+	s = rehash.ReplaceAllString(s, `{{template "rehashBody" buildDict "Global" . "HasSel" $6 "HasNulls" $7}}`)
 
 	s = replaceManipulationFuncsAmbiguous(".Global", s)
 
diff --git a/pkg/sql/colexec/execgen/cmd/execgen/hashjoiner_gen.go b/pkg/sql/colexec/execgen/cmd/execgen/hashjoiner_gen.go
index 4fd6855..cc3b4d1 100644
--- a/pkg/sql/colexec/execgen/cmd/execgen/hashjoiner_gen.go
+++ b/pkg/sql/colexec/execgen/cmd/execgen/hashjoiner_gen.go
@@ -1,12 +1,7 @@
 // Copyright 2018 The Cockroach Authors.
 //
-// Use of this software is governed by the Business Source License
-// included in the file licenses/BSL.txt.
-//
-// As of the Change Date specified in that file, in accordance with
-// the Business Source License, use of this software will be governed
-// by the Apache License, Version 2.0, included in the file
-// licenses/APL.txt.
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
 
 package main
 
diff --git a/pkg/sql/colexec/execgen/cmd/execgen/hashtable_gen.go b/pkg/sql/colexec/execgen/cmd/execgen/hashtable_gen.go
index b45f6bb..dfbc892 100644
--- a/pkg/sql/colexec/execgen/cmd/execgen/hashtable_gen.go
+++ b/pkg/sql/colexec/execgen/cmd/execgen/hashtable_gen.go
@@ -1,12 +1,7 @@
 // Copyright 2020 The Cockroach Authors.
 //
-// Use of this software is governed by the Business Source License
-// included in the file licenses/BSL.txt.
-//
-// As of the Change Date specified in that file, in accordance with
-// the Business Source License, use of this software will be governed
-// by the Apache License, Version 2.0, included in the file
-// licenses/APL.txt.
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
 
 package main
 
diff --git a/pkg/sql/colexec/execgen/cmd/execgen/is_null_ops_gen.go b/pkg/sql/colexec/execgen/cmd/execgen/is_null_ops_gen.go
index 15394fd..0cfaafe 100644
--- a/pkg/sql/colexec/execgen/cmd/execgen/is_null_ops_gen.go
+++ b/pkg/sql/colexec/execgen/cmd/execgen/is_null_ops_gen.go
@@ -1,12 +1,7 @@
 // Copyright 2020 The Cockroach Authors.
 //
-// Use of this software is governed by the Business Source License
-// included in the file licenses/BSL.txt.
-//
-// As of the Change Date specified in that file, in accordance with
-// the Business Source License, use of this software will be governed
-// by the Apache License, Version 2.0, included in the file
-// licenses/APL.txt.
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
 
 package main
 
diff --git a/pkg/sql/colexec/execgen/cmd/execgen/lead_lag_gen.go b/pkg/sql/colexec/execgen/cmd/execgen/lead_lag_gen.go
index 911261b..a14ecba 100644
--- a/pkg/sql/colexec/execgen/cmd/execgen/lead_lag_gen.go
+++ b/pkg/sql/colexec/execgen/cmd/execgen/lead_lag_gen.go
@@ -1,12 +1,7 @@
 // Copyright 2021 The Cockroach Authors.
 //
-// Use of this software is governed by the Business Source License
-// included in the file licenses/BSL.txt.
-//
-// As of the Change Date specified in that file, in accordance with
-// the Business Source License, use of this software will be governed
-// by the Apache License, Version 2.0, included in the file
-// licenses/APL.txt.
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
 
 package main
 
diff --git a/pkg/sql/colexec/execgen/cmd/execgen/like_ops_gen.go b/pkg/sql/colexec/execgen/cmd/execgen/like_ops_gen.go
index 93dac85..f205881 100644
--- a/pkg/sql/colexec/execgen/cmd/execgen/like_ops_gen.go
+++ b/pkg/sql/colexec/execgen/cmd/execgen/like_ops_gen.go
@@ -1,12 +1,7 @@
 // Copyright 2019 The Cockroach Authors.
 //
-// Use of this software is governed by the Business Source License
-// included in the file licenses/BSL.txt.
-//
-// As of the Change Date specified in that file, in accordance with
-// the Business Source License, use of this software will be governed
-// by the Apache License, Version 2.0, included in the file
-// licenses/APL.txt.
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
 
 package main
 
@@ -31,13 +26,8 @@ import (
 const likeTemplate = `
 // Copyright 2019 The Cockroach Authors.
 //
-// Use of this software is governed by the Business Source License
-// included in the file licenses/BSL.txt.
-//
-// As of the Change Date specified in that file, in accordance with
-// the Business Source License, use of this software will be governed
-// by the Apache License, Version 2.0, included in the file
-// licenses/APL.txt.
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
 
 package colexec%[1]s
 
diff --git a/pkg/sql/colexec/execgen/cmd/execgen/main.go b/pkg/sql/colexec/execgen/cmd/execgen/main.go
index 5760876..acf6c2c 100644
--- a/pkg/sql/colexec/execgen/cmd/execgen/main.go
+++ b/pkg/sql/colexec/execgen/cmd/execgen/main.go
@@ -1,12 +1,7 @@
 // Copyright 2018 The Cockroach Authors.
 //
-// Use of this software is governed by the Business Source License
-// included in the file licenses/BSL.txt.
-//
-// As of the Change Date specified in that file, in accordance with
-// the Business Source License, use of this software will be governed
-// by the Apache License, Version 2.0, included in the file
-// licenses/APL.txt.
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
 
 package main
 
@@ -145,7 +140,7 @@ func (g *execgenTool) generate(path string, entry entry) error {
 			return err
 		}
 		// Delete execgen_template build tag.
-		inputFileBytes = bytes.ReplaceAll(inputFileBytes, []byte("// +build execgen_template"), []byte{})
+		inputFileBytes = bytes.ReplaceAll(inputFileBytes, []byte("//go:build execgen_template"), []byte{})
 		inputFileContents, err = execgen.Generate(string(inputFileBytes))
 		if err != nil {
 			return err
@@ -164,9 +159,6 @@ func (g *execgenTool) generate(path string, entry entry) error {
 	}
 
 	b := buf.Bytes()
-	// Delete execgen_template build tag.
-	b = bytes.ReplaceAll(b, []byte("//go:build execgen_template"), []byte{})
-	b = bytes.ReplaceAll(b, []byte("// +build execgen_template"), []byte{})
 
 	// Delete empty comments (/* */) that tend to get generated by templating.
 	// As well as empty line comments that are _not_ at the beginning of a line.
diff --git a/pkg/sql/colexec/execgen/cmd/execgen/mergejoinbase_gen.go b/pkg/sql/colexec/execgen/cmd/execgen/mergejoinbase_gen.go
index db215b5..e259757 100644
--- a/pkg/sql/colexec/execgen/cmd/execgen/mergejoinbase_gen.go
+++ b/pkg/sql/colexec/execgen/cmd/execgen/mergejoinbase_gen.go
@@ -1,12 +1,7 @@
 // Copyright 2019 The Cockroach Authors.
 //
-// Use of this software is governed by the Business Source License
-// included in the file licenses/BSL.txt.
-//
-// As of the Change Date specified in that file, in accordance with
-// the Business Source License, use of this software will be governed
-// by the Apache License, Version 2.0, included in the file
-// licenses/APL.txt.
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
 
 package main
 
diff --git a/pkg/sql/colexec/execgen/cmd/execgen/mergejoiner_gen.go b/pkg/sql/colexec/execgen/cmd/execgen/mergejoiner_gen.go
index ae72707..9920745 100644
--- a/pkg/sql/colexec/execgen/cmd/execgen/mergejoiner_gen.go
+++ b/pkg/sql/colexec/execgen/cmd/execgen/mergejoiner_gen.go
@@ -1,12 +1,7 @@
 // Copyright 2019 The Cockroach Authors.
 //
-// Use of this software is governed by the Business Source License
-// included in the file licenses/BSL.txt.
-//
-// As of the Change Date specified in that file, in accordance with
-// the Business Source License, use of this software will be governed
-// by the Apache License, Version 2.0, included in the file
-// licenses/APL.txt.
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
 
 package main
 
diff --git a/pkg/sql/colexec/execgen/cmd/execgen/min_max_agg_gen.go b/pkg/sql/colexec/execgen/cmd/execgen/min_max_agg_gen.go
index 1618bad..1697a22 100644
--- a/pkg/sql/colexec/execgen/cmd/execgen/min_max_agg_gen.go
+++ b/pkg/sql/colexec/execgen/cmd/execgen/min_max_agg_gen.go
@@ -1,12 +1,7 @@
 // Copyright 2018 The Cockroach Authors.
 //
-// Use of this software is governed by the Business Source License
-// included in the file licenses/BSL.txt.
-//
-// As of the Change Date specified in that file, in accordance with
-// the Business Source License, use of this software will be governed
-// by the Apache License, Version 2.0, included in the file
-// licenses/APL.txt.
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
 
 package main
 
@@ -65,5 +60,7 @@ func genMinMaxAgg(inputFileContents string, wr io.Writer) error {
 
 func init() {
 	registerAggGenerator(
-		genMinMaxAgg, "min_max_agg.eg.go", minMaxAggTmpl, true /* genWindowVariant */)
+		genMinMaxAgg, "min_max_agg.eg.go", /* filenameSuffix */
+		minMaxAggTmpl, "minMax" /* aggName */, true, /* genWindowVariant */
+	)
 }
diff --git a/pkg/sql/colexec/execgen/cmd/execgen/min_max_removable_agg_gen.go b/pkg/sql/colexec/execgen/cmd/execgen/min_max_removable_agg_gen.go
index 2f2f8bc..4f34729 100644
--- a/pkg/sql/colexec/execgen/cmd/execgen/min_max_removable_agg_gen.go
+++ b/pkg/sql/colexec/execgen/cmd/execgen/min_max_removable_agg_gen.go
@@ -1,12 +1,7 @@
 // Copyright 2021 The Cockroach Authors.
 //
-// Use of this software is governed by the Business Source License
-// included in the file licenses/BSL.txt.
-//
-// As of the Change Date specified in that file, in accordance with
-// the Business Source License, use of this software will be governed
-// by the Apache License, Version 2.0, included in the file
-// licenses/APL.txt.
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
 
 package main
 
diff --git a/pkg/sql/colexec/execgen/cmd/execgen/ntile_gen.go b/pkg/sql/colexec/execgen/cmd/execgen/ntile_gen.go
index c284986..687046b 100644
--- a/pkg/sql/colexec/execgen/cmd/execgen/ntile_gen.go
+++ b/pkg/sql/colexec/execgen/cmd/execgen/ntile_gen.go
@@ -1,12 +1,7 @@
 // Copyright 2021 The Cockroach Authors.
 //
-// Use of this software is governed by the Business Source License
-// included in the file licenses/BSL.txt.
-//
-// As of the Change Date specified in that file, in accordance with
-// the Business Source License, use of this software will be governed
-// by the Apache License, Version 2.0, included in the file
-// licenses/APL.txt.
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
 
 package main
 
diff --git a/pkg/sql/colexec/execgen/cmd/execgen/ordered_synchronizer_gen.go b/pkg/sql/colexec/execgen/cmd/execgen/ordered_synchronizer_gen.go
index b846859..2e17965 100644
--- a/pkg/sql/colexec/execgen/cmd/execgen/ordered_synchronizer_gen.go
+++ b/pkg/sql/colexec/execgen/cmd/execgen/ordered_synchronizer_gen.go
@@ -1,12 +1,7 @@
 // Copyright 2020 The Cockroach Authors.
 //
-// Use of this software is governed by the Business Source License
-// included in the file licenses/BSL.txt.
-//
-// As of the Change Date specified in that file, in accordance with
-// the Business Source License, use of this software will be governed
-// by the Apache License, Version 2.0, included in the file
-// licenses/APL.txt.
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
 
 package main
 
diff --git a/pkg/sql/colexec/execgen/cmd/execgen/overloads_abbr.go b/pkg/sql/colexec/execgen/cmd/execgen/overloads_abbr.go
index 15cf35d..f77618e 100644
--- a/pkg/sql/colexec/execgen/cmd/execgen/overloads_abbr.go
+++ b/pkg/sql/colexec/execgen/cmd/execgen/overloads_abbr.go
@@ -1,12 +1,7 @@
 // Copyright 2021 The Cockroach Authors.
 //
-// Use of this software is governed by the Business Source License
-// included in the file licenses/BSL.txt.
-//
-// As of the Change Date specified in that file, in accordance with
-// the Business Source License, use of this software will be governed
-// by the Apache License, Version 2.0, included in the file
-// licenses/APL.txt.
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
 
 package main
 
diff --git a/pkg/sql/colexec/execgen/cmd/execgen/overloads_base.go b/pkg/sql/colexec/execgen/cmd/execgen/overloads_base.go
index 72c8a82..bed2ca1 100644
--- a/pkg/sql/colexec/execgen/cmd/execgen/overloads_base.go
+++ b/pkg/sql/colexec/execgen/cmd/execgen/overloads_base.go
@@ -1,12 +1,7 @@
 // Copyright 2018 The Cockroach Authors.
 //
-// Use of this software is governed by the Business Source License
-// included in the file licenses/BSL.txt.
-//
-// As of the Change Date specified in that file, in accordance with
-// the Business Source License, use of this software will be governed
-// by the Apache License, Version 2.0, included in the file
-// licenses/APL.txt.
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
 
 package main
 
@@ -855,8 +850,8 @@ var supportedWidthsByCanonicalTypeFamily = map[types.Family][]int32{
 
 var numericCanonicalTypeFamilies = []types.Family{types.IntFamily, types.FloatFamily, types.DecimalFamily}
 
-// toVecMethod returns the method name from coldata.Vec interface that can be
-// used to get the well-typed underlying memory from a vector.
+// toVecMethod returns the method name from coldata.Vec struct that can be used
+// to get the well-typed underlying memory from a vector.
 func toVecMethod(canonicalTypeFamily types.Family, width int32) string {
 	switch canonicalTypeFamily {
 	case types.BoolFamily:
diff --git a/pkg/sql/colexec/execgen/cmd/execgen/overloads_bin.go b/pkg/sql/colexec/execgen/cmd/execgen/overloads_bin.go
index 561673e..8fe0351 100644
--- a/pkg/sql/colexec/execgen/cmd/execgen/overloads_bin.go
+++ b/pkg/sql/colexec/execgen/cmd/execgen/overloads_bin.go
@@ -1,12 +1,7 @@
 // Copyright 2020 The Cockroach Authors.
 //
-// Use of this software is governed by the Business Source License
-// included in the file licenses/BSL.txt.
-//
-// As of the Change Date specified in that file, in accordance with
-// the Business Source License, use of this software will be governed
-// by the Apache License, Version 2.0, included in the file
-// licenses/APL.txt.
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
 
 package main
 
@@ -31,7 +26,7 @@ var binaryOpDecMethod = map[treebin.BinaryOperatorSymbol]string{
 	treebin.Div:      "Quo",
 	treebin.FloorDiv: "QuoInteger",
 	treebin.Mod:      "Rem",
-	treebin.Pow:      "Pow",
+	treebin.Pow:      "DecimalPow",
 }
 
 var binaryOpFloatMethod = map[treebin.BinaryOperatorSymbol]string{
@@ -119,7 +114,7 @@ func registerBinOpOutputTypes() {
 	for _, binOp := range []treebin.BinaryOperatorSymbol{treebin.Bitand, treebin.Bitor, treebin.Bitxor} {
 		binOpOutputTypes[binOp] = make(map[typePair]*types.T)
 		populateBinOpIntOutputTypeOnIntArgs(binOp)
-		binOpOutputTypes[binOp][typePair{typeconv.DatumVecCanonicalTypeFamily, anyWidth, typeconv.DatumVecCanonicalTypeFamily, anyWidth}] = types.Any
+		binOpOutputTypes[binOp][typePair{typeconv.DatumVecCanonicalTypeFamily, anyWidth, typeconv.DatumVecCanonicalTypeFamily, anyWidth}] = types.AnyElement
 	}
 
 	// Simple arithmetic binary operators.
@@ -162,8 +157,8 @@ func registerBinOpOutputTypes() {
 		types.IntervalFamily, // types.Time + types.Interval
 	} {
 		for _, width := range supportedWidthsByCanonicalTypeFamily[compatibleFamily] {
-			binOpOutputTypes[treebin.Plus][typePair{typeconv.DatumVecCanonicalTypeFamily, anyWidth, compatibleFamily, width}] = types.Any
-			binOpOutputTypes[treebin.Plus][typePair{compatibleFamily, width, typeconv.DatumVecCanonicalTypeFamily, anyWidth}] = types.Any
+			binOpOutputTypes[treebin.Plus][typePair{typeconv.DatumVecCanonicalTypeFamily, anyWidth, compatibleFamily, width}] = types.AnyElement
+			binOpOutputTypes[treebin.Plus][typePair{compatibleFamily, width, typeconv.DatumVecCanonicalTypeFamily, anyWidth}] = types.AnyElement
 		}
 	}
 	for _, compatibleFamily := range []types.Family{
@@ -173,8 +168,8 @@ func registerBinOpOutputTypes() {
 		types.BytesFamily,                    // types.Jsonb - types.String
 	} {
 		for _, width := range supportedWidthsByCanonicalTypeFamily[compatibleFamily] {
-			binOpOutputTypes[treebin.Minus][typePair{typeconv.DatumVecCanonicalTypeFamily, anyWidth, compatibleFamily, width}] = types.Any
-			binOpOutputTypes[treebin.Minus][typePair{compatibleFamily, width, typeconv.DatumVecCanonicalTypeFamily, anyWidth}] = types.Any
+			binOpOutputTypes[treebin.Minus][typePair{typeconv.DatumVecCanonicalTypeFamily, anyWidth, compatibleFamily, width}] = types.AnyElement
+			binOpOutputTypes[treebin.Minus][typePair{compatibleFamily, width, typeconv.DatumVecCanonicalTypeFamily, anyWidth}] = types.AnyElement
 		}
 	}
 
@@ -193,14 +188,14 @@ func registerBinOpOutputTypes() {
 	// Other non-arithmetic binary operators.
 	binOpOutputTypes[treebin.Concat] = map[typePair]*types.T{
 		{types.BytesFamily, anyWidth, types.BytesFamily, anyWidth}:                                       types.Bytes,
-		{typeconv.DatumVecCanonicalTypeFamily, anyWidth, typeconv.DatumVecCanonicalTypeFamily, anyWidth}: types.Any,
+		{typeconv.DatumVecCanonicalTypeFamily, anyWidth, typeconv.DatumVecCanonicalTypeFamily, anyWidth}: types.AnyElement,
 	}
 
 	for _, binOp := range []treebin.BinaryOperatorSymbol{treebin.LShift, treebin.RShift} {
 		binOpOutputTypes[binOp] = make(map[typePair]*types.T)
 		populateBinOpIntOutputTypeOnIntArgs(binOp)
 		for _, intWidth := range supportedWidthsByCanonicalTypeFamily[types.IntFamily] {
-			binOpOutputTypes[binOp][typePair{typeconv.DatumVecCanonicalTypeFamily, anyWidth, types.IntFamily, intWidth}] = types.Any
+			binOpOutputTypes[binOp][typePair{typeconv.DatumVecCanonicalTypeFamily, anyWidth, types.IntFamily, intWidth}] = types.AnyElement
 		}
 	}
 
@@ -327,6 +322,7 @@ func (decimalCustomizer) getBinOpAssignFunc() assignFunc {
 			"Target":           targetElem,
 			"Left":             leftElem,
 			"Right":            rightElem,
+			"IsPow":            binOp == treebin.Pow,
 		}
 		buf := strings.Builder{}
 		t := template.Must(template.New("").Parse(`
@@ -336,7 +332,11 @@ func (decimalCustomizer) getBinOpAssignFunc() assignFunc {
 					colexecerror.ExpectedError(tree.ErrDivByZero)
 				}
 				{{end}}
+				{{if .IsPow -}}
+				err := eval.{{.Op}}(tree.{{.Ctx}}, &{{.Target}}, &{{.Left}}, &{{.Right}})
+				{{else -}}
 				_, err := tree.{{.Ctx}}.{{.Op}}(&{{.Target}}, &{{.Left}}, &{{.Right}})
+				{{end -}}
 				if err != nil {
 					colexecerror.ExpectedError(err)
 				}
@@ -494,7 +494,7 @@ func (c intCustomizer) getBinOpAssignFunc() assignFunc {
 				var leftTmpDec, rightTmpDec apd.Decimal //gcassert:noescape
 				leftTmpDec.SetInt64(int64({{.Left}}))
 				rightTmpDec.SetInt64(int64({{.Right}}))
-				if _, err := tree.{{.Ctx}}.Pow(&leftTmpDec, &leftTmpDec, &rightTmpDec); err != nil {
+				if err := eval.DecimalPow(tree.{{.Ctx}}, &leftTmpDec, &leftTmpDec, &rightTmpDec); err != nil {
 					colexecerror.ExpectedError(err)
 				}
 				resultInt, err := leftTmpDec.Int64()
@@ -547,6 +547,7 @@ func (c decimalIntCustomizer) getBinOpAssignFunc() assignFunc {
 			"Target":           targetElem,
 			"Left":             leftElem,
 			"Right":            rightElem,
+			"IsPow":            binOp == treebin.Pow,
 		}
 		buf := strings.Builder{}
 		t := template.Must(template.New("").Parse(`
@@ -558,7 +559,11 @@ func (c decimalIntCustomizer) getBinOpAssignFunc() assignFunc {
 				{{end}}
 				var tmpDec apd.Decimal //gcassert:noescape
 				tmpDec.SetInt64(int64({{.Right}}))
+				{{if .IsPow -}}
+				if err := eval.{{.Op}}(tree.{{.Ctx}}, &{{.Target}}, &{{.Left}}, &tmpDec); err != nil {
+				{{else -}}
 				if _, err := tree.{{.Ctx}}.{{.Op}}(&{{.Target}}, &{{.Left}}, &tmpDec); err != nil {
+				{{end -}}
 					colexecerror.ExpectedError(err)
 				}
 			}
@@ -581,6 +586,7 @@ func (c intDecimalCustomizer) getBinOpAssignFunc() assignFunc {
 			"Target":           targetElem,
 			"Left":             leftElem,
 			"Right":            rightElem,
+			"IsPow":            binOp == treebin.Pow,
 		}
 		buf := strings.Builder{}
 		t := template.Must(template.New("").Parse(`
@@ -592,7 +598,11 @@ func (c intDecimalCustomizer) getBinOpAssignFunc() assignFunc {
 				{{end}}
 				var tmpDec apd.Decimal //gcassert:noescape
 				tmpDec.SetInt64(int64({{.Left}}))
+				{{if .IsPow -}}
+				err := eval.{{.Op}}(tree.{{.Ctx}}, &{{.Target}}, &tmpDec, &{{.Right}})
+				{{else -}}
 				_, err := tree.{{.Ctx}}.{{.Op}}(&{{.Target}}, &tmpDec, &{{.Right}})
+				{{end -}}
 				if err != nil {
 					colexecerror.ExpectedError(err)
 				}
diff --git a/pkg/sql/colexec/execgen/cmd/execgen/overloads_cmp.go b/pkg/sql/colexec/execgen/cmd/execgen/overloads_cmp.go
index 3038f5c..5d32d1e 100644
--- a/pkg/sql/colexec/execgen/cmd/execgen/overloads_cmp.go
+++ b/pkg/sql/colexec/execgen/cmd/execgen/overloads_cmp.go
@@ -1,12 +1,7 @@
 // Copyright 2020 The Cockroach Authors.
 //
-// Use of this software is governed by the Business Source License
-// included in the file licenses/BSL.txt.
-//
-// As of the Change Date specified in that file, in accordance with
-// the Business Source License, use of this software will be governed
-// by the Apache License, Version 2.0, included in the file
-// licenses/APL.txt.
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
 
 package main
 
diff --git a/pkg/sql/colexec/execgen/cmd/execgen/overloads_gen_util.go b/pkg/sql/colexec/execgen/cmd/execgen/overloads_gen_util.go
index 9ece7e9..ef08021 100644
--- a/pkg/sql/colexec/execgen/cmd/execgen/overloads_gen_util.go
+++ b/pkg/sql/colexec/execgen/cmd/execgen/overloads_gen_util.go
@@ -1,12 +1,7 @@
 // Copyright 2020 The Cockroach Authors.
 //
-// Use of this software is governed by the Business Source License
-// included in the file licenses/BSL.txt.
-//
-// As of the Change Date specified in that file, in accordance with
-// the Business Source License, use of this software will be governed
-// by the Apache License, Version 2.0, included in the file
-// licenses/APL.txt.
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
 
 package main
 
diff --git a/pkg/sql/colexec/execgen/cmd/execgen/overloads_hash.go b/pkg/sql/colexec/execgen/cmd/execgen/overloads_hash.go
index 972239f..524c0b5 100644
--- a/pkg/sql/colexec/execgen/cmd/execgen/overloads_hash.go
+++ b/pkg/sql/colexec/execgen/cmd/execgen/overloads_hash.go
@@ -1,12 +1,7 @@
 // Copyright 2020 The Cockroach Authors.
 //
-// Use of this software is governed by the Business Source License
-// included in the file licenses/BSL.txt.
-//
-// As of the Change Date specified in that file, in accordance with
-// the Business Source License, use of this software will be governed
-// by the Apache License, Version 2.0, included in the file
-// licenses/APL.txt.
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
 
 package main
 
diff --git a/pkg/sql/colexec/execgen/cmd/execgen/projection_ops_gen.go b/pkg/sql/colexec/execgen/cmd/execgen/projection_ops_gen.go
index d9cbc47..7151a25 100644
--- a/pkg/sql/colexec/execgen/cmd/execgen/projection_ops_gen.go
+++ b/pkg/sql/colexec/execgen/cmd/execgen/projection_ops_gen.go
@@ -1,12 +1,7 @@
 // Copyright 2018 The Cockroach Authors.
 //
-// Use of this software is governed by the Business Source License
-// included in the file licenses/BSL.txt.
-//
-// As of the Change Date specified in that file, in accordance with
-// the Business Source License, use of this software will be governed
-// by the Apache License, Version 2.0, included in the file
-// licenses/APL.txt.
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
 
 package main
 
diff --git a/pkg/sql/colexec/execgen/cmd/execgen/range_offset_handler_gen.go b/pkg/sql/colexec/execgen/cmd/execgen/range_offset_handler_gen.go
index e2f9808..be34ecd 100644
--- a/pkg/sql/colexec/execgen/cmd/execgen/range_offset_handler_gen.go
+++ b/pkg/sql/colexec/execgen/cmd/execgen/range_offset_handler_gen.go
@@ -1,12 +1,7 @@
 // Copyright 2021 The Cockroach Authors.
 //
-// Use of this software is governed by the Business Source License
-// included in the file licenses/BSL.txt.
-//
-// As of the Change Date specified in that file, in accordance with
-// the Business Source License, use of this software will be governed
-// by the Apache License, Version 2.0, included in the file
-// licenses/APL.txt.
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
 
 package main
 
diff --git a/pkg/sql/colexec/execgen/cmd/execgen/rank_gen.go b/pkg/sql/colexec/execgen/cmd/execgen/rank_gen.go
index 5f59144..9a53578 100644
--- a/pkg/sql/colexec/execgen/cmd/execgen/rank_gen.go
+++ b/pkg/sql/colexec/execgen/cmd/execgen/rank_gen.go
@@ -1,12 +1,7 @@
 // Copyright 2019 The Cockroach Authors.
 //
-// Use of this software is governed by the Business Source License
-// included in the file licenses/BSL.txt.
-//
-// As of the Change Date specified in that file, in accordance with
-// the Business Source License, use of this software will be governed
-// by the Apache License, Version 2.0, included in the file
-// licenses/APL.txt.
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
 
 package main
 
diff --git a/pkg/sql/colexec/execgen/cmd/execgen/relative_rank_gen.go b/pkg/sql/colexec/execgen/cmd/execgen/relative_rank_gen.go
index 2a67d37..de7e778 100644
--- a/pkg/sql/colexec/execgen/cmd/execgen/relative_rank_gen.go
+++ b/pkg/sql/colexec/execgen/cmd/execgen/relative_rank_gen.go
@@ -1,12 +1,7 @@
 // Copyright 2020 The Cockroach Authors.
 //
-// Use of this software is governed by the Business Source License
-// included in the file licenses/BSL.txt.
-//
-// As of the Change Date specified in that file, in accordance with
-// the Business Source License, use of this software will be governed
-// by the Apache License, Version 2.0, included in the file
-// licenses/APL.txt.
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
 
 package main
 
diff --git a/pkg/sql/colexec/execgen/cmd/execgen/row_number_gen.go b/pkg/sql/colexec/execgen/cmd/execgen/row_number_gen.go
index 3cc0968..bfe52ba 100644
--- a/pkg/sql/colexec/execgen/cmd/execgen/row_number_gen.go
+++ b/pkg/sql/colexec/execgen/cmd/execgen/row_number_gen.go
@@ -1,12 +1,7 @@
 // Copyright 2019 The Cockroach Authors.
 //
-// Use of this software is governed by the Business Source License
-// included in the file licenses/BSL.txt.
-//
-// As of the Change Date specified in that file, in accordance with
-// the Business Source License, use of this software will be governed
-// by the Apache License, Version 2.0, included in the file
-// licenses/APL.txt.
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
 
 package main
 
diff --git a/pkg/sql/colexec/execgen/cmd/execgen/rowtovec_gen.go b/pkg/sql/colexec/execgen/cmd/execgen/rowtovec_gen.go
index 2c5c393..e37f5f7 100644
--- a/pkg/sql/colexec/execgen/cmd/execgen/rowtovec_gen.go
+++ b/pkg/sql/colexec/execgen/cmd/execgen/rowtovec_gen.go
@@ -1,12 +1,7 @@
 // Copyright 2018 The Cockroach Authors.
 //
-// Use of this software is governed by the Business Source License
-// included in the file licenses/BSL.txt.
-//
-// As of the Change Date specified in that file, in accordance with
-// the Business Source License, use of this software will be governed
-// by the Apache License, Version 2.0, included in the file
-// licenses/APL.txt.
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
 
 package main
 
diff --git a/pkg/sql/colexec/execgen/cmd/execgen/select_in_gen.go b/pkg/sql/colexec/execgen/cmd/execgen/select_in_gen.go
index 8a501c1..878e9b2 100644
--- a/pkg/sql/colexec/execgen/cmd/execgen/select_in_gen.go
+++ b/pkg/sql/colexec/execgen/cmd/execgen/select_in_gen.go
@@ -1,12 +1,7 @@
 // Copyright 2019 The Cockroach Authors.
 //
-// Use of this software is governed by the Business Source License
-// included in the file licenses/BSL.txt.
-//
-// As of the Change Date specified in that file, in accordance with
-// the Business Source License, use of this software will be governed
-// by the Apache License, Version 2.0, included in the file
-// licenses/APL.txt.
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
 
 package main
 
@@ -25,6 +20,7 @@ func genSelectIn(inputFileContents string, wr io.Writer) error {
 		"_CANONICAL_TYPE_FAMILY", "{{.CanonicalTypeFamilyStr}}",
 		"_TYPE_WIDTH", typeWidthReplacement,
 		"_GOTYPESLICE", "{{.GoTypeSliceName}}",
+		"_GOTYPE_UPCAST_INT", `{{if or (eq .VecMethod "Int16") (eq .VecMethod "Int32")}}int64{{else}}{{.GoType}}{{end}}`,
 		"_GOTYPE", "{{.GoType}}",
 		"_TYPE", "{{.VecMethod}}",
 		"TemplateType", "{{.VecMethod}}",
diff --git a/pkg/sql/colexec/execgen/cmd/execgen/selection_ops_gen.go b/pkg/sql/colexec/execgen/cmd/execgen/selection_ops_gen.go
index 912085d..88ecf38 100644
--- a/pkg/sql/colexec/execgen/cmd/execgen/selection_ops_gen.go
+++ b/pkg/sql/colexec/execgen/cmd/execgen/selection_ops_gen.go
@@ -1,12 +1,7 @@
 // Copyright 2018 The Cockroach Authors.
 //
-// Use of this software is governed by the Business Source License
-// included in the file licenses/BSL.txt.
-//
-// As of the Change Date specified in that file, in accordance with
-// the Business Source License, use of this software will be governed
-// by the Apache License, Version 2.0, included in the file
-// licenses/APL.txt.
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
 
 package main
 
diff --git a/pkg/sql/colexec/execgen/cmd/execgen/sort_gen.go b/pkg/sql/colexec/execgen/cmd/execgen/sort_gen.go
index 4ed1532..7d8b5ff 100644
--- a/pkg/sql/colexec/execgen/cmd/execgen/sort_gen.go
+++ b/pkg/sql/colexec/execgen/cmd/execgen/sort_gen.go
@@ -1,12 +1,7 @@
 // Copyright 2018 The Cockroach Authors.
 //
-// Use of this software is governed by the Business Source License
-// included in the file licenses/BSL.txt.
-//
-// As of the Change Date specified in that file, in accordance with
-// the Business Source License, use of this software will be governed
-// by the Apache License, Version 2.0, included in the file
-// licenses/APL.txt.
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
 
 package main
 
diff --git a/pkg/sql/colexec/execgen/cmd/execgen/sorttopk_gen.go b/pkg/sql/colexec/execgen/cmd/execgen/sorttopk_gen.go
index 5826d8b..e44955c 100644
--- a/pkg/sql/colexec/execgen/cmd/execgen/sorttopk_gen.go
+++ b/pkg/sql/colexec/execgen/cmd/execgen/sorttopk_gen.go
@@ -1,12 +1,7 @@
 // Copyright 2021 The Cockroach Authors.
 //
-// Use of this software is governed by the Business Source License
-// included in the file licenses/BSL.txt.
-//
-// As of the Change Date specified in that file, in accordance with
-// the Business Source License, use of this software will be governed
-// by the Apache License, Version 2.0, included in the file
-// licenses/APL.txt.
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
 
 package main
 
diff --git a/pkg/sql/colexec/execgen/cmd/execgen/span_encoder_gen.go b/pkg/sql/colexec/execgen/cmd/execgen/span_encoder_gen.go
index 10704b4..50043e7 100644
--- a/pkg/sql/colexec/execgen/cmd/execgen/span_encoder_gen.go
+++ b/pkg/sql/colexec/execgen/cmd/execgen/span_encoder_gen.go
@@ -1,12 +1,7 @@
 // Copyright 2021 The Cockroach Authors.
 //
-// Use of this software is governed by the Business Source License
-// included in the file licenses/BSL.txt.
-//
-// As of the Change Date specified in that file, in accordance with
-// the Business Source License, use of this software will be governed
-// by the Apache License, Version 2.0, included in the file
-// licenses/APL.txt.
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
 
 package main
 
diff --git a/pkg/sql/colexec/execgen/cmd/execgen/substring_gen.go b/pkg/sql/colexec/execgen/cmd/execgen/substring_gen.go
index 133a88c..a0d0f88 100644
--- a/pkg/sql/colexec/execgen/cmd/execgen/substring_gen.go
+++ b/pkg/sql/colexec/execgen/cmd/execgen/substring_gen.go
@@ -1,12 +1,7 @@
 // Copyright 2020 The Cockroach Authors.
 //
-// Use of this software is governed by the Business Source License
-// included in the file licenses/BSL.txt.
-//
-// As of the Change Date specified in that file, in accordance with
-// the Business Source License, use of this software will be governed
-// by the Apache License, Version 2.0, included in the file
-// licenses/APL.txt.
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
 
 package main
 
diff --git a/pkg/sql/colexec/execgen/cmd/execgen/sum_agg_gen.go b/pkg/sql/colexec/execgen/cmd/execgen/sum_agg_gen.go
index bfac9e8..d8bcc65 100644
--- a/pkg/sql/colexec/execgen/cmd/execgen/sum_agg_gen.go
+++ b/pkg/sql/colexec/execgen/cmd/execgen/sum_agg_gen.go
@@ -1,12 +1,7 @@
 // Copyright 2018 The Cockroach Authors.
 //
-// Use of this software is governed by the Business Source License
-// included in the file licenses/BSL.txt.
-//
-// As of the Change Date specified in that file, in accordance with
-// the Business Source License, use of this software will be governed
-// by the Apache License, Version 2.0, included in the file
-// licenses/APL.txt.
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
 
 package main
 
@@ -112,7 +107,7 @@ const sumAggTmpl = "pkg/sql/colexec/colexecagg/sum_agg_tmpl.go"
 
 func genSumAgg(inputFileContents string, wr io.Writer, isSumInt bool) error {
 	r := strings.NewReplacer(
-		"_TYPE_FAMILY", "{{.TypeFamily}}",
+		"_CANONICAL_TYPE_FAMILY", "{{.TypeFamily}}",
 		"_TYPE_WIDTH", typeWidthReplacement,
 		"_SUMKIND", "{{.SumKind}}",
 		"_RET_GOTYPESLICE", `{{.RetGoTypeSlice}}`,
@@ -164,9 +159,10 @@ func genSumAgg(inputFileContents string, wr io.Writer, isSumInt bool) error {
 			TypeFamily: familyToString(inputTypeFamily),
 		}
 		for _, inputTypeWidth := range supportedWidthsByCanonicalTypeFamily[inputTypeFamily] {
-			// Note that we don't use execinfrapb.GetAggregateInfo because we don't
-			// want to bring in a dependency on that package to reduce the burden
-			// of regenerating execgen code when the protobufs get generated.
+			// Note that we don't use execinfrapb.GetAggregateOutputType because
+			// we don't want to bring in a dependency on that package to reduce
+			// the burden of regenerating execgen code when the protobufs get
+			// generated.
 			retTypeFamily, retTypeWidth := inputTypeFamily, inputTypeWidth
 			if inputTypeFamily == types.IntFamily {
 				if isSumInt {
@@ -207,9 +203,11 @@ func init() {
 		}
 	}
 	registerAggGenerator(
-		sumAggGenerator(false /* isSumInt */), "sum_agg.eg.go",
-		sumAggTmpl, true /* genWindowVariant */)
+		sumAggGenerator(false /* isSumInt */), "sum_agg.eg.go", /* filenameSuffix */
+		sumAggTmpl, "sum" /* aggName */, true, /* genWindowVariant */
+	)
 	registerAggGenerator(
-		sumAggGenerator(true /* isSumInt */), "sum_int_agg.eg.go",
-		sumAggTmpl, true /* genWindowVariant */)
+		sumAggGenerator(true /* isSumInt */), "sum_int_agg.eg.go", /* filenameSuffix */
+		sumAggTmpl, "sumInt" /* aggName */, true, /* genWindowVariant */
+	)
 }
diff --git a/pkg/sql/colexec/execgen/cmd/execgen/values_differ_gen.go b/pkg/sql/colexec/execgen/cmd/execgen/values_differ_gen.go
index 22ad307..e82102d 100644
--- a/pkg/sql/colexec/execgen/cmd/execgen/values_differ_gen.go
+++ b/pkg/sql/colexec/execgen/cmd/execgen/values_differ_gen.go
@@ -1,12 +1,7 @@
 // Copyright 2019 The Cockroach Authors.
 //
-// Use of this software is governed by the Business Source License
-// included in the file licenses/BSL.txt.
-//
-// As of the Change Date specified in that file, in accordance with
-// the Business Source License, use of this software will be governed
-// by the Apache License, Version 2.0, included in the file
-// licenses/APL.txt.
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
 
 package main
 
diff --git a/pkg/sql/colexec/execgen/cmd/execgen/vec_comparators_gen.go b/pkg/sql/colexec/execgen/cmd/execgen/vec_comparators_gen.go
index 694a75e..9326947 100644
--- a/pkg/sql/colexec/execgen/cmd/execgen/vec_comparators_gen.go
+++ b/pkg/sql/colexec/execgen/cmd/execgen/vec_comparators_gen.go
@@ -1,12 +1,7 @@
 // Copyright 2019 The Cockroach Authors.
 //
-// Use of this software is governed by the Business Source License
-// included in the file licenses/BSL.txt.
-//
-// As of the Change Date specified in that file, in accordance with
-// the Business Source License, use of this software will be governed
-// by the Apache License, Version 2.0, included in the file
-// licenses/APL.txt.
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
 
 package main
 
diff --git a/pkg/sql/colexec/execgen/cmd/execgen/vec_gen.go b/pkg/sql/colexec/execgen/cmd/execgen/vec_gen.go
index 2d7fbec..4b8eae4 100644
--- a/pkg/sql/colexec/execgen/cmd/execgen/vec_gen.go
+++ b/pkg/sql/colexec/execgen/cmd/execgen/vec_gen.go
@@ -1,12 +1,7 @@
 // Copyright 2018 The Cockroach Authors.
 //
-// Use of this software is governed by the Business Source License
-// included in the file licenses/BSL.txt.
-//
-// As of the Change Date specified in that file, in accordance with
-// the Business Source License, use of this software will be governed
-// by the Apache License, Version 2.0, included in the file
-// licenses/APL.txt.
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
 
 package main
 
diff --git a/pkg/sql/colexec/execgen/cmd/execgen/vec_to_datum_gen.go b/pkg/sql/colexec/execgen/cmd/execgen/vec_to_datum_gen.go
index b3b0ff3..d958073 100644
--- a/pkg/sql/colexec/execgen/cmd/execgen/vec_to_datum_gen.go
+++ b/pkg/sql/colexec/execgen/cmd/execgen/vec_to_datum_gen.go
@@ -1,12 +1,7 @@
 // Copyright 2020 The Cockroach Authors.
 //
-// Use of this software is governed by the Business Source License
-// included in the file licenses/BSL.txt.
-//
-// As of the Change Date specified in that file, in accordance with
-// the Business Source License, use of this software will be governed
-// by the Apache License, Version 2.0, included in the file
-// licenses/APL.txt.
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
 
 package main
 
diff --git a/pkg/sql/colexec/execgen/cmd/execgen/window_aggregator_gen.go b/pkg/sql/colexec/execgen/cmd/execgen/window_aggregator_gen.go
index 1e57247..bf9ea00 100644
--- a/pkg/sql/colexec/execgen/cmd/execgen/window_aggregator_gen.go
+++ b/pkg/sql/colexec/execgen/cmd/execgen/window_aggregator_gen.go
@@ -1,12 +1,7 @@
 // Copyright 2021 The Cockroach Authors.
 //
-// Use of this software is governed by the Business Source License
-// included in the file licenses/BSL.txt.
-//
-// As of the Change Date specified in that file, in accordance with
-// the Business Source License, use of this software will be governed
-// by the Apache License, Version 2.0, included in the file
-// licenses/APL.txt.
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
 
 package main
 
diff --git a/pkg/sql/colexec/execgen/cmd/execgen/window_framer_gen.go b/pkg/sql/colexec/execgen/cmd/execgen/window_framer_gen.go
index b5db98b..953486a 100644
--- a/pkg/sql/colexec/execgen/cmd/execgen/window_framer_gen.go
+++ b/pkg/sql/colexec/execgen/cmd/execgen/window_framer_gen.go
@@ -1,12 +1,7 @@
 // Copyright 2021 The Cockroach Authors.
 //
-// Use of this software is governed by the Business Source License
-// included in the file licenses/BSL.txt.
-//
-// As of the Change Date specified in that file, in accordance with
-// the Business Source License, use of this software will be governed
-// by the Apache License, Version 2.0, included in the file
-// licenses/APL.txt.
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
 
 package main
 
diff --git a/pkg/sql/colexec/execgen/cmd/execgen/window_peer_grouper_gen.go b/pkg/sql/colexec/execgen/cmd/execgen/window_peer_grouper_gen.go
index 863617f..6e0486e 100644
--- a/pkg/sql/colexec/execgen/cmd/execgen/window_peer_grouper_gen.go
+++ b/pkg/sql/colexec/execgen/cmd/execgen/window_peer_grouper_gen.go
@@ -1,12 +1,7 @@
 // Copyright 2019 The Cockroach Authors.
 //
-// Use of this software is governed by the Business Source License
-// included in the file licenses/BSL.txt.
-//
-// As of the Change Date specified in that file, in accordance with
-// the Business Source License, use of this software will be governed
-// by the Apache License, Version 2.0, included in the file
-// licenses/APL.txt.
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
 
 package main
 
diff --git a/pkg/sql/colexec/execgen/execgen.go b/pkg/sql/colexec/execgen/execgen.go
index c744a0a..bf2739f 100644
--- a/pkg/sql/colexec/execgen/execgen.go
+++ b/pkg/sql/colexec/execgen/execgen.go
@@ -1,12 +1,7 @@
 // Copyright 2020 The Cockroach Authors.
 //
-// Use of this software is governed by the Business Source License
-// included in the file licenses/BSL.txt.
-//
-// As of the Change Date specified in that file, in accordance with
-// the Business Source License, use of this software will be governed
-// by the Apache License, Version 2.0, included in the file
-// licenses/APL.txt.
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
 
 package execgen
 
diff --git a/pkg/sql/colexec/execgen/inline.go b/pkg/sql/colexec/execgen/inline.go
index 753d97a..c23f29b 100644
--- a/pkg/sql/colexec/execgen/inline.go
+++ b/pkg/sql/colexec/execgen/inline.go
@@ -1,12 +1,7 @@
 // Copyright 2020 The Cockroach Authors.
 //
-// Use of this software is governed by the Business Source License
-// included in the file licenses/BSL.txt.
-//
-// As of the Change Date specified in that file, in accordance with
-// the Business Source License, use of this software will be governed
-// by the Apache License, Version 2.0, included in the file
-// licenses/APL.txt.
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
 
 package execgen
 
diff --git a/pkg/sql/colexec/execgen/placeholders.go b/pkg/sql/colexec/execgen/placeholders.go
index 57518b2..7779045 100644
--- a/pkg/sql/colexec/execgen/placeholders.go
+++ b/pkg/sql/colexec/execgen/placeholders.go
@@ -1,12 +1,7 @@
 // Copyright 2019 The Cockroach Authors.
 //
-// Use of this software is governed by the Business Source License
-// included in the file licenses/BSL.txt.
-//
-// As of the Change Date specified in that file, in accordance with
-// the Business Source License, use of this software will be governed
-// by the Apache License, Version 2.0, included in the file
-// licenses/APL.txt.
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
 
 package execgen
 
diff --git a/pkg/sql/colexec/execgen/supported_bin_cmp_ops.go b/pkg/sql/colexec/execgen/supported_bin_cmp_ops.go
index 0358bd3..6276e8b 100644
--- a/pkg/sql/colexec/execgen/supported_bin_cmp_ops.go
+++ b/pkg/sql/colexec/execgen/supported_bin_cmp_ops.go
@@ -1,12 +1,7 @@
 // Copyright 2020 The Cockroach Authors.
 //
-// Use of this software is governed by the Business Source License
-// included in the file licenses/BSL.txt.
-//
-// As of the Change Date specified in that file, in accordance with
-// the Business Source License, use of this software will be governed
-// by the Apache License, Version 2.0, included in the file
-// licenses/APL.txt.
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
 
 package execgen
 
diff --git a/pkg/sql/colexec/execgen/template.go b/pkg/sql/colexec/execgen/template.go
index 4e37be9..cba9137 100644
--- a/pkg/sql/colexec/execgen/template.go
+++ b/pkg/sql/colexec/execgen/template.go
@@ -1,12 +1,7 @@
 // Copyright 2020 The Cockroach Authors.
 //
-// Use of this software is governed by the Business Source License
-// included in the file licenses/BSL.txt.
-//
-// As of the Change Date specified in that file, in accordance with
-// the Business Source License, use of this software will be governed
-// by the Apache License, Version 2.0, included in the file
-// licenses/APL.txt.
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
 
 package execgen
 
diff --git a/pkg/sql/colexec/execgen/util.go b/pkg/sql/colexec/execgen/util.go
index 273cef2..12406e0 100644
--- a/pkg/sql/colexec/execgen/util.go
+++ b/pkg/sql/colexec/execgen/util.go
@@ -1,12 +1,7 @@
 // Copyright 2020 The Cockroach Authors.
 //
-// Use of this software is governed by the Business Source License
-// included in the file licenses/BSL.txt.
-//
-// As of the Change Date specified in that file, in accordance with
-// the Business Source License, use of this software will be governed
-// by the Apache License, Version 2.0, included in the file
-// licenses/APL.txt.
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
 
 package execgen
 
diff --git a/pkg/sql/colexecerror/error.go b/pkg/sql/colexecerror/error.go
index a003943..0923525 100644
--- a/pkg/sql/colexecerror/error.go
+++ b/pkg/sql/colexecerror/error.go
@@ -1,28 +1,43 @@
 // Copyright 2019 The Cockroach Authors.
 //
-// Use of this software is governed by the Business Source License
-// included in the file licenses/BSL.txt.
-//
-// As of the Change Date specified in that file, in accordance with
-// the Business Source License, use of this software will be governed
-// by the Apache License, Version 2.0, included in the file
-// licenses/APL.txt.
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
 
 package colexecerror
 
 import (
-	"bufio"
 	"context"
-	"runtime/debug"
+	"runtime"
 	"strings"
 
 	"github.com/cockroachdb/cockroachdb-parser/pkg/sql/pgwire/pgcode"
 	"github.com/cockroachdb/cockroachdb-parser/pkg/sql/pgwire/pgerror"
+	"github.com/cockroachdb/cockroachdb-parser/pkg/util/buildutil"
 	"github.com/cockroachdb/errors"
 	"github.com/gogo/protobuf/proto"
 )
 
-const panicLineSubstring = "runtime/panic.go"
+const (
+	panicLineSubstring            = "runtime/panic.go"
+	runtimePanicFileSubstring     = "runtime"
+	runtimePanicFunctionSubstring = "runtime."
+)
+
+var testingKnobShouldCatchPanic bool
+
+// ProductionBehaviorForTests reinstates the release-build behavior for
+// CatchVectorizedRuntimeError, which is to catch *all* panics originating from
+// within the vectorized execution engine, including runtime panics that are not
+// wrapped in InternalError, ExpectedError, or StorageError. (Without calling
+// this, in crdb_test builds, CatchVectorizedRuntimeError will only catch panics
+// that are wrapped in InternalError, ExpectedError, or StorageError.)
+func ProductionBehaviorForTests() func() {
+	old := testingKnobShouldCatchPanic
+	testingKnobShouldCatchPanic = true
+	return func() {
+		testingKnobShouldCatchPanic = old
+	}
+}
 
 // CatchVectorizedRuntimeError executes operation, catches a runtime error if
 // it is coming from the vectorized engine, and returns it. If an error not
@@ -36,25 +51,89 @@ func CatchVectorizedRuntimeError(operation func()) (retErr error) {
 			return
 		}
 
-		// Find where the panic came from and only proceed if it is related to the
-		// vectorized engine.
-		stackTrace := string(debug.Stack())
-		scanner := bufio.NewScanner(strings.NewReader(stackTrace))
-		panicLineFound := false
-		for scanner.Scan() {
-			if strings.Contains(scanner.Text(), panicLineSubstring) {
-				panicLineFound = true
-				break
+		// First check for error types that should only come from the vectorized
+		// engine.
+		if err, ok := panicObj.(error); ok {
+			// StorageError was caused by something below SQL, and represents an error
+			// that we'd simply like to propagate along.
+			var se *StorageError
+			// notInternalError is an error from the vectorized engine that we'd
+			// simply like to propagate along.
+			var nie *notInternalError
+			// internalError is an error from the vectorized engine that might need to
+			// be returned to the client with a stacktrace, sentry report, and
+			// "internal error" designation.
+			var ie *internalError
+			passthrough := errors.As(err, &se) || errors.As(err, &nie)
+			if errors.As(err, &ie) {
+				// Unwrap so that internalError doesn't show up in sentry reports.
+				retErr = ie.Unwrap()
+				// If the internal error doesn't already have an error code, mark it as
+				// an assertion error so that we generate a sentry report. (We don't do
+				// this for StorageError, notInternalError, or context.Canceled to avoid
+				// creating unnecessary sentry reports.)
+				if !passthrough && !errors.Is(retErr, context.Canceled) {
+					if code := pgerror.GetPGCode(retErr); code == pgcode.Uncategorized {
+						retErr = errors.NewAssertionErrorWithWrappedErrf(
+							retErr, "unexpected error from the vectorized engine",
+						)
+					}
+				}
+				return
+			}
+			if passthrough {
+				retErr = err
+				return
 			}
 		}
-		if !panicLineFound {
-			panic(errors.AssertionFailedf("panic line %q not found in the stack trace\n%s", panicLineSubstring, stackTrace))
-		}
-		if !scanner.Scan() {
-			panic(errors.AssertionFailedf("unexpectedly there is no line below the panic line in the stack trace\n%s", stackTrace))
+
+		// For other types of errors, we need to check whence the panic originated
+		// to know what to do. If the panic originated in the vectorized engine, we
+		// can safely return it as a normal error knowing that any illegal state
+		// will be cleaned up when the statement finishes. If the panic originated
+		// lower in the stack, however, we must treat it as unrecoverable because it
+		// could indicate an illegal state that might persist even after this
+		// statement finishes.
+		//
+		// To check whence the panic originated, we find the frame just before the
+		// panic frame.
+		var panicLineFound bool
+		var panicEmittedFrom string
+		// Usually, we'll find the offending frame within 3 program counters,
+		// starting with the caller of this deferred function (2 above the
+		// runtime.Callers frame). However, we also want to catch panics
+		// originating in the Go runtime with the runtime frames being returned
+		// by CallersFrames, so we allow for 5 more program counters for that
+		// case (e.g. invalid interface conversions use 2 counters).
+		pc := make([]uintptr, 8)
+		n := runtime.Callers(2, pc)
+		if n >= 1 {
+			frames := runtime.CallersFrames(pc[:n])
+			// A fixed number of program counters can expand to any number of frames.
+			for {
+				frame, more := frames.Next()
+				if strings.Contains(frame.File, panicLineSubstring) {
+					panicLineFound = true
+				} else if panicLineFound {
+					if strings.HasPrefix(frame.Function, runtimePanicFunctionSubstring) &&
+						strings.Contains(frame.File, runtimePanicFileSubstring) {
+						// This frame is from the Go runtime, so we simply
+						// ignore it to get to the offending one within the
+						// CRDB.
+						continue
+					}
+					panicEmittedFrom = frame.Function
+					break
+				}
+				if !more {
+					break
+				}
+			}
 		}
-		panicEmittedFrom := strings.TrimSpace(scanner.Text())
 		if !shouldCatchPanic(panicEmittedFrom) {
+			// The panic is from outside the vectorized engine (or we didn't find it
+			// in the stack). We treat it as unrecoverable because it could indicate
+			// an illegal state that might persist even after this statement finishes.
 			panic(panicObj)
 		}
 
@@ -66,20 +145,11 @@ func CatchVectorizedRuntimeError(operation func()) (retErr error) {
 		}
 		retErr = err
 
-		if _, ok := panicObj.(*StorageError); ok {
-			// A StorageError was caused by something below SQL, and represents
-			// an error that we'd simply like to propagate along.
-			// Do nothing.
-			return
-		}
-
 		annotateErrorWithoutCode := true
-		var nie *notInternalError
-		if errors.Is(err, context.Canceled) || errors.As(err, &nie) {
-			// We don't want to annotate the context cancellation and
-			// notInternalError errors in case they don't have a valid PG code
-			// so that the sentry report is not sent (errors with failed
-			// assertions get sentry reports).
+		if errors.Is(err, context.Canceled) {
+			// We don't want to annotate the context cancellation errors in case they
+			// don't have a valid PG code so that the sentry report is not sent
+			// (errors with failed assertions get sentry reports).
 			annotateErrorWithoutCode = false
 		}
 		if code := pgerror.GetPGCode(err); annotateErrorWithoutCode && code == pgcode.Uncategorized {
@@ -106,6 +176,9 @@ const (
 	sqlColPackagesPrefix   = "github.com/cockroachdb/cockroachdb-parser/pkg/sql/col"
 	sqlRowPackagesPrefix   = "github.com/cockroachdb/cockroachdb-parser/pkg/sql/row"
 	sqlSemPackagesPrefix   = "github.com/cockroachdb/cockroachdb-parser/pkg/sql/sem"
+	// When running BenchmarkCatchVectorizedRuntimeError under bazel, the
+	// repository prefix is missing.
+	testSqlColPackagesPrefix = "pkg/sql/col"
 )
 
 // shouldCatchPanic checks whether the panic that was emitted from
@@ -118,6 +191,14 @@ const (
 //
 // panicEmittedFrom must be trimmed to not have any white spaces in the prefix.
 func shouldCatchPanic(panicEmittedFrom string) bool {
+	// In crdb_test builds we do not catch runtime panics even if they originate
+	// from within the vectorized execution engine. These panics probably
+	// represent bugs in vectorized execution, and we want them to fail loudly in
+	// tests (but not in production clusters).
+	if buildutil.CrdbTestBuild && !testingKnobShouldCatchPanic {
+		return false
+	}
+
 	const panicFromTheCatcherItselfPrefix = "github.com/cockroachdb/cockroachdb-parser/pkg/sql/colexecerror.CatchVectorizedRuntimeError"
 	if strings.HasPrefix(panicEmittedFrom, panicFromTheCatcherItselfPrefix) {
 		// This panic came from the catcher itself, so we will propagate it
@@ -135,25 +216,25 @@ func shouldCatchPanic(panicEmittedFrom string) bool {
 		strings.HasPrefix(panicEmittedFrom, execinfraPackagePrefix) ||
 		strings.HasPrefix(panicEmittedFrom, sqlColPackagesPrefix) ||
 		strings.HasPrefix(panicEmittedFrom, sqlRowPackagesPrefix) ||
-		strings.HasPrefix(panicEmittedFrom, sqlSemPackagesPrefix)
+		strings.HasPrefix(panicEmittedFrom, sqlSemPackagesPrefix) ||
+		strings.HasPrefix(panicEmittedFrom, testSqlColPackagesPrefix)
 }
 
 // StorageError is an error that was created by a component below the sql
 // stack, such as the network or storage layers. A StorageError will be bubbled
 // up all the way past the SQL layer unchanged.
 type StorageError struct {
-	error
+	cause error
 }
 
-// Cause implements the Causer interface.
-func (s *StorageError) Cause() error {
-	return s.error
-}
+func (s *StorageError) Error() string { return s.cause.Error() }
+func (s *StorageError) Cause() error  { return s.cause }
+func (s *StorageError) Unwrap() error { return s.cause }
 
 // NewStorageError returns a new storage error. This can be used to propagate
 // an error through the exec subsystem unchanged.
 func NewStorageError(err error) *StorageError {
-	return &StorageError{error: err}
+	return &StorageError{cause: err}
 }
 
 // notInternalError is an error that occurs not because the vectorized engine
@@ -183,16 +264,41 @@ func decodeNotInternalError(
 	return newNotInternalError(cause)
 }
 
+// internalError is an error that occurs because the vectorized engine is in an
+// unexpected state. Usually it wraps an assertion error.
+type internalError struct {
+	cause error
+}
+
+func newInternalError(err error) *internalError {
+	return &internalError{cause: err}
+}
+
+var (
+	_ errors.Wrapper = &internalError{}
+)
+
+func (e *internalError) Error() string { return e.cause.Error() }
+func (e *internalError) Cause() error  { return e.cause }
+func (e *internalError) Unwrap() error { return e.Cause() }
+
+func decodeInternalError(
+	_ context.Context, cause error, _ string, _ []string, _ proto.Message,
+) error {
+	return newInternalError(cause)
+}
+
 func init() {
 	errors.RegisterWrapperDecoder(errors.GetTypeKey((*notInternalError)(nil)), decodeNotInternalError)
+	errors.RegisterWrapperDecoder(errors.GetTypeKey((*internalError)(nil)), decodeInternalError)
 }
 
-// InternalError simply panics with the provided object. It will always be
-// caught and returned as internal error to the client with the corresponding
+// InternalError panics with the error wrapped by internalError. It will always
+// be caught and returned as internal error to the client with the corresponding
 // stack trace. This method should be called to propagate errors that resulted
 // in the vectorized engine being in an *unexpected* state.
 func InternalError(err error) {
-	panic(err)
+	panic(newInternalError(err))
 }
 
 // ExpectedError panics with the error that is wrapped by
diff --git a/pkg/sql/inverted/expression.go b/pkg/sql/inverted/expression.go
index 712c8bb..de562a4 100644
--- a/pkg/sql/inverted/expression.go
+++ b/pkg/sql/inverted/expression.go
@@ -1,21 +1,17 @@
 // Copyright 2020 The Cockroach Authors.
 //
-// Use of this software is governed by the Business Source License
-// included in the file licenses/BSL.txt.
-//
-// As of the Change Date specified in that file, in accordance with
-// the Business Source License, use of this software will be governed
-// by the Apache License, Version 2.0, included in the file
-// licenses/APL.txt.
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
 
 package inverted
 
 import (
 	"bytes"
 	"fmt"
-	"strconv"
+	"strings"
 
 	"github.com/cockroachdb/cockroachdb-parser/pkg/keysbase"
+	"github.com/cockroachdb/cockroachdb-parser/pkg/util/encoding"
 	"github.com/cockroachdb/cockroachdb-parser/pkg/util/treeprinter"
 	"github.com/cockroachdb/errors"
 	"github.com/cockroachdb/redact"
@@ -107,7 +103,7 @@ func MakeSingleValSpan(val EncVal) Span {
 
 // IsSingleVal returns true iff the span is equivalent to [val, val].
 func (s Span) IsSingleVal() bool {
-	return bytes.Equal(keysbase.PrefixEnd(s.Start), s.End)
+	return s.Start != nil && bytes.Equal(keysbase.PrefixEnd(s.Start), s.End)
 }
 
 // Equals returns true if this span has the same start and end as the given
@@ -158,16 +154,20 @@ func (is Spans) Format(tp treeprinter.Node, label string, redactable bool) {
 }
 
 func formatSpan(span Span, redactable bool) string {
-	end := span.End
 	spanEndOpenOrClosed := ')'
+	vals, _ := encoding.PrettyPrintValuesWithTypes(nil, span.Start)
+	start := strings.Join(vals, "/")
+	var end string
 	if span.IsSingleVal() {
-		end = span.Start
+		end = start
 		spanEndOpenOrClosed = ']'
+	} else {
+		vals, _ := encoding.PrettyPrintValuesWithTypes(nil, span.End)
+		end = strings.Join(vals, "/")
 	}
-	output := fmt.Sprintf("[%s, %s%c", strconv.Quote(string(span.Start)),
-		strconv.Quote(string(end)), spanEndOpenOrClosed)
+	output := fmt.Sprintf("[%s, %s%c", start, end, spanEndOpenOrClosed)
 	if redactable {
-		output = string(redact.Sprintf("%s", redact.Unsafe(output)))
+		output = string(redact.Sprintf("%s", encoding.Unsafe(output)))
 	}
 	return output
 }
@@ -309,7 +309,7 @@ type SpanExpression struct {
 	// produce duplicate primary keys. Otherwise, Unique is false. Unique may
 	// be true for certain JSON or Array SpanExpressions, and it holds when
 	// unique SpanExpressions are combined with And. It does not hold when
-	// these SpanExpressions are combined with Or.
+	// these non-empty SpanExpressions are combined with Or.
 	//
 	// Once a SpanExpression is built, this field is relevant if the root
 	// SpanExpression has no children (i.e., Operator is None). In this case,
@@ -685,14 +685,17 @@ func intersectSpanExpressions(left, right *SpanExpression) *SpanExpression {
 		left.FactoredUnionSpans = subtractSpans(left.FactoredUnionSpans, expr.FactoredUnionSpans)
 		right.FactoredUnionSpans = subtractSpans(right.FactoredUnionSpans, expr.FactoredUnionSpans)
 	}
-	tryPruneChildren(expr, SetIntersection)
+	tryPruneChildren(expr)
 	return expr
 }
 
 // Unions two SpanExpressions.
 func unionSpanExpressions(left, right *SpanExpression) *SpanExpression {
 	expr := &SpanExpression{
-		Tight:              left.Tight && right.Tight,
+		Tight: left.Tight && right.Tight,
+		// Whenever one side is empty, we keep the Unique property from the
+		// other side.
+		Unique:             (left.Unique && len(right.FactoredUnionSpans) == 0) || (right.Unique && len(left.FactoredUnionSpans) == 0),
 		SpansToRead:        unionSpans(left.SpansToRead, right.SpansToRead),
 		FactoredUnionSpans: unionSpans(left.FactoredUnionSpans, right.FactoredUnionSpans),
 		Operator:           SetUnion,
@@ -701,13 +704,13 @@ func unionSpanExpressions(left, right *SpanExpression) *SpanExpression {
 	}
 	left.FactoredUnionSpans = nil
 	right.FactoredUnionSpans = nil
-	tryPruneChildren(expr, SetUnion)
+	tryPruneChildren(expr)
 	return expr
 }
 
 // tryPruneChildren takes an expr with two child *SpanExpression and removes
 // children when safe to do so.
-func tryPruneChildren(expr *SpanExpression, op SetOperator) {
+func tryPruneChildren(expr *SpanExpression) {
 	isEmptyExpr := func(e *SpanExpression) bool {
 		return len(e.FactoredUnionSpans) == 0 && e.Left == nil && e.Right == nil
 	}
diff --git a/pkg/sql/inverted/span_expression.pb.go b/pkg/sql/inverted/span_expression.pb.go
index d8a0090..e4fd4bd 100644
--- a/pkg/sql/inverted/span_expression.pb.go
+++ b/pkg/sql/inverted/span_expression.pb.go
@@ -426,7 +426,7 @@ func (m *SpanExpressionProto_Node) Size() (n int) {
 }
 
 func sovSpanExpression(x uint64) (n int) {
-	return (math_bits.Len64(x|1) + 6) / 7
+	return int((uint32(math_bits.Len64(x|1)+6) * 37) >> 8)
 }
 func sozSpanExpression(x uint64) (n int) {
 	return sovSpanExpression(uint64((x << 1) ^ uint64((int64(x) >> 63))))
diff --git a/pkg/sql/inverted/span_expression.proto b/pkg/sql/inverted/span_expression.proto
index e36aad2..9bf5683 100644
--- a/pkg/sql/inverted/span_expression.proto
+++ b/pkg/sql/inverted/span_expression.proto
@@ -1,12 +1,7 @@
 // Copyright 2020 The Cockroach Authors.
 //
-// Use of this software is governed by the Business Source License
-// included in the file licenses/BSL.txt.
-//
-// As of the Change Date specified in that file, in accordance with
-// the Business Source License, use of this software will be governed
-// by the Apache License, Version 2.0, included in the file
-// licenses/APL.txt.
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
 
 syntax = "proto3";
 package cockroach.sql.inverted;
diff --git a/pkg/sql/lex/encode.go b/pkg/sql/lex/encode.go
index 93117c3..2e3bba8 100644
--- a/pkg/sql/lex/encode.go
+++ b/pkg/sql/lex/encode.go
@@ -7,13 +7,8 @@
 //
 // Copyright 2015 The Cockroach Authors.
 //
-// Use of this software is governed by the Business Source License
-// included in the file licenses/BSL.txt.
-//
-// As of the Change Date specified in that file, in accordance with
-// the Business Source License, use of this software will be governed
-// by the Apache License, Version 2.0, included in the file
-// licenses/APL.txt.
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
 
 // This code was derived from https://github.com/youtube/vitess.
 
@@ -29,6 +24,7 @@ import (
 
 	"github.com/cockroachdb/cockroachdb-parser/pkg/sql/pgwire/pgcode"
 	"github.com/cockroachdb/cockroachdb-parser/pkg/sql/pgwire/pgerror"
+	"github.com/cockroachdb/cockroachdb-parser/pkg/util/collatedstring"
 	"github.com/cockroachdb/errors"
 	"golang.org/x/text/language"
 )
@@ -47,8 +43,12 @@ func NormalizeLocaleName(s string) string {
 // need to be quoted, and they are considered equivalent to dash characters by
 // the CLDR standard: http://cldr.unicode.org/.
 func EncodeLocaleName(buf *bytes.Buffer, s string) {
-	// If possible, try to normalize the case of the locale name.
-	if normalized, err := language.Parse(s); err == nil {
+	// If possible, try to normalize the case of the locale name (only for non-default
+	// locales). Default locales will always be quoted so they can be parsed correctly.
+	isDefaultLocale := collatedstring.IsDefaultEquivalentCollation(s)
+	if isDefaultLocale {
+		s = fmt.Sprintf("%q", s)
+	} else if normalized, err := language.Parse(s); err == nil {
 		s = normalized.String()
 	}
 	for i, n := 0, len(s); i < n; i++ {
diff --git a/pkg/sql/lex/encode.proto b/pkg/sql/lex/encode.proto
index 1402097..de8532d 100644
--- a/pkg/sql/lex/encode.proto
+++ b/pkg/sql/lex/encode.proto
@@ -1,12 +1,7 @@
 // Copyright 2022 The Cockroach Authors.
 //
-// Use of this software is governed by the Business Source License
-// included in the file licenses/BSL.txt.
-//
-// As of the Change Date specified in that file, in accordance with
-// the Business Source License, use of this software will be governed
-// by the Apache License, Version 2.0, included in the file
-// licenses/APL.txt.
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
 
 syntax = "proto3";
 package cockroach.sql.sessiondatapb;
diff --git a/pkg/sql/lexbase/allkeywords/main.go b/pkg/sql/lexbase/allkeywords/main.go
index 0f54dca..927bda8 100644
--- a/pkg/sql/lexbase/allkeywords/main.go
+++ b/pkg/sql/lexbase/allkeywords/main.go
@@ -1,12 +1,7 @@
 // Copyright 2019 The Cockroach Authors.
 //
-// Use of this software is governed by the Business Source License
-// included in the file licenses/BSL.txt.
-//
-// As of the Change Date specified in that file, in accordance with
-// the Business Source License, use of this software will be governed
-// by the Apache License, Version 2.0, included in the file
-// licenses/APL.txt.
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
 
 // all-keywords generates sql/lexbase/keywords.go from sql.y.
 //
diff --git a/pkg/sql/lexbase/encode.go b/pkg/sql/lexbase/encode.go
index 7056a8c..5b31fd0 100644
--- a/pkg/sql/lexbase/encode.go
+++ b/pkg/sql/lexbase/encode.go
@@ -7,13 +7,8 @@
 //
 // Copyright 2020 The Cockroach Authors.
 //
-// Use of this software is governed by the Business Source License
-// included in the file licenses/BSL.txt.
-//
-// As of the Change Date specified in that file, in accordance with
-// the Business Source License, use of this software will be governed
-// by the Apache License, Version 2.0, included in the file
-// licenses/APL.txt.
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
 
 // This code was derived from https://github.com/youtube/vitess.
 
@@ -47,6 +42,22 @@ const (
 	// without wrapping quotes.
 	EncBareIdentifiers
 
+	// EncBareReservedKeywords indicates that reserved keywords will be rendered
+	// without wrapping quotes.
+	EncBareReservedKeywords
+
+	// EncAlwaysQuoted makes sure the string is always wrapped with quotes.
+	// This is used only to construct a statement against Oracle source,
+	// as Oracle is case insensitive if object name is not quoted.
+	EncAlwaysQuoted
+
+	// EncSkipEscapeString indicates that the string should not be escaped,
+	// and non-ASCII characters are allowed.
+	// More specifically, it means that the tree.DString won't be wrapped
+	// with e'text' as the prefix and suffix, and single quotes within
+	// the string will not be escaped with a backslash.
+	EncSkipEscapeString
+
 	// EncFirstFreeFlagBit needs to remain unused; it is used as base
 	// bit offset for tree.FmtFlags.
 	EncFirstFreeFlagBit
@@ -57,7 +68,7 @@ const (
 // contains special characters, or the identifier is a reserved SQL
 // keyword.
 func EncodeRestrictedSQLIdent(buf *bytes.Buffer, s string, flags EncodeFlags) {
-	if flags.HasFlags(EncBareIdentifiers) || (!isReservedKeyword(s) && IsBareIdentifier(s)) {
+	if !flags.HasFlags(EncAlwaysQuoted) && (flags.HasFlags(EncBareIdentifiers) || (!isReservedKeyword(s) && IsBareIdentifier(s))) {
 		buf.WriteString(s)
 		return
 	}
@@ -68,7 +79,7 @@ func EncodeRestrictedSQLIdent(buf *bytes.Buffer, s string, flags EncodeFlags) {
 // The identifier is only quoted if the flags don't tell otherwise and
 // the identifier contains special characters.
 func EncodeUnrestrictedSQLIdent(buf *bytes.Buffer, s string, flags EncodeFlags) {
-	if flags.HasFlags(EncBareIdentifiers) || IsBareIdentifier(s) {
+	if !flags.HasFlags(EncAlwaysQuoted) && (flags.HasFlags(EncBareIdentifiers) || IsBareIdentifier(s)) {
 		buf.WriteString(s)
 		return
 	}
@@ -108,7 +119,12 @@ func EncodeEscapedSQLIdent(buf *bytes.Buffer, s string) {
 	buf.WriteByte('"')
 }
 
-var mustQuoteMap = map[byte]bool{
+const (
+	minPrintableChar = 0x20 // ' '
+	maxPrintableChar = 0x7E // '~'
+)
+
+var mustQuoteMap = [maxPrintableChar + 1]bool{
 	' ': true,
 	',': true,
 	'{': true,
@@ -138,6 +154,7 @@ func EscapeSQLString(in string) string {
 func EncodeSQLStringWithFlags(buf *bytes.Buffer, in string, flags EncodeFlags) {
 	// See http://www.postgresql.org/docs/9.4/static/sql-syntax-lexical.html
 	start := 0
+	skipEscape := flags.HasFlags(EncSkipEscapeString)
 	escapedString := false
 	bareStrings := flags.HasFlags(EncBareStrings)
 	// Loop through each unicode code point.
@@ -146,7 +163,7 @@ func EncodeSQLStringWithFlags(buf *bytes.Buffer, in string, flags EncodeFlags) {
 			continue
 		}
 		ch := byte(r)
-		if r >= 0x20 && r < 0x7F {
+		if r >= minPrintableChar && r <= maxPrintableChar {
 			if mustQuoteMap[ch] {
 				// We have to quote this string - ignore bareStrings setting
 				bareStrings = false
@@ -156,28 +173,37 @@ func EncodeSQLStringWithFlags(buf *bytes.Buffer, in string, flags EncodeFlags) {
 			}
 		}
 
-		if !escapedString {
+		// If non-ASCII characters are allowed,
+		// skip escaping and write the original UTF-8 character.
+		if r > maxPrintableChar && skipEscape {
+			continue
+		}
+
+		if !skipEscape && !escapedString {
 			buf.WriteString("e'") // begin e'xxx' string
 			escapedString = true
 		}
 		buf.WriteString(in[start:i])
+
 		ln := utf8.RuneLen(r)
 		if ln < 0 {
 			start = i + 1
 		} else {
 			start = i + ln
 		}
-		stringencoding.EncodeEscapedChar(buf, in, r, ch, i, '\'')
+		// If we skip escaping, we don't write the slash char before the
+		// quote char, so we will  write the quote char directly.
+		stringencoding.EncodeEscapedChar(buf, in, r, ch, i, '\'', !skipEscape)
 	}
 
-	quote := !escapedString && !bareStrings
+	quote := !escapedString && !bareStrings && !skipEscape
 	if quote {
 		buf.WriteByte('\'') // begin 'xxx' string if nothing was escaped
 	}
 	if start < len(in) {
 		buf.WriteString(in[start:])
 	}
-	if escapedString || quote {
+	if !skipEscape && (escapedString || quote) {
 		buf.WriteByte('\'')
 	}
 }
diff --git a/pkg/sql/lexbase/experimental_keywords.go b/pkg/sql/lexbase/experimental_keywords.go
index 3f43f50..6c6a227 100644
--- a/pkg/sql/lexbase/experimental_keywords.go
+++ b/pkg/sql/lexbase/experimental_keywords.go
@@ -1,12 +1,7 @@
 // Copyright 2019 The Cockroach Authors.
 //
-// Use of this software is governed by the Business Source License
-// included in the file licenses/BSL.txt.
-//
-// As of the Change Date specified in that file, in accordance with
-// the Business Source License, use of this software will be governed
-// by the Apache License, Version 2.0, included in the file
-// licenses/APL.txt.
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
 
 package lexbase
 
diff --git a/pkg/sql/lexbase/keywords.go b/pkg/sql/lexbase/keywords.go
index 8c93523..fd6a768 100644
--- a/pkg/sql/lexbase/keywords.go
+++ b/pkg/sql/lexbase/keywords.go
@@ -31,6 +31,7 @@ var KeywordsCategories = map[string]string{
 "authorization": "T",
 "automatic": "U",
 "availability": "U",
+"avoid_full_scan": "U",
 "backup": "U",
 "backups": "U",
 "backward": "U",
@@ -38,6 +39,7 @@ var KeywordsCategories = map[string]string{
 "before": "U",
 "begin": "U",
 "between": "C",
+"bidirectional": "U",
 "bigint": "C",
 "binary": "U",
 "bit": "C",
@@ -47,6 +49,7 @@ var KeywordsCategories = map[string]string{
 "bucket_count": "U",
 "bundle": "U",
 "by": "U",
+"bypassrls": "U",
 "cache": "U",
 "call": "U",
 "called": "U",
@@ -116,9 +119,7 @@ var KeywordsCategories = map[string]string{
 "databases": "U",
 "day": "U",
 "deallocate": "U",
-"debug_dump_metadata_sst": "U",
 "debug_ids": "U",
-"debug_pause_on": "U",
 "dec": "C",
 "decimal": "C",
 "declare": "U",
@@ -134,13 +135,16 @@ var KeywordsCategories = map[string]string{
 "destination": "U",
 "detached": "U",
 "details": "U",
+"disable": "U",
 "discard": "U",
 "distinct": "R",
 "do": "R",
 "domain": "U",
 "double": "U",
 "drop": "U",
+"each": "U",
 "else": "R",
+"enable": "U",
 "encoding": "U",
 "encrypted": "U",
 "encryption_info_dir": "U",
@@ -180,6 +184,7 @@ var KeywordsCategories = map[string]string{
 "for": "R",
 "force": "U",
 "force_index": "U",
+"force_inverted_index": "U",
 "force_not_null": "U",
 "force_null": "U",
 "force_quote": "U",
@@ -225,6 +230,7 @@ var KeywordsCategories = map[string]string{
 "ignore_foreign_keys": "U",
 "ilike": "T",
 "immediate": "U",
+"immediately": "U",
 "immutable": "U",
 "import": "U",
 "in": "R",
@@ -248,6 +254,7 @@ var KeywordsCategories = map[string]string{
 "input": "U",
 "insensitive": "U",
 "insert": "U",
+"instead": "U",
 "int": "C",
 "integer": "C",
 "intersect": "R",
@@ -295,6 +302,8 @@ var KeywordsCategories = map[string]string{
 "localtime": "R",
 "localtimestamp": "R",
 "locked": "U",
+"logical": "U",
+"logically": "U",
 "login": "U",
 "lookup": "U",
 "low": "U",
@@ -305,6 +314,7 @@ var KeywordsCategories = map[string]string{
 "method": "U",
 "minute": "U",
 "minvalue": "U",
+"mode": "U",
 "modifyclustersetting": "U",
 "modifysqlclustersetting": "U",
 "month": "U",
@@ -325,16 +335,19 @@ var KeywordsCategories = map[string]string{
 "nan": "U",
 "natural": "T",
 "never": "U",
+"new": "U",
 "new_db_name": "U",
 "new_kms": "U",
 "next": "U",
 "no": "U",
+"nobypassrls": "U",
 "nocancelquery": "U",
 "nocontrolchangefeed": "U",
 "nocontroljob": "U",
 "nocreatedb": "U",
 "nocreatelogin": "U",
 "nocreaterole": "U",
+"node": "U",
 "nologin": "U",
 "nomodifyclustersetting": "U",
 "none": "T",
@@ -361,6 +374,7 @@ var KeywordsCategories = map[string]string{
 "off": "U",
 "offset": "R",
 "oids": "U",
+"old": "U",
 "old_kms": "U",
 "on": "R",
 "only": "R",
@@ -387,6 +401,8 @@ var KeywordsCategories = map[string]string{
 "password": "U",
 "pause": "U",
 "paused": "U",
+"per": "U",
+"permissive": "U",
 "physical": "U",
 "placement": "U",
 "placing": "R",
@@ -396,6 +412,8 @@ var KeywordsCategories = map[string]string{
 "pointm": "U",
 "pointz": "U",
 "pointzm": "U",
+"policies": "U",
+"policy": "U",
 "polygon": "C",
 "polygonm": "U",
 "polygonz": "U",
@@ -404,6 +422,7 @@ var KeywordsCategories = map[string]string{
 "preceding": "U",
 "precision": "C",
 "prepare": "U",
+"prepared": "U",
 "preserve": "U",
 "primary": "R",
 "prior": "U",
@@ -427,6 +446,7 @@ var KeywordsCategories = map[string]string{
 "redact": "U",
 "ref": "U",
 "references": "R",
+"referencing": "U",
 "refresh": "U",
 "region": "U",
 "regional": "U",
@@ -439,12 +459,14 @@ var KeywordsCategories = map[string]string{
 "rename": "U",
 "repeatable": "U",
 "replace": "U",
+"replicated": "U",
 "replication": "U",
 "reset": "U",
 "restart": "U",
 "restore": "U",
 "restrict": "U",
 "restricted": "U",
+"restrictive": "U",
 "resume": "U",
 "retention": "U",
 "retry": "U",
@@ -507,12 +529,14 @@ var KeywordsCategories = map[string]string{
 "smallint": "C",
 "snapshot": "U",
 "some": "R",
+"source": "U",
 "split": "U",
 "sql": "U",
 "sqllogin": "U",
 "stable": "U",
 "start": "U",
 "state": "U",
+"statement": "U",
 "statements": "U",
 "statistics": "U",
 "status": "U",
@@ -523,9 +547,11 @@ var KeywordsCategories = map[string]string{
 "store": "U",
 "stored": "U",
 "storing": "U",
+"straight": "U",
 "stream": "U",
 "strict": "U",
 "string": "C",
+"subject": "U",
 "subscription": "U",
 "substring": "C",
 "super": "U",
@@ -563,6 +589,7 @@ var KeywordsCategories = map[string]string{
 "transform": "U",
 "treat": "C",
 "trigger": "U",
+"triggers": "U",
 "trim": "C",
 "true": "R",
 "truncate": "U",
@@ -571,6 +598,7 @@ var KeywordsCategories = map[string]string{
 "types": "U",
 "unbounded": "U",
 "uncommitted": "U",
+"unidirectional": "U",
 "union": "R",
 "unique": "R",
 "unknown": "U",
@@ -593,8 +621,10 @@ var KeywordsCategories = map[string]string{
 "values": "C",
 "varbit": "C",
 "varchar": "C",
+"variables": "U",
 "variadic": "R",
 "varying": "U",
+"vector": "C",
 "verify_backup_table_data": "U",
 "view": "U",
 "viewactivity": "U",
@@ -652,6 +682,7 @@ var KeywordNames = []string{
 "authorization",
 "automatic",
 "availability",
+"avoid_full_scan",
 "backup",
 "backups",
 "backward",
@@ -659,6 +690,7 @@ var KeywordNames = []string{
 "before",
 "begin",
 "between",
+"bidirectional",
 "bigint",
 "binary",
 "bit",
@@ -668,6 +700,7 @@ var KeywordNames = []string{
 "bucket_count",
 "bundle",
 "by",
+"bypassrls",
 "cache",
 "call",
 "called",
@@ -737,9 +770,7 @@ var KeywordNames = []string{
 "databases",
 "day",
 "deallocate",
-"debug_dump_metadata_sst",
 "debug_ids",
-"debug_pause_on",
 "dec",
 "decimal",
 "declare",
@@ -755,13 +786,16 @@ var KeywordNames = []string{
 "destination",
 "detached",
 "details",
+"disable",
 "discard",
 "distinct",
 "do",
 "domain",
 "double",
 "drop",
+"each",
 "else",
+"enable",
 "encoding",
 "encrypted",
 "encryption_info_dir",
@@ -801,6 +835,7 @@ var KeywordNames = []string{
 "for",
 "force",
 "force_index",
+"force_inverted_index",
 "force_not_null",
 "force_null",
 "force_quote",
@@ -846,6 +881,7 @@ var KeywordNames = []string{
 "ignore_foreign_keys",
 "ilike",
 "immediate",
+"immediately",
 "immutable",
 "import",
 "in",
@@ -869,6 +905,7 @@ var KeywordNames = []string{
 "input",
 "insensitive",
 "insert",
+"instead",
 "int",
 "integer",
 "intersect",
@@ -916,6 +953,8 @@ var KeywordNames = []string{
 "localtime",
 "localtimestamp",
 "locked",
+"logical",
+"logically",
 "login",
 "lookup",
 "low",
@@ -926,6 +965,7 @@ var KeywordNames = []string{
 "method",
 "minute",
 "minvalue",
+"mode",
 "modifyclustersetting",
 "modifysqlclustersetting",
 "month",
@@ -946,16 +986,19 @@ var KeywordNames = []string{
 "nan",
 "natural",
 "never",
+"new",
 "new_db_name",
 "new_kms",
 "next",
 "no",
+"nobypassrls",
 "nocancelquery",
 "nocontrolchangefeed",
 "nocontroljob",
 "nocreatedb",
 "nocreatelogin",
 "nocreaterole",
+"node",
 "nologin",
 "nomodifyclustersetting",
 "none",
@@ -982,6 +1025,7 @@ var KeywordNames = []string{
 "off",
 "offset",
 "oids",
+"old",
 "old_kms",
 "on",
 "only",
@@ -1008,6 +1052,8 @@ var KeywordNames = []string{
 "password",
 "pause",
 "paused",
+"per",
+"permissive",
 "physical",
 "placement",
 "placing",
@@ -1017,6 +1063,8 @@ var KeywordNames = []string{
 "pointm",
 "pointz",
 "pointzm",
+"policies",
+"policy",
 "polygon",
 "polygonm",
 "polygonz",
@@ -1025,6 +1073,7 @@ var KeywordNames = []string{
 "preceding",
 "precision",
 "prepare",
+"prepared",
 "preserve",
 "primary",
 "prior",
@@ -1048,6 +1097,7 @@ var KeywordNames = []string{
 "redact",
 "ref",
 "references",
+"referencing",
 "refresh",
 "region",
 "regional",
@@ -1060,12 +1110,14 @@ var KeywordNames = []string{
 "rename",
 "repeatable",
 "replace",
+"replicated",
 "replication",
 "reset",
 "restart",
 "restore",
 "restrict",
 "restricted",
+"restrictive",
 "resume",
 "retention",
 "retry",
@@ -1128,12 +1180,14 @@ var KeywordNames = []string{
 "smallint",
 "snapshot",
 "some",
+"source",
 "split",
 "sql",
 "sqllogin",
 "stable",
 "start",
 "state",
+"statement",
 "statements",
 "statistics",
 "status",
@@ -1144,9 +1198,11 @@ var KeywordNames = []string{
 "store",
 "stored",
 "storing",
+"straight",
 "stream",
 "strict",
 "string",
+"subject",
 "subscription",
 "substring",
 "super",
@@ -1184,6 +1240,7 @@ var KeywordNames = []string{
 "transform",
 "treat",
 "trigger",
+"triggers",
 "trim",
 "true",
 "truncate",
@@ -1192,6 +1249,7 @@ var KeywordNames = []string{
 "types",
 "unbounded",
 "uncommitted",
+"unidirectional",
 "union",
 "unique",
 "unknown",
@@ -1214,8 +1272,10 @@ var KeywordNames = []string{
 "values",
 "varbit",
 "varchar",
+"variables",
 "variadic",
 "varying",
+"vector",
 "verify_backup_table_data",
 "view",
 "viewactivity",
@@ -1278,6 +1338,7 @@ func GetKeywordID(k string) int32 {
 	case "authorization": return AUTHORIZATION
 	case "automatic": return AUTOMATIC
 	case "availability": return AVAILABILITY
+	case "avoid_full_scan": return AVOID_FULL_SCAN
 	case "backup": return BACKUP
 	case "backups": return BACKUPS
 	case "backward": return BACKWARD
@@ -1285,6 +1346,7 @@ func GetKeywordID(k string) int32 {
 	case "before": return BEFORE
 	case "begin": return BEGIN
 	case "between": return BETWEEN
+	case "bidirectional": return BIDIRECTIONAL
 	case "bigint": return BIGINT
 	case "binary": return BINARY
 	case "bit": return BIT
@@ -1294,6 +1356,7 @@ func GetKeywordID(k string) int32 {
 	case "bucket_count": return BUCKET_COUNT
 	case "bundle": return BUNDLE
 	case "by": return BY
+	case "bypassrls": return BYPASSRLS
 	case "cache": return CACHE
 	case "call": return CALL
 	case "called": return CALLED
@@ -1363,9 +1426,7 @@ func GetKeywordID(k string) int32 {
 	case "databases": return DATABASES
 	case "day": return DAY
 	case "deallocate": return DEALLOCATE
-	case "debug_dump_metadata_sst": return DEBUG_DUMP_METADATA_SST
 	case "debug_ids": return DEBUG_IDS
-	case "debug_pause_on": return DEBUG_PAUSE_ON
 	case "dec": return DEC
 	case "decimal": return DECIMAL
 	case "declare": return DECLARE
@@ -1381,13 +1442,16 @@ func GetKeywordID(k string) int32 {
 	case "destination": return DESTINATION
 	case "detached": return DETACHED
 	case "details": return DETAILS
+	case "disable": return DISABLE
 	case "discard": return DISCARD
 	case "distinct": return DISTINCT
 	case "do": return DO
 	case "domain": return DOMAIN
 	case "double": return DOUBLE
 	case "drop": return DROP
+	case "each": return EACH
 	case "else": return ELSE
+	case "enable": return ENABLE
 	case "encoding": return ENCODING
 	case "encrypted": return ENCRYPTED
 	case "encryption_info_dir": return ENCRYPTION_INFO_DIR
@@ -1427,6 +1491,7 @@ func GetKeywordID(k string) int32 {
 	case "for": return FOR
 	case "force": return FORCE
 	case "force_index": return FORCE_INDEX
+	case "force_inverted_index": return FORCE_INVERTED_INDEX
 	case "force_not_null": return FORCE_NOT_NULL
 	case "force_null": return FORCE_NULL
 	case "force_quote": return FORCE_QUOTE
@@ -1472,6 +1537,7 @@ func GetKeywordID(k string) int32 {
 	case "ignore_foreign_keys": return IGNORE_FOREIGN_KEYS
 	case "ilike": return ILIKE
 	case "immediate": return IMMEDIATE
+	case "immediately": return IMMEDIATELY
 	case "immutable": return IMMUTABLE
 	case "import": return IMPORT
 	case "in": return IN
@@ -1495,6 +1561,7 @@ func GetKeywordID(k string) int32 {
 	case "input": return INPUT
 	case "insensitive": return INSENSITIVE
 	case "insert": return INSERT
+	case "instead": return INSTEAD
 	case "int": return INT
 	case "integer": return INTEGER
 	case "intersect": return INTERSECT
@@ -1542,6 +1609,8 @@ func GetKeywordID(k string) int32 {
 	case "localtime": return LOCALTIME
 	case "localtimestamp": return LOCALTIMESTAMP
 	case "locked": return LOCKED
+	case "logical": return LOGICAL
+	case "logically": return LOGICALLY
 	case "login": return LOGIN
 	case "lookup": return LOOKUP
 	case "low": return LOW
@@ -1552,6 +1621,7 @@ func GetKeywordID(k string) int32 {
 	case "method": return METHOD
 	case "minute": return MINUTE
 	case "minvalue": return MINVALUE
+	case "mode": return MODE
 	case "modifyclustersetting": return MODIFYCLUSTERSETTING
 	case "modifysqlclustersetting": return MODIFYSQLCLUSTERSETTING
 	case "month": return MONTH
@@ -1572,16 +1642,19 @@ func GetKeywordID(k string) int32 {
 	case "nan": return NAN
 	case "natural": return NATURAL
 	case "never": return NEVER
+	case "new": return NEW
 	case "new_db_name": return NEW_DB_NAME
 	case "new_kms": return NEW_KMS
 	case "next": return NEXT
 	case "no": return NO
+	case "nobypassrls": return NOBYPASSRLS
 	case "nocancelquery": return NOCANCELQUERY
 	case "nocontrolchangefeed": return NOCONTROLCHANGEFEED
 	case "nocontroljob": return NOCONTROLJOB
 	case "nocreatedb": return NOCREATEDB
 	case "nocreatelogin": return NOCREATELOGIN
 	case "nocreaterole": return NOCREATEROLE
+	case "node": return NODE
 	case "nologin": return NOLOGIN
 	case "nomodifyclustersetting": return NOMODIFYCLUSTERSETTING
 	case "none": return NONE
@@ -1608,6 +1681,7 @@ func GetKeywordID(k string) int32 {
 	case "off": return OFF
 	case "offset": return OFFSET
 	case "oids": return OIDS
+	case "old": return OLD
 	case "old_kms": return OLD_KMS
 	case "on": return ON
 	case "only": return ONLY
@@ -1634,6 +1708,8 @@ func GetKeywordID(k string) int32 {
 	case "password": return PASSWORD
 	case "pause": return PAUSE
 	case "paused": return PAUSED
+	case "per": return PER
+	case "permissive": return PERMISSIVE
 	case "physical": return PHYSICAL
 	case "placement": return PLACEMENT
 	case "placing": return PLACING
@@ -1643,6 +1719,8 @@ func GetKeywordID(k string) int32 {
 	case "pointm": return POINTM
 	case "pointz": return POINTZ
 	case "pointzm": return POINTZM
+	case "policies": return POLICIES
+	case "policy": return POLICY
 	case "polygon": return POLYGON
 	case "polygonm": return POLYGONM
 	case "polygonz": return POLYGONZ
@@ -1651,6 +1729,7 @@ func GetKeywordID(k string) int32 {
 	case "preceding": return PRECEDING
 	case "precision": return PRECISION
 	case "prepare": return PREPARE
+	case "prepared": return PREPARED
 	case "preserve": return PRESERVE
 	case "primary": return PRIMARY
 	case "prior": return PRIOR
@@ -1674,6 +1753,7 @@ func GetKeywordID(k string) int32 {
 	case "redact": return REDACT
 	case "ref": return REF
 	case "references": return REFERENCES
+	case "referencing": return REFERENCING
 	case "refresh": return REFRESH
 	case "region": return REGION
 	case "regional": return REGIONAL
@@ -1686,12 +1766,14 @@ func GetKeywordID(k string) int32 {
 	case "rename": return RENAME
 	case "repeatable": return REPEATABLE
 	case "replace": return REPLACE
+	case "replicated": return REPLICATED
 	case "replication": return REPLICATION
 	case "reset": return RESET
 	case "restart": return RESTART
 	case "restore": return RESTORE
 	case "restrict": return RESTRICT
 	case "restricted": return RESTRICTED
+	case "restrictive": return RESTRICTIVE
 	case "resume": return RESUME
 	case "retention": return RETENTION
 	case "retry": return RETRY
@@ -1754,12 +1836,14 @@ func GetKeywordID(k string) int32 {
 	case "smallint": return SMALLINT
 	case "snapshot": return SNAPSHOT
 	case "some": return SOME
+	case "source": return SOURCE
 	case "split": return SPLIT
 	case "sql": return SQL
 	case "sqllogin": return SQLLOGIN
 	case "stable": return STABLE
 	case "start": return START
 	case "state": return STATE
+	case "statement": return STATEMENT
 	case "statements": return STATEMENTS
 	case "statistics": return STATISTICS
 	case "status": return STATUS
@@ -1770,9 +1854,11 @@ func GetKeywordID(k string) int32 {
 	case "store": return STORE
 	case "stored": return STORED
 	case "storing": return STORING
+	case "straight": return STRAIGHT
 	case "stream": return STREAM
 	case "strict": return STRICT
 	case "string": return STRING
+	case "subject": return SUBJECT
 	case "subscription": return SUBSCRIPTION
 	case "substring": return SUBSTRING
 	case "super": return SUPER
@@ -1810,6 +1896,7 @@ func GetKeywordID(k string) int32 {
 	case "transform": return TRANSFORM
 	case "treat": return TREAT
 	case "trigger": return TRIGGER
+	case "triggers": return TRIGGERS
 	case "trim": return TRIM
 	case "true": return TRUE
 	case "truncate": return TRUNCATE
@@ -1818,6 +1905,7 @@ func GetKeywordID(k string) int32 {
 	case "types": return TYPES
 	case "unbounded": return UNBOUNDED
 	case "uncommitted": return UNCOMMITTED
+	case "unidirectional": return UNIDIRECTIONAL
 	case "union": return UNION
 	case "unique": return UNIQUE
 	case "unknown": return UNKNOWN
@@ -1840,8 +1928,10 @@ func GetKeywordID(k string) int32 {
 	case "values": return VALUES
 	case "varbit": return VARBIT
 	case "varchar": return VARCHAR
+	case "variables": return VARIABLES
 	case "variadic": return VARIADIC
 	case "varying": return VARYING
+	case "vector": return VECTOR
 	case "verify_backup_table_data": return VERIFY_BACKUP_TABLE_DATA
 	case "view": return VIEW
 	case "viewactivity": return VIEWACTIVITY
diff --git a/pkg/sql/lexbase/normalize.go b/pkg/sql/lexbase/normalize.go
index 197b2bc..de59ff2 100644
--- a/pkg/sql/lexbase/normalize.go
+++ b/pkg/sql/lexbase/normalize.go
@@ -1,12 +1,7 @@
 // Copyright 2017 The Cockroach Authors.
 //
-// Use of this software is governed by the Business Source License
-// included in the file licenses/BSL.txt.
-//
-// As of the Change Date specified in that file, in accordance with
-// the Business Source License, use of this software will be governed
-// by the Apache License, Version 2.0, included in the file
-// licenses/APL.txt.
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
 
 package lexbase
 
diff --git a/pkg/sql/lexbase/predicates.go b/pkg/sql/lexbase/predicates.go
index f166b28..5cbd442 100644
--- a/pkg/sql/lexbase/predicates.go
+++ b/pkg/sql/lexbase/predicates.go
@@ -1,12 +1,7 @@
 // Copyright 2017 The Cockroach Authors.
 //
-// Use of this software is governed by the Business Source License
-// included in the file licenses/BSL.txt.
-//
-// As of the Change Date specified in that file, in accordance with
-// the Business Source License, use of this software will be governed
-// by the Apache License, Version 2.0, included in the file
-// licenses/APL.txt.
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
 
 package lexbase
 
diff --git a/pkg/sql/lexbase/reserved_keywords.go b/pkg/sql/lexbase/reserved_keywords.go
index 6779ff7..eb4fb70 100644
--- a/pkg/sql/lexbase/reserved_keywords.go
+++ b/pkg/sql/lexbase/reserved_keywords.go
@@ -155,6 +155,7 @@ var reservedKeywords = map[string]struct{}{
 "varbit": {},
 "varchar": {},
 "variadic": {},
+"vector": {},
 "virtual": {},
 "when": {},
 "where": {},
diff --git a/pkg/sql/lexbase/sql-gen.sh b/pkg/sql/lexbase/sql-gen.sh
index b242ab6..d753916 100755
--- a/pkg/sql/lexbase/sql-gen.sh
+++ b/pkg/sql/lexbase/sql-gen.sh
@@ -1,8 +1,14 @@
 #!/usr/bin/env bash
 
-# This is used through bazel when generating sql.go and plpgsql.go.
-# Look at BUILD.bazel in pkg/sql/parser or pkg/plpgsql/parser for
-# usage.
+# Copyright 2022 The Cockroach Authors.
+#
+# Use of this software is governed by the CockroachDB Software License
+# included in the /LICENSE file.
+
+
+# This is used through bazel when generating sql.go, plpgsql.go, and jsonpath.go.
+# Look at BUILD.bazel in pkg/sql/parser, pkg/sql/plpgsql/parser, or
+# pkg/util/jsonpath/parser for usage.
 
 set -euo pipefail
 
@@ -17,7 +23,7 @@ GENYACC=$LANG-gen.y
         awk '{print $0")>_\\1 <union> /* <\\2> */_"}' > types_regex.tmp
 
     sed -E -f types_regex.tmp < $1 | \
-        if [ $LANG != plpgsql ] && [ $LANG != pgrepl ]; then \
+        if [ $LANG != plpgsql ] && [ $LANG != pgrepl ] && [ $LANG != jsonpath ]; then \
             awk -f $3 | \
           sed -Ee 's,//.*$$,,g;s,/[*]([^*]|[*][^/])*[*]/, ,g;s/ +$$//g' > $GENYACC
         else
diff --git a/pkg/sql/lexbase/tokens.go b/pkg/sql/lexbase/tokens.go
index 872c988..6c01167 100644
--- a/pkg/sql/lexbase/tokens.go
+++ b/pkg/sql/lexbase/tokens.go
@@ -50,643 +50,676 @@ const ATTRIBUTE = 57389
 const AUTHORIZATION = 57390
 const AUTOMATIC = 57391
 const AVAILABILITY = 57392
-const BACKUP = 57393
-const BACKUPS = 57394
-const BACKWARD = 57395
-const BATCH = 57396
-const BEFORE = 57397
-const BEGIN = 57398
-const BETWEEN = 57399
-const BIGINT = 57400
-const BIGSERIAL = 57401
-const BINARY = 57402
-const BIT = 57403
-const BUCKET_COUNT = 57404
-const BOOLEAN = 57405
-const BOTH = 57406
-const BOX2D = 57407
-const BUNDLE = 57408
-const BY = 57409
-const CACHE = 57410
-const CALL = 57411
-const CALLED = 57412
-const CANCEL = 57413
-const CANCELQUERY = 57414
-const CAPABILITIES = 57415
-const CAPABILITY = 57416
-const CASCADE = 57417
-const CASE = 57418
-const CAST = 57419
-const CBRT = 57420
-const CHANGEFEED = 57421
-const CHAR = 57422
-const CHARACTER = 57423
-const CHARACTERISTICS = 57424
-const CHECK = 57425
-const CHECK_FILES = 57426
-const CLOSE = 57427
-const CLUSTER = 57428
-const CLUSTERS = 57429
-const COALESCE = 57430
-const COLLATE = 57431
-const COLLATION = 57432
-const COLUMN = 57433
-const COLUMNS = 57434
-const COMMENT = 57435
-const COMMENTS = 57436
-const COMMIT = 57437
-const COMMITTED = 57438
-const COMPACT = 57439
-const COMPLETE = 57440
-const COMPLETIONS = 57441
-const CONCAT = 57442
-const CONCURRENTLY = 57443
-const CONFIGURATION = 57444
-const CONFIGURATIONS = 57445
-const CONFIGURE = 57446
-const CONFLICT = 57447
-const CONNECTION = 57448
-const CONNECTIONS = 57449
-const CONSTRAINT = 57450
-const CONSTRAINTS = 57451
-const CONTAINS = 57452
-const CONTROLCHANGEFEED = 57453
-const CONTROLJOB = 57454
-const CONVERSION = 57455
-const CONVERT = 57456
-const COPY = 57457
-const COST = 57458
-const COVERING = 57459
-const CREATE = 57460
-const CREATEDB = 57461
-const CREATELOGIN = 57462
-const CREATEROLE = 57463
-const CROSS = 57464
-const CSV = 57465
-const CUBE = 57466
-const CURRENT = 57467
-const CURRENT_CATALOG = 57468
-const CURRENT_DATE = 57469
-const CURRENT_SCHEMA = 57470
-const CURRENT_ROLE = 57471
-const CURRENT_TIME = 57472
-const CURRENT_TIMESTAMP = 57473
-const CURRENT_USER = 57474
-const CURSOR = 57475
-const CYCLE = 57476
-const DATA = 57477
-const DATABASE = 57478
-const DATABASES = 57479
-const DATE = 57480
-const DAY = 57481
-const DEBUG_IDS = 57482
-const DEBUG_PAUSE_ON = 57483
-const DEC = 57484
-const DEBUG_DUMP_METADATA_SST = 57485
-const DECIMAL = 57486
-const DEFAULT = 57487
-const DEFAULTS = 57488
-const DEFINER = 57489
-const DEALLOCATE = 57490
-const DECLARE = 57491
-const DEFERRABLE = 57492
-const DEFERRED = 57493
-const DELETE = 57494
-const DELIMITER = 57495
-const DEPENDS = 57496
-const DESC = 57497
-const DESTINATION = 57498
-const DETACHED = 57499
-const DETAILS = 57500
-const DISCARD = 57501
-const DISTINCT = 57502
-const DO = 57503
-const DOMAIN = 57504
-const DOUBLE = 57505
-const DROP = 57506
-const ELSE = 57507
-const ENCODING = 57508
-const ENCRYPTED = 57509
-const ENCRYPTION_INFO_DIR = 57510
-const ENCRYPTION_PASSPHRASE = 57511
-const END = 57512
-const ENUM = 57513
-const ENUMS = 57514
-const ESCAPE = 57515
-const EXCEPT = 57516
-const EXCLUDE = 57517
-const EXCLUDING = 57518
-const EXISTS = 57519
-const EXECUTE = 57520
-const EXECUTION = 57521
-const EXPERIMENTAL = 57522
-const EXPERIMENTAL_FINGERPRINTS = 57523
-const EXPERIMENTAL_REPLICA = 57524
-const EXPERIMENTAL_AUDIT = 57525
-const EXPERIMENTAL_RELOCATE = 57526
-const EXPIRATION = 57527
-const EXPLAIN = 57528
-const EXPORT = 57529
-const EXTENSION = 57530
-const EXTERNAL = 57531
-const EXTRACT = 57532
-const EXTRACT_DURATION = 57533
-const EXTREMES = 57534
-const FAILURE = 57535
-const FALSE = 57536
-const FAMILY = 57537
-const FETCH = 57538
-const FETCHVAL = 57539
-const FETCHTEXT = 57540
-const FETCHVAL_PATH = 57541
-const FETCHTEXT_PATH = 57542
-const FILES = 57543
-const FILTER = 57544
-const FIRST = 57545
-const FLOAT = 57546
-const FLOAT4 = 57547
-const FLOAT8 = 57548
-const FLOORDIV = 57549
-const FOLLOWING = 57550
-const FOR = 57551
-const FORCE = 57552
-const FORCE_INDEX = 57553
-const FORCE_NOT_NULL = 57554
-const FORCE_NULL = 57555
-const FORCE_QUOTE = 57556
-const FORCE_ZIGZAG = 57557
-const FOREIGN = 57558
-const FORMAT = 57559
-const FORWARD = 57560
-const FREEZE = 57561
-const FROM = 57562
-const FULL = 57563
-const FUNCTION = 57564
-const FUNCTIONS = 57565
-const GENERATED = 57566
-const GEOGRAPHY = 57567
-const GEOMETRY = 57568
-const GEOMETRYM = 57569
-const GEOMETRYZ = 57570
-const GEOMETRYZM = 57571
-const GEOMETRYCOLLECTION = 57572
-const GEOMETRYCOLLECTIONM = 57573
-const GEOMETRYCOLLECTIONZ = 57574
-const GEOMETRYCOLLECTIONZM = 57575
-const GLOBAL = 57576
-const GOAL = 57577
-const GRANT = 57578
-const GRANTEE = 57579
-const GRANTS = 57580
-const GREATEST = 57581
-const GROUP = 57582
-const GROUPING = 57583
-const GROUPS = 57584
-const HAVING = 57585
-const HASH = 57586
-const HEADER = 57587
-const HIGH = 57588
-const HISTOGRAM = 57589
-const HOLD = 57590
-const HOUR = 57591
-const IDENTITY = 57592
-const IF = 57593
-const IFERROR = 57594
-const IFNULL = 57595
-const IGNORE_FOREIGN_KEYS = 57596
-const ILIKE = 57597
-const IMMEDIATE = 57598
-const IMMUTABLE = 57599
-const IMPORT = 57600
-const IN = 57601
-const INCLUDE = 57602
-const INCLUDING = 57603
-const INCLUDE_ALL_SECONDARY_TENANTS = 57604
-const INCLUDE_ALL_VIRTUAL_CLUSTERS = 57605
-const INCREMENT = 57606
-const INCREMENTAL = 57607
-const INCREMENTAL_LOCATION = 57608
-const INET = 57609
-const INET_CONTAINED_BY_OR_EQUALS = 57610
-const INET_CONTAINS_OR_EQUALS = 57611
-const INDEX = 57612
-const INDEXES = 57613
-const INHERITS = 57614
-const INJECT = 57615
-const INITIALLY = 57616
-const INDEX_BEFORE_PAREN = 57617
-const INDEX_BEFORE_NAME_THEN_PAREN = 57618
-const INDEX_AFTER_ORDER_BY_BEFORE_AT = 57619
-const INNER = 57620
-const INOUT = 57621
-const INPUT = 57622
-const INSENSITIVE = 57623
-const INSERT = 57624
-const INT = 57625
-const INTEGER = 57626
-const INTERSECT = 57627
-const INTERVAL = 57628
-const INTO = 57629
-const INTO_DB = 57630
-const INVERTED = 57631
-const INVOKER = 57632
-const IS = 57633
-const ISERROR = 57634
-const ISNULL = 57635
-const ISOLATION = 57636
-const JOB = 57637
-const JOBS = 57638
-const JOIN = 57639
-const JSON = 57640
-const JSONB = 57641
-const JSON_SOME_EXISTS = 57642
-const JSON_ALL_EXISTS = 57643
-const KEY = 57644
-const KEYS = 57645
-const KMS = 57646
-const KV = 57647
-const LABEL = 57648
-const LANGUAGE = 57649
-const LAST = 57650
-const LATERAL = 57651
-const LATEST = 57652
-const LC_CTYPE = 57653
-const LC_COLLATE = 57654
-const LEADING = 57655
-const LEASE = 57656
-const LEAST = 57657
-const LEAKPROOF = 57658
-const LEFT = 57659
-const LESS = 57660
-const LEVEL = 57661
-const LIKE = 57662
-const LIMIT = 57663
-const LINESTRING = 57664
-const LINESTRINGM = 57665
-const LINESTRINGZ = 57666
-const LINESTRINGZM = 57667
-const LIST = 57668
-const LOCAL = 57669
-const LOCALITY = 57670
-const LOCALTIME = 57671
-const LOCALTIMESTAMP = 57672
-const LOCKED = 57673
-const LOGIN = 57674
-const LOOKUP = 57675
-const LOW = 57676
-const LSHIFT = 57677
-const MATCH = 57678
-const MATERIALIZED = 57679
-const MERGE = 57680
-const MINVALUE = 57681
-const MAXVALUE = 57682
-const METHOD = 57683
-const MINUTE = 57684
-const MODIFYCLUSTERSETTING = 57685
-const MODIFYSQLCLUSTERSETTING = 57686
-const MONTH = 57687
-const MOVE = 57688
-const MULTILINESTRING = 57689
-const MULTILINESTRINGM = 57690
-const MULTILINESTRINGZ = 57691
-const MULTILINESTRINGZM = 57692
-const MULTIPOINT = 57693
-const MULTIPOINTM = 57694
-const MULTIPOINTZ = 57695
-const MULTIPOINTZM = 57696
-const MULTIPOLYGON = 57697
-const MULTIPOLYGONM = 57698
-const MULTIPOLYGONZ = 57699
-const MULTIPOLYGONZM = 57700
-const NAN = 57701
-const NAME = 57702
-const NAMES = 57703
-const NATURAL = 57704
-const NEVER = 57705
-const NEW_DB_NAME = 57706
-const NEW_KMS = 57707
-const NEXT = 57708
-const NO = 57709
-const NOCANCELQUERY = 57710
-const NOCONTROLCHANGEFEED = 57711
-const NOCONTROLJOB = 57712
-const NOCREATEDB = 57713
-const NOCREATELOGIN = 57714
-const NOCREATEROLE = 57715
-const NOLOGIN = 57716
-const NOMODIFYCLUSTERSETTING = 57717
-const NOREPLICATION = 57718
-const NOSQLLOGIN = 57719
-const NO_INDEX_JOIN = 57720
-const NO_ZIGZAG_JOIN = 57721
-const NO_FULL_SCAN = 57722
-const NONE = 57723
-const NONVOTERS = 57724
-const NORMAL = 57725
-const NOT = 57726
-const NOTHING = 57727
-const NOTHING_AFTER_RETURNING = 57728
-const NOTNULL = 57729
-const NOVIEWACTIVITY = 57730
-const NOVIEWACTIVITYREDACTED = 57731
-const NOVIEWCLUSTERSETTING = 57732
-const NOWAIT = 57733
-const NULL = 57734
-const NULLIF = 57735
-const NULLS = 57736
-const NUMERIC = 57737
-const OF = 57738
-const OFF = 57739
-const OFFSET = 57740
-const OID = 57741
-const OIDS = 57742
-const OIDVECTOR = 57743
-const OLD_KMS = 57744
-const ON = 57745
-const ONLY = 57746
-const OPT = 57747
-const OPTION = 57748
-const OPTIONS = 57749
-const OR = 57750
-const ORDER = 57751
-const ORDINALITY = 57752
-const OTHERS = 57753
-const OUT = 57754
-const OUTER = 57755
-const OVER = 57756
-const OVERLAPS = 57757
-const OVERLAY = 57758
-const OWNED = 57759
-const OWNER = 57760
-const OPERATOR = 57761
-const PARALLEL = 57762
-const PARENT = 57763
-const PARTIAL = 57764
-const PARTITION = 57765
-const PARTITIONS = 57766
-const PASSWORD = 57767
-const PAUSE = 57768
-const PAUSED = 57769
-const PHYSICAL = 57770
-const PLACEMENT = 57771
-const PLACING = 57772
-const PLAN = 57773
-const PLANS = 57774
-const POINT = 57775
-const POINTM = 57776
-const POINTZ = 57777
-const POINTZM = 57778
-const POLYGON = 57779
-const POLYGONM = 57780
-const POLYGONZ = 57781
-const POLYGONZM = 57782
-const POSITION = 57783
-const PRECEDING = 57784
-const PRECISION = 57785
-const PREPARE = 57786
-const PRESERVE = 57787
-const PRIMARY = 57788
-const PRIOR = 57789
-const PRIORITY = 57790
-const PRIVILEGES = 57791
-const PROCEDURAL = 57792
-const PROCEDURE = 57793
-const PROCEDURES = 57794
-const PUBLIC = 57795
-const PUBLICATION = 57796
-const QUERIES = 57797
-const QUERY = 57798
-const QUOTE = 57799
-const RANGE = 57800
-const RANGES = 57801
-const READ = 57802
-const REAL = 57803
-const REASON = 57804
-const REASSIGN = 57805
-const RECURSIVE = 57806
-const RECURRING = 57807
-const REDACT = 57808
-const REF = 57809
-const REFERENCES = 57810
-const REFRESH = 57811
-const REGCLASS = 57812
-const REGION = 57813
-const REGIONAL = 57814
-const REGIONS = 57815
-const REGNAMESPACE = 57816
-const REGPROC = 57817
-const REGPROCEDURE = 57818
-const REGROLE = 57819
-const REGTYPE = 57820
-const REINDEX = 57821
-const RELATIVE = 57822
-const RELOCATE = 57823
-const REMOVE_PATH = 57824
-const REMOVE_REGIONS = 57825
-const RENAME = 57826
-const REPEATABLE = 57827
-const REPLACE = 57828
-const REPLICATION = 57829
-const RELEASE = 57830
-const RESET = 57831
-const RESTART = 57832
-const RESTORE = 57833
-const RESTRICT = 57834
-const RESTRICTED = 57835
-const RESUME = 57836
-const RETENTION = 57837
-const RETURNING = 57838
-const RETURN = 57839
-const RETURNS = 57840
-const RETRY = 57841
-const REVISION_HISTORY = 57842
-const REVOKE = 57843
-const RIGHT = 57844
-const ROLE = 57845
-const ROLES = 57846
-const ROLLBACK = 57847
-const ROLLUP = 57848
-const ROUTINES = 57849
-const ROW = 57850
-const ROWS = 57851
-const RSHIFT = 57852
-const RULE = 57853
-const RUNNING = 57854
-const SAVEPOINT = 57855
-const SCANS = 57856
-const SCATTER = 57857
-const SCHEDULE = 57858
-const SCHEDULES = 57859
-const SCROLL = 57860
-const SCHEMA = 57861
-const SCHEMA_ONLY = 57862
-const SCHEMAS = 57863
-const SCRUB = 57864
-const SEARCH = 57865
-const SECOND = 57866
-const SECONDARY = 57867
-const SECURITY = 57868
-const SELECT = 57869
-const SEQUENCE = 57870
-const SEQUENCES = 57871
-const SERIALIZABLE = 57872
-const SERVER = 57873
-const SERVICE = 57874
-const SESSION = 57875
-const SESSIONS = 57876
-const SESSION_USER = 57877
-const SET = 57878
-const SETOF = 57879
-const SETS = 57880
-const SETTING = 57881
-const SETTINGS = 57882
-const SHARE = 57883
-const SHARED = 57884
-const SHOW = 57885
-const SIMILAR = 57886
-const SIMPLE = 57887
-const SIZE = 57888
-const SKIP = 57889
-const SKIP_LOCALITIES_CHECK = 57890
-const SKIP_MISSING_FOREIGN_KEYS = 57891
-const SKIP_MISSING_SEQUENCES = 57892
-const SKIP_MISSING_SEQUENCE_OWNERS = 57893
-const SKIP_MISSING_VIEWS = 57894
-const SKIP_MISSING_UDFS = 57895
-const SMALLINT = 57896
-const SMALLSERIAL = 57897
-const SNAPSHOT = 57898
-const SOME = 57899
-const SPLIT = 57900
-const SQL = 57901
-const SQLLOGIN = 57902
-const STABLE = 57903
-const START = 57904
-const STATE = 57905
-const STATISTICS = 57906
-const STATUS = 57907
-const STDIN = 57908
-const STDOUT = 57909
-const STOP = 57910
-const STREAM = 57911
-const STRICT = 57912
-const STRING = 57913
-const STORAGE = 57914
-const STORE = 57915
-const STORED = 57916
-const STORING = 57917
-const SUBSTRING = 57918
-const SUPER = 57919
-const SUPPORT = 57920
-const SURVIVE = 57921
-const SURVIVAL = 57922
-const SYMMETRIC = 57923
-const SYNTAX = 57924
-const SYSTEM = 57925
-const SQRT = 57926
-const SUBSCRIPTION = 57927
-const STATEMENTS = 57928
-const TABLE = 57929
-const TABLES = 57930
-const TABLESPACE = 57931
-const TEMP = 57932
-const TEMPLATE = 57933
-const TEMPORARY = 57934
-const TENANT = 57935
-const TENANT_NAME = 57936
-const TENANTS = 57937
-const TESTING_RELOCATE = 57938
-const TEXT = 57939
-const THEN = 57940
-const TIES = 57941
-const TIME = 57942
-const TIMETZ = 57943
-const TIMESTAMP = 57944
-const TIMESTAMPTZ = 57945
-const TO = 57946
-const THROTTLING = 57947
-const TRAILING = 57948
-const TRACE = 57949
-const TRANSACTION = 57950
-const TRANSACTIONS = 57951
-const TRANSFER = 57952
-const TRANSFORM = 57953
-const TREAT = 57954
-const TRIGGER = 57955
-const TRIM = 57956
-const TRUE = 57957
-const TRUNCATE = 57958
-const TRUSTED = 57959
-const TYPE = 57960
-const TYPES = 57961
-const TRACING = 57962
-const UNBOUNDED = 57963
-const UNCOMMITTED = 57964
-const UNION = 57965
-const UNIQUE = 57966
-const UNKNOWN = 57967
-const UNLISTEN = 57968
-const UNLOGGED = 57969
-const UNSAFE_RESTORE_INCOMPATIBLE_VERSION = 57970
-const UNSPLIT = 57971
-const UPDATE = 57972
-const UPDATES_CLUSTER_MONITORING_METRICS = 57973
-const UPSERT = 57974
-const UNSET = 57975
-const UNTIL = 57976
-const USE = 57977
-const USER = 57978
-const USERS = 57979
-const USING = 57980
-const UUID = 57981
-const VALID = 57982
-const VALIDATE = 57983
-const VALUE = 57984
-const VALUES = 57985
-const VARBIT = 57986
-const VARCHAR = 57987
-const VARIADIC = 57988
-const VERIFY_BACKUP_TABLE_DATA = 57989
-const VIEW = 57990
-const VARYING = 57991
-const VIEWACTIVITY = 57992
-const VIEWACTIVITYREDACTED = 57993
-const VIEWDEBUG = 57994
-const VIEWCLUSTERMETADATA = 57995
-const VIEWCLUSTERSETTING = 57996
-const VIRTUAL = 57997
-const VISIBLE = 57998
-const INVISIBLE = 57999
-const VISIBILITY = 58000
-const VOLATILE = 58001
-const VOTERS = 58002
-const VIRTUAL_CLUSTER_NAME = 58003
-const VIRTUAL_CLUSTER = 58004
-const WHEN = 58005
-const WHERE = 58006
-const WINDOW = 58007
-const WITH = 58008
-const WITHIN = 58009
-const WITHOUT = 58010
-const WORK = 58011
-const WRITE = 58012
-const YEAR = 58013
-const ZONE = 58014
-const NOT_LA = 58015
-const NULLS_LA = 58016
-const WITH_LA = 58017
-const AS_LA = 58018
-const GENERATED_ALWAYS = 58019
-const GENERATED_BY_DEFAULT = 58020
-const RESET_ALL = 58021
-const ROLE_ALL = 58022
-const USER_ALL = 58023
-const ON_LA = 58024
-const TENANT_ALL = 58025
-const CLUSTER_ALL = 58026
-const SET_TRACING = 58027
-const CONTAINED_BY = 58028
-const POSTFIXOP = 58029
-const INTERVAL_SIMPLE = 58030
-const UMINUS = 58031
-const HELPTOKEN = 58032
+const AVOID_FULL_SCAN = 57393
+const BACKUP = 57394
+const BACKUPS = 57395
+const BACKWARD = 57396
+const BATCH = 57397
+const BEFORE = 57398
+const BEGIN = 57399
+const BETWEEN = 57400
+const BIDIRECTIONAL = 57401
+const BIGINT = 57402
+const BIGSERIAL = 57403
+const BINARY = 57404
+const BIT = 57405
+const BUCKET_COUNT = 57406
+const BOOLEAN = 57407
+const BOTH = 57408
+const BOX2D = 57409
+const BUNDLE = 57410
+const BY = 57411
+const BYPASSRLS = 57412
+const CACHE = 57413
+const CALL = 57414
+const CALLED = 57415
+const CANCEL = 57416
+const CANCELQUERY = 57417
+const CAPABILITIES = 57418
+const CAPABILITY = 57419
+const CASCADE = 57420
+const CASE = 57421
+const CAST = 57422
+const CBRT = 57423
+const CHANGEFEED = 57424
+const CHAR = 57425
+const CHARACTER = 57426
+const CHARACTERISTICS = 57427
+const CHECK = 57428
+const CHECK_FILES = 57429
+const CLOSE = 57430
+const CLUSTER = 57431
+const CLUSTERS = 57432
+const COALESCE = 57433
+const COLLATE = 57434
+const COLLATION = 57435
+const COLUMN = 57436
+const COLUMNS = 57437
+const COMMENT = 57438
+const COMMENTS = 57439
+const COMMIT = 57440
+const COMMITTED = 57441
+const COMPACT = 57442
+const COMPLETE = 57443
+const COMPLETIONS = 57444
+const CONCAT = 57445
+const CONCURRENTLY = 57446
+const CONFIGURATION = 57447
+const CONFIGURATIONS = 57448
+const CONFIGURE = 57449
+const CONFLICT = 57450
+const CONNECTION = 57451
+const CONNECTIONS = 57452
+const CONSTRAINT = 57453
+const CONSTRAINTS = 57454
+const CONTAINS = 57455
+const CONTROLCHANGEFEED = 57456
+const CONTROLJOB = 57457
+const CONVERSION = 57458
+const CONVERT = 57459
+const COPY = 57460
+const COS_DISTANCE = 57461
+const COST = 57462
+const COVERING = 57463
+const CREATE = 57464
+const CREATEDB = 57465
+const CREATELOGIN = 57466
+const CREATEROLE = 57467
+const CROSS = 57468
+const CSV = 57469
+const CUBE = 57470
+const CURRENT = 57471
+const CURRENT_CATALOG = 57472
+const CURRENT_DATE = 57473
+const CURRENT_SCHEMA = 57474
+const CURRENT_ROLE = 57475
+const CURRENT_TIME = 57476
+const CURRENT_TIMESTAMP = 57477
+const CURRENT_USER = 57478
+const CURSOR = 57479
+const CYCLE = 57480
+const DATA = 57481
+const DATABASE = 57482
+const DATABASES = 57483
+const DATE = 57484
+const DAY = 57485
+const DEBUG_IDS = 57486
+const DEC = 57487
+const DECIMAL = 57488
+const DEFAULT = 57489
+const DEFAULTS = 57490
+const DEFINER = 57491
+const DEALLOCATE = 57492
+const DECLARE = 57493
+const DEFERRABLE = 57494
+const DEFERRED = 57495
+const DELETE = 57496
+const DELIMITER = 57497
+const DEPENDS = 57498
+const DESC = 57499
+const DESTINATION = 57500
+const DETACHED = 57501
+const DETAILS = 57502
+const DISABLE = 57503
+const DISCARD = 57504
+const DISTANCE = 57505
+const DISTINCT = 57506
+const DO = 57507
+const DOMAIN = 57508
+const DOUBLE = 57509
+const DROP = 57510
+const EACH = 57511
+const ELSE = 57512
+const ENABLE = 57513
+const ENCODING = 57514
+const ENCRYPTED = 57515
+const ENCRYPTION_INFO_DIR = 57516
+const ENCRYPTION_PASSPHRASE = 57517
+const END = 57518
+const ENUM = 57519
+const ENUMS = 57520
+const ESCAPE = 57521
+const EXCEPT = 57522
+const EXCLUDE = 57523
+const EXCLUDING = 57524
+const EXISTS = 57525
+const EXECUTE = 57526
+const EXECUTION = 57527
+const EXPERIMENTAL = 57528
+const EXPERIMENTAL_FINGERPRINTS = 57529
+const EXPERIMENTAL_REPLICA = 57530
+const EXPERIMENTAL_AUDIT = 57531
+const EXPERIMENTAL_RELOCATE = 57532
+const EXPIRATION = 57533
+const EXPLAIN = 57534
+const EXPORT = 57535
+const EXTENSION = 57536
+const EXTERNAL = 57537
+const EXTRACT = 57538
+const EXTRACT_DURATION = 57539
+const EXTREMES = 57540
+const FAILURE = 57541
+const FALSE = 57542
+const FAMILY = 57543
+const FETCH = 57544
+const FETCHVAL = 57545
+const FETCHTEXT = 57546
+const FETCHVAL_PATH = 57547
+const FETCHTEXT_PATH = 57548
+const FILES = 57549
+const FILTER = 57550
+const FIRST = 57551
+const FLOAT = 57552
+const FLOAT4 = 57553
+const FLOAT8 = 57554
+const FLOORDIV = 57555
+const FOLLOWING = 57556
+const FOR = 57557
+const FORCE = 57558
+const FORCE_INDEX = 57559
+const FORCE_INVERTED_INDEX = 57560
+const FORCE_NOT_NULL = 57561
+const FORCE_NULL = 57562
+const FORCE_QUOTE = 57563
+const FORCE_ZIGZAG = 57564
+const FOREIGN = 57565
+const FORMAT = 57566
+const FORWARD = 57567
+const FREEZE = 57568
+const FROM = 57569
+const FULL = 57570
+const FUNCTION = 57571
+const FUNCTIONS = 57572
+const GENERATED = 57573
+const GEOGRAPHY = 57574
+const GEOMETRY = 57575
+const GEOMETRYM = 57576
+const GEOMETRYZ = 57577
+const GEOMETRYZM = 57578
+const GEOMETRYCOLLECTION = 57579
+const GEOMETRYCOLLECTIONM = 57580
+const GEOMETRYCOLLECTIONZ = 57581
+const GEOMETRYCOLLECTIONZM = 57582
+const GLOBAL = 57583
+const GOAL = 57584
+const GRANT = 57585
+const GRANTEE = 57586
+const GRANTS = 57587
+const GREATEST = 57588
+const GROUP = 57589
+const GROUPING = 57590
+const GROUPS = 57591
+const HAVING = 57592
+const HASH = 57593
+const HEADER = 57594
+const HIGH = 57595
+const HISTOGRAM = 57596
+const HOLD = 57597
+const HOUR = 57598
+const IDENTITY = 57599
+const IF = 57600
+const IFERROR = 57601
+const IFNULL = 57602
+const IGNORE_FOREIGN_KEYS = 57603
+const ILIKE = 57604
+const IMMEDIATE = 57605
+const IMMEDIATELY = 57606
+const IMMUTABLE = 57607
+const IMPORT = 57608
+const IN = 57609
+const INCLUDE = 57610
+const INCLUDING = 57611
+const INCLUDE_ALL_SECONDARY_TENANTS = 57612
+const INCLUDE_ALL_VIRTUAL_CLUSTERS = 57613
+const INCREMENT = 57614
+const INCREMENTAL = 57615
+const INCREMENTAL_LOCATION = 57616
+const INET = 57617
+const INET_CONTAINED_BY_OR_EQUALS = 57618
+const INET_CONTAINS_OR_EQUALS = 57619
+const INDEX = 57620
+const INDEXES = 57621
+const INHERITS = 57622
+const INJECT = 57623
+const INITIALLY = 57624
+const INDEX_BEFORE_PAREN = 57625
+const INDEX_BEFORE_NAME_THEN_PAREN = 57626
+const INDEX_AFTER_ORDER_BY_BEFORE_AT = 57627
+const INNER = 57628
+const INOUT = 57629
+const INPUT = 57630
+const INSENSITIVE = 57631
+const INSERT = 57632
+const INSTEAD = 57633
+const INT = 57634
+const INTEGER = 57635
+const INTERSECT = 57636
+const INTERVAL = 57637
+const INTO = 57638
+const INTO_DB = 57639
+const INVERTED = 57640
+const INVOKER = 57641
+const IS = 57642
+const ISERROR = 57643
+const ISNULL = 57644
+const ISOLATION = 57645
+const JOB = 57646
+const JOBS = 57647
+const JOIN = 57648
+const JSON = 57649
+const JSONB = 57650
+const JSON_SOME_EXISTS = 57651
+const JSON_ALL_EXISTS = 57652
+const KEY = 57653
+const KEYS = 57654
+const KMS = 57655
+const KV = 57656
+const LABEL = 57657
+const LANGUAGE = 57658
+const LAST = 57659
+const LATERAL = 57660
+const LATEST = 57661
+const LC_CTYPE = 57662
+const LC_COLLATE = 57663
+const LEADING = 57664
+const LEASE = 57665
+const LEAST = 57666
+const LEAKPROOF = 57667
+const LEFT = 57668
+const LESS = 57669
+const LEVEL = 57670
+const LIKE = 57671
+const LIMIT = 57672
+const LINESTRING = 57673
+const LINESTRINGM = 57674
+const LINESTRINGZ = 57675
+const LINESTRINGZM = 57676
+const LIST = 57677
+const LOCAL = 57678
+const LOCALITY = 57679
+const LOCALTIME = 57680
+const LOCALTIMESTAMP = 57681
+const LOCKED = 57682
+const LOGICAL = 57683
+const LOGICALLY = 57684
+const LOGIN = 57685
+const LOOKUP = 57686
+const LOW = 57687
+const LSHIFT = 57688
+const MATCH = 57689
+const MATERIALIZED = 57690
+const MERGE = 57691
+const MINVALUE = 57692
+const MAXVALUE = 57693
+const METHOD = 57694
+const MINUTE = 57695
+const MODIFYCLUSTERSETTING = 57696
+const MODIFYSQLCLUSTERSETTING = 57697
+const MODE = 57698
+const MONTH = 57699
+const MOVE = 57700
+const MULTILINESTRING = 57701
+const MULTILINESTRINGM = 57702
+const MULTILINESTRINGZ = 57703
+const MULTILINESTRINGZM = 57704
+const MULTIPOINT = 57705
+const MULTIPOINTM = 57706
+const MULTIPOINTZ = 57707
+const MULTIPOINTZM = 57708
+const MULTIPOLYGON = 57709
+const MULTIPOLYGONM = 57710
+const MULTIPOLYGONZ = 57711
+const MULTIPOLYGONZM = 57712
+const NAN = 57713
+const NAME = 57714
+const NAMES = 57715
+const NATURAL = 57716
+const NEG_INNER_PRODUCT = 57717
+const NEVER = 57718
+const NEW = 57719
+const NEW_DB_NAME = 57720
+const NEW_KMS = 57721
+const NEXT = 57722
+const NO = 57723
+const NOBYPASSRLS = 57724
+const NOCANCELQUERY = 57725
+const NOCONTROLCHANGEFEED = 57726
+const NOCONTROLJOB = 57727
+const NOCREATEDB = 57728
+const NOCREATELOGIN = 57729
+const NOCREATEROLE = 57730
+const NODE = 57731
+const NOLOGIN = 57732
+const NOMODIFYCLUSTERSETTING = 57733
+const NOREPLICATION = 57734
+const NOSQLLOGIN = 57735
+const NO_INDEX_JOIN = 57736
+const NO_ZIGZAG_JOIN = 57737
+const NO_FULL_SCAN = 57738
+const NONE = 57739
+const NONVOTERS = 57740
+const NORMAL = 57741
+const NOT = 57742
+const NOTHING = 57743
+const NOTHING_AFTER_RETURNING = 57744
+const NOTNULL = 57745
+const NOVIEWACTIVITY = 57746
+const NOVIEWACTIVITYREDACTED = 57747
+const NOVIEWCLUSTERSETTING = 57748
+const NOWAIT = 57749
+const NULL = 57750
+const NULLIF = 57751
+const NULLS = 57752
+const NUMERIC = 57753
+const OF = 57754
+const OFF = 57755
+const OFFSET = 57756
+const OID = 57757
+const OIDS = 57758
+const OIDVECTOR = 57759
+const OLD = 57760
+const OLD_KMS = 57761
+const ON = 57762
+const ONLY = 57763
+const OPT = 57764
+const OPTION = 57765
+const OPTIONS = 57766
+const OR = 57767
+const ORDER = 57768
+const ORDINALITY = 57769
+const OTHERS = 57770
+const OUT = 57771
+const OUTER = 57772
+const OVER = 57773
+const OVERLAPS = 57774
+const OVERLAY = 57775
+const OWNED = 57776
+const OWNER = 57777
+const OPERATOR = 57778
+const PARALLEL = 57779
+const PARENT = 57780
+const PARTIAL = 57781
+const PARTITION = 57782
+const PARTITIONS = 57783
+const PASSWORD = 57784
+const PAUSE = 57785
+const PAUSED = 57786
+const PER = 57787
+const PERMISSIVE = 57788
+const PHYSICAL = 57789
+const PLACEMENT = 57790
+const PLACING = 57791
+const PLAN = 57792
+const PLANS = 57793
+const POINT = 57794
+const POINTM = 57795
+const POINTZ = 57796
+const POINTZM = 57797
+const POLICIES = 57798
+const POLICY = 57799
+const POLYGON = 57800
+const POLYGONM = 57801
+const POLYGONZ = 57802
+const POLYGONZM = 57803
+const POSITION = 57804
+const PRECEDING = 57805
+const PRECISION = 57806
+const PREPARE = 57807
+const PREPARED = 57808
+const PRESERVE = 57809
+const PRIMARY = 57810
+const PRIOR = 57811
+const PRIORITY = 57812
+const PRIVILEGES = 57813
+const PROCEDURAL = 57814
+const PROCEDURE = 57815
+const PROCEDURES = 57816
+const PUBLIC = 57817
+const PUBLICATION = 57818
+const QUERIES = 57819
+const QUERY = 57820
+const QUOTE = 57821
+const RANGE = 57822
+const RANGES = 57823
+const READ = 57824
+const REAL = 57825
+const REASON = 57826
+const REASSIGN = 57827
+const RECURSIVE = 57828
+const RECURRING = 57829
+const REDACT = 57830
+const REF = 57831
+const REFERENCES = 57832
+const REFERENCING = 57833
+const REFRESH = 57834
+const REGCLASS = 57835
+const REGION = 57836
+const REGIONAL = 57837
+const REGIONS = 57838
+const REGNAMESPACE = 57839
+const REGPROC = 57840
+const REGPROCEDURE = 57841
+const REGROLE = 57842
+const REGTYPE = 57843
+const REINDEX = 57844
+const RELATIVE = 57845
+const RELOCATE = 57846
+const REMOVE_PATH = 57847
+const REMOVE_REGIONS = 57848
+const RENAME = 57849
+const REPEATABLE = 57850
+const REPLACE = 57851
+const REPLICATED = 57852
+const REPLICATION = 57853
+const RELEASE = 57854
+const RESET = 57855
+const RESTART = 57856
+const RESTORE = 57857
+const RESTRICT = 57858
+const RESTRICTED = 57859
+const RESTRICTIVE = 57860
+const RESUME = 57861
+const RETENTION = 57862
+const RETURNING = 57863
+const RETURN = 57864
+const RETURNS = 57865
+const RETRY = 57866
+const REVISION_HISTORY = 57867
+const REVOKE = 57868
+const RIGHT = 57869
+const ROLE = 57870
+const ROLES = 57871
+const ROLLBACK = 57872
+const ROLLUP = 57873
+const ROUTINES = 57874
+const ROW = 57875
+const ROWS = 57876
+const RSHIFT = 57877
+const RULE = 57878
+const RUNNING = 57879
+const SAVEPOINT = 57880
+const SCANS = 57881
+const SCATTER = 57882
+const SCHEDULE = 57883
+const SCHEDULES = 57884
+const SCROLL = 57885
+const SCHEMA = 57886
+const SCHEMA_ONLY = 57887
+const SCHEMAS = 57888
+const SCRUB = 57889
+const SEARCH = 57890
+const SECOND = 57891
+const SECONDARY = 57892
+const SECURITY = 57893
+const SELECT = 57894
+const SEQUENCE = 57895
+const SEQUENCES = 57896
+const SERIALIZABLE = 57897
+const SERVER = 57898
+const SERVICE = 57899
+const SESSION = 57900
+const SESSIONS = 57901
+const SESSION_USER = 57902
+const SET = 57903
+const SETOF = 57904
+const SETS = 57905
+const SETTING = 57906
+const SETTINGS = 57907
+const SHARE = 57908
+const SHARED = 57909
+const SHOW = 57910
+const SIMILAR = 57911
+const SIMPLE = 57912
+const SIZE = 57913
+const SKIP = 57914
+const SKIP_LOCALITIES_CHECK = 57915
+const SKIP_MISSING_FOREIGN_KEYS = 57916
+const SKIP_MISSING_SEQUENCES = 57917
+const SKIP_MISSING_SEQUENCE_OWNERS = 57918
+const SKIP_MISSING_VIEWS = 57919
+const SKIP_MISSING_UDFS = 57920
+const SMALLINT = 57921
+const SMALLSERIAL = 57922
+const SNAPSHOT = 57923
+const SOME = 57924
+const SOURCE = 57925
+const SPLIT = 57926
+const SQL = 57927
+const SQLLOGIN = 57928
+const STABLE = 57929
+const START = 57930
+const STATE = 57931
+const STATEMENT = 57932
+const STATISTICS = 57933
+const STATUS = 57934
+const STDIN = 57935
+const STDOUT = 57936
+const STOP = 57937
+const STRAIGHT = 57938
+const STREAM = 57939
+const STRICT = 57940
+const STRING = 57941
+const STORAGE = 57942
+const STORE = 57943
+const STORED = 57944
+const STORING = 57945
+const SUBJECT = 57946
+const SUBSTRING = 57947
+const SUPER = 57948
+const SUPPORT = 57949
+const SURVIVE = 57950
+const SURVIVAL = 57951
+const SYMMETRIC = 57952
+const SYNTAX = 57953
+const SYSTEM = 57954
+const SQRT = 57955
+const SUBSCRIPTION = 57956
+const STATEMENTS = 57957
+const TABLE = 57958
+const TABLES = 57959
+const TABLESPACE = 57960
+const TEMP = 57961
+const TEMPLATE = 57962
+const TEMPORARY = 57963
+const TENANT = 57964
+const TENANT_NAME = 57965
+const TENANTS = 57966
+const TESTING_RELOCATE = 57967
+const TEXT = 57968
+const THEN = 57969
+const TIES = 57970
+const TIME = 57971
+const TIMETZ = 57972
+const TIMESTAMP = 57973
+const TIMESTAMPTZ = 57974
+const TO = 57975
+const THROTTLING = 57976
+const TRAILING = 57977
+const TRACE = 57978
+const TRANSACTION = 57979
+const TRANSACTIONS = 57980
+const TRANSFER = 57981
+const TRANSFORM = 57982
+const TREAT = 57983
+const TRIGGER = 57984
+const TRIGGERS = 57985
+const TRIM = 57986
+const TRUE = 57987
+const TRUNCATE = 57988
+const TRUSTED = 57989
+const TYPE = 57990
+const TYPES = 57991
+const TRACING = 57992
+const UNBOUNDED = 57993
+const UNCOMMITTED = 57994
+const UNIDIRECTIONAL = 57995
+const UNION = 57996
+const UNIQUE = 57997
+const UNKNOWN = 57998
+const UNLISTEN = 57999
+const UNLOGGED = 58000
+const UNSAFE_RESTORE_INCOMPATIBLE_VERSION = 58001
+const UNSPLIT = 58002
+const UPDATE = 58003
+const UPDATES_CLUSTER_MONITORING_METRICS = 58004
+const UPSERT = 58005
+const UNSET = 58006
+const UNTIL = 58007
+const USE = 58008
+const USER = 58009
+const USERS = 58010
+const USING = 58011
+const UUID = 58012
+const VALID = 58013
+const VALIDATE = 58014
+const VALUE = 58015
+const VALUES = 58016
+const VARBIT = 58017
+const VARCHAR = 58018
+const VARIADIC = 58019
+const VECTOR = 58020
+const VERIFY_BACKUP_TABLE_DATA = 58021
+const VIEW = 58022
+const VARIABLES = 58023
+const VARYING = 58024
+const VIEWACTIVITY = 58025
+const VIEWACTIVITYREDACTED = 58026
+const VIEWDEBUG = 58027
+const VIEWCLUSTERMETADATA = 58028
+const VIEWCLUSTERSETTING = 58029
+const VIRTUAL = 58030
+const VISIBLE = 58031
+const INVISIBLE = 58032
+const VISIBILITY = 58033
+const VOLATILE = 58034
+const VOTERS = 58035
+const VIRTUAL_CLUSTER_NAME = 58036
+const VIRTUAL_CLUSTER = 58037
+const WHEN = 58038
+const WHERE = 58039
+const WINDOW = 58040
+const WITH = 58041
+const WITHIN = 58042
+const WITHOUT = 58043
+const WORK = 58044
+const WRITE = 58045
+const YEAR = 58046
+const ZONE = 58047
+const NOT_LA = 58048
+const NULLS_LA = 58049
+const WITH_LA = 58050
+const AS_LA = 58051
+const GENERATED_ALWAYS = 58052
+const GENERATED_BY_DEFAULT = 58053
+const RESET_ALL = 58054
+const ROLE_ALL = 58055
+const USER_ALL = 58056
+const ON_LA = 58057
+const TENANT_ALL = 58058
+const CLUSTER_ALL = 58059
+const SET_TRACING = 58060
+const CONTAINED_BY = 58061
+const POSTFIXOP = 58062
+const INTERVAL_SIMPLE = 58063
+const UMINUS = 58064
+const HELPTOKEN = 58065
diff --git a/pkg/sql/oidext/oidext.go b/pkg/sql/oidext/oidext.go
index ac7da45..b629a94 100644
--- a/pkg/sql/oidext/oidext.go
+++ b/pkg/sql/oidext/oidext.go
@@ -1,12 +1,7 @@
 // Copyright 2020 The Cockroach Authors.
 //
-// Use of this software is governed by the Business Source License
-// included in the file licenses/BSL.txt.
-//
-// As of the Change Date specified in that file, in accordance with
-// the Business Source License, use of this software will be governed
-// by the Apache License, Version 2.0, included in the file
-// licenses/APL.txt.
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
 
 // Package oidext contains oids that are not in `github.com/lib/pq/oid`
 // as they are not shipped by default with postgres.
@@ -34,6 +29,15 @@ const (
 	T__geography = oid.Oid(90003)
 	T_box2d      = oid.Oid(90004)
 	T__box2d     = oid.Oid(90005)
+	T_pgvector   = oid.Oid(90006)
+	T__pgvector  = oid.Oid(90007)
+)
+
+// OIDs in this block are not extensions of postgres, but are not supported in
+// github.com/lib/pq/oid. See postgres/src/include/catalog/pg_type.dat for oids.
+const (
+	T_jsonpath  = oid.Oid(4072)
+	T__jsonpath = oid.Oid(4073)
 )
 
 // ExtensionTypeName returns a mapping from extension oids
@@ -45,6 +49,10 @@ var ExtensionTypeName = map[oid.Oid]string{
 	T__geography: "_GEOGRAPHY",
 	T_box2d:      "BOX2D",
 	T__box2d:     "_BOX2D",
+	T_pgvector:   "VECTOR",
+	T__pgvector:  "_VECTOR",
+	T_jsonpath:   "JSONPATH",
+	T__jsonpath:  "_JSONPATH",
 }
 
 // TypeName checks the name for a given type by first looking up oid.TypeName
diff --git a/pkg/sql/parser/help.go b/pkg/sql/parser/help.go
index 8a0cf32..d6b1b33 100644
--- a/pkg/sql/parser/help.go
+++ b/pkg/sql/parser/help.go
@@ -1,12 +1,7 @@
 // Copyright 2017 The Cockroach Authors.
 //
-// Use of this software is governed by the Business Source License
-// included in the file licenses/BSL.txt.
-//
-// As of the Change Date specified in that file, in accordance with
-// the Business Source License, use of this software will be governed
-// by the Apache License, Version 2.0, included in the file
-// licenses/APL.txt.
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
 
 // Package parser contains exposes a SQL parser for cockroach.
 package parser
diff --git a/pkg/sql/parser/help_gen_test.sh b/pkg/sql/parser/help_gen_test.sh
index 702efbc..2a58fac 100755
--- a/pkg/sql/parser/help_gen_test.sh
+++ b/pkg/sql/parser/help_gen_test.sh
@@ -1,5 +1,11 @@
 #!/usr/bin/env bash
 
+# Copyright 2017 The Cockroach Authors.
+#
+# Use of this software is governed by the CockroachDB Software License
+# included in the /LICENSE file.
+
+
 # Trigger this script by running `make generate PKG=./pkg/sql/parser` from the
 # repository root to ensure your PATH includes vendored binaries.
 
diff --git a/pkg/sql/parser/help_messages.go b/pkg/sql/parser/help_messages.go
index 43366f7..f2c4944 100644
--- a/pkg/sql/parser/help_messages.go
+++ b/pkg/sql/parser/help_messages.go
@@ -4,20 +4,20 @@
 package parser
 
 var helpMessages = map[string]HelpMessageBody{
-  //line sql.y: 1817
+  //line sql.y: 1925
   `ALTER`: {
-    //line sql.y: 1818
+    //line sql.y: 1926
     Category: hGroup,
-    //line sql.y: 1819
+    //line sql.y: 1927
     Text: `ALTER TABLE, ALTER INDEX, ALTER VIEW, ALTER SEQUENCE, ALTER DATABASE, ALTER USER, ALTER ROLE, ALTER DEFAULT PRIVILEGES
 `,
   },
-  //line sql.y: 1844
+  //line sql.y: 1954
   `ALTER TABLE`: {
     ShortDescription: `change the definition of a table`,
-    //line sql.y: 1845
+    //line sql.y: 1955
     Category: hDDL,
-    //line sql.y: 1846
+    //line sql.y: 1956
     Text: `
 ALTER TABLE [IF EXISTS] <tablename> <command> [, ...]
 
@@ -30,6 +30,10 @@ Commands:
   ALTER TABLE ... ALTER [COLUMN] <colname> {SET ON UPDATE <expr> | DROP ON UPDATE}
   ALTER TABLE ... ALTER [COLUMN] <colname> DROP NOT NULL
   ALTER TABLE ... ALTER [COLUMN] <colname> DROP STORED
+  ALTER TABLE ... ALTER [COLUMN] <colname> ADD GENERATED { ALWAYS | BY DEFAULT } AS IDENTITY [ ( opt_sequence_option_list ) ]
+  ALTER TABLE ... ALTER [COLUMN] <colname> SET GENERATED { ALWAYS | BY DEFAULT }
+  ALTER TABLE ... ALTER [COLUMN] <colname> <identity_option_list>
+  ALTER TABLE ... ALTER [COLUMN] <colname> DROP IDENTITY [ IF EXISTS ]
   ALTER TABLE ... ALTER [COLUMN] <colname> [SET DATA] TYPE <type> [COLLATE <collation>]
   ALTER TABLE ... ALTER PRIMARY KEY USING COLUMNS ( <colnames...> )
   ALTER TABLE ... RENAME TO <newname>
@@ -48,6 +52,7 @@ Commands:
   ALTER TABLE ... CONFIGURE ZONE <zoneconfig>
   ALTER TABLE ... SET SCHEMA <newschemaname>
   ALTER TABLE ... SET LOCALITY [REGIONAL BY [TABLE IN <region> | ROW] | GLOBAL]
+  ALTER TABLE ... {ENABLE | DISABLE | FORCE | NO FORCE} ROW LEVEL SECURITY
 
 Column qualifiers:
   [CONSTRAINT <constraintname>] {NULL | NOT NULL | UNIQUE | PRIMARY KEY | CHECK (<expr>) | DEFAULT <expr>}
@@ -62,16 +67,16 @@ Zone configurations:
   { TO | = } <expr>
 
 `,
-    //line sql.y: 1889
+    //line sql.y: 2004
     SeeAlso: `WEBDOCS/alter-table.html
 `,
   },
-  //line sql.y: 1905
+  //line sql.y: 2020
   `ALTER PARTITION`: {
     ShortDescription: `apply zone configurations to a partition`,
-    //line sql.y: 1906
+    //line sql.y: 2021
     Category: hDDL,
-    //line sql.y: 1907
+    //line sql.y: 2022
     Text: `
 ALTER PARTITION <name> <command>
 
@@ -92,30 +97,30 @@ Zone configurations:
   { TO | = } <expr>
 
 `,
-    //line sql.y: 1926
-    SeeAlso: `WEBDOCS/configure-zone.html
+    //line sql.y: 2041
+    SeeAlso: `WEBDOCS/alter-partition.html
 `,
   },
-  //line sql.y: 1931
+  //line sql.y: 2046
   `ALTER VIEW`: {
     ShortDescription: `change the definition of a view`,
-    //line sql.y: 1932
+    //line sql.y: 2047
     Category: hDDL,
-    //line sql.y: 1933
+    //line sql.y: 2048
     Text: `
 ALTER [MATERIALIZED] VIEW [IF EXISTS] <name> RENAME TO <newname>
 ALTER [MATERIALIZED] VIEW [IF EXISTS] <name> SET SCHEMA <newschemaname>
 `,
-    //line sql.y: 1936
+    //line sql.y: 2051
     SeeAlso: `WEBDOCS/alter-view.html
 `,
   },
-  //line sql.y: 1945
+  //line sql.y: 2060
   `ALTER SEQUENCE`: {
     ShortDescription: `change the definition of a sequence`,
-    //line sql.y: 1946
+    //line sql.y: 2061
     Category: hDDL,
-    //line sql.y: 1947
+    //line sql.y: 2062
     Text: `
 ALTER SEQUENCE [IF EXISTS] <name>
   [AS <typename>]
@@ -129,12 +134,12 @@ ALTER SEQUENCE [IF EXISTS] <name> RENAME TO <newname>
 ALTER SEQUENCE [IF EXISTS] <name> SET SCHEMA <newschemaname>
 `,
   },
-  //line sql.y: 1976
+  //line sql.y: 2091
   `ALTER DATABASE`: {
     ShortDescription: `change the definition of a database`,
-    //line sql.y: 1977
+    //line sql.y: 2092
     Category: hDDL,
-    //line sql.y: 1978
+    //line sql.y: 2093
     Text: `
 ALTER DATABASE <name> RENAME TO <newname>
 ALTER DATABASE <name> CONFIGURE ZONE <zone config>
@@ -149,16 +154,16 @@ ALTER DATABASE <name> SET var { TO | = } { value | DEFAULT }
 ALTER DATABASE <name> RESET { var | ALL }
 ALTER DATABASE <name> ALTER LOCALITY { GLOBAL | REGIONAL [IN <region>] } CONFIGURE ZONE <zone config>
 `,
-    //line sql.y: 1991
+    //line sql.y: 2106
     SeeAlso: `WEBDOCS/alter-database.html
 `,
   },
-  //line sql.y: 2010
+  //line sql.y: 2125
   `ALTER FUNCTION`: {
     ShortDescription: `change the definition of a function`,
-    //line sql.y: 2011
+    //line sql.y: 2126
     Category: hDDL,
-    //line sql.y: 2012
+    //line sql.y: 2127
     Text: `
 ALTER FUNCTION name [ ( [ [ argmode ] [ argname ] argtype [, ...] ] ) ]
    action [ ... ] [ RESTRICT ]
@@ -174,17 +179,18 @@ where action is one of:
    CALLED ON NULL INPUT | RETURNS NULL ON NULL INPUT | STRICT
    IMMUTABLE | STABLE | VOLATILE
    [ NOT ] LEAKPROOF
+   [ EXTERNAL ] SECURITY { INVOKER | DEFINER }
 `,
-    //line sql.y: 2027
+    //line sql.y: 2143
     SeeAlso: `WEBDOCS/alter-function.html
 `,
   },
-  //line sql.y: 2036
+  //line sql.y: 2152
   `ALTER PROCEDURE`: {
     ShortDescription: `change the definition of a procedure`,
-    //line sql.y: 2037
+    //line sql.y: 2153
     Category: hDDL,
-    //line sql.y: 2038
+    //line sql.y: 2154
     Text: `
 ALTER PROCEDURE name [ ( [ [ argmode ] [ argname ] argtype [, ...] ] ) ]
    RENAME TO new_name
@@ -194,16 +200,16 @@ ALTER PROCEDURE name [ ( [ [ argmode ] [ argname ] argtype [, ...] ] ) ]
    SET SCHEMA new_schema
 
 `,
-    //line sql.y: 2046
+    //line sql.y: 2162
     SeeAlso: `WEBDOCS/alter-procedure.html
 `,
   },
-  //line sql.y: 2240
+  //line sql.y: 2356
   `ALTER RANGE`: {
     ShortDescription: `change the parameters of a range`,
-    //line sql.y: 2241
+    //line sql.y: 2357
     Category: hDDL,
-    //line sql.y: 2242
+    //line sql.y: 2358
     Text: `
 ALTER RANGE <zonename> <command>
 
@@ -221,16 +227,16 @@ Zone configurations:
   { TO | = } <expr>
 
 `,
-    //line sql.y: 2258
+    //line sql.y: 2374
     SeeAlso: `ALTER TABLE
 `,
   },
-  //line sql.y: 2264
+  //line sql.y: 2380
   `ALTER INDEX`: {
     ShortDescription: `change the definition of an index`,
-    //line sql.y: 2265
+    //line sql.y: 2381
     Category: hDDL,
-    //line sql.y: 2266
+    //line sql.y: 2382
     Text: `
 ALTER INDEX [IF EXISTS] <idxname> <command>
 
@@ -250,16 +256,16 @@ Zone configurations:
   { TO | = } <expr>
 
 `,
-    //line sql.y: 2284
+    //line sql.y: 2400
     SeeAlso: `WEBDOCS/alter-index.html
 `,
   },
-  //line sql.y: 2986
+  //line sql.y: 3187
   `ALTER TYPE`: {
     ShortDescription: `change the definition of a type.`,
-    //line sql.y: 2987
+    //line sql.y: 3188
     Category: hDDL,
-    //line sql.y: 2988
+    //line sql.y: 3189
     Text: `ALTER TYPE <typename> <command>
 
 Commands:
@@ -277,26 +283,26 @@ Attribute action:
   ALTER ATTRIBUTE <name> [ SET DATA ] TYPE <type> [ COLLATE <collation> ] [ CASCADE | RESTRICT ]
 
 `,
-    //line sql.y: 3004
+    //line sql.y: 3205
     SeeAlso: `WEBDOCS/alter-type.html
 `,
   },
-  //line sql.y: 3153
+  //line sql.y: 3354
   `REFRESH`: {
     ShortDescription: `recalculate a materialized view`,
-    //line sql.y: 3154
+    //line sql.y: 3355
     Category: hMisc,
-    //line sql.y: 3155
+    //line sql.y: 3356
     Text: `
-REFRESH MATERIALIZED VIEW [CONCURRENTLY] view_name [WITH [NO] DATA]
+REFRESH MATERIALIZED VIEW [CONCURRENTLY] view_name [AS OF SYSTEM TIME <expr>>] [WITH [NO] DATA]
 `,
   },
-  //line sql.y: 3182
+  //line sql.y: 3384
   `BACKUP`: {
     ShortDescription: `back up data to external storage`,
-    //line sql.y: 3183
+    //line sql.y: 3385
     Category: hCCL,
-    //line sql.y: 3184
+    //line sql.y: 3386
     Text: `
 
 Create a full backup
@@ -333,16 +339,16 @@ Options:
    include_all_virtual_clusters: enable backups of all virtual clusters during a cluster backup
 
 `,
-    //line sql.y: 3219
+    //line sql.y: 3421
     SeeAlso: `RESTORE, WEBDOCS/backup.html
 `,
   },
-  //line sql.y: 3365
+  //line sql.y: 3559
   `CREATE SCHEDULE FOR BACKUP`: {
     ShortDescription: `backup data periodically`,
-    //line sql.y: 3366
+    //line sql.y: 3560
     Category: hCCL,
-    //line sql.y: 3367
+    //line sql.y: 3561
     Text: `
 CREATE SCHEDULE [IF NOT EXISTS]
 [<description>]
@@ -414,16 +420,16 @@ FULL BACKUP <crontab|ALWAYS>:
     objects.
 
 `,
-    //line sql.y: 3437
+    //line sql.y: 3631
     SeeAlso: `BACKUP
 `,
   },
-  //line sql.y: 3455
+  //line sql.y: 3649
   `ALTER BACKUP SCHEDULE`: {
     ShortDescription: `alter an existing backup schedule`,
-    //line sql.y: 3456
+    //line sql.y: 3650
     Category: hCCL,
-    //line sql.y: 3457
+    //line sql.y: 3651
     Text: `
 ALTER BACKUP SCHEDULE <id> <command> [, ...]
 
@@ -437,16 +443,16 @@ Commands:
 
 See CREATE SCHEDULE FOR BACKUP for detailed option descriptions.
 `,
-    //line sql.y: 3469
+    //line sql.y: 3663
     SeeAlso: `CREATE SCHEDULE FOR BACKUP
 `,
   },
-  //line sql.y: 3609
+  //line sql.y: 3811
   `CREATE EXTERNAL CONNECTION`: {
     ShortDescription: `create a new external connection`,
-    //line sql.y: 3610
+    //line sql.y: 3812
     Category: hMisc,
-    //line sql.y: 3611
+    //line sql.y: 3813
     Text: `
 CREATE EXTERNAL CONNECTION [IF NOT EXISTS] <name> AS <endpoint>
 
@@ -457,12 +463,25 @@ Endpoint:
   Endpoint of the resource that the external connection represents.
 `,
   },
-  //line sql.y: 3629
+  //line sql.y: 3831
+  `CHECK EXTERNAL CONNECTION`: {
+    ShortDescription: `check the status of an external connection`,
+    //line sql.y: 3832
+    Category: hMisc,
+    //line sql.y: 3833
+    Text: `
+CREATE EXTERNAL CONNECTION <uri> [WITH <options>]
+
+Uri:
+  Uri for the external connection.
+`,
+  },
+  //line sql.y: 3889
   `DROP EXTERNAL CONNECTION`: {
     ShortDescription: `drop an existing external connection`,
-    //line sql.y: 3630
+    //line sql.y: 3890
     Category: hMisc,
-    //line sql.y: 3631
+    //line sql.y: 3891
     Text: `
 DROP EXTERNAL CONNECTION <name>
 
@@ -470,12 +489,12 @@ Name:
   Unique name for this external connection.
 `,
   },
-  //line sql.y: 3645
+  //line sql.y: 3905
   `RESTORE`: {
     ShortDescription: `restore data from external storage`,
-    //line sql.y: 3646
+    //line sql.y: 3906
     Category: hCCL,
-    //line sql.y: 3647
+    //line sql.y: 3907
     Text: `
 RESTORE <targets...> FROM <location...>
         [ AS OF SYSTEM TIME <expr> ]
@@ -503,20 +522,19 @@ Options:
    kms="[kms_provider]://[kms_host]/[master_key_identifier]?[parameters]" : decrypt backups using KMS
    detached: execute restore job asynchronously, without waiting for its completion
    skip_localities_check: ignore difference of zone configuration between restore cluster and backup cluster
-   debug_pause_on: describes the events that the job should pause itself on for debugging purposes.
    new_db_name: renames the restored database. only applies to database restores
    include_all_virtual_clusters: enable backups of all virtual clusters during a cluster backup
 `,
-    //line sql.y: 3677
+    //line sql.y: 3936
     SeeAlso: `BACKUP, WEBDOCS/restore.html
 `,
   },
-  //line sql.y: 3905
+  //line sql.y: 4134
   `IMPORT`: {
     ShortDescription: `load data from file in a distributed manner`,
-    //line sql.y: 3906
+    //line sql.y: 4135
     Category: hCCL,
-    //line sql.y: 3907
+    //line sql.y: 4136
     Text: `
 -- Import both schema and table data:
 IMPORT [ TABLE <tablename> FROM ]
@@ -536,16 +554,16 @@ Use CREATE TABLE followed by IMPORT INTO to create and import into a table
 from external files that only have table data.
 
 `,
-    //line sql.y: 3925
+    //line sql.y: 4154
     SeeAlso: `CREATE TABLE, WEBDOCS/import-into.html
 `,
   },
-  //line sql.y: 3959
+  //line sql.y: 4188
   `EXPORT`: {
     ShortDescription: `export data to file in a distributed manner`,
-    //line sql.y: 3960
+    //line sql.y: 4189
     Category: hCCL,
-    //line sql.y: 3961
+    //line sql.y: 4190
     Text: `
 EXPORT INTO <format> <datafile> [WITH <option> [= value] [,...]] FROM <query>
 
@@ -557,131 +575,212 @@ Options:
    delimiter = '...'   [CSV-specific]
 
 `,
-    //line sql.y: 3971
+    //line sql.y: 4200
     SeeAlso: `SELECT
 `,
   },
-  //line sql.y: 4053
+  //line sql.y: 4272
   `CALL`: {
     ShortDescription: `invoke a procedure`,
-    //line sql.y: 4054
+    //line sql.y: 4273
     Category: hMisc,
-    //line sql.y: 4055
+    //line sql.y: 4274
     Text: `CALL <name> ( [ <expr> [, ...] ] )
 `,
-    //line sql.y: 4056
+    //line sql.y: 4275
     SeeAlso: `CREATE PROCEDURE
 `,
   },
-  //line sql.y: 4298
+  //line sql.y: 4517
   `CANCEL`: {
-    //line sql.y: 4299
+    //line sql.y: 4518
     Category: hGroup,
-    //line sql.y: 4300
+    //line sql.y: 4519
     Text: `CANCEL JOBS, CANCEL QUERIES, CANCEL SESSIONS
 `,
   },
-  //line sql.y: 4308
+  //line sql.y: 4527
   `CANCEL JOBS`: {
     ShortDescription: `cancel background jobs`,
-    //line sql.y: 4309
+    //line sql.y: 4528
     Category: hMisc,
-    //line sql.y: 4310
+    //line sql.y: 4529
     Text: `
 CANCEL JOBS <selectclause>
 CANCEL JOB <jobid>
 `,
-    //line sql.y: 4313
+    //line sql.y: 4532
     SeeAlso: `SHOW JOBS, PAUSE JOBS, RESUME JOBS
 `,
   },
-  //line sql.y: 4335
+  //line sql.y: 4554
   `CANCEL QUERIES`: {
     ShortDescription: `cancel running queries`,
-    //line sql.y: 4336
+    //line sql.y: 4555
     Category: hMisc,
-    //line sql.y: 4337
+    //line sql.y: 4556
     Text: `
 CANCEL QUERIES [IF EXISTS] <selectclause>
 CANCEL QUERY [IF EXISTS] <expr>
 `,
-    //line sql.y: 4340
+    //line sql.y: 4559
     SeeAlso: `SHOW STATEMENTS
 `,
   },
-  //line sql.y: 4371
+  //line sql.y: 4590
   `CANCEL SESSIONS`: {
     ShortDescription: `cancel open sessions`,
-    //line sql.y: 4372
+    //line sql.y: 4591
     Category: hMisc,
-    //line sql.y: 4373
+    //line sql.y: 4592
     Text: `
 CANCEL SESSIONS [IF EXISTS] <selectclause>
 CANCEL SESSION [IF EXISTS] <sessionid>
 `,
-    //line sql.y: 4376
+    //line sql.y: 4595
     SeeAlso: `SHOW SESSIONS
 `,
   },
-  //line sql.y: 4407
+  //line sql.y: 4626
   `CANCEL ALL JOBS`: {
     ShortDescription: `cancel all background jobs`,
-    //line sql.y: 4408
+    //line sql.y: 4627
     Category: hMisc,
-    //line sql.y: 4409
+    //line sql.y: 4628
     Text: `
 CANCEL ALL {BACKUP|CHANGEFEED|IMPORT|RESTORE} JOBS
 `,
   },
-  //line sql.y: 4472
+  //line sql.y: 4695
   `CREATE`: {
-    //line sql.y: 4473
+    //line sql.y: 4696
     Category: hGroup,
-    //line sql.y: 4474
+    //line sql.y: 4697
     Text: `
 CREATE DATABASE, CREATE TABLE, CREATE INDEX, CREATE TABLE AS,
 CREATE USER, CREATE VIEW, CREATE SEQUENCE, CREATE STATISTICS,
 CREATE ROLE, CREATE TYPE, CREATE EXTENSION, CREATE SCHEDULE
 `,
   },
-  //line sql.y: 4490
+  //line sql.y: 4714
+  `CHECK`: {
+    //line sql.y: 4715
+    Category: hGroup,
+    //line sql.y: 4716
+    Text: `
+CHECK EXTERNAL CONNECTION
+`,
+  },
+  //line sql.y: 4722
+  `CREATE LOGICAL REPLICATION STREAM`: {
+    ShortDescription: `create a new logical replication stream`,
+    //line sql.y: 4723
+    Category: hExperimental,
+    //line sql.y: 4724
+    Text: `
+CREATE LOGICAL REPLICATION STREAM
+ FROM <TABLE remote_name | TABLES (remote_name, ...) | DATABASE remote_name>
+ ON 'stream_uri'
+ INTO <TABLE remote_name | TABLES (remote_name, ...) | DATABASE remote_name>
+ [WITH
+ < MODE = immediate | validated > |
+ < CURSOR = start_time > |
+ < DEFAULT FUNCTION = lww | dlq | udf
+ < FUNCTION 'udf' FOR TABLE local_name  , ... > |
+ < DISCARD = 'ttl-deletes' >
+]
+`,
+  },
+  //line sql.y: 4911
   `CREATE VIRTUAL CLUSTER`: {
     ShortDescription: `create a new virtual cluster`,
-    //line sql.y: 4491
+    //line sql.y: 4912
     Category: hExperimental,
-    //line sql.y: 4492
+    //line sql.y: 4913
     Text: `
-CREATE VIRTUAL CLUSTER [ IF NOT EXISTS ] name [ LIKE <virtual_cluster_spec> ] [ <replication> ]
+CREATE VIRTUAL CLUSTER [ IF NOT EXISTS ] name [ <replication> ]
 
 Replication option:
-   FROM REPLICATION OF <virtual_cluster_spec> ON <location> [ WITH OPTIONS ... ]
+   FROM REPLICATION OF name ON <location> [ WITH OPTIONS ... ]
 `,
   },
-  //line sql.y: 4597
+  //line sql.y: 5020
   `CREATE SCHEDULE`: {
-    //line sql.y: 4598
+    //line sql.y: 5021
     Category: hGroup,
-    //line sql.y: 4599
+    //line sql.y: 5022
     Text: `
 CREATE SCHEDULE FOR BACKUP,
 CREATE SCHEDULE FOR CHANGEFEED
 `,
   },
-  //line sql.y: 4607
+  //line sql.y: 5030
   `CREATE EXTENSION`: {
     ShortDescription: `pseudo-statement for PostgreSQL compatibility`,
-    //line sql.y: 4608
+    //line sql.y: 5031
     Category: hCfg,
-    //line sql.y: 4609
+    //line sql.y: 5032
     Text: `CREATE EXTENSION [IF NOT EXISTS] name
 `,
   },
-  //line sql.y: 4627
+  //line sql.y: 5050
+  `ALTER POLICY`: {
+    ShortDescription: `alter an existing row-level security policy`,
+    //line sql.y: 5051
+    Category: hDDL,
+    //line sql.y: 5052
+    Text: `
+ALTER POLICY name ON table_name RENAME TO new_policy_name
+
+ALTER POLICY name ON table_name
+      [ TO { role_name | PUBLIC | CURRENT_USER | SESSION_USER } [, ...] ]
+      [ USING ( using_expression ) ]
+      [ WITH CHECK ( check_expression ) ]
+
+`,
+    //line sql.y: 5060
+    SeeAlso: `CREATE POLICY, DROP POLICY
+`,
+  },
+  //line sql.y: 5081
+  `CREATE POLICY`: {
+    ShortDescription: `define a new row-level security policy for a table`,
+    //line sql.y: 5082
+    Category: hDDL,
+    //line sql.y: 5083
+    Text: `
+CREATE POLICY [IF NOT EXISTS] name ON table_name
+    [ AS { PERMISSIVE | RESTRICTIVE } ]
+    [ FOR { ALL | SELECT | INSERT | UPDATE | DELETE } ]
+    [ TO { role_name | PUBLIC | CURRENT_USER | SESSION_USER } [, ...] ]
+    [ USING ( using_expression ) ]
+    [ WITH CHECK ( check_expression ) ]
+
+`,
+    //line sql.y: 5091
+    SeeAlso: `ALTER POLICY, DROP POLICY
+`,
+  },
+  //line sql.y: 5119
+  `DROP POLICY`: {
+    ShortDescription: `remove an existing row-level security policy from a table`,
+    //line sql.y: 5120
+    Category: hDDL,
+    //line sql.y: 5121
+    Text: `
+DROP POLICY [ IF EXISTS ] name ON table_name [ CASCADE | RESTRICT ]
+
+`,
+    //line sql.y: 5124
+    SeeAlso: `CREATE POLICY, ALTER POLICY
+`,
+  },
+  //line sql.y: 5244
   `CREATE FUNCTION`: {
     ShortDescription: `define a new function`,
-    //line sql.y: 4628
+    //line sql.y: 5245
     Category: hDDL,
-    //line sql.y: 4629
+    //line sql.y: 5246
     Text: `
 CREATE [ OR REPLACE ] FUNCTION
    name ( [ [ argmode ] [ argname ] argtype [, ...] ] )
@@ -691,18 +790,19 @@ CREATE [ OR REPLACE ] FUNCTION
    | [ NOT ] LEAKPROOF
    | { CALLED ON NULL INPUT | RETURNS NULL ON NULL INPUT | STRICT }
    | AS 'definition'
+   | { [ EXTERNAL ] SECURITY { INVOKER | DEFINER } }
  } ...
 `,
-    //line sql.y: 4639
+    //line sql.y: 5257
     SeeAlso: `WEBDOCS/create-function.html
 `,
   },
-  //line sql.y: 4661
+  //line sql.y: 5324
   `CREATE PROCEDURE`: {
     ShortDescription: `define a new procedure`,
-    //line sql.y: 4662
+    //line sql.y: 5325
     Category: hDDL,
-    //line sql.y: 4663
+    //line sql.y: 5326
     Text: `
 CREATE [ OR REPLACE ] PROCEDURE
    name ( [ [ argmode ] [ argname ] argtype [, ...] ] )
@@ -710,56 +810,91 @@ CREATE [ OR REPLACE ] PROCEDURE
    | AS 'definition'
  } ...
 `,
-    //line sql.y: 4669
+    //line sql.y: 5332
     SeeAlso: `WEBDOCS/create-procedure.html
 `,
   },
-  //line sql.y: 4933
+  //line sql.y: 5609
+  `DO`: {
+    ShortDescription: `execute an anonymous code block`,
+    //line sql.y: 5610
+    Category: hMisc,
+    //line sql.y: 5611
+    Text: `
+DO [LANGUAGE lang_name] code
+`,
+  },
+  //line sql.y: 5648
   `DROP FUNCTION`: {
     ShortDescription: `remove a function`,
-    //line sql.y: 4934
+    //line sql.y: 5649
     Category: hDDL,
-    //line sql.y: 4935
+    //line sql.y: 5650
     Text: `
 DROP FUNCTION [ IF EXISTS ] name [ ( [ [ argmode ] [ argname ] argtype [, ...] ] ) ] [, ...]
    [ CASCADE | RESTRICT ]
 `,
-    //line sql.y: 4938
+    //line sql.y: 5653
     SeeAlso: `WEBDOCS/drop-function.html
 `,
   },
-  //line sql.y: 4957
+  //line sql.y: 5672
   `DROP PROCEDURE`: {
     ShortDescription: `remove a procedure`,
-    //line sql.y: 4958
+    //line sql.y: 5673
     Category: hDDL,
-    //line sql.y: 4959
+    //line sql.y: 5674
     Text: `
 DROP PROCEDURE [ IF EXISTS ] name [ ( [ [ argmode ] [ argname ] argtype [, ...] ] ) ] [, ...]
    [ CASCADE | RESTRICT ]
 `,
-    //line sql.y: 4962
+    //line sql.y: 5677
     SeeAlso: `WEBDOCS/drop-procedure.html
 `,
   },
-  //line sql.y: 5189
+  //line sql.y: 5843
+  `CREATE TRIGGER`: {
+    ShortDescription: `define a new trigger`,
+    //line sql.y: 5844
+    Category: hDDL,
+    //line sql.y: 5845
+    Text: `
+CREATE [ OR REPLACE ] TRIGGER name { BEFORE | AFTER | INSTEAD OF }
+ { INSERT | DELETE | UPDATE [ OF column_name [, ...] ] | TRUNCATE | UPSERT }
+ ON table_name [ REFERENCING { NEW | OLD } TABLE [ AS ] table_alias_name [...] ]
+ [ FOR { EACH ROW | EACH STATEMENT } ]
+ [ WHEN a_expr ]
+ EXECUTE FUNCTION func_name ( trigger_func_args )
+`,
+  },
+  //line sql.y: 6030
+  `DROP TRIGGER`: {
+    ShortDescription: `remove a trigger`,
+    //line sql.y: 6031
+    Category: hDDL,
+    //line sql.y: 6032
+    Text: `
+DROP TRIGGER [ IF EXISTS ] name ON table_name [ CASCADE | RESTRICT ]
+`,
+  },
+  //line sql.y: 6115
   `CREATE STATISTICS`: {
     ShortDescription: `create a new table statistic`,
-    //line sql.y: 5190
+    //line sql.y: 6116
     Category: hMisc,
-    //line sql.y: 5191
+    //line sql.y: 6117
     Text: `
 CREATE STATISTICS <statisticname>
   [ON <colname> [, ...]]
   FROM <tablename> [AS OF SYSTEM TIME <expr>]
 `,
   },
-  //line sql.y: 5291
+  //line sql.y: 6217
   `CREATE CHANGEFEED`: {
     ShortDescription: `create change data capture`,
-    //line sql.y: 5292
+    //line sql.y: 6218
     Category: hCCL,
-    //line sql.y: 5293
+    //line sql.y: 6219
     Text: `
 CREATE CHANGEFEED
 FOR <targets> [INTO sink] [WITH <options>]
@@ -767,12 +902,12 @@ FOR <targets> [INTO sink] [WITH <options>]
 sink: data capture stream destination (Enterprise only)
 `,
   },
-  //line sql.y: 5335
+  //line sql.y: 6261
   `CREATE SCHEDULE FOR CHANGEFEED`: {
     ShortDescription: `create changefeed periodically`,
-    //line sql.y: 5336
+    //line sql.y: 6262
     Category: hCCL,
-    //line sql.y: 5337
+    //line sql.y: 6263
     Text: `
 CREATE SCHEDULE [IF NOT EXISTS]
 [<description>]
@@ -796,16 +931,16 @@ RECURRING <crontab>:
 
 sink: data capture stream destination (Enterprise only)
 `,
-    //line sql.y: 5359
+    //line sql.y: 6285
     SeeAlso: `CREATE CHANGEFEED
 `,
   },
-  //line sql.y: 5458
+  //line sql.y: 6384
   `DELETE`: {
     ShortDescription: `delete rows from a table`,
-    //line sql.y: 5459
+    //line sql.y: 6385
     Category: hDML,
-    //line sql.y: 5460
+    //line sql.y: 6386
     Text: `
 DELETE
    [BATCH [SIZE <expr>]]
@@ -816,148 +951,148 @@ DELETE
    [LIMIT <expr>]
    [RETURNING <exprs...>]
 `,
-    //line sql.y: 5469
+    //line sql.y: 6395
     SeeAlso: `WEBDOCS/delete.html
 `,
   },
-  //line sql.y: 5527
+  //line sql.y: 6453
   `DISCARD`: {
     ShortDescription: `reset the session to its initial state`,
-    //line sql.y: 5528
+    //line sql.y: 6454
     Category: hCfg,
-    //line sql.y: 5529
+    //line sql.y: 6455
     Text: `DISCARD ALL
 `,
   },
-  //line sql.y: 5550
+  //line sql.y: 6476
   `DROP`: {
-    //line sql.y: 5551
+    //line sql.y: 6477
     Category: hGroup,
-    //line sql.y: 5552
+    //line sql.y: 6478
     Text: `
 DROP DATABASE, DROP INDEX, DROP TABLE, DROP VIEW, DROP SEQUENCE,
 DROP USER, DROP ROLE, DROP TYPE
 `,
   },
-  //line sql.y: 5575
+  //line sql.y: 6503
   `DROP VIEW`: {
     ShortDescription: `remove a view`,
-    //line sql.y: 5576
+    //line sql.y: 6504
     Category: hDDL,
-    //line sql.y: 5577
+    //line sql.y: 6505
     Text: `DROP [MATERIALIZED] VIEW [IF EXISTS] <tablename> [, ...] [CASCADE | RESTRICT]
 `,
-    //line sql.y: 5578
+    //line sql.y: 6506
     SeeAlso: `WEBDOCS/drop-index.html
 `,
   },
-  //line sql.y: 5608
+  //line sql.y: 6536
   `DROP SEQUENCE`: {
     ShortDescription: `remove a sequence`,
-    //line sql.y: 5609
+    //line sql.y: 6537
     Category: hDDL,
-    //line sql.y: 5610
+    //line sql.y: 6538
     Text: `DROP SEQUENCE [IF EXISTS] <sequenceName> [, ...] [CASCADE | RESTRICT]
 `,
-    //line sql.y: 5611
+    //line sql.y: 6539
     SeeAlso: `DROP
 `,
   },
-  //line sql.y: 5623
+  //line sql.y: 6551
   `DROP TABLE`: {
     ShortDescription: `remove a table`,
-    //line sql.y: 5624
+    //line sql.y: 6552
     Category: hDDL,
-    //line sql.y: 5625
+    //line sql.y: 6553
     Text: `DROP TABLE [IF EXISTS] <tablename> [, ...] [CASCADE | RESTRICT]
 `,
-    //line sql.y: 5626
+    //line sql.y: 6554
     SeeAlso: `WEBDOCS/drop-table.html
 `,
   },
-  //line sql.y: 5638
+  //line sql.y: 6566
   `DROP INDEX`: {
     ShortDescription: `remove an index`,
-    //line sql.y: 5639
+    //line sql.y: 6567
     Category: hDDL,
-    //line sql.y: 5640
+    //line sql.y: 6568
     Text: `DROP INDEX [CONCURRENTLY] [IF EXISTS] <idxname> [, ...] [CASCADE | RESTRICT]
 `,
-    //line sql.y: 5641
+    //line sql.y: 6569
     SeeAlso: `WEBDOCS/drop-index.html
 `,
   },
-  //line sql.y: 5663
+  //line sql.y: 6591
   `DROP DATABASE`: {
     ShortDescription: `remove a database`,
-    //line sql.y: 5664
+    //line sql.y: 6592
     Category: hDDL,
-    //line sql.y: 5665
+    //line sql.y: 6593
     Text: `DROP DATABASE [IF EXISTS] <databasename> [CASCADE | RESTRICT]
 `,
-    //line sql.y: 5666
+    //line sql.y: 6594
     SeeAlso: `WEBDOCS/drop-database.html
 `,
   },
-  //line sql.y: 5686
+  //line sql.y: 6614
   `DROP TYPE`: {
     ShortDescription: `remove a type`,
-    //line sql.y: 5687
+    //line sql.y: 6615
     Category: hDDL,
-    //line sql.y: 5688
+    //line sql.y: 6616
     Text: `DROP TYPE [IF EXISTS] <type_name> [, ...] [CASCASE | RESTRICT]
 `,
   },
-  //line sql.y: 5708
+  //line sql.y: 6636
   `DROP VIRTUAL CLUSTER`: {
     ShortDescription: `remove a virtual cluster`,
-    //line sql.y: 5709
+    //line sql.y: 6637
     Category: hExperimental,
-    //line sql.y: 5710
+    //line sql.y: 6638
     Text: `DROP VIRTUAL CLUSTER [IF EXISTS] <virtual_cluster_spec> [IMMEDIATE]
 `,
   },
-  //line sql.y: 5754
+  //line sql.y: 6682
   `DROP SCHEMA`: {
     ShortDescription: `remove a schema`,
-    //line sql.y: 5755
+    //line sql.y: 6683
     Category: hDDL,
-    //line sql.y: 5756
+    //line sql.y: 6684
     Text: `DROP SCHEMA [IF EXISTS] <schema_name> [, ...] [CASCADE | RESTRICT]
 `,
   },
-  //line sql.y: 5776
+  //line sql.y: 6704
   `DROP ROLE`: {
     ShortDescription: `remove a user`,
-    //line sql.y: 5777
+    //line sql.y: 6705
     Category: hPriv,
-    //line sql.y: 5778
+    //line sql.y: 6706
     Text: `DROP ROLE [IF EXISTS] <user> [, ...]
 `,
-    //line sql.y: 5779
+    //line sql.y: 6707
     SeeAlso: `CREATE ROLE, SHOW ROLE
 `,
   },
-  //line sql.y: 5812
+  //line sql.y: 6740
   `ANALYZE`: {
     ShortDescription: `collect table statistics`,
-    //line sql.y: 5813
+    //line sql.y: 6741
     Category: hMisc,
-    //line sql.y: 5814
+    //line sql.y: 6742
     Text: `
 ANALYZE <tablename>
 
 `,
-    //line sql.y: 5817
+    //line sql.y: 6745
     SeeAlso: `CREATE STATISTICS
 `,
   },
-  //line sql.y: 5840
+  //line sql.y: 6768
   `EXPLAIN`: {
     ShortDescription: `show the logical plan of a query`,
-    //line sql.y: 5841
+    //line sql.y: 6769
     Category: hMisc,
-    //line sql.y: 5842
+    //line sql.y: 6770
     Text: `
 EXPLAIN <statement>
 EXPLAIN ([PLAN ,] <planoptions...> ) <statement>
@@ -973,26 +1108,39 @@ Plan options:
     TYPES, VERBOSE, OPT
 
 `,
-    //line sql.y: 5856
+    //line sql.y: 6784
     SeeAlso: `WEBDOCS/explain.html
 `,
   },
-  //line sql.y: 5979
+  //line sql.y: 6909
+  `ALTER JOB`: {
+    ShortDescription: `alter an existing job`,
+    //line sql.y: 6910
+    Category: hMisc,
+    //line sql.y: 6911
+    Text: `
+ALTER JOB <jobid> <cmd>
+`,
+    //line sql.y: 6913
+    SeeAlso: `SHOW JOBS, CANCEL JOBS, RESUME JOBS
+`,
+  },
+  //line sql.y: 6925
   `ALTER CHANGEFEED`: {
     ShortDescription: `alter an existing changefeed`,
-    //line sql.y: 5980
+    //line sql.y: 6926
     Category: hCCL,
-    //line sql.y: 5981
+    //line sql.y: 6927
     Text: `
 ALTER CHANGEFEED <job_id> {{ADD|DROP <targets...>} | SET <options...>}...
 `,
   },
-  //line sql.y: 6032
+  //line sql.y: 6978
   `ALTER BACKUP`: {
     ShortDescription: `alter an existing backup's encryption keys`,
-    //line sql.y: 6033
+    //line sql.y: 6979
     Category: hCCL,
-    //line sql.y: 6034
+    //line sql.y: 6980
     Text: `
 ALTER BACKUP <location...>
        [ ADD NEW_KMS = <kms...> ]
@@ -1004,12 +1152,12 @@ KMS:
    "[kms_provider]://[kms_host]/[master_key_identifier]?[parameters]" : add new kms keys to backup
 `,
   },
-  //line sql.y: 6088
+  //line sql.y: 7034
   `SHOW VIRTUAL CLUSTER`: {
     ShortDescription: `display metadata about virtual clusters`,
-    //line sql.y: 6089
+    //line sql.y: 7035
     Category: hExperimental,
-    //line sql.y: 6090
+    //line sql.y: 7036
     Text: `
 SHOW VIRTUAL CLUSTER { <virtual_cluster_spec> | ALL } [ WITH <options> ]
 SHOW VIRTUAL CLUSTERS                                 [ WITH <options> ]
@@ -1019,48 +1167,60 @@ Options:
     CAPABILITIES
 `,
   },
-  //line sql.y: 6175
+  //line sql.y: 7133
+  `SHOW LOGICAL REPLICATION JOBS`: {
+    ShortDescription: `display metadata about logical replication jobs`,
+    //line sql.y: 7134
+    Category: hExperimental,
+    //line sql.y: 7135
+    Text: `SHOW LOGICAL REPLICATION JOBS [ WITH <options> ]
+
+Options:
+    DETAILS
+`,
+  },
+  //line sql.y: 7168
   `PREPARE`: {
     ShortDescription: `prepare a statement for later execution`,
-    //line sql.y: 6176
+    //line sql.y: 7169
     Category: hMisc,
-    //line sql.y: 6177
+    //line sql.y: 7170
     Text: `PREPARE <name> [ ( <types...> ) ] AS <query>
 `,
-    //line sql.y: 6178
+    //line sql.y: 7171
     SeeAlso: `EXECUTE, DEALLOCATE, DISCARD
 `,
   },
-  //line sql.y: 6209
+  //line sql.y: 7202
   `EXECUTE`: {
     ShortDescription: `execute a statement prepared previously`,
-    //line sql.y: 6210
+    //line sql.y: 7203
     Category: hMisc,
-    //line sql.y: 6211
+    //line sql.y: 7204
     Text: `EXECUTE <name> [ ( <exprs...> ) ]
 `,
-    //line sql.y: 6212
+    //line sql.y: 7205
     SeeAlso: `PREPARE, DEALLOCATE, DISCARD
 `,
   },
-  //line sql.y: 6242
+  //line sql.y: 7235
   `DEALLOCATE`: {
     ShortDescription: `remove a prepared statement`,
-    //line sql.y: 6243
+    //line sql.y: 7236
     Category: hMisc,
-    //line sql.y: 6244
+    //line sql.y: 7237
     Text: `DEALLOCATE [PREPARE] { <name> | ALL }
 `,
-    //line sql.y: 6245
+    //line sql.y: 7238
     SeeAlso: `PREPARE, EXECUTE, DISCARD
 `,
   },
-  //line sql.y: 6265
+  //line sql.y: 7258
   `GRANT`: {
     ShortDescription: `define access privileges and role memberships`,
-    //line sql.y: 6266
+    //line sql.y: 7259
     Category: hPriv,
-    //line sql.y: 6267
+    //line sql.y: 7260
     Text: `
 Grant privileges:
   GRANT {ALL [PRIVILEGES] | <privileges...> } ON <targets...> TO <grantees...>
@@ -1079,16 +1239,16 @@ Targets:
   ALL TABLES IN SCHEMA schema_name [, ...]
 
 `,
-    //line sql.y: 6284
+    //line sql.y: 7277
     SeeAlso: `REVOKE, WEBDOCS/grant.html
 `,
   },
-  //line sql.y: 6378
+  //line sql.y: 7371
   `REVOKE`: {
     ShortDescription: `remove access privileges and role memberships`,
-    //line sql.y: 6379
+    //line sql.y: 7372
     Category: hPriv,
-    //line sql.y: 6380
+    //line sql.y: 7373
     Text: `
 Revoke privileges:
   REVOKE {ALL | <privileges...> } ON <targets...> FROM <grantees...>
@@ -1107,54 +1267,54 @@ Targets:
   ALL TABLES IN SCHEMA schema_name [, ...]
 
 `,
-    //line sql.y: 6397
+    //line sql.y: 7390
     SeeAlso: `GRANT, WEBDOCS/revoke.html
 `,
   },
-  //line sql.y: 6595
+  //line sql.y: 7588
   `RESET`: {
     ShortDescription: `reset a session variable to its default value`,
-    //line sql.y: 6596
+    //line sql.y: 7589
     Category: hCfg,
-    //line sql.y: 6597
+    //line sql.y: 7590
     Text: `RESET [SESSION] <var>
 `,
-    //line sql.y: 6598
+    //line sql.y: 7591
     SeeAlso: `RESET CLUSTER SETTING, WEBDOCS/set-vars.html
 `,
   },
-  //line sql.y: 6614
+  //line sql.y: 7607
   `RESET CLUSTER SETTING`: {
     ShortDescription: `reset a cluster setting to its default value`,
-    //line sql.y: 6615
+    //line sql.y: 7608
     Category: hCfg,
-    //line sql.y: 6616
+    //line sql.y: 7609
     Text: `RESET CLUSTER SETTING <var>
 `,
-    //line sql.y: 6617
+    //line sql.y: 7610
     SeeAlso: `SET CLUSTER SETTING, RESET
 `,
   },
-  //line sql.y: 6626
+  //line sql.y: 7619
   `USE`: {
     ShortDescription: `set the current database`,
-    //line sql.y: 6627
+    //line sql.y: 7620
     Category: hCfg,
-    //line sql.y: 6628
+    //line sql.y: 7621
     Text: `USE <dbname>
 
 "USE <dbname>" is an alias for "SET [SESSION] database = <dbname>".
 `,
-    //line sql.y: 6631
+    //line sql.y: 7624
     SeeAlso: `SET SESSION, WEBDOCS/set-vars.html
 `,
   },
-  //line sql.y: 6652
+  //line sql.y: 7645
   `SCRUB`: {
     ShortDescription: `run checks against databases or tables`,
-    //line sql.y: 6653
+    //line sql.y: 7646
     Category: hExperimental,
-    //line sql.y: 6654
+    //line sql.y: 7647
     Text: `
 EXPERIMENTAL SCRUB TABLE <table> ...
 EXPERIMENTAL SCRUB DATABASE <database>
@@ -1164,16 +1324,16 @@ The various checks that ca be run with SCRUB includes:
   - Secondary index integrity
   - Constraint integrity (NOT NULL, CHECK, FOREIGN KEY, UNIQUE)
 `,
-    //line sql.y: 6662
+    //line sql.y: 7655
     SeeAlso: `SCRUB TABLE, SCRUB DATABASE
 `,
   },
-  //line sql.y: 6668
+  //line sql.y: 7661
   `SCRUB DATABASE`: {
     ShortDescription: `run scrub checks on a database`,
-    //line sql.y: 6669
+    //line sql.y: 7662
     Category: hExperimental,
-    //line sql.y: 6670
+    //line sql.y: 7663
     Text: `
 EXPERIMENTAL SCRUB DATABASE <database>
                             [AS OF SYSTEM TIME <expr>]
@@ -1183,16 +1343,16 @@ All scrub checks will be run on the database. This includes:
   - Secondary index integrity
   - Constraint integrity (NOT NULL, CHECK, FOREIGN KEY, UNIQUE)
 `,
-    //line sql.y: 6678
+    //line sql.y: 7671
     SeeAlso: `SCRUB TABLE, SCRUB
 `,
   },
-  //line sql.y: 6686
+  //line sql.y: 7679
   `SCRUB TABLE`: {
     ShortDescription: `run scrub checks on a table`,
-    //line sql.y: 6687
+    //line sql.y: 7680
     Category: hExperimental,
-    //line sql.y: 6688
+    //line sql.y: 7681
     Text: `
 SCRUB TABLE <tablename>
             [AS OF SYSTEM TIME <expr>]
@@ -1205,234 +1365,245 @@ Options:
   EXPERIMENTAL SCRUB TABLE ... WITH OPTIONS CONSTRAINT (<constraint>...)
   EXPERIMENTAL SCRUB TABLE ... WITH OPTIONS PHYSICAL
 `,
-    //line sql.y: 6699
+    //line sql.y: 7692
     SeeAlso: `SCRUB DATABASE, SRUB
 `,
   },
-  //line sql.y: 6754
+  //line sql.y: 7747
   `SET CLUSTER SETTING`: {
     ShortDescription: `change a cluster setting`,
-    //line sql.y: 6755
+    //line sql.y: 7748
     Category: hCfg,
-    //line sql.y: 6756
+    //line sql.y: 7749
     Text: `SET CLUSTER SETTING <var> { TO | = } <value>
 `,
-    //line sql.y: 6757
+    //line sql.y: 7750
     SeeAlso: `SHOW CLUSTER SETTING, RESET CLUSTER SETTING, SET SESSION, SET LOCAL
 WEBDOCS/cluster-settings.html
 `,
   },
-  //line sql.y: 6767
+  //line sql.y: 7760
   `ALTER VIRTUAL CLUSTER`: {
     ShortDescription: `alter configuration of virtual clusters`,
-    //line sql.y: 6768
+    //line sql.y: 7761
     Category: hGroup,
-    //line sql.y: 6769
+    //line sql.y: 7762
     Text: `
 ALTER VIRTUAL CLUSTER REPLICATION, ALTER VIRTUAL CLUSTER SETTING,
 ALTER VIRTUAL CLUSTER CAPABILITY, ALTER VIRTUAL CLUSTER RENAME,
-ALTER VIRTUAL CLUSTER SERVICE
+ALTER VIRTUAL CLUSTER RESET, ALTER VIRTUAL CLUSTER SERVICE
+`,
+  },
+  //line sql.y: 7782
+  `ALTER VIRTUAL CLUSTER RESET`: {
+    ShortDescription: `reset data state of a virtual cluster`,
+    //line sql.y: 7783
+    Category: hExperimental,
+    //line sql.y: 7784
+    Text: `
+ALTER VIRTUAL CLUSTER <virtual_cluster_spec> RESET DATA TO SYSTEM TIME <time>
 `,
   },
-  //line sql.y: 6787
+  //line sql.y: 7796
   `ALTER VIRTUAL CLUSTER RENAME`: {
     ShortDescription: `rename a virtual cluster`,
-    //line sql.y: 6788
+    //line sql.y: 7797
     Category: hExperimental,
-    //line sql.y: 6789
+    //line sql.y: 7798
     Text: `
 ALTER VIRTUAL CLUSTER <virtual_cluster_spec> RENAME TO <name>
 `,
   },
-  //line sql.y: 6801
+  //line sql.y: 7809
   `ALTER VIRTUAL CLUSTER SERVICE`: {
     ShortDescription: `alter service mode of a virtual cluster`,
-    //line sql.y: 6802
+    //line sql.y: 7810
     Category: hExperimental,
-    //line sql.y: 6803
+    //line sql.y: 7811
     Text: `
 ALTER VIRTUAL CLUSTER <virtual_cluster_spec> START SERVICE EXTERNAL
 ALTER VIRTUAL CLUSTER <virtual_cluster_spec> START SERVICE SHARED
 ALTER VIRTUAL CLUSTER <virtual_cluster_spec> STOP SERVICE
 `,
   },
-  //line sql.y: 6836
+  //line sql.y: 7842
   `ALTER VIRTUAL CLUSTER REPLICATION`: {
     ShortDescription: `alter replication stream between virtual clusters`,
-    //line sql.y: 6837
+    //line sql.y: 7843
     Category: hExperimental,
-    //line sql.y: 6838
+    //line sql.y: 7844
     Text: `
 ALTER VIRTUAL CLUSTER <virtual_cluster_spec> PAUSE REPLICATION
 ALTER VIRTUAL CLUSTER <virtual_cluster_spec> RESUME REPLICATION
 ALTER VIRTUAL CLUSTER <virtual_cluster_spec> COMPLETE REPLICATION TO LATEST
 ALTER VIRTUAL CLUSTER <virtual_cluster_spec> COMPLETE REPLICATION TO SYSTEM TIME 'time'
 ALTER VIRTUAL CLUSTER <virtual_cluster_spec> SET REPLICATION opt=value,...
+ALTER VIRTUAL CLUSTER <virtual_cluster_spec> SET SOURCE REPLICATION opt=value,...
 `,
   },
-  //line sql.y: 6891
+  //line sql.y: 7910
   `ALTER VIRTUAL CLUSTER SETTING`: {
     ShortDescription: `alter cluster setting overrides for virtual clusters`,
-    //line sql.y: 6892
+    //line sql.y: 7911
     Category: hGroup,
-    //line sql.y: 6893
+    //line sql.y: 7912
     Text: `
 ALTER VIRTUAL CLUSTER { <virtual_cluster_spec> | ALL } SET CLUSTER SETTING <var> { TO | = } <value>
 ALTER VIRTUAL CLUSTER { <virtual_cluster_spec> | ALL } RESET CLUSTER SETTING <var>
 `,
-    //line sql.y: 6896
+    //line sql.y: 7915
     SeeAlso: `SET CLUSTER SETTING
 `,
   },
-  //line sql.y: 6936
+  //line sql.y: 7955
   `ALTER VIRTUAL CLUSTER CAPABILITY`: {
     ShortDescription: `alter system capability of virtual cluster`,
-    //line sql.y: 6937
+    //line sql.y: 7956
     Category: hGroup,
-    //line sql.y: 6938
+    //line sql.y: 7957
     Text: `
 ALTER VIRTUAL CLUSTER <tenant_id> GRANT CAPABILITY <var> { TO | = } <value>
 ALTER VIRTUAL CLUSTER <tenant_id> REVOKE CAPABILITY <var>
 `,
   },
-  //line sql.y: 7016
+  //line sql.y: 8031
   `SET SESSION`: {
     ShortDescription: `change a session variable`,
-    //line sql.y: 7017
+    //line sql.y: 8032
     Category: hCfg,
-    //line sql.y: 7018
+    //line sql.y: 8033
     Text: `
 SET [SESSION] <var> { TO | = } <values...>
 SET [SESSION] TIME ZONE <tz>
-SET [SESSION] CHARACTERISTICS AS TRANSACTION ISOLATION LEVEL { READ COMMITTED | SERIALIZABLE }
+SET [SESSION] CHARACTERISTICS AS TRANSACTION ISOLATION LEVEL { READ COMMITTED | REPEATABLE READ | SERIALIZABLE }
 SET [SESSION] TRACING { TO | = } { on | off | cluster | kv | results } [,...]
 
 `,
-    //line sql.y: 7024
+    //line sql.y: 8039
     SeeAlso: `SHOW SESSION, RESET, DISCARD, SHOW, SET CLUSTER SETTING, SET TRANSACTION, SET LOCAL
 WEBDOCS/set-vars.html
 `,
   },
-  //line sql.y: 7055
+  //line sql.y: 8070
   `SET LOCAL`: {
     ShortDescription: `change a session variable scoped to the current transaction`,
-    //line sql.y: 7056
+    //line sql.y: 8071
     Category: hCfg,
-    //line sql.y: 7057
+    //line sql.y: 8072
     Text: `
 SET LOCAL <var> { TO | = } <values...>
 SET LOCAL TIME ZONE <tz>
 
 `,
-    //line sql.y: 7061
+    //line sql.y: 8076
     SeeAlso: `SHOW SESSION, RESET, DISCARD, SHOW, SET CLUSTER SETTING, SET TRANSACTION, SET SESSION
 WEBDOCS/set-vars.html
 `,
   },
-  //line sql.y: 7072
+  //line sql.y: 8087
   `SET TRANSACTION`: {
     ShortDescription: `configure the transaction settings`,
-    //line sql.y: 7073
+    //line sql.y: 8088
     Category: hTxn,
-    //line sql.y: 7074
+    //line sql.y: 8089
     Text: `
 SET [SESSION] TRANSACTION <txnparameters...>
 
 Transaction parameters:
-   ISOLATION LEVEL { READ COMMITTED | SERIALIZABLE }
+   ISOLATION LEVEL { READ COMMITTED | REPEATABLE READ | SERIALIZABLE }
    PRIORITY { LOW | NORMAL | HIGH }
    AS OF SYSTEM TIME <expr>
    [NOT] DEFERRABLE
 
 `,
-    //line sql.y: 7083
+    //line sql.y: 8098
     SeeAlso: `SHOW TRANSACTION, SET SESSION, SET LOCAL
 WEBDOCS/set-transaction.html
 `,
   },
-  //line sql.y: 7282
+  //line sql.y: 8297
   `SHOW`: {
-    //line sql.y: 7283
+    //line sql.y: 8298
     Category: hGroup,
-    //line sql.y: 7284
+    //line sql.y: 8299
     Text: `
-SHOW BACKUP, SHOW CLUSTER SETTING, SHOW COLUMNS, SHOW CONSTRAINTS,
-SHOW CREATE, SHOW CREATE SCHEDULES, SHOW DATABASES, SHOW ENUMS, SHOW
-FUNCTION, SHOW FUNCTIONS, SHOW HISTOGRAM, SHOW INDEXES, SHOW PARTITIONS, SHOW JOBS,
-SHOW STATEMENTS, SHOW RANGE, SHOW RANGES, SHOW REGIONS, SHOW SURVIVAL GOAL,
+SHOW BACKUP, SHOW CLUSTER SETTING, SHOW COLUMNS, SHOW CONSTRAINTS, SHOW TRIGGERS,
+SHOW CREATE, SHOW CREATE SCHEDULES, SHOW DATABASES, SHOW DEFAULT SESSION VARIABLES,
+SHOW ENUMS, SHOW FUNCTION, SHOW FUNCTIONS, SHOW HISTOGRAM, SHOW INDEXES, SHOW PARTITIONS,
+SHOW JOBS, SHOW STATEMENTS, SHOW RANGE, SHOW RANGES, SHOW REGIONS, SHOW SURVIVAL GOAL,
 SHOW ROLES, SHOW SCHEMAS, SHOW SEQUENCES, SHOW SESSION, SHOW SESSIONS,
 SHOW STATISTICS, SHOW SYNTAX, SHOW TABLES, SHOW TRACE, SHOW TRANSACTION,
 SHOW TRANSACTIONS, SHOW TRANSFER, SHOW TYPES, SHOW USERS, SHOW LAST QUERY STATISTICS,
 SHOW SCHEDULES, SHOW LOCALITY, SHOW ZONE CONFIGURATION, SHOW COMMIT TIMESTAMP,
-SHOW FULL TABLE SCANS, SHOW CREATE EXTERNAL CONNECTIONS
+SHOW FULL TABLE SCANS, SHOW CREATE EXTERNAL CONNECTIONS, SHOW EXTERNAL CONNECTIONS
 `,
   },
-  //line sql.y: 7342
+  //line sql.y: 8362
   `CLOSE`: {
     ShortDescription: `close SQL cursor`,
-    //line sql.y: 7343
+    //line sql.y: 8363
     Category: hMisc,
-    //line sql.y: 7344
+    //line sql.y: 8364
     Text: `CLOSE [ ALL | <name> ]
 `,
-    //line sql.y: 7345
+    //line sql.y: 8365
     SeeAlso: `DECLARE, FETCH
 `,
   },
-  //line sql.y: 7361
+  //line sql.y: 8381
   `DECLARE`: {
     ShortDescription: `declare SQL cursor`,
-    //line sql.y: 7362
+    //line sql.y: 8382
     Category: hMisc,
-    //line sql.y: 7363
+    //line sql.y: 8383
     Text: `DECLARE <name> [ options ] CURSOR p [ WITH | WITHOUT HOLD ] FOR <query>
 `,
-    //line sql.y: 7364
+    //line sql.y: 8384
     SeeAlso: `CLOSE, FETCH
 `,
   },
-  //line sql.y: 7433
+  //line sql.y: 8453
   `FETCH`: {
     ShortDescription: `fetch rows from a SQL cursor`,
-    //line sql.y: 7434
+    //line sql.y: 8454
     Category: hMisc,
-    //line sql.y: 7435
+    //line sql.y: 8455
     Text: `FETCH [ direction [ FROM | IN ] ] <name>
 `,
-    //line sql.y: 7436
+    //line sql.y: 8456
     SeeAlso: `MOVE, CLOSE, DECLARE
 `,
   },
-  //line sql.y: 7446
+  //line sql.y: 8466
   `MOVE`: {
     ShortDescription: `move a SQL cursor without fetching rows`,
-    //line sql.y: 7447
+    //line sql.y: 8467
     Category: hMisc,
-    //line sql.y: 7448
+    //line sql.y: 8468
     Text: `MOVE [ direction [ FROM | IN ] ] <name>
 `,
-    //line sql.y: 7449
+    //line sql.y: 8469
     SeeAlso: `FETCH, CLOSE, DECLARE
 `,
   },
-  //line sql.y: 7585
+  //line sql.y: 8605
   `SHOW SESSION`: {
     ShortDescription: `display session variables`,
-    //line sql.y: 7586
+    //line sql.y: 8606
     Category: hCfg,
-    //line sql.y: 7587
+    //line sql.y: 8607
     Text: `SHOW [SESSION] { <var> | ALL }
 `,
-    //line sql.y: 7588
+    //line sql.y: 8608
     SeeAlso: `WEBDOCS/show-vars.html
 `,
   },
-  //line sql.y: 7633
+  //line sql.y: 8653
   `SHOW STATISTICS`: {
     ShortDescription: `display table statistics`,
-    //line sql.y: 7634
+    //line sql.y: 8654
     Category: hMisc,
-    //line sql.y: 7635
+    //line sql.y: 8655
     Text: `SHOW STATISTICS [USING JSON] FOR TABLE <table_name> [WITH FORECAST]
 
 Returns the available statistics for a table. The statistics can include a
@@ -1445,123 +1616,134 @@ If WITH FORECAST is specified, forecasted statistics are included if
 available.
 
 `,
-    //line sql.y: 7646
+    //line sql.y: 8666
     SeeAlso: `SHOW HISTOGRAM
 `,
   },
-  //line sql.y: 7668
+  //line sql.y: 8688
   `SHOW HISTOGRAM`: {
     ShortDescription: `display histogram (experimental)`,
-    //line sql.y: 7669
+    //line sql.y: 8689
     Category: hExperimental,
-    //line sql.y: 7670
+    //line sql.y: 8690
     Text: `SHOW HISTOGRAM <histogram_id>
 
 Returns the data in the histogram with the
 given ID (as returned by SHOW STATISTICS).
 `,
-    //line sql.y: 7674
+    //line sql.y: 8694
     SeeAlso: `SHOW STATISTICS
 `,
   },
-  //line sql.y: 7687
+  //line sql.y: 8707
   `SHOW BACKUP`: {
     ShortDescription: `list backup contents`,
-    //line sql.y: 7688
+    //line sql.y: 8708
     Category: hCCL,
-    //line sql.y: 7689
+    //line sql.y: 8709
     Text: `SHOW BACKUP [SCHEMAS|FILES|RANGES] <location>
 `,
-    //line sql.y: 7690
+    //line sql.y: 8710
     SeeAlso: `WEBDOCS/show-backup.html
 `,
   },
-  //line sql.y: 7904
+  //line sql.y: 8868
   `SHOW CLUSTER SETTING`: {
     ShortDescription: `display cluster settings`,
-    //line sql.y: 7905
+    //line sql.y: 8869
     Category: hCfg,
-    //line sql.y: 7906
+    //line sql.y: 8870
     Text: `
 SHOW CLUSTER SETTING <var> [ FOR VIRTUAL CLUSTER <virtual_cluster_spec> ]
 SHOW [ PUBLIC | ALL ] CLUSTER SETTINGS [ FOR VIRTUAL CLUSTER <virtual_cluster_spec> ]
 `,
-    //line sql.y: 7909
+    //line sql.y: 8873
     SeeAlso: `WEBDOCS/cluster-settings.html
 `,
   },
-  //line sql.y: 7959
+  //line sql.y: 8923
   `SHOW COLUMNS`: {
     ShortDescription: `list columns in relation`,
-    //line sql.y: 7960
+    //line sql.y: 8924
     Category: hDDL,
-    //line sql.y: 7961
+    //line sql.y: 8925
     Text: `SHOW COLUMNS FROM <tablename>
 `,
-    //line sql.y: 7962
+    //line sql.y: 8926
     SeeAlso: `WEBDOCS/show-columns.html
 `,
   },
-  //line sql.y: 7970
+  //line sql.y: 8934
   `SHOW PARTITIONS`: {
     ShortDescription: `list partition information`,
-    //line sql.y: 7971
+    //line sql.y: 8935
     Category: hDDL,
-    //line sql.y: 7972
+    //line sql.y: 8936
     Text: `SHOW PARTITIONS FROM { TABLE <table> | INDEX <index> | DATABASE <database> }
 `,
-    //line sql.y: 7973
+    //line sql.y: 8937
     SeeAlso: `WEBDOCS/show-partitions.html
 `,
   },
-  //line sql.y: 7993
+  //line sql.y: 8957
   `SHOW DATABASES`: {
     ShortDescription: `list databases`,
-    //line sql.y: 7994
+    //line sql.y: 8958
     Category: hDDL,
-    //line sql.y: 7995
+    //line sql.y: 8959
     Text: `SHOW DATABASES
 `,
-    //line sql.y: 7996
+    //line sql.y: 8960
     SeeAlso: `WEBDOCS/show-databases.html
 `,
   },
-  //line sql.y: 8004
+  //line sql.y: 8968
   `SHOW DEFAULT PRIVILEGES`: {
     ShortDescription: `list default privileges`,
-    //line sql.y: 8005
+    //line sql.y: 8969
     Category: hDDL,
-    //line sql.y: 8006
+    //line sql.y: 8970
     Text: `SHOW DEFAULT PRIVILEGES
 `,
-    //line sql.y: 8007
+    //line sql.y: 8971
     SeeAlso: `WEBDOCS/show-default-privileges
 `,
   },
-  //line sql.y: 8030
+  //line sql.y: 8994
   `SHOW ENUMS`: {
     ShortDescription: `list enums`,
-    //line sql.y: 8031
+    //line sql.y: 8995
     Category: hMisc,
-    //line sql.y: 8032
+    //line sql.y: 8996
     Text: `SHOW ENUMS
 `,
   },
-  //line sql.y: 8060
+  //line sql.y: 9024
+  `SHOW EXTERNAL CONNECTIONS`: {
+    ShortDescription: `list external connections`,
+    //line sql.y: 9025
+    Category: hMisc,
+    //line sql.y: 9026
+    Text: `
+SHOW EXTERNAL CONNECTIONS
+SHOW EXTERNAL CONNECTION <connection_name>
+`,
+  },
+  //line sql.y: 9041
   `SHOW TYPES`: {
     ShortDescription: `list user defined types`,
-    //line sql.y: 8061
+    //line sql.y: 9042
     Category: hMisc,
-    //line sql.y: 8062
-    Text: `SHOW TYPES
+    //line sql.y: 9043
+    Text: `SHOW TYPES [WITH_COMMENT]
 `,
   },
-  //line sql.y: 8070
+  //line sql.y: 9051
   `SHOW GRANTS`: {
     ShortDescription: `list grants`,
-    //line sql.y: 8071
+    //line sql.y: 9052
     Category: hPriv,
-    //line sql.y: 8072
+    //line sql.y: 9053
     Text: `
 Show privilege grants:
   SHOW GRANTS [ON <targets...>] [FOR <users...>]
@@ -1569,28 +1751,28 @@ Show role grants:
   SHOW GRANTS ON ROLE [<roles...>] [FOR <grantees...>]
 
 `,
-    //line sql.y: 8078
+    //line sql.y: 9059
     SeeAlso: `WEBDOCS/show-grants.html
 `,
   },
-  //line sql.y: 8098
+  //line sql.y: 9079
   `SHOW INDEXES`: {
     ShortDescription: `list indexes`,
-    //line sql.y: 8099
+    //line sql.y: 9080
     Category: hDDL,
-    //line sql.y: 8100
+    //line sql.y: 9081
     Text: `SHOW INDEXES FROM { <tablename> | DATABASE <database_name> } [WITH COMMENT]
 `,
-    //line sql.y: 8101
+    //line sql.y: 9082
     SeeAlso: `WEBDOCS/show-index.html
 `,
   },
-  //line sql.y: 8131
+  //line sql.y: 9112
   `SHOW COMMIT TIMESTAMP`: {
     ShortDescription: `show timestamp commit timestamp of last transaction`,
-    //line sql.y: 8132
+    //line sql.y: 9113
     Category: hMisc,
-    //line sql.y: 8133
+    //line sql.y: 9114
     Text: `SHOW COMMIT TIMESTAMP
 
 Shows the commit timestamp of the last committed transaction if not currently
@@ -1601,186 +1783,205 @@ meaning that a COMMIT must be issued to move the connection back to a state
 where new statements may be issued.
 `,
   },
-  //line sql.y: 8147
+  //line sql.y: 9128
   `SHOW CONSTRAINTS`: {
     ShortDescription: `list constraints`,
-    //line sql.y: 8148
+    //line sql.y: 9129
     Category: hDDL,
-    //line sql.y: 8149
+    //line sql.y: 9130
     Text: `SHOW CONSTRAINTS FROM <tablename>
 `,
-    //line sql.y: 8150
+    //line sql.y: 9131
     SeeAlso: `WEBDOCS/show-constraints.html
 `,
   },
-  //line sql.y: 8163
+  //line sql.y: 9144
+  `SHOW TRIGGERS`: {
+    ShortDescription: `list triggers on a table`,
+    //line sql.y: 9145
+    Category: hDDL,
+    //line sql.y: 9146
+    Text: `SHOW TRIGGERS FROM <tablename>
+TODO(drewk): Add docs link.
+`,
+  },
+  //line sql.y: 9156
   `SHOW STATEMENTS`: {
     ShortDescription: `list running statements`,
-    //line sql.y: 8164
+    //line sql.y: 9157
     Category: hMisc,
-    //line sql.y: 8165
+    //line sql.y: 9158
     Text: `SHOW [ALL] [CLUSTER | LOCAL] STATEMENTS
 `,
-    //line sql.y: 8166
+    //line sql.y: 9159
     SeeAlso: `CANCEL QUERIES
 `,
   },
-  //line sql.y: 8193
+  //line sql.y: 9186
   `SHOW JOBS`: {
     ShortDescription: `list background jobs`,
-    //line sql.y: 8194
+    //line sql.y: 9187
     Category: hMisc,
-    //line sql.y: 8195
+    //line sql.y: 9188
     Text: `
 SHOW [AUTOMATIC | CHANGEFEED] JOBS [select clause] [WITH EXECUTION DETAILS]
 SHOW JOBS FOR SCHEDULES [select clause]
 SHOW [CHANGEFEED] JOB <jobid> [WITH EXECUTION DETAILS]
 `,
-    //line sql.y: 8199
+    //line sql.y: 9192
     SeeAlso: `CANCEL JOBS, PAUSE JOBS, RESUME JOBS
 `,
   },
-  //line sql.y: 8309
+  //line sql.y: 9302
   `SHOW SCHEDULES`: {
     ShortDescription: `list periodic schedules`,
-    //line sql.y: 8310
+    //line sql.y: 9303
     Category: hMisc,
-    //line sql.y: 8311
+    //line sql.y: 9304
     Text: `
 SHOW [RUNNING | PAUSED] SCHEDULES [FOR BACKUP]
 SHOW SCHEDULE <schedule_id>
 `,
-    //line sql.y: 8314
+    //line sql.y: 9307
     SeeAlso: `PAUSE SCHEDULES, RESUME SCHEDULES, DROP SCHEDULES
 `,
   },
-  //line sql.y: 8369
+  //line sql.y: 9362
   `SHOW TRACE`: {
     ShortDescription: `display an execution trace`,
-    //line sql.y: 8370
+    //line sql.y: 9363
     Category: hMisc,
-    //line sql.y: 8371
+    //line sql.y: 9364
     Text: `
 SHOW [COMPACT] [KV] TRACE FOR SESSION
 `,
-    //line sql.y: 8373
+    //line sql.y: 9366
     SeeAlso: `EXPLAIN
 `,
   },
-  //line sql.y: 8396
+  //line sql.y: 9389
   `SHOW SESSIONS`: {
     ShortDescription: `list open client sessions`,
-    //line sql.y: 8397
+    //line sql.y: 9390
     Category: hMisc,
-    //line sql.y: 8398
+    //line sql.y: 9391
     Text: `SHOW [ALL] [CLUSTER | LOCAL] SESSIONS
 `,
-    //line sql.y: 8399
+    //line sql.y: 9392
     SeeAlso: `CANCEL SESSIONS
 `,
   },
-  //line sql.y: 8412
+  //line sql.y: 9405
   `SHOW TABLES`: {
     ShortDescription: `list tables`,
-    //line sql.y: 8413
+    //line sql.y: 9406
     Category: hDDL,
-    //line sql.y: 8414
+    //line sql.y: 9407
     Text: `SHOW TABLES [FROM <databasename> [ . <schemaname> ] ] [WITH COMMENT]
 `,
-    //line sql.y: 8415
+    //line sql.y: 9408
     SeeAlso: `WEBDOCS/show-tables.html
 `,
   },
-  //line sql.y: 8443
+  //line sql.y: 9436
   `SHOW FUNCTIONS`: {
     ShortDescription: `list functions`,
-    //line sql.y: 8444
+    //line sql.y: 9437
     Category: hDDL,
-    //line sql.y: 8445
+    //line sql.y: 9438
     Text: `SHOW FUNCTIONS [FROM <databasename> [ . <schemaname> ] ]
 `,
   },
-  //line sql.y: 8471
+  //line sql.y: 9464
   `SHOW PROCEDURES`: {
     ShortDescription: `list procedures`,
-    //line sql.y: 8472
+    //line sql.y: 9465
     Category: hDDL,
-    //line sql.y: 8473
+    //line sql.y: 9466
     Text: `SHOW PROCEDURES [FROM <databasename> [ . <schemaname> ] ]
 `,
   },
-  //line sql.y: 8499
+  //line sql.y: 9492
   `SHOW TRANSACTIONS`: {
     ShortDescription: `list open client transactions across the cluster`,
-    //line sql.y: 8500
+    //line sql.y: 9493
     Category: hMisc,
-    //line sql.y: 8501
+    //line sql.y: 9494
     Text: `SHOW [ALL] [CLUSTER | LOCAL] TRANSACTIONS
 `,
   },
-  //line sql.y: 8518
+  //line sql.y: 9511
   `SHOW SCHEMAS`: {
     ShortDescription: `list schemas`,
-    //line sql.y: 8519
+    //line sql.y: 9512
     Category: hDDL,
-    //line sql.y: 8520
-    Text: `SHOW SCHEMAS [FROM <databasename> ]
+    //line sql.y: 9513
+    Text: `SHOW SCHEMAS [FROM <databasename> ] [WITH COMMENT]
 `,
   },
-  //line sql.y: 8532
+  //line sql.y: 9525
   `SHOW SEQUENCES`: {
     ShortDescription: `list sequences`,
-    //line sql.y: 8533
+    //line sql.y: 9526
     Category: hDDL,
-    //line sql.y: 8534
+    //line sql.y: 9527
     Text: `SHOW SEQUENCES [FROM <databasename> ]
 `,
   },
-  //line sql.y: 8546
+  //line sql.y: 9539
   `SHOW SYNTAX`: {
     ShortDescription: `analyze SQL syntax`,
-    //line sql.y: 8547
+    //line sql.y: 9540
     Category: hMisc,
-    //line sql.y: 8548
+    //line sql.y: 9541
     Text: `SHOW SYNTAX <string>
 `,
   },
-  //line sql.y: 8586
+  //line sql.y: 9560
+  `SHOW POLICIES`: {
+    ShortDescription: `list row-level security policies defined for a table`,
+    //line sql.y: 9561
+    Category: hDDL,
+    //line sql.y: 9562
+    Text: `SHOW POLICIES FOR <table_name>
+`,
+  },
+  //line sql.y: 9592
   `SHOW SAVEPOINT`: {
     ShortDescription: `display current savepoint properties`,
-    //line sql.y: 8587
+    //line sql.y: 9593
     Category: hCfg,
-    //line sql.y: 8588
+    //line sql.y: 9594
     Text: `SHOW SAVEPOINT STATUS
 `,
   },
-  //line sql.y: 8596
+  //line sql.y: 9602
   `SHOW TRANSACTION`: {
     ShortDescription: `display current transaction properties`,
-    //line sql.y: 8597
+    //line sql.y: 9603
     Category: hCfg,
-    //line sql.y: 8598
+    //line sql.y: 9604
     Text: `SHOW TRANSACTION {ISOLATION LEVEL | PRIORITY | STATUS}
 `,
-    //line sql.y: 8599
+    //line sql.y: 9605
     SeeAlso: `WEBDOCS/show-vars.html
 `,
   },
-  //line sql.y: 8618
+  //line sql.y: 9624
   `SHOW TRANSFER`: {
     ShortDescription: `display session state for connection migration`,
-    //line sql.y: 8619
+    //line sql.y: 9625
     Category: hMisc,
-    //line sql.y: 8620
+    //line sql.y: 9626
     Text: `SHOW TRANSFER STATE [ WITH '<transfer_key>' ]
 `,
   },
-  //line sql.y: 8632
+  //line sql.y: 9638
   `SHOW CREATE`: {
     ShortDescription: `display the CREATE statement for a table, sequence, view, or database`,
-    //line sql.y: 8633
+    //line sql.y: 9639
     Category: hDDL,
-    //line sql.y: 8634
+    //line sql.y: 9640
     Text: `
 SHOW CREATE [ TABLE | SEQUENCE | VIEW | DATABASE ] <object_name>
 SHOW CREATE [ SECONDARY ] INDEXES FROM <table_name>
@@ -1788,90 +1989,99 @@ SHOW CREATE ALL SCHEMAS
 SHOW CREATE ALL TABLES
 SHOW CREATE ALL TYPES
 `,
-    //line sql.y: 8640
+    //line sql.y: 9646
     SeeAlso: `WEBDOCS/show-create.html
 `,
   },
-  //line sql.y: 8729
+  //line sql.y: 9747
   `SHOW CREATE SCHEDULES`: {
     ShortDescription: `list CREATE statements for scheduled jobs`,
-    //line sql.y: 8730
+    //line sql.y: 9748
     Category: hDDL,
-    //line sql.y: 8731
+    //line sql.y: 9749
     Text: `
 SHOW CREATE ALL SCHEDULES
 SHOW CREATE SCHEDULE <schedule_id>
 `,
-    //line sql.y: 8734
+    //line sql.y: 9752
     SeeAlso: `SHOW SCHEDULES, PAUSE SCHEDULES, RESUME SCHEDULES, DROP SCHEDULES
 `,
   },
-  //line sql.y: 8747
+  //line sql.y: 9765
   `SHOW CREATE EXTERNAL CONNECTIONS`: {
     ShortDescription: `list CREATE statements for external connections`,
-    //line sql.y: 8748
+    //line sql.y: 9766
     Category: hDDL,
-    //line sql.y: 8749
+    //line sql.y: 9767
     Text: `
 SHOW CREATE ALL EXTERNAL CONNECTIONS
 SHOW CREATE EXTERNAL CONNECTION <connection_name>
 `,
   },
-  //line sql.y: 8764
+  //line sql.y: 9782
   `SHOW USERS`: {
     ShortDescription: `list defined users`,
-    //line sql.y: 8765
+    //line sql.y: 9783
     Category: hPriv,
-    //line sql.y: 8766
+    //line sql.y: 9784
     Text: `SHOW USERS
 `,
-    //line sql.y: 8767
+    //line sql.y: 9785
     SeeAlso: `CREATE USER, DROP USER, WEBDOCS/show-users.html
 `,
   },
-  //line sql.y: 8775
+  //line sql.y: 9793
+  `SHOW DEFAULT SESSION VARIABLES FOR ROLE`: {
+    ShortDescription: `list default session variables for role`,
+    //line sql.y: 9794
+    Category: hPriv,
+    //line sql.y: 9795
+    Text: `SHOW DEFAULT SESSION VARIABLES FOR ROLE <name>
+`,
+  },
+  //line sql.y: 9811
   `SHOW ROLES`: {
     ShortDescription: `list defined roles`,
-    //line sql.y: 8776
+    //line sql.y: 9812
     Category: hPriv,
-    //line sql.y: 8777
+    //line sql.y: 9813
     Text: `SHOW ROLES
 `,
-    //line sql.y: 8778
+    //line sql.y: 9814
     SeeAlso: `CREATE ROLE, ALTER ROLE, DROP ROLE
 `,
   },
-  //line sql.y: 8786
+  //line sql.y: 9822
   `SHOW ZONE CONFIGURATION`: {
     ShortDescription: `display current zone configuration`,
-    //line sql.y: 8787
+    //line sql.y: 9823
     Category: hCfg,
-    //line sql.y: 8788
+    //line sql.y: 9824
     Text: `SHOW ZONE CONFIGURATION FROM [ RANGE | DATABASE | TABLE | INDEX ] <name>
 SHOW ZONE CONFIGURATION FROM PARTITION OF [ INDEX | TABLE ] <name>
 SHOW [ALL] ZONE CONFIGURATIONS
 `,
-    //line sql.y: 8791
+    //line sql.y: 9827
     SeeAlso: `WEBDOCS/show-zone-configurations.html
 `,
   },
-  //line sql.y: 8847
+  //line sql.y: 9883
   `SHOW RANGE`: {
     ShortDescription: `show range information for a row`,
-    //line sql.y: 8848
+    //line sql.y: 9884
     Category: hMisc,
-    //line sql.y: 8849
+    //line sql.y: 9885
     Text: `
 SHOW RANGE FROM TABLE <tablename> FOR ROW (value1, value2, ...)
 SHOW RANGE FROM INDEX [ <tablename> @ ] <indexname> FOR ROW (value1, value2, ...)
 `,
   },
-  //line sql.y: 8870
+  //line sql.y: 9906
   `SHOW RANGES`: {
     ShortDescription: `list ranges`,
-    //line sql.y: 8871
+    //line sql.y: 9907
     Category: hMisc,
-    //line sql.y: 8872
+    //line sql.y: 9908
     Text: `
 SHOW CLUSTER RANGES                                  [ WITH <options...> ]
 SHOW RANGES FROM DATABASE <databasename>             [ WITH <options...> ]
@@ -1890,27 +2100,27 @@ Note: the availability of some of the options listed above is subject
 to cluster configuration. See the documentation for details.
 
 `,
-    //line sql.y: 8889
+    //line sql.y: 9925
     SeeAlso: `WEBDOCS/show-ranges.html
 `,
   },
-  //line sql.y: 8965
+  //line sql.y: 10001
   `SHOW SURVIVAL GOAL`: {
     ShortDescription: `list survival goals`,
-    //line sql.y: 8966
+    //line sql.y: 10002
     Category: hDDL,
-    //line sql.y: 8967
+    //line sql.y: 10003
     Text: `
 SHOW SURVIVAL GOAL FROM DATABASE
 SHOW SURVIVAL GOAL FROM DATABASE <database>
 `,
   },
-  //line sql.y: 8982
+  //line sql.y: 10018
   `SHOW REGIONS`: {
     ShortDescription: `list regions`,
-    //line sql.y: 8983
+    //line sql.y: 10019
     Category: hDDL,
-    //line sql.y: 8984
+    //line sql.y: 10020
     Text: `
 SHOW REGIONS
 SHOW REGIONS FROM ALL DATABASES
@@ -1919,89 +2129,89 @@ SHOW REGIONS FROM DATABASE
 SHOW REGIONS FROM DATABASE <database>
 `,
   },
-  //line sql.y: 9356
+  //line sql.y: 10431
   `PAUSE`: {
     ShortDescription: `pause background tasks`,
-    //line sql.y: 9357
+    //line sql.y: 10432
     Category: hGroup,
-    //line sql.y: 9358
+    //line sql.y: 10433
     Text: `PAUSE JOBS, PAUSE SCHEDULES, PAUSE ALL JOBS
 `,
   },
-  //line sql.y: 9365
+  //line sql.y: 10440
   `RESUME`: {
     ShortDescription: `resume background tasks`,
-    //line sql.y: 9366
+    //line sql.y: 10441
     Category: hGroup,
-    //line sql.y: 9367
+    //line sql.y: 10442
     Text: `RESUME JOBS, RESUME SCHEDULES, RESUME ALL BACKUP JOBS
 `,
   },
-  //line sql.y: 9374
+  //line sql.y: 10449
   `RESUME ALL JOBS`: {
     ShortDescription: `resume background jobs`,
-    //line sql.y: 9375
+    //line sql.y: 10450
     Category: hMisc,
-    //line sql.y: 9376
+    //line sql.y: 10451
     Text: `
 RESUME ALL {BACKUP|CHANGEFEED|IMPORT|RESTORE} JOBS
 `,
   },
-  //line sql.y: 9385
+  //line sql.y: 10460
   `PAUSE JOBS`: {
     ShortDescription: `pause selected background jobs`,
-    //line sql.y: 9386
+    //line sql.y: 10461
     Category: hMisc,
-    //line sql.y: 9387
+    //line sql.y: 10462
     Text: `
 PAUSE JOBS <selectclause>
 PAUSE JOB <jobid>
 `,
-    //line sql.y: 9390
+    //line sql.y: 10465
     SeeAlso: `SHOW JOBS, CANCEL JOBS, RESUME JOBS
 `,
   },
-  //line sql.y: 9439
+  //line sql.y: 10514
   `PAUSE SCHEDULES`: {
     ShortDescription: `pause scheduled jobs`,
-    //line sql.y: 9440
+    //line sql.y: 10515
     Category: hMisc,
-    //line sql.y: 9441
+    //line sql.y: 10516
     Text: `
 PAUSE SCHEDULES <selectclause>
   select clause: select statement returning schedule id to pause.
 PAUSE SCHEDULE <scheduleID>
 `,
-    //line sql.y: 9445
+    //line sql.y: 10520
     SeeAlso: `RESUME SCHEDULES, SHOW JOBS, CANCEL JOBS
 `,
   },
-  //line sql.y: 9466
+  //line sql.y: 10541
   `PAUSE ALL JOBS`: {
     ShortDescription: `pause all background jobs`,
-    //line sql.y: 9467
+    //line sql.y: 10542
     Category: hMisc,
-    //line sql.y: 9468
+    //line sql.y: 10543
     Text: `
 PAUSE ALL {BACKUP|CHANGEFEED|IMPORT|RESTORE} JOBS
 `,
   },
-  //line sql.y: 9478
+  //line sql.y: 10553
   `CREATE SCHEMA`: {
     ShortDescription: `create a new schema`,
-    //line sql.y: 9479
+    //line sql.y: 10554
     Category: hDDL,
-    //line sql.y: 9480
+    //line sql.y: 10555
     Text: `
 CREATE SCHEMA [IF NOT EXISTS] { [<databasename>.]<schemaname> | [[<databasename>.]<schemaname>] AUTHORIZATION <rolename> }
 `,
   },
-  //line sql.y: 9513
+  //line sql.y: 10588
   `ALTER SCHEMA`: {
     ShortDescription: `alter an existing schema`,
-    //line sql.y: 9514
+    //line sql.y: 10589
     Category: hDDL,
-    //line sql.y: 9515
+    //line sql.y: 10590
     Text: `
 
 Commands:
@@ -2009,19 +2219,19 @@ Commands:
   ALTER SCHEMA ... OWNER TO {<newowner> | CURRENT_USER | SESSION_USER }
 `,
   },
-  //line sql.y: 9541
+  //line sql.y: 10616
   `CREATE TABLE`: {
     ShortDescription: `create a new table`,
-    //line sql.y: 9542
+    //line sql.y: 10617
     Category: hDDL,
-    //line sql.y: 9543
+    //line sql.y: 10618
     Text: `
 CREATE [[GLOBAL | LOCAL] {TEMPORARY | TEMP}] TABLE [IF NOT EXISTS] <tablename> ( <elements...> ) [<on_commit>]
 CREATE [[GLOBAL | LOCAL] {TEMPORARY | TEMP}] TABLE [IF NOT EXISTS] <tablename> [( <colnames...> )] AS <source> [<on commit>]
 
 Table elements:
    <name> <type> [<qualifiers...>]
-   [UNIQUE | INVERTED] INDEX [<name>] ( <colname> [ASC | DESC] [, ...] )
+   [UNIQUE | INVERTED | VECTOR] INDEX [<name>] ( <colname> [ASC | DESC] [, ...] )
                            [USING HASH] [{STORING | INCLUDE | COVERING} ( <colnames...> )]
    FAMILY [<name>] ( <colnames...> )
    [CONSTRAINT <name>] <constraint>
@@ -2043,18 +2253,18 @@ On commit clause:
    ON COMMIT {PRESERVE ROWS | DROP | DELETE ROWS}
 
 `,
-    //line sql.y: 9570
+    //line sql.y: 10645
     SeeAlso: `SHOW TABLES, CREATE VIEW, SHOW CREATE,
 WEBDOCS/create-table.html
 WEBDOCS/create-table-as.html
 `,
   },
-  //line sql.y: 10534
+  //line sql.y: 11640
   `CREATE SEQUENCE`: {
     ShortDescription: `create a new sequence`,
-    //line sql.y: 10535
+    //line sql.y: 11641
     Category: hDDL,
-    //line sql.y: 10536
+    //line sql.y: 11642
     Text: `
 CREATE [TEMPORARY | TEMP] SEQUENCE <seqname>
   [AS <typename>]
@@ -2067,135 +2277,135 @@ CREATE [TEMPORARY | TEMP] SEQUENCE <seqname>
   [VIRTUAL]
 
 `,
-    //line sql.y: 10547
+    //line sql.y: 11653
     SeeAlso: `CREATE TABLE
 `,
   },
-  //line sql.y: 10630
+  //line sql.y: 11738
   `TRUNCATE`: {
     ShortDescription: `empty one or more tables`,
-    //line sql.y: 10631
+    //line sql.y: 11739
     Category: hDML,
-    //line sql.y: 10632
+    //line sql.y: 11740
     Text: `TRUNCATE [TABLE] <tablename> [, ...] [CASCADE | RESTRICT]
 `,
-    //line sql.y: 10633
+    //line sql.y: 11741
     SeeAlso: `WEBDOCS/truncate.html
 `,
   },
-  //line sql.y: 10657
+  //line sql.y: 11765
   `CREATE ROLE`: {
     ShortDescription: `define a new role`,
-    //line sql.y: 10658
+    //line sql.y: 11766
     Category: hPriv,
-    //line sql.y: 10659
+    //line sql.y: 11767
     Text: `CREATE ROLE [IF NOT EXISTS] <name> [ [WITH] <OPTIONS...> ]
 `,
-    //line sql.y: 10660
+    //line sql.y: 11768
     SeeAlso: `ALTER ROLE, DROP ROLE, SHOW ROLES
 `,
   },
-  //line sql.y: 10672
+  //line sql.y: 11780
   `ALTER ROLE`: {
     ShortDescription: `alter a role`,
-    //line sql.y: 10673
+    //line sql.y: 11781
     Category: hPriv,
-    //line sql.y: 10674
+    //line sql.y: 11782
     Text: `
 ALTER ROLE <name> [WITH] <options...>
 ALTER ROLE { name | ALL } [ IN DATABASE database_name ] SET var { TO | = } { value | DEFAULT }
 ALTER ROLE { name | ALL } [ IN DATABASE database_name ] RESET { var | ALL }
 `,
-    //line sql.y: 10678
+    //line sql.y: 11786
     SeeAlso: `CREATE ROLE, DROP ROLE, SHOW ROLES
 `,
   },
-  //line sql.y: 10756
+  //line sql.y: 11864
   `CREATE VIEW`: {
     ShortDescription: `create a new view`,
-    //line sql.y: 10757
+    //line sql.y: 11865
     Category: hDDL,
-    //line sql.y: 10758
+    //line sql.y: 11866
     Text: `
 CREATE [TEMPORARY | TEMP] VIEW [IF NOT EXISTS] <viewname> [( <colnames...> )] AS <source>
 CREATE [TEMPORARY | TEMP] MATERIALIZED VIEW [IF NOT EXISTS] <viewname> [( <colnames...> )] AS <source> [WITH [NO] DATA]
 `,
-    //line sql.y: 10761
+    //line sql.y: 11869
     SeeAlso: `CREATE TABLE, SHOW CREATE, WEBDOCS/create-view.html
 `,
   },
-  //line sql.y: 10983
+  //line sql.y: 12110
   `CREATE TYPE`: {
     ShortDescription: `create a type`,
-    //line sql.y: 10984
+    //line sql.y: 12111
     Category: hDDL,
-    //line sql.y: 10985
+    //line sql.y: 12112
     Text: `CREATE TYPE [IF NOT EXISTS] <type_name> AS ENUM (...)
 `,
   },
-  //line sql.y: 11083
+  //line sql.y: 12210
   `CREATE INDEX`: {
     ShortDescription: `create a new index`,
-    //line sql.y: 11084
+    //line sql.y: 12211
     Category: hDDL,
-    //line sql.y: 11085
+    //line sql.y: 12212
     Text: `
-CREATE [UNIQUE | INVERTED] INDEX [CONCURRENTLY] [IF NOT EXISTS] [<idxname>]
+CREATE [UNIQUE | INVERTED | VECTOR] INDEX [CONCURRENTLY] [IF NOT EXISTS] [<idxname>]
        ON <tablename> ( <colname> [ASC | DESC] [, ...] )
        [USING HASH] [STORING ( <colnames...> )]
        [PARTITION BY <partition params>]
        [WITH <storage_parameter_list] [WHERE <where_conds...>]
 
 `,
-    //line sql.y: 11092
+    //line sql.y: 12219
     SeeAlso: `CREATE TABLE, SHOW INDEXES, SHOW CREATE,
 WEBDOCS/create-index.html
 `,
   },
-  //line sql.y: 11617
+  //line sql.y: 12785
   `ALTER DEFAULT PRIVILEGES`: {
     ShortDescription: `alter default privileges on an object`,
-    //line sql.y: 11618
+    //line sql.y: 12786
     Category: hDDL,
-    //line sql.y: 11619
+    //line sql.y: 12787
     Text: `
 
 Commands:
   ALTER DEFAULT PRIVILEGES [ FOR { ROLE | USER } target_roles... ] [ IN SCHEMA schema_name...] abbreviated_grant_or_revoke
 `,
   },
-  //line sql.y: 11766
+  //line sql.y: 12934
   `RELEASE`: {
     ShortDescription: `complete a sub-transaction`,
-    //line sql.y: 11767
+    //line sql.y: 12935
     Category: hTxn,
-    //line sql.y: 11768
+    //line sql.y: 12936
     Text: `RELEASE [SAVEPOINT] <savepoint name>
 `,
-    //line sql.y: 11769
+    //line sql.y: 12937
     SeeAlso: `SAVEPOINT, WEBDOCS/savepoint.html
 `,
   },
-  //line sql.y: 11777
+  //line sql.y: 12945
   `RESUME JOBS`: {
     ShortDescription: `resume selected background jobs`,
-    //line sql.y: 11778
+    //line sql.y: 12946
     Category: hMisc,
-    //line sql.y: 11779
+    //line sql.y: 12947
     Text: `
 RESUME JOBS <selectclause>
 RESUME JOB <jobid>
 `,
-    //line sql.y: 11782
+    //line sql.y: 12950
     SeeAlso: `SHOW JOBS, CANCEL JOBS, PAUSE JOBS
 `,
   },
-  //line sql.y: 11804
+  //line sql.y: 12972
   `RESUME SCHEDULES`: {
     ShortDescription: `resume executing scheduled jobs`,
-    //line sql.y: 11805
+    //line sql.y: 12973
     Category: hMisc,
-    //line sql.y: 11806
+    //line sql.y: 12974
     Text: `
 RESUME SCHEDULES <selectclause>
  selectclause: select statement returning schedule IDs to resume.
@@ -2203,16 +2413,16 @@ RESUME SCHEDULES <selectclause>
 RESUME SCHEDULE <scheduleID>
 
 `,
-    //line sql.y: 11812
+    //line sql.y: 12980
     SeeAlso: `PAUSE SCHEDULES, SHOW JOBS, RESUME JOBS
 `,
   },
-  //line sql.y: 11833
+  //line sql.y: 13001
   `DROP SCHEDULES`: {
     ShortDescription: `destroy specified schedules`,
-    //line sql.y: 11834
+    //line sql.y: 13002
     Category: hMisc,
-    //line sql.y: 11835
+    //line sql.y: 13003
     Text: `
 DROP SCHEDULES <selectclause>
  selectclause: select statement returning schedule IDs to resume.
@@ -2220,87 +2430,123 @@ DROP SCHEDULES <selectclause>
 DROP SCHEDULE <scheduleID>
 
 `,
-    //line sql.y: 11841
+    //line sql.y: 13009
     SeeAlso: `PAUSE SCHEDULES, SHOW JOBS, CANCEL JOBS
 `,
   },
-  //line sql.y: 11862
+  //line sql.y: 13030
   `SAVEPOINT`: {
     ShortDescription: `start a sub-transaction`,
-    //line sql.y: 11863
+    //line sql.y: 13031
     Category: hTxn,
-    //line sql.y: 11864
+    //line sql.y: 13032
     Text: `SAVEPOINT <savepoint name>
 `,
-    //line sql.y: 11865
+    //line sql.y: 13033
     SeeAlso: `RELEASE, WEBDOCS/savepoint.html
 `,
   },
-  //line sql.y: 11880
+  //line sql.y: 13051
   `BEGIN`: {
     ShortDescription: `start a transaction`,
-    //line sql.y: 11881
+    //line sql.y: 13052
     Category: hTxn,
-    //line sql.y: 11882
+    //line sql.y: 13053
     Text: `
 BEGIN [TRANSACTION] [ <txnparameter> [[,] ...] ]
 START TRANSACTION [ <txnparameter> [[,] ...] ]
 
 Transaction parameters:
-   ISOLATION LEVEL { READ COMMITTED | SERIALIZABLE }
+   ISOLATION LEVEL { READ COMMITTED | REPEATABLE READ | SERIALIZABLE }
    PRIORITY { LOW | NORMAL | HIGH }
 
 `,
-    //line sql.y: 11890
+    //line sql.y: 13061
     SeeAlso: `COMMIT, ROLLBACK, WEBDOCS/begin-transaction.html
 `,
   },
-  //line sql.y: 11900
+  //line sql.y: 13071
   `COMMIT`: {
     ShortDescription: `commit the current transaction`,
-    //line sql.y: 11901
+    //line sql.y: 13072
     Category: hTxn,
-    //line sql.y: 11902
+    //line sql.y: 13073
     Text: `
 COMMIT [TRANSACTION]
 END [TRANSACTION]
 `,
-    //line sql.y: 11905
+    //line sql.y: 13076
     SeeAlso: `BEGIN, ROLLBACK, WEBDOCS/commit-transaction.html
 `,
   },
-  //line sql.y: 11924
+  //line sql.y: 13095
   `ROLLBACK`: {
     ShortDescription: `abort the current (sub-)transaction`,
-    //line sql.y: 11925
+    //line sql.y: 13096
     Category: hTxn,
-    //line sql.y: 11926
+    //line sql.y: 13097
     Text: `
 ROLLBACK [TRANSACTION]
 ROLLBACK [TRANSACTION] TO [SAVEPOINT] <savepoint name>
 `,
-    //line sql.y: 11929
+    //line sql.y: 13100
     SeeAlso: `BEGIN, COMMIT, SAVEPOINT, WEBDOCS/rollback-transaction.html
 `,
   },
-  //line sql.y: 12065
+  //line sql.y: 13235
+  `PREPARE TRANSACTION`: {
+    ShortDescription: `prepare the current transaction for two-phase commit`,
+    //line sql.y: 13236
+    Category: hTxn,
+    //line sql.y: 13237
+    Text: `PREPARE TRANSACTION <transaction-id>
+`,
+    //line sql.y: 13238
+    SeeAlso: `COMMIT PREPARED, ROLLBACK PREPARED
+`,
+  },
+  //line sql.y: 13245
+  `COMMIT PREPARED`: {
+    ShortDescription: `commit the named transaction as part of two-phase commit`,
+    //line sql.y: 13246
+    Category: hTxn,
+    //line sql.y: 13247
+    Text: `COMMIT PREPARED <transaction-id>
+`,
+    //line sql.y: 13248
+    SeeAlso: `PREPARE TRANSACTION, ROLLBACK PREPARED
+`,
+  },
+  //line sql.y: 13255
+  `ROLLBACK PREPARED`: {
+    ShortDescription: `rollback the named transaction as part of two-phase commit`,
+    //line sql.y: 13256
+    Category: hTxn,
+    //line sql.y: 13257
+    Text: `ROLLBACK PREPARED <transaction-id>
+`,
+    //line sql.y: 13258
+    SeeAlso: `PREPARE TRANSACTION, COMMIT PREPARED
+`,
+  },
+  //line sql.y: 13265
   `CREATE DATABASE`: {
     ShortDescription: `create a new database`,
-    //line sql.y: 12066
+    //line sql.y: 13266
     Category: hDDL,
-    //line sql.y: 12067
+    //line sql.y: 13267
     Text: `CREATE DATABASE [IF NOT EXISTS] <name>
 `,
-    //line sql.y: 12068
+    //line sql.y: 13268
     SeeAlso: `WEBDOCS/create-database.html
 `,
   },
-  //line sql.y: 12273
+  //line sql.y: 13473
   `INSERT`: {
     ShortDescription: `create new rows in a table`,
-    //line sql.y: 12274
+    //line sql.y: 13474
     Category: hDML,
-    //line sql.y: 12275
+    //line sql.y: 13475
     Text: `
 INSERT INTO <tablename> [[AS] <name>] [( <colnames...> )]
        <selectclause>
@@ -2310,31 +2556,31 @@ INSERT INTO <tablename> [[AS] <name>] [( <colnames...> )]
        }
        [RETURNING <exprs...>]
 `,
-    //line sql.y: 12283
+    //line sql.y: 13483
     SeeAlso: `UPSERT, UPDATE, DELETE, WEBDOCS/insert.html
 `,
   },
-  //line sql.y: 12302
+  //line sql.y: 13502
   `UPSERT`: {
     ShortDescription: `create or replace rows in a table`,
-    //line sql.y: 12303
+    //line sql.y: 13503
     Category: hDML,
-    //line sql.y: 12304
+    //line sql.y: 13504
     Text: `
 UPSERT INTO <tablename> [AS <name>] [( <colnames...> )]
        <selectclause>
        [RETURNING <exprs...>]
 `,
-    //line sql.y: 12308
+    //line sql.y: 13508
     SeeAlso: `INSERT, UPDATE, DELETE, WEBDOCS/upsert.html
 `,
   },
-  //line sql.y: 12438
+  //line sql.y: 13642
   `UPDATE`: {
     ShortDescription: `update rows of a table`,
-    //line sql.y: 12439
+    //line sql.y: 13643
     Category: hDML,
-    //line sql.y: 12440
+    //line sql.y: 13644
     Text: `
 UPDATE <tablename> [[AS] <name>]
        SET ...
@@ -2344,42 +2590,42 @@ UPDATE <tablename> [[AS] <name>]
        [LIMIT <expr>]
        [RETURNING <exprs...>]
 `,
-    //line sql.y: 12448
+    //line sql.y: 13652
     SeeAlso: `INSERT, UPSERT, DELETE, WEBDOCS/update.html
 `,
   },
-  //line sql.y: 12504
+  //line sql.y: 13708
   `REASSIGN OWNED BY`: {
     ShortDescription: `change ownership of all objects`,
-    //line sql.y: 12505
+    //line sql.y: 13709
     Category: hPriv,
-    //line sql.y: 12506
+    //line sql.y: 13710
     Text: `REASSIGN OWNED BY {<name> | CURRENT_USER | SESSION_USER}[,...]
 TO {<name> | CURRENT_USER | SESSION_USER}
 `,
-    //line sql.y: 12508
+    //line sql.y: 13712
     SeeAlso: `DROP OWNED BY
 `,
   },
-  //line sql.y: 12519
+  //line sql.y: 13723
   `DROP OWNED BY`: {
     ShortDescription: `remove database objects owned by role(s).`,
-    //line sql.y: 12520
+    //line sql.y: 13724
     Category: hPriv,
-    //line sql.y: 12521
+    //line sql.y: 13725
     Text: `DROP OWNED BY {<name> | CURRENT_USER | SESSION_USER}[,...]
 [RESTRICT | CASCADE]
 `,
-    //line sql.y: 12523
+    //line sql.y: 13727
     SeeAlso: `REASSIGN OWNED BY
 `,
   },
-  //line sql.y: 12703
+  //line sql.y: 13907
   `<SELECTCLAUSE>`: {
     ShortDescription: `access tabular data`,
-    //line sql.y: 12704
+    //line sql.y: 13908
     Category: hDML,
-    //line sql.y: 12705
+    //line sql.y: 13909
     Text: `
 Select clause:
   TABLE <tablename>
@@ -2387,12 +2633,12 @@ Select clause:
   SELECT ... [ { INTERSECT | UNION | EXCEPT } [ ALL | DISTINCT ] <selectclause> ]
 `,
   },
-  //line sql.y: 12716
+  //line sql.y: 13920
   `SELECT`: {
     ShortDescription: `retrieve rows from a data source and compute a result`,
-    //line sql.y: 12717
+    //line sql.y: 13921
     Category: hDML,
-    //line sql.y: 12718
+    //line sql.y: 13922
     Text: `
 SELECT [DISTINCT [ ON ( <expr> [ , ... ] ) ] ]
        { <expr> [[AS] <name>] | [ [<dbname>.] <tablename>. ] * } [, ...]
@@ -2406,40 +2652,40 @@ SELECT [DISTINCT [ ON ( <expr> [ , ... ] ) ] ]
        [ LIMIT { <expr> | ALL } ]
        [ OFFSET <expr> [ ROW | ROWS ] ]
 `,
-    //line sql.y: 12730
+    //line sql.y: 13934
     SeeAlso: `WEBDOCS/select-clause.html
 `,
   },
-  //line sql.y: 12805
+  //line sql.y: 14008
   `TABLE`: {
     ShortDescription: `select an entire table`,
-    //line sql.y: 12806
+    //line sql.y: 14009
     Category: hDML,
-    //line sql.y: 12807
+    //line sql.y: 14010
     Text: `TABLE <tablename>
 `,
-    //line sql.y: 12808
+    //line sql.y: 14011
     SeeAlso: `SELECT, VALUES, WEBDOCS/table-expressions.html
 `,
   },
-  //line sql.y: 13209
+  //line sql.y: 14412
   `VALUES`: {
     ShortDescription: `select a given set of values`,
-    //line sql.y: 13210
+    //line sql.y: 14413
     Category: hDML,
-    //line sql.y: 13211
+    //line sql.y: 14414
     Text: `VALUES ( <exprs...> ) [, ...]
 `,
-    //line sql.y: 13212
+    //line sql.y: 14415
     SeeAlso: `SELECT, TABLE, WEBDOCS/table-expressions.html
 `,
   },
-  //line sql.y: 13353
+  //line sql.y: 14559
   `<SOURCE>`: {
     ShortDescription: `define a data source for SELECT`,
-    //line sql.y: 13354
+    //line sql.y: 14560
     Category: hDML,
-    //line sql.y: 13355
+    //line sql.y: 14561
     Text: `
 Data sources:
   <tablename> [ @ { <idxname> | <indexflags> } ]
@@ -2459,14 +2705,15 @@ Index flags:
   '{' NO_INDEX_JOIN [, ...] '}'
   '{' NO_ZIGZAG_JOIN [, ...] '}'
   '{' NO_FULL_SCAN [, ...] '}'
+  '{' AVOID_FULL_SCAN [, ...] '}'
   '{' IGNORE_FOREIGN_KEYS [, ...] '}'
   '{' FORCE_ZIGZAG = <idxname> [, ...]  '}'
 
 Join types:
-  { INNER | { LEFT | RIGHT | FULL } [OUTER] } [ { HASH | MERGE | LOOKUP | INVERTED } ]
+  { INNER | { LEFT | RIGHT | FULL } [OUTER] } [ { HASH | MERGE | LOOKUP | INVERTED | STRAIGHT } ]
 
 `,
-    //line sql.y: 13380
+    //line sql.y: 14587
     SeeAlso: `WEBDOCS/table-expressions.html
 `,
   },
diff --git a/pkg/sql/parser/lexer.go b/pkg/sql/parser/lexer.go
index 632d35b..8349b3c 100644
--- a/pkg/sql/parser/lexer.go
+++ b/pkg/sql/parser/lexer.go
@@ -1,12 +1,7 @@
 // Copyright 2018 The Cockroach Authors.
 //
-// Use of this software is governed by the Business Source License
-// included in the file licenses/BSL.txt.
-//
-// As of the Change Date specified in that file, in accordance with
-// the Business Source License, use of this software will be governed
-// by the Apache License, Version 2.0, included in the file
-// licenses/APL.txt.
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
 
 package parser
 
@@ -144,6 +139,7 @@ func (l *lexer) Lex(lval *sqlSymType) int {
 		afterCommaOrParen := prevID == ',' || prevID == '('
 		afterCommaOrOPTIONS := prevID == ',' || prevID == OPTIONS
 		afterCommaOrParenThenINVERTED := prevID == INVERTED && (pprevID == ',' || pprevID == '(')
+		afterCommaOrParenThenVECTOR := prevID == VECTOR && (pprevID == ',' || pprevID == '(')
 		followedByParen := nextID == '('
 		followedByNonPunctThenParen := nextID > 255 /* non-punctuation */ && secondID == '('
 		if //
@@ -155,7 +151,10 @@ func (l *lexer) Lex(lval *sqlSymType) int {
 			(afterCommaOrOPTIONS && followedByParen) ||
 			// CREATE ... (INVERTED INDEX (
 			// CREATE ... (x INT, y INT, INVERTED INDEX (
-			(afterCommaOrParenThenINVERTED && followedByParen) {
+			(afterCommaOrParenThenINVERTED && followedByParen) ||
+			// CREATE ... (VECTOR INDEX (
+			// CREATE ... (x INT, y INT, VECTOR INDEX (
+			(afterCommaOrParenThenVECTOR && followedByParen) {
 			lval.id = INDEX_BEFORE_PAREN
 			break
 		}
@@ -165,7 +164,10 @@ func (l *lexer) Lex(lval *sqlSymType) int {
 		(afterCommaOrParen && followedByNonPunctThenParen) ||
 			// CREATE ... (INVERTED INDEX abc (
 			// CREATE ... (x INT, y INT, INVERTED INDEX abc (
-			(afterCommaOrParenThenINVERTED && followedByNonPunctThenParen) {
+			(afterCommaOrParenThenINVERTED && followedByNonPunctThenParen) ||
+			// CREATE ... (VECTOR INDEX abc (
+			// CREATE ... (x INT, y INT, VECTOR INDEX abc (
+			(afterCommaOrParenThenVECTOR && followedByNonPunctThenParen) {
 			lval.id = INDEX_BEFORE_NAME_THEN_PAREN
 			break
 		}
@@ -399,6 +401,16 @@ func (l *lexer) setErr(err error) {
 	l.populateErrorDetails()
 }
 
+// setErrNoDetails is similar to setErr, but is used for an error that should
+// not be further annotated with details. If there is no candidate code for the
+// error, it is annotated with pgcode.Syntax.
+func (l *lexer) setErrNoDetails(err error) {
+	if !pgerror.HasCandidateCode(err) {
+		err = pgerror.WithCandidateCode(err, pgcode.Syntax)
+	}
+	l.lastError = err
+}
+
 func (l *lexer) Error(e string) {
 	e = strings.TrimPrefix(e, "syntax error: ") // we'll add it again below.
 	l.lastError = pgerror.WithCandidateCode(errors.Newf("%s", e), pgcode.Syntax)
diff --git a/pkg/sql/parser/parse.go b/pkg/sql/parser/parse.go
index 4dffe42..b420673 100644
--- a/pkg/sql/parser/parse.go
+++ b/pkg/sql/parser/parse.go
@@ -7,13 +7,8 @@
 //
 // Copyright 2015 The Cockroach Authors.
 //
-// Use of this software is governed by the Business Source License
-// included in the file licenses/BSL.txt.
-//
-// As of the Change Date specified in that file, in accordance with
-// the Business Source License, use of this software will be governed
-// by the Apache License, Version 2.0, included in the file
-// licenses/APL.txt.
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
 
 // This code was derived from https://github.com/youtube/vitess.
 
@@ -68,19 +63,19 @@ func NakedIntTypeFromDefaultIntSize(defaultIntSize int32) *types.T {
 
 // Parse parses the sql and returns a list of statements.
 func (p *Parser) Parse(sql string) (statements.Statements, error) {
-	return p.parseWithDepth(1, sql, defaultNakedIntType)
+	return p.parseWithDepth(1, sql, defaultNakedIntType, discardComments)
 }
 
 // ParseWithInt parses a sql statement string and returns a list of
 // Statements. The INT token will result in the specified TInt type.
 func (p *Parser) ParseWithInt(sql string, nakedIntType *types.T) (statements.Statements, error) {
-	return p.parseWithDepth(1, sql, nakedIntType)
+	return p.parseWithDepth(1, sql, nakedIntType, discardComments)
 }
 
 func (p *Parser) parseOneWithInt(
-	sql string, nakedIntType *types.T,
+	sql string, nakedIntType *types.T, comments commentsMode,
 ) (statements.Statement[tree.Statement], error) {
-	stmts, err := p.parseWithDepth(1, sql, nakedIntType)
+	stmts, err := p.parseWithDepth(1, sql, nakedIntType, comments)
 	if err != nil {
 		return statements.Statement[tree.Statement]{}, err
 	}
@@ -144,11 +139,21 @@ func (p *Parser) scanOneStmt() (sql string, tokens []sqlSymType, done bool) {
 	}
 }
 
+type commentsMode bool
+
+const (
+	retainComments  commentsMode = true
+	discardComments commentsMode = false
+)
+
 func (p *Parser) parseWithDepth(
-	depth int, sql string, nakedIntType *types.T,
+	depth int, sql string, nakedIntType *types.T, cm commentsMode,
 ) (statements.Statements, error) {
 	stmts := statements.Statements(p.stmtBuf[:0])
 	p.scanner.Init(sql)
+	if cm == retainComments {
+		p.scanner.RetainComments()
+	}
 	defer p.scanner.Cleanup()
 	for {
 		sql, tokens, done := p.scanOneStmt()
@@ -232,26 +237,33 @@ func Parse(sql string) (statements.Statements, error) {
 // Statements. The INT token will result in the specified TInt type.
 func ParseWithInt(sql string, nakedIntType *types.T) (statements.Statements, error) {
 	var p Parser
-	return p.parseWithDepth(1, sql, nakedIntType)
+	return p.parseWithDepth(1, sql, nakedIntType, discardComments)
 }
 
 // ParseOne parses a sql statement string, ensuring that it contains only a
 // single statement, and returns that Statement. ParseOne will always
 // interpret the INT and SERIAL types as 64-bit types, since this is
 // used in various internal-execution paths where we might receive
-// bits of SQL from other nodes. In general,earwe expect that all
+// bits of SQL from other nodes. In general, we expect that all
 // user-generated SQL has been run through the ParseWithInt() function.
 func ParseOne(sql string) (statements.Statement[tree.Statement], error) {
 	return ParseOneWithInt(sql, defaultNakedIntType)
 }
 
+// ParseOneRetainComments is similar to ParseOne, but it retains scanned
+// comments in the returned statement's Comment field.
+func ParseOneRetainComments(sql string) (statements.Statement[tree.Statement], error) {
+	var p Parser
+	return p.parseOneWithInt(sql, defaultNakedIntType, retainComments)
+}
+
 // ParseOneWithInt is similar to ParseOn but interprets the INT and SERIAL
 // types as the provided integer type.
 func ParseOneWithInt(
 	sql string, nakedIntType *types.T,
 ) (statements.Statement[tree.Statement], error) {
 	var p Parser
-	return p.parseOneWithInt(sql, nakedIntType)
+	return p.parseOneWithInt(sql, nakedIntType, discardComments)
 }
 
 // ParseQualifiedTableName parses a possibly qualified table name. The
@@ -290,6 +302,26 @@ func ParseTableName(sql string) (*tree.UnresolvedObjectName, error) {
 	return rename.Name, nil
 }
 
+// ParseFunctionName parses a function name. The function name must contain one
+// or more name parts, using the full input SQL syntax: each name
+// part containing special characters, or non-lowercase characters,
+// must be enclosed in double quote. The name may not be an invalid
+// function name (the caller is responsible for guaranteeing that only
+// valid function names are provided as input).
+func ParseFunctionName(sql string) (*tree.UnresolvedObjectName, error) {
+	// We wrap the name we want to parse into a dummy statement since our parser
+	// can only parse full statements.
+	stmt, err := ParseOne(fmt.Sprintf("ALTER FUNCTION %s RENAME TO x", sql))
+	if err != nil {
+		return nil, err
+	}
+	rename, ok := stmt.AST.(*tree.AlterRoutineRename)
+	if !ok {
+		return nil, errors.AssertionFailedf("expected an ALTER FUNCTION statement, but found %T", stmt)
+	}
+	return rename.Function.FuncName.ToUnresolvedObjectName(), nil
+}
+
 // ParseTablePattern parses a table pattern. The table name must contain one
 // or more name parts, using the full input SQL syntax: each name
 // part containing special characters, or non-lowercase characters,
@@ -417,17 +449,18 @@ func GetTypeFromCastOrCollate(expr tree.Expr) (tree.ResolvableTypeReference, err
 	return cast.Type, nil
 }
 
-var errBitLengthNotPositive = pgerror.WithCandidateCode(
-	errors.New("length for type bit must be at least 1"), pgcode.InvalidParameterValue)
+var errVarBitLengthNotPositive = pgerror.WithCandidateCode(
+	errors.New("length for type varbit must be at least 1"), pgcode.InvalidParameterValue)
 
 // newBitType creates a new BIT type with the given bit width.
 func newBitType(width int32, varying bool) (*types.T, error) {
-	if width < 1 {
-		return nil, errBitLengthNotPositive
-	}
 	if varying {
+		if width < 1 {
+			return nil, errVarBitLengthNotPositive
+		}
 		return types.MakeVarBit(width), nil
 	}
+	// The iconst32 pattern in the parser guarantees that the width is positive.
 	return types.MakeBit(width), nil
 }
 
@@ -469,12 +502,11 @@ func arrayOf(
 	// If the reference is a statically known type, then return an array type,
 	// rather than an array type reference.
 	if typ, ok := tree.GetStaticallyKnownType(ref); ok {
-		// Do not allow type unknown[]. This is consistent with Postgres' behavior.
-		if typ.Family() == types.UnknownFamily {
-			return nil, pgerror.Newf(pgcode.UndefinedObject, "type unknown[] does not exist")
-		}
-		if typ.Family() == types.VoidFamily {
-			return nil, pgerror.Newf(pgcode.UndefinedObject, "type void[] does not exist")
+		switch typ.Family() {
+		case types.UnknownFamily, types.VoidFamily, types.TriggerFamily:
+			// Do not allow arrays of these types. This is consistent with Postgres'
+			// behavior.
+			return nil, pgerror.Newf(pgcode.UndefinedObject, "type %s[] does not exist", typ.Name())
 		}
 		if err := types.CheckArrayElementType(typ); err != nil {
 			return nil, err
@@ -483,3 +515,6 @@ func arrayOf(
 	}
 	return &tree.ArrayTypeReference{ElementType: ref}, nil
 }
+
+// ParseDoBlockFn allows the SQL parser to parse a PL/pgSQL DO block body.
+var ParseDoBlockFn func(tree.DoBlockOptions) (tree.DoBlockBody, error)
diff --git a/pkg/sql/parser/scanner.go b/pkg/sql/parser/scanner.go
index d6b6d4b..c4ef72b 100644
--- a/pkg/sql/parser/scanner.go
+++ b/pkg/sql/parser/scanner.go
@@ -1,12 +1,7 @@
 // Copyright 2021 The Cockroach Authors.
 //
-// Use of this software is governed by the Business Source License
-// included in the file licenses/BSL.txt.
-//
-// As of the Change Date specified in that file, in accordance with
-// the Business Source License, use of this software will be governed
-// by the Apache License, Version 2.0, included in the file
-// licenses/APL.txt.
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
 
 package parser
 
@@ -56,21 +51,6 @@ func Tokens(sql string) (tokens []TokenString, ok bool) {
 	return tokens, true
 }
 
-// TokensIgnoreErrors decomposes the input into lexical tokens and
-// ignores errors.
-func TokensIgnoreErrors(sql string) (tokens []TokenString) {
-	s := makeSQLScanner(sql)
-	for {
-		var lval = &sqlSymType{}
-		s.Scan(lval)
-		if lval.ID() == 0 {
-			break
-		}
-		tokens = append(tokens, TokenString{TokenID: lval.ID(), Str: lval.Str()})
-	}
-	return tokens
-}
-
 // TokenString is the unit value returned by Tokens.
 type TokenString struct {
 	TokenID int32
diff --git a/pkg/sql/parser/show_syntax.go b/pkg/sql/parser/show_syntax.go
index 4c00e8f..719a0b6 100644
--- a/pkg/sql/parser/show_syntax.go
+++ b/pkg/sql/parser/show_syntax.go
@@ -1,12 +1,7 @@
 // Copyright 2019 The Cockroach Authors.
 //
-// Use of this software is governed by the Business Source License
-// included in the file licenses/BSL.txt.
-//
-// As of the Change Date specified in that file, in accordance with
-// the Business Source License, use of this software will be governed
-// by the Apache License, Version 2.0, included in the file
-// licenses/APL.txt.
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
 
 package parser
 
diff --git a/pkg/sql/parser/sql.go b/pkg/sql/parser/sql.go
index 0284688..439cc5b 100644
--- a/pkg/sql/parser/sql.go
+++ b/pkg/sql/parser/sql.go
@@ -20,11 +20,13 @@ import (
 	"github.com/cockroachdb/cockroachdb-parser/pkg/sql/pgwire/pgerror"
 	"github.com/cockroachdb/cockroachdb-parser/pkg/sql/privilege"
 	"github.com/cockroachdb/cockroachdb-parser/pkg/sql/scanner"
+	"github.com/cockroachdb/cockroachdb-parser/pkg/sql/sem/idxtype"
 	"github.com/cockroachdb/cockroachdb-parser/pkg/sql/sem/tree"
 	"github.com/cockroachdb/cockroachdb-parser/pkg/sql/sem/tree/treebin"
 	"github.com/cockroachdb/cockroachdb-parser/pkg/sql/sem/tree/treecmp"
 	"github.com/cockroachdb/cockroachdb-parser/pkg/sql/sem/tree/treewindow"
 	"github.com/cockroachdb/cockroachdb-parser/pkg/sql/types"
+	"github.com/cockroachdb/cockroachdb-parser/pkg/util/vector"
 	"github.com/cockroachdb/errors"
 	"github.com/lib/pq/oid"
 )
@@ -48,6 +50,11 @@ func setErr(sqllex sqlLexer, err error) int {
 	return 1
 }
 
+func setErrNoDetails(sqllex sqlLexer, err error) int {
+	sqllex.(*lexer).setErrNoDetails(err)
+	return 1
+}
+
 func unimplementedWithIssue(sqllex sqlLexer, issue int) int {
 	sqllex.(*lexer).UnimplementedWithIssue(issue)
 	return 1
@@ -143,7 +150,7 @@ func processUnaryQualOpInternal(
 	return nil, 1
 }
 
-//line sql-gen.y:168
+//line sql-gen.y:175
 
 var _ scanner.ScanSymType = &sqlSymType{}
 
@@ -340,8 +347,8 @@ func (u *sqlSymUnion) storageParams() []tree.StorageParam {
 	}
 	return nil
 }
-func (u *sqlSymUnion) storageParamKeys() []tree.Name {
-	if params, ok := u.val.([]tree.Name); ok {
+func (u *sqlSymUnion) storageParamKeys() []string {
+	if params, ok := u.val.([]string); ok {
 		return params
 	}
 	return nil
@@ -583,6 +590,24 @@ func (u *sqlSymUnion) indexInvisibility() tree.IndexInvisibility {
 func (u *sqlSymUnion) dropBehavior() tree.DropBehavior {
 	return u.val.(tree.DropBehavior)
 }
+func (u *sqlSymUnion) rlsTableMode() tree.TableRLSMode {
+	return u.val.(tree.TableRLSMode)
+}
+func (u *sqlSymUnion) alterPolicy() tree.AlterPolicy {
+	return u.val.(tree.AlterPolicy)
+}
+func (u *sqlSymUnion) createPolicy() tree.CreatePolicy {
+	return u.val.(tree.CreatePolicy)
+}
+func (u *sqlSymUnion) policyType() tree.PolicyType {
+	return u.val.(tree.PolicyType)
+}
+func (u *sqlSymUnion) policyCommand() tree.PolicyCommand {
+	return u.val.(tree.PolicyCommand)
+}
+func (u *sqlSymUnion) policyExpressions() tree.PolicyExpressions {
+	return u.val.(tree.PolicyExpressions)
+}
 func (u *sqlSymUnion) validationBehavior() tree.ValidationBehavior {
 	return u.val.(tree.ValidationBehavior)
 }
@@ -661,6 +686,9 @@ func (u *sqlSymUnion) showBackupDetails() tree.ShowBackupDetails {
 func (u *sqlSymUnion) showBackupOptions() *tree.ShowBackupOptions {
 	return u.val.(*tree.ShowBackupOptions)
 }
+func (u *sqlSymUnion) checkExternalConnectionOptions() *tree.CheckExternalConnectionOptions {
+	return u.val.(*tree.CheckExternalConnectionOptions)
+}
 func (u *sqlSymUnion) restoreOptions() *tree.RestoreOptions {
 	return u.val.(*tree.RestoreOptions)
 }
@@ -809,23 +837,59 @@ func (u *sqlSymUnion) showRangesOpts() *tree.ShowRangesOptions {
 func (u *sqlSymUnion) tenantSpec() *tree.TenantSpec {
 	return u.val.(*tree.TenantSpec)
 }
-func (u *sqlSymUnion) likeTenantSpec() *tree.LikeTenantSpec {
-	return u.val.(*tree.LikeTenantSpec)
-}
 func (u *sqlSymUnion) cteMaterializeClause() tree.CTEMaterializeClause {
 	return u.val.(tree.CTEMaterializeClause)
 }
 func (u *sqlSymUnion) showTenantOpts() tree.ShowTenantOptions {
 	return u.val.(tree.ShowTenantOptions)
 }
+func (u *sqlSymUnion) showLogicalReplicationJobsOpts() tree.ShowLogicalReplicationJobsOptions {
+	return u.val.(tree.ShowLogicalReplicationJobsOptions)
+}
 func (u *sqlSymUnion) showCreateFormatOption() tree.ShowCreateFormatOption {
 	return u.val.(tree.ShowCreateFormatOption)
 }
 func (u *sqlSymUnion) beginTransaction() *tree.BeginTransaction {
 	return u.val.(*tree.BeginTransaction)
 }
+func (u *sqlSymUnion) showFingerprintOptions() *tree.ShowFingerprintOptions {
+	return u.val.(*tree.ShowFingerprintOptions)
+}
+func (u *sqlSymUnion) logicalReplicationResources() tree.LogicalReplicationResources {
+	return u.val.(tree.LogicalReplicationResources)
+}
+func (u *sqlSymUnion) logicalReplicationOptions() *tree.LogicalReplicationOptions {
+	return u.val.(*tree.LogicalReplicationOptions)
+}
+func (u *sqlSymUnion) triggerActionTime() tree.TriggerActionTime {
+	return u.val.(tree.TriggerActionTime)
+}
+func (u *sqlSymUnion) triggerEvent() *tree.TriggerEvent {
+	return u.val.(*tree.TriggerEvent)
+}
+func (u *sqlSymUnion) triggerEvents() []*tree.TriggerEvent {
+	return u.val.([]*tree.TriggerEvent)
+}
+func (u *sqlSymUnion) triggerTransition() *tree.TriggerTransition {
+	return u.val.(*tree.TriggerTransition)
+}
+func (u *sqlSymUnion) triggerTransitions() []*tree.TriggerTransition {
+	return u.val.([]*tree.TriggerTransition)
+}
+func (u *sqlSymUnion) triggerForEach() tree.TriggerForEach {
+	return u.val.(tree.TriggerForEach)
+}
+func (u *sqlSymUnion) indexType() idxtype.T {
+	return u.val.(idxtype.T)
+}
+func (u *sqlSymUnion) doBlockOptions() tree.DoBlockOptions {
+	return u.val.(tree.DoBlockOptions)
+}
+func (u *sqlSymUnion) doBlockOption() tree.DoBlockOption {
+	return u.val.(tree.DoBlockOption)
+}
 
-//line sql-gen.y:1044
+//line sql-gen.y:1108
 type sqlSymType struct {
 	yys   int
 	id    int32
@@ -881,646 +945,679 @@ const ATTRIBUTE = 57389
 const AUTHORIZATION = 57390
 const AUTOMATIC = 57391
 const AVAILABILITY = 57392
-const BACKUP = 57393
-const BACKUPS = 57394
-const BACKWARD = 57395
-const BATCH = 57396
-const BEFORE = 57397
-const BEGIN = 57398
-const BETWEEN = 57399
-const BIGINT = 57400
-const BIGSERIAL = 57401
-const BINARY = 57402
-const BIT = 57403
-const BUCKET_COUNT = 57404
-const BOOLEAN = 57405
-const BOTH = 57406
-const BOX2D = 57407
-const BUNDLE = 57408
-const BY = 57409
-const CACHE = 57410
-const CALL = 57411
-const CALLED = 57412
-const CANCEL = 57413
-const CANCELQUERY = 57414
-const CAPABILITIES = 57415
-const CAPABILITY = 57416
-const CASCADE = 57417
-const CASE = 57418
-const CAST = 57419
-const CBRT = 57420
-const CHANGEFEED = 57421
-const CHAR = 57422
-const CHARACTER = 57423
-const CHARACTERISTICS = 57424
-const CHECK = 57425
-const CHECK_FILES = 57426
-const CLOSE = 57427
-const CLUSTER = 57428
-const CLUSTERS = 57429
-const COALESCE = 57430
-const COLLATE = 57431
-const COLLATION = 57432
-const COLUMN = 57433
-const COLUMNS = 57434
-const COMMENT = 57435
-const COMMENTS = 57436
-const COMMIT = 57437
-const COMMITTED = 57438
-const COMPACT = 57439
-const COMPLETE = 57440
-const COMPLETIONS = 57441
-const CONCAT = 57442
-const CONCURRENTLY = 57443
-const CONFIGURATION = 57444
-const CONFIGURATIONS = 57445
-const CONFIGURE = 57446
-const CONFLICT = 57447
-const CONNECTION = 57448
-const CONNECTIONS = 57449
-const CONSTRAINT = 57450
-const CONSTRAINTS = 57451
-const CONTAINS = 57452
-const CONTROLCHANGEFEED = 57453
-const CONTROLJOB = 57454
-const CONVERSION = 57455
-const CONVERT = 57456
-const COPY = 57457
-const COST = 57458
-const COVERING = 57459
-const CREATE = 57460
-const CREATEDB = 57461
-const CREATELOGIN = 57462
-const CREATEROLE = 57463
-const CROSS = 57464
-const CSV = 57465
-const CUBE = 57466
-const CURRENT = 57467
-const CURRENT_CATALOG = 57468
-const CURRENT_DATE = 57469
-const CURRENT_SCHEMA = 57470
-const CURRENT_ROLE = 57471
-const CURRENT_TIME = 57472
-const CURRENT_TIMESTAMP = 57473
-const CURRENT_USER = 57474
-const CURSOR = 57475
-const CYCLE = 57476
-const DATA = 57477
-const DATABASE = 57478
-const DATABASES = 57479
-const DATE = 57480
-const DAY = 57481
-const DEBUG_IDS = 57482
-const DEBUG_PAUSE_ON = 57483
-const DEC = 57484
-const DEBUG_DUMP_METADATA_SST = 57485
-const DECIMAL = 57486
-const DEFAULT = 57487
-const DEFAULTS = 57488
-const DEFINER = 57489
-const DEALLOCATE = 57490
-const DECLARE = 57491
-const DEFERRABLE = 57492
-const DEFERRED = 57493
-const DELETE = 57494
-const DELIMITER = 57495
-const DEPENDS = 57496
-const DESC = 57497
-const DESTINATION = 57498
-const DETACHED = 57499
-const DETAILS = 57500
-const DISCARD = 57501
-const DISTINCT = 57502
-const DO = 57503
-const DOMAIN = 57504
-const DOUBLE = 57505
-const DROP = 57506
-const ELSE = 57507
-const ENCODING = 57508
-const ENCRYPTED = 57509
-const ENCRYPTION_INFO_DIR = 57510
-const ENCRYPTION_PASSPHRASE = 57511
-const END = 57512
-const ENUM = 57513
-const ENUMS = 57514
-const ESCAPE = 57515
-const EXCEPT = 57516
-const EXCLUDE = 57517
-const EXCLUDING = 57518
-const EXISTS = 57519
-const EXECUTE = 57520
-const EXECUTION = 57521
-const EXPERIMENTAL = 57522
-const EXPERIMENTAL_FINGERPRINTS = 57523
-const EXPERIMENTAL_REPLICA = 57524
-const EXPERIMENTAL_AUDIT = 57525
-const EXPERIMENTAL_RELOCATE = 57526
-const EXPIRATION = 57527
-const EXPLAIN = 57528
-const EXPORT = 57529
-const EXTENSION = 57530
-const EXTERNAL = 57531
-const EXTRACT = 57532
-const EXTRACT_DURATION = 57533
-const EXTREMES = 57534
-const FAILURE = 57535
-const FALSE = 57536
-const FAMILY = 57537
-const FETCH = 57538
-const FETCHVAL = 57539
-const FETCHTEXT = 57540
-const FETCHVAL_PATH = 57541
-const FETCHTEXT_PATH = 57542
-const FILES = 57543
-const FILTER = 57544
-const FIRST = 57545
-const FLOAT = 57546
-const FLOAT4 = 57547
-const FLOAT8 = 57548
-const FLOORDIV = 57549
-const FOLLOWING = 57550
-const FOR = 57551
-const FORCE = 57552
-const FORCE_INDEX = 57553
-const FORCE_NOT_NULL = 57554
-const FORCE_NULL = 57555
-const FORCE_QUOTE = 57556
-const FORCE_ZIGZAG = 57557
-const FOREIGN = 57558
-const FORMAT = 57559
-const FORWARD = 57560
-const FREEZE = 57561
-const FROM = 57562
-const FULL = 57563
-const FUNCTION = 57564
-const FUNCTIONS = 57565
-const GENERATED = 57566
-const GEOGRAPHY = 57567
-const GEOMETRY = 57568
-const GEOMETRYM = 57569
-const GEOMETRYZ = 57570
-const GEOMETRYZM = 57571
-const GEOMETRYCOLLECTION = 57572
-const GEOMETRYCOLLECTIONM = 57573
-const GEOMETRYCOLLECTIONZ = 57574
-const GEOMETRYCOLLECTIONZM = 57575
-const GLOBAL = 57576
-const GOAL = 57577
-const GRANT = 57578
-const GRANTEE = 57579
-const GRANTS = 57580
-const GREATEST = 57581
-const GROUP = 57582
-const GROUPING = 57583
-const GROUPS = 57584
-const HAVING = 57585
-const HASH = 57586
-const HEADER = 57587
-const HIGH = 57588
-const HISTOGRAM = 57589
-const HOLD = 57590
-const HOUR = 57591
-const IDENTITY = 57592
-const IF = 57593
-const IFERROR = 57594
-const IFNULL = 57595
-const IGNORE_FOREIGN_KEYS = 57596
-const ILIKE = 57597
-const IMMEDIATE = 57598
-const IMMUTABLE = 57599
-const IMPORT = 57600
-const IN = 57601
-const INCLUDE = 57602
-const INCLUDING = 57603
-const INCLUDE_ALL_SECONDARY_TENANTS = 57604
-const INCLUDE_ALL_VIRTUAL_CLUSTERS = 57605
-const INCREMENT = 57606
-const INCREMENTAL = 57607
-const INCREMENTAL_LOCATION = 57608
-const INET = 57609
-const INET_CONTAINED_BY_OR_EQUALS = 57610
-const INET_CONTAINS_OR_EQUALS = 57611
-const INDEX = 57612
-const INDEXES = 57613
-const INHERITS = 57614
-const INJECT = 57615
-const INITIALLY = 57616
-const INDEX_BEFORE_PAREN = 57617
-const INDEX_BEFORE_NAME_THEN_PAREN = 57618
-const INDEX_AFTER_ORDER_BY_BEFORE_AT = 57619
-const INNER = 57620
-const INOUT = 57621
-const INPUT = 57622
-const INSENSITIVE = 57623
-const INSERT = 57624
-const INT = 57625
-const INTEGER = 57626
-const INTERSECT = 57627
-const INTERVAL = 57628
-const INTO = 57629
-const INTO_DB = 57630
-const INVERTED = 57631
-const INVOKER = 57632
-const IS = 57633
-const ISERROR = 57634
-const ISNULL = 57635
-const ISOLATION = 57636
-const JOB = 57637
-const JOBS = 57638
-const JOIN = 57639
-const JSON = 57640
-const JSONB = 57641
-const JSON_SOME_EXISTS = 57642
-const JSON_ALL_EXISTS = 57643
-const KEY = 57644
-const KEYS = 57645
-const KMS = 57646
-const KV = 57647
-const LABEL = 57648
-const LANGUAGE = 57649
-const LAST = 57650
-const LATERAL = 57651
-const LATEST = 57652
-const LC_CTYPE = 57653
-const LC_COLLATE = 57654
-const LEADING = 57655
-const LEASE = 57656
-const LEAST = 57657
-const LEAKPROOF = 57658
-const LEFT = 57659
-const LESS = 57660
-const LEVEL = 57661
-const LIKE = 57662
-const LIMIT = 57663
-const LINESTRING = 57664
-const LINESTRINGM = 57665
-const LINESTRINGZ = 57666
-const LINESTRINGZM = 57667
-const LIST = 57668
-const LOCAL = 57669
-const LOCALITY = 57670
-const LOCALTIME = 57671
-const LOCALTIMESTAMP = 57672
-const LOCKED = 57673
-const LOGIN = 57674
-const LOOKUP = 57675
-const LOW = 57676
-const LSHIFT = 57677
-const MATCH = 57678
-const MATERIALIZED = 57679
-const MERGE = 57680
-const MINVALUE = 57681
-const MAXVALUE = 57682
-const METHOD = 57683
-const MINUTE = 57684
-const MODIFYCLUSTERSETTING = 57685
-const MODIFYSQLCLUSTERSETTING = 57686
-const MONTH = 57687
-const MOVE = 57688
-const MULTILINESTRING = 57689
-const MULTILINESTRINGM = 57690
-const MULTILINESTRINGZ = 57691
-const MULTILINESTRINGZM = 57692
-const MULTIPOINT = 57693
-const MULTIPOINTM = 57694
-const MULTIPOINTZ = 57695
-const MULTIPOINTZM = 57696
-const MULTIPOLYGON = 57697
-const MULTIPOLYGONM = 57698
-const MULTIPOLYGONZ = 57699
-const MULTIPOLYGONZM = 57700
-const NAN = 57701
-const NAME = 57702
-const NAMES = 57703
-const NATURAL = 57704
-const NEVER = 57705
-const NEW_DB_NAME = 57706
-const NEW_KMS = 57707
-const NEXT = 57708
-const NO = 57709
-const NOCANCELQUERY = 57710
-const NOCONTROLCHANGEFEED = 57711
-const NOCONTROLJOB = 57712
-const NOCREATEDB = 57713
-const NOCREATELOGIN = 57714
-const NOCREATEROLE = 57715
-const NOLOGIN = 57716
-const NOMODIFYCLUSTERSETTING = 57717
-const NOREPLICATION = 57718
-const NOSQLLOGIN = 57719
-const NO_INDEX_JOIN = 57720
-const NO_ZIGZAG_JOIN = 57721
-const NO_FULL_SCAN = 57722
-const NONE = 57723
-const NONVOTERS = 57724
-const NORMAL = 57725
-const NOT = 57726
-const NOTHING = 57727
-const NOTHING_AFTER_RETURNING = 57728
-const NOTNULL = 57729
-const NOVIEWACTIVITY = 57730
-const NOVIEWACTIVITYREDACTED = 57731
-const NOVIEWCLUSTERSETTING = 57732
-const NOWAIT = 57733
-const NULL = 57734
-const NULLIF = 57735
-const NULLS = 57736
-const NUMERIC = 57737
-const OF = 57738
-const OFF = 57739
-const OFFSET = 57740
-const OID = 57741
-const OIDS = 57742
-const OIDVECTOR = 57743
-const OLD_KMS = 57744
-const ON = 57745
-const ONLY = 57746
-const OPT = 57747
-const OPTION = 57748
-const OPTIONS = 57749
-const OR = 57750
-const ORDER = 57751
-const ORDINALITY = 57752
-const OTHERS = 57753
-const OUT = 57754
-const OUTER = 57755
-const OVER = 57756
-const OVERLAPS = 57757
-const OVERLAY = 57758
-const OWNED = 57759
-const OWNER = 57760
-const OPERATOR = 57761
-const PARALLEL = 57762
-const PARENT = 57763
-const PARTIAL = 57764
-const PARTITION = 57765
-const PARTITIONS = 57766
-const PASSWORD = 57767
-const PAUSE = 57768
-const PAUSED = 57769
-const PHYSICAL = 57770
-const PLACEMENT = 57771
-const PLACING = 57772
-const PLAN = 57773
-const PLANS = 57774
-const POINT = 57775
-const POINTM = 57776
-const POINTZ = 57777
-const POINTZM = 57778
-const POLYGON = 57779
-const POLYGONM = 57780
-const POLYGONZ = 57781
-const POLYGONZM = 57782
-const POSITION = 57783
-const PRECEDING = 57784
-const PRECISION = 57785
-const PREPARE = 57786
-const PRESERVE = 57787
-const PRIMARY = 57788
-const PRIOR = 57789
-const PRIORITY = 57790
-const PRIVILEGES = 57791
-const PROCEDURAL = 57792
-const PROCEDURE = 57793
-const PROCEDURES = 57794
-const PUBLIC = 57795
-const PUBLICATION = 57796
-const QUERIES = 57797
-const QUERY = 57798
-const QUOTE = 57799
-const RANGE = 57800
-const RANGES = 57801
-const READ = 57802
-const REAL = 57803
-const REASON = 57804
-const REASSIGN = 57805
-const RECURSIVE = 57806
-const RECURRING = 57807
-const REDACT = 57808
-const REF = 57809
-const REFERENCES = 57810
-const REFRESH = 57811
-const REGCLASS = 57812
-const REGION = 57813
-const REGIONAL = 57814
-const REGIONS = 57815
-const REGNAMESPACE = 57816
-const REGPROC = 57817
-const REGPROCEDURE = 57818
-const REGROLE = 57819
-const REGTYPE = 57820
-const REINDEX = 57821
-const RELATIVE = 57822
-const RELOCATE = 57823
-const REMOVE_PATH = 57824
-const REMOVE_REGIONS = 57825
-const RENAME = 57826
-const REPEATABLE = 57827
-const REPLACE = 57828
-const REPLICATION = 57829
-const RELEASE = 57830
-const RESET = 57831
-const RESTART = 57832
-const RESTORE = 57833
-const RESTRICT = 57834
-const RESTRICTED = 57835
-const RESUME = 57836
-const RETENTION = 57837
-const RETURNING = 57838
-const RETURN = 57839
-const RETURNS = 57840
-const RETRY = 57841
-const REVISION_HISTORY = 57842
-const REVOKE = 57843
-const RIGHT = 57844
-const ROLE = 57845
-const ROLES = 57846
-const ROLLBACK = 57847
-const ROLLUP = 57848
-const ROUTINES = 57849
-const ROW = 57850
-const ROWS = 57851
-const RSHIFT = 57852
-const RULE = 57853
-const RUNNING = 57854
-const SAVEPOINT = 57855
-const SCANS = 57856
-const SCATTER = 57857
-const SCHEDULE = 57858
-const SCHEDULES = 57859
-const SCROLL = 57860
-const SCHEMA = 57861
-const SCHEMA_ONLY = 57862
-const SCHEMAS = 57863
-const SCRUB = 57864
-const SEARCH = 57865
-const SECOND = 57866
-const SECONDARY = 57867
-const SECURITY = 57868
-const SELECT = 57869
-const SEQUENCE = 57870
-const SEQUENCES = 57871
-const SERIALIZABLE = 57872
-const SERVER = 57873
-const SERVICE = 57874
-const SESSION = 57875
-const SESSIONS = 57876
-const SESSION_USER = 57877
-const SET = 57878
-const SETOF = 57879
-const SETS = 57880
-const SETTING = 57881
-const SETTINGS = 57882
-const SHARE = 57883
-const SHARED = 57884
-const SHOW = 57885
-const SIMILAR = 57886
-const SIMPLE = 57887
-const SIZE = 57888
-const SKIP = 57889
-const SKIP_LOCALITIES_CHECK = 57890
-const SKIP_MISSING_FOREIGN_KEYS = 57891
-const SKIP_MISSING_SEQUENCES = 57892
-const SKIP_MISSING_SEQUENCE_OWNERS = 57893
-const SKIP_MISSING_VIEWS = 57894
-const SKIP_MISSING_UDFS = 57895
-const SMALLINT = 57896
-const SMALLSERIAL = 57897
-const SNAPSHOT = 57898
-const SOME = 57899
-const SPLIT = 57900
-const SQL = 57901
-const SQLLOGIN = 57902
-const STABLE = 57903
-const START = 57904
-const STATE = 57905
-const STATISTICS = 57906
-const STATUS = 57907
-const STDIN = 57908
-const STDOUT = 57909
-const STOP = 57910
-const STREAM = 57911
-const STRICT = 57912
-const STRING = 57913
-const STORAGE = 57914
-const STORE = 57915
-const STORED = 57916
-const STORING = 57917
-const SUBSTRING = 57918
-const SUPER = 57919
-const SUPPORT = 57920
-const SURVIVE = 57921
-const SURVIVAL = 57922
-const SYMMETRIC = 57923
-const SYNTAX = 57924
-const SYSTEM = 57925
-const SQRT = 57926
-const SUBSCRIPTION = 57927
-const STATEMENTS = 57928
-const TABLE = 57929
-const TABLES = 57930
-const TABLESPACE = 57931
-const TEMP = 57932
-const TEMPLATE = 57933
-const TEMPORARY = 57934
-const TENANT = 57935
-const TENANT_NAME = 57936
-const TENANTS = 57937
-const TESTING_RELOCATE = 57938
-const TEXT = 57939
-const THEN = 57940
-const TIES = 57941
-const TIME = 57942
-const TIMETZ = 57943
-const TIMESTAMP = 57944
-const TIMESTAMPTZ = 57945
-const TO = 57946
-const THROTTLING = 57947
-const TRAILING = 57948
-const TRACE = 57949
-const TRANSACTION = 57950
-const TRANSACTIONS = 57951
-const TRANSFER = 57952
-const TRANSFORM = 57953
-const TREAT = 57954
-const TRIGGER = 57955
-const TRIM = 57956
-const TRUE = 57957
-const TRUNCATE = 57958
-const TRUSTED = 57959
-const TYPE = 57960
-const TYPES = 57961
-const TRACING = 57962
-const UNBOUNDED = 57963
-const UNCOMMITTED = 57964
-const UNION = 57965
-const UNIQUE = 57966
-const UNKNOWN = 57967
-const UNLISTEN = 57968
-const UNLOGGED = 57969
-const UNSAFE_RESTORE_INCOMPATIBLE_VERSION = 57970
-const UNSPLIT = 57971
-const UPDATE = 57972
-const UPDATES_CLUSTER_MONITORING_METRICS = 57973
-const UPSERT = 57974
-const UNSET = 57975
-const UNTIL = 57976
-const USE = 57977
-const USER = 57978
-const USERS = 57979
-const USING = 57980
-const UUID = 57981
-const VALID = 57982
-const VALIDATE = 57983
-const VALUE = 57984
-const VALUES = 57985
-const VARBIT = 57986
-const VARCHAR = 57987
-const VARIADIC = 57988
-const VERIFY_BACKUP_TABLE_DATA = 57989
-const VIEW = 57990
-const VARYING = 57991
-const VIEWACTIVITY = 57992
-const VIEWACTIVITYREDACTED = 57993
-const VIEWDEBUG = 57994
-const VIEWCLUSTERMETADATA = 57995
-const VIEWCLUSTERSETTING = 57996
-const VIRTUAL = 57997
-const VISIBLE = 57998
-const INVISIBLE = 57999
-const VISIBILITY = 58000
-const VOLATILE = 58001
-const VOTERS = 58002
-const VIRTUAL_CLUSTER_NAME = 58003
-const VIRTUAL_CLUSTER = 58004
-const WHEN = 58005
-const WHERE = 58006
-const WINDOW = 58007
-const WITH = 58008
-const WITHIN = 58009
-const WITHOUT = 58010
-const WORK = 58011
-const WRITE = 58012
-const YEAR = 58013
-const ZONE = 58014
-const NOT_LA = 58015
-const NULLS_LA = 58016
-const WITH_LA = 58017
-const AS_LA = 58018
-const GENERATED_ALWAYS = 58019
-const GENERATED_BY_DEFAULT = 58020
-const RESET_ALL = 58021
-const ROLE_ALL = 58022
-const USER_ALL = 58023
-const ON_LA = 58024
-const TENANT_ALL = 58025
-const CLUSTER_ALL = 58026
-const SET_TRACING = 58027
-const CONTAINED_BY = 58028
-const POSTFIXOP = 58029
-const INTERVAL_SIMPLE = 58030
-const UMINUS = 58031
-const HELPTOKEN = 58032
+const AVOID_FULL_SCAN = 57393
+const BACKUP = 57394
+const BACKUPS = 57395
+const BACKWARD = 57396
+const BATCH = 57397
+const BEFORE = 57398
+const BEGIN = 57399
+const BETWEEN = 57400
+const BIDIRECTIONAL = 57401
+const BIGINT = 57402
+const BIGSERIAL = 57403
+const BINARY = 57404
+const BIT = 57405
+const BUCKET_COUNT = 57406
+const BOOLEAN = 57407
+const BOTH = 57408
+const BOX2D = 57409
+const BUNDLE = 57410
+const BY = 57411
+const BYPASSRLS = 57412
+const CACHE = 57413
+const CALL = 57414
+const CALLED = 57415
+const CANCEL = 57416
+const CANCELQUERY = 57417
+const CAPABILITIES = 57418
+const CAPABILITY = 57419
+const CASCADE = 57420
+const CASE = 57421
+const CAST = 57422
+const CBRT = 57423
+const CHANGEFEED = 57424
+const CHAR = 57425
+const CHARACTER = 57426
+const CHARACTERISTICS = 57427
+const CHECK = 57428
+const CHECK_FILES = 57429
+const CLOSE = 57430
+const CLUSTER = 57431
+const CLUSTERS = 57432
+const COALESCE = 57433
+const COLLATE = 57434
+const COLLATION = 57435
+const COLUMN = 57436
+const COLUMNS = 57437
+const COMMENT = 57438
+const COMMENTS = 57439
+const COMMIT = 57440
+const COMMITTED = 57441
+const COMPACT = 57442
+const COMPLETE = 57443
+const COMPLETIONS = 57444
+const CONCAT = 57445
+const CONCURRENTLY = 57446
+const CONFIGURATION = 57447
+const CONFIGURATIONS = 57448
+const CONFIGURE = 57449
+const CONFLICT = 57450
+const CONNECTION = 57451
+const CONNECTIONS = 57452
+const CONSTRAINT = 57453
+const CONSTRAINTS = 57454
+const CONTAINS = 57455
+const CONTROLCHANGEFEED = 57456
+const CONTROLJOB = 57457
+const CONVERSION = 57458
+const CONVERT = 57459
+const COPY = 57460
+const COS_DISTANCE = 57461
+const COST = 57462
+const COVERING = 57463
+const CREATE = 57464
+const CREATEDB = 57465
+const CREATELOGIN = 57466
+const CREATEROLE = 57467
+const CROSS = 57468
+const CSV = 57469
+const CUBE = 57470
+const CURRENT = 57471
+const CURRENT_CATALOG = 57472
+const CURRENT_DATE = 57473
+const CURRENT_SCHEMA = 57474
+const CURRENT_ROLE = 57475
+const CURRENT_TIME = 57476
+const CURRENT_TIMESTAMP = 57477
+const CURRENT_USER = 57478
+const CURSOR = 57479
+const CYCLE = 57480
+const DATA = 57481
+const DATABASE = 57482
+const DATABASES = 57483
+const DATE = 57484
+const DAY = 57485
+const DEBUG_IDS = 57486
+const DEC = 57487
+const DECIMAL = 57488
+const DEFAULT = 57489
+const DEFAULTS = 57490
+const DEFINER = 57491
+const DEALLOCATE = 57492
+const DECLARE = 57493
+const DEFERRABLE = 57494
+const DEFERRED = 57495
+const DELETE = 57496
+const DELIMITER = 57497
+const DEPENDS = 57498
+const DESC = 57499
+const DESTINATION = 57500
+const DETACHED = 57501
+const DETAILS = 57502
+const DISABLE = 57503
+const DISCARD = 57504
+const DISTANCE = 57505
+const DISTINCT = 57506
+const DO = 57507
+const DOMAIN = 57508
+const DOUBLE = 57509
+const DROP = 57510
+const EACH = 57511
+const ELSE = 57512
+const ENABLE = 57513
+const ENCODING = 57514
+const ENCRYPTED = 57515
+const ENCRYPTION_INFO_DIR = 57516
+const ENCRYPTION_PASSPHRASE = 57517
+const END = 57518
+const ENUM = 57519
+const ENUMS = 57520
+const ESCAPE = 57521
+const EXCEPT = 57522
+const EXCLUDE = 57523
+const EXCLUDING = 57524
+const EXISTS = 57525
+const EXECUTE = 57526
+const EXECUTION = 57527
+const EXPERIMENTAL = 57528
+const EXPERIMENTAL_FINGERPRINTS = 57529
+const EXPERIMENTAL_REPLICA = 57530
+const EXPERIMENTAL_AUDIT = 57531
+const EXPERIMENTAL_RELOCATE = 57532
+const EXPIRATION = 57533
+const EXPLAIN = 57534
+const EXPORT = 57535
+const EXTENSION = 57536
+const EXTERNAL = 57537
+const EXTRACT = 57538
+const EXTRACT_DURATION = 57539
+const EXTREMES = 57540
+const FAILURE = 57541
+const FALSE = 57542
+const FAMILY = 57543
+const FETCH = 57544
+const FETCHVAL = 57545
+const FETCHTEXT = 57546
+const FETCHVAL_PATH = 57547
+const FETCHTEXT_PATH = 57548
+const FILES = 57549
+const FILTER = 57550
+const FIRST = 57551
+const FLOAT = 57552
+const FLOAT4 = 57553
+const FLOAT8 = 57554
+const FLOORDIV = 57555
+const FOLLOWING = 57556
+const FOR = 57557
+const FORCE = 57558
+const FORCE_INDEX = 57559
+const FORCE_INVERTED_INDEX = 57560
+const FORCE_NOT_NULL = 57561
+const FORCE_NULL = 57562
+const FORCE_QUOTE = 57563
+const FORCE_ZIGZAG = 57564
+const FOREIGN = 57565
+const FORMAT = 57566
+const FORWARD = 57567
+const FREEZE = 57568
+const FROM = 57569
+const FULL = 57570
+const FUNCTION = 57571
+const FUNCTIONS = 57572
+const GENERATED = 57573
+const GEOGRAPHY = 57574
+const GEOMETRY = 57575
+const GEOMETRYM = 57576
+const GEOMETRYZ = 57577
+const GEOMETRYZM = 57578
+const GEOMETRYCOLLECTION = 57579
+const GEOMETRYCOLLECTIONM = 57580
+const GEOMETRYCOLLECTIONZ = 57581
+const GEOMETRYCOLLECTIONZM = 57582
+const GLOBAL = 57583
+const GOAL = 57584
+const GRANT = 57585
+const GRANTEE = 57586
+const GRANTS = 57587
+const GREATEST = 57588
+const GROUP = 57589
+const GROUPING = 57590
+const GROUPS = 57591
+const HAVING = 57592
+const HASH = 57593
+const HEADER = 57594
+const HIGH = 57595
+const HISTOGRAM = 57596
+const HOLD = 57597
+const HOUR = 57598
+const IDENTITY = 57599
+const IF = 57600
+const IFERROR = 57601
+const IFNULL = 57602
+const IGNORE_FOREIGN_KEYS = 57603
+const ILIKE = 57604
+const IMMEDIATE = 57605
+const IMMEDIATELY = 57606
+const IMMUTABLE = 57607
+const IMPORT = 57608
+const IN = 57609
+const INCLUDE = 57610
+const INCLUDING = 57611
+const INCLUDE_ALL_SECONDARY_TENANTS = 57612
+const INCLUDE_ALL_VIRTUAL_CLUSTERS = 57613
+const INCREMENT = 57614
+const INCREMENTAL = 57615
+const INCREMENTAL_LOCATION = 57616
+const INET = 57617
+const INET_CONTAINED_BY_OR_EQUALS = 57618
+const INET_CONTAINS_OR_EQUALS = 57619
+const INDEX = 57620
+const INDEXES = 57621
+const INHERITS = 57622
+const INJECT = 57623
+const INITIALLY = 57624
+const INDEX_BEFORE_PAREN = 57625
+const INDEX_BEFORE_NAME_THEN_PAREN = 57626
+const INDEX_AFTER_ORDER_BY_BEFORE_AT = 57627
+const INNER = 57628
+const INOUT = 57629
+const INPUT = 57630
+const INSENSITIVE = 57631
+const INSERT = 57632
+const INSTEAD = 57633
+const INT = 57634
+const INTEGER = 57635
+const INTERSECT = 57636
+const INTERVAL = 57637
+const INTO = 57638
+const INTO_DB = 57639
+const INVERTED = 57640
+const INVOKER = 57641
+const IS = 57642
+const ISERROR = 57643
+const ISNULL = 57644
+const ISOLATION = 57645
+const JOB = 57646
+const JOBS = 57647
+const JOIN = 57648
+const JSON = 57649
+const JSONB = 57650
+const JSON_SOME_EXISTS = 57651
+const JSON_ALL_EXISTS = 57652
+const KEY = 57653
+const KEYS = 57654
+const KMS = 57655
+const KV = 57656
+const LABEL = 57657
+const LANGUAGE = 57658
+const LAST = 57659
+const LATERAL = 57660
+const LATEST = 57661
+const LC_CTYPE = 57662
+const LC_COLLATE = 57663
+const LEADING = 57664
+const LEASE = 57665
+const LEAST = 57666
+const LEAKPROOF = 57667
+const LEFT = 57668
+const LESS = 57669
+const LEVEL = 57670
+const LIKE = 57671
+const LIMIT = 57672
+const LINESTRING = 57673
+const LINESTRINGM = 57674
+const LINESTRINGZ = 57675
+const LINESTRINGZM = 57676
+const LIST = 57677
+const LOCAL = 57678
+const LOCALITY = 57679
+const LOCALTIME = 57680
+const LOCALTIMESTAMP = 57681
+const LOCKED = 57682
+const LOGICAL = 57683
+const LOGICALLY = 57684
+const LOGIN = 57685
+const LOOKUP = 57686
+const LOW = 57687
+const LSHIFT = 57688
+const MATCH = 57689
+const MATERIALIZED = 57690
+const MERGE = 57691
+const MINVALUE = 57692
+const MAXVALUE = 57693
+const METHOD = 57694
+const MINUTE = 57695
+const MODIFYCLUSTERSETTING = 57696
+const MODIFYSQLCLUSTERSETTING = 57697
+const MODE = 57698
+const MONTH = 57699
+const MOVE = 57700
+const MULTILINESTRING = 57701
+const MULTILINESTRINGM = 57702
+const MULTILINESTRINGZ = 57703
+const MULTILINESTRINGZM = 57704
+const MULTIPOINT = 57705
+const MULTIPOINTM = 57706
+const MULTIPOINTZ = 57707
+const MULTIPOINTZM = 57708
+const MULTIPOLYGON = 57709
+const MULTIPOLYGONM = 57710
+const MULTIPOLYGONZ = 57711
+const MULTIPOLYGONZM = 57712
+const NAN = 57713
+const NAME = 57714
+const NAMES = 57715
+const NATURAL = 57716
+const NEG_INNER_PRODUCT = 57717
+const NEVER = 57718
+const NEW = 57719
+const NEW_DB_NAME = 57720
+const NEW_KMS = 57721
+const NEXT = 57722
+const NO = 57723
+const NOBYPASSRLS = 57724
+const NOCANCELQUERY = 57725
+const NOCONTROLCHANGEFEED = 57726
+const NOCONTROLJOB = 57727
+const NOCREATEDB = 57728
+const NOCREATELOGIN = 57729
+const NOCREATEROLE = 57730
+const NODE = 57731
+const NOLOGIN = 57732
+const NOMODIFYCLUSTERSETTING = 57733
+const NOREPLICATION = 57734
+const NOSQLLOGIN = 57735
+const NO_INDEX_JOIN = 57736
+const NO_ZIGZAG_JOIN = 57737
+const NO_FULL_SCAN = 57738
+const NONE = 57739
+const NONVOTERS = 57740
+const NORMAL = 57741
+const NOT = 57742
+const NOTHING = 57743
+const NOTHING_AFTER_RETURNING = 57744
+const NOTNULL = 57745
+const NOVIEWACTIVITY = 57746
+const NOVIEWACTIVITYREDACTED = 57747
+const NOVIEWCLUSTERSETTING = 57748
+const NOWAIT = 57749
+const NULL = 57750
+const NULLIF = 57751
+const NULLS = 57752
+const NUMERIC = 57753
+const OF = 57754
+const OFF = 57755
+const OFFSET = 57756
+const OID = 57757
+const OIDS = 57758
+const OIDVECTOR = 57759
+const OLD = 57760
+const OLD_KMS = 57761
+const ON = 57762
+const ONLY = 57763
+const OPT = 57764
+const OPTION = 57765
+const OPTIONS = 57766
+const OR = 57767
+const ORDER = 57768
+const ORDINALITY = 57769
+const OTHERS = 57770
+const OUT = 57771
+const OUTER = 57772
+const OVER = 57773
+const OVERLAPS = 57774
+const OVERLAY = 57775
+const OWNED = 57776
+const OWNER = 57777
+const OPERATOR = 57778
+const PARALLEL = 57779
+const PARENT = 57780
+const PARTIAL = 57781
+const PARTITION = 57782
+const PARTITIONS = 57783
+const PASSWORD = 57784
+const PAUSE = 57785
+const PAUSED = 57786
+const PER = 57787
+const PERMISSIVE = 57788
+const PHYSICAL = 57789
+const PLACEMENT = 57790
+const PLACING = 57791
+const PLAN = 57792
+const PLANS = 57793
+const POINT = 57794
+const POINTM = 57795
+const POINTZ = 57796
+const POINTZM = 57797
+const POLICIES = 57798
+const POLICY = 57799
+const POLYGON = 57800
+const POLYGONM = 57801
+const POLYGONZ = 57802
+const POLYGONZM = 57803
+const POSITION = 57804
+const PRECEDING = 57805
+const PRECISION = 57806
+const PREPARE = 57807
+const PREPARED = 57808
+const PRESERVE = 57809
+const PRIMARY = 57810
+const PRIOR = 57811
+const PRIORITY = 57812
+const PRIVILEGES = 57813
+const PROCEDURAL = 57814
+const PROCEDURE = 57815
+const PROCEDURES = 57816
+const PUBLIC = 57817
+const PUBLICATION = 57818
+const QUERIES = 57819
+const QUERY = 57820
+const QUOTE = 57821
+const RANGE = 57822
+const RANGES = 57823
+const READ = 57824
+const REAL = 57825
+const REASON = 57826
+const REASSIGN = 57827
+const RECURSIVE = 57828
+const RECURRING = 57829
+const REDACT = 57830
+const REF = 57831
+const REFERENCES = 57832
+const REFERENCING = 57833
+const REFRESH = 57834
+const REGCLASS = 57835
+const REGION = 57836
+const REGIONAL = 57837
+const REGIONS = 57838
+const REGNAMESPACE = 57839
+const REGPROC = 57840
+const REGPROCEDURE = 57841
+const REGROLE = 57842
+const REGTYPE = 57843
+const REINDEX = 57844
+const RELATIVE = 57845
+const RELOCATE = 57846
+const REMOVE_PATH = 57847
+const REMOVE_REGIONS = 57848
+const RENAME = 57849
+const REPEATABLE = 57850
+const REPLACE = 57851
+const REPLICATED = 57852
+const REPLICATION = 57853
+const RELEASE = 57854
+const RESET = 57855
+const RESTART = 57856
+const RESTORE = 57857
+const RESTRICT = 57858
+const RESTRICTED = 57859
+const RESTRICTIVE = 57860
+const RESUME = 57861
+const RETENTION = 57862
+const RETURNING = 57863
+const RETURN = 57864
+const RETURNS = 57865
+const RETRY = 57866
+const REVISION_HISTORY = 57867
+const REVOKE = 57868
+const RIGHT = 57869
+const ROLE = 57870
+const ROLES = 57871
+const ROLLBACK = 57872
+const ROLLUP = 57873
+const ROUTINES = 57874
+const ROW = 57875
+const ROWS = 57876
+const RSHIFT = 57877
+const RULE = 57878
+const RUNNING = 57879
+const SAVEPOINT = 57880
+const SCANS = 57881
+const SCATTER = 57882
+const SCHEDULE = 57883
+const SCHEDULES = 57884
+const SCROLL = 57885
+const SCHEMA = 57886
+const SCHEMA_ONLY = 57887
+const SCHEMAS = 57888
+const SCRUB = 57889
+const SEARCH = 57890
+const SECOND = 57891
+const SECONDARY = 57892
+const SECURITY = 57893
+const SELECT = 57894
+const SEQUENCE = 57895
+const SEQUENCES = 57896
+const SERIALIZABLE = 57897
+const SERVER = 57898
+const SERVICE = 57899
+const SESSION = 57900
+const SESSIONS = 57901
+const SESSION_USER = 57902
+const SET = 57903
+const SETOF = 57904
+const SETS = 57905
+const SETTING = 57906
+const SETTINGS = 57907
+const SHARE = 57908
+const SHARED = 57909
+const SHOW = 57910
+const SIMILAR = 57911
+const SIMPLE = 57912
+const SIZE = 57913
+const SKIP = 57914
+const SKIP_LOCALITIES_CHECK = 57915
+const SKIP_MISSING_FOREIGN_KEYS = 57916
+const SKIP_MISSING_SEQUENCES = 57917
+const SKIP_MISSING_SEQUENCE_OWNERS = 57918
+const SKIP_MISSING_VIEWS = 57919
+const SKIP_MISSING_UDFS = 57920
+const SMALLINT = 57921
+const SMALLSERIAL = 57922
+const SNAPSHOT = 57923
+const SOME = 57924
+const SOURCE = 57925
+const SPLIT = 57926
+const SQL = 57927
+const SQLLOGIN = 57928
+const STABLE = 57929
+const START = 57930
+const STATE = 57931
+const STATEMENT = 57932
+const STATISTICS = 57933
+const STATUS = 57934
+const STDIN = 57935
+const STDOUT = 57936
+const STOP = 57937
+const STRAIGHT = 57938
+const STREAM = 57939
+const STRICT = 57940
+const STRING = 57941
+const STORAGE = 57942
+const STORE = 57943
+const STORED = 57944
+const STORING = 57945
+const SUBJECT = 57946
+const SUBSTRING = 57947
+const SUPER = 57948
+const SUPPORT = 57949
+const SURVIVE = 57950
+const SURVIVAL = 57951
+const SYMMETRIC = 57952
+const SYNTAX = 57953
+const SYSTEM = 57954
+const SQRT = 57955
+const SUBSCRIPTION = 57956
+const STATEMENTS = 57957
+const TABLE = 57958
+const TABLES = 57959
+const TABLESPACE = 57960
+const TEMP = 57961
+const TEMPLATE = 57962
+const TEMPORARY = 57963
+const TENANT = 57964
+const TENANT_NAME = 57965
+const TENANTS = 57966
+const TESTING_RELOCATE = 57967
+const TEXT = 57968
+const THEN = 57969
+const TIES = 57970
+const TIME = 57971
+const TIMETZ = 57972
+const TIMESTAMP = 57973
+const TIMESTAMPTZ = 57974
+const TO = 57975
+const THROTTLING = 57976
+const TRAILING = 57977
+const TRACE = 57978
+const TRANSACTION = 57979
+const TRANSACTIONS = 57980
+const TRANSFER = 57981
+const TRANSFORM = 57982
+const TREAT = 57983
+const TRIGGER = 57984
+const TRIGGERS = 57985
+const TRIM = 57986
+const TRUE = 57987
+const TRUNCATE = 57988
+const TRUSTED = 57989
+const TYPE = 57990
+const TYPES = 57991
+const TRACING = 57992
+const UNBOUNDED = 57993
+const UNCOMMITTED = 57994
+const UNIDIRECTIONAL = 57995
+const UNION = 57996
+const UNIQUE = 57997
+const UNKNOWN = 57998
+const UNLISTEN = 57999
+const UNLOGGED = 58000
+const UNSAFE_RESTORE_INCOMPATIBLE_VERSION = 58001
+const UNSPLIT = 58002
+const UPDATE = 58003
+const UPDATES_CLUSTER_MONITORING_METRICS = 58004
+const UPSERT = 58005
+const UNSET = 58006
+const UNTIL = 58007
+const USE = 58008
+const USER = 58009
+const USERS = 58010
+const USING = 58011
+const UUID = 58012
+const VALID = 58013
+const VALIDATE = 58014
+const VALUE = 58015
+const VALUES = 58016
+const VARBIT = 58017
+const VARCHAR = 58018
+const VARIADIC = 58019
+const VECTOR = 58020
+const VERIFY_BACKUP_TABLE_DATA = 58021
+const VIEW = 58022
+const VARIABLES = 58023
+const VARYING = 58024
+const VIEWACTIVITY = 58025
+const VIEWACTIVITYREDACTED = 58026
+const VIEWDEBUG = 58027
+const VIEWCLUSTERMETADATA = 58028
+const VIEWCLUSTERSETTING = 58029
+const VIRTUAL = 58030
+const VISIBLE = 58031
+const INVISIBLE = 58032
+const VISIBILITY = 58033
+const VOLATILE = 58034
+const VOTERS = 58035
+const VIRTUAL_CLUSTER_NAME = 58036
+const VIRTUAL_CLUSTER = 58037
+const WHEN = 58038
+const WHERE = 58039
+const WINDOW = 58040
+const WITH = 58041
+const WITHIN = 58042
+const WITHOUT = 58043
+const WORK = 58044
+const WRITE = 58045
+const YEAR = 58046
+const ZONE = 58047
+const NOT_LA = 58048
+const NULLS_LA = 58049
+const WITH_LA = 58050
+const AS_LA = 58051
+const GENERATED_ALWAYS = 58052
+const GENERATED_BY_DEFAULT = 58053
+const RESET_ALL = 58054
+const ROLE_ALL = 58055
+const USER_ALL = 58056
+const ON_LA = 58057
+const TENANT_ALL = 58058
+const CLUSTER_ALL = 58059
+const SET_TRACING = 58060
+const CONTAINED_BY = 58061
+const POSTFIXOP = 58062
+const INTERVAL_SIMPLE = 58063
+const UMINUS = 58064
+const HELPTOKEN = 58065
 
 var sqlToknames = [...]string{
 	"$end",
@@ -1573,6 +1670,7 @@ var sqlToknames = [...]string{
 	"AUTHORIZATION",
 	"AUTOMATIC",
 	"AVAILABILITY",
+	"AVOID_FULL_SCAN",
 	"BACKUP",
 	"BACKUPS",
 	"BACKWARD",
@@ -1580,6 +1678,7 @@ var sqlToknames = [...]string{
 	"BEFORE",
 	"BEGIN",
 	"BETWEEN",
+	"BIDIRECTIONAL",
 	"BIGINT",
 	"BIGSERIAL",
 	"BINARY",
@@ -1590,6 +1689,7 @@ var sqlToknames = [...]string{
 	"BOX2D",
 	"BUNDLE",
 	"BY",
+	"BYPASSRLS",
 	"CACHE",
 	"CALL",
 	"CALLED",
@@ -1638,6 +1738,7 @@ var sqlToknames = [...]string{
 	"CONVERSION",
 	"CONVERT",
 	"COPY",
+	"COS_DISTANCE",
 	"COST",
 	"COVERING",
 	"CREATE",
@@ -1663,9 +1764,7 @@ var sqlToknames = [...]string{
 	"DATE",
 	"DAY",
 	"DEBUG_IDS",
-	"DEBUG_PAUSE_ON",
 	"DEC",
-	"DEBUG_DUMP_METADATA_SST",
 	"DECIMAL",
 	"DEFAULT",
 	"DEFAULTS",
@@ -1681,13 +1780,17 @@ var sqlToknames = [...]string{
 	"DESTINATION",
 	"DETACHED",
 	"DETAILS",
+	"DISABLE",
 	"DISCARD",
+	"DISTANCE",
 	"DISTINCT",
 	"DO",
 	"DOMAIN",
 	"DOUBLE",
 	"DROP",
+	"EACH",
 	"ELSE",
+	"ENABLE",
 	"ENCODING",
 	"ENCRYPTED",
 	"ENCRYPTION_INFO_DIR",
@@ -1734,6 +1837,7 @@ var sqlToknames = [...]string{
 	"FOR",
 	"FORCE",
 	"FORCE_INDEX",
+	"FORCE_INVERTED_INDEX",
 	"FORCE_NOT_NULL",
 	"FORCE_NULL",
 	"FORCE_QUOTE",
@@ -1779,6 +1883,7 @@ var sqlToknames = [...]string{
 	"IGNORE_FOREIGN_KEYS",
 	"ILIKE",
 	"IMMEDIATE",
+	"IMMEDIATELY",
 	"IMMUTABLE",
 	"IMPORT",
 	"IN",
@@ -1805,6 +1910,7 @@ var sqlToknames = [...]string{
 	"INPUT",
 	"INSENSITIVE",
 	"INSERT",
+	"INSTEAD",
 	"INT",
 	"INTEGER",
 	"INTERSECT",
@@ -1854,6 +1960,8 @@ var sqlToknames = [...]string{
 	"LOCALTIME",
 	"LOCALTIMESTAMP",
 	"LOCKED",
+	"LOGICAL",
+	"LOGICALLY",
 	"LOGIN",
 	"LOOKUP",
 	"LOW",
@@ -1867,6 +1975,7 @@ var sqlToknames = [...]string{
 	"MINUTE",
 	"MODIFYCLUSTERSETTING",
 	"MODIFYSQLCLUSTERSETTING",
+	"MODE",
 	"MONTH",
 	"MOVE",
 	"MULTILINESTRING",
@@ -1885,17 +1994,21 @@ var sqlToknames = [...]string{
 	"NAME",
 	"NAMES",
 	"NATURAL",
+	"NEG_INNER_PRODUCT",
 	"NEVER",
+	"NEW",
 	"NEW_DB_NAME",
 	"NEW_KMS",
 	"NEXT",
 	"NO",
+	"NOBYPASSRLS",
 	"NOCANCELQUERY",
 	"NOCONTROLCHANGEFEED",
 	"NOCONTROLJOB",
 	"NOCREATEDB",
 	"NOCREATELOGIN",
 	"NOCREATEROLE",
+	"NODE",
 	"NOLOGIN",
 	"NOMODIFYCLUSTERSETTING",
 	"NOREPLICATION",
@@ -1924,6 +2037,7 @@ var sqlToknames = [...]string{
 	"OID",
 	"OIDS",
 	"OIDVECTOR",
+	"OLD",
 	"OLD_KMS",
 	"ON",
 	"ONLY",
@@ -1950,6 +2064,8 @@ var sqlToknames = [...]string{
 	"PASSWORD",
 	"PAUSE",
 	"PAUSED",
+	"PER",
+	"PERMISSIVE",
 	"PHYSICAL",
 	"PLACEMENT",
 	"PLACING",
@@ -1959,6 +2075,8 @@ var sqlToknames = [...]string{
 	"POINTM",
 	"POINTZ",
 	"POINTZM",
+	"POLICIES",
+	"POLICY",
 	"POLYGON",
 	"POLYGONM",
 	"POLYGONZ",
@@ -1967,6 +2085,7 @@ var sqlToknames = [...]string{
 	"PRECEDING",
 	"PRECISION",
 	"PREPARE",
+	"PREPARED",
 	"PRESERVE",
 	"PRIMARY",
 	"PRIOR",
@@ -1991,6 +2110,7 @@ var sqlToknames = [...]string{
 	"REDACT",
 	"REF",
 	"REFERENCES",
+	"REFERENCING",
 	"REFRESH",
 	"REGCLASS",
 	"REGION",
@@ -2009,6 +2129,7 @@ var sqlToknames = [...]string{
 	"RENAME",
 	"REPEATABLE",
 	"REPLACE",
+	"REPLICATED",
 	"REPLICATION",
 	"RELEASE",
 	"RESET",
@@ -2016,6 +2137,7 @@ var sqlToknames = [...]string{
 	"RESTORE",
 	"RESTRICT",
 	"RESTRICTED",
+	"RESTRICTIVE",
 	"RESUME",
 	"RETENTION",
 	"RETURNING",
@@ -2080,17 +2202,20 @@ var sqlToknames = [...]string{
 	"SMALLSERIAL",
 	"SNAPSHOT",
 	"SOME",
+	"SOURCE",
 	"SPLIT",
 	"SQL",
 	"SQLLOGIN",
 	"STABLE",
 	"START",
 	"STATE",
+	"STATEMENT",
 	"STATISTICS",
 	"STATUS",
 	"STDIN",
 	"STDOUT",
 	"STOP",
+	"STRAIGHT",
 	"STREAM",
 	"STRICT",
 	"STRING",
@@ -2098,6 +2223,7 @@ var sqlToknames = [...]string{
 	"STORE",
 	"STORED",
 	"STORING",
+	"SUBJECT",
 	"SUBSTRING",
 	"SUPER",
 	"SUPPORT",
@@ -2136,6 +2262,7 @@ var sqlToknames = [...]string{
 	"TRANSFORM",
 	"TREAT",
 	"TRIGGER",
+	"TRIGGERS",
 	"TRIM",
 	"TRUE",
 	"TRUNCATE",
@@ -2145,6 +2272,7 @@ var sqlToknames = [...]string{
 	"TRACING",
 	"UNBOUNDED",
 	"UNCOMMITTED",
+	"UNIDIRECTIONAL",
 	"UNION",
 	"UNIQUE",
 	"UNKNOWN",
@@ -2169,8 +2297,10 @@ var sqlToknames = [...]string{
 	"VARBIT",
 	"VARCHAR",
 	"VARIADIC",
+	"VECTOR",
 	"VERIFY_BACKUP_TABLE_DATA",
 	"VIEW",
+	"VARIABLES",
 	"VARYING",
 	"VIEWACTIVITY",
 	"VIEWACTIVITYREDACTED",
@@ -2246,23590 +2376,25685 @@ const sqlEofCode = 1
 const sqlErrCode = 2
 const sqlInitialStackSize = 16
 
-//line sql-gen.y:18061
+//line sql-gen.y:19374
 
 //line yacctab:1
 var sqlExca = [...]int16{
 	-1, 0,
 	1, 5,
-	-2, 2171,
+	-2, 2394,
 	-1, 1,
 	1, -1,
 	-2, 0,
-	-1, 67,
-	307, 668,
+	-1, 70,
+	316, 825,
 	-2, 0,
-	-1, 79,
-	8, 1232,
-	29, 1232,
-	696, 1232,
-	697, 1232,
-	-2, 0,
-	-1, 80,
-	8, 1232,
-	29, 1232,
-	696, 1232,
-	697, 1232,
+	-1, 85,
+	8, 1422,
+	29, 1422,
+	729, 1422,
+	730, 1422,
 	-2, 0,
-	-1, 83,
-	182, 1404,
-	305, 1404,
-	455, 1358,
-	534, 1358,
-	586, 1358,
-	607, 1404,
-	609, 1358,
+	-1, 86,
+	8, 1422,
+	29, 1422,
+	729, 1422,
+	730, 1422,
 	-2, 0,
-	-1, 84,
-	1, 2015,
-	150, 2015,
-	294, 2015,
-	384, 2015,
-	448, 2015,
-	460, 2015,
-	676, 2015,
-	709, 2015,
+	-1, 89,
+	188, 1592,
+	314, 1592,
+	477, 1546,
+	559, 1546,
+	615, 1546,
+	636, 1592,
+	638, 1546,
 	-2, 0,
-	-1, 85,
-	1, 2015,
-	709, 2015,
+	-1, 90,
+	1, 2236,
+	152, 2236,
+	303, 2236,
+	400, 2236,
+	470, 2236,
+	482, 2236,
+	709, 2236,
+	742, 2236,
 	-2, 0,
 	-1, 91,
-	287, 305,
-	604, 305,
-	-2, 0,
-	-1, 106,
-	222, 558,
-	270, 1887,
-	289, 1887,
-	307, 558,
-	450, 558,
-	451, 558,
-	464, 1621,
-	511, 558,
-	528, 1621,
-	587, 1621,
-	617, 558,
-	648, 1621,
+	1, 2236,
+	742, 2236,
 	-2, 0,
-	-1, 114,
-	152, 2171,
-	282, 2171,
-	630, 2171,
-	632, 2171,
+	-1, 97,
+	296, 338,
+	633, 338,
 	-2, 0,
-	-1, 132,
-	174, 2142,
-	196, 2142,
-	209, 2142,
-	285, 2142,
-	321, 2142,
-	398, 2142,
-	409, 2142,
-	623, 2142,
-	-2, 2113,
-	-1, 182,
-	4, 2173,
-	21, 2173,
-	22, 2173,
-	23, 2173,
-	24, 2173,
-	25, 2173,
-	26, 2173,
-	27, 2173,
-	28, 2173,
-	30, 2173,
-	31, 2173,
-	37, 2173,
-	41, 2173,
-	43, 2173,
-	45, 2173,
-	46, 2173,
-	47, 2173,
-	49, 2173,
-	50, 2173,
-	51, 2173,
-	52, 2173,
-	53, 2173,
-	54, 2173,
-	55, 2173,
-	56, 2173,
-	57, 2173,
-	58, 2173,
-	60, 2173,
-	61, 2173,
-	62, 2173,
-	63, 2173,
-	65, 2173,
-	66, 2173,
-	67, 2173,
-	68, 2173,
-	69, 2173,
-	70, 2173,
-	71, 2173,
-	72, 2173,
-	73, 2173,
-	74, 2173,
-	75, 2173,
-	79, 2173,
-	80, 2173,
-	81, 2173,
-	82, 2173,
-	84, 2173,
-	85, 2173,
-	86, 2173,
-	87, 2173,
-	88, 2173,
-	92, 2173,
-	93, 2173,
-	94, 2173,
-	95, 2173,
-	96, 2173,
-	97, 2173,
-	98, 2173,
-	99, 2173,
-	102, 2173,
-	103, 2173,
-	104, 2173,
-	105, 2173,
-	106, 2173,
-	107, 2173,
-	109, 2173,
-	111, 2173,
-	112, 2173,
-	113, 2173,
-	114, 2173,
-	115, 2173,
-	116, 2173,
-	117, 2173,
-	119, 2173,
-	120, 2173,
-	121, 2173,
-	123, 2173,
-	124, 2173,
-	125, 2173,
-	133, 2173,
-	134, 2173,
-	135, 2173,
-	136, 2173,
-	137, 2173,
-	139, 2173,
-	140, 2173,
-	141, 2173,
-	142, 2173,
-	143, 2173,
-	144, 2173,
-	146, 2173,
-	147, 2173,
-	148, 2173,
-	149, 2173,
-	151, 2173,
-	152, 2173,
-	153, 2173,
-	154, 2173,
-	156, 2173,
-	157, 2173,
-	158, 2173,
-	159, 2173,
-	162, 2173,
-	163, 2173,
-	164, 2173,
-	166, 2173,
-	167, 2173,
-	168, 2173,
-	169, 2173,
-	171, 2173,
-	172, 2173,
-	173, 2173,
-	175, 2173,
-	176, 2173,
-	177, 2173,
-	178, 2173,
-	179, 2173,
-	180, 2173,
-	181, 2173,
-	182, 2173,
-	183, 2173,
-	184, 2173,
-	185, 2173,
-	186, 2173,
-	187, 2173,
-	188, 2173,
-	189, 2173,
-	190, 2173,
-	191, 2173,
-	192, 2173,
-	193, 2173,
-	195, 2173,
-	201, 2173,
-	202, 2173,
-	203, 2173,
-	204, 2173,
-	208, 2173,
-	210, 2173,
-	211, 2173,
-	212, 2173,
-	213, 2173,
-	214, 2173,
-	215, 2173,
-	217, 2173,
-	218, 2173,
-	219, 2173,
-	222, 2173,
-	223, 2173,
-	224, 2173,
-	225, 2173,
-	226, 2173,
-	227, 2173,
-	228, 2173,
-	229, 2173,
-	230, 2173,
-	231, 2173,
-	232, 2173,
-	233, 2173,
-	234, 2173,
-	235, 2173,
-	237, 2173,
-	238, 2173,
-	239, 2173,
-	241, 2173,
-	242, 2173,
-	244, 2173,
-	245, 2173,
-	246, 2173,
-	247, 2173,
-	248, 2173,
-	249, 2173,
-	250, 2173,
-	251, 2173,
-	252, 2173,
-	253, 2173,
-	254, 2173,
-	256, 2173,
-	257, 2173,
-	258, 2173,
-	260, 2173,
-	261, 2173,
-	262, 2173,
-	263, 2173,
-	264, 2173,
-	265, 2173,
-	266, 2173,
-	270, 2173,
-	271, 2173,
-	272, 2173,
-	273, 2173,
-	275, 2173,
-	276, 2173,
-	277, 2173,
-	279, 2173,
-	280, 2173,
-	281, 2173,
-	282, 2173,
-	283, 2173,
-	284, 2173,
-	286, 2173,
-	288, 2173,
-	289, 2173,
-	290, 2173,
-	292, 2173,
-	294, 2173,
-	295, 2173,
-	296, 2173,
-	298, 2173,
-	302, 2173,
-	303, 2173,
-	304, 2173,
-	305, 2173,
-	306, 2173,
-	307, 2173,
-	308, 2173,
-	310, 2173,
-	311, 2173,
-	312, 2173,
-	314, 2173,
-	315, 2173,
-	316, 2173,
-	318, 2173,
-	319, 2173,
-	322, 2173,
-	323, 2173,
-	324, 2173,
-	325, 2173,
-	326, 2173,
-	327, 2173,
-	328, 2173,
-	331, 2173,
-	332, 2173,
-	333, 2173,
-	334, 2173,
-	336, 2173,
-	337, 2173,
-	338, 2173,
-	339, 2173,
-	340, 2173,
-	341, 2173,
-	342, 2173,
-	343, 2173,
-	344, 2173,
-	345, 2173,
-	346, 2173,
-	347, 2173,
-	348, 2173,
-	349, 2173,
-	350, 2173,
-	351, 2173,
-	352, 2173,
-	353, 2173,
-	354, 2173,
-	355, 2173,
-	356, 2173,
-	357, 2173,
-	358, 2173,
-	359, 2173,
-	361, 2173,
-	363, 2173,
-	364, 2173,
-	365, 2173,
-	366, 2173,
-	367, 2173,
-	368, 2173,
-	369, 2173,
-	370, 2173,
-	371, 2173,
-	372, 2173,
-	373, 2173,
-	374, 2173,
-	375, 2173,
-	376, 2173,
-	377, 2173,
-	378, 2173,
-	379, 2173,
-	380, 2173,
-	382, 2173,
-	383, 2173,
-	385, 2173,
-	386, 2173,
-	388, 2173,
-	389, 2173,
-	390, 2173,
-	391, 2173,
-	393, 2173,
-	394, 2173,
-	395, 2173,
-	396, 2173,
-	397, 2173,
-	400, 2173,
-	402, 2173,
-	404, 2173,
-	405, 2173,
-	406, 2173,
-	407, 2173,
-	410, 2173,
-	411, 2173,
-	412, 2173,
-	414, 2173,
-	416, 2173,
-	417, 2173,
-	418, 2173,
-	419, 2173,
-	420, 2173,
-	421, 2173,
-	422, 2173,
-	423, 2173,
-	424, 2173,
-	425, 2173,
-	426, 2173,
-	427, 2173,
-	428, 2173,
-	429, 2173,
-	431, 2173,
-	432, 2173,
-	433, 2173,
-	434, 2173,
-	435, 2173,
-	436, 2173,
-	437, 2173,
-	438, 2173,
-	439, 2173,
-	440, 2173,
-	441, 2173,
-	442, 2173,
-	443, 2173,
-	444, 2173,
-	445, 2173,
-	447, 2173,
-	448, 2173,
-	449, 2173,
-	451, 2173,
-	452, 2173,
-	453, 2173,
-	454, 2173,
-	455, 2173,
-	456, 2173,
-	457, 2173,
-	458, 2173,
-	459, 2173,
-	460, 2173,
-	461, 2173,
-	462, 2173,
-	463, 2173,
-	464, 2173,
-	465, 2173,
-	466, 2173,
-	467, 2173,
-	469, 2173,
-	471, 2173,
-	472, 2173,
-	473, 2173,
-	479, 2173,
-	480, 2173,
-	481, 2173,
-	483, 2173,
-	484, 2173,
-	485, 2173,
-	486, 2173,
-	487, 2173,
-	488, 2173,
-	489, 2173,
-	490, 2173,
-	491, 2173,
-	492, 2173,
-	493, 2173,
-	494, 2173,
-	495, 2173,
-	497, 2173,
-	498, 2173,
-	499, 2173,
-	500, 2173,
-	501, 2173,
-	503, 2173,
-	504, 2173,
-	505, 2173,
-	506, 2173,
-	507, 2173,
-	508, 2173,
-	509, 2173,
-	511, 2173,
-	512, 2173,
-	513, 2173,
-	514, 2173,
-	515, 2173,
-	516, 2173,
-	517, 2173,
-	518, 2173,
-	519, 2173,
-	520, 2173,
-	521, 2173,
-	522, 2173,
-	523, 2173,
-	524, 2173,
-	525, 2173,
-	526, 2173,
-	528, 2173,
-	529, 2173,
-	530, 2173,
-	531, 2173,
-	532, 2173,
-	533, 2173,
-	534, 2173,
-	536, 2173,
-	537, 2173,
-	538, 2173,
-	539, 2173,
-	540, 2173,
-	541, 2173,
-	542, 2173,
-	543, 2173,
-	545, 2173,
-	546, 2173,
-	547, 2173,
-	548, 2173,
-	549, 2173,
-	550, 2173,
-	551, 2173,
-	552, 2173,
-	553, 2173,
-	554, 2173,
-	556, 2173,
-	558, 2173,
-	559, 2173,
-	560, 2173,
-	561, 2173,
-	562, 2173,
-	563, 2173,
-	564, 2173,
-	565, 2173,
-	566, 2173,
-	567, 2173,
-	568, 2173,
-	569, 2173,
-	570, 2173,
-	571, 2173,
-	572, 2173,
-	573, 2173,
-	574, 2173,
-	575, 2173,
-	576, 2173,
-	577, 2173,
-	578, 2173,
-	579, 2173,
-	580, 2173,
-	582, 2173,
-	583, 2173,
-	585, 2173,
-	586, 2173,
-	588, 2173,
-	589, 2173,
-	590, 2173,
-	591, 2173,
-	592, 2173,
-	593, 2173,
-	594, 2173,
-	595, 2173,
-	596, 2173,
-	597, 2173,
-	599, 2173,
-	600, 2173,
-	601, 2173,
-	602, 2173,
-	603, 2173,
-	605, 2173,
-	607, 2173,
-	608, 2173,
-	609, 2173,
-	610, 2173,
-	611, 2173,
-	612, 2173,
-	613, 2173,
-	614, 2173,
-	616, 2173,
-	617, 2173,
-	618, 2173,
-	619, 2173,
-	620, 2173,
-	621, 2173,
-	622, 2173,
-	625, 2173,
-	626, 2173,
-	627, 2173,
-	628, 2173,
-	629, 2173,
-	630, 2173,
-	631, 2173,
-	632, 2173,
-	633, 2173,
-	634, 2173,
-	635, 2173,
-	637, 2173,
-	640, 2173,
-	641, 2173,
-	642, 2173,
-	643, 2173,
-	644, 2173,
-	645, 2173,
-	647, 2173,
-	648, 2173,
-	649, 2173,
-	650, 2173,
-	651, 2173,
-	652, 2173,
-	653, 2173,
-	654, 2173,
-	655, 2173,
-	656, 2173,
-	657, 2173,
-	658, 2173,
-	659, 2173,
-	660, 2173,
-	661, 2173,
-	662, 2173,
-	667, 2173,
-	668, 2173,
-	669, 2173,
-	670, 2173,
-	671, 2173,
-	672, 2173,
+	-1, 113,
+	229, 666,
+	278, 2102,
+	298, 2102,
+	316, 666,
+	472, 666,
+	473, 666,
+	486, 1824,
+	536, 666,
+	553, 1824,
+	616, 1824,
+	642, 666,
+	647, 666,
+	678, 2102,
+	680, 1824,
 	-2, 0,
-	-1, 184,
-	1, 2015,
-	709, 2015,
-	712, 2015,
-	-2, 0,
-	-1, 185,
-	1, 2015,
-	604, 2015,
-	709, 2015,
-	712, 2015,
+	-1, 123,
+	154, 2394,
+	290, 2394,
+	661, 2394,
+	663, 2394,
 	-2, 0,
-	-1, 231,
-	174, 2141,
-	196, 2141,
-	209, 2141,
-	285, 2141,
-	321, 2141,
-	398, 2141,
-	409, 2141,
-	623, 2141,
-	-2, 2116,
-	-1, 295,
-	4, 2180,
-	5, 2180,
-	6, 2180,
-	7, 2180,
-	8, 2180,
-	9, 2180,
-	10, 2180,
-	21, 2180,
-	22, 2180,
-	23, 2180,
-	24, 2180,
-	25, 2180,
-	26, 2180,
-	27, 2180,
-	28, 2180,
-	30, 2180,
-	31, 2180,
-	37, 2180,
-	38, 2180,
-	41, 2180,
-	43, 2180,
-	45, 2180,
-	46, 2180,
-	47, 2180,
-	48, 2180,
-	49, 2180,
-	50, 2180,
-	51, 2180,
-	52, 2180,
-	53, 2180,
-	54, 2180,
-	55, 2180,
-	56, 2180,
-	57, 2180,
-	58, 2180,
-	60, 2180,
-	61, 2180,
-	62, 2180,
-	63, 2180,
-	65, 2180,
-	66, 2180,
-	67, 2180,
-	68, 2180,
-	69, 2180,
-	70, 2180,
-	71, 2180,
-	72, 2180,
-	73, 2180,
-	74, 2180,
-	75, 2180,
-	76, 2180,
-	77, 2180,
-	78, 2180,
-	79, 2180,
-	80, 2180,
-	81, 2180,
-	82, 2180,
-	84, 2180,
-	85, 2180,
-	86, 2180,
-	87, 2180,
-	88, 2180,
-	90, 2180,
-	92, 2180,
-	93, 2180,
-	94, 2180,
-	95, 2180,
-	96, 2180,
-	97, 2180,
-	98, 2180,
-	99, 2180,
-	102, 2180,
-	103, 2180,
-	104, 2180,
-	105, 2180,
-	106, 2180,
-	107, 2180,
-	109, 2180,
-	111, 2180,
-	112, 2180,
-	113, 2180,
-	114, 2180,
-	115, 2180,
-	116, 2180,
-	117, 2180,
-	119, 2180,
-	120, 2180,
-	121, 2180,
-	122, 2180,
-	123, 2180,
-	124, 2180,
-	125, 2180,
-	126, 2180,
-	127, 2180,
-	128, 2180,
-	129, 2180,
-	130, 2180,
-	131, 2180,
-	132, 2180,
-	133, 2180,
-	134, 2180,
-	135, 2180,
-	136, 2180,
-	137, 2180,
-	138, 2180,
-	139, 2180,
-	140, 2180,
-	141, 2180,
-	142, 2180,
-	143, 2180,
-	144, 2180,
-	145, 2180,
-	146, 2180,
-	147, 2180,
-	148, 2180,
-	149, 2180,
-	151, 2180,
-	152, 2180,
-	153, 2180,
-	154, 2180,
-	156, 2180,
-	157, 2180,
-	158, 2180,
-	159, 2180,
-	162, 2180,
-	163, 2180,
-	164, 2180,
-	166, 2180,
-	167, 2180,
-	168, 2180,
-	169, 2180,
-	171, 2180,
-	172, 2180,
-	173, 2180,
-	175, 2180,
-	176, 2180,
-	177, 2180,
-	178, 2180,
-	179, 2180,
-	180, 2180,
-	181, 2180,
-	182, 2180,
-	183, 2180,
-	184, 2180,
-	185, 2180,
-	186, 2180,
-	187, 2180,
-	188, 2180,
-	189, 2180,
-	190, 2180,
-	191, 2180,
-	192, 2180,
-	193, 2180,
-	194, 2180,
-	195, 2180,
-	201, 2180,
-	202, 2180,
-	203, 2180,
-	204, 2180,
-	208, 2180,
-	210, 2180,
-	211, 2180,
-	212, 2180,
-	213, 2180,
-	214, 2180,
-	215, 2180,
-	217, 2180,
-	218, 2180,
-	219, 2180,
-	221, 2180,
-	222, 2180,
-	223, 2180,
-	224, 2180,
-	225, 2180,
-	226, 2180,
-	227, 2180,
-	228, 2180,
-	229, 2180,
-	230, 2180,
-	231, 2180,
-	232, 2180,
-	233, 2180,
-	234, 2180,
-	235, 2180,
-	237, 2180,
-	238, 2180,
-	239, 2180,
-	241, 2180,
-	242, 2180,
-	244, 2180,
-	245, 2180,
-	246, 2180,
-	247, 2180,
-	248, 2180,
-	249, 2180,
-	250, 2180,
-	251, 2180,
-	252, 2180,
-	253, 2180,
-	254, 2180,
-	255, 2180,
-	256, 2180,
-	257, 2180,
-	258, 2180,
-	260, 2180,
-	261, 2180,
-	262, 2180,
-	263, 2180,
-	264, 2180,
-	265, 2180,
-	266, 2180,
-	270, 2180,
-	271, 2180,
-	272, 2180,
-	273, 2180,
-	275, 2180,
-	276, 2180,
-	277, 2180,
-	278, 2180,
-	279, 2180,
-	280, 2180,
-	281, 2180,
-	282, 2180,
-	283, 2180,
-	284, 2180,
-	286, 2180,
-	288, 2180,
-	289, 2180,
-	290, 2180,
-	291, 2180,
-	292, 2180,
-	293, 2180,
-	294, 2180,
-	295, 2180,
-	296, 2180,
-	297, 2180,
-	298, 2180,
-	302, 2180,
-	303, 2180,
-	304, 2180,
-	305, 2180,
-	306, 2180,
-	307, 2180,
-	308, 2180,
-	310, 2180,
-	311, 2180,
-	312, 2180,
-	314, 2180,
-	315, 2180,
-	316, 2180,
-	317, 2180,
-	318, 2180,
-	319, 2180,
-	320, 2180,
-	322, 2180,
-	323, 2180,
-	324, 2180,
-	325, 2180,
-	326, 2180,
-	327, 2180,
-	328, 2180,
-	329, 2180,
-	330, 2180,
-	331, 2180,
-	332, 2180,
-	333, 2180,
-	334, 2180,
-	336, 2180,
-	337, 2180,
-	338, 2180,
-	339, 2180,
-	340, 2180,
-	341, 2180,
-	342, 2180,
-	343, 2180,
-	344, 2180,
-	345, 2180,
-	346, 2180,
-	347, 2180,
-	348, 2180,
-	349, 2180,
-	350, 2180,
-	351, 2180,
-	352, 2180,
-	353, 2180,
-	354, 2180,
-	355, 2180,
-	356, 2180,
-	357, 2180,
-	358, 2180,
-	359, 2180,
-	361, 2180,
-	362, 2180,
-	363, 2180,
-	364, 2180,
-	365, 2180,
-	366, 2180,
-	367, 2180,
-	368, 2180,
-	369, 2180,
-	370, 2180,
-	371, 2180,
-	372, 2180,
-	373, 2180,
-	374, 2180,
-	375, 2180,
-	376, 2180,
-	377, 2180,
-	378, 2180,
-	379, 2180,
-	380, 2180,
-	381, 2180,
-	382, 2180,
-	383, 2180,
-	384, 2180,
-	385, 2180,
-	386, 2180,
-	387, 2180,
-	388, 2180,
-	389, 2180,
-	390, 2180,
-	391, 2180,
-	392, 2180,
-	393, 2180,
-	394, 2180,
-	395, 2180,
-	396, 2180,
-	397, 2180,
-	400, 2180,
-	402, 2180,
-	405, 2180,
-	406, 2180,
-	407, 2180,
-	410, 2180,
-	411, 2180,
-	412, 2180,
-	413, 2180,
-	414, 2180,
-	415, 2180,
-	416, 2180,
-	417, 2180,
-	418, 2180,
-	419, 2180,
-	420, 2180,
-	421, 2180,
-	422, 2180,
-	423, 2180,
-	424, 2180,
-	425, 2180,
-	426, 2180,
-	427, 2180,
-	428, 2180,
-	429, 2180,
-	431, 2180,
-	432, 2180,
-	433, 2180,
-	434, 2180,
-	435, 2180,
-	436, 2180,
-	437, 2180,
-	438, 2180,
-	439, 2180,
-	440, 2180,
-	441, 2180,
-	442, 2180,
-	443, 2180,
-	444, 2180,
-	445, 2180,
-	447, 2180,
-	448, 2180,
-	449, 2180,
-	451, 2180,
-	452, 2180,
-	453, 2180,
-	454, 2180,
-	455, 2180,
-	456, 2180,
-	457, 2180,
-	458, 2180,
-	459, 2180,
-	460, 2180,
-	461, 2180,
-	462, 2180,
-	463, 2180,
-	464, 2180,
-	465, 2180,
-	466, 2180,
-	467, 2180,
-	469, 2180,
-	471, 2180,
-	472, 2180,
-	473, 2180,
-	479, 2180,
-	480, 2180,
-	481, 2180,
-	483, 2180,
-	484, 2180,
-	485, 2180,
-	486, 2180,
-	487, 2180,
-	488, 2180,
-	489, 2180,
-	490, 2180,
-	491, 2180,
-	492, 2180,
-	493, 2180,
-	494, 2180,
-	495, 2180,
-	497, 2180,
-	498, 2180,
-	499, 2180,
-	500, 2180,
-	501, 2180,
-	502, 2180,
-	503, 2180,
-	504, 2180,
-	505, 2180,
-	506, 2180,
-	507, 2180,
-	508, 2180,
-	509, 2180,
-	511, 2180,
-	512, 2180,
-	513, 2180,
-	514, 2180,
-	515, 2180,
-	516, 2180,
-	517, 2180,
-	518, 2180,
-	519, 2180,
-	520, 2180,
-	521, 2180,
-	522, 2180,
-	523, 2180,
-	524, 2180,
-	525, 2180,
-	526, 2180,
-	528, 2180,
-	529, 2180,
-	530, 2180,
-	531, 2180,
-	532, 2180,
-	533, 2180,
-	534, 2180,
-	535, 2180,
-	536, 2180,
-	537, 2180,
-	538, 2180,
-	539, 2180,
-	540, 2180,
-	541, 2180,
-	542, 2180,
-	543, 2180,
-	544, 2180,
-	545, 2180,
-	546, 2180,
-	547, 2180,
-	548, 2180,
-	549, 2180,
-	550, 2180,
-	551, 2180,
-	552, 2180,
-	553, 2180,
-	554, 2180,
-	556, 2180,
-	558, 2180,
-	559, 2180,
-	560, 2180,
-	561, 2180,
-	562, 2180,
-	563, 2180,
-	564, 2180,
-	565, 2180,
-	566, 2180,
-	567, 2180,
-	568, 2180,
-	569, 2180,
-	570, 2180,
-	571, 2180,
-	572, 2180,
-	573, 2180,
-	574, 2180,
-	575, 2180,
-	576, 2180,
-	577, 2180,
-	578, 2180,
-	579, 2180,
-	580, 2180,
-	582, 2180,
-	583, 2180,
-	584, 2180,
-	585, 2180,
-	586, 2180,
-	588, 2180,
-	589, 2180,
-	590, 2180,
-	591, 2180,
-	592, 2180,
-	593, 2180,
-	594, 2180,
-	595, 2180,
-	596, 2180,
-	597, 2180,
-	599, 2180,
-	600, 2180,
-	601, 2180,
-	602, 2180,
-	603, 2180,
-	605, 2180,
-	607, 2180,
-	608, 2180,
-	609, 2180,
-	610, 2180,
-	611, 2180,
-	612, 2180,
-	613, 2180,
-	614, 2180,
-	615, 2180,
-	616, 2180,
-	617, 2180,
-	618, 2180,
-	619, 2180,
-	620, 2180,
-	621, 2180,
-	622, 2180,
-	624, 2180,
-	625, 2180,
-	626, 2180,
-	627, 2180,
-	628, 2180,
-	629, 2180,
-	630, 2180,
-	631, 2180,
-	632, 2180,
-	633, 2180,
-	634, 2180,
-	635, 2180,
-	636, 2180,
-	637, 2180,
-	640, 2180,
-	641, 2180,
-	642, 2180,
-	643, 2180,
-	644, 2180,
-	645, 2180,
-	647, 2180,
-	648, 2180,
-	649, 2180,
-	650, 2180,
-	651, 2180,
-	652, 2180,
-	653, 2180,
-	654, 2180,
-	655, 2180,
-	656, 2180,
-	657, 2180,
-	658, 2180,
-	659, 2180,
-	660, 2180,
-	661, 2180,
-	662, 2180,
-	667, 2180,
-	668, 2180,
-	669, 2180,
-	670, 2180,
-	671, 2180,
-	672, 2180,
-	673, 2180,
-	689, 2180,
-	696, 2180,
-	697, 2180,
-	698, 2180,
-	704, 2180,
-	706, 2180,
-	710, 2180,
+	-1, 141,
+	180, 2366,
+	202, 2366,
+	215, 2366,
+	294, 2366,
+	330, 2366,
+	414, 2366,
+	426, 2366,
+	654, 2366,
+	-2, 2337,
+	-1, 196,
+	4, 2396,
+	21, 2396,
+	22, 2396,
+	23, 2396,
+	24, 2396,
+	25, 2396,
+	26, 2396,
+	27, 2396,
+	28, 2396,
+	30, 2396,
+	31, 2396,
+	37, 2396,
+	41, 2396,
+	43, 2396,
+	45, 2396,
+	46, 2396,
+	47, 2396,
+	49, 2396,
+	50, 2396,
+	51, 2396,
+	52, 2396,
+	53, 2396,
+	54, 2396,
+	55, 2396,
+	56, 2396,
+	57, 2396,
+	58, 2396,
+	59, 2396,
+	60, 2396,
+	62, 2396,
+	63, 2396,
+	64, 2396,
+	65, 2396,
+	67, 2396,
+	68, 2396,
+	69, 2396,
+	70, 2396,
+	71, 2396,
+	72, 2396,
+	73, 2396,
+	74, 2396,
+	75, 2396,
+	76, 2396,
+	77, 2396,
+	78, 2396,
+	82, 2396,
+	83, 2396,
+	84, 2396,
+	85, 2396,
+	87, 2396,
+	88, 2396,
+	89, 2396,
+	90, 2396,
+	91, 2396,
+	95, 2396,
+	96, 2396,
+	97, 2396,
+	98, 2396,
+	99, 2396,
+	100, 2396,
+	101, 2396,
+	102, 2396,
+	105, 2396,
+	106, 2396,
+	107, 2396,
+	108, 2396,
+	109, 2396,
+	110, 2396,
+	112, 2396,
+	114, 2396,
+	115, 2396,
+	116, 2396,
+	117, 2396,
+	118, 2396,
+	120, 2396,
+	121, 2396,
+	123, 2396,
+	124, 2396,
+	125, 2396,
+	127, 2396,
+	128, 2396,
+	129, 2396,
+	137, 2396,
+	138, 2396,
+	139, 2396,
+	140, 2396,
+	141, 2396,
+	143, 2396,
+	144, 2396,
+	145, 2396,
+	146, 2396,
+	148, 2396,
+	149, 2396,
+	150, 2396,
+	151, 2396,
+	153, 2396,
+	154, 2396,
+	155, 2396,
+	156, 2396,
+	158, 2396,
+	159, 2396,
+	160, 2396,
+	161, 2396,
+	162, 2396,
+	166, 2396,
+	167, 2396,
+	168, 2396,
+	169, 2396,
+	171, 2396,
+	172, 2396,
+	173, 2396,
+	174, 2396,
+	175, 2396,
+	177, 2396,
+	178, 2396,
+	179, 2396,
+	181, 2396,
+	182, 2396,
+	183, 2396,
+	184, 2396,
+	185, 2396,
+	186, 2396,
+	187, 2396,
+	188, 2396,
+	189, 2396,
+	190, 2396,
+	191, 2396,
+	192, 2396,
+	193, 2396,
+	194, 2396,
+	195, 2396,
+	196, 2396,
+	197, 2396,
+	198, 2396,
+	199, 2396,
+	201, 2396,
+	207, 2396,
+	208, 2396,
+	209, 2396,
+	210, 2396,
+	214, 2396,
+	216, 2396,
+	217, 2396,
+	218, 2396,
+	219, 2396,
+	220, 2396,
+	221, 2396,
+	222, 2396,
+	224, 2396,
+	225, 2396,
+	226, 2396,
+	229, 2396,
+	230, 2396,
+	231, 2396,
+	232, 2396,
+	233, 2396,
+	234, 2396,
+	235, 2396,
+	236, 2396,
+	237, 2396,
+	238, 2396,
+	239, 2396,
+	240, 2396,
+	241, 2396,
+	242, 2396,
+	244, 2396,
+	245, 2396,
+	246, 2396,
+	248, 2396,
+	249, 2396,
+	251, 2396,
+	252, 2396,
+	253, 2396,
+	254, 2396,
+	255, 2396,
+	256, 2396,
+	257, 2396,
+	258, 2396,
+	259, 2396,
+	260, 2396,
+	261, 2396,
+	263, 2396,
+	264, 2396,
+	265, 2396,
+	266, 2396,
+	268, 2396,
+	269, 2396,
+	270, 2396,
+	271, 2396,
+	272, 2396,
+	273, 2396,
+	274, 2396,
+	278, 2396,
+	279, 2396,
+	280, 2396,
+	281, 2396,
+	283, 2396,
+	284, 2396,
+	285, 2396,
+	287, 2396,
+	288, 2396,
+	289, 2396,
+	290, 2396,
+	291, 2396,
+	292, 2396,
+	293, 2396,
+	295, 2396,
+	297, 2396,
+	298, 2396,
+	299, 2396,
+	301, 2396,
+	303, 2396,
+	304, 2396,
+	305, 2396,
+	307, 2396,
+	311, 2396,
+	312, 2396,
+	313, 2396,
+	314, 2396,
+	315, 2396,
+	316, 2396,
+	317, 2396,
+	319, 2396,
+	320, 2396,
+	321, 2396,
+	323, 2396,
+	324, 2396,
+	325, 2396,
+	327, 2396,
+	328, 2396,
+	331, 2396,
+	332, 2396,
+	333, 2396,
+	334, 2396,
+	335, 2396,
+	336, 2396,
+	337, 2396,
+	340, 2396,
+	341, 2396,
+	342, 2396,
+	343, 2396,
+	344, 2396,
+	345, 2396,
+	347, 2396,
+	348, 2396,
+	349, 2396,
+	350, 2396,
+	351, 2396,
+	352, 2396,
+	353, 2396,
+	354, 2396,
+	355, 2396,
+	356, 2396,
+	357, 2396,
+	358, 2396,
+	359, 2396,
+	360, 2396,
+	361, 2396,
+	362, 2396,
+	363, 2396,
+	364, 2396,
+	365, 2396,
+	366, 2396,
+	367, 2396,
+	368, 2396,
+	369, 2396,
+	370, 2396,
+	371, 2396,
+	373, 2396,
+	376, 2396,
+	377, 2396,
+	378, 2396,
+	379, 2396,
+	380, 2396,
+	381, 2396,
+	382, 2396,
+	383, 2396,
+	384, 2396,
+	385, 2396,
+	386, 2396,
+	387, 2396,
+	388, 2396,
+	389, 2396,
+	390, 2396,
+	391, 2396,
+	392, 2396,
+	393, 2396,
+	394, 2396,
+	395, 2396,
+	396, 2396,
+	398, 2396,
+	399, 2396,
+	401, 2396,
+	402, 2396,
+	404, 2396,
+	405, 2396,
+	406, 2396,
+	407, 2396,
+	409, 2396,
+	410, 2396,
+	411, 2396,
+	412, 2396,
+	413, 2396,
+	416, 2396,
+	418, 2396,
+	419, 2396,
+	421, 2396,
+	422, 2396,
+	423, 2396,
+	424, 2396,
+	427, 2396,
+	428, 2396,
+	429, 2396,
+	431, 2396,
+	433, 2396,
+	434, 2396,
+	435, 2396,
+	436, 2396,
+	437, 2396,
+	438, 2396,
+	439, 2396,
+	440, 2396,
+	441, 2396,
+	442, 2396,
+	443, 2396,
+	444, 2396,
+	445, 2396,
+	446, 2396,
+	447, 2396,
+	448, 2396,
+	450, 2396,
+	451, 2396,
+	452, 2396,
+	453, 2396,
+	454, 2396,
+	455, 2396,
+	456, 2396,
+	457, 2396,
+	458, 2396,
+	459, 2396,
+	460, 2396,
+	461, 2396,
+	462, 2396,
+	463, 2396,
+	464, 2396,
+	465, 2396,
+	466, 2396,
+	467, 2396,
+	469, 2396,
+	470, 2396,
+	471, 2396,
+	473, 2396,
+	474, 2396,
+	475, 2396,
+	476, 2396,
+	477, 2396,
+	478, 2396,
+	479, 2396,
+	480, 2396,
+	481, 2396,
+	482, 2396,
+	483, 2396,
+	484, 2396,
+	485, 2396,
+	486, 2396,
+	487, 2396,
+	488, 2396,
+	489, 2396,
+	491, 2396,
+	492, 2396,
+	494, 2396,
+	495, 2396,
+	496, 2396,
+	502, 2396,
+	503, 2396,
+	504, 2396,
+	506, 2396,
+	507, 2396,
+	508, 2396,
+	509, 2396,
+	510, 2396,
+	511, 2396,
+	512, 2396,
+	513, 2396,
+	514, 2396,
+	515, 2396,
+	516, 2396,
+	517, 2396,
+	518, 2396,
+	519, 2396,
+	520, 2396,
+	522, 2396,
+	523, 2396,
+	524, 2396,
+	525, 2396,
+	526, 2396,
+	528, 2396,
+	529, 2396,
+	530, 2396,
+	531, 2396,
+	532, 2396,
+	533, 2396,
+	534, 2396,
+	536, 2396,
+	537, 2396,
+	538, 2396,
+	539, 2396,
+	540, 2396,
+	541, 2396,
+	542, 2396,
+	543, 2396,
+	544, 2396,
+	545, 2396,
+	546, 2396,
+	547, 2396,
+	548, 2396,
+	549, 2396,
+	550, 2396,
+	551, 2396,
+	553, 2396,
+	554, 2396,
+	555, 2396,
+	556, 2396,
+	557, 2396,
+	558, 2396,
+	559, 2396,
+	561, 2396,
+	562, 2396,
+	563, 2396,
+	564, 2396,
+	565, 2396,
+	566, 2396,
+	567, 2396,
+	568, 2396,
+	570, 2396,
+	571, 2396,
+	572, 2396,
+	573, 2396,
+	574, 2396,
+	575, 2396,
+	576, 2396,
+	577, 2396,
+	578, 2396,
+	579, 2396,
+	581, 2396,
+	583, 2396,
+	584, 2396,
+	585, 2396,
+	586, 2396,
+	587, 2396,
+	588, 2396,
+	589, 2396,
+	590, 2396,
+	591, 2396,
+	592, 2396,
+	593, 2396,
+	594, 2396,
+	595, 2396,
+	596, 2396,
+	597, 2396,
+	598, 2396,
+	599, 2396,
+	600, 2396,
+	601, 2396,
+	602, 2396,
+	603, 2396,
+	604, 2396,
+	605, 2396,
+	606, 2396,
+	607, 2396,
+	608, 2396,
+	609, 2396,
+	611, 2396,
+	612, 2396,
+	614, 2396,
+	615, 2396,
+	617, 2396,
+	618, 2396,
+	619, 2396,
+	620, 2396,
+	621, 2396,
+	622, 2396,
+	623, 2396,
+	624, 2396,
+	625, 2396,
+	626, 2396,
+	628, 2396,
+	629, 2396,
+	630, 2396,
+	631, 2396,
+	632, 2396,
+	634, 2396,
+	636, 2396,
+	637, 2396,
+	638, 2396,
+	639, 2396,
+	640, 2396,
+	641, 2396,
+	642, 2396,
+	643, 2396,
+	644, 2396,
+	646, 2396,
+	647, 2396,
+	648, 2396,
+	649, 2396,
+	650, 2396,
+	651, 2396,
+	652, 2396,
+	653, 2396,
+	656, 2396,
+	657, 2396,
+	658, 2396,
+	659, 2396,
+	660, 2396,
+	661, 2396,
+	662, 2396,
+	663, 2396,
+	664, 2396,
+	665, 2396,
+	666, 2396,
+	668, 2396,
+	671, 2396,
+	672, 2396,
+	673, 2396,
+	674, 2396,
+	675, 2396,
+	676, 2396,
+	678, 2396,
+	679, 2396,
+	680, 2396,
+	681, 2396,
+	682, 2396,
+	683, 2396,
+	684, 2396,
+	685, 2396,
+	686, 2396,
+	687, 2396,
+	688, 2396,
+	689, 2396,
+	690, 2396,
+	691, 2396,
+	692, 2396,
+	693, 2396,
+	694, 2396,
+	695, 2396,
+	700, 2396,
+	701, 2396,
+	702, 2396,
+	703, 2396,
+	704, 2396,
+	705, 2396,
 	-2, 0,
-	-1, 867,
-	706, 2933,
-	-2, 4161,
-	-1, 868,
-	706, 2953,
-	-2, 2944,
-	-1, 869,
-	706, 2954,
-	-2, 2945,
-	-1, 873,
-	706, 4060,
-	-2, 2942,
-	-1, 953,
-	4, 1885,
-	21, 1885,
-	22, 1885,
-	23, 1885,
-	24, 1885,
-	25, 1885,
-	26, 1885,
-	27, 1885,
-	28, 1885,
-	30, 1885,
-	31, 1885,
-	37, 1885,
-	41, 1885,
-	43, 1885,
-	45, 1885,
-	46, 1885,
-	47, 1885,
-	49, 1885,
-	50, 1885,
-	51, 1885,
-	52, 1885,
-	53, 1885,
-	54, 1885,
-	55, 1885,
-	56, 1885,
-	57, 1885,
-	58, 1885,
-	60, 1885,
-	61, 1885,
-	62, 1885,
-	63, 1885,
-	65, 1885,
-	66, 1885,
-	67, 1885,
-	68, 1885,
-	69, 1885,
-	70, 1885,
-	71, 1885,
-	72, 1885,
-	73, 1885,
-	74, 1885,
-	75, 1885,
-	79, 1885,
-	80, 1885,
-	81, 1885,
-	82, 1885,
-	84, 1885,
-	85, 1885,
-	86, 1885,
-	87, 1885,
-	88, 1885,
-	92, 1885,
-	93, 1885,
-	94, 1885,
-	95, 1885,
-	96, 1885,
-	97, 1885,
-	98, 1885,
-	99, 1885,
-	102, 1885,
-	103, 1885,
-	104, 1885,
-	105, 1885,
-	106, 1885,
-	107, 1885,
-	109, 1885,
-	111, 1885,
-	112, 1885,
-	113, 1885,
-	114, 1885,
-	115, 1885,
-	116, 1885,
-	117, 1885,
-	119, 1885,
-	120, 1885,
-	121, 1885,
-	123, 1885,
-	124, 1885,
-	125, 1885,
-	133, 1885,
-	134, 1885,
-	135, 1885,
-	136, 1885,
-	137, 1885,
-	139, 1885,
-	140, 1885,
-	141, 1885,
-	142, 1885,
-	143, 1885,
-	144, 1885,
-	146, 1885,
-	147, 1885,
-	148, 1885,
-	149, 1885,
-	151, 1885,
-	152, 1885,
-	153, 1885,
-	154, 1885,
-	156, 1885,
-	157, 1885,
-	158, 1885,
-	159, 1885,
-	162, 1885,
-	163, 1885,
-	164, 1885,
-	166, 1885,
-	167, 1885,
-	168, 1885,
-	169, 1885,
-	171, 1885,
-	172, 1885,
-	173, 1885,
-	175, 1885,
-	176, 1885,
-	177, 1885,
-	178, 1885,
-	179, 1885,
-	180, 1885,
-	181, 1885,
-	182, 1885,
-	183, 1885,
-	184, 1885,
-	185, 1885,
-	186, 1885,
-	187, 1885,
-	188, 1885,
-	189, 1885,
-	190, 1885,
-	191, 1885,
-	192, 1885,
-	193, 1885,
-	195, 1885,
-	201, 1885,
-	202, 1885,
-	203, 1885,
-	204, 1885,
-	208, 1885,
-	210, 1885,
-	211, 1885,
-	212, 1885,
-	213, 1885,
-	214, 1885,
-	215, 1885,
-	217, 1885,
-	218, 1885,
-	219, 1885,
-	222, 1885,
-	223, 1885,
-	224, 1885,
-	225, 1885,
-	226, 1885,
-	227, 1885,
-	228, 1885,
-	229, 1885,
-	230, 1885,
-	231, 1885,
-	232, 1885,
-	233, 1885,
-	234, 1885,
-	235, 1885,
-	237, 1885,
-	238, 1885,
-	239, 1885,
-	241, 1885,
-	242, 1885,
-	244, 1885,
-	245, 1885,
-	246, 1885,
-	247, 1885,
-	248, 1885,
-	249, 1885,
-	250, 1885,
-	251, 1885,
-	252, 1885,
-	253, 1885,
-	254, 1885,
-	256, 1885,
-	257, 1885,
-	258, 1885,
-	260, 1885,
-	261, 1885,
-	262, 1885,
-	263, 1885,
-	264, 1885,
-	265, 1885,
-	266, 1885,
-	270, 1885,
-	271, 1885,
-	272, 1885,
-	273, 1885,
-	275, 1885,
-	276, 1885,
-	277, 1885,
-	279, 1885,
-	280, 1885,
-	281, 1885,
-	282, 1885,
-	283, 1885,
-	284, 1885,
-	286, 1885,
-	288, 1885,
-	289, 1885,
-	290, 1885,
-	292, 1885,
-	294, 1885,
-	295, 1885,
-	296, 1885,
-	298, 1885,
-	302, 1885,
-	303, 1885,
-	304, 1885,
-	305, 1885,
-	306, 1885,
-	307, 1885,
-	308, 1885,
-	310, 1885,
-	311, 1885,
-	312, 1885,
-	314, 1885,
-	315, 1885,
-	316, 1885,
-	318, 1885,
-	319, 1885,
-	322, 1885,
-	323, 1885,
-	324, 1885,
-	325, 1885,
-	326, 1885,
-	327, 1885,
-	328, 1885,
-	331, 1885,
-	332, 1885,
-	333, 1885,
-	334, 1885,
-	336, 1885,
-	337, 1885,
-	338, 1885,
-	339, 1885,
-	340, 1885,
-	341, 1885,
-	342, 1885,
-	343, 1885,
-	344, 1885,
-	345, 1885,
-	346, 1885,
-	347, 1885,
-	348, 1885,
-	349, 1885,
-	350, 1885,
-	351, 1885,
-	352, 1885,
-	353, 1885,
-	354, 1885,
-	355, 1885,
-	356, 1885,
-	357, 1885,
-	358, 1885,
-	359, 1885,
-	361, 1885,
-	363, 1885,
-	364, 1885,
-	365, 1885,
-	366, 1885,
-	367, 1885,
-	368, 1885,
-	369, 1885,
-	370, 1885,
-	371, 1885,
-	372, 1885,
-	373, 1885,
-	374, 1885,
-	375, 1885,
-	376, 1885,
-	377, 1885,
-	378, 1885,
-	379, 1885,
-	380, 1885,
-	382, 1885,
-	383, 1885,
-	385, 1885,
-	386, 1885,
-	388, 1885,
-	389, 1885,
-	390, 1885,
-	391, 1885,
-	393, 1885,
-	394, 1885,
-	395, 1885,
-	396, 1885,
-	397, 1885,
-	400, 1885,
-	402, 1885,
-	405, 1885,
-	406, 1885,
-	407, 1885,
-	410, 1885,
-	411, 1885,
-	412, 1885,
-	414, 1885,
-	416, 1885,
-	417, 1885,
-	418, 1885,
-	419, 1885,
-	420, 1885,
-	421, 1885,
-	422, 1885,
-	423, 1885,
-	424, 1885,
-	425, 1885,
-	426, 1885,
-	427, 1885,
-	428, 1885,
-	429, 1885,
-	431, 1885,
-	432, 1885,
-	433, 1885,
-	434, 1885,
-	435, 1885,
-	436, 1885,
-	437, 1885,
-	438, 1885,
-	439, 1885,
-	440, 1885,
-	441, 1885,
-	442, 1885,
-	443, 1885,
-	444, 1885,
-	445, 1885,
-	447, 1885,
-	448, 1885,
-	449, 1885,
-	451, 1885,
-	452, 1885,
-	453, 1885,
-	454, 1885,
-	455, 1885,
-	456, 1885,
-	457, 1885,
-	458, 1885,
-	459, 1885,
-	460, 1885,
-	461, 1885,
-	462, 1885,
-	463, 1885,
-	464, 1885,
-	465, 1885,
-	466, 1885,
-	467, 1885,
-	469, 1885,
-	471, 1885,
-	472, 1885,
-	473, 1885,
-	479, 1885,
-	480, 1885,
-	481, 1885,
-	483, 1885,
-	484, 1885,
-	485, 1885,
-	486, 1885,
-	487, 1885,
-	488, 1885,
-	489, 1885,
-	490, 1885,
-	491, 1885,
-	492, 1885,
-	493, 1885,
-	494, 1885,
-	495, 1885,
-	497, 1885,
-	498, 1885,
-	499, 1885,
-	500, 1885,
-	501, 1885,
-	503, 1885,
-	504, 1885,
-	505, 1885,
-	506, 1885,
-	507, 1885,
-	508, 1885,
-	509, 1885,
-	511, 1885,
-	512, 1885,
-	513, 1885,
-	514, 1885,
-	515, 1885,
-	516, 1885,
-	517, 1885,
-	518, 1885,
-	519, 1885,
-	520, 1885,
-	521, 1885,
-	522, 1885,
-	523, 1885,
-	524, 1885,
-	525, 1885,
-	526, 1885,
-	528, 1885,
-	529, 1885,
-	530, 1885,
-	531, 1885,
-	532, 1885,
-	533, 1885,
-	534, 1885,
-	536, 1885,
-	537, 1885,
-	538, 1885,
-	539, 1885,
-	540, 1885,
-	541, 1885,
-	542, 1885,
-	543, 1885,
-	545, 1885,
-	546, 1885,
-	547, 1885,
-	548, 1885,
-	549, 1885,
-	550, 1885,
-	551, 1885,
-	552, 1885,
-	553, 1885,
-	554, 1885,
-	556, 1885,
-	558, 1885,
-	559, 1885,
-	560, 1885,
-	561, 1885,
-	562, 1885,
-	563, 1885,
-	564, 1885,
-	565, 1885,
-	566, 1885,
-	567, 1885,
-	568, 1885,
-	569, 1885,
-	570, 1885,
-	571, 1885,
-	572, 1885,
-	573, 1885,
-	574, 1885,
-	575, 1885,
-	576, 1885,
-	577, 1885,
-	578, 1885,
-	579, 1885,
-	580, 1885,
-	582, 1885,
-	583, 1885,
-	585, 1885,
-	586, 1885,
-	588, 1885,
-	589, 1885,
-	590, 1885,
-	591, 1885,
-	592, 1885,
-	593, 1885,
-	594, 1885,
-	595, 1885,
-	596, 1885,
-	597, 1885,
-	599, 1885,
-	600, 1885,
-	601, 1885,
-	602, 1885,
-	603, 1885,
-	605, 1885,
-	607, 1885,
-	608, 1885,
-	609, 1885,
-	610, 1885,
-	611, 1885,
-	612, 1885,
-	613, 1885,
-	614, 1885,
-	616, 1885,
-	617, 1885,
-	618, 1885,
-	619, 1885,
-	620, 1885,
-	621, 1885,
-	622, 1885,
-	625, 1885,
-	626, 1885,
-	627, 1885,
-	628, 1885,
-	629, 1885,
-	630, 1885,
-	631, 1885,
-	632, 1885,
-	633, 1885,
-	634, 1885,
-	635, 1885,
-	637, 1885,
-	640, 1885,
-	641, 1885,
-	642, 1885,
-	643, 1885,
-	644, 1885,
-	645, 1885,
-	647, 1885,
-	648, 1885,
-	649, 1885,
-	650, 1885,
-	651, 1885,
-	652, 1885,
-	653, 1885,
-	654, 1885,
-	655, 1885,
-	656, 1885,
-	657, 1885,
-	658, 1885,
-	659, 1885,
-	660, 1885,
-	661, 1885,
-	662, 1885,
-	667, 1885,
-	668, 1885,
-	669, 1885,
-	670, 1885,
-	671, 1885,
-	672, 1885,
+	-1, 198,
+	1, 2236,
+	742, 2236,
+	745, 2236,
 	-2, 0,
-	-1, 975,
-	220, 3023,
-	604, 3023,
-	688, 3023,
-	708, 3023,
+	-1, 199,
+	1, 2236,
+	633, 2236,
+	742, 2236,
+	745, 2236,
 	-2, 0,
-	-1, 976,
-	220, 3007,
-	604, 3007,
-	688, 3007,
-	708, 3007,
+	-1, 252,
+	180, 2365,
+	202, 2365,
+	215, 2365,
+	294, 2365,
+	330, 2365,
+	414, 2365,
+	426, 2365,
+	654, 2365,
+	-2, 2340,
+	-1, 919,
+	739, 3170,
+	-2, 4458,
+	-1, 920,
+	739, 3190,
+	-2, 3181,
+	-1, 921,
+	739, 3191,
+	-2, 3182,
+	-1, 925,
+	739, 4357,
+	-2, 3179,
+	-1, 1012,
+	4, 2100,
+	21, 2100,
+	22, 2100,
+	23, 2100,
+	24, 2100,
+	25, 2100,
+	26, 2100,
+	27, 2100,
+	28, 2100,
+	30, 2100,
+	31, 2100,
+	37, 2100,
+	41, 2100,
+	43, 2100,
+	45, 2100,
+	46, 2100,
+	47, 2100,
+	49, 2100,
+	50, 2100,
+	51, 2100,
+	52, 2100,
+	53, 2100,
+	54, 2100,
+	55, 2100,
+	56, 2100,
+	57, 2100,
+	58, 2100,
+	59, 2100,
+	60, 2100,
+	62, 2100,
+	63, 2100,
+	64, 2100,
+	65, 2100,
+	67, 2100,
+	68, 2100,
+	69, 2100,
+	70, 2100,
+	71, 2100,
+	72, 2100,
+	73, 2100,
+	74, 2100,
+	75, 2100,
+	76, 2100,
+	77, 2100,
+	78, 2100,
+	82, 2100,
+	83, 2100,
+	84, 2100,
+	85, 2100,
+	87, 2100,
+	88, 2100,
+	89, 2100,
+	90, 2100,
+	91, 2100,
+	95, 2100,
+	96, 2100,
+	97, 2100,
+	98, 2100,
+	99, 2100,
+	100, 2100,
+	101, 2100,
+	102, 2100,
+	105, 2100,
+	106, 2100,
+	107, 2100,
+	108, 2100,
+	109, 2100,
+	110, 2100,
+	112, 2100,
+	114, 2100,
+	115, 2100,
+	116, 2100,
+	117, 2100,
+	118, 2100,
+	120, 2100,
+	121, 2100,
+	123, 2100,
+	124, 2100,
+	125, 2100,
+	127, 2100,
+	128, 2100,
+	129, 2100,
+	137, 2100,
+	138, 2100,
+	139, 2100,
+	140, 2100,
+	141, 2100,
+	143, 2100,
+	144, 2100,
+	145, 2100,
+	146, 2100,
+	148, 2100,
+	149, 2100,
+	150, 2100,
+	151, 2100,
+	153, 2100,
+	154, 2100,
+	155, 2100,
+	156, 2100,
+	158, 2100,
+	159, 2100,
+	160, 2100,
+	161, 2100,
+	162, 2100,
+	166, 2100,
+	167, 2100,
+	168, 2100,
+	169, 2100,
+	171, 2100,
+	172, 2100,
+	173, 2100,
+	174, 2100,
+	175, 2100,
+	177, 2100,
+	178, 2100,
+	179, 2100,
+	181, 2100,
+	182, 2100,
+	183, 2100,
+	184, 2100,
+	185, 2100,
+	186, 2100,
+	187, 2100,
+	188, 2100,
+	189, 2100,
+	190, 2100,
+	191, 2100,
+	192, 2100,
+	193, 2100,
+	194, 2100,
+	195, 2100,
+	196, 2100,
+	197, 2100,
+	198, 2100,
+	199, 2100,
+	201, 2100,
+	207, 2100,
+	208, 2100,
+	209, 2100,
+	210, 2100,
+	214, 2100,
+	216, 2100,
+	217, 2100,
+	218, 2100,
+	219, 2100,
+	220, 2100,
+	221, 2100,
+	222, 2100,
+	224, 2100,
+	225, 2100,
+	226, 2100,
+	229, 2100,
+	230, 2100,
+	231, 2100,
+	232, 2100,
+	233, 2100,
+	234, 2100,
+	235, 2100,
+	236, 2100,
+	237, 2100,
+	238, 2100,
+	239, 2100,
+	240, 2100,
+	241, 2100,
+	242, 2100,
+	244, 2100,
+	245, 2100,
+	246, 2100,
+	248, 2100,
+	249, 2100,
+	251, 2100,
+	252, 2100,
+	253, 2100,
+	254, 2100,
+	255, 2100,
+	256, 2100,
+	257, 2100,
+	258, 2100,
+	259, 2100,
+	260, 2100,
+	261, 2100,
+	263, 2100,
+	264, 2100,
+	265, 2100,
+	266, 2100,
+	268, 2100,
+	269, 2100,
+	270, 2100,
+	271, 2100,
+	272, 2100,
+	273, 2100,
+	274, 2100,
+	278, 2100,
+	279, 2100,
+	280, 2100,
+	281, 2100,
+	283, 2100,
+	284, 2100,
+	285, 2100,
+	287, 2100,
+	288, 2100,
+	289, 2100,
+	290, 2100,
+	291, 2100,
+	292, 2100,
+	293, 2100,
+	295, 2100,
+	297, 2100,
+	298, 2100,
+	299, 2100,
+	301, 2100,
+	303, 2100,
+	304, 2100,
+	305, 2100,
+	307, 2100,
+	311, 2100,
+	312, 2100,
+	313, 2100,
+	314, 2100,
+	315, 2100,
+	316, 2100,
+	317, 2100,
+	319, 2100,
+	320, 2100,
+	321, 2100,
+	323, 2100,
+	324, 2100,
+	325, 2100,
+	327, 2100,
+	328, 2100,
+	331, 2100,
+	332, 2100,
+	333, 2100,
+	334, 2100,
+	335, 2100,
+	336, 2100,
+	337, 2100,
+	340, 2100,
+	341, 2100,
+	342, 2100,
+	343, 2100,
+	344, 2100,
+	345, 2100,
+	347, 2100,
+	348, 2100,
+	349, 2100,
+	350, 2100,
+	351, 2100,
+	352, 2100,
+	353, 2100,
+	354, 2100,
+	355, 2100,
+	356, 2100,
+	357, 2100,
+	358, 2100,
+	359, 2100,
+	360, 2100,
+	361, 2100,
+	362, 2100,
+	363, 2100,
+	364, 2100,
+	365, 2100,
+	366, 2100,
+	367, 2100,
+	368, 2100,
+	369, 2100,
+	370, 2100,
+	371, 2100,
+	373, 2100,
+	376, 2100,
+	377, 2100,
+	378, 2100,
+	379, 2100,
+	380, 2100,
+	381, 2100,
+	382, 2100,
+	383, 2100,
+	384, 2100,
+	385, 2100,
+	386, 2100,
+	387, 2100,
+	388, 2100,
+	389, 2100,
+	390, 2100,
+	391, 2100,
+	392, 2100,
+	393, 2100,
+	394, 2100,
+	395, 2100,
+	396, 2100,
+	398, 2100,
+	399, 2100,
+	401, 2100,
+	402, 2100,
+	404, 2100,
+	405, 2100,
+	406, 2100,
+	407, 2100,
+	409, 2100,
+	410, 2100,
+	411, 2100,
+	412, 2100,
+	413, 2100,
+	416, 2100,
+	418, 2100,
+	419, 2100,
+	422, 2100,
+	423, 2100,
+	424, 2100,
+	427, 2100,
+	428, 2100,
+	429, 2100,
+	431, 2100,
+	433, 2100,
+	434, 2100,
+	435, 2100,
+	436, 2100,
+	437, 2100,
+	438, 2100,
+	439, 2100,
+	440, 2100,
+	441, 2100,
+	442, 2100,
+	443, 2100,
+	444, 2100,
+	445, 2100,
+	446, 2100,
+	447, 2100,
+	448, 2100,
+	450, 2100,
+	451, 2100,
+	452, 2100,
+	453, 2100,
+	454, 2100,
+	455, 2100,
+	456, 2100,
+	457, 2100,
+	458, 2100,
+	459, 2100,
+	460, 2100,
+	461, 2100,
+	462, 2100,
+	463, 2100,
+	464, 2100,
+	465, 2100,
+	466, 2100,
+	467, 2100,
+	469, 2100,
+	470, 2100,
+	471, 2100,
+	473, 2100,
+	474, 2100,
+	475, 2100,
+	476, 2100,
+	477, 2100,
+	478, 2100,
+	479, 2100,
+	480, 2100,
+	481, 2100,
+	482, 2100,
+	483, 2100,
+	484, 2100,
+	485, 2100,
+	486, 2100,
+	487, 2100,
+	488, 2100,
+	489, 2100,
+	491, 2100,
+	492, 2100,
+	494, 2100,
+	495, 2100,
+	496, 2100,
+	502, 2100,
+	503, 2100,
+	504, 2100,
+	506, 2100,
+	507, 2100,
+	508, 2100,
+	509, 2100,
+	510, 2100,
+	511, 2100,
+	512, 2100,
+	513, 2100,
+	514, 2100,
+	515, 2100,
+	516, 2100,
+	517, 2100,
+	518, 2100,
+	519, 2100,
+	520, 2100,
+	522, 2100,
+	523, 2100,
+	524, 2100,
+	525, 2100,
+	526, 2100,
+	528, 2100,
+	529, 2100,
+	530, 2100,
+	531, 2100,
+	532, 2100,
+	533, 2100,
+	534, 2100,
+	536, 2100,
+	537, 2100,
+	538, 2100,
+	539, 2100,
+	540, 2100,
+	541, 2100,
+	542, 2100,
+	543, 2100,
+	544, 2100,
+	545, 2100,
+	546, 2100,
+	547, 2100,
+	548, 2100,
+	549, 2100,
+	550, 2100,
+	551, 2100,
+	553, 2100,
+	554, 2100,
+	555, 2100,
+	556, 2100,
+	557, 2100,
+	558, 2100,
+	559, 2100,
+	561, 2100,
+	562, 2100,
+	563, 2100,
+	564, 2100,
+	565, 2100,
+	566, 2100,
+	567, 2100,
+	568, 2100,
+	570, 2100,
+	571, 2100,
+	572, 2100,
+	573, 2100,
+	574, 2100,
+	575, 2100,
+	576, 2100,
+	577, 2100,
+	578, 2100,
+	579, 2100,
+	581, 2100,
+	583, 2100,
+	584, 2100,
+	585, 2100,
+	586, 2100,
+	587, 2100,
+	588, 2100,
+	589, 2100,
+	590, 2100,
+	591, 2100,
+	592, 2100,
+	593, 2100,
+	594, 2100,
+	595, 2100,
+	596, 2100,
+	597, 2100,
+	598, 2100,
+	599, 2100,
+	600, 2100,
+	601, 2100,
+	602, 2100,
+	603, 2100,
+	604, 2100,
+	605, 2100,
+	606, 2100,
+	607, 2100,
+	608, 2100,
+	609, 2100,
+	611, 2100,
+	612, 2100,
+	614, 2100,
+	615, 2100,
+	617, 2100,
+	618, 2100,
+	619, 2100,
+	620, 2100,
+	621, 2100,
+	622, 2100,
+	623, 2100,
+	624, 2100,
+	625, 2100,
+	626, 2100,
+	628, 2100,
+	629, 2100,
+	630, 2100,
+	631, 2100,
+	632, 2100,
+	634, 2100,
+	636, 2100,
+	637, 2100,
+	638, 2100,
+	639, 2100,
+	640, 2100,
+	641, 2100,
+	642, 2100,
+	643, 2100,
+	644, 2100,
+	646, 2100,
+	647, 2100,
+	648, 2100,
+	649, 2100,
+	650, 2100,
+	651, 2100,
+	652, 2100,
+	653, 2100,
+	656, 2100,
+	657, 2100,
+	658, 2100,
+	659, 2100,
+	660, 2100,
+	661, 2100,
+	662, 2100,
+	663, 2100,
+	664, 2100,
+	665, 2100,
+	666, 2100,
+	668, 2100,
+	671, 2100,
+	672, 2100,
+	673, 2100,
+	674, 2100,
+	675, 2100,
+	676, 2100,
+	678, 2100,
+	679, 2100,
+	680, 2100,
+	681, 2100,
+	682, 2100,
+	683, 2100,
+	684, 2100,
+	685, 2100,
+	686, 2100,
+	687, 2100,
+	688, 2100,
+	689, 2100,
+	690, 2100,
+	691, 2100,
+	692, 2100,
+	693, 2100,
+	694, 2100,
+	695, 2100,
+	700, 2100,
+	701, 2100,
+	702, 2100,
+	703, 2100,
+	704, 2100,
+	705, 2100,
 	-2, 0,
-	-1, 978,
-	220, 3329,
-	604, 3329,
-	688, 3329,
-	708, 3329,
+	-1, 1034,
+	227, 3263,
+	633, 3263,
+	721, 3263,
+	741, 3263,
 	-2, 0,
-	-1, 981,
-	220, 3162,
-	604, 3162,
-	688, 3162,
-	708, 3162,
+	-1, 1035,
+	227, 3247,
+	633, 3247,
+	721, 3247,
+	741, 3247,
 	-2, 0,
-	-1, 982,
-	220, 3383,
-	604, 3383,
-	688, 3383,
-	708, 3383,
+	-1, 1037,
+	227, 3588,
+	633, 3588,
+	721, 3588,
+	741, 3588,
 	-2, 0,
-	-1, 990,
-	220, 3191,
-	604, 3191,
-	688, 3191,
-	708, 3191,
-	-2, 1089,
-	-1, 1006,
-	8, 1231,
-	29, 1231,
-	696, 1231,
-	697, 1231,
-	-2, 1236,
-	-1, 1010,
-	1, 3086,
-	709, 3086,
-	712, 3086,
-	-2, 1236,
-	-1, 1011,
-	1, 3149,
-	709, 3149,
-	712, 3149,
-	-2, 1236,
-	-1, 1014,
-	1, 3196,
-	709, 3196,
-	712, 3196,
-	-2, 1229,
-	-1, 1015,
-	1, 3255,
-	709, 3255,
-	712, 3255,
-	-2, 1230,
-	-1, 1016,
-	1, 3095,
-	709, 3095,
-	712, 3095,
-	-2, 1233,
-	-1, 1017,
-	1, 2988,
-	709, 2988,
-	712, 2988,
-	-2, 1234,
-	-1, 1036,
-	220, 1278,
+	-1, 1040,
+	227, 3406,
+	633, 3406,
+	721, 3406,
+	741, 3406,
 	-2, 0,
-	-1, 1037,
-	455, 1359,
-	534, 1359,
-	586, 1359,
-	609, 1359,
+	-1, 1041,
+	227, 3646,
+	633, 3646,
+	721, 3646,
+	741, 3646,
 	-2, 0,
-	-1, 1038,
-	455, 1358,
-	534, 1358,
-	586, 1358,
-	609, 1358,
-	-2, 1249,
-	-1, 1042,
-	1, 1426,
-	705, 1426,
-	707, 1426,
-	709, 1426,
-	712, 1426,
+	-1, 1049,
+	227, 3438,
+	633, 3438,
+	721, 3438,
+	741, 3438,
+	-2, 1269,
+	-1, 1068,
+	8, 1421,
+	29, 1421,
+	729, 1421,
+	730, 1421,
+	-2, 1426,
+	-1, 1072,
+	1, 3327,
+	742, 3327,
+	745, 3327,
+	-2, 1426,
+	-1, 1073,
+	1, 3393,
+	742, 3393,
+	745, 3393,
+	-2, 1426,
+	-1, 1076,
+	1, 3444,
+	742, 3444,
+	745, 3444,
+	-2, 1419,
+	-1, 1077,
+	1, 3511,
+	742, 3511,
+	745, 3511,
+	-2, 1420,
+	-1, 1078,
+	1, 3337,
+	742, 3337,
+	745, 3337,
+	-2, 1423,
+	-1, 1079,
+	1, 3226,
+	742, 3226,
+	745, 3226,
+	-2, 1424,
+	-1, 1099,
+	227, 1468,
 	-2, 0,
-	-1, 1044,
-	1, 1331,
-	705, 1331,
-	707, 1331,
-	709, 1331,
-	712, 1331,
+	-1, 1100,
+	477, 1547,
+	559, 1547,
+	615, 1547,
+	638, 1547,
 	-2, 0,
-	-1, 1045,
-	1, 1335,
-	705, 1335,
-	707, 1335,
-	709, 1335,
-	712, 1335,
+	-1, 1101,
+	477, 1546,
+	559, 1546,
+	615, 1546,
+	638, 1546,
+	-2, 1439,
+	-1, 1105,
+	1, 1614,
+	738, 1614,
+	740, 1614,
+	742, 1614,
+	745, 1614,
 	-2, 0,
-	-1, 1046,
-	1, 1525,
-	209, 1525,
-	705, 1525,
-	707, 1525,
-	709, 1525,
-	712, 1525,
+	-1, 1107,
+	1, 1512,
+	738, 1512,
+	740, 1512,
+	742, 1512,
+	745, 1512,
 	-2, 0,
-	-1, 1056,
-	1, 1364,
-	705, 1364,
-	707, 1364,
-	709, 1364,
-	712, 1364,
+	-1, 1109,
+	1, 1614,
+	738, 1614,
+	740, 1614,
+	742, 1614,
+	745, 1614,
 	-2, 0,
-	-1, 1063,
-	1, 1426,
-	705, 1426,
-	707, 1426,
-	709, 1426,
-	712, 1426,
+	-1, 1110,
+	1, 1728,
+	215, 1728,
+	738, 1728,
+	740, 1728,
+	742, 1728,
+	745, 1728,
 	-2, 0,
-	-1, 1064,
-	1, 1415,
-	705, 1415,
-	707, 1415,
-	709, 1415,
-	712, 1415,
+	-1, 1122,
+	1, 1552,
+	738, 1552,
+	740, 1552,
+	742, 1552,
+	745, 1552,
 	-2, 0,
-	-1, 1065,
-	1, 1419,
-	705, 1419,
-	707, 1419,
-	709, 1419,
-	712, 1419,
+	-1, 1129,
+	1, 1614,
+	738, 1614,
+	740, 1614,
+	742, 1614,
+	745, 1614,
 	-2, 0,
-	-1, 1066,
-	1, 1428,
-	705, 1428,
-	707, 1428,
-	709, 1428,
-	712, 1428,
+	-1, 1130,
+	1, 1603,
+	738, 1603,
+	740, 1603,
+	742, 1603,
+	745, 1603,
 	-2, 0,
-	-1, 1067,
-	1, 1431,
-	705, 1431,
-	707, 1431,
-	709, 1431,
-	712, 1431,
+	-1, 1131,
+	1, 1607,
+	738, 1607,
+	740, 1607,
+	742, 1607,
+	745, 1607,
 	-2, 0,
-	-1, 1075,
-	1, 1471,
-	705, 1471,
-	707, 1471,
-	709, 1471,
-	712, 1471,
+	-1, 1132,
+	1, 1614,
+	738, 1614,
+	740, 1614,
+	742, 1614,
+	745, 1614,
 	-2, 0,
-	-1, 1076,
-	1, 1473,
-	705, 1473,
-	707, 1473,
-	709, 1473,
-	712, 1473,
+	-1, 1133,
+	1, 1619,
+	738, 1619,
+	740, 1619,
+	742, 1619,
+	745, 1619,
 	-2, 0,
-	-1, 1079,
-	1, 1499,
-	705, 1499,
-	707, 1499,
-	709, 1499,
-	712, 1499,
+	-1, 1142,
+	1, 1663,
+	738, 1663,
+	740, 1663,
+	742, 1663,
+	745, 1663,
 	-2, 0,
-	-1, 1081,
-	1, 1517,
-	705, 1517,
-	707, 1517,
-	709, 1517,
-	712, 1517,
+	-1, 1143,
+	1, 1669,
+	738, 1669,
+	740, 1669,
+	742, 1669,
+	745, 1669,
 	-2, 0,
-	-1, 1137,
-	708, 2944,
-	711, 2944,
-	-2, 1537,
-	-1, 1138,
-	708, 2946,
-	711, 2946,
-	-2, 1538,
-	-1, 1139,
-	708, 2945,
-	711, 2945,
-	-2, 1539,
-	-1, 1140,
-	711, 2865,
-	-2, 1540,
 	-1, 1146,
-	4, 532,
-	8, 532,
-	-2, 3375,
-	-1, 1169,
-	209, 346,
+	1, 1695,
+	738, 1695,
+	740, 1695,
+	742, 1695,
+	745, 1695,
 	-2, 0,
-	-1, 1192,
-	48, 2916,
+	-1, 1148,
+	1, 1713,
+	738, 1713,
+	740, 1713,
+	742, 1713,
+	745, 1713,
 	-2, 0,
-	-1, 1193,
-	648, 1858,
-	-2, 1622,
+	-1, 1206,
+	741, 3181,
+	744, 3181,
+	-2, 1740,
 	-1, 1207,
-	220, 744,
+	741, 3183,
+	744, 3183,
+	-2, 1741,
+	-1, 1208,
+	741, 3182,
+	744, 3182,
+	-2, 1742,
+	-1, 1209,
+	744, 3102,
+	-2, 1743,
+	-1, 1215,
+	4, 608,
+	8, 608,
+	-2, 3638,
+	-1, 1239,
+	215, 381,
+	-2, 0,
+	-1, 1264,
+	48, 3153,
 	-2, 0,
-	-1, 1210,
-	4, 2339,
-	21, 2339,
-	22, 2339,
-	23, 2339,
-	24, 2339,
-	25, 2339,
-	26, 2339,
-	27, 2339,
-	28, 2339,
-	30, 2339,
-	31, 2339,
-	37, 2339,
-	41, 2339,
-	43, 2339,
-	45, 2339,
-	46, 2339,
-	47, 2339,
-	49, 2339,
-	50, 2339,
-	51, 2339,
-	52, 2339,
-	53, 2339,
-	54, 2339,
-	55, 2339,
-	56, 2339,
-	57, 2339,
-	58, 2339,
-	60, 2339,
-	61, 2339,
-	62, 2339,
-	63, 2339,
-	65, 2339,
-	66, 2339,
-	67, 2339,
-	68, 2339,
-	69, 2339,
-	70, 2339,
-	71, 2339,
-	72, 2339,
-	73, 2339,
-	74, 2339,
-	75, 2339,
-	79, 2339,
-	80, 2339,
-	81, 2339,
-	82, 2339,
-	84, 2339,
-	85, 2339,
-	86, 2339,
-	87, 2339,
-	88, 2339,
-	92, 2339,
-	93, 2339,
-	94, 2339,
-	95, 2339,
-	96, 2339,
-	97, 2339,
-	98, 2339,
-	99, 2339,
-	102, 2339,
-	103, 2339,
-	104, 2339,
-	105, 2339,
-	106, 2339,
-	107, 2339,
-	109, 2339,
-	111, 2339,
-	112, 2339,
-	113, 2339,
-	114, 2339,
-	115, 2339,
-	116, 2339,
-	117, 2339,
-	119, 2339,
-	120, 2339,
-	121, 2339,
-	123, 2339,
-	124, 2339,
-	125, 2339,
-	133, 2339,
-	134, 2339,
-	135, 2339,
-	136, 2339,
-	137, 2339,
-	139, 2339,
-	140, 2339,
-	141, 2339,
-	142, 2339,
-	143, 2339,
-	144, 2339,
-	146, 2339,
-	147, 2339,
-	148, 2339,
-	149, 2339,
-	151, 2339,
-	152, 2339,
-	153, 2339,
-	154, 2339,
-	156, 2339,
-	157, 2339,
-	158, 2339,
-	159, 2339,
-	162, 2339,
-	163, 2339,
-	164, 2339,
-	166, 2339,
-	167, 2339,
-	168, 2339,
-	169, 2339,
-	171, 2339,
-	172, 2339,
-	173, 2339,
-	175, 2339,
-	176, 2339,
-	177, 2339,
-	178, 2339,
-	179, 2339,
-	180, 2339,
-	181, 2339,
-	182, 2339,
-	183, 2339,
-	184, 2339,
-	185, 2339,
-	186, 2339,
-	187, 2339,
-	188, 2339,
-	189, 2339,
-	190, 2339,
-	191, 2339,
-	192, 2339,
-	193, 2339,
-	195, 2339,
-	201, 2339,
-	202, 2339,
-	203, 2339,
-	204, 2339,
-	208, 2339,
-	210, 2339,
-	211, 2339,
-	212, 2339,
-	213, 2339,
-	214, 2339,
-	215, 2339,
-	217, 2339,
-	218, 2339,
-	219, 2339,
-	222, 2339,
-	223, 2339,
-	224, 2339,
-	225, 2339,
-	226, 2339,
-	227, 2339,
-	228, 2339,
-	229, 2339,
-	230, 2339,
-	231, 2339,
-	232, 2339,
-	233, 2339,
-	234, 2339,
-	235, 2339,
-	237, 2339,
-	238, 2339,
-	239, 2339,
-	241, 2339,
-	242, 2339,
-	244, 2339,
-	245, 2339,
-	246, 2339,
-	247, 2339,
-	248, 2339,
-	249, 2339,
-	250, 2339,
-	251, 2339,
-	252, 2339,
-	253, 2339,
-	254, 2339,
-	256, 2339,
-	257, 2339,
-	258, 2339,
-	260, 2339,
-	261, 2339,
-	262, 2339,
-	263, 2339,
-	264, 2339,
-	265, 2339,
-	266, 2339,
-	270, 2339,
-	271, 2339,
-	272, 2339,
-	273, 2339,
-	275, 2339,
-	276, 2339,
-	277, 2339,
-	279, 2339,
-	280, 2339,
-	281, 2339,
-	282, 2339,
-	283, 2339,
-	284, 2339,
-	286, 2339,
-	288, 2339,
-	289, 2339,
-	290, 2339,
-	292, 2339,
-	294, 2339,
-	295, 2339,
-	296, 2339,
-	298, 2339,
-	302, 2339,
-	303, 2339,
-	304, 2339,
-	305, 2339,
-	306, 2339,
-	307, 2339,
-	308, 2339,
-	310, 2339,
-	311, 2339,
-	312, 2339,
-	314, 2339,
-	315, 2339,
-	316, 2339,
-	318, 2339,
-	319, 2339,
-	322, 2339,
-	323, 2339,
-	324, 2339,
-	325, 2339,
-	326, 2339,
-	327, 2339,
-	328, 2339,
-	331, 2339,
-	332, 2339,
-	333, 2339,
-	334, 2339,
-	336, 2339,
-	337, 2339,
-	338, 2339,
-	339, 2339,
-	340, 2339,
-	341, 2339,
-	342, 2339,
-	343, 2339,
-	344, 2339,
-	345, 2339,
-	346, 2339,
-	347, 2339,
-	348, 2339,
-	349, 2339,
-	350, 2339,
-	351, 2339,
-	352, 2339,
-	353, 2339,
-	354, 2339,
-	355, 2339,
-	356, 2339,
-	357, 2339,
-	358, 2339,
-	359, 2339,
-	361, 2339,
-	363, 2339,
-	364, 2339,
-	365, 2339,
-	366, 2339,
-	367, 2339,
-	368, 2339,
-	369, 2339,
-	370, 2339,
-	371, 2339,
-	372, 2339,
-	373, 2339,
-	374, 2339,
-	375, 2339,
-	376, 2339,
-	377, 2339,
-	378, 2339,
-	379, 2339,
-	380, 2339,
-	382, 2339,
-	383, 2339,
-	385, 2339,
-	386, 2339,
-	388, 2339,
-	389, 2339,
-	390, 2339,
-	391, 2339,
-	393, 2339,
-	394, 2339,
-	395, 2339,
-	396, 2339,
-	397, 2339,
-	400, 2339,
-	402, 2339,
-	405, 2339,
-	406, 2339,
-	407, 2339,
-	410, 2339,
-	411, 2339,
-	412, 2339,
-	414, 2339,
-	416, 2339,
-	417, 2339,
-	418, 2339,
-	419, 2339,
-	420, 2339,
-	421, 2339,
-	422, 2339,
-	423, 2339,
-	424, 2339,
-	425, 2339,
-	426, 2339,
-	427, 2339,
-	428, 2339,
-	429, 2339,
-	431, 2339,
-	432, 2339,
-	433, 2339,
-	434, 2339,
-	435, 2339,
-	436, 2339,
-	437, 2339,
-	438, 2339,
-	439, 2339,
-	440, 2339,
-	441, 2339,
-	442, 2339,
-	443, 2339,
-	444, 2339,
-	445, 2339,
-	447, 2339,
-	448, 2339,
-	449, 2339,
-	451, 2339,
-	452, 2339,
-	453, 2339,
-	454, 2339,
-	455, 2339,
-	456, 2339,
-	457, 2339,
-	458, 2339,
-	459, 2339,
-	460, 2339,
-	461, 2339,
-	462, 2339,
-	463, 2339,
-	464, 2339,
-	465, 2339,
-	466, 2339,
-	467, 2339,
-	469, 2339,
-	471, 2339,
-	472, 2339,
-	473, 2339,
-	479, 2339,
-	480, 2339,
-	481, 2339,
-	483, 2339,
-	484, 2339,
-	485, 2339,
-	486, 2339,
-	487, 2339,
-	488, 2339,
-	489, 2339,
-	490, 2339,
-	491, 2339,
-	492, 2339,
-	493, 2339,
-	494, 2339,
-	495, 2339,
-	497, 2339,
-	498, 2339,
-	499, 2339,
-	500, 2339,
-	501, 2339,
-	503, 2339,
-	504, 2339,
-	505, 2339,
-	506, 2339,
-	507, 2339,
-	508, 2339,
-	509, 2339,
-	511, 2339,
-	512, 2339,
-	513, 2339,
-	514, 2339,
-	515, 2339,
-	516, 2339,
-	517, 2339,
-	518, 2339,
-	519, 2339,
-	520, 2339,
-	521, 2339,
-	522, 2339,
-	523, 2339,
-	524, 2339,
-	525, 2339,
-	526, 2339,
-	528, 2339,
-	529, 2339,
-	530, 2339,
-	531, 2339,
-	532, 2339,
-	533, 2339,
-	534, 2339,
-	536, 2339,
-	537, 2339,
-	538, 2339,
-	539, 2339,
-	540, 2339,
-	541, 2339,
-	542, 2339,
-	543, 2339,
-	545, 2339,
-	546, 2339,
-	547, 2339,
-	548, 2339,
-	549, 2339,
-	550, 2339,
-	551, 2339,
-	552, 2339,
-	553, 2339,
-	554, 2339,
-	556, 2339,
-	558, 2339,
-	559, 2339,
-	560, 2339,
-	561, 2339,
-	562, 2339,
-	563, 2339,
-	564, 2339,
-	565, 2339,
-	566, 2339,
-	567, 2339,
-	568, 2339,
-	569, 2339,
-	570, 2339,
-	571, 2339,
-	572, 2339,
-	573, 2339,
-	574, 2339,
-	575, 2339,
-	576, 2339,
-	577, 2339,
-	578, 2339,
-	579, 2339,
-	580, 2339,
-	582, 2339,
-	583, 2339,
-	585, 2339,
-	586, 2339,
-	588, 2339,
-	589, 2339,
-	590, 2339,
-	591, 2339,
-	592, 2339,
-	593, 2339,
-	594, 2339,
-	595, 2339,
-	596, 2339,
-	597, 2339,
-	599, 2339,
-	600, 2339,
-	601, 2339,
-	602, 2339,
-	603, 2339,
-	605, 2339,
-	607, 2339,
-	608, 2339,
-	609, 2339,
-	610, 2339,
-	611, 2339,
-	612, 2339,
-	613, 2339,
-	614, 2339,
-	616, 2339,
-	617, 2339,
-	618, 2339,
-	619, 2339,
-	620, 2339,
-	621, 2339,
-	622, 2339,
-	625, 2339,
-	626, 2339,
-	627, 2339,
-	628, 2339,
-	629, 2339,
-	630, 2339,
-	631, 2339,
-	632, 2339,
-	633, 2339,
-	634, 2339,
-	635, 2339,
-	637, 2339,
-	640, 2339,
-	641, 2339,
-	642, 2339,
-	643, 2339,
-	644, 2339,
-	645, 2339,
-	647, 2339,
-	648, 2339,
-	649, 2339,
-	650, 2339,
-	651, 2339,
-	652, 2339,
-	653, 2339,
-	654, 2339,
-	655, 2339,
-	656, 2339,
-	657, 2339,
-	658, 2339,
-	659, 2339,
-	660, 2339,
-	661, 2339,
-	662, 2339,
-	667, 2339,
-	668, 2339,
-	669, 2339,
-	670, 2339,
-	671, 2339,
-	672, 2339,
+	-1, 1265,
+	680, 2071,
+	-2, 1825,
+	-1, 1282,
+	227, 904,
 	-2, 0,
-	-1, 1224,
-	307, 668,
+	-1, 1285,
+	4, 2565,
+	21, 2565,
+	22, 2565,
+	23, 2565,
+	24, 2565,
+	25, 2565,
+	26, 2565,
+	27, 2565,
+	28, 2565,
+	30, 2565,
+	31, 2565,
+	37, 2565,
+	41, 2565,
+	43, 2565,
+	45, 2565,
+	46, 2565,
+	47, 2565,
+	49, 2565,
+	50, 2565,
+	51, 2565,
+	52, 2565,
+	53, 2565,
+	54, 2565,
+	55, 2565,
+	56, 2565,
+	57, 2565,
+	58, 2565,
+	59, 2565,
+	60, 2565,
+	62, 2565,
+	63, 2565,
+	64, 2565,
+	65, 2565,
+	67, 2565,
+	68, 2565,
+	69, 2565,
+	70, 2565,
+	71, 2565,
+	72, 2565,
+	73, 2565,
+	74, 2565,
+	75, 2565,
+	76, 2565,
+	77, 2565,
+	78, 2565,
+	82, 2565,
+	83, 2565,
+	84, 2565,
+	85, 2565,
+	87, 2565,
+	88, 2565,
+	89, 2565,
+	90, 2565,
+	91, 2565,
+	95, 2565,
+	96, 2565,
+	97, 2565,
+	98, 2565,
+	99, 2565,
+	100, 2565,
+	101, 2565,
+	102, 2565,
+	105, 2565,
+	106, 2565,
+	107, 2565,
+	108, 2565,
+	109, 2565,
+	110, 2565,
+	112, 2565,
+	114, 2565,
+	115, 2565,
+	116, 2565,
+	117, 2565,
+	118, 2565,
+	120, 2565,
+	121, 2565,
+	123, 2565,
+	124, 2565,
+	125, 2565,
+	127, 2565,
+	128, 2565,
+	129, 2565,
+	137, 2565,
+	138, 2565,
+	139, 2565,
+	140, 2565,
+	141, 2565,
+	143, 2565,
+	144, 2565,
+	145, 2565,
+	146, 2565,
+	148, 2565,
+	149, 2565,
+	150, 2565,
+	151, 2565,
+	153, 2565,
+	154, 2565,
+	155, 2565,
+	156, 2565,
+	158, 2565,
+	159, 2565,
+	160, 2565,
+	161, 2565,
+	162, 2565,
+	166, 2565,
+	167, 2565,
+	168, 2565,
+	169, 2565,
+	171, 2565,
+	172, 2565,
+	173, 2565,
+	174, 2565,
+	175, 2565,
+	177, 2565,
+	178, 2565,
+	179, 2565,
+	181, 2565,
+	182, 2565,
+	183, 2565,
+	184, 2565,
+	185, 2565,
+	186, 2565,
+	187, 2565,
+	188, 2565,
+	189, 2565,
+	190, 2565,
+	191, 2565,
+	192, 2565,
+	193, 2565,
+	194, 2565,
+	195, 2565,
+	196, 2565,
+	197, 2565,
+	198, 2565,
+	199, 2565,
+	201, 2565,
+	207, 2565,
+	208, 2565,
+	209, 2565,
+	210, 2565,
+	214, 2565,
+	216, 2565,
+	217, 2565,
+	218, 2565,
+	219, 2565,
+	220, 2565,
+	221, 2565,
+	222, 2565,
+	224, 2565,
+	225, 2565,
+	226, 2565,
+	229, 2565,
+	230, 2565,
+	231, 2565,
+	232, 2565,
+	233, 2565,
+	234, 2565,
+	235, 2565,
+	236, 2565,
+	237, 2565,
+	238, 2565,
+	239, 2565,
+	240, 2565,
+	241, 2565,
+	242, 2565,
+	244, 2565,
+	245, 2565,
+	246, 2565,
+	248, 2565,
+	249, 2565,
+	251, 2565,
+	252, 2565,
+	253, 2565,
+	254, 2565,
+	255, 2565,
+	256, 2565,
+	257, 2565,
+	258, 2565,
+	259, 2565,
+	260, 2565,
+	261, 2565,
+	263, 2565,
+	264, 2565,
+	265, 2565,
+	266, 2565,
+	268, 2565,
+	269, 2565,
+	270, 2565,
+	271, 2565,
+	272, 2565,
+	273, 2565,
+	274, 2565,
+	278, 2565,
+	279, 2565,
+	280, 2565,
+	281, 2565,
+	283, 2565,
+	284, 2565,
+	285, 2565,
+	287, 2565,
+	288, 2565,
+	289, 2565,
+	290, 2565,
+	291, 2565,
+	292, 2565,
+	293, 2565,
+	295, 2565,
+	297, 2565,
+	298, 2565,
+	299, 2565,
+	301, 2565,
+	303, 2565,
+	304, 2565,
+	305, 2565,
+	307, 2565,
+	311, 2565,
+	312, 2565,
+	313, 2565,
+	314, 2565,
+	315, 2565,
+	316, 2565,
+	317, 2565,
+	319, 2565,
+	320, 2565,
+	321, 2565,
+	323, 2565,
+	324, 2565,
+	325, 2565,
+	327, 2565,
+	328, 2565,
+	331, 2565,
+	332, 2565,
+	333, 2565,
+	334, 2565,
+	335, 2565,
+	336, 2565,
+	337, 2565,
+	340, 2565,
+	341, 2565,
+	342, 2565,
+	343, 2565,
+	344, 2565,
+	345, 2565,
+	347, 2565,
+	348, 2565,
+	349, 2565,
+	350, 2565,
+	351, 2565,
+	352, 2565,
+	353, 2565,
+	354, 2565,
+	355, 2565,
+	356, 2565,
+	357, 2565,
+	358, 2565,
+	359, 2565,
+	360, 2565,
+	361, 2565,
+	362, 2565,
+	363, 2565,
+	364, 2565,
+	365, 2565,
+	366, 2565,
+	367, 2565,
+	368, 2565,
+	369, 2565,
+	370, 2565,
+	371, 2565,
+	373, 2565,
+	376, 2565,
+	377, 2565,
+	378, 2565,
+	379, 2565,
+	380, 2565,
+	381, 2565,
+	382, 2565,
+	383, 2565,
+	384, 2565,
+	385, 2565,
+	386, 2565,
+	387, 2565,
+	388, 2565,
+	389, 2565,
+	390, 2565,
+	391, 2565,
+	392, 2565,
+	393, 2565,
+	394, 2565,
+	395, 2565,
+	396, 2565,
+	398, 2565,
+	399, 2565,
+	401, 2565,
+	402, 2565,
+	404, 2565,
+	405, 2565,
+	406, 2565,
+	407, 2565,
+	409, 2565,
+	410, 2565,
+	411, 2565,
+	412, 2565,
+	413, 2565,
+	416, 2565,
+	418, 2565,
+	419, 2565,
+	422, 2565,
+	423, 2565,
+	424, 2565,
+	427, 2565,
+	428, 2565,
+	429, 2565,
+	431, 2565,
+	433, 2565,
+	434, 2565,
+	435, 2565,
+	436, 2565,
+	437, 2565,
+	438, 2565,
+	439, 2565,
+	440, 2565,
+	441, 2565,
+	442, 2565,
+	443, 2565,
+	444, 2565,
+	445, 2565,
+	446, 2565,
+	447, 2565,
+	448, 2565,
+	450, 2565,
+	451, 2565,
+	452, 2565,
+	453, 2565,
+	454, 2565,
+	455, 2565,
+	456, 2565,
+	457, 2565,
+	458, 2565,
+	459, 2565,
+	460, 2565,
+	461, 2565,
+	462, 2565,
+	463, 2565,
+	464, 2565,
+	465, 2565,
+	466, 2565,
+	467, 2565,
+	469, 2565,
+	470, 2565,
+	471, 2565,
+	473, 2565,
+	474, 2565,
+	475, 2565,
+	476, 2565,
+	477, 2565,
+	478, 2565,
+	479, 2565,
+	480, 2565,
+	481, 2565,
+	482, 2565,
+	483, 2565,
+	484, 2565,
+	485, 2565,
+	486, 2565,
+	487, 2565,
+	488, 2565,
+	489, 2565,
+	491, 2565,
+	492, 2565,
+	494, 2565,
+	495, 2565,
+	496, 2565,
+	502, 2565,
+	503, 2565,
+	504, 2565,
+	506, 2565,
+	507, 2565,
+	508, 2565,
+	509, 2565,
+	510, 2565,
+	511, 2565,
+	512, 2565,
+	513, 2565,
+	514, 2565,
+	515, 2565,
+	516, 2565,
+	517, 2565,
+	518, 2565,
+	519, 2565,
+	520, 2565,
+	522, 2565,
+	523, 2565,
+	524, 2565,
+	525, 2565,
+	526, 2565,
+	528, 2565,
+	529, 2565,
+	530, 2565,
+	531, 2565,
+	532, 2565,
+	533, 2565,
+	534, 2565,
+	536, 2565,
+	537, 2565,
+	538, 2565,
+	539, 2565,
+	540, 2565,
+	541, 2565,
+	542, 2565,
+	543, 2565,
+	544, 2565,
+	545, 2565,
+	546, 2565,
+	547, 2565,
+	548, 2565,
+	549, 2565,
+	550, 2565,
+	551, 2565,
+	553, 2565,
+	554, 2565,
+	555, 2565,
+	556, 2565,
+	557, 2565,
+	558, 2565,
+	559, 2565,
+	561, 2565,
+	562, 2565,
+	563, 2565,
+	564, 2565,
+	565, 2565,
+	566, 2565,
+	567, 2565,
+	568, 2565,
+	570, 2565,
+	571, 2565,
+	572, 2565,
+	573, 2565,
+	574, 2565,
+	575, 2565,
+	576, 2565,
+	577, 2565,
+	578, 2565,
+	579, 2565,
+	581, 2565,
+	583, 2565,
+	584, 2565,
+	585, 2565,
+	586, 2565,
+	587, 2565,
+	588, 2565,
+	589, 2565,
+	590, 2565,
+	591, 2565,
+	592, 2565,
+	593, 2565,
+	594, 2565,
+	595, 2565,
+	596, 2565,
+	597, 2565,
+	598, 2565,
+	599, 2565,
+	600, 2565,
+	601, 2565,
+	602, 2565,
+	603, 2565,
+	604, 2565,
+	605, 2565,
+	606, 2565,
+	607, 2565,
+	608, 2565,
+	609, 2565,
+	611, 2565,
+	612, 2565,
+	614, 2565,
+	615, 2565,
+	617, 2565,
+	618, 2565,
+	619, 2565,
+	620, 2565,
+	621, 2565,
+	622, 2565,
+	623, 2565,
+	624, 2565,
+	625, 2565,
+	626, 2565,
+	628, 2565,
+	629, 2565,
+	630, 2565,
+	631, 2565,
+	632, 2565,
+	634, 2565,
+	636, 2565,
+	637, 2565,
+	638, 2565,
+	639, 2565,
+	640, 2565,
+	641, 2565,
+	642, 2565,
+	643, 2565,
+	644, 2565,
+	646, 2565,
+	647, 2565,
+	648, 2565,
+	649, 2565,
+	650, 2565,
+	651, 2565,
+	652, 2565,
+	653, 2565,
+	656, 2565,
+	657, 2565,
+	658, 2565,
+	659, 2565,
+	660, 2565,
+	661, 2565,
+	662, 2565,
+	663, 2565,
+	664, 2565,
+	665, 2565,
+	666, 2565,
+	668, 2565,
+	671, 2565,
+	672, 2565,
+	673, 2565,
+	674, 2565,
+	675, 2565,
+	676, 2565,
+	678, 2565,
+	679, 2565,
+	680, 2565,
+	681, 2565,
+	682, 2565,
+	683, 2565,
+	684, 2565,
+	685, 2565,
+	686, 2565,
+	687, 2565,
+	688, 2565,
+	689, 2565,
+	690, 2565,
+	691, 2565,
+	692, 2565,
+	693, 2565,
+	694, 2565,
+	695, 2565,
+	700, 2565,
+	701, 2565,
+	702, 2565,
+	703, 2565,
+	704, 2565,
+	705, 2565,
 	-2, 0,
-	-1, 1225,
-	182, 1404,
-	305, 1404,
-	455, 1358,
-	534, 1358,
-	586, 1358,
-	607, 1404,
-	609, 1358,
+	-1, 1300,
+	316, 825,
 	-2, 0,
-	-1, 1346,
-	196, 2184,
-	209, 2184,
-	321, 2184,
-	398, 2184,
-	-2, 2120,
-	-1, 1364,
-	196, 2183,
-	209, 2183,
-	321, 2183,
-	398, 2183,
-	-2, 2117,
-	-1, 1393,
-	5, 4073,
-	706, 4073,
-	-2, 1097,
-	-1, 1394,
-	708, 2943,
-	-2, 1098,
-	-1, 1429,
-	5, 2935,
-	706, 2932,
-	-2, 2923,
-	-1, 1438,
-	708, 2941,
-	-2, 2922,
-	-1, 1460,
-	5, 2956,
-	706, 2953,
-	-2, 2944,
-	-1, 1461,
-	5, 2957,
-	706, 2954,
-	-2, 2945,
-	-1, 1462,
-	5, 2958,
-	38, 2958,
-	145, 2958,
-	688, 2958,
-	704, 2958,
-	707, 2958,
-	708, 2958,
-	711, 2958,
-	-2, 4059,
-	-1, 1463,
-	5, 2414,
-	-2, 4029,
-	-1, 1464,
-	5, 2415,
-	-2, 4030,
-	-1, 1465,
-	5, 2416,
-	-2, 4045,
-	-1, 1466,
-	5, 2417,
-	-2, 4007,
-	-1, 1467,
-	5, 2418,
-	-2, 4042,
-	-1, 1468,
-	5, 2426,
-	-2, 4020,
-	-1, 1470,
-	5, 2413,
-	-2, 4016,
-	-1, 1471,
-	5, 2413,
-	-2, 4015,
-	-1, 1472,
-	5, 2413,
-	-2, 4035,
-	-1, 1473,
-	5, 2424,
-	-2, 4009,
-	-1, 1474,
-	5, 2429,
-	706, 2441,
-	-2, 4008,
-	-1, 1475,
-	5, 2431,
-	-2, 4055,
-	-1, 1478,
-	5, 2453,
-	-2, 4048,
-	-1, 1479,
-	5, 2445,
-	-2, 4049,
-	-1, 1480,
-	5, 2453,
-	-2, 4050,
-	-1, 1481,
-	5, 2449,
-	-2, 4051,
-	-1, 1482,
-	5, 2397,
-	-2, 4021,
+	-1, 1301,
+	188, 1592,
+	314, 1592,
+	477, 1546,
+	559, 1546,
+	615, 1546,
+	636, 1592,
+	638, 1546,
+	-2, 0,
+	-1, 1434,
+	202, 2407,
+	215, 2407,
+	330, 2407,
+	414, 2407,
+	-2, 2344,
+	-1, 1454,
+	202, 2406,
+	215, 2406,
+	330, 2406,
+	414, 2406,
+	-2, 2341,
 	-1, 1483,
-	5, 2398,
-	-2, 4022,
+	5, 4370,
+	739, 4370,
+	-2, 1277,
 	-1, 1484,
-	5, 2399,
-	-2, 4010,
-	-1, 1495,
-	5, 2436,
-	706, 2436,
-	-2, 4056,
-	-1, 1496,
-	5, 2437,
-	706, 2437,
-	-2, 4046,
-	-1, 1497,
-	5, 2438,
-	649, 2438,
-	706, 2438,
-	-2, 4011,
-	-1, 1498,
-	5, 2439,
-	649, 2439,
-	706, 2439,
-	-2, 4012,
-	-1, 1659,
-	220, 3383,
-	604, 3383,
-	688, 3383,
-	708, 3383,
+	741, 3180,
+	-2, 1278,
+	-1, 1519,
+	5, 3172,
+	739, 3169,
+	-2, 3160,
+	-1, 1529,
+	741, 3178,
+	-2, 3159,
+	-1, 1551,
+	5, 3193,
+	739, 3190,
+	-2, 3181,
+	-1, 1552,
+	5, 3194,
+	739, 3191,
+	-2, 3182,
+	-1, 1553,
+	5, 3195,
+	38, 3195,
+	147, 3195,
+	721, 3195,
+	737, 3195,
+	740, 3195,
+	741, 3195,
+	744, 3195,
+	-2, 4356,
+	-1, 1554,
+	5, 2643,
+	-2, 4325,
+	-1, 1555,
+	5, 2644,
+	-2, 4326,
+	-1, 1556,
+	5, 2645,
+	-2, 4341,
+	-1, 1557,
+	5, 2646,
+	-2, 4303,
+	-1, 1558,
+	5, 2647,
+	-2, 4338,
+	-1, 1559,
+	5, 2655,
+	-2, 4316,
+	-1, 1561,
+	5, 2642,
+	-2, 4312,
+	-1, 1562,
+	5, 2642,
+	-2, 4311,
+	-1, 1563,
+	5, 2642,
+	-2, 4331,
+	-1, 1564,
+	5, 2653,
+	-2, 4305,
+	-1, 1565,
+	5, 2658,
+	739, 2670,
+	-2, 4304,
+	-1, 1566,
+	5, 2660,
+	-2, 4351,
+	-1, 1569,
+	5, 2682,
+	-2, 4344,
+	-1, 1570,
+	5, 2674,
+	-2, 4345,
+	-1, 1571,
+	5, 2682,
+	-2, 4346,
+	-1, 1572,
+	5, 2678,
+	-2, 4347,
+	-1, 1573,
+	5, 2623,
+	-2, 4317,
+	-1, 1574,
+	5, 2624,
+	-2, 4318,
+	-1, 1575,
+	5, 2625,
+	-2, 4306,
+	-1, 1576,
+	5, 2630,
+	-2, 4353,
+	-1, 1587,
+	5, 2665,
+	739, 2665,
+	-2, 4352,
+	-1, 1588,
+	5, 2666,
+	739, 2666,
+	-2, 4342,
+	-1, 1589,
+	5, 2667,
+	682, 2667,
+	739, 2667,
+	-2, 4307,
+	-1, 1590,
+	5, 2668,
+	682, 2668,
+	739, 2668,
+	-2, 4308,
+	-1, 1766,
+	227, 3646,
+	633, 3646,
+	721, 3646,
+	741, 3646,
 	-2, 0,
-	-1, 1664,
-	1, 1073,
-	709, 1073,
-	712, 1073,
-	-2, 2023,
-	-1, 1723,
-	220, 1279,
-	-2, 3318,
-	-1, 1724,
-	220, 1280,
-	-2, 3084,
-	-1, 1725,
-	220, 1281,
-	-2, 3266,
-	-1, 1726,
-	220, 1282,
-	-2, 3408,
-	-1, 1741,
-	1, 1499,
-	705, 1499,
-	707, 1499,
-	709, 1499,
-	712, 1499,
+	-1, 1771,
+	1, 1253,
+	742, 1253,
+	745, 1253,
+	-2, 2244,
+	-1, 1831,
+	227, 1469,
+	-2, 3577,
+	-1, 1832,
+	227, 1470,
+	-2, 3325,
+	-1, 1833,
+	227, 1471,
+	-2, 3522,
+	-1, 1834,
+	227, 1472,
+	-2, 3673,
+	-1, 1842,
+	1, 1695,
+	738, 1695,
+	740, 1695,
+	742, 1695,
+	745, 1695,
 	-2, 0,
-	-1, 1742,
-	455, 1359,
-	534, 1359,
-	586, 1359,
-	609, 1359,
+	-1, 1843,
+	477, 1547,
+	559, 1547,
+	615, 1547,
+	638, 1547,
 	-2, 0,
-	-1, 1753,
-	1, 1962,
-	259, 1962,
-	705, 1962,
-	707, 1962,
-	709, 1962,
-	712, 1962,
+	-1, 1854,
+	1, 2177,
+	267, 2177,
+	738, 2177,
+	740, 2177,
+	742, 2177,
+	745, 2177,
 	-2, 0,
-	-1, 1772,
-	1, 1354,
-	705, 1354,
-	707, 1354,
-	709, 1354,
-	712, 1354,
+	-1, 1858,
+	1, 1516,
+	738, 1516,
+	740, 1516,
+	742, 1516,
+	745, 1516,
 	-2, 0,
-	-1, 1773,
-	1, 1405,
-	705, 1405,
-	707, 1405,
-	709, 1405,
-	712, 1405,
+	-1, 1880,
+	1, 1542,
+	738, 1542,
+	740, 1542,
+	742, 1542,
+	745, 1542,
 	-2, 0,
-	-1, 1774,
-	1, 1421,
-	705, 1421,
-	707, 1421,
-	709, 1421,
-	712, 1421,
+	-1, 1881,
+	1, 1593,
+	738, 1593,
+	740, 1593,
+	742, 1593,
+	745, 1593,
 	-2, 0,
-	-1, 1777,
-	1, 1363,
-	705, 1363,
-	707, 1363,
-	709, 1363,
-	712, 1363,
+	-1, 1882,
+	1, 1609,
+	738, 1609,
+	740, 1609,
+	742, 1609,
+	745, 1609,
 	-2, 0,
-	-1, 1780,
-	1, 1370,
-	705, 1370,
-	707, 1370,
-	709, 1370,
-	712, 1370,
+	-1, 1885,
+	1, 1551,
+	738, 1551,
+	740, 1551,
+	742, 1551,
+	745, 1551,
 	-2, 0,
-	-1, 1784,
-	1, 1366,
-	705, 1366,
-	707, 1366,
-	709, 1366,
-	712, 1366,
+	-1, 1888,
+	1, 1558,
+	738, 1558,
+	740, 1558,
+	742, 1558,
+	745, 1558,
 	-2, 0,
-	-1, 1789,
-	1, 1385,
-	705, 1385,
-	707, 1385,
-	709, 1385,
-	712, 1385,
+	-1, 1892,
+	1, 1554,
+	738, 1554,
+	740, 1554,
+	742, 1554,
+	745, 1554,
 	-2, 0,
-	-1, 1831,
-	1, 3307,
-	666, 3307,
-	705, 3307,
-	707, 3307,
-	708, 3307,
-	709, 3307,
-	712, 3307,
+	-1, 1897,
+	1, 1573,
+	738, 1573,
+	740, 1573,
+	742, 1573,
+	745, 1573,
 	-2, 0,
-	-1, 1836,
-	1, 1482,
-	705, 1482,
-	707, 1482,
-	709, 1482,
-	712, 1482,
+	-1, 1943,
+	1, 3566,
+	699, 3566,
+	738, 3566,
+	740, 3566,
+	741, 3566,
+	742, 3566,
+	745, 3566,
+	-2, 0,
+	-1, 1948,
+	1, 1678,
+	738, 1678,
+	740, 1678,
+	742, 1678,
+	745, 1678,
 	-2, 0,
-	-1, 1860,
-	1, 2018,
-	709, 2018,
-	712, 2018,
-	-2, 2023,
-	-1, 1960,
-	418, 2917,
-	484, 2917,
-	536, 2917,
-	698, 2917,
-	-2, 2903,
-	-1, 1970,
-	220, 178,
-	314, 178,
-	382, 178,
-	660, 178,
-	-2, 3378,
-	-1, 1971,
-	220, 179,
-	314, 179,
-	382, 179,
-	660, 179,
-	-2, 3075,
 	-1, 1972,
-	220, 180,
-	314, 180,
-	382, 180,
-	660, 180,
-	-2, 3281,
-	-1, 1978,
-	710, 2917,
-	-2, 2919,
-	-1, 1981,
-	25, 3307,
-	259, 3307,
+	1, 2239,
+	742, 2239,
+	745, 2239,
+	-2, 2244,
+	-1, 2072,
+	435, 3154,
+	507, 3154,
+	561, 3154,
+	731, 3154,
+	-2, 3140,
+	-1, 2082,
+	227, 184,
+	323, 184,
+	398, 184,
+	693, 184,
+	-2, 3641,
+	-1, 2083,
+	227, 185,
+	323, 185,
+	398, 185,
+	693, 185,
+	-2, 3316,
+	-1, 2084,
+	227, 186,
+	323, 186,
+	398, 186,
+	693, 186,
+	-2, 3538,
+	-1, 2090,
+	743, 3154,
+	-2, 3156,
+	-1, 2093,
+	25, 3566,
+	267, 3566,
+	-2, 0,
+	-1, 2110,
+	1, 2066,
+	513, 2015,
+	561, 2015,
+	712, 2015,
+	718, 2015,
+	738, 2066,
+	740, 2066,
+	742, 2066,
+	745, 2066,
+	-2, 2392,
+	-1, 2116,
+	243, 2177,
+	267, 2177,
+	526, 2177,
 	-2, 0,
-	-1, 1994,
-	1, 1855,
-	489, 1807,
-	536, 1807,
-	679, 1807,
-	685, 1807,
-	705, 1855,
-	707, 1855,
-	709, 1855,
-	712, 1855,
-	-2, 2169,
-	-1, 2000,
-	236, 1962,
-	259, 1962,
-	501, 1962,
+	-1, 2192,
+	48, 3152,
+	-2, 1787,
+	-1, 2199,
+	1, 2066,
+	738, 2066,
+	740, 2066,
+	742, 2066,
+	745, 2066,
+	-2, 2392,
+	-1, 2202,
+	486, 1824,
+	680, 1824,
+	-2, 665,
+	-1, 2208,
+	4, 2100,
+	21, 2100,
+	22, 2100,
+	23, 2100,
+	24, 2100,
+	25, 2100,
+	26, 2100,
+	27, 2100,
+	28, 2100,
+	30, 2100,
+	31, 2100,
+	37, 2100,
+	41, 2100,
+	43, 2100,
+	45, 2100,
+	46, 2100,
+	47, 2100,
+	49, 2100,
+	50, 2100,
+	51, 2100,
+	52, 2100,
+	53, 2100,
+	54, 2100,
+	55, 2100,
+	56, 2100,
+	57, 2100,
+	58, 2100,
+	59, 2100,
+	60, 2100,
+	62, 2100,
+	63, 2100,
+	64, 2100,
+	65, 2100,
+	67, 2100,
+	68, 2100,
+	69, 2100,
+	70, 2100,
+	71, 2100,
+	72, 2100,
+	73, 2100,
+	74, 2100,
+	75, 2100,
+	76, 2100,
+	77, 2100,
+	78, 2100,
+	82, 2100,
+	83, 2100,
+	84, 2100,
+	85, 2100,
+	87, 2100,
+	88, 2100,
+	89, 2100,
+	90, 2100,
+	91, 2100,
+	95, 2100,
+	96, 2100,
+	97, 2100,
+	98, 2100,
+	99, 2100,
+	100, 2100,
+	101, 2100,
+	102, 2100,
+	105, 2100,
+	106, 2100,
+	107, 2100,
+	108, 2100,
+	109, 2100,
+	110, 2100,
+	112, 2100,
+	114, 2100,
+	115, 2100,
+	116, 2100,
+	117, 2100,
+	118, 2100,
+	120, 2100,
+	121, 2100,
+	123, 2100,
+	124, 2100,
+	125, 2100,
+	127, 2100,
+	128, 2100,
+	129, 2100,
+	137, 2100,
+	138, 2100,
+	139, 2100,
+	140, 2100,
+	141, 2100,
+	143, 2100,
+	144, 2100,
+	145, 2100,
+	146, 2100,
+	148, 2100,
+	149, 2100,
+	150, 2100,
+	151, 2100,
+	153, 2100,
+	154, 2100,
+	155, 2100,
+	156, 2100,
+	158, 2100,
+	159, 2100,
+	160, 2100,
+	161, 2100,
+	162, 2100,
+	166, 2100,
+	167, 2100,
+	168, 2100,
+	169, 2100,
+	171, 2100,
+	172, 2100,
+	173, 2100,
+	174, 2100,
+	175, 2100,
+	177, 2100,
+	178, 2100,
+	179, 2100,
+	181, 2100,
+	182, 2100,
+	183, 2100,
+	184, 2100,
+	185, 2100,
+	186, 2100,
+	187, 2100,
+	188, 2100,
+	189, 2100,
+	190, 2100,
+	191, 2100,
+	192, 2100,
+	193, 2100,
+	194, 2100,
+	195, 2100,
+	196, 2100,
+	197, 2100,
+	198, 2100,
+	199, 2100,
+	207, 2100,
+	208, 2100,
+	209, 2100,
+	210, 2100,
+	214, 2100,
+	216, 2100,
+	217, 2100,
+	218, 2100,
+	219, 2100,
+	220, 2100,
+	221, 2100,
+	222, 2100,
+	224, 2100,
+	225, 2100,
+	226, 2100,
+	229, 2100,
+	230, 2100,
+	231, 2100,
+	232, 2100,
+	233, 2100,
+	234, 2100,
+	235, 2100,
+	236, 2100,
+	237, 2100,
+	238, 2100,
+	239, 2100,
+	240, 2100,
+	241, 2100,
+	242, 2100,
+	244, 2100,
+	245, 2100,
+	246, 2100,
+	248, 2100,
+	249, 2100,
+	251, 2100,
+	252, 2100,
+	253, 2100,
+	254, 2100,
+	255, 2100,
+	256, 2100,
+	257, 2100,
+	258, 2100,
+	259, 2100,
+	260, 2100,
+	261, 2100,
+	263, 2100,
+	264, 2100,
+	265, 2100,
+	266, 2100,
+	268, 2100,
+	269, 2100,
+	270, 2100,
+	271, 2100,
+	272, 2100,
+	273, 2100,
+	274, 2100,
+	278, 2100,
+	279, 2100,
+	280, 2100,
+	281, 2100,
+	287, 2100,
+	288, 2100,
+	289, 2100,
+	290, 2100,
+	291, 2100,
+	292, 2100,
+	293, 2100,
+	295, 2100,
+	297, 2100,
+	298, 2100,
+	299, 2100,
+	301, 2100,
+	303, 2100,
+	304, 2100,
+	305, 2100,
+	307, 2100,
+	311, 2100,
+	312, 2100,
+	313, 2100,
+	314, 2100,
+	315, 2100,
+	316, 2100,
+	317, 2100,
+	319, 2100,
+	320, 2100,
+	321, 2100,
+	323, 2100,
+	324, 2100,
+	325, 2100,
+	327, 2100,
+	328, 2100,
+	331, 2100,
+	332, 2100,
+	333, 2100,
+	334, 2100,
+	335, 2100,
+	336, 2100,
+	337, 2100,
+	340, 2100,
+	341, 2100,
+	342, 2100,
+	343, 2100,
+	344, 2100,
+	345, 2100,
+	347, 2100,
+	348, 2100,
+	349, 2100,
+	350, 2100,
+	351, 2100,
+	352, 2100,
+	353, 2100,
+	354, 2100,
+	355, 2100,
+	356, 2100,
+	357, 2100,
+	358, 2100,
+	359, 2100,
+	360, 2100,
+	361, 2100,
+	362, 2100,
+	363, 2100,
+	364, 2100,
+	365, 2100,
+	366, 2100,
+	367, 2100,
+	368, 2100,
+	369, 2100,
+	370, 2100,
+	371, 2100,
+	373, 2100,
+	376, 2100,
+	377, 2100,
+	378, 2100,
+	379, 2100,
+	380, 2100,
+	381, 2100,
+	382, 2100,
+	383, 2100,
+	384, 2100,
+	385, 2100,
+	386, 2100,
+	387, 2100,
+	388, 2100,
+	389, 2100,
+	390, 2100,
+	391, 2100,
+	392, 2100,
+	393, 2100,
+	394, 2100,
+	395, 2100,
+	396, 2100,
+	398, 2100,
+	399, 2100,
+	401, 2100,
+	404, 2100,
+	405, 2100,
+	406, 2100,
+	407, 2100,
+	409, 2100,
+	410, 2100,
+	411, 2100,
+	412, 2100,
+	413, 2100,
+	416, 2100,
+	418, 2100,
+	419, 2100,
+	420, 2100,
+	422, 2100,
+	423, 2100,
+	424, 2100,
+	427, 2100,
+	428, 2100,
+	429, 2100,
+	431, 2100,
+	433, 2100,
+	434, 2100,
+	435, 2100,
+	436, 2100,
+	437, 2100,
+	438, 2100,
+	439, 2100,
+	440, 2100,
+	441, 2100,
+	442, 2100,
+	443, 2100,
+	444, 2100,
+	445, 2100,
+	446, 2100,
+	447, 2100,
+	448, 2100,
+	450, 2100,
+	451, 2100,
+	452, 2100,
+	453, 2100,
+	454, 2100,
+	455, 2100,
+	456, 2100,
+	457, 2100,
+	458, 2100,
+	459, 2100,
+	460, 2100,
+	461, 2100,
+	462, 2100,
+	463, 2100,
+	464, 2100,
+	465, 2100,
+	466, 2100,
+	467, 2100,
+	469, 2100,
+	470, 2100,
+	471, 2100,
+	473, 2100,
+	474, 2100,
+	475, 2100,
+	476, 2100,
+	477, 2100,
+	478, 2100,
+	479, 2100,
+	480, 2100,
+	481, 2100,
+	482, 2100,
+	483, 2100,
+	484, 2100,
+	485, 2100,
+	486, 2100,
+	487, 2100,
+	488, 2100,
+	489, 2100,
+	491, 2100,
+	492, 2100,
+	494, 2100,
+	495, 2100,
+	496, 2100,
+	502, 2100,
+	503, 2100,
+	504, 2100,
+	506, 2100,
+	507, 2100,
+	508, 2100,
+	509, 2100,
+	510, 2100,
+	511, 2100,
+	512, 2100,
+	513, 2100,
+	514, 2100,
+	515, 2100,
+	516, 2100,
+	517, 2100,
+	518, 2100,
+	519, 2100,
+	520, 2100,
+	522, 2100,
+	523, 2100,
+	524, 2100,
+	525, 2100,
+	526, 2100,
+	528, 2100,
+	529, 2100,
+	530, 2100,
+	531, 2100,
+	532, 2100,
+	533, 2100,
+	534, 2100,
+	536, 2100,
+	537, 2100,
+	538, 2100,
+	539, 2100,
+	540, 2100,
+	541, 2100,
+	542, 2100,
+	543, 2100,
+	544, 2100,
+	545, 2100,
+	546, 2100,
+	547, 2100,
+	548, 2100,
+	549, 2100,
+	550, 2100,
+	551, 2100,
+	553, 2100,
+	554, 2100,
+	555, 2100,
+	556, 2100,
+	557, 2100,
+	558, 2100,
+	559, 2100,
+	561, 2100,
+	562, 2100,
+	563, 2100,
+	564, 2100,
+	565, 2100,
+	566, 2100,
+	567, 2100,
+	568, 2100,
+	570, 2100,
+	571, 2100,
+	572, 2100,
+	573, 2100,
+	574, 2100,
+	575, 2100,
+	576, 2100,
+	577, 2100,
+	578, 2100,
+	579, 2100,
+	581, 2100,
+	583, 2100,
+	584, 2100,
+	585, 2100,
+	586, 2100,
+	587, 2100,
+	588, 2100,
+	589, 2100,
+	590, 2100,
+	591, 2100,
+	592, 2100,
+	593, 2100,
+	594, 2100,
+	595, 2100,
+	596, 2100,
+	597, 2100,
+	598, 2100,
+	599, 2100,
+	600, 2100,
+	601, 2100,
+	602, 2100,
+	603, 2100,
+	604, 2100,
+	605, 2100,
+	606, 2100,
+	607, 2100,
+	608, 2100,
+	609, 2100,
+	611, 2100,
+	612, 2100,
+	614, 2100,
+	615, 2100,
+	617, 2100,
+	618, 2100,
+	619, 2100,
+	620, 2100,
+	621, 2100,
+	622, 2100,
+	623, 2100,
+	624, 2100,
+	625, 2100,
+	626, 2100,
+	628, 2100,
+	629, 2100,
+	630, 2100,
+	631, 2100,
+	632, 2100,
+	634, 2100,
+	636, 2100,
+	637, 2100,
+	638, 2100,
+	639, 2100,
+	640, 2100,
+	641, 2100,
+	642, 2100,
+	643, 2100,
+	644, 2100,
+	646, 2100,
+	647, 2100,
+	648, 2100,
+	649, 2100,
+	650, 2100,
+	651, 2100,
+	652, 2100,
+	653, 2100,
+	656, 2100,
+	657, 2100,
+	658, 2100,
+	659, 2100,
+	660, 2100,
+	661, 2100,
+	662, 2100,
+	663, 2100,
+	664, 2100,
+	665, 2100,
+	666, 2100,
+	668, 2100,
+	671, 2100,
+	672, 2100,
+	673, 2100,
+	674, 2100,
+	675, 2100,
+	676, 2100,
+	678, 2100,
+	679, 2100,
+	680, 2100,
+	681, 2100,
+	682, 2100,
+	683, 2100,
+	684, 2100,
+	685, 2100,
+	686, 2100,
+	687, 2100,
+	688, 2100,
+	689, 2100,
+	690, 2100,
+	691, 2100,
+	692, 2100,
+	693, 2100,
+	694, 2100,
+	695, 2100,
+	700, 2100,
+	701, 2100,
+	702, 2100,
+	703, 2100,
+	704, 2100,
+	705, 2100,
 	-2, 0,
-	-1, 2071,
-	48, 2915,
-	-2, 1584,
-	-1, 2078,
-	1, 1855,
-	705, 1855,
-	707, 1855,
-	709, 1855,
-	712, 1855,
-	-2, 2169,
-	-1, 2081,
-	464, 1621,
-	648, 1621,
-	-2, 557,
-	-1, 2087,
-	4, 1885,
-	21, 1885,
-	22, 1885,
-	23, 1885,
-	24, 1885,
-	25, 1885,
-	26, 1885,
-	27, 1885,
-	28, 1885,
-	30, 1885,
-	31, 1885,
-	37, 1885,
-	41, 1885,
-	43, 1885,
-	45, 1885,
-	46, 1885,
-	47, 1885,
-	49, 1885,
-	50, 1885,
-	51, 1885,
-	52, 1885,
-	53, 1885,
-	54, 1885,
-	55, 1885,
-	56, 1885,
-	57, 1885,
-	58, 1885,
-	60, 1885,
-	61, 1885,
-	62, 1885,
-	63, 1885,
-	65, 1885,
-	66, 1885,
-	67, 1885,
-	68, 1885,
-	69, 1885,
-	70, 1885,
-	71, 1885,
-	72, 1885,
-	73, 1885,
-	74, 1885,
-	75, 1885,
-	79, 1885,
-	80, 1885,
-	81, 1885,
-	82, 1885,
-	84, 1885,
-	85, 1885,
-	86, 1885,
-	87, 1885,
-	88, 1885,
-	92, 1885,
-	93, 1885,
-	94, 1885,
-	95, 1885,
-	96, 1885,
-	97, 1885,
-	98, 1885,
-	99, 1885,
-	102, 1885,
-	103, 1885,
-	104, 1885,
-	105, 1885,
-	106, 1885,
-	107, 1885,
-	109, 1885,
-	111, 1885,
-	112, 1885,
-	113, 1885,
-	114, 1885,
-	115, 1885,
-	116, 1885,
-	117, 1885,
-	119, 1885,
-	120, 1885,
-	121, 1885,
-	123, 1885,
-	124, 1885,
-	125, 1885,
-	133, 1885,
-	134, 1885,
-	135, 1885,
-	136, 1885,
-	137, 1885,
-	139, 1885,
-	140, 1885,
-	141, 1885,
-	142, 1885,
-	143, 1885,
-	144, 1885,
-	146, 1885,
-	147, 1885,
-	148, 1885,
-	149, 1885,
-	151, 1885,
-	152, 1885,
-	153, 1885,
-	154, 1885,
-	156, 1885,
-	157, 1885,
-	158, 1885,
-	159, 1885,
-	162, 1885,
-	163, 1885,
-	164, 1885,
-	166, 1885,
-	167, 1885,
-	168, 1885,
-	169, 1885,
-	171, 1885,
-	172, 1885,
-	173, 1885,
-	175, 1885,
-	176, 1885,
-	177, 1885,
-	178, 1885,
-	179, 1885,
-	180, 1885,
-	181, 1885,
-	182, 1885,
-	183, 1885,
-	184, 1885,
-	185, 1885,
-	186, 1885,
-	187, 1885,
-	188, 1885,
-	189, 1885,
-	190, 1885,
-	191, 1885,
-	192, 1885,
-	193, 1885,
-	201, 1885,
-	202, 1885,
-	203, 1885,
-	204, 1885,
-	208, 1885,
-	210, 1885,
-	211, 1885,
-	212, 1885,
-	213, 1885,
-	214, 1885,
-	215, 1885,
-	217, 1885,
-	218, 1885,
-	219, 1885,
-	222, 1885,
-	223, 1885,
-	224, 1885,
-	225, 1885,
-	226, 1885,
-	227, 1885,
-	228, 1885,
-	229, 1885,
-	230, 1885,
-	231, 1885,
-	232, 1885,
-	233, 1885,
-	234, 1885,
-	235, 1885,
-	237, 1885,
-	238, 1885,
-	239, 1885,
-	241, 1885,
-	242, 1885,
-	244, 1885,
-	245, 1885,
-	246, 1885,
-	247, 1885,
-	248, 1885,
-	249, 1885,
-	250, 1885,
-	251, 1885,
-	252, 1885,
-	253, 1885,
-	254, 1885,
-	256, 1885,
-	257, 1885,
-	258, 1885,
-	260, 1885,
-	261, 1885,
-	262, 1885,
-	263, 1885,
-	264, 1885,
-	265, 1885,
-	266, 1885,
-	270, 1885,
-	271, 1885,
-	272, 1885,
-	273, 1885,
-	279, 1885,
-	280, 1885,
-	281, 1885,
-	282, 1885,
-	283, 1885,
-	284, 1885,
-	286, 1885,
-	288, 1885,
-	289, 1885,
-	290, 1885,
-	292, 1885,
-	294, 1885,
-	295, 1885,
-	296, 1885,
-	298, 1885,
-	302, 1885,
-	303, 1885,
-	304, 1885,
-	305, 1885,
-	306, 1885,
-	307, 1885,
-	308, 1885,
-	310, 1885,
-	311, 1885,
-	312, 1885,
-	314, 1885,
-	315, 1885,
-	316, 1885,
-	318, 1885,
-	319, 1885,
-	322, 1885,
-	323, 1885,
-	324, 1885,
-	325, 1885,
-	326, 1885,
-	327, 1885,
-	328, 1885,
-	331, 1885,
-	332, 1885,
-	333, 1885,
-	334, 1885,
-	336, 1885,
-	337, 1885,
-	338, 1885,
-	339, 1885,
-	340, 1885,
-	341, 1885,
-	342, 1885,
-	343, 1885,
-	344, 1885,
-	345, 1885,
-	346, 1885,
-	347, 1885,
-	348, 1885,
-	349, 1885,
-	350, 1885,
-	351, 1885,
-	352, 1885,
-	353, 1885,
-	354, 1885,
-	355, 1885,
-	356, 1885,
-	357, 1885,
-	358, 1885,
-	359, 1885,
-	361, 1885,
-	363, 1885,
-	364, 1885,
-	365, 1885,
-	366, 1885,
-	367, 1885,
-	368, 1885,
-	369, 1885,
-	370, 1885,
-	371, 1885,
-	372, 1885,
-	373, 1885,
-	374, 1885,
-	375, 1885,
-	376, 1885,
-	377, 1885,
-	378, 1885,
-	379, 1885,
-	380, 1885,
-	382, 1885,
-	383, 1885,
-	385, 1885,
-	388, 1885,
-	389, 1885,
-	390, 1885,
-	391, 1885,
-	393, 1885,
-	394, 1885,
-	395, 1885,
-	396, 1885,
-	397, 1885,
-	400, 1885,
-	402, 1885,
-	403, 1885,
-	405, 1885,
-	406, 1885,
-	407, 1885,
-	410, 1885,
-	411, 1885,
-	412, 1885,
-	414, 1885,
-	416, 1885,
-	417, 1885,
-	418, 1885,
-	419, 1885,
-	420, 1885,
-	421, 1885,
-	422, 1885,
-	423, 1885,
-	424, 1885,
-	425, 1885,
-	426, 1885,
-	427, 1885,
-	428, 1885,
-	429, 1885,
-	431, 1885,
-	432, 1885,
-	433, 1885,
-	434, 1885,
-	435, 1885,
-	436, 1885,
-	437, 1885,
-	438, 1885,
-	439, 1885,
-	440, 1885,
-	441, 1885,
-	442, 1885,
-	443, 1885,
-	444, 1885,
-	445, 1885,
-	447, 1885,
-	448, 1885,
-	449, 1885,
-	451, 1885,
-	452, 1885,
-	453, 1885,
-	454, 1885,
-	455, 1885,
-	456, 1885,
-	457, 1885,
-	458, 1885,
-	459, 1885,
-	460, 1885,
-	461, 1885,
-	462, 1885,
-	463, 1885,
-	464, 1885,
-	465, 1885,
-	466, 1885,
-	467, 1885,
-	469, 1885,
-	471, 1885,
-	472, 1885,
-	473, 1885,
-	479, 1885,
-	480, 1885,
-	481, 1885,
-	483, 1885,
-	484, 1885,
-	485, 1885,
-	486, 1885,
-	487, 1885,
-	488, 1885,
-	489, 1885,
-	490, 1885,
-	491, 1885,
-	492, 1885,
-	493, 1885,
-	494, 1885,
-	495, 1885,
-	497, 1885,
-	498, 1885,
-	499, 1885,
-	500, 1885,
-	501, 1885,
-	503, 1885,
-	504, 1885,
-	505, 1885,
-	506, 1885,
-	507, 1885,
-	508, 1885,
-	509, 1885,
-	511, 1885,
-	512, 1885,
-	513, 1885,
-	514, 1885,
-	515, 1885,
-	516, 1885,
-	517, 1885,
-	518, 1885,
-	519, 1885,
-	520, 1885,
-	521, 1885,
-	522, 1885,
-	523, 1885,
-	524, 1885,
-	525, 1885,
-	526, 1885,
-	528, 1885,
-	529, 1885,
-	530, 1885,
-	531, 1885,
-	532, 1885,
-	533, 1885,
-	534, 1885,
-	536, 1885,
-	537, 1885,
-	538, 1885,
-	539, 1885,
-	540, 1885,
-	541, 1885,
-	542, 1885,
-	543, 1885,
-	545, 1885,
-	546, 1885,
-	547, 1885,
-	548, 1885,
-	549, 1885,
-	550, 1885,
-	551, 1885,
-	552, 1885,
-	553, 1885,
-	554, 1885,
-	556, 1885,
-	558, 1885,
-	559, 1885,
-	560, 1885,
-	561, 1885,
-	562, 1885,
-	563, 1885,
-	564, 1885,
-	565, 1885,
-	566, 1885,
-	567, 1885,
-	568, 1885,
-	569, 1885,
-	570, 1885,
-	571, 1885,
-	572, 1885,
-	573, 1885,
-	574, 1885,
-	575, 1885,
-	576, 1885,
-	577, 1885,
-	578, 1885,
-	579, 1885,
-	580, 1885,
-	582, 1885,
-	583, 1885,
-	585, 1885,
-	586, 1885,
-	588, 1885,
-	589, 1885,
-	590, 1885,
-	591, 1885,
-	592, 1885,
-	593, 1885,
-	594, 1885,
-	595, 1885,
-	596, 1885,
-	597, 1885,
-	599, 1885,
-	600, 1885,
-	601, 1885,
-	602, 1885,
-	603, 1885,
-	605, 1885,
-	607, 1885,
-	608, 1885,
-	609, 1885,
-	610, 1885,
-	611, 1885,
-	612, 1885,
-	613, 1885,
-	614, 1885,
-	616, 1885,
-	617, 1885,
-	618, 1885,
-	619, 1885,
-	620, 1885,
-	621, 1885,
-	622, 1885,
-	625, 1885,
-	626, 1885,
-	627, 1885,
-	628, 1885,
-	629, 1885,
-	630, 1885,
-	631, 1885,
-	632, 1885,
-	633, 1885,
-	634, 1885,
-	635, 1885,
-	637, 1885,
-	640, 1885,
-	641, 1885,
-	642, 1885,
-	643, 1885,
-	644, 1885,
-	645, 1885,
-	647, 1885,
-	648, 1885,
-	649, 1885,
-	650, 1885,
-	651, 1885,
-	652, 1885,
-	653, 1885,
-	654, 1885,
-	655, 1885,
-	656, 1885,
-	657, 1885,
-	658, 1885,
-	659, 1885,
-	660, 1885,
-	661, 1885,
-	662, 1885,
-	667, 1885,
-	668, 1885,
-	669, 1885,
-	670, 1885,
-	671, 1885,
-	672, 1885,
+	-1, 2234,
+	1, 1000,
+	738, 1000,
+	740, 1000,
+	742, 1000,
+	745, 1000,
+	-2, 2364,
+	-1, 2237,
+	4, 4350,
+	11, 4350,
+	12, 4350,
+	14, 4350,
+	15, 4350,
+	16, 4350,
+	17, 4350,
+	18, 4350,
+	19, 4350,
+	21, 4350,
+	22, 4350,
+	23, 4350,
+	24, 4350,
+	25, 4350,
+	26, 4350,
+	27, 4350,
+	28, 4350,
+	30, 4350,
+	31, 4350,
+	34, 4350,
+	35, 4350,
+	37, 4350,
+	39, 4350,
+	41, 4350,
+	42, 4350,
+	43, 4350,
+	45, 4350,
+	46, 4350,
+	47, 4350,
+	49, 4350,
+	50, 4350,
+	51, 4350,
+	52, 4350,
+	53, 4350,
+	54, 4350,
+	55, 4350,
+	56, 4350,
+	57, 4350,
+	58, 4350,
+	59, 4350,
+	60, 4350,
+	62, 4350,
+	63, 4350,
+	64, 4350,
+	65, 4350,
+	67, 4350,
+	68, 4350,
+	69, 4350,
+	70, 4350,
+	71, 4350,
+	72, 4350,
+	73, 4350,
+	74, 4350,
+	75, 4350,
+	76, 4350,
+	77, 4350,
+	78, 4350,
+	81, 4350,
+	82, 4350,
+	83, 4350,
+	84, 4350,
+	85, 4350,
+	87, 4350,
+	88, 4350,
+	89, 4350,
+	90, 4350,
+	91, 4350,
+	92, 4350,
+	95, 4350,
+	96, 4350,
+	97, 4350,
+	98, 4350,
+	99, 4350,
+	100, 4350,
+	101, 4350,
+	102, 4350,
+	103, 4350,
+	105, 4350,
+	106, 4350,
+	107, 4350,
+	108, 4350,
+	109, 4350,
+	110, 4350,
+	112, 4350,
+	113, 4350,
+	114, 4350,
+	115, 4350,
+	116, 4350,
+	117, 4350,
+	118, 4350,
+	119, 4350,
+	120, 4350,
+	121, 4350,
+	123, 4350,
+	124, 4350,
+	125, 4350,
+	126, 4350,
+	127, 4350,
+	128, 4350,
+	129, 4350,
+	137, 4350,
+	138, 4350,
+	139, 4350,
+	140, 4350,
+	141, 4350,
+	143, 4350,
+	144, 4350,
+	145, 4350,
+	146, 4350,
+	148, 4350,
+	149, 4350,
+	150, 4350,
+	151, 4350,
+	153, 4350,
+	154, 4350,
+	155, 4350,
+	156, 4350,
+	158, 4350,
+	159, 4350,
+	160, 4350,
+	161, 4350,
+	162, 4350,
+	163, 4350,
+	166, 4350,
+	167, 4350,
+	168, 4350,
+	169, 4350,
+	171, 4350,
+	172, 4350,
+	173, 4350,
+	174, 4350,
+	175, 4350,
+	177, 4350,
+	178, 4350,
+	179, 4350,
+	181, 4350,
+	182, 4350,
+	183, 4350,
+	184, 4350,
+	185, 4350,
+	186, 4350,
+	187, 4350,
+	188, 4350,
+	189, 4350,
+	190, 4350,
+	191, 4350,
+	192, 4350,
+	193, 4350,
+	194, 4350,
+	195, 4350,
+	196, 4350,
+	197, 4350,
+	198, 4350,
+	199, 4350,
+	203, 4350,
+	204, 4350,
+	205, 4350,
+	206, 4350,
+	207, 4350,
+	208, 4350,
+	209, 4350,
+	210, 4350,
+	213, 4350,
+	214, 4350,
+	216, 4350,
+	217, 4350,
+	218, 4350,
+	219, 4350,
+	220, 4350,
+	221, 4350,
+	222, 4350,
+	224, 4350,
+	225, 4350,
+	226, 4350,
+	228, 4350,
+	229, 4350,
+	230, 4350,
+	231, 4350,
+	232, 4350,
+	233, 4350,
+	234, 4350,
+	235, 4350,
+	236, 4350,
+	237, 4350,
+	238, 4350,
+	239, 4350,
+	240, 4350,
+	241, 4350,
+	242, 4350,
+	244, 4350,
+	245, 4350,
+	246, 4350,
+	248, 4350,
+	249, 4350,
+	251, 4350,
+	252, 4350,
+	253, 4350,
+	254, 4350,
+	255, 4350,
+	256, 4350,
+	257, 4350,
+	258, 4350,
+	259, 4350,
+	260, 4350,
+	261, 4350,
+	262, 4350,
+	263, 4350,
+	264, 4350,
+	265, 4350,
+	266, 4350,
+	267, 4350,
+	268, 4350,
+	269, 4350,
+	270, 4350,
+	271, 4350,
+	272, 4350,
+	273, 4350,
+	274, 4350,
+	276, 4350,
+	277, 4350,
+	278, 4350,
+	279, 4350,
+	280, 4350,
+	281, 4350,
+	286, 4350,
+	287, 4350,
+	288, 4350,
+	289, 4350,
+	290, 4350,
+	291, 4350,
+	292, 4350,
+	293, 4350,
+	295, 4350,
+	297, 4350,
+	298, 4350,
+	299, 4350,
+	300, 4350,
+	301, 4350,
+	302, 4350,
+	303, 4350,
+	304, 4350,
+	305, 4350,
+	306, 4350,
+	307, 4350,
+	309, 4350,
+	310, 4350,
+	311, 4350,
+	312, 4350,
+	313, 4350,
+	314, 4350,
+	315, 4350,
+	316, 4350,
+	317, 4350,
+	319, 4350,
+	320, 4350,
+	321, 4350,
+	323, 4350,
+	324, 4350,
+	325, 4350,
+	326, 4350,
+	327, 4350,
+	328, 4350,
+	329, 4350,
+	331, 4350,
+	332, 4350,
+	333, 4350,
+	334, 4350,
+	335, 4350,
+	336, 4350,
+	337, 4350,
+	340, 4350,
+	341, 4350,
+	342, 4350,
+	343, 4350,
+	344, 4350,
+	345, 4350,
+	346, 4350,
+	347, 4350,
+	348, 4350,
+	349, 4350,
+	350, 4350,
+	351, 4350,
+	352, 4350,
+	353, 4350,
+	354, 4350,
+	355, 4350,
+	356, 4350,
+	357, 4350,
+	358, 4350,
+	359, 4350,
+	360, 4350,
+	361, 4350,
+	362, 4350,
+	363, 4350,
+	364, 4350,
+	365, 4350,
+	366, 4350,
+	367, 4350,
+	368, 4350,
+	369, 4350,
+	370, 4350,
+	371, 4350,
+	373, 4350,
+	374, 4350,
+	375, 4350,
+	376, 4350,
+	377, 4350,
+	378, 4350,
+	379, 4350,
+	380, 4350,
+	381, 4350,
+	382, 4350,
+	383, 4350,
+	384, 4350,
+	385, 4350,
+	386, 4350,
+	387, 4350,
+	388, 4350,
+	389, 4350,
+	390, 4350,
+	391, 4350,
+	392, 4350,
+	393, 4350,
+	394, 4350,
+	395, 4350,
+	396, 4350,
+	398, 4350,
+	399, 4350,
+	401, 4350,
+	403, 4350,
+	404, 4350,
+	405, 4350,
+	406, 4350,
+	407, 4350,
+	409, 4350,
+	410, 4350,
+	411, 4350,
+	412, 4350,
+	413, 4350,
+	416, 4350,
+	418, 4350,
+	419, 4350,
+	422, 4350,
+	423, 4350,
+	424, 4350,
+	425, 4350,
+	427, 4350,
+	428, 4350,
+	429, 4350,
+	431, 4350,
+	433, 4350,
+	434, 4350,
+	435, 4350,
+	436, 4350,
+	437, 4350,
+	438, 4350,
+	439, 4350,
+	440, 4350,
+	441, 4350,
+	442, 4350,
+	443, 4350,
+	444, 4350,
+	445, 4350,
+	446, 4350,
+	447, 4350,
+	448, 4350,
+	450, 4350,
+	451, 4350,
+	452, 4350,
+	453, 4350,
+	454, 4350,
+	455, 4350,
+	456, 4350,
+	457, 4350,
+	458, 4350,
+	459, 4350,
+	460, 4350,
+	461, 4350,
+	462, 4350,
+	463, 4350,
+	464, 4350,
+	465, 4350,
+	466, 4350,
+	467, 4350,
+	469, 4350,
+	470, 4350,
+	471, 4350,
+	473, 4350,
+	474, 4350,
+	475, 4350,
+	476, 4350,
+	477, 4350,
+	478, 4350,
+	479, 4350,
+	480, 4350,
+	481, 4350,
+	482, 4350,
+	483, 4350,
+	484, 4350,
+	485, 4350,
+	486, 4350,
+	487, 4350,
+	488, 4350,
+	489, 4350,
+	491, 4350,
+	492, 4350,
+	494, 4350,
+	495, 4350,
+	496, 4350,
+	502, 4350,
+	503, 4350,
+	504, 4350,
+	505, 4350,
+	506, 4350,
+	507, 4350,
+	508, 4350,
+	509, 4350,
+	510, 4350,
+	511, 4350,
+	512, 4350,
+	513, 4350,
+	514, 4350,
+	515, 4350,
+	516, 4350,
+	517, 4350,
+	518, 4350,
+	519, 4350,
+	520, 4350,
+	522, 4350,
+	523, 4350,
+	524, 4350,
+	525, 4350,
+	526, 4350,
+	527, 4350,
+	528, 4350,
+	529, 4350,
+	530, 4350,
+	531, 4350,
+	532, 4350,
+	533, 4350,
+	534, 4350,
+	535, 4350,
+	536, 4350,
+	537, 4350,
+	538, 4350,
+	539, 4350,
+	540, 4350,
+	541, 4350,
+	542, 4350,
+	543, 4350,
+	544, 4350,
+	545, 4350,
+	546, 4350,
+	547, 4350,
+	548, 4350,
+	549, 4350,
+	550, 4350,
+	551, 4350,
+	553, 4350,
+	554, 4350,
+	555, 4350,
+	556, 4350,
+	557, 4350,
+	558, 4350,
+	559, 4350,
+	561, 4350,
+	562, 4350,
+	563, 4350,
+	564, 4350,
+	565, 4350,
+	566, 4350,
+	567, 4350,
+	568, 4350,
+	569, 4350,
+	570, 4350,
+	571, 4350,
+	572, 4350,
+	573, 4350,
+	574, 4350,
+	575, 4350,
+	576, 4350,
+	577, 4350,
+	578, 4350,
+	579, 4350,
+	581, 4350,
+	583, 4350,
+	584, 4350,
+	585, 4350,
+	586, 4350,
+	587, 4350,
+	588, 4350,
+	589, 4350,
+	590, 4350,
+	591, 4350,
+	592, 4350,
+	593, 4350,
+	594, 4350,
+	595, 4350,
+	596, 4350,
+	597, 4350,
+	598, 4350,
+	599, 4350,
+	600, 4350,
+	601, 4350,
+	602, 4350,
+	603, 4350,
+	604, 4350,
+	605, 4350,
+	606, 4350,
+	607, 4350,
+	608, 4350,
+	609, 4350,
+	611, 4350,
+	612, 4350,
+	613, 4350,
+	614, 4350,
+	615, 4350,
+	617, 4350,
+	618, 4350,
+	619, 4350,
+	620, 4350,
+	621, 4350,
+	622, 4350,
+	623, 4350,
+	624, 4350,
+	625, 4350,
+	626, 4350,
+	628, 4350,
+	629, 4350,
+	630, 4350,
+	631, 4350,
+	632, 4350,
+	634, 4350,
+	636, 4350,
+	637, 4350,
+	638, 4350,
+	639, 4350,
+	640, 4350,
+	641, 4350,
+	642, 4350,
+	643, 4350,
+	644, 4350,
+	646, 4350,
+	647, 4350,
+	648, 4350,
+	649, 4350,
+	650, 4350,
+	651, 4350,
+	652, 4350,
+	653, 4350,
+	656, 4350,
+	657, 4350,
+	658, 4350,
+	659, 4350,
+	660, 4350,
+	661, 4350,
+	662, 4350,
+	663, 4350,
+	664, 4350,
+	665, 4350,
+	666, 4350,
+	668, 4350,
+	671, 4350,
+	672, 4350,
+	673, 4350,
+	674, 4350,
+	675, 4350,
+	676, 4350,
+	678, 4350,
+	679, 4350,
+	680, 4350,
+	681, 4350,
+	682, 4350,
+	683, 4350,
+	684, 4350,
+	685, 4350,
+	686, 4350,
+	687, 4350,
+	688, 4350,
+	689, 4350,
+	690, 4350,
+	691, 4350,
+	692, 4350,
+	693, 4350,
+	694, 4350,
+	695, 4350,
+	700, 4350,
+	701, 4350,
+	702, 4350,
+	703, 4350,
+	704, 4350,
+	705, 4350,
+	706, 4350,
+	708, 4350,
+	719, 4350,
+	720, 4350,
+	721, 4350,
+	722, 4350,
+	723, 4350,
+	724, 4350,
+	726, 4350,
+	727, 4350,
+	728, 4350,
+	729, 4350,
+	730, 4350,
+	731, 4350,
+	732, 4350,
+	733, 4350,
+	734, 4350,
+	737, 4350,
+	740, 4350,
+	741, 4350,
+	743, 4350,
+	744, 4350,
 	-2, 0,
-	-1, 2111,
-	1, 836,
-	705, 836,
-	707, 836,
-	709, 836,
-	712, 836,
-	-2, 2140,
-	-1, 2114,
-	4, 4054,
-	11, 4054,
-	12, 4054,
-	14, 4054,
-	15, 4054,
-	16, 4054,
-	17, 4054,
-	18, 4054,
-	19, 4054,
-	21, 4054,
-	22, 4054,
-	23, 4054,
-	24, 4054,
-	25, 4054,
-	26, 4054,
-	27, 4054,
-	28, 4054,
-	30, 4054,
-	31, 4054,
-	34, 4054,
-	35, 4054,
-	37, 4054,
-	39, 4054,
-	41, 4054,
-	42, 4054,
-	43, 4054,
-	45, 4054,
-	46, 4054,
-	47, 4054,
-	49, 4054,
-	50, 4054,
-	51, 4054,
-	52, 4054,
-	53, 4054,
-	54, 4054,
-	55, 4054,
-	56, 4054,
-	57, 4054,
-	58, 4054,
-	60, 4054,
-	61, 4054,
-	62, 4054,
-	63, 4054,
-	65, 4054,
-	66, 4054,
-	67, 4054,
-	68, 4054,
-	69, 4054,
-	70, 4054,
-	71, 4054,
-	72, 4054,
-	73, 4054,
-	74, 4054,
-	75, 4054,
-	78, 4054,
-	79, 4054,
-	80, 4054,
-	81, 4054,
-	82, 4054,
-	84, 4054,
-	85, 4054,
-	86, 4054,
-	87, 4054,
-	88, 4054,
-	89, 4054,
-	92, 4054,
-	93, 4054,
-	94, 4054,
-	95, 4054,
-	96, 4054,
-	97, 4054,
-	98, 4054,
-	99, 4054,
-	100, 4054,
-	102, 4054,
-	103, 4054,
-	104, 4054,
-	105, 4054,
-	106, 4054,
-	107, 4054,
-	109, 4054,
-	110, 4054,
-	111, 4054,
-	112, 4054,
-	113, 4054,
-	114, 4054,
-	115, 4054,
-	116, 4054,
-	117, 4054,
-	119, 4054,
-	120, 4054,
-	121, 4054,
-	122, 4054,
-	123, 4054,
-	124, 4054,
-	125, 4054,
-	133, 4054,
-	134, 4054,
-	135, 4054,
-	136, 4054,
-	137, 4054,
-	139, 4054,
-	140, 4054,
-	141, 4054,
-	142, 4054,
-	143, 4054,
-	144, 4054,
-	146, 4054,
-	147, 4054,
-	148, 4054,
-	149, 4054,
-	151, 4054,
-	152, 4054,
-	153, 4054,
-	154, 4054,
-	156, 4054,
-	157, 4054,
-	158, 4054,
-	159, 4054,
-	162, 4054,
-	163, 4054,
-	164, 4054,
-	166, 4054,
-	167, 4054,
-	168, 4054,
-	169, 4054,
-	171, 4054,
-	172, 4054,
-	173, 4054,
-	175, 4054,
-	176, 4054,
-	177, 4054,
-	178, 4054,
-	179, 4054,
-	180, 4054,
-	181, 4054,
-	182, 4054,
-	183, 4054,
-	184, 4054,
-	185, 4054,
-	186, 4054,
-	187, 4054,
-	188, 4054,
-	189, 4054,
-	190, 4054,
-	191, 4054,
-	192, 4054,
-	193, 4054,
-	197, 4054,
-	198, 4054,
-	199, 4054,
-	200, 4054,
-	201, 4054,
-	202, 4054,
-	203, 4054,
-	204, 4054,
-	207, 4054,
-	208, 4054,
-	210, 4054,
-	211, 4054,
-	212, 4054,
-	213, 4054,
-	214, 4054,
-	215, 4054,
-	217, 4054,
-	218, 4054,
-	219, 4054,
-	221, 4054,
-	222, 4054,
-	223, 4054,
-	224, 4054,
-	225, 4054,
-	226, 4054,
-	227, 4054,
-	228, 4054,
-	229, 4054,
-	230, 4054,
-	231, 4054,
-	232, 4054,
-	233, 4054,
-	234, 4054,
-	235, 4054,
-	237, 4054,
-	238, 4054,
-	239, 4054,
-	241, 4054,
-	242, 4054,
-	244, 4054,
-	245, 4054,
-	246, 4054,
-	247, 4054,
-	248, 4054,
-	249, 4054,
-	250, 4054,
-	251, 4054,
-	252, 4054,
-	253, 4054,
-	254, 4054,
-	255, 4054,
-	256, 4054,
-	257, 4054,
-	258, 4054,
-	259, 4054,
-	260, 4054,
-	261, 4054,
-	262, 4054,
-	263, 4054,
-	264, 4054,
-	265, 4054,
-	266, 4054,
-	268, 4054,
-	269, 4054,
-	270, 4054,
-	271, 4054,
-	272, 4054,
-	273, 4054,
-	278, 4054,
-	279, 4054,
-	280, 4054,
-	281, 4054,
-	282, 4054,
-	283, 4054,
-	284, 4054,
-	286, 4054,
-	288, 4054,
-	289, 4054,
-	290, 4054,
-	291, 4054,
-	292, 4054,
-	293, 4054,
-	294, 4054,
-	295, 4054,
-	296, 4054,
-	297, 4054,
-	298, 4054,
-	300, 4054,
-	301, 4054,
-	302, 4054,
-	303, 4054,
-	304, 4054,
-	305, 4054,
-	306, 4054,
-	307, 4054,
-	308, 4054,
-	310, 4054,
-	311, 4054,
-	312, 4054,
-	314, 4054,
-	315, 4054,
-	316, 4054,
-	317, 4054,
-	318, 4054,
-	319, 4054,
-	320, 4054,
-	322, 4054,
-	323, 4054,
-	324, 4054,
-	325, 4054,
-	326, 4054,
-	327, 4054,
-	328, 4054,
-	331, 4054,
-	332, 4054,
-	333, 4054,
-	334, 4054,
-	335, 4054,
-	336, 4054,
-	337, 4054,
-	338, 4054,
-	339, 4054,
-	340, 4054,
-	341, 4054,
-	342, 4054,
-	343, 4054,
-	344, 4054,
-	345, 4054,
-	346, 4054,
-	347, 4054,
-	348, 4054,
-	349, 4054,
-	350, 4054,
-	351, 4054,
-	352, 4054,
-	353, 4054,
-	354, 4054,
-	355, 4054,
-	356, 4054,
-	357, 4054,
-	358, 4054,
-	359, 4054,
-	361, 4054,
-	362, 4054,
-	363, 4054,
-	364, 4054,
-	365, 4054,
-	366, 4054,
-	367, 4054,
-	368, 4054,
-	369, 4054,
-	370, 4054,
-	371, 4054,
-	372, 4054,
-	373, 4054,
-	374, 4054,
-	375, 4054,
-	376, 4054,
-	377, 4054,
-	378, 4054,
-	379, 4054,
-	380, 4054,
-	382, 4054,
-	383, 4054,
-	385, 4054,
-	387, 4054,
-	388, 4054,
-	389, 4054,
-	390, 4054,
-	391, 4054,
-	393, 4054,
-	394, 4054,
-	395, 4054,
-	396, 4054,
-	397, 4054,
-	400, 4054,
-	402, 4054,
-	405, 4054,
-	406, 4054,
-	407, 4054,
-	408, 4054,
-	410, 4054,
-	411, 4054,
-	412, 4054,
-	414, 4054,
-	416, 4054,
-	417, 4054,
-	418, 4054,
-	419, 4054,
-	420, 4054,
-	421, 4054,
-	422, 4054,
-	423, 4054,
-	424, 4054,
-	425, 4054,
-	426, 4054,
-	427, 4054,
-	428, 4054,
-	429, 4054,
-	431, 4054,
-	432, 4054,
-	433, 4054,
-	434, 4054,
-	435, 4054,
-	436, 4054,
-	437, 4054,
-	438, 4054,
-	439, 4054,
-	440, 4054,
-	441, 4054,
-	442, 4054,
-	443, 4054,
-	444, 4054,
-	445, 4054,
-	447, 4054,
-	448, 4054,
-	449, 4054,
-	451, 4054,
-	452, 4054,
-	453, 4054,
-	454, 4054,
-	455, 4054,
-	456, 4054,
-	457, 4054,
-	458, 4054,
-	459, 4054,
-	460, 4054,
-	461, 4054,
-	462, 4054,
-	463, 4054,
-	464, 4054,
-	465, 4054,
-	466, 4054,
-	467, 4054,
-	469, 4054,
-	471, 4054,
-	472, 4054,
-	473, 4054,
-	479, 4054,
-	480, 4054,
-	481, 4054,
-	482, 4054,
-	483, 4054,
-	484, 4054,
-	485, 4054,
-	486, 4054,
-	487, 4054,
-	488, 4054,
-	489, 4054,
-	490, 4054,
-	491, 4054,
-	492, 4054,
-	493, 4054,
-	494, 4054,
-	495, 4054,
-	497, 4054,
-	498, 4054,
-	499, 4054,
-	500, 4054,
-	501, 4054,
-	502, 4054,
-	503, 4054,
-	504, 4054,
-	505, 4054,
-	506, 4054,
-	507, 4054,
-	508, 4054,
-	509, 4054,
-	510, 4054,
-	511, 4054,
-	512, 4054,
-	513, 4054,
-	514, 4054,
-	515, 4054,
-	516, 4054,
-	517, 4054,
-	518, 4054,
-	519, 4054,
-	520, 4054,
-	521, 4054,
-	522, 4054,
-	523, 4054,
-	524, 4054,
-	525, 4054,
-	526, 4054,
-	528, 4054,
-	529, 4054,
-	530, 4054,
-	531, 4054,
-	532, 4054,
-	533, 4054,
-	534, 4054,
-	536, 4054,
-	537, 4054,
-	538, 4054,
-	539, 4054,
-	540, 4054,
-	541, 4054,
-	542, 4054,
-	543, 4054,
-	544, 4054,
-	545, 4054,
-	546, 4054,
-	547, 4054,
-	548, 4054,
-	549, 4054,
-	550, 4054,
-	551, 4054,
-	552, 4054,
-	553, 4054,
-	554, 4054,
-	556, 4054,
-	558, 4054,
-	559, 4054,
-	560, 4054,
-	561, 4054,
-	562, 4054,
-	563, 4054,
-	564, 4054,
-	565, 4054,
-	566, 4054,
-	567, 4054,
-	568, 4054,
-	569, 4054,
-	570, 4054,
-	571, 4054,
-	572, 4054,
-	573, 4054,
-	574, 4054,
-	575, 4054,
-	576, 4054,
-	577, 4054,
-	578, 4054,
-	579, 4054,
-	580, 4054,
-	582, 4054,
-	583, 4054,
-	584, 4054,
-	585, 4054,
-	586, 4054,
-	588, 4054,
-	589, 4054,
-	590, 4054,
-	591, 4054,
-	592, 4054,
-	593, 4054,
-	594, 4054,
-	595, 4054,
-	596, 4054,
-	597, 4054,
-	599, 4054,
-	600, 4054,
-	601, 4054,
-	602, 4054,
-	603, 4054,
-	605, 4054,
-	607, 4054,
-	608, 4054,
-	609, 4054,
-	610, 4054,
-	611, 4054,
-	612, 4054,
-	613, 4054,
-	614, 4054,
-	616, 4054,
-	617, 4054,
-	618, 4054,
-	619, 4054,
-	620, 4054,
-	621, 4054,
-	622, 4054,
-	625, 4054,
-	626, 4054,
-	627, 4054,
-	628, 4054,
-	629, 4054,
-	630, 4054,
-	631, 4054,
-	632, 4054,
-	633, 4054,
-	634, 4054,
-	635, 4054,
-	637, 4054,
-	640, 4054,
-	641, 4054,
-	642, 4054,
-	643, 4054,
-	644, 4054,
-	645, 4054,
-	647, 4054,
-	648, 4054,
-	649, 4054,
-	650, 4054,
-	651, 4054,
-	652, 4054,
-	653, 4054,
-	654, 4054,
-	655, 4054,
-	656, 4054,
-	657, 4054,
-	658, 4054,
-	659, 4054,
-	660, 4054,
-	661, 4054,
-	662, 4054,
-	667, 4054,
-	668, 4054,
-	669, 4054,
-	670, 4054,
-	671, 4054,
-	672, 4054,
-	673, 4054,
-	675, 4054,
-	686, 4054,
-	687, 4054,
-	688, 4054,
-	689, 4054,
-	690, 4054,
-	691, 4054,
-	693, 4054,
-	694, 4054,
-	695, 4054,
-	696, 4054,
-	697, 4054,
-	698, 4054,
-	699, 4054,
-	700, 4054,
-	701, 4054,
-	704, 4054,
-	707, 4054,
-	708, 4054,
-	710, 4054,
-	711, 4054,
+	-1, 2242,
+	227, 3588,
+	633, 3588,
+	721, 3588,
+	741, 3588,
 	-2, 0,
-	-1, 2119,
-	220, 3329,
-	604, 3329,
-	688, 3329,
-	708, 3329,
+	-1, 2284,
+	202, 2406,
+	215, 2406,
+	330, 2406,
+	414, 2406,
+	-2, 2345,
+	-1, 2390,
+	180, 2366,
+	202, 2366,
+	215, 2366,
+	294, 2366,
+	330, 2366,
+	414, 2366,
+	426, 2366,
+	654, 2366,
+	-2, 2851,
+	-1, 2437,
+	739, 2669,
+	-2, 2659,
+	-1, 2455,
+	740, 3032,
 	-2, 0,
-	-1, 2161,
-	196, 2183,
-	209, 2183,
-	321, 2183,
-	398, 2183,
-	-2, 2121,
-	-1, 2264,
-	174, 2142,
-	196, 2142,
-	209, 2142,
-	285, 2142,
-	321, 2142,
-	398, 2142,
-	409, 2142,
-	623, 2142,
-	-2, 2619,
-	-1, 2311,
-	706, 2440,
-	-2, 2430,
-	-1, 2328,
-	707, 2797,
+	-1, 2492,
+	180, 2366,
+	202, 2366,
+	215, 2366,
+	294, 2366,
+	330, 2366,
+	414, 2366,
+	426, 2366,
+	654, 2366,
+	-2, 2519,
+	-1, 2547,
+	741, 3181,
+	744, 3181,
+	-2, 1729,
+	-1, 2548,
+	741, 3183,
+	744, 3183,
+	-2, 1730,
+	-1, 2549,
+	741, 3182,
+	744, 3182,
+	-2, 1731,
+	-1, 2550,
+	744, 3102,
+	-2, 1732,
+	-1, 2587,
+	739, 2670,
+	-2, 2658,
+	-1, 2605,
+	227, 3584,
+	741, 3584,
+	744, 3584,
 	-2, 0,
-	-1, 2364,
-	174, 2142,
-	196, 2142,
-	209, 2142,
-	285, 2142,
-	321, 2142,
-	398, 2142,
-	409, 2142,
-	623, 2142,
-	-2, 2294,
-	-1, 2418,
-	708, 2944,
-	711, 2944,
-	-2, 1526,
-	-1, 2419,
-	708, 2946,
-	711, 2946,
-	-2, 1527,
-	-1, 2420,
-	708, 2945,
-	711, 2945,
-	-2, 1528,
-	-1, 2421,
-	711, 2865,
-	-2, 1529,
-	-1, 2458,
-	706, 2441,
-	-2, 2429,
-	-1, 2475,
-	220, 3325,
-	708, 3325,
-	711, 3325,
+	-1, 2667,
+	1, 1255,
+	742, 1255,
+	745, 1255,
+	-2, 2244,
+	-1, 2719,
+	1, 1096,
+	738, 1096,
+	740, 1096,
+	742, 1096,
+	745, 1096,
 	-2, 0,
-	-1, 2533,
-	1, 1075,
-	709, 1075,
-	712, 1075,
-	-2, 2023,
-	-1, 2603,
-	1, 1356,
-	705, 1356,
-	707, 1356,
-	709, 1356,
-	712, 1356,
+	-1, 2740,
+	1, 1544,
+	738, 1544,
+	740, 1544,
+	742, 1544,
+	745, 1544,
 	-2, 0,
-	-1, 2604,
-	1, 1407,
-	705, 1407,
-	707, 1407,
-	709, 1407,
-	712, 1407,
+	-1, 2741,
+	1, 1595,
+	738, 1595,
+	740, 1595,
+	742, 1595,
+	745, 1595,
 	-2, 0,
-	-1, 2605,
-	1, 1423,
-	705, 1423,
-	707, 1423,
-	709, 1423,
-	712, 1423,
+	-1, 2742,
+	1, 1611,
+	738, 1611,
+	740, 1611,
+	742, 1611,
+	745, 1611,
 	-2, 0,
-	-1, 2606,
-	1, 1484,
-	705, 1484,
-	707, 1484,
-	709, 1484,
-	712, 1484,
+	-1, 2743,
+	1, 1680,
+	738, 1680,
+	740, 1680,
+	742, 1680,
+	745, 1680,
 	-2, 0,
-	-1, 2656,
-	1, 1387,
-	705, 1387,
-	707, 1387,
-	709, 1387,
-	712, 1387,
+	-1, 2798,
+	1, 1575,
+	738, 1575,
+	740, 1575,
+	742, 1575,
+	745, 1575,
 	-2, 0,
-	-1, 2687,
-	1, 1463,
-	705, 1463,
-	707, 1463,
-	709, 1463,
-	712, 1463,
+	-1, 2831,
+	1, 1655,
+	738, 1655,
+	740, 1655,
+	742, 1655,
+	745, 1655,
 	-2, 0,
-	-1, 2891,
-	259, 340,
-	-2, 2952,
-	-1, 2892,
-	259, 341,
-	-2, 413,
-	-1, 3023,
-	508, 2220,
-	509, 2220,
-	-2, 2474,
-	-1, 3057,
+	-1, 3043,
+	267, 375,
+	-2, 3189,
+	-1, 3044,
+	267, 376,
+	-2, 454,
+	-1, 3181,
+	533, 2443,
+	534, 2443,
+	-2, 2703,
+	-1, 3215,
 	14, 0,
 	15, 0,
 	16, 0,
-	686, 0,
-	687, 0,
-	688, 0,
-	-2, 2494,
-	-1, 3058,
+	719, 0,
+	720, 0,
+	721, 0,
+	-2, 2723,
+	-1, 3216,
 	14, 0,
 	15, 0,
 	16, 0,
-	686, 0,
-	687, 0,
-	688, 0,
-	-2, 2495,
-	-1, 3059,
-	110, 0,
-	300, 0,
-	301, 0,
-	690, 0,
-	691, 0,
-	-2, 2496,
-	-1, 3060,
-	110, 0,
-	300, 0,
-	301, 0,
-	690, 0,
-	691, 0,
-	-2, 2497,
-	-1, 3061,
-	110, 0,
-	300, 0,
-	301, 0,
-	690, 0,
-	691, 0,
-	-2, 2498,
-	-1, 3062,
-	110, 0,
-	300, 0,
-	301, 0,
-	690, 0,
-	691, 0,
-	-2, 2499,
-	-1, 3063,
-	110, 0,
-	300, 0,
-	301, 0,
-	690, 0,
-	691, 0,
-	-2, 2500,
-	-1, 3064,
+	719, 0,
+	720, 0,
+	721, 0,
+	-2, 2724,
+	-1, 3217,
+	113, 0,
+	309, 0,
+	310, 0,
+	723, 0,
+	724, 0,
+	-2, 2725,
+	-1, 3218,
+	113, 0,
+	309, 0,
+	310, 0,
+	723, 0,
+	724, 0,
+	-2, 2726,
+	-1, 3219,
+	113, 0,
+	309, 0,
+	310, 0,
+	723, 0,
+	724, 0,
+	-2, 2727,
+	-1, 3220,
+	113, 0,
+	309, 0,
+	310, 0,
+	723, 0,
+	724, 0,
+	-2, 2728,
+	-1, 3221,
+	113, 0,
+	309, 0,
+	310, 0,
+	723, 0,
+	724, 0,
+	-2, 2729,
+	-1, 3222,
 	14, 0,
 	15, 0,
 	16, 0,
-	686, 0,
-	687, 0,
-	688, 0,
-	-2, 2501,
-	-1, 3077,
+	719, 0,
+	720, 0,
+	721, 0,
+	-2, 2730,
+	-1, 3238,
 	14, 0,
 	15, 0,
 	16, 0,
-	686, 0,
-	687, 0,
-	688, 0,
-	-2, 2514,
-	-1, 3078,
+	719, 0,
+	720, 0,
+	721, 0,
+	-2, 2746,
+	-1, 3239,
 	14, 0,
 	15, 0,
 	16, 0,
-	686, 0,
-	687, 0,
-	688, 0,
-	-2, 2515,
-	-1, 3079,
+	719, 0,
+	720, 0,
+	721, 0,
+	-2, 2747,
+	-1, 3240,
 	14, 0,
 	15, 0,
 	16, 0,
-	686, 0,
-	687, 0,
-	688, 0,
-	-2, 2516,
-	-1, 3083,
+	719, 0,
+	720, 0,
+	721, 0,
+	-2, 2748,
+	-1, 3244,
 	17, 0,
 	18, 0,
 	19, 0,
-	57, 0,
-	255, 0,
-	259, 0,
-	320, 0,
-	544, 0,
-	673, 0,
-	689, 0,
-	-2, 2523,
-	-1, 3089,
+	58, 0,
+	262, 0,
+	267, 0,
+	329, 0,
+	569, 0,
+	706, 0,
+	722, 0,
+	-2, 2755,
+	-1, 3250,
 	17, 0,
 	18, 0,
 	19, 0,
-	57, 0,
-	255, 0,
-	259, 0,
-	320, 0,
-	544, 0,
-	673, 0,
-	689, 0,
-	-2, 2527,
-	-1, 3091,
+	58, 0,
+	262, 0,
+	267, 0,
+	329, 0,
+	569, 0,
+	706, 0,
+	722, 0,
+	-2, 2759,
+	-1, 3252,
 	17, 0,
 	18, 0,
 	19, 0,
-	57, 0,
-	255, 0,
-	259, 0,
-	320, 0,
-	544, 0,
-	673, 0,
-	689, 0,
-	-2, 2535,
-	-1, 3092,
+	58, 0,
+	262, 0,
+	267, 0,
+	329, 0,
+	569, 0,
+	706, 0,
+	722, 0,
+	-2, 2767,
+	-1, 3253,
 	17, 0,
 	18, 0,
 	19, 0,
-	57, 0,
-	255, 0,
-	259, 0,
-	320, 0,
-	544, 0,
-	673, 0,
-	689, 0,
-	-2, 2536,
-	-1, 3093,
+	58, 0,
+	262, 0,
+	267, 0,
+	329, 0,
+	569, 0,
+	706, 0,
+	722, 0,
+	-2, 2768,
+	-1, 3254,
 	17, 0,
 	18, 0,
 	19, 0,
-	57, 0,
-	255, 0,
-	259, 0,
-	320, 0,
-	544, 0,
-	673, 0,
-	689, 0,
-	-2, 2537,
-	-1, 3094,
+	58, 0,
+	262, 0,
+	267, 0,
+	329, 0,
+	569, 0,
+	706, 0,
+	722, 0,
+	-2, 2769,
+	-1, 3255,
 	17, 0,
 	18, 0,
 	19, 0,
-	57, 0,
-	255, 0,
-	259, 0,
-	320, 0,
-	544, 0,
-	673, 0,
-	689, 0,
-	-2, 2538,
-	-1, 3266,
-	5, 2956,
-	220, 2808,
-	706, 2953,
-	-2, 2944,
-	-1, 3267,
-	220, 2809,
-	-2, 3427,
-	-1, 3268,
-	220, 2810,
-	-2, 3189,
-	-1, 3269,
-	220, 2811,
-	-2, 3042,
-	-1, 3270,
-	220, 2812,
-	-2, 3117,
-	-1, 3271,
-	220, 2813,
-	-2, 3173,
-	-1, 3272,
-	220, 2814,
-	-2, 3321,
-	-1, 3273,
-	220, 2815,
-	-2, 2602,
-	-1, 3316,
-	29, 2783,
-	36, 2783,
-	557, 2783,
-	-2, 3690,
-	-1, 3317,
-	29, 2785,
-	36, 2785,
-	557, 2785,
-	-2, 3633,
-	-1, 3320,
-	1, 3461,
-	2, 3461,
-	174, 3461,
-	196, 3461,
-	209, 3461,
-	220, 3461,
-	240, 3461,
-	243, 3461,
-	285, 3461,
-	321, 3461,
-	398, 3461,
-	403, 3461,
-	409, 3461,
-	496, 3461,
-	623, 3461,
-	664, 3461,
-	665, 3461,
-	666, 3461,
-	705, 3461,
-	707, 3461,
-	709, 3461,
-	711, 3461,
-	712, 3461,
-	-2, 2849,
-	-1, 3924,
-	1, 2295,
-	2, 2295,
-	122, 2295,
-	174, 2295,
-	196, 2295,
-	209, 2295,
-	221, 2295,
-	240, 2295,
-	243, 2295,
-	278, 2295,
-	285, 2295,
-	297, 2295,
-	317, 2295,
-	321, 2295,
-	362, 2295,
-	398, 2295,
-	403, 2295,
-	409, 2295,
-	496, 2295,
-	502, 2295,
-	623, 2295,
-	638, 2295,
-	664, 2295,
-	665, 2295,
-	666, 2295,
-	676, 2295,
-	705, 2295,
-	707, 2295,
-	709, 2295,
-	711, 2295,
-	712, 2295,
-	-2, 2294,
-	-1, 3939,
-	706, 2924,
-	-2, 2939,
-	-1, 3951,
-	1, 436,
-	664, 436,
-	712, 436,
-	-2, 2169,
-	-1, 3953,
-	1, 436,
-	712, 436,
-	-2, 2169,
-	-1, 4022,
-	38, 2956,
-	145, 2956,
-	688, 2956,
-	704, 2956,
-	707, 2956,
-	708, 2956,
-	711, 2956,
-	-2, 2953,
-	-1, 4023,
-	38, 2957,
-	145, 2957,
-	688, 2957,
-	704, 2957,
-	707, 2957,
-	708, 2957,
-	711, 2957,
-	-2, 2954,
-	-1, 4153,
-	1, 1467,
-	705, 1467,
-	707, 1467,
-	709, 1467,
-	712, 1467,
+	58, 0,
+	262, 0,
+	267, 0,
+	329, 0,
+	569, 0,
+	706, 0,
+	722, 0,
+	-2, 2770,
+	-1, 3431,
+	5, 3193,
+	227, 3043,
+	739, 3190,
+	-2, 3181,
+	-1, 3432,
+	227, 3044,
+	-2, 3693,
+	-1, 3433,
+	227, 3045,
+	-2, 3436,
+	-1, 3434,
+	227, 3046,
+	-2, 3282,
+	-1, 3435,
+	227, 3047,
+	-2, 3359,
+	-1, 3436,
+	227, 3048,
+	-2, 3419,
+	-1, 3437,
+	227, 3049,
+	-2, 3580,
+	-1, 3438,
+	227, 3050,
+	-2, 2834,
+	-1, 3481,
+	29, 3018,
+	36, 3018,
+	582, 3018,
+	-2, 3963,
+	-1, 3482,
+	29, 3020,
+	36, 3020,
+	582, 3020,
+	-2, 3904,
+	-1, 3485,
+	1, 3728,
+	2, 3728,
+	180, 3728,
+	202, 3728,
+	215, 3728,
+	227, 3728,
+	247, 3728,
+	250, 3728,
+	294, 3728,
+	330, 3728,
+	414, 3728,
+	420, 3728,
+	426, 3728,
+	521, 3728,
+	654, 3728,
+	697, 3728,
+	698, 3728,
+	699, 3728,
+	738, 3728,
+	740, 3728,
+	742, 3728,
+	744, 3728,
+	745, 3728,
+	-2, 3084,
+	-1, 4120,
+	1, 2520,
+	2, 2520,
+	126, 2520,
+	180, 2520,
+	202, 2520,
+	215, 2520,
+	228, 2520,
+	247, 2520,
+	250, 2520,
+	286, 2520,
+	294, 2520,
+	306, 2520,
+	326, 2520,
+	330, 2520,
+	374, 2520,
+	414, 2520,
+	420, 2520,
+	426, 2520,
+	521, 2520,
+	527, 2520,
+	654, 2520,
+	669, 2520,
+	697, 2520,
+	698, 2520,
+	699, 2520,
+	709, 2520,
+	738, 2520,
+	740, 2520,
+	742, 2520,
+	744, 2520,
+	745, 2520,
+	-2, 2519,
+	-1, 4135,
+	739, 3161,
+	-2, 3176,
+	-1, 4147,
+	1, 475,
+	697, 475,
+	745, 475,
+	-2, 2392,
+	-1, 4149,
+	1, 475,
+	745, 475,
+	-2, 2392,
+	-1, 4221,
+	38, 3193,
+	147, 3193,
+	721, 3193,
+	737, 3193,
+	740, 3193,
+	741, 3193,
+	744, 3193,
+	-2, 3190,
+	-1, 4222,
+	38, 3194,
+	147, 3194,
+	721, 3194,
+	737, 3194,
+	740, 3194,
+	741, 3194,
+	744, 3194,
+	-2, 3191,
+	-1, 4363,
+	1, 1659,
+	738, 1659,
+	740, 1659,
+	742, 1659,
+	745, 1659,
 	-2, 0,
-	-1, 4385,
-	1, 1855,
-	489, 1807,
-	536, 1807,
-	679, 1807,
-	685, 1807,
-	705, 1855,
-	707, 1855,
-	709, 1855,
-	712, 1855,
-	-2, 2169,
-	-1, 4406,
-	287, 305,
+	-1, 4607,
+	1, 2066,
+	513, 2015,
+	561, 2015,
+	712, 2015,
+	718, 2015,
+	738, 2066,
+	740, 2066,
+	742, 2066,
+	745, 2066,
+	-2, 2392,
+	-1, 4628,
+	296, 338,
 	-2, 0,
-	-1, 4407,
-	4, 734,
-	21, 734,
-	22, 734,
-	23, 734,
-	24, 734,
-	25, 734,
-	26, 734,
-	27, 734,
-	28, 734,
-	30, 734,
-	31, 734,
-	37, 734,
-	41, 734,
-	43, 734,
-	45, 734,
-	46, 734,
-	47, 734,
-	49, 734,
-	50, 734,
-	51, 734,
-	52, 734,
-	53, 734,
-	54, 734,
-	55, 734,
-	56, 734,
-	57, 734,
-	58, 734,
-	60, 734,
-	61, 734,
-	62, 734,
-	63, 734,
-	65, 734,
-	66, 734,
-	67, 734,
-	68, 734,
-	69, 734,
-	70, 734,
-	71, 734,
-	72, 734,
-	73, 734,
-	74, 734,
-	75, 734,
-	79, 734,
-	80, 734,
-	81, 734,
-	82, 734,
-	84, 734,
-	85, 734,
-	86, 734,
-	87, 734,
-	88, 734,
-	92, 734,
-	93, 734,
-	94, 734,
-	95, 734,
-	96, 734,
-	97, 734,
-	98, 734,
-	99, 734,
-	102, 734,
-	103, 734,
-	104, 734,
-	105, 734,
-	106, 734,
-	107, 734,
-	109, 734,
-	111, 734,
-	112, 734,
-	113, 734,
-	114, 734,
-	115, 734,
-	116, 734,
-	117, 734,
-	119, 734,
-	120, 734,
-	121, 734,
-	123, 734,
-	124, 734,
-	125, 734,
-	133, 734,
-	134, 734,
-	135, 734,
-	136, 734,
-	137, 734,
-	139, 734,
-	140, 734,
-	141, 734,
-	142, 734,
-	143, 734,
-	144, 734,
-	146, 734,
-	147, 734,
-	148, 734,
-	149, 734,
-	151, 734,
-	152, 734,
-	153, 734,
-	154, 734,
-	156, 734,
-	157, 734,
-	158, 734,
-	159, 734,
-	162, 734,
-	163, 734,
-	164, 734,
-	166, 734,
-	167, 734,
-	168, 734,
-	169, 734,
-	171, 734,
-	172, 734,
-	173, 734,
-	175, 734,
-	176, 734,
-	177, 734,
-	178, 734,
-	179, 734,
-	180, 734,
-	181, 734,
-	182, 734,
-	183, 734,
-	184, 734,
-	185, 734,
-	186, 734,
-	187, 734,
-	188, 734,
-	189, 734,
-	190, 734,
-	191, 734,
-	192, 734,
-	193, 734,
-	195, 734,
-	201, 734,
-	202, 734,
-	203, 734,
-	204, 734,
-	208, 734,
-	210, 734,
-	211, 734,
-	212, 734,
-	213, 734,
-	214, 734,
-	215, 734,
-	217, 734,
-	218, 734,
-	219, 734,
-	222, 734,
-	223, 734,
-	224, 734,
-	225, 734,
-	226, 734,
-	227, 734,
-	228, 734,
-	229, 734,
-	230, 734,
-	231, 734,
-	232, 734,
-	233, 734,
-	234, 734,
-	235, 734,
-	237, 734,
-	238, 734,
-	239, 734,
-	241, 734,
-	242, 734,
-	244, 734,
-	245, 734,
-	246, 734,
-	247, 734,
-	248, 734,
-	249, 734,
-	250, 734,
-	251, 734,
-	252, 734,
-	253, 734,
-	254, 734,
-	256, 734,
-	257, 734,
-	258, 734,
-	260, 734,
-	261, 734,
-	262, 734,
-	263, 734,
-	264, 734,
-	265, 734,
-	266, 734,
-	270, 734,
-	271, 734,
-	272, 734,
-	273, 734,
-	275, 734,
-	276, 734,
-	277, 734,
-	279, 734,
-	280, 734,
-	281, 734,
-	282, 734,
-	283, 734,
-	284, 734,
-	286, 734,
-	288, 734,
-	289, 734,
-	290, 734,
-	292, 734,
-	294, 734,
-	295, 734,
-	296, 734,
-	298, 734,
-	302, 734,
-	303, 734,
-	304, 734,
-	305, 734,
-	306, 734,
-	307, 734,
-	308, 734,
-	310, 734,
-	311, 734,
-	312, 734,
-	314, 734,
-	315, 734,
-	316, 734,
-	318, 734,
-	319, 734,
-	322, 734,
-	323, 734,
-	324, 734,
-	325, 734,
-	326, 734,
-	327, 734,
-	328, 734,
-	331, 734,
-	332, 734,
-	333, 734,
-	334, 734,
-	336, 734,
-	337, 734,
-	338, 734,
-	339, 734,
-	340, 734,
-	341, 734,
-	342, 734,
-	343, 734,
-	344, 734,
-	345, 734,
-	346, 734,
-	347, 734,
-	348, 734,
-	349, 734,
-	350, 734,
-	351, 734,
-	352, 734,
-	353, 734,
-	354, 734,
-	355, 734,
-	356, 734,
-	357, 734,
-	358, 734,
-	359, 734,
-	361, 734,
-	363, 734,
-	364, 734,
-	365, 734,
-	366, 734,
-	367, 734,
-	368, 734,
-	369, 734,
-	370, 734,
-	371, 734,
-	372, 734,
-	373, 734,
-	374, 734,
-	375, 734,
-	376, 734,
-	377, 734,
-	378, 734,
-	379, 734,
-	380, 734,
-	382, 734,
-	383, 734,
-	385, 734,
-	386, 734,
-	388, 734,
-	389, 734,
-	390, 734,
-	391, 734,
-	393, 734,
-	394, 734,
-	395, 734,
-	396, 734,
-	397, 734,
-	400, 734,
-	402, 734,
-	405, 734,
-	406, 734,
-	407, 734,
-	410, 734,
-	411, 734,
-	412, 734,
-	414, 734,
-	416, 734,
-	417, 734,
-	418, 734,
-	419, 734,
-	420, 734,
-	421, 734,
-	422, 734,
-	423, 734,
-	424, 734,
-	425, 734,
-	426, 734,
-	427, 734,
-	428, 734,
-	429, 734,
-	431, 734,
-	432, 734,
-	433, 734,
-	434, 734,
-	435, 734,
-	436, 734,
-	437, 734,
-	438, 734,
-	439, 734,
-	440, 734,
-	441, 734,
-	442, 734,
-	443, 734,
-	444, 734,
-	445, 734,
-	447, 734,
-	448, 734,
-	449, 734,
-	451, 734,
-	452, 734,
-	453, 734,
-	454, 734,
-	455, 734,
-	456, 734,
-	457, 734,
-	458, 734,
-	459, 734,
-	460, 734,
-	461, 734,
-	462, 734,
-	463, 734,
-	464, 734,
-	465, 734,
-	466, 734,
-	467, 734,
-	469, 734,
-	471, 734,
-	472, 734,
-	473, 734,
-	479, 734,
-	480, 734,
-	481, 734,
-	483, 734,
-	484, 734,
-	485, 734,
-	486, 734,
-	487, 734,
-	488, 734,
-	489, 734,
-	490, 734,
-	491, 734,
-	492, 734,
-	493, 734,
-	494, 734,
-	495, 734,
-	497, 734,
-	498, 734,
-	499, 734,
-	500, 734,
-	501, 734,
-	503, 734,
-	504, 734,
-	505, 734,
-	506, 734,
-	507, 734,
-	508, 734,
-	509, 734,
-	511, 734,
-	512, 734,
-	513, 734,
-	514, 734,
-	515, 734,
-	516, 734,
-	517, 734,
-	518, 734,
-	519, 734,
-	520, 734,
-	521, 734,
-	522, 734,
-	523, 734,
-	524, 734,
-	525, 734,
-	526, 734,
-	528, 734,
-	529, 734,
-	530, 734,
-	531, 734,
-	532, 734,
-	533, 734,
-	534, 734,
-	536, 734,
-	537, 734,
-	538, 734,
-	539, 734,
-	540, 734,
-	541, 734,
-	542, 734,
-	543, 734,
-	545, 734,
-	546, 734,
-	547, 734,
-	548, 734,
-	549, 734,
-	550, 734,
-	551, 734,
-	552, 734,
-	553, 734,
-	554, 734,
-	556, 734,
-	558, 734,
-	559, 734,
-	560, 734,
-	561, 734,
-	562, 734,
-	563, 734,
-	564, 734,
-	565, 734,
-	566, 734,
-	567, 734,
-	568, 734,
-	569, 734,
-	570, 734,
-	571, 734,
-	572, 734,
-	573, 734,
-	574, 734,
-	575, 734,
-	576, 734,
-	577, 734,
-	578, 734,
-	579, 734,
-	580, 734,
-	582, 734,
-	583, 734,
-	585, 734,
-	586, 734,
-	588, 734,
-	589, 734,
-	590, 734,
-	591, 734,
-	592, 734,
-	593, 734,
-	594, 734,
-	595, 734,
-	596, 734,
-	597, 734,
-	599, 734,
-	600, 734,
-	601, 734,
-	602, 734,
-	603, 734,
-	605, 734,
-	607, 734,
-	608, 734,
-	609, 734,
-	610, 734,
-	611, 734,
-	612, 734,
-	613, 734,
-	614, 734,
-	616, 734,
-	617, 734,
-	618, 734,
-	619, 734,
-	620, 734,
-	621, 734,
-	622, 734,
-	625, 734,
-	626, 734,
-	627, 734,
-	628, 734,
-	629, 734,
-	630, 734,
-	631, 734,
-	632, 734,
-	633, 734,
-	634, 734,
-	635, 734,
-	637, 734,
-	640, 734,
-	641, 734,
-	642, 734,
-	643, 734,
-	644, 734,
-	645, 734,
-	647, 734,
-	648, 734,
-	649, 734,
-	650, 734,
-	651, 734,
-	652, 734,
-	653, 734,
-	654, 734,
-	655, 734,
-	656, 734,
-	657, 734,
-	658, 734,
-	659, 734,
-	660, 734,
-	661, 734,
-	662, 734,
-	667, 734,
-	668, 734,
-	669, 734,
-	670, 734,
-	671, 734,
-	672, 734,
+	-1, 4629,
+	4, 894,
+	21, 894,
+	22, 894,
+	23, 894,
+	24, 894,
+	25, 894,
+	26, 894,
+	27, 894,
+	28, 894,
+	30, 894,
+	31, 894,
+	37, 894,
+	41, 894,
+	43, 894,
+	45, 894,
+	46, 894,
+	47, 894,
+	49, 894,
+	50, 894,
+	51, 894,
+	52, 894,
+	53, 894,
+	54, 894,
+	55, 894,
+	56, 894,
+	57, 894,
+	58, 894,
+	59, 894,
+	60, 894,
+	62, 894,
+	63, 894,
+	64, 894,
+	65, 894,
+	67, 894,
+	68, 894,
+	69, 894,
+	70, 894,
+	71, 894,
+	72, 894,
+	73, 894,
+	74, 894,
+	75, 894,
+	76, 894,
+	77, 894,
+	78, 894,
+	82, 894,
+	83, 894,
+	84, 894,
+	85, 894,
+	87, 894,
+	88, 894,
+	89, 894,
+	90, 894,
+	91, 894,
+	95, 894,
+	96, 894,
+	97, 894,
+	98, 894,
+	99, 894,
+	100, 894,
+	101, 894,
+	102, 894,
+	105, 894,
+	106, 894,
+	107, 894,
+	108, 894,
+	109, 894,
+	110, 894,
+	112, 894,
+	114, 894,
+	115, 894,
+	116, 894,
+	117, 894,
+	118, 894,
+	120, 894,
+	121, 894,
+	123, 894,
+	124, 894,
+	125, 894,
+	127, 894,
+	128, 894,
+	129, 894,
+	137, 894,
+	138, 894,
+	139, 894,
+	140, 894,
+	141, 894,
+	143, 894,
+	144, 894,
+	145, 894,
+	146, 894,
+	148, 894,
+	149, 894,
+	150, 894,
+	151, 894,
+	153, 894,
+	154, 894,
+	155, 894,
+	156, 894,
+	158, 894,
+	159, 894,
+	160, 894,
+	161, 894,
+	162, 894,
+	166, 894,
+	167, 894,
+	168, 894,
+	169, 894,
+	171, 894,
+	172, 894,
+	173, 894,
+	174, 894,
+	175, 894,
+	177, 894,
+	178, 894,
+	179, 894,
+	181, 894,
+	182, 894,
+	183, 894,
+	184, 894,
+	185, 894,
+	186, 894,
+	187, 894,
+	188, 894,
+	189, 894,
+	190, 894,
+	191, 894,
+	192, 894,
+	193, 894,
+	194, 894,
+	195, 894,
+	196, 894,
+	197, 894,
+	198, 894,
+	199, 894,
+	201, 894,
+	207, 894,
+	208, 894,
+	209, 894,
+	210, 894,
+	214, 894,
+	216, 894,
+	217, 894,
+	218, 894,
+	219, 894,
+	220, 894,
+	221, 894,
+	222, 894,
+	224, 894,
+	225, 894,
+	226, 894,
+	229, 894,
+	230, 894,
+	231, 894,
+	232, 894,
+	233, 894,
+	234, 894,
+	235, 894,
+	236, 894,
+	237, 894,
+	238, 894,
+	239, 894,
+	240, 894,
+	241, 894,
+	242, 894,
+	244, 894,
+	245, 894,
+	246, 894,
+	248, 894,
+	249, 894,
+	251, 894,
+	252, 894,
+	253, 894,
+	254, 894,
+	255, 894,
+	256, 894,
+	257, 894,
+	258, 894,
+	259, 894,
+	260, 894,
+	261, 894,
+	263, 894,
+	264, 894,
+	265, 894,
+	266, 894,
+	268, 894,
+	269, 894,
+	270, 894,
+	271, 894,
+	272, 894,
+	273, 894,
+	274, 894,
+	278, 894,
+	279, 894,
+	280, 894,
+	281, 894,
+	283, 894,
+	284, 894,
+	285, 894,
+	287, 894,
+	288, 894,
+	289, 894,
+	290, 894,
+	291, 894,
+	292, 894,
+	293, 894,
+	295, 894,
+	297, 894,
+	298, 894,
+	299, 894,
+	301, 894,
+	303, 894,
+	304, 894,
+	305, 894,
+	307, 894,
+	311, 894,
+	312, 894,
+	313, 894,
+	314, 894,
+	315, 894,
+	316, 894,
+	317, 894,
+	319, 894,
+	320, 894,
+	321, 894,
+	323, 894,
+	324, 894,
+	325, 894,
+	327, 894,
+	328, 894,
+	331, 894,
+	332, 894,
+	333, 894,
+	334, 894,
+	335, 894,
+	336, 894,
+	337, 894,
+	340, 894,
+	341, 894,
+	342, 894,
+	343, 894,
+	344, 894,
+	345, 894,
+	347, 894,
+	348, 894,
+	349, 894,
+	350, 894,
+	351, 894,
+	352, 894,
+	353, 894,
+	354, 894,
+	355, 894,
+	356, 894,
+	357, 894,
+	358, 894,
+	359, 894,
+	360, 894,
+	361, 894,
+	362, 894,
+	363, 894,
+	364, 894,
+	365, 894,
+	366, 894,
+	367, 894,
+	368, 894,
+	369, 894,
+	370, 894,
+	371, 894,
+	373, 894,
+	376, 894,
+	377, 894,
+	378, 894,
+	379, 894,
+	380, 894,
+	381, 894,
+	382, 894,
+	383, 894,
+	384, 894,
+	385, 894,
+	386, 894,
+	387, 894,
+	388, 894,
+	389, 894,
+	390, 894,
+	391, 894,
+	392, 894,
+	393, 894,
+	394, 894,
+	395, 894,
+	396, 894,
+	398, 894,
+	399, 894,
+	401, 894,
+	402, 894,
+	404, 894,
+	405, 894,
+	406, 894,
+	407, 894,
+	409, 894,
+	410, 894,
+	411, 894,
+	412, 894,
+	413, 894,
+	416, 894,
+	418, 894,
+	419, 894,
+	422, 894,
+	423, 894,
+	424, 894,
+	427, 894,
+	428, 894,
+	429, 894,
+	431, 894,
+	433, 894,
+	434, 894,
+	435, 894,
+	436, 894,
+	437, 894,
+	438, 894,
+	439, 894,
+	440, 894,
+	441, 894,
+	442, 894,
+	443, 894,
+	444, 894,
+	445, 894,
+	446, 894,
+	447, 894,
+	448, 894,
+	450, 894,
+	451, 894,
+	452, 894,
+	453, 894,
+	454, 894,
+	455, 894,
+	456, 894,
+	457, 894,
+	458, 894,
+	459, 894,
+	460, 894,
+	461, 894,
+	462, 894,
+	463, 894,
+	464, 894,
+	465, 894,
+	466, 894,
+	467, 894,
+	469, 894,
+	470, 894,
+	471, 894,
+	473, 894,
+	474, 894,
+	475, 894,
+	476, 894,
+	477, 894,
+	478, 894,
+	479, 894,
+	480, 894,
+	481, 894,
+	482, 894,
+	483, 894,
+	484, 894,
+	485, 894,
+	486, 894,
+	487, 894,
+	488, 894,
+	489, 894,
+	491, 894,
+	492, 894,
+	494, 894,
+	495, 894,
+	496, 894,
+	502, 894,
+	503, 894,
+	504, 894,
+	506, 894,
+	507, 894,
+	508, 894,
+	509, 894,
+	510, 894,
+	511, 894,
+	512, 894,
+	513, 894,
+	514, 894,
+	515, 894,
+	516, 894,
+	517, 894,
+	518, 894,
+	519, 894,
+	520, 894,
+	522, 894,
+	523, 894,
+	524, 894,
+	525, 894,
+	526, 894,
+	528, 894,
+	529, 894,
+	530, 894,
+	531, 894,
+	532, 894,
+	533, 894,
+	534, 894,
+	536, 894,
+	537, 894,
+	538, 894,
+	539, 894,
+	540, 894,
+	541, 894,
+	542, 894,
+	543, 894,
+	544, 894,
+	545, 894,
+	546, 894,
+	547, 894,
+	548, 894,
+	549, 894,
+	550, 894,
+	551, 894,
+	553, 894,
+	554, 894,
+	555, 894,
+	556, 894,
+	557, 894,
+	558, 894,
+	559, 894,
+	561, 894,
+	562, 894,
+	563, 894,
+	564, 894,
+	565, 894,
+	566, 894,
+	567, 894,
+	568, 894,
+	570, 894,
+	571, 894,
+	572, 894,
+	573, 894,
+	574, 894,
+	575, 894,
+	576, 894,
+	577, 894,
+	578, 894,
+	579, 894,
+	581, 894,
+	583, 894,
+	584, 894,
+	585, 894,
+	586, 894,
+	587, 894,
+	588, 894,
+	589, 894,
+	590, 894,
+	591, 894,
+	592, 894,
+	593, 894,
+	594, 894,
+	595, 894,
+	596, 894,
+	597, 894,
+	598, 894,
+	599, 894,
+	600, 894,
+	601, 894,
+	602, 894,
+	603, 894,
+	604, 894,
+	605, 894,
+	606, 894,
+	607, 894,
+	608, 894,
+	609, 894,
+	611, 894,
+	612, 894,
+	614, 894,
+	615, 894,
+	617, 894,
+	618, 894,
+	619, 894,
+	620, 894,
+	621, 894,
+	622, 894,
+	623, 894,
+	624, 894,
+	625, 894,
+	626, 894,
+	628, 894,
+	629, 894,
+	630, 894,
+	631, 894,
+	632, 894,
+	634, 894,
+	636, 894,
+	637, 894,
+	638, 894,
+	639, 894,
+	640, 894,
+	641, 894,
+	642, 894,
+	643, 894,
+	644, 894,
+	646, 894,
+	647, 894,
+	648, 894,
+	649, 894,
+	650, 894,
+	651, 894,
+	652, 894,
+	653, 894,
+	656, 894,
+	657, 894,
+	658, 894,
+	659, 894,
+	660, 894,
+	661, 894,
+	662, 894,
+	663, 894,
+	664, 894,
+	665, 894,
+	666, 894,
+	668, 894,
+	671, 894,
+	672, 894,
+	673, 894,
+	674, 894,
+	675, 894,
+	676, 894,
+	678, 894,
+	679, 894,
+	680, 894,
+	681, 894,
+	682, 894,
+	683, 894,
+	684, 894,
+	685, 894,
+	686, 894,
+	687, 894,
+	688, 894,
+	689, 894,
+	690, 894,
+	691, 894,
+	692, 894,
+	693, 894,
+	694, 894,
+	695, 894,
+	700, 894,
+	701, 894,
+	702, 894,
+	703, 894,
+	704, 894,
+	705, 894,
 	-2, 0,
-	-1, 4507,
-	404, 2223,
-	-2, 4043,
-	-1, 4508,
-	404, 2224,
-	-2, 3304,
-	-1, 4512,
-	508, 2876,
-	509, 2876,
-	-2, 2600,
-	-1, 4513,
-	508, 2880,
-	509, 2880,
-	-2, 2601,
-	-1, 4514,
-	508, 2877,
-	509, 2877,
-	-2, 2600,
-	-1, 4515,
-	508, 2881,
-	509, 2881,
-	-2, 2601,
-	-1, 4529,
+	-1, 4738,
+	421, 2446,
+	-2, 4339,
+	-1, 4739,
+	421, 2447,
+	-2, 3563,
+	-1, 4743,
+	533, 3113,
+	534, 3113,
+	-2, 2832,
+	-1, 4744,
+	533, 3117,
+	534, 3117,
+	-2, 2833,
+	-1, 4745,
+	533, 3114,
+	534, 3114,
+	-2, 2832,
+	-1, 4746,
+	533, 3118,
+	534, 3118,
+	-2, 2833,
+	-1, 4760,
 	17, 0,
 	18, 0,
 	19, 0,
-	57, 0,
-	255, 0,
-	259, 0,
-	320, 0,
-	544, 0,
-	673, 0,
-	689, 0,
-	-2, 2525,
-	-1, 4530,
+	58, 0,
+	262, 0,
+	267, 0,
+	329, 0,
+	569, 0,
+	706, 0,
+	722, 0,
+	-2, 2757,
+	-1, 4761,
 	17, 0,
 	18, 0,
 	19, 0,
-	57, 0,
-	255, 0,
-	259, 0,
-	320, 0,
-	544, 0,
-	673, 0,
-	689, 0,
-	-2, 2529,
-	-1, 4536,
+	58, 0,
+	262, 0,
+	267, 0,
+	329, 0,
+	569, 0,
+	706, 0,
+	722, 0,
+	-2, 2761,
+	-1, 4767,
 	17, 0,
 	18, 0,
 	19, 0,
-	57, 0,
-	255, 0,
-	259, 0,
-	320, 0,
-	544, 0,
-	673, 0,
-	689, 0,
-	-2, 2531,
-	-1, 4728,
-	1, 436,
-	712, 436,
-	-2, 2169,
-	-1, 4791,
-	1, 1070,
-	705, 1070,
-	707, 1070,
-	709, 1070,
-	712, 1070,
-	-2, 2023,
-	-1, 5101,
-	48, 2915,
-	-2, 1585,
-	-1, 5106,
-	1, 1855,
-	705, 1855,
-	707, 1855,
-	709, 1855,
-	712, 1855,
-	-2, 2169,
-	-1, 5210,
+	58, 0,
+	262, 0,
+	267, 0,
+	329, 0,
+	569, 0,
+	706, 0,
+	722, 0,
+	-2, 2763,
+	-1, 4962,
+	1, 475,
+	745, 475,
+	-2, 2392,
+	-1, 5029,
+	1, 1250,
+	738, 1250,
+	740, 1250,
+	742, 1250,
+	745, 1250,
+	-2, 2244,
+	-1, 5376,
+	48, 3152,
+	-2, 1788,
+	-1, 5381,
+	1, 2066,
+	738, 2066,
+	740, 2066,
+	742, 2066,
+	745, 2066,
+	-2, 2392,
+	-1, 5459,
 	17, 0,
 	18, 0,
 	19, 0,
-	57, 0,
-	255, 0,
-	259, 0,
-	320, 0,
-	544, 0,
-	673, 0,
-	689, 0,
-	-2, 2533,
-	-1, 5217,
-	291, 0,
-	293, 0,
-	387, 0,
-	-2, 2552,
-	-1, 5282,
+	58, 0,
+	262, 0,
+	267, 0,
+	329, 0,
+	569, 0,
+	706, 0,
+	722, 0,
+	-2, 2765,
+	-1, 5466,
+	300, 0,
+	302, 0,
+	403, 0,
+	-2, 2784,
+	-1, 5531,
 	14, 0,
 	15, 0,
 	16, 0,
-	686, 0,
-	687, 0,
-	688, 0,
-	-2, 2581,
-	-1, 5283,
+	719, 0,
+	720, 0,
+	721, 0,
+	-2, 2813,
+	-1, 5532,
 	14, 0,
 	15, 0,
 	16, 0,
-	686, 0,
-	687, 0,
-	688, 0,
-	-2, 2582,
-	-1, 5284,
+	719, 0,
+	720, 0,
+	721, 0,
+	-2, 2814,
+	-1, 5533,
 	14, 0,
 	15, 0,
 	16, 0,
-	686, 0,
-	687, 0,
-	688, 0,
-	-2, 2583,
-	-1, 5288,
+	719, 0,
+	720, 0,
+	721, 0,
+	-2, 2815,
+	-1, 5537,
 	14, 0,
 	15, 0,
 	16, 0,
-	686, 0,
-	687, 0,
-	688, 0,
-	-2, 2587,
-	-1, 5289,
+	719, 0,
+	720, 0,
+	721, 0,
+	-2, 2819,
+	-1, 5538,
 	14, 0,
 	15, 0,
 	16, 0,
-	686, 0,
-	687, 0,
-	688, 0,
-	-2, 2588,
-	-1, 5290,
+	719, 0,
+	720, 0,
+	721, 0,
+	-2, 2820,
+	-1, 5539,
 	14, 0,
 	15, 0,
 	16, 0,
-	686, 0,
-	687, 0,
-	688, 0,
-	-2, 2589,
-	-1, 5340,
-	706, 2925,
-	-2, 2940,
-	-1, 5648,
-	708, 4163,
-	-2, 2095,
-	-1, 5695,
-	291, 0,
-	293, 0,
-	387, 0,
-	-2, 2553,
-	-1, 5698,
+	719, 0,
+	720, 0,
+	721, 0,
+	-2, 2821,
+	-1, 5589,
+	739, 3162,
+	-2, 3177,
+	-1, 5944,
+	741, 4460,
+	-2, 2319,
+	-1, 5978,
+	300, 0,
+	302, 0,
+	403, 0,
+	-2, 2785,
+	-1, 5981,
 	17, 0,
 	18, 0,
 	19, 0,
-	57, 0,
-	255, 0,
-	259, 0,
-	320, 0,
-	544, 0,
-	673, 0,
-	689, 0,
-	-2, 2556,
-	-1, 5699,
+	58, 0,
+	262, 0,
+	267, 0,
+	329, 0,
+	569, 0,
+	706, 0,
+	722, 0,
+	-2, 2788,
+	-1, 5982,
 	17, 0,
 	18, 0,
 	19, 0,
-	57, 0,
-	255, 0,
-	259, 0,
-	320, 0,
-	544, 0,
-	673, 0,
-	689, 0,
-	-2, 2558,
-	-1, 5857,
-	708, 2941,
-	-2, 1895,
-	-1, 6057,
+	58, 0,
+	262, 0,
+	267, 0,
+	329, 0,
+	569, 0,
+	706, 0,
+	722, 0,
+	-2, 2790,
+	-1, 6143,
+	741, 3178,
+	-2, 2110,
+	-1, 6160,
+	2, 1981,
+	-2, 285,
+	-1, 6403,
 	17, 0,
 	18, 0,
 	19, 0,
-	57, 0,
-	255, 0,
-	259, 0,
-	320, 0,
-	544, 0,
-	673, 0,
-	689, 0,
-	-2, 2557,
-	-1, 6058,
+	58, 0,
+	262, 0,
+	267, 0,
+	329, 0,
+	569, 0,
+	706, 0,
+	722, 0,
+	-2, 2789,
+	-1, 6404,
 	17, 0,
 	18, 0,
 	19, 0,
-	57, 0,
-	255, 0,
-	259, 0,
-	320, 0,
-	544, 0,
-	673, 0,
-	689, 0,
-	-2, 2559,
-	-1, 6068,
-	291, 0,
-	-2, 2592,
-	-1, 6318,
-	291, 0,
-	-2, 2593,
-	-1, 6575,
-	57, 0,
-	255, 0,
-	320, 0,
-	544, 0,
-	673, 0,
-	689, 0,
-	-2, 4006,
+	58, 0,
+	262, 0,
+	267, 0,
+	329, 0,
+	569, 0,
+	706, 0,
+	722, 0,
+	-2, 2791,
+	-1, 6414,
+	300, 0,
+	-2, 2824,
+	-1, 6533,
+	2, 1982,
+	-2, 286,
+	-1, 6534,
+	2, 1990,
+	-2, 291,
+	-1, 6535,
+	2, 1992,
+	-2, 293,
+	-1, 6536,
+	2, 1985,
+	-2, 287,
+	-1, 6537,
+	2, 1987,
+	-2, 288,
+	-1, 6539,
+	2, 1989,
+	-2, 290,
+	-1, 6540,
+	2, 1991,
+	-2, 292,
+	-1, 6541,
+	2, 1993,
+	-2, 294,
+	-1, 6713,
+	300, 0,
+	-2, 2825,
+	-1, 6784,
+	2, 1988,
+	-2, 289,
+	-1, 6785,
+	2, 1994,
+	-2, 295,
+	-1, 7047,
+	58, 0,
+	262, 0,
+	329, 0,
+	569, 0,
+	706, 0,
+	722, 0,
+	-2, 4302,
 }
 
 const sqlPrivate = 57344
 
-const sqlLast = 184886
+const sqlLast = 209234
 
 var sqlAct = [...]int16{
-	338, 6810, 6502, 6803, 6788, 4665, 6758, 6746, 4464, 6716,
-	6650, 6195, 6632, 6380, 6405, 6561, 6163, 1639, 6574, 6436,
-	5015, 6533, 5001, 6589, 6729, 6453, 6542, 5425, 4324, 6501,
-	6492, 5087, 6513, 6196, 6516, 6591, 6590, 2888, 6659, 6289,
-	6267, 6244, 6372, 2733, 1696, 1529, 6252, 6273, 1220, 6,
-	5615, 1222, 11, 1221, 10, 6587, 1519, 869, 4285, 3158,
-	5961, 1223, 8, 5246, 1373, 219, 6245, 6226, 6322, 4,
-	6018, 6573, 6013, 6005, 5969, 4015, 6168, 2564, 5202, 5913,
-	4431, 6077, 3033, 4875, 6050, 1729, 5638, 5129, 2985, 908,
-	5515, 6419, 1139, 4748, 5609, 5627, 5755, 5854, 4521, 1395,
-	5834, 2433, 2983, 4191, 3941, 4878, 5088, 2340, 5853, 1624,
-	2170, 3106, 4666, 6294, 5120, 5111, 5607, 5071, 5591, 5963,
-	2435, 5570, 5331, 1139, 5568, 5076, 4881, 3044, 2934, 4302,
-	2742, 1538, 2370, 5156, 4451, 5158, 3034, 3035, 1365, 2510,
-	4419, 5078, 4862, 4446, 5075, 5020, 5067, 6073, 4812, 5016,
-	4864, 4863, 4814, 865, 920, 1866, 1631, 5536, 3966, 4730,
-	5042, 5350, 4714, 2946, 2590, 4688, 1430, 5041, 4325, 4680,
-	4479, 4484, 4465, 987, 4647, 2135, 2137, 4448, 2981, 219,
-	1227, 2877, 4456, 2908, 4671, 2848, 5057, 4315, 4669, 4392,
-	6633, 1679, 1025, 4902, 5048, 4104, 5424, 1750, 4075, 2875,
-	4077, 4725, 5730, 5068, 2414, 3925, 4705, 2754, 5308, 2337,
-	2006, 2795, 3918, 3041, 4646, 2314, 2391, 3917, 3167, 1957,
-	6323, 3180, 2242, 3119, 4505, 4478, 4352, 1215, 3920, 2073,
-	5019, 5065, 2826, 983, 2846, 2931, 1461, 1134, 1425, 1634,
-	2822, 2818, 2721, 2842, 4013, 2639, 131, 2516, 332, 2725,
-	1600, 1860, 2508, 3898, 2005, 4014, 331, 4190, 2341, 3295,
-	3973, 1520, 3171, 3103, 2930, 2360, 2563, 1840, 3005, 2010,
-	1603, 3022, 1610, 2560, 3003, 2112, 4458, 1698, 4432, 1731,
-	2103, 1614, 2076, 1694, 2069, 2851, 4215, 2876, 895, 958,
-	2357, 1625, 918, 1031, 6804, 4216, 5079, 135, 869, 6454,
-	2672, 2553, 1140, 2638, 5968, 1666, 3967, 1606, 4176, 1577,
-	1562, 1574, 2306, 1376, 1636, 121, 3174, 2863, 3310, 3907,
-	1523, 3165, 1502, 2350, 3228, 1380, 2256, 231, 968, 1003,
-	3262, 2171, 232, 1140, 2172, 979, 6274, 2484, 1193, 2110,
-	1147, 3004, 2034, 2614, 3006, 6651, 1141, 940, 1150, 2913,
-	6717, 2618, 1789, 1691, 1772, 913, 1408, 1525, 53, 50,
-	1500, 39, 52, 2177, 41, 6024, 37, 1427, 1859, 1782,
-	1854, 1147, 1969, 909, 1054, 922, 4553, 1141, 1429, 1150,
-	1129, 5322, 2009, 2486, 5323, 5352, 2486, 4667, 2486, 2486,
-	2486, 2486, 6699, 6829, 6796, 4749, 1194, 3897, 3897, 1143,
-	6795, 6776, 6774, 6585, 3897, 5547, 5008, 996, 999, 6757,
-	6755, 6682, 6634, 6167, 6167, 2896, 6635, 6615, 6584, 6583,
-	6532, 3897, 2187, 2188, 861, 2221, 2222, 2223, 2232, 2233,
-	2234, 6129, 6613, 6610, 5138, 866, 3897, 6611, 6607, 1617,
-	2525, 6126, 6608, 6571, 6125, 2225, 2218, 2896, 5353, 6124,
-	2187, 2188, 5059, 2219, 6570, 6569, 2190, 6559, 2896, 4489,
-	6557, 6167, 6548, 6123, 6167, 6546, 6167, 956, 2238, 6167,
-	5783, 6511, 6473, 6459, 2218, 6167, 3985, 2896, 5354, 6120,
-	1370, 5351, 1517, 1029, 2190, 6119, 6118, 6117, 6435, 2244,
-	1125, 5362, 2896, 6433, 5998, 6431, 5139, 6167, 5360, 6167,
-	2189, 6403, 4766, 2935, 6349, 5947, 1172, 1779, 3897, 6348,
-	1216, 2209, 6320, 3897, 4105, 2525, 3985, 2244, 1503, 1503,
-	6304, 2206, 6269, 1358, 5665, 6261, 5434, 6186, 2189, 6167,
-	6185, 2896, 1675, 6174, 2896, 5361, 2147, 2896, 90, 6173,
-	1219, 1218, 6166, 6167, 5357, 6134, 6167, 1347, 4424, 5412,
-	6092, 6084, 1346, 6059, 6093, 2896, 4759, 3985, 6033, 91,
-	114, 3944, 4489, 3944, 5999, 2128, 4740, 2982, 5008, 5908,
-	5358, 5881, 5810, 3897, 5745, 3897, 4805, 56, 5746, 96,
-	5697, 5656, 2070, 5650, 3985, 5151, 2522, 5151, 1675, 4007,
-	3312, 5588, 2522, 2522, 2522, 5589, 1536, 1569, 1364, 5465,
-	5433, 58, 5337, 5466, 5434, 6391, 5338, 4562, 2212, 2213,
-	2214, 2215, 5335, 4563, 1559, 5315, 5336, 4867, 2195, 3897,
-	5230, 5150, 3177, 5312, 2896, 5151, 106, 5126, 4769, 4723,
-	4664, 5127, 4770, 3897, 3897, 4662, 4658, 4657, 4608, 4663,
-	3897, 3897, 4609, 4606, 4595, 4593, 2195, 4607, 4596, 3897,
-	4564, 1504, 3980, 1506, 3897, 1507, 3132, 3133, 3134, 3151,
-	3152, 3153, 5008, 1389, 2525, 1531, 2229, 4488, 4617, 4618,
-	2239, 4489, 1224, 2522, 4475, 5547, 866, 3154, 2970, 2217,
-	2220, 4474, 4520, 4049, 3155, 2970, 59, 3897, 130, 3984,
-	3897, 6474, 6415, 3985, 114, 127, 2525, 2525, 6324, 3964,
-	6315, 3955, 2235, 3897, 2236, 2896, 1406, 2217, 2220, 3896,
-	6314, 2204, 2205, 3897, 1783, 2969, 6307, 5355, 295, 2970,
-	2244, 1560, 4489, 5312, 3311, 5356, 6009, 5947, 2522, 5882,
-	5751, 2227, 3178, 5665, 5631, 5590, 5582, 5550, 4292, 4175,
-	2747, 2896, 3144, 1783, 5412, 2539, 2210, 2895, 4060, 4424,
-	4997, 4125, 3140, 2514, 4805, 4617, 4618, 4632, 2485, 4312,
-	4167, 4069, 3974, 862, 2335, 2501, 115, 1560, 2003, 5483,
-	5205, 4818, 1783, 2358, 2210, 2835, 5140, 3936, 297, 1752,
-	3935, 3934, 5359, 3933, 3932, 2401, 2400, 2029, 295, 2399,
-	4617, 4618, 2398, 4635, 4636, 4637, 5141, 5346, 2237, 1508,
-	2487, 1505, 1357, 2487, 1356, 2487, 2487, 2487, 2487, 1355,
-	1354, 1353, 1352, 5693, 90, 1351, 1350, 1349, 1345, 2226,
-	2023, 4139, 2009, 1344, 1343, 3179, 1342, 1341, 3176, 1340,
-	2241, 1339, 1338, 1337, 296, 91, 1336, 1335, 1334, 3145,
-	3146, 3147, 3148, 1333, 1332, 2017, 1331, 1330, 297, 3139,
-	1329, 1328, 1327, 56, 1326, 96, 1325, 289, 2241, 1324,
-	1323, 6025, 1322, 3897, 4623, 3942, 290, 1321, 1320, 1319,
-	1318, 1317, 1316, 1315, 6600, 1314, 4424, 58, 1301, 4632,
-	1300, 1299, 1298, 1297, 1296, 1295, 1294, 1293, 1292, 1291,
-	1290, 1289, 5706, 2216, 2522, 4617, 4618, 233, 1288, 1287,
-	5378, 295, 106, 1286, 296, 1285, 1284, 3208, 3206, 2522,
-	2522, 3311, 1283, 1282, 1281, 1280, 1279, 1225, 1278, 1277,
-	5152, 2211, 2522, 1276, 1275, 1274, 1273, 1272, 2646, 1271,
-	3192, 1270, 2522, 4824, 119, 2522, 1269, 1268, 4183, 1267,
-	2522, 1266, 3149, 3150, 1265, 1264, 1263, 1262, 1224, 2211,
-	1261, 4623, 6599, 1260, 2522, 2230, 1249, 1461, 219, 1641,
-	1461, 297, 59, 1248, 130, 1247, 2525, 233, 1242, 1241,
-	114, 127, 1234, 1428, 1233, 1232, 1214, 3142, 1213, 1212,
-	1211, 1168, 4617, 4618, 1167, 3311, 4623, 5138, 1166, 1461,
-	1461, 1461, 4633, 1560, 1165, 2243, 1164, 229, 1163, 122,
-	1561, 1154, 126, 1153, 862, 1152, 4424, 3181, 1151, 2151,
-	4461, 1109, 994, 993, 1571, 992, 974, 296, 326, 2525,
-	6310, 325, 4034, 2243, 2522, 2514, 2485, 2998, 324, 323,
-	322, 5349, 295, 321, 4716, 295, 2028, 1734, 320, 319,
-	289, 318, 115, 317, 1226, 4183, 316, 2522, 315, 290,
-	314, 1225, 1783, 313, 312, 311, 1628, 310, 309, 1461,
-	308, 295, 1461, 307, 306, 305, 1683, 1684, 1685, 2022,
-	4639, 304, 303, 2132, 302, 1647, 2241, 301, 1372, 4633,
-	233, 3311, 300, 4575, 2228, 1670, 2187, 2188, 1560, 1461,
-	295, 4623, 297, 299, 298, 297, 4558, 2201, 2202, 2208,
-	2231, 2207, 2203, 6027, 2200, 2198, 2199, 2191, 2192, 2193,
-	2194, 2196, 2197, 1869, 4633, 4555, 4401, 4441, 6495, 1461,
-	2190, 297, 1734, 4142, 182, 1461, 1461, 4141, 4109, 5471,
-	1641, 3989, 2200, 2198, 2199, 2191, 2192, 2193, 2194, 2196,
-	2197, 3950, 3940, 235, 2361, 3190, 2317, 1994, 296, 2719,
-	297, 296, 3143, 2316, 3175, 2566, 2524, 1461, 2317, 1461,
-	2382, 1461, 2283, 2241, 2189, 2316, 2012, 4634, 1781, 1855,
-	1734, 1778, 1687, 1461, 289, 1537, 2184, 296, 4623, 1534,
-	290, 4617, 4618, 290, 2320, 2910, 6596, 230, 1628, 3994,
-	6158, 6572, 6556, 234, 6448, 1641, 2315, 2274, 2241, 6440,
-	289, 6327, 6089, 6072, 6031, 6008, 296, 1670, 5728, 290,
-	119, 233, 2078, 5722, 1217, 1662, 5721, 5720, 1734, 4633,
-	6011, 5713, 1609, 1613, 5712, 1628, 2243, 5710, 1734, 289,
-	1979, 5705, 5630, 5603, 1664, 5587, 4181, 1461, 290, 1461,
-	233, 2281, 5585, 1579, 1734, 5581, 5379, 5345, 5344, 5303,
-	5302, 5301, 1545, 1461, 4634, 1461, 1544, 5262, 1542, 1974,
-	1541, 1798, 1621, 5226, 5221, 4718, 4712, 2106, 4654, 233,
-	2949, 1532, 2038, 229, 4645, 122, 2007, 4616, 126, 4613,
-	4612, 4610, 2195, 219, 219, 4605, 4617, 4618, 4604, 4634,
-	4603, 4600, 1701, 1702, 4599, 4598, 4594, 4574, 4556, 4554,
-	4476, 3948, 3924, 2241, 3163, 2184, 4633, 2083, 2086, 4617,
-	4618, 295, 295, 1516, 1656, 2397, 4180, 2274, 2901, 2899,
-	1226, 2183, 2518, 6819, 6737, 6736, 1713, 1225, 3129, 3130,
-	3131, 3156, 3141, 3135, 1690, 3137, 3138, 3136, 3123, 3124,
-	3125, 3126, 3127, 3128, 6696, 295, 5481, 6649, 4754, 6647,
-	4628, 4626, 4627, 4619, 4620, 4621, 4622, 4624, 4625, 1539,
-	1693, 5248, 6503, 2104, 1703, 1704, 5604, 6417, 1992, 2276,
-	295, 297, 297, 1862, 6393, 1954, 1959, 4623, 6388, 6387,
-	1850, 6386, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461,
-	2241, 1147, 295, 2275, 4634, 2273, 6366, 6365, 6363, 1150,
-	182, 6326, 6325, 2004, 4443, 297, 6026, 6309, 1670, 6302,
-	3109, 6287, 6284, 1743, 6282, 6265, 1461, 1989, 6263, 235,
-	6182, 6153, 1461, 4180, 6070, 1962, 1964, 296, 296, 5991,
-	297, 5987, 2071, 5985, 5983, 5948, 5820, 2152, 4626, 4627,
-	4619, 4620, 4621, 4622, 4624, 4625, 2115, 2117, 5819, 5727,
-	289, 289, 297, 295, 5666, 5594, 5469, 5468, 5449, 290,
-	290, 296, 5448, 230, 1370, 4629, 4630, 4631, 1856, 234,
-	5446, 4180, 4628, 4626, 4627, 4619, 4620, 4621, 4622, 4624,
-	4625, 4634, 4623, 5413, 289, 2162, 296, 4706, 2338, 5318,
-	233, 233, 5305, 290, 5216, 2261, 5153, 2113, 5110, 5100,
-	4977, 4913, 4880, 4806, 2260, 4623, 4579, 2297, 296, 289,
-	1461, 1461, 1461, 297, 4578, 3115, 1461, 4573, 290, 4545,
-	6330, 4709, 4418, 869, 233, 869, 4416, 2016, 4415, 4208,
-	2323, 289, 2322, 2321, 295, 1869, 1461, 2318, 1869, 5604,
-	290, 2312, 2307, 2304, 3938, 3931, 2263, 3895, 3219, 233,
-	3188, 2959, 2490, 2339, 2332, 2331, 1461, 1966, 2330, 2420,
-	1641, 2329, 2328, 2327, 2158, 2326, 2185, 2446, 2420, 296,
-	1641, 4460, 2325, 1641, 1734, 2347, 2324, 4628, 4626, 4627,
-	4619, 4620, 4621, 4622, 4624, 4625, 2313, 2302, 2301, 2241,
-	6329, 219, 289, 2300, 297, 2385, 2299, 2298, 295, 2297,
-	295, 290, 2296, 295, 2295, 2294, 2293, 2127, 2292, 2291,
-	2290, 6121, 3207, 3205, 2289, 2413, 2288, 2287, 2344, 2345,
-	1630, 2276, 2262, 2146, 956, 1029, 2259, 2254, 1655, 1566,
-	1461, 1555, 233, 4633, 6328, 3191, 1535, 5997, 2272, 5789,
-	2089, 5701, 5377, 5334, 5321, 4561, 2109, 3987, 3949, 1641,
-	296, 5791, 4442, 2163, 3929, 2747, 1461, 2408, 297, 5744,
-	297, 5376, 1370, 297, 2275, 4752, 4627, 4619, 4620, 4621,
-	4622, 4624, 4625, 289, 2159, 5144, 2257, 2378, 4617, 4618,
-	1461, 5884, 290, 1680, 1682, 4286, 2187, 2188, 1869, 6728,
-	2407, 6398, 6389, 1697, 2559, 5583, 2319, 6311, 6217, 6045,
-	6030, 1347, 5935, 5927, 5926, 5924, 1346, 2167, 5923, 2367,
-	2166, 5922, 2161, 233, 296, 2531, 296, 2241, 1697, 296,
-	2190, 1734, 5921, 2557, 1734, 1734, 1734, 1734, 1734, 5920,
-	1503, 2180, 2181, 2443, 5883, 2745, 5769, 289, 5675, 289,
-	4617, 4618, 289, 4635, 4636, 4637, 290, 5674, 290, 5673,
-	5672, 290, 1630, 5671, 1697, 6012, 2187, 2188, 5670, 1649,
-	2420, 1675, 1670, 5692, 2189, 2109, 5669, 5668, 1681, 2421,
-	5667, 1370, 2471, 2193, 2194, 2196, 2197, 233, 2421, 233,
-	5548, 1697, 233, 1697, 2308, 2309, 1461, 2403, 2405, 1630,
-	2190, 2368, 2808, 2551, 2550, 5435, 5416, 1697, 2559, 5415,
-	5414, 5326, 5325, 5324, 1697, 5155, 5154, 1147, 4634, 2396,
-	4916, 2359, 5010, 2423, 5009, 1150, 1147, 5006, 4811, 4810,
-	4809, 4808, 2423, 5203, 1150, 1695, 6592, 2530, 6678, 4632,
-	6676, 6588, 1461, 2361, 2189, 4967, 1630, 1851, 1853, 4350,
-	1676, 1858, 4234, 5610, 48, 2365, 2317, 2297, 2297, 5506,
-	3189, 2297, 1461, 2316, 1742, 4602, 2502, 4601, 4527, 4219,
-	2545, 1678, 2336, 5464, 5002, 2736, 4619, 4620, 4621, 4622,
-	4624, 4625, 5610, 5090, 2429, 5089, 5612, 5596, 1312, 5401,
-	2363, 5402, 2195, 4882, 2477, 2377, 2375, 2480, 2372, 2376,
-	1531, 2373, 1531, 2371, 6157, 1841, 6358, 2586, 6359, 2334,
-	2878, 866, 4667, 866, 5608, 5612, 1799, 2642, 2600, 2589,
-	2285, 2533, 2597, 1751, 1675, 6406, 2430, 2491, 6534, 2935,
-	6268, 6006, 4485, 5049, 6359, 5931, 2591, 2879, 2406, 3177,
-	4999, 4667, 5580, 2529, 2554, 5512, 4623, 2950, 2499, 1313,
-	5503, 6074, 2282, 1675, 2504, 5474, 2108, 1752, 2506, 4998,
-	5195, 1628, 1842, 4789, 2673, 2511, 4094, 2979, 2912, 2513,
-	2671, 1711, 4567, 2527, 2624, 4667, 5250, 3172, 6747, 2521,
-	2421, 6780, 2827, 4621, 4622, 4624, 4625, 2832, 4217, 6177,
-	6597, 4299, 2807, 2714, 1672, 963, 2402, 6149, 2806, 963,
-	2311, 4288, 2333, 5107, 4619, 4620, 4621, 4622, 4624, 4625,
-	2814, 2942, 1734, 1734, 2082, 1999, 1651, 1503, 1147, 2599,
-	1605, 2833, 4309, 1869, 2423, 6822, 1150, 1515, 6612, 6609,
-	4639, 2571, 5900, 2572, 5896, 5134, 5440, 6381, 6014, 2534,
-	2852, 6510, 2746, 2579, 2580, 2552, 4885, 4306, 1734, 3178,
-	4304, 1717, 5459, 2676, 2140, 4753, 2817, 964, 2573, 2574,
-	5125, 964, 5033, 6680, 6679, 2577, 2578, 6180, 6176, 2817,
-	6155, 6598, 5196, 2186, 4633, 2108, 2743, 1682, 2817, 6210,
-	4793, 1734, 4981, 6720, 1677, 2556, 1375, 5870, 5525, 2266,
-	3013, 2044, 2052, 2271, 4050, 4817, 2662, 2001, 6812, 4179,
-	1310, 1308, 1306, 5868, 2241, 1100, 6214, 2803, 2603, 2812,
-	4394, 6104, 6399, 5865, 6656, 2823, 4177, 1108, 5004, 2739,
-	2394, 1105, 2625, 1839, 2844, 6203, 2555, 1734, 6188, 1734,
-	5940, 1734, 2660, 1207, 1797, 5939, 2546, 5523, 5522, 5514,
-	5489, 1796, 3179, 5488, 5486, 3176, 5485, 4107, 1673, 1734,
-	1734, 5473, 5432, 2717, 2656, 3011, 5549, 2744, 2241, 4179,
-	1674, 1681, 5431, 1734, 1767, 5932, 2962, 5039, 2962, 5003,
-	5524, 5038, 5014, 1374, 4969, 4739, 4177, 3090, 4572, 2853,
-	1368, 4571, 4570, 4817, 1461, 1665, 1461, 1676, 2889, 2893,
-	2740, 4569, 4531, 1461, 4348, 4347, 1461, 4193, 2446, 2446,
-	1869, 4795, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461,
-	1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461,
-	1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461,
-	1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 862,
-	1461, 862, 1461, 1461, 1461, 1461, 2753, 2741, 5584, 4634,
-	6749, 6748, 6750, 6178, 2829, 2828, 2830, 2715, 1715, 2378,
-	2974, 6150, 1147, 1208, 1795, 1682, 4965, 4329, 1461, 4311,
-	1150, 2883, 1461, 1461, 2894, 2815, 2800, 2775, 5058, 4298,
-	1461, 2956, 4290, 4279, 1461, 4882, 1461, 1461, 2943, 5443,
-	4278, 1367, 3015, 3046, 1869, 2881, 2882, 2867, 2867, 4915,
-	1461, 1461, 1461, 1461, 3224, 2939, 1461, 1461, 1461, 1461,
-	1461, 1461, 1461, 1461, 2977, 2866, 2866, 2879, 2869, 5000,
-	2045, 966, 2799, 3988, 3181, 2987, 2591, 2796, 6721, 3012,
-	4196, 1672, 3159, 1676, 2816, 1461, 1461, 1461, 1461, 1461,
-	1461, 1461, 1461, 1461, 2965, 1461, 3169, 2816, 3002, 1681,
-	1461, 2813, 5864, 4266, 2885, 4106, 2816, 2821, 966, 6657,
-	3223, 4265, 869, 6231, 2443, 2443, 5849, 1991, 4263, 1869,
-	4021, 5866, 3216, 1370, 4252, 1370, 1675, 869, 4625, 2953,
-	2047, 2191, 2192, 2193, 2194, 2196, 2197, 5885, 3040, 4452,
-	2906, 2561, 2562, 1869, 3265, 3265, 3279, 1461, 1461, 1461,
-	3298, 3299, 3301, 2688, 2918, 2916, 2113, 2967, 2113, 3309,
-	5842, 6243, 4250, 3013, 2002, 1369, 1699, 1700, 3010, 4245,
-	4244, 1677, 4240, 4224, 4223, 4629, 4630, 4631, 2992, 4184,
-	2945, 3965, 4628, 4626, 4627, 4619, 4620, 4621, 4622, 4624,
-	4625, 3956, 1641, 2431, 1628, 1852, 2960, 2160, 2963, 4238,
-	1744, 2056, 1699, 1700, 1776, 1303, 2197, 3946, 3947, 3027,
-	5818, 2933, 3039, 3026, 1776, 1656, 2971, 4966, 2972, 1591,
-	3172, 3175, 5843, 1205, 6723, 1204, 4802, 1672, 3011, 1699,
-	1700, 1699, 1700, 2797, 2584, 1673, 2048, 5546, 2802, 4813,
-	1641, 3982, 2095, 3121, 2094, 2561, 2562, 1674, 3912, 2999,
-	2702, 4023, 1699, 1700, 2395, 2997, 1532, 219, 1532, 3182,
-	2701, 3023, 3014, 3007, 3001, 1347, 1370, 3000, 1347, 1347,
-	3030, 1857, 1423, 3031, 3032, 1630, 1370, 6213, 5801, 1461,
-	1370, 6098, 6103, 2604, 3218, 2064, 1641, 1641, 4221, 3220,
-	3221, 6679, 3222, 1773, 2154, 3225, 3904, 3226, 3227, 1848,
-	2093, 2854, 2092, 4044, 4057, 2810, 3105, 4277, 4000, 4267,
-	4195, 2367, 2747, 5059, 2698, 3105, 1794, 1677, 6790, 1842,
-	5862, 3009, 2804, 4269, 1503, 2611, 4003, 1869, 5826, 4308,
-	1752, 2641, 1842, 3968, 965, 1775, 6095, 1752, 4729, 6724,
-	3954, 5403, 3117, 3157, 4816, 1775, 1813, 4070, 4207, 1734,
-	1734, 4457, 6374, 3952, 4815, 2993, 4792, 3928, 2605, 4134,
-	3971, 1210, 5470, 1209, 3903, 2669, 1819, 4307, 1774, 4157,
-	4807, 965, 2798, 1370, 5867, 4542, 2349, 4271, 1628, 1366,
-	1641, 1673, 1641, 3911, 4037, 3916, 3303, 5012, 3922, 3923,
-	3997, 3996, 4305, 1674, 2699, 4303, 4503, 6232, 2855, 6096,
-	1739, 1670, 3012, 1654, 4020, 4518, 1461, 5825, 3261, 4540,
-	3290, 6230, 1461, 3282, 3990, 4268, 3274, 2443, 3305, 6228,
-	2653, 6411, 4178, 3893, 3894, 1090, 2608, 2602, 2155, 4270,
-	6732, 1147, 4816, 1147, 3909, 3910, 3905, 1716, 2319, 1150,
-	4042, 1150, 4815, 2165, 6594, 3975, 6761, 2365, 2655, 6722,
-	1362, 2661, 1734, 4047, 4012, 3976, 1106, 1106, 1305, 2612,
-	4316, 5838, 4206, 1675, 2964, 4830, 6726, 967, 3281, 5839,
-	4829, 5532, 4053, 1106, 4136, 2353, 1461, 1106, 6227, 1531,
-	5844, 2687, 4048, 5530, 1147, 2684, 2077, 2659, 4194, 6239,
-	866, 3010, 1150, 5535, 1531, 6376, 5099, 4055, 1543, 3978,
-	3979, 3113, 5236, 4160, 967, 866, 3981, 5802, 3111, 6229,
-	5545, 4027, 4102, 4333, 4346, 1023, 2446, 4089, 4090, 4091,
-	4092, 3993, 4041, 5841, 4256, 6805, 4074, 5817, 2308, 2309,
-	1817, 2870, 2356, 3181, 1258, 6347, 1609, 4001, 1613, 4112,
-	4032, 5532, 4056, 4617, 4618, 5845, 4635, 4636, 4637, 4005,
-	2075, 2351, 2685, 5530, 4006, 4008, 4276, 1091, 6346, 5860,
-	4009, 4517, 5560, 5535, 4024, 1646, 5220, 4099, 4054, 4933,
-	4039, 2354, 6345, 4031, 4537, 1628, 5181, 5182, 5863, 4331,
-	5534, 5456, 4038, 2686, 4117, 4924, 4119, 5938, 4121, 3972,
-	4123, 4124, 2557, 2557, 5487, 5237, 1869, 5484, 4162, 4163,
-	4029, 4045, 4851, 1791, 4051, 4220, 4033, 4538, 1734, 1675,
-	1549, 4543, 4185, 2933, 3999, 5385, 2352, 5239, 5533, 4617,
-	4618, 4140, 4635, 4636, 4637, 4046, 2794, 1551, 5561, 5384,
-	4852, 2697, 4632, 5383, 4389, 4934, 5382, 2809, 5371, 3087,
-	5370, 1641, 5219, 5800, 5369, 6595, 5181, 5182, 5368, 1021,
-	5534, 4925, 5045, 2055, 2811, 1546, 4159, 4682, 4385, 5037,
-	1461, 1780, 1461, 4065, 4066, 4108, 3969, 4067, 4068, 4963,
-	1461, 1590, 4819, 3998, 4182, 4310, 4264, 3114, 4251, 4243,
-	5559, 4222, 2443, 4798, 2645, 2644, 6531, 4932, 5533, 2706,
-	4116, 4156, 2805, 2266, 4110, 2793, 4111, 2808, 6725, 1641,
-	4390, 5840, 1714, 4923, 1090, 4127, 2768, 1552, 4632, 2716,
-	6708, 2700, 4036, 6707, 4132, 4850, 4430, 2708, 2747, 3963,
-	5454, 4226, 6730, 4064, 4427, 3970, 4510, 4511, 6763, 1362,
-	4166, 1734, 1096, 1095, 4301, 4148, 4149, 6469, 907, 4623,
-	5013, 1553, 6664, 1734, 2801, 1734, 4241, 4853, 5430, 5861,
-	1734, 1630, 4388, 5429, 5850, 5851, 2355, 5043, 1630, 3101,
-	4211, 2791, 2015, 5046, 2021, 902, 2027, 4173, 6593, 1628,
-	4821, 6246, 2769, 4284, 4225, 2106, 2610, 3181, 5957, 1461,
-	5018, 5017, 1092, 4188, 6241, 1461, 1461, 2810, 4242, 1550,
-	1304, 5569, 4317, 3099, 219, 4274, 4198, 4201, 2745, 3181,
-	4280, 1461, 2705, 4232, 4233, 4235, 4236, 4237, 4239, 5131,
-	6375, 4101, 4145, 2792, 5531, 4623, 4337, 2750, 862, 6625,
-	4158, 5132, 1814, 4639, 2767, 4800, 2583, 4118, 4396, 4120,
-	4539, 4122, 4398, 862, 2707, 4247, 1091, 3085, 4439, 2486,
-	4541, 3088, 2126, 3104, 2131, 1461, 1461, 6731, 4349, 4260,
-	4261, 1461, 4533, 4386, 4387, 5062, 4273, 1741, 2145, 1250,
-	2150, 4272, 4282, 4336, 1461, 1461, 4434, 4633, 4296, 4289,
-	1461, 1461, 4335, 6097, 4063, 4334, 1461, 4322, 4323, 2156,
-	4494, 4495, 2081, 2751, 5531, 4328, 1251, 2807, 2874, 1846,
-	4959, 6733, 4681, 2806, 6806, 6382, 4321, 4961, 1022, 4639,
-	4869, 4165, 3084, 4728, 1147, 3953, 5018, 5017, 6487, 1812,
-	4399, 4169, 1150, 6141, 5131, 336, 4477, 3951, 2836, 4486,
-	4487, 4960, 1461, 2843, 1093, 4492, 4490, 1818, 2654, 1461,
-	2867, 4958, 4496, 1461, 4497, 2749, 4108, 1738, 1740, 4957,
-	1653, 2755, 1630, 4633, 4954, 5537, 90, 4287, 2866, 1461,
-	4345, 2241, 1235, 6467, 2873, 4470, 1094, 4472, 3095, 4422,
-	4534, 4411, 1024, 4147, 2607, 2601, 1020, 91, 5004, 2077,
-	2759, 3915, 6563, 4794, 6564, 4423, 1815, 1259, 4483, 1240,
-	2164, 4559, 4468, 3096, 4482, 56, 4897, 96, 4438, 1811,
-	962, 3097, 2187, 2188, 4480, 3102, 2000, 4450, 2827, 4454,
-	4463, 2868, 1753, 1564, 6468, 4903, 4473, 4509, 2811, 58,
-	2113, 1096, 1095, 2305, 4750, 5537, 2218, 2861, 2868, 4471,
-	4498, 1098, 5044, 2219, 4557, 2809, 2190, 2241, 6642, 3112,
-	4500, 5028, 4849, 6663, 106, 4499, 2756, 2833, 1547, 5979,
-	6643, 1097, 4634, 4332, 1461, 1461, 1461, 1461, 2871, 4896,
-	4504, 2353, 3027, 1461, 1461, 1461, 3026, 2837, 1461, 2244,
-	1613, 1092, 4519, 2833, 4905, 2871, 5426, 4526, 6428, 2737,
-	2189, 5777, 1461, 869, 6062, 1461, 1461, 1461, 1461, 5778,
-	1224, 2209, 1099, 1869, 3162, 1532, 6689, 6759, 6521, 5902,
-	4179, 2206, 5455, 1816, 59, 2746, 130, 928, 2825, 2253,
-	1532, 3908, 114, 127, 4506, 4577, 1548, 4199, 2356, 4330,
-	4775, 4532, 3298, 3298, 3298, 6764, 1370, 4656, 4634, 2704,
-	3921, 4283, 3944, 1369, 6622, 5252, 3086, 3906, 90, 2824,
-	5994, 2374, 5849, 6420, 5683, 4962, 5684, 4904, 4870, 1630,
-	2777, 5943, 5198, 5788, 5776, 5539, 5372, 2354, 6421, 91,
-	1570, 1394, 1252, 1253, 5691, 2864, 6053, 1568, 4617, 4618,
-	4501, 4635, 4636, 4637, 6437, 6626, 2760, 56, 903, 96,
-	2187, 2188, 2819, 6528, 115, 1758, 5842, 6452, 2212, 2213,
-	2214, 2215, 5835, 6286, 6240, 6422, 2787, 5942, 2195, 3282,
-	3282, 58, 4560, 4566, 2218, 5941, 4597, 5636, 2777, 5116,
-	4943, 5833, 2726, 1093, 2190, 4941, 4764, 2727, 4254, 3962,
-	2744, 5837, 6247, 2929, 3098, 2346, 106, 4338, 4629, 4630,
-	4631, 1567, 1558, 894, 3100, 4628, 4626, 4627, 4619, 4620,
-	4621, 4622, 4624, 4625, 6220, 1094, 4078, 2244, 5843, 4799,
-	2582, 2761, 2762, 2820, 2787, 1236, 1237, 4632, 2189, 2217,
-	2220, 5602, 2175, 2668, 2174, 2174, 2487, 5725, 6409, 2783,
-	5578, 5427, 1224, 6424, 1360, 904, 1090, 6662, 2169, 2757,
-	2829, 2828, 2830, 5292, 3029, 2748, 59, 2547, 130, 4079,
-	6175, 2204, 2205, 2349, 114, 127, 6769, 6113, 5836, 6423,
-	5980, 1362, 5492, 4942, 4629, 4630, 4631, 4078, 4255, 6296,
-	1098, 4628, 4626, 4627, 4619, 4620, 4621, 4622, 4624, 4625,
-	6425, 2840, 4651, 4652, 4653, 4731, 2210, 2783, 6051, 2758,
-	1097, 6641, 4876, 6052, 6356, 5637, 905, 2780, 906, 5031,
-	4668, 4660, 2355, 1630, 5032, 4082, 5518, 5493, 4088, 5441,
-	4079, 2728, 119, 5439, 5117, 2859, 2544, 5105, 1361, 4872,
-	4440, 4433, 4420, 2957, 4623, 2951, 115, 2944, 2937, 2911,
-	2732, 1099, 2905, 4087, 4085, 4320, 2195, 3019, 5235, 3282,
-	3282, 3282, 3282, 1254, 1255, 2049, 6438, 2838, 4661, 2173,
-	2173, 6278, 2353, 5397, 1582, 2780, 2785, 973, 5306, 2647,
-	3899, 6493, 2764, 5199, 4183, 5925, 4082, 5676, 1091, 4088,
-	2241, 2174, 6455, 2856, 4228, 229, 4640, 122, 2868, 2909,
-	126, 4617, 4618, 2860, 4635, 4636, 4637, 4259, 2670, 5639,
-	2865, 2540, 4690, 6019, 4087, 4085, 5685, 2217, 2220, 2839,
-	4417, 1592, 6258, 6256, 2542, 3902, 6152, 2776, 4639, 2356,
-	1531, 4888, 1630, 295, 2785, 4200, 4884, 4883, 2585, 2729,
-	2734, 866, 1226, 4524, 2786, 2862, 2175, 2175, 2351, 1225,
-	2253, 4083, 4502, 2216, 2763, 5320, 1238, 1239, 4679, 4678,
-	1785, 1784, 2990, 5364, 2980, 2903, 6054, 5838, 2354, 3901,
-	1777, 2857, 4633, 2543, 3900, 5839, 2087, 2858, 2773, 3961,
-	2790, 2211, 4944, 5726, 2210, 4257, 5844, 5293, 3960, 4084,
-	4632, 3959, 3958, 297, 3957, 2088, 2102, 2100, 1257, 5294,
-	2068, 5574, 2786, 1367, 2570, 5894, 5491, 5597, 5598, 6164,
-	2681, 6369, 4083, 2352, 119, 5970, 2173, 1630, 1630, 4204,
-	3020, 5686, 182, 6768, 5447, 2955, 5352, 4691, 5052, 5841,
-	5436, 2747, 6260, 6686, 2730, 1012, 2849, 6139, 2790, 6132,
-	6131, 235, 6130, 4393, 2771, 4105, 5192, 2765, 4803, 296,
-	4084, 5845, 4763, 4762, 4761, 2243, 2241, 4760, 2778, 4982,
-	4744, 1155, 4743, 1096, 1095, 4742, 1759, 4697, 2241, 2788,
-	4741, 4491, 289, 6499, 1013, 4397, 4081, 229, 2070, 122,
-	4395, 290, 126, 4689, 2984, 230, 2784, 4696, 1162, 5353,
-	2737, 234, 4076, 6426, 6160, 2878, 2772, 4623, 6439, 4229,
-	4230, 6427, 1720, 6277, 6370, 5398, 2517, 6147, 5497, 6507,
-	4248, 6159, 2118, 1092, 5807, 295, 2778, 6259, 5806, 5354,
-	6490, 2781, 5351, 5731, 1226, 4945, 4695, 2788, 4258, 5309,
-	2779, 1225, 5362, 6165, 4086, 3187, 1760, 4081, 2789, 5360,
-	6116, 5373, 1843, 1536, 2784, 6530, 1461, 4634, 1461, 4674,
-	4675, 4857, 6690, 2355, 4249, 2693, 2735, 869, 6688, 2211,
-	1845, 2207, 2203, 6148, 2200, 2198, 2199, 2191, 2192, 2193,
-	2194, 2196, 2197, 3186, 1838, 297, 5361, 2434, 6500, 2781,
-	6614, 4639, 6401, 1807, 6390, 5357, 5502, 6128, 2779, 869,
-	1805, 1869, 4732, 1461, 1803, 4086, 2789, 1630, 1630, 1630,
-	1630, 1869, 1801, 4858, 182, 4676, 5030, 5840, 1771, 6371,
-	6069, 5358, 972, 5955, 1769, 1766, 1641, 5797, 1764, 2782,
-	1762, 1755, 5437, 235, 1749, 4633, 1747, 5724, 5573, 5390,
-	4648, 296, 4080, 2243, 4715, 5215, 2446, 5193, 4970, 4758,
-	1869, 4611, 2569, 4544, 4421, 4410, 1641, 4297, 4291, 4218,
-	4692, 4693, 4694, 4151, 289, 1093, 3995, 2989, 1641, 2975,
-	5850, 5851, 2958, 290, 4023, 2446, 2713, 230, 2709, 862,
-	2847, 2680, 2588, 234, 6234, 4767, 2479, 2782, 2381, 2887,
-	2139, 2101, 2099, 1256, 1847, 1359, 2658, 1094, 5805, 2616,
-	4649, 4845, 4844, 4080, 2116, 4834, 4686, 2169, 4138, 1461,
-	4721, 4722, 4137, 4072, 3008, 4983, 2904, 1790, 2731, 2241,
-	2619, 1461, 2478, 2476, 4711, 2286, 2153, 1499, 6586, 5098,
-	5903, 5505, 5504, 4629, 4630, 4631, 5996, 5490, 5907, 2439,
-	4628, 4626, 4627, 4619, 4620, 4621, 4622, 4624, 4625, 4772,
-	4774, 4684, 5880, 1104, 4765, 2191, 2192, 2193, 2194, 2196,
-	2197, 6660, 1098, 4128, 1156, 1157, 6489, 1641, 5355, 1641,
-	6017, 5912, 2695, 5898, 5895, 5232, 5356, 5831, 4733, 4734,
-	4735, 4736, 1097, 2694, 5373, 5830, 4790, 5121, 1844, 4685,
-	4700, 5635, 5622, 4726, 4698, 4726, 5521, 5495, 4796, 6655,
-	4701, 4702, 1837, 4708, 1394, 1394, 1394, 5462, 4699, 2412,
-	4634, 1806, 2443, 1670, 5460, 4727, 4704, 1869, 1804, 4683,
-	1869, 5438, 1802, 1099, 5109, 5103, 5091, 4020, 4453, 4445,
-	1800, 4437, 4429, 5359, 4782, 4413, 1770, 4412, 2736, 1107,
-	2443, 2443, 1768, 1765, 4408, 1641, 1763, 4391, 1761, 1754,
-	4703, 2446, 1748, 4035, 1746, 4707, 4030, 2902, 2900, 2880,
-	4801, 2834, 4871, 2766, 6568, 2752, 2738, 2526, 1461, 2523,
-	2515, 4756, 2512, 2507, 2736, 2505, 2500, 2494, 2492, 2488,
-	2178, 4994, 4126, 1147, 1641, 1512, 2843, 4253, 6680, 4522,
-	5677, 1150, 2548, 6368, 4170, 4745, 2886, 2536, 2537, 4804,
-	4384, 4921, 4171, 2657, 4168, 1641, 2615, 4746, 6550, 6445,
-	6032, 5919, 1513, 1641, 5804, 4481, 4797, 2712, 2565, 4773,
-	6046, 1136, 4936, 2054, 1159, 1158, 1641, 1641, 1952, 4771,
-	4940, 6298, 4179, 4179, 1531, 4205, 4153, 6290, 1307, 1309,
-	4738, 4779, 3977, 4948, 4949, 866, 1532, 4786, 4783, 4177,
-	4202, 1461, 1461, 2691, 2037, 2832, 1573, 5649, 2747, 1869,
-	4843, 4950, 4791, 4955, 2832, 4887, 1531, 2606, 4892, 2954,
-	4757, 4894, 1641, 4873, 2710, 4842, 4825, 866, 4826, 1615,
-	4827, 1835, 1836, 1616, 1867, 2651, 4629, 4630, 4631, 4992,
-	1461, 6549, 2643, 4628, 4626, 4627, 4619, 4620, 4621, 4622,
-	4624, 4625, 1160, 1161, 4523, 2613, 4968, 4768, 5871, 1641,
-	5914, 2179, 2187, 2188, 4337, 1361, 1649, 2443, 1745, 4900,
-	4995, 4918, 4776, 1692, 2711, 4778, 5026, 2187, 2188, 4780,
-	4781, 4828, 1001, 4406, 4784, 5024, 4785, 4344, 2535, 5022,
-	4787, 4209, 6313, 1514, 1244, 4341, 2190, 6162, 4922, 1689,
-	5732, 5711, 4901, 4720, 4210, 4231, 1734, 2182, 1734, 1648,
-	1572, 4407, 1869, 5619, 4343, 6674, 327, 1139, 1616, 1734,
-	1734, 4914, 4340, 1461, 5517, 4835, 4023, 4023, 1616, 4210,
-	5029, 4820, 2097, 4822, 6621, 4856, 2938, 5538, 4978, 5011,
-	2189, 4846, 4847, 4848, 4859, 4860, 1660, 4306, 1641, 4304,
-	4313, 6412, 5516, 1004, 1004, 2189, 4293, 4295, 4214, 4342,
-	4212, 5007, 1810, 1018, 4906, 5106, 4886, 4339, 1461, 4890,
-	6498, 6475, 859, 4294, 4213, 4937, 6443, 6441, 6367, 6279,
-	4927, 6276, 6140, 5953, 2098, 5633, 5621, 5601, 1734, 5108,
-	4462, 4426, 4409, 3306, 2532, 2432, 6727, 6161, 4129, 4130,
-	1734, 5031, 1734, 5031, 6308, 4281, 5032, 2872, 5032, 2718,
-	1998, 1997, 1990, 1849, 1363, 4747, 2849, 6767, 4617, 4618,
-	6781, 5122, 5063, 5021, 2187, 2188, 5021, 6692, 4928, 5928,
-	4931, 1461, 4929, 5995, 4930, 4973, 5031, 4300, 1461, 1461,
-	2009, 5032, 1461, 1461, 1461, 2845, 1461, 2576, 4059, 219,
-	219, 2009, 4980, 4979, 1719, 1461, 2446, 5703, 3042, 3043,
-	1718, 5136, 5095, 5005, 1461, 5115, 4993, 2575, 4058, 1869,
-	5375, 2008, 4984, 2392, 4986, 2009, 5104, 4990, 1461, 4020,
-	4020, 4996, 5047, 5023, 5050, 4143, 1869, 3217, 5027, 2576,
-	2575, 6539, 2443, 2443, 4274, 5035, 2446, 2446, 1461, 1461,
-	5629, 1461, 1461, 1461, 5118, 1809, 6280, 4840, 1808, 6250,
-	6204, 6110, 6106, 6105, 5916, 5147, 5911, 5910, 4854, 5779,
-	2406, 4855, 1461, 862, 5775, 5774, 1461, 1140, 2446, 2446,
-	1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461,
-	1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461,
-	4226, 1461, 5702, 5171, 5054, 862, 5423, 5218, 5069, 1461,
-	1461, 2446, 5265, 5040, 5266, 1147, 1461, 5200, 5201, 5102,
-	5096, 1141, 5189, 1150, 5374, 5243, 5187, 5190, 1461, 5101,
-	4988, 5191, 5056, 5036, 4985, 4146, 5074, 2280, 2279, 869,
-	869, 4174, 2720, 1461, 6752, 6709, 5133, 6554, 6479, 6478,
-	1952, 5135, 6477, 1952, 6400, 5142, 6338, 6333, 6332, 6254,
-	2439, 2439, 5145, 5146, 6192, 6122, 6115, 1370, 6114, 6112,
-	6109, 6108, 2443, 6107, 6102, 5304, 6101, 1869, 4480, 4964,
-	1461, 1461, 5989, 5956, 5869, 5790, 5773, 4480, 5772, 5197,
-	5661, 5347, 5655, 5586, 5458, 5450, 5114, 4893, 4837, 4777,
-	1641, 1641, 4444, 4414, 4203, 4403, 2383, 4405, 4152, 2393,
-	4135, 4098, 2443, 2443, 4097, 4096, 4095, 4026, 3992, 1641,
-	1641, 3991, 3116, 2952, 2924, 2420, 2923, 1641, 2922, 2921,
-	2920, 4023, 2446, 2919, 2446, 2696, 2652, 5223, 5225, 2637,
-	2636, 2635, 5231, 2634, 2443, 2443, 2497, 2496, 2495, 2493,
-	5242, 2411, 5238, 5240, 5241, 2410, 1461, 2063, 5247, 5254,
-	2062, 2061, 2060, 2059, 1734, 4459, 2058, 2057, 4459, 1734,
-	1734, 1734, 1734, 5261, 2053, 2051, 5263, 2443, 2050, 1869,
-	5264, 5296, 1985, 1984, 5034, 1834, 1833, 1756, 1712, 5268,
-	1709, 5270, 5365, 1708, 1707, 1394, 1706, 1705, 1652, 1599,
-	4920, 1598, 1597, 1952, 1596, 1595, 1594, 5393, 5311, 5394,
-	1593, 1587, 1586, 1585, 1584, 1583, 1494, 5343, 3282, 3282,
-	2538, 4935, 5297, 5316, 5317, 1311, 1302, 6373, 5848, 4939,
-	5847, 5846, 2692, 2932, 113, 2046, 4246, 105, 5174, 5173,
-	1532, 1461, 4947, 5313, 5314, 2841, 5457, 2703, 6414, 6538,
-	6628, 2770, 5962, 5123, 6536, 4010, 2489, 5066, 6249, 2567,
-	2774, 6410, 6242, 1174, 1060, 6529, 2032, 1189, 6509, 5327,
-	4726, 5329, 1532, 4895, 1461, 1461, 5328, 4351, 1757, 2620,
-	4710, 5339, 3930, 6466, 4020, 5333, 5707, 4576, 4991, 6321,
-	5363, 6061, 3185, 2284, 4659, 107, 1416, 2443, 2443, 1459,
-	2443, 5978, 5977, 5832, 3928, 3282, 3282, 3282, 3282, 3282,
-	3282, 3282, 3282, 3282, 3282, 3282, 3282, 3282, 3282, 3282,
-	3282, 3282, 3282, 3282, 3282, 5025, 3282, 5444, 5077, 5386,
-	1461, 1461, 5974, 5475, 5392, 2421, 5973, 2436, 1461, 2438,
-	5405, 1379, 5442, 1872, 3323, 5408, 5409, 3326, 5494, 6562,
-	2549, 5496, 2558, 1630, 5499, 2310, 3264, 1437, 1476, 1734,
-	1734, 1432, 5507, 2439, 1433, 5407, 5406, 1734, 2440, 1436,
-	1734, 1734, 1434, 1147, 1435, 2303, 5419, 5420, 5498, 2423,
-	1431, 1150, 5112, 5628, 5097, 4466, 5143, 2107, 2105, 5422,
-	1062, 3926, 3110, 3170, 1734, 4565, 2277, 5513, 1396, 1641,
-	5428, 1418, 5540, 3166, 1565, 1407, 1531, 1531, 5480, 5482,
-	4687, 5130, 3307, 5330, 5366, 5367, 5557, 866, 866, 3018,
-	1734, 1199, 1028, 4614, 3173, 1554, 5552, 3287, 3280, 3276,
-	4455, 4788, 5124, 5380, 5381, 2446, 1630, 2157, 6076, 2255,
-	4467, 5391, 1686, 1400, 3108, 2268, 4549, 3028, 5137, 5479,
-	4713, 2096, 5500, 5501, 5519, 5467, 3986, 6541, 5342, 5472,
-	1461, 5251, 3943, 4144, 2928, 1511, 1510, 1563, 1509, 1438,
-	6515, 6512, 2831, 5981, 2446, 5072, 4227, 5395, 5073, 2541,
-	4052, 5396, 5529, 1734, 3120, 5092, 869, 1412, 4113, 5618,
-	5643, 4114, 1461, 5562, 5563, 1977, 2678, 4838, 4672, 4226,
-	869, 1461, 5599, 5651, 2065, 6169, 1422, 863, 2240, 1734,
-	4378, 4377, 6362, 1671, 1734, 1734, 1734, 1669, 1668, 1667,
-	6789, 4319, 4314, 5592, 334, 334, 334, 334, 1952, 897,
-	898, 2850, 914, 897, 914, 926, 5528, 5542, 971, 5453,
-	5640, 5452, 991, 5541, 5451, 5526, 5576, 998, 998, 998,
-	998, 4317, 334, 1734, 294, 5611, 1630, 1630, 4516, 2176,
-	2168, 334, 5565, 5558, 291, 5613, 1869, 5617, 5641, 1461,
-	1461, 293, 292, 5551, 4899, 1461, 1461, 2446, 5646, 5754,
-	1461, 1461, 5348, 1461, 2897, 1231, 5567, 5614, 5461, 5571,
-	5463, 4093, 334, 1721, 5632, 1461, 5566, 5477, 5051, 5647,
-	28, 2443, 5662, 5575, 1005, 1006, 5572, 5579, 5555, 1007,
-	4062, 1461, 2568, 1688, 5400, 27, 26, 25, 24, 136,
-	29, 51, 32, 5600, 31, 5, 23, 181, 2439, 179,
-	156, 5624, 177, 5626, 176, 146, 175, 174, 5658, 173,
-	2443, 172, 5700, 1630, 1630, 1630, 1630, 1630, 1630, 1630,
-	1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630,
-	1630, 1630, 1630, 5687, 1630, 5642, 5623, 2581, 1710, 171,
-	5645, 5652, 170, 869, 5644, 178, 169, 168, 5696, 163,
-	167, 869, 5660, 5620, 5520, 1869, 1869, 166, 5653, 165,
-	164, 5659, 162, 2446, 160, 5688, 161, 155, 159, 869,
-	158, 1394, 157, 154, 2726, 1952, 153, 1869, 152, 2727,
-	151, 150, 149, 148, 5729, 1734, 1734, 147, 145, 5678,
-	180, 144, 143, 5680, 236, 142, 141, 140, 5681, 5679,
-	219, 139, 30, 138, 137, 984, 985, 71, 70, 1869,
-	133, 134, 22, 2443, 4715, 862, 862, 49, 17, 75,
-	76, 1641, 21, 16, 44, 110, 4468, 125, 124, 897,
-	897, 3045, 123, 45, 120, 43, 20, 334, 19, 4480,
-	18, 118, 117, 116, 42, 1734, 1734, 1461, 40, 14,
-	12, 46, 1540, 2369, 15, 7, 112, 1869, 228, 227,
-	224, 223, 226, 222, 225, 109, 1461, 5418, 221, 1952,
-	111, 220, 108, 5723, 38, 13, 5750, 869, 212, 869,
-	5606, 99, 216, 215, 5740, 5742, 214, 213, 103, 211,
-	5781, 5782, 210, 209, 201, 218, 97, 208, 102, 5748,
-	101, 5827, 207, 98, 1641, 217, 100, 104, 36, 9,
-	74, 6049, 5194, 2728, 1869, 128, 1641, 5736, 5739, 1641,
-	129, 5879, 5855, 1531, 5855, 3183, 47, 5733, 95, 2443,
-	94, 5749, 2732, 5888, 866, 5738, 5891, 1531, 93, 92,
-	5753, 35, 1461, 5824, 1952, 1869, 5734, 5735, 866, 73,
-	34, 287, 288, 286, 5780, 5784, 5785, 5786, 5787, 5897,
-	285, 283, 5899, 5808, 284, 282, 5901, 281, 1952, 5793,
-	5794, 5795, 5796, 196, 261, 5799, 5798, 260, 259, 1461,
-	258, 257, 1461, 256, 255, 254, 253, 5858, 248, 252,
-	250, 249, 5812, 251, 5829, 5811, 247, 277, 5873, 276,
-	5809, 275, 274, 273, 1734, 1734, 5929, 272, 271, 1461,
-	270, 264, 5816, 4023, 1461, 1461, 5823, 263, 5737, 269,
-	268, 2729, 2734, 267, 3939, 869, 266, 265, 262, 280,
-	206, 205, 202, 204, 203, 88, 246, 245, 244, 242,
-	238, 241, 243, 240, 239, 237, 279, 5874, 278, 200,
-	1641, 199, 89, 194, 195, 87, 193, 192, 191, 5937,
-	190, 189, 188, 187, 5918, 86, 1869, 6000, 198, 197,
-	5855, 1734, 33, 2, 5909, 1, 0, 0, 5934, 0,
-	5889, 0, 1532, 1532, 0, 5556, 0, 0, 0, 0,
-	0, 0, 5950, 0, 0, 0, 0, 0, 1734, 1734,
-	1734, 1734, 1734, 1461, 1734, 1734, 1734, 0, 5954, 0,
-	1531, 0, 0, 0, 0, 0, 2730, 0, 1531, 5821,
-	5822, 866, 1461, 1461, 1461, 0, 5936, 5933, 6020, 866,
-	0, 6001, 5993, 5982, 5952, 5803, 1531, 1869, 5930, 5892,
-	5611, 0, 1461, 0, 0, 1461, 1461, 866, 5872, 5859,
-	5613, 0, 1952, 0, 5021, 1461, 6021, 5945, 2446, 5958,
-	0, 5972, 1461, 1461, 5944, 5976, 4020, 4909, 5875, 5876,
-	5984, 0, 2737, 0, 0, 0, 5992, 5990, 0, 2443,
-	0, 5951, 1461, 0, 0, 0, 6004, 1734, 6007, 1734,
-	1734, 0, 5946, 0, 0, 6015, 5949, 0, 0, 0,
-	1734, 0, 0, 0, 0, 0, 0, 6022, 4061, 5915,
-	0, 5917, 6023, 0, 0, 0, 6003, 6055, 0, 0,
-	6029, 0, 0, 0, 0, 0, 0, 0, 1641, 0,
-	6035, 6034, 0, 4907, 0, 0, 0, 0, 2735, 0,
-	0, 0, 4546, 4547, 1531, 0, 1531, 0, 0, 0,
-	1461, 1461, 0, 5171, 5171, 866, 0, 866, 0, 6071,
-	0, 0, 862, 0, 0, 0, 1869, 0, 0, 0,
-	0, 0, 0, 0, 1461, 6037, 862, 5971, 6064, 6065,
-	6042, 6047, 0, 0, 0, 4908, 0, 1461, 0, 0,
-	6048, 0, 0, 0, 0, 0, 1461, 0, 0, 6088,
-	0, 2446, 0, 0, 6085, 0, 6086, 6087, 0, 6137,
-	6138, 1461, 6082, 6083, 1461, 0, 0, 6146, 6090, 6091,
-	0, 0, 0, 0, 2443, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 1461, 0, 0, 1461, 0,
-	5758, 0, 6197, 5756, 0, 1869, 0, 0, 0, 0,
-	0, 1734, 1461, 5768, 1734, 1734, 0, 1461, 1461, 6194,
-	5764, 0, 0, 1461, 6172, 0, 1461, 6143, 0, 6144,
-	1641, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 6142, 6224, 6136, 0,
-	2731, 6191, 1531, 6145, 0, 0, 1734, 6151, 0, 5766,
-	5767, 5765, 2736, 866, 5757, 6238, 5761, 0, 0, 0,
-	0, 0, 0, 0, 869, 0, 869, 0, 0, 0,
-	0, 1952, 4641, 4642, 4643, 4644, 0, 0, 6209, 0,
-	0, 0, 5762, 0, 0, 0, 0, 0, 0, 1556,
-	6233, 2446, 0, 6253, 0, 0, 0, 6193, 1869, 862,
-	914, 1734, 0, 0, 6271, 0, 0, 862, 0, 5855,
-	6257, 5855, 6198, 0, 914, 6222, 0, 2443, 0, 0,
-	334, 334, 6206, 0, 0, 862, 1734, 0, 1589, 0,
-	3282, 6251, 0, 0, 0, 2962, 6189, 4910, 4911, 334,
-	4912, 334, 334, 0, 1620, 334, 0, 1635, 0, 6235,
-	1461, 2446, 0, 6236, 0, 0, 0, 0, 6291, 0,
-	1650, 0, 6248, 0, 0, 0, 0, 0, 991, 5878,
-	6255, 991, 6262, 0, 6264, 0, 0, 5611, 0, 1532,
-	6215, 6216, 5887, 0, 6225, 5890, 6292, 5613, 0, 6270,
-	0, 6272, 6127, 1532, 998, 0, 0, 0, 1641, 1641,
-	1641, 1641, 0, 0, 1641, 1641, 1641, 1641, 6283, 1641,
-	1641, 6281, 0, 0, 6295, 6275, 0, 6293, 4974, 4975,
-	6295, 4976, 6300, 6299, 0, 0, 6237, 6288, 0, 5759,
-	0, 0, 0, 862, 1461, 862, 1461, 5760, 1461, 0,
-	6301, 0, 6303, 0, 0, 0, 6312, 0, 869, 3282,
-	0, 0, 6319, 6350, 0, 0, 0, 2443, 0, 0,
-	0, 1461, 0, 869, 334, 0, 0, 0, 0, 0,
-	6331, 0, 0, 0, 0, 0, 1394, 0, 6355, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	6183, 6184, 1630, 5855, 5763, 0, 0, 0, 1734, 0,
-	6306, 334, 0, 334, 334, 334, 334, 1620, 5855, 334,
-	334, 0, 0, 0, 0, 0, 0, 2443, 1635, 0,
-	1461, 1461, 1630, 0, 0, 6354, 0, 6353, 1461, 5074,
-	0, 6205, 334, 6207, 2011, 6208, 0, 6266, 0, 6357,
-	6404, 6384, 0, 0, 869, 6377, 869, 0, 6378, 0,
-	0, 0, 2030, 0, 330, 6430, 0, 0, 0, 6442,
-	0, 0, 0, 2042, 6416, 869, 1532, 0, 869, 0,
-	0, 6385, 1734, 0, 1532, 6394, 6297, 0, 0, 0,
-	2067, 862, 1635, 1734, 0, 0, 0, 334, 334, 5855,
-	1620, 5855, 1532, 0, 1461, 1461, 1461, 0, 0, 0,
-	6396, 0, 0, 0, 6402, 1461, 0, 0, 0, 0,
-	5855, 0, 0, 5855, 0, 0, 991, 0, 334, 334,
-	6408, 0, 6199, 0, 0, 0, 4751, 6407, 0, 0,
-	2133, 1531, 6429, 1531, 0, 0, 0, 1027, 0, 0,
-	0, 2141, 866, 0, 866, 6418, 1231, 5993, 0, 0,
-	0, 0, 6432, 6470, 6434, 5611, 0, 6456, 6447, 0,
-	6457, 0, 6458, 0, 0, 5613, 0, 6461, 1630, 1461,
-	1461, 6462, 6463, 6449, 1461, 3282, 6451, 6471, 6472, 1734,
-	1641, 0, 1641, 0, 6460, 0, 6476, 0, 0, 0,
-	1461, 2446, 334, 0, 6514, 6517, 0, 0, 0, 0,
-	1532, 0, 1532, 0, 0, 6522, 0, 0, 6480, 6481,
-	6482, 6483, 6334, 6335, 6336, 6337, 6540, 6488, 6339, 6340,
-	6341, 6342, 0, 6343, 6344, 6545, 6496, 6497, 6518, 0,
-	0, 0, 0, 6523, 0, 0, 6505, 6504, 0, 0,
-	0, 0, 0, 6547, 0, 6567, 0, 6519, 1461, 1461,
-	1461, 0, 0, 6544, 0, 0, 6524, 0, 1952, 0,
-	0, 3282, 0, 0, 0, 0, 6537, 6506, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 2439, 0,
-	0, 0, 6484, 6485, 6486, 0, 3282, 1630, 0, 6535,
-	0, 1461, 0, 0, 6565, 6551, 0, 0, 6601, 0,
-	6555, 0, 0, 6558, 0, 6606, 2439, 2439, 6566, 0,
-	0, 0, 0, 0, 4673, 1531, 0, 0, 0, 6582,
-	6579, 6580, 0, 6581, 6620, 0, 866, 6395, 0, 0,
-	1531, 4879, 0, 0, 2736, 6624, 6223, 0, 0, 0,
-	6638, 866, 0, 6603, 0, 0, 0, 0, 1532, 0,
-	0, 6646, 0, 0, 6636, 6525, 1461, 2443, 6640, 6464,
-	6623, 6465, 0, 0, 1641, 1641, 1641, 6, 6637, 2962,
-	11, 0, 10, 6645, 6661, 6253, 6619, 6627, 6644, 1630,
-	8, 0, 6648, 219, 0, 6631, 6654, 6681, 6630, 0,
-	6653, 897, 0, 0, 0, 0, 0, 0, 6667, 6668,
-	6617, 6652, 0, 0, 0, 0, 6675, 1461, 6677, 6695,
-	0, 1531, 334, 1531, 334, 6683, 6514, 6672, 334, 6517,
-	6604, 6685, 866, 0, 866, 6705, 6687, 0, 869, 2011,
-	869, 6693, 1531, 0, 6639, 1531, 1620, 1635, 334, 6691,
-	334, 2409, 6701, 866, 6718, 6711, 866, 6703, 334, 6698,
-	914, 0, 0, 0, 0, 6543, 6710, 334, 6714, 0,
-	6719, 6704, 0, 0, 0, 0, 0, 0, 0, 6712,
-	862, 1641, 862, 5855, 6673, 5855, 0, 0, 6658, 0,
-	0, 0, 2498, 2439, 0, 6734, 0, 6735, 6743, 0,
-	0, 0, 6751, 6684, 6526, 334, 6527, 6741, 6740, 6742,
-	0, 0, 0, 6739, 334, 0, 6697, 0, 1461, 1461,
-	6753, 6762, 0, 1630, 6745, 6760, 0, 1461, 1461, 0,
-	0, 6700, 6754, 6702, 0, 0, 6765, 6706, 0, 0,
-	6778, 6777, 6770, 0, 0, 6775, 6713, 0, 6715, 6782,
-	0, 0, 6786, 991, 0, 0, 6783, 0, 6794, 6785,
-	6793, 6792, 0, 6602, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 6798, 6797, 0, 0, 0,
-	6799, 0, 1641, 0, 6801, 0, 6771, 6772, 6811, 6809,
-	6787, 998, 6808, 998, 0, 0, 6813, 6814, 0, 6807,
-	6744, 0, 0, 998, 998, 6818, 0, 6802, 6791, 1630,
-	1461, 6756, 6821, 6823, 0, 0, 6825, 6828, 6800, 6826,
-	6815, 6831, 6811, 6830, 6827, 0, 0, 0, 0, 0,
-	6817, 0, 0, 0, 1630, 0, 0, 0, 991, 0,
-	0, 0, 6779, 0, 0, 0, 334, 0, 0, 0,
-	0, 6784, 6616, 0, 2617, 6618, 0, 0, 0, 334,
-	0, 334, 0, 334, 862, 334, 0, 0, 334, 6824,
-	334, 0, 0, 0, 0, 0, 0, 0, 897, 862,
-	0, 0, 0, 6543, 0, 0, 0, 0, 6669, 6670,
-	6671, 0, 0, 2726, 1630, 0, 2434, 2663, 2727, 6816,
-	2664, 0, 2665, 0, 2666, 0, 2667, 0, 0, 0,
-	0, 0, 6820, 0, 0, 0, 0, 0, 2439, 2439,
-	0, 334, 334, 334, 334, 0, 0, 334, 334, 0,
-	0, 0, 0, 0, 0, 0, 3042, 5255, 0, 0,
-	0, 0, 0, 5625, 0, 0, 0, 1532, 0, 1532,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	862, 0, 862, 0, 0, 0, 0, 0, 3042, 5271,
-	4468, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 862, 0, 0, 862, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 6738, 0, 0, 0, 0,
-	0, 5300, 0, 0, 0, 1531, 0, 1531, 0, 4468,
-	0, 0, 0, 90, 0, 0, 866, 0, 866, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 5682, 0,
-	0, 0, 2728, 0, 91, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 2439, 0,
-	0, 2732, 0, 0, 96, 0, 0, 0, 0, 0,
-	0, 0, 0, 1630, 0, 0, 6773, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 2187, 2188, 0, 1952, 0, 2439, 2439,
-	0, 0, 0, 0, 0, 0, 1952, 0, 0, 334,
-	0, 106, 0, 334, 0, 0, 0, 2218, 0, 0,
-	0, 0, 0, 0, 2219, 0, 2587, 2190, 0, 0,
-	2439, 2439, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 1532, 0, 0, 0, 1952, 0, 0, 0, 0,
-	2729, 2734, 4717, 0, 334, 334, 1532, 1224, 0, 0,
-	2244, 0, 4724, 2439, 0, 0, 0, 0, 0, 0,
-	0, 2189, 0, 130, 334, 0, 0, 0, 0, 114,
-	127, 0, 2209, 0, 0, 334, 0, 0, 0, 0,
-	0, 0, 334, 0, 0, 0, 0, 0, 0, 0,
-	0, 4755, 0, 0, 1394, 1578, 1578, 0, 0, 334,
-	0, 334, 0, 0, 0, 897, 1394, 334, 0, 0,
-	0, 0, 0, 0, 1604, 0, 1604, 1604, 0, 991,
-	1027, 0, 0, 1231, 0, 0, 0, 1532, 0, 1532,
-	0, 5211, 5212, 0, 0, 2730, 0, 0, 0, 0,
-	0, 115, 0, 0, 0, 0, 0, 0, 1532, 0,
-	0, 1532, 0, 0, 0, 1620, 334, 0, 0, 0,
-	971, 0, 0, 0, 991, 5964, 0, 0, 0, 2212,
-	2213, 2214, 2215, 2439, 2439, 0, 2439, 0, 0, 2195,
-	1630, 0, 0, 0, 0, 0, 2724, 0, 0, 0,
-	0, 2737, 0, 0, 0, 0, 2777, 0, 0, 0,
-	0, 0, 1952, 0, 0, 1952, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 5272, 5273,
-	5274, 5275, 5276, 5277, 5278, 5279, 5280, 5281, 5282, 5283,
-	5284, 5285, 5286, 5287, 5288, 5289, 5290, 5291, 0, 5295,
-	2217, 2220, 2787, 0, 862, 5905, 862, 0, 0, 0,
-	0, 0, 2722, 0, 0, 0, 0, 2735, 4839, 0,
-	3122, 1867, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 1960,
-	1578, 1578, 0, 0, 1978, 1027, 0, 0, 3983, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 2723, 0, 0, 2210, 0, 119,
-	0, 0, 0, 0, 0, 2783, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 4879, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 897, 5988, 0, 3308, 0,
-	0, 0, 0, 0, 1952, 0, 0, 0, 0, 0,
-	0, 334, 0, 0, 0, 0, 6002, 0, 0, 0,
-	897, 0, 1027, 1027, 0, 0, 334, 0, 897, 0,
-	0, 0, 229, 0, 122, 0, 0, 126, 0, 0,
-	334, 0, 0, 2780, 0, 6028, 0, 0, 0, 0,
-	0, 2241, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 2731,
-	295, 0, 0, 0, 90, 334, 1635, 0, 0, 1226,
-	0, 0, 334, 0, 334, 2011, 1225, 334, 334, 0,
-	0, 0, 0, 5965, 0, 91, 0, 0, 0, 0,
-	0, 0, 2785, 0, 0, 0, 0, 1952, 0, 0,
-	0, 0, 0, 0, 2216, 96, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 2434, 0, 0,
-	297, 0, 334, 1635, 0, 334, 914, 2439, 914, 0,
-	0, 0, 2211, 0, 0, 334, 0, 0, 334, 0,
-	0, 0, 334, 0, 4025, 0, 0, 0, 0, 182,
-	334, 334, 106, 4717, 0, 334, 0, 334, 0, 0,
-	2786, 1532, 1620, 1532, 334, 334, 2439, 0, 235, 0,
-	0, 0, 1635, 1635, 4043, 0, 296, 0, 0, 334,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	6133, 0, 0, 0, 0, 0, 2790, 0, 1224, 289,
-	0, 0, 0, 0, 0, 0, 2243, 0, 290, 0,
-	0, 0, 230, 0, 130, 0, 0, 0, 234, 0,
-	114, 127, 0, 998, 998, 0, 0, 998, 998, 0,
-	0, 0, 0, 5747, 334, 0, 0, 0, 0, 233,
-	0, 0, 0, 1386, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 1952, 0, 0, 0, 0, 0,
-	334, 1620, 334, 0, 0, 0, 0, 0, 0, 2439,
-	0, 1952, 4115, 334, 2778, 0, 0, 1620, 0, 1620,
-	0, 1620, 0, 0, 0, 2788, 0, 0, 0, 0,
-	0, 0, 115, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 2784, 0, 0, 0, 0, 0, 0, 0,
-	5228, 0, 4249, 0, 0, 2200, 2198, 2199, 2191, 2192,
-	2193, 2194, 2196, 2197, 0, 0, 0, 5244, 0, 0,
-	334, 0, 0, 0, 0, 0, 0, 2781, 0, 0,
-	0, 0, 0, 0, 0, 0, 2779, 334, 334, 334,
-	334, 1620, 0, 0, 2789, 0, 0, 0, 0, 0,
-	0, 1620, 0, 0, 334, 1978, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 4192, 0, 0, 0,
-	0, 0, 0, 0, 0, 2439, 0, 5966, 334, 0,
-	0, 0, 0, 4617, 4618, 0, 4635, 4636, 4637, 0,
-	0, 0, 334, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 1952, 0, 0, 0, 334, 0, 0, 0,
-	1604, 0, 0, 0, 0, 0, 0, 0, 0, 1978,
-	0, 0, 0, 0, 0, 2782, 0, 0, 0, 4262,
-	0, 5967, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 991, 0, 0, 0, 0, 991, 0, 0, 0,
-	119, 0, 0, 0, 0, 0, 0, 0, 5340, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 4632, 0, 334, 2187, 2188, 0, 2221, 2222,
-	2223, 2232, 2233, 2234, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 4326, 2011, 0, 0, 2225, 2218,
-	0, 0, 0, 0, 1952, 0, 2219, 0, 0, 2190,
-	0, 0, 0, 229, 0, 122, 0, 0, 126, 0,
-	0, 2238, 1417, 132, 2187, 2188, 0, 0, 0, 0,
-	2232, 2233, 2234, 0, 0, 334, 4400, 0, 0, 0,
-	0, 0, 2244, 0, 0, 0, 0, 0, 2218, 0,
-	0, 295, 0, 2189, 0, 2219, 0, 0, 2190, 0,
-	1226, 0, 0, 0, 2209, 0, 0, 1225, 0, 2011,
-	2238, 0, 334, 0, 2206, 4326, 6392, 0, 0, 4623,
-	0, 0, 334, 0, 0, 0, 0, 0, 0, 0,
-	0, 2244, 0, 4449, 0, 0, 0, 0, 0, 0,
-	0, 0, 2189, 0, 4192, 0, 897, 0, 0, 0,
-	0, 297, 0, 2209, 0, 1231, 4192, 0, 2434, 0,
-	0, 0, 0, 2206, 0, 2439, 0, 0, 2677, 2679,
-	0, 0, 2682, 2683, 0, 0, 0, 132, 334, 0,
-	182, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 6444, 0, 0, 6446, 0, 0, 0, 0, 235,
-	0, 2212, 2213, 2214, 2215, 0, 0, 296, 0, 334,
-	0, 2195, 0, 0, 0, 0, 0, 0, 334, 0,
-	0, 2187, 2188, 0, 0, 0, 0, 0, 0, 0,
-	289, 0, 0, 1722, 0, 0, 0, 0, 0, 290,
-	0, 0, 0, 230, 0, 2218, 0, 4633, 0, 234,
-	2212, 2213, 2214, 2215, 0, 2190, 0, 0, 0, 2229,
-	2195, 0, 0, 2239, 0, 0, 0, 0, 0, 0,
-	233, 0, 2217, 2220, 0, 0, 0, 0, 0, 0,
-	0, 0, 1348, 0, 0, 0, 0, 0, 2244, 0,
-	0, 0, 0, 0, 0, 2235, 1371, 2236, 0, 2189,
-	0, 6181, 0, 0, 2204, 2205, 0, 0, 2229, 0,
-	2439, 0, 2239, 0, 0, 0, 0, 0, 1982, 0,
-	0, 2217, 2220, 0, 2227, 0, 0, 0, 0, 0,
-	0, 2241, 186, 0, 0, 0, 0, 0, 0, 2210,
-	0, 90, 2011, 55, 54, 0, 0, 0, 0, 0,
-	0, 0, 0, 2204, 2205, 0, 6552, 0, 6553, 0,
-	1521, 0, 91, 0, 0, 0, 2035, 84, 0, 0,
-	0, 0, 0, 2227, 0, 0, 0, 0, 0, 0,
-	56, 0, 96, 0, 0, 0, 0, 0, 2210, 2915,
-	2915, 2237, 0, 0, 0, 0, 77, 0, 0, 0,
-	0, 0, 0, 0, 58, 0, 184, 0, 0, 0,
-	0, 0, 2226, 0, 0, 0, 0, 2195, 0, 0,
-	2677, 0, 4634, 2241, 2121, 0, 57, 0, 0, 106,
-	0, 1952, 0, 0, 0, 0, 0, 0, 0, 0,
-	2136, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 2439, 0, 0, 0, 0, 0, 60,
-	78, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	61, 0, 2241, 0, 0, 67, 0, 0, 2217, 2220,
-	0, 85, 0, 0, 0, 0, 2216, 0, 0, 59,
-	0, 130, 334, 0, 0, 0, 0, 114, 127, 0,
-	0, 2434, 0, 6068, 0, 0, 0, 79, 0, 0,
-	0, 0, 0, 0, 2211, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 2216, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 2210, 0, 62, 2230, 0,
-	1952, 1952, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 2211, 0, 0, 0, 0, 0, 115,
-	0, 0, 1952, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 2243, 0,
-	0, 0, 0, 2439, 0, 0, 0, 2230, 4629, 4630,
-	4631, 0, 0, 0, 1952, 4628, 4626, 4627, 4619, 4620,
-	4621, 4622, 4624, 4625, 0, 0, 0, 0, 0, 0,
-	0, 0, 6154, 0, 0, 0, 0, 0, 5752, 2241,
-	0, 0, 0, 0, 0, 0, 0, 2243, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 1952, 2439, 0, 0, 0, 80, 0, 0,
-	5792, 1394, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 2228, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	2201, 2202, 2208, 2231, 2207, 2203, 0, 2200, 2198, 2199,
-	2191, 2192, 2193, 2194, 2196, 2197, 0, 0, 1867, 1952,
-	0, 5716, 0, 0, 0, 5715, 0, 0, 0, 0,
-	2211, 0, 0, 0, 0, 0, 2228, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 119, 0, 0,
-	1952, 0, 2231, 2207, 2203, 0, 2200, 2198, 2199, 2191,
-	2192, 2193, 2194, 2196, 2197, 63, 0, 0, 0, 0,
-	1027, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	2482, 0, 1578, 1578, 66, 0, 0, 1394, 0, 0,
-	69, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	81, 0, 0, 0, 2243, 0, 0, 0, 0, 68,
-	229, 0, 122, 0, 0, 126, 0, 0, 0, 0,
-	0, 0, 64, 0, 0, 0, 185, 1027, 0, 0,
+	360, 6943, 7373, 7304, 5363, 7366, 4897, 7342, 6561, 7353,
+	7245, 7157, 4701, 7135, 6813, 6512, 7031, 6769, 4540, 4498,
+	7288, 6864, 7046, 915, 6621, 5252, 7061, 7101, 5362, 6777,
+	7103, 7258, 6883, 6139, 6277, 7008, 5274, 6992, 4213, 6804,
+	3040, 6959, 4116, 6956, 6933, 7062, 5904, 7063, 7166, 5677,
+	6673, 6649, 917, 6632, 1803, 6655, 6622, 2877, 6819, 921,
+	7059, 5810, 1463, 238, 6942, 6562, 1295, 6, 4214, 6345,
+	1297, 11, 1299, 14, 3322, 4983, 6817, 1296, 10, 1298,
+	8, 4, 5495, 6338, 4111, 6717, 6330, 6292, 2698, 6838,
+	6216, 5261, 5451, 6423, 4664, 5124, 6396, 7045, 1208, 6366,
+	4278, 3191, 5929, 6517, 947, 6368, 6597, 5916, 5860, 975,
+	6845, 5412, 3094, 4619, 5127, 4898, 6140, 2468, 1629, 5779,
+	5898, 3061, 6038, 4752, 6120, 5961, 1801, 4401, 965, 2562,
+	4137, 1731, 1208, 3267, 5397, 2293, 6679, 2564, 1837, 5896,
+	5345, 5386, 5878, 6279, 5845, 5329, 5847, 5310, 3106, 5823,
+	3202, 5350, 1046, 1610, 5130, 5683, 5580, 5685, 1455, 1746,
+	5401, 1724, 3192, 2902, 3193, 5403, 4652, 2890, 2644, 5111,
+	6419, 5349, 5334, 4685, 5338, 5304, 5303, 4618, 5280, 5276,
+	4220, 5352, 2498, 5718, 5113, 4541, 238, 4163, 2069, 6134,
+	6133, 4679, 5112, 4920, 4948, 6013, 978, 4912, 4716, 4515,
+	5599, 1303, 1978, 4702, 4879, 2727, 5317, 4900, 4902, 4692,
+	4681, 4614, 2997, 4528, 7136, 4310, 5152, 5676, 5335, 4964,
+	1087, 4283, 4959, 4121, 4939, 2944, 4285, 1786, 4113, 4114,
+	5557, 3029, 3027, 2543, 2464, 2440, 6718, 3331, 4878, 3344,
+	3199, 3280, 2368, 4736, 4570, 4715, 1290, 2194, 354, 353,
+	3091, 5332, 1732, 2991, 1741, 5279, 140, 1552, 1203, 1042,
+	2995, 2121, 1485, 2971, 2975, 2967, 2865, 2869, 1515, 1972,
+	2781, 5102, 1017, 2650, 1952, 3090, 2642, 3028, 1707, 5116,
+	2122, 4212, 2488, 1851, 4170, 4665, 4093, 2469, 3460, 1611,
+	3335, 3264, 3180, 2697, 2694, 1805, 3163, 1717, 2519, 2485,
+	2235, 4694, 3161, 1652, 3124, 1710, 2197, 2226, 2190, 1094,
+	3002, 4427, 2687, 4428, 144, 6284, 4386, 7367, 2815, 921,
+	5353, 4164, 1721, 2126, 3015, 2780, 1773, 130, 1713, 1614,
+	6884, 1679, 1682, 1663, 2432, 3338, 1065, 4103, 3427, 3392,
+	3475, 2478, 1594, 2294, 2295, 1466, 1216, 1219, 3329, 3162,
+	252, 1738, 1265, 1595, 1595, 1027, 1038, 2382, 253, 1210,
+	3164, 2233, 2751, 1743, 6656, 2150, 1000, 7158, 7246, 1198,
+	1897, 3071, 358, 2759, 1498, 1880, 52, 970, 1209, 55,
+	1216, 1219, 54, 1592, 43, 2081, 1266, 39, 41, 1616,
+	6356, 2300, 1971, 1210, 1890, 1966, 1120, 5571, 962, 966,
+	5572, 980, 4784, 1212, 4899, 2618, 2618, 7398, 2618, 7220,
+	2618, 4092, 1209, 2618, 2618, 1798, 7057, 7056, 7376, 7350,
+	1058, 1061, 7377, 4092, 7349, 1887, 2268, 2125, 4092, 7324,
+	4984, 2310, 2311, 7206, 2347, 2348, 2349, 2358, 2359, 2360,
+	7322, 7303, 7301, 7299, 5265, 6516, 6516, 6516, 7269, 7216,
+	5319, 5421, 5821, 6982, 2351, 2341, 7189, 7137, 4311, 7121,
+	3048, 7138, 2342, 7122, 7089, 2313, 6141, 7087, 4092, 7084,
+	4140, 4092, 7081, 7085, 1015, 2659, 7082, 7055, 2364, 7043,
+	7042, 7040, 6979, 3048, 3048, 6689, 2310, 2311, 5601, 6474,
+	7039, 7029, 4400, 1091, 5046, 6516, 6465, 6464, 6471, 6463,
+	1194, 2370, 4849, 4850, 7027, 4867, 4868, 4869, 6516, 7025,
+	2341, 1460, 2312, 6516, 7016, 7014, 6462, 1244, 6516, 6516,
+	2313, 6470, 7012, 2332, 6954, 5976, 6516, 1608, 6516, 6469,
+	6914, 2310, 2311, 2329, 4182, 6468, 6889, 6863, 6861, 2344,
+	3048, 3048, 6516, 6859, 6857, 6811, 6744, 6516, 6516, 6257,
+	6103, 6323, 5422, 5602, 6743, 2341, 2370, 6742, 4092, 2251,
+	1448, 4092, 6715, 4140, 6678, 2313, 4182, 2312, 5934, 6651,
+	6641, 2145, 6552, 5691, 6516, 6551, 3048, 6066, 6523, 3048,
+	4975, 5603, 3048, 2343, 5600, 5001, 6522, 6515, 6438, 1435,
+	6516, 6516, 6439, 4994, 4864, 6430, 6405, 1434, 5611, 3048,
+	4182, 2370, 6365, 3476, 6794, 5609, 5046, 2656, 2656, 6324,
+	2656, 123, 2312, 5265, 6211, 6184, 6097, 6028, 4092, 4092,
+	5049, 6029, 2659, 2335, 2336, 2337, 2338, 2656, 5980, 1484,
+	5952, 5946, 4182, 2318, 5434, 5434, 5875, 5855, 1891, 1891,
+	5876, 5856, 5610, 5727, 1454, 4849, 4850, 5728, 1627, 5690,
+	5586, 5584, 5606, 5691, 5587, 5585, 5564, 5479, 1782, 5433,
+	4092, 3048, 5409, 5434, 3095, 5045, 5410, 4204, 2191, 5046,
+	1671, 3293, 3294, 3295, 3312, 3313, 3314, 5006, 5607, 4957,
+	4896, 5007, 2355, 4092, 4092, 4894, 4890, 2365, 2318, 4895,
+	4092, 2656, 3315, 5561, 4889, 1596, 2340, 2346, 4092, 3316,
+	4177, 4839, 4837, 4826, 4855, 4840, 4838, 4827, 4824, 4657,
+	4849, 4850, 4092, 4795, 4712, 4793, 5265, 4092, 3133, 4711,
+	2361, 4794, 2362, 3133, 4250, 2659, 7206, 4181, 4092, 2327,
+	2328, 4182, 4161, 2318, 5821, 4151, 4092, 4864, 2370, 3048,
+	4091, 4751, 3132, 1660, 4092, 2659, 3133, 4092, 1598, 2353,
+	1599, 2340, 2346, 316, 6982, 6915, 6834, 6719, 6710, 6709,
+	3305, 6702, 6689, 3048, 5561, 3477, 2333, 6334, 6257, 2656,
+	3301, 6242, 1891, 6185, 6103, 6034, 3318, 5934, 2659, 5920,
+	5877, 5866, 5827, 4505, 4385, 1620, 2673, 2895, 4092, 3047,
+	4261, 4871, 4657, 5248, 4332, 2345, 2340, 2346, 2648, 5049,
+	2617, 4525, 4377, 4270, 4171, 2462, 2635, 1661, 2119, 5746,
+	4849, 4850, 5454, 5060, 2486, 2984, 1853, 318, 5423, 4132,
+	3317, 2333, 4131, 2363, 4130, 2310, 2311, 2144, 4129, 4128,
+	316, 2529, 2528, 2527, 5604, 2310, 2311, 4865, 5424, 3372,
+	2526, 1600, 5605, 2619, 2619, 2352, 2619, 4855, 2619, 2310,
+	2311, 2619, 2619, 1597, 1661, 1447, 2367, 1446, 4346, 2313,
+	3306, 3307, 3308, 3309, 1445, 1444, 2333, 2616, 1520, 2313,
+	3300, 1443, 1442, 2341, 1441, 317, 1440, 1439, 1438, 5595,
+	2342, 4138, 1437, 2313, 1433, 1432, 1431, 1430, 1429, 1428,
+	1427, 1426, 1425, 1424, 318, 1423, 2125, 1422, 4657, 1421,
+	310, 1420, 1419, 2139, 2133, 5608, 2312, 1418, 1417, 311,
+	1416, 2367, 4855, 1415, 1414, 1413, 2312, 1412, 1411, 2370,
+	1410, 1409, 1408, 1407, 1406, 2339, 1405, 2367, 1404, 1403,
+	2312, 6336, 7078, 2656, 2656, 2659, 1402, 1401, 1400, 1399,
+	254, 2332, 1398, 6705, 1397, 1382, 1381, 3341, 1380, 1379,
+	1378, 1377, 317, 1376, 1375, 2334, 2367, 2344, 1374, 1373,
+	2788, 1372, 1519, 1371, 1370, 1655, 3310, 3311, 1369, 1368,
+	1367, 316, 2272, 1366, 1365, 316, 316, 1364, 1363, 1362,
+	4865, 1361, 1360, 1359, 1358, 1357, 1356, 1301, 1355, 2356,
+	1354, 1353, 7077, 1352, 2656, 1351, 1350, 7072, 1349, 3477,
+	1348, 2343, 1347, 3303, 7071, 1346, 2656, 1345, 238, 1344,
+	2334, 1343, 4855, 4849, 4850, 2656, 1552, 254, 1748, 1552,
+	6357, 918, 1342, 1341, 1340, 1339, 4866, 2318, 1338, 1337,
+	1336, 1325, 3319, 2369, 1324, 318, 5989, 2318, 2656, 318,
+	318, 2335, 2336, 2337, 2338, 4865, 2656, 1323, 1552, 1552,
+	1552, 2318, 2656, 1318, 1317, 2334, 1310, 1309, 1308, 1289,
+	3342, 1288, 1287, 1286, 1279, 1238, 3370, 5627, 3477, 5421,
+	2367, 2659, 4235, 1237, 2656, 1236, 2648, 3356, 5435, 2617,
+	3156, 1235, 1234, 1233, 1232, 1223, 1222, 1221, 2369, 1220,
+	4697, 1176, 1056, 317, 1055, 1054, 1662, 317, 317, 1053,
+	1655, 1052, 1661, 1651, 2255, 1051, 1033, 348, 5069, 316,
+	2656, 1673, 347, 346, 2340, 2346, 4657, 1891, 310, 1889,
+	3477, 316, 1886, 310, 1754, 1552, 2354, 311, 1552, 345,
+	344, 311, 311, 2369, 343, 2367, 1790, 1791, 1792, 2324,
+	2325, 2331, 2357, 2330, 2326, 4865, 2323, 2321, 2322, 2314,
+	2315, 2316, 2317, 2319, 2320, 1777, 1552, 3343, 254, 2138,
+	5999, 3340, 254, 254, 5998, 5598, 4950, 4849, 4850, 4866,
+	4867, 4868, 4869, 318, 342, 341, 340, 339, 338, 337,
+	1981, 336, 335, 334, 2333, 318, 1552, 1661, 333, 1655,
+	5975, 332, 3304, 1552, 1552, 1552, 331, 1808, 1809, 1748,
+	330, 2323, 2321, 2322, 2314, 2315, 2316, 2317, 2319, 2320,
+	4861, 4862, 4863, 2345, 329, 4855, 328, 4860, 4858, 4859,
+	4851, 4852, 4853, 4854, 4856, 4857, 1552, 327, 1552, 326,
+	1552, 317, 325, 1462, 4866, 2367, 324, 323, 4849, 4850,
+	1655, 322, 321, 317, 320, 1552, 319, 2321, 2322, 2314,
+	2315, 2316, 2317, 2319, 2320, 4806, 310, 4393, 4789, 4864,
+	2367, 3354, 4786, 4623, 1979, 311, 4349, 1748, 310, 4348,
+	2369, 4316, 4186, 4146, 2367, 6359, 4674, 311, 1735, 2722,
+	2443, 918, 4136, 4393, 2863, 1777, 2700, 2442, 2443, 4849,
+	4850, 2489, 2658, 1655, 2510, 2442, 254, 2409, 7068, 2400,
+	1769, 2128, 1967, 1794, 1655, 1628, 1625, 7044, 254, 6507,
+	7024, 1771, 6876, 1552, 6868, 1552, 1716, 1720, 2446, 2091,
+	1655, 6435, 1684, 2307, 6418, 1636, 2441, 5892, 1635, 1552,
+	1633, 1552, 6363, 1632, 4866, 6722, 1728, 6333, 6011, 6005,
+	4849, 4850, 6004, 2339, 6003, 5996, 2078, 5995, 4865, 5993,
+	5988, 5919, 5874, 3345, 5869, 2086, 238, 238, 2110, 1650,
+	4860, 4858, 4859, 4851, 4852, 4853, 4854, 4856, 4857, 4855,
+	5865, 5628, 5594, 2334, 2407, 5593, 3290, 3291, 3292, 3320,
+	3302, 3296, 5552, 3298, 3299, 3297, 3284, 3285, 3286, 3287,
+	3288, 3289, 5551, 1860, 1763, 2123, 5550, 1607, 5511, 5475,
+	5470, 2204, 2207, 1797, 4952, 1821, 4946, 4886, 1962, 4877,
+	4848, 4845, 4844, 1906, 4842, 1291, 1913, 4841, 1735, 4836,
+	1484, 1484, 1484, 5744, 4835, 4834, 2199, 4859, 4851, 4852,
+	4853, 4854, 4856, 4857, 2211, 4831, 4830, 4829, 2367, 2229,
+	4855, 4825, 4805, 96, 4787, 1294, 1293, 2105, 4785, 4713,
+	4144, 2369, 2108, 316, 316, 4120, 4871, 1735, 3327, 2307,
+	1216, 1219, 3109, 3066, 5734, 97, 3053, 3051, 1974, 2652,
+	2066, 2071, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552,
+	2525, 2400, 2306, 7385, 1800, 58, 7327, 102, 1810, 1811,
+	4391, 4855, 7266, 6337, 7265, 316, 2120, 2156, 1844, 115,
+	1777, 7207, 4865, 2401, 7198, 2399, 1552, 1735, 3339, 60,
+	316, 2402, 1552, 7197, 7156, 2074, 2076, 318, 318, 2192,
+	7154, 7152, 316, 7093, 1630, 4860, 4858, 4859, 4851, 4852,
+	4853, 4854, 4856, 4857, 2273, 113, 5497, 4866, 4989, 6983,
+	2238, 2240, 4855, 4191, 6944, 2316, 2317, 2319, 2320, 1460,
+	5893, 6843, 2064, 2314, 2315, 2316, 2317, 2319, 2320, 318,
+	1968, 6830, 6796, 2227, 2323, 2321, 2322, 2314, 2315, 2316,
+	2317, 2319, 2320, 6791, 318, 317, 317, 3371, 64, 4676,
+	6790, 1300, 6789, 6782, 6781, 6763, 318, 6762, 6760, 6721,
+	2228, 6720, 2367, 2285, 6358, 6704, 2236, 61, 6690, 139,
+	310, 310, 1552, 1552, 1552, 123, 136, 1552, 6687, 311,
+	311, 3270, 6671, 6669, 921, 6666, 921, 317, 6664, 6647,
+	6645, 2132, 6643, 6588, 4865, 6548, 1981, 1552, 4943, 1981,
+	6502, 6416, 317, 6316, 6312, 6310, 1595, 6308, 6306, 6258,
+	254, 254, 310, 6236, 317, 6104, 6102, 6101, 1552, 6010,
+	5893, 311, 5935, 6706, 316, 5881, 5732, 310, 5731, 4390,
+	2549, 1748, 5706, 2367, 5705, 5703, 311, 4390, 2575, 310,
+	2549, 4940, 1748, 2279, 316, 1748, 1655, 2465, 311, 124,
+	238, 2475, 4696, 5567, 5554, 4390, 2389, 3276, 5465, 2387,
+	5436, 4866, 2308, 5385, 5375, 5228, 5163, 254, 5129, 5050,
+	2386, 2513, 4810, 4809, 1015, 1091, 4804, 4776, 2250, 254,
+	2511, 4651, 4645, 2521, 2367, 4644, 4636, 4419, 318, 352,
+	2472, 2473, 2542, 2450, 2267, 2449, 2448, 2447, 2444, 4858,
+	4859, 4851, 4852, 4853, 4854, 4856, 4857, 1552, 318, 2438,
+	2433, 2232, 2430, 4134, 4127, 4090, 3383, 2398, 1513, 3352,
+	3122, 2622, 2466, 2459, 2458, 2457, 1748, 2456, 2537, 2286,
+	2455, 2454, 1460, 1552, 2453, 2452, 2451, 2439, 2428, 2427,
+	2426, 2532, 2425, 2424, 2423, 2422, 317, 2421, 2420, 2280,
+	2419, 2418, 2417, 316, 2416, 2415, 2414, 1552, 2413, 2402,
+	2388, 2385, 2380, 1762, 1667, 1981, 317, 1647, 1626, 2530,
+	6725, 310, 2423, 6724, 3369, 2290, 6723, 2445, 1089, 6322,
+	311, 2536, 6072, 4866, 1435, 3355, 2289, 5984, 5626, 5583,
+	5570, 310, 1434, 4792, 2495, 2284, 4184, 4145, 4125, 1655,
+	311, 6466, 1655, 1655, 1655, 1655, 1655, 2665, 4675, 5427,
+	2691, 254, 6074, 6027, 2310, 2311, 5625, 318, 2563, 2303,
+	2304, 2401, 4987, 2383, 4849, 4850, 128, 6187, 1804, 2506,
+	1655, 254, 1804, 5867, 4499, 2549, 7277, 1789, 7257, 7215,
+	7214, 1787, 1460, 7212, 7209, 4861, 4862, 4863, 2313, 2701,
+	1777, 7208, 4860, 4858, 4859, 4851, 4852, 4853, 4854, 4856,
+	4857, 2685, 2684, 2531, 1552, 1804, 2693, 2434, 2435, 2496,
+	1804, 2693, 6986, 2601, 1804, 317, 5166, 6985, 1216, 1219,
+	2534, 2487, 6984, 2664, 6902, 6801, 6792, 6697, 1216, 1219,
+	6696, 2552, 6695, 6538, 6694, 2312, 250, 1804, 131, 1595,
+	310, 2552, 135, 6693, 6692, 6691, 1804, 6593, 6583, 311,
+	2550, 6487, 6486, 1804, 1552, 2493, 1804, 6362, 7064, 6230,
+	2550, 6229, 1804, 6227, 2524, 1788, 4851, 4852, 4853, 4854,
+	4856, 4857, 6226, 6225, 1552, 316, 6224, 1802, 6223, 6186,
+	254, 6052, 5938, 5937, 1302, 5936, 2881, 2463, 2957, 5825,
+	1756, 1301, 2232, 5692, 5575, 50, 5574, 5573, 5438, 5437,
+	5267, 2636, 2734, 5266, 2503, 2461, 5259, 2505, 2064, 3353,
+	2504, 2064, 2501, 2491, 7185, 2499, 2500, 4851, 4852, 4853,
+	4854, 4856, 4857, 4447, 5055, 5054, 5053, 5052, 7183, 1963,
+	1965, 5899, 2423, 2423, 2558, 2423, 4568, 1782, 5452, 318,
+	5899, 7060, 2489, 6153, 2688, 2607, 2667, 2443, 2610, 2559,
+	5770, 5218, 4833, 4832, 2442, 1970, 6506, 4758, 4431, 1785,
+	5726, 1395, 5365, 1843, 5364, 5131, 5901, 2231, 2411, 196,
+	4853, 4854, 4856, 4857, 5652, 5901, 5653, 5883, 3030, 1953,
+	1914, 5811, 3341, 6755, 4274, 2784, 2726, 6756, 1907, 256,
+	1620, 2663, 1620, 6814, 4899, 2668, 1772, 317, 2981, 2679,
+	6805, 2895, 1025, 4899, 4899, 5897, 1782, 3095, 2765, 2737,
+	1861, 5812, 1852, 6756, 6650, 1782, 6331, 6981, 2408, 6969,
+	5962, 6613, 310, 1216, 1219, 5311, 1396, 2736, 1655, 2661,
+	1517, 311, 6420, 2819, 6234, 251, 2552, 2728, 3031, 1981,
+	5859, 255, 5776, 5767, 1606, 2705, 5737, 2706, 1853, 5649,
+	5444, 5103, 1954, 4689, 2816, 2550, 3142, 2713, 2714, 3068,
+	2814, 1783, 1292, 1818, 1655, 6243, 5499, 4798, 6999, 1484,
+	2686, 6529, 3110, 3336, 6498, 2858, 7331, 2064, 4512, 7069,
+	4429, 1022, 4501, 5826, 2893, 1022, 2963, 2956, 2437, 913,
+	2460, 2754, 2690, 2955, 7289, 3342, 5382, 3102, 2208, 2203,
+	2115, 1758, 1655, 1712, 7390, 7086, 7083, 6203, 6199, 5417,
+	4519, 1825, 4517, 5697, 6778, 5253, 7092, 6339, 2209, 4522,
+	6953, 5134, 5721, 3049, 5408, 2261, 2861, 2707, 2708, 1655,
+	2740, 5293, 7249, 2689, 2711, 2712, 1735, 7186, 2309, 1822,
+	6532, 1157, 6526, 7163, 6504, 1783, 1783, 1023, 5445, 2766,
+	1655, 1023, 1655, 7187, 1655, 2966, 2952, 2966, 2961, 6576,
+	6171, 2966, 1518, 4313, 2972, 7070, 1452, 6580, 4616, 6450,
+	2174, 1655, 5340, 5031, 1387, 4251, 2522, 5260, 4988, 7375,
+	2798, 3128, 1282, 5250, 1655, 1904, 2993, 1789, 1465, 5789,
+	2804, 5262, 3343, 2802, 6807, 6569, 3340, 6554, 6250, 6249,
+	5809, 1175, 5249, 1172, 1951, 1912, 5787, 1552, 2231, 1552,
+	1167, 3003, 1779, 1905, 5406, 5786, 1552, 5778, 2117, 1552,
+	5753, 2575, 2575, 1981, 1392, 1552, 1552, 1552, 1552, 1552,
+	1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552,
+	1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552,
+	1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552,
+	1552, 1552, 1552, 1552, 1552, 2901, 1552, 3137, 1552, 1552,
+	1552, 1552, 2889, 2859, 5752, 1788, 5788, 1158, 1216, 1219,
+	1464, 2680, 5749, 1024, 5748, 5736, 3125, 1789, 3125, 1389,
+	5689, 5688, 5301, 6824, 1552, 3099, 1779, 1779, 1552, 1552,
+	2924, 3033, 3034, 5262, 6824, 2964, 1552, 3203, 5339, 1784,
+	1552, 1903, 1552, 1552, 3046, 3035, 5300, 5273, 1283, 2949,
+	1981, 5268, 5220, 5165, 1823, 4974, 1552, 1552, 1552, 1552,
+	3019, 3019, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552,
+	3173, 3020, 3103, 3018, 3018, 3251, 4803, 5868, 3151, 1622,
+	3160, 4802, 6530, 3117, 3004, 6499, 2948, 2945, 3140, 4801,
+	4800, 4762, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552,
+	1552, 4566, 1552, 3323, 5255, 1788, 2962, 1552, 4312, 1780,
+	4565, 1025, 2970, 7291, 7290, 7292, 1025, 3333, 3345, 3037,
+	921, 1781, 7250, 1784, 1784, 5216, 6821, 1981, 2894, 4546,
+	5131, 3200, 3201, 7164, 3347, 921, 1460, 6821, 1460, 4536,
+	3031, 2064, 4524, 3380, 1496, 1595, 4511, 4503, 2728, 4492,
+	4491, 1981, 1026, 4479, 4478, 1552, 1552, 1552, 5254, 3058,
+	4686, 4476, 4465, 4463, 2891, 4185, 3430, 3430, 3444, 3130,
+	4458, 3113, 3463, 3464, 3466, 3078, 2572, 3198, 3074, 4124,
+	2965, 3474, 2965, 2236, 4457, 2236, 2965, 1163, 1162, 6542,
+	3150, 4436, 2623, 1780, 1780, 3105, 4389, 4389, 5066, 5067,
+	4435, 1748, 3171, 914, 6270, 1781, 1781, 2320, 2887, 4394,
+	4162, 1623, 2976, 4387, 4387, 2633, 918, 4857, 918, 1806,
+	1807, 2638, 4152, 1806, 1807, 2640, 6188, 3123, 2210, 3126,
+	4142, 4143, 2645, 3185, 3184, 4135, 2647, 6105, 2560, 1763,
+	1159, 3134, 3197, 3135, 2535, 5406, 2655, 2282, 2107, 2892,
+	1748, 1872, 2982, 6084, 3171, 1884, 2695, 2696, 6173, 6240,
+	6100, 2695, 2696, 4222, 238, 1806, 1807, 4453, 4179, 3282,
+	6238, 5033, 3169, 3339, 4451, 3159, 3165, 3172, 3157, 6822,
+	3204, 6602, 1460, 3388, 2888, 2118, 3158, 1964, 1806, 1807,
+	6822, 1435, 1460, 1552, 1435, 1435, 1460, 1806, 1807, 3188,
+	1748, 1748, 3189, 3190, 1806, 1807, 3387, 1806, 1807, 1845,
+	1458, 7326, 2523, 1806, 1807, 4219, 5251, 1085, 3064, 5232,
+	6820, 1484, 4433, 3336, 3169, 2064, 4108, 5820, 4100, 6274,
+	1277, 6820, 1276, 2842, 2178, 5796, 5217, 2741, 2217, 5318,
+	2216, 1981, 6579, 2495, 6449, 5817, 1384, 3346, 1782, 1683,
+	1683, 5794, 3093, 2959, 3468, 2506, 4403, 5044, 2720, 2832,
+	6444, 5799, 2185, 1902, 1735, 1655, 1655, 1655, 1711, 7252,
+	1711, 1711, 3382, 3167, 1089, 4200, 3321, 3384, 3385, 3278,
+	3386, 6136, 6137, 3389, 2275, 3390, 3391, 1699, 1969, 3426,
+	7186, 1460, 1024, 1883, 5342, 1160, 2215, 1024, 2214, 6818,
+	1960, 1748, 1884, 1748, 4258, 4099, 1954, 1853, 4107, 5341,
+	4112, 4275, 2783, 4118, 4119, 1853, 2742, 6441, 1393, 1285,
+	4238, 1284, 2064, 4197, 1457, 4262, 1777, 1161, 1552, 3425,
+	4193, 3439, 1782, 1782, 1552, 4521, 1954, 1853, 7004, 1853,
+	1216, 1219, 1216, 1219, 3455, 3470, 5802, 5803, 4237, 4490,
+	5798, 5700, 4248, 4088, 4089, 1083, 5030, 3170, 4468, 4245,
+	4105, 4106, 4101, 914, 2493, 6272, 4518, 2445, 4516, 5405,
+	2846, 7344, 4480, 3060, 5097, 4520, 1655, 3005, 4172, 5404,
+	2845, 4211, 6442, 1390, 1881, 3266, 1450, 7253, 1157, 5797,
+	5654, 1157, 3266, 4406, 1216, 1219, 1165, 6085, 6112, 2064,
+	1552, 2978, 2977, 2979, 5796, 4187, 5098, 4271, 1824, 3170,
+	2748, 4148, 6771, 1452, 4963, 2165, 1452, 1164, 4173, 4418,
+	5794, 7005, 2276, 2064, 1924, 4341, 2812, 4693, 4175, 4176,
+	5799, 1026, 4249, 5687, 4150, 4734, 1026, 4165, 5051, 1386,
+	1883, 2072, 1683, 1683, 2575, 4240, 2090, 1089, 1930, 4190,
+	4307, 4242, 3168, 4228, 2803, 1735, 1459, 2801, 4308, 2434,
+	2435, 1166, 4254, 1882, 4178, 5402, 1173, 959, 1173, 4530,
+	4325, 1634, 4327, 1451, 4329, 4296, 4297, 4298, 4299, 4233,
+	3006, 6111, 4202, 6603, 4481, 1716, 1620, 1720, 4256, 1173,
+	4207, 4749, 4208, 5096, 954, 4194, 4223, 6601, 6099, 5719,
+	5846, 1620, 1761, 5270, 3168, 6599, 5687, 4482, 4232, 4094,
+	7307, 4239, 6620, 4203, 2288, 5802, 5803, 6823, 2843, 5798,
+	5819, 7255, 7251, 4417, 1158, 1981, 5099, 1158, 6823, 1089,
+	1089, 2691, 2691, 5319, 4367, 4257, 3274, 1655, 2745, 4252,
+	6083, 4168, 7131, 3272, 2739, 1753, 6155, 4375, 2749, 4243,
+	3127, 4372, 4373, 1854, 1173, 5075, 4097, 4379, 5797, 6773,
+	4432, 4255, 4395, 4484, 4246, 4314, 6619, 4198, 6598, 5074,
+	4305, 2841, 4551, 1748, 4444, 4343, 4446, 4448, 4449, 4450,
+	4452, 6610, 5278, 4564, 4266, 4267, 1840, 1928, 4268, 4269,
+	6149, 4324, 1552, 4326, 1552, 4328, 5374, 4330, 4331, 7132,
+	6600, 5795, 4096, 2795, 2198, 4438, 2831, 4095, 4548, 5729,
+	2828, 4849, 4850, 2064, 4867, 4868, 4869, 4469, 4489, 4483,
+	5277, 1084, 4392, 3021, 4439, 7213, 4323, 6271, 2850, 4347,
+	7368, 1334, 4350, 2797, 5469, 5733, 4388, 3345, 4405, 1748,
+	1855, 6741, 5488, 2903, 4454, 2310, 2311, 4196, 1888, 4334,
+	5712, 6740, 4383, 7066, 4660, 4319, 4748, 6739, 4339, 2166,
+	2852, 4376, 1735, 3248, 4317, 6248, 4318, 5751, 5747, 2341,
+	5405, 2196, 4370, 5634, 1655, 6162, 4357, 4358, 3262, 2313,
+	5404, 2829, 2477, 5275, 1456, 1655, 3155, 6135, 1655, 1086,
+	5633, 5485, 4514, 1082, 3062, 3063, 5632, 4773, 5631, 6854,
+	6147, 5620, 7261, 4864, 1163, 1162, 5837, 1163, 1162, 5619,
+	4195, 2177, 4707, 2830, 3260, 2370, 4423, 1552, 5618, 2572,
+	2572, 5617, 2169, 1552, 1552, 5307, 2312, 5299, 4408, 4411,
+	4437, 4398, 4607, 4771, 6128, 238, 6273, 5214, 5801, 1552,
+	5061, 4523, 6160, 6170, 4477, 4455, 4464, 2849, 4531, 5684,
+	4487, 6157, 2131, 4456, 2137, 4493, 2143, 1159, 4849, 4850,
+	1159, 4867, 4868, 4869, 1698, 4672, 4637, 6846, 7254, 4434,
+	5795, 5036, 1899, 4265, 6978, 4460, 6135, 2860, 5838, 7309,
+	2851, 5468, 6847, 7235, 2481, 4169, 1552, 1552, 5486, 4473,
+	4474, 4667, 1552, 5711, 4567, 6129, 7234, 1224, 4663, 4608,
+	4609, 4160, 4725, 4726, 5308, 1552, 1552, 4495, 4486, 2787,
+	2786, 1552, 1552, 4855, 7171, 2229, 4502, 1552, 6848, 4538,
+	4539, 4485, 4509, 6128, 1231, 4404, 5682, 3446, 2167, 6121,
+	5681, 5095, 5836, 2170, 4369, 4420, 1216, 1219, 3345, 2249,
+	5686, 2254, 2484, 6146, 5063, 6623, 4529, 2318, 6119, 4621,
+	4864, 4314, 4537, 3093, 4098, 2266, 2844, 2271, 5415, 6123,
+	1385, 5184, 2479, 6150, 7067, 4166, 1552, 3246, 5278, 4727,
+	4544, 4728, 3249, 1552, 4366, 5271, 6163, 1552, 2895, 3019,
+	4714, 6443, 2482, 5414, 6129, 3256, 2747, 4353, 1925, 4563,
+	4741, 4742, 3018, 1552, 6772, 4497, 5305, 2064, 2277, 1089,
+	4871, 6850, 2090, 4555, 4768, 2155, 5277, 5801, 2723, 2618,
+	2340, 2346, 1160, 5686, 3257, 1160, 955, 6267, 5655, 4709,
+	2202, 6910, 3258, 4765, 4638, 4554, 3263, 6849, 4167, 4553,
+	2480, 4552, 4272, 5185, 3245, 4264, 1958, 3041, 6122, 4656,
+	4790, 4769, 1449, 5038, 1161, 4774, 4865, 1161, 2154, 6851,
+	6972, 3265, 4671, 4655, 6164, 6165, 2568, 5210, 4764, 5414,
+	4855, 2893, 2870, 1820, 4740, 4699, 2228, 2871, 4700, 4690,
+	2946, 4708, 1711, 7369, 4710, 2951, 4914, 2236, 4683, 4684,
+	2333, 2090, 918, 6928, 3345, 6161, 4729, 5183, 2985, 1552,
+	1552, 1552, 1552, 2992, 4788, 7065, 4731, 918, 1552, 1552,
+	1552, 4730, 4147, 1552, 6156, 7259, 4962, 6490, 5278, 4735,
+	4368, 3185, 3184, 1165, 1923, 5174, 1165, 921, 1552, 956,
+	1552, 1552, 1552, 1552, 6158, 4750, 4149, 5212, 1981, 2903,
+	2717, 2572, 4757, 1720, 1164, 1929, 2367, 1164, 2906, 3013,
+	5118, 7033, 4611, 7034, 4230, 6148, 5277, 4871, 6124, 2908,
+	4234, 5211, 2895, 5209, 5208, 1926, 6125, 5205, 4500, 6631,
+	2198, 2907, 2953, 6779, 1760, 1842, 5255, 1460, 6130, 4247,
+	2367, 4720, 3463, 3463, 3463, 2942, 2287, 4888, 1166, 200,
+	4763, 1166, 4356, 2483, 957, 2848, 958, 5175, 96, 3273,
+	57, 56, 5862, 4865, 3022, 4719, 1335, 5032, 2884, 1225,
+	1226, 2744, 1326, 2917, 5146, 2872, 1922, 2738, 2883, 1021,
+	97, 1484, 4905, 2947, 4612, 90, 6127, 4549, 2913, 2898,
+	4849, 4850, 2116, 4867, 4868, 4869, 2876, 4550, 2904, 1327,
+	58, 2986, 102, 1665, 3022, 4866, 2796, 6124, 6131, 5719,
+	7260, 5173, 3023, 2502, 115, 6125, 83, 2940, 1839, 1841,
+	7222, 2960, 6908, 2885, 60, 4985, 198, 6130, 7170, 3259,
+	4705, 3026, 5153, 4547, 5863, 4797, 6302, 1641, 4610, 2334,
+	3261, 2976, 4717, 5145, 3247, 2918, 59, 1927, 4770, 5306,
+	113, 3016, 3023, 2367, 1643, 7262, 5716, 4389, 2431, 4772,
+	4791, 2899, 6166, 2958, 2820, 2822, 7147, 5288, 2825, 2826,
+	2982, 2941, 5678, 2882, 4409, 6127, 6909, 6408, 62, 84,
+	7148, 2982, 4864, 1637, 7196, 6964, 6399, 2873, 2878, 6205,
+	63, 7104, 4828, 64, 7305, 4913, 70, 6131, 5155, 2916,
+	2926, 7106, 986, 3025, 91, 2379, 4808, 2477, 2926, 3326,
+	4104, 5012, 61, 7310, 139, 2897, 7108, 2369, 7099, 4117,
+	123, 136, 4140, 1311, 1459, 5501, 6060, 6319, 5870, 2481,
+	85, 6852, 2909, 5871, 6061, 4496, 5966, 1644, 6253, 6071,
+	6853, 5805, 1228, 1227, 1622, 2894, 1622, 2936, 2974, 5967,
+	1316, 5213, 4866, 5621, 1672, 2936, 4883, 4884, 4885, 1670,
+	5447, 4732, 2914, 6159, 5119, 4849, 4850, 6865, 4867, 4868,
+	4869, 65, 1645, 6126, 1863, 4903, 6988, 5154, 6987, 4355,
+	6624, 2973, 2572, 7107, 6168, 6169, 6975, 2484, 2874, 4861,
+	4862, 4863, 4855, 6882, 124, 4556, 4860, 4858, 4859, 4851,
+	4852, 4853, 4854, 4856, 4857, 6059, 5039, 4102, 6880, 2481,
+	2910, 2911, 6668, 2903, 6266, 6252, 6251, 2619, 6239, 5927,
+	5925, 1642, 2932, 1229, 1230, 2968, 5864, 2482, 6136, 6137,
+	2932, 5854, 2322, 2314, 2315, 2316, 2317, 2319, 2320, 5853,
+	5391, 2905, 5159, 5194, 6586, 6162, 4872, 2882, 5037, 5192,
+	2943, 3011, 5015, 6397, 2870, 5891, 5004, 4864, 6398, 2871,
+	4999, 4467, 6126, 2958, 7223, 4361, 2892, 2484, 2989, 7110,
+	2064, 4159, 3089, 3069, 1328, 1329, 1623, 7169, 1623, 4871,
+	2298, 2999, 2625, 2960, 2614, 2474, 86, 2479, 2789, 1669,
+	1659, 946, 2929, 2718, 2906, 3073, 3073, 2810, 6840, 7104,
+	2929, 2969, 6615, 6303, 5541, 2908, 6008, 2482, 5872, 7106,
+	7105, 2297, 6160, 4965, 5157, 3008, 5679, 6136, 6137, 5343,
+	2879, 3007, 2954, 5326, 7108, 4865, 2820, 3012, 2957, 2297,
+	2978, 2977, 2979, 6524, 3017, 2716, 4861, 4862, 4863, 6841,
+	2987, 5272, 2292, 4860, 4858, 4859, 4851, 4852, 4853, 4854,
+	4856, 4857, 2934, 1620, 3187, 2480, 2896, 2681, 6459, 5756,
+	2934, 5193, 6681, 4468, 5125, 4286, 6753, 4855, 5158, 3014,
+	6866, 128, 4892, 2678, 2913, 6660, 2950, 7315, 7102, 7146,
+	5291, 4445, 5928, 5926, 5782, 5292, 5757, 4286, 5698, 5696,
+	2884, 7107, 7111, 66, 2988, 5392, 3009, 2872, 5380, 5121,
+	2883, 4673, 4666, 3010, 4653, 3118, 3111, 3104, 2925, 3097,
+	3070, 4287, 3067, 69, 3057, 2367, 4281, 4534, 2876, 5484,
+	72, 2171, 6400, 2959, 4893, 1312, 1313, 2935, 2483, 6089,
+	87, 4410, 6533, 4287, 3177, 2935, 4440, 1690, 5555, 2296,
+	71, 250, 6934, 131, 5448, 2885, 6163, 135, 2912, 4393,
+	1032, 6698, 6228, 2297, 67, 6885, 5150, 2296, 199, 2813,
+	2674, 4472, 2922, 6346, 2939, 2676, 68, 5930, 4290, 2568,
+	2568, 5968, 2939, 4650, 1700, 6638, 6636, 7110, 961, 2875,
+	316, 963, 963, 2721, 6501, 5569, 5137, 1638, 5133, 75,
+	4290, 5132, 4755, 4733, 4911, 4910, 89, 3148, 4295, 4293,
+	4865, 1552, 2379, 1552, 3143, 4906, 4907, 3055, 2483, 2873,
+	2878, 1330, 1331, 921, 4866, 2719, 197, 1885, 7105, 2677,
+	4295, 4293, 5613, 2298, 6164, 6165, 7109, 2956, 914, 5195,
+	914, 1893, 1892, 2955, 2920, 4470, 6611, 4158, 4157, 4156,
+	5542, 2298, 4155, 4154, 318, 921, 4153, 1981, 2914, 1552,
+	2927, 4461, 5543, 2225, 6009, 6161, 2223, 1981, 2927, 1640,
+	1333, 2937, 2189, 5849, 1457, 6197, 2704, 5755, 4933, 2937,
+	5886, 5887, 6293, 1748, 196, 4908, 4938, 4648, 2933, 5969,
+	2824, 2296, 5884, 5885, 6513, 88, 2933, 6766, 2921, 4415,
+	2367, 1639, 1864, 2575, 256, 5704, 4462, 1981, 4291, 3116,
+	7111, 3115, 317, 1748, 5693, 3178, 4647, 6640, 2906, 2998,
+	2874, 1074, 6867, 5807, 2930, 1748, 2895, 6659, 7193, 2908,
+	4291, 6488, 2930, 4222, 2575, 2928, 6477, 310, 6476, 6475,
+	4615, 4951, 4311, 2928, 2938, 5441, 311, 4292, 7314, 5047,
+	251, 4958, 2938, 2191, 6534, 6535, 255, 6496, 4441, 4442,
+	4998, 1075, 4997, 4414, 4996, 4995, 4979, 4978, 4977, 4292,
+	1552, 5008, 1314, 1315, 2868, 4976, 4722, 254, 4620, 2882,
+	3, 6090, 1552, 4617, 1089, 4219, 3144, 3030, 1828, 5196,
+	2651, 4990, 4955, 4956, 6940, 4471, 1683, 1683, 2913, 4866,
+	5257, 5009, 5011, 6767, 6639, 5233, 6525, 5761, 4861, 4862,
+	4863, 6528, 4918, 6948, 6497, 4860, 4858, 4859, 4851, 4852,
+	4853, 4854, 4856, 4857, 6514, 6527, 4966, 6509, 6508, 2931,
+	4945, 4916, 6093, 1748, 6092, 1748, 5256, 2931, 5558, 6931,
+	6014, 4289, 1089, 3351, 7109, 1865, 2866, 5622, 1955, 6461,
+	5000, 7210, 2879, 1627, 6977, 4633, 4917, 1683, 5028, 2837,
+	1683, 4932, 7200, 4289, 1683, 7195, 1957, 4935, 4936, 7088,
+	5034, 4934, 6166, 6809, 1711, 4229, 4942, 1950, 1916, 1711,
+	4284, 1711, 1911, 4986, 5002, 1777, 5766, 1981, 1089, 1089,
+	1981, 2568, 4961, 5290, 4967, 4968, 4969, 4970, 4971, 4960,
+	2867, 4960, 964, 964, 6941, 4294, 1031, 2881, 4915, 5043,
+	6793, 1909, 5694, 6768, 1878, 1748, 6473, 6415, 1876, 6080,
+	6007, 2575, 2703, 4937, 5021, 1874, 5858, 4294, 4941, 5639,
+	4880, 1871, 1869, 5464, 5442, 5221, 1867, 1857, 1850, 1552,
+	1216, 1219, 4993, 4843, 4721, 2881, 5027, 4775, 4654, 4634,
+	4510, 4649, 1848, 4504, 4430, 4360, 1748, 2224, 4192, 918,
+	2222, 2996, 3476, 3147, 1332, 3138, 3121, 3065, 2857, 2853,
+	2823, 5085, 2914, 2725, 1979, 2609, 4980, 2509, 1748, 2260,
+	1959, 3039, 2800, 4861, 4862, 4863, 1748, 2753, 1830, 2090,
+	4860, 4858, 4859, 4851, 4852, 4853, 4854, 4856, 4857, 1748,
+	1748, 7278, 1921, 6836, 1089, 5861, 4288, 5048, 6605, 6091,
+	4991, 2875, 4881, 5091, 5090, 5010, 5079, 2292, 4981, 4345,
+	4344, 4315, 4277, 3166, 1552, 1552, 3056, 2981, 4288, 2064,
+	5018, 1898, 1981, 5022, 5025, 2760, 2981, 2608, 1470, 2064,
+	5219, 5029, 2606, 2412, 5136, 1748, 4973, 5141, 2274, 5086,
+	1591, 5143, 3350, 7058, 1171, 5373, 6321, 1748, 5234, 5089,
+	5100, 6206, 5769, 5101, 5768, 1281, 5201, 1552, 5206, 5122,
+	5824, 5754, 2839, 6210, 5120, 6183, 4992, 2094, 4335, 2064,
+	4632, 7128, 2090, 2090, 2838, 6930, 6780, 1748, 4922, 1620,
+	5622, 1956, 5088, 6344, 5179, 5481, 6342, 6215, 5180, 4927,
+	5181, 5128, 1949, 1915, 6201, 5172, 7167, 1910, 5065, 6198,
+	6117, 6116, 5398, 2301, 5924, 5171, 5911, 7001, 7162, 7038,
+	1622, 4949, 5168, 5073, 5149, 5785, 1655, 5759, 2151, 5070,
+	5724, 5071, 5722, 5072, 5695, 1622, 1908, 5187, 1655, 1877,
+	5384, 1655, 1484, 1875, 1981, 5191, 1174, 5378, 5366, 1208,
+	1873, 1655, 1655, 4687, 1484, 2072, 1870, 1868, 5199, 5200,
+	1552, 1866, 1856, 1849, 5289, 4222, 4222, 5188, 5092, 5093,
+	5094, 5264, 2568, 5105, 5215, 5104, 4678, 1847, 4670, 5164,
+	4662, 4643, 4640, 1604, 4639, 4630, 4613, 4236, 4231, 3054,
+	3052, 1748, 2244, 3032, 3038, 2799, 5062, 5080, 5064, 2983,
+	2752, 2915, 2900, 2886, 5243, 4923, 2660, 2657, 2259, 2649,
+	5156, 2646, 2641, 2639, 1552, 1920, 5263, 4219, 4219, 2634,
+	2628, 2626, 2624, 2090, 2620, 2615, 5399, 2541, 4951, 6094,
+	5281, 5229, 5177, 5281, 5170, 1655, 4333, 5042, 5040, 4753,
+	7187, 4466, 2682, 1655, 6786, 6765, 5286, 6700, 2302, 4931,
+	4380, 2856, 1623, 1388, 1391, 4606, 5186, 1451, 1280, 2064,
+	5182, 5418, 2064, 5245, 5190, 4921, 4929, 1623, 2992, 7018,
+	4930, 4381, 1552, 4378, 5322, 6873, 5323, 5198, 6478, 1552,
+	1552, 6364, 6699, 1552, 1552, 1552, 6222, 1552, 5296, 5370,
+	5224, 4336, 4337, 5035, 238, 238, 1552, 2575, 5231, 5244,
+	5230, 4718, 4635, 2670, 2671, 1552, 5379, 4545, 1205, 4928,
+	1981, 2854, 2699, 5258, 6903, 6683, 2176, 4416, 1605, 1552,
+	1859, 1858, 4363, 5242, 4389, 6674, 4174, 1981, 4389, 5269,
+	5390, 5945, 5419, 2835, 5287, 2218, 5283, 2575, 2575, 1552,
+	1552, 4387, 1552, 1552, 1552, 4412, 5430, 2895, 4487, 4438,
+	5381, 2153, 1675, 1947, 1948, 2743, 4754, 3114, 1722, 1723,
+	5297, 2793, 2855, 2785, 1552, 5285, 7017, 2750, 1552, 5400,
+	2575, 2575, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552,
+	1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552,
+	1552, 1552, 6174, 1552, 5477, 5393, 5395, 1216, 1219, 5108,
+	5109, 1552, 1552, 2575, 2064, 5298, 5246, 5314, 1552, 6106,
+	1210, 5493, 5327, 5514, 6217, 5515, 6245, 5336, 4555, 5439,
+	1552, 5135, 1735, 5302, 5139, 5316, 5467, 1711, 5371, 1209,
+	5377, 921, 921, 1451, 5449, 1552, 5450, 5376, 1756, 1846,
+	1320, 5284, 4924, 4925, 4926, 7280, 2669, 7091, 6237, 4562,
+	4628, 1799, 5282, 2310, 2311, 2310, 2311, 1063, 4559, 1723,
+	1723, 5178, 5416, 4421, 6708, 6545, 6511, 7181, 6015, 5994,
+	5151, 1981, 5425, 1460, 1552, 1552, 4561, 2563, 5428, 5429,
+	4629, 4954, 5553, 4422, 4443, 4558, 5596, 2313, 2305, 1755,
+	1674, 1796, 5781, 7098, 2220, 1748, 1748, 5804, 349, 5446,
+	5908, 3098, 1767, 4422, 914, 4519, 4517, 4526, 6831, 4508,
+	4426, 4506, 4124, 4424, 1748, 1748, 2064, 3200, 5504, 914,
+	2549, 5780, 1748, 1919, 4560, 4507, 4425, 7134, 4222, 2575,
+	5235, 2575, 5237, 4557, 2312, 5241, 2312, 1066, 1066, 5247,
+	6939, 6916, 6871, 6869, 1080, 6764, 5472, 2221, 6661, 5474,
+	3200, 5520, 5480, 6658, 1552, 5589, 911, 5330, 4625, 6489,
+	4627, 5487, 5489, 5490, 2612, 5496, 6262, 1655, 1655, 5614,
+	5922, 2572, 5910, 1655, 1655, 1655, 1655, 5503, 5890, 5383,
+	4219, 1981, 4698, 5549, 4659, 918, 1748, 5512, 4631, 3471,
+	2666, 5513, 2561, 5003, 7256, 6544, 5005, 5643, 5560, 5644,
+	6510, 2572, 2572, 5545, 5291, 5517, 6703, 5672, 5291, 5292,
+	5519, 5013, 5014, 5292, 5671, 4494, 5017, 918, 3024, 2862,
+	5019, 5020, 2114, 5491, 2113, 5023, 2106, 5024, 4982, 4695,
+	7202, 5026, 4695, 1961, 6231, 1453, 2998, 5592, 5546, 5565,
+	5566, 7313, 4849, 4850, 2310, 2311, 5510, 5291, 2710, 4260,
+	1552, 2125, 5292, 2709, 4259, 7332, 6320, 5562, 5563, 4513,
+	2994, 2124, 1827, 5986, 5348, 2125, 2125, 5624, 1826, 2520,
+	4351, 3381, 2710, 2709, 1918, 6997, 5918, 1917, 6662, 6627,
+	6570, 6456, 2064, 5578, 1552, 1552, 6452, 5577, 5576, 6451,
+	5582, 6219, 6214, 5588, 6213, 6062, 6058, 6057, 5985, 2064,
+	5675, 5623, 5492, 5239, 5236, 5612, 4354, 2406, 2870, 4717,
+	2405, 2283, 2281, 2871, 4960, 1668, 4384, 2864, 7296, 4717,
+	2729, 2730, 2731, 2732, 2733, 7236, 7022, 6920, 6919, 6918,
+	6808, 6732, 6727, 6634, 6558, 6543, 6467, 6460, 6458, 6455,
+	6454, 1552, 1552, 6453, 6448, 5669, 5642, 6447, 2757, 1552,
+	5762, 6314, 6268, 5635, 6073, 6056, 6055, 5957, 5738, 5951,
+	5873, 5720, 5707, 5389, 5142, 5083, 5059, 5058, 1216, 1219,
+	1655, 1655, 5057, 5056, 5016, 5699, 4677, 4641, 4413, 4362,
+	1655, 2552, 4342, 1748, 4304, 4303, 4302, 1655, 1655, 2572,
+	4301, 5758, 5660, 1552, 5760, 4300, 5659, 5763, 5667, 5668,
+	2550, 4282, 4227, 4189, 4188, 5771, 3277, 3112, 3084, 3083,
+	3082, 3081, 3080, 3079, 1655, 3045, 5806, 2840, 2794, 2779,
+	2778, 1748, 2777, 5777, 2776, 5750, 2756, 5680, 2631, 2630,
+	2629, 2627, 2540, 2539, 2184, 2183, 2182, 2181, 5742, 2180,
+	1655, 2179, 2175, 2064, 2884, 2173, 2172, 1552, 2097, 5829,
+	2096, 2872, 1946, 1945, 2883, 5743, 5745, 1879, 5615, 5616,
+	1819, 5666, 1816, 1815, 1814, 1813, 4438, 1812, 1759, 2575,
+	1706, 1705, 2876, 1704, 1703, 1702, 1701, 5629, 5630, 1695,
+	5674, 1694, 1693, 1692, 1691, 5640, 1586, 5783, 5730, 2672,
+	1394, 1383, 6770, 5735, 6132, 1552, 2836, 1620, 1620, 2885,
+	5764, 5765, 3092, 122, 2168, 7000, 4459, 112, 6382, 2575,
+	6381, 5800, 2990, 5717, 5907, 5714, 5713, 2847, 5793, 7352,
+	1655, 7221, 7133, 6998, 7130, 6835, 2535, 7003, 6839, 921,
+	6630, 6837, 5337, 4646, 5939, 1552, 6833, 6996, 5931, 7124,
+	960, 2919, 6278, 921, 1552, 6828, 6991, 5947, 4209, 2621,
+	5851, 5333, 1655, 2064, 5839, 5840, 6626, 1655, 1655, 1655,
+	2923, 6618, 1655, 2873, 2878, 1247, 2880, 1126, 6976, 5879,
+	5835, 5814, 2148, 1261, 6952, 1981, 5144, 4569, 1552, 1552,
+	5834, 1862, 5790, 2761, 1552, 1552, 2575, 4944, 4126, 1552,
+	1552, 4531, 1552, 6907, 5990, 4807, 6716, 6407, 3349, 2410,
+	4891, 5900, 116, 5902, 1552, 1506, 1550, 5844, 6301, 6300,
+	5848, 6118, 5906, 5701, 5351, 6297, 6296, 2565, 2567, 1469,
+	1552, 1984, 3488, 3491, 7032, 2683, 2692, 2436, 3429, 5828,
+	1528, 1527, 1567, 2572, 2572, 1522, 1523, 2569, 1526, 1524,
+	5843, 1525, 2151, 5850, 5832, 5942, 5921, 2429, 1521, 5128,
+	5387, 5913, 5943, 5915, 5917, 5818, 5372, 5958, 5932, 4703,
+	5426, 2230, 1128, 4122, 2874, 5954, 5983, 3271, 3334, 4796,
+	2403, 1486, 5903, 1508, 3330, 1666, 1497, 4919, 5413, 3472,
+	3096, 5579, 921, 3176, 1271, 1090, 4846, 5909, 3337, 1646,
+	921, 5889, 3452, 3445, 1981, 1981, 3441, 5970, 5715, 5833,
+	4691, 5648, 2575, 5407, 2278, 6422, 2381, 3119, 921, 5857,
+	4704, 2467, 1793, 1490, 3269, 5979, 1981, 1622, 6041, 2394,
+	4780, 6039, 3186, 2882, 1655, 1655, 5420, 4947, 2219, 4183,
+	7007, 5591, 3136, 5500, 5912, 6051, 5940, 238, 5963, 4139,
+	5941, 6012, 6047, 4352, 3088, 5948, 5813, 1603, 1981, 3146,
+	5949, 1602, 5933, 5956, 1664, 5955, 1601, 6958, 6955, 2980,
+	1748, 6304, 3149, 5346, 5347, 2572, 2563, 2675, 4253, 3281,
+	5367, 1502, 4320, 4321, 5971, 2089, 2821, 5084, 4904, 5842,
+	5888, 2186, 6049, 6050, 6048, 6518, 1512, 6040, 2366, 6044,
+	5106, 4597, 4596, 4595, 6759, 1778, 2879, 1776, 1775, 1981,
+	6035, 1774, 7343, 4533, 4527, 2572, 2572, 3001, 5710, 5709,
+	5708, 6064, 6065, 1552, 315, 6045, 4747, 2299, 2291, 312,
+	314, 313, 5148, 6037, 921, 5597, 921, 1829, 5822, 5740,
+	29, 1067, 6075, 1068, 1069, 4263, 2702, 1795, 2572, 2572,
+	5651, 6033, 6006, 28, 5107, 27, 26, 25, 145, 1623,
+	30, 53, 33, 1529, 32, 5, 24, 1748, 191, 6144,
+	5041, 4273, 154, 195, 193, 168, 190, 1981, 189, 1748,
+	188, 2572, 158, 1748, 187, 186, 185, 184, 6017, 6018,
+	6113, 2715, 6030, 1979, 6019, 6022, 1817, 183, 6031, 6095,
+	6016, 182, 192, 6023, 6025, 181, 1552, 180, 6021, 1981,
+	175, 6110, 6032, 179, 178, 177, 176, 174, 172, 173,
+	356, 356, 356, 356, 167, 949, 950, 171, 6036, 971,
+	949, 971, 984, 170, 169, 1030, 166, 165, 164, 1050,
+	163, 162, 161, 160, 159, 157, 156, 1060, 1060, 1060,
+	1060, 194, 356, 155, 6081, 6200, 1552, 2064, 6202, 1552,
+	153, 356, 6204, 6063, 257, 2875, 152, 151, 150, 6176,
+	149, 148, 31, 147, 146, 6232, 6172, 6115, 1043, 1044,
+	1655, 6042, 74, 73, 1655, 1655, 142, 143, 1307, 6043,
+	23, 51, 82, 81, 6096, 356, 80, 4222, 1552, 1552,
+	18, 78, 79, 918, 918, 1620, 2572, 2572, 22, 2572,
+	6167, 6098, 921, 17, 6109, 46, 5646, 119, 134, 1620,
+	5647, 6020, 133, 132, 47, 129, 6182, 5309, 6192, 6154,
+	5312, 45, 6152, 6151, 6288, 21, 20, 19, 6191, 1748,
+	217, 127, 6194, 6177, 4705, 6305, 126, 6247, 125, 4219,
+	6221, 44, 6046, 42, 15, 1981, 12, 4717, 48, 1631,
+	2497, 2568, 1655, 16, 7, 121, 248, 1655, 1655, 1552,
+	247, 249, 6195, 246, 243, 242, 2064, 2064, 245, 241,
+	6347, 1711, 6269, 244, 118, 2090, 2090, 240, 120, 239,
+	117, 2568, 2568, 6261, 40, 13, 229, 4688, 2064, 6067,
+	6068, 6069, 6070, 5895, 105, 1552, 1552, 1552, 6212, 6612,
+	5281, 914, 6980, 6076, 6077, 6078, 6079, 5324, 114, 6082,
+	1981, 6233, 6256, 38, 235, 1552, 6259, 234, 1552, 1552,
+	2064, 6241, 5440, 6086, 6326, 233, 6246, 5723, 1552, 5725,
+	5900, 2575, 5902, 232, 6181, 1552, 1552, 6318, 231, 6255,
+	6254, 230, 110, 109, 228, 227, 226, 6190, 1620, 215,
+	6145, 6193, 6329, 237, 6332, 1552, 1620, 103, 225, 6285,
+	1655, 108, 1655, 1655, 949, 949, 6290, 107, 224, 6299,
+	104, 2064, 356, 1655, 4949, 6178, 6179, 236, 6295, 106,
+	6328, 6317, 111, 6315, 37, 1484, 9, 77, 6325, 6395,
+	6348, 5443, 137, 138, 6035, 6307, 49, 101, 100, 99,
+	98, 1748, 36, 76, 35, 308, 309, 307, 6244, 6393,
+	2090, 306, 304, 4279, 4280, 6401, 6351, 305, 6355, 303,
+	6350, 302, 1552, 1552, 210, 5784, 6361, 6349, 282, 281,
+	280, 279, 278, 277, 276, 275, 274, 269, 273, 2064,
+	271, 270, 1981, 272, 6340, 268, 298, 297, 296, 295,
+	1552, 294, 293, 292, 291, 285, 284, 290, 289, 288,
+	6417, 287, 6394, 1552, 286, 283, 301, 223, 222, 2568,
+	221, 2064, 218, 2090, 220, 219, 94, 6410, 1552, 6411,
+	267, 266, 265, 263, 259, 262, 264, 261, 260, 6495,
+	258, 300, 2575, 299, 216, 214, 6482, 6483, 2820, 213,
+	95, 6107, 6108, 208, 1552, 209, 6434, 1552, 6428, 6429,
+	93, 2563, 207, 206, 205, 204, 6291, 6436, 203, 6437,
+	202, 1484, 201, 92, 4364, 212, 3203, 6431, 1552, 6432,
+	6433, 1552, 6563, 211, 34, 6175, 2, 2572, 1981, 1,
+	0, 0, 0, 1622, 1655, 1552, 0, 1655, 1655, 0,
+	1552, 1552, 6492, 0, 6493, 0, 0, 1552, 0, 1552,
+	1552, 1552, 0, 0, 0, 0, 0, 6521, 0, 0,
+	1748, 0, 0, 0, 0, 1622, 0, 2572, 0, 0,
+	6485, 6484, 0, 0, 6560, 0, 0, 1552, 6491, 6481,
+	0, 0, 6494, 0, 0, 6557, 0, 0, 6218, 0,
+	6220, 6500, 1655, 0, 0, 0, 0, 6609, 0, 6536,
+	6537, 6539, 6540, 6541, 2881, 0, 0, 2064, 0, 0,
+	6547, 0, 3203, 0, 0, 0, 0, 921, 0, 921,
+	0, 921, 6575, 6629, 0, 0, 0, 0, 0, 6167,
+	0, 0, 0, 0, 0, 0, 0, 5658, 0, 0,
+	0, 6616, 5661, 5662, 2572, 0, 2575, 0, 6555, 0,
+	6642, 0, 6644, 1981, 6646, 1981, 6653, 0, 1655, 6637,
+	6633, 0, 6546, 0, 0, 1623, 5325, 6559, 0, 6604,
+	0, 0, 2064, 0, 0, 4532, 6675, 6565, 6572, 6294,
+	0, 918, 6564, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 918, 0, 1623, 0, 0,
+	0, 0, 6592, 2568, 2568, 0, 0, 0, 1089, 6596,
+	0, 0, 0, 6607, 6606, 0, 0, 0, 6608, 6595,
+	5160, 5161, 0, 5162, 0, 0, 1552, 2575, 0, 0,
+	6628, 6617, 6625, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 5900, 0, 5902, 0, 6635, 0, 0,
+	0, 0, 0, 0, 6472, 0, 0, 6657, 0, 0,
+	2572, 0, 0, 0, 0, 0, 0, 6652, 0, 6654,
+	0, 0, 0, 1748, 1748, 1748, 1748, 0, 0, 1748,
+	1748, 1748, 1748, 6663, 1748, 1748, 6686, 3125, 6688, 6665,
+	0, 0, 0, 0, 6677, 0, 6676, 1552, 1655, 0,
+	0, 6680, 5225, 5226, 2064, 5227, 6685, 6680, 6684, 0,
+	0, 0, 6590, 1552, 0, 1552, 6754, 1552, 0, 6087,
+	0, 0, 0, 6088, 0, 0, 4724, 921, 0, 0,
+	6701, 0, 0, 0, 918, 2568, 0, 0, 6594, 6614,
+	5792, 0, 918, 1552, 0, 1479, 0, 0, 6707, 5808,
+	0, 0, 6670, 6752, 6672, 0, 6714, 0, 0, 921,
+	918, 0, 4777, 4778, 6747, 0, 0, 0, 0, 1484,
+	0, 0, 6726, 0, 0, 2568, 2568, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 6788, 0, 1655, 0, 0, 0, 0, 1552,
+	2064, 0, 0, 0, 1552, 0, 0, 2563, 2568, 2568,
+	0, 0, 0, 0, 0, 0, 0, 914, 0, 0,
+	0, 1552, 0, 0, 0, 0, 1552, 0, 6751, 2575,
+	6750, 0, 0, 0, 0, 1552, 0, 0, 0, 0,
+	0, 2568, 0, 6774, 6812, 0, 6648, 6787, 0, 914,
+	0, 0, 6775, 6844, 921, 0, 921, 0, 921, 0,
+	0, 0, 0, 0, 6825, 0, 0, 0, 0, 0,
+	0, 6842, 6870, 0, 0, 6784, 918, 921, 918, 6785,
+	921, 6856, 921, 0, 0, 0, 1655, 6858, 0, 6860,
+	0, 6862, 6682, 0, 0, 1648, 0, 6829, 1655, 0,
+	6797, 0, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 0,
+	6877, 971, 0, 6879, 0, 6881, 0, 0, 6799, 1552,
+	1552, 1552, 0, 0, 0, 2064, 971, 2064, 0, 0,
+	1552, 5964, 1676, 356, 356, 1687, 6827, 0, 6815, 0,
+	0, 0, 1697, 6816, 6810, 2572, 4873, 4874, 4875, 4876,
+	0, 0, 356, 0, 356, 356, 0, 1727, 356, 6745,
+	1742, 6855, 0, 0, 0, 0, 2568, 2568, 0, 2568,
+	0, 0, 0, 1757, 0, 0, 0, 0, 5900, 0,
+	5902, 1050, 6875, 0, 1050, 6318, 0, 0, 0, 0,
+	6887, 0, 6947, 6911, 0, 0, 0, 0, 6892, 0,
+	6894, 6888, 1552, 1552, 0, 6893, 6891, 1552, 6890, 6904,
+	1060, 0, 1655, 0, 6921, 6922, 6923, 6924, 1748, 5348,
+	1748, 6912, 6913, 6917, 6886, 0, 0, 3181, 0, 0,
+	0, 0, 0, 0, 0, 0, 6728, 6729, 6730, 6731,
+	0, 6995, 6733, 6734, 6735, 6736, 0, 6737, 6738, 6957,
+	6960, 0, 6971, 0, 918, 0, 6929, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 6806, 6937, 6938, 0,
+	6965, 0, 0, 6990, 7006, 0, 6961, 0, 6945, 6993,
+	0, 6966, 0, 0, 7010, 356, 6950, 6951, 6826, 2572,
+	6946, 6962, 0, 4219, 0, 0, 0, 7011, 0, 0,
+	6967, 0, 0, 0, 0, 0, 7037, 0, 0, 0,
+	0, 0, 0, 1655, 0, 7035, 0, 0, 0, 1552,
+	1552, 1552, 356, 0, 356, 356, 356, 356, 1727, 6989,
+	356, 356, 0, 0, 7013, 2098, 7015, 7002, 0, 0,
+	0, 1742, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 356, 0, 2127, 0, 0,
+	0, 0, 0, 0, 1552, 1089, 7019, 7036, 7073, 0,
+	0, 7023, 7026, 0, 0, 2146, 0, 0, 0, 0,
+	0, 0, 0, 3447, 0, 0, 0, 0, 0, 2160,
+	2162, 0, 0, 0, 7080, 1655, 1655, 1655, 1655, 1552,
+	0, 7097, 0, 0, 2575, 0, 2188, 0, 1742, 7054,
+	1552, 7053, 0, 356, 356, 0, 1727, 7051, 7052, 7075,
+	0, 0, 0, 0, 0, 7120, 0, 0, 7142, 0,
+	7144, 2881, 0, 0, 0, 0, 0, 0, 6905, 7140,
+	6906, 1622, 1622, 0, 0, 7100, 1050, 0, 356, 356,
+	2572, 7112, 7141, 6549, 6550, 7153, 0, 7155, 1552, 7094,
+	2256, 7119, 7159, 7127, 0, 7151, 1748, 1748, 1748, 238,
+	7113, 2262, 7123, 6, 7180, 0, 1307, 11, 7076, 14,
+	7168, 0, 7150, 7149, 10, 7139, 8, 6633, 7126, 7143,
+	7188, 7145, 7096, 0, 6571, 7191, 6573, 7161, 6574, 0,
+	7160, 6925, 6926, 6927, 0, 0, 0, 2568, 2820, 0,
+	7174, 7175, 0, 0, 0, 7179, 0, 7205, 0, 7184,
+	7182, 0, 0, 0, 0, 0, 0, 356, 7203, 0,
+	0, 7190, 0, 6995, 0, 0, 7192, 7194, 0, 6260,
+	7199, 0, 6957, 3125, 0, 6960, 0, 2568, 0, 7201,
+	0, 0, 7225, 0, 7227, 0, 0, 0, 7231, 7230,
+	7233, 7232, 7165, 921, 0, 921, 7218, 921, 7217, 7229,
+	7219, 6993, 0, 1623, 1623, 1484, 0, 0, 7247, 7239,
+	0, 6973, 7238, 6974, 7226, 4219, 7224, 0, 7237, 0,
+	0, 0, 0, 0, 0, 0, 7240, 0, 7242, 0,
+	7244, 0, 0, 0, 7248, 0, 0, 0, 1552, 1552,
+	0, 1748, 0, 0, 2572, 7228, 0, 0, 0, 1655,
+	1655, 0, 0, 1655, 2568, 1655, 1655, 7264, 7241, 7263,
+	7243, 0, 921, 7271, 0, 4849, 4850, 0, 4867, 4868,
+	4869, 7272, 0, 7286, 7285, 7274, 0, 7273, 7293, 0,
+	7295, 0, 0, 7283, 0, 7284, 7300, 0, 7302, 0,
+	0, 7118, 0, 7294, 0, 0, 0, 1552, 1552, 7297,
+	0, 0, 0, 0, 7308, 7306, 1552, 1552, 7074, 918,
+	0, 918, 0, 918, 0, 0, 0, 0, 1655, 7311,
+	7316, 0, 0, 0, 0, 2572, 0, 7323, 0, 0,
+	0, 0, 7330, 7329, 7287, 0, 0, 0, 0, 0,
+	0, 0, 0, 7336, 7298, 0, 7328, 7338, 0, 7340,
+	0, 7335, 0, 0, 7333, 7348, 7334, 4864, 7346, 7339,
+	7347, 7341, 0, 0, 0, 7345, 0, 949, 1981, 7337,
+	2568, 0, 0, 0, 0, 0, 7009, 7359, 0, 0,
+	7317, 7318, 0, 7360, 0, 0, 1748, 356, 0, 356,
+	7358, 7374, 0, 356, 7372, 7361, 1089, 7371, 0, 7362,
+	0, 7364, 0, 0, 2127, 0, 0, 0, 7381, 5914,
+	7382, 1727, 1742, 356, 356, 7384, 356, 2538, 1981, 0,
+	7378, 7379, 0, 0, 0, 7387, 1552, 7386, 7388, 7389,
+	0, 0, 7391, 356, 7393, 971, 0, 7397, 0, 7396,
+	7374, 7400, 0, 356, 7363, 0, 7365, 0, 0, 7394,
+	7395, 0, 7357, 0, 7399, 914, 914, 0, 0, 7176,
+	7177, 7178, 0, 0, 0, 0, 7380, 4855, 5965, 0,
+	0, 0, 0, 0, 2632, 7383, 0, 0, 0, 0,
+	0, 0, 0, 6798, 0, 0, 356, 0, 0, 0,
+	0, 6377, 0, 0, 0, 356, 0, 2310, 2311, 0,
+	7392, 0, 7357, 0, 0, 0, 0, 6369, 0, 0,
+	0, 0, 0, 2820, 0, 0, 0, 6386, 6387, 918,
+	0, 2341, 0, 0, 0, 0, 0, 2572, 0, 0,
+	0, 2313, 0, 0, 1050, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 7370, 6581, 6582, 1089, 0,
+	0, 918, 0, 0, 4871, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 2370, 0, 1622,
+	0, 0, 1060, 0, 1060, 0, 0, 0, 2312, 0,
+	0, 0, 0, 1622, 1060, 1060, 0, 0, 0, 0,
+	0, 1737, 0, 0, 0, 0, 0, 0, 0, 0,
+	4865, 0, 0, 0, 7270, 0, 6380, 0, 0, 0,
+	0, 0, 0, 1050, 0, 0, 6265, 0, 0, 0,
+	0, 356, 0, 0, 0, 0, 0, 0, 0, 6371,
+	2755, 0, 0, 0, 0, 0, 0, 0, 356, 0,
+	356, 0, 356, 0, 356, 6370, 918, 356, 918, 356,
+	918, 356, 0, 0, 0, 2568, 0, 0, 0, 0,
+	949, 0, 0, 0, 0, 0, 0, 0, 0, 918,
+	0, 7009, 918, 0, 918, 0, 0, 0, 0, 2805,
+	0, 0, 2806, 0, 2807, 0, 2808, 0, 0, 2809,
+	2367, 0, 0, 0, 356, 5601, 0, 0, 0, 2318,
+	0, 1623, 0, 0, 0, 0, 356, 356, 356, 356,
+	6379, 0, 356, 356, 2827, 1623, 0, 0, 0, 0,
+	0, 0, 1622, 0, 0, 0, 0, 0, 0, 0,
+	1622, 1737, 0, 0, 0, 4737, 0, 0, 0, 0,
+	2064, 0, 0, 0, 0, 0, 0, 0, 1622, 0,
+	0, 0, 0, 0, 0, 0, 6367, 0, 0, 0,
+	5602, 0, 2340, 2346, 0, 0, 0, 0, 0, 0,
+	1737, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 4705, 0, 0, 0, 5603, 4866,
+	2064, 5600, 0, 0, 0, 0, 0, 0, 0, 2568,
+	6208, 0, 0, 0, 0, 5611, 0, 6746, 0, 0,
+	0, 0, 5609, 0, 0, 0, 0, 0, 0, 0,
+	1737, 0, 0, 3447, 3447, 0, 0, 0, 0, 0,
+	0, 0, 2333, 0, 0, 0, 0, 0, 6388, 0,
+	4705, 0, 0, 0, 0, 0, 0, 0, 0, 5610,
+	0, 0, 0, 0, 1623, 0, 0, 0, 0, 5606,
+	2090, 0, 1623, 0, 1622, 0, 1622, 0, 0, 0,
+	0, 0, 0, 0, 0, 7090, 0, 6383, 0, 0,
+	1623, 0, 7095, 0, 0, 5607, 0, 0, 0, 356,
+	0, 0, 0, 356, 0, 0, 0, 0, 0, 0,
+	0, 0, 2572, 0, 0, 6378, 6372, 6373, 6374, 6375,
+	6376, 0, 0, 0, 0, 0, 6313, 0, 0, 0,
+	0, 0, 2367, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 6327, 0, 0, 356,
+	356, 3076, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 914, 6391, 6389, 0, 0, 0, 356,
+	2568, 0, 0, 0, 0, 0, 0, 914, 0, 0,
+	356, 0, 6360, 4861, 4862, 4863, 0, 356, 0, 0,
+	4860, 4858, 4859, 4851, 4852, 4853, 4854, 4856, 4857, 0,
+	0, 6385, 0, 0, 0, 6280, 1623, 0, 1623, 0,
+	0, 0, 949, 0, 356, 0, 0, 3447, 3447, 3447,
+	3447, 6384, 6896, 0, 5294, 6899, 1050, 0, 0, 0,
+	1307, 2334, 0, 0, 0, 0, 6390, 6392, 0, 2926,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 5320,
+	5321, 5604, 1622, 0, 0, 0, 0, 1507, 141, 5605,
+	1727, 356, 0, 0, 0, 0, 1030, 0, 0, 0,
+	0, 1050, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 2936, 0, 0, 0,
+	0, 2392, 0, 0, 0, 2397, 0, 0, 0, 0,
+	0, 5460, 5461, 0, 0, 0, 0, 0, 0, 2369,
+	0, 0, 0, 0, 0, 0, 914, 0, 0, 0,
+	0, 0, 5608, 0, 914, 0, 0, 6479, 0, 0,
+	0, 6968, 0, 5432, 2568, 0, 0, 0, 0, 0,
+	0, 0, 914, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	6377, 2932, 0, 0, 0, 918, 0, 918, 0, 918,
+	3283, 0, 0, 0, 0, 0, 6369, 0, 0, 0,
+	0, 141, 0, 0, 1623, 0, 6386, 6387, 7321, 5521,
+	5522, 5523, 5524, 5525, 5526, 5527, 5528, 5529, 5530, 5531,
+	5532, 5533, 5534, 5535, 5536, 5537, 5538, 5539, 5540, 0,
+	5544, 0, 0, 0, 0, 2568, 0, 0, 96, 0,
+	0, 0, 0, 0, 0, 2314, 2315, 2316, 2317, 2319,
+	2320, 2929, 6280, 0, 918, 0, 0, 0, 0, 0,
+	97, 0, 0, 0, 0, 0, 949, 0, 0, 3473,
+	0, 0, 0, 0, 0, 0, 0, 0, 914, 0,
+	914, 0, 102, 356, 0, 0, 2926, 0, 0, 0,
+	0, 0, 949, 0, 115, 6380, 0, 0, 356, 0,
+	949, 0, 6281, 0, 0, 0, 0, 0, 0, 0,
+	0, 2934, 356, 0, 0, 0, 1436, 0, 6371, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	113, 0, 1461, 2936, 6370, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 356, 1742,
+	0, 0, 0, 0, 0, 356, 0, 356, 2127, 0,
+	356, 356, 0, 0, 0, 0, 1089, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 1300, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 2935, 0, 0, 0,
+	0, 0, 0, 0, 139, 0, 1612, 0, 0, 6379,
+	123, 136, 0, 0, 0, 0, 356, 1742, 2932, 356,
+	971, 0, 971, 0, 0, 0, 0, 0, 356, 4206,
+	0, 356, 0, 2939, 356, 0, 0, 0, 356, 356,
+	4225, 0, 4226, 0, 0, 0, 0, 2568, 356, 356,
+	0, 0, 0, 356, 0, 356, 0, 0, 0, 0,
+	1727, 0, 356, 356, 0, 0, 914, 0, 0, 0,
+	1742, 1742, 4244, 0, 0, 0, 0, 356, 0, 0,
+	0, 0, 0, 0, 124, 0, 0, 0, 2929, 0,
+	0, 0, 0, 0, 0, 5657, 0, 0, 0, 0,
+	0, 0, 0, 5663, 5664, 0, 0, 1622, 0, 1622,
+	0, 1622, 0, 0, 0, 0, 0, 0, 0, 2927,
+	0, 1060, 1060, 0, 0, 1060, 1060, 0, 0, 96,
+	2937, 0, 0, 0, 356, 0, 0, 6388, 0, 6281,
+	0, 0, 0, 0, 0, 0, 0, 2933, 2934, 0,
+	0, 97, 0, 0, 0, 0, 0, 4462, 0, 0,
+	0, 356, 1727, 356, 0, 0, 0, 0, 0, 0,
+	0, 58, 0, 102, 0, 0, 6383, 4322, 356, 1737,
+	0, 0, 1727, 2930, 1727, 115, 1727, 0, 0, 0,
+	0, 0, 0, 0, 2928, 60, 0, 0, 0, 0,
+	0, 0, 0, 2938, 6378, 6372, 6373, 6374, 6375, 6376,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 113, 0, 2935, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 6795, 0, 0, 6282, 356, 0, 1623,
+	4180, 1623, 0, 1623, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 6391, 6389, 356, 356, 356, 356, 1727,
+	2939, 128, 0, 0, 64, 0, 0, 1300, 0, 1727,
+	0, 0, 356, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 61, 4402, 139, 0, 0, 2931, 0,
+	6385, 123, 136, 0, 6283, 0, 0, 0, 5791, 0,
+	356, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	6384, 0, 0, 0, 356, 5815, 5816, 1622, 0, 0,
+	0, 0, 0, 0, 6872, 6390, 6392, 6874, 0, 356,
+	0, 250, 0, 131, 0, 0, 0, 135, 0, 0,
+	0, 0, 5830, 0, 0, 0, 6276, 0, 0, 1622,
+	0, 0, 4475, 0, 0, 0, 0, 2937, 0, 0,
+	0, 0, 0, 0, 1050, 124, 0, 0, 5852, 1050,
+	316, 0, 0, 0, 2933, 0, 0, 0, 0, 1302,
+	0, 0, 0, 0, 4462, 0, 1301, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 356, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	2930, 0, 0, 356, 0, 0, 0, 0, 0, 4542,
+	2127, 2928, 2568, 0, 0, 0, 0, 0, 0, 0,
+	2938, 0, 0, 0, 318, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 1622, 0, 1622, 0, 1622, 1623,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 356, 4622, 6282, 196, 0, 0, 1622, 0, 0,
+	1622, 0, 1622, 0, 0, 0, 356, 0, 1727, 0,
+	5953, 1623, 0, 356, 256, 4279, 5959, 5960, 0, 0,
+	0, 914, 317, 914, 0, 914, 0, 0, 2310, 2311,
+	0, 0, 0, 2127, 0, 0, 356, 7211, 0, 4542,
+	0, 0, 0, 0, 0, 2931, 356, 310, 0, 0,
+	0, 6283, 2341, 0, 0, 0, 311, 4682, 0, 2342,
+	251, 0, 2313, 0, 0, 7020, 255, 7021, 0, 0,
+	0, 4402, 128, 949, 0, 0, 0, 0, 0, 0,
+	0, 0, 1307, 4402, 0, 0, 0, 254, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 2370, 0,
+	356, 0, 0, 0, 0, 0, 1623, 0, 1623, 2312,
+	1623, 0, 0, 0, 0, 0, 0, 96, 0, 0,
+	2332, 0, 0, 0, 0, 3275, 0, 0, 0, 1623,
+	2329, 356, 1623, 0, 1623, 0, 2344, 0, 0, 97,
+	356, 2392, 250, 0, 131, 0, 0, 0, 135, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 102, 0, 141, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 115, 0, 0, 0, 0, 0, 0,
+	2343, 316, 6053, 6054, 0, 0, 0, 0, 0, 0,
+	1302, 0, 0, 0, 0, 0, 5974, 1301, 0, 0,
+	1737, 0, 0, 0, 0, 0, 0, 1737, 0, 113,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	2335, 2336, 2337, 2338, 0, 0, 0, 0, 0, 0,
+	2318, 914, 0, 0, 0, 0, 0, 141, 0, 0,
+	0, 0, 0, 2310, 2311, 318, 2347, 2348, 2349, 2358,
+	2359, 2360, 0, 0, 0, 1300, 7351, 0, 0, 0,
+	0, 0, 0, 914, 0, 0, 2351, 2341, 0, 0,
+	2127, 0, 0, 139, 2342, 196, 0, 2313, 0, 123,
+	136, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	2364, 0, 0, 2340, 2346, 256, 0, 0, 0, 0,
+	0, 0, 0, 317, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 2370, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 2312, 0, 2327, 2328, 310, 0,
+	0, 0, 0, 0, 0, 2332, 0, 311, 0, 0,
+	141, 251, 0, 0, 0, 2329, 0, 255, 0, 0,
+	0, 2344, 0, 124, 0, 0, 0, 0, 914, 0,
+	914, 0, 914, 2333, 0, 0, 0, 0, 254, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 914, 0, 0, 914, 0, 914, 0, 0, 0,
+	0, 0, 2345, 0, 0, 2343, 0, 0, 1737, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	356, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 6263, 6264, 0, 2335, 2336, 2337, 2338, 0,
+	0, 0, 0, 0, 141, 2318, 141, 0, 141, 0,
+	0, 0, 0, 2367, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 1622, 0, 1622, 0, 1622, 0, 0,
+	0, 0, 3447, 3447, 2355, 0, 0, 0, 0, 2365,
+	0, 0, 0, 0, 0, 6414, 0, 0, 2340, 2346,
+	1461, 141, 141, 0, 0, 6352, 6353, 0, 0, 0,
+	0, 0, 2339, 0, 0, 0, 0, 0, 0, 0,
+	128, 141, 2361, 141, 2362, 0, 0, 0, 0, 0,
+	0, 2327, 2328, 0, 0, 0, 0, 141, 0, 141,
+	0, 0, 2334, 0, 0, 0, 0, 0, 0, 0,
+	0, 2353, 3421, 3422, 3423, 3424, 3417, 3418, 3419, 3420,
+	0, 0, 0, 0, 0, 0, 0, 0, 2333, 0,
+	3447, 3447, 3447, 3447, 3447, 3447, 3447, 3447, 3447, 3447,
+	3447, 3447, 3447, 3447, 3447, 3447, 3447, 3447, 3447, 3447,
+	250, 3447, 131, 0, 0, 1737, 135, 2345, 0, 0,
+	0, 0, 0, 0, 0, 1623, 0, 1623, 6440, 1623,
+	6445, 6446, 0, 0, 0, 0, 0, 6503, 0, 0,
+	2369, 6457, 0, 0, 0, 2363, 0, 0, 0, 316,
+	0, 0, 0, 0, 0, 0, 0, 0, 1302, 0,
+	0, 0, 0, 0, 0, 1301, 0, 2352, 0, 0,
+	3397, 3398, 3399, 3400, 0, 0, 0, 0, 2367, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 1436, 0, 0, 0, 0, 0, 0, 3409, 3410,
+	3411, 3412, 3405, 3406, 3407, 3408, 3413, 3414, 3415, 3416,
+	0, 0, 0, 318, 0, 2384, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 2390, 0, 0, 0, 2396, 0, 0,
+	0, 0, 0, 196, 0, 0, 0, 2339, 0, 0,
+	2330, 2326, 0, 2323, 2321, 2322, 2314, 2315, 2316, 2317,
+	2319, 2320, 0, 256, 0, 0, 0, 0, 0, 0,
+	0, 317, 0, 0, 0, 0, 0, 2334, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 3393, 3394, 3395, 3396, 0, 310, 3401, 3402, 3403,
+	3404, 0, 0, 0, 0, 311, 0, 0, 0, 251,
+	0, 2356, 6577, 0, 0, 255, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 2310, 2311, 0, 254, 0, 0, 0,
+	0, 2490, 0, 2492, 0, 141, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 2369, 0, 2341, 0, 0,
+	0, 0, 0, 0, 2342, 0, 0, 2313, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 914, 0, 914,
+	0, 914, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 2370, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 2312, 0, 0, 0, 0, 0,
+	0, 0, 0, 6713, 0, 2332, 0, 0, 0, 0,
+	0, 0, 1737, 0, 0, 2329, 0, 0, 0, 0,
+	0, 2344, 0, 0, 0, 0, 0, 0, 2354, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 2324, 2325, 2331, 2357, 2330, 2326, 0, 2323, 2321,
+	2322, 2314, 2315, 2316, 2317, 2319, 2320, 0, 0, 0,
+	0, 0, 4820, 0, 0, 2343, 4821, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 5463, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 6758, 0, 0, 0, 0, 0, 0, 0,
+	1737, 1737, 0, 0, 0, 2335, 2336, 2337, 2338, 0,
+	0, 0, 0, 0, 0, 2318, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 356, 0, 0, 0,
+	0, 949, 0, 0, 0, 0, 949, 0, 0, 949,
+	0, 0, 949, 949, 0, 0, 0, 949, 0, 0,
+	949, 0, 0, 0, 0, 4600, 0, 0, 356, 0,
+	4587, 0, 0, 0, 0, 0, 0, 0, 2340, 2346,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 356, 0, 0, 0, 0, 0, 0,
+	141, 0, 0, 0, 0, 356, 0, 0, 2127, 4577,
+	4575, 2327, 2328, 0, 0, 0, 0, 0, 4579, 4581,
+	4571, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 971, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 2333, 0,
+	0, 0, 6800, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 356, 0, 0, 4602, 356,
+	356, 0, 0, 0, 0, 0, 0, 2345, 0, 0,
+	0, 0, 0, 0, 1737, 1737, 1737, 1737, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 2367, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	5068, 0, 0, 0, 0, 0, 4279, 0, 0, 0,
+	6895, 0, 6897, 6898, 0, 6900, 6901, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	5076, 0, 5077, 5078, 0, 0, 0, 2127, 0, 0,
+	0, 0, 0, 0, 356, 356, 0, 0, 0, 0,
+	0, 1727, 356, 0, 356, 0, 0, 2339, 0, 0,
+	0, 0, 1727, 0, 0, 1727, 0, 0, 0, 0,
+	4402, 4402, 356, 0, 5114, 5117, 0, 0, 0, 0,
+	0, 4402, 0, 2538, 0, 0, 0, 2334, 4573, 0,
+	0, 0, 4402, 2538, 0, 4402, 2538, 0, 0, 4589,
+	2538, 0, 0, 5114, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 356, 356, 5117, 0,
+	356, 0, 0, 0, 0, 0, 0, 4601, 4588, 4578,
+	4576, 4580, 4582, 4572, 0, 4574, 4590, 4599, 4592, 0,
+	5117, 0, 356, 0, 0, 0, 0, 5189, 5117, 4584,
+	4586, 4594, 0, 0, 0, 0, 0, 0, 0, 0,
+	5197, 5117, 0, 0, 5203, 2369, 5203, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 1727, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 4603, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 1461, 0, 1461,
+	0, 4402, 0, 4402, 0, 5240, 4402, 5117, 0, 0,
+	4402, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 7041, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 1050, 0, 0, 1050, 0, 0, 0, 0, 5117,
+	0, 0, 1050, 0, 0, 0, 4598, 0, 1436, 0,
+	0, 1436, 1436, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 2330, 2326, 0, 2323, 2321,
+	2322, 2314, 2315, 2316, 2317, 2319, 2320, 0, 0, 0,
+	1727, 0, 0, 0, 0, 0, 0, 356, 0, 0,
+	96, 0, 0, 7114, 7115, 7116, 7117, 0, 0, 0,
+	0, 0, 356, 0, 0, 0, 0, 0, 0, 925,
+	356, 0, 97, 3268, 5328, 0, 0, 5331, 0, 0,
+	0, 4591, 0, 0, 5344, 4402, 0, 0, 356, 0,
+	0, 0, 58, 1461, 102, 0, 1742, 0, 0, 4605,
+	0, 0, 0, 2390, 0, 0, 115, 2390, 0, 5388,
+	0, 0, 356, 0, 0, 0, 60, 4682, 4682, 0,
+	0, 1727, 0, 0, 0, 0, 357, 357, 0, 357,
+	4402, 0, 949, 0, 0, 0, 0, 0, 0, 0,
+	4402, 0, 113, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 357, 0,
+	0, 0, 0, 0, 0, 0, 4604, 357, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 4583, 4585,
+	0, 0, 4593, 0, 0, 64, 0, 1612, 1300, 356,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 357, 2492, 0, 61, 0, 139, 0, 0, 0,
+	0, 0, 123, 136, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 3447, 0, 0, 0,
+	0, 0, 0, 2310, 2311, 0, 2347, 2348, 2349, 2358,
+	2359, 2360, 5498, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 2351, 2341, 0, 0,
+	0, 0, 0, 0, 2342, 0, 0, 2313, 0, 141,
+	0, 0, 0, 0, 0, 0, 0, 7275, 7276, 0,
+	2364, 7279, 0, 7281, 7282, 0, 124, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 2370, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 2312, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 2332, 0, 0, 0, 5556,
+	0, 0, 0, 0, 0, 2329, 0, 0, 0, 0,
+	0, 2344, 0, 0, 356, 356, 7325, 0, 3447, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 949, 0, 0, 5581, 949, 0, 0, 0, 0,
+	0, 0, 0, 949, 0, 2343, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 2335, 2336, 2337, 2338, 0,
+	0, 0, 0, 356, 0, 2318, 0, 0, 356, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 356,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 128, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 356, 0,
+	0, 0, 0, 0, 2355, 0, 0, 0, 0, 2365,
+	0, 0, 0, 141, 141, 5117, 0, 0, 2340, 2346,
+	0, 0, 0, 4244, 0, 0, 0, 0, 0, 0,
+	0, 0, 2310, 2311, 0, 0, 0, 0, 0, 0,
+	0, 0, 2361, 0, 2362, 0, 0, 0, 0, 0,
+	0, 2327, 2328, 250, 0, 131, 2341, 0, 0, 135,
+	0, 0, 0, 2342, 0, 0, 2313, 0, 0, 0,
+	0, 2353, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 2333, 0,
+	0, 0, 316, 0, 0, 1618, 0, 0, 0, 0,
+	0, 1302, 2370, 0, 0, 0, 0, 0, 1301, 0,
+	0, 0, 0, 2312, 0, 0, 0, 2345, 0, 1050,
+	0, 0, 0, 0, 2332, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 2329, 0, 0, 0, 0, 0,
+	2344, 0, 0, 0, 0, 2363, 0, 0, 0, 0,
+	0, 0, 351, 351, 3447, 944, 318, 0, 0, 5203,
+	0, 0, 5203, 0, 0, 5203, 0, 2352, 0, 0,
+	0, 0, 0, 5203, 0, 0, 0, 0, 2367, 0,
+	0, 0, 0, 0, 2343, 0, 196, 0, 0, 356,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	5458, 0, 0, 0, 0, 0, 256, 0, 0, 0,
+	0, 0, 0, 0, 317, 0, 0, 0, 0, 4542,
+	0, 0, 0, 0, 2335, 2336, 2337, 2338, 0, 0,
+	0, 0, 0, 0, 2318, 0, 0, 0, 0, 310,
+	0, 0, 0, 3447, 0, 0, 0, 2339, 311, 0,
+	0, 0, 251, 5117, 0, 356, 0, 0, 255, 971,
+	971, 1742, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 2334, 0, 2241,
+	141, 0, 141, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 2340, 2346, 0,
+	0, 0, 1737, 0, 0, 0, 0, 0, 356, 0,
+	5882, 2356, 0, 0, 4682, 2538, 0, 0, 0, 0,
+	356, 0, 0, 0, 0, 0, 0, 5905, 0, 4542,
+	2327, 2328, 356, 0, 0, 0, 356, 0, 356, 0,
+	0, 0, 0, 0, 0, 356, 0, 0, 0, 0,
+	0, 141, 0, 0, 141, 2369, 0, 0, 0, 0,
+	141, 0, 356, 0, 0, 0, 0, 2333, 0, 0,
+	0, 0, 0, 0, 0, 4402, 356, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 1307, 4402, 0,
+	0, 0, 0, 0, 0, 1737, 2345, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 2354, 0,
+	0, 5991, 0, 0, 0, 0, 0, 2367, 0, 0,
+	0, 2324, 2325, 2331, 2357, 2330, 2326, 0, 2323, 2321,
+	2322, 2314, 2315, 2316, 2317, 2319, 2320, 3268, 0, 0,
+	0, 0, 3324, 0, 0, 0, 3325, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 2390, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 356, 0, 0, 0, 1737,
+	1737, 2127, 0, 356, 0, 0, 2339, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 356, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 1658, 0, 2334, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 1742, 1742, 1742, 1742, 0, 0, 0, 0, 357,
+	357, 0, 0, 0, 0, 1742, 1742, 1742, 1742, 0,
+	356, 1742, 0, 0, 0, 0, 0, 0, 357, 0,
+	357, 357, 0, 0, 357, 0, 0, 1737, 1737, 1737,
+	1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737,
+	1737, 1737, 1737, 1737, 1737, 1737, 1737, 0, 1737, 0,
+	0, 0, 0, 0, 2369, 0, 0, 0, 0, 0,
+	0, 0, 4402, 4402, 0, 5114, 0, 0, 5203, 4402,
+	0, 0, 0, 0, 0, 0, 0, 6143, 0, 6143,
+	2127, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 4402, 0, 2538, 0,
+	0, 0, 5114, 0, 0, 2127, 2127, 356, 5117, 1658,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 5117, 0, 356, 1612, 5117, 0, 356, 6196, 0,
+	0, 0, 0, 5203, 3268, 0, 5203, 0, 0, 0,
+	5203, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 357, 0, 0, 0, 0, 0, 0, 0, 4402,
+	0, 4402, 356, 0, 2330, 2326, 0, 2323, 2321, 2322,
+	2314, 2315, 2316, 2317, 2319, 2320, 0, 0, 0, 4542,
+	0, 0, 0, 6235, 0, 0, 0, 0, 357, 1658,
+	357, 357, 357, 357, 0, 0, 357, 357, 1658, 0,
+	0, 1050, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 357, 0, 0, 0, 0, 0, 0, 0, 0,
+	356, 0, 0, 0, 0, 0, 0, 0, 356, 0,
+	0, 0, 0, 0, 356, 0, 2127, 0, 0, 1658,
+	4402, 4402, 0, 0, 0, 6143, 0, 4682, 0, 6309,
+	0, 6311, 0, 0, 0, 0, 0, 5114, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 357,
+	357, 0, 0, 0, 0, 356, 0, 0, 0, 0,
+	0, 0, 0, 0, 6335, 96, 0, 0, 0, 356,
+	0, 356, 1658, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 1658, 357, 357, 0, 97, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 1658,
+	0, 0, 0, 0, 0, 0, 0, 58, 0, 102,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 115, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 60, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 2310, 2311, 0, 2347, 2348, 2349,
+	2358, 2359, 2360, 0, 0, 0, 0, 113, 0, 0,
+	0, 0, 0, 357, 0, 0, 0, 2351, 2341, 0,
+	0, 0, 0, 5581, 0, 2342, 0, 0, 2313, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 2364, 0, 0, 0, 0, 0, 0, 0, 0,
+	64, 0, 0, 1300, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 2370, 0, 0, 0, 1737, 61,
+	0, 139, 0, 0, 0, 2312, 0, 123, 136, 0,
+	0, 0, 0, 0, 0, 0, 2332, 0, 0, 0,
+	0, 0, 0, 356, 356, 0, 2329, 0, 0, 0,
+	0, 0, 2344, 0, 0, 0, 0, 0, 0, 0,
+	4402, 2538, 0, 2538, 0, 0, 5905, 0, 0, 0,
+	0, 0, 1737, 0, 0, 356, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 6519, 0, 6519, 0, 0,
+	0, 0, 0, 0, 0, 0, 2343, 0, 0, 0,
+	0, 124, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 1050,
+	0, 0, 0, 0, 0, 0, 2335, 2336, 2337, 2338,
+	0, 0, 5203, 5203, 0, 0, 2318, 5203, 1553, 1727,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 5117, 0, 356, 2355, 0, 0, 0, 357,
+	2365, 0, 0, 0, 0, 1658, 0, 924, 1658, 2340,
+	2346, 0, 0, 0, 0, 0, 0, 0, 0, 357,
+	357, 357, 357, 0, 0, 0, 0, 1931, 0, 0,
+	0, 0, 0, 2361, 0, 2362, 0, 0, 0, 357,
+	0, 0, 2327, 2328, 0, 0, 5905, 0, 0, 357,
+	6143, 0, 6143, 0, 6143, 1658, 2127, 0, 0, 0,
+	4402, 0, 2353, 0, 1976, 0, 0, 0, 0, 0,
+	0, 0, 2088, 0, 0, 0, 0, 0, 128, 2333,
+	0, 5388, 0, 6667, 0, 0, 0, 0, 0, 0,
+	0, 0, 357, 0, 0, 0, 0, 0, 0, 0,
+	0, 357, 2127, 0, 0, 0, 0, 0, 2345, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	1612, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 2363, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 250, 0,
+	131, 0, 0, 0, 135, 0, 0, 0, 2352, 0,
+	0, 0, 0, 0, 5498, 0, 0, 0, 0, 2367,
+	0, 0, 0, 0, 1658, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 316, 0, 0,
+	2245, 2246, 0, 0, 0, 0, 1302, 0, 0, 0,
+	0, 0, 0, 1301, 0, 0, 0, 0, 1658, 0,
+	0, 1658, 1658, 1658, 1658, 1658, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 357, 0, 0,
+	0, 0, 5203, 6749, 0, 0, 0, 0, 2339, 1658,
+	5905, 0, 0, 0, 357, 0, 357, 0, 357, 0,
+	357, 318, 0, 357, 0, 357, 0, 357, 0, 0,
+	6143, 0, 0, 0, 0, 0, 0, 924, 2334, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 196, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 6143, 0, 0, 0, 0, 0, 0, 0,
+	357, 256, 2356, 0, 0, 0, 0, 0, 0, 317,
+	0, 0, 357, 357, 357, 357, 0, 0, 357, 357,
+	356, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 310, 0, 0, 0, 0, 0,
+	0, 0, 0, 311, 0, 0, 2369, 251, 0, 971,
+	0, 0, 0, 255, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 1737, 0, 0, 2239, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 6143, 0, 6143,
+	0, 6143, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	6143, 0, 356, 6143, 0, 6143, 0, 0, 0, 0,
+	0, 1177, 0, 0, 0, 0, 0, 2538, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 2354,
+	0, 0, 141, 141, 0, 141, 0, 1190, 2127, 0,
+	2127, 0, 2324, 2325, 2331, 2357, 2330, 2326, 0, 2323,
+	2321, 2322, 2314, 2315, 2316, 2317, 2319, 2320, 0, 0,
+	0, 1188, 0, 0, 0, 0, 0, 5997, 0, 0,
+	0, 0, 0, 1742, 1742, 1742, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 357, 0, 1658, 0, 357,
+	0, 1193, 0, 0, 6935, 2507, 0, 0, 1658, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	6519, 0, 0, 356, 141, 141, 2533, 141, 2088, 0,
+	0, 0, 0, 1658, 0, 0, 0, 0, 5203, 0,
+	0, 0, 0, 0, 0, 357, 357, 0, 0, 0,
+	0, 0, 0, 1737, 0, 0, 0, 0, 0, 1184,
+	0, 0, 0, 0, 0, 357, 1202, 0, 0, 0,
+	0, 1658, 0, 0, 0, 0, 357, 0, 0, 0,
+	0, 0, 0, 357, 0, 1189, 0, 4402, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 1658, 0,
+	0, 0, 0, 0, 0, 0, 0, 2088, 0, 0,
+	357, 0, 0, 0, 0, 0, 0, 0, 0, 1658,
+	0, 1658, 0, 1658, 356, 0, 356, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	1658, 1241, 0, 0, 0, 0, 0, 0, 1182, 0,
+	0, 0, 0, 1658, 0, 0, 0, 357, 0, 5498,
+	0, 0, 1248, 0, 0, 0, 1025, 1249, 0, 0,
+	0, 0, 0, 0, 0, 1737, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 2127, 0,
+	0, 0, 1658, 0, 0, 0, 0, 1186, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 1461, 0, 0, 0, 0, 1250,
+	0, 1263, 0, 1192, 0, 0, 0, 0, 0, 141,
+	141, 0, 0, 2746, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	1251, 0, 2767, 0, 2769, 1252, 2771, 0, 0, 2773,
+	0, 2774, 0, 2775, 0, 0, 0, 1201, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 1272,
+	0, 0, 0, 0, 0, 1737, 1253, 0, 0, 1658,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 5905, 0, 0, 1270, 2811, 0, 0, 0,
+	0, 0, 1737, 0, 0, 0, 0, 0, 2817, 2818,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 1245, 1240, 0, 0, 0, 0, 0,
+	0, 0, 0, 4542, 0, 0, 0, 0, 0, 0,
+	0, 356, 0, 0, 0, 0, 0, 0, 0, 1179,
+	0, 0, 1254, 0, 0, 0, 1658, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 1191, 949, 0, 0,
+	1274, 0, 4402, 0, 0, 0, 1025, 0, 357, 0,
+	1658, 0, 1183, 0, 0, 0, 6143, 0, 6143, 1185,
+	6143, 0, 0, 5203, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 924, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 357, 0, 0, 0, 1612, 1612,
+	0, 357, 0, 357, 0, 0, 357, 357, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 1024, 4542, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 1737, 0, 1197, 0, 356, 0, 0, 0, 0,
+	0, 0, 1181, 0, 0, 1273, 0, 0, 0, 0,
+	1242, 1243, 357, 0, 0, 357, 0, 1268, 0, 0,
+	0, 0, 0, 0, 357, 4402, 0, 357, 0, 0,
+	357, 0, 1658, 0, 357, 357, 0, 0, 0, 0,
+	0, 0, 0, 0, 357, 357, 0, 0, 0, 357,
+	0, 357, 0, 0, 0, 0, 0, 0, 357, 357,
+	0, 0, 1737, 0, 0, 1178, 0, 0, 0, 0,
+	0, 1022, 0, 357, 0, 0, 0, 0, 924, 0,
+	1737, 4402, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 1267, 0, 0, 1187, 0, 0,
+	356, 3086, 0, 0, 0, 1255, 0, 0, 0, 0,
+	1658, 0, 0, 0, 0, 0, 1026, 0, 0, 3108,
+	0, 0, 0, 0, 0, 0, 1246, 0, 0, 1180,
+	357, 0, 0, 0, 1658, 1658, 1658, 1196, 0, 0,
+	0, 0, 0, 5203, 0, 1256, 3131, 2310, 2311, 0,
+	2347, 2348, 2349, 2358, 2359, 2360, 0, 357, 924, 357,
+	0, 0, 1199, 1200, 5203, 1195, 0, 924, 0, 1737,
+	2351, 2341, 0, 0, 357, 0, 0, 0, 2342, 0,
+	0, 2313, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 1737, 0, 3153, 2364, 0, 0, 1024, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	1239, 0, 0, 1264, 0, 0, 0, 2370, 924, 0,
+	0, 0, 0, 0, 0, 1257, 0, 0, 2312, 0,
+	0, 0, 0, 357, 0, 0, 0, 0, 0, 2332,
+	0, 0, 0, 0, 0, 1658, 0, 0, 0, 2329,
+	0, 357, 357, 357, 357, 2344, 0, 0, 0, 0,
+	1262, 0, 0, 0, 0, 0, 0, 0, 357, 0,
+	0, 924, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 924, 1258, 0, 0, 0, 1259, 1277, 0,
+	1276, 1022, 0, 0, 0, 1260, 357, 0, 924, 2343,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	357, 0, 0, 0, 0, 0, 0, 1269, 0, 0,
+	0, 0, 0, 0, 1278, 357, 0, 1275, 0, 0,
+	0, 0, 0, 0, 0, 0, 1026, 0, 0, 2335,
+	2336, 2337, 2338, 0, 0, 0, 0, 0, 0, 2318,
+	0, 0, 0, 0, 0, 0, 0, 1023, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 357, 1658, 0, 0, 0, 2355, 0,
+	0, 0, 0, 2365, 0, 0, 1658, 0, 0, 357,
+	0, 0, 2340, 2346, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 4133, 0, 0, 0, 0, 0,
+	0, 141, 0, 0, 0, 0, 2361, 0, 2362, 0,
+	0, 0, 0, 0, 0, 2327, 2328, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 1612, 357, 0, 0,
+	0, 0, 0, 0, 0, 2353, 0, 0, 0, 0,
+	1612, 0, 357, 0, 0, 0, 0, 0, 0, 357,
+	0, 0, 2333, 0, 0, 0, 0, 0, 0, 0,
+	141, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 357, 0, 0, 0, 0, 0, 0, 0,
+	0, 2345, 357, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	4205, 0, 0, 0, 0, 0, 0, 0, 0, 2363,
+	0, 4224, 0, 1658, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 1658, 0, 0, 1658, 0, 0,
+	0, 2352, 0, 0, 1737, 0, 357, 0, 0, 0,
+	0, 0, 2367, 0, 0, 0, 0, 0, 0, 3108,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 924, 0, 924, 0, 0, 357, 0, 0,
+	0, 0, 141, 0, 924, 0, 357, 924, 0, 1612,
+	0, 0, 0, 0, 0, 0, 0, 1612, 0, 0,
+	0, 0, 0, 0, 0, 2310, 2311, 0, 2347, 2348,
+	2349, 2358, 2359, 2360, 0, 0, 4276, 0, 0, 0,
+	0, 2339, 0, 0, 0, 0, 2576, 0, 2351, 2341,
+	0, 0, 0, 0, 924, 0, 2342, 0, 0, 2313,
+	0, 0, 0, 4306, 0, 4309, 0, 0, 0, 0,
+	0, 2334, 2364, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 2370, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 2356, 2312, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 2332, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 2329, 0, 0,
+	0, 0, 0, 2344, 0, 0, 0, 0, 0, 4359,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 2369,
+	0, 0, 0, 0, 0, 0, 0, 4371, 2088, 2088,
+	4374, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 924, 4382, 0, 0, 2343, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 924, 0, 0,
+	924, 924, 924, 924, 924, 0, 0, 2335, 2336, 2337,
+	2338, 0, 141, 0, 0, 0, 0, 2318, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 924, 0,
+	0, 0, 2354, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 2324, 2325, 2331, 2357, 2330,
+	2326, 0, 2323, 2321, 2322, 2314, 2315, 2316, 2317, 2319,
+	2320, 0, 0, 0, 0, 0, 2355, 0, 0, 0,
+	5471, 2365, 0, 0, 0, 0, 0, 0, 0, 0,
+	2340, 2346, 0, 0, 0, 0, 0, 1658, 0, 2088,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 2361, 4535, 2362, 0, 0, 0,
+	0, 0, 0, 2327, 2328, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 141, 0,
+	0, 0, 0, 2353, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 141, 0,
+	2333, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 4642, 0, 0, 0, 2345,
+	0, 0, 0, 0, 141, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 4658, 0,
+	0, 0, 0, 0, 0, 0, 0, 2363, 3108, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 2352,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	2367, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 924, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 924, 0, 0,
+	0, 0, 4756, 0, 0, 0, 0, 0, 0, 2339,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 924, 0, 0, 0, 0, 0, 0, 141,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 2334,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	924, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 2356, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 924, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 924, 0,
+	924, 0, 924, 0, 0, 0, 0, 2369, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 924,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 924, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 2310,
+	2311, 0, 2347, 2348, 2349, 2358, 2359, 2360, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 2576,
+	2576, 924, 2351, 2341, 0, 0, 0, 0, 0, 0,
+	2342, 0, 0, 2313, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 2364, 0, 0, 0,
+	2354, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 2324, 2325, 2331, 2357, 2330, 2326, 2370,
+	2323, 2321, 2322, 2314, 2315, 2316, 2317, 2319, 2320, 0,
+	2312, 0, 0, 0, 0, 0, 0, 0, 4823, 0,
+	0, 2332, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 2329, 0, 0, 0, 0, 0, 2344, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 924, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 2310, 2311,
+	0, 2347, 2348, 2349, 2358, 2359, 2360, 0, 0, 0,
+	3268, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 2343, 2341, 0, 0, 0, 0, 0, 0, 2342,
+	0, 0, 2313, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 2364, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 924, 0,
+	0, 2335, 2336, 2337, 2338, 924, 0, 0, 2370, 0,
+	0, 2318, 0, 924, 0, 0, 0, 0, 0, 2312,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 924,
+	2332, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	2329, 0, 0, 0, 0, 0, 2344, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	2355, 0, 0, 0, 0, 2365, 0, 0, 0, 0,
+	0, 0, 0, 0, 2340, 2346, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 1658, 0, 0, 0,
+	2343, 0, 0, 0, 0, 0, 1658, 0, 2361, 0,
+	2362, 0, 0, 0, 0, 0, 0, 2327, 2328, 357,
+	0, 0, 0, 0, 0, 0, 0, 0, 361, 0,
+	0, 357, 0, 0, 0, 0, 0, 2353, 0, 0,
+	2335, 2336, 2337, 2338, 0, 0, 1658, 0, 0, 0,
+	2318, 0, 0, 0, 2333, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 141, 0, 0, 0, 0,
+	0, 0, 1658, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 2345, 0, 0, 0, 0, 0, 0,
+	0, 357, 0, 0, 0, 357, 357, 0, 0, 2355,
+	0, 0, 0, 0, 2365, 0, 0, 0, 0, 0,
+	0, 2363, 0, 2340, 2346, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 1207, 0, 0, 924,
+	0, 0, 0, 2352, 0, 0, 0, 2361, 0, 2362,
+	0, 0, 0, 0, 2367, 0, 2327, 2328, 0, 0,
+	0, 0, 0, 924, 924, 924, 141, 0, 0, 141,
+	1207, 0, 0, 0, 0, 0, 2353, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 2333, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 2345, 2339, 0, 0, 0, 0, 0, 0,
+	357, 357, 0, 0, 0, 0, 1658, 0, 357, 1658,
+	357, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	2363, 0, 0, 2334, 0, 0, 0, 0, 357, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 924, 0, 0, 0, 0, 0,
+	0, 0, 0, 2367, 0, 0, 0, 2356, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 357, 357, 0, 0, 357, 0, 0, 0,
+	0, 0, 0, 357, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 357, 0,
+	0, 2369, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 2576, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 2339, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 141, 0, 141,
+	0, 1658, 2334, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 2356, 0, 0, 0,
+	0, 0, 0, 924, 2354, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 924, 0, 2324, 2325, 2331,
+	2357, 2330, 2326, 0, 2323, 2321, 2322, 2314, 2315, 2316,
+	2317, 2319, 2320, 0, 0, 0, 0, 0, 0, 0,
+	2369, 0, 4822, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 1658, 0, 0, 0, 0,
+	0, 0, 0, 357, 0, 0, 0, 1658, 0, 0,
+	1658, 0, 0, 1658, 0, 0, 0, 0, 357, 0,
+	1658, 1658, 0, 0, 141, 0, 357, 0, 0, 0,
+	0, 0, 0, 0, 1658, 1658, 0, 0, 0, 0,
+	0, 0, 0, 0, 357, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 4972, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 357, 0,
+	0, 0, 0, 2354, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 2324, 2325, 2331, 2357,
+	2330, 2326, 924, 2323, 2321, 2322, 2314, 2315, 2316, 2317,
+	2319, 2320, 0, 924, 1658, 0, 924, 0, 0, 0,
+	0, 0, 1658, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 2088, 2088, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 357, 0, 0, 0, 0,
+	0, 0, 0, 2310, 2311, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 2341, 0, 1658,
+	0, 0, 0, 0, 2342, 0, 0, 2313, 0, 0,
+	0, 0, 0, 0, 0, 0, 1658, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 2310, 2311, 0, 2347,
+	2348, 2349, 2358, 2359, 2360, 0, 0, 0, 0, 0,
+	0, 0, 0, 2370, 0, 0, 0, 0, 0, 2351,
+	2341, 0, 0, 0, 2312, 0, 0, 2342, 0, 0,
+	2313, 0, 0, 0, 0, 2332, 0, 0, 0, 0,
+	0, 0, 0, 2364, 0, 2329, 5081, 5082, 0, 0,
+	0, 2344, 0, 0, 5087, 0, 2088, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 2370, 0, 0, 0,
+	0, 0, 0, 0, 5110, 0, 0, 2312, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 2332, 0,
+	0, 0, 0, 0, 0, 2343, 0, 0, 2329, 0,
+	0, 0, 0, 0, 2344, 0, 0, 0, 0, 0,
+	0, 5457, 0, 0, 0, 0, 0, 0, 5167, 5169,
+	0, 0, 3108, 0, 0, 0, 0, 0, 0, 0,
+	1658, 0, 0, 0, 0, 2335, 2336, 2337, 2338, 0,
+	0, 0, 0, 0, 0, 2318, 0, 0, 2343, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 357,
+	0, 0, 0, 0, 357, 0, 0, 1658, 2335, 2336,
+	2337, 2338, 0, 0, 0, 357, 0, 0, 2318, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 2340, 2346,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 357, 924, 1658, 1658, 0, 0,
+	0, 0, 1658, 1658, 1658, 1658, 924, 0, 0, 0,
+	1658, 2327, 2328, 0, 0, 0, 0, 2355, 0, 0,
+	0, 0, 2365, 0, 0, 0, 0, 0, 0, 0,
+	0, 2340, 2346, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 2333, 0,
+	0, 0, 0, 0, 0, 2361, 0, 2362, 0, 0,
+	0, 0, 0, 0, 2327, 2328, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 2345, 0, 0,
+	0, 0, 0, 1656, 2353, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 2333, 0, 0, 0, 0, 0, 0, 0, 0,
+	5368, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	2345, 0, 0, 0, 0, 0, 0, 0, 2367, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 1476, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 2363, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	2352, 0, 0, 0, 0, 357, 0, 0, 0, 0,
+	0, 2367, 0, 0, 0, 0, 0, 0, 0, 1658,
+	1658, 0, 0, 0, 0, 0, 0, 2339, 0, 1658,
+	0, 5453, 0, 0, 0, 0, 1658, 1658, 1656, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 2334, 0, 0,
+	0, 0, 0, 1658, 0, 0, 0, 0, 2310, 2311,
+	0, 357, 0, 0, 0, 0, 0, 0, 0, 0,
+	2339, 0, 0, 0, 0, 0, 0, 0, 0, 1658,
+	0, 0, 2341, 0, 0, 0, 0, 0, 0, 2342,
+	0, 0, 2313, 0, 0, 0, 0, 0, 0, 0,
+	2334, 0, 0, 0, 0, 0, 0, 0, 1982, 0,
+	0, 0, 0, 0, 357, 0, 0, 1656, 0, 0,
+	0, 0, 0, 0, 0, 2369, 357, 0, 2370, 0,
+	0, 0, 0, 0, 2356, 0, 0, 0, 357, 2312,
+	0, 0, 357, 0, 357, 0, 0, 0, 0, 0,
+	2332, 357, 0, 0, 0, 0, 0, 0, 0, 1658,
+	2329, 0, 0, 0, 0, 0, 2344, 0, 1656, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 2369, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 1658, 0, 0, 0, 0, 1658, 1658, 1658, 0,
+	0, 1658, 0, 0, 0, 0, 0, 0, 0, 0,
+	2343, 0, 0, 0, 1658, 0, 0, 0, 0, 0,
+	0, 1656, 0, 0, 0, 0, 4766, 0, 0, 0,
+	0, 0, 1656, 0, 0, 2330, 2326, 0, 2323, 2321,
+	2322, 2314, 2315, 2316, 2317, 2319, 2320, 0, 1656, 0,
+	2335, 2336, 2337, 2338, 0, 0, 0, 0, 0, 0,
+	2318, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	5641, 2354, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 5645, 0, 0, 2324, 2325, 2331, 2357, 2330, 2326,
+	0, 2323, 2321, 2322, 2314, 2315, 2316, 2317, 2319, 2320,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 4819,
+	5656, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 2340, 2346, 0, 0, 0, 0, 0,
+	0, 0, 0, 1658, 1658, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 1658, 2327, 2328, 0, 0,
+	0, 0, 0, 1658, 1658, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 2310, 2311,
+	0, 0, 0, 0, 0, 0, 0, 1658, 0, 0,
+	0, 0, 0, 2333, 0, 0, 357, 0, 0, 0,
+	0, 0, 2341, 0, 0, 0, 0, 0, 0, 2342,
+	0, 0, 2313, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 2345, 0, 0, 0, 0, 0, 0, 0,
+	0, 924, 0, 0, 0, 0, 0, 0, 1658, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 2370, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 2312,
+	0, 0, 0, 924, 0, 924, 0, 0, 0, 0,
+	2332, 0, 0, 0, 0, 924, 0, 0, 0, 0,
+	2329, 0, 0, 2367, 0, 0, 2344, 0, 0, 0,
+	0, 0, 0, 357, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 1658, 0, 0, 357,
+	0, 2576, 0, 357, 0, 924, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	2343, 0, 0, 0, 0, 0, 0, 0, 1658, 0,
+	0, 0, 2576, 0, 0, 0, 4759, 0, 357, 0,
+	0, 0, 2339, 0, 1982, 0, 0, 1982, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 3108, 0, 0,
+	2335, 2336, 2337, 2338, 0, 0, 0, 0, 0, 0,
+	2318, 0, 2334, 0, 0, 0, 0, 0, 2548, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 2548, 0,
+	0, 0, 0, 0, 1656, 0, 0, 0, 0, 1658,
+	0, 0, 0, 1658, 1658, 0, 357, 0, 0, 0,
+	5880, 0, 0, 0, 357, 0, 1658, 0, 0, 0,
+	357, 0, 5894, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 2340, 2346, 0, 0, 0, 3108, 0,
+	3108, 0, 0, 0, 0, 0, 0, 5923, 0, 0,
+	2369, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 357, 0, 0, 0, 0, 2327, 2328, 0, 0,
+	0, 0, 0, 0, 1658, 357, 0, 357, 0, 0,
+	0, 1658, 0, 0, 0, 924, 1658, 1658, 924, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 2333, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 1982, 0, 0, 0, 0, 0, 2576,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 2345, 0, 0, 0, 0, 0, 0, 1658,
+	0, 0, 0, 0, 0, 0, 0, 1656, 0, 0,
+	1656, 1656, 1656, 1656, 1656, 0, 0, 0, 0, 0,
+	2330, 2326, 0, 2323, 2321, 2322, 2314, 2315, 2316, 2317,
+	2319, 2320, 0, 0, 0, 0, 0, 0, 1656, 0,
+	0, 0, 0, 2548, 0, 0, 0, 0, 0, 1658,
+	0, 1658, 1658, 2367, 0, 0, 0, 0, 0, 0,
+	0, 0, 1658, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	924, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 357,
+	357, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 2339, 0, 0, 0, 0, 0, 0, 0,
+	0, 1658, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 357, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 2334, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 924, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 924, 0, 0, 924,
+	0, 0, 924, 0, 0, 0, 0, 0, 0, 924,
+	924, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 1658, 0, 0,
+	2369, 0, 0, 1658, 0, 0, 1658, 1658, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 6180,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	357, 0, 0, 0, 0, 3108, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 1658, 0, 924, 0, 0, 1656, 0, 0, 0,
+	0, 924, 0, 0, 0, 0, 0, 1982, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 1656, 0, 0, 0, 0, 0, 0, 0,
+	2330, 2326, 0, 2323, 2321, 2322, 2314, 2315, 2316, 2317,
+	2319, 2320, 1658, 0, 1658, 2576, 0, 1658, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 924, 0,
+	1656, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	6275, 0, 0, 0, 0, 924, 6289, 0, 0, 0,
+	0, 0, 0, 0, 0, 2576, 2576, 1656, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 1656, 0,
+	1656, 0, 1656, 0, 0, 0, 0, 3108, 2576, 2576,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 1656,
+	0, 6341, 0, 6343, 0, 0, 0, 0, 0, 0,
+	0, 0, 1656, 0, 0, 0, 0, 0, 0, 0,
+	0, 2576, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 924,
+	924, 1982, 0, 0, 0, 0, 0, 1658, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 924,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 2310, 2311, 0, 2347, 2348, 2349, 2358,
+	2359, 2360, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 2351, 2341, 0, 0,
+	0, 0, 0, 0, 2342, 0, 0, 2313, 0, 0,
+	0, 0, 0, 0, 0, 0, 357, 2576, 1982, 2576,
+	2364, 0, 0, 1658, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 2370, 0, 6480, 2088, 0, 0, 0,
+	0, 0, 0, 0, 2312, 924, 924, 0, 0, 0,
+	0, 924, 924, 924, 924, 2332, 0, 0, 0, 924,
+	0, 0, 0, 0, 0, 2329, 0, 6505, 0, 0,
+	0, 2344, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 1982, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 2350, 357, 0,
+	0, 0, 0, 0, 0, 1658, 0, 0, 0, 1982,
+	0, 0, 0, 0, 0, 2343, 0, 1658, 0, 0,
+	0, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 2335, 2336, 2337, 2338, 0,
+	0, 0, 0, 0, 0, 2318, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 3108, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 357,
+	0, 0, 0, 0, 2355, 0, 0, 0, 0, 2365,
+	0, 0, 0, 0, 0, 0, 0, 0, 2340, 2346,
+	0, 1658, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 924, 924,
+	0, 0, 2361, 0, 2362, 0, 0, 0, 924, 0,
+	1658, 2327, 2328, 0, 0, 924, 924, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 2353, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 924, 0, 0, 0, 0, 0, 2333, 1982,
+	0, 0, 0, 0, 0, 1007, 0, 0, 0, 0,
+	357, 0, 357, 0, 0, 0, 0, 0, 924, 0,
+	0, 0, 0, 1656, 1656, 1656, 992, 2345, 0, 0,
+	0, 993, 1658, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 2576, 0, 0,
+	0, 0, 0, 0, 0, 2363, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 2352, 0, 0,
+	2350, 0, 0, 994, 0, 0, 0, 2576, 2367, 0,
+	0, 0, 0, 0, 0, 0, 995, 0, 924, 0,
+	0, 0, 0, 0, 0, 0, 0, 924, 0, 0,
+	0, 0, 0, 0, 1658, 1658, 1658, 1658, 0, 996,
+	0, 924, 0, 0, 0, 0, 0, 0, 0, 0,
+	924, 0, 0, 0, 1656, 924, 924, 924, 0, 0,
+	924, 0, 0, 1013, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 924, 0, 0, 0, 2339, 0, 0,
+	0, 0, 0, 0, 2576, 0, 0, 0, 0, 997,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 2334, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 998, 987, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 2356, 0, 2350, 0, 0, 999, 0, 0, 2350,
+	0, 0, 989, 0, 0, 0, 0, 357, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	1025, 0, 1658, 0, 0, 0, 0, 0, 0, 0,
+	924, 0, 0, 0, 0, 2369, 0, 0, 924, 0,
+	0, 0, 924, 924, 0, 0, 0, 0, 0, 0,
+	2576, 1012, 0, 1982, 0, 0, 924, 0, 0, 0,
+	0, 0, 0, 0, 924, 1656, 0, 0, 0, 0,
+	0, 0, 924, 924, 6878, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 924, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 1658, 1658,
+	0, 0, 1658, 0, 1658, 1658, 0, 0, 0, 0,
+	0, 1009, 0, 0, 0, 0, 0, 0, 2354, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 2324, 2325, 2331, 2357, 2330, 2326, 924, 2323, 2321,
+	2322, 2314, 2315, 2316, 2317, 2319, 2320, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 4818, 0, 0, 0,
+	0, 0, 924, 0, 924, 0, 0, 1658, 0, 2350,
+	0, 0, 0, 0, 0, 6949, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 2350,
+	0, 2350, 1656, 0, 0, 0, 0, 1020, 0, 1001,
+	0, 0, 0, 1656, 0, 924, 1656, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 357, 1658, 2350, 0,
+	988, 0, 0, 2350, 0, 0, 0, 0, 0, 2350,
+	0, 0, 0, 0, 0, 1021, 990, 924, 0, 1002,
+	2310, 2311, 0, 2347, 2348, 2349, 2358, 2359, 2360, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 2351, 2341, 0, 0, 1658, 0, 0,
+	0, 2342, 0, 0, 2313, 0, 7028, 0, 7030, 0,
+	0, 0, 0, 0, 0, 0, 0, 2364, 0, 0,
+	0, 1024, 0, 0, 0, 0, 0, 0, 0, 1003,
+	0, 0, 0, 0, 1018, 1019, 0, 1016, 924, 0,
+	2370, 0, 924, 924, 0, 0, 1010, 0, 0, 1004,
+	0, 2312, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 2332, 0, 0, 0, 2350, 0, 0, 0,
+	924, 2350, 2329, 0, 0, 0, 0, 0, 2344, 0,
+	0, 0, 0, 2350, 0, 0, 0, 0, 2350, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 1005, 0, 1011,
+	0, 0, 0, 924, 0, 1022, 0, 0, 0, 1006,
+	924, 0, 2343, 0, 0, 924, 924, 0, 0, 0,
+	0, 0, 0, 0, 0, 991, 0, 0, 0, 0,
+	0, 1014, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	1026, 0, 2335, 2336, 2337, 2338, 0, 0, 0, 0,
+	0, 0, 2318, 1008, 0, 0, 0, 0, 924, 0,
+	0, 1023, 0, 0, 0, 0, 0, 0, 0, 0,
+	2350, 2350, 2350, 2350, 2350, 2350, 2350, 2350, 0, 2576,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	2350, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 2355, 0, 2350, 0, 0, 2365, 0, 924, 0,
+	924, 924, 0, 0, 0, 2340, 2346, 0, 0, 0,
+	0, 924, 0, 0, 0, 0, 0, 2310, 2311, 0,
+	2347, 2348, 2349, 2358, 2359, 2360, 0, 0, 0, 2361,
+	0, 2362, 0, 0, 0, 0, 0, 0, 2327, 2328,
+	0, 2341, 0, 3451, 0, 0, 1982, 0, 2342, 0,
+	0, 2313, 0, 0, 0, 0, 0, 0, 2353, 2350,
+	0, 0, 0, 0, 2364, 2350, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 2333, 0, 0, 0, 0,
+	924, 0, 0, 1516, 0, 0, 0, 2370, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 2312, 0,
+	0, 0, 0, 0, 2345, 0, 0, 0, 0, 2332,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 2329,
+	0, 0, 0, 0, 0, 2344, 0, 0, 0, 0,
+	2576, 0, 2363, 0, 0, 0, 0, 0, 0, 0,
+	355, 355, 923, 355, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 2352, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 2367, 0, 0, 0, 2343,
+	0, 0, 355, 0, 0, 0, 924, 0, 0, 0,
+	0, 1217, 924, 0, 0, 924, 924, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 2335,
+	2336, 2337, 2338, 0, 0, 1217, 0, 0, 0, 2318,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 2339, 0, 0, 0, 0, 0,
+	924, 0, 2350, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 2334, 924, 0, 924, 2355, 924,
+	0, 0, 0, 2365, 0, 0, 0, 0, 0, 0,
+	0, 0, 2340, 2346, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 2576, 0, 0, 0, 2356, 0,
+	0, 924, 0, 924, 0, 0, 924, 0, 0, 0,
+	0, 0, 0, 0, 0, 2327, 2328, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 2353, 0, 0, 0, 0,
+	0, 0, 2369, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 2333, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 2576, 0, 0, 0, 2350,
+	0, 2345, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 1624, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 2350, 0, 0, 0, 0, 0, 0, 922,
+	0, 0, 0, 0, 0, 2354, 0, 0, 0, 0,
+	0, 0, 2367, 0, 0, 0, 924, 0, 2324, 2325,
+	2331, 2357, 2330, 2326, 0, 2323, 2321, 2322, 2314, 2315,
+	2316, 2317, 2319, 2320, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 4817, 0, 924, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 924, 0, 0,
+	0, 2339, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 2334, 924, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 2356, 0, 2576, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 924, 0, 924, 0, 924, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 2369,
+	0, 0, 0, 0, 0, 924, 0, 0, 924, 0,
+	924, 0, 0, 0, 924, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 924, 0, 0, 0,
+	924, 924, 924, 924, 924, 924, 924, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 1982, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 1982, 0, 0, 0, 0,
+	0, 0, 2354, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 2324, 2325, 2331, 2357, 2330,
+	2326, 0, 2323, 2321, 2322, 2314, 2315, 2316, 2317, 2319,
+	2320, 0, 0, 0, 0, 1982, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	924, 0, 0, 0, 2350, 0, 0, 0, 2350, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 2350, 0, 0, 0, 0, 0, 924,
+	0, 0, 0, 0, 2350, 2350, 2350, 2350, 2350, 2350,
+	2350, 2350, 2350, 2350, 2350, 2350, 2350, 2350, 2350, 2350,
+	2350, 2350, 2350, 2350, 2350, 2350, 2350, 2350, 2350, 2350,
+	2350, 2350, 2350, 2350, 2350, 2350, 2350, 2350, 2350, 2350,
+	2350, 2350, 2350, 2350, 0, 0, 0, 0, 0, 2350,
+	0, 2350, 2350, 2350, 2350, 0, 0, 0, 0, 0,
+	0, 0, 0, 3451, 3451, 0, 0, 0, 0, 0,
+	0, 924, 0, 0, 0, 0, 0, 0, 2350, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 2350, 0, 0,
+	0, 0, 0, 0, 0, 1982, 0, 0, 1982, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 924, 924, 924, 924, 2350, 0, 0,
+	2350, 0, 2576, 2350, 0, 0, 2350, 0, 0, 0,
+	0, 0, 2350, 2350, 2350, 2350, 2350, 2350, 2350, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 2350, 0, 0, 4870, 0, 3451, 3451, 3451,
+	3451, 0, 0, 2350, 0, 2350, 0, 0, 0, 0,
+	2350, 0, 2310, 2311, 0, 2347, 2348, 2349, 2358, 2359,
+	2360, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	1982, 0, 0, 355, 355, 2351, 2341, 0, 0, 0,
+	0, 924, 0, 2342, 0, 0, 2313, 0, 0, 0,
+	0, 0, 355, 0, 355, 355, 0, 0, 355, 2364,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 924, 0, 924, 0, 924, 0, 0, 0, 0,
+	0, 0, 2370, 0, 0, 0, 0, 2310, 2311, 0,
+	0, 0, 0, 2312, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 2332, 0, 0, 0, 0, 0,
+	0, 2341, 0, 0, 2329, 0, 0, 0, 2342, 0,
+	2344, 2313, 0, 0, 1656, 0, 0, 924, 924, 0,
+	0, 924, 0, 924, 924, 0, 1656, 0, 0, 1656,
+	924, 0, 1982, 0, 0, 0, 0, 1207, 0, 1656,
+	1656, 0, 0, 0, 0, 0, 0, 2370, 0, 0,
+	0, 0, 0, 0, 2343, 0, 0, 0, 2312, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 2332,
+	0, 0, 0, 0, 0, 355, 0, 0, 0, 2329,
+	0, 0, 0, 0, 0, 2344, 924, 0, 0, 0,
+	0, 0, 0, 0, 2335, 2336, 2337, 2338, 0, 0,
+	0, 0, 0, 0, 2318, 0, 0, 0, 0, 0,
+	0, 0, 355, 0, 355, 355, 355, 355, 0, 0,
+	355, 355, 0, 1656, 0, 0, 0, 0, 0, 2343,
+	0, 1656, 0, 0, 0, 0, 924, 0, 0, 0,
+	0, 0, 0, 0, 0, 1217, 0, 0, 0, 0,
+	0, 0, 0, 2355, 0, 0, 0, 0, 2365, 0,
+	0, 0, 0, 0, 0, 0, 0, 2340, 2346, 2335,
+	2336, 2337, 2338, 0, 0, 0, 0, 0, 0, 2318,
+	0, 0, 0, 0, 0, 0, 924, 0, 0, 0,
+	0, 2361, 0, 2362, 0, 0, 0, 0, 1982, 0,
+	2327, 2328, 0, 355, 355, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 1982, 0, 0, 0, 0,
+	2353, 0, 2310, 2311, 0, 0, 0, 0, 2358, 2359,
+	2360, 0, 0, 0, 0, 0, 0, 2333, 355, 355,
+	0, 0, 2340, 2346, 1657, 0, 2341, 0, 0, 0,
+	0, 0, 0, 2342, 0, 0, 2313, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 2345, 0, 0, 2364,
+	0, 0, 0, 0, 0, 2327, 2328, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 2370, 0, 2363, 0, 0, 0, 0, 0,
+	0, 0, 0, 2312, 0, 0, 0, 0, 0, 0,
+	0, 0, 2333, 0, 2332, 0, 2352, 355, 0, 0,
+	0, 0, 0, 0, 2329, 0, 0, 2367, 0, 0,
+	2344, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 2345, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 1982,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 2343, 0, 0, 0, 0, 1657,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 2339, 0, 0, 0,
+	0, 0, 2367, 0, 0, 0, 0, 0, 2548, 0,
+	0, 0, 0, 0, 2335, 2336, 2337, 2338, 0, 0,
+	0, 0, 0, 0, 2318, 0, 2334, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 1656, 1656, 0, 0, 1983,
+	2356, 1656, 1656, 1656, 1656, 0, 0, 0, 1657, 1982,
+	0, 2339, 0, 2355, 0, 0, 0, 0, 2365, 0,
+	0, 0, 0, 0, 0, 0, 0, 2340, 2346, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 2334, 0, 0, 2369, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 1657,
+	2327, 2328, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	2353, 0, 0, 0, 0, 0, 0, 923, 0, 1624,
+	0, 0, 0, 355, 0, 0, 0, 2333, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 1657, 355, 355, 923, 355, 0, 0, 2369,
+	2350, 0, 0, 1657, 0, 0, 2345, 0, 0, 0,
+	0, 0, 0, 1217, 0, 0, 0, 2354, 0, 1657,
+	0, 0, 0, 1217, 0, 0, 0, 0, 0, 0,
+	2324, 2325, 2331, 2357, 2330, 2326, 0, 2323, 2321, 2322,
+	2314, 2315, 2316, 2317, 2319, 2320, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 3325, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 355, 2367, 0, 0,
+	0, 0, 0, 0, 0, 355, 0, 0, 1656, 1656,
+	0, 0, 0, 0, 0, 0, 0, 0, 1656, 0,
+	0, 0, 0, 0, 0, 1656, 1656, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 2330,
+	2326, 0, 2323, 2321, 2322, 2314, 2315, 2316, 2317, 2319,
+	2320, 0, 1656, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 2339, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 1656, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 2334, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 2350, 0, 2350,
+	2356, 355, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 1217, 0,
+	355, 0, 355, 0, 355, 0, 0, 355, 1656, 355,
+	0, 355, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 2369, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	1656, 0, 0, 0, 0, 1656, 1656, 1656, 0, 0,
+	1656, 0, 0, 0, 355, 0, 0, 0, 0, 0,
+	0, 0, 0, 1982, 0, 0, 355, 355, 355, 355,
+	0, 0, 355, 355, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 1983, 0, 0, 1983, 0,
+	0, 0, 0, 0, 0, 0, 0, 2354, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 2357, 2330, 2326, 0, 2323, 2321, 2322,
+	2314, 2315, 2316, 2317, 2319, 2320, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 1657, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 1982, 1982, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 1982, 0, 0, 0, 0, 0,
+	0, 0, 1656, 1656, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 1982, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 355,
+	0, 0, 0, 1217, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 2350, 0, 2350, 0, 0, 0, 0,
+	0, 0, 0, 0, 1983, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 1982, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 355,
+	355, 0, 0, 0, 0, 0, 0, 0, 1657, 0,
+	0, 1657, 1657, 1657, 1657, 1657, 0, 0, 0, 355,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	355, 0, 0, 0, 0, 0, 0, 355, 0, 1657,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 1982, 0, 0, 0, 0,
+	0, 0, 0, 0, 355, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 1982, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 2350,
+	2350, 0, 3451, 3451, 0, 0, 2350, 0, 0, 0,
+	0, 355, 0, 0, 0, 0, 4870, 4870, 0, 0,
+	2350, 2350, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 2350, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	2350, 0, 0, 0, 0, 0, 0, 0, 1656, 0,
+	0, 0, 1656, 1656, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	3451, 3451, 3451, 3451, 3451, 3451, 3451, 3451, 3451, 3451,
+	3451, 3451, 3451, 3451, 3451, 3451, 3451, 3451, 3451, 3451,
+	0, 3451, 4870, 4870, 4870, 4870, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 1982, 0, 0, 0, 0, 0, 0,
+	1656, 0, 0, 0, 0, 1656, 1656, 0, 2350, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 1007, 0,
+	0, 0, 0, 0, 0, 0, 0, 1657, 1982, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 1983, 992,
+	0, 0, 0, 1624, 993, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 1624, 0,
+	0, 0, 0, 1657, 0, 0, 0, 0, 0, 0,
+	0, 0, 355, 0, 0, 0, 0, 0, 1656, 0,
+	1656, 1656, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 1656, 0, 0, 0, 0, 994, 0, 0, 0,
+	0, 1657, 0, 0, 0, 0, 0, 0, 355, 995,
+	0, 0, 0, 0, 0, 1217, 0, 1217, 0, 0,
+	355, 355, 0, 0, 0, 0, 0, 0, 1657, 0,
+	0, 0, 996, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 1657,
+	0, 1657, 0, 1657, 0, 0, 1013, 0, 0, 0,
+	1982, 0, 0, 0, 0, 0, 355, 0, 0, 1217,
+	1657, 0, 0, 0, 0, 0, 0, 0, 355, 0,
+	0, 355, 997, 1657, 355, 0, 0, 0, 355, 355,
+	0, 0, 0, 0, 0, 0, 0, 0, 355, 355,
+	0, 0, 0, 355, 0, 355, 0, 0, 0, 0,
+	998, 987, 355, 355, 0, 0, 2350, 0, 0, 0,
+	0, 0, 1983, 0, 0, 0, 0, 355, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 999,
+	0, 0, 0, 0, 0, 989, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 1982, 0, 0, 0,
+	0, 0, 1656, 1025, 0, 1656, 1656, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 355, 0, 0, 0, 0, 0,
+	0, 2350, 2350, 0, 1012, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 355, 0, 355, 0, 0, 0, 0, 0, 1983,
+	1656, 0, 0, 0, 0, 0, 0, 0, 355, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 1009, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 1982, 0, 1982, 0, 0, 1656, 355, 0, 0,
+	0, 0, 0, 0, 0, 0, 1983, 0, 0, 0,
+	0, 0, 0, 0, 0, 355, 355, 355, 355, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	1983, 0, 355, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	355, 0, 1001, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 355, 0, 0, 0, 0, 0,
+	0, 0, 0, 988, 0, 0, 0, 0, 0, 355,
+	2350, 0, 0, 0, 0, 0, 0, 0, 1021, 990,
+	0, 0, 1002, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 2350, 2350, 1656, 0, 2350, 4870,
+	4870, 2350, 0, 0, 0, 2350, 0, 0, 0, 0,
+	0, 0, 2350, 0, 1024, 0, 0, 355, 0, 0,
+	0, 2350, 1003, 0, 0, 0, 0, 1018, 1019, 0,
+	1016, 0, 0, 355, 0, 0, 0, 0, 0, 1010,
+	0, 0, 1004, 0, 2350, 2350, 2350, 2350, 2350, 0,
+	0, 0, 0, 0, 0, 2350, 0, 2350, 0, 0,
+	4870, 4870, 4870, 4870, 4870, 4870, 4870, 4870, 4870, 4870,
+	4870, 4870, 4870, 4870, 4870, 4870, 4870, 4870, 4870, 4870,
+	1983, 1217, 0, 4870, 0, 0, 2350, 2350, 0, 0,
+	0, 0, 1656, 0, 0, 0, 355, 0, 2350, 0,
+	1005, 0, 1011, 355, 1657, 1657, 1657, 2350, 1022, 0,
+	0, 0, 1006, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 355, 0, 991, 2350,
+	0, 0, 200, 0, 1014, 0, 355, 0, 0, 0,
+	0, 96, 0, 57, 56, 0, 0, 0, 0, 0,
+	0, 0, 0, 1026, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 97, 0, 0, 1008, 0, 0, 0,
+	0, 0, 0, 0, 1023, 0, 0, 0, 0, 0,
+	0, 0, 0, 58, 1656, 102, 0, 0, 0, 2350,
+	355, 0, 0, 0, 0, 0, 1656, 115, 0, 83,
+	1656, 1656, 1656, 1656, 1656, 1656, 1656, 60, 0, 198,
+	0, 0, 0, 0, 0, 1657, 0, 0, 0, 0,
+	0, 355, 0, 0, 0, 0, 0, 0, 0, 59,
+	355, 0, 0, 113, 0, 0, 0, 0, 0, 0,
+	0, 2350, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 62, 84, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 63, 0, 0, 64, 0, 2350, 70,
+	0, 0, 0, 0, 0, 0, 0, 7125, 0, 0,
+	0, 0, 0, 0, 0, 61, 0, 139, 0, 0,
+	0, 0, 0, 123, 136, 0, 0, 0, 0, 0,
+	1656, 2350, 2350, 85, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 	0, 0, 0, 0, 65, 0, 0, 0, 0, 0,
-	1578, 0, 0, 1578, 0, 0, 0, 1578, 295, 0,
-	0, 0, 0, 0, 0, 1604, 4028, 72, 6318, 0,
-	1604, 0, 1604, 0, 83, 0, 0, 0, 0, 1027,
-	1027, 1952, 0, 0, 0, 0, 2187, 2188, 0, 0,
-	0, 0, 0, 183, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	2218, 0, 0, 0, 0, 0, 0, 0, 297, 0,
-	2190, 0, 0, 0, 2198, 2199, 2191, 2192, 2193, 2194,
-	2196, 2197, 0, 0, 0, 0, 0, 0, 0, 0,
-	2592, 2593, 2594, 2595, 2596, 0, 0, 182, 0, 0,
-	0, 0, 1952, 2244, 6361, 0, 0, 82, 0, 0,
-	0, 0, 0, 0, 2189, 0, 235, 0, 0, 0,
-	0, 0, 0, 0, 296, 0, 132, 1978, 0, 6383,
-	0, 0, 0, 0, 0, 0, 0, 0, 1027, 0,
-	0, 0, 0, 0, 0, 2187, 2188, 289, 2221, 2222,
-	2223, 2232, 2233, 2234, 0, 0, 290, 0, 5752, 0,
-	230, 0, 0, 2439, 0, 0, 234, 0, 0, 2218,
-	0, 0, 0, 0, 0, 0, 2219, 0, 0, 2190,
-	0, 0, 0, 0, 0, 0, 0, 233, 0, 0,
-	3, 2238, 0, 132, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 2244, 1978, 1978, 0, 0, 0, 0, 0,
-	0, 0, 0, 2189, 0, 0, 0, 0, 0, 0,
-	0, 1952, 2195, 0, 2209, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 2206, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 334, 0, 0, 0,
-	0, 897, 0, 0, 0, 0, 897, 0, 0, 897,
-	0, 0, 897, 897, 0, 0, 0, 897, 0, 1394,
-	897, 1960, 0, 0, 0, 0, 0, 3045, 334, 132,
-	0, 0, 0, 2217, 2220, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	1952, 0, 334, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 2224, 0, 334, 0, 0, 2011, 0, 0,
-	0, 2212, 2213, 2214, 2215, 0, 0, 0, 0, 0,
-	0, 2195, 0, 0, 0, 0, 0, 0, 0, 1978,
-	0, 0, 0, 0, 914, 0, 1527, 0, 0, 0,
-	2210, 0, 0, 0, 0, 0, 3045, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	334, 0, 0, 0, 334, 334, 0, 0, 0, 2229,
-	132, 0, 132, 2239, 132, 0, 0, 0, 0, 0,
-	0, 0, 2217, 2220, 2035, 0, 0, 0, 0, 0,
-	0, 329, 329, 1952, 892, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 2204, 2205, 0, 2936, 0, 5169,
-	0, 0, 0, 0, 2241, 0, 0, 0, 0, 0,
-	1371, 132, 132, 0, 2227, 5167, 0, 0, 0, 4823,
-	0, 0, 0, 0, 0, 0, 0, 5159, 0, 2210,
-	132, 0, 132, 0, 0, 0, 0, 5178, 5179, 0,
-	0, 0, 0, 0, 0, 0, 132, 2973, 132, 4831,
-	0, 4832, 4833, 0, 0, 2011, 0, 0, 0, 0,
-	0, 334, 0, 0, 0, 2986, 2988, 1620, 334, 0,
-	334, 0, 0, 0, 0, 0, 0, 0, 1620, 2991,
-	0, 1620, 0, 0, 0, 0, 4192, 4192, 334, 0,
-	4865, 4868, 0, 0, 0, 2211, 0, 4192, 0, 2409,
-	0, 0, 0, 0, 1604, 0, 0, 0, 4192, 2409,
-	0, 4192, 2409, 2241, 0, 2409, 0, 0, 4865, 0,
-	5181, 5182, 0, 0, 5172, 0, 0, 0, 0, 0,
-	334, 334, 4868, 0, 334, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 5161, 0, 2224, 0,
-	0, 0, 0, 4868, 0, 334, 0, 0, 0, 0,
-	4938, 4868, 5160, 0, 0, 0, 1348, 0, 0, 2243,
-	0, 0, 0, 4946, 4868, 0, 2216, 4952, 0, 4952,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 1620,
-	2258, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 2211, 0, 0, 0, 2264, 0,
-	0, 0, 2270, 0, 4192, 0, 4192, 0, 4989, 4192,
-	4868, 0, 5170, 4192, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 2230, 0,
-	0, 0, 0, 2187, 2188, 0, 0, 0, 0, 991,
-	0, 0, 991, 0, 0, 0, 0, 4868, 4369, 0,
-	991, 0, 0, 0, 0, 5157, 0, 2218, 0, 0,
-	0, 0, 0, 0, 2219, 0, 0, 2190, 2243, 0,
-	2199, 2191, 2192, 2193, 2194, 2196, 2197, 0, 0, 0,
-	2224, 0, 0, 0, 1620, 0, 2224, 4359, 4357, 0,
-	0, 334, 0, 0, 0, 4361, 4363, 4353, 0, 0,
-	2244, 0, 0, 0, 0, 2362, 334, 2364, 0, 132,
-	0, 2189, 0, 5064, 0, 0, 0, 5070, 4192, 0,
-	0, 334, 2209, 0, 0, 0, 0, 0, 0, 1635,
-	0, 5180, 2206, 0, 0, 1394, 0, 0, 0, 0,
-	0, 0, 5113, 4381, 0, 334, 0, 0, 0, 0,
-	4449, 0, 0, 1620, 0, 0, 0, 2228, 0, 0,
-	4192, 0, 897, 0, 0, 0, 0, 0, 5175, 4192,
-	2201, 2202, 2208, 2231, 2207, 2203, 0, 2200, 2198, 2199,
-	2191, 2192, 2193, 2194, 2196, 2197, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 5214, 5168, 5162, 5163, 5164,
-	5165, 5166, 0, 2187, 2188, 0, 2221, 2222, 2223, 2232,
-	2233, 2234, 0, 0, 0, 0, 0, 0, 0, 2212,
-	2213, 2214, 2215, 0, 334, 0, 2225, 2218, 0, 2195,
-	0, 0, 0, 0, 2219, 0, 0, 2190, 0, 0,
-	0, 5185, 5183, 0, 0, 0, 0, 0, 0, 2238,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 2224, 0, 0, 0, 0, 0, 0, 0,
-	2244, 0, 0, 0, 0, 0, 5177, 5249, 0, 0,
-	2224, 2189, 0, 0, 0, 0, 0, 0, 0, 0,
-	2217, 2220, 2209, 0, 0, 5176, 0, 0, 0, 0,
-	0, 0, 2206, 0, 0, 4073, 0, 2224, 4355, 5184,
-	5186, 0, 2224, 0, 0, 0, 0, 0, 2224, 4371,
-	0, 0, 2204, 2205, 0, 0, 0, 0, 1110, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 4370, 4360, 4358, 4362, 4364, 4354,
-	4356, 4372, 4380, 4374, 1123, 0, 0, 2210, 0, 0,
-	0, 0, 0, 5307, 4366, 4368, 4376, 132, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 1121, 334, 334,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 2212,
-	2213, 2214, 2215, 0, 0, 0, 0, 0, 0, 2195,
-	0, 4382, 0, 897, 0, 1124, 5332, 897, 4154, 0,
-	0, 0, 0, 0, 0, 897, 0, 0, 2224, 0,
-	0, 0, 0, 2224, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 2224, 0, 0,
-	0, 2241, 2224, 0, 0, 0, 0, 2229, 0, 0,
-	0, 2239, 0, 0, 0, 0, 0, 0, 0, 0,
-	2217, 2220, 1117, 4379, 334, 0, 0, 0, 0, 0,
-	0, 1133, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 2235, 0, 2236, 0, 0, 1122, 0,
-	0, 0, 2204, 2205, 0, 0, 0, 0, 0, 0,
-	0, 0, 334, 0, 2216, 0, 0, 0, 0, 0,
-	0, 0, 2227, 0, 0, 0, 0, 0, 0, 4868,
-	0, 0, 0, 0, 4043, 0, 0, 2210, 0, 0,
-	0, 0, 2211, 0, 0, 0, 4373, 0, 0, 2224,
-	2224, 2224, 2224, 2224, 2224, 2224, 2224, 0, 1115, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 2224,
-	0, 0, 0, 0, 4318, 0, 966, 0, 0, 0,
-	0, 0, 2224, 0, 0, 0, 0, 0, 0, 2237,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 1119, 0, 0, 0,
-	2226, 0, 0, 0, 0, 0, 2243, 0, 0, 0,
-	0, 2241, 0, 0, 0, 991, 4383, 0, 0, 0,
-	0, 3286, 0, 0, 0, 0, 4365, 4367, 0, 0,
-	4375, 0, 0, 0, 0, 0, 2224, 0, 0, 0,
-	0, 0, 2224, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 4952, 0, 0, 4952, 0, 0,
-	4952, 0, 0, 1132, 0, 0, 0, 0, 4952, 0,
-	0, 0, 0, 0, 2216, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 334, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 1371,
-	0, 1371, 2211, 0, 0, 0, 4493, 0, 4326, 0,
-	0, 0, 2207, 2203, 0, 2200, 2198, 2199, 2191, 2192,
-	2193, 2194, 2196, 2197, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 2187, 2188, 2230, 4868, 0, 334,
-	0, 0, 0, 914, 914, 1635, 0, 0, 0, 1112,
-	0, 0, 0, 0, 0, 0, 0, 0, 2218, 0,
-	1348, 0, 0, 1348, 1348, 2219, 0, 0, 2190, 0,
-	0, 0, 0, 0, 0, 0, 2243, 1116, 0, 0,
-	334, 1820, 5595, 0, 1118, 4449, 2409, 0, 0, 0,
-	0, 334, 0, 0, 0, 0, 2348, 0, 5616, 0,
-	4326, 2244, 0, 334, 0, 0, 0, 334, 0, 334,
-	0, 0, 2189, 2224, 0, 0, 334, 0, 1864, 0,
-	0, 0, 3107, 2209, 0, 334, 1976, 0, 0, 965,
-	0, 0, 0, 2206, 0, 0, 0, 0, 4192, 334,
-	0, 0, 1371, 0, 0, 1128, 0, 0, 0, 0,
-	1231, 4192, 2264, 0, 1114, 0, 2264, 0, 0, 0,
-	0, 0, 0, 0, 0, 2228, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 2201, 2202,
-	2208, 2231, 2207, 2203, 0, 2200, 2198, 2199, 2191, 2192,
-	2193, 2194, 2196, 2197, 0, 1604, 5209, 0, 0, 1978,
-	1978, 0, 0, 5714, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 1111, 0, 0, 0, 0, 0, 963,
-	2212, 2213, 2214, 2215, 0, 0, 0, 0, 0, 0,
-	2195, 0, 0, 0, 1521, 2122, 2123, 0, 0, 0,
-	0, 0, 2224, 0, 1120, 0, 0, 0, 5708, 2364,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 967, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 1113, 0, 0, 0, 0, 0,
-	0, 1127, 0, 2224, 0, 0, 0, 0, 0, 0,
-	0, 2217, 2220, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 1130, 1131, 0, 1126,
-	0, 0, 334, 0, 0, 132, 0, 0, 2011, 0,
-	334, 0, 0, 2204, 2205, 1978, 0, 0, 0, 0,
-	0, 0, 1378, 0, 0, 0, 0, 0, 334, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 2210, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 1635, 1635,
-	1635, 1635, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 1635, 1635, 1635, 1635, 1978, 334, 1635, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	2677, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 4192, 4192, 0, 4865, 0, 0, 4952, 4192, 0,
-	0, 0, 2241, 0, 0, 0, 5857, 0, 5857, 2011,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	4192, 0, 2409, 0, 0, 0, 4865, 0, 2011, 2011,
-	334, 4868, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 4868, 0, 334, 4868, 0, 334,
-	5893, 0, 0, 0, 0, 4952, 0, 0, 4952, 0,
-	0, 0, 4952, 0, 0, 2216, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 4192, 0, 4192, 334, 0, 132, 132, 0, 0,
-	0, 0, 0, 2211, 0, 2379, 0, 0, 0, 4326,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	991, 0, 0, 0, 0, 2404, 0, 1976, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 4192,
-	4192, 0, 0, 0, 5857, 0, 4449, 0, 5986, 0,
-	0, 0, 0, 0, 4865, 0, 0, 2243, 0, 0,
-	1027, 2224, 0, 0, 0, 2224, 0, 0, 0, 0,
-	0, 1976, 334, 0, 0, 0, 0, 0, 0, 0,
-	2224, 6010, 0, 0, 0, 0, 334, 0, 0, 0,
-	0, 2224, 2224, 2224, 2224, 2224, 2224, 2224, 2224, 2224,
-	2224, 2224, 2224, 2224, 2224, 2224, 2224, 2224, 2224, 2224,
-	2224, 2224, 2224, 2224, 2224, 2224, 2224, 2224, 2224, 2224,
-	2224, 2224, 2224, 2224, 2224, 2224, 2224, 2224, 0, 0,
-	0, 0, 0, 2224, 0, 2224, 2224, 2224, 2224, 0,
-	0, 0, 0, 0, 0, 0, 0, 3286, 3286, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 2224, 2207, 2203, 0, 2200, 2198, 2199, 2191,
-	2192, 2193, 2194, 2196, 2197, 0, 5169, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 5167, 0, 0, 0, 5332, 0, 0, 0,
-	0, 0, 0, 2609, 5159, 0, 0, 0, 2224, 0,
-	0, 0, 0, 0, 5178, 5179, 0, 0, 2626, 0,
-	2628, 0, 2630, 0, 0, 2632, 0, 2633, 0, 0,
-	0, 0, 0, 132, 0, 132, 0, 0, 2224, 0,
-	0, 2224, 0, 0, 2224, 0, 0, 2224, 0, 0,
-	0, 0, 0, 2224, 2224, 2224, 2224, 2224, 2224, 2224,
-	0, 0, 0, 0, 0, 0, 0, 334, 334, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 2674, 2675,
-	4192, 2409, 0, 2409, 0, 0, 5616, 0, 0, 0,
-	0, 0, 0, 132, 0, 334, 132, 5181, 5182, 0,
-	0, 5172, 132, 0, 0, 6170, 0, 6170, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 2224, 5161, 0, 4638, 0, 3286, 3286, 3286,
-	3286, 0, 991, 2224, 0, 2224, 0, 0, 0, 5160,
-	2224, 0, 0, 0, 0, 4952, 4952, 0, 0, 0,
-	4952, 0, 1620, 0, 0, 0, 0, 0, 3257, 3258,
-	3259, 3260, 3253, 3254, 3255, 3256, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 4868, 0,
-	334, 0, 0, 0, 0, 0, 0, 0, 0, 5170,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 3107, 0, 0, 0, 0, 0, 0, 0, 5616,
-	0, 0, 0, 5857, 0, 5857, 0, 2011, 0, 0,
-	0, 4192, 2264, 0, 0, 0, 0, 0, 334, 0,
-	0, 0, 0, 0, 3233, 3234, 3235, 3236, 0, 0,
-	0, 0, 5113, 0, 6285, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 2011, 0, 0, 3245,
-	3246, 3247, 3248, 3241, 3242, 3243, 3244, 3249, 3250, 3251,
-	3252, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 1644, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 5180, 0,
-	0, 2926, 0, 0, 5249, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 1378, 1378, 1378, 0, 2948,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 5175, 2961, 0, 2961, 0,
-	0, 0, 0, 0, 2968, 3229, 3230, 3231, 3232, 3237,
-	3238, 3239, 3240, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 5168, 5162, 5163, 5164, 5165, 5166, 4952,
-	6352, 0, 0, 0, 0, 0, 0, 5616, 0, 1027,
-	0, 0, 0, 0, 0, 1786, 0, 0, 1792, 0,
-	0, 0, 0, 2995, 0, 0, 0, 5857, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 5185, 5183,
-	0, 0, 5857, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 1521, 0, 0, 0, 0,
-	0, 0, 0, 0, 3107, 0, 0, 0, 0, 0,
-	334, 0, 0, 5177, 0, 1968, 0, 0, 0, 0,
-	0, 1986, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 5176, 0, 914, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 5184, 5186, 0, 0,
-	0, 0, 0, 2013, 0, 2018, 0, 2024, 0, 0,
-	0, 0, 0, 5857, 0, 5857, 0, 0, 2677, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 5857, 0, 334, 5857, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 2409, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 2011,
-	0, 2011, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 2124, 0, 2129, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 1635, 1635, 1635, 0, 2143,
-	0, 2148, 0, 0, 2187, 2188, 0, 2221, 2222, 2223,
-	2232, 2233, 2234, 6494, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 2225, 2218, 6170,
-	0, 0, 334, 0, 1462, 2219, 0, 3937, 2190, 0,
-	0, 4952, 0, 0, 0, 0, 0, 0, 0, 0,
-	2238, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 4192, 0, 0,
-	0, 2244, 0, 0, 0, 5060, 5061, 0, 0, 0,
-	0, 0, 2189, 0, 0, 0, 0, 0, 0, 0,
-	0, 872, 0, 2209, 0, 0, 0, 0, 0, 0,
-	0, 0, 334, 2206, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 5249, 0, 0, 0, 2245, 2246,
-	2247, 2248, 2249, 2250, 2251, 2252, 0, 0, 0, 0,
-	0, 0, 0, 0, 5149, 0, 0, 0, 0, 0,
-	0, 0, 0, 2011, 0, 0, 5188, 0, 0, 0,
-	0, 0, 2265, 0, 2187, 2188, 0, 0, 2278, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 334, 0, 0, 0, 2948, 0, 2218, 2224,
-	2212, 2213, 2214, 2215, 0, 2219, 0, 0, 2190, 0,
-	2195, 0, 1027, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 2244, 0, 0, 0, 0, 5616, 0, 0, 0,
-	0, 4071, 2189, 0, 0, 0, 0, 0, 2229, 0,
-	0, 0, 2239, 2209, 0, 0, 2342, 2342, 2342, 0,
-	0, 2217, 2220, 2206, 0, 0, 0, 4100, 0, 4103,
-	0, 0, 4326, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 2235, 4192, 2236, 0, 0, 0,
-	0, 0, 0, 2204, 2205, 0, 0, 5857, 0, 5857,
-	0, 0, 4952, 0, 2677, 0, 0, 0, 0, 0,
-	0, 0, 0, 2227, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 5208, 0, 2210, 0,
-	0, 0, 872, 0, 0, 0, 0, 4150, 0, 1027,
-	0, 0, 0, 0, 4326, 0, 0, 0, 0, 0,
-	2212, 2213, 2214, 2215, 4161, 1976, 1976, 4164, 0, 0,
-	2195, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 4172, 4192, 0, 0, 2224, 2519, 2224, 0, 0,
-	2237, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 2226, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 4192, 2241, 0, 0, 0, 0, 0, 0, 0,
-	0, 2217, 2220, 0, 0, 0, 1378, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 1521,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 2204, 2205, 0, 4952, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 4952, 0, 0, 2216, 0, 5410, 5411, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 2210, 0,
-	0, 1976, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 2211, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 2648, 0, 0, 0, 0, 2230, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 2241, 0, 0, 0, 0, 2243, 2689, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 4425,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 2948,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 1978, 0, 2216, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 2224, 0, 2224, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 2211, 0, 5527, 2228, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 5543, 5544, 0, 2201,
-	2202, 2208, 2231, 2207, 2203, 0, 2200, 2198, 2199, 2191,
-	2192, 2193, 2194, 2196, 2197, 4525, 0, 0, 0, 0,
-	5553, 0, 0, 0, 5222, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 5577, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 2243, 0, 0,
-	0, 0, 0, 0, 0, 132, 132, 0, 132, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 2224, 2224, 0, 3286, 3286, 0, 0,
-	2224, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	4638, 4638, 0, 0, 2224, 2224, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 2224, 0, 0, 5657, 0, 0, 0, 0,
-	2986, 5663, 5664, 0, 2224, 0, 132, 132, 0, 132,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 2207, 2203, 0, 2200, 2198, 2199, 2191,
-	2192, 2193, 2194, 2196, 2197, 0, 0, 0, 0, 0,
-	0, 0, 0, 3286, 3286, 3286, 3286, 3286, 3286, 3286,
-	3286, 3286, 3286, 3286, 3286, 3286, 3286, 3286, 3286, 3286,
-	3286, 3286, 3286, 0, 3286, 4638, 4638, 4638, 4638, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	3017, 2224, 3021, 0, 0, 0, 0, 0, 0, 3036,
-	0, 0, 1378, 0, 0, 0, 0, 0, 3047, 3048,
-	3049, 3050, 3051, 3052, 3053, 3054, 3055, 3056, 3057, 3058,
-	3059, 3060, 3061, 3062, 3063, 3064, 3065, 3066, 3067, 3068,
-	3069, 3070, 3071, 3072, 3073, 3074, 3075, 3076, 3077, 3078,
-	3079, 3080, 3081, 3082, 3083, 0, 3089, 0, 3091, 3092,
-	3093, 3094, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 1371, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 3118, 0, 0, 132, 132, 0,
-	0, 0, 0, 0, 0, 0, 2265, 0, 0, 0,
-	3164, 5770, 5771, 0, 0, 1027, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 3194, 3197, 3200, 3203,
-	0, 0, 3209, 3210, 3211, 3212, 3213, 3214, 3215, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 872, 0, 3278, 0, 3289, 3291, 3296, 0, 0,
-	0, 5813, 5814, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 2187, 2188, 0, 2221,
-	2222, 2223, 2232, 2233, 2234, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 2225,
-	2218, 0, 0, 3945, 0, 0, 0, 2219, 0, 0,
-	2190, 0, 2224, 0, 0, 0, 0, 872, 0, 0,
-	0, 0, 2238, 0, 0, 0, 872, 0, 0, 0,
+	0, 0, 0, 0, 1983, 0, 2310, 2311, 0, 2347,
+	2348, 2349, 2358, 2359, 2360, 0, 1657, 124, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 2351,
+	2341, 0, 0, 0, 0, 0, 0, 2342, 0, 0,
+	2313, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 1656, 0, 2364, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 2370, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 2312, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 2332, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 2329, 86,
+	0, 0, 0, 0, 2344, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 2350,
+	0, 0, 0, 1656, 1656, 1656, 1656, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	1624, 2350, 2350, 1657, 0, 0, 2350, 2350, 2343, 0,
+	2350, 2350, 0, 0, 1657, 0, 2350, 1657, 0, 0,
+	0, 2350, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 3451, 0, 0, 0,
+	0, 0, 0, 0, 128, 0, 0, 0, 2335, 2336,
+	2337, 2338, 0, 0, 0, 0, 0, 0, 2318, 0,
+	0, 0, 0, 0, 0, 0, 66, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 69, 0, 0, 0,
+	0, 0, 0, 72, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 87, 0, 0, 0, 2355, 0, 0,
+	0, 0, 2365, 71, 250, 0, 131, 0, 0, 0,
+	135, 2340, 2346, 6624, 0, 0, 0, 67, 0, 0,
+	0, 199, 0, 0, 0, 0, 0, 0, 0, 68,
+	0, 0, 0, 0, 0, 2361, 0, 2362, 0, 0,
+	0, 0, 0, 316, 2327, 2328, 0, 0, 3451, 0,
+	0, 0, 75, 0, 0, 0, 0, 0, 0, 89,
+	0, 0, 0, 0, 2353, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 197,
+	0, 2333, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 1656, 1656, 0,
+	0, 1656, 0, 1656, 1656, 0, 0, 318, 0, 0,
+	2345, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 2476, 0, 0, 0, 2350, 0,
+	0, 0, 0, 0, 0, 0, 0, 196, 2363, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 88, 0,
+	0, 0, 0, 0, 0, 0, 0, 256, 0, 0,
+	2352, 0, 0, 0, 0, 317, 1656, 0, 0, 0,
+	0, 2367, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	310, 0, 0, 0, 0, 0, 0, 0, 0, 311,
+	0, 0, 0, 251, 0, 2350, 2350, 0, 0, 255,
+	0, 0, 0, 0, 0, 0, 1982, 0, 0, 0,
 	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 2244, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 2189, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 2209, 0, 0, 0, 0,
-	0, 0, 0, 0, 872, 2206, 0, 0, 0, 0,
-	0, 1521, 1521, 0, 0, 2224, 2224, 0, 0, 0,
+	254, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	2339, 0, 0, 0, 0, 0, 0, 1983, 0, 0,
 	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 1982, 0, 0, 0,
+	2334, 0, 0, 2350, 0, 0, 0, 0, 0, 0,
 	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	2986, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 872, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 872, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 872, 0,
 	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 2212, 2213, 2214, 2215, 0, 0, 0, 0,
-	0, 0, 2195, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 2356, 0, 0, 0, 0, 0,
 	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 2350, 2350, 2350, 0, 0, 0, 0, 0, 0,
+	0, 2350, 2350, 4870, 3451, 0, 0, 0, 0, 0,
+	2350, 0, 0, 2350, 0, 0, 0, 0, 2369, 0,
 	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 6036, 0, 6038, 6039, 6040, 0,
-	0, 6043, 6044, 0, 0, 0, 0, 0, 0, 0,
-	2229, 0, 0, 0, 2239, 0, 0, 0, 0, 0,
-	0, 0, 0, 2217, 2220, 0, 0, 0, 0, 0,
-	0, 0, 2224, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 2235, 0, 2236, 0,
-	0, 0, 4131, 0, 0, 2204, 2205, 0, 4133, 0,
 	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 2227, 0, 0, 0, 0,
-	0, 0, 0, 6094, 0, 6099, 6100, 0, 0, 0,
-	2210, 0, 0, 0, 0, 0, 6111, 0, 0, 0,
 	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	2224, 2224, 0, 0, 2224, 4638, 4638, 2224, 0, 0,
-	0, 2224, 0, 0, 0, 0, 0, 0, 2224, 0,
-	0, 0, 0, 0, 0, 0, 0, 2224, 0, 0,
-	0, 0, 2237, 0, 0, 0, 0, 0, 0, 0,
+	0, 1468, 0, 0, 0, 0, 0, 0, 0, 0,
 	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	2224, 2224, 2224, 2224, 2224, 0, 0, 0, 0, 0,
-	0, 2224, 0, 2224, 2241, 0, 4638, 4638, 4638, 4638,
-	4638, 4638, 4638, 4638, 4638, 4638, 4638, 4638, 4638, 4638,
-	4638, 4638, 4638, 4638, 4638, 4638, 0, 0, 0, 4638,
-	0, 0, 2224, 2224, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 2224, 0, 0, 872, 0, 872,
-	0, 0, 0, 2224, 0, 0, 0, 0, 0, 872,
-	0, 0, 872, 0, 0, 0, 0, 2216, 0, 0,
-	0, 0, 0, 0, 0, 2224, 0, 6211, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 2447, 0, 0, 0, 2211, 0, 0, 872, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 4737,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 2230,
-	0, 132, 0, 2224, 0, 0, 4402, 0, 4404, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 1521, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 1521, 0, 0, 0, 0, 0, 0, 2243,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 2224,
-	0, 1976, 1976, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 6305, 0, 0, 0, 0, 0, 0, 0,
-	2224, 0, 872, 0, 0, 0, 132, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 2224, 2224, 0, 872, 0, 0, 872, 872,
-	872, 872, 872, 0, 0, 0, 0, 0, 2228, 0,
-	0, 2245, 2246, 0, 0, 0, 0, 0, 0, 0,
-	0, 2201, 2202, 2208, 2231, 2207, 2203, 1378, 2200, 2198,
-	2199, 2191, 2192, 2193, 2194, 2196, 2197, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 4836, 0,
-	0, 0, 0, 0, 0, 4841, 0, 1976, 2187, 2188,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 4529, 4530, 0, 0, 4861, 0, 4536, 132, 0,
-	0, 0, 2218, 0, 0, 1521, 0, 0, 0, 2219,
-	0, 0, 2190, 1521, 0, 0, 4550, 4551, 0, 0,
-	0, 0, 3164, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 4917, 4919, 0,
-	0, 2948, 0, 0, 6397, 2244, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 2189, 0, 2224, 0,
-	0, 0, 0, 0, 0, 0, 0, 2209, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 2206, 0, 4568,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 2224, 2224, 4580, 0, 0, 2224, 2224,
-	0, 0, 2224, 2224, 0, 0, 0, 0, 2224, 0,
-	0, 0, 0, 2224, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 3286, 2986,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	4535, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 2212, 2213, 2214, 2215, 0, 0,
-	0, 0, 0, 0, 2195, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 872, 872, 0, 3296,
-	3296, 3296, 0, 132, 0, 0, 0, 872, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 2342, 2224,
-	0, 3081, 3082, 3083, 3089, 0, 0, 0, 0, 0,
-	0, 0, 872, 0, 0, 2217, 2220, 0, 5093, 0,
-	0, 0, 0, 0, 0, 0, 0, 3286, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 872, 0, 2204, 2205, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 132, 0, 0, 0, 0, 0,
-	0, 0, 2210, 0, 0, 0, 0, 0, 0, 0,
-	2224, 872, 0, 872, 132, 872, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 872, 872, 0, 0, 0, 0, 0,
-	0, 5204, 0, 132, 0, 0, 0, 872, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 2224, 2224, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 2447, 2447, 872, 0, 2241, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 1171, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 1175, 0, 0,
-	0, 0, 1176, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 2224, 0, 0, 0, 2216,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	2224, 2224, 2224, 0, 0, 0, 0, 0, 0, 0,
-	2224, 2224, 4638, 3286, 0, 0, 0, 2211, 872, 2224,
-	0, 1177, 2224, 1191, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 132, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 1178, 0, 0, 0, 0, 1179, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	1200, 0, 0, 0, 0, 0, 872, 0, 0, 1180,
-	0, 2243, 0, 872, 0, 0, 0, 0, 4638, 3286,
-	0, 872, 0, 0, 0, 0, 1198, 0, 0, 0,
-	0, 0, 0, 0, 0, 2224, 0, 872, 0, 0,
-	0, 0, 0, 2224, 3286, 0, 0, 0, 0, 0,
-	0, 2224, 1173, 1170, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 2224, 0, 2224, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 2224, 0, 0, 5404,
-	1181, 0, 2224, 2224, 0, 2224, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 1202, 0,
-	0, 0, 0, 0, 966, 0, 0, 2187, 2188, 0,
-	2221, 2222, 2223, 2232, 2233, 2234, 0, 2207, 2203, 0,
-	2200, 2198, 2199, 2191, 2192, 2193, 2194, 2196, 2197, 0,
-	2225, 2218, 0, 0, 0, 0, 0, 0, 2219, 0,
-	0, 2190, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 2238, 0, 0, 2187, 2188, 0, 2221,
-	2222, 2223, 2232, 2233, 2234, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 2244, 0, 0, 0, 0, 2225,
-	2218, 0, 4638, 3107, 0, 2189, 0, 2219, 0, 0,
-	2190, 1201, 0, 0, 0, 0, 2209, 0, 0, 0,
-	0, 1196, 2238, 0, 0, 0, 2206, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 872, 0, 2244, 2224, 4638, 0, 0, 2224, 0,
-	0, 0, 0, 0, 2189, 0, 0, 0, 0, 0,
-	0, 0, 0, 872, 872, 2209, 0, 4638, 0, 0,
-	0, 0, 0, 0, 0, 2206, 0, 0, 0, 0,
-	0, 0, 0, 0, 4677, 0, 0, 0, 0, 0,
-	0, 0, 1195, 0, 0, 0, 0, 2224, 0, 0,
-	0, 0, 0, 1182, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 2212, 2213, 2214, 2215, 0, 0, 0,
-	0, 0, 0, 2195, 0, 0, 0, 0, 0, 4677,
-	0, 0, 0, 0, 0, 0, 2948, 0, 1183, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 2212, 2213, 2214, 2215, 872, 0, 0, 0,
-	0, 2229, 2195, 0, 132, 2239, 0, 5593, 0, 0,
-	0, 0, 0, 0, 2217, 2220, 0, 965, 5605, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	1169, 0, 0, 1192, 2948, 0, 2948, 2235, 0, 2236,
-	0, 0, 0, 5634, 0, 1184, 2204, 2205, 0, 0,
-	2229, 0, 0, 0, 2239, 0, 0, 0, 0, 0,
-	2447, 0, 0, 2217, 2220, 1378, 2227, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 1378, 1190, 132,
-	0, 2210, 132, 0, 0, 0, 2235, 0, 2236, 0,
-	0, 0, 2224, 0, 0, 2204, 2205, 0, 0, 1185,
-	0, 0, 0, 1186, 1205, 0, 1204, 963, 0, 0,
-	0, 1187, 0, 0, 0, 2227, 0, 0, 0, 2224,
-	0, 0, 0, 0, 0, 0, 0, 1188, 0, 0,
-	2210, 0, 1197, 2237, 0, 0, 0, 0, 1206, 0,
-	872, 1203, 0, 0, 0, 0, 0, 0, 0, 0,
-	967, 0, 872, 0, 2226, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 2241, 0, 0, 0, 964,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 2237, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 2226, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 2241, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 4898, 0, 0, 0, 2216, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 132, 0, 132, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 2211, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 872, 0, 2216, 0, 0,
-	2224, 0, 0, 0, 0, 0, 0, 872, 0, 872,
-	2230, 0, 0, 0, 872, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 2211, 0, 4971, 4972, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	2243, 0, 0, 0, 0, 0, 0, 0, 0, 2230,
-	0, 132, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 2243,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 5877, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 2948, 0, 0, 0, 0, 0, 2228,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 2201, 2202, 2208, 2231, 2207, 2203, 0, 2200,
-	2198, 2199, 2191, 2192, 2193, 2194, 2196, 2197, 0, 0,
-	0, 0, 0, 4589, 0, 0, 0, 4590, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 2228, 0,
-	0, 0, 0, 0, 5128, 0, 0, 0, 0, 0,
-	0, 2201, 2202, 2208, 2231, 2207, 2203, 0, 2200, 2198,
-	2199, 2191, 2192, 2193, 2194, 2196, 2197, 0, 0, 0,
-	0, 0, 3160, 0, 2187, 2188, 3161, 2221, 2222, 2223,
-	2232, 2233, 2234, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 2225, 2218, 0,
-	0, 0, 0, 0, 0, 2219, 0, 3036, 2190, 0,
-	0, 0, 0, 0, 5206, 5207, 0, 0, 5210, 2948,
-	2238, 0, 5213, 0, 0, 0, 0, 0, 0, 0,
-	0, 5217, 0, 6016, 0, 0, 0, 0, 0, 0,
-	5224, 2244, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 2189, 0, 5233, 0, 0, 0, 0, 0,
-	0, 0, 0, 2209, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 2206, 5256, 5257, 0, 5258, 5259, 5260,
-	0, 0, 0, 0, 0, 0, 0, 872, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 872, 5267, 0,
-	0, 0, 5269, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 5298, 5299, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 5310, 0, 0, 0, 0, 0,
-	2212, 2213, 2214, 2215, 0, 0, 0, 0, 0, 5319,
-	2195, 0, 0, 0, 0, 0, 0, 2187, 2188, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 2218, 0, 0, 0, 0, 5341, 3036, 2219, 0,
-	0, 2190, 0, 0, 6135, 1976, 0, 0, 2229, 0,
-	0, 0, 2239, 0, 0, 0, 0, 0, 0, 0,
-	0, 2217, 2220, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 6156, 0, 2244, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 2235, 2189, 2236, 0, 0, 0,
-	0, 0, 0, 2204, 2205, 0, 2209, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 2206, 0, 0, 0,
-	0, 0, 5399, 2227, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 2210, 0,
-	0, 2187, 2188, 0, 2221, 2222, 2223, 2232, 2233, 2234,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 2225, 2218, 0, 0, 0, 0,
-	0, 0, 2219, 0, 0, 2190, 0, 2948, 0, 4528,
-	0, 0, 0, 0, 0, 0, 0, 2238, 0, 0,
-	2237, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 2212, 2213, 2214, 2215, 5445, 2244, 0,
-	0, 2226, 0, 2195, 0, 0, 0, 0, 0, 2189,
-	0, 0, 2241, 0, 0, 0, 0, 0, 0, 0,
-	2209, 0, 0, 0, 0, 2961, 0, 0, 0, 0,
-	2206, 5476, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 1426, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 2217, 2220, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 2216, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 5508, 5509, 0, 0,
-	0, 0, 0, 0, 0, 0, 2204, 2205, 333, 333,
-	871, 333, 0, 2211, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 2212, 2213, 2214,
-	2215, 0, 0, 0, 0, 0, 333, 2195, 0, 0,
-	0, 2210, 0, 0, 0, 1148, 0, 2230, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 1148, 0, 0, 0,
-	0, 0, 0, 0, 0, 2229, 0, 2243, 0, 2239,
-	0, 0, 0, 0, 0, 0, 0, 0, 2217, 2220,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 2235, 0, 2236, 0, 2241, 2342, 0, 0, 0,
-	2204, 2205, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	2227, 0, 0, 0, 0, 0, 0, 0, 2342, 0,
-	0, 0, 0, 0, 0, 2210, 0, 5654, 0, 0,
-	0, 0, 0, 0, 0, 0, 2228, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 2216, 2201,
-	2202, 2208, 2231, 2207, 2203, 0, 2200, 2198, 2199, 2191,
-	2192, 2193, 2194, 2196, 2197, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 4592, 0, 2211, 2237, 0, 0,
-	0, 872, 0, 6450, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 5689, 5690, 0, 2226, 0,
-	0, 5694, 5695, 0, 0, 0, 5698, 5699, 0, 2241,
-	0, 1533, 0, 872, 0, 872, 0, 0, 0, 0,
-	0, 5704, 0, 0, 0, 872, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 5709, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	2243, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	2447, 0, 0, 0, 872, 0, 0, 0, 0, 0,
-	0, 0, 2216, 0, 0, 0, 0, 0, 0, 6508,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 2447,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 870,
-	2211, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 2187, 2188, 0, 2221, 2222, 2223,
-	2232, 2233, 2234, 0, 2230, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 2225, 2218, 6560,
-	0, 0, 0, 0, 0, 2219, 2207, 2203, 2190, 2200,
-	2198, 2199, 2191, 2192, 2193, 2194, 2196, 2197, 0, 0,
-	2238, 0, 0, 0, 2243, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 2244, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 2189, 5815, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 2209, 0, 0, 0, 0, 0, 0,
-	0, 0, 1378, 2206, 0, 0, 0, 0, 0, 2961,
-	0, 872, 0, 0, 872, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 2228, 0, 2447, 0, 0, 2187, 2188,
-	0, 0, 0, 0, 0, 0, 2201, 2202, 2208, 2231,
-	2207, 2203, 0, 2200, 2198, 2199, 2191, 2192, 2193, 2194,
-	2196, 2197, 2218, 0, 0, 0, 0, 0, 5906, 2219,
-	0, 4591, 2190, 0, 0, 0, 0, 0, 0, 0,
-	2212, 2213, 2214, 2215, 0, 0, 0, 0, 0, 0,
-	2195, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 2244, 0, 0, 1378, 0,
-	0, 0, 0, 0, 0, 0, 2189, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 2209, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 2206, 2229, 0,
-	5959, 5960, 2239, 872, 0, 0, 0, 0, 0, 0,
-	0, 2217, 2220, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 2235, 0, 2236, 0, 0, 0,
-	0, 0, 0, 2204, 2205, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 2227, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 2210, 0,
-	0, 0, 0, 0, 2212, 2213, 2214, 2215, 0, 6041,
-	0, 0, 0, 0, 2195, 0, 0, 0, 0, 0,
-	872, 0, 872, 0, 0, 0, 872, 0, 6056, 6057,
-	6058, 0, 0, 872, 872, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 3036, 0,
-	2237, 6066, 6067, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 948, 0, 0, 0, 6075, 6078,
-	0, 2226, 0, 0, 0, 2217, 2220, 0, 0, 0,
-	0, 0, 2241, 0, 0, 932, 0, 0, 3036, 0,
-	933, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 872, 0, 0, 0, 0, 2204, 2205, 0,
-	0, 0, 0, 0, 872, 0, 872, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 934,
-	0, 0, 2210, 0, 0, 2216, 0, 0, 0, 0,
-	0, 0, 935, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	2447, 0, 0, 2211, 0, 936, 0, 0, 0, 0,
-	0, 0, 0, 872, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 6171, 333, 333, 0, 0, 954, 0,
-	872, 0, 6179, 0, 0, 0, 0, 2230, 0, 0,
-	2447, 2447, 0, 333, 0, 333, 333, 6187, 0, 333,
-	1378, 0, 0, 0, 937, 0, 2241, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 6200, 2447, 2447, 6202, 0, 0, 2243, 0, 0,
-	938, 929, 0, 0, 0, 0, 0, 0, 6212, 0,
-	0, 0, 0, 6218, 6219, 0, 0, 0, 0, 6221,
-	0, 0, 0, 0, 0, 2447, 0, 0, 939, 0,
-	0, 0, 0, 0, 930, 0, 0, 0, 0, 2216,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 966, 872, 872, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 2211, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 953, 0, 0, 0, 2228, 0, 333, 0,
-	0, 872, 0, 0, 0, 0, 0, 0, 0, 2201,
-	2202, 2208, 2231, 2207, 2203, 0, 2200, 2198, 2199, 2191,
-	2192, 2193, 2194, 2196, 2197, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 4588, 333, 0, 333, 333, 333,
-	333, 0, 0, 333, 333, 0, 0, 0, 0, 0,
-	0, 2243, 0, 0, 0, 0, 2447, 0, 2447, 950,
-	0, 0, 0, 0, 0, 0, 1148, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 872, 0,
-	0, 0, 0, 872, 872, 872, 872, 0, 0, 0,
-	0, 0, 0, 872, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 333, 333, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 961,
-	0, 941, 0, 0, 0, 0, 0, 0, 0, 0,
-	6360, 0, 333, 333, 6364, 0, 0, 2207, 2203, 0,
-	2200, 2198, 2199, 2191, 2192, 2193, 2194, 2196, 2197, 0,
-	0, 0, 962, 931, 0, 0, 942, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 965, 333, 0, 0, 0,
-	0, 0, 0, 943, 0, 0, 2342, 0, 959, 960,
-	0, 957, 0, 0, 6413, 0, 0, 0, 0, 0,
-	951, 0, 0, 944, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 872, 872, 0, 0, 0, 0, 0,
-	0, 872, 0, 0, 872, 872, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 945, 0, 952,
-	0, 3036, 3036, 0, 0, 963, 0, 0, 872, 946,
-	0, 6078, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 947, 0, 0, 0, 0,
-	955, 0, 0, 0, 872, 0, 1736, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 967, 2447,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	949, 0, 0, 0, 0, 0, 0, 964, 0, 0,
-	0, 0, 0, 0, 0, 0, 1378, 0, 0, 2187,
-	2188, 0, 2221, 2222, 2223, 2232, 2233, 2234, 2447, 0,
-	0, 0, 0, 0, 0, 0, 0, 872, 0, 0,
-	872, 0, 2225, 2218, 0, 0, 0, 0, 0, 0,
-	2219, 0, 1871, 2190, 872, 0, 0, 0, 0, 0,
-	0, 1736, 0, 872, 0, 2238, 0, 0, 872, 872,
-	872, 873, 0, 0, 0, 0, 871, 0, 1533, 0,
-	0, 0, 333, 0, 0, 0, 2244, 0, 0, 0,
-	0, 0, 0, 0, 6578, 6578, 6578, 2189, 0, 0,
-	0, 0, 333, 871, 333, 0, 0, 872, 2209, 1736,
-	0, 0, 1148, 0, 0, 0, 0, 0, 2206, 0,
-	872, 1148, 0, 0, 0, 0, 335, 335, 0, 335,
-	0, 2447, 0, 0, 0, 0, 0, 6605, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 335, 0, 0, 1736, 0, 333,
-	0, 0, 0, 335, 0, 0, 0, 1736, 333, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 1736, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 335, 0, 0, 0, 0, 0,
-	0, 0, 6578, 0, 0, 2212, 2213, 2214, 2215, 0,
-	0, 0, 0, 0, 0, 2195, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 872, 0, 0,
-	0, 0, 0, 0, 0, 872, 0, 0, 0, 872,
-	872, 0, 0, 0, 0, 0, 0, 2447, 0, 0,
-	0, 0, 0, 872, 0, 0, 0, 0, 0, 0,
-	0, 872, 0, 2229, 0, 0, 0, 2239, 0, 872,
-	872, 0, 0, 0, 0, 0, 2217, 2220, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 872, 0, 0, 0, 0, 0, 2235,
-	333, 2236, 0, 0, 0, 0, 0, 0, 2204, 2205,
-	0, 948, 0, 1148, 0, 333, 0, 333, 0, 333,
-	0, 0, 333, 0, 333, 0, 0, 0, 2227, 872,
-	872, 0, 932, 0, 0, 0, 0, 933, 0, 0,
-	0, 872, 0, 2210, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 6578, 6766, 0, 0, 0, 0,
-	0, 872, 0, 872, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 333, 333, 333, 333, 0,
-	0, 333, 333, 0, 0, 0, 934, 0, 0, 0,
-	0, 0, 0, 0, 0, 2237, 0, 0, 872, 935,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 2226, 0, 0, 0,
-	0, 0, 936, 0, 0, 0, 0, 2241, 0, 872,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 954, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 937, 0, 0, 1871, 0, 0, 1871, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 872, 872,
-	2216, 0, 0, 0, 0, 0, 0, 938, 929, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 872,
-	0, 0, 0, 1736, 0, 0, 0, 0, 2211, 0,
-	0, 0, 0, 0, 0, 939, 0, 0, 0, 0,
-	0, 930, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 966,
-	872, 0, 2230, 333, 0, 872, 0, 1148, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 953,
-	0, 0, 872, 872, 872, 872, 872, 0, 872, 872,
-	872, 0, 2243, 0, 0, 0, 0, 0, 333, 333,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 333, 0,
-	0, 872, 0, 0, 0, 0, 0, 1871, 0, 333,
-	0, 0, 0, 0, 0, 0, 333, 0, 0, 0,
-	0, 0, 2447, 0, 0, 0, 950, 0, 0, 0,
-	0, 0, 0, 333, 0, 333, 0, 0, 0, 0,
-	1736, 333, 0, 1736, 1736, 1736, 1736, 1736, 0, 0,
-	0, 872, 0, 872, 872, 0, 0, 0, 0, 0,
-	0, 2228, 0, 0, 872, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 2201, 2202, 2208, 2231, 2207, 2203,
-	0, 2200, 2198, 2199, 2191, 2192, 2193, 2194, 2196, 2197,
-	333, 0, 0, 0, 0, 0, 0, 0, 0, 4587,
-	0, 0, 0, 0, 0, 0, 0, 0, 941, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	872, 0, 0, 0, 0, 0, 0, 0, 0, 962,
-	931, 0, 0, 942, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 2447, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 965, 0, 0, 0, 0, 0, 0, 0,
-	943, 0, 0, 0, 0, 959, 960, 0, 957, 872,
-	0, 0, 0, 0, 0, 872, 0, 951, 872, 872,
-	944, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	872, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 945, 0, 952, 0, 872, 0,
-	872, 0, 963, 0, 0, 1533, 946, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	1533, 0, 947, 0, 0, 2447, 0, 955, 0, 0,
-	0, 0, 872, 0, 333, 872, 0, 0, 0, 0,
-	0, 1736, 1736, 0, 0, 967, 0, 0, 0, 0,
-	0, 0, 1871, 0, 0, 0, 0, 949, 0, 0,
-	872, 0, 0, 0, 964, 0, 0, 0, 0, 333,
-	0, 0, 0, 0, 0, 0, 1148, 1736, 1148, 0,
-	0, 333, 333, 0, 0, 2447, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 335, 335, 0, 0, 0, 0, 0, 0,
-	1736, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 335, 0, 335, 335, 0, 333, 335, 0, 1148,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 333,
-	0, 0, 333, 0, 0, 0, 333, 0, 0, 0,
-	0, 0, 0, 0, 333, 333, 1736, 0, 1736, 333,
-	1736, 333, 0, 0, 0, 0, 0, 0, 333, 333,
-	0, 0, 0, 0, 0, 0, 0, 0, 1736, 1736,
-	0, 0, 872, 333, 0, 0, 0, 0, 0, 0,
-	0, 0, 1736, 0, 0, 0, 0, 872, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 1737, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 1871,
-	0, 0, 872, 0, 0, 0, 0, 0, 333, 0,
-	0, 0, 0, 339, 0, 0, 335, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 333, 0, 333, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 333, 872, 0,
-	872, 0, 0, 335, 1737, 335, 335, 335, 335, 0,
-	0, 335, 335, 1737, 0, 0, 0, 0, 0, 872,
-	0, 0, 872, 0, 0, 0, 872, 0, 0, 0,
-	0, 0, 0, 0, 335, 0, 0, 872, 0, 0,
-	0, 0, 0, 1871, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 333, 1138, 0, 0, 0, 0,
-	0, 1737, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 333, 333, 333, 333, 0, 2187, 2188, 0, 2221,
-	2222, 2223, 2232, 2233, 2234, 0, 1138, 0, 333, 335,
-	335, 0, 0, 0, 0, 0, 0, 0, 0, 2225,
-	2218, 0, 0, 0, 0, 0, 0, 2219, 0, 1737,
-	2190, 0, 333, 0, 0, 0, 0, 0, 1871, 1737,
-	335, 335, 2238, 0, 0, 0, 333, 0, 0, 0,
-	0, 0, 0, 872, 0, 1737, 0, 0, 0, 0,
-	333, 0, 1871, 2244, 0, 2447, 0, 0, 0, 0,
-	0, 0, 0, 0, 2189, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 2209, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 2206, 0, 0, 0, 0,
 	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 335, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 333, 0,
 	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 4870, 3451, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 2350,
+	0, 2354, 0, 0, 0, 0, 0, 0, 0, 0,
+	2350, 0, 0, 0, 2324, 2325, 2331, 2357, 2330, 2326,
+	0, 2323, 2321, 2322, 2314, 2315, 2316, 2317, 2319, 2320,
+	0, 0, 2350, 0, 0, 7320, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 2350, 0, 2350, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 2350, 0, 0,
+	0, 0, 0, 2350, 2350, 0, 2350, 0, 2350, 0,
+	2350, 0, 0, 0, 0, 0, 1624, 0, 0, 0,
 	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 923, 0,
 	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 2212, 2213, 2214, 2215, 0, 0, 0, 1148,
-	0, 0, 2195, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 355, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 1217, 2310, 2311, 0, 2347,
+	2348, 2349, 2358, 2359, 2360, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 2351,
+	2341, 0, 0, 0, 0, 0, 0, 2342, 0, 0,
+	2313, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 4870, 2364, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 355, 0, 0, 0, 355,
+	355, 0, 0, 0, 0, 0, 2370, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 2312, 0, 0,
+	0, 0, 0, 0, 0, 0, 2350, 4870, 2332, 0,
+	2350, 0, 0, 0, 0, 0, 0, 0, 2329, 0,
+	0, 0, 0, 0, 2344, 0, 0, 0, 0, 0,
+	0, 0, 2350, 0, 0, 0, 0, 0, 0, 0,
 	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 2350, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 2343, 0,
 	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 333, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 333, 0, 0, 0,
-	2229, 0, 0, 0, 2239, 0, 1871, 0, 0, 0,
-	0, 0, 0, 2217, 2220, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 1736, 1736,
-	0, 0, 0, 0, 0, 0, 2235, 0, 2236, 0,
-	0, 0, 0, 0, 0, 2204, 2205, 0, 0, 0,
-	0, 0, 333, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 872, 0, 872, 2227, 0, 0, 0, 0,
+	0, 2350, 0, 0, 0, 0, 0, 0, 0, 0,
 	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	2210, 0, 0, 333, 0, 0, 0, 0, 0, 0,
-	0, 0, 333, 0, 0, 0, 0, 0, 0, 0,
-	335, 0, 0, 0, 0, 0, 1737, 0, 0, 1737,
+	0, 0, 0, 0, 355, 355, 0, 0, 2335, 2336,
+	2337, 2338, 355, 0, 355, 0, 0, 0, 2318, 0,
 	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	335, 335, 335, 0, 0, 0, 0, 0, 0, 0,
-	335, 1736, 2237, 0, 0, 0, 0, 0, 0, 335,
-	0, 0, 0, 0, 0, 1737, 0, 0, 0, 0,
-	0, 0, 0, 2226, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 2241, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 335, 0, 0,
-	0, 0, 0, 0, 0, 0, 335, 0, 0, 0,
+	0, 0, 355, 0, 0, 0, 0, 0, 0, 0,
 	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 2187, 2188, 0, 2221, 2222,
-	2223, 2232, 2233, 2234, 0, 0, 0, 2216, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 2225, 2218,
-	0, 0, 0, 0, 0, 0, 2219, 0, 0, 2190,
-	0, 0, 0, 0, 0, 2211, 0, 0, 0, 1737,
-	0, 2238, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 1871, 0, 0, 0, 0,
-	0, 0, 2244, 0, 0, 0, 0, 1736, 0, 2230,
-	0, 0, 1737, 2189, 0, 1737, 1737, 1737, 1737, 1737,
-	0, 0, 0, 0, 2209, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 2206, 0, 0, 0, 335, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 2243,
-	0, 335, 0, 335, 0, 335, 0, 335, 0, 0,
-	335, 0, 335, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 2355, 0, 0,
+	0, 0, 2365, 0, 0, 0, 355, 355, 0, 0,
+	355, 2340, 2346, 0, 0, 0, 0, 923, 0, 0,
 	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 1533, 0, 0, 0,
+	0, 0, 355, 0, 0, 2361, 0, 2362, 0, 0,
+	0, 0, 0, 0, 2327, 2328, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 1983, 0, 0, 0,
+	0, 0, 0, 0, 2353, 0, 1983, 0, 0, 0,
 	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 2333, 0, 0, 0, 0, 0, 0, 0, 0,
 	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 335, 335, 335, 335, 0, 0, 335,
-	335, 2212, 2213, 2214, 2215, 0, 0, 0, 0, 0,
-	1736, 2195, 0, 0, 0, 0, 0, 0, 2228, 0,
-	0, 0, 1736, 0, 1736, 0, 0, 0, 0, 1736,
-	0, 2201, 2202, 2208, 2231, 2207, 2203, 0, 2200, 2198,
-	2199, 2191, 2192, 2193, 2194, 2196, 2197, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 4586, 0, 0, 2229,
-	0, 0, 0, 2239, 0, 0, 0, 0, 0, 0,
-	0, 0, 2217, 2220, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 1983, 0, 0, 0,
+	2345, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 2350,
+	0, 0, 0, 0, 0, 0, 0, 0, 2363, 0,
 	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 2235, 0, 2236, 0, 0,
-	0, 0, 0, 0, 2204, 2205, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 2350, 0,
+	2352, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 2367, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 355, 0, 0,
 	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 2227, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 2210,
+	0, 0, 1217, 0, 0, 0, 0, 0, 2350, 0,
+	355, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 355, 0,
 	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	2339, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 355, 0, 0, 0, 0, 0, 0, 0,
 	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	2334, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 1983, 0, 0, 1983,
 	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 335, 0, 1737, 1737, 335, 0, 0, 0, 0,
-	0, 0, 0, 0, 1737, 0, 0, 0, 0, 0,
-	0, 2237, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 1737,
-	0, 0, 2226, 0, 0, 0, 335, 335, 0, 0,
-	0, 0, 0, 2241, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 335, 0, 0, 0,
-	0, 0, 1737, 0, 0, 0, 0, 335, 0, 0,
-	0, 0, 0, 0, 335, 0, 0, 0, 0, 0,
+	0, 0, 0, 1751, 2356, 0, 0, 0, 0, 0,
 	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 335, 0, 335, 0, 0, 0, 0, 0, 335,
-	1735, 0, 0, 0, 0, 0, 2216, 0, 1737, 0,
-	1737, 0, 1737, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 355,
+	0, 0, 1468, 1468, 1468, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 2350, 2350, 2369, 0,
 	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	1737, 1737, 0, 0, 2211, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 1737, 0, 0, 0, 335, 0,
 	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 2230, 0,
-	0, 0, 0, 0, 0, 0, 1870, 0, 0, 0,
-	0, 1737, 1871, 0, 0, 1735, 0, 0, 0, 0,
 	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 2243, 0,
 	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 2350, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 1894,
+	0, 0, 1900, 0, 0, 0, 0, 0, 0, 0,
 	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 1735, 0, 0, 0, 0, 0, 0,
+	0, 1983, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 2354, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 2324, 2325, 2331, 2357, 2330, 2326,
+	0, 2323, 2321, 2322, 2314, 2315, 2316, 2317, 2319, 2320,
+	2080, 0, 0, 0, 0, 7319, 0, 2100, 2102, 0,
+	0, 0, 0, 0, 1624, 1624, 0, 0, 0, 0,
 	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	2129, 0, 2134, 0, 2140, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 1657, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 1657, 0, 0,
+	1657, 0, 0, 1983, 0, 0, 0, 0, 0, 0,
+	1657, 1657, 0, 0, 0, 0, 0, 0, 0, 0,
 	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 1737, 0, 0, 0, 0,
-	0, 1735, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 1735, 0, 0, 0, 0, 0, 2228, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 1735, 0, 0,
-	2201, 2202, 2208, 2231, 2207, 2203, 0, 2200, 2198, 2199,
-	2191, 2192, 2193, 2194, 2196, 2197, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 3161, 0, 0, 0, 0,
+	0, 0, 0, 1217, 0, 0, 0, 0, 355, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 355,
+	0, 0, 0, 0, 0, 0, 0, 2247, 0, 2252,
 	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	1737, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 2264, 0, 2269, 0, 0, 355, 0,
+	0, 0, 0, 0, 0, 2310, 2311, 0, 2347, 2348,
+	2349, 2358, 2359, 2360, 1657, 0, 0, 0, 0, 0,
+	0, 0, 1657, 0, 0, 0, 0, 0, 2351, 2341,
+	0, 0, 0, 0, 0, 0, 2342, 0, 0, 2313,
 	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 335, 0, 1737, 0, 0, 0, 0, 0,
-	1533, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 335, 0, 0,
-	0, 0, 871, 0, 335, 0, 335, 0, 0, 335,
-	335, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 333, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 1148, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 335, 0, 0, 335, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 335, 0, 0,
-	335, 0, 1737, 0, 335, 0, 0, 0, 0, 0,
-	0, 0, 335, 335, 0, 0, 0, 335, 0, 335,
-	0, 0, 0, 0, 333, 0, 335, 335, 333, 333,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 335, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 1737, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 335, 0, 0, 0,
-	1737, 1737, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 1870, 0,
-	0, 1870, 335, 0, 335, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 335, 0, 0, 0, 0,
-	0, 0, 2419, 0, 0, 333, 0, 0, 0, 0,
-	0, 2419, 333, 0, 333, 0, 0, 1735, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 333, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 335, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 1737, 0, 0, 0, 0, 0, 335,
-	335, 335, 335, 0, 333, 333, 0, 0, 333, 0,
-	0, 0, 0, 0, 0, 871, 335, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 333,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	335, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 335, 0, 0, 0, 0, 0,
-	0, 1870, 0, 0, 0, 0, 0, 0, 335, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 1735, 0, 0, 1735, 1735, 1735,
-	1735, 1735, 0, 0, 0, 0, 0, 0, 0, 0,
-	1871, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	1871, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 2419, 0, 0, 335, 1737, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 1737,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 1871,
-	0, 0, 0, 0, 0, 2187, 2188, 0, 2221, 2222,
-	2223, 2232, 2233, 2234, 0, 333, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 2225, 2218,
-	1148, 0, 0, 0, 0, 0, 2219, 335, 0, 2190,
-	0, 0, 0, 0, 0, 333, 0, 0, 0, 0,
-	0, 2238, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 333,
-	0, 0, 2244, 0, 335, 0, 0, 0, 0, 0,
-	0, 0, 0, 2189, 335, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 2209, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 2206, 0, 0, 0, 0, 0,
-	0, 0, 1737, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 1737, 0, 1737, 0, 0, 0,
-	0, 1737, 0, 0, 0, 0, 0, 0, 0, 0,
-	335, 0, 0, 0, 0, 0, 0, 0, 333, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 1871, 0, 0, 1871,
-	0, 335, 0, 0, 0, 0, 0, 0, 0, 0,
-	335, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 2212, 2213, 2214, 2215, 0, 0, 0, 0, 0,
-	0, 2195, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 1735, 1735, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 1870, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 2229,
-	0, 1735, 0, 2239, 0, 0, 0, 0, 0, 0,
-	0, 0, 2217, 2220, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 1735, 2235, 0, 2236, 0, 0,
-	0, 0, 0, 0, 2204, 2205, 0, 0, 0, 0,
-	0, 0, 1533, 1533, 0, 0, 0, 0, 1871, 0,
-	0, 0, 0, 0, 2227, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 2210,
-	1735, 0, 1735, 0, 1735, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 1735, 1735, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 1735, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 2237, 0, 0, 0, 0, 0, 0, 1148, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 2226, 1870, 0, 1736, 0, 1736, 0, 0,
-	0, 1871, 0, 2241, 0, 0, 0, 0, 1736, 1736,
-	0, 0, 0, 0, 0, 0, 333, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 1737, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 2216, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 1736, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 1870, 0, 1736,
-	0, 1736, 0, 0, 2211, 0, 0, 0, 0, 0,
+	0, 0, 2364, 0, 0, 0, 0, 0, 0, 0,
 	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 2370, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 2312, 0, 0, 1983,
+	0, 0, 0, 0, 0, 0, 0, 2332, 0, 0,
+	0, 0, 0, 0, 0, 0, 1983, 2329, 0, 0,
+	0, 0, 0, 2344, 0, 0, 0, 0, 0, 0,
 	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 2230, 0,
+	0, 0, 0, 0, 0, 0, 2371, 2372, 2373, 2374,
+	2375, 2376, 2377, 2378, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 2343, 0, 0,
 	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	2391, 0, 0, 0, 0, 0, 2404, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 355,
+	0, 0, 0, 0, 0, 0, 0, 2335, 2336, 2337,
+	2338, 0, 0, 0, 0, 0, 0, 2318, 0, 0,
 	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 1871, 0,
-	0, 0, 1870, 0, 0, 0, 0, 0, 2243, 0,
-	0, 0, 0, 0, 0, 1871, 0, 2187, 2188, 0,
-	2221, 2222, 2223, 2232, 2233, 2234, 1870, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 333, 0,
-	2225, 2218, 0, 0, 0, 0, 0, 0, 2219, 0,
-	0, 2190, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 2238, 0, 0, 0, 0, 0, 0,
 	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 2244, 0, 0, 0, 0, 0,
-	0, 0, 0, 333, 0, 2189, 0, 2228, 0, 0,
-	0, 0, 0, 0, 0, 0, 2209, 0, 0, 0,
-	2201, 2202, 2208, 2231, 2207, 2203, 2206, 2200, 2198, 2199,
-	2191, 2192, 2193, 2194, 2196, 2197, 0, 0, 0, 0,
-	0, 6491, 0, 0, 333, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 333, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 1871, 333, 0, 0,
-	0, 333, 0, 333, 0, 0, 0, 0, 0, 0,
-	333, 0, 0, 0, 0, 0, 0, 0, 0, 1533,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 1533, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 2212, 2213, 2214, 2215, 0, 0, 0,
-	1870, 0, 0, 2195, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 1735, 1735, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 1736, 0, 0, 0, 0, 1736, 1736,
-	1736, 1736, 0, 0, 0, 0, 0, 0, 1871, 0,
-	0, 2229, 0, 0, 0, 2239, 0, 0, 0, 0,
-	0, 0, 0, 0, 2217, 2220, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 2235, 0, 2236,
-	0, 0, 0, 0, 0, 0, 2204, 2205, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 2227, 0, 0, 0,
-	0, 0, 0, 0, 0, 1735, 0, 0, 0, 0,
-	0, 2210, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 1533, 0, 0, 0,
-	0, 0, 0, 0, 1533, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 871, 2237, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 2226, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 2241, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 1736, 1736,
-	0, 333, 0, 0, 0, 0, 1736, 0, 0, 1736,
-	1736, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 1736, 0, 0, 0, 0, 0, 1870,
-	0, 0, 0, 0, 0, 0, 0, 0, 2216, 0,
-	0, 1735, 0, 0, 0, 0, 0, 0, 0, 1736,
-	871, 0, 871, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 1737, 0, 0, 0, 2211, 0, 0, 0,
-	0, 0, 1737, 0, 333, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 335, 0, 0, 0, 0, 0,
-	333, 0, 0, 333, 0, 0, 335, 0, 0, 0,
-	2230, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 1737, 1736, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 333, 0,
-	0, 0, 0, 0, 0, 1737, 0, 0, 1736, 0,
-	2243, 0, 0, 1736, 1736, 1736, 0, 0, 0, 0,
-	0, 0, 335, 0, 0, 0, 335, 335, 0, 0,
-	0, 0, 0, 0, 1735, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 1735, 0, 1735, 0,
-	0, 0, 1736, 1735, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 1871, 0, 0, 871, 0,
 	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 333, 0, 0, 2228,
+	1983, 0, 0, 0, 0, 355, 2355, 0, 0, 0,
+	0, 2365, 0, 0, 0, 0, 2470, 2470, 2470, 0,
+	2340, 2346, 0, 0, 0, 0, 0, 0, 0, 0,
 	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	333, 0, 2201, 2202, 2208, 2231, 2207, 2203, 0, 2200,
-	2198, 2199, 2191, 2192, 2193, 2194, 2196, 2197, 0, 0,
-	0, 0, 0, 6379, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 335, 0, 0, 0, 0, 1737, 0,
-	335, 1737, 335, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 2361, 0, 2362, 0, 0, 0,
+	0, 0, 0, 2327, 2328, 0, 0, 0, 355, 0,
 	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	335, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 1871, 1871, 0, 0, 0, 0,
+	355, 0, 0, 2353, 0, 0, 0, 0, 0, 0,
+	0, 0, 355, 0, 0, 0, 355, 0, 355, 0,
+	2333, 0, 0, 0, 0, 355, 1657, 1657, 0, 0,
+	0, 0, 1657, 1657, 1657, 1657, 0, 0, 0, 0,
+	1983, 0, 1624, 0, 0, 0, 0, 0, 0, 2345,
+	0, 0, 0, 0, 0, 0, 1624, 0, 0, 0,
 	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 1871, 0, 0, 0,
-	0, 0, 335, 335, 1736, 1736, 335, 0, 0, 0,
-	0, 0, 0, 335, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 335, 1871, 0,
+	0, 0, 0, 0, 0, 0, 0, 2363, 0, 0,
+	0, 2653, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 2352,
 	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	2367, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 1736, 1736, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 1871, 0, 0, 0,
-	1737, 333, 333, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 333,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 1871, 0, 0, 0, 0, 0, 0,
+	0, 1468, 0, 0, 0, 0, 0, 0, 0, 0,
 	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 1871, 0, 0, 0, 0, 0,
-	0, 0, 0, 335, 0, 0, 1870, 1737, 0, 1737,
-	0, 0, 0, 1737, 0, 0, 0, 0, 335, 0,
-	1737, 1737, 0, 0, 0, 0, 0, 1737, 1737, 0,
-	0, 0, 0, 335, 333, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 1736, 1736, 0, 0, 335, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 871, 0, 871,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 1737,
-	0, 0, 333, 0, 0, 0, 0, 0, 0, 0,
-	0, 1737, 0, 1737, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 1871, 0, 0, 0, 0,
-	1736, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 335, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 1736, 1736, 1736,
-	1736, 1736, 0, 1736, 1736, 1736, 0, 0, 0, 0,
 	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	1737, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 1871, 1737, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 2339,
 	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 1624, 0, 0, 0, 0,
+	0, 0, 0, 1624, 0, 0, 0, 0, 0, 2334,
 	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 923, 0, 0, 0, 0, 0, 0, 0, 1657,
+	1657, 0, 0, 0, 0, 0, 0, 0, 2790, 1657,
+	0, 0, 0, 2356, 0, 0, 1657, 1657, 0, 0,
 	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 2187, 2188, 0, 2221, 2222, 2223, 2232,
-	2233, 2234, 0, 0, 0, 0, 1736, 0, 1736, 1736,
-	0, 0, 0, 0, 0, 0, 2225, 2218, 0, 1736,
-	0, 0, 0, 0, 2219, 0, 0, 2190, 0, 0,
-	0, 871, 0, 0, 0, 0, 0, 0, 0, 2238,
-	0, 0, 0, 0, 0, 0, 871, 0, 0, 0,
 	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	2244, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 2189, 0, 0, 333, 0, 0, 0, 0, 0,
-	0, 0, 2209, 0, 0, 1871, 0, 0, 0, 0,
-	0, 0, 2206, 0, 0, 0, 0, 0, 1737, 0,
+	355, 0, 0, 1657, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 2369, 2833, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 1657,
 	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 871, 0, 871,
 	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 335, 0, 871, 0,
-	333, 871, 1737, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 1871, 0, 0, 0, 0, 0,
-	1736, 0, 0, 1736, 1736, 0, 0, 0, 0, 2212,
-	2213, 2214, 2215, 0, 335, 1737, 0, 0, 0, 2195,
-	1737, 1737, 1737, 1737, 0, 0, 0, 0, 0, 0,
-	1737, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 1736, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 923, 0, 923,
 	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 2229, 0, 0,
-	0, 2239, 0, 0, 0, 0, 333, 0, 0, 0,
-	2217, 2220, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 1871, 0, 0,
-	1736, 0, 0, 2235, 0, 2236, 0, 0, 0, 0,
-	0, 0, 2204, 2205, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 1736, 0, 0, 0, 0,
-	0, 0, 2227, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 333, 2210, 0, 0,
 	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 355, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 1657,
+	2354, 0, 0, 355, 0, 0, 0, 355, 0, 0,
+	0, 0, 0, 2324, 2325, 2331, 2357, 2330, 2326, 0,
+	2323, 2321, 2322, 2314, 2315, 2316, 2317, 2319, 2320, 0,
+	0, 1657, 0, 0, 6970, 0, 1657, 1657, 1657, 0,
+	0, 1657, 355, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 1983, 0, 0, 0, 0, 0,
 	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 335, 0, 0, 2237,
 	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	1737, 1737, 0, 0, 0, 0, 0, 0, 1737, 0,
-	2226, 1737, 1737, 0, 1870, 0, 333, 0, 0, 0,
-	0, 2241, 0, 0, 1870, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 1737, 0, 0, 0, 0,
-	0, 335, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 1737, 0, 1870, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 335, 0, 2216, 0, 0, 1736, 0, 0,
-	0, 0, 0, 335, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 335, 0, 0, 0, 335,
-	0, 335, 2211, 0, 0, 0, 0, 0, 335, 0,
-	0, 0, 0, 0, 1737, 0, 0, 0, 0, 0,
-	0, 871, 0, 871, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 2230, 0, 0, 0,
-	1737, 0, 0, 0, 0, 1737, 1737, 1737, 0, 0,
-	0, 1736, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 1736, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 2243, 0, 0, 0,
-	0, 0, 0, 0, 1737, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 1737, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	1870, 0, 0, 1870, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 1736, 0,
-	0, 0, 0, 0, 0, 2228, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 2201, 2202,
-	2208, 2231, 2207, 2203, 0, 2200, 2198, 2199, 2191, 2192,
-	2193, 2194, 2196, 2197, 0, 0, 0, 0, 0, 6317,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 1737, 1737, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 1737, 0,
-	0, 0, 0, 0, 0, 0, 1737, 1737, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 1870, 0, 0, 0, 0, 0, 0, 0,
-	1737, 0, 0, 0, 0, 0, 0, 0, 0, 335,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 1737, 1737, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 1737, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 1735,
-	0, 1735, 335, 0, 0, 1870, 0, 0, 0, 0,
-	1138, 0, 1735, 1735, 0, 1737, 0, 0, 335, 0,
-	0, 335, 0, 0, 2187, 2188, 0, 2221, 2222, 2223,
-	2232, 2233, 2234, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 1737, 2225, 2218, 0,
-	0, 0, 0, 0, 0, 2219, 335, 0, 2190, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	2238, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 1735, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 2244, 0, 1735, 0, 1735, 0, 0, 0, 0,
-	0, 0, 2189, 0, 0, 1737, 1737, 0, 0, 0,
-	0, 0, 0, 2209, 1737, 0, 0, 0, 0, 0,
-	0, 0, 0, 2206, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 335, 0, 0, 0, 0, 0,
-	0, 0, 1870, 0, 0, 0, 0, 1737, 335, 0,
-	0, 0, 1737, 0, 0, 0, 0, 0, 0, 1870,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 1737,
-	1737, 1737, 1737, 1737, 0, 1737, 1737, 1737, 0, 0,
-	2212, 2213, 2214, 2215, 0, 0, 0, 0, 0, 0,
-	2195, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 1737, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 2229, 0,
-	0, 0, 2239, 0, 0, 0, 0, 0, 0, 0,
-	0, 2217, 2220, 0, 0, 0, 0, 0, 1737, 0,
-	1737, 1737, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 1737, 0, 0, 2235, 0, 2236, 0, 0, 0,
-	0, 0, 0, 2204, 2205, 0, 0, 0, 0, 0,
-	1870, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 2227, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 2210, 335,
-	335, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 1737, 2419, 0,
-	0, 0, 0, 0, 0, 0, 0, 335, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	2237, 0, 0, 0, 0, 0, 0, 1735, 0, 0,
-	0, 0, 1735, 1735, 1735, 1735, 0, 0, 0, 0,
-	0, 2226, 1870, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 2241, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 1737, 0, 0, 0,
-	0, 0, 1737, 0, 0, 1737, 1737, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 335, 0, 0, 0, 0, 0, 0, 0,
-	2187, 2188, 0, 2221, 2222, 2223, 2232, 2233, 2234, 0,
-	0, 0, 0, 0, 0, 2216, 0, 1737, 0, 0,
-	0, 0, 0, 2225, 2218, 0, 0, 0, 0, 0,
-	0, 2219, 0, 0, 2190, 0, 0, 0, 0, 0,
-	0, 0, 0, 2211, 0, 0, 2238, 0, 0, 0,
-	335, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 2244, 0, 1737,
-	0, 0, 1737, 0, 0, 0, 0, 2230, 2189, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 2209,
-	0, 0, 0, 0, 0, 0, 0, 1737, 0, 2206,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 2243, 0, 0,
-	0, 0, 1735, 1735, 0, 0, 0, 0, 0, 0,
-	1735, 0, 0, 1735, 1735, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 1735, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 2187, 2188, 0, 2221, 2222, 2223, 2232, 2233, 2234,
-	0, 0, 0, 1735, 0, 0, 2212, 2213, 2214, 2215,
-	0, 0, 0, 0, 2225, 2218, 2195, 0, 0, 0,
-	0, 0, 2219, 0, 0, 2190, 2228, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 2238, 0, 2201,
-	2202, 2208, 2231, 2207, 2203, 0, 2200, 2198, 2199, 2191,
-	2192, 2193, 2194, 2196, 2197, 0, 0, 0, 2244, 0,
-	6316, 0, 0, 0, 2229, 0, 1735, 0, 2239, 2189,
-	0, 0, 0, 0, 0, 0, 0, 2217, 2220, 0,
-	2209, 0, 335, 0, 0, 0, 0, 0, 0, 1737,
-	2206, 0, 1735, 0, 0, 0, 0, 1735, 1735, 1735,
-	2235, 0, 2236, 0, 0, 0, 0, 0, 0, 2204,
-	2205, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 2227,
-	0, 0, 0, 0, 0, 0, 1735, 0, 0, 0,
-	0, 0, 0, 0, 2210, 0, 0, 0, 0, 1870,
-	0, 0, 0, 0, 0, 0, 0, 0, 335, 0,
-	0, 0, 0, 1737, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 1737, 0, 0, 2212, 2213, 2214,
-	2215, 0, 0, 0, 0, 0, 0, 2195, 0, 0,
-	0, 0, 0, 0, 0, 0, 2237, 0, 0, 0,
 	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 2226, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 2241, 0,
-	0, 0, 0, 0, 0, 2229, 0, 0, 0, 2239,
-	0, 0, 0, 0, 0, 0, 0, 0, 2217, 2220,
-	0, 0, 0, 0, 335, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 1870, 1870,
-	1737, 2235, 0, 2236, 0, 0, 0, 0, 0, 0,
-	2204, 2205, 0, 0, 0, 0, 0, 0, 0, 0,
-	1870, 2216, 0, 0, 0, 0, 0, 0, 1735, 1735,
-	2227, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 2210, 0, 0, 0, 2211,
-	0, 0, 1870, 0, 335, 0, 0, 0, 0, 0,
+	355, 0, 0, 0, 0, 0, 0, 0, 355, 0,
+	0, 0, 0, 0, 355, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 923, 0, 0, 0, 0,
 	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 2230, 0, 0, 0, 0, 1735, 1735,
-	0, 0, 0, 0, 0, 0, 0, 2237, 0, 0,
-	1870, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 2226, 0,
-	0, 0, 0, 2243, 0, 0, 0, 0, 0, 2241,
-	0, 0, 0, 0, 335, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 355, 0, 0, 0, 0,
+	0, 0, 0, 1983, 1983, 0, 0, 0, 0, 355,
+	0, 355, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 1983, 0, 0, 0, 0,
+	0, 0, 0, 1657, 1657, 0, 0, 0, 0, 0,
 	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 1870, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 1983, 0, 0,
 	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 2187, 2188, 0,
-	2221, 2222, 2223, 2232, 2233, 2234, 0, 0, 1870, 0,
-	0, 0, 2216, 0, 0, 0, 0, 0, 0, 0,
-	2225, 2218, 0, 0, 0, 0, 0, 0, 2219, 0,
-	0, 2190, 2228, 0, 0, 0, 0, 0, 0, 0,
-	2211, 0, 0, 2238, 0, 2201, 2202, 2208, 2231, 2207,
-	2203, 0, 2200, 2198, 2199, 2191, 2192, 2193, 2194, 2196,
-	2197, 0, 0, 0, 2244, 0, 6063, 1735, 1735, 0,
-	0, 0, 0, 0, 2230, 2189, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 2209, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 2206, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 2243, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 1870,
-	0, 0, 0, 0, 1735, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 1735, 1735, 1735, 1735, 1735, 0, 1735, 1735, 1735,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 2212, 2213, 2214, 2215, 0, 0, 0,
-	0, 0, 0, 2195, 0, 0, 0, 0, 0, 0,
-	1870, 0, 0, 2228, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 2201, 2202, 2208, 2231,
-	2207, 2203, 0, 2200, 2198, 2199, 2191, 2192, 2193, 2194,
-	2196, 2197, 0, 0, 0, 0, 0, 5852, 0, 0,
-	0, 2229, 0, 0, 0, 2239, 0, 0, 0, 0,
-	1735, 0, 1735, 1735, 2217, 2220, 0, 0, 0, 0,
-	0, 0, 0, 1735, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 2235, 0, 2236,
-	0, 0, 0, 0, 0, 0, 2204, 2205, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 2227, 0, 0, 0,
 	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 2210, 0, 0, 0, 0, 0, 0, 0, 1870,
 	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 3175, 0, 3179, 0, 0, 0, 0, 0, 0,
+	3194, 0, 0, 1468, 0, 0, 0, 0, 1983, 3205,
+	3206, 3207, 3208, 3209, 3210, 3211, 3212, 3213, 3214, 3215,
+	3216, 3217, 3218, 3219, 3220, 3221, 3222, 3223, 3224, 3225,
+	3226, 3227, 3228, 3229, 3230, 3231, 3232, 3233, 3234, 3235,
+	3236, 3237, 3238, 3239, 3240, 3241, 3242, 3243, 3244, 0,
+	3250, 0, 3252, 3253, 3254, 3255, 0, 0, 0, 0,
 	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 1983, 0, 3279, 0,
+	0, 0, 0, 355, 355, 0, 0, 0, 0, 0,
+	2391, 0, 0, 0, 3328, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 1983, 0,
+	3358, 3361, 3364, 3367, 0, 355, 3373, 3374, 3375, 3376,
+	3377, 3378, 3379, 2310, 2311, 0, 2347, 2348, 2349, 2358,
+	2359, 2360, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 2351, 2341, 3443, 0,
+	3454, 3456, 3461, 0, 2342, 0, 0, 2313, 0, 0,
 	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	2364, 0, 0, 0, 0, 0, 0, 0, 0, 1657,
+	0, 0, 0, 1657, 1657, 0, 0, 0, 0, 0,
+	0, 0, 0, 2370, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 2312, 0, 0, 0, 0, 4141,
+	0, 0, 0, 0, 0, 2332, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 2329, 0, 0, 0, 0,
+	0, 2344, 0, 0, 355, 0, 0, 0, 0, 0,
 	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 2237, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 1983, 0, 0, 0, 0, 0,
+	0, 1657, 0, 0, 0, 0, 1657, 1657, 0, 0,
+	0, 0, 0, 0, 0, 2343, 0, 0, 0, 0,
 	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 2226, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 2241, 0, 0, 1870, 0,
-	0, 0, 0, 0, 1735, 0, 0, 1735, 1735, 0,
+	923, 0, 923, 0, 923, 0, 0, 0, 0, 0,
 	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 2335, 2336, 2337, 2338, 1983,
+	0, 0, 0, 0, 0, 2318, 0, 0, 0, 0,
 	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 1735,
-	0, 0, 0, 0, 0, 0, 0, 0, 2216, 0,
 	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 1657,
+	0, 1657, 1657, 0, 2355, 0, 0, 0, 0, 2365,
+	0, 0, 1657, 0, 0, 0, 0, 0, 2340, 2346,
 	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 2211, 0, 0, 0,
+	2310, 2311, 0, 2347, 2348, 2349, 2358, 2359, 2360, 0,
+	0, 0, 2361, 0, 2362, 0, 0, 0, 0, 0,
+	0, 2327, 2328, 2351, 2341, 0, 0, 0, 0, 0,
+	0, 2342, 0, 0, 2313, 0, 0, 0, 0, 0,
+	0, 2353, 0, 0, 0, 0, 0, 2364, 0, 0,
+	0, 1983, 0, 0, 0, 0, 0, 0, 2333, 0,
 	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 1870, 0, 0, 1735, 0, 0, 0, 0, 0,
+	2370, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 2312, 4338, 0, 0, 0, 0, 2345, 4340, 0,
+	0, 0, 2332, 0, 0, 0, 0, 0, 0, 0,
+	923, 0, 2329, 0, 0, 0, 0, 0, 2344, 0,
+	0, 0, 0, 0, 0, 2363, 0, 0, 0, 0,
 	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	2230, 0, 0, 0, 0, 0, 0, 0, 0, 1735,
+	0, 0, 923, 0, 0, 0, 0, 2352, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 1983, 2367, 0,
+	0, 0, 2343, 1657, 0, 0, 1657, 1657, 0, 0,
+	355, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 2335, 2336, 2337, 2338, 0, 0, 0, 0,
+	0, 0, 2318, 0, 0, 0, 0, 0, 0, 0,
+	0, 1657, 0, 0, 0, 0, 0, 2339, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 923, 0, 923,
+	0, 923, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 2334, 0, 0,
+	923, 2355, 355, 923, 0, 923, 2365, 0, 0, 0,
+	0, 0, 0, 0, 0, 2340, 2346, 0, 0, 0,
+	0, 0, 1983, 0, 1983, 0, 0, 1657, 0, 0,
+	0, 2356, 0, 0, 0, 0, 0, 0, 0, 2361,
+	0, 2362, 0, 0, 0, 0, 0, 0, 2327, 2328,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 2353, 0,
+	0, 0, 0, 0, 0, 2369, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 2333, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 4624, 0, 4626, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 355, 2345, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 2363, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 2352, 0, 0, 1657, 2354, 0,
+	0, 0, 0, 0, 0, 2367, 0, 0, 0, 0,
+	0, 2324, 2325, 2331, 2357, 2330, 2326, 0, 2323, 2321,
+	2322, 2314, 2315, 2316, 2317, 2319, 2320, 0, 0, 0,
+	0, 0, 6936, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 355, 0, 355, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 2371, 2372, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 1468, 2339, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 2310, 2311, 0, 2347, 2348, 2349,
+	2358, 2359, 2360, 1657, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 2334, 0, 0, 2351, 2341, 0,
+	0, 0, 0, 0, 0, 2342, 0, 0, 2313, 0,
+	4760, 4761, 0, 0, 0, 0, 4767, 0, 0, 0,
+	0, 2364, 0, 0, 0, 0, 0, 0, 2356, 0,
+	0, 0, 0, 0, 0, 4781, 4782, 0, 0, 0,
+	0, 3328, 0, 0, 2370, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 2312, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 2332, 0, 0, 0,
+	0, 0, 2369, 0, 0, 1657, 2329, 0, 0, 0,
+	0, 0, 2344, 0, 0, 0, 0, 1657, 0, 0,
+	0, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 0, 0,
+	0, 4799, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 4811, 0, 0,
+	0, 0, 0, 0, 0, 0, 2343, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 355, 0, 0, 0, 2354, 2335, 2336, 2337, 2338,
+	0, 0, 0, 0, 0, 0, 2318, 0, 2324, 2325,
+	2331, 2357, 2330, 2326, 0, 2323, 2321, 2322, 2314, 2315,
+	2316, 2317, 2319, 2320, 0, 0, 0, 0, 0, 6932,
+	0, 1657, 0, 0, 0, 0, 923, 0, 923, 0,
+	923, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 3461, 3461, 3461, 2355, 0, 0, 0, 0,
+	2365, 0, 0, 0, 0, 0, 0, 0, 0, 2340,
+	2346, 0, 2470, 0, 3242, 3243, 3244, 3250, 0, 0,
+	0, 0, 0, 0, 2310, 2311, 0, 2347, 2348, 2349,
+	2358, 2359, 2360, 2361, 0, 2362, 0, 0, 0, 0,
+	0, 0, 2327, 2328, 0, 923, 0, 2351, 2341, 0,
+	0, 0, 0, 0, 0, 2342, 0, 0, 2313, 0,
+	0, 0, 2353, 0, 0, 0, 0, 0, 0, 0,
+	0, 2364, 1657, 0, 0, 0, 0, 0, 0, 2333,
 	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	2243, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 2370, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 2312, 0, 0, 2345, 0,
+	0, 0, 0, 0, 0, 0, 2332, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 2329, 0, 0, 0,
+	0, 0, 2344, 0, 0, 0, 2363, 0, 0, 0,
 	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	355, 0, 0, 0, 1657, 1657, 1657, 1657, 2352, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 2367,
+	0, 0, 0, 0, 0, 0, 2343, 0, 0, 0,
 	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 2335, 2336, 2337, 2338,
+	0, 0, 0, 0, 0, 0, 2318, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 2339, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 2334, 0,
+	0, 0, 0, 0, 0, 2355, 0, 0, 0, 0,
+	2365, 0, 0, 0, 0, 0, 0, 0, 0, 2340,
+	2346, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 2356, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 2361, 0, 2362, 0, 0, 0, 0,
+	0, 0, 2327, 2328, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 2353, 0, 0, 0, 2369, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 2333,
 	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 1657, 1657,
+	0, 0, 1657, 0, 1657, 1657, 0, 0, 2345, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 2363, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 2352, 2354,
+	0, 0, 0, 0, 0, 0, 0, 1657, 0, 2367,
+	0, 0, 2324, 2325, 2331, 2357, 2330, 2326, 0, 2323,
+	2321, 2322, 2314, 2315, 2316, 2317, 2319, 2320, 0, 0,
+	0, 0, 0, 6802, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 1983, 0, 0,
+	0, 0, 0, 2310, 2311, 0, 2347, 2348, 2349, 2358,
+	2359, 2360, 0, 0, 0, 0, 0, 0, 2339, 0,
+	0, 0, 0, 0, 0, 0, 2351, 2341, 0, 0,
+	0, 0, 0, 0, 2342, 0, 0, 2313, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 1983, 2334, 0,
+	2364, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 2370, 0, 0, 0, 0, 0, 0,
+	0, 0, 2356, 0, 2312, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 2332, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 2329, 0, 0, 0, 0,
+	0, 2344, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 2369, 4909, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 2343, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 4909, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 2335, 2336, 2337, 2338, 0,
+	0, 0, 0, 0, 0, 2318, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 2354,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 2324, 2325, 2331, 2357, 2330, 2326, 0, 2323,
+	2321, 2322, 2314, 2315, 2316, 2317, 2319, 2320, 0, 0,
+	0, 0, 0, 6776, 2355, 0, 0, 0, 0, 2365,
+	0, 0, 0, 0, 0, 0, 0, 0, 2340, 2346,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 1468, 0, 0, 0, 0, 0,
+	0, 0, 2361, 0, 2362, 0, 1468, 0, 0, 0,
+	0, 2327, 2328, 0, 0, 0, 0, 0, 0, 0,
 	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 2228,
+	0, 2353, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 2333, 0,
+	0, 2310, 2311, 0, 2347, 2348, 2349, 2358, 2359, 2360,
 	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 2201, 2202, 2208, 2231, 2207, 2203, 0, 2200,
-	2198, 2199, 2191, 2192, 2193, 2194, 2196, 2197, 0, 0,
-	0, 0, 0, 5719, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 2351, 2341, 0, 2345, 0, 0,
+	0, 0, 2342, 0, 0, 2313, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 2364, 0,
+	0, 0, 0, 0, 0, 2363, 0, 0, 0, 0,
 	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 1735, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 2370, 0, 0, 0, 0, 0, 2352, 0, 0,
+	0, 0, 2312, 0, 0, 0, 0, 0, 2367, 0,
+	0, 0, 0, 2332, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 2329, 0, 0, 0, 0, 0, 2344,
+	0, 0, 0, 5147, 0, 0, 0, 0, 0, 0,
 	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 2343, 0, 0, 0, 2339, 0, 0,
 	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 2334, 0, 0,
+	0, 0, 0, 2335, 2336, 2337, 2338, 0, 5222, 5223,
+	0, 0, 0, 2318, 0, 0, 0, 0, 0, 0,
 	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 1735, 1868, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 1735, 0, 0, 0,
-	0, 0, 0, 345, 346, 348, 347, 349, 350, 351,
-	352, 1873, 353, 354, 1874, 1875, 1876, 0, 1877, 805,
-	1878, 1879, 1880, 356, 0, 355, 1881, 357, 358, 359,
-	874, 360, 361, 362, 363, 364, 365, 366, 367, 806,
-	807, 0, 368, 808, 369, 809, 1882, 810, 370, 371,
-	372, 373, 374, 375, 376, 377, 378, 379, 1883, 1884,
-	0, 380, 811, 812, 813, 1885, 381, 382, 383, 384,
-	814, 1886, 875, 1887, 385, 386, 387, 388, 389, 390,
-	391, 392, 0, 1888, 394, 395, 396, 393, 397, 398,
-	1889, 399, 1735, 400, 401, 402, 403, 404, 405, 406,
-	1890, 407, 408, 409, 876, 410, 411, 412, 1891, 1892,
-	1894, 1893, 1895, 1896, 1897, 413, 414, 415, 416, 417,
-	0, 418, 420, 421, 815, 422, 816, 1898, 425, 427,
-	419, 423, 1899, 426, 424, 428, 429, 1900, 430, 431,
-	432, 433, 1901, 1902, 434, 435, 436, 1903, 437, 438,
-	440, 439, 1904, 441, 442, 443, 1905, 444, 445, 817,
-	446, 447, 448, 450, 452, 449, 451, 453, 454, 455,
-	456, 457, 818, 819, 458, 459, 1906, 340, 1907, 0,
-	0, 0, 0, 460, 461, 462, 820, 0, 0, 0,
-	463, 1908, 465, 469, 466, 467, 468, 470, 1909, 464,
-	471, 472, 1910, 877, 473, 474, 475, 821, 822, 476,
-	477, 478, 479, 480, 481, 482, 483, 484, 1911, 485,
-	486, 823, 1912, 824, 487, 1913, 488, 489, 490, 491,
-	492, 493, 494, 825, 826, 827, 595, 879, 495, 496,
-	497, 1914, 498, 499, 500, 501, 502, 503, 504, 0,
-	0, 0, 505, 506, 507, 508, 1915, 342, 341, 343,
-	878, 828, 509, 596, 510, 829, 830, 1916, 831, 1917,
-	511, 512, 515, 880, 832, 881, 514, 516, 517, 882,
-	518, 0, 0, 0, 519, 520, 521, 522, 523, 524,
-	525, 1918, 526, 528, 527, 1919, 530, 833, 529, 883,
-	531, 532, 884, 1920, 533, 534, 535, 536, 537, 538,
-	541, 1921, 1922, 539, 540, 542, 543, 0, 544, 545,
-	547, 550, 546, 548, 549, 551, 552, 565, 566, 553,
-	554, 555, 556, 557, 558, 559, 560, 561, 562, 563,
-	564, 568, 0, 567, 885, 569, 570, 571, 572, 573,
-	581, 583, 584, 579, 580, 582, 585, 586, 588, 589,
-	576, 577, 578, 886, 587, 574, 1923, 575, 344, 887,
-	590, 591, 592, 593, 1924, 834, 594, 835, 597, 598,
-	1925, 0, 599, 0, 600, 1926, 1927, 602, 603, 604,
-	1928, 1929, 605, 606, 836, 888, 607, 889, 837, 608,
-	609, 601, 610, 611, 612, 613, 614, 615, 616, 617,
-	618, 619, 1930, 620, 621, 838, 622, 623, 624, 839,
-	625, 626, 627, 840, 628, 841, 629, 630, 1931, 631,
-	632, 633, 0, 634, 635, 636, 637, 638, 639, 640,
-	641, 642, 643, 842, 644, 645, 647, 646, 648, 649,
-	1932, 650, 0, 651, 652, 653, 0, 0, 0, 0,
-	0, 654, 655, 657, 0, 658, 659, 660, 661, 662,
-	656, 663, 664, 665, 666, 667, 668, 669, 1933, 671,
-	672, 670, 673, 674, 890, 675, 676, 677, 678, 679,
-	843, 680, 0, 681, 682, 690, 691, 692, 683, 684,
-	686, 693, 685, 694, 695, 696, 697, 699, 698, 1934,
-	701, 702, 700, 703, 704, 705, 706, 1935, 707, 844,
-	708, 687, 688, 709, 710, 711, 891, 712, 713, 714,
-	715, 716, 717, 718, 719, 720, 845, 0, 721, 1936,
-	722, 723, 724, 725, 726, 727, 729, 689, 730, 731,
-	732, 737, 738, 846, 733, 734, 735, 736, 847, 740,
-	741, 742, 743, 1937, 744, 745, 0, 739, 728, 1938,
-	746, 747, 748, 749, 750, 751, 752, 753, 754, 755,
-	1939, 756, 848, 849, 850, 851, 1940, 768, 1941, 757,
-	759, 760, 761, 762, 852, 763, 853, 1942, 764, 765,
-	766, 767, 758, 769, 770, 1943, 1944, 771, 772, 773,
-	774, 776, 778, 779, 780, 775, 777, 781, 1945, 782,
-	1946, 0, 783, 784, 785, 854, 855, 856, 1947, 787,
-	788, 786, 789, 790, 793, 791, 792, 857, 796, 513,
-	797, 798, 799, 794, 795, 1948, 1949, 1950, 1951, 800,
-	801, 858, 802, 803, 804, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 1868,
-	0, 0, 0, 0, 0, 0, 3913, 0, 0, 0,
-	0, 0, 0, 0, 0, 3914, 345, 346, 348, 347,
-	349, 350, 351, 352, 1873, 353, 354, 1874, 1875, 1876,
-	0, 1877, 805, 1878, 1879, 1880, 356, 0, 355, 1881,
-	357, 358, 359, 874, 360, 361, 362, 363, 364, 365,
-	366, 367, 806, 807, 0, 368, 808, 369, 809, 1882,
-	810, 370, 371, 372, 373, 374, 375, 376, 377, 378,
-	379, 1883, 1884, 0, 380, 811, 812, 813, 1885, 381,
-	382, 383, 384, 814, 1886, 875, 1887, 385, 386, 387,
-	388, 389, 390, 391, 392, 0, 1888, 394, 395, 396,
-	393, 397, 398, 1889, 399, 0, 400, 401, 402, 403,
-	404, 405, 406, 1890, 407, 408, 409, 876, 410, 411,
-	412, 1891, 1892, 1894, 1893, 1895, 1896, 1897, 413, 414,
-	415, 416, 417, 0, 418, 420, 421, 815, 422, 816,
-	1898, 425, 427, 419, 423, 1899, 426, 424, 428, 429,
-	1900, 430, 431, 432, 433, 1901, 1902, 434, 435, 436,
-	1903, 437, 438, 440, 439, 1904, 441, 442, 443, 1905,
-	444, 445, 817, 446, 447, 448, 450, 452, 449, 451,
-	453, 454, 455, 456, 457, 818, 819, 458, 459, 1906,
-	340, 1907, 0, 0, 0, 0, 460, 461, 462, 820,
-	0, 0, 0, 463, 1908, 465, 469, 466, 467, 468,
-	470, 1909, 464, 471, 472, 1910, 877, 473, 474, 475,
-	821, 822, 476, 477, 478, 479, 480, 481, 482, 483,
-	484, 1911, 485, 486, 823, 1912, 824, 487, 1913, 488,
-	489, 490, 491, 492, 493, 494, 825, 826, 827, 595,
-	879, 495, 496, 497, 1914, 498, 499, 500, 501, 502,
-	503, 504, 0, 0, 0, 505, 506, 507, 508, 1915,
-	342, 341, 343, 878, 828, 509, 596, 510, 829, 830,
-	1916, 831, 1917, 511, 512, 515, 880, 832, 881, 514,
-	516, 517, 882, 518, 0, 0, 0, 519, 520, 521,
-	522, 523, 524, 525, 1918, 526, 528, 527, 1919, 530,
-	833, 529, 883, 531, 532, 884, 1920, 533, 534, 535,
-	536, 537, 538, 541, 1921, 1922, 539, 540, 542, 543,
-	0, 544, 545, 547, 550, 546, 548, 549, 551, 552,
-	565, 566, 553, 554, 555, 556, 557, 558, 559, 560,
-	561, 562, 563, 564, 568, 0, 567, 885, 569, 570,
-	571, 572, 573, 581, 583, 584, 579, 580, 582, 585,
-	586, 588, 589, 576, 577, 578, 886, 587, 574, 1923,
-	575, 344, 887, 590, 591, 592, 593, 1924, 834, 594,
-	835, 597, 598, 1925, 0, 599, 0, 600, 1926, 1927,
-	602, 603, 604, 1928, 1929, 605, 606, 836, 888, 607,
-	889, 837, 608, 609, 601, 610, 611, 612, 613, 614,
-	615, 616, 617, 618, 619, 1930, 620, 621, 838, 622,
-	623, 624, 839, 625, 626, 627, 840, 628, 841, 629,
-	630, 1931, 631, 632, 633, 0, 634, 635, 636, 637,
-	638, 639, 640, 641, 642, 643, 842, 644, 645, 647,
-	646, 648, 649, 1932, 650, 0, 651, 652, 653, 0,
-	0, 0, 0, 0, 654, 655, 657, 0, 658, 659,
-	660, 661, 662, 656, 663, 664, 665, 666, 667, 668,
-	669, 1933, 671, 672, 670, 673, 674, 890, 675, 676,
-	677, 678, 679, 843, 680, 0, 681, 682, 690, 691,
-	692, 683, 684, 686, 693, 685, 694, 695, 696, 697,
-	699, 698, 1934, 701, 702, 700, 703, 704, 705, 706,
-	1935, 707, 844, 708, 687, 688, 709, 710, 711, 891,
-	712, 713, 714, 715, 716, 717, 718, 719, 720, 845,
-	0, 721, 1936, 722, 723, 724, 725, 726, 727, 729,
-	689, 730, 731, 732, 737, 738, 846, 733, 734, 735,
-	736, 847, 740, 741, 742, 743, 1937, 744, 745, 0,
-	739, 728, 1938, 746, 747, 748, 749, 750, 751, 752,
-	753, 754, 755, 1939, 756, 848, 849, 850, 851, 1940,
-	768, 1941, 757, 759, 760, 761, 762, 852, 763, 853,
-	1942, 764, 765, 766, 767, 758, 769, 770, 1943, 1944,
-	771, 772, 773, 774, 776, 778, 779, 780, 775, 777,
-	781, 1945, 782, 1946, 0, 783, 784, 785, 854, 855,
-	856, 1947, 787, 788, 786, 789, 790, 793, 791, 792,
-	857, 796, 513, 797, 798, 799, 794, 795, 1948, 1949,
-	1950, 1951, 800, 801, 858, 802, 803, 804, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 3325,
-	0, 0, 0, 5227, 0, 0, 2187, 2188, 0, 2221,
-	2222, 2223, 2232, 2233, 2234, 5229, 3327, 3328, 3329, 3330,
-	3331, 3332, 3333, 3334, 3335, 3336, 3337, 3338, 3339, 3314,
-	2218, 3341, 3340, 0, 3322, 3342, 3345, 2219, 3343, 3344,
-	3313, 3346, 3347, 3348, 3349, 3350, 3351, 3352, 3353, 3354,
-	3355, 3356, 3320, 3357, 0, 3358, 3359, 3363, 3360, 3361,
-	3362, 3364, 3365, 3366, 3367, 3368, 3369, 3370, 3371, 3372,
-	3373, 3374, 3375, 2244, 3376, 0, 0, 3377, 3378, 3379,
-	3380, 3381, 3382, 3383, 2189, 3384, 3385, 3386, 3387, 3388,
-	3389, 3390, 3391, 3392, 3393, 2209, 3394, 3395, 3396, 3397,
-	3398, 3399, 3400, 3401, 3402, 2206, 3403, 3404, 3405, 3406,
-	3407, 3408, 3409, 0, 3410, 3411, 3412, 3413, 3414, 3415,
-	3416, 3417, 3418, 3420, 3419, 3421, 3422, 3423, 3424, 3425,
-	3426, 3427, 3428, 0, 0, 3431, 3432, 3433, 3430, 3434,
-	3436, 3437, 3440, 3429, 3435, 3438, 3439, 3441, 3442, 3443,
-	3444, 3445, 3446, 3447, 3448, 3449, 3450, 3451, 3452, 3453,
-	3454, 3455, 3456, 3457, 3458, 3459, 3460, 3461, 3462, 0,
-	3463, 3464, 3467, 3465, 3466, 3468, 3470, 3472, 3469, 3471,
-	3473, 3474, 3475, 3476, 3477, 3478, 3479, 3480, 3481, 3482,
-	3483, 0, 2212, 2213, 2214, 2215, 3484, 0, 3485, 3486,
-	0, 0, 2195, 3487, 0, 3488, 3492, 3489, 3490, 3491,
-	3493, 3494, 3495, 3496, 3497, 0, 3498, 3499, 3500, 3501,
-	3502, 3503, 3508, 3509, 3510, 3504, 3505, 3506, 3507, 3511,
-	3512, 0, 3513, 3514, 3515, 0, 3516, 3517, 0, 3518,
-	3519, 3520, 3521, 3522, 0, 3523, 3524, 3525, 3526, 3527,
-	3317, 3528, 3529, 3530, 3321, 3531, 3534, 3532, 3533, 3535,
-	3536, 3537, 0, 2217, 2220, 3538, 3539, 3543, 3545, 3544,
-	3542, 3541, 3540, 3546, 3547, 3548, 3549, 3550, 3551, 3552,
-	0, 3553, 0, 3554, 3555, 3557, 3319, 3558, 2236, 3559,
-	3560, 3561, 3562, 3563, 0, 2204, 2205, 3564, 3565, 3566,
-	3567, 3568, 3569, 3570, 3571, 3572, 3574, 3573, 3575, 3577,
-	3578, 3576, 3579, 3580, 3581, 3316, 0, 3582, 3583, 3584,
-	3585, 3586, 3587, 3588, 3589, 3590, 3591, 3592, 3593, 3594,
-	2210, 3595, 3596, 3598, 3600, 3597, 3599, 0, 3601, 3602,
-	0, 3603, 3604, 3605, 3606, 3607, 3608, 3609, 3610, 3611,
-	3612, 3613, 3614, 3615, 3617, 0, 3616, 3618, 3619, 3620,
-	3621, 3622, 3623, 3624, 3625, 3626, 3627, 3628, 3629, 3630,
-	3631, 3635, 3636, 3645, 3646, 3644, 3632, 3633, 3634, 3637,
-	3638, 3639, 2237, 3640, 3641, 3642, 3643, 3647, 3648, 3649,
-	3650, 3651, 3652, 0, 0, 3653, 0, 3654, 0, 3655,
-	3656, 3657, 3658, 3315, 0, 3659, 3660, 3661, 3662, 0,
-	0, 3663, 3664, 3665, 3324, 3666, 3667, 3668, 3669, 3670,
-	3671, 3672, 3673, 3674, 3675, 3676, 3677, 3678, 3679, 3680,
-	3681, 3682, 3683, 3684, 3685, 3686, 3687, 3688, 0, 3689,
-	3690, 3691, 3692, 3693, 3694, 0, 3695, 3696, 3697, 3698,
-	3699, 3700, 3701, 3702, 3703, 3704, 3705, 3706, 3707, 3709,
-	3708, 3710, 3711, 3712, 3713, 0, 3714, 3715, 3716, 0,
-	0, 0, 0, 0, 3717, 3718, 3720, 2216, 3721, 3722,
-	3723, 3724, 3725, 3719, 3726, 3727, 3728, 3729, 3730, 3731,
-	3732, 0, 3734, 3735, 3733, 3736, 3737, 3738, 3739, 3740,
-	3741, 3742, 3743, 3744, 3745, 2211, 3746, 3747, 3748, 3749,
-	3750, 3751, 3752, 3756, 3753, 3755, 3754, 3757, 3758, 0,
-	3759, 3760, 3761, 3762, 3763, 3764, 3765, 3766, 3767, 3768,
-	3769, 3770, 3771, 3772, 3773, 3774, 3775, 3776, 3777, 3318,
-	3778, 3779, 3780, 3781, 3782, 3783, 3784, 3786, 3785, 3787,
-	0, 3788, 3789, 3790, 3791, 3792, 3793, 3794, 3795, 3797,
-	3798, 3799, 3800, 3801, 3806, 3807, 3808, 3802, 3803, 3804,
-	3805, 3810, 3811, 3812, 3814, 3813, 3815, 3816, 3817, 2243,
-	3809, 3796, 3818, 3819, 3820, 3821, 3822, 3823, 3824, 3826,
-	3825, 3827, 3828, 3829, 3831, 3832, 3835, 3833, 3834, 0,
-	3830, 3838, 3836, 3839, 3840, 3841, 3842, 3843, 3844, 3845,
-	3846, 3847, 3848, 3849, 3850, 3837, 3851, 3852, 0, 3853,
-	3854, 3855, 3856, 3857, 3859, 3861, 3862, 3863, 3858, 3860,
-	3864, 3865, 3866, 3867, 0, 3868, 3869, 3870, 3871, 3872,
-	3873, 3874, 3875, 3876, 0, 3877, 3878, 3881, 3879, 3880,
-	3882, 3885, 3556, 3886, 3887, 3888, 3883, 3884, 3889, 0,
-	0, 0, 0, 0, 3890, 3891, 0, 3892, 2228, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	1868, 2201, 2202, 2208, 2231, 2207, 2203, 0, 2200, 2198,
-	2199, 2191, 2192, 2193, 2194, 2196, 2197, 345, 346, 348,
-	347, 349, 350, 351, 352, 1873, 353, 354, 1874, 1875,
-	1876, 0, 1877, 805, 1878, 1879, 1880, 356, 0, 355,
-	1881, 357, 358, 359, 874, 360, 361, 362, 363, 364,
-	365, 366, 367, 806, 807, 0, 368, 808, 369, 809,
-	1882, 810, 370, 371, 372, 373, 374, 375, 376, 377,
-	378, 379, 1883, 1884, 0, 380, 811, 812, 813, 1885,
-	381, 382, 383, 384, 814, 1886, 875, 1887, 385, 386,
-	387, 388, 389, 390, 391, 392, 0, 1888, 394, 395,
-	396, 393, 397, 398, 1889, 399, 0, 400, 401, 402,
-	403, 404, 405, 406, 1890, 407, 408, 409, 876, 410,
-	411, 412, 1891, 1892, 1894, 1893, 1895, 1896, 1897, 413,
-	414, 415, 416, 417, 0, 418, 420, 421, 815, 422,
-	816, 1898, 425, 427, 419, 423, 1899, 426, 424, 428,
-	429, 1900, 430, 431, 432, 433, 1901, 1902, 434, 435,
-	436, 1903, 437, 438, 440, 439, 1904, 441, 442, 443,
-	1905, 444, 445, 817, 446, 447, 448, 450, 452, 449,
-	451, 453, 454, 455, 456, 457, 818, 819, 458, 459,
-	1906, 340, 1907, 0, 0, 0, 0, 460, 461, 462,
-	820, 0, 0, 0, 463, 1908, 465, 469, 466, 467,
-	468, 470, 1909, 464, 471, 472, 1910, 877, 473, 474,
-	475, 821, 822, 476, 477, 478, 479, 480, 481, 482,
-	483, 484, 1911, 485, 486, 823, 1912, 824, 487, 1913,
-	488, 489, 490, 491, 492, 493, 494, 825, 826, 827,
-	595, 879, 495, 496, 497, 1914, 498, 499, 500, 501,
-	502, 503, 504, 0, 0, 0, 505, 506, 507, 508,
-	1915, 342, 341, 343, 878, 828, 509, 596, 510, 829,
-	830, 1916, 831, 1917, 511, 512, 515, 880, 832, 881,
-	514, 516, 517, 882, 518, 0, 0, 0, 519, 520,
-	521, 522, 523, 524, 525, 1918, 526, 528, 527, 1919,
-	530, 833, 529, 883, 531, 532, 884, 1920, 533, 534,
-	535, 536, 537, 538, 541, 1921, 1922, 539, 540, 542,
-	543, 0, 544, 545, 547, 550, 546, 548, 549, 551,
-	552, 565, 566, 553, 554, 555, 556, 557, 558, 559,
-	560, 561, 562, 563, 564, 568, 0, 567, 885, 569,
-	570, 571, 572, 573, 581, 583, 584, 579, 580, 582,
-	585, 586, 588, 589, 576, 577, 578, 886, 587, 574,
-	1923, 575, 344, 887, 590, 591, 592, 593, 1924, 834,
-	594, 835, 597, 598, 1925, 0, 599, 0, 600, 1926,
-	1927, 602, 603, 604, 1928, 1929, 605, 606, 836, 888,
-	607, 889, 837, 608, 609, 601, 610, 611, 612, 613,
-	614, 615, 616, 617, 618, 619, 1930, 620, 621, 838,
-	622, 623, 624, 839, 625, 626, 627, 840, 628, 841,
-	629, 630, 1931, 631, 632, 633, 0, 634, 635, 636,
-	637, 638, 639, 640, 641, 642, 643, 842, 644, 645,
-	647, 646, 648, 649, 1932, 650, 0, 651, 652, 653,
-	0, 0, 0, 0, 0, 654, 655, 657, 0, 658,
-	659, 660, 661, 662, 656, 663, 664, 665, 666, 667,
-	668, 669, 1933, 671, 672, 670, 673, 674, 890, 675,
-	676, 677, 678, 679, 843, 680, 0, 681, 682, 690,
-	691, 692, 683, 684, 686, 693, 685, 694, 695, 696,
-	697, 699, 698, 1934, 701, 702, 700, 703, 704, 705,
-	706, 1935, 707, 844, 708, 687, 688, 709, 710, 711,
-	891, 712, 713, 714, 715, 716, 717, 718, 719, 720,
-	845, 0, 721, 1936, 722, 723, 724, 725, 726, 727,
-	729, 689, 730, 731, 732, 737, 738, 846, 733, 734,
-	735, 736, 847, 740, 741, 742, 743, 1937, 744, 745,
-	0, 739, 728, 1938, 746, 747, 748, 749, 750, 751,
-	752, 753, 754, 755, 1939, 756, 848, 849, 850, 851,
-	1940, 768, 1941, 757, 759, 760, 761, 762, 852, 763,
-	853, 1942, 764, 765, 766, 767, 758, 769, 770, 1943,
-	1944, 771, 772, 773, 774, 776, 778, 779, 780, 775,
-	777, 781, 1945, 782, 1946, 0, 783, 784, 785, 854,
-	855, 856, 1947, 787, 788, 786, 789, 790, 793, 791,
-	792, 857, 796, 513, 797, 798, 799, 794, 795, 1948,
-	1949, 1950, 1951, 800, 801, 858, 802, 803, 804, 1868,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 345, 346, 348, 347,
-	349, 350, 351, 352, 1873, 353, 354, 1874, 1875, 1876,
-	5743, 1877, 805, 1878, 1879, 1880, 356, 0, 355, 1881,
-	357, 358, 359, 874, 360, 361, 362, 363, 364, 365,
-	366, 367, 806, 807, 0, 368, 808, 369, 809, 1882,
-	810, 370, 371, 372, 373, 374, 375, 376, 377, 378,
-	379, 1883, 1884, 0, 380, 811, 812, 813, 1885, 381,
-	382, 383, 384, 814, 1886, 875, 1887, 385, 386, 387,
-	388, 389, 390, 391, 392, 0, 1888, 394, 395, 396,
-	393, 397, 398, 1889, 399, 0, 400, 401, 402, 403,
-	404, 405, 406, 1890, 407, 408, 409, 876, 410, 411,
-	412, 1891, 1892, 1894, 1893, 1895, 1896, 1897, 413, 414,
-	415, 416, 417, 0, 418, 420, 421, 815, 422, 816,
-	1898, 425, 427, 419, 423, 1899, 426, 424, 428, 429,
-	1900, 430, 431, 432, 433, 1901, 1902, 434, 435, 436,
-	1903, 437, 438, 440, 439, 1904, 441, 442, 443, 1905,
-	444, 445, 817, 446, 447, 448, 450, 452, 449, 451,
-	453, 454, 455, 456, 457, 818, 819, 458, 459, 1906,
-	340, 1907, 0, 0, 0, 0, 460, 461, 462, 820,
-	0, 0, 0, 463, 1908, 465, 469, 466, 467, 468,
-	470, 1909, 464, 471, 472, 1910, 877, 473, 474, 475,
-	821, 822, 476, 477, 478, 479, 480, 481, 482, 483,
-	484, 1911, 485, 486, 823, 1912, 824, 487, 1913, 488,
-	489, 490, 491, 492, 493, 494, 825, 826, 827, 595,
-	879, 495, 496, 497, 1914, 498, 499, 500, 501, 502,
-	503, 504, 0, 0, 0, 505, 506, 507, 508, 1915,
-	342, 341, 343, 878, 828, 509, 596, 510, 829, 830,
-	1916, 831, 1917, 511, 512, 515, 880, 832, 881, 514,
-	516, 517, 882, 518, 0, 0, 0, 519, 520, 521,
-	522, 523, 524, 525, 1918, 526, 528, 527, 1919, 530,
-	833, 529, 883, 531, 532, 884, 1920, 533, 534, 535,
-	536, 537, 538, 541, 1921, 1922, 539, 540, 542, 543,
-	0, 544, 545, 547, 550, 546, 548, 549, 551, 552,
-	565, 566, 553, 554, 555, 556, 557, 558, 559, 560,
-	561, 562, 563, 564, 568, 0, 567, 885, 569, 570,
-	571, 572, 573, 581, 583, 584, 579, 580, 582, 585,
-	586, 588, 589, 576, 577, 578, 886, 587, 574, 1923,
-	575, 344, 887, 590, 591, 592, 593, 1924, 834, 594,
-	835, 597, 598, 1925, 0, 599, 0, 600, 1926, 1927,
-	602, 603, 604, 1928, 1929, 605, 606, 836, 888, 607,
-	889, 837, 608, 609, 601, 610, 611, 612, 613, 614,
-	615, 616, 617, 618, 619, 1930, 620, 621, 838, 622,
-	623, 624, 839, 625, 626, 627, 840, 628, 841, 629,
-	630, 1931, 631, 632, 633, 0, 634, 635, 636, 637,
-	638, 639, 640, 641, 642, 643, 842, 644, 645, 647,
-	646, 648, 649, 1932, 650, 0, 651, 652, 653, 0,
-	0, 0, 0, 0, 654, 655, 657, 0, 658, 659,
-	660, 661, 662, 656, 663, 664, 665, 666, 667, 668,
-	669, 1933, 671, 672, 670, 673, 674, 890, 675, 676,
-	677, 678, 679, 843, 680, 0, 681, 682, 690, 691,
-	692, 683, 684, 686, 693, 685, 694, 695, 696, 697,
-	699, 698, 1934, 701, 702, 700, 703, 704, 705, 706,
-	1935, 707, 844, 708, 687, 688, 709, 710, 711, 891,
-	712, 713, 714, 715, 716, 717, 718, 719, 720, 845,
-	0, 721, 1936, 722, 723, 724, 725, 726, 727, 729,
-	689, 730, 731, 732, 737, 738, 846, 733, 734, 735,
-	736, 847, 740, 741, 742, 743, 1937, 744, 745, 0,
-	739, 728, 1938, 746, 747, 748, 749, 750, 751, 752,
-	753, 754, 755, 1939, 756, 848, 849, 850, 851, 1940,
-	768, 1941, 757, 759, 760, 761, 762, 852, 763, 853,
-	1942, 764, 765, 766, 767, 758, 769, 770, 1943, 1944,
-	771, 772, 773, 774, 776, 778, 779, 780, 775, 777,
-	781, 1945, 782, 1946, 0, 783, 784, 785, 854, 855,
-	856, 1947, 787, 788, 786, 789, 790, 793, 791, 792,
-	857, 796, 513, 797, 798, 799, 794, 795, 1948, 1949,
-	1950, 1951, 800, 801, 858, 802, 803, 804, 1868, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 345, 346, 348, 347, 349,
-	350, 351, 352, 1873, 353, 354, 1874, 1875, 1876, 5741,
-	1877, 805, 1878, 1879, 1880, 356, 0, 355, 1881, 357,
-	358, 359, 874, 360, 361, 362, 363, 364, 365, 366,
-	367, 806, 807, 0, 368, 808, 369, 809, 1882, 810,
-	370, 371, 372, 373, 374, 375, 376, 377, 378, 379,
-	1883, 1884, 0, 380, 811, 812, 813, 1885, 381, 382,
-	383, 384, 814, 1886, 875, 1887, 385, 386, 387, 388,
-	389, 390, 391, 392, 0, 1888, 394, 395, 396, 393,
-	397, 398, 1889, 399, 0, 400, 401, 402, 403, 404,
-	405, 406, 1890, 407, 408, 409, 876, 410, 411, 412,
-	1891, 1892, 1894, 1893, 1895, 1896, 1897, 413, 414, 415,
-	416, 417, 0, 418, 420, 421, 815, 422, 816, 1898,
-	425, 427, 419, 423, 1899, 426, 424, 428, 429, 1900,
-	430, 431, 432, 433, 1901, 1902, 434, 435, 436, 1903,
-	437, 438, 440, 439, 1904, 441, 442, 443, 1905, 444,
-	445, 817, 446, 447, 448, 450, 452, 449, 451, 453,
-	454, 455, 456, 457, 818, 819, 458, 459, 1906, 340,
-	1907, 0, 0, 0, 0, 460, 461, 462, 820, 0,
-	0, 0, 463, 1908, 465, 469, 466, 467, 468, 470,
-	1909, 464, 471, 472, 1910, 877, 473, 474, 475, 821,
-	822, 476, 477, 478, 479, 480, 481, 482, 483, 484,
-	1911, 485, 486, 823, 1912, 824, 487, 1913, 488, 489,
-	490, 491, 492, 493, 494, 825, 826, 827, 595, 879,
-	495, 496, 497, 1914, 498, 499, 500, 501, 502, 503,
-	504, 0, 0, 0, 505, 506, 507, 508, 1915, 342,
-	341, 343, 878, 828, 509, 596, 510, 829, 830, 1916,
-	831, 1917, 511, 512, 515, 880, 832, 881, 514, 516,
-	517, 882, 518, 0, 0, 0, 519, 520, 521, 522,
-	523, 524, 525, 1918, 526, 528, 527, 1919, 530, 833,
-	529, 883, 531, 532, 884, 1920, 533, 534, 535, 536,
-	537, 538, 541, 1921, 1922, 539, 540, 542, 543, 0,
-	544, 545, 547, 550, 546, 548, 549, 551, 552, 565,
-	566, 553, 554, 555, 556, 557, 558, 559, 560, 561,
-	562, 563, 564, 568, 0, 567, 885, 569, 570, 571,
-	572, 573, 581, 583, 584, 579, 580, 582, 585, 586,
-	588, 589, 576, 577, 578, 886, 587, 574, 1923, 575,
-	344, 887, 590, 591, 592, 593, 1924, 834, 594, 835,
-	597, 598, 1925, 0, 599, 0, 600, 1926, 1927, 602,
-	603, 604, 1928, 1929, 605, 606, 836, 888, 607, 889,
-	837, 608, 609, 601, 610, 611, 612, 613, 614, 615,
-	616, 617, 618, 619, 1930, 620, 621, 838, 622, 623,
-	624, 839, 625, 626, 627, 840, 628, 841, 629, 630,
-	1931, 631, 632, 633, 0, 634, 635, 636, 637, 638,
-	639, 640, 641, 642, 643, 842, 644, 645, 647, 646,
-	648, 649, 1932, 650, 0, 651, 652, 653, 0, 0,
-	0, 0, 0, 654, 655, 657, 0, 658, 659, 660,
-	661, 662, 656, 663, 664, 665, 666, 667, 668, 669,
-	1933, 671, 672, 670, 673, 674, 890, 675, 676, 677,
-	678, 679, 843, 680, 0, 681, 682, 690, 691, 692,
-	683, 684, 686, 693, 685, 694, 695, 696, 697, 699,
-	698, 1934, 701, 702, 700, 703, 704, 705, 706, 1935,
-	707, 844, 708, 687, 688, 709, 710, 711, 891, 712,
-	713, 714, 715, 716, 717, 718, 719, 720, 845, 0,
-	721, 1936, 722, 723, 724, 725, 726, 727, 729, 689,
-	730, 731, 732, 737, 738, 846, 733, 734, 735, 736,
-	847, 740, 741, 742, 743, 1937, 744, 745, 0, 739,
-	728, 1938, 746, 747, 748, 749, 750, 751, 752, 753,
-	754, 755, 1939, 756, 848, 849, 850, 851, 1940, 768,
-	1941, 757, 759, 760, 761, 762, 852, 763, 853, 1942,
-	764, 765, 766, 767, 758, 769, 770, 1943, 1944, 771,
-	772, 773, 774, 776, 778, 779, 780, 775, 777, 781,
-	1945, 782, 1946, 0, 783, 784, 785, 854, 855, 856,
-	1947, 787, 788, 786, 789, 790, 793, 791, 792, 857,
-	796, 513, 797, 798, 799, 794, 795, 1948, 1949, 1950,
-	1951, 800, 801, 858, 802, 803, 804, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 1868, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 6060, 345, 346, 348, 347, 349, 350, 351,
-	352, 1873, 353, 354, 1874, 1875, 1876, 0, 1877, 805,
-	1878, 1879, 1880, 356, 0, 355, 1881, 357, 358, 359,
-	874, 360, 361, 362, 363, 364, 365, 366, 367, 806,
-	807, 0, 368, 808, 369, 809, 1882, 810, 370, 371,
-	372, 373, 374, 375, 376, 377, 378, 379, 1883, 1884,
-	0, 380, 811, 812, 813, 1885, 381, 382, 383, 384,
-	814, 1886, 875, 1887, 385, 386, 387, 388, 389, 390,
-	391, 392, 0, 1888, 394, 395, 396, 393, 397, 398,
-	1889, 399, 0, 400, 401, 402, 403, 404, 405, 406,
-	1890, 407, 408, 409, 876, 410, 411, 412, 1891, 1892,
-	1894, 1893, 1895, 1896, 1897, 413, 414, 415, 416, 417,
-	0, 418, 420, 421, 815, 422, 816, 1898, 425, 427,
-	419, 423, 1899, 426, 424, 428, 429, 1900, 430, 431,
-	432, 433, 1901, 1902, 434, 435, 436, 1903, 437, 438,
-	440, 439, 1904, 441, 442, 443, 1905, 444, 445, 817,
-	446, 447, 448, 450, 452, 449, 451, 453, 454, 455,
-	456, 457, 818, 819, 458, 459, 1906, 340, 1907, 0,
-	0, 0, 0, 460, 461, 462, 820, 0, 0, 0,
-	463, 1908, 465, 469, 466, 467, 468, 470, 1909, 464,
-	471, 472, 1910, 877, 473, 474, 475, 821, 822, 476,
-	477, 478, 479, 480, 481, 482, 483, 484, 1911, 485,
-	486, 823, 1912, 824, 487, 1913, 488, 489, 490, 491,
-	492, 493, 494, 825, 826, 827, 595, 879, 495, 496,
-	497, 1914, 498, 499, 500, 501, 502, 503, 504, 0,
-	0, 0, 505, 506, 507, 508, 1915, 342, 341, 343,
-	878, 828, 509, 596, 510, 829, 830, 1916, 831, 1917,
-	511, 512, 515, 880, 832, 881, 514, 516, 517, 882,
-	518, 0, 0, 0, 519, 520, 521, 522, 523, 524,
-	525, 1918, 526, 528, 527, 1919, 530, 833, 529, 883,
-	531, 532, 884, 1920, 533, 534, 535, 536, 537, 538,
-	541, 1921, 1922, 539, 540, 542, 543, 0, 544, 545,
-	547, 550, 546, 548, 549, 551, 552, 565, 566, 553,
-	554, 555, 556, 557, 558, 559, 560, 561, 562, 563,
-	564, 568, 0, 567, 885, 569, 570, 571, 572, 573,
-	581, 583, 584, 579, 580, 582, 585, 586, 588, 589,
-	576, 577, 578, 886, 587, 574, 1923, 575, 344, 887,
-	590, 591, 592, 593, 1924, 834, 594, 835, 597, 598,
-	1925, 0, 599, 0, 600, 1926, 1927, 602, 603, 604,
-	1928, 1929, 605, 606, 836, 888, 607, 889, 837, 608,
-	609, 601, 610, 611, 612, 613, 614, 615, 616, 617,
-	618, 619, 1930, 620, 621, 838, 622, 623, 624, 839,
-	625, 626, 627, 840, 628, 841, 629, 630, 1931, 631,
-	632, 633, 0, 634, 635, 636, 637, 638, 639, 640,
-	641, 642, 643, 842, 644, 645, 647, 646, 648, 649,
-	1932, 650, 0, 651, 652, 653, 0, 0, 0, 0,
-	0, 654, 655, 657, 0, 658, 659, 660, 661, 662,
-	656, 663, 664, 665, 666, 667, 668, 669, 1933, 671,
-	672, 670, 673, 674, 890, 675, 676, 677, 678, 679,
-	843, 680, 0, 681, 682, 690, 691, 692, 683, 684,
-	686, 693, 685, 694, 695, 696, 697, 699, 698, 1934,
-	701, 702, 700, 703, 704, 705, 706, 1935, 707, 844,
-	708, 687, 688, 709, 710, 711, 891, 712, 713, 714,
-	715, 716, 717, 718, 719, 720, 845, 0, 721, 1936,
-	722, 723, 724, 725, 726, 727, 729, 689, 730, 731,
-	732, 737, 738, 846, 733, 734, 735, 736, 847, 740,
-	741, 742, 743, 1937, 744, 745, 0, 739, 728, 1938,
-	746, 747, 748, 749, 750, 751, 752, 753, 754, 755,
-	1939, 756, 848, 849, 850, 851, 1940, 768, 1941, 757,
-	759, 760, 761, 762, 852, 763, 853, 1942, 764, 765,
-	766, 767, 758, 769, 770, 1943, 1944, 771, 772, 773,
-	774, 776, 778, 779, 780, 775, 777, 781, 1945, 782,
-	1946, 0, 783, 784, 785, 854, 855, 856, 1947, 787,
-	788, 786, 789, 790, 793, 791, 792, 857, 796, 513,
-	797, 798, 799, 794, 795, 1948, 1949, 1950, 1951, 800,
-	801, 858, 802, 803, 804, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 1868, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	5886, 345, 346, 348, 347, 349, 350, 351, 352, 1873,
-	353, 354, 1874, 1875, 1876, 0, 1877, 805, 1878, 1879,
-	1880, 356, 0, 355, 1881, 357, 358, 359, 874, 360,
-	361, 362, 363, 364, 365, 366, 367, 806, 807, 0,
-	368, 808, 369, 809, 1882, 810, 370, 371, 372, 373,
-	374, 375, 376, 377, 378, 379, 1883, 1884, 0, 380,
-	811, 812, 813, 1885, 381, 382, 383, 384, 814, 1886,
-	875, 1887, 385, 386, 387, 388, 389, 390, 391, 392,
-	0, 1888, 394, 395, 396, 393, 397, 398, 1889, 399,
-	0, 400, 401, 402, 403, 404, 405, 406, 1890, 407,
-	408, 409, 876, 410, 411, 412, 1891, 1892, 1894, 1893,
-	1895, 1896, 1897, 413, 414, 415, 416, 417, 0, 418,
-	420, 421, 815, 422, 816, 1898, 425, 427, 419, 423,
-	1899, 426, 424, 428, 429, 1900, 430, 431, 432, 433,
-	1901, 1902, 434, 435, 436, 1903, 437, 438, 440, 439,
-	1904, 441, 442, 443, 1905, 444, 445, 817, 446, 447,
-	448, 450, 452, 449, 451, 453, 454, 455, 456, 457,
-	818, 819, 458, 459, 1906, 340, 1907, 0, 0, 0,
-	0, 460, 461, 462, 820, 0, 0, 0, 463, 1908,
-	465, 469, 466, 467, 468, 470, 1909, 464, 471, 472,
-	1910, 877, 473, 474, 475, 821, 822, 476, 477, 478,
-	479, 480, 481, 482, 483, 484, 1911, 485, 486, 823,
-	1912, 824, 487, 1913, 488, 489, 490, 491, 492, 493,
-	494, 825, 826, 827, 595, 879, 495, 496, 497, 1914,
-	498, 499, 500, 501, 502, 503, 504, 0, 0, 0,
-	505, 506, 507, 508, 1915, 342, 341, 343, 878, 828,
-	509, 596, 510, 829, 830, 1916, 831, 1917, 511, 512,
-	515, 880, 832, 881, 514, 516, 517, 882, 518, 0,
-	0, 0, 519, 520, 521, 522, 523, 524, 525, 1918,
-	526, 528, 527, 1919, 530, 833, 529, 883, 531, 532,
-	884, 1920, 533, 534, 535, 536, 537, 538, 541, 1921,
-	1922, 539, 540, 542, 543, 0, 544, 545, 547, 550,
-	546, 548, 549, 551, 552, 565, 566, 553, 554, 555,
-	556, 557, 558, 559, 560, 561, 562, 563, 564, 568,
-	0, 567, 885, 569, 570, 571, 572, 573, 581, 583,
-	584, 579, 580, 582, 585, 586, 588, 589, 576, 577,
-	578, 886, 587, 574, 1923, 575, 344, 887, 590, 591,
-	592, 593, 1924, 834, 594, 835, 597, 598, 1925, 0,
-	599, 0, 600, 1926, 1927, 602, 603, 604, 1928, 1929,
-	605, 606, 836, 888, 607, 889, 837, 608, 609, 601,
-	610, 611, 612, 613, 614, 615, 616, 617, 618, 619,
-	1930, 620, 621, 838, 622, 623, 624, 839, 625, 626,
-	627, 840, 628, 841, 629, 630, 1931, 631, 632, 633,
-	0, 634, 635, 636, 637, 638, 639, 640, 641, 642,
-	643, 842, 644, 645, 647, 646, 648, 649, 1932, 650,
-	0, 651, 652, 653, 0, 0, 0, 0, 0, 654,
-	655, 657, 0, 658, 659, 660, 661, 662, 656, 663,
-	664, 665, 666, 667, 668, 669, 1933, 671, 672, 670,
-	673, 674, 890, 675, 676, 677, 678, 679, 843, 680,
-	0, 681, 682, 690, 691, 692, 683, 684, 686, 693,
-	685, 694, 695, 696, 697, 699, 698, 1934, 701, 702,
-	700, 703, 704, 705, 706, 1935, 707, 844, 708, 687,
-	688, 709, 710, 711, 891, 712, 713, 714, 715, 716,
-	717, 718, 719, 720, 845, 0, 721, 1936, 722, 723,
-	724, 725, 726, 727, 729, 689, 730, 731, 732, 737,
-	738, 846, 733, 734, 735, 736, 847, 740, 741, 742,
-	743, 1937, 744, 745, 0, 739, 728, 1938, 746, 747,
-	748, 749, 750, 751, 752, 753, 754, 755, 1939, 756,
-	848, 849, 850, 851, 1940, 768, 1941, 757, 759, 760,
-	761, 762, 852, 763, 853, 1942, 764, 765, 766, 767,
-	758, 769, 770, 1943, 1944, 771, 772, 773, 774, 776,
-	778, 779, 780, 775, 777, 781, 1945, 782, 1946, 0,
-	783, 784, 785, 854, 855, 856, 1947, 787, 788, 786,
-	789, 790, 793, 791, 792, 857, 796, 513, 797, 798,
-	799, 794, 795, 1948, 1949, 1950, 1951, 800, 801, 858,
-	802, 803, 804, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 1868, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 5417, 345,
-	346, 348, 347, 349, 350, 351, 352, 1873, 353, 354,
-	1874, 1875, 1876, 0, 1877, 805, 1878, 1879, 1880, 356,
-	0, 355, 1881, 357, 358, 359, 874, 360, 361, 362,
-	363, 364, 365, 366, 367, 806, 807, 0, 368, 808,
-	369, 809, 1882, 810, 370, 371, 372, 373, 374, 375,
-	376, 377, 378, 379, 1883, 1884, 0, 380, 811, 812,
-	813, 1885, 381, 382, 383, 384, 814, 1886, 875, 1887,
-	385, 386, 387, 388, 389, 390, 391, 392, 0, 1888,
-	394, 395, 396, 393, 397, 398, 1889, 399, 0, 400,
-	401, 402, 403, 404, 405, 406, 1890, 407, 408, 409,
-	876, 410, 411, 412, 1891, 1892, 1894, 1893, 1895, 1896,
-	1897, 413, 414, 415, 416, 417, 0, 418, 420, 421,
-	815, 422, 816, 1898, 425, 427, 419, 423, 1899, 426,
-	424, 428, 429, 1900, 430, 431, 432, 433, 1901, 1902,
-	434, 435, 436, 1903, 437, 438, 440, 439, 1904, 441,
-	442, 443, 1905, 444, 445, 817, 446, 447, 448, 450,
-	452, 449, 451, 453, 454, 455, 456, 457, 818, 819,
-	458, 459, 1906, 340, 1907, 0, 0, 0, 0, 460,
-	461, 462, 820, 0, 0, 0, 463, 1908, 465, 469,
-	466, 467, 468, 470, 1909, 464, 471, 472, 1910, 877,
-	473, 474, 475, 821, 822, 476, 477, 478, 479, 480,
-	481, 482, 483, 484, 1911, 485, 486, 823, 1912, 824,
-	487, 1913, 488, 489, 490, 491, 492, 493, 494, 825,
-	826, 827, 595, 879, 495, 496, 497, 1914, 498, 499,
-	500, 501, 502, 503, 504, 0, 0, 0, 505, 506,
-	507, 508, 1915, 342, 341, 343, 878, 828, 509, 596,
-	510, 829, 830, 1916, 831, 1917, 511, 512, 515, 880,
-	832, 881, 514, 516, 517, 882, 518, 0, 0, 0,
-	519, 520, 521, 522, 523, 524, 525, 1918, 526, 528,
-	527, 1919, 530, 833, 529, 883, 531, 532, 884, 1920,
-	533, 534, 535, 536, 537, 538, 541, 1921, 1922, 539,
-	540, 542, 543, 0, 544, 545, 547, 550, 546, 548,
-	549, 551, 552, 565, 566, 553, 554, 555, 556, 557,
-	558, 559, 560, 561, 562, 563, 564, 568, 0, 567,
-	885, 569, 570, 571, 572, 573, 581, 583, 584, 579,
-	580, 582, 585, 586, 588, 589, 576, 577, 578, 886,
-	587, 574, 1923, 575, 344, 887, 590, 591, 592, 593,
-	1924, 834, 594, 835, 597, 598, 1925, 0, 599, 0,
-	600, 1926, 1927, 602, 603, 604, 1928, 1929, 605, 606,
-	836, 888, 607, 889, 837, 608, 609, 601, 610, 611,
-	612, 613, 614, 615, 616, 617, 618, 619, 1930, 620,
-	621, 838, 622, 623, 624, 839, 625, 626, 627, 840,
-	628, 841, 629, 630, 1931, 631, 632, 633, 0, 634,
-	635, 636, 637, 638, 639, 640, 641, 642, 643, 842,
-	644, 645, 647, 646, 648, 649, 1932, 650, 0, 651,
-	652, 653, 0, 0, 0, 0, 0, 654, 655, 657,
-	0, 658, 659, 660, 661, 662, 656, 663, 664, 665,
-	666, 667, 668, 669, 1933, 671, 672, 670, 673, 674,
-	890, 675, 676, 677, 678, 679, 843, 680, 0, 681,
-	682, 690, 691, 692, 683, 684, 686, 693, 685, 694,
-	695, 696, 697, 699, 698, 1934, 701, 702, 700, 703,
-	704, 705, 706, 1935, 707, 844, 708, 687, 688, 709,
-	710, 711, 891, 712, 713, 714, 715, 716, 717, 718,
-	719, 720, 845, 0, 721, 1936, 722, 723, 724, 725,
-	726, 727, 729, 689, 730, 731, 732, 737, 738, 846,
-	733, 734, 735, 736, 847, 740, 741, 742, 743, 1937,
-	744, 745, 0, 739, 728, 1938, 746, 747, 748, 749,
-	750, 751, 752, 753, 754, 755, 1939, 756, 848, 849,
-	850, 851, 1940, 768, 1941, 757, 759, 760, 761, 762,
-	852, 763, 853, 1942, 764, 765, 766, 767, 758, 769,
-	770, 1943, 1944, 771, 772, 773, 774, 776, 778, 779,
-	780, 775, 777, 781, 1945, 782, 1946, 0, 783, 784,
-	785, 854, 855, 856, 1947, 787, 788, 786, 789, 790,
-	793, 791, 792, 857, 796, 513, 797, 798, 799, 794,
-	795, 1948, 1949, 1950, 1951, 800, 801, 858, 802, 803,
-	804, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	1868, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 5245, 345, 346, 348,
-	347, 349, 350, 351, 352, 1873, 353, 354, 1874, 1875,
-	1876, 0, 1877, 805, 1878, 1879, 1880, 356, 0, 355,
-	1881, 357, 358, 359, 874, 360, 361, 362, 363, 364,
-	365, 366, 367, 806, 807, 0, 368, 808, 369, 809,
-	1882, 810, 370, 371, 372, 373, 374, 375, 376, 377,
-	378, 379, 1883, 1884, 0, 380, 811, 812, 813, 1885,
-	381, 382, 383, 384, 814, 1886, 875, 1887, 385, 386,
-	387, 388, 389, 390, 391, 392, 0, 1888, 394, 395,
-	396, 393, 397, 398, 1889, 399, 0, 400, 401, 402,
-	403, 404, 405, 406, 1890, 407, 408, 409, 876, 410,
-	411, 412, 1891, 1892, 1894, 1893, 1895, 1896, 1897, 413,
-	414, 415, 416, 417, 0, 418, 420, 421, 815, 422,
-	816, 1898, 425, 427, 419, 423, 1899, 426, 424, 428,
-	429, 1900, 430, 431, 432, 433, 1901, 1902, 434, 435,
-	436, 1903, 437, 438, 440, 439, 1904, 441, 442, 443,
-	1905, 444, 445, 817, 446, 447, 448, 450, 452, 449,
-	451, 453, 454, 455, 456, 457, 818, 819, 458, 459,
-	1906, 340, 1907, 0, 0, 0, 0, 460, 461, 462,
-	820, 0, 0, 0, 463, 1908, 465, 469, 466, 467,
-	468, 470, 1909, 464, 471, 472, 1910, 877, 473, 474,
-	475, 821, 822, 476, 477, 478, 479, 480, 481, 482,
-	483, 484, 1911, 485, 486, 823, 1912, 824, 487, 1913,
-	488, 489, 490, 491, 492, 493, 494, 825, 826, 827,
-	595, 879, 495, 496, 497, 1914, 498, 499, 500, 501,
-	502, 503, 504, 0, 0, 0, 505, 506, 507, 508,
-	1915, 342, 341, 343, 878, 828, 509, 596, 510, 829,
-	830, 1916, 831, 1917, 511, 512, 515, 880, 832, 881,
-	514, 516, 517, 882, 518, 0, 0, 0, 519, 520,
-	521, 522, 523, 524, 525, 1918, 526, 528, 527, 1919,
-	530, 833, 529, 883, 531, 532, 884, 1920, 533, 534,
-	535, 536, 537, 538, 541, 1921, 1922, 539, 540, 542,
-	543, 0, 544, 545, 547, 550, 546, 548, 549, 551,
-	552, 565, 566, 553, 554, 555, 556, 557, 558, 559,
-	560, 561, 562, 563, 564, 568, 0, 567, 885, 569,
-	570, 571, 572, 573, 581, 583, 584, 579, 580, 582,
-	585, 586, 588, 589, 576, 577, 578, 886, 587, 574,
-	1923, 575, 344, 887, 590, 591, 592, 593, 1924, 834,
-	594, 835, 597, 598, 1925, 0, 599, 0, 600, 1926,
-	1927, 602, 603, 604, 1928, 1929, 605, 606, 836, 888,
-	607, 889, 837, 608, 609, 601, 610, 611, 612, 613,
-	614, 615, 616, 617, 618, 619, 1930, 620, 621, 838,
-	622, 623, 624, 839, 625, 626, 627, 840, 628, 841,
-	629, 630, 1931, 631, 632, 633, 0, 634, 635, 636,
-	637, 638, 639, 640, 641, 642, 643, 842, 644, 645,
-	647, 646, 648, 649, 1932, 650, 0, 651, 652, 653,
-	0, 0, 0, 0, 0, 654, 655, 657, 0, 658,
-	659, 660, 661, 662, 656, 663, 664, 665, 666, 667,
-	668, 669, 1933, 671, 672, 670, 673, 674, 890, 675,
-	676, 677, 678, 679, 843, 680, 0, 681, 682, 690,
-	691, 692, 683, 684, 686, 693, 685, 694, 695, 696,
-	697, 699, 698, 1934, 701, 702, 700, 703, 704, 705,
-	706, 1935, 707, 844, 708, 687, 688, 709, 710, 711,
-	891, 712, 713, 714, 715, 716, 717, 718, 719, 720,
-	845, 0, 721, 1936, 722, 723, 724, 725, 726, 727,
-	729, 689, 730, 731, 732, 737, 738, 846, 733, 734,
-	735, 736, 847, 740, 741, 742, 743, 1937, 744, 745,
-	0, 739, 728, 1938, 746, 747, 748, 749, 750, 751,
-	752, 753, 754, 755, 1939, 756, 848, 849, 850, 851,
-	1940, 768, 1941, 757, 759, 760, 761, 762, 852, 763,
-	853, 1942, 764, 765, 766, 767, 758, 769, 770, 1943,
-	1944, 771, 772, 773, 774, 776, 778, 779, 780, 775,
-	777, 781, 1945, 782, 1946, 0, 783, 784, 785, 854,
-	855, 856, 1947, 787, 788, 786, 789, 790, 793, 791,
-	792, 857, 796, 513, 797, 798, 799, 794, 795, 1948,
-	1949, 1950, 1951, 800, 801, 858, 802, 803, 804, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 1868, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 5053, 345, 346, 348, 347, 349,
-	350, 351, 352, 1873, 353, 354, 1874, 1875, 1876, 0,
-	1877, 805, 1878, 1879, 1880, 356, 0, 355, 1881, 357,
-	358, 359, 874, 360, 361, 362, 363, 364, 365, 366,
-	367, 806, 807, 0, 368, 808, 369, 809, 1882, 810,
-	370, 371, 372, 373, 374, 375, 376, 377, 378, 379,
-	1883, 1884, 0, 380, 811, 812, 813, 1885, 381, 382,
-	383, 384, 814, 1886, 875, 1887, 385, 386, 387, 388,
-	389, 390, 391, 392, 0, 1888, 394, 395, 396, 393,
-	397, 398, 1889, 399, 0, 400, 401, 402, 403, 404,
-	405, 406, 1890, 407, 408, 409, 876, 410, 411, 412,
-	1891, 1892, 1894, 1893, 1895, 1896, 1897, 413, 414, 415,
-	416, 417, 0, 418, 420, 421, 815, 422, 816, 1898,
-	425, 427, 419, 423, 1899, 426, 424, 428, 429, 1900,
-	430, 431, 432, 433, 1901, 1902, 434, 435, 436, 1903,
-	437, 438, 440, 439, 1904, 441, 442, 443, 1905, 444,
-	445, 817, 446, 447, 448, 450, 452, 449, 451, 453,
-	454, 455, 456, 457, 818, 819, 458, 459, 1906, 340,
-	1907, 0, 0, 0, 0, 460, 461, 462, 820, 0,
-	0, 0, 463, 1908, 465, 469, 466, 467, 468, 470,
-	1909, 464, 471, 472, 1910, 877, 473, 474, 475, 821,
-	822, 476, 477, 478, 479, 480, 481, 482, 483, 484,
-	1911, 485, 486, 823, 1912, 824, 487, 1913, 488, 489,
-	490, 491, 492, 493, 494, 825, 826, 827, 595, 879,
-	495, 496, 497, 1914, 498, 499, 500, 501, 502, 503,
-	504, 0, 0, 0, 505, 506, 507, 508, 1915, 342,
-	341, 343, 878, 828, 509, 596, 510, 829, 830, 1916,
-	831, 1917, 511, 512, 515, 880, 832, 881, 514, 516,
-	517, 882, 518, 0, 0, 0, 519, 520, 521, 522,
-	523, 524, 525, 1918, 526, 528, 527, 1919, 530, 833,
-	529, 883, 531, 532, 884, 1920, 533, 534, 535, 536,
-	537, 538, 541, 1921, 1922, 539, 540, 542, 543, 0,
-	544, 545, 547, 550, 546, 548, 549, 551, 552, 565,
-	566, 553, 554, 555, 556, 557, 558, 559, 560, 561,
-	562, 563, 564, 568, 0, 567, 885, 569, 570, 571,
-	572, 573, 581, 583, 584, 579, 580, 582, 585, 586,
-	588, 589, 576, 577, 578, 886, 587, 574, 1923, 575,
-	344, 887, 590, 591, 592, 593, 1924, 834, 594, 835,
-	597, 598, 1925, 0, 599, 0, 600, 1926, 1927, 602,
-	603, 604, 1928, 1929, 605, 606, 836, 888, 607, 889,
-	837, 608, 609, 601, 610, 611, 612, 613, 614, 615,
-	616, 617, 618, 619, 1930, 620, 621, 838, 622, 623,
-	624, 839, 625, 626, 627, 840, 628, 841, 629, 630,
-	1931, 631, 632, 633, 0, 634, 635, 636, 637, 638,
-	639, 640, 641, 642, 643, 842, 644, 645, 647, 646,
-	648, 649, 1932, 650, 0, 651, 652, 653, 0, 0,
-	0, 0, 0, 654, 655, 657, 0, 658, 659, 660,
-	661, 662, 656, 663, 664, 665, 666, 667, 668, 669,
-	1933, 671, 672, 670, 673, 674, 890, 675, 676, 677,
-	678, 679, 843, 680, 0, 681, 682, 690, 691, 692,
-	683, 684, 686, 693, 685, 694, 695, 696, 697, 699,
-	698, 1934, 701, 702, 700, 703, 704, 705, 706, 1935,
-	707, 844, 708, 687, 688, 709, 710, 711, 891, 712,
-	713, 714, 715, 716, 717, 718, 719, 720, 845, 0,
-	721, 1936, 722, 723, 724, 725, 726, 727, 729, 689,
-	730, 731, 732, 737, 738, 846, 733, 734, 735, 736,
-	847, 740, 741, 742, 743, 1937, 744, 745, 0, 739,
-	728, 1938, 746, 747, 748, 749, 750, 751, 752, 753,
-	754, 755, 1939, 756, 848, 849, 850, 851, 1940, 768,
-	1941, 757, 759, 760, 761, 762, 852, 763, 853, 1942,
-	764, 765, 766, 767, 758, 769, 770, 1943, 1944, 771,
-	772, 773, 774, 776, 778, 779, 780, 775, 777, 781,
-	1945, 782, 1946, 0, 783, 784, 785, 854, 855, 856,
-	1947, 787, 788, 786, 789, 790, 793, 791, 792, 857,
-	796, 513, 797, 798, 799, 794, 795, 1948, 1949, 1950,
-	1951, 800, 801, 858, 802, 803, 804, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 1868, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 3184, 345, 346, 348, 347, 349, 350, 351,
-	352, 1873, 353, 354, 1874, 1875, 1876, 0, 1877, 805,
-	1878, 1879, 1880, 356, 0, 355, 1881, 357, 358, 359,
-	874, 360, 361, 362, 363, 364, 365, 366, 367, 806,
-	807, 0, 368, 808, 369, 809, 1882, 810, 370, 371,
-	372, 373, 374, 375, 376, 377, 378, 379, 1883, 1884,
-	0, 380, 811, 812, 813, 1885, 381, 382, 383, 384,
-	814, 1886, 875, 1887, 385, 386, 387, 388, 389, 390,
-	391, 392, 0, 1888, 394, 395, 396, 393, 397, 398,
-	1889, 399, 0, 400, 401, 402, 403, 404, 405, 406,
-	1890, 407, 408, 409, 876, 410, 411, 412, 1891, 1892,
-	1894, 1893, 1895, 1896, 1897, 413, 414, 415, 416, 417,
-	0, 418, 420, 421, 815, 422, 816, 1898, 425, 427,
-	419, 423, 1899, 426, 424, 428, 429, 1900, 430, 431,
-	432, 433, 1901, 1902, 434, 435, 436, 1903, 437, 438,
-	440, 439, 1904, 441, 442, 443, 1905, 444, 445, 817,
-	446, 447, 448, 450, 452, 449, 451, 453, 454, 455,
-	456, 457, 818, 819, 458, 459, 1906, 340, 1907, 0,
-	0, 0, 0, 460, 461, 462, 820, 0, 0, 0,
-	463, 1908, 465, 469, 466, 467, 468, 470, 1909, 464,
-	471, 472, 1910, 877, 473, 474, 475, 821, 822, 476,
-	477, 478, 479, 480, 481, 482, 483, 484, 1911, 485,
-	486, 823, 1912, 824, 487, 1913, 488, 489, 490, 491,
-	492, 493, 494, 825, 826, 827, 595, 879, 495, 496,
-	497, 1914, 498, 499, 500, 501, 502, 503, 504, 0,
-	0, 0, 505, 506, 507, 508, 1915, 342, 341, 343,
-	878, 828, 509, 596, 510, 829, 830, 1916, 831, 1917,
-	511, 512, 515, 880, 832, 881, 514, 516, 517, 882,
-	518, 0, 0, 0, 519, 520, 521, 522, 523, 524,
-	525, 1918, 526, 528, 527, 1919, 530, 833, 529, 883,
-	531, 532, 884, 1920, 533, 534, 535, 536, 537, 538,
-	541, 1921, 1922, 539, 540, 542, 543, 0, 544, 545,
-	547, 550, 546, 548, 549, 551, 552, 565, 566, 553,
-	554, 555, 556, 557, 558, 559, 560, 561, 562, 563,
-	564, 568, 0, 567, 885, 569, 570, 571, 572, 573,
-	581, 583, 584, 579, 580, 582, 585, 586, 588, 589,
-	576, 577, 578, 886, 587, 574, 1923, 575, 344, 887,
-	590, 591, 592, 593, 1924, 834, 594, 835, 597, 598,
-	1925, 0, 599, 0, 600, 1926, 1927, 602, 603, 604,
-	1928, 1929, 605, 606, 836, 888, 607, 889, 837, 608,
-	609, 601, 610, 611, 612, 613, 614, 615, 616, 617,
-	618, 619, 1930, 620, 621, 838, 622, 623, 624, 839,
-	625, 626, 627, 840, 628, 841, 629, 630, 1931, 631,
-	632, 633, 0, 634, 635, 636, 637, 638, 639, 640,
-	641, 642, 643, 842, 644, 645, 647, 646, 648, 649,
-	1932, 650, 0, 651, 652, 653, 0, 0, 0, 0,
-	0, 654, 655, 657, 0, 658, 659, 660, 661, 662,
-	656, 663, 664, 665, 666, 667, 668, 669, 1933, 671,
-	672, 670, 673, 674, 890, 675, 676, 677, 678, 679,
-	843, 680, 0, 681, 682, 690, 691, 692, 683, 684,
-	686, 693, 685, 694, 695, 696, 697, 699, 698, 1934,
-	701, 702, 700, 703, 704, 705, 706, 1935, 707, 844,
-	708, 687, 688, 709, 710, 711, 891, 712, 713, 714,
-	715, 716, 717, 718, 719, 720, 845, 0, 721, 1936,
-	722, 723, 724, 725, 726, 727, 729, 689, 730, 731,
-	732, 737, 738, 846, 733, 734, 735, 736, 847, 740,
-	741, 742, 743, 1937, 744, 745, 0, 739, 728, 1938,
-	746, 747, 748, 749, 750, 751, 752, 753, 754, 755,
-	1939, 756, 848, 849, 850, 851, 1940, 768, 1941, 757,
-	759, 760, 761, 762, 852, 763, 853, 1942, 764, 765,
-	766, 767, 758, 769, 770, 1943, 1944, 771, 772, 773,
-	774, 776, 778, 779, 780, 775, 777, 781, 1945, 782,
-	1946, 0, 783, 784, 785, 854, 855, 856, 1947, 787,
-	788, 786, 789, 790, 793, 791, 792, 857, 796, 513,
-	797, 798, 799, 794, 795, 1948, 1949, 1950, 1951, 800,
-	801, 858, 802, 803, 804, 0, 0, 0, 0, 0,
-	0, 0, 1372, 0, 1460, 1403, 1404, 1405, 1401, 1402,
-	1414, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	2898, 345, 346, 348, 347, 349, 350, 351, 352, 0,
-	353, 354, 0, 0, 0, 0, 0, 1452, 1419, 0,
-	0, 356, 0, 355, 0, 357, 358, 359, 874, 360,
-	361, 362, 363, 364, 365, 366, 367, 806, 1466, 0,
-	368, 1474, 369, 1473, 0, 1484, 370, 371, 372, 373,
-	374, 375, 376, 377, 378, 379, 1421, 1451, 1385, 380,
-	1497, 1498, 813, 0, 381, 382, 383, 384, 1458, 0,
-	1439, 0, 385, 386, 387, 388, 389, 390, 391, 392,
-	0, 0, 394, 395, 396, 393, 397, 398, 0, 399,
-	0, 400, 401, 402, 403, 404, 405, 406, 0, 407,
-	408, 409, 876, 410, 411, 412, 1442, 1440, 1441, 1448,
-	1444, 1443, 1447, 413, 414, 415, 416, 417, 1477, 418,
-	420, 421, 1471, 422, 1470, 1390, 425, 427, 419, 423,
-	0, 426, 424, 428, 429, 0, 430, 431, 432, 433,
-	0, 0, 434, 1469, 436, 0, 437, 438, 440, 439,
-	0, 441, 442, 443, 0, 444, 445, 1397, 446, 447,
-	448, 450, 452, 449, 451, 453, 454, 455, 456, 457,
-	1485, 1486, 458, 459, 1410, 340, 0, 0, 0, 0,
-	0, 460, 461, 462, 1468, 0, 0, 0, 463, 0,
-	465, 469, 466, 467, 468, 470, 0, 464, 471, 472,
-	0, 877, 473, 474, 475, 1482, 1483, 476, 477, 478,
-	479, 480, 481, 482, 483, 484, 0, 485, 486, 1492,
-	0, 1420, 487, 0, 488, 489, 490, 491, 492, 493,
-	494, 1453, 1454, 1457, 595, 879, 495, 496, 497, 0,
-	498, 499, 500, 501, 502, 503, 504, 0, 0, 0,
-	505, 506, 507, 508, 0, 867, 341, 343, 878, 828,
-	509, 596, 510, 1463, 1464, 0, 1424, 0, 511, 512,
-	515, 880, 1455, 881, 514, 516, 517, 882, 518, 0,
-	0, 0, 519, 520, 521, 522, 523, 524, 525, 0,
-	526, 528, 527, 0, 530, 1493, 529, 883, 531, 532,
-	884, 0, 533, 534, 535, 536, 537, 538, 541, 1446,
-	1445, 539, 540, 542, 543, 0, 544, 545, 547, 550,
-	546, 548, 549, 551, 552, 565, 566, 553, 554, 555,
-	556, 557, 558, 559, 560, 561, 562, 563, 564, 568,
-	0, 567, 885, 569, 570, 571, 572, 573, 581, 583,
-	584, 579, 580, 582, 585, 586, 588, 589, 576, 577,
-	578, 886, 587, 574, 1387, 575, 344, 887, 590, 591,
-	592, 593, 1411, 1456, 594, 1472, 597, 598, 0, 0,
-	599, 0, 600, 0, 0, 602, 603, 604, 0, 0,
-	605, 606, 836, 888, 607, 889, 1487, 608, 609, 1398,
-	610, 611, 612, 613, 614, 615, 616, 617, 618, 619,
-	0, 620, 621, 838, 622, 623, 624, 839, 625, 626,
-	627, 1488, 628, 841, 629, 630, 0, 631, 632, 633,
-	0, 634, 635, 636, 637, 638, 639, 640, 641, 642,
-	643, 1467, 644, 645, 647, 646, 648, 649, 0, 650,
-	0, 651, 652, 653, 0, 0, 0, 0, 0, 654,
-	655, 657, 0, 658, 659, 660, 661, 662, 656, 663,
-	664, 665, 666, 667, 668, 669, 0, 671, 672, 670,
-	673, 674, 890, 675, 676, 677, 678, 679, 1399, 680,
-	0, 681, 682, 690, 691, 692, 683, 684, 686, 693,
-	685, 694, 695, 696, 697, 699, 698, 295, 701, 702,
-	700, 703, 704, 705, 706, 1449, 707, 844, 708, 687,
-	688, 709, 710, 711, 891, 712, 713, 714, 715, 716,
-	717, 718, 719, 720, 1465, 0, 721, 0, 722, 723,
-	724, 725, 726, 727, 729, 689, 730, 731, 732, 737,
-	738, 1496, 733, 734, 735, 736, 1489, 740, 741, 742,
-	743, 0, 744, 745, 1384, 739, 728, 297, 746, 747,
-	748, 749, 750, 751, 752, 753, 754, 755, 0, 756,
-	1478, 1479, 1480, 1481, 0, 768, 0, 757, 759, 760,
-	761, 762, 1490, 763, 1491, 1409, 764, 765, 766, 767,
-	758, 769, 770, 0, 1391, 771, 772, 773, 774, 776,
-	778, 779, 780, 775, 777, 781, 1450, 782, 0, 0,
-	783, 784, 785, 2114, 1475, 1495, 0, 787, 788, 786,
-	789, 790, 793, 791, 792, 857, 796, 513, 797, 798,
-	799, 794, 795, 0, 0, 0, 289, 800, 801, 858,
-	802, 803, 804, 1388, 0, 290, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 1383,
-	0, 0, 0, 0, 0, 0, 1381, 1382, 0, 0,
-	0, 0, 0, 0, 864, 0, 2269, 2267, 0, 2390,
-	1413, 1460, 1403, 1404, 1405, 1401, 1402, 1414, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 345, 346,
-	348, 347, 349, 350, 351, 352, 2387, 353, 354, 0,
-	0, 0, 0, 0, 1452, 1419, 0, 0, 356, 0,
-	355, 0, 357, 358, 359, 874, 360, 361, 362, 363,
-	364, 365, 366, 367, 806, 1466, 0, 368, 1474, 369,
-	1473, 0, 1484, 370, 371, 372, 373, 374, 375, 376,
-	377, 378, 379, 1421, 1451, 1385, 380, 1497, 1498, 813,
-	0, 381, 382, 383, 384, 1458, 0, 1439, 0, 385,
-	386, 387, 388, 389, 390, 391, 392, 0, 0, 394,
-	395, 396, 393, 397, 398, 0, 399, 0, 400, 401,
-	402, 403, 404, 405, 406, 0, 407, 408, 409, 876,
-	410, 411, 412, 1442, 1440, 1441, 1448, 1444, 1443, 1447,
-	413, 414, 415, 416, 417, 1477, 418, 420, 421, 1471,
-	422, 1470, 1390, 425, 427, 419, 423, 0, 426, 424,
-	428, 429, 0, 430, 431, 432, 433, 2388, 0, 434,
-	1469, 436, 0, 437, 438, 440, 439, 0, 441, 442,
-	443, 0, 444, 445, 1397, 446, 447, 448, 450, 452,
-	449, 451, 453, 454, 455, 456, 457, 1485, 1486, 458,
-	459, 1410, 340, 0, 0, 0, 0, 0, 460, 461,
-	462, 1468, 0, 0, 0, 463, 0, 465, 469, 466,
-	467, 468, 470, 0, 464, 471, 472, 0, 877, 473,
-	474, 475, 1482, 1483, 476, 477, 478, 479, 480, 481,
-	482, 483, 484, 0, 485, 486, 1492, 0, 1420, 487,
-	0, 488, 489, 490, 491, 492, 493, 494, 1453, 1454,
-	1457, 595, 879, 495, 496, 497, 0, 498, 499, 500,
-	501, 502, 503, 504, 0, 0, 0, 505, 506, 507,
-	508, 0, 867, 341, 343, 878, 828, 509, 596, 510,
-	1463, 1464, 0, 1424, 0, 511, 512, 515, 880, 1455,
-	881, 514, 516, 517, 882, 518, 0, 0, 0, 519,
-	520, 521, 522, 523, 524, 525, 0, 526, 528, 527,
-	0, 530, 1493, 529, 883, 531, 532, 884, 0, 533,
-	534, 535, 536, 537, 538, 541, 1446, 1445, 539, 540,
-	542, 543, 0, 544, 545, 547, 550, 546, 548, 549,
-	551, 552, 565, 566, 553, 554, 555, 556, 557, 558,
-	559, 560, 561, 562, 563, 564, 568, 0, 567, 885,
-	569, 570, 571, 572, 573, 581, 583, 584, 579, 580,
-	582, 585, 586, 588, 589, 576, 577, 578, 886, 587,
-	574, 1387, 575, 344, 887, 590, 591, 592, 593, 1411,
-	1456, 594, 1472, 597, 598, 0, 0, 599, 0, 600,
-	0, 0, 602, 603, 604, 0, 0, 605, 606, 836,
-	888, 607, 889, 1487, 608, 609, 1398, 610, 611, 612,
-	613, 614, 615, 616, 617, 618, 619, 0, 620, 621,
-	838, 622, 623, 624, 839, 625, 626, 627, 1488, 628,
-	841, 629, 630, 0, 631, 632, 633, 0, 634, 635,
-	636, 637, 638, 639, 640, 641, 642, 643, 1467, 644,
-	645, 647, 646, 648, 649, 0, 650, 0, 651, 652,
-	653, 0, 0, 0, 0, 0, 654, 655, 657, 0,
-	658, 659, 660, 661, 662, 656, 663, 664, 665, 666,
-	667, 668, 669, 0, 671, 672, 670, 673, 674, 890,
-	675, 676, 677, 678, 679, 1399, 680, 0, 681, 682,
-	690, 691, 692, 683, 684, 686, 693, 685, 694, 695,
-	696, 697, 699, 698, 0, 701, 702, 700, 703, 704,
-	705, 706, 1449, 707, 844, 708, 687, 688, 709, 710,
-	711, 891, 712, 713, 714, 715, 716, 717, 718, 719,
-	720, 1465, 0, 721, 0, 722, 723, 724, 725, 726,
-	727, 729, 689, 730, 731, 732, 737, 738, 1496, 733,
-	734, 735, 736, 1489, 740, 741, 742, 743, 0, 744,
-	745, 1384, 739, 728, 0, 746, 747, 748, 749, 750,
-	751, 752, 753, 754, 755, 0, 756, 1478, 1479, 1480,
-	1481, 0, 768, 0, 757, 759, 760, 761, 762, 1490,
-	763, 1491, 1409, 764, 765, 766, 767, 758, 769, 770,
-	0, 1391, 771, 772, 773, 774, 776, 778, 779, 780,
-	775, 777, 781, 1450, 782, 0, 0, 783, 784, 785,
-	854, 1475, 1495, 2386, 787, 788, 786, 789, 790, 793,
-	791, 792, 857, 796, 513, 797, 798, 799, 794, 795,
-	0, 0, 0, 0, 800, 801, 858, 802, 803, 804,
-	1388, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 1383, 0, 0, 1865,
-	0, 1868, 0, 1381, 1382, 2389, 0, 0, 0, 0,
-	0, 864, 0, 1415, 2384, 0, 0, 1413, 345, 346,
-	348, 347, 349, 350, 351, 352, 1873, 353, 354, 1874,
-	1875, 1876, 0, 1877, 805, 1878, 1879, 1880, 356, 0,
-	355, 1881, 357, 358, 359, 874, 360, 361, 362, 363,
-	364, 365, 366, 367, 806, 807, 0, 368, 808, 369,
-	809, 1882, 810, 370, 371, 372, 373, 374, 375, 376,
-	377, 378, 379, 1883, 1884, 0, 380, 811, 812, 813,
-	1885, 381, 382, 383, 384, 814, 1886, 875, 1887, 385,
-	386, 387, 388, 389, 390, 391, 392, 0, 1888, 394,
-	395, 396, 393, 397, 398, 1889, 399, 0, 400, 401,
-	402, 403, 404, 405, 406, 1890, 407, 408, 409, 876,
-	410, 411, 412, 1891, 1892, 1894, 1893, 1895, 1896, 1897,
-	413, 414, 415, 416, 417, 0, 418, 420, 421, 815,
-	422, 816, 1898, 425, 427, 419, 423, 1899, 426, 424,
-	428, 429, 1900, 430, 431, 432, 433, 1901, 1902, 434,
-	435, 436, 1903, 437, 438, 440, 439, 1904, 441, 442,
-	443, 1905, 444, 445, 817, 446, 447, 448, 450, 452,
-	449, 451, 453, 454, 455, 456, 457, 818, 819, 458,
-	459, 1906, 340, 1907, 0, 0, 0, 0, 460, 461,
-	462, 820, 0, 0, 0, 463, 1908, 465, 469, 466,
-	467, 468, 470, 1909, 464, 471, 472, 1910, 877, 473,
-	474, 475, 821, 822, 476, 477, 478, 479, 480, 481,
-	482, 483, 484, 1911, 485, 486, 823, 1912, 824, 487,
-	1913, 488, 489, 490, 491, 492, 493, 494, 825, 826,
-	827, 595, 879, 495, 496, 497, 1914, 498, 499, 500,
-	501, 502, 503, 504, 0, 0, 0, 505, 506, 507,
-	508, 1915, 342, 341, 343, 878, 828, 509, 596, 510,
-	829, 830, 1916, 831, 1917, 511, 512, 515, 880, 832,
-	881, 514, 516, 517, 882, 518, 0, 0, 0, 519,
-	520, 521, 522, 523, 524, 525, 1918, 526, 528, 527,
-	1919, 530, 833, 529, 883, 531, 532, 884, 1920, 533,
-	534, 535, 536, 537, 538, 541, 1921, 1922, 539, 540,
-	542, 543, 0, 544, 545, 547, 550, 546, 548, 549,
-	551, 552, 565, 566, 553, 554, 555, 556, 557, 558,
-	559, 560, 561, 562, 563, 564, 568, 0, 567, 885,
-	569, 570, 571, 572, 573, 581, 583, 584, 579, 580,
-	582, 585, 586, 588, 589, 576, 577, 578, 886, 587,
-	574, 1923, 575, 344, 887, 590, 591, 592, 593, 1924,
-	834, 594, 835, 597, 598, 1925, 0, 599, 0, 600,
-	1926, 1927, 602, 603, 604, 1928, 1929, 605, 606, 836,
-	888, 607, 889, 837, 608, 609, 601, 610, 611, 612,
-	613, 614, 615, 616, 617, 618, 619, 1930, 620, 621,
-	838, 622, 623, 624, 839, 625, 626, 627, 840, 628,
-	841, 629, 630, 1931, 631, 632, 633, 0, 634, 635,
-	636, 637, 638, 639, 640, 641, 642, 643, 842, 644,
-	645, 647, 646, 648, 649, 1932, 650, 0, 651, 652,
-	653, 0, 0, 0, 0, 0, 654, 655, 657, 0,
-	658, 659, 660, 661, 662, 656, 663, 664, 665, 666,
-	667, 668, 669, 1933, 671, 672, 670, 673, 674, 890,
-	675, 676, 677, 678, 679, 843, 680, 0, 681, 682,
-	690, 691, 692, 683, 684, 686, 693, 685, 694, 695,
-	696, 697, 699, 698, 1934, 701, 702, 700, 703, 704,
-	705, 706, 1935, 707, 844, 708, 687, 688, 709, 710,
-	711, 891, 712, 713, 714, 715, 716, 717, 718, 719,
-	720, 845, 0, 721, 1936, 722, 723, 724, 725, 726,
-	727, 729, 689, 730, 731, 732, 737, 738, 846, 733,
-	734, 735, 736, 847, 740, 741, 742, 743, 1937, 744,
-	745, 0, 739, 728, 1938, 746, 747, 748, 749, 750,
-	751, 752, 753, 754, 755, 1939, 756, 848, 849, 850,
-	851, 1940, 768, 1941, 757, 759, 760, 761, 762, 852,
-	763, 853, 1942, 764, 765, 766, 767, 758, 769, 770,
-	1943, 1944, 771, 772, 773, 774, 776, 778, 779, 780,
-	775, 777, 781, 1945, 782, 1946, 0, 783, 784, 785,
-	854, 855, 856, 1947, 787, 788, 786, 789, 790, 793,
-	791, 792, 857, 796, 513, 797, 798, 799, 794, 795,
-	1948, 1949, 1950, 1951, 800, 801, 858, 802, 803, 804,
-	1868, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 345, 346, 348,
-	347, 349, 350, 351, 352, 1873, 353, 354, 1874, 1875,
-	1876, 0, 1877, 805, 1878, 1879, 1880, 356, 0, 355,
-	1881, 357, 358, 359, 874, 360, 361, 362, 363, 364,
-	365, 366, 367, 806, 807, 0, 368, 808, 369, 809,
-	1882, 810, 370, 371, 372, 373, 374, 375, 376, 377,
-	378, 379, 1883, 1884, 0, 380, 811, 812, 813, 1885,
-	381, 382, 383, 384, 814, 1886, 875, 1887, 385, 386,
-	387, 388, 389, 390, 391, 392, 0, 1888, 394, 395,
-	396, 393, 397, 398, 1889, 399, 0, 400, 401, 402,
-	403, 404, 405, 406, 1890, 407, 408, 409, 876, 410,
-	411, 412, 1891, 1892, 1894, 1893, 1895, 1896, 1897, 413,
-	414, 415, 416, 417, 0, 418, 420, 421, 815, 422,
-	816, 1898, 425, 427, 419, 423, 1899, 426, 424, 428,
-	429, 1900, 430, 431, 432, 433, 1901, 1902, 434, 435,
-	436, 1903, 437, 438, 440, 439, 1904, 441, 442, 443,
-	1905, 444, 445, 817, 446, 447, 448, 450, 452, 449,
-	451, 453, 454, 455, 456, 457, 818, 819, 458, 459,
-	1906, 340, 1907, 0, 0, 0, 0, 460, 461, 462,
-	820, 0, 0, 0, 463, 1908, 465, 469, 466, 467,
-	468, 470, 1909, 464, 471, 472, 1910, 877, 473, 474,
-	475, 821, 822, 476, 477, 478, 479, 480, 481, 482,
-	483, 484, 1911, 485, 486, 823, 1912, 824, 487, 1913,
-	488, 489, 490, 491, 492, 493, 494, 825, 826, 827,
-	595, 879, 495, 496, 497, 1914, 498, 499, 500, 501,
-	502, 503, 504, 0, 0, 0, 505, 506, 507, 508,
-	1915, 342, 341, 343, 878, 828, 509, 596, 510, 829,
-	830, 1916, 831, 1917, 511, 512, 515, 880, 832, 881,
-	514, 516, 517, 882, 518, 0, 0, 0, 519, 520,
-	521, 522, 523, 524, 525, 1918, 526, 528, 527, 1919,
-	530, 833, 529, 883, 531, 532, 884, 1920, 533, 534,
-	535, 536, 537, 538, 541, 1921, 1922, 539, 540, 542,
-	543, 0, 544, 545, 547, 550, 546, 548, 549, 551,
-	552, 565, 566, 553, 554, 555, 556, 557, 558, 559,
-	560, 561, 562, 563, 564, 568, 0, 567, 885, 569,
-	570, 571, 572, 573, 581, 583, 584, 579, 580, 582,
-	585, 586, 588, 589, 576, 577, 578, 886, 587, 574,
-	1923, 575, 344, 887, 590, 591, 592, 593, 1924, 834,
-	594, 835, 597, 598, 1925, 0, 599, 0, 600, 1926,
-	1927, 602, 603, 604, 1928, 1929, 605, 606, 836, 888,
-	607, 889, 837, 608, 609, 601, 610, 611, 612, 613,
-	614, 615, 616, 617, 618, 619, 1930, 620, 621, 838,
-	622, 623, 624, 839, 625, 626, 627, 840, 628, 841,
-	629, 630, 1931, 631, 632, 633, 0, 634, 635, 636,
-	637, 638, 639, 640, 641, 642, 643, 842, 644, 645,
-	647, 646, 648, 649, 1932, 650, 0, 651, 652, 653,
-	0, 0, 0, 0, 0, 654, 655, 657, 0, 658,
-	659, 660, 661, 662, 656, 663, 664, 665, 666, 667,
-	668, 669, 1933, 671, 672, 670, 673, 674, 890, 675,
-	676, 677, 678, 679, 843, 680, 0, 681, 682, 690,
-	691, 692, 683, 684, 686, 693, 685, 694, 695, 696,
-	697, 699, 698, 1934, 701, 702, 700, 703, 704, 705,
-	706, 1935, 707, 844, 708, 687, 688, 709, 710, 711,
-	891, 712, 713, 714, 715, 716, 717, 718, 719, 720,
-	845, 0, 721, 1936, 722, 723, 724, 725, 726, 727,
-	729, 689, 730, 731, 732, 737, 738, 846, 733, 734,
-	735, 736, 847, 740, 741, 742, 743, 1937, 744, 745,
-	0, 739, 728, 1938, 746, 747, 748, 749, 750, 751,
-	752, 753, 754, 755, 1939, 756, 848, 849, 850, 851,
-	1940, 768, 1941, 757, 759, 760, 761, 762, 852, 763,
-	853, 1942, 764, 765, 766, 767, 758, 769, 770, 1943,
-	1944, 771, 772, 773, 774, 776, 778, 779, 780, 775,
-	777, 781, 1945, 782, 1946, 0, 783, 784, 785, 854,
-	855, 856, 1947, 787, 788, 786, 789, 790, 793, 791,
-	792, 857, 796, 513, 797, 798, 799, 794, 795, 1948,
-	1949, 1950, 1951, 800, 801, 858, 802, 803, 804, 1460,
-	1403, 1404, 1405, 1401, 1402, 1414, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 345, 346, 348, 347,
-	349, 350, 351, 352, 0, 353, 354, 0, 0, 0,
-	0, 0, 1452, 1419, 0, 0, 356, 0, 355, 0,
-	357, 358, 359, 874, 360, 361, 362, 363, 364, 365,
-	366, 367, 806, 1466, 0, 368, 1474, 369, 1473, 0,
-	1484, 370, 371, 372, 373, 374, 375, 376, 377, 378,
-	379, 1421, 1451, 1385, 380, 1497, 1498, 813, 0, 381,
-	382, 383, 384, 1458, 0, 1439, 0, 385, 386, 387,
-	388, 389, 390, 391, 392, 0, 0, 394, 395, 396,
-	393, 397, 398, 0, 399, 0, 400, 401, 402, 403,
-	404, 405, 406, 0, 407, 408, 409, 876, 410, 411,
-	412, 1442, 1440, 1441, 1448, 1444, 1443, 1447, 413, 414,
-	415, 416, 417, 1477, 418, 420, 421, 1471, 422, 1470,
-	1390, 425, 427, 419, 423, 0, 426, 424, 428, 429,
-	0, 430, 431, 432, 433, 0, 0, 434, 1469, 436,
-	0, 437, 438, 440, 439, 0, 441, 442, 443, 0,
-	444, 445, 1397, 446, 447, 448, 450, 452, 449, 451,
-	453, 454, 455, 456, 457, 1485, 1486, 458, 459, 1410,
-	340, 0, 0, 0, 0, 0, 460, 461, 462, 1468,
-	0, 0, 0, 463, 0, 465, 469, 466, 467, 468,
-	470, 0, 464, 471, 472, 0, 877, 473, 474, 475,
-	1482, 1483, 476, 477, 478, 479, 480, 481, 482, 483,
-	484, 0, 485, 486, 1492, 0, 1420, 487, 0, 488,
-	489, 490, 491, 492, 493, 494, 1453, 1454, 1457, 595,
-	879, 495, 496, 497, 0, 498, 499, 500, 501, 502,
-	503, 504, 0, 0, 0, 505, 506, 507, 508, 0,
-	867, 341, 343, 878, 828, 509, 596, 510, 1463, 1464,
-	0, 1424, 0, 511, 512, 515, 880, 1455, 881, 514,
-	516, 517, 882, 518, 0, 0, 0, 519, 520, 521,
-	522, 523, 524, 525, 0, 526, 528, 527, 0, 530,
-	1493, 529, 883, 531, 532, 884, 0, 533, 534, 535,
-	536, 537, 538, 541, 1446, 1445, 539, 540, 542, 543,
-	0, 544, 545, 547, 550, 546, 548, 549, 551, 552,
-	565, 566, 553, 554, 555, 556, 557, 558, 559, 560,
-	561, 562, 563, 564, 568, 0, 567, 885, 569, 570,
-	571, 572, 573, 581, 583, 584, 579, 580, 582, 585,
-	586, 588, 589, 576, 577, 578, 886, 587, 574, 1387,
-	575, 344, 887, 590, 591, 592, 593, 1411, 1456, 594,
-	1472, 597, 598, 0, 0, 599, 0, 600, 0, 0,
-	602, 603, 604, 0, 0, 605, 606, 836, 888, 607,
-	889, 1487, 608, 609, 1398, 610, 611, 612, 613, 614,
-	615, 616, 617, 618, 619, 0, 620, 621, 838, 622,
-	623, 624, 839, 625, 626, 627, 1488, 628, 841, 629,
-	630, 0, 631, 632, 633, 0, 634, 635, 636, 637,
-	638, 639, 640, 641, 642, 643, 1467, 644, 645, 647,
-	646, 648, 649, 0, 650, 0, 651, 652, 653, 0,
-	0, 0, 0, 0, 654, 655, 657, 0, 658, 659,
-	660, 661, 662, 656, 663, 664, 665, 666, 667, 668,
-	669, 0, 671, 672, 670, 673, 674, 890, 675, 676,
-	677, 678, 679, 1399, 680, 0, 681, 682, 690, 691,
-	692, 683, 684, 686, 693, 685, 694, 695, 696, 697,
-	699, 698, 295, 701, 702, 700, 703, 704, 705, 706,
-	1449, 707, 844, 708, 687, 688, 709, 710, 711, 891,
-	712, 713, 714, 715, 716, 717, 718, 719, 720, 1465,
-	0, 721, 0, 722, 723, 724, 725, 726, 727, 729,
-	689, 730, 731, 732, 737, 738, 1496, 733, 734, 735,
-	736, 1489, 740, 741, 742, 743, 0, 744, 745, 1384,
-	739, 728, 297, 746, 747, 748, 749, 750, 751, 752,
-	753, 754, 755, 0, 756, 1478, 1479, 1480, 1481, 0,
-	768, 0, 757, 759, 760, 761, 762, 1490, 763, 1491,
-	1409, 764, 765, 766, 767, 758, 769, 770, 0, 1391,
-	771, 772, 773, 774, 776, 778, 779, 780, 775, 777,
-	781, 1450, 782, 0, 0, 783, 784, 785, 2114, 1475,
-	1495, 0, 787, 788, 786, 789, 790, 793, 791, 792,
-	857, 796, 513, 797, 798, 799, 794, 795, 0, 0,
-	0, 289, 800, 801, 858, 802, 803, 804, 1388, 0,
-	290, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 1383, 0, 0, 0, 0, 0,
-	0, 1381, 1382, 0, 0, 0, 0, 0, 0, 864,
-	0, 2269, 4548, 0, 0, 1413, 1460, 1403, 1404, 1405,
-	1401, 1402, 1414, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 345, 346, 348, 347, 349, 350, 351,
-	352, 0, 353, 354, 0, 0, 0, 0, 0, 1452,
-	1419, 0, 0, 356, 0, 355, 0, 357, 358, 359,
-	874, 360, 361, 362, 363, 364, 365, 366, 367, 806,
-	1466, 0, 368, 1474, 369, 1473, 0, 1484, 370, 371,
-	372, 373, 374, 375, 376, 377, 378, 379, 1421, 1451,
-	1385, 380, 1497, 1498, 813, 0, 381, 382, 383, 384,
-	1458, 0, 1439, 0, 385, 386, 387, 388, 389, 390,
-	391, 392, 0, 0, 394, 395, 396, 393, 397, 398,
-	0, 399, 0, 400, 401, 402, 403, 404, 405, 406,
-	0, 407, 408, 409, 876, 410, 411, 412, 1442, 1440,
-	1441, 1448, 1444, 1443, 1447, 413, 414, 415, 416, 417,
-	1477, 418, 420, 421, 1471, 422, 1470, 1390, 425, 427,
-	419, 423, 0, 426, 424, 428, 429, 0, 430, 431,
-	432, 433, 0, 0, 434, 1469, 436, 0, 437, 438,
-	440, 439, 0, 441, 442, 443, 0, 444, 445, 1397,
-	446, 447, 448, 450, 452, 449, 451, 453, 454, 455,
-	456, 457, 1485, 1486, 458, 459, 1410, 340, 0, 0,
-	0, 0, 0, 460, 461, 462, 1468, 0, 0, 0,
-	463, 0, 465, 469, 466, 467, 468, 470, 0, 464,
-	471, 472, 0, 877, 473, 474, 475, 1482, 1483, 476,
-	477, 478, 479, 480, 481, 482, 483, 484, 0, 485,
-	486, 1492, 0, 1420, 487, 0, 488, 489, 490, 491,
-	492, 493, 494, 1453, 1454, 1457, 595, 879, 495, 496,
-	497, 0, 498, 499, 500, 501, 502, 503, 504, 0,
-	0, 0, 505, 506, 507, 508, 0, 867, 341, 343,
-	878, 828, 509, 596, 510, 1463, 1464, 0, 1424, 0,
-	511, 512, 515, 880, 1455, 881, 514, 516, 517, 882,
-	518, 0, 0, 0, 519, 520, 521, 522, 523, 524,
-	525, 0, 526, 528, 527, 0, 530, 1493, 529, 883,
-	531, 532, 884, 0, 533, 534, 535, 536, 537, 538,
-	541, 1446, 1445, 539, 540, 542, 543, 0, 544, 545,
-	547, 550, 546, 548, 549, 551, 552, 565, 566, 553,
-	554, 555, 556, 557, 558, 559, 560, 561, 562, 563,
-	564, 568, 0, 567, 885, 569, 570, 571, 572, 573,
-	581, 583, 584, 579, 580, 582, 585, 586, 588, 589,
-	576, 577, 578, 886, 587, 574, 1387, 575, 344, 887,
-	590, 591, 592, 593, 1411, 1456, 594, 1472, 597, 598,
-	0, 0, 599, 0, 600, 0, 0, 602, 603, 604,
-	0, 0, 605, 606, 836, 888, 607, 889, 1487, 608,
-	609, 1398, 610, 611, 612, 613, 614, 615, 616, 617,
-	618, 619, 0, 620, 621, 838, 622, 623, 624, 839,
-	625, 626, 627, 1488, 628, 841, 629, 630, 0, 631,
-	632, 633, 0, 634, 635, 636, 637, 638, 639, 640,
-	641, 642, 643, 1467, 644, 645, 647, 646, 648, 649,
-	0, 650, 0, 651, 652, 653, 0, 0, 0, 0,
-	0, 654, 655, 657, 0, 658, 659, 660, 661, 662,
-	656, 663, 664, 665, 666, 667, 668, 669, 0, 671,
-	672, 670, 673, 674, 890, 675, 676, 677, 678, 679,
-	1399, 680, 0, 681, 682, 690, 691, 692, 683, 684,
-	686, 693, 685, 694, 695, 696, 697, 699, 698, 295,
-	701, 702, 700, 703, 704, 705, 706, 1449, 707, 844,
-	708, 687, 688, 709, 710, 711, 891, 712, 713, 714,
-	715, 716, 717, 718, 719, 720, 1465, 0, 721, 0,
-	722, 723, 724, 725, 726, 727, 729, 689, 730, 731,
-	732, 737, 738, 1496, 733, 734, 735, 736, 1489, 740,
-	741, 742, 743, 0, 744, 745, 1384, 739, 728, 297,
-	746, 747, 748, 749, 750, 751, 752, 753, 754, 755,
-	0, 756, 1478, 1479, 1480, 1481, 0, 768, 0, 757,
-	759, 760, 761, 762, 1490, 763, 1491, 1409, 764, 765,
-	766, 767, 758, 769, 770, 0, 1391, 771, 772, 773,
-	774, 776, 778, 779, 780, 775, 777, 781, 1450, 782,
-	0, 0, 783, 784, 785, 2114, 1475, 1495, 0, 787,
-	788, 786, 789, 790, 793, 791, 792, 857, 796, 513,
-	797, 798, 799, 794, 795, 0, 0, 0, 289, 800,
-	801, 858, 802, 803, 804, 1388, 0, 290, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 1383, 0, 0, 0, 0, 0, 0, 1381, 1382,
-	0, 0, 0, 0, 0, 0, 864, 0, 2269, 2267,
-	0, 0, 1413, 1460, 1403, 1404, 1405, 1401, 1402, 1414,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	345, 346, 348, 347, 349, 350, 351, 352, 0, 353,
-	354, 0, 0, 0, 0, 0, 1452, 1419, 0, 0,
-	356, 0, 355, 0, 357, 358, 359, 874, 360, 361,
-	362, 363, 364, 365, 366, 367, 806, 1466, 0, 368,
-	1474, 369, 1473, 3292, 1484, 370, 371, 372, 373, 374,
-	375, 376, 377, 378, 379, 1421, 1451, 1385, 380, 1497,
-	1498, 813, 0, 381, 382, 383, 384, 1458, 0, 1439,
-	0, 385, 386, 387, 388, 389, 390, 391, 392, 0,
-	0, 394, 395, 396, 393, 397, 398, 0, 399, 0,
-	400, 401, 402, 403, 404, 405, 406, 0, 407, 408,
-	409, 876, 410, 411, 412, 1442, 1440, 1441, 1448, 1444,
-	1443, 1447, 413, 414, 415, 416, 417, 1477, 418, 420,
-	421, 1471, 422, 1470, 1390, 425, 427, 419, 423, 0,
-	426, 424, 428, 429, 0, 430, 431, 432, 433, 0,
-	0, 434, 1469, 436, 0, 437, 438, 440, 439, 0,
-	441, 442, 443, 0, 444, 445, 1397, 446, 447, 448,
-	450, 452, 449, 451, 453, 454, 455, 456, 457, 1485,
-	1486, 458, 459, 1410, 340, 0, 0, 0, 0, 0,
-	460, 461, 462, 1468, 0, 0, 0, 463, 0, 465,
-	469, 466, 467, 468, 470, 0, 464, 471, 472, 3297,
-	877, 473, 474, 475, 1482, 1483, 476, 477, 478, 479,
-	480, 481, 482, 483, 484, 0, 485, 486, 1492, 0,
-	1420, 487, 0, 488, 489, 490, 491, 492, 493, 494,
-	1453, 1454, 1457, 595, 879, 495, 496, 497, 0, 498,
-	499, 500, 501, 502, 503, 504, 0, 0, 0, 505,
-	506, 507, 508, 0, 867, 341, 343, 878, 828, 509,
-	596, 510, 1463, 1464, 0, 1424, 0, 511, 512, 515,
-	880, 1455, 881, 514, 516, 517, 882, 518, 0, 0,
-	0, 519, 520, 521, 522, 523, 524, 525, 0, 526,
-	528, 527, 3293, 530, 1493, 529, 883, 531, 532, 884,
-	0, 533, 534, 535, 536, 537, 538, 541, 1446, 1445,
-	539, 540, 542, 543, 0, 544, 545, 547, 550, 546,
-	548, 549, 551, 552, 565, 566, 553, 554, 555, 556,
-	557, 558, 559, 560, 561, 562, 563, 564, 568, 0,
-	567, 885, 569, 570, 571, 572, 573, 581, 583, 584,
-	579, 580, 582, 585, 586, 588, 589, 576, 577, 578,
-	886, 587, 574, 1387, 575, 344, 887, 590, 591, 592,
-	593, 1411, 1456, 594, 1472, 597, 598, 0, 0, 599,
-	0, 600, 0, 0, 602, 603, 604, 0, 0, 605,
-	606, 836, 888, 607, 889, 1487, 608, 609, 1398, 610,
-	611, 612, 613, 614, 615, 616, 617, 618, 619, 0,
-	620, 621, 838, 622, 623, 624, 839, 625, 626, 627,
-	1488, 628, 841, 629, 630, 0, 631, 632, 633, 0,
-	634, 635, 636, 637, 638, 639, 640, 641, 642, 643,
-	1467, 644, 645, 647, 646, 648, 649, 0, 650, 0,
-	651, 652, 653, 0, 0, 0, 0, 0, 654, 655,
-	657, 0, 658, 659, 660, 661, 662, 656, 663, 664,
-	665, 666, 667, 668, 669, 0, 671, 672, 670, 673,
-	674, 890, 675, 676, 677, 678, 679, 1399, 680, 0,
-	681, 682, 690, 691, 692, 683, 684, 686, 693, 685,
-	694, 695, 696, 697, 699, 698, 0, 701, 702, 700,
-	703, 704, 705, 706, 1449, 707, 844, 708, 687, 688,
-	709, 710, 711, 891, 712, 713, 714, 715, 716, 717,
-	718, 719, 720, 1465, 0, 721, 0, 722, 723, 724,
-	725, 726, 727, 729, 689, 730, 731, 732, 737, 738,
-	1496, 733, 734, 735, 736, 1489, 740, 741, 742, 743,
-	0, 744, 745, 1384, 739, 728, 0, 746, 747, 748,
-	749, 750, 751, 752, 753, 754, 755, 0, 756, 1478,
-	1479, 1480, 1481, 0, 768, 3294, 757, 759, 760, 761,
-	762, 1490, 763, 1491, 1409, 764, 765, 766, 767, 758,
-	769, 770, 0, 1391, 771, 772, 773, 774, 776, 778,
-	779, 780, 775, 777, 781, 1450, 782, 0, 0, 783,
-	784, 785, 854, 1475, 1495, 0, 787, 788, 786, 789,
-	790, 793, 791, 792, 857, 796, 513, 797, 798, 799,
-	794, 795, 0, 0, 0, 0, 800, 801, 858, 802,
-	803, 804, 1388, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 1383, 0,
-	0, 0, 0, 0, 0, 1381, 1382, 0, 0, 0,
-	0, 0, 0, 864, 0, 1415, 0, 0, 3204, 1413,
-	1460, 1403, 1404, 1405, 1401, 1402, 1414, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 345, 346, 348,
-	347, 349, 350, 351, 352, 0, 353, 354, 0, 0,
-	0, 0, 0, 1452, 1419, 0, 0, 356, 0, 355,
-	0, 357, 358, 359, 874, 360, 361, 362, 363, 364,
-	365, 366, 367, 806, 1466, 0, 368, 1474, 369, 1473,
-	0, 1484, 370, 371, 372, 373, 374, 375, 376, 377,
-	378, 379, 1421, 1451, 1385, 380, 1497, 1498, 813, 0,
-	381, 382, 383, 384, 1458, 0, 1439, 0, 385, 386,
-	387, 388, 389, 390, 391, 392, 0, 0, 394, 395,
-	396, 393, 397, 398, 0, 399, 0, 400, 401, 402,
-	403, 404, 405, 406, 0, 407, 408, 409, 876, 410,
-	411, 412, 1442, 1440, 1441, 1448, 1444, 1443, 1447, 413,
-	414, 415, 416, 417, 1477, 418, 420, 421, 1471, 422,
-	1470, 1390, 425, 427, 419, 423, 0, 426, 424, 428,
-	429, 0, 430, 431, 432, 433, 0, 0, 434, 1469,
-	436, 0, 437, 438, 440, 439, 0, 441, 442, 443,
-	0, 444, 445, 1397, 446, 447, 448, 450, 452, 449,
-	451, 453, 454, 455, 456, 457, 1485, 1486, 458, 459,
-	1410, 340, 0, 0, 0, 0, 0, 460, 461, 462,
-	1468, 0, 0, 0, 463, 0, 465, 469, 466, 467,
-	468, 470, 0, 464, 471, 472, 0, 877, 473, 474,
-	475, 1482, 1483, 476, 477, 478, 479, 480, 481, 482,
-	483, 484, 0, 485, 486, 1492, 0, 1420, 487, 0,
-	488, 489, 490, 491, 492, 493, 494, 1453, 1454, 1457,
-	595, 879, 495, 496, 497, 0, 498, 499, 500, 501,
-	502, 503, 504, 0, 0, 0, 505, 506, 507, 508,
-	0, 867, 341, 343, 878, 828, 509, 596, 510, 1463,
-	1464, 0, 1424, 0, 511, 512, 515, 880, 1455, 881,
-	514, 516, 517, 882, 518, 0, 0, 0, 519, 520,
-	521, 522, 523, 524, 525, 0, 526, 528, 527, 0,
-	530, 1493, 529, 883, 531, 532, 884, 0, 533, 534,
-	535, 536, 537, 538, 541, 1446, 1445, 539, 540, 542,
-	543, 0, 544, 545, 547, 550, 546, 548, 549, 551,
-	552, 565, 566, 553, 554, 555, 556, 557, 558, 559,
-	560, 561, 562, 563, 564, 568, 0, 567, 885, 569,
-	570, 571, 572, 573, 581, 583, 584, 579, 580, 582,
-	585, 586, 588, 589, 576, 577, 578, 886, 587, 574,
-	1387, 575, 344, 887, 590, 591, 592, 593, 1411, 1456,
-	594, 1472, 597, 598, 0, 0, 599, 0, 600, 0,
-	0, 602, 603, 604, 0, 0, 605, 606, 836, 888,
-	607, 889, 1487, 608, 609, 1398, 610, 611, 612, 613,
-	614, 615, 616, 617, 618, 619, 0, 620, 621, 838,
-	622, 623, 624, 839, 625, 626, 627, 1488, 628, 841,
-	629, 630, 0, 631, 632, 633, 0, 634, 635, 636,
-	637, 638, 639, 640, 641, 642, 643, 1467, 644, 645,
-	647, 646, 648, 649, 0, 650, 0, 651, 652, 653,
-	0, 0, 0, 0, 0, 654, 655, 657, 0, 658,
-	659, 660, 661, 662, 656, 663, 664, 665, 666, 667,
-	668, 669, 0, 671, 672, 670, 673, 674, 890, 675,
-	676, 677, 678, 679, 1399, 680, 0, 681, 682, 690,
-	691, 692, 683, 684, 686, 693, 685, 694, 695, 696,
-	697, 699, 698, 0, 701, 702, 700, 703, 704, 705,
-	706, 1449, 707, 844, 708, 687, 688, 709, 710, 711,
-	891, 712, 713, 714, 715, 716, 717, 718, 719, 720,
-	1465, 0, 721, 0, 722, 723, 724, 725, 726, 727,
-	729, 689, 730, 731, 732, 737, 738, 1496, 733, 734,
-	735, 736, 1489, 740, 741, 742, 743, 0, 744, 745,
-	1384, 739, 728, 0, 746, 747, 748, 749, 750, 751,
-	752, 753, 754, 755, 0, 756, 1478, 1479, 1480, 1481,
-	0, 768, 0, 757, 759, 760, 761, 762, 1490, 763,
-	1491, 1409, 764, 765, 766, 767, 758, 769, 770, 0,
-	1391, 771, 772, 773, 774, 776, 778, 779, 780, 775,
-	777, 781, 1450, 782, 0, 0, 783, 784, 785, 854,
-	1475, 1495, 0, 787, 788, 786, 789, 790, 793, 791,
-	792, 857, 796, 513, 797, 798, 799, 794, 795, 0,
-	0, 0, 0, 800, 801, 858, 802, 803, 804, 1388,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 1383, 0, 0, 0, 0,
-	0, 0, 1381, 1382, 0, 0, 0, 0, 0, 0,
-	864, 0, 1415, 3202, 0, 3201, 1413, 1460, 1403, 1404,
-	1405, 1401, 1402, 1414, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 345, 346, 348, 347, 349, 350,
-	351, 352, 0, 353, 354, 0, 0, 0, 0, 0,
-	1452, 1419, 0, 0, 356, 0, 355, 0, 357, 358,
-	359, 874, 360, 361, 362, 363, 364, 365, 366, 367,
-	806, 1466, 0, 368, 1474, 369, 1473, 0, 1484, 370,
-	371, 372, 373, 374, 375, 376, 377, 378, 379, 1421,
-	1451, 1385, 380, 1497, 1498, 813, 0, 381, 382, 383,
-	384, 1458, 0, 1439, 0, 385, 386, 387, 388, 389,
-	390, 391, 392, 0, 0, 394, 395, 396, 393, 397,
-	398, 0, 399, 0, 400, 401, 402, 403, 404, 405,
-	406, 0, 407, 408, 409, 876, 410, 411, 412, 1442,
-	1440, 1441, 1448, 1444, 1443, 1447, 413, 414, 415, 416,
-	417, 1477, 418, 420, 421, 1471, 422, 1470, 1390, 425,
-	427, 419, 423, 0, 426, 424, 428, 429, 0, 430,
-	431, 432, 433, 0, 0, 434, 1469, 436, 0, 437,
-	438, 440, 439, 0, 441, 442, 443, 0, 444, 445,
-	1397, 446, 447, 448, 450, 452, 449, 451, 453, 454,
-	455, 456, 457, 1485, 1486, 458, 459, 1410, 340, 0,
-	0, 0, 0, 0, 460, 461, 462, 1468, 0, 0,
-	0, 463, 0, 465, 469, 466, 467, 468, 470, 0,
-	464, 471, 472, 0, 877, 473, 474, 475, 1482, 1483,
-	476, 477, 478, 479, 480, 481, 482, 483, 484, 0,
-	485, 486, 1492, 0, 1420, 487, 0, 488, 489, 490,
-	491, 492, 493, 494, 1453, 1454, 1457, 595, 879, 495,
-	496, 497, 0, 498, 499, 500, 501, 502, 503, 504,
-	0, 0, 0, 505, 506, 507, 508, 0, 867, 341,
-	343, 878, 828, 509, 596, 510, 1463, 1464, 0, 1424,
-	0, 511, 512, 515, 880, 1455, 881, 514, 516, 517,
-	882, 518, 0, 0, 0, 519, 520, 521, 522, 523,
-	524, 525, 0, 526, 528, 527, 0, 530, 1493, 529,
-	883, 531, 532, 884, 0, 533, 534, 535, 536, 537,
-	538, 541, 1446, 1445, 539, 540, 542, 543, 0, 544,
-	545, 547, 550, 546, 548, 549, 551, 552, 565, 566,
-	553, 554, 555, 556, 557, 558, 559, 560, 561, 562,
-	563, 564, 568, 0, 567, 885, 569, 570, 571, 572,
-	573, 581, 583, 584, 579, 580, 582, 585, 586, 588,
-	589, 576, 577, 578, 886, 587, 574, 1387, 575, 344,
-	887, 590, 591, 592, 593, 1411, 1456, 594, 1472, 597,
-	598, 0, 0, 599, 0, 600, 0, 0, 602, 603,
-	604, 0, 0, 605, 606, 836, 888, 607, 889, 1487,
-	608, 609, 1398, 610, 611, 612, 613, 614, 615, 616,
-	617, 618, 619, 0, 620, 621, 838, 622, 623, 624,
-	839, 625, 626, 627, 1488, 628, 841, 629, 630, 0,
-	631, 632, 633, 0, 634, 635, 636, 637, 638, 639,
-	640, 641, 642, 643, 1467, 644, 645, 647, 646, 648,
-	649, 0, 650, 0, 651, 652, 653, 0, 0, 0,
-	0, 0, 654, 655, 657, 0, 658, 659, 660, 661,
-	662, 656, 663, 664, 665, 666, 667, 668, 669, 0,
-	671, 672, 670, 673, 674, 890, 675, 676, 677, 678,
-	679, 1399, 680, 0, 681, 682, 690, 691, 692, 683,
-	684, 686, 693, 685, 694, 695, 696, 697, 699, 698,
-	0, 701, 702, 700, 703, 704, 705, 706, 1449, 707,
-	844, 708, 687, 688, 709, 710, 711, 891, 712, 713,
-	714, 715, 716, 717, 718, 719, 720, 1465, 0, 721,
-	0, 722, 723, 724, 725, 726, 727, 729, 689, 730,
-	731, 732, 737, 738, 1496, 733, 734, 735, 736, 1489,
-	740, 741, 742, 743, 0, 744, 745, 1384, 739, 728,
-	0, 746, 747, 748, 749, 750, 751, 752, 753, 754,
-	755, 0, 756, 1478, 1479, 1480, 1481, 0, 768, 0,
-	757, 759, 760, 761, 762, 1490, 763, 1491, 1409, 764,
-	765, 766, 767, 758, 769, 770, 0, 1391, 771, 772,
-	773, 774, 776, 778, 779, 780, 775, 777, 781, 1450,
-	782, 0, 0, 783, 784, 785, 854, 1475, 1495, 0,
-	787, 788, 786, 789, 790, 793, 791, 792, 857, 796,
-	513, 797, 798, 799, 794, 795, 0, 0, 0, 0,
-	800, 801, 858, 802, 803, 804, 1388, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 1383, 0, 0, 0, 0, 0, 0, 1381,
-	1382, 0, 0, 0, 0, 0, 0, 864, 0, 1415,
-	3199, 0, 3198, 1413, 1460, 1403, 1404, 1405, 1401, 1402,
-	1414, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 345, 346, 348, 347, 349, 350, 351, 352, 0,
-	353, 354, 0, 0, 0, 0, 0, 1452, 1419, 0,
-	0, 356, 0, 355, 0, 357, 358, 359, 874, 360,
-	361, 362, 363, 364, 365, 366, 367, 806, 1466, 0,
-	368, 1474, 369, 1473, 0, 1484, 370, 371, 372, 373,
-	374, 375, 376, 377, 378, 379, 1421, 1451, 1385, 380,
-	1497, 1498, 813, 0, 381, 382, 383, 384, 1458, 0,
-	1439, 0, 385, 386, 387, 388, 389, 390, 391, 392,
-	0, 0, 394, 395, 396, 393, 397, 398, 0, 399,
-	0, 400, 401, 402, 403, 404, 405, 406, 0, 407,
-	408, 409, 876, 410, 411, 412, 1442, 1440, 1441, 1448,
-	1444, 1443, 1447, 413, 414, 415, 416, 417, 1477, 418,
-	420, 421, 1471, 422, 1470, 1390, 425, 427, 419, 423,
-	0, 426, 424, 428, 429, 0, 430, 431, 432, 433,
-	0, 0, 434, 1469, 436, 0, 437, 438, 440, 439,
-	0, 441, 442, 443, 0, 444, 445, 1397, 446, 447,
-	448, 450, 452, 449, 451, 453, 454, 455, 456, 457,
-	1485, 1486, 458, 459, 1410, 340, 0, 0, 0, 0,
-	0, 460, 461, 462, 1468, 0, 0, 0, 463, 0,
-	465, 469, 466, 467, 468, 470, 0, 464, 471, 472,
-	0, 877, 473, 474, 475, 1482, 1483, 476, 477, 478,
-	479, 480, 481, 482, 483, 484, 0, 485, 486, 1492,
-	0, 1420, 487, 0, 488, 489, 490, 491, 492, 493,
-	494, 1453, 1454, 1457, 595, 879, 495, 496, 497, 0,
-	498, 499, 500, 501, 502, 503, 504, 0, 0, 0,
-	505, 506, 507, 508, 0, 867, 341, 343, 878, 828,
-	509, 596, 510, 1463, 1464, 0, 1424, 0, 511, 512,
-	515, 880, 1455, 881, 514, 516, 517, 882, 518, 0,
-	0, 0, 519, 520, 521, 522, 523, 524, 525, 0,
-	526, 528, 527, 0, 530, 1493, 529, 883, 531, 532,
-	884, 0, 533, 534, 535, 536, 537, 538, 541, 1446,
-	1445, 539, 540, 542, 543, 0, 544, 545, 547, 550,
-	546, 548, 549, 551, 552, 565, 566, 553, 554, 555,
-	556, 557, 558, 559, 560, 561, 562, 563, 564, 568,
-	0, 567, 885, 569, 570, 571, 572, 573, 581, 583,
-	584, 579, 580, 582, 585, 586, 588, 589, 576, 577,
-	578, 886, 587, 574, 1387, 575, 344, 887, 590, 591,
-	592, 593, 1411, 1456, 594, 1472, 597, 598, 0, 0,
-	599, 0, 600, 0, 0, 602, 603, 604, 0, 0,
-	605, 606, 836, 888, 607, 889, 1487, 608, 609, 1398,
-	610, 611, 612, 613, 614, 615, 616, 617, 618, 619,
-	0, 620, 621, 838, 622, 623, 624, 839, 625, 626,
-	627, 1488, 628, 841, 629, 630, 0, 631, 632, 633,
-	0, 634, 635, 636, 637, 638, 639, 640, 641, 642,
-	643, 1467, 644, 645, 647, 646, 648, 649, 0, 650,
-	0, 651, 652, 653, 0, 0, 0, 0, 0, 654,
-	655, 657, 0, 658, 659, 660, 661, 662, 656, 663,
-	664, 665, 666, 667, 668, 669, 0, 671, 672, 670,
-	673, 674, 890, 675, 676, 677, 678, 679, 1399, 680,
-	0, 681, 682, 690, 691, 692, 683, 684, 686, 693,
-	685, 694, 695, 696, 697, 699, 698, 0, 701, 702,
-	700, 703, 704, 705, 706, 1449, 707, 844, 708, 687,
-	688, 709, 710, 711, 891, 712, 713, 714, 715, 716,
-	717, 718, 719, 720, 1465, 0, 721, 0, 722, 723,
-	724, 725, 726, 727, 729, 689, 730, 731, 732, 737,
-	738, 1496, 733, 734, 735, 736, 1489, 740, 741, 742,
-	743, 0, 744, 745, 1384, 739, 728, 0, 746, 747,
-	748, 749, 750, 751, 752, 753, 754, 755, 0, 756,
-	1478, 1479, 1480, 1481, 0, 768, 0, 757, 759, 760,
-	761, 762, 1490, 763, 1491, 1409, 764, 765, 766, 767,
-	758, 769, 770, 0, 1391, 771, 772, 773, 774, 776,
-	778, 779, 780, 775, 777, 781, 1450, 782, 0, 0,
-	783, 784, 785, 854, 1475, 1495, 0, 787, 788, 786,
-	789, 790, 793, 791, 792, 857, 796, 513, 797, 798,
-	799, 794, 795, 0, 0, 0, 0, 800, 801, 858,
-	802, 803, 804, 1388, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 1383,
-	0, 0, 0, 0, 0, 0, 1381, 1382, 0, 0,
-	0, 0, 0, 0, 864, 0, 1415, 3196, 0, 3195,
-	1413, 1460, 1403, 1404, 1405, 1401, 1402, 1414, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 345, 346,
-	348, 347, 349, 350, 351, 352, 0, 353, 354, 0,
-	0, 0, 0, 0, 1452, 1419, 0, 0, 356, 0,
-	355, 0, 357, 358, 359, 874, 360, 361, 362, 363,
-	364, 365, 366, 367, 806, 1466, 0, 368, 1474, 369,
-	1473, 0, 1484, 370, 371, 372, 373, 374, 375, 376,
-	377, 378, 379, 1421, 1451, 1385, 380, 1497, 1498, 813,
-	0, 381, 382, 383, 384, 1458, 0, 1439, 0, 385,
-	386, 387, 388, 389, 390, 391, 392, 0, 0, 394,
-	395, 396, 393, 397, 398, 0, 399, 0, 400, 401,
-	402, 403, 404, 405, 406, 0, 407, 408, 409, 876,
-	410, 411, 412, 1442, 1440, 1441, 1448, 1444, 1443, 1447,
-	413, 414, 415, 416, 417, 1477, 418, 420, 421, 1471,
-	422, 1470, 1390, 425, 427, 419, 423, 0, 426, 424,
-	428, 429, 0, 430, 431, 432, 433, 0, 0, 434,
-	1469, 436, 0, 437, 438, 440, 439, 0, 441, 442,
-	443, 0, 444, 445, 1397, 446, 447, 448, 450, 452,
-	449, 451, 453, 454, 455, 456, 457, 1485, 1486, 458,
-	459, 1410, 340, 0, 0, 0, 0, 0, 460, 461,
-	462, 1468, 0, 0, 0, 463, 0, 465, 469, 466,
-	467, 468, 470, 0, 464, 471, 472, 0, 877, 473,
-	474, 475, 1482, 1483, 476, 477, 478, 479, 480, 481,
-	482, 483, 484, 0, 485, 486, 1492, 0, 1420, 487,
-	0, 488, 489, 490, 491, 492, 493, 494, 1453, 1454,
-	1457, 595, 879, 495, 496, 497, 0, 498, 499, 500,
-	501, 502, 503, 504, 0, 0, 0, 505, 506, 507,
-	508, 0, 867, 341, 343, 878, 828, 509, 596, 510,
-	1463, 1464, 0, 1424, 0, 511, 512, 515, 880, 1455,
-	881, 514, 516, 517, 882, 518, 0, 0, 0, 519,
-	520, 521, 522, 523, 524, 525, 0, 526, 528, 527,
-	0, 530, 1493, 529, 883, 531, 532, 884, 0, 533,
-	534, 535, 536, 537, 538, 541, 1446, 1445, 539, 540,
-	542, 543, 0, 544, 545, 547, 550, 546, 548, 549,
-	551, 552, 565, 566, 553, 554, 555, 556, 557, 558,
-	559, 560, 561, 562, 563, 564, 568, 0, 567, 885,
-	569, 570, 571, 572, 573, 581, 583, 584, 579, 580,
-	582, 585, 586, 588, 589, 576, 577, 578, 886, 587,
-	574, 1387, 575, 344, 887, 590, 591, 592, 593, 1411,
-	1456, 594, 1472, 597, 598, 0, 0, 599, 0, 600,
-	0, 0, 602, 603, 604, 0, 0, 605, 606, 836,
-	888, 607, 889, 1487, 608, 609, 1398, 610, 611, 612,
-	613, 614, 615, 616, 617, 618, 619, 0, 620, 621,
-	838, 622, 623, 624, 839, 625, 626, 627, 1488, 628,
-	841, 629, 630, 0, 631, 632, 633, 0, 634, 635,
-	636, 637, 638, 639, 640, 641, 642, 643, 1467, 644,
-	645, 647, 646, 648, 649, 0, 650, 0, 651, 652,
-	653, 0, 0, 0, 0, 0, 654, 655, 657, 0,
-	658, 659, 660, 661, 662, 656, 663, 664, 665, 666,
-	667, 668, 669, 0, 671, 672, 670, 673, 674, 890,
-	675, 676, 677, 678, 679, 1399, 680, 0, 681, 682,
-	690, 691, 692, 683, 684, 686, 693, 685, 694, 695,
-	696, 697, 699, 698, 0, 701, 702, 700, 703, 704,
-	705, 706, 1449, 707, 844, 708, 687, 688, 709, 710,
-	711, 891, 712, 713, 714, 715, 716, 717, 718, 719,
-	720, 1465, 0, 721, 0, 722, 723, 724, 725, 726,
-	727, 729, 689, 730, 731, 732, 737, 738, 1496, 733,
-	734, 735, 736, 1489, 740, 741, 742, 743, 0, 744,
-	745, 1384, 739, 728, 0, 746, 747, 748, 749, 750,
-	751, 752, 753, 754, 755, 0, 756, 1478, 1479, 1480,
-	1481, 0, 768, 0, 757, 759, 760, 761, 762, 1490,
-	763, 1491, 1409, 764, 765, 766, 767, 758, 769, 770,
-	0, 1391, 771, 772, 773, 774, 776, 778, 779, 780,
-	775, 777, 781, 1450, 782, 0, 0, 783, 784, 785,
-	854, 1475, 1495, 0, 787, 788, 786, 789, 790, 793,
-	791, 792, 857, 796, 513, 797, 798, 799, 794, 795,
-	0, 0, 0, 0, 800, 801, 858, 802, 803, 804,
-	1388, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 1383, 0, 0, 0,
-	0, 0, 0, 1381, 1382, 0, 0, 0, 0, 0,
-	0, 864, 0, 1415, 3193, 0, 1788, 1413, 1460, 1403,
-	1404, 1405, 1401, 1402, 1414, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 345, 346, 348, 347, 349,
-	350, 351, 352, 0, 353, 354, 0, 0, 0, 0,
-	0, 1452, 1419, 0, 0, 356, 0, 355, 0, 357,
-	358, 359, 874, 360, 361, 362, 363, 364, 365, 366,
-	367, 806, 1466, 0, 368, 1474, 369, 1473, 0, 1484,
-	370, 371, 372, 373, 374, 375, 376, 377, 378, 379,
-	1421, 1451, 1385, 380, 1497, 1498, 813, 0, 381, 382,
-	383, 384, 1458, 0, 1439, 0, 385, 386, 387, 388,
-	389, 390, 391, 392, 0, 0, 394, 395, 396, 393,
-	397, 398, 0, 399, 0, 400, 401, 402, 403, 404,
-	405, 406, 0, 407, 408, 409, 876, 410, 411, 412,
-	1442, 1440, 1441, 1448, 1444, 1443, 1447, 413, 414, 415,
-	416, 417, 1477, 418, 420, 421, 1471, 422, 1470, 1390,
-	425, 427, 419, 423, 0, 426, 424, 428, 429, 0,
-	430, 431, 432, 433, 0, 0, 434, 1469, 436, 0,
-	437, 438, 440, 439, 0, 441, 442, 443, 0, 444,
-	445, 1397, 446, 447, 448, 450, 452, 449, 451, 453,
-	454, 455, 456, 457, 1485, 1486, 458, 459, 1410, 340,
-	0, 0, 0, 0, 0, 460, 461, 462, 1468, 0,
-	0, 0, 463, 0, 465, 469, 466, 467, 468, 470,
-	0, 464, 471, 472, 0, 877, 473, 474, 475, 1482,
-	1483, 476, 477, 478, 479, 480, 481, 482, 483, 484,
-	0, 485, 486, 1492, 0, 1420, 487, 0, 488, 489,
-	490, 491, 492, 493, 494, 1453, 1454, 1457, 595, 879,
-	495, 496, 497, 0, 498, 499, 500, 501, 502, 503,
-	504, 0, 0, 0, 505, 506, 507, 508, 0, 867,
-	341, 343, 878, 828, 509, 596, 510, 1463, 1464, 0,
-	1424, 0, 511, 512, 515, 880, 1455, 881, 514, 516,
-	517, 882, 518, 0, 0, 0, 519, 520, 521, 522,
-	523, 524, 525, 0, 526, 528, 527, 0, 530, 1493,
-	529, 883, 531, 532, 884, 0, 533, 534, 535, 536,
-	537, 538, 541, 1446, 1445, 539, 540, 542, 543, 0,
-	544, 545, 547, 550, 546, 548, 549, 551, 552, 565,
-	566, 553, 554, 555, 556, 557, 558, 559, 560, 561,
-	562, 563, 564, 568, 0, 567, 885, 569, 570, 571,
-	572, 573, 581, 583, 584, 579, 580, 582, 585, 586,
-	588, 589, 576, 577, 578, 886, 587, 574, 1387, 575,
-	344, 887, 590, 591, 592, 593, 1411, 1456, 594, 1472,
-	597, 598, 0, 0, 599, 0, 600, 0, 0, 602,
-	603, 604, 0, 0, 605, 606, 836, 888, 607, 889,
-	1487, 608, 609, 1398, 610, 611, 612, 613, 614, 615,
-	616, 617, 618, 619, 0, 620, 621, 838, 622, 623,
-	624, 839, 625, 626, 627, 1488, 628, 841, 629, 630,
-	0, 631, 632, 633, 0, 634, 635, 636, 637, 638,
-	639, 640, 641, 642, 643, 1467, 644, 645, 647, 646,
-	648, 649, 0, 650, 0, 651, 652, 653, 0, 0,
-	0, 0, 0, 654, 655, 657, 0, 658, 659, 660,
-	661, 662, 656, 663, 664, 665, 666, 667, 668, 669,
-	0, 671, 672, 670, 673, 674, 890, 675, 676, 677,
-	678, 679, 1399, 680, 0, 681, 682, 690, 691, 692,
-	683, 684, 686, 693, 685, 694, 695, 696, 697, 699,
-	698, 0, 701, 702, 700, 703, 704, 705, 706, 1449,
-	707, 844, 708, 687, 688, 709, 710, 711, 891, 712,
-	713, 714, 715, 716, 717, 718, 719, 720, 1465, 0,
-	721, 0, 722, 723, 724, 725, 726, 727, 729, 689,
-	730, 731, 732, 737, 738, 1496, 733, 734, 735, 736,
-	1489, 740, 741, 742, 743, 0, 744, 745, 1384, 739,
-	728, 0, 746, 747, 748, 749, 750, 751, 752, 753,
-	754, 755, 0, 756, 1478, 1479, 1480, 1481, 0, 768,
-	0, 757, 759, 760, 761, 762, 1490, 763, 1491, 1409,
-	764, 765, 766, 767, 758, 769, 770, 0, 1391, 771,
-	772, 773, 774, 776, 778, 779, 780, 775, 777, 781,
-	1450, 782, 0, 0, 783, 784, 785, 854, 1475, 1495,
-	0, 787, 788, 786, 789, 790, 793, 791, 792, 857,
-	796, 513, 797, 798, 799, 794, 795, 1787, 0, 0,
-	0, 800, 801, 858, 802, 803, 804, 1388, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 1383, 0, 0, 0, 0, 0, 0,
-	1381, 1382, 0, 0, 0, 0, 0, 0, 864, 0,
-	1415, 0, 0, 1377, 1413, 1460, 1403, 1404, 1405, 1401,
-	1402, 1414, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 345, 346, 348, 347, 349, 350, 351, 352,
-	0, 353, 354, 0, 0, 0, 0, 0, 1452, 1419,
-	0, 0, 356, 0, 355, 0, 357, 358, 359, 874,
-	360, 361, 362, 363, 364, 365, 366, 367, 806, 1466,
-	0, 368, 1474, 369, 1473, 0, 1484, 370, 371, 372,
-	373, 374, 375, 376, 377, 378, 379, 1421, 1451, 1385,
-	380, 1497, 1498, 813, 0, 381, 382, 383, 384, 1458,
-	0, 1439, 0, 385, 386, 387, 388, 389, 390, 391,
-	392, 0, 0, 394, 395, 396, 393, 397, 398, 0,
-	399, 0, 400, 401, 402, 403, 404, 405, 406, 0,
-	407, 408, 409, 876, 410, 411, 412, 1442, 1440, 1441,
-	1448, 1444, 1443, 1447, 413, 414, 415, 416, 417, 1477,
-	418, 420, 421, 1471, 422, 1470, 1390, 425, 427, 419,
-	423, 0, 426, 424, 428, 429, 0, 430, 431, 432,
-	433, 0, 0, 434, 1469, 436, 0, 437, 438, 440,
-	439, 0, 441, 442, 443, 0, 444, 445, 1397, 446,
-	447, 448, 450, 452, 449, 451, 453, 454, 455, 456,
-	457, 1485, 1486, 458, 459, 1410, 340, 0, 0, 0,
-	0, 0, 460, 461, 462, 1468, 0, 0, 0, 463,
-	0, 465, 469, 466, 467, 468, 470, 0, 464, 471,
-	472, 0, 877, 473, 474, 475, 1482, 1483, 476, 477,
-	478, 479, 480, 481, 482, 483, 484, 0, 485, 486,
-	1492, 0, 1420, 487, 0, 488, 489, 490, 491, 492,
-	493, 494, 1453, 1454, 1457, 595, 879, 495, 496, 497,
-	0, 498, 499, 500, 501, 502, 503, 504, 0, 0,
-	0, 505, 506, 507, 508, 0, 867, 341, 343, 878,
-	828, 509, 596, 510, 1463, 1464, 0, 1424, 0, 511,
-	512, 515, 880, 1455, 881, 514, 516, 517, 882, 518,
-	0, 0, 0, 519, 520, 521, 522, 523, 524, 525,
-	0, 526, 528, 527, 0, 530, 1493, 529, 883, 531,
-	532, 884, 0, 533, 534, 535, 536, 537, 538, 541,
-	1446, 1445, 539, 540, 542, 543, 0, 544, 545, 547,
-	550, 546, 548, 549, 551, 552, 565, 566, 553, 554,
-	555, 556, 557, 558, 559, 560, 561, 562, 563, 564,
-	568, 0, 567, 885, 569, 570, 571, 572, 573, 581,
-	583, 584, 579, 580, 582, 585, 586, 588, 589, 576,
-	577, 578, 1393, 587, 574, 1387, 575, 344, 887, 590,
-	591, 592, 593, 1411, 1456, 594, 1472, 597, 598, 0,
-	0, 599, 0, 600, 1392, 0, 602, 603, 604, 0,
-	0, 605, 606, 836, 888, 607, 889, 1487, 608, 609,
-	1398, 610, 611, 612, 613, 614, 615, 616, 617, 618,
-	619, 0, 620, 621, 838, 622, 623, 624, 839, 625,
-	626, 627, 1488, 628, 841, 629, 630, 0, 631, 632,
-	633, 0, 634, 635, 636, 637, 638, 639, 640, 641,
-	642, 643, 1467, 644, 645, 647, 646, 648, 649, 0,
-	650, 0, 651, 652, 653, 0, 0, 0, 0, 0,
-	654, 655, 657, 0, 658, 659, 660, 661, 662, 656,
-	663, 664, 665, 666, 667, 668, 669, 0, 671, 672,
-	670, 673, 674, 890, 675, 676, 677, 678, 679, 1399,
-	680, 0, 681, 682, 690, 691, 692, 683, 684, 686,
-	693, 685, 694, 695, 696, 697, 699, 698, 0, 701,
-	702, 700, 703, 704, 705, 706, 1449, 707, 844, 708,
-	687, 688, 709, 710, 711, 891, 712, 713, 714, 715,
-	716, 717, 718, 719, 720, 1465, 0, 721, 0, 722,
-	723, 724, 725, 726, 727, 729, 689, 730, 731, 732,
-	737, 738, 1496, 733, 734, 735, 736, 1489, 740, 741,
-	742, 743, 0, 744, 745, 1384, 739, 728, 0, 746,
-	747, 748, 749, 750, 751, 752, 753, 754, 755, 0,
-	756, 1478, 1479, 1480, 1481, 0, 768, 0, 757, 759,
-	760, 761, 762, 1490, 763, 1491, 1409, 764, 765, 766,
-	767, 758, 769, 770, 0, 1391, 771, 772, 773, 774,
-	776, 778, 779, 780, 775, 777, 781, 1450, 782, 0,
-	0, 783, 784, 785, 854, 1475, 1495, 0, 787, 788,
-	786, 789, 790, 793, 791, 792, 857, 796, 513, 797,
-	798, 799, 794, 795, 0, 0, 0, 0, 800, 801,
-	858, 802, 803, 804, 1388, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	1383, 0, 0, 0, 0, 0, 0, 1381, 1382, 0,
-	0, 0, 0, 0, 0, 864, 0, 1415, 0, 0,
-	0, 1413, 1460, 1403, 1404, 1405, 1401, 1402, 1414, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 345,
-	346, 348, 347, 349, 350, 351, 352, 0, 353, 354,
-	0, 0, 0, 0, 0, 1452, 1419, 0, 0, 356,
-	0, 355, 0, 357, 358, 359, 874, 360, 361, 362,
-	363, 364, 365, 366, 367, 806, 1466, 0, 368, 1474,
-	369, 1473, 0, 1484, 370, 371, 372, 373, 374, 375,
-	376, 377, 378, 379, 1421, 1451, 1385, 380, 1497, 1498,
-	813, 0, 381, 382, 383, 384, 1458, 0, 1439, 0,
-	385, 386, 387, 388, 389, 390, 391, 392, 0, 0,
-	394, 395, 396, 393, 397, 398, 0, 399, 0, 400,
-	401, 402, 403, 6520, 405, 406, 0, 407, 408, 409,
-	876, 410, 411, 412, 1442, 1440, 1441, 1448, 1444, 1443,
-	1447, 413, 414, 415, 416, 417, 1477, 418, 420, 421,
-	1471, 422, 1470, 1390, 425, 427, 419, 423, 0, 426,
-	424, 428, 429, 0, 430, 431, 432, 433, 0, 0,
-	434, 1469, 436, 0, 437, 438, 440, 439, 0, 441,
-	442, 443, 0, 444, 445, 1397, 446, 447, 448, 450,
-	452, 449, 451, 453, 454, 455, 456, 457, 1485, 1486,
-	458, 459, 1410, 340, 0, 0, 0, 0, 0, 460,
-	461, 462, 1468, 0, 0, 0, 463, 0, 465, 469,
-	466, 467, 468, 470, 0, 464, 471, 472, 0, 877,
-	473, 474, 475, 1482, 1483, 476, 477, 478, 479, 480,
-	481, 482, 483, 484, 0, 485, 486, 1492, 0, 1420,
-	487, 0, 488, 489, 490, 491, 492, 493, 494, 1453,
-	1454, 1457, 595, 879, 495, 496, 497, 0, 498, 499,
-	500, 501, 502, 503, 504, 0, 0, 0, 505, 506,
-	507, 508, 0, 867, 341, 343, 878, 828, 509, 596,
-	510, 1463, 1464, 0, 1424, 0, 511, 512, 515, 880,
-	1455, 881, 514, 516, 517, 882, 518, 0, 0, 0,
-	519, 520, 521, 522, 523, 524, 525, 0, 526, 528,
-	527, 0, 530, 1493, 529, 883, 531, 532, 884, 0,
-	533, 534, 535, 536, 537, 538, 541, 1446, 1445, 539,
-	540, 542, 543, 0, 544, 545, 547, 550, 546, 548,
-	549, 551, 552, 565, 566, 553, 554, 555, 556, 557,
-	558, 559, 560, 561, 562, 563, 564, 568, 0, 567,
-	885, 569, 570, 571, 572, 573, 581, 583, 584, 579,
-	580, 582, 585, 586, 588, 589, 576, 577, 578, 1393,
-	587, 574, 1387, 575, 344, 887, 590, 591, 592, 593,
-	1411, 1456, 594, 1472, 597, 598, 0, 0, 599, 0,
-	600, 1392, 0, 602, 603, 604, 0, 0, 605, 606,
-	836, 888, 607, 889, 1487, 608, 609, 1398, 610, 611,
-	612, 613, 614, 615, 616, 617, 618, 619, 0, 620,
-	621, 838, 622, 623, 624, 839, 625, 626, 627, 1488,
-	628, 841, 629, 630, 0, 631, 632, 633, 0, 634,
-	635, 636, 637, 638, 639, 640, 641, 642, 643, 1467,
-	644, 645, 647, 646, 648, 649, 0, 650, 0, 651,
-	652, 653, 0, 0, 0, 0, 0, 654, 655, 657,
-	0, 658, 659, 660, 661, 662, 656, 663, 664, 665,
-	666, 667, 668, 669, 0, 671, 672, 670, 673, 674,
-	890, 675, 676, 677, 678, 679, 1399, 680, 0, 681,
-	682, 690, 691, 692, 683, 684, 686, 693, 685, 694,
-	695, 696, 697, 699, 698, 0, 701, 702, 700, 703,
-	704, 705, 706, 1449, 707, 844, 708, 687, 688, 709,
-	710, 711, 891, 712, 713, 714, 715, 716, 717, 718,
-	719, 720, 1465, 0, 721, 0, 722, 723, 724, 725,
-	726, 727, 729, 689, 730, 731, 732, 737, 738, 1496,
-	733, 734, 735, 736, 1489, 740, 741, 742, 743, 0,
-	744, 745, 1384, 739, 728, 0, 746, 747, 748, 749,
-	750, 751, 752, 753, 754, 755, 0, 756, 1478, 1479,
-	1480, 1481, 0, 768, 0, 757, 759, 760, 761, 762,
-	1490, 763, 1491, 1409, 764, 765, 766, 767, 758, 769,
-	770, 0, 1391, 771, 772, 773, 774, 776, 778, 779,
-	780, 775, 777, 781, 1450, 782, 0, 0, 783, 784,
-	785, 854, 1475, 1495, 0, 787, 788, 786, 789, 790,
-	793, 791, 792, 857, 796, 513, 797, 798, 799, 794,
-	795, 0, 0, 0, 0, 800, 801, 858, 802, 803,
-	804, 1388, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 1383, 0, 0,
-	0, 0, 0, 0, 1381, 1382, 0, 0, 0, 0,
-	0, 0, 864, 0, 1415, 0, 0, 0, 1413, 1460,
-	1403, 1404, 1405, 1401, 1402, 1414, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 345, 346, 348, 347,
-	349, 350, 351, 352, 0, 353, 354, 0, 0, 0,
-	0, 0, 1452, 1419, 0, 0, 356, 0, 355, 0,
-	357, 358, 359, 874, 360, 361, 362, 363, 364, 365,
-	366, 367, 806, 1466, 0, 368, 1474, 369, 1473, 0,
-	1484, 370, 371, 372, 373, 374, 375, 376, 377, 378,
-	379, 1421, 1451, 1385, 380, 1497, 1498, 813, 0, 381,
-	382, 383, 384, 1458, 0, 1439, 0, 385, 386, 387,
-	388, 389, 390, 391, 392, 0, 0, 394, 395, 396,
-	393, 397, 398, 0, 399, 0, 400, 401, 402, 403,
-	404, 405, 406, 0, 407, 408, 409, 876, 410, 411,
-	412, 1442, 1440, 1441, 1448, 1444, 1443, 1447, 413, 414,
-	415, 416, 417, 1477, 418, 420, 421, 1471, 422, 1470,
-	1390, 425, 427, 419, 423, 0, 426, 424, 428, 429,
-	0, 430, 431, 432, 433, 0, 0, 434, 1469, 436,
-	0, 437, 438, 440, 439, 0, 441, 442, 443, 0,
-	444, 445, 1397, 446, 447, 448, 450, 452, 449, 451,
-	453, 454, 455, 456, 457, 1485, 1486, 458, 459, 1410,
-	340, 0, 0, 0, 0, 0, 460, 461, 462, 1468,
-	0, 0, 0, 463, 0, 465, 469, 466, 467, 468,
-	470, 0, 464, 471, 472, 0, 877, 473, 474, 475,
-	1482, 1483, 476, 477, 478, 479, 480, 481, 482, 483,
-	484, 0, 485, 486, 1492, 0, 1420, 487, 0, 488,
-	489, 490, 491, 492, 493, 494, 1453, 1454, 1457, 595,
-	879, 495, 496, 497, 0, 498, 499, 500, 501, 502,
-	503, 504, 0, 0, 0, 505, 506, 507, 508, 0,
-	867, 341, 3038, 878, 828, 509, 596, 510, 1463, 1464,
-	0, 1424, 0, 511, 512, 515, 880, 1455, 881, 514,
-	516, 517, 882, 518, 0, 0, 0, 519, 520, 521,
-	522, 523, 524, 525, 0, 526, 528, 527, 0, 530,
-	1493, 529, 883, 531, 532, 884, 0, 533, 534, 535,
-	536, 537, 538, 541, 1446, 1445, 539, 540, 542, 543,
-	0, 544, 545, 547, 550, 546, 548, 549, 551, 552,
-	565, 566, 553, 554, 555, 556, 557, 558, 559, 560,
-	561, 562, 563, 564, 568, 0, 567, 885, 569, 570,
-	571, 572, 573, 581, 583, 584, 579, 580, 582, 585,
-	586, 588, 589, 576, 577, 578, 886, 587, 574, 1387,
-	575, 344, 887, 590, 591, 592, 593, 1411, 1456, 594,
-	1472, 597, 598, 0, 0, 599, 0, 600, 0, 0,
-	602, 603, 604, 0, 0, 605, 606, 836, 888, 607,
-	889, 1487, 608, 609, 1398, 610, 611, 612, 613, 614,
-	615, 616, 617, 618, 619, 0, 620, 621, 838, 622,
-	623, 624, 839, 625, 626, 627, 1488, 628, 841, 629,
-	630, 3037, 631, 632, 633, 0, 634, 635, 636, 637,
-	638, 639, 640, 641, 642, 643, 1467, 644, 645, 647,
-	646, 648, 649, 0, 650, 0, 651, 652, 653, 0,
-	0, 0, 0, 0, 654, 655, 657, 0, 658, 659,
-	660, 661, 662, 656, 663, 664, 665, 666, 667, 668,
-	669, 0, 671, 672, 670, 673, 674, 890, 675, 676,
-	677, 678, 679, 1399, 680, 0, 681, 682, 690, 691,
-	692, 683, 684, 686, 693, 685, 694, 695, 696, 697,
-	699, 698, 0, 701, 702, 700, 703, 704, 705, 706,
-	1449, 707, 844, 708, 687, 688, 709, 710, 711, 891,
-	712, 713, 714, 715, 716, 717, 718, 719, 720, 1465,
-	0, 721, 0, 722, 723, 724, 725, 726, 727, 729,
-	689, 730, 731, 732, 737, 738, 1496, 733, 734, 735,
-	736, 1489, 740, 741, 742, 743, 0, 744, 745, 1384,
-	739, 728, 0, 746, 747, 748, 749, 750, 751, 752,
-	753, 754, 755, 0, 756, 1478, 1479, 1480, 1481, 0,
-	768, 0, 757, 759, 760, 761, 762, 1490, 763, 1491,
-	1409, 764, 765, 766, 767, 758, 769, 770, 0, 1391,
-	771, 772, 773, 774, 776, 778, 779, 780, 775, 777,
-	781, 1450, 782, 0, 0, 783, 784, 785, 854, 1475,
-	1495, 0, 787, 788, 786, 789, 790, 793, 791, 792,
-	857, 796, 513, 797, 798, 799, 794, 795, 0, 0,
-	0, 0, 800, 801, 858, 802, 803, 804, 1388, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 1383, 0, 0, 0, 0, 0,
-	0, 1381, 1382, 0, 0, 0, 0, 0, 0, 864,
-	0, 1415, 0, 0, 0, 1413, 1460, 1403, 1404, 1405,
-	1401, 1402, 1414, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 345, 346, 348, 347, 349, 350, 351,
-	352, 0, 353, 354, 0, 0, 0, 0, 0, 1452,
-	1419, 0, 0, 356, 0, 355, 0, 357, 358, 359,
-	874, 360, 361, 362, 363, 364, 365, 366, 367, 806,
-	1466, 0, 368, 1474, 369, 1473, 0, 1484, 370, 371,
-	372, 373, 374, 375, 376, 377, 378, 379, 1421, 1451,
-	1385, 380, 1497, 1498, 813, 0, 381, 382, 383, 384,
-	1458, 0, 1439, 0, 385, 386, 387, 388, 389, 390,
-	391, 392, 0, 0, 394, 395, 396, 393, 397, 398,
-	0, 399, 0, 400, 401, 402, 403, 404, 405, 406,
-	0, 407, 408, 409, 876, 410, 411, 412, 1442, 1440,
-	1441, 1448, 1444, 1443, 1447, 413, 414, 415, 416, 417,
-	1477, 418, 420, 421, 1471, 422, 1470, 1390, 425, 427,
-	419, 423, 0, 426, 424, 428, 429, 0, 430, 431,
-	432, 433, 0, 0, 434, 1469, 436, 0, 437, 438,
-	440, 439, 0, 441, 442, 443, 0, 444, 445, 1397,
-	446, 447, 448, 450, 452, 449, 451, 453, 454, 455,
-	456, 457, 1485, 1486, 458, 459, 1410, 340, 0, 0,
-	0, 0, 0, 460, 461, 462, 1468, 0, 0, 0,
-	463, 0, 465, 469, 466, 467, 468, 470, 0, 464,
-	471, 472, 0, 877, 473, 474, 475, 1482, 1483, 476,
-	477, 478, 479, 480, 481, 482, 483, 484, 0, 485,
-	486, 1492, 0, 1420, 487, 0, 488, 489, 490, 491,
-	492, 493, 494, 1453, 1454, 1457, 595, 879, 495, 496,
-	497, 0, 498, 499, 500, 501, 502, 503, 504, 0,
-	0, 0, 505, 506, 507, 508, 0, 867, 341, 343,
-	878, 828, 509, 596, 510, 1463, 1464, 0, 1424, 0,
-	511, 512, 515, 880, 1455, 881, 514, 516, 517, 882,
-	518, 0, 0, 0, 519, 520, 521, 522, 523, 524,
-	525, 0, 526, 528, 527, 0, 530, 1493, 529, 883,
-	531, 532, 884, 0, 533, 534, 535, 536, 537, 538,
-	541, 1446, 1445, 539, 540, 542, 543, 0, 544, 545,
-	547, 550, 546, 548, 549, 551, 552, 565, 566, 553,
-	554, 555, 556, 557, 558, 559, 560, 561, 562, 563,
-	564, 568, 0, 567, 885, 569, 570, 571, 572, 573,
-	581, 583, 584, 579, 580, 582, 585, 586, 588, 589,
-	576, 577, 578, 886, 587, 574, 1387, 575, 344, 887,
-	590, 591, 592, 593, 1411, 1456, 594, 1472, 597, 598,
-	0, 0, 599, 0, 600, 0, 0, 602, 603, 604,
-	0, 0, 605, 606, 836, 888, 607, 889, 1487, 608,
-	609, 1398, 610, 611, 612, 613, 614, 615, 616, 617,
-	618, 619, 0, 620, 621, 838, 622, 623, 624, 839,
-	625, 626, 627, 1488, 628, 841, 629, 630, 0, 631,
-	632, 633, 0, 634, 635, 636, 637, 638, 639, 640,
-	641, 642, 643, 1467, 644, 645, 647, 646, 648, 649,
-	0, 650, 0, 651, 652, 653, 0, 0, 0, 0,
-	0, 654, 655, 657, 0, 658, 659, 660, 661, 662,
-	656, 663, 664, 665, 666, 667, 668, 669, 0, 671,
-	672, 670, 673, 674, 890, 675, 676, 677, 678, 679,
-	1399, 680, 0, 681, 682, 690, 691, 692, 683, 684,
-	686, 693, 685, 694, 695, 696, 697, 699, 698, 0,
-	701, 702, 700, 703, 704, 705, 706, 1449, 707, 844,
-	708, 687, 688, 709, 710, 711, 891, 712, 713, 714,
-	715, 716, 717, 718, 719, 720, 1465, 0, 721, 0,
-	722, 723, 724, 725, 726, 727, 729, 689, 730, 731,
-	732, 737, 738, 1496, 733, 734, 735, 736, 1489, 740,
-	741, 742, 743, 0, 744, 745, 1384, 739, 728, 0,
-	746, 747, 748, 749, 750, 751, 752, 753, 754, 755,
-	0, 756, 1478, 1479, 1480, 1481, 0, 768, 0, 757,
-	759, 760, 761, 762, 1490, 763, 1491, 1409, 764, 765,
-	766, 767, 758, 769, 770, 0, 1391, 771, 772, 773,
-	774, 776, 778, 779, 780, 775, 777, 781, 1450, 782,
-	0, 0, 783, 784, 785, 854, 1475, 1495, 0, 787,
-	788, 786, 789, 790, 793, 791, 792, 857, 796, 513,
-	797, 798, 799, 794, 795, 0, 0, 0, 0, 800,
-	801, 858, 802, 803, 804, 1388, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 1383, 0, 0, 0, 0, 0, 0, 1381, 1382,
-	2343, 0, 0, 0, 0, 0, 864, 0, 1415, 0,
-	0, 0, 1413, 1460, 1403, 1404, 1405, 1401, 1402, 1414,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	345, 346, 348, 347, 349, 350, 351, 352, 0, 353,
-	354, 0, 0, 0, 0, 0, 1452, 1419, 0, 0,
-	356, 0, 355, 0, 357, 358, 359, 874, 360, 361,
-	362, 363, 364, 365, 366, 367, 806, 1466, 0, 368,
-	1474, 369, 1473, 0, 1484, 370, 371, 372, 373, 374,
-	375, 376, 377, 378, 379, 1421, 1451, 1385, 380, 1497,
-	1498, 813, 0, 381, 382, 383, 384, 1458, 0, 1439,
-	0, 385, 386, 387, 388, 389, 390, 391, 392, 0,
-	0, 394, 395, 396, 393, 397, 398, 0, 399, 0,
-	400, 401, 402, 403, 6190, 405, 406, 0, 407, 408,
-	409, 876, 410, 411, 412, 1442, 1440, 1441, 1448, 1444,
-	1443, 1447, 413, 414, 415, 416, 417, 1477, 418, 420,
-	421, 1471, 422, 1470, 1390, 425, 427, 419, 423, 0,
-	426, 424, 428, 429, 0, 430, 431, 432, 433, 0,
-	0, 434, 1469, 436, 0, 437, 438, 440, 439, 0,
-	441, 442, 443, 0, 444, 445, 1397, 446, 447, 448,
-	450, 452, 449, 451, 453, 454, 455, 456, 457, 1485,
-	1486, 458, 459, 1410, 340, 0, 0, 0, 0, 0,
-	460, 461, 462, 1468, 0, 0, 0, 463, 0, 465,
-	469, 466, 467, 468, 470, 0, 464, 471, 472, 0,
-	877, 473, 474, 475, 1482, 1483, 476, 477, 478, 479,
-	480, 481, 482, 483, 484, 0, 485, 486, 1492, 0,
-	1420, 487, 0, 488, 489, 490, 491, 492, 493, 494,
-	1453, 1454, 1457, 595, 879, 495, 496, 497, 0, 498,
-	499, 500, 501, 502, 503, 504, 0, 0, 0, 505,
-	506, 507, 508, 0, 867, 341, 343, 878, 828, 509,
-	596, 510, 1463, 1464, 0, 1424, 0, 511, 512, 515,
-	880, 1455, 881, 514, 516, 517, 882, 518, 0, 0,
-	0, 519, 520, 521, 522, 523, 524, 525, 0, 526,
-	528, 527, 0, 530, 1493, 529, 883, 531, 532, 884,
-	0, 533, 534, 535, 536, 537, 538, 541, 1446, 1445,
-	539, 540, 542, 543, 0, 544, 545, 547, 550, 546,
-	548, 549, 551, 552, 565, 566, 553, 554, 555, 556,
-	557, 558, 559, 560, 561, 562, 563, 564, 568, 0,
-	567, 885, 569, 570, 571, 572, 573, 581, 583, 584,
-	579, 580, 582, 585, 586, 588, 589, 576, 577, 578,
-	1393, 587, 574, 1387, 575, 344, 887, 590, 591, 592,
-	593, 1411, 1456, 594, 1472, 597, 598, 0, 0, 599,
-	0, 600, 1392, 0, 602, 603, 604, 0, 0, 605,
-	606, 836, 888, 607, 889, 1487, 608, 609, 1398, 610,
-	611, 612, 613, 614, 615, 616, 617, 618, 619, 0,
-	620, 621, 838, 622, 623, 624, 839, 625, 626, 627,
-	1488, 628, 841, 629, 630, 0, 631, 632, 633, 0,
-	634, 635, 636, 637, 638, 639, 640, 641, 642, 643,
-	1467, 644, 645, 647, 646, 648, 649, 0, 650, 0,
-	651, 652, 653, 0, 0, 0, 0, 0, 654, 655,
-	657, 0, 658, 659, 660, 661, 662, 656, 663, 664,
-	665, 666, 667, 668, 669, 0, 671, 672, 670, 673,
-	674, 890, 675, 676, 677, 678, 679, 1399, 680, 0,
-	681, 682, 690, 691, 692, 683, 684, 686, 693, 685,
-	694, 695, 696, 697, 699, 698, 0, 701, 702, 700,
-	703, 704, 705, 706, 1449, 707, 844, 708, 687, 688,
-	709, 710, 711, 891, 712, 713, 714, 715, 716, 717,
-	718, 719, 720, 1465, 0, 721, 0, 722, 723, 724,
-	725, 726, 727, 729, 689, 730, 731, 732, 737, 738,
-	1496, 733, 734, 735, 736, 1489, 740, 741, 742, 743,
-	0, 744, 745, 1384, 739, 728, 0, 746, 747, 748,
-	749, 750, 751, 752, 753, 754, 755, 0, 756, 1478,
-	1479, 1480, 1481, 0, 768, 0, 757, 759, 760, 761,
-	762, 1490, 763, 1491, 1409, 764, 765, 766, 767, 758,
-	769, 770, 0, 1391, 771, 772, 773, 774, 776, 778,
-	779, 780, 775, 777, 781, 1450, 782, 0, 0, 783,
-	784, 785, 854, 1475, 1495, 0, 787, 788, 786, 789,
-	790, 793, 791, 792, 857, 796, 513, 797, 798, 799,
-	794, 795, 0, 0, 0, 0, 800, 801, 858, 802,
-	803, 804, 1388, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 1383, 0,
-	0, 0, 0, 0, 0, 1381, 1382, 0, 0, 0,
-	0, 0, 0, 864, 0, 1415, 0, 0, 0, 1413,
-	1460, 1403, 1404, 1405, 1401, 1402, 1414, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 345, 346, 348,
-	347, 349, 350, 351, 352, 0, 353, 354, 0, 0,
-	0, 0, 0, 1452, 1419, 0, 0, 356, 0, 355,
-	0, 357, 358, 359, 874, 360, 361, 362, 363, 364,
-	365, 366, 367, 806, 1466, 0, 368, 1474, 369, 1473,
-	0, 1484, 370, 371, 372, 373, 374, 375, 376, 377,
-	378, 379, 1421, 1451, 1385, 380, 1497, 1498, 813, 0,
-	381, 382, 383, 384, 1458, 0, 1439, 0, 385, 386,
-	387, 388, 389, 390, 391, 392, 0, 0, 394, 395,
-	396, 393, 397, 398, 0, 399, 0, 400, 401, 402,
-	403, 404, 405, 406, 0, 407, 408, 409, 876, 410,
-	411, 412, 1442, 1440, 1441, 1448, 1444, 1443, 1447, 413,
-	414, 415, 416, 417, 1477, 418, 420, 421, 1471, 422,
-	1470, 1390, 425, 427, 419, 423, 0, 426, 424, 428,
-	429, 0, 430, 431, 432, 433, 0, 0, 434, 1469,
-	436, 0, 437, 438, 440, 439, 0, 441, 442, 443,
-	0, 444, 445, 1397, 446, 447, 448, 450, 452, 449,
-	451, 453, 454, 455, 456, 457, 1485, 1486, 458, 459,
-	1410, 340, 0, 0, 0, 0, 0, 460, 461, 462,
-	1468, 0, 0, 0, 463, 0, 465, 469, 466, 467,
-	468, 470, 0, 464, 471, 472, 0, 877, 473, 474,
-	475, 1482, 1483, 476, 477, 478, 479, 480, 481, 482,
-	483, 484, 0, 485, 486, 1492, 0, 1420, 487, 0,
-	488, 489, 490, 491, 492, 493, 494, 1453, 1454, 1457,
-	595, 879, 495, 496, 497, 0, 498, 499, 500, 501,
-	502, 503, 504, 0, 0, 0, 505, 506, 507, 508,
-	0, 867, 341, 343, 878, 828, 509, 596, 510, 1463,
-	1464, 0, 1424, 0, 511, 512, 515, 880, 1455, 881,
-	514, 516, 517, 882, 518, 0, 0, 0, 519, 520,
-	521, 522, 523, 524, 525, 0, 526, 528, 527, 0,
-	530, 1493, 529, 883, 531, 532, 884, 0, 533, 534,
-	535, 536, 537, 538, 541, 1446, 1445, 539, 540, 542,
-	543, 0, 544, 545, 547, 550, 546, 548, 549, 551,
-	552, 565, 566, 553, 554, 555, 556, 557, 558, 559,
-	560, 561, 562, 563, 564, 568, 0, 567, 885, 569,
-	570, 571, 572, 573, 581, 583, 584, 579, 580, 582,
-	585, 586, 588, 589, 576, 577, 578, 1393, 587, 574,
-	1387, 575, 344, 887, 590, 591, 592, 593, 1411, 1456,
-	594, 1472, 597, 598, 0, 0, 599, 0, 600, 1392,
-	0, 602, 603, 604, 0, 0, 605, 606, 836, 888,
-	607, 889, 1487, 608, 609, 1398, 610, 611, 612, 613,
-	614, 615, 616, 617, 618, 619, 0, 620, 621, 838,
-	622, 623, 624, 839, 625, 626, 627, 1488, 628, 841,
-	629, 630, 0, 631, 632, 633, 0, 634, 635, 636,
-	637, 638, 639, 640, 641, 642, 643, 1467, 644, 645,
-	647, 646, 648, 649, 0, 650, 0, 651, 652, 653,
-	0, 0, 0, 0, 0, 654, 655, 657, 0, 658,
-	659, 660, 661, 662, 656, 663, 664, 665, 666, 667,
-	668, 669, 0, 671, 672, 670, 673, 674, 890, 675,
-	676, 677, 678, 679, 1399, 680, 0, 681, 682, 690,
-	691, 692, 683, 684, 686, 693, 685, 694, 695, 696,
-	697, 699, 698, 0, 701, 702, 700, 703, 704, 705,
-	706, 1449, 707, 844, 708, 687, 688, 709, 710, 711,
-	891, 712, 713, 714, 715, 716, 717, 718, 719, 720,
-	1465, 0, 721, 0, 722, 723, 724, 725, 726, 727,
-	729, 689, 730, 731, 732, 737, 738, 1496, 733, 734,
-	735, 736, 1489, 740, 741, 742, 743, 0, 744, 745,
-	1384, 739, 728, 0, 746, 747, 748, 749, 750, 751,
-	752, 753, 754, 755, 0, 756, 1478, 1479, 1480, 1481,
-	0, 768, 0, 757, 759, 760, 761, 762, 1490, 763,
-	1491, 1409, 764, 765, 766, 767, 758, 769, 770, 0,
-	1391, 771, 772, 773, 774, 776, 778, 779, 780, 775,
-	777, 781, 1450, 782, 0, 0, 783, 784, 785, 854,
-	1475, 1495, 0, 787, 788, 786, 789, 790, 793, 791,
-	792, 857, 796, 513, 797, 798, 799, 794, 795, 0,
-	0, 0, 0, 800, 801, 858, 802, 803, 804, 1388,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 1383, 0, 0, 0, 0,
-	0, 0, 1381, 1382, 0, 0, 0, 0, 0, 0,
-	864, 0, 1415, 0, 0, 0, 1413, 1460, 1403, 1404,
-	1405, 1401, 1402, 1414, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 345, 346, 348, 347, 349, 350,
-	351, 352, 0, 353, 354, 0, 0, 0, 0, 0,
-	1452, 1419, 0, 0, 356, 0, 355, 0, 357, 358,
-	359, 874, 360, 361, 362, 363, 364, 365, 366, 367,
-	806, 1466, 0, 368, 1474, 369, 1473, 0, 1484, 370,
-	371, 372, 373, 374, 375, 376, 377, 378, 379, 1421,
-	1451, 1385, 380, 1497, 1498, 813, 0, 381, 382, 383,
-	384, 1458, 0, 1439, 0, 385, 386, 387, 388, 389,
-	390, 391, 392, 0, 0, 394, 395, 396, 393, 397,
-	398, 0, 399, 0, 400, 401, 402, 403, 404, 405,
-	406, 0, 407, 408, 409, 876, 410, 411, 412, 1442,
-	1440, 1441, 1448, 1444, 1443, 1447, 413, 414, 415, 416,
-	417, 1477, 418, 420, 421, 1471, 422, 1470, 1390, 425,
-	427, 419, 423, 0, 426, 424, 428, 429, 0, 430,
-	431, 432, 433, 0, 0, 434, 1469, 436, 0, 437,
-	438, 440, 439, 0, 441, 442, 443, 0, 444, 445,
-	1397, 446, 447, 448, 450, 452, 449, 451, 453, 454,
-	455, 456, 457, 1485, 1486, 458, 459, 1410, 340, 0,
-	0, 0, 0, 0, 460, 461, 462, 1468, 0, 0,
-	0, 463, 0, 465, 469, 466, 467, 468, 470, 0,
-	464, 471, 472, 0, 877, 473, 474, 475, 1482, 1483,
-	476, 477, 478, 479, 480, 481, 482, 483, 484, 0,
-	485, 486, 1492, 0, 1420, 487, 0, 488, 489, 490,
-	491, 492, 493, 494, 1453, 1454, 1457, 595, 879, 495,
-	496, 497, 0, 498, 499, 500, 501, 502, 503, 504,
-	0, 0, 0, 505, 506, 507, 508, 0, 867, 341,
-	343, 878, 828, 509, 596, 510, 1463, 1464, 0, 1424,
-	0, 511, 512, 515, 880, 1455, 881, 514, 516, 517,
-	882, 518, 0, 0, 0, 519, 520, 521, 522, 523,
-	524, 525, 0, 526, 528, 527, 0, 530, 1493, 529,
-	883, 531, 532, 884, 0, 533, 534, 535, 536, 537,
-	538, 541, 1446, 1445, 539, 540, 542, 543, 0, 544,
-	545, 547, 550, 546, 548, 549, 551, 552, 565, 566,
-	553, 554, 555, 556, 557, 558, 559, 560, 561, 562,
-	563, 564, 568, 0, 567, 885, 569, 570, 571, 572,
-	573, 581, 583, 584, 579, 580, 582, 585, 586, 588,
-	589, 576, 577, 578, 886, 587, 574, 1387, 575, 5648,
-	887, 590, 591, 592, 593, 1411, 1456, 594, 1472, 597,
-	598, 0, 0, 599, 0, 600, 0, 0, 602, 603,
-	604, 0, 0, 605, 606, 836, 888, 607, 889, 1487,
-	608, 609, 1398, 610, 611, 612, 613, 614, 615, 616,
-	617, 618, 619, 0, 620, 621, 838, 622, 623, 624,
-	839, 625, 626, 627, 1488, 628, 841, 629, 630, 0,
-	631, 632, 633, 0, 634, 635, 636, 637, 638, 639,
-	640, 641, 642, 643, 1467, 644, 645, 647, 646, 648,
-	649, 0, 650, 0, 651, 652, 653, 0, 0, 0,
-	0, 0, 654, 655, 657, 0, 658, 659, 660, 661,
-	662, 656, 663, 664, 665, 666, 667, 668, 669, 0,
-	671, 672, 670, 673, 674, 890, 675, 676, 677, 678,
-	679, 1399, 680, 0, 681, 682, 690, 691, 692, 683,
-	684, 686, 693, 685, 694, 695, 696, 697, 699, 698,
-	0, 701, 702, 700, 703, 704, 705, 706, 1449, 707,
-	844, 708, 687, 688, 709, 710, 711, 891, 712, 713,
-	714, 715, 716, 717, 718, 719, 720, 1465, 0, 721,
-	0, 722, 723, 724, 725, 726, 727, 729, 689, 730,
-	731, 732, 737, 738, 1496, 733, 734, 735, 736, 1489,
-	740, 741, 742, 743, 0, 744, 745, 1384, 739, 728,
-	0, 746, 747, 748, 749, 750, 751, 752, 753, 754,
-	755, 0, 756, 1478, 1479, 1480, 1481, 0, 768, 0,
-	757, 759, 760, 761, 762, 1490, 763, 1491, 1409, 764,
-	765, 766, 767, 758, 769, 770, 0, 1391, 771, 772,
-	773, 774, 776, 778, 779, 780, 775, 777, 781, 1450,
-	782, 0, 0, 783, 784, 785, 854, 1475, 1495, 0,
-	787, 788, 786, 789, 790, 793, 791, 792, 857, 796,
-	513, 797, 798, 799, 794, 795, 0, 0, 0, 0,
-	800, 801, 858, 802, 803, 804, 1388, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 1383, 0, 0, 0, 0, 0, 0, 1381,
-	1382, 2343, 0, 0, 0, 0, 0, 864, 0, 1415,
-	0, 0, 0, 1413, 1460, 1403, 1404, 1405, 1401, 1402,
-	1414, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 345, 346, 348, 347, 349, 350, 351, 352, 0,
-	353, 354, 0, 0, 0, 0, 0, 1452, 1419, 0,
-	0, 356, 0, 355, 0, 357, 358, 359, 874, 360,
-	361, 362, 363, 364, 365, 366, 367, 806, 1466, 0,
-	368, 1474, 369, 1473, 0, 1484, 370, 371, 372, 373,
-	374, 375, 376, 377, 378, 379, 1421, 1451, 1385, 380,
-	1497, 1498, 813, 0, 381, 382, 383, 384, 1458, 0,
-	1439, 0, 385, 386, 387, 388, 389, 390, 391, 392,
-	0, 0, 394, 395, 396, 393, 397, 398, 0, 399,
-	0, 400, 401, 402, 403, 404, 405, 406, 0, 407,
-	408, 409, 876, 410, 411, 412, 1442, 1440, 1441, 1448,
-	1444, 1443, 1447, 413, 414, 415, 416, 417, 1477, 418,
-	420, 421, 1471, 422, 1470, 1390, 425, 427, 419, 423,
-	0, 426, 424, 428, 429, 0, 430, 431, 432, 433,
-	0, 0, 434, 1469, 436, 0, 437, 438, 440, 439,
-	0, 441, 442, 443, 0, 444, 445, 1397, 446, 447,
-	448, 450, 452, 449, 451, 453, 454, 455, 456, 457,
-	1485, 1486, 458, 459, 1410, 340, 0, 0, 0, 0,
-	0, 460, 461, 462, 1468, 0, 0, 0, 463, 0,
-	465, 469, 466, 467, 468, 470, 0, 464, 471, 472,
-	0, 877, 473, 474, 475, 1482, 1483, 476, 477, 478,
-	479, 480, 481, 482, 483, 484, 0, 485, 486, 1492,
-	0, 1420, 487, 0, 488, 489, 490, 491, 492, 493,
-	494, 1453, 1454, 1457, 595, 879, 495, 496, 497, 0,
-	498, 499, 500, 501, 502, 503, 504, 0, 0, 0,
-	505, 506, 507, 508, 0, 867, 341, 343, 878, 828,
-	509, 596, 510, 1463, 1464, 0, 1424, 0, 511, 512,
-	515, 880, 1455, 881, 514, 516, 517, 882, 518, 0,
-	0, 0, 519, 520, 521, 522, 523, 524, 525, 0,
-	526, 528, 527, 0, 530, 1493, 529, 883, 531, 532,
-	884, 0, 533, 534, 535, 536, 537, 538, 541, 1446,
-	1445, 539, 540, 542, 543, 0, 544, 545, 547, 550,
-	546, 548, 549, 551, 552, 565, 566, 553, 554, 555,
-	556, 557, 558, 559, 560, 561, 562, 563, 564, 568,
-	0, 567, 885, 569, 570, 571, 572, 573, 581, 583,
-	584, 579, 580, 582, 585, 586, 588, 589, 576, 577,
-	578, 886, 587, 574, 1387, 575, 344, 887, 590, 591,
-	592, 593, 1411, 1456, 594, 1472, 597, 598, 0, 0,
-	599, 0, 600, 0, 0, 602, 603, 604, 0, 0,
-	605, 606, 836, 888, 607, 889, 1487, 608, 609, 1398,
-	610, 611, 612, 613, 614, 615, 616, 617, 618, 619,
-	0, 620, 621, 838, 622, 623, 624, 839, 625, 626,
-	627, 1488, 628, 841, 629, 630, 0, 631, 632, 633,
-	0, 634, 635, 636, 637, 638, 639, 640, 641, 642,
-	643, 1467, 644, 645, 647, 646, 648, 649, 0, 650,
-	0, 651, 652, 653, 0, 0, 0, 0, 0, 654,
-	655, 657, 0, 658, 659, 660, 661, 662, 656, 663,
-	664, 665, 666, 667, 668, 669, 0, 671, 672, 670,
-	673, 674, 890, 675, 676, 677, 678, 679, 1399, 680,
-	0, 681, 682, 690, 691, 692, 683, 684, 686, 693,
-	685, 694, 695, 696, 697, 699, 698, 0, 701, 702,
-	700, 703, 704, 705, 706, 1449, 707, 844, 708, 687,
-	688, 709, 710, 711, 891, 712, 713, 714, 715, 716,
-	717, 718, 719, 720, 1465, 0, 721, 0, 722, 723,
-	724, 725, 726, 727, 729, 689, 730, 731, 732, 737,
-	738, 1496, 733, 734, 735, 736, 1489, 740, 741, 742,
-	743, 0, 744, 745, 1384, 739, 728, 0, 746, 747,
-	748, 749, 750, 751, 752, 753, 754, 755, 0, 756,
-	1478, 1479, 1480, 1481, 0, 768, 0, 757, 759, 760,
-	761, 762, 1490, 763, 1491, 1409, 764, 765, 766, 767,
-	758, 769, 770, 0, 1391, 771, 772, 773, 774, 776,
-	778, 779, 780, 775, 777, 781, 1450, 782, 0, 0,
-	783, 784, 785, 854, 1475, 1495, 4719, 787, 788, 786,
-	789, 790, 793, 791, 792, 857, 796, 513, 797, 798,
-	799, 794, 795, 0, 0, 0, 0, 800, 801, 858,
-	802, 803, 804, 1388, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 1383,
-	0, 0, 0, 0, 0, 0, 1381, 1382, 0, 0,
-	0, 0, 0, 0, 864, 0, 1415, 0, 0, 0,
-	1413, 1460, 1403, 1404, 1405, 1401, 1402, 1414, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 345, 346,
-	348, 347, 349, 350, 351, 352, 0, 353, 354, 0,
-	0, 0, 0, 0, 1452, 1419, 0, 0, 356, 0,
-	355, 0, 357, 358, 359, 874, 360, 361, 362, 363,
-	364, 365, 366, 367, 806, 1466, 0, 368, 1474, 369,
-	1473, 0, 1484, 370, 371, 372, 373, 374, 375, 376,
-	377, 378, 379, 1421, 1451, 1385, 380, 1497, 1498, 813,
-	0, 381, 382, 383, 384, 1458, 0, 1439, 0, 385,
-	386, 387, 388, 389, 390, 391, 392, 0, 0, 394,
-	395, 396, 393, 397, 398, 0, 399, 0, 400, 401,
-	402, 403, 404, 405, 406, 0, 407, 408, 409, 876,
-	410, 411, 412, 1442, 1440, 1441, 1448, 1444, 1443, 1447,
-	413, 414, 415, 416, 417, 1477, 418, 420, 421, 1471,
-	422, 1470, 1390, 425, 427, 419, 423, 0, 426, 424,
-	428, 429, 0, 430, 431, 432, 433, 0, 0, 434,
-	1469, 436, 0, 437, 438, 440, 439, 0, 441, 442,
-	443, 0, 444, 445, 1397, 446, 447, 448, 450, 452,
-	449, 451, 453, 454, 455, 456, 457, 1485, 1486, 458,
-	459, 1410, 340, 0, 0, 0, 0, 0, 460, 461,
-	462, 1468, 0, 0, 0, 463, 0, 465, 469, 466,
-	467, 468, 470, 0, 464, 471, 472, 3297, 877, 473,
-	474, 475, 1482, 1483, 476, 477, 478, 479, 480, 481,
-	482, 483, 484, 0, 485, 486, 1492, 0, 1420, 487,
-	0, 488, 489, 490, 491, 492, 493, 494, 1453, 1454,
-	1457, 595, 879, 495, 496, 497, 0, 498, 499, 500,
-	501, 502, 503, 504, 0, 0, 0, 505, 506, 507,
-	508, 0, 867, 341, 343, 878, 828, 509, 596, 510,
-	1463, 1464, 0, 1424, 0, 511, 512, 515, 880, 1455,
-	881, 514, 516, 517, 882, 518, 0, 0, 0, 519,
-	520, 521, 522, 523, 524, 525, 0, 526, 528, 527,
-	0, 530, 1493, 529, 883, 531, 532, 884, 0, 533,
-	534, 535, 536, 537, 538, 541, 1446, 1445, 539, 540,
-	542, 543, 0, 544, 545, 547, 550, 546, 548, 549,
-	551, 552, 565, 566, 553, 554, 555, 556, 557, 558,
-	559, 560, 561, 562, 563, 564, 568, 0, 567, 885,
-	569, 570, 571, 572, 573, 581, 583, 584, 579, 580,
-	582, 585, 586, 588, 589, 576, 577, 578, 886, 587,
-	574, 1387, 575, 344, 887, 590, 591, 592, 593, 1411,
-	1456, 594, 1472, 597, 598, 0, 0, 599, 0, 600,
-	0, 0, 602, 603, 604, 0, 0, 605, 606, 836,
-	888, 607, 889, 1487, 608, 609, 1398, 610, 611, 612,
-	613, 614, 615, 616, 617, 618, 619, 0, 620, 621,
-	838, 622, 623, 624, 839, 625, 626, 627, 1488, 628,
-	841, 629, 630, 0, 631, 632, 633, 0, 634, 635,
-	636, 637, 638, 639, 640, 641, 642, 643, 1467, 644,
-	645, 647, 646, 648, 649, 0, 650, 0, 651, 652,
-	653, 0, 0, 0, 0, 0, 654, 655, 657, 0,
-	658, 659, 660, 661, 662, 656, 663, 664, 665, 666,
-	667, 668, 669, 0, 671, 672, 670, 673, 674, 890,
-	675, 676, 677, 678, 679, 1399, 680, 0, 681, 682,
-	690, 691, 692, 683, 684, 686, 693, 685, 694, 695,
-	696, 697, 699, 698, 0, 701, 702, 700, 703, 704,
-	705, 706, 1449, 707, 844, 708, 687, 688, 709, 710,
-	711, 891, 712, 713, 714, 715, 716, 717, 718, 719,
-	720, 1465, 0, 721, 0, 722, 723, 724, 725, 726,
-	727, 729, 689, 730, 731, 732, 737, 738, 1496, 733,
-	734, 735, 736, 1489, 740, 741, 742, 743, 0, 744,
-	745, 1384, 739, 728, 0, 746, 747, 748, 749, 750,
-	751, 752, 753, 754, 755, 0, 756, 1478, 1479, 1480,
-	1481, 0, 768, 0, 757, 759, 760, 761, 762, 1490,
-	763, 1491, 1409, 764, 765, 766, 767, 758, 769, 770,
-	0, 1391, 771, 772, 773, 774, 776, 778, 779, 780,
-	775, 777, 781, 1450, 782, 0, 0, 783, 784, 785,
-	854, 1475, 1495, 0, 787, 788, 786, 789, 790, 793,
-	791, 792, 857, 796, 513, 797, 798, 799, 794, 795,
-	0, 0, 0, 0, 800, 801, 858, 802, 803, 804,
-	1388, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 1383, 0, 0, 0,
-	0, 0, 0, 1381, 1382, 0, 0, 0, 0, 0,
-	0, 864, 0, 1415, 0, 0, 0, 1413, 1460, 1403,
-	1404, 1405, 1401, 1402, 1414, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 345, 346, 348, 347, 349,
-	350, 351, 352, 0, 353, 354, 0, 0, 0, 0,
-	0, 1452, 1419, 0, 0, 356, 0, 355, 0, 357,
-	358, 359, 874, 360, 361, 362, 363, 364, 365, 366,
-	367, 806, 1466, 0, 368, 1474, 369, 1473, 0, 1484,
-	370, 371, 372, 373, 374, 375, 376, 377, 378, 379,
-	1421, 1451, 1385, 380, 1497, 1498, 813, 0, 381, 382,
-	383, 384, 1458, 0, 1439, 0, 385, 386, 387, 388,
-	389, 390, 391, 392, 0, 0, 394, 395, 396, 393,
-	397, 398, 0, 399, 0, 400, 401, 402, 403, 404,
-	405, 406, 0, 407, 408, 409, 876, 410, 411, 412,
-	1442, 1440, 1441, 1448, 1444, 1443, 1447, 413, 414, 415,
-	416, 417, 1477, 418, 420, 421, 1471, 422, 1470, 1390,
-	425, 427, 419, 423, 0, 426, 424, 428, 429, 0,
-	430, 431, 432, 433, 0, 0, 434, 1469, 436, 0,
-	437, 438, 440, 439, 0, 441, 442, 443, 0, 444,
-	445, 1397, 446, 447, 448, 450, 452, 449, 451, 453,
-	454, 455, 456, 457, 1485, 1486, 458, 459, 1410, 340,
-	0, 0, 0, 0, 0, 460, 461, 462, 1468, 0,
-	0, 0, 463, 0, 465, 469, 466, 467, 468, 470,
-	0, 464, 471, 472, 0, 877, 473, 474, 475, 1482,
-	1483, 476, 477, 478, 479, 480, 481, 482, 483, 484,
-	0, 485, 486, 1492, 0, 1420, 487, 0, 488, 489,
-	490, 491, 492, 493, 494, 1453, 1454, 1457, 595, 879,
-	495, 496, 497, 0, 498, 499, 500, 501, 502, 503,
-	504, 0, 0, 0, 505, 506, 507, 508, 0, 867,
-	341, 343, 878, 828, 509, 596, 510, 1463, 1464, 0,
-	1424, 0, 511, 512, 515, 880, 1455, 881, 514, 516,
-	517, 882, 518, 0, 0, 0, 519, 520, 521, 522,
-	523, 524, 525, 0, 526, 528, 527, 0, 530, 1493,
-	529, 883, 531, 532, 884, 0, 533, 534, 535, 536,
-	537, 538, 541, 1446, 1445, 539, 540, 542, 543, 0,
-	544, 545, 547, 550, 546, 548, 549, 551, 552, 565,
-	566, 553, 554, 555, 556, 557, 558, 559, 560, 561,
-	562, 563, 564, 568, 0, 567, 885, 569, 570, 571,
-	572, 573, 581, 583, 584, 579, 580, 582, 585, 586,
-	588, 589, 576, 577, 578, 886, 587, 574, 1387, 575,
-	344, 887, 590, 591, 592, 593, 1411, 1456, 594, 1472,
-	597, 598, 0, 0, 599, 0, 600, 0, 0, 602,
-	603, 604, 0, 0, 605, 606, 836, 888, 607, 889,
-	1487, 608, 609, 1398, 610, 611, 612, 613, 614, 615,
-	616, 617, 618, 619, 0, 620, 621, 838, 622, 623,
-	624, 839, 625, 626, 627, 1488, 628, 841, 629, 630,
-	0, 631, 632, 633, 0, 634, 635, 636, 637, 638,
-	639, 640, 641, 642, 643, 1467, 644, 645, 647, 646,
-	648, 649, 0, 650, 0, 651, 652, 653, 0, 0,
-	0, 0, 0, 654, 655, 657, 0, 658, 659, 660,
-	661, 662, 656, 663, 664, 665, 666, 667, 668, 669,
-	0, 671, 672, 670, 673, 674, 890, 675, 676, 677,
-	678, 679, 1399, 680, 0, 681, 682, 690, 691, 692,
-	683, 684, 686, 693, 685, 694, 695, 696, 697, 699,
-	698, 0, 701, 702, 700, 703, 704, 705, 706, 1449,
-	707, 844, 708, 687, 688, 709, 710, 711, 891, 712,
-	713, 714, 715, 716, 717, 718, 719, 720, 1465, 0,
-	721, 0, 722, 723, 724, 725, 726, 727, 729, 689,
-	730, 731, 732, 737, 738, 1496, 733, 734, 735, 736,
-	1489, 740, 741, 742, 743, 0, 744, 745, 1384, 739,
-	728, 0, 746, 747, 748, 749, 750, 751, 752, 753,
-	754, 755, 0, 756, 1478, 1479, 1480, 1481, 0, 768,
-	0, 757, 759, 760, 761, 762, 1490, 763, 1491, 1409,
-	764, 765, 766, 767, 758, 769, 770, 0, 1391, 771,
-	772, 773, 774, 776, 778, 779, 780, 775, 777, 781,
-	1450, 782, 0, 0, 783, 784, 785, 854, 1475, 1495,
-	0, 787, 788, 786, 789, 790, 793, 791, 792, 857,
-	796, 513, 797, 798, 799, 794, 795, 0, 0, 0,
-	0, 800, 801, 858, 802, 803, 804, 1388, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 1383, 0, 0, 0, 0, 0, 0,
-	1381, 1382, 0, 0, 0, 0, 0, 0, 864, 0,
-	1415, 2267, 0, 3302, 1413, 1460, 1403, 1404, 1405, 1401,
-	1402, 1414, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 345, 346, 348, 347, 349, 350, 351, 352,
-	0, 353, 354, 0, 0, 0, 0, 0, 1452, 1419,
-	0, 0, 356, 0, 355, 0, 357, 358, 359, 874,
-	360, 361, 362, 363, 364, 365, 366, 367, 806, 1466,
-	0, 368, 1474, 369, 1473, 0, 1484, 370, 371, 372,
-	373, 374, 375, 376, 377, 378, 379, 1421, 1451, 1385,
-	380, 1497, 1498, 813, 0, 381, 382, 383, 384, 1458,
-	0, 1439, 0, 385, 386, 387, 388, 389, 390, 391,
-	392, 0, 0, 394, 395, 396, 393, 397, 398, 0,
-	399, 0, 400, 401, 402, 403, 404, 405, 406, 0,
-	407, 408, 409, 876, 410, 411, 412, 1442, 1440, 1441,
-	1448, 1444, 1443, 1447, 413, 414, 415, 416, 417, 1477,
-	418, 420, 421, 1471, 422, 1470, 1390, 425, 427, 419,
-	423, 0, 426, 424, 428, 429, 0, 430, 431, 432,
-	433, 0, 0, 434, 1469, 436, 0, 437, 438, 440,
-	439, 0, 441, 442, 443, 0, 444, 445, 1397, 446,
-	447, 448, 450, 452, 449, 451, 453, 454, 455, 456,
-	457, 1485, 1486, 458, 459, 1410, 340, 0, 0, 0,
-	0, 0, 460, 461, 462, 1468, 0, 0, 0, 463,
-	0, 465, 469, 466, 467, 468, 470, 0, 464, 471,
-	472, 0, 877, 473, 474, 475, 1482, 1483, 476, 477,
-	478, 479, 480, 481, 482, 483, 484, 0, 485, 486,
-	1492, 0, 1420, 487, 0, 488, 489, 490, 491, 492,
-	493, 494, 1453, 1454, 1457, 595, 879, 495, 496, 497,
-	0, 498, 499, 500, 501, 502, 503, 504, 0, 0,
-	0, 505, 506, 507, 508, 0, 867, 341, 343, 878,
-	828, 509, 596, 510, 1463, 1464, 0, 1424, 0, 511,
-	512, 515, 880, 1455, 881, 514, 516, 517, 882, 518,
-	0, 0, 0, 519, 520, 521, 522, 523, 524, 525,
-	0, 526, 528, 527, 0, 530, 1493, 529, 883, 531,
-	532, 884, 0, 533, 534, 535, 536, 537, 538, 541,
-	1446, 1445, 539, 540, 542, 543, 0, 544, 545, 547,
-	550, 546, 548, 549, 551, 552, 565, 566, 553, 554,
-	555, 556, 557, 558, 559, 560, 561, 562, 563, 564,
-	568, 0, 567, 885, 569, 570, 571, 572, 573, 581,
-	583, 584, 579, 580, 582, 585, 586, 588, 589, 576,
-	577, 578, 886, 587, 574, 1387, 575, 344, 887, 590,
-	591, 592, 593, 1411, 1456, 594, 1472, 597, 598, 0,
-	0, 599, 0, 600, 0, 0, 602, 603, 604, 0,
-	0, 605, 606, 836, 888, 607, 889, 1487, 608, 609,
-	1398, 610, 611, 612, 613, 614, 615, 616, 617, 618,
-	619, 0, 620, 621, 838, 622, 623, 624, 839, 625,
-	626, 627, 1488, 628, 841, 629, 630, 0, 631, 632,
-	633, 0, 634, 635, 636, 637, 638, 639, 640, 641,
-	642, 643, 1467, 644, 645, 647, 646, 648, 649, 0,
-	650, 0, 651, 652, 653, 0, 0, 0, 0, 0,
-	654, 655, 657, 0, 658, 659, 660, 661, 662, 656,
-	663, 664, 665, 666, 667, 668, 669, 0, 671, 672,
-	670, 673, 674, 890, 675, 676, 677, 678, 679, 1399,
-	680, 0, 681, 682, 690, 691, 692, 683, 684, 686,
-	693, 685, 694, 695, 696, 697, 699, 698, 0, 701,
-	702, 700, 703, 704, 705, 706, 1449, 707, 844, 708,
-	687, 688, 709, 710, 711, 891, 712, 713, 714, 715,
-	716, 717, 718, 719, 720, 1465, 0, 721, 0, 722,
-	723, 724, 725, 726, 727, 729, 689, 730, 731, 732,
-	737, 738, 1496, 733, 734, 735, 736, 1489, 740, 741,
-	742, 743, 0, 744, 745, 1384, 739, 728, 0, 746,
-	747, 748, 749, 750, 751, 752, 753, 754, 755, 0,
-	756, 1478, 1479, 1480, 1481, 0, 768, 0, 757, 759,
-	760, 761, 762, 1490, 763, 1491, 1409, 764, 765, 766,
-	767, 758, 769, 770, 0, 1391, 771, 772, 773, 774,
-	776, 778, 779, 780, 775, 777, 781, 1450, 782, 0,
-	0, 783, 784, 785, 854, 1475, 1495, 0, 787, 788,
-	786, 789, 790, 793, 791, 792, 857, 796, 513, 797,
-	798, 799, 794, 795, 0, 0, 0, 0, 800, 801,
-	858, 802, 803, 804, 1388, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	1383, 0, 0, 0, 0, 0, 0, 1381, 1382, 0,
-	0, 0, 0, 0, 0, 864, 0, 1415, 0, 0,
-	3300, 1413, 1460, 1403, 1404, 1405, 1401, 1402, 1414, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 345,
-	346, 348, 347, 349, 350, 351, 352, 0, 353, 354,
-	0, 0, 0, 0, 0, 1452, 1419, 0, 0, 356,
-	0, 355, 0, 357, 358, 359, 874, 360, 361, 362,
-	363, 364, 365, 366, 367, 806, 1466, 0, 368, 1474,
-	369, 1473, 0, 1484, 370, 371, 372, 373, 374, 375,
-	376, 377, 378, 379, 1421, 1451, 1385, 380, 1497, 1498,
-	813, 0, 381, 382, 383, 384, 1458, 0, 1439, 0,
-	385, 386, 387, 388, 389, 390, 391, 392, 0, 0,
-	394, 395, 396, 393, 397, 398, 0, 399, 0, 400,
-	401, 402, 403, 404, 405, 406, 0, 407, 408, 409,
-	876, 410, 411, 412, 1442, 1440, 1441, 1448, 1444, 1443,
-	1447, 413, 414, 415, 416, 417, 1477, 418, 420, 421,
-	1471, 422, 1470, 1390, 425, 427, 419, 423, 0, 426,
-	424, 428, 429, 0, 430, 431, 432, 433, 0, 0,
-	434, 1469, 436, 0, 437, 438, 440, 439, 0, 441,
-	442, 443, 0, 444, 445, 1397, 446, 447, 448, 450,
-	452, 449, 451, 453, 454, 455, 456, 457, 1485, 1486,
-	458, 459, 1410, 340, 0, 0, 0, 0, 0, 460,
-	461, 462, 1468, 0, 0, 0, 463, 0, 465, 469,
-	466, 467, 468, 470, 0, 464, 471, 472, 0, 877,
-	473, 474, 475, 1482, 1483, 476, 477, 478, 479, 480,
-	481, 482, 483, 484, 0, 485, 486, 1492, 0, 1420,
-	487, 0, 488, 489, 490, 491, 492, 493, 494, 1453,
-	1454, 1457, 595, 879, 495, 496, 497, 0, 498, 499,
-	500, 501, 502, 503, 504, 0, 0, 0, 505, 506,
-	507, 508, 0, 867, 341, 343, 878, 828, 509, 596,
-	510, 1463, 1464, 0, 1424, 0, 511, 512, 515, 880,
-	1455, 881, 514, 516, 517, 882, 518, 0, 0, 0,
-	519, 520, 521, 522, 523, 524, 525, 0, 526, 528,
-	527, 0, 530, 1493, 529, 883, 531, 532, 884, 0,
-	533, 534, 535, 536, 537, 538, 541, 1446, 1445, 539,
-	540, 542, 543, 0, 544, 545, 547, 550, 546, 548,
-	549, 551, 552, 565, 566, 553, 554, 555, 556, 557,
-	558, 559, 560, 561, 562, 563, 564, 568, 0, 567,
-	885, 569, 570, 571, 572, 573, 581, 583, 584, 579,
-	580, 582, 585, 586, 588, 589, 576, 577, 578, 886,
-	587, 574, 1387, 575, 344, 887, 590, 591, 592, 593,
-	1411, 1456, 594, 1472, 597, 598, 0, 0, 599, 0,
-	600, 0, 0, 602, 603, 604, 0, 0, 605, 606,
-	836, 888, 607, 889, 1487, 608, 609, 1398, 610, 611,
-	612, 613, 614, 615, 616, 617, 618, 619, 0, 620,
-	621, 838, 622, 623, 624, 839, 625, 626, 627, 1488,
-	628, 841, 629, 630, 0, 631, 632, 633, 0, 634,
-	635, 636, 637, 638, 639, 640, 641, 642, 643, 1467,
-	644, 645, 647, 646, 648, 649, 0, 650, 0, 651,
-	652, 653, 0, 0, 0, 0, 0, 654, 655, 657,
-	0, 658, 659, 660, 661, 662, 656, 663, 664, 665,
-	666, 667, 668, 669, 0, 671, 672, 670, 673, 674,
-	890, 675, 676, 677, 678, 679, 1399, 680, 0, 681,
-	682, 690, 691, 692, 683, 684, 686, 693, 685, 694,
-	695, 696, 697, 699, 698, 0, 701, 702, 700, 703,
-	704, 705, 706, 1449, 707, 844, 708, 687, 688, 709,
-	710, 711, 891, 712, 713, 714, 715, 716, 717, 718,
-	719, 720, 1465, 0, 721, 0, 722, 723, 724, 725,
-	726, 727, 729, 689, 730, 731, 732, 737, 738, 1496,
-	733, 734, 735, 736, 1489, 740, 741, 742, 743, 0,
-	744, 745, 1384, 739, 728, 0, 746, 747, 748, 749,
-	750, 751, 752, 753, 754, 755, 0, 756, 1478, 1479,
-	1480, 1481, 0, 768, 0, 757, 759, 760, 761, 762,
-	1490, 763, 1491, 1409, 764, 765, 766, 767, 758, 769,
-	770, 0, 1391, 771, 772, 773, 774, 776, 778, 779,
-	780, 775, 777, 781, 1450, 782, 0, 0, 783, 784,
-	785, 854, 1475, 1495, 0, 787, 788, 786, 789, 790,
-	793, 791, 792, 857, 796, 513, 797, 798, 799, 794,
-	795, 0, 0, 0, 0, 800, 801, 858, 802, 803,
-	804, 1388, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 1383, 0, 0,
-	0, 0, 0, 0, 1381, 1382, 0, 0, 0, 0,
-	0, 0, 864, 0, 1415, 0, 0, 3288, 1413, 1460,
-	1403, 1404, 1405, 1401, 1402, 1414, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 345, 346, 348, 347,
-	349, 350, 351, 352, 0, 353, 354, 0, 0, 0,
-	0, 0, 1452, 1419, 0, 0, 356, 0, 355, 0,
-	357, 358, 359, 874, 360, 361, 362, 363, 364, 365,
-	366, 367, 806, 1466, 0, 368, 1474, 369, 1473, 0,
-	1484, 370, 371, 372, 373, 374, 375, 376, 377, 378,
-	379, 1421, 1451, 1385, 380, 1497, 1498, 813, 0, 381,
-	382, 383, 384, 1458, 0, 1439, 0, 385, 386, 387,
-	388, 389, 390, 391, 392, 0, 0, 394, 395, 396,
-	393, 397, 398, 0, 399, 0, 400, 401, 402, 403,
-	404, 405, 406, 0, 407, 408, 409, 876, 410, 411,
-	412, 1442, 1440, 1441, 1448, 1444, 1443, 1447, 413, 414,
-	415, 416, 417, 1477, 418, 420, 421, 1471, 422, 1470,
-	1390, 425, 427, 419, 423, 0, 426, 424, 428, 429,
-	0, 430, 431, 432, 433, 0, 0, 434, 1469, 436,
-	0, 437, 438, 440, 439, 0, 441, 442, 443, 0,
-	444, 445, 1397, 446, 447, 448, 450, 452, 449, 451,
-	453, 454, 455, 456, 457, 1485, 1486, 458, 459, 1410,
-	340, 0, 0, 0, 0, 0, 460, 461, 462, 1468,
-	0, 0, 0, 463, 0, 465, 469, 466, 467, 468,
-	470, 0, 464, 471, 472, 0, 877, 473, 474, 475,
-	1482, 1483, 476, 477, 478, 479, 480, 481, 482, 483,
-	484, 0, 485, 486, 1492, 0, 1420, 487, 0, 488,
-	489, 490, 491, 492, 493, 494, 1453, 1454, 1457, 595,
-	879, 495, 496, 497, 0, 498, 499, 500, 501, 502,
-	503, 504, 0, 0, 0, 505, 506, 507, 508, 0,
-	867, 341, 343, 878, 828, 509, 596, 510, 1463, 1464,
-	0, 1424, 0, 511, 512, 515, 880, 1455, 881, 514,
-	516, 517, 882, 518, 0, 0, 0, 519, 520, 521,
-	522, 523, 524, 525, 0, 526, 528, 527, 0, 530,
-	1493, 529, 883, 531, 532, 884, 0, 533, 534, 535,
-	536, 537, 538, 541, 1446, 1445, 539, 540, 542, 543,
-	0, 544, 545, 547, 550, 546, 548, 549, 551, 552,
-	565, 566, 553, 554, 555, 556, 557, 558, 559, 560,
-	561, 562, 563, 564, 568, 0, 567, 885, 569, 570,
-	571, 572, 573, 581, 583, 584, 579, 580, 582, 585,
-	586, 588, 589, 576, 577, 578, 886, 587, 574, 1387,
-	575, 344, 887, 590, 591, 592, 593, 1411, 1456, 594,
-	1472, 597, 598, 0, 0, 599, 0, 600, 0, 0,
-	602, 603, 604, 0, 0, 605, 606, 836, 888, 607,
-	889, 1487, 608, 609, 1398, 610, 611, 612, 613, 614,
-	615, 616, 617, 618, 619, 0, 620, 621, 838, 622,
-	623, 624, 839, 625, 626, 627, 1488, 628, 841, 629,
-	630, 0, 631, 632, 633, 0, 634, 635, 636, 637,
-	638, 639, 640, 641, 642, 643, 1467, 644, 645, 647,
-	646, 648, 649, 0, 650, 0, 651, 652, 653, 0,
-	0, 0, 0, 0, 654, 655, 657, 0, 658, 659,
-	660, 661, 662, 656, 663, 664, 665, 666, 667, 668,
-	669, 0, 671, 672, 670, 673, 674, 890, 675, 676,
-	677, 678, 679, 1399, 680, 0, 681, 682, 690, 691,
-	692, 683, 684, 686, 693, 685, 694, 695, 696, 697,
-	699, 698, 0, 701, 702, 700, 703, 704, 705, 706,
-	1449, 707, 844, 708, 687, 688, 709, 710, 711, 891,
-	712, 713, 714, 715, 716, 717, 718, 719, 720, 1465,
-	0, 721, 0, 722, 723, 724, 725, 726, 727, 729,
-	689, 730, 731, 732, 737, 738, 1496, 733, 734, 735,
-	736, 1489, 740, 741, 742, 743, 0, 744, 745, 1384,
-	739, 728, 0, 746, 747, 748, 749, 750, 751, 752,
-	753, 754, 755, 0, 756, 1478, 1479, 1480, 1481, 0,
-	768, 0, 757, 759, 760, 761, 762, 1490, 763, 1491,
-	1409, 764, 765, 766, 767, 758, 769, 770, 0, 1391,
-	771, 772, 773, 774, 776, 778, 779, 780, 775, 777,
-	781, 1450, 782, 0, 0, 783, 784, 785, 854, 1475,
-	1495, 0, 787, 788, 786, 789, 790, 793, 791, 792,
-	857, 796, 513, 797, 798, 799, 794, 795, 0, 0,
-	0, 0, 800, 801, 858, 802, 803, 804, 1388, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 1383, 0, 0, 0, 0, 0,
-	0, 1381, 1382, 0, 0, 0, 0, 0, 0, 864,
-	0, 1415, 0, 0, 3277, 1413, 1460, 1403, 1404, 1405,
-	1401, 1402, 1414, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 345, 346, 348, 347, 349, 350, 351,
-	352, 0, 353, 354, 0, 0, 0, 0, 0, 1452,
-	1419, 0, 0, 356, 0, 355, 0, 357, 358, 359,
-	874, 360, 361, 362, 363, 364, 365, 366, 367, 806,
-	1466, 0, 368, 1474, 369, 1473, 0, 1484, 370, 371,
-	372, 373, 374, 375, 376, 377, 378, 379, 1421, 1451,
-	1385, 380, 1497, 1498, 813, 0, 381, 382, 383, 384,
-	1458, 0, 1439, 0, 385, 386, 387, 388, 389, 390,
-	391, 392, 0, 0, 394, 395, 396, 393, 397, 398,
-	0, 399, 0, 400, 401, 402, 403, 404, 405, 406,
-	0, 407, 408, 409, 876, 410, 411, 412, 1442, 1440,
-	1441, 1448, 1444, 1443, 1447, 413, 414, 415, 416, 417,
-	1477, 418, 420, 421, 1471, 422, 1470, 1390, 425, 427,
-	419, 423, 0, 426, 424, 428, 429, 0, 430, 431,
-	432, 433, 0, 0, 434, 1469, 436, 0, 437, 438,
-	440, 439, 0, 441, 442, 443, 0, 444, 445, 1397,
-	446, 447, 448, 450, 452, 449, 451, 453, 454, 455,
-	456, 457, 1485, 1486, 458, 459, 1410, 340, 0, 0,
-	0, 0, 0, 460, 461, 462, 1468, 0, 0, 0,
-	463, 0, 465, 469, 466, 467, 468, 470, 0, 464,
-	471, 472, 0, 877, 473, 474, 475, 1482, 1483, 476,
-	477, 478, 479, 480, 481, 482, 483, 484, 0, 485,
-	486, 1492, 0, 1420, 487, 0, 488, 489, 490, 491,
-	492, 493, 494, 1453, 1454, 1457, 595, 879, 495, 496,
-	497, 0, 498, 499, 500, 501, 502, 503, 504, 0,
-	0, 0, 505, 506, 507, 508, 0, 867, 341, 343,
-	878, 828, 509, 596, 510, 1463, 1464, 0, 1424, 0,
-	511, 512, 515, 880, 1455, 881, 514, 516, 517, 882,
-	518, 0, 0, 0, 519, 520, 521, 522, 523, 524,
-	525, 0, 526, 528, 527, 0, 530, 1493, 529, 883,
-	531, 532, 884, 0, 533, 534, 535, 536, 537, 538,
-	541, 1446, 1445, 539, 540, 542, 543, 0, 544, 545,
-	547, 550, 546, 548, 549, 551, 552, 565, 566, 553,
-	554, 555, 556, 557, 558, 559, 560, 561, 562, 563,
-	564, 568, 0, 567, 885, 569, 570, 571, 572, 573,
-	581, 583, 584, 579, 580, 582, 585, 586, 588, 589,
-	576, 577, 578, 886, 587, 574, 1387, 575, 344, 887,
-	590, 591, 592, 593, 1411, 1456, 594, 1472, 597, 598,
-	0, 0, 599, 0, 600, 0, 0, 602, 603, 604,
-	0, 0, 605, 606, 836, 888, 607, 889, 1487, 608,
-	609, 1398, 610, 611, 612, 613, 614, 615, 616, 617,
-	618, 619, 0, 620, 621, 838, 622, 623, 624, 839,
-	625, 626, 627, 1488, 628, 841, 629, 630, 0, 631,
-	632, 633, 0, 634, 635, 636, 637, 638, 639, 640,
-	641, 642, 643, 1467, 644, 645, 647, 646, 648, 649,
-	0, 650, 0, 651, 652, 653, 0, 0, 0, 0,
-	0, 654, 655, 657, 0, 658, 659, 660, 661, 662,
-	656, 663, 664, 665, 666, 667, 668, 669, 0, 671,
-	672, 670, 673, 674, 890, 675, 676, 677, 678, 679,
-	1399, 680, 0, 681, 682, 690, 691, 692, 683, 684,
-	686, 693, 685, 694, 695, 696, 697, 699, 698, 0,
-	701, 702, 700, 703, 704, 705, 706, 1449, 707, 844,
-	708, 687, 688, 709, 710, 711, 891, 712, 713, 714,
-	715, 716, 717, 718, 719, 720, 1465, 0, 721, 0,
-	722, 723, 724, 725, 726, 727, 729, 689, 730, 731,
-	732, 737, 738, 1496, 733, 734, 735, 736, 1489, 740,
-	741, 742, 743, 0, 744, 745, 1384, 739, 728, 0,
-	746, 747, 748, 749, 750, 751, 752, 753, 754, 755,
-	0, 756, 1478, 1479, 1480, 1481, 0, 768, 0, 757,
-	759, 760, 761, 762, 1490, 763, 1491, 1409, 764, 765,
-	766, 767, 758, 769, 770, 0, 1391, 771, 772, 773,
-	774, 776, 778, 779, 780, 775, 777, 781, 1450, 782,
-	0, 0, 783, 784, 785, 854, 1475, 1495, 0, 787,
-	788, 786, 789, 790, 793, 791, 792, 857, 796, 513,
-	797, 798, 799, 794, 795, 0, 0, 0, 0, 800,
-	801, 858, 802, 803, 804, 1388, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 1383, 0, 0, 0, 0, 0, 0, 1381, 1382,
-	0, 0, 0, 0, 0, 0, 864, 0, 1415, 0,
-	0, 3275, 1413, 3266, 3273, 1404, 1405, 1401, 1402, 1414,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	345, 346, 348, 347, 349, 350, 351, 352, 0, 353,
-	354, 0, 0, 0, 0, 0, 1452, 1419, 0, 0,
-	356, 0, 355, 0, 357, 358, 359, 874, 360, 361,
-	362, 363, 364, 365, 366, 367, 806, 1466, 0, 368,
-	1474, 369, 1473, 0, 1484, 370, 371, 372, 373, 374,
-	375, 376, 377, 378, 379, 1421, 1451, 1385, 380, 1497,
-	1498, 813, 0, 381, 382, 383, 384, 1458, 0, 1439,
-	0, 385, 386, 387, 388, 389, 390, 391, 392, 0,
-	0, 394, 395, 396, 393, 397, 398, 0, 399, 0,
-	400, 401, 402, 403, 404, 405, 406, 0, 407, 408,
-	409, 876, 410, 411, 412, 1442, 1440, 1441, 1448, 1444,
-	1443, 1447, 413, 414, 415, 416, 417, 1477, 3269, 420,
-	421, 1471, 422, 1470, 1390, 425, 427, 419, 423, 0,
-	426, 424, 428, 429, 0, 430, 431, 432, 433, 0,
-	0, 434, 1469, 436, 0, 437, 438, 440, 439, 0,
-	441, 442, 443, 0, 444, 445, 1397, 446, 447, 448,
-	450, 452, 449, 451, 453, 454, 455, 456, 457, 1485,
-	1486, 458, 459, 1410, 340, 0, 0, 0, 0, 0,
-	460, 461, 462, 1468, 0, 0, 0, 463, 0, 465,
-	469, 466, 467, 468, 470, 0, 464, 471, 472, 0,
-	877, 473, 474, 475, 1482, 1483, 476, 477, 478, 479,
-	480, 481, 482, 483, 484, 0, 485, 486, 1492, 0,
-	1420, 487, 0, 488, 489, 490, 491, 492, 3270, 494,
-	1453, 1454, 1457, 595, 879, 495, 496, 497, 0, 498,
-	499, 500, 501, 502, 503, 504, 0, 0, 0, 505,
-	506, 507, 508, 0, 867, 341, 343, 878, 828, 509,
-	596, 510, 1463, 1464, 0, 1424, 0, 511, 512, 515,
-	880, 1455, 881, 514, 516, 517, 882, 518, 0, 0,
-	0, 519, 520, 521, 522, 523, 524, 525, 0, 526,
-	528, 527, 0, 530, 1493, 529, 883, 531, 532, 884,
-	0, 533, 534, 535, 536, 537, 538, 541, 1446, 1445,
-	539, 540, 542, 543, 0, 544, 545, 547, 550, 546,
-	548, 3271, 551, 552, 3268, 566, 553, 554, 555, 556,
-	557, 558, 559, 560, 561, 562, 563, 564, 568, 0,
-	567, 885, 569, 570, 571, 572, 573, 581, 583, 584,
-	579, 580, 582, 585, 586, 588, 589, 576, 577, 578,
-	886, 587, 574, 1387, 575, 344, 887, 590, 591, 592,
-	593, 1411, 1456, 594, 1472, 597, 598, 0, 0, 599,
-	0, 600, 0, 0, 602, 603, 604, 0, 0, 605,
-	606, 836, 888, 607, 889, 1487, 608, 609, 1398, 610,
-	611, 612, 613, 614, 615, 616, 617, 618, 619, 0,
-	620, 621, 838, 622, 623, 624, 839, 625, 626, 627,
-	1488, 628, 841, 629, 630, 0, 631, 632, 633, 0,
-	634, 635, 636, 637, 638, 639, 640, 641, 642, 643,
-	1467, 644, 645, 647, 646, 648, 649, 0, 650, 0,
-	651, 652, 653, 0, 0, 0, 0, 0, 654, 655,
-	657, 0, 658, 659, 660, 661, 662, 656, 663, 664,
-	665, 666, 667, 668, 669, 0, 671, 672, 670, 673,
-	674, 890, 675, 676, 677, 678, 679, 1399, 680, 0,
-	681, 682, 690, 691, 692, 683, 684, 686, 693, 685,
-	694, 695, 696, 3272, 699, 698, 0, 701, 702, 700,
-	703, 704, 705, 706, 1449, 707, 844, 708, 687, 688,
-	709, 710, 711, 891, 712, 713, 714, 715, 716, 717,
-	718, 719, 720, 1465, 0, 721, 0, 722, 723, 724,
-	725, 726, 727, 729, 689, 730, 731, 732, 737, 738,
-	1496, 733, 734, 735, 736, 1489, 740, 741, 742, 743,
-	0, 744, 745, 1384, 739, 728, 0, 746, 747, 748,
-	749, 750, 751, 752, 753, 754, 755, 0, 756, 1478,
-	1479, 1480, 1481, 0, 768, 0, 757, 759, 760, 761,
-	762, 1490, 763, 1491, 1409, 764, 765, 766, 767, 758,
-	769, 770, 0, 1391, 771, 772, 773, 774, 776, 778,
-	779, 780, 775, 777, 781, 1450, 782, 0, 0, 783,
-	784, 785, 854, 1475, 1495, 0, 787, 788, 786, 789,
-	790, 793, 791, 792, 857, 796, 513, 797, 798, 799,
-	794, 795, 0, 0, 0, 0, 800, 801, 858, 802,
-	3267, 804, 1388, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 1383, 0,
-	0, 0, 0, 0, 0, 1381, 1382, 0, 0, 0,
-	0, 0, 0, 864, 0, 1415, 0, 0, 3263, 1413,
-	3266, 3273, 1404, 1405, 1401, 1402, 1414, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 345, 346, 348,
-	347, 349, 350, 351, 352, 0, 353, 354, 0, 0,
-	0, 0, 0, 1452, 1419, 0, 0, 356, 0, 355,
-	0, 357, 358, 359, 874, 360, 361, 362, 363, 364,
-	365, 366, 367, 806, 1466, 0, 368, 1474, 369, 1473,
-	0, 1484, 370, 371, 372, 373, 374, 375, 376, 377,
-	378, 379, 1421, 1451, 1385, 380, 1497, 1498, 813, 0,
-	381, 382, 383, 384, 1458, 0, 1439, 0, 385, 386,
-	387, 388, 389, 390, 391, 392, 0, 0, 394, 395,
-	396, 393, 397, 398, 0, 399, 0, 400, 401, 402,
-	403, 404, 405, 406, 0, 407, 408, 409, 876, 410,
-	411, 412, 1442, 1440, 1441, 1448, 1444, 1443, 1447, 413,
-	414, 415, 416, 417, 1477, 3269, 420, 421, 1471, 422,
-	1470, 1390, 425, 427, 419, 423, 0, 426, 424, 428,
-	429, 0, 430, 431, 432, 433, 0, 0, 434, 1469,
-	436, 0, 437, 438, 440, 439, 0, 441, 442, 443,
-	0, 444, 445, 1397, 446, 447, 448, 450, 452, 449,
-	451, 453, 454, 455, 456, 457, 1485, 1486, 458, 459,
-	1410, 340, 0, 0, 0, 0, 0, 460, 461, 462,
-	1468, 0, 0, 0, 463, 0, 465, 469, 466, 467,
-	468, 470, 0, 464, 471, 472, 0, 877, 473, 474,
-	475, 1482, 1483, 476, 477, 478, 479, 480, 481, 482,
-	483, 484, 0, 485, 486, 1492, 0, 1420, 487, 0,
-	488, 489, 490, 491, 492, 3270, 494, 1453, 1454, 1457,
-	595, 879, 495, 496, 497, 0, 498, 499, 500, 501,
-	502, 503, 504, 0, 0, 0, 505, 506, 507, 508,
-	0, 867, 341, 343, 878, 828, 509, 596, 510, 1463,
-	1464, 0, 1424, 0, 511, 512, 515, 880, 1455, 881,
-	514, 516, 517, 882, 518, 0, 0, 0, 519, 520,
-	521, 522, 523, 524, 525, 0, 526, 528, 527, 0,
-	530, 1493, 529, 883, 531, 532, 884, 0, 533, 534,
-	535, 536, 537, 538, 541, 1446, 1445, 539, 540, 542,
-	543, 0, 544, 545, 547, 550, 546, 548, 3271, 551,
-	552, 3268, 566, 553, 554, 555, 556, 557, 558, 559,
-	560, 561, 562, 563, 564, 568, 0, 567, 885, 569,
-	570, 571, 572, 573, 581, 583, 584, 579, 580, 582,
-	585, 586, 588, 589, 576, 577, 578, 886, 587, 574,
-	1387, 575, 344, 887, 590, 591, 592, 593, 1411, 1456,
-	594, 1472, 597, 598, 0, 0, 599, 0, 600, 0,
-	0, 602, 603, 604, 0, 0, 605, 606, 836, 888,
-	607, 889, 1487, 608, 609, 1398, 610, 611, 612, 613,
-	614, 615, 616, 617, 618, 619, 0, 620, 621, 838,
-	622, 623, 624, 839, 625, 626, 627, 1488, 628, 841,
-	629, 630, 0, 631, 632, 633, 0, 634, 635, 636,
-	637, 638, 639, 640, 641, 642, 643, 1467, 644, 645,
-	647, 646, 648, 649, 0, 650, 0, 651, 652, 653,
-	0, 0, 0, 0, 0, 654, 655, 657, 0, 658,
-	659, 660, 661, 662, 656, 663, 664, 665, 666, 667,
-	668, 669, 0, 671, 672, 670, 673, 674, 890, 675,
-	676, 677, 678, 679, 1399, 680, 0, 681, 682, 690,
-	691, 692, 683, 684, 686, 693, 685, 694, 695, 696,
-	3272, 699, 698, 0, 701, 702, 700, 703, 704, 705,
-	706, 1449, 707, 844, 708, 687, 688, 709, 710, 711,
-	891, 712, 713, 714, 715, 716, 717, 718, 719, 720,
-	1465, 0, 721, 0, 722, 723, 724, 725, 726, 727,
-	729, 689, 730, 731, 732, 737, 738, 1496, 733, 734,
-	735, 736, 1489, 740, 741, 742, 743, 0, 744, 745,
-	1384, 739, 728, 0, 746, 747, 748, 749, 750, 751,
-	752, 753, 754, 755, 0, 756, 1478, 1479, 1480, 1481,
-	0, 768, 0, 757, 759, 760, 761, 762, 1490, 763,
-	1491, 1409, 764, 765, 766, 767, 758, 769, 770, 0,
-	1391, 771, 772, 773, 774, 776, 778, 779, 780, 775,
-	777, 781, 1450, 782, 0, 0, 783, 784, 785, 854,
-	1475, 1495, 0, 787, 788, 786, 789, 790, 793, 791,
-	792, 857, 796, 513, 797, 798, 799, 794, 795, 0,
-	0, 0, 0, 800, 801, 858, 802, 3267, 804, 1388,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 1383, 0, 0, 0, 0,
-	0, 0, 1381, 1382, 0, 0, 0, 0, 0, 0,
-	864, 0, 1415, 0, 0, 0, 1413, 1460, 1403, 1404,
-	1405, 1401, 1402, 1414, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 345, 346, 348, 347, 349, 350,
-	351, 352, 3016, 353, 354, 0, 0, 0, 0, 0,
-	1452, 1419, 0, 0, 356, 0, 355, 0, 357, 358,
-	359, 874, 360, 361, 362, 363, 364, 365, 366, 367,
-	806, 1466, 0, 368, 1474, 369, 1473, 0, 1484, 370,
-	371, 372, 373, 374, 375, 376, 377, 378, 379, 1421,
-	1451, 1385, 380, 1497, 1498, 813, 0, 381, 382, 383,
-	384, 1458, 0, 1439, 0, 385, 386, 387, 388, 389,
-	390, 391, 392, 0, 0, 394, 395, 396, 393, 397,
-	398, 0, 399, 0, 400, 401, 402, 403, 404, 405,
-	406, 0, 407, 408, 409, 876, 410, 411, 412, 1442,
-	1440, 1441, 1448, 1444, 1443, 1447, 413, 414, 415, 416,
-	417, 1477, 418, 420, 421, 1471, 422, 1470, 1390, 425,
-	427, 419, 423, 0, 426, 424, 428, 429, 0, 430,
-	431, 432, 433, 0, 0, 434, 1469, 436, 0, 437,
-	438, 440, 439, 0, 441, 442, 443, 0, 444, 445,
-	1397, 446, 447, 448, 450, 452, 449, 451, 453, 454,
-	455, 456, 457, 1485, 1486, 458, 459, 1410, 340, 0,
-	0, 0, 0, 0, 460, 461, 462, 1468, 0, 0,
-	0, 463, 0, 465, 469, 466, 467, 468, 470, 0,
-	464, 471, 472, 0, 877, 473, 474, 475, 1482, 1483,
-	476, 477, 478, 479, 480, 481, 482, 483, 484, 0,
-	485, 486, 1492, 0, 1420, 487, 0, 488, 489, 490,
-	491, 492, 493, 494, 1453, 1454, 1457, 595, 879, 495,
-	496, 497, 0, 498, 499, 500, 501, 502, 503, 504,
-	0, 0, 0, 505, 506, 507, 508, 0, 867, 341,
-	343, 878, 828, 509, 596, 510, 1463, 1464, 0, 1424,
-	0, 511, 512, 515, 880, 1455, 881, 514, 516, 517,
-	882, 518, 0, 0, 0, 519, 520, 521, 522, 523,
-	524, 525, 0, 526, 528, 527, 0, 530, 1493, 529,
-	883, 531, 532, 884, 0, 533, 534, 535, 536, 537,
-	538, 541, 1446, 1445, 539, 540, 542, 543, 0, 544,
-	545, 547, 550, 546, 548, 549, 551, 552, 565, 566,
-	553, 554, 555, 556, 557, 558, 559, 560, 561, 562,
-	563, 564, 568, 0, 567, 885, 569, 570, 571, 572,
-	573, 581, 583, 584, 579, 580, 582, 585, 586, 588,
-	589, 576, 577, 578, 886, 587, 574, 1387, 575, 344,
-	887, 590, 591, 592, 593, 1411, 1456, 594, 1472, 597,
-	598, 0, 0, 599, 0, 600, 0, 0, 602, 603,
-	604, 0, 0, 605, 606, 836, 888, 607, 889, 1487,
-	608, 609, 1398, 610, 611, 612, 613, 614, 615, 616,
-	617, 618, 619, 0, 620, 621, 838, 622, 623, 624,
-	839, 625, 626, 627, 1488, 628, 841, 629, 630, 0,
-	631, 632, 633, 0, 634, 635, 636, 637, 638, 639,
-	640, 641, 642, 643, 1467, 644, 645, 647, 646, 648,
-	649, 0, 650, 0, 651, 652, 653, 0, 0, 0,
-	0, 0, 654, 655, 657, 0, 658, 659, 660, 661,
-	662, 656, 663, 664, 665, 666, 667, 668, 669, 0,
-	671, 672, 670, 673, 674, 890, 675, 676, 677, 678,
-	679, 1399, 680, 0, 681, 682, 690, 691, 692, 683,
-	684, 686, 693, 685, 694, 695, 696, 697, 699, 698,
-	0, 701, 702, 700, 703, 704, 705, 706, 1449, 707,
-	844, 708, 687, 688, 709, 710, 711, 891, 712, 713,
-	714, 715, 716, 717, 718, 719, 720, 1465, 0, 721,
-	0, 722, 723, 724, 725, 726, 727, 729, 689, 730,
-	731, 732, 737, 738, 1496, 733, 734, 735, 736, 1489,
-	740, 741, 742, 743, 0, 744, 745, 1384, 739, 728,
-	0, 746, 747, 748, 749, 750, 751, 752, 753, 754,
-	755, 0, 756, 1478, 1479, 1480, 1481, 0, 768, 0,
-	757, 759, 760, 761, 762, 1490, 763, 1491, 1409, 764,
-	765, 766, 767, 758, 769, 770, 0, 1391, 771, 772,
-	773, 774, 776, 778, 779, 780, 775, 777, 781, 1450,
-	782, 0, 0, 783, 784, 785, 854, 1475, 1495, 0,
-	787, 788, 786, 789, 790, 793, 791, 792, 857, 796,
-	513, 797, 798, 799, 794, 795, 0, 0, 0, 0,
-	800, 801, 858, 802, 803, 804, 1388, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 1383, 0, 0, 0, 0, 0, 0, 1381,
-	1382, 0, 0, 0, 0, 0, 0, 864, 0, 1415,
-	0, 0, 2690, 1413, 1460, 1403, 1404, 1405, 1401, 1402,
-	1414, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 345, 346, 348, 347, 349, 350, 351, 352, 0,
-	353, 354, 0, 0, 0, 0, 0, 1452, 1419, 0,
-	0, 356, 0, 355, 0, 357, 358, 359, 874, 360,
-	361, 362, 363, 364, 365, 366, 367, 806, 1466, 0,
-	368, 1474, 369, 1473, 0, 1484, 370, 371, 372, 373,
-	374, 375, 376, 377, 378, 379, 1421, 1451, 1385, 380,
-	1497, 1498, 813, 0, 381, 382, 383, 384, 1458, 0,
-	1439, 0, 385, 386, 387, 388, 389, 390, 391, 392,
-	0, 0, 394, 395, 396, 393, 397, 398, 0, 399,
-	0, 400, 401, 402, 403, 404, 405, 406, 0, 407,
-	408, 409, 876, 410, 411, 412, 1442, 1440, 1441, 1448,
-	1444, 1443, 1447, 413, 414, 415, 416, 417, 1477, 418,
-	420, 421, 1471, 422, 1470, 1390, 425, 427, 419, 423,
-	0, 426, 424, 428, 429, 0, 430, 431, 432, 433,
-	0, 0, 434, 1469, 436, 0, 437, 438, 440, 439,
-	0, 441, 442, 443, 0, 444, 445, 1397, 446, 447,
-	448, 450, 452, 449, 451, 453, 454, 455, 456, 457,
-	1485, 1486, 458, 459, 1410, 340, 0, 0, 0, 0,
-	0, 460, 461, 462, 1468, 0, 0, 0, 463, 0,
-	465, 469, 466, 467, 468, 470, 0, 464, 471, 472,
-	0, 877, 473, 474, 475, 1482, 1483, 476, 477, 478,
-	479, 480, 481, 482, 483, 484, 0, 485, 486, 1492,
-	0, 1420, 487, 0, 488, 489, 490, 491, 492, 493,
-	494, 1453, 1454, 1457, 595, 879, 495, 496, 497, 0,
-	498, 499, 500, 501, 502, 503, 504, 0, 0, 0,
-	505, 506, 507, 508, 0, 867, 341, 343, 878, 828,
-	509, 596, 510, 1463, 1464, 0, 1424, 0, 511, 512,
-	515, 880, 1455, 881, 514, 516, 517, 882, 518, 0,
-	0, 0, 519, 520, 521, 522, 523, 524, 525, 0,
-	526, 528, 527, 0, 530, 1493, 529, 883, 531, 532,
-	884, 0, 533, 534, 535, 536, 537, 538, 541, 1446,
-	1445, 539, 540, 542, 543, 0, 544, 545, 547, 550,
-	546, 548, 549, 551, 552, 565, 566, 553, 554, 555,
-	556, 557, 558, 559, 560, 561, 562, 563, 564, 568,
-	0, 567, 885, 569, 570, 571, 572, 573, 581, 583,
-	584, 579, 580, 582, 585, 586, 588, 589, 576, 577,
-	578, 886, 587, 574, 1387, 575, 344, 887, 590, 591,
-	592, 593, 1411, 1456, 594, 1472, 597, 598, 0, 0,
-	599, 0, 600, 0, 0, 602, 603, 604, 0, 0,
-	605, 606, 836, 888, 607, 889, 1487, 608, 609, 1398,
-	610, 611, 612, 613, 614, 615, 616, 617, 618, 619,
-	0, 620, 621, 838, 622, 623, 624, 839, 625, 626,
-	627, 1488, 628, 841, 629, 630, 0, 631, 632, 633,
-	0, 634, 635, 636, 637, 638, 639, 640, 641, 642,
-	643, 1467, 644, 645, 647, 646, 648, 649, 0, 650,
-	0, 651, 652, 653, 0, 0, 0, 0, 0, 654,
-	655, 657, 0, 658, 659, 660, 661, 662, 656, 663,
-	664, 665, 666, 667, 668, 669, 0, 671, 672, 670,
-	673, 674, 890, 675, 676, 677, 678, 679, 1399, 680,
-	0, 681, 682, 690, 691, 692, 683, 684, 686, 693,
-	685, 694, 695, 696, 697, 699, 698, 0, 701, 702,
-	700, 703, 704, 705, 706, 1449, 707, 844, 708, 687,
-	688, 709, 710, 711, 891, 712, 713, 714, 715, 716,
-	717, 718, 719, 720, 1465, 0, 721, 0, 722, 723,
-	724, 725, 726, 727, 729, 689, 730, 731, 732, 737,
-	738, 1496, 733, 734, 735, 736, 1489, 740, 741, 742,
-	743, 0, 744, 745, 1384, 739, 728, 0, 746, 747,
-	748, 749, 750, 751, 752, 753, 754, 755, 0, 756,
-	1478, 1479, 1480, 1481, 0, 768, 0, 757, 759, 760,
-	761, 762, 1490, 763, 1491, 1409, 764, 765, 766, 767,
-	758, 769, 770, 0, 1391, 771, 772, 773, 774, 776,
-	778, 779, 780, 775, 777, 781, 1450, 782, 0, 0,
-	783, 784, 785, 854, 1475, 1495, 0, 787, 788, 786,
-	789, 790, 793, 791, 792, 857, 796, 513, 797, 798,
-	799, 794, 795, 0, 0, 0, 0, 800, 801, 858,
-	802, 803, 804, 1388, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 1383,
-	0, 0, 0, 0, 0, 0, 1381, 1382, 0, 0,
-	0, 0, 0, 0, 864, 0, 1415, 0, 0, 2649,
-	1413, 1460, 1403, 1404, 1405, 1401, 1402, 1414, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 345, 346,
-	348, 347, 349, 350, 351, 352, 0, 353, 354, 0,
-	0, 0, 0, 0, 1452, 1419, 0, 0, 356, 0,
-	355, 0, 357, 358, 359, 874, 360, 361, 362, 363,
-	364, 365, 366, 367, 806, 1466, 0, 368, 1474, 369,
-	1473, 0, 1484, 370, 371, 372, 373, 374, 375, 376,
-	377, 378, 379, 1421, 1451, 1385, 380, 1497, 1498, 813,
-	0, 381, 382, 383, 384, 1458, 0, 1439, 0, 385,
-	386, 387, 388, 389, 390, 391, 392, 0, 0, 394,
-	395, 396, 393, 397, 398, 0, 399, 0, 400, 401,
-	402, 403, 404, 405, 406, 0, 407, 408, 409, 876,
-	410, 411, 412, 1442, 1440, 1441, 1448, 1444, 1443, 1447,
-	413, 414, 415, 416, 417, 1477, 418, 420, 421, 1471,
-	422, 1470, 1390, 425, 427, 419, 423, 0, 426, 424,
-	428, 429, 0, 430, 431, 432, 433, 0, 0, 434,
-	1469, 436, 0, 437, 438, 440, 439, 0, 441, 442,
-	443, 0, 444, 445, 1397, 446, 447, 448, 450, 452,
-	449, 451, 453, 454, 455, 456, 457, 1485, 1486, 458,
-	459, 1410, 340, 0, 0, 0, 0, 0, 460, 461,
-	462, 1468, 0, 0, 0, 463, 0, 465, 469, 466,
-	467, 468, 470, 0, 464, 471, 472, 0, 877, 473,
-	474, 475, 1482, 1483, 476, 477, 478, 479, 480, 481,
-	482, 483, 484, 0, 485, 486, 1492, 0, 1420, 487,
-	0, 488, 489, 490, 491, 492, 493, 494, 1453, 1454,
-	1457, 595, 879, 495, 496, 497, 0, 498, 499, 500,
-	501, 502, 503, 504, 0, 0, 0, 505, 506, 507,
-	508, 0, 867, 341, 343, 878, 828, 509, 596, 510,
-	1463, 1464, 0, 1424, 0, 511, 512, 515, 880, 1455,
-	881, 514, 516, 517, 882, 518, 0, 0, 0, 519,
-	520, 521, 522, 523, 524, 525, 0, 526, 528, 527,
-	0, 530, 1493, 529, 883, 531, 532, 884, 0, 533,
-	534, 535, 536, 537, 538, 541, 1446, 1445, 539, 540,
-	542, 543, 0, 544, 545, 547, 550, 546, 548, 549,
-	551, 552, 565, 566, 553, 554, 555, 556, 557, 558,
-	559, 560, 561, 562, 563, 564, 568, 0, 567, 885,
-	569, 570, 571, 572, 573, 581, 583, 584, 579, 580,
-	582, 585, 586, 588, 589, 576, 577, 578, 886, 587,
-	574, 1387, 575, 344, 887, 590, 591, 592, 593, 1411,
-	1456, 594, 1472, 597, 598, 0, 0, 599, 0, 600,
-	0, 0, 602, 603, 604, 0, 0, 605, 606, 836,
-	888, 607, 889, 1487, 608, 609, 1398, 610, 611, 612,
-	613, 614, 615, 616, 617, 618, 619, 0, 620, 621,
-	838, 622, 623, 624, 839, 625, 626, 627, 1488, 628,
-	841, 629, 630, 0, 631, 632, 633, 0, 634, 635,
-	636, 637, 638, 639, 640, 641, 642, 643, 1467, 644,
-	645, 647, 646, 648, 649, 0, 650, 0, 651, 652,
-	653, 0, 0, 0, 0, 0, 654, 655, 657, 0,
-	658, 659, 660, 661, 662, 656, 663, 664, 665, 666,
-	667, 668, 669, 0, 671, 672, 670, 673, 674, 890,
-	675, 676, 677, 678, 679, 1399, 680, 0, 681, 682,
-	690, 691, 692, 683, 684, 686, 693, 685, 694, 695,
-	696, 697, 699, 698, 0, 701, 702, 700, 703, 704,
-	705, 706, 1449, 707, 844, 708, 687, 688, 709, 710,
-	711, 891, 712, 713, 714, 715, 716, 717, 718, 719,
-	720, 1465, 0, 721, 0, 722, 723, 724, 725, 726,
-	727, 729, 689, 730, 731, 732, 737, 738, 1496, 733,
-	734, 735, 736, 1489, 740, 741, 742, 743, 0, 744,
-	745, 1384, 739, 728, 0, 746, 747, 748, 749, 750,
-	751, 752, 753, 754, 755, 0, 756, 1478, 1479, 1480,
-	1481, 0, 768, 0, 757, 759, 760, 761, 762, 1490,
-	763, 1491, 1409, 764, 765, 766, 767, 758, 769, 770,
-	0, 1391, 771, 772, 773, 774, 776, 778, 779, 780,
-	775, 777, 781, 1450, 782, 0, 0, 783, 784, 785,
-	854, 1475, 1495, 0, 787, 788, 786, 789, 790, 793,
-	791, 792, 857, 796, 513, 797, 798, 799, 794, 795,
-	0, 0, 0, 0, 800, 801, 858, 802, 803, 804,
-	1388, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 1383, 0, 0, 0,
-	0, 0, 0, 1381, 1382, 0, 0, 0, 0, 0,
-	0, 864, 0, 1415, 0, 0, 2149, 1413, 1460, 1403,
-	1404, 1405, 1401, 1402, 1414, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 345, 346, 348, 347, 349,
-	350, 351, 352, 0, 353, 354, 0, 0, 0, 0,
-	0, 1452, 1419, 0, 0, 356, 0, 355, 0, 357,
-	358, 359, 874, 360, 361, 362, 363, 364, 365, 366,
-	367, 806, 1466, 0, 368, 1474, 369, 1473, 0, 1484,
-	370, 371, 372, 373, 374, 375, 376, 377, 378, 379,
-	1421, 1451, 1385, 380, 1497, 1498, 813, 0, 381, 382,
-	383, 384, 1458, 0, 1439, 0, 385, 386, 387, 388,
-	389, 390, 391, 392, 0, 0, 394, 395, 396, 393,
-	397, 398, 0, 399, 0, 400, 401, 402, 403, 404,
-	405, 406, 0, 407, 408, 409, 876, 410, 411, 412,
-	1442, 1440, 1441, 1448, 1444, 1443, 1447, 413, 414, 415,
-	416, 417, 1477, 418, 420, 421, 1471, 422, 1470, 1390,
-	425, 427, 419, 423, 0, 426, 424, 428, 429, 0,
-	430, 431, 432, 433, 0, 0, 434, 1469, 436, 0,
-	437, 438, 440, 439, 0, 441, 442, 443, 0, 444,
-	445, 1397, 446, 447, 448, 450, 452, 449, 451, 453,
-	454, 455, 456, 457, 1485, 1486, 458, 459, 1410, 340,
-	0, 0, 0, 0, 0, 460, 461, 462, 1468, 0,
-	0, 0, 463, 0, 465, 469, 466, 467, 468, 470,
-	0, 464, 471, 472, 0, 877, 473, 474, 475, 1482,
-	1483, 476, 477, 478, 479, 480, 481, 482, 483, 484,
-	0, 485, 486, 1492, 0, 1420, 487, 0, 488, 489,
-	490, 491, 492, 493, 494, 1453, 1454, 1457, 595, 879,
-	495, 496, 497, 0, 498, 499, 500, 501, 502, 503,
-	504, 0, 0, 0, 505, 506, 507, 508, 0, 867,
-	341, 343, 878, 828, 509, 596, 510, 1463, 1464, 0,
-	1424, 0, 511, 512, 515, 880, 1455, 881, 514, 516,
-	517, 882, 518, 0, 0, 0, 519, 520, 521, 522,
-	523, 524, 525, 0, 526, 528, 527, 0, 530, 1493,
-	529, 883, 531, 532, 884, 0, 533, 534, 535, 536,
-	537, 538, 541, 1446, 1445, 539, 540, 542, 543, 0,
-	544, 545, 547, 550, 546, 548, 549, 551, 552, 565,
-	566, 553, 554, 555, 556, 557, 558, 559, 560, 561,
-	562, 563, 564, 568, 0, 567, 885, 569, 570, 571,
-	572, 573, 581, 583, 584, 579, 580, 582, 585, 586,
-	588, 589, 576, 577, 578, 886, 587, 574, 1387, 575,
-	344, 887, 590, 591, 592, 593, 1411, 1456, 594, 1472,
-	597, 598, 0, 0, 599, 0, 600, 0, 0, 602,
-	603, 604, 0, 0, 605, 606, 836, 888, 607, 889,
-	1487, 608, 609, 1398, 610, 611, 612, 613, 614, 615,
-	616, 617, 618, 619, 0, 620, 621, 838, 622, 623,
-	624, 839, 625, 626, 627, 1488, 628, 841, 629, 630,
-	0, 631, 632, 633, 0, 634, 635, 636, 637, 638,
-	639, 640, 641, 642, 643, 1467, 644, 645, 647, 646,
-	648, 649, 0, 650, 0, 651, 652, 653, 0, 0,
-	0, 0, 0, 654, 655, 657, 0, 658, 659, 660,
-	661, 662, 656, 663, 664, 665, 666, 667, 668, 669,
-	0, 671, 672, 670, 673, 674, 890, 675, 676, 677,
-	678, 679, 1399, 680, 0, 681, 682, 690, 691, 692,
-	683, 684, 686, 693, 685, 694, 695, 696, 697, 699,
-	698, 0, 701, 702, 700, 703, 704, 705, 706, 1449,
-	707, 844, 708, 687, 688, 709, 710, 711, 891, 712,
-	713, 714, 715, 716, 717, 718, 719, 720, 1465, 0,
-	721, 0, 722, 723, 724, 725, 726, 727, 729, 689,
-	730, 731, 732, 737, 738, 1496, 733, 734, 735, 736,
-	1489, 740, 741, 742, 743, 0, 744, 745, 1384, 739,
-	728, 0, 746, 747, 748, 749, 750, 751, 752, 753,
-	754, 755, 0, 756, 1478, 1479, 1480, 1481, 0, 768,
-	0, 757, 759, 760, 761, 762, 1490, 763, 1491, 1409,
-	764, 765, 766, 767, 758, 769, 770, 0, 1391, 771,
-	772, 773, 774, 776, 778, 779, 780, 775, 777, 781,
-	1450, 782, 0, 0, 783, 784, 785, 854, 1475, 1495,
-	0, 787, 788, 786, 789, 790, 793, 791, 792, 857,
-	796, 513, 797, 798, 799, 794, 795, 0, 0, 0,
-	0, 800, 801, 858, 802, 803, 804, 1388, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 1383, 0, 0, 0, 0, 0, 0,
-	1381, 1382, 0, 0, 0, 0, 0, 0, 864, 0,
-	1415, 0, 0, 2144, 1413, 1460, 1403, 1404, 1405, 1401,
-	1402, 1414, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 345, 346, 348, 347, 349, 350, 351, 352,
-	0, 353, 354, 0, 0, 0, 0, 0, 1452, 1419,
-	0, 0, 356, 0, 355, 0, 357, 358, 359, 874,
-	360, 361, 362, 363, 364, 365, 366, 367, 806, 1466,
-	0, 368, 1474, 369, 1473, 0, 1484, 370, 371, 372,
-	373, 374, 375, 376, 377, 378, 379, 1421, 1451, 1385,
-	380, 1497, 1498, 813, 0, 381, 382, 383, 384, 1458,
-	0, 1439, 0, 385, 386, 387, 388, 389, 390, 391,
-	392, 0, 0, 394, 395, 396, 393, 397, 398, 0,
-	399, 0, 400, 401, 402, 403, 404, 405, 406, 0,
-	407, 408, 409, 876, 410, 411, 412, 1442, 1440, 1441,
-	1448, 1444, 1443, 1447, 413, 414, 415, 416, 417, 1477,
-	418, 420, 421, 1471, 422, 1470, 1390, 425, 427, 419,
-	423, 0, 426, 424, 428, 429, 0, 430, 431, 432,
-	433, 0, 0, 434, 1469, 436, 0, 437, 438, 440,
-	439, 0, 441, 442, 443, 0, 444, 445, 1397, 446,
-	447, 448, 450, 452, 449, 451, 453, 454, 455, 456,
-	457, 1485, 1486, 458, 459, 1410, 340, 0, 0, 0,
-	0, 0, 460, 461, 462, 1468, 0, 0, 0, 463,
-	0, 465, 469, 466, 467, 468, 470, 0, 464, 471,
-	472, 0, 877, 473, 474, 475, 1482, 1483, 476, 477,
-	478, 479, 480, 481, 482, 483, 484, 0, 485, 486,
-	1492, 0, 1420, 487, 0, 488, 489, 490, 491, 492,
-	493, 494, 1453, 1454, 1457, 595, 879, 495, 496, 497,
-	0, 498, 499, 500, 501, 502, 503, 504, 0, 0,
-	0, 505, 506, 507, 508, 0, 867, 341, 343, 878,
-	828, 509, 596, 510, 1463, 1464, 0, 1424, 0, 511,
-	512, 515, 880, 1455, 881, 514, 516, 517, 882, 518,
-	0, 0, 0, 519, 520, 521, 522, 523, 524, 525,
-	0, 526, 528, 527, 0, 530, 1493, 529, 883, 531,
-	532, 884, 0, 533, 534, 535, 536, 537, 538, 541,
-	1446, 1445, 539, 540, 542, 543, 0, 544, 545, 547,
-	550, 546, 548, 549, 551, 552, 565, 566, 553, 554,
-	555, 556, 557, 558, 559, 560, 561, 562, 563, 564,
-	568, 0, 567, 885, 569, 570, 571, 572, 573, 581,
-	583, 584, 579, 580, 582, 585, 586, 588, 589, 576,
-	577, 578, 886, 587, 574, 1387, 575, 344, 887, 590,
-	591, 592, 593, 1411, 1456, 594, 1472, 597, 598, 0,
-	0, 599, 0, 600, 0, 0, 602, 603, 604, 0,
-	0, 605, 606, 836, 888, 607, 889, 1487, 608, 609,
-	1398, 610, 611, 612, 613, 614, 615, 616, 617, 618,
-	619, 0, 620, 621, 838, 622, 623, 624, 839, 625,
-	626, 627, 1488, 628, 841, 629, 630, 0, 631, 632,
-	633, 0, 634, 635, 636, 637, 638, 639, 640, 641,
-	642, 643, 1467, 644, 645, 647, 646, 648, 649, 0,
-	650, 0, 651, 652, 653, 0, 0, 0, 0, 0,
-	654, 655, 657, 0, 658, 659, 660, 661, 662, 656,
-	663, 664, 665, 666, 667, 668, 669, 0, 671, 672,
-	670, 673, 674, 890, 675, 676, 677, 678, 679, 1399,
-	680, 0, 681, 682, 690, 691, 692, 683, 684, 686,
-	693, 685, 694, 695, 696, 697, 699, 698, 0, 701,
-	702, 700, 703, 704, 705, 706, 1449, 707, 844, 708,
-	687, 688, 709, 710, 711, 891, 712, 713, 714, 715,
-	716, 717, 718, 719, 720, 1465, 0, 721, 0, 722,
-	723, 724, 725, 726, 727, 729, 689, 730, 731, 732,
-	737, 738, 1496, 733, 734, 735, 736, 1489, 740, 741,
-	742, 743, 0, 744, 745, 1384, 739, 728, 0, 746,
-	747, 748, 749, 750, 751, 752, 753, 754, 755, 0,
-	756, 1478, 1479, 1480, 1481, 0, 768, 0, 757, 759,
-	760, 761, 762, 1490, 763, 1491, 1409, 764, 765, 766,
-	767, 758, 769, 770, 0, 1391, 771, 772, 773, 774,
-	776, 778, 779, 780, 775, 777, 781, 1450, 782, 0,
-	0, 783, 784, 785, 854, 1475, 1495, 0, 787, 788,
-	786, 789, 790, 793, 791, 792, 857, 796, 513, 797,
-	798, 799, 794, 795, 0, 0, 0, 0, 800, 801,
-	858, 802, 803, 804, 1388, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	1383, 0, 0, 0, 0, 0, 0, 1381, 1382, 0,
-	0, 0, 0, 0, 0, 864, 0, 1415, 0, 0,
-	2130, 1413, 1460, 1403, 1404, 1405, 1401, 1402, 1414, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 345,
-	346, 348, 347, 349, 350, 351, 352, 0, 353, 354,
-	0, 0, 0, 0, 0, 1452, 1419, 0, 0, 356,
-	0, 355, 0, 357, 358, 359, 874, 360, 361, 362,
-	363, 364, 365, 366, 367, 806, 1466, 0, 368, 1474,
-	369, 1473, 0, 1484, 370, 371, 372, 373, 374, 375,
-	376, 377, 378, 379, 1421, 1451, 1385, 380, 1497, 1498,
-	813, 0, 381, 382, 383, 384, 1458, 0, 1439, 0,
-	385, 386, 387, 388, 389, 390, 391, 392, 0, 0,
-	394, 395, 396, 393, 397, 398, 0, 399, 0, 400,
-	401, 402, 403, 404, 405, 406, 0, 407, 408, 409,
-	876, 410, 411, 412, 1442, 1440, 1441, 1448, 1444, 1443,
-	1447, 413, 414, 415, 416, 417, 1477, 418, 420, 421,
-	1471, 422, 1470, 1390, 425, 427, 419, 423, 0, 426,
-	424, 428, 429, 0, 430, 431, 432, 433, 0, 0,
-	434, 1469, 436, 0, 437, 438, 440, 439, 0, 441,
-	442, 443, 0, 444, 445, 1397, 446, 447, 448, 450,
-	452, 449, 451, 453, 454, 455, 456, 457, 1485, 1486,
-	458, 459, 1410, 340, 0, 0, 0, 0, 0, 460,
-	461, 462, 1468, 0, 0, 0, 463, 0, 465, 469,
-	466, 467, 468, 470, 0, 464, 471, 472, 0, 877,
-	473, 474, 475, 1482, 1483, 476, 477, 478, 479, 480,
-	481, 482, 483, 484, 0, 485, 486, 1492, 0, 1420,
-	487, 0, 488, 489, 490, 491, 492, 493, 494, 1453,
-	1454, 1457, 595, 879, 495, 496, 497, 0, 498, 499,
-	500, 501, 502, 503, 504, 0, 0, 0, 505, 506,
-	507, 508, 0, 867, 341, 343, 878, 828, 509, 596,
-	510, 1463, 1464, 0, 1424, 0, 511, 512, 515, 880,
-	1455, 881, 514, 516, 517, 882, 518, 0, 0, 0,
-	519, 520, 521, 522, 523, 524, 525, 0, 526, 528,
-	527, 0, 530, 1493, 529, 883, 531, 532, 884, 0,
-	533, 534, 535, 536, 537, 538, 541, 1446, 1445, 539,
-	540, 542, 543, 0, 544, 545, 547, 550, 546, 548,
-	549, 551, 552, 565, 566, 553, 554, 555, 556, 557,
-	558, 559, 560, 561, 562, 563, 564, 568, 0, 567,
-	885, 569, 570, 571, 572, 573, 581, 583, 584, 579,
-	580, 582, 585, 586, 588, 589, 576, 577, 578, 886,
-	587, 574, 1387, 575, 344, 887, 590, 591, 592, 593,
-	1411, 1456, 594, 1472, 597, 598, 0, 0, 599, 0,
-	600, 0, 0, 602, 603, 604, 0, 0, 605, 606,
-	836, 888, 607, 889, 1487, 608, 609, 1398, 610, 611,
-	612, 613, 614, 615, 616, 617, 618, 619, 0, 620,
-	621, 838, 622, 623, 624, 839, 625, 626, 627, 1488,
-	628, 841, 629, 630, 0, 631, 632, 633, 0, 634,
-	635, 636, 637, 638, 639, 640, 641, 642, 643, 1467,
-	644, 645, 647, 646, 648, 649, 0, 650, 0, 651,
-	652, 653, 0, 0, 0, 0, 0, 654, 655, 657,
-	0, 658, 659, 660, 661, 662, 656, 663, 664, 665,
-	666, 667, 668, 669, 0, 671, 672, 670, 673, 674,
-	890, 675, 676, 677, 678, 679, 1399, 680, 0, 681,
-	682, 690, 691, 692, 683, 684, 686, 693, 685, 694,
-	695, 696, 697, 699, 698, 0, 701, 702, 700, 703,
-	704, 705, 706, 1449, 707, 844, 708, 687, 688, 709,
-	710, 711, 891, 712, 713, 714, 715, 716, 717, 718,
-	719, 720, 1465, 0, 721, 0, 722, 723, 724, 725,
-	726, 727, 729, 689, 730, 731, 732, 737, 738, 1496,
-	733, 734, 735, 736, 1489, 740, 741, 742, 743, 0,
-	744, 745, 1384, 739, 728, 0, 746, 747, 748, 749,
-	750, 751, 752, 753, 754, 755, 0, 756, 1478, 1479,
-	1480, 1481, 0, 768, 0, 757, 759, 760, 761, 762,
-	1490, 763, 1491, 1409, 764, 765, 766, 767, 758, 769,
-	770, 0, 1391, 771, 772, 773, 774, 776, 778, 779,
-	780, 775, 777, 781, 1450, 782, 0, 0, 783, 784,
-	785, 854, 1475, 1495, 0, 787, 788, 786, 789, 790,
-	793, 791, 792, 857, 796, 513, 797, 798, 799, 794,
-	795, 0, 0, 0, 0, 800, 801, 858, 802, 803,
-	804, 1388, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 1383, 0, 0,
-	0, 0, 0, 0, 1381, 1382, 0, 0, 0, 0,
-	0, 0, 864, 0, 1415, 0, 0, 2125, 1413, 1460,
-	1403, 1404, 1405, 1401, 1402, 1414, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 345, 346, 348, 347,
-	349, 350, 351, 352, 0, 353, 354, 0, 0, 0,
-	0, 0, 1452, 1419, 0, 0, 356, 0, 355, 0,
-	357, 358, 359, 874, 360, 361, 362, 363, 364, 365,
-	366, 367, 806, 1466, 0, 368, 1474, 369, 1473, 0,
-	1484, 370, 371, 372, 373, 374, 375, 376, 377, 378,
-	379, 1421, 1451, 1385, 380, 1497, 1498, 813, 0, 381,
-	382, 383, 384, 1458, 0, 1439, 0, 385, 386, 387,
-	388, 389, 390, 391, 392, 0, 0, 394, 395, 396,
-	393, 397, 398, 0, 399, 0, 400, 401, 402, 403,
-	404, 405, 406, 0, 407, 408, 409, 876, 410, 411,
-	412, 1442, 1440, 1441, 1448, 1444, 1443, 1447, 413, 414,
-	415, 416, 417, 1477, 418, 420, 421, 1471, 422, 1470,
-	1390, 425, 427, 419, 423, 0, 426, 424, 428, 429,
-	0, 430, 431, 432, 433, 0, 0, 434, 1469, 436,
-	0, 437, 438, 440, 439, 0, 441, 442, 443, 0,
-	444, 445, 1397, 446, 447, 448, 450, 452, 449, 451,
-	453, 454, 455, 456, 457, 1485, 1486, 458, 459, 1410,
-	340, 0, 0, 0, 0, 0, 460, 461, 462, 1468,
-	0, 0, 0, 463, 0, 465, 469, 466, 467, 468,
-	470, 0, 464, 471, 472, 0, 877, 473, 474, 475,
-	1482, 1483, 476, 477, 478, 479, 480, 481, 482, 483,
-	484, 0, 485, 486, 1492, 0, 1420, 487, 0, 488,
-	489, 490, 491, 492, 493, 494, 1453, 1454, 1457, 595,
-	879, 495, 496, 497, 0, 498, 499, 500, 501, 502,
-	503, 504, 0, 0, 0, 505, 506, 507, 508, 0,
-	867, 341, 343, 878, 828, 509, 596, 510, 1463, 1464,
-	0, 1424, 0, 511, 512, 515, 880, 1455, 881, 514,
-	516, 517, 882, 518, 0, 0, 0, 519, 520, 521,
-	522, 523, 524, 525, 0, 526, 528, 527, 0, 530,
-	1493, 529, 883, 531, 532, 884, 0, 533, 534, 535,
-	536, 537, 538, 541, 1446, 1445, 539, 540, 542, 543,
-	0, 544, 545, 547, 550, 546, 548, 549, 551, 552,
-	565, 566, 553, 554, 555, 556, 557, 558, 559, 560,
-	561, 562, 563, 564, 568, 0, 567, 885, 569, 570,
-	571, 572, 573, 581, 583, 584, 579, 580, 582, 585,
-	586, 588, 589, 576, 577, 578, 886, 587, 574, 1387,
-	575, 344, 887, 590, 591, 592, 593, 1411, 1456, 594,
-	1472, 597, 598, 0, 0, 599, 0, 600, 0, 0,
-	602, 603, 604, 0, 0, 605, 606, 836, 888, 607,
-	889, 1487, 608, 609, 1398, 610, 611, 612, 613, 614,
-	615, 616, 617, 618, 619, 0, 620, 621, 838, 622,
-	623, 624, 839, 625, 626, 627, 1488, 628, 841, 629,
-	630, 0, 631, 632, 633, 0, 634, 635, 636, 637,
-	638, 639, 640, 641, 642, 643, 1467, 644, 645, 647,
-	646, 648, 649, 0, 650, 0, 651, 652, 653, 0,
-	0, 0, 0, 0, 654, 655, 657, 0, 658, 659,
-	660, 661, 662, 656, 663, 664, 665, 666, 667, 668,
-	669, 0, 671, 672, 670, 673, 674, 890, 675, 676,
-	677, 678, 679, 1399, 680, 0, 681, 682, 690, 691,
-	692, 683, 684, 686, 693, 685, 694, 695, 696, 697,
-	699, 698, 0, 701, 702, 700, 703, 704, 705, 706,
-	1449, 707, 844, 708, 687, 688, 709, 710, 711, 891,
-	712, 713, 714, 715, 716, 717, 718, 719, 720, 1465,
-	0, 721, 0, 722, 723, 724, 725, 726, 727, 729,
-	689, 730, 731, 732, 737, 738, 1496, 733, 734, 735,
-	736, 1489, 740, 741, 742, 743, 0, 744, 745, 1384,
-	739, 728, 0, 746, 747, 748, 749, 750, 751, 752,
-	753, 754, 755, 0, 756, 1478, 1479, 1480, 1481, 0,
-	768, 0, 757, 759, 760, 761, 762, 1490, 763, 1491,
-	1409, 764, 765, 766, 767, 758, 769, 770, 0, 1391,
-	771, 772, 773, 774, 776, 778, 779, 780, 775, 777,
-	781, 1450, 782, 0, 0, 783, 784, 785, 854, 1475,
-	1495, 0, 787, 788, 786, 789, 790, 793, 791, 792,
-	857, 796, 513, 797, 798, 799, 794, 795, 0, 0,
-	0, 0, 800, 801, 858, 802, 803, 804, 1388, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 1383, 0, 0, 0, 0, 0,
-	0, 1381, 1382, 0, 0, 0, 0, 0, 0, 864,
-	0, 1415, 0, 0, 2026, 1413, 1460, 1403, 1404, 1405,
-	1401, 1402, 1414, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 345, 346, 348, 347, 349, 350, 351,
-	352, 0, 353, 354, 0, 0, 0, 0, 0, 1452,
-	1419, 0, 0, 356, 0, 355, 0, 357, 358, 359,
-	874, 360, 361, 362, 363, 364, 365, 366, 367, 806,
-	1466, 0, 368, 1474, 369, 1473, 0, 1484, 370, 371,
-	372, 373, 374, 375, 376, 377, 378, 379, 1421, 1451,
-	1385, 380, 1497, 1498, 813, 0, 381, 382, 383, 384,
-	1458, 0, 1439, 0, 385, 386, 387, 388, 389, 390,
-	391, 392, 0, 0, 394, 395, 396, 393, 397, 398,
-	0, 399, 0, 400, 401, 402, 403, 404, 405, 406,
-	0, 407, 408, 409, 876, 410, 411, 412, 1442, 1440,
-	1441, 1448, 1444, 1443, 1447, 413, 414, 415, 416, 417,
-	1477, 418, 420, 421, 1471, 422, 1470, 1390, 425, 427,
-	419, 423, 0, 426, 424, 428, 429, 0, 430, 431,
-	432, 433, 0, 0, 434, 1469, 436, 0, 437, 438,
-	440, 439, 0, 441, 442, 443, 0, 444, 445, 1397,
-	446, 447, 448, 450, 452, 449, 451, 453, 454, 455,
-	456, 457, 1485, 1486, 458, 459, 1410, 340, 0, 0,
-	0, 0, 0, 460, 461, 462, 1468, 0, 0, 0,
-	463, 0, 465, 469, 466, 467, 468, 470, 0, 464,
-	471, 472, 0, 877, 473, 474, 475, 1482, 1483, 476,
-	477, 478, 479, 480, 481, 482, 483, 484, 0, 485,
-	486, 1492, 0, 1420, 487, 0, 488, 489, 490, 491,
-	492, 493, 494, 2025, 1454, 1457, 595, 879, 495, 496,
-	497, 0, 498, 499, 500, 501, 502, 503, 504, 0,
-	0, 0, 505, 506, 507, 508, 0, 867, 341, 343,
-	878, 828, 509, 596, 510, 1463, 1464, 0, 1424, 0,
-	511, 512, 515, 880, 1455, 881, 514, 516, 517, 882,
-	518, 0, 0, 0, 519, 520, 521, 522, 523, 524,
-	525, 0, 526, 528, 527, 0, 530, 1493, 529, 883,
-	531, 532, 884, 0, 533, 534, 535, 536, 537, 538,
-	541, 1446, 1445, 539, 540, 542, 543, 0, 544, 545,
-	547, 550, 546, 548, 549, 551, 552, 565, 566, 553,
-	554, 555, 556, 557, 558, 559, 560, 561, 562, 563,
-	564, 568, 0, 567, 885, 569, 570, 571, 572, 573,
-	581, 583, 584, 579, 580, 582, 585, 586, 588, 589,
-	576, 577, 578, 886, 587, 574, 1387, 575, 344, 887,
-	590, 591, 592, 593, 1411, 1456, 594, 1472, 597, 598,
-	0, 0, 599, 0, 600, 0, 0, 602, 603, 604,
-	0, 0, 605, 606, 836, 888, 607, 889, 1487, 608,
-	609, 1398, 610, 611, 612, 613, 614, 615, 616, 617,
-	618, 619, 0, 620, 621, 838, 622, 623, 624, 839,
-	625, 626, 627, 1488, 628, 841, 629, 630, 0, 631,
-	632, 633, 0, 634, 635, 636, 637, 638, 639, 640,
-	641, 642, 643, 1467, 644, 645, 647, 646, 648, 649,
-	0, 650, 0, 651, 652, 653, 0, 0, 0, 0,
-	0, 654, 655, 657, 0, 658, 659, 660, 661, 662,
-	656, 663, 664, 665, 666, 667, 668, 669, 0, 671,
-	672, 670, 673, 674, 890, 675, 676, 677, 678, 679,
-	1399, 680, 0, 681, 682, 690, 691, 692, 683, 684,
-	686, 693, 685, 694, 695, 696, 697, 699, 698, 0,
-	701, 702, 700, 703, 704, 705, 706, 1449, 707, 844,
-	708, 687, 688, 709, 710, 711, 891, 712, 713, 714,
-	715, 716, 717, 718, 719, 720, 1465, 0, 721, 0,
-	722, 723, 724, 725, 726, 727, 729, 689, 730, 731,
-	732, 737, 738, 1496, 733, 734, 735, 736, 1489, 740,
-	741, 742, 743, 0, 744, 745, 1384, 739, 728, 0,
-	746, 747, 748, 749, 750, 751, 752, 753, 754, 755,
-	0, 756, 1478, 1479, 1480, 1481, 0, 768, 0, 757,
-	759, 760, 761, 762, 1490, 763, 1491, 1409, 764, 765,
-	766, 767, 758, 769, 770, 0, 1391, 771, 772, 773,
-	774, 776, 778, 779, 780, 775, 777, 781, 1450, 782,
-	0, 0, 783, 784, 785, 854, 1475, 1495, 0, 787,
-	788, 786, 789, 790, 793, 791, 792, 857, 796, 513,
-	797, 798, 799, 794, 795, 0, 0, 0, 0, 800,
-	801, 858, 802, 803, 804, 1388, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 1383, 0, 0, 0, 0, 0, 0, 1381, 1382,
-	0, 0, 0, 0, 0, 0, 864, 0, 1415, 0,
-	0, 2020, 1413, 1460, 1403, 1404, 1405, 1401, 1402, 1414,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	345, 346, 348, 347, 349, 350, 351, 352, 0, 353,
-	354, 0, 0, 0, 0, 0, 1452, 1419, 0, 0,
-	356, 0, 355, 0, 357, 358, 359, 874, 360, 361,
-	362, 363, 364, 365, 366, 367, 806, 1466, 0, 368,
-	1474, 369, 1473, 0, 1484, 370, 371, 372, 373, 374,
-	375, 376, 377, 378, 379, 1421, 1451, 1385, 380, 1497,
-	1498, 813, 0, 381, 382, 383, 384, 1458, 0, 1439,
-	0, 385, 386, 387, 388, 389, 390, 391, 392, 0,
-	0, 394, 395, 396, 393, 397, 398, 0, 399, 0,
-	400, 401, 402, 403, 404, 405, 406, 0, 407, 408,
-	409, 876, 410, 411, 412, 1442, 1440, 1441, 1448, 1444,
-	1443, 1447, 413, 414, 415, 416, 417, 1477, 418, 420,
-	421, 1471, 422, 1470, 1390, 425, 427, 419, 423, 0,
-	426, 424, 428, 429, 0, 430, 431, 432, 433, 0,
-	0, 434, 1469, 436, 0, 437, 438, 440, 439, 0,
-	441, 442, 443, 0, 444, 445, 1397, 446, 447, 448,
-	450, 452, 449, 451, 453, 454, 455, 456, 457, 1485,
-	1486, 458, 459, 1410, 340, 0, 0, 0, 0, 0,
-	460, 461, 462, 1468, 0, 0, 0, 463, 0, 465,
-	469, 466, 467, 468, 470, 0, 464, 471, 472, 0,
-	877, 473, 474, 475, 1482, 1483, 476, 477, 478, 479,
-	480, 481, 482, 483, 484, 0, 485, 486, 1492, 0,
-	1420, 487, 0, 488, 489, 490, 491, 492, 493, 494,
-	2019, 1454, 1457, 595, 879, 495, 496, 497, 0, 498,
-	499, 500, 501, 502, 503, 504, 0, 0, 0, 505,
-	506, 507, 508, 0, 867, 341, 343, 878, 828, 509,
-	596, 510, 1463, 1464, 0, 1424, 0, 511, 512, 515,
-	880, 1455, 881, 514, 516, 517, 882, 518, 0, 0,
-	0, 519, 520, 521, 522, 523, 524, 525, 0, 526,
-	528, 527, 0, 530, 1493, 529, 883, 531, 532, 884,
-	0, 533, 534, 535, 536, 537, 538, 541, 1446, 1445,
-	539, 540, 542, 543, 0, 544, 545, 547, 550, 546,
-	548, 549, 551, 552, 565, 566, 553, 554, 555, 556,
-	557, 558, 559, 560, 561, 562, 563, 564, 568, 0,
-	567, 885, 569, 570, 571, 572, 573, 581, 583, 584,
-	579, 580, 582, 585, 586, 588, 589, 576, 577, 578,
-	886, 587, 574, 1387, 575, 344, 887, 590, 591, 592,
-	593, 1411, 1456, 594, 1472, 597, 598, 0, 0, 599,
-	0, 600, 0, 0, 602, 603, 604, 0, 0, 605,
-	606, 836, 888, 607, 889, 1487, 608, 609, 1398, 610,
-	611, 612, 613, 614, 615, 616, 617, 618, 619, 0,
-	620, 621, 838, 622, 623, 624, 839, 625, 626, 627,
-	1488, 628, 841, 629, 630, 0, 631, 632, 633, 0,
-	634, 635, 636, 637, 638, 639, 640, 641, 642, 643,
-	1467, 644, 645, 647, 646, 648, 649, 0, 650, 0,
-	651, 652, 653, 0, 0, 0, 0, 0, 654, 655,
-	657, 0, 658, 659, 660, 661, 662, 656, 663, 664,
-	665, 666, 667, 668, 669, 0, 671, 672, 670, 673,
-	674, 890, 675, 676, 677, 678, 679, 1399, 680, 0,
-	681, 682, 690, 691, 692, 683, 684, 686, 693, 685,
-	694, 695, 696, 697, 699, 698, 0, 701, 702, 700,
-	703, 704, 705, 706, 1449, 707, 844, 708, 687, 688,
-	709, 710, 711, 891, 712, 713, 714, 715, 716, 717,
-	718, 719, 720, 1465, 0, 721, 0, 722, 723, 724,
-	725, 726, 727, 729, 689, 730, 731, 732, 737, 738,
-	1496, 733, 734, 735, 736, 1489, 740, 741, 742, 743,
-	0, 744, 745, 1384, 739, 728, 0, 746, 747, 748,
-	749, 750, 751, 752, 753, 754, 755, 0, 756, 1478,
-	1479, 1480, 1481, 0, 768, 0, 757, 759, 760, 761,
-	762, 1490, 763, 1491, 1409, 764, 765, 766, 767, 758,
-	769, 770, 0, 1391, 771, 772, 773, 774, 776, 778,
-	779, 780, 775, 777, 781, 1450, 782, 0, 0, 783,
-	784, 785, 854, 1475, 1495, 0, 787, 788, 786, 789,
-	790, 793, 791, 792, 857, 796, 513, 797, 798, 799,
-	794, 795, 0, 0, 0, 0, 800, 801, 858, 802,
-	803, 804, 1388, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 1383, 0,
-	0, 0, 0, 0, 0, 1381, 1382, 0, 0, 0,
-	0, 0, 0, 864, 0, 1415, 0, 0, 2014, 1413,
-	1460, 1403, 1404, 1405, 1401, 1402, 1414, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 345, 346, 348,
-	347, 349, 350, 351, 352, 0, 353, 354, 0, 0,
-	0, 0, 0, 1452, 1419, 0, 0, 356, 0, 355,
-	0, 357, 358, 359, 874, 360, 361, 362, 363, 364,
-	365, 366, 367, 806, 1466, 0, 368, 1474, 369, 1473,
-	0, 1484, 370, 371, 372, 373, 374, 375, 376, 377,
-	378, 379, 1421, 1451, 1385, 380, 1497, 1498, 813, 0,
-	381, 382, 383, 384, 1458, 0, 1439, 0, 385, 386,
-	387, 388, 389, 390, 391, 392, 0, 0, 394, 395,
-	396, 393, 397, 398, 0, 399, 0, 400, 401, 402,
-	403, 404, 405, 406, 0, 407, 408, 409, 876, 410,
-	411, 412, 1442, 1440, 1441, 1448, 1444, 1443, 1447, 413,
-	414, 415, 416, 417, 1477, 418, 420, 421, 1471, 422,
-	1470, 1390, 425, 427, 419, 423, 0, 426, 424, 428,
-	429, 0, 430, 431, 432, 433, 0, 0, 434, 1469,
-	436, 0, 437, 438, 440, 439, 0, 441, 442, 443,
-	0, 444, 445, 1397, 446, 447, 448, 450, 452, 449,
-	451, 453, 454, 455, 456, 457, 1485, 1486, 458, 459,
-	1410, 340, 0, 0, 0, 0, 0, 460, 461, 462,
-	1468, 0, 0, 0, 463, 0, 465, 469, 466, 467,
-	468, 470, 0, 464, 471, 472, 0, 877, 473, 474,
-	475, 1482, 1483, 476, 477, 478, 479, 480, 481, 482,
-	483, 484, 0, 485, 486, 1492, 0, 1420, 487, 0,
-	488, 489, 490, 491, 492, 493, 494, 1453, 1454, 1457,
-	595, 879, 495, 496, 497, 0, 498, 499, 500, 501,
-	502, 503, 504, 0, 0, 0, 505, 506, 507, 508,
-	0, 867, 341, 343, 878, 828, 509, 596, 510, 1463,
-	1464, 0, 1424, 0, 511, 512, 515, 880, 1455, 881,
-	514, 516, 517, 882, 518, 0, 0, 0, 519, 520,
-	521, 522, 523, 524, 525, 0, 526, 528, 527, 0,
-	530, 1493, 529, 883, 531, 532, 884, 0, 533, 534,
-	535, 536, 537, 538, 541, 1446, 1445, 539, 540, 542,
-	543, 0, 544, 545, 547, 550, 546, 548, 549, 551,
-	552, 565, 566, 553, 554, 555, 556, 557, 558, 559,
-	560, 561, 562, 563, 564, 568, 0, 567, 885, 569,
-	570, 571, 572, 573, 581, 583, 584, 579, 580, 582,
-	585, 586, 588, 589, 576, 577, 578, 886, 587, 574,
-	1387, 575, 344, 887, 590, 591, 592, 593, 1411, 1456,
-	594, 1472, 597, 598, 0, 0, 599, 0, 600, 0,
-	0, 602, 603, 604, 0, 0, 605, 606, 836, 888,
-	607, 889, 1487, 608, 609, 1398, 610, 611, 612, 613,
-	614, 615, 616, 617, 618, 619, 0, 620, 621, 838,
-	622, 623, 624, 839, 625, 626, 627, 1488, 628, 841,
-	629, 630, 0, 631, 632, 633, 0, 634, 635, 636,
-	637, 638, 639, 640, 641, 642, 643, 1467, 644, 645,
-	647, 646, 648, 649, 0, 650, 0, 651, 652, 653,
-	0, 0, 0, 0, 0, 654, 655, 657, 0, 658,
-	659, 660, 661, 662, 656, 663, 664, 665, 666, 667,
-	668, 669, 0, 671, 672, 670, 673, 674, 890, 675,
-	676, 677, 678, 679, 1399, 680, 0, 681, 682, 690,
-	691, 692, 683, 684, 686, 693, 685, 694, 695, 696,
-	697, 699, 698, 0, 701, 702, 700, 703, 704, 705,
-	706, 1449, 707, 844, 708, 687, 688, 709, 710, 711,
-	891, 712, 713, 714, 715, 716, 717, 718, 719, 720,
-	1465, 0, 721, 0, 722, 723, 724, 725, 726, 727,
-	729, 689, 730, 731, 732, 737, 738, 1496, 733, 734,
-	735, 736, 1489, 740, 741, 742, 743, 0, 744, 745,
-	1384, 739, 728, 0, 746, 747, 748, 749, 750, 751,
-	752, 753, 754, 755, 0, 756, 1478, 1479, 1480, 1481,
-	0, 768, 0, 757, 759, 760, 761, 762, 1490, 763,
-	1491, 1409, 764, 765, 766, 767, 758, 769, 770, 0,
-	1391, 771, 772, 773, 774, 776, 778, 779, 780, 775,
-	777, 781, 1450, 782, 0, 0, 783, 784, 785, 854,
-	1475, 1495, 0, 787, 788, 786, 789, 790, 793, 791,
-	792, 857, 796, 513, 797, 798, 799, 794, 795, 0,
-	0, 0, 0, 800, 801, 858, 802, 803, 804, 1388,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 1383, 0, 0, 0, 0,
-	0, 0, 1381, 1382, 0, 0, 0, 0, 0, 0,
-	864, 0, 1415, 0, 0, 1987, 1413, 1460, 1403, 1404,
-	1405, 1401, 1402, 1414, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 345, 346, 348, 347, 349, 350,
-	351, 352, 0, 353, 354, 0, 0, 0, 0, 0,
-	1452, 1419, 0, 0, 356, 0, 355, 0, 357, 358,
-	359, 874, 360, 361, 362, 363, 364, 365, 366, 367,
-	806, 1466, 0, 368, 1474, 369, 1473, 0, 1484, 370,
-	371, 372, 373, 374, 375, 376, 377, 378, 379, 1421,
-	1451, 1385, 380, 1497, 1498, 813, 0, 381, 382, 383,
-	384, 1458, 0, 1439, 0, 385, 386, 387, 388, 389,
-	390, 391, 392, 0, 0, 394, 395, 396, 393, 397,
-	398, 0, 399, 0, 400, 401, 402, 403, 404, 405,
-	406, 0, 407, 408, 409, 876, 410, 411, 412, 1442,
-	1440, 1441, 1448, 1444, 1443, 1447, 413, 414, 415, 416,
-	417, 1477, 418, 420, 421, 1471, 422, 1470, 1390, 425,
-	427, 419, 423, 0, 426, 424, 428, 429, 0, 430,
-	431, 432, 433, 0, 0, 434, 1469, 436, 0, 437,
-	438, 440, 439, 0, 441, 442, 443, 0, 444, 445,
-	1397, 446, 447, 448, 450, 452, 449, 451, 453, 454,
-	455, 456, 457, 1485, 1486, 458, 459, 1410, 340, 0,
-	0, 0, 0, 0, 460, 461, 462, 1468, 0, 0,
-	0, 463, 0, 465, 469, 466, 467, 468, 470, 0,
-	464, 471, 472, 0, 877, 473, 474, 475, 1482, 1483,
-	476, 477, 478, 479, 480, 481, 482, 483, 484, 0,
-	485, 486, 1492, 0, 1420, 487, 0, 488, 489, 490,
-	491, 492, 493, 494, 1453, 1454, 1457, 595, 879, 495,
-	496, 497, 0, 498, 499, 500, 501, 502, 503, 504,
-	0, 0, 0, 505, 506, 507, 508, 0, 867, 341,
-	343, 878, 828, 509, 596, 510, 1463, 1464, 0, 1424,
-	0, 511, 512, 515, 880, 1455, 881, 514, 516, 517,
-	882, 518, 0, 0, 0, 519, 520, 521, 522, 523,
-	524, 525, 0, 526, 528, 527, 0, 530, 1493, 529,
-	883, 531, 532, 884, 0, 533, 534, 535, 536, 537,
-	538, 541, 1446, 1445, 539, 540, 542, 543, 0, 544,
-	545, 547, 550, 546, 548, 549, 551, 552, 565, 566,
-	553, 554, 555, 556, 557, 558, 559, 560, 561, 562,
-	563, 564, 568, 0, 567, 885, 569, 570, 571, 572,
-	573, 581, 583, 584, 579, 580, 582, 585, 586, 588,
-	589, 576, 577, 578, 886, 587, 574, 1387, 575, 344,
-	887, 590, 591, 592, 593, 1411, 1456, 594, 1472, 597,
-	598, 0, 0, 599, 0, 600, 0, 0, 602, 603,
-	604, 0, 0, 605, 606, 836, 888, 607, 889, 1487,
-	608, 609, 1398, 610, 611, 612, 613, 614, 615, 616,
-	617, 618, 619, 0, 620, 621, 838, 622, 623, 624,
-	839, 625, 626, 627, 1488, 628, 841, 629, 630, 0,
-	631, 632, 633, 0, 634, 635, 636, 637, 638, 639,
-	640, 641, 642, 643, 1467, 644, 645, 647, 646, 648,
-	649, 0, 650, 0, 651, 652, 653, 0, 0, 0,
-	0, 0, 654, 655, 657, 0, 658, 659, 660, 661,
-	662, 656, 663, 664, 665, 666, 667, 668, 669, 0,
-	671, 672, 670, 673, 674, 890, 675, 676, 677, 678,
-	679, 1399, 680, 0, 681, 682, 690, 691, 692, 683,
-	684, 686, 693, 685, 694, 695, 696, 697, 699, 698,
-	0, 701, 702, 700, 703, 704, 705, 706, 1449, 707,
-	844, 708, 687, 688, 709, 710, 711, 891, 712, 713,
-	714, 715, 716, 717, 718, 719, 720, 1465, 0, 721,
-	0, 722, 723, 724, 725, 726, 727, 729, 689, 730,
-	731, 732, 737, 738, 1496, 733, 734, 735, 736, 1489,
-	740, 741, 742, 743, 0, 744, 745, 1384, 739, 728,
-	0, 746, 747, 748, 749, 750, 751, 752, 753, 754,
-	755, 0, 756, 1478, 1479, 1480, 1481, 0, 768, 0,
-	757, 759, 760, 761, 762, 1490, 763, 1491, 1409, 764,
-	765, 766, 767, 758, 769, 770, 0, 1391, 771, 772,
-	773, 774, 776, 778, 779, 780, 775, 777, 781, 1450,
-	782, 0, 0, 783, 784, 785, 854, 1475, 1495, 0,
-	787, 788, 786, 789, 790, 793, 791, 792, 857, 796,
-	513, 797, 798, 799, 794, 795, 0, 0, 0, 0,
-	800, 801, 858, 802, 803, 804, 1388, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 1383, 0, 0, 0, 0, 0, 0, 1381,
-	1382, 0, 0, 0, 0, 0, 0, 864, 0, 1415,
-	0, 0, 1967, 1413, 1460, 1403, 1404, 1405, 1401, 1402,
-	1414, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 345, 346, 348, 347, 349, 350, 351, 352, 0,
-	353, 354, 0, 0, 0, 0, 0, 1452, 1419, 0,
-	0, 356, 0, 355, 0, 357, 358, 359, 874, 360,
-	361, 362, 363, 364, 365, 366, 367, 806, 1466, 0,
-	368, 1474, 369, 1473, 0, 1484, 370, 371, 372, 373,
-	374, 375, 376, 377, 378, 379, 1421, 1451, 1385, 380,
-	1497, 1498, 813, 0, 381, 382, 383, 384, 1458, 0,
-	1439, 0, 385, 386, 387, 388, 389, 390, 391, 392,
-	0, 0, 394, 395, 396, 393, 397, 398, 0, 399,
-	0, 400, 401, 402, 403, 404, 405, 406, 0, 407,
-	408, 409, 876, 410, 411, 412, 1442, 1440, 1441, 1448,
-	1444, 1443, 1447, 413, 414, 415, 416, 417, 1477, 418,
-	420, 421, 1471, 422, 1470, 1390, 425, 427, 419, 423,
-	0, 426, 424, 428, 429, 0, 430, 431, 432, 433,
-	0, 0, 434, 1469, 436, 0, 437, 438, 440, 439,
-	0, 441, 442, 443, 0, 444, 445, 1397, 446, 447,
-	448, 450, 452, 449, 1971, 453, 454, 455, 456, 457,
-	1485, 1486, 458, 459, 1410, 340, 0, 0, 0, 0,
-	0, 460, 461, 462, 1468, 0, 0, 0, 463, 0,
-	465, 469, 466, 467, 468, 470, 0, 464, 471, 472,
-	0, 877, 473, 474, 475, 1482, 1483, 476, 477, 478,
-	479, 480, 481, 482, 483, 484, 0, 485, 486, 1492,
-	0, 1420, 487, 0, 488, 489, 490, 491, 492, 493,
-	494, 1453, 1454, 1457, 595, 879, 495, 496, 497, 0,
-	498, 499, 500, 501, 502, 503, 504, 0, 0, 0,
-	505, 506, 507, 508, 0, 867, 341, 343, 878, 828,
-	509, 596, 510, 1463, 1464, 0, 1424, 0, 511, 512,
-	515, 880, 1455, 881, 514, 516, 517, 882, 518, 0,
-	0, 0, 519, 520, 521, 522, 523, 524, 525, 0,
-	526, 528, 527, 0, 530, 1493, 529, 883, 531, 532,
-	884, 0, 533, 534, 535, 536, 537, 538, 541, 1446,
-	1445, 539, 540, 542, 543, 0, 544, 545, 547, 550,
-	546, 548, 549, 551, 552, 565, 566, 553, 554, 555,
-	556, 557, 558, 559, 560, 561, 562, 563, 564, 568,
-	0, 567, 885, 569, 570, 571, 572, 573, 581, 583,
-	584, 579, 580, 582, 585, 586, 588, 589, 576, 577,
-	578, 886, 587, 574, 1387, 575, 344, 887, 590, 591,
-	592, 593, 1411, 1456, 594, 1472, 597, 598, 0, 0,
-	599, 0, 600, 0, 0, 602, 603, 604, 0, 0,
-	605, 606, 836, 888, 607, 889, 1487, 608, 609, 1398,
-	610, 611, 612, 613, 614, 615, 616, 617, 618, 619,
-	0, 620, 621, 838, 622, 623, 624, 839, 625, 626,
-	627, 1488, 628, 841, 629, 630, 0, 631, 632, 633,
-	0, 634, 635, 636, 637, 638, 639, 640, 641, 642,
-	643, 1467, 644, 645, 647, 646, 648, 649, 0, 650,
-	0, 651, 652, 653, 0, 0, 0, 0, 0, 654,
-	655, 1972, 0, 658, 659, 660, 661, 662, 656, 663,
-	664, 665, 666, 667, 668, 669, 0, 671, 672, 670,
-	673, 674, 890, 675, 676, 677, 678, 679, 1399, 680,
-	0, 681, 682, 690, 691, 692, 683, 684, 686, 693,
-	685, 694, 695, 696, 697, 699, 698, 0, 701, 702,
-	700, 703, 704, 705, 706, 1449, 707, 844, 708, 687,
-	688, 709, 710, 711, 891, 712, 713, 714, 715, 716,
-	717, 718, 719, 720, 1465, 0, 721, 0, 722, 723,
-	724, 725, 726, 727, 729, 689, 730, 731, 732, 737,
-	738, 1496, 733, 734, 735, 736, 1489, 740, 741, 742,
-	743, 0, 744, 745, 1384, 739, 728, 0, 746, 747,
-	748, 749, 750, 751, 752, 753, 1970, 755, 0, 756,
-	1478, 1479, 1480, 1481, 0, 768, 0, 757, 759, 760,
-	761, 762, 1490, 763, 1491, 1409, 764, 765, 766, 767,
-	758, 769, 770, 0, 1391, 771, 772, 773, 774, 776,
-	778, 779, 780, 775, 777, 781, 1450, 782, 0, 0,
-	783, 784, 785, 854, 1475, 1495, 0, 787, 788, 786,
-	789, 790, 793, 791, 792, 857, 796, 513, 797, 798,
-	799, 794, 795, 0, 0, 0, 0, 800, 801, 858,
-	802, 803, 804, 1388, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 1383,
-	0, 0, 0, 0, 0, 0, 1381, 1382, 0, 0,
-	0, 0, 0, 0, 864, 0, 1415, 0, 0, 1793,
-	1413, 1460, 1403, 1404, 1405, 1401, 1402, 1414, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 345, 346,
-	348, 347, 349, 350, 351, 352, 0, 353, 354, 0,
-	0, 0, 0, 0, 1452, 1419, 0, 0, 356, 0,
-	355, 0, 357, 358, 359, 874, 360, 361, 362, 363,
-	364, 365, 366, 367, 806, 1466, 0, 368, 1474, 369,
-	1473, 0, 1484, 370, 371, 372, 373, 374, 375, 376,
-	377, 378, 379, 1421, 1451, 1385, 380, 1497, 1498, 813,
-	0, 381, 382, 383, 384, 1458, 0, 1439, 0, 385,
-	386, 387, 388, 389, 390, 391, 392, 0, 0, 394,
-	395, 396, 393, 397, 398, 0, 399, 0, 400, 401,
-	402, 403, 404, 405, 406, 0, 407, 408, 409, 876,
-	410, 411, 412, 1442, 1440, 1441, 1448, 1444, 1443, 1447,
-	413, 414, 415, 416, 417, 1477, 418, 420, 421, 1471,
-	422, 1470, 1390, 425, 427, 419, 423, 0, 426, 424,
-	428, 429, 0, 430, 431, 432, 433, 0, 0, 434,
-	1469, 436, 0, 437, 438, 440, 439, 0, 441, 442,
-	443, 0, 444, 445, 1397, 446, 447, 448, 450, 452,
-	449, 451, 453, 454, 455, 456, 457, 1485, 1486, 458,
-	459, 1410, 340, 0, 0, 0, 0, 0, 460, 461,
-	462, 1468, 0, 0, 0, 463, 0, 465, 469, 466,
-	467, 468, 470, 0, 464, 471, 472, 0, 877, 473,
-	474, 475, 1482, 1483, 476, 477, 478, 479, 480, 481,
-	482, 483, 484, 0, 485, 486, 1492, 0, 1420, 487,
-	0, 488, 489, 490, 491, 492, 493, 494, 1453, 1454,
-	1457, 595, 879, 495, 496, 497, 0, 498, 499, 500,
-	501, 502, 503, 504, 0, 0, 0, 505, 506, 507,
-	508, 0, 867, 341, 343, 878, 828, 509, 596, 510,
-	1463, 1464, 0, 1424, 0, 511, 512, 515, 880, 1455,
-	881, 514, 516, 517, 882, 518, 0, 0, 0, 519,
-	520, 521, 522, 523, 524, 525, 0, 526, 528, 527,
-	0, 530, 1493, 529, 883, 531, 532, 884, 0, 533,
-	534, 535, 536, 537, 538, 541, 1446, 1445, 539, 540,
-	542, 543, 0, 544, 545, 547, 550, 546, 548, 549,
-	551, 552, 565, 566, 553, 554, 555, 556, 557, 558,
-	559, 560, 561, 562, 563, 564, 568, 0, 567, 885,
-	569, 570, 571, 572, 573, 581, 583, 584, 579, 580,
-	582, 585, 586, 588, 589, 576, 577, 578, 886, 587,
-	574, 1387, 575, 344, 887, 590, 591, 592, 593, 1411,
-	1456, 594, 1472, 597, 598, 0, 0, 599, 0, 600,
-	0, 0, 602, 603, 604, 0, 0, 605, 606, 836,
-	888, 607, 889, 1487, 608, 609, 1398, 610, 611, 612,
-	613, 614, 615, 616, 617, 618, 619, 0, 620, 621,
-	838, 622, 623, 624, 839, 625, 626, 627, 1488, 628,
-	841, 629, 630, 0, 631, 632, 633, 0, 634, 635,
-	636, 637, 638, 639, 640, 641, 642, 643, 1467, 644,
-	645, 647, 646, 648, 649, 0, 650, 0, 651, 652,
-	653, 0, 0, 0, 0, 0, 654, 655, 657, 0,
-	658, 659, 660, 661, 662, 656, 663, 664, 665, 666,
-	667, 668, 669, 0, 671, 672, 670, 673, 674, 890,
-	675, 676, 677, 678, 679, 1399, 680, 0, 681, 682,
-	690, 691, 692, 683, 684, 686, 693, 685, 694, 695,
-	696, 697, 699, 698, 0, 701, 702, 700, 703, 704,
-	705, 706, 1449, 707, 844, 708, 687, 688, 709, 710,
-	711, 891, 712, 713, 714, 715, 716, 717, 718, 719,
-	720, 1465, 0, 721, 0, 722, 723, 724, 725, 726,
-	727, 729, 689, 730, 731, 732, 737, 738, 1496, 733,
-	734, 735, 736, 1489, 740, 741, 742, 743, 0, 744,
-	745, 1384, 739, 728, 0, 746, 747, 748, 749, 750,
-	751, 752, 753, 754, 755, 0, 756, 1478, 1479, 1480,
-	1481, 0, 768, 0, 757, 759, 760, 761, 762, 1490,
-	763, 1491, 1409, 764, 765, 766, 767, 758, 769, 770,
-	0, 1391, 771, 772, 773, 774, 776, 778, 779, 780,
-	775, 777, 781, 1450, 782, 0, 0, 783, 784, 785,
-	854, 1475, 1495, 0, 787, 788, 786, 789, 790, 793,
-	791, 792, 857, 796, 513, 797, 798, 799, 794, 795,
-	0, 0, 0, 0, 800, 801, 858, 802, 803, 804,
-	1388, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 1383, 0, 0, 0,
-	0, 0, 0, 1381, 1382, 0, 0, 0, 0, 0,
-	0, 864, 0, 1415, 0, 0, 1645, 1413, 1460, 1403,
-	1404, 1405, 1401, 1402, 1414, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 345, 346, 348, 347, 349,
-	350, 351, 352, 0, 353, 354, 0, 0, 0, 0,
-	0, 1452, 1419, 0, 0, 356, 0, 355, 0, 357,
-	358, 359, 874, 360, 361, 362, 363, 364, 365, 366,
-	367, 806, 1466, 0, 368, 1474, 369, 1473, 0, 1484,
-	370, 371, 372, 373, 374, 375, 376, 377, 378, 379,
-	1421, 1451, 1385, 380, 1497, 1498, 813, 0, 381, 382,
-	383, 384, 1458, 0, 1439, 0, 385, 386, 387, 388,
-	389, 390, 391, 392, 0, 0, 394, 395, 396, 393,
-	397, 398, 0, 399, 0, 400, 401, 402, 403, 404,
-	405, 406, 0, 407, 408, 409, 876, 410, 411, 412,
-	1442, 1440, 1441, 1448, 1444, 1443, 1447, 413, 414, 415,
-	416, 417, 1477, 418, 420, 421, 1471, 422, 1470, 1390,
-	425, 427, 419, 423, 0, 426, 424, 428, 429, 0,
-	430, 431, 432, 433, 0, 0, 434, 1469, 436, 0,
-	437, 438, 440, 439, 0, 441, 442, 443, 0, 444,
-	445, 1397, 446, 447, 448, 450, 452, 449, 451, 453,
-	454, 455, 456, 457, 1485, 1486, 458, 459, 1410, 340,
-	0, 0, 0, 0, 0, 460, 461, 462, 1468, 0,
-	0, 0, 463, 0, 465, 469, 466, 467, 468, 470,
-	0, 464, 471, 472, 0, 877, 473, 474, 475, 1482,
-	1483, 476, 477, 478, 479, 480, 481, 482, 483, 484,
-	0, 485, 486, 1492, 0, 1420, 487, 0, 488, 489,
-	490, 491, 492, 493, 494, 1453, 1454, 1457, 595, 879,
-	495, 496, 497, 0, 498, 499, 500, 501, 502, 503,
-	504, 0, 0, 0, 505, 506, 507, 508, 0, 867,
-	341, 343, 878, 828, 509, 596, 510, 1463, 1464, 0,
-	1424, 0, 511, 512, 515, 880, 1455, 881, 514, 516,
-	517, 882, 518, 0, 0, 0, 519, 520, 521, 522,
-	523, 524, 525, 0, 526, 528, 527, 0, 530, 1493,
-	529, 883, 531, 532, 884, 0, 533, 534, 535, 536,
-	537, 538, 541, 1446, 1445, 539, 540, 542, 543, 0,
-	544, 545, 547, 550, 546, 548, 549, 551, 552, 565,
-	566, 553, 554, 555, 556, 557, 558, 559, 560, 561,
-	562, 563, 564, 568, 0, 567, 885, 569, 570, 571,
-	572, 573, 581, 583, 584, 579, 580, 582, 585, 586,
-	588, 589, 576, 577, 578, 886, 587, 574, 1387, 575,
-	344, 887, 590, 591, 592, 593, 1411, 1456, 594, 1472,
-	597, 598, 0, 0, 599, 0, 600, 0, 0, 602,
-	603, 604, 0, 0, 605, 606, 836, 888, 607, 889,
-	1487, 608, 609, 1398, 610, 611, 612, 613, 614, 615,
-	616, 617, 618, 619, 0, 620, 621, 838, 622, 623,
-	624, 839, 625, 626, 627, 1488, 628, 841, 629, 630,
-	0, 631, 632, 633, 0, 634, 635, 636, 637, 638,
-	639, 640, 641, 642, 643, 1467, 644, 645, 647, 646,
-	648, 649, 0, 650, 0, 651, 652, 653, 0, 0,
-	0, 0, 0, 654, 655, 657, 0, 658, 659, 660,
-	661, 662, 656, 663, 664, 665, 666, 667, 668, 669,
-	0, 671, 672, 670, 673, 674, 890, 675, 676, 677,
-	678, 679, 1399, 680, 0, 681, 682, 690, 691, 692,
-	683, 684, 686, 693, 685, 694, 695, 696, 697, 699,
-	698, 0, 701, 702, 700, 703, 704, 705, 706, 1449,
-	707, 844, 708, 687, 688, 709, 710, 711, 891, 712,
-	713, 714, 715, 716, 717, 718, 719, 720, 1465, 0,
-	721, 0, 722, 723, 724, 725, 726, 727, 729, 689,
-	730, 731, 732, 737, 738, 1496, 733, 734, 735, 736,
-	1489, 740, 741, 742, 743, 0, 744, 745, 1384, 739,
-	728, 0, 746, 747, 748, 749, 750, 751, 752, 753,
-	754, 755, 0, 756, 1478, 1479, 1480, 1481, 0, 768,
-	0, 757, 759, 760, 761, 762, 1490, 763, 1491, 1409,
-	764, 765, 766, 767, 758, 769, 770, 0, 1391, 771,
-	772, 773, 774, 776, 778, 779, 780, 775, 777, 781,
-	1450, 782, 0, 0, 783, 784, 785, 854, 1475, 1495,
-	0, 787, 788, 786, 789, 790, 793, 791, 792, 857,
-	796, 513, 797, 798, 799, 794, 795, 0, 0, 0,
-	0, 800, 801, 858, 802, 803, 804, 1388, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 1383, 0, 0, 0, 0, 0, 0,
-	1381, 1382, 0, 0, 0, 0, 0, 0, 864, 0,
-	1415, 0, 0, 0, 1413, 1460, 1403, 1404, 1405, 1401,
-	1402, 1414, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 345, 346, 348, 347, 349, 350, 351, 352,
-	0, 353, 354, 0, 0, 0, 0, 0, 1452, 1419,
-	0, 0, 356, 0, 355, 0, 357, 358, 359, 874,
-	360, 361, 362, 363, 364, 365, 366, 367, 806, 1466,
-	0, 368, 1474, 369, 1473, 0, 1484, 370, 371, 372,
-	373, 374, 375, 376, 377, 378, 379, 1421, 1451, 1385,
-	380, 1497, 1498, 813, 0, 381, 382, 383, 384, 1458,
-	0, 1439, 0, 385, 386, 387, 388, 389, 390, 391,
-	392, 0, 0, 394, 395, 396, 393, 397, 398, 0,
-	399, 0, 400, 401, 402, 403, 404, 405, 406, 0,
-	407, 408, 409, 876, 410, 411, 412, 1442, 1440, 1441,
-	1448, 1444, 1443, 1447, 413, 414, 415, 416, 417, 1477,
-	418, 420, 421, 1471, 422, 1470, 1390, 425, 427, 419,
-	423, 0, 426, 424, 428, 429, 0, 430, 431, 432,
-	433, 0, 0, 434, 1469, 436, 0, 437, 438, 440,
-	439, 0, 441, 442, 443, 0, 444, 445, 1397, 446,
-	447, 448, 450, 452, 449, 451, 453, 454, 455, 456,
-	457, 1485, 1486, 458, 459, 1410, 340, 0, 0, 0,
-	0, 0, 460, 461, 462, 1468, 0, 0, 0, 463,
-	0, 465, 469, 466, 467, 468, 470, 0, 464, 471,
-	472, 0, 877, 473, 474, 475, 1482, 1483, 476, 477,
-	478, 479, 480, 481, 482, 483, 484, 0, 485, 486,
-	1492, 0, 1420, 487, 0, 488, 489, 490, 491, 492,
-	493, 494, 1453, 1454, 1457, 595, 879, 495, 496, 497,
-	0, 498, 499, 500, 501, 502, 503, 504, 0, 0,
-	0, 505, 506, 507, 508, 0, 867, 341, 343, 878,
-	828, 509, 596, 510, 1463, 1464, 0, 1424, 0, 511,
-	512, 515, 880, 1455, 881, 514, 516, 517, 882, 518,
-	0, 0, 0, 519, 520, 521, 522, 523, 524, 525,
-	0, 526, 528, 527, 0, 530, 1493, 529, 883, 531,
-	532, 884, 0, 533, 534, 535, 536, 537, 538, 541,
-	1446, 1445, 539, 540, 542, 543, 0, 544, 545, 547,
-	550, 546, 548, 549, 551, 552, 565, 566, 553, 554,
-	555, 556, 557, 558, 559, 560, 561, 562, 563, 564,
-	568, 0, 567, 885, 569, 570, 571, 572, 573, 581,
-	583, 584, 579, 580, 582, 585, 586, 588, 589, 576,
-	577, 578, 886, 587, 574, 1387, 575, 344, 887, 590,
-	591, 592, 593, 1411, 1456, 594, 1472, 597, 598, 0,
-	0, 599, 0, 600, 0, 0, 602, 603, 604, 0,
-	0, 605, 606, 836, 888, 607, 889, 1487, 608, 609,
-	1398, 610, 611, 612, 613, 614, 615, 616, 617, 618,
-	619, 0, 620, 621, 838, 622, 623, 624, 839, 625,
-	626, 627, 1488, 628, 841, 629, 630, 0, 631, 632,
-	633, 0, 634, 635, 636, 637, 638, 639, 640, 641,
-	642, 643, 1467, 644, 645, 647, 646, 648, 649, 0,
-	650, 0, 651, 652, 653, 0, 0, 0, 0, 0,
-	654, 655, 657, 0, 658, 659, 660, 661, 662, 656,
-	663, 664, 665, 666, 667, 668, 669, 0, 671, 672,
-	670, 673, 674, 890, 675, 676, 677, 678, 679, 1399,
-	680, 0, 681, 682, 690, 691, 692, 683, 684, 686,
-	693, 685, 694, 695, 696, 697, 699, 698, 0, 701,
-	702, 700, 703, 704, 705, 706, 1449, 707, 844, 708,
-	687, 688, 709, 710, 711, 891, 712, 713, 714, 715,
-	716, 717, 718, 719, 720, 1465, 0, 721, 0, 722,
-	723, 724, 725, 726, 727, 729, 689, 730, 731, 732,
-	737, 738, 1496, 733, 734, 735, 736, 1489, 740, 741,
-	742, 743, 0, 744, 745, 1384, 739, 728, 0, 746,
-	747, 748, 749, 750, 751, 752, 753, 754, 755, 0,
-	756, 1478, 1479, 1480, 1481, 0, 768, 0, 757, 759,
-	760, 761, 762, 1490, 763, 1491, 1409, 764, 765, 766,
-	767, 758, 769, 770, 0, 1391, 771, 772, 773, 774,
-	776, 778, 779, 780, 775, 777, 781, 1450, 782, 0,
-	0, 783, 784, 785, 854, 1475, 1495, 0, 787, 788,
-	786, 789, 790, 793, 791, 792, 857, 796, 513, 797,
-	798, 799, 794, 795, 0, 0, 0, 0, 800, 801,
-	858, 802, 803, 804, 1388, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	1383, 0, 0, 0, 0, 0, 0, 1381, 1382, 0,
-	0, 0, 0, 0, 0, 864, 0, 1415, 0, 0,
-	0, 1413, 1460, 1403, 1404, 1405, 1401, 1402, 1414, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 345,
-	346, 348, 347, 349, 350, 351, 352, 0, 353, 354,
-	0, 0, 0, 0, 0, 1452, 1419, 0, 0, 356,
-	0, 355, 0, 357, 358, 359, 874, 360, 361, 362,
-	363, 364, 365, 366, 367, 806, 1466, 0, 368, 1474,
-	369, 1473, 0, 1484, 370, 371, 372, 373, 374, 375,
-	376, 377, 378, 379, 1421, 1451, 1385, 380, 1497, 1498,
-	813, 0, 381, 382, 383, 384, 1458, 0, 1439, 0,
-	385, 386, 387, 388, 389, 390, 391, 392, 0, 0,
-	394, 395, 396, 393, 397, 398, 0, 399, 0, 400,
-	401, 402, 403, 404, 405, 406, 0, 407, 408, 409,
-	876, 410, 411, 6577, 1442, 1440, 1441, 1448, 1444, 1443,
-	1447, 413, 414, 415, 416, 417, 1477, 418, 420, 421,
-	1471, 422, 1470, 1390, 425, 427, 419, 423, 0, 426,
-	424, 428, 429, 0, 430, 431, 432, 433, 0, 0,
-	434, 1469, 436, 0, 437, 438, 440, 439, 0, 441,
-	442, 443, 0, 444, 445, 1397, 446, 447, 448, 450,
-	452, 449, 451, 453, 454, 455, 456, 457, 1485, 1486,
-	458, 459, 1410, 340, 0, 0, 0, 0, 0, 460,
-	461, 462, 1468, 0, 0, 0, 463, 0, 465, 469,
-	466, 467, 468, 470, 0, 464, 471, 472, 0, 877,
-	473, 474, 475, 1482, 1483, 476, 477, 478, 479, 480,
-	481, 482, 483, 484, 0, 485, 486, 1492, 0, 1420,
-	487, 0, 488, 489, 490, 491, 492, 493, 494, 1453,
-	1454, 1457, 595, 879, 495, 496, 497, 0, 498, 499,
-	500, 501, 502, 503, 504, 0, 0, 0, 505, 506,
-	507, 508, 0, 867, 341, 343, 878, 828, 509, 596,
-	510, 1463, 1464, 0, 1424, 0, 511, 512, 515, 880,
-	1455, 881, 514, 516, 517, 882, 518, 0, 0, 0,
-	519, 520, 521, 522, 523, 524, 525, 0, 526, 528,
-	527, 0, 530, 1493, 529, 883, 531, 532, 884, 0,
-	533, 534, 535, 536, 537, 538, 541, 1446, 1445, 539,
-	540, 542, 543, 0, 544, 545, 547, 550, 546, 548,
-	549, 551, 552, 565, 566, 553, 554, 555, 556, 557,
-	558, 559, 560, 561, 562, 563, 564, 568, 0, 567,
-	885, 569, 570, 571, 572, 573, 581, 583, 584, 579,
-	580, 582, 585, 586, 588, 589, 576, 577, 578, 886,
-	587, 574, 1387, 575, 344, 887, 590, 591, 592, 593,
-	1411, 1456, 594, 1472, 597, 598, 0, 0, 599, 0,
-	600, 0, 0, 602, 603, 604, 0, 0, 605, 606,
-	836, 888, 607, 889, 1487, 608, 609, 1398, 610, 611,
-	612, 613, 614, 615, 616, 617, 618, 619, 0, 620,
-	621, 838, 622, 623, 624, 839, 625, 626, 627, 1488,
-	628, 841, 629, 630, 0, 631, 632, 633, 0, 634,
-	635, 636, 637, 638, 639, 640, 641, 642, 643, 1467,
-	644, 645, 647, 646, 648, 649, 0, 650, 0, 651,
-	652, 653, 0, 0, 0, 0, 0, 654, 655, 657,
-	0, 658, 659, 660, 661, 662, 656, 663, 664, 665,
-	666, 667, 668, 669, 0, 671, 672, 670, 673, 674,
-	890, 675, 676, 677, 678, 679, 1399, 680, 0, 681,
-	682, 690, 691, 692, 683, 684, 686, 693, 685, 694,
-	695, 696, 697, 699, 698, 0, 701, 702, 700, 703,
-	704, 705, 706, 1449, 707, 844, 708, 687, 688, 709,
-	710, 711, 891, 712, 713, 714, 715, 716, 717, 718,
-	719, 720, 1465, 0, 721, 0, 722, 723, 724, 725,
-	726, 727, 729, 689, 730, 731, 732, 737, 738, 1496,
-	733, 734, 735, 736, 1489, 740, 741, 742, 743, 0,
-	744, 745, 1384, 739, 728, 0, 746, 747, 748, 749,
-	750, 751, 752, 753, 754, 755, 0, 756, 1478, 1479,
-	1480, 1481, 0, 768, 0, 757, 759, 760, 761, 762,
-	1490, 763, 1491, 1409, 764, 765, 766, 767, 758, 6576,
-	770, 0, 1391, 771, 772, 773, 774, 776, 778, 779,
-	780, 775, 777, 781, 1450, 782, 0, 0, 783, 784,
-	785, 854, 1475, 1495, 0, 787, 788, 786, 789, 790,
-	793, 791, 792, 857, 796, 513, 797, 798, 799, 794,
-	795, 0, 0, 0, 0, 800, 801, 858, 802, 803,
-	804, 1388, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 1383, 0, 0,
-	0, 0, 0, 0, 1381, 1382, 0, 0, 0, 0,
-	0, 0, 864, 0, 1415, 0, 0, 0, 1413, 1460,
-	1403, 1404, 1405, 1401, 1402, 1414, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 345, 346, 348, 347,
-	349, 350, 351, 352, 0, 353, 354, 0, 0, 0,
-	0, 0, 1452, 1419, 0, 0, 356, 0, 355, 0,
-	357, 358, 359, 874, 360, 361, 362, 363, 364, 365,
-	366, 367, 6575, 1466, 0, 368, 1474, 369, 1473, 0,
-	1484, 370, 371, 372, 373, 374, 375, 376, 377, 378,
-	379, 1421, 1451, 1385, 380, 1497, 1498, 813, 0, 381,
-	382, 383, 384, 1458, 0, 1439, 0, 385, 386, 387,
-	388, 389, 390, 391, 392, 0, 0, 394, 395, 396,
-	393, 397, 398, 0, 399, 0, 400, 401, 402, 403,
-	404, 405, 406, 0, 407, 408, 409, 876, 410, 411,
-	6577, 1442, 1440, 1441, 1448, 1444, 1443, 1447, 413, 414,
-	415, 416, 417, 1477, 418, 420, 421, 1471, 422, 1470,
-	1390, 425, 427, 419, 423, 0, 426, 424, 428, 429,
-	0, 430, 431, 432, 433, 0, 0, 434, 1469, 436,
-	0, 437, 438, 440, 439, 0, 441, 442, 443, 0,
-	444, 445, 1397, 446, 447, 448, 450, 452, 449, 451,
-	453, 454, 455, 456, 457, 1485, 1486, 458, 459, 1410,
-	340, 0, 0, 0, 0, 0, 460, 461, 462, 1468,
-	0, 0, 0, 463, 0, 465, 469, 466, 467, 468,
-	470, 0, 464, 471, 472, 0, 877, 473, 474, 475,
-	1482, 1483, 476, 477, 478, 479, 480, 481, 482, 483,
-	484, 0, 485, 486, 1492, 0, 1420, 487, 0, 488,
-	489, 490, 491, 492, 493, 494, 1453, 1454, 1457, 595,
-	879, 495, 496, 497, 0, 498, 499, 500, 501, 502,
-	503, 504, 0, 0, 0, 505, 506, 507, 508, 0,
-	867, 341, 343, 878, 828, 509, 596, 510, 1463, 1464,
-	0, 1424, 0, 511, 512, 515, 880, 1455, 881, 514,
-	516, 517, 882, 518, 0, 0, 0, 519, 520, 521,
-	522, 523, 524, 525, 0, 526, 528, 527, 0, 530,
-	1493, 529, 883, 531, 532, 884, 0, 533, 534, 535,
-	536, 537, 538, 541, 1446, 1445, 539, 540, 542, 543,
-	0, 544, 545, 547, 550, 546, 548, 549, 551, 552,
-	565, 566, 553, 554, 555, 556, 557, 558, 559, 560,
-	561, 562, 563, 564, 568, 0, 567, 885, 569, 570,
-	571, 572, 573, 581, 583, 584, 579, 580, 582, 585,
-	586, 588, 589, 576, 577, 578, 886, 587, 574, 1387,
-	575, 344, 887, 590, 591, 592, 593, 1411, 1456, 594,
-	1472, 597, 598, 0, 0, 599, 0, 600, 0, 0,
-	602, 603, 604, 0, 0, 605, 606, 836, 888, 607,
-	889, 1487, 608, 609, 1398, 610, 611, 612, 613, 614,
-	615, 616, 617, 618, 619, 0, 620, 621, 838, 622,
-	623, 624, 839, 625, 626, 627, 1488, 628, 841, 629,
-	630, 0, 631, 632, 633, 0, 634, 635, 636, 637,
-	638, 639, 640, 641, 642, 643, 1467, 644, 645, 647,
-	646, 648, 649, 0, 650, 0, 651, 652, 653, 0,
-	0, 0, 0, 0, 654, 655, 657, 0, 658, 659,
-	660, 661, 662, 656, 663, 664, 665, 666, 667, 668,
-	669, 0, 671, 672, 670, 673, 674, 890, 675, 676,
-	677, 678, 679, 1399, 680, 0, 681, 682, 690, 691,
-	692, 683, 684, 686, 693, 685, 694, 695, 696, 697,
-	699, 698, 0, 701, 702, 700, 703, 704, 705, 706,
-	1449, 707, 844, 708, 687, 688, 709, 710, 711, 891,
-	712, 713, 714, 715, 716, 717, 718, 719, 720, 1465,
-	0, 721, 0, 722, 723, 724, 725, 726, 727, 729,
-	689, 730, 731, 732, 737, 738, 1496, 733, 734, 735,
-	736, 1489, 740, 741, 742, 743, 0, 744, 745, 1384,
-	739, 728, 0, 746, 747, 748, 749, 750, 751, 752,
-	753, 754, 755, 0, 756, 1478, 1479, 1480, 1481, 0,
-	768, 0, 757, 759, 760, 761, 762, 1490, 763, 1491,
-	1409, 764, 765, 766, 767, 758, 6576, 770, 0, 1391,
-	771, 772, 773, 774, 776, 778, 779, 780, 775, 777,
-	781, 1450, 782, 0, 0, 783, 784, 785, 854, 1475,
-	1495, 0, 787, 788, 786, 789, 790, 793, 791, 792,
-	857, 796, 513, 797, 798, 799, 794, 795, 0, 0,
-	0, 0, 800, 801, 858, 802, 803, 804, 1388, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 1383, 0, 0, 0, 0, 0,
-	0, 1381, 1382, 0, 0, 0, 0, 0, 0, 864,
-	0, 1415, 0, 0, 0, 1413, 1460, 1403, 1404, 1405,
-	1401, 1402, 1414, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 345, 346, 348, 347, 349, 350, 351,
-	352, 0, 353, 354, 0, 0, 0, 0, 0, 1452,
-	1419, 0, 0, 356, 0, 355, 0, 357, 358, 359,
-	874, 360, 361, 362, 363, 364, 365, 366, 367, 806,
-	1466, 0, 368, 1474, 369, 1473, 0, 1484, 370, 371,
-	372, 373, 374, 375, 376, 377, 378, 379, 1421, 1451,
-	1385, 380, 1497, 1498, 813, 0, 381, 382, 383, 384,
-	1458, 0, 1439, 0, 385, 386, 387, 388, 389, 390,
-	391, 392, 0, 0, 394, 395, 396, 393, 397, 398,
-	0, 399, 0, 400, 401, 402, 403, 404, 405, 406,
-	0, 407, 408, 409, 876, 410, 6080, 412, 1442, 1440,
-	1441, 1448, 1444, 1443, 1447, 413, 414, 415, 416, 417,
-	1477, 418, 420, 421, 1471, 422, 1470, 1390, 425, 427,
-	419, 423, 0, 426, 424, 428, 429, 0, 430, 431,
-	432, 433, 0, 0, 434, 1469, 436, 0, 437, 438,
-	440, 439, 0, 441, 442, 443, 0, 444, 445, 1397,
-	446, 447, 448, 450, 452, 449, 451, 453, 454, 455,
-	456, 457, 1485, 1486, 458, 459, 1410, 340, 0, 0,
-	0, 0, 0, 460, 461, 462, 1468, 0, 0, 0,
-	463, 0, 465, 469, 466, 467, 468, 470, 0, 464,
-	471, 472, 0, 877, 473, 474, 475, 1482, 1483, 476,
-	477, 478, 479, 480, 481, 482, 483, 484, 0, 485,
-	486, 1492, 0, 6081, 487, 0, 488, 489, 490, 491,
-	492, 493, 494, 1453, 1454, 1457, 595, 879, 495, 496,
-	497, 0, 498, 499, 500, 501, 502, 503, 504, 0,
-	0, 0, 505, 506, 507, 508, 0, 867, 341, 343,
-	878, 828, 509, 596, 510, 1463, 1464, 0, 1424, 0,
-	511, 512, 515, 880, 1455, 881, 514, 516, 517, 882,
-	518, 0, 0, 0, 519, 520, 521, 522, 523, 524,
-	525, 0, 526, 528, 527, 0, 530, 1493, 529, 883,
-	531, 532, 884, 0, 533, 534, 535, 536, 537, 538,
-	541, 1446, 1445, 539, 540, 542, 543, 0, 544, 545,
-	547, 550, 546, 548, 549, 551, 552, 565, 566, 553,
-	554, 555, 556, 557, 558, 559, 560, 561, 562, 563,
-	564, 568, 0, 567, 885, 569, 570, 571, 572, 573,
-	581, 583, 584, 579, 580, 582, 585, 586, 588, 589,
-	576, 577, 578, 886, 587, 574, 1387, 575, 344, 887,
-	590, 591, 592, 593, 1411, 1456, 594, 1472, 597, 598,
-	0, 0, 599, 0, 600, 0, 0, 602, 603, 604,
-	0, 0, 605, 606, 836, 888, 607, 889, 1487, 608,
-	609, 1398, 610, 611, 612, 613, 614, 615, 616, 617,
-	618, 619, 0, 620, 621, 838, 622, 623, 624, 839,
-	625, 626, 627, 1488, 628, 841, 629, 630, 0, 631,
-	632, 633, 0, 634, 635, 636, 637, 638, 639, 640,
-	641, 642, 643, 1467, 644, 645, 647, 646, 648, 649,
-	0, 650, 0, 651, 652, 653, 0, 0, 0, 0,
-	0, 654, 655, 657, 0, 658, 659, 660, 661, 662,
-	656, 663, 664, 665, 666, 667, 668, 669, 0, 671,
-	672, 670, 673, 674, 890, 675, 676, 677, 6079, 679,
-	1399, 680, 0, 681, 682, 690, 691, 692, 683, 684,
-	686, 693, 685, 694, 695, 696, 697, 699, 698, 0,
-	701, 702, 700, 703, 704, 705, 706, 1449, 707, 844,
-	708, 687, 688, 709, 710, 711, 891, 712, 713, 714,
-	715, 716, 717, 718, 719, 720, 1465, 0, 721, 0,
-	722, 723, 724, 725, 726, 727, 729, 689, 730, 731,
-	732, 737, 738, 1496, 733, 734, 735, 736, 1489, 740,
-	741, 742, 743, 0, 744, 745, 1384, 739, 728, 0,
-	746, 747, 748, 749, 750, 751, 752, 753, 754, 755,
-	0, 756, 1478, 1479, 1480, 1481, 0, 768, 0, 757,
-	759, 760, 761, 762, 1490, 763, 1491, 1409, 764, 765,
-	766, 767, 758, 769, 770, 0, 1391, 771, 772, 773,
-	774, 776, 778, 779, 780, 775, 777, 781, 1450, 782,
-	0, 0, 783, 784, 785, 854, 1475, 1495, 0, 787,
-	788, 786, 789, 790, 793, 791, 792, 857, 796, 513,
-	797, 798, 799, 794, 795, 0, 0, 0, 0, 800,
-	801, 858, 802, 803, 804, 1388, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 1383, 0, 0, 0, 0, 0, 0, 1381, 1382,
-	0, 0, 0, 0, 0, 0, 864, 0, 1415, 0,
-	0, 0, 1413, 1460, 1403, 1404, 1405, 1401, 1402, 1414,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	345, 346, 348, 347, 349, 350, 351, 352, 0, 353,
-	354, 0, 0, 0, 0, 0, 1452, 1419, 0, 0,
-	356, 0, 355, 0, 357, 358, 359, 874, 360, 361,
-	362, 363, 364, 365, 366, 367, 806, 1466, 0, 368,
-	1474, 369, 1473, 0, 1484, 370, 371, 372, 373, 374,
-	375, 376, 377, 378, 379, 1421, 1451, 1385, 380, 1497,
-	1498, 813, 0, 381, 382, 383, 384, 1458, 0, 1439,
-	0, 385, 386, 387, 388, 389, 390, 391, 392, 0,
-	0, 394, 395, 396, 393, 397, 398, 0, 399, 0,
-	400, 401, 402, 403, 404, 405, 406, 0, 407, 408,
-	409, 876, 410, 411, 412, 1442, 1440, 1441, 1448, 1444,
-	1443, 1447, 413, 414, 415, 416, 417, 1477, 418, 420,
-	421, 1471, 422, 1470, 1390, 425, 427, 419, 423, 0,
-	426, 424, 428, 429, 0, 430, 431, 432, 433, 0,
-	0, 434, 1469, 436, 0, 437, 438, 440, 439, 0,
-	441, 442, 443, 0, 444, 445, 1397, 446, 447, 448,
-	450, 452, 449, 451, 453, 454, 455, 456, 457, 1485,
-	1486, 458, 459, 1410, 340, 0, 0, 0, 0, 0,
-	460, 461, 462, 1468, 0, 0, 0, 463, 0, 465,
-	469, 466, 467, 468, 470, 0, 464, 471, 472, 0,
-	877, 2520, 474, 475, 1482, 1483, 476, 477, 478, 479,
-	480, 481, 482, 483, 484, 0, 485, 486, 1492, 0,
-	1420, 487, 0, 488, 489, 490, 491, 492, 493, 494,
-	1453, 1454, 1457, 595, 879, 495, 496, 497, 0, 498,
-	499, 500, 501, 502, 503, 504, 0, 0, 0, 505,
-	506, 507, 508, 0, 867, 341, 343, 878, 828, 509,
-	596, 510, 1463, 1464, 0, 1424, 0, 511, 512, 515,
-	880, 1455, 881, 514, 516, 517, 882, 518, 0, 0,
-	0, 519, 520, 521, 522, 523, 524, 525, 0, 526,
-	528, 527, 0, 530, 1493, 529, 883, 531, 532, 884,
-	0, 533, 534, 535, 536, 537, 538, 541, 1446, 1445,
-	539, 540, 542, 543, 0, 544, 545, 547, 550, 546,
-	548, 549, 551, 552, 565, 566, 553, 554, 555, 556,
-	557, 558, 559, 560, 561, 562, 563, 564, 568, 0,
-	567, 885, 569, 570, 571, 572, 573, 581, 583, 584,
-	579, 580, 582, 585, 586, 588, 589, 576, 577, 578,
-	886, 587, 574, 1387, 575, 344, 887, 590, 591, 592,
-	593, 1411, 1456, 594, 1472, 597, 598, 0, 0, 599,
-	0, 600, 0, 0, 602, 603, 604, 0, 0, 605,
-	606, 836, 888, 607, 889, 1487, 608, 609, 1398, 610,
-	611, 612, 613, 614, 615, 616, 617, 618, 619, 0,
-	620, 621, 838, 622, 623, 624, 839, 625, 626, 627,
-	1488, 628, 841, 629, 630, 0, 631, 632, 633, 0,
-	634, 635, 636, 637, 638, 639, 640, 641, 642, 643,
-	1467, 644, 645, 647, 646, 648, 649, 0, 650, 0,
-	651, 652, 653, 0, 0, 0, 0, 0, 654, 655,
-	657, 0, 658, 659, 660, 661, 662, 656, 663, 664,
-	665, 666, 667, 668, 669, 0, 671, 672, 670, 673,
-	674, 890, 675, 676, 677, 678, 679, 1399, 680, 0,
-	681, 682, 690, 691, 692, 683, 684, 686, 693, 685,
-	694, 695, 696, 697, 699, 698, 0, 701, 702, 700,
-	703, 704, 705, 706, 1449, 707, 844, 708, 687, 688,
-	709, 710, 711, 891, 712, 713, 714, 715, 716, 717,
-	718, 719, 720, 1465, 0, 721, 0, 722, 723, 724,
-	725, 726, 727, 729, 689, 730, 731, 732, 737, 738,
-	1496, 733, 734, 735, 736, 1489, 740, 741, 742, 743,
-	0, 744, 745, 1384, 739, 728, 0, 746, 747, 748,
-	749, 750, 751, 752, 753, 754, 755, 0, 756, 1478,
-	1479, 1480, 1481, 0, 768, 0, 757, 759, 760, 761,
-	762, 1490, 763, 1491, 1409, 764, 765, 766, 767, 758,
-	769, 770, 0, 1391, 771, 772, 773, 774, 776, 778,
-	779, 780, 775, 777, 781, 1450, 782, 0, 0, 783,
-	784, 785, 854, 1475, 1495, 0, 787, 788, 786, 789,
-	790, 793, 791, 792, 857, 796, 513, 797, 798, 799,
-	794, 795, 0, 0, 0, 0, 800, 801, 858, 802,
-	803, 804, 1388, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 1383, 0,
-	0, 0, 0, 0, 0, 1381, 1382, 0, 0, 0,
-	0, 0, 0, 3168, 0, 1415, 0, 0, 0, 1413,
-	1460, 1403, 1404, 1405, 4514, 4515, 1414, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 345, 346, 348,
-	347, 349, 350, 351, 352, 0, 353, 354, 0, 0,
-	0, 0, 0, 1452, 1419, 0, 0, 356, 0, 355,
-	0, 357, 358, 359, 874, 360, 361, 362, 363, 364,
-	365, 366, 367, 806, 1466, 0, 368, 1474, 369, 1473,
-	0, 1484, 370, 371, 372, 373, 374, 375, 376, 377,
-	378, 379, 1421, 1451, 1385, 380, 1497, 1498, 813, 0,
-	381, 382, 383, 384, 1458, 0, 1439, 0, 385, 386,
-	387, 388, 389, 390, 391, 392, 0, 0, 394, 395,
-	396, 393, 397, 398, 0, 399, 0, 400, 401, 402,
-	403, 404, 405, 406, 0, 407, 408, 409, 876, 410,
-	411, 412, 1442, 1440, 1441, 1448, 1444, 1443, 1447, 413,
-	414, 415, 416, 417, 1477, 418, 420, 421, 1471, 422,
-	1470, 1390, 425, 427, 419, 423, 0, 426, 424, 428,
-	429, 0, 430, 431, 432, 433, 0, 0, 434, 1469,
-	436, 0, 437, 438, 440, 439, 0, 441, 442, 443,
-	0, 444, 445, 1397, 446, 447, 448, 450, 452, 449,
-	451, 453, 454, 455, 456, 457, 1485, 1486, 458, 459,
-	1410, 340, 0, 0, 0, 0, 0, 460, 461, 462,
-	1468, 0, 0, 0, 463, 0, 465, 469, 466, 467,
-	468, 470, 0, 464, 471, 472, 0, 877, 473, 474,
-	475, 1482, 1483, 476, 477, 478, 479, 480, 481, 482,
-	483, 484, 0, 485, 486, 1492, 0, 1420, 487, 0,
-	488, 489, 490, 491, 492, 493, 494, 1453, 1454, 1457,
-	595, 879, 495, 496, 497, 0, 498, 499, 500, 501,
-	502, 503, 504, 0, 0, 0, 505, 506, 507, 508,
-	0, 867, 341, 343, 878, 828, 509, 596, 510, 1463,
-	1464, 0, 1424, 0, 511, 512, 515, 880, 1455, 881,
-	514, 516, 517, 882, 518, 0, 0, 0, 519, 520,
-	521, 522, 523, 524, 525, 0, 526, 528, 527, 0,
-	530, 1493, 529, 883, 531, 532, 884, 0, 533, 534,
-	535, 536, 537, 538, 541, 1446, 1445, 539, 540, 542,
-	543, 0, 544, 545, 547, 550, 546, 548, 549, 551,
-	552, 565, 566, 553, 554, 555, 556, 557, 558, 559,
-	560, 561, 562, 563, 564, 568, 0, 567, 885, 569,
-	570, 571, 572, 573, 581, 583, 584, 579, 580, 582,
-	585, 586, 588, 589, 576, 577, 578, 886, 587, 574,
-	1387, 575, 344, 887, 590, 591, 592, 593, 1411, 1456,
-	594, 1472, 597, 598, 0, 0, 599, 0, 600, 0,
-	0, 602, 603, 604, 0, 0, 605, 606, 836, 888,
-	607, 889, 1487, 608, 609, 1398, 610, 611, 612, 613,
-	614, 615, 616, 617, 618, 619, 0, 620, 621, 838,
-	622, 623, 624, 839, 625, 626, 627, 1488, 628, 841,
-	629, 630, 0, 631, 632, 633, 0, 634, 635, 636,
-	637, 638, 639, 640, 641, 642, 643, 1467, 644, 645,
-	647, 646, 648, 649, 0, 650, 0, 651, 652, 653,
-	0, 0, 0, 0, 0, 654, 655, 657, 0, 658,
-	659, 660, 661, 662, 656, 663, 664, 665, 666, 667,
-	668, 669, 0, 671, 672, 670, 673, 674, 890, 675,
-	676, 677, 678, 679, 1399, 680, 0, 681, 682, 690,
-	691, 692, 683, 684, 686, 693, 685, 694, 695, 696,
-	697, 699, 698, 0, 701, 702, 700, 703, 704, 705,
-	706, 1449, 707, 844, 708, 687, 688, 709, 710, 711,
-	891, 712, 713, 714, 715, 716, 717, 718, 719, 720,
-	1465, 0, 721, 0, 722, 723, 724, 725, 726, 727,
-	729, 689, 730, 731, 732, 737, 738, 1496, 733, 734,
-	735, 736, 1489, 740, 741, 742, 743, 0, 744, 745,
-	1384, 739, 728, 0, 746, 747, 748, 749, 750, 751,
-	752, 753, 754, 755, 0, 756, 1478, 1479, 1480, 1481,
-	0, 768, 0, 757, 759, 760, 761, 762, 1490, 763,
-	1491, 1409, 764, 765, 766, 767, 758, 769, 770, 0,
-	1391, 771, 772, 773, 774, 776, 778, 779, 780, 775,
-	777, 781, 1450, 782, 0, 0, 783, 784, 785, 854,
-	1475, 1495, 0, 787, 788, 786, 789, 790, 793, 791,
-	792, 857, 796, 513, 797, 798, 799, 794, 795, 0,
-	0, 0, 0, 800, 801, 858, 802, 803, 804, 1388,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 1383, 0, 0, 0, 0,
-	0, 0, 1381, 1382, 0, 0, 0, 0, 0, 0,
-	864, 0, 1415, 0, 0, 0, 1413, 1460, 1403, 1404,
-	1405, 4512, 4513, 1414, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 345, 346, 348, 347, 349, 350,
-	351, 352, 0, 353, 354, 0, 0, 0, 0, 0,
-	1452, 1419, 0, 0, 356, 0, 355, 0, 357, 358,
-	359, 874, 360, 361, 362, 363, 364, 365, 366, 367,
-	806, 1466, 0, 368, 1474, 369, 1473, 0, 1484, 370,
-	371, 372, 373, 374, 375, 376, 377, 378, 379, 1421,
-	1451, 1385, 380, 1497, 1498, 813, 0, 381, 382, 383,
-	384, 1458, 0, 1439, 0, 385, 386, 387, 388, 389,
-	390, 391, 392, 0, 0, 394, 395, 396, 393, 397,
-	398, 0, 399, 0, 400, 401, 402, 403, 404, 405,
-	406, 0, 407, 408, 409, 876, 410, 411, 412, 1442,
-	1440, 1441, 1448, 1444, 1443, 1447, 413, 414, 415, 416,
-	417, 1477, 418, 420, 421, 1471, 422, 1470, 1390, 425,
-	427, 419, 423, 0, 426, 424, 428, 429, 0, 430,
-	431, 432, 433, 0, 0, 434, 1469, 436, 0, 437,
-	438, 440, 439, 0, 441, 442, 443, 0, 444, 445,
-	1397, 446, 447, 448, 450, 452, 449, 451, 453, 454,
-	455, 456, 457, 1485, 1486, 458, 459, 1410, 340, 0,
-	0, 0, 0, 0, 460, 461, 462, 1468, 0, 0,
-	0, 463, 0, 465, 469, 466, 467, 468, 470, 0,
-	464, 471, 472, 0, 877, 473, 474, 475, 1482, 1483,
-	476, 477, 478, 479, 480, 481, 482, 483, 484, 0,
-	485, 486, 1492, 0, 1420, 487, 0, 488, 489, 490,
-	491, 492, 493, 494, 1453, 1454, 1457, 595, 879, 495,
-	496, 497, 0, 498, 499, 500, 501, 502, 503, 504,
-	0, 0, 0, 505, 506, 507, 508, 0, 867, 341,
-	343, 878, 828, 509, 596, 510, 1463, 1464, 0, 1424,
-	0, 511, 512, 515, 880, 1455, 881, 514, 516, 517,
-	882, 518, 0, 0, 0, 519, 520, 521, 522, 523,
-	524, 525, 0, 526, 528, 527, 0, 530, 1493, 529,
-	883, 531, 532, 884, 0, 533, 534, 535, 536, 537,
-	538, 541, 1446, 1445, 539, 540, 542, 543, 0, 544,
-	545, 547, 550, 546, 548, 549, 551, 552, 565, 566,
-	553, 554, 555, 556, 557, 558, 559, 560, 561, 562,
-	563, 564, 568, 0, 567, 885, 569, 570, 571, 572,
-	573, 581, 583, 584, 579, 580, 582, 585, 586, 588,
-	589, 576, 577, 578, 886, 587, 574, 1387, 575, 344,
-	887, 590, 591, 592, 593, 1411, 1456, 594, 1472, 597,
-	598, 0, 0, 599, 0, 600, 0, 0, 602, 603,
-	604, 0, 0, 605, 606, 836, 888, 607, 889, 1487,
-	608, 609, 1398, 610, 611, 612, 613, 614, 615, 616,
-	617, 618, 619, 0, 620, 621, 838, 622, 623, 624,
-	839, 625, 626, 627, 1488, 628, 841, 629, 630, 0,
-	631, 632, 633, 0, 634, 635, 636, 637, 638, 639,
-	640, 641, 642, 643, 1467, 644, 645, 647, 646, 648,
-	649, 0, 650, 0, 651, 652, 653, 0, 0, 0,
-	0, 0, 654, 655, 657, 0, 658, 659, 660, 661,
-	662, 656, 663, 664, 665, 666, 667, 668, 669, 0,
-	671, 672, 670, 673, 674, 890, 675, 676, 677, 678,
-	679, 1399, 680, 0, 681, 682, 690, 691, 692, 683,
-	684, 686, 693, 685, 694, 695, 696, 697, 699, 698,
-	0, 701, 702, 700, 703, 704, 705, 706, 1449, 707,
-	844, 708, 687, 688, 709, 710, 711, 891, 712, 713,
-	714, 715, 716, 717, 718, 719, 720, 1465, 0, 721,
-	0, 722, 723, 724, 725, 726, 727, 729, 689, 730,
-	731, 732, 737, 738, 1496, 733, 734, 735, 736, 1489,
-	740, 741, 742, 743, 0, 744, 745, 1384, 739, 728,
-	0, 746, 747, 748, 749, 750, 751, 752, 753, 754,
-	755, 0, 756, 1478, 1479, 1480, 1481, 0, 768, 0,
-	757, 759, 760, 761, 762, 1490, 763, 1491, 1409, 764,
-	765, 766, 767, 758, 769, 770, 0, 1391, 771, 772,
-	773, 774, 776, 778, 779, 780, 775, 777, 781, 1450,
-	782, 0, 0, 783, 784, 785, 854, 1475, 1495, 0,
-	787, 788, 786, 789, 790, 793, 791, 792, 857, 796,
-	513, 797, 798, 799, 794, 795, 0, 0, 0, 0,
-	800, 801, 858, 802, 803, 804, 1388, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 1383, 0, 0, 0, 0, 0, 0, 1381,
-	1382, 0, 0, 0, 0, 0, 0, 864, 0, 1415,
-	0, 0, 0, 1413, 1460, 1403, 1404, 1405, 1401, 1402,
-	1414, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 345, 346, 348, 347, 349, 350, 351, 352, 0,
-	353, 354, 0, 0, 0, 0, 0, 1452, 1419, 0,
-	0, 356, 0, 355, 0, 357, 358, 359, 874, 360,
-	361, 362, 363, 364, 365, 366, 367, 806, 1466, 0,
-	368, 1474, 369, 1473, 0, 1484, 370, 371, 372, 373,
-	374, 375, 376, 377, 378, 379, 1421, 1451, 1385, 380,
-	1497, 1498, 813, 0, 381, 382, 383, 384, 1458, 0,
-	1439, 0, 385, 386, 387, 388, 389, 390, 391, 392,
-	0, 0, 394, 395, 396, 393, 397, 398, 0, 399,
-	0, 400, 401, 402, 403, 404, 405, 406, 0, 407,
-	408, 409, 876, 410, 411, 412, 1442, 1440, 1441, 1448,
-	1444, 1443, 1447, 413, 414, 415, 416, 417, 1477, 418,
-	420, 421, 1471, 422, 1470, 1390, 425, 427, 419, 423,
-	0, 426, 424, 428, 429, 0, 430, 431, 432, 433,
-	0, 0, 434, 1469, 436, 0, 437, 438, 440, 439,
-	0, 441, 442, 443, 0, 444, 445, 1397, 446, 447,
-	448, 450, 452, 449, 451, 453, 454, 455, 456, 457,
-	1485, 1486, 458, 459, 1410, 340, 0, 0, 0, 0,
-	0, 460, 461, 462, 1468, 0, 0, 0, 463, 0,
-	465, 469, 466, 467, 468, 470, 0, 464, 471, 472,
-	0, 877, 473, 474, 475, 1482, 1483, 476, 477, 478,
-	479, 480, 481, 482, 483, 484, 0, 485, 486, 1492,
-	0, 1420, 487, 0, 488, 489, 490, 491, 492, 493,
-	494, 1453, 1454, 1457, 595, 879, 495, 496, 497, 0,
-	498, 499, 500, 501, 502, 503, 504, 0, 0, 0,
-	505, 506, 507, 508, 0, 867, 341, 343, 878, 828,
-	509, 596, 510, 1463, 1464, 0, 1424, 0, 511, 512,
-	515, 880, 1455, 881, 514, 516, 517, 882, 518, 0,
-	0, 0, 519, 520, 521, 522, 523, 524, 525, 0,
-	526, 528, 527, 0, 530, 1493, 529, 883, 531, 532,
-	884, 0, 533, 534, 535, 536, 537, 538, 541, 1446,
-	1445, 539, 540, 542, 543, 0, 544, 545, 547, 550,
-	546, 548, 549, 551, 552, 565, 566, 553, 554, 555,
-	556, 557, 558, 559, 560, 561, 562, 563, 564, 568,
-	0, 567, 885, 569, 570, 571, 572, 573, 581, 583,
-	584, 579, 580, 582, 585, 586, 588, 589, 576, 577,
-	578, 886, 587, 574, 1387, 575, 344, 887, 590, 591,
-	592, 593, 1411, 1456, 594, 1472, 597, 598, 0, 0,
-	599, 0, 600, 0, 0, 602, 603, 604, 0, 0,
-	605, 606, 836, 888, 607, 889, 1487, 608, 609, 1398,
-	610, 611, 612, 613, 614, 615, 616, 617, 618, 619,
-	0, 620, 621, 838, 622, 623, 624, 839, 625, 626,
-	627, 1488, 628, 841, 629, 630, 0, 631, 632, 633,
-	0, 634, 635, 636, 637, 638, 639, 640, 641, 642,
-	643, 1467, 644, 645, 647, 646, 648, 649, 0, 650,
-	0, 651, 652, 653, 0, 0, 0, 0, 0, 654,
-	655, 657, 0, 658, 659, 660, 661, 662, 656, 663,
-	664, 665, 666, 667, 668, 669, 0, 671, 672, 670,
-	673, 674, 890, 675, 676, 677, 678, 679, 1399, 680,
-	0, 681, 682, 690, 691, 692, 683, 684, 686, 693,
-	685, 694, 695, 696, 697, 699, 698, 0, 701, 702,
-	700, 703, 704, 705, 706, 1449, 707, 844, 708, 687,
-	688, 709, 710, 711, 891, 712, 713, 714, 715, 716,
-	717, 718, 719, 720, 1465, 0, 721, 0, 722, 723,
-	724, 725, 726, 727, 729, 689, 730, 731, 732, 737,
-	738, 1496, 733, 734, 735, 736, 1489, 740, 741, 742,
-	743, 0, 744, 745, 1384, 739, 728, 0, 746, 747,
-	748, 749, 750, 751, 752, 753, 754, 755, 0, 756,
-	1478, 1479, 1480, 1481, 0, 768, 0, 757, 759, 760,
-	761, 762, 1490, 763, 1491, 1409, 764, 765, 766, 767,
-	758, 769, 770, 0, 1391, 771, 772, 773, 774, 776,
-	778, 779, 780, 775, 777, 781, 1450, 782, 0, 0,
-	783, 784, 785, 854, 1475, 1495, 0, 787, 788, 786,
-	789, 790, 793, 791, 792, 857, 796, 513, 797, 798,
-	799, 794, 795, 0, 0, 0, 0, 800, 801, 858,
-	802, 803, 804, 1388, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 1383,
-	0, 0, 0, 0, 0, 0, 1381, 1382, 0, 0,
-	0, 0, 0, 0, 3168, 0, 1415, 0, 0, 0,
-	1413, 1460, 1403, 1404, 1405, 1401, 1402, 1414, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 345, 346,
-	348, 347, 349, 350, 351, 352, 0, 353, 354, 0,
-	0, 0, 0, 0, 1452, 1419, 0, 0, 356, 0,
-	355, 0, 357, 358, 359, 874, 360, 361, 362, 363,
-	364, 365, 366, 367, 806, 1466, 0, 368, 1474, 369,
-	1473, 0, 1484, 370, 371, 372, 373, 374, 375, 376,
-	377, 378, 379, 1421, 1451, 1385, 380, 1497, 1498, 813,
-	0, 381, 382, 383, 384, 1458, 0, 1439, 0, 385,
-	386, 387, 388, 389, 390, 391, 392, 0, 0, 394,
-	395, 396, 393, 397, 398, 0, 399, 0, 400, 401,
-	402, 403, 404, 405, 406, 0, 407, 408, 409, 876,
-	410, 411, 412, 1442, 1440, 1441, 1448, 1444, 1443, 1447,
-	413, 414, 415, 416, 417, 1477, 418, 420, 421, 1471,
-	422, 1470, 1390, 425, 427, 419, 423, 0, 426, 424,
-	428, 429, 0, 430, 431, 432, 433, 0, 0, 434,
-	1469, 436, 0, 437, 438, 440, 439, 0, 441, 442,
-	443, 0, 444, 445, 1397, 446, 447, 448, 450, 452,
-	449, 451, 453, 454, 455, 456, 457, 1485, 1486, 458,
-	459, 1410, 340, 0, 0, 0, 0, 0, 460, 461,
-	462, 1468, 0, 0, 0, 463, 0, 465, 469, 466,
-	467, 468, 470, 0, 464, 471, 472, 0, 877, 473,
-	474, 475, 1482, 1483, 476, 477, 478, 479, 480, 481,
-	482, 483, 484, 0, 485, 486, 1492, 0, 1420, 487,
-	0, 488, 489, 490, 491, 492, 493, 494, 1453, 1454,
-	1457, 595, 879, 495, 496, 497, 0, 498, 499, 500,
-	501, 502, 503, 504, 0, 0, 0, 505, 506, 507,
-	508, 0, 867, 341, 343, 878, 828, 509, 596, 510,
-	1463, 1464, 0, 1424, 0, 511, 512, 515, 880, 1455,
-	881, 514, 516, 517, 882, 518, 0, 0, 0, 519,
-	520, 521, 522, 523, 524, 525, 0, 526, 528, 527,
-	0, 530, 1493, 529, 883, 531, 532, 884, 0, 533,
-	534, 535, 536, 537, 538, 541, 1446, 1445, 539, 540,
-	542, 543, 0, 544, 545, 547, 550, 546, 548, 549,
-	551, 552, 565, 566, 553, 554, 555, 556, 557, 558,
-	559, 560, 561, 562, 563, 564, 568, 0, 567, 885,
-	569, 570, 571, 572, 573, 581, 583, 584, 579, 580,
-	582, 585, 586, 588, 589, 576, 577, 578, 886, 587,
-	574, 1387, 575, 344, 887, 590, 591, 592, 593, 1411,
-	1456, 594, 1472, 597, 598, 0, 0, 599, 0, 600,
-	0, 0, 602, 603, 604, 0, 0, 605, 606, 836,
-	888, 607, 889, 1487, 608, 609, 1398, 610, 611, 612,
-	613, 614, 615, 616, 617, 618, 619, 0, 620, 621,
-	838, 622, 623, 624, 839, 625, 626, 627, 1488, 628,
-	841, 629, 630, 0, 631, 632, 633, 0, 634, 635,
-	636, 637, 638, 639, 640, 641, 642, 643, 1467, 644,
-	645, 647, 646, 648, 649, 0, 650, 0, 651, 652,
-	653, 0, 0, 0, 0, 0, 654, 655, 657, 0,
-	658, 659, 660, 661, 662, 656, 663, 664, 665, 666,
-	667, 668, 669, 0, 671, 672, 670, 673, 674, 890,
-	675, 676, 677, 678, 679, 1399, 680, 0, 681, 682,
-	690, 691, 692, 683, 684, 686, 693, 685, 694, 695,
-	696, 697, 699, 698, 0, 701, 702, 700, 703, 704,
-	705, 706, 1449, 707, 844, 708, 687, 688, 709, 710,
-	711, 891, 712, 713, 714, 715, 716, 717, 718, 719,
-	720, 1465, 0, 721, 0, 722, 723, 724, 725, 726,
-	727, 729, 689, 730, 731, 732, 737, 738, 1496, 733,
-	734, 735, 736, 1489, 740, 741, 742, 743, 0, 744,
-	745, 1384, 739, 728, 0, 746, 747, 748, 749, 750,
-	751, 752, 753, 754, 755, 0, 756, 1478, 1479, 1480,
-	1481, 0, 768, 0, 757, 759, 760, 761, 762, 1490,
-	763, 1491, 1409, 764, 765, 766, 767, 758, 769, 770,
-	0, 1391, 771, 772, 773, 774, 776, 778, 779, 780,
-	775, 777, 781, 1450, 782, 0, 0, 783, 784, 785,
-	854, 1475, 1495, 0, 787, 788, 786, 789, 790, 793,
-	791, 792, 857, 796, 513, 797, 798, 799, 794, 795,
-	0, 0, 0, 0, 800, 801, 858, 802, 803, 804,
-	1388, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 1383, 0, 0, 0,
-	0, 0, 0, 3024, 3025, 0, 0, 0, 0, 0,
-	0, 864, 0, 1415, 0, 0, 0, 1413, 1460, 1403,
-	1404, 1405, 1401, 1402, 1414, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 345, 346, 348, 347, 349,
-	350, 351, 352, 0, 353, 354, 0, 0, 0, 0,
-	0, 1452, 1419, 0, 0, 356, 0, 355, 0, 357,
-	358, 359, 874, 360, 361, 362, 363, 364, 365, 366,
-	367, 806, 1466, 0, 368, 1474, 369, 1473, 0, 1484,
-	370, 371, 372, 373, 374, 375, 376, 377, 378, 379,
-	1421, 1451, 1385, 380, 1497, 1498, 813, 0, 381, 382,
-	383, 384, 1458, 0, 1439, 0, 385, 386, 387, 388,
-	389, 390, 391, 392, 0, 0, 394, 395, 396, 393,
-	397, 398, 0, 399, 0, 400, 401, 402, 403, 404,
-	405, 406, 0, 407, 408, 409, 876, 410, 411, 412,
-	1442, 1440, 1441, 1448, 1444, 1443, 1447, 413, 414, 415,
-	416, 417, 1477, 418, 420, 421, 1471, 422, 1470, 1390,
-	425, 427, 419, 423, 0, 426, 424, 428, 429, 0,
-	430, 431, 432, 433, 0, 0, 434, 1469, 436, 0,
-	437, 438, 440, 439, 0, 441, 442, 443, 0, 444,
-	445, 1397, 446, 447, 448, 450, 452, 449, 451, 453,
-	454, 455, 456, 457, 1485, 1486, 458, 459, 1410, 340,
-	0, 0, 0, 0, 0, 460, 461, 462, 1468, 0,
-	0, 0, 463, 0, 465, 469, 466, 467, 468, 470,
-	0, 464, 471, 472, 0, 877, 2520, 474, 475, 1482,
-	1483, 476, 477, 478, 479, 480, 481, 482, 483, 484,
-	0, 485, 486, 1492, 0, 1420, 487, 0, 488, 489,
-	490, 491, 492, 493, 494, 1453, 1454, 1457, 595, 879,
-	495, 496, 497, 0, 498, 499, 500, 501, 502, 503,
-	504, 0, 0, 0, 505, 506, 507, 508, 0, 867,
-	341, 343, 878, 828, 509, 596, 510, 1463, 1464, 0,
-	1424, 0, 511, 512, 515, 880, 1455, 881, 514, 516,
-	517, 882, 518, 0, 0, 0, 519, 520, 521, 522,
-	523, 524, 525, 0, 526, 528, 527, 0, 530, 1493,
-	529, 883, 531, 532, 884, 0, 533, 534, 535, 536,
-	537, 538, 541, 1446, 1445, 539, 540, 542, 543, 0,
-	544, 545, 547, 550, 546, 548, 549, 551, 552, 565,
-	566, 553, 554, 555, 556, 557, 558, 559, 560, 561,
-	562, 563, 564, 568, 0, 567, 885, 569, 570, 571,
-	572, 573, 581, 583, 584, 579, 580, 582, 585, 586,
-	588, 589, 576, 577, 578, 886, 587, 574, 1387, 575,
-	344, 887, 590, 591, 592, 593, 1411, 1456, 594, 1472,
-	597, 598, 0, 0, 599, 0, 600, 0, 0, 602,
-	603, 604, 0, 0, 605, 606, 836, 888, 607, 889,
-	1487, 608, 609, 1398, 610, 611, 612, 613, 614, 615,
-	616, 617, 618, 619, 0, 620, 621, 838, 622, 623,
-	624, 839, 625, 626, 627, 1488, 628, 841, 629, 630,
-	0, 631, 632, 633, 0, 634, 635, 636, 637, 638,
-	639, 640, 641, 642, 643, 1467, 644, 645, 647, 646,
-	648, 649, 0, 650, 0, 651, 652, 653, 0, 0,
-	0, 0, 0, 654, 655, 657, 0, 658, 659, 660,
-	661, 662, 656, 663, 664, 665, 666, 667, 668, 669,
-	0, 671, 672, 670, 673, 674, 890, 675, 676, 677,
-	678, 679, 1399, 680, 0, 681, 682, 690, 691, 692,
-	683, 684, 686, 693, 685, 694, 695, 696, 697, 699,
-	698, 0, 701, 702, 700, 703, 704, 705, 706, 1449,
-	707, 844, 708, 687, 688, 709, 710, 711, 891, 712,
-	713, 714, 715, 716, 717, 718, 719, 720, 1465, 0,
-	721, 0, 722, 723, 724, 725, 726, 727, 729, 689,
-	730, 731, 732, 737, 738, 1496, 733, 734, 735, 736,
-	1489, 740, 741, 742, 743, 0, 744, 745, 1384, 739,
-	728, 0, 746, 747, 748, 749, 750, 751, 752, 753,
-	754, 755, 0, 756, 1478, 1479, 1480, 1481, 0, 768,
-	0, 757, 759, 760, 761, 762, 1490, 763, 1491, 1409,
-	764, 765, 766, 767, 758, 769, 770, 0, 1391, 771,
-	772, 773, 774, 776, 778, 779, 780, 775, 777, 781,
-	1450, 782, 0, 0, 783, 784, 785, 854, 1475, 1495,
-	0, 787, 788, 786, 789, 790, 793, 791, 792, 857,
-	796, 513, 797, 798, 799, 794, 795, 0, 0, 0,
-	0, 800, 801, 858, 802, 803, 804, 1388, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 1383, 0, 0, 0, 0, 0, 0,
-	1381, 1382, 0, 0, 0, 0, 0, 0, 864, 0,
-	1415, 0, 0, 0, 1413, 1460, 1403, 1404, 1405, 1401,
-	1402, 1414, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 345, 346, 348, 347, 349, 350, 351, 352,
-	0, 353, 354, 0, 0, 0, 0, 0, 1452, 1419,
-	0, 0, 356, 0, 355, 0, 357, 358, 359, 874,
-	360, 361, 362, 363, 364, 365, 366, 367, 806, 1466,
-	0, 368, 1474, 369, 1473, 0, 1484, 370, 371, 372,
-	373, 374, 375, 376, 377, 378, 379, 1421, 1451, 0,
-	380, 1497, 1498, 813, 0, 381, 382, 383, 384, 1458,
-	0, 1439, 0, 385, 386, 387, 388, 389, 390, 391,
-	392, 0, 0, 394, 395, 396, 393, 397, 398, 0,
-	399, 0, 400, 401, 402, 403, 404, 405, 406, 0,
-	407, 408, 409, 876, 410, 411, 412, 1442, 1440, 1441,
-	1448, 1444, 1443, 1447, 413, 414, 415, 416, 417, 1477,
-	418, 420, 421, 1471, 422, 1470, 0, 425, 427, 419,
-	423, 0, 426, 424, 428, 429, 0, 430, 431, 432,
-	433, 0, 0, 434, 1469, 436, 0, 437, 438, 440,
-	439, 0, 441, 442, 443, 0, 444, 445, 1397, 446,
-	447, 448, 450, 452, 449, 451, 453, 454, 455, 456,
-	457, 1485, 1486, 458, 459, 1410, 340, 0, 0, 0,
-	0, 0, 460, 461, 462, 1468, 0, 0, 0, 463,
-	0, 465, 469, 466, 467, 468, 470, 0, 464, 471,
-	472, 0, 877, 473, 474, 475, 1482, 1483, 476, 477,
-	478, 479, 480, 481, 482, 483, 484, 0, 485, 486,
-	1492, 0, 1420, 487, 0, 488, 489, 490, 491, 492,
-	493, 494, 1453, 1454, 1457, 595, 879, 495, 496, 497,
-	0, 498, 499, 500, 501, 502, 503, 504, 0, 0,
-	0, 505, 506, 507, 508, 0, 867, 341, 343, 878,
-	828, 509, 596, 510, 1463, 1464, 0, 1424, 0, 511,
-	512, 515, 880, 1455, 881, 514, 516, 517, 882, 518,
-	0, 0, 0, 519, 520, 521, 522, 523, 524, 525,
-	0, 526, 528, 527, 0, 530, 1493, 529, 883, 531,
-	532, 884, 0, 533, 534, 535, 536, 537, 538, 541,
-	1446, 1445, 539, 540, 542, 543, 0, 544, 545, 547,
-	550, 546, 548, 549, 551, 552, 565, 566, 553, 554,
-	555, 556, 557, 558, 559, 560, 561, 562, 563, 564,
-	568, 0, 567, 885, 569, 570, 571, 572, 573, 581,
-	583, 584, 579, 580, 582, 585, 586, 588, 589, 576,
-	577, 578, 886, 587, 574, 0, 575, 344, 887, 590,
-	591, 592, 593, 1411, 1456, 594, 1472, 597, 598, 0,
-	0, 599, 0, 600, 0, 0, 602, 603, 604, 0,
-	0, 605, 606, 836, 888, 607, 889, 1487, 608, 609,
-	1398, 610, 611, 612, 613, 614, 615, 616, 617, 618,
-	619, 0, 620, 621, 838, 622, 623, 624, 839, 625,
-	626, 627, 1488, 628, 841, 629, 630, 0, 631, 632,
-	633, 0, 634, 635, 636, 637, 638, 639, 640, 641,
-	642, 643, 1467, 644, 645, 647, 646, 648, 649, 0,
-	650, 0, 651, 652, 653, 0, 0, 0, 0, 0,
-	654, 655, 657, 0, 658, 659, 660, 661, 662, 656,
-	663, 664, 665, 666, 667, 668, 669, 0, 671, 672,
-	670, 673, 674, 890, 675, 676, 677, 678, 679, 1399,
-	680, 0, 681, 682, 690, 691, 692, 683, 684, 686,
-	693, 685, 694, 695, 696, 697, 699, 698, 0, 701,
-	702, 700, 703, 704, 705, 706, 1449, 707, 844, 708,
-	687, 688, 709, 710, 711, 891, 712, 713, 714, 715,
-	716, 717, 718, 719, 720, 1465, 0, 721, 0, 722,
-	723, 724, 725, 726, 727, 729, 689, 730, 731, 732,
-	737, 738, 1496, 733, 734, 735, 736, 1489, 740, 741,
-	742, 743, 0, 744, 745, 0, 739, 728, 0, 746,
-	747, 748, 749, 750, 751, 752, 753, 754, 755, 0,
-	756, 1478, 1479, 1480, 1481, 0, 768, 0, 757, 759,
-	760, 761, 762, 1490, 763, 1491, 1409, 764, 765, 766,
-	767, 758, 769, 770, 0, 0, 771, 772, 773, 774,
-	776, 778, 779, 780, 775, 777, 781, 1450, 782, 0,
-	0, 783, 784, 785, 854, 1475, 1495, 0, 787, 788,
-	786, 789, 790, 793, 791, 792, 857, 796, 513, 797,
-	798, 799, 794, 795, 0, 0, 0, 0, 800, 801,
-	858, 802, 803, 804, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	3285, 0, 0, 0, 0, 0, 0, 3283, 3284, 0,
-	0, 0, 0, 0, 0, 864, 0, 1415, 0, 0,
-	0, 1413, 1460, 1403, 1404, 1405, 1401, 1402, 1414, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 345,
-	346, 348, 347, 349, 350, 351, 352, 0, 353, 354,
-	0, 0, 0, 0, 0, 1452, 1419, 0, 0, 356,
-	0, 355, 0, 357, 358, 359, 874, 360, 361, 362,
-	363, 364, 365, 366, 367, 806, 1466, 0, 368, 1474,
-	369, 1473, 0, 1484, 370, 371, 372, 373, 374, 375,
-	376, 377, 378, 379, 1421, 1451, 0, 380, 1497, 1498,
-	813, 0, 381, 382, 383, 384, 1458, 0, 1439, 0,
-	385, 386, 387, 388, 389, 390, 391, 392, 0, 0,
-	394, 395, 396, 393, 397, 398, 0, 399, 0, 400,
-	401, 402, 403, 404, 405, 406, 0, 407, 408, 409,
-	876, 410, 411, 412, 1442, 1440, 1441, 1448, 1444, 1443,
-	1447, 413, 414, 415, 416, 417, 1477, 418, 420, 421,
-	1471, 422, 1470, 0, 425, 427, 419, 423, 0, 426,
-	424, 428, 429, 0, 430, 431, 432, 433, 0, 0,
-	434, 1469, 436, 0, 437, 438, 440, 439, 0, 441,
-	442, 443, 0, 444, 445, 1397, 446, 447, 448, 450,
-	452, 449, 451, 453, 454, 455, 456, 457, 1485, 1486,
-	458, 459, 1410, 340, 0, 0, 0, 0, 0, 460,
-	461, 462, 1468, 0, 0, 0, 463, 0, 465, 469,
-	466, 467, 468, 470, 0, 464, 471, 472, 0, 877,
-	473, 474, 475, 1482, 1483, 476, 477, 478, 479, 480,
-	481, 482, 483, 484, 0, 485, 486, 1492, 0, 1420,
-	487, 0, 488, 489, 490, 491, 492, 493, 494, 1453,
-	1454, 1457, 595, 879, 495, 496, 497, 0, 498, 499,
-	500, 501, 502, 503, 504, 0, 0, 0, 505, 506,
-	507, 508, 0, 867, 341, 343, 878, 828, 509, 596,
-	510, 1463, 1464, 0, 1424, 0, 511, 512, 515, 880,
-	1455, 881, 514, 516, 517, 882, 518, 0, 0, 0,
-	519, 520, 521, 522, 523, 524, 525, 0, 526, 528,
-	527, 0, 530, 1493, 529, 883, 531, 532, 884, 0,
-	533, 534, 535, 536, 537, 538, 541, 1446, 1445, 539,
-	540, 542, 543, 0, 544, 545, 547, 550, 546, 548,
-	549, 551, 552, 565, 566, 553, 554, 555, 556, 557,
-	558, 559, 560, 561, 562, 563, 564, 568, 0, 567,
-	885, 569, 570, 571, 572, 573, 581, 583, 584, 579,
-	580, 582, 585, 586, 588, 589, 576, 577, 578, 886,
-	587, 574, 0, 575, 344, 887, 590, 591, 592, 593,
-	1411, 1456, 594, 1472, 597, 598, 0, 0, 599, 0,
-	600, 0, 0, 602, 603, 604, 0, 0, 605, 606,
-	836, 888, 607, 889, 1487, 608, 609, 601, 610, 611,
-	612, 613, 614, 615, 616, 617, 618, 619, 0, 620,
-	621, 838, 622, 623, 624, 839, 625, 626, 627, 1488,
-	628, 841, 629, 630, 0, 631, 632, 633, 0, 634,
-	635, 636, 637, 638, 639, 640, 641, 642, 643, 1467,
-	644, 645, 647, 646, 648, 649, 0, 650, 0, 651,
-	652, 653, 0, 0, 0, 0, 0, 654, 655, 657,
-	0, 658, 659, 660, 661, 662, 656, 663, 664, 665,
-	666, 667, 668, 669, 0, 671, 672, 670, 673, 674,
-	890, 675, 676, 677, 678, 679, 4507, 4508, 0, 681,
-	682, 690, 691, 692, 683, 684, 686, 693, 685, 694,
-	695, 696, 697, 699, 698, 0, 701, 702, 700, 703,
-	704, 705, 706, 1449, 707, 844, 708, 687, 688, 709,
-	710, 711, 891, 712, 713, 714, 715, 716, 717, 718,
-	719, 720, 1465, 0, 721, 0, 722, 723, 724, 725,
-	726, 727, 729, 689, 730, 731, 732, 737, 738, 1496,
-	733, 734, 735, 736, 1489, 740, 741, 742, 743, 0,
-	744, 745, 0, 739, 728, 0, 746, 747, 748, 749,
-	750, 751, 752, 753, 754, 755, 0, 756, 1478, 1479,
-	1480, 1481, 0, 768, 0, 757, 759, 760, 761, 762,
-	1490, 763, 1491, 1409, 764, 765, 766, 767, 758, 769,
-	770, 0, 0, 771, 772, 773, 774, 776, 778, 779,
-	780, 775, 777, 781, 1450, 782, 0, 0, 783, 784,
-	785, 854, 1475, 1495, 0, 787, 788, 786, 789, 790,
-	793, 791, 792, 857, 796, 513, 797, 798, 799, 794,
-	795, 0, 0, 0, 0, 800, 801, 858, 802, 803,
-	804, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 2561, 2562, 0, 0, 0, 0,
-	0, 0, 864, 0, 1415, 0, 0, 0, 1413, 1460,
-	1403, 1404, 1405, 1401, 1402, 1414, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 345, 346, 348, 347,
-	349, 350, 351, 352, 0, 353, 354, 0, 0, 0,
-	0, 0, 1452, 1419, 0, 0, 356, 0, 355, 0,
-	357, 358, 359, 874, 360, 361, 362, 363, 364, 365,
-	366, 367, 0, 1466, 0, 368, 1474, 369, 1473, 0,
-	1484, 370, 371, 372, 373, 374, 375, 376, 377, 378,
-	379, 1421, 1451, 1385, 380, 1497, 1498, 813, 0, 381,
-	382, 383, 384, 1458, 0, 1439, 0, 385, 386, 387,
-	388, 389, 390, 391, 392, 0, 0, 394, 395, 396,
-	393, 397, 398, 0, 399, 0, 400, 401, 402, 403,
-	404, 405, 406, 0, 407, 408, 409, 876, 410, 411,
-	6577, 1442, 1440, 1441, 1448, 1444, 1443, 1447, 413, 414,
-	415, 416, 417, 1477, 418, 420, 421, 1471, 422, 1470,
-	1390, 425, 427, 419, 423, 0, 426, 424, 428, 429,
-	0, 430, 431, 432, 433, 0, 0, 434, 1469, 436,
-	0, 437, 438, 440, 439, 0, 441, 442, 443, 0,
-	444, 445, 1397, 446, 447, 448, 450, 452, 449, 451,
-	453, 454, 455, 456, 457, 1485, 1486, 458, 459, 1410,
-	340, 0, 0, 0, 0, 0, 460, 461, 462, 1468,
-	0, 0, 0, 463, 0, 465, 469, 466, 467, 468,
-	470, 0, 464, 471, 472, 0, 877, 473, 474, 475,
-	1482, 1483, 476, 477, 478, 479, 480, 481, 482, 483,
-	484, 0, 485, 486, 1492, 0, 1420, 487, 0, 488,
-	489, 490, 491, 492, 493, 494, 1453, 1454, 1457, 595,
-	0, 495, 496, 497, 0, 498, 499, 500, 501, 502,
-	503, 504, 0, 0, 0, 505, 506, 507, 508, 0,
-	867, 341, 343, 878, 828, 509, 596, 510, 1463, 1464,
-	0, 1424, 0, 511, 512, 515, 0, 1455, 0, 514,
-	516, 517, 882, 518, 0, 0, 0, 519, 520, 521,
-	522, 523, 524, 525, 0, 526, 528, 527, 0, 530,
-	1493, 529, 883, 531, 532, 0, 0, 533, 534, 535,
-	536, 537, 538, 541, 1446, 1445, 539, 540, 542, 543,
-	0, 544, 545, 547, 550, 546, 548, 549, 551, 552,
-	565, 566, 553, 554, 555, 556, 557, 558, 559, 560,
-	561, 562, 563, 564, 568, 0, 567, 885, 569, 570,
-	571, 572, 573, 581, 583, 584, 579, 580, 582, 585,
-	586, 588, 589, 576, 577, 578, 886, 587, 574, 1387,
-	575, 344, 0, 590, 591, 592, 593, 1411, 1456, 594,
-	1472, 597, 598, 0, 0, 599, 0, 600, 0, 0,
-	602, 603, 604, 0, 0, 605, 606, 836, 888, 607,
-	889, 1487, 608, 609, 1398, 610, 611, 612, 613, 614,
-	615, 616, 617, 618, 619, 0, 620, 621, 838, 622,
-	623, 624, 839, 625, 626, 627, 1488, 628, 841, 629,
-	630, 0, 631, 632, 633, 0, 634, 635, 636, 637,
-	638, 639, 640, 641, 642, 643, 1467, 644, 645, 647,
-	646, 648, 649, 0, 650, 0, 651, 652, 653, 0,
-	0, 0, 0, 0, 654, 655, 657, 0, 658, 659,
-	660, 661, 662, 656, 663, 664, 665, 666, 667, 668,
-	669, 0, 671, 672, 670, 673, 674, 890, 675, 676,
-	677, 678, 679, 1399, 680, 0, 681, 682, 690, 691,
-	692, 683, 684, 686, 693, 685, 694, 695, 696, 697,
-	699, 698, 0, 701, 702, 700, 703, 704, 705, 706,
-	1449, 707, 844, 708, 687, 688, 709, 710, 711, 0,
-	712, 713, 714, 715, 716, 717, 718, 719, 720, 1465,
-	0, 721, 0, 722, 723, 724, 725, 726, 727, 729,
-	689, 730, 731, 732, 737, 738, 1496, 733, 734, 735,
-	736, 1489, 740, 741, 742, 743, 0, 744, 745, 1384,
-	739, 728, 0, 746, 747, 748, 749, 750, 751, 752,
-	753, 754, 755, 0, 756, 1478, 1479, 1480, 1481, 0,
-	768, 0, 757, 759, 760, 761, 762, 1490, 763, 1491,
-	1409, 764, 765, 766, 767, 758, 6576, 770, 0, 1391,
-	771, 772, 773, 774, 776, 778, 779, 780, 775, 777,
-	781, 1450, 782, 0, 0, 783, 784, 785, 854, 1475,
-	1495, 0, 787, 788, 786, 789, 790, 793, 791, 792,
-	857, 796, 513, 797, 798, 799, 794, 795, 0, 0,
-	0, 0, 800, 801, 858, 802, 803, 804, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 1381, 1382, 0, 0, 0, 0, 0, 0, 864,
-	0, 1415, 0, 0, 3304, 1413, 1460, 1403, 1404, 1405,
-	1401, 1402, 1414, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 345, 346, 348, 347, 349, 350, 351,
-	352, 0, 353, 354, 0, 0, 0, 0, 0, 1452,
-	1419, 0, 0, 356, 0, 355, 0, 357, 358, 359,
-	874, 360, 361, 362, 363, 364, 365, 366, 367, 806,
-	1466, 0, 368, 1474, 369, 1473, 0, 1484, 370, 371,
-	372, 373, 374, 375, 376, 377, 378, 379, 0, 1451,
-	0, 380, 1497, 1498, 813, 0, 381, 382, 383, 384,
-	1458, 0, 1439, 0, 385, 386, 387, 388, 389, 390,
-	391, 392, 0, 0, 394, 395, 396, 393, 397, 398,
-	0, 399, 0, 400, 401, 402, 403, 404, 405, 406,
-	0, 407, 408, 409, 876, 410, 411, 412, 1442, 1440,
-	1441, 1448, 1444, 1443, 1447, 413, 414, 415, 416, 417,
-	1477, 418, 420, 421, 1471, 422, 1470, 0, 425, 427,
-	419, 423, 0, 426, 424, 428, 429, 0, 430, 431,
-	432, 433, 0, 0, 434, 1469, 436, 0, 437, 438,
-	440, 439, 0, 441, 442, 443, 0, 444, 445, 817,
-	446, 447, 448, 450, 452, 449, 451, 453, 454, 455,
-	456, 457, 1485, 1486, 458, 459, 1410, 340, 0, 0,
-	0, 0, 0, 460, 461, 462, 1468, 0, 0, 0,
-	463, 0, 465, 469, 466, 467, 468, 470, 0, 464,
-	471, 472, 0, 877, 473, 474, 475, 1482, 1483, 476,
-	477, 478, 479, 480, 481, 482, 483, 484, 0, 485,
-	486, 1492, 0, 1420, 487, 0, 488, 489, 490, 491,
-	492, 493, 494, 1453, 1454, 1457, 595, 879, 495, 496,
-	497, 0, 498, 499, 500, 501, 502, 503, 504, 0,
-	0, 0, 505, 506, 507, 508, 0, 867, 341, 343,
-	878, 828, 509, 596, 510, 1463, 1464, 0, 1424, 0,
-	511, 512, 515, 880, 1455, 881, 514, 516, 517, 882,
-	518, 0, 0, 0, 519, 520, 521, 522, 523, 524,
-	525, 0, 526, 528, 527, 0, 530, 1493, 529, 883,
-	531, 532, 884, 0, 533, 534, 535, 536, 537, 538,
-	541, 1446, 1445, 539, 540, 542, 543, 0, 544, 545,
-	547, 550, 546, 548, 549, 551, 552, 565, 566, 553,
-	554, 555, 556, 557, 558, 559, 560, 561, 562, 563,
-	564, 568, 0, 567, 885, 569, 570, 571, 572, 573,
-	581, 583, 584, 579, 580, 582, 585, 586, 588, 589,
-	576, 577, 578, 886, 587, 574, 0, 575, 344, 887,
-	590, 591, 592, 593, 1411, 1456, 594, 1472, 597, 598,
-	0, 0, 599, 0, 600, 0, 0, 602, 603, 604,
-	0, 0, 605, 606, 836, 888, 607, 889, 1487, 608,
-	609, 601, 610, 611, 612, 613, 614, 615, 616, 617,
-	618, 619, 0, 620, 621, 838, 622, 623, 624, 839,
-	625, 626, 627, 1488, 628, 841, 629, 630, 0, 631,
-	632, 633, 0, 634, 635, 636, 637, 638, 639, 640,
-	641, 642, 643, 1467, 644, 645, 647, 646, 648, 649,
-	0, 650, 0, 651, 652, 653, 0, 0, 0, 0,
-	0, 654, 655, 657, 0, 658, 659, 660, 661, 662,
-	656, 663, 664, 665, 666, 667, 668, 669, 0, 671,
-	672, 670, 673, 674, 890, 675, 676, 677, 678, 679,
-	1399, 680, 0, 681, 682, 690, 691, 692, 683, 684,
-	686, 693, 685, 694, 695, 696, 697, 699, 698, 0,
-	701, 702, 700, 703, 704, 705, 706, 1449, 707, 844,
-	708, 687, 688, 709, 710, 711, 891, 712, 713, 714,
-	715, 716, 717, 718, 719, 720, 1465, 0, 721, 0,
-	722, 723, 724, 725, 726, 727, 729, 689, 730, 731,
-	732, 737, 738, 1496, 733, 734, 735, 736, 1489, 740,
-	741, 742, 743, 0, 744, 745, 0, 739, 728, 0,
-	746, 747, 748, 749, 750, 751, 752, 753, 754, 755,
-	0, 756, 1478, 1479, 1480, 1481, 0, 768, 0, 757,
-	759, 760, 761, 762, 1490, 763, 1491, 1409, 764, 765,
-	766, 767, 758, 769, 770, 0, 0, 771, 772, 773,
-	774, 776, 778, 779, 780, 775, 777, 781, 1450, 782,
-	0, 0, 783, 784, 785, 854, 1475, 1495, 0, 787,
-	788, 786, 789, 790, 793, 791, 792, 857, 796, 513,
-	797, 798, 799, 794, 795, 0, 0, 0, 0, 800,
-	801, 858, 802, 803, 804, 2040, 0, 1460, 1403, 1404,
-	1405, 1401, 1402, 1414, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 345, 346, 348, 347, 349, 350,
-	351, 352, 0, 353, 354, 0, 1629, 0, 1415, 0,
-	1452, 1419, 1413, 0, 356, 0, 355, 0, 357, 358,
-	359, 874, 360, 361, 362, 363, 364, 365, 366, 367,
-	806, 1466, 0, 368, 1474, 369, 1473, 0, 1484, 370,
-	371, 372, 373, 374, 375, 376, 377, 378, 379, 0,
-	1451, 0, 380, 1497, 1498, 813, 0, 381, 382, 383,
-	384, 1458, 0, 1439, 0, 385, 386, 387, 388, 389,
-	390, 391, 392, 0, 0, 394, 395, 396, 393, 397,
-	398, 0, 399, 0, 400, 401, 402, 403, 404, 405,
-	406, 0, 407, 408, 409, 876, 410, 411, 412, 1442,
-	1440, 1441, 1448, 1444, 1443, 1447, 413, 414, 415, 416,
-	417, 1477, 418, 420, 421, 1471, 422, 1470, 0, 425,
-	427, 419, 423, 0, 426, 424, 428, 429, 0, 430,
-	431, 432, 433, 0, 0, 434, 1469, 436, 0, 437,
-	438, 440, 439, 0, 441, 442, 443, 0, 444, 445,
-	817, 446, 447, 448, 450, 452, 449, 451, 453, 454,
-	455, 456, 457, 1485, 1486, 458, 459, 1410, 340, 0,
-	0, 0, 0, 0, 460, 461, 462, 1468, 0, 0,
-	0, 463, 0, 465, 469, 466, 467, 468, 470, 0,
-	464, 471, 472, 0, 877, 473, 474, 475, 1482, 1483,
-	476, 477, 478, 479, 480, 481, 482, 483, 484, 0,
-	485, 486, 1492, 0, 1420, 487, 0, 488, 489, 490,
-	491, 492, 493, 494, 2039, 1454, 1457, 595, 879, 495,
-	496, 497, 0, 498, 499, 500, 501, 502, 503, 504,
-	0, 0, 0, 505, 506, 507, 508, 0, 867, 341,
-	343, 878, 828, 509, 596, 510, 1463, 1464, 0, 1424,
-	0, 511, 512, 515, 880, 1455, 881, 514, 516, 517,
-	882, 518, 0, 0, 0, 519, 520, 521, 522, 523,
-	524, 525, 0, 526, 528, 527, 0, 530, 1493, 529,
-	883, 531, 532, 884, 0, 533, 534, 535, 536, 537,
-	538, 541, 1446, 1445, 539, 540, 542, 543, 0, 544,
-	545, 547, 550, 546, 548, 549, 551, 552, 565, 566,
-	553, 554, 555, 556, 557, 558, 559, 560, 561, 562,
-	563, 564, 568, 0, 567, 885, 569, 570, 571, 572,
-	573, 581, 583, 584, 579, 580, 582, 585, 586, 588,
-	589, 576, 577, 578, 886, 587, 574, 0, 575, 344,
-	887, 590, 591, 592, 593, 1411, 1456, 594, 1472, 597,
-	598, 0, 0, 599, 0, 600, 0, 0, 602, 603,
-	604, 0, 0, 605, 606, 836, 888, 607, 889, 1487,
-	608, 609, 601, 610, 611, 612, 613, 614, 615, 616,
-	617, 618, 619, 0, 620, 621, 838, 622, 623, 624,
-	839, 625, 626, 627, 1488, 628, 841, 629, 630, 0,
-	631, 632, 633, 0, 634, 635, 636, 637, 638, 639,
-	640, 641, 642, 643, 1467, 644, 645, 647, 646, 648,
-	649, 0, 650, 0, 651, 652, 653, 0, 0, 0,
-	0, 0, 654, 655, 657, 0, 658, 659, 660, 661,
-	662, 656, 663, 664, 665, 666, 667, 668, 669, 0,
-	671, 672, 670, 673, 674, 890, 675, 676, 677, 678,
-	679, 1399, 680, 0, 681, 682, 690, 691, 692, 683,
-	684, 686, 693, 685, 694, 695, 696, 697, 699, 698,
-	0, 701, 702, 700, 703, 704, 705, 706, 1449, 707,
-	844, 708, 687, 688, 709, 710, 711, 891, 712, 713,
-	714, 715, 716, 717, 718, 719, 720, 1465, 0, 721,
-	0, 722, 723, 724, 725, 726, 727, 729, 689, 730,
-	731, 732, 737, 738, 1496, 733, 734, 735, 736, 1489,
-	740, 741, 742, 743, 0, 744, 745, 0, 739, 728,
-	0, 746, 747, 748, 749, 750, 751, 752, 753, 754,
-	755, 0, 756, 1478, 1479, 1480, 1481, 0, 768, 0,
-	757, 759, 760, 761, 762, 1490, 763, 1491, 1409, 764,
-	765, 766, 767, 758, 769, 770, 0, 0, 771, 772,
-	773, 774, 776, 778, 779, 780, 775, 777, 781, 1450,
-	782, 0, 0, 783, 784, 785, 854, 1475, 1495, 0,
-	787, 788, 786, 789, 790, 793, 791, 792, 857, 796,
-	513, 797, 798, 799, 794, 795, 0, 0, 0, 0,
-	800, 801, 858, 802, 803, 804, 1988, 0, 1460, 1403,
-	1404, 1405, 1401, 1402, 1414, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 345, 346, 348, 347, 349,
-	350, 351, 352, 0, 353, 354, 0, 864, 0, 1415,
-	0, 1452, 1419, 1413, 0, 356, 0, 355, 0, 357,
-	358, 359, 874, 360, 361, 362, 363, 364, 365, 366,
-	367, 806, 1466, 0, 368, 1474, 369, 1473, 0, 1484,
-	370, 371, 372, 373, 374, 375, 376, 377, 378, 379,
-	0, 1451, 0, 380, 1497, 1498, 813, 0, 381, 382,
-	383, 384, 1458, 0, 1439, 0, 385, 386, 387, 388,
-	389, 390, 391, 392, 0, 0, 394, 395, 396, 393,
-	397, 398, 0, 399, 0, 400, 401, 402, 403, 404,
-	405, 406, 0, 407, 408, 409, 876, 410, 411, 412,
-	1442, 1440, 1441, 1448, 1444, 1443, 1447, 413, 414, 415,
-	416, 417, 1477, 418, 420, 421, 1471, 422, 1470, 0,
-	425, 427, 419, 423, 0, 426, 424, 428, 429, 0,
-	430, 431, 432, 433, 0, 0, 434, 1469, 436, 0,
-	437, 438, 440, 439, 0, 441, 442, 443, 0, 444,
-	445, 817, 446, 447, 448, 450, 452, 449, 451, 453,
-	454, 455, 456, 457, 1485, 1486, 458, 459, 1410, 340,
-	0, 0, 0, 0, 0, 460, 461, 462, 1468, 0,
-	0, 0, 463, 0, 465, 469, 466, 467, 468, 470,
-	0, 464, 471, 472, 0, 877, 473, 474, 475, 1482,
-	1483, 476, 477, 478, 479, 480, 481, 482, 483, 484,
-	0, 485, 486, 1492, 0, 1420, 487, 0, 488, 489,
-	490, 491, 492, 493, 494, 1453, 1454, 1457, 595, 879,
-	495, 496, 497, 0, 498, 499, 500, 501, 502, 503,
-	504, 0, 0, 0, 505, 506, 507, 508, 0, 867,
-	341, 343, 878, 828, 509, 596, 510, 1463, 1464, 0,
-	1424, 0, 511, 512, 515, 880, 1455, 881, 514, 516,
-	517, 882, 518, 0, 0, 0, 519, 520, 521, 522,
-	523, 524, 525, 0, 526, 528, 527, 0, 530, 1493,
-	529, 883, 531, 532, 884, 0, 533, 534, 535, 536,
-	537, 538, 541, 1446, 1445, 539, 540, 542, 543, 0,
-	544, 545, 547, 550, 546, 548, 549, 551, 552, 565,
-	566, 553, 554, 555, 556, 557, 558, 559, 560, 561,
-	562, 563, 564, 568, 0, 567, 885, 569, 570, 571,
-	572, 573, 581, 583, 584, 579, 580, 582, 585, 586,
-	588, 589, 576, 577, 578, 886, 587, 574, 0, 575,
-	344, 887, 590, 591, 592, 593, 1411, 1456, 594, 1472,
-	597, 598, 0, 0, 599, 0, 600, 0, 0, 602,
-	603, 604, 0, 0, 605, 606, 836, 888, 607, 889,
-	1487, 608, 609, 601, 610, 611, 612, 613, 614, 615,
-	616, 617, 618, 619, 0, 620, 621, 838, 622, 623,
-	624, 839, 625, 626, 627, 1488, 628, 841, 629, 630,
-	0, 631, 632, 633, 0, 634, 635, 636, 637, 638,
-	639, 640, 641, 642, 643, 1467, 644, 645, 647, 646,
-	648, 649, 0, 650, 0, 651, 652, 653, 0, 0,
-	0, 0, 0, 654, 655, 657, 0, 658, 659, 660,
-	661, 662, 656, 663, 664, 665, 666, 667, 668, 669,
-	0, 671, 672, 670, 673, 674, 890, 675, 676, 677,
-	678, 679, 1399, 680, 0, 681, 682, 690, 691, 692,
-	683, 684, 686, 693, 685, 694, 695, 696, 697, 699,
-	698, 0, 701, 702, 700, 703, 704, 705, 706, 1449,
-	707, 844, 708, 687, 688, 709, 710, 711, 891, 712,
-	713, 714, 715, 716, 717, 718, 719, 720, 1465, 0,
-	721, 0, 722, 723, 724, 725, 726, 727, 729, 689,
-	730, 731, 732, 737, 738, 1496, 733, 734, 735, 736,
-	1489, 740, 741, 742, 743, 0, 744, 745, 0, 739,
-	728, 0, 746, 747, 748, 749, 750, 751, 752, 753,
-	754, 755, 0, 756, 1478, 1479, 1480, 1481, 0, 768,
-	0, 757, 759, 760, 761, 762, 1490, 763, 1491, 1409,
-	764, 765, 766, 767, 758, 769, 770, 0, 0, 771,
-	772, 773, 774, 776, 778, 779, 780, 775, 777, 781,
-	1450, 782, 0, 0, 783, 784, 785, 854, 1475, 1495,
-	0, 787, 788, 786, 789, 790, 793, 791, 792, 857,
-	796, 513, 797, 798, 799, 794, 795, 0, 0, 0,
-	0, 800, 801, 858, 802, 803, 804, 1627, 0, 1460,
-	1403, 1404, 1405, 1401, 1402, 1414, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 345, 346, 348, 347,
-	349, 350, 351, 352, 0, 353, 354, 0, 1629, 0,
-	1415, 0, 1452, 1419, 1413, 0, 356, 0, 355, 0,
-	357, 358, 359, 874, 360, 361, 362, 363, 364, 365,
-	366, 367, 806, 1466, 0, 368, 1474, 369, 1473, 0,
-	1484, 370, 371, 372, 373, 374, 375, 376, 377, 378,
-	379, 0, 1451, 0, 380, 1497, 1498, 813, 0, 381,
-	382, 383, 384, 1458, 0, 1439, 0, 385, 386, 387,
-	388, 389, 390, 391, 392, 0, 0, 394, 395, 396,
-	393, 397, 398, 0, 399, 0, 400, 401, 402, 403,
-	404, 405, 406, 0, 407, 408, 409, 876, 410, 411,
-	412, 1442, 1440, 1441, 1448, 1444, 1443, 1447, 413, 414,
-	415, 416, 417, 1477, 418, 420, 421, 1471, 422, 1470,
-	0, 425, 427, 419, 423, 0, 426, 424, 428, 429,
-	0, 430, 431, 432, 433, 0, 0, 434, 1469, 436,
-	0, 437, 438, 440, 439, 0, 441, 442, 443, 0,
-	444, 445, 817, 446, 447, 448, 450, 452, 449, 451,
-	453, 454, 455, 456, 457, 1485, 1486, 458, 459, 1410,
-	340, 0, 0, 0, 0, 0, 460, 461, 462, 1468,
-	0, 0, 0, 463, 0, 465, 469, 466, 467, 468,
-	470, 0, 464, 471, 472, 0, 877, 473, 474, 475,
-	1482, 1483, 476, 477, 478, 479, 480, 481, 482, 483,
-	484, 0, 485, 486, 1492, 0, 1420, 487, 0, 488,
-	489, 490, 491, 492, 493, 494, 1626, 1454, 1457, 595,
-	879, 495, 496, 497, 0, 498, 499, 500, 501, 502,
-	503, 504, 0, 0, 0, 505, 506, 507, 508, 0,
-	867, 341, 343, 878, 828, 509, 596, 510, 1463, 1464,
-	0, 1424, 0, 511, 512, 515, 880, 1455, 881, 514,
-	516, 517, 882, 518, 0, 0, 0, 519, 520, 521,
-	522, 523, 524, 525, 0, 526, 528, 527, 0, 530,
-	1493, 529, 883, 531, 532, 884, 0, 533, 534, 535,
-	536, 537, 538, 541, 1446, 1445, 539, 540, 542, 543,
-	0, 544, 545, 547, 550, 546, 548, 549, 551, 552,
-	565, 566, 553, 554, 555, 556, 557, 558, 559, 560,
-	561, 562, 563, 564, 568, 0, 567, 885, 569, 570,
-	571, 572, 573, 581, 583, 584, 579, 580, 582, 585,
-	586, 588, 589, 576, 577, 578, 886, 587, 574, 0,
-	575, 344, 887, 590, 591, 592, 593, 1411, 1456, 594,
-	1472, 597, 598, 0, 0, 599, 0, 600, 0, 0,
-	602, 603, 604, 0, 0, 605, 606, 836, 888, 607,
-	889, 1487, 608, 609, 601, 610, 611, 612, 613, 614,
-	615, 616, 617, 618, 619, 0, 620, 621, 838, 622,
-	623, 624, 839, 625, 626, 627, 1488, 628, 841, 629,
-	630, 0, 631, 632, 633, 0, 634, 635, 636, 637,
-	638, 639, 640, 641, 642, 643, 1467, 644, 645, 647,
-	646, 648, 649, 0, 650, 0, 651, 652, 653, 0,
-	0, 0, 0, 0, 654, 655, 657, 0, 658, 659,
-	660, 661, 662, 656, 663, 664, 665, 666, 667, 668,
-	669, 0, 671, 672, 670, 673, 674, 890, 675, 676,
-	677, 678, 679, 1399, 680, 0, 681, 682, 690, 691,
-	692, 683, 684, 686, 693, 685, 694, 695, 696, 697,
-	699, 698, 0, 701, 702, 700, 703, 704, 705, 706,
-	1449, 707, 844, 708, 687, 688, 709, 710, 711, 891,
-	712, 713, 714, 715, 716, 717, 718, 719, 720, 1465,
-	0, 721, 0, 722, 723, 724, 725, 726, 727, 729,
-	689, 730, 731, 732, 737, 738, 1496, 733, 734, 735,
-	736, 1489, 740, 741, 742, 743, 0, 744, 745, 0,
-	739, 728, 0, 746, 747, 748, 749, 750, 751, 752,
-	753, 754, 755, 0, 756, 1478, 1479, 1480, 1481, 0,
-	768, 0, 757, 759, 760, 761, 762, 1490, 763, 1491,
-	1409, 764, 765, 766, 767, 758, 769, 770, 0, 0,
-	771, 772, 773, 774, 776, 778, 779, 780, 775, 777,
-	781, 1450, 782, 0, 0, 783, 784, 785, 854, 1475,
-	1495, 0, 787, 788, 786, 789, 790, 793, 791, 792,
-	857, 796, 513, 797, 798, 799, 794, 795, 0, 0,
-	0, 0, 800, 801, 858, 802, 803, 804, 0, 1460,
-	1403, 1404, 1405, 1401, 1402, 1414, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 345, 346, 348, 347,
-	349, 350, 351, 352, 0, 353, 354, 0, 0, 1629,
-	0, 1415, 1452, 1419, 0, 1413, 356, 0, 355, 0,
-	357, 358, 359, 874, 360, 361, 362, 363, 364, 365,
-	366, 367, 806, 1466, 0, 368, 1474, 369, 1473, 0,
-	1484, 370, 371, 372, 373, 374, 375, 376, 377, 378,
-	379, 0, 1451, 0, 380, 1497, 1498, 813, 0, 381,
-	382, 383, 384, 1458, 0, 1439, 0, 385, 386, 387,
-	388, 389, 390, 391, 392, 0, 0, 394, 395, 396,
-	393, 397, 398, 0, 399, 0, 400, 401, 402, 403,
-	404, 405, 406, 0, 407, 408, 409, 876, 410, 411,
-	412, 1442, 1440, 1441, 1448, 1444, 1443, 1447, 413, 414,
-	415, 416, 417, 1477, 418, 420, 421, 1471, 422, 1470,
-	0, 425, 427, 419, 423, 0, 426, 424, 428, 429,
-	0, 430, 431, 432, 433, 0, 0, 434, 1469, 436,
-	0, 437, 438, 440, 439, 0, 441, 442, 443, 0,
-	444, 445, 817, 446, 447, 448, 450, 452, 449, 451,
-	453, 454, 455, 456, 457, 1485, 1486, 458, 459, 1410,
-	340, 0, 0, 0, 0, 0, 460, 461, 462, 1468,
-	0, 0, 0, 463, 0, 465, 469, 466, 467, 468,
-	470, 0, 464, 471, 472, 0, 877, 473, 474, 475,
-	1482, 1483, 476, 477, 478, 479, 480, 481, 482, 483,
-	484, 0, 485, 486, 1492, 0, 1420, 487, 0, 488,
-	489, 490, 491, 492, 493, 494, 1453, 1454, 1457, 595,
-	879, 495, 496, 497, 0, 498, 499, 500, 501, 502,
-	503, 504, 0, 0, 0, 505, 506, 507, 508, 0,
-	867, 341, 343, 878, 828, 509, 596, 510, 1463, 1464,
-	0, 1424, 0, 511, 512, 515, 880, 1455, 881, 514,
-	516, 517, 882, 518, 0, 0, 0, 519, 520, 521,
-	522, 523, 524, 525, 0, 526, 528, 527, 0, 530,
-	1493, 529, 883, 531, 532, 884, 0, 533, 534, 535,
-	536, 537, 538, 541, 1446, 1445, 539, 540, 542, 543,
-	0, 544, 545, 547, 550, 546, 548, 549, 551, 552,
-	565, 566, 553, 554, 555, 556, 557, 558, 559, 560,
-	561, 562, 563, 564, 568, 0, 567, 885, 569, 570,
-	571, 572, 573, 581, 583, 584, 579, 580, 582, 585,
-	586, 588, 589, 576, 577, 578, 886, 587, 574, 0,
-	575, 344, 887, 590, 591, 592, 593, 1411, 1456, 594,
-	1472, 597, 598, 0, 0, 599, 0, 600, 0, 0,
-	602, 603, 604, 0, 0, 605, 606, 836, 888, 607,
-	889, 1487, 608, 609, 601, 610, 611, 612, 613, 614,
-	615, 616, 617, 618, 619, 0, 620, 621, 838, 622,
-	623, 624, 839, 625, 626, 627, 1488, 628, 841, 629,
-	630, 0, 631, 632, 633, 0, 634, 635, 636, 637,
-	638, 639, 640, 641, 642, 643, 1467, 644, 645, 647,
-	646, 648, 649, 0, 650, 0, 651, 652, 653, 0,
-	0, 0, 0, 0, 654, 655, 657, 0, 658, 659,
-	660, 661, 662, 656, 663, 664, 665, 666, 667, 668,
-	669, 0, 671, 672, 670, 673, 674, 890, 675, 676,
-	677, 678, 679, 1399, 680, 0, 681, 682, 690, 691,
-	692, 683, 684, 686, 693, 685, 694, 695, 696, 697,
-	699, 698, 0, 701, 702, 700, 703, 704, 705, 706,
-	1449, 707, 844, 708, 687, 688, 709, 710, 711, 891,
-	712, 713, 714, 715, 716, 717, 718, 719, 720, 1465,
-	0, 721, 0, 722, 723, 724, 725, 726, 727, 729,
-	689, 730, 731, 732, 737, 738, 1496, 733, 734, 735,
-	736, 1489, 740, 741, 742, 743, 0, 744, 745, 0,
-	739, 728, 0, 746, 747, 748, 749, 750, 751, 752,
-	753, 754, 755, 0, 756, 1478, 1479, 1480, 1481, 0,
-	768, 0, 757, 759, 760, 761, 762, 1490, 763, 1491,
-	1409, 764, 765, 766, 767, 758, 769, 770, 0, 0,
-	771, 772, 773, 774, 776, 778, 779, 780, 775, 777,
-	781, 1450, 782, 0, 0, 783, 784, 785, 854, 1475,
-	1495, 0, 787, 788, 786, 789, 790, 793, 791, 792,
-	857, 796, 513, 797, 798, 799, 794, 795, 0, 0,
-	0, 0, 800, 801, 858, 802, 803, 804, 0, 1460,
-	1403, 1404, 1405, 1401, 1402, 1414, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 345, 346, 348, 347,
-	349, 350, 351, 352, 0, 353, 354, 0, 0, 864,
-	0, 1415, 1452, 1419, 0, 1413, 356, 0, 355, 0,
-	357, 358, 359, 874, 360, 361, 362, 363, 364, 365,
-	366, 367, 806, 1466, 0, 368, 1474, 369, 1473, 0,
-	1484, 370, 371, 372, 373, 374, 375, 376, 377, 378,
-	379, 0, 1451, 0, 380, 1497, 1498, 813, 0, 381,
-	382, 383, 384, 1458, 0, 1439, 0, 385, 386, 387,
-	388, 389, 390, 391, 392, 0, 0, 394, 395, 396,
-	393, 397, 398, 0, 399, 0, 400, 401, 402, 403,
-	404, 405, 406, 0, 407, 408, 409, 876, 410, 411,
-	412, 1442, 1440, 1441, 1448, 1444, 1443, 1447, 413, 414,
-	415, 416, 417, 1477, 418, 420, 421, 1471, 422, 1470,
-	0, 425, 427, 419, 423, 0, 426, 424, 428, 429,
-	0, 430, 431, 432, 433, 0, 0, 434, 1469, 436,
-	0, 437, 438, 440, 439, 0, 441, 442, 443, 0,
-	444, 445, 817, 446, 447, 448, 450, 452, 449, 451,
-	453, 454, 455, 456, 457, 1485, 1486, 458, 459, 1410,
-	340, 0, 0, 0, 0, 0, 460, 461, 462, 1468,
-	0, 0, 0, 463, 0, 465, 469, 466, 467, 468,
-	470, 0, 464, 471, 472, 0, 877, 473, 474, 475,
-	1482, 1483, 476, 477, 478, 479, 480, 481, 482, 483,
-	484, 0, 485, 486, 1492, 0, 1420, 487, 0, 488,
-	489, 490, 491, 492, 493, 494, 1453, 1454, 1457, 595,
-	879, 495, 496, 497, 0, 498, 499, 500, 501, 502,
-	503, 504, 0, 0, 0, 505, 506, 507, 508, 0,
-	867, 341, 343, 878, 828, 509, 596, 510, 1463, 1464,
-	0, 1424, 0, 511, 512, 515, 880, 1455, 881, 514,
-	516, 517, 882, 518, 0, 0, 0, 519, 520, 521,
-	522, 523, 524, 525, 0, 526, 528, 527, 0, 530,
-	1493, 529, 883, 531, 532, 884, 0, 533, 534, 535,
-	536, 537, 538, 541, 1446, 1445, 539, 540, 542, 543,
-	0, 544, 545, 547, 550, 546, 548, 549, 551, 552,
-	565, 566, 553, 554, 555, 556, 557, 558, 559, 560,
-	561, 562, 563, 564, 568, 0, 567, 885, 569, 570,
-	571, 572, 573, 581, 583, 584, 579, 580, 582, 585,
-	586, 588, 589, 576, 577, 578, 886, 587, 574, 0,
-	575, 344, 887, 590, 591, 592, 593, 1411, 1456, 594,
-	1472, 597, 598, 0, 0, 599, 0, 600, 0, 0,
-	602, 603, 604, 0, 0, 605, 606, 836, 888, 607,
-	889, 1487, 608, 609, 601, 610, 611, 612, 613, 614,
-	615, 616, 617, 618, 619, 0, 620, 621, 838, 622,
-	623, 624, 839, 625, 626, 627, 1488, 628, 841, 629,
-	630, 0, 631, 632, 633, 0, 634, 635, 636, 637,
-	638, 639, 640, 641, 642, 643, 1467, 644, 645, 647,
-	646, 648, 649, 0, 650, 0, 651, 652, 653, 0,
-	0, 0, 0, 0, 654, 655, 657, 0, 658, 659,
-	660, 661, 662, 656, 663, 664, 665, 666, 667, 668,
-	669, 0, 671, 672, 670, 673, 674, 890, 675, 676,
-	677, 678, 679, 1399, 680, 0, 681, 682, 690, 691,
-	692, 683, 684, 686, 693, 685, 694, 695, 696, 697,
-	699, 698, 0, 701, 702, 700, 703, 704, 705, 706,
-	1449, 707, 844, 708, 687, 688, 709, 710, 711, 891,
-	712, 713, 714, 715, 716, 717, 718, 719, 720, 1465,
-	0, 721, 0, 722, 723, 724, 725, 726, 727, 729,
-	689, 730, 731, 732, 737, 738, 1496, 733, 734, 735,
-	736, 1489, 740, 741, 742, 743, 0, 744, 745, 0,
-	739, 728, 0, 746, 747, 748, 749, 750, 751, 752,
-	753, 754, 755, 0, 756, 1478, 1479, 1480, 1481, 0,
-	768, 0, 757, 759, 760, 761, 762, 1490, 763, 1491,
-	1409, 764, 765, 766, 767, 758, 769, 770, 0, 0,
-	771, 772, 773, 774, 776, 778, 779, 780, 775, 777,
-	781, 1450, 782, 0, 0, 783, 784, 785, 854, 1475,
-	1495, 0, 787, 788, 786, 789, 790, 793, 791, 792,
-	857, 796, 513, 797, 798, 799, 794, 795, 0, 0,
-	0, 0, 800, 801, 858, 802, 803, 804, 1372, 0,
-	868, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 345, 346, 348,
-	347, 349, 350, 351, 352, 0, 353, 354, 0, 1629,
-	0, 1415, 0, 1452, 0, 1413, 0, 356, 0, 355,
-	0, 357, 358, 359, 874, 360, 361, 362, 363, 364,
-	365, 366, 367, 806, 807, 0, 368, 808, 369, 809,
-	0, 810, 370, 371, 372, 373, 374, 375, 376, 377,
-	378, 379, 0, 1451, 0, 380, 811, 812, 813, 0,
-	381, 382, 383, 384, 1458, 0, 1439, 0, 385, 386,
-	387, 388, 389, 390, 391, 392, 0, 0, 394, 395,
-	396, 393, 397, 398, 0, 399, 0, 400, 401, 402,
-	403, 404, 405, 406, 0, 407, 408, 409, 876, 410,
-	411, 412, 1442, 1440, 1441, 1448, 1444, 1443, 1447, 413,
-	414, 415, 416, 417, 0, 418, 420, 421, 815, 422,
-	816, 0, 425, 427, 419, 423, 0, 426, 424, 428,
-	429, 0, 430, 431, 432, 433, 0, 0, 434, 435,
-	436, 0, 437, 438, 440, 439, 0, 441, 442, 443,
-	0, 444, 445, 817, 446, 447, 448, 450, 452, 449,
-	451, 453, 454, 455, 456, 457, 1485, 1486, 458, 459,
-	0, 340, 0, 0, 0, 0, 0, 460, 461, 462,
-	820, 0, 0, 0, 463, 0, 465, 469, 466, 467,
-	468, 470, 0, 464, 471, 472, 0, 877, 473, 474,
-	475, 821, 822, 476, 477, 478, 479, 480, 481, 482,
-	483, 484, 0, 485, 486, 1492, 0, 824, 487, 0,
-	488, 489, 490, 491, 492, 493, 494, 1453, 1454, 1457,
-	595, 879, 495, 496, 497, 0, 498, 499, 500, 501,
-	502, 503, 504, 0, 0, 0, 505, 506, 507, 508,
-	0, 867, 341, 343, 878, 828, 509, 596, 510, 829,
-	830, 0, 831, 0, 511, 512, 515, 880, 1455, 881,
-	514, 516, 517, 882, 518, 0, 0, 0, 519, 520,
-	521, 522, 523, 524, 525, 1522, 526, 528, 527, 0,
-	530, 1493, 529, 883, 531, 532, 884, 0, 533, 534,
-	535, 536, 537, 538, 541, 1446, 1445, 539, 540, 542,
-	543, 0, 544, 545, 547, 550, 546, 548, 549, 551,
-	552, 565, 566, 553, 554, 555, 556, 557, 558, 559,
-	560, 561, 562, 563, 564, 568, 0, 567, 885, 569,
-	570, 571, 572, 573, 581, 583, 584, 579, 580, 582,
-	585, 586, 588, 589, 576, 577, 578, 886, 587, 574,
-	0, 575, 344, 887, 590, 591, 592, 593, 0, 1456,
-	594, 835, 597, 598, 0, 0, 599, 0, 600, 0,
-	1528, 602, 603, 604, 0, 0, 605, 606, 836, 888,
-	607, 889, 1487, 608, 609, 601, 610, 611, 612, 613,
-	614, 615, 616, 617, 618, 619, 0, 620, 621, 838,
-	622, 623, 624, 839, 625, 626, 627, 1488, 628, 841,
-	629, 630, 0, 631, 632, 633, 0, 634, 635, 636,
-	637, 638, 639, 640, 641, 642, 643, 842, 644, 645,
-	647, 646, 648, 649, 0, 650, 0, 651, 652, 653,
-	0, 0, 0, 0, 0, 654, 655, 657, 0, 658,
-	659, 660, 661, 662, 656, 663, 664, 665, 666, 667,
-	668, 669, 0, 671, 672, 670, 673, 674, 890, 675,
-	676, 677, 678, 679, 843, 1530, 0, 681, 682, 690,
-	691, 692, 683, 684, 686, 693, 685, 694, 695, 696,
-	697, 699, 698, 295, 701, 702, 700, 703, 704, 705,
-	706, 1449, 707, 844, 708, 687, 688, 709, 710, 711,
-	891, 712, 713, 714, 715, 716, 717, 718, 719, 720,
-	845, 0, 721, 0, 722, 723, 724, 725, 726, 727,
-	729, 689, 730, 731, 732, 737, 738, 846, 733, 734,
-	735, 736, 1489, 740, 741, 742, 743, 0, 744, 745,
-	0, 739, 728, 297, 746, 747, 748, 749, 750, 751,
-	752, 753, 754, 755, 0, 756, 848, 849, 850, 851,
-	0, 768, 0, 757, 759, 760, 761, 762, 1490, 763,
-	1491, 0, 764, 765, 766, 767, 758, 769, 770, 0,
-	0, 771, 772, 773, 774, 776, 778, 779, 780, 775,
-	777, 781, 1450, 782, 0, 0, 783, 784, 785, 2114,
-	855, 856, 0, 787, 788, 786, 789, 790, 793, 791,
-	792, 857, 796, 513, 797, 798, 799, 794, 795, 0,
-	0, 0, 289, 800, 801, 858, 802, 803, 804, 0,
-	868, 290, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 345, 346, 348,
-	347, 349, 350, 351, 352, 0, 353, 354, 0, 0,
-	1526, 0, 2366, 1452, 0, 0, 0, 356, 0, 355,
-	0, 357, 358, 359, 874, 360, 361, 362, 363, 364,
-	365, 366, 367, 806, 807, 0, 368, 808, 369, 809,
-	0, 810, 370, 371, 372, 373, 374, 375, 376, 377,
-	378, 379, 0, 1451, 0, 380, 811, 812, 813, 0,
-	381, 382, 383, 384, 1458, 0, 1439, 0, 385, 386,
-	387, 388, 389, 390, 391, 392, 0, 0, 394, 395,
-	396, 393, 397, 398, 0, 399, 0, 400, 401, 402,
-	403, 404, 405, 406, 0, 407, 408, 409, 876, 410,
-	411, 412, 1442, 1440, 1441, 1448, 1444, 1443, 1447, 413,
-	414, 415, 416, 417, 0, 418, 420, 421, 815, 422,
-	816, 0, 425, 427, 419, 423, 0, 426, 424, 428,
-	429, 0, 430, 431, 432, 433, 0, 0, 434, 435,
-	436, 0, 437, 438, 440, 439, 0, 441, 442, 443,
-	0, 444, 445, 817, 446, 447, 448, 450, 452, 449,
-	451, 453, 454, 455, 456, 457, 1485, 1486, 458, 459,
-	0, 340, 0, 0, 0, 0, 0, 460, 461, 462,
-	820, 0, 0, 0, 463, 0, 465, 469, 466, 467,
-	468, 470, 0, 464, 471, 472, 0, 877, 473, 474,
-	475, 821, 822, 476, 477, 478, 479, 480, 481, 482,
-	483, 484, 0, 485, 486, 1492, 0, 824, 487, 0,
-	488, 489, 490, 491, 492, 493, 494, 1453, 1454, 1457,
-	595, 879, 495, 496, 497, 0, 498, 499, 500, 501,
-	502, 503, 504, 0, 0, 0, 505, 506, 507, 508,
-	0, 867, 341, 343, 878, 828, 509, 596, 510, 829,
-	830, 0, 831, 0, 511, 512, 515, 880, 1455, 881,
-	514, 516, 517, 882, 518, 0, 0, 0, 519, 520,
-	521, 522, 523, 524, 525, 1522, 526, 528, 527, 0,
-	530, 1493, 529, 883, 531, 532, 884, 0, 533, 534,
-	535, 536, 537, 538, 541, 1446, 1445, 539, 540, 542,
-	543, 0, 544, 545, 547, 550, 546, 548, 549, 551,
-	552, 565, 566, 553, 554, 555, 556, 557, 558, 559,
-	560, 561, 562, 563, 564, 568, 0, 567, 885, 569,
-	570, 571, 572, 573, 581, 583, 584, 579, 580, 582,
-	585, 586, 588, 589, 576, 577, 578, 886, 587, 574,
-	0, 575, 344, 887, 590, 591, 592, 593, 0, 1456,
-	594, 835, 597, 598, 0, 0, 599, 0, 600, 0,
-	1528, 602, 603, 604, 0, 0, 605, 606, 836, 888,
-	607, 889, 1487, 608, 609, 601, 610, 611, 612, 613,
-	614, 615, 616, 617, 618, 619, 0, 620, 621, 838,
-	622, 623, 624, 839, 625, 626, 627, 1488, 628, 841,
-	629, 630, 0, 631, 632, 633, 0, 634, 635, 636,
-	637, 638, 639, 640, 641, 642, 643, 842, 644, 645,
-	647, 646, 648, 649, 0, 650, 0, 651, 652, 653,
-	0, 0, 0, 0, 0, 654, 655, 657, 0, 658,
-	659, 660, 661, 662, 656, 663, 664, 665, 666, 667,
-	668, 669, 0, 671, 672, 670, 673, 674, 890, 675,
-	676, 677, 678, 679, 843, 1530, 0, 681, 682, 690,
-	691, 692, 683, 684, 686, 693, 685, 694, 695, 696,
-	697, 699, 698, 295, 701, 702, 700, 703, 704, 705,
-	706, 1449, 707, 844, 708, 687, 688, 709, 710, 711,
-	891, 712, 713, 714, 715, 716, 717, 718, 719, 720,
-	845, 0, 721, 0, 722, 723, 724, 725, 726, 727,
-	729, 689, 730, 731, 732, 737, 738, 846, 733, 734,
-	735, 736, 1489, 740, 741, 742, 743, 0, 744, 745,
-	0, 739, 728, 297, 746, 747, 748, 749, 750, 751,
-	752, 753, 754, 755, 0, 756, 848, 849, 850, 851,
-	0, 768, 0, 757, 759, 760, 761, 762, 1490, 763,
-	1491, 0, 764, 765, 766, 767, 758, 769, 770, 0,
-	0, 771, 772, 773, 774, 776, 778, 779, 780, 775,
-	777, 781, 1450, 782, 0, 0, 783, 784, 785, 2114,
-	855, 856, 0, 787, 788, 786, 789, 790, 793, 791,
-	792, 857, 796, 513, 797, 798, 799, 794, 795, 0,
-	0, 0, 289, 800, 801, 858, 802, 803, 804, 0,
-	4670, 290, 868, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 345,
-	346, 348, 347, 349, 350, 351, 352, 0, 353, 354,
-	1526, 0, 2366, 0, 0, 1452, 0, 0, 0, 356,
-	0, 355, 0, 357, 358, 359, 874, 360, 361, 362,
-	363, 364, 365, 366, 367, 806, 807, 0, 368, 808,
-	369, 809, 0, 810, 370, 371, 372, 373, 374, 375,
-	376, 377, 378, 379, 0, 1451, 0, 380, 811, 812,
-	813, 0, 381, 382, 383, 384, 1458, 0, 1439, 0,
-	385, 386, 387, 388, 389, 390, 391, 392, 0, 0,
-	394, 395, 396, 393, 397, 398, 0, 399, 0, 400,
-	401, 402, 403, 404, 405, 406, 0, 407, 408, 409,
-	876, 410, 411, 412, 1442, 1440, 1441, 1448, 1444, 1443,
-	1447, 413, 414, 415, 416, 417, 0, 418, 420, 421,
-	815, 422, 816, 0, 425, 427, 419, 423, 0, 426,
-	424, 428, 429, 0, 430, 431, 432, 433, 0, 0,
-	434, 435, 436, 0, 437, 438, 440, 439, 0, 441,
-	442, 443, 0, 444, 445, 817, 446, 447, 448, 450,
-	452, 449, 451, 453, 454, 455, 456, 457, 1485, 1486,
-	458, 459, 0, 340, 0, 0, 0, 0, 0, 460,
-	461, 462, 820, 0, 0, 0, 463, 0, 465, 469,
-	466, 467, 468, 470, 0, 464, 471, 472, 0, 877,
-	473, 474, 475, 821, 822, 476, 477, 478, 479, 480,
-	481, 482, 483, 484, 0, 485, 486, 1492, 0, 824,
-	487, 0, 488, 489, 490, 491, 492, 493, 494, 1453,
-	1454, 1457, 595, 879, 495, 496, 497, 0, 498, 499,
-	500, 501, 502, 503, 504, 0, 0, 0, 505, 506,
-	507, 508, 0, 867, 341, 343, 878, 828, 509, 596,
-	510, 829, 830, 0, 831, 0, 511, 512, 515, 880,
-	1455, 881, 514, 516, 517, 882, 518, 0, 0, 0,
-	519, 520, 521, 522, 523, 524, 525, 1522, 526, 528,
-	527, 0, 530, 1493, 529, 883, 531, 532, 884, 0,
-	533, 534, 535, 536, 537, 538, 541, 1446, 1445, 539,
-	540, 542, 543, 0, 544, 545, 547, 550, 546, 548,
-	549, 551, 552, 565, 566, 553, 554, 555, 556, 557,
-	558, 559, 560, 561, 562, 563, 564, 568, 0, 567,
-	885, 569, 570, 571, 572, 573, 581, 583, 584, 579,
-	580, 582, 585, 586, 588, 589, 576, 577, 578, 886,
-	587, 574, 0, 575, 344, 887, 590, 591, 592, 593,
-	0, 1456, 594, 835, 597, 598, 0, 0, 599, 0,
-	600, 0, 1528, 602, 603, 604, 0, 0, 605, 606,
-	836, 888, 607, 889, 1487, 608, 609, 601, 610, 611,
-	612, 613, 614, 615, 616, 617, 618, 619, 0, 620,
-	621, 838, 622, 623, 624, 839, 625, 626, 627, 1488,
-	628, 841, 629, 630, 0, 631, 632, 633, 0, 634,
-	635, 636, 637, 638, 639, 640, 641, 642, 643, 842,
-	644, 645, 647, 646, 648, 649, 0, 650, 0, 651,
-	652, 653, 0, 0, 0, 0, 0, 654, 655, 657,
-	0, 658, 659, 660, 661, 662, 656, 663, 664, 665,
-	666, 667, 668, 669, 0, 671, 672, 670, 673, 674,
-	890, 675, 676, 677, 678, 679, 843, 1530, 0, 681,
-	682, 690, 691, 692, 683, 684, 686, 693, 685, 694,
-	695, 696, 697, 699, 698, 0, 701, 702, 700, 703,
-	704, 705, 706, 1449, 707, 844, 708, 687, 688, 709,
-	710, 711, 891, 712, 713, 714, 715, 716, 717, 718,
-	719, 720, 845, 0, 721, 0, 722, 723, 724, 725,
-	726, 727, 729, 689, 730, 731, 732, 737, 738, 846,
-	733, 734, 735, 736, 1489, 740, 741, 742, 743, 0,
-	744, 745, 0, 739, 728, 0, 746, 747, 748, 749,
-	750, 751, 752, 753, 754, 755, 0, 756, 848, 849,
-	850, 851, 0, 768, 0, 757, 759, 760, 761, 762,
-	1490, 763, 1491, 0, 764, 765, 766, 767, 758, 769,
-	770, 0, 0, 771, 772, 773, 774, 776, 778, 779,
-	780, 775, 777, 781, 1450, 782, 0, 0, 783, 784,
-	785, 854, 855, 856, 0, 787, 788, 786, 789, 790,
-	793, 791, 792, 857, 796, 513, 797, 798, 799, 794,
-	795, 0, 1518, 0, 868, 800, 801, 858, 802, 803,
-	804, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 345, 346, 348, 347, 349, 350, 351, 352, 0,
-	353, 354, 0, 0, 0, 0, 0, 1452, 0, 0,
-	0, 356, 1526, 355, 1524, 357, 358, 359, 874, 360,
-	361, 362, 363, 364, 365, 366, 367, 806, 807, 0,
-	368, 808, 369, 809, 0, 810, 370, 371, 372, 373,
-	374, 375, 376, 377, 378, 379, 0, 1451, 0, 380,
-	811, 812, 813, 0, 381, 382, 383, 384, 1458, 0,
-	1439, 0, 385, 386, 387, 388, 389, 390, 391, 392,
-	0, 0, 394, 395, 396, 393, 397, 398, 0, 399,
-	0, 400, 401, 402, 403, 404, 405, 406, 0, 407,
-	408, 409, 876, 410, 411, 412, 1442, 1440, 1441, 1448,
-	1444, 1443, 1447, 413, 414, 415, 416, 417, 0, 418,
-	420, 421, 815, 422, 816, 0, 425, 427, 419, 423,
-	0, 426, 424, 428, 429, 0, 430, 431, 432, 433,
-	0, 0, 434, 435, 436, 0, 437, 438, 440, 439,
-	0, 441, 442, 443, 0, 444, 445, 817, 446, 447,
-	448, 450, 452, 449, 451, 453, 454, 455, 456, 457,
-	1485, 1486, 458, 459, 0, 340, 0, 0, 0, 0,
-	0, 460, 461, 462, 820, 0, 0, 0, 463, 0,
-	465, 469, 466, 467, 468, 470, 0, 464, 471, 472,
-	0, 877, 473, 474, 475, 821, 822, 476, 477, 478,
-	479, 480, 481, 482, 483, 484, 0, 485, 486, 1492,
-	0, 824, 487, 0, 488, 489, 490, 491, 492, 493,
-	494, 1453, 1454, 1457, 595, 879, 495, 496, 497, 0,
-	498, 499, 500, 501, 502, 503, 504, 0, 0, 0,
-	505, 506, 507, 508, 0, 867, 341, 343, 878, 828,
-	509, 596, 510, 829, 830, 0, 831, 0, 511, 512,
-	515, 880, 1455, 881, 514, 516, 517, 882, 518, 0,
-	0, 0, 519, 520, 521, 522, 523, 524, 525, 1522,
-	526, 528, 527, 0, 530, 1493, 529, 883, 531, 532,
-	884, 0, 533, 534, 535, 536, 537, 538, 541, 1446,
-	1445, 539, 540, 542, 543, 0, 544, 545, 547, 550,
-	546, 548, 549, 551, 552, 565, 566, 553, 554, 555,
-	556, 557, 558, 559, 560, 561, 562, 563, 564, 568,
-	0, 567, 885, 569, 570, 571, 572, 573, 581, 583,
-	584, 579, 580, 582, 585, 586, 588, 589, 576, 577,
-	578, 886, 587, 574, 0, 575, 344, 887, 590, 591,
-	592, 593, 0, 1456, 594, 835, 597, 598, 0, 0,
-	599, 0, 600, 0, 1528, 602, 603, 604, 0, 0,
-	605, 606, 836, 888, 607, 889, 1487, 608, 609, 601,
-	610, 611, 612, 613, 614, 615, 616, 617, 618, 619,
-	0, 620, 621, 838, 622, 623, 624, 839, 625, 626,
-	627, 1488, 628, 841, 629, 630, 0, 631, 632, 633,
-	0, 634, 635, 636, 637, 638, 639, 640, 641, 642,
-	643, 842, 644, 645, 647, 646, 648, 649, 0, 650,
-	0, 651, 652, 653, 0, 0, 0, 0, 0, 654,
-	655, 657, 0, 658, 659, 660, 661, 662, 656, 663,
-	664, 665, 666, 667, 668, 669, 0, 671, 672, 670,
-	673, 674, 890, 675, 676, 677, 678, 679, 843, 1530,
-	0, 681, 682, 690, 691, 692, 683, 684, 686, 693,
-	685, 694, 695, 696, 697, 699, 698, 0, 701, 702,
-	700, 703, 704, 705, 706, 1449, 707, 844, 708, 687,
-	688, 709, 710, 711, 891, 712, 713, 714, 715, 716,
-	717, 718, 719, 720, 845, 0, 721, 0, 722, 723,
-	724, 725, 726, 727, 729, 689, 730, 731, 732, 737,
-	738, 846, 733, 734, 735, 736, 1489, 740, 741, 742,
-	743, 0, 744, 745, 0, 739, 728, 0, 746, 747,
-	748, 749, 750, 751, 752, 753, 754, 755, 0, 756,
-	848, 849, 850, 851, 0, 768, 0, 757, 759, 760,
-	761, 762, 1490, 763, 1491, 0, 764, 765, 766, 767,
-	758, 769, 770, 0, 0, 771, 772, 773, 774, 776,
-	778, 779, 780, 775, 777, 781, 1450, 782, 0, 0,
-	783, 784, 785, 854, 855, 856, 0, 787, 788, 786,
-	789, 790, 793, 791, 792, 857, 796, 513, 797, 798,
-	799, 794, 795, 0, 0, 0, 868, 800, 801, 858,
-	802, 803, 804, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 345, 346, 348, 347, 349, 350, 351,
-	352, 0, 353, 354, 0, 0, 0, 0, 0, 1452,
-	0, 0, 0, 356, 1526, 355, 1524, 357, 358, 359,
-	874, 360, 361, 362, 363, 364, 365, 366, 367, 806,
-	807, 0, 368, 808, 369, 809, 0, 810, 370, 371,
-	372, 373, 374, 375, 376, 377, 378, 379, 0, 1451,
-	0, 380, 811, 812, 813, 0, 381, 382, 383, 384,
-	1458, 0, 1439, 0, 385, 386, 387, 388, 389, 390,
-	391, 392, 0, 0, 394, 395, 396, 393, 397, 398,
-	0, 399, 0, 400, 401, 402, 403, 404, 405, 406,
-	0, 407, 408, 409, 876, 410, 411, 412, 1442, 1440,
-	1441, 1448, 1444, 1443, 1447, 413, 414, 415, 416, 417,
-	0, 418, 420, 421, 815, 422, 816, 0, 425, 427,
-	419, 423, 0, 426, 424, 428, 429, 0, 430, 431,
-	432, 433, 0, 0, 434, 435, 436, 0, 437, 438,
-	440, 439, 0, 441, 442, 443, 0, 444, 445, 817,
-	446, 447, 448, 450, 452, 449, 451, 453, 454, 455,
-	456, 457, 1485, 1486, 458, 459, 0, 340, 0, 0,
-	0, 0, 0, 460, 461, 462, 820, 0, 0, 0,
-	463, 0, 465, 469, 466, 467, 468, 470, 0, 464,
-	471, 472, 0, 877, 473, 474, 475, 821, 822, 476,
-	477, 478, 479, 480, 481, 482, 483, 484, 0, 485,
-	486, 1492, 0, 824, 487, 0, 488, 489, 490, 491,
-	492, 493, 494, 1453, 1454, 1457, 595, 879, 495, 496,
-	497, 0, 498, 499, 500, 501, 502, 503, 504, 0,
-	0, 0, 505, 506, 507, 508, 0, 867, 341, 343,
-	878, 828, 509, 596, 510, 829, 830, 0, 831, 0,
-	511, 512, 515, 880, 1455, 881, 514, 516, 517, 882,
-	518, 0, 0, 0, 519, 520, 521, 522, 523, 524,
-	525, 1522, 526, 528, 527, 0, 530, 1493, 529, 883,
-	531, 532, 884, 0, 533, 534, 535, 536, 537, 538,
-	541, 1446, 1445, 539, 540, 542, 543, 0, 544, 545,
-	547, 550, 546, 548, 549, 551, 552, 565, 566, 553,
-	554, 555, 556, 557, 558, 559, 560, 561, 562, 563,
-	564, 568, 0, 567, 885, 569, 570, 571, 572, 573,
-	581, 583, 584, 579, 580, 582, 585, 586, 588, 589,
-	576, 577, 578, 886, 587, 574, 0, 575, 344, 887,
-	590, 591, 592, 593, 0, 1456, 594, 835, 597, 598,
-	0, 0, 599, 0, 600, 0, 1528, 602, 603, 604,
-	0, 0, 605, 606, 836, 888, 607, 889, 1487, 608,
-	609, 601, 610, 611, 612, 613, 614, 615, 616, 617,
-	618, 619, 0, 620, 621, 838, 622, 623, 624, 839,
-	625, 626, 627, 1488, 628, 841, 629, 630, 0, 631,
-	632, 633, 0, 634, 635, 636, 637, 638, 639, 640,
-	641, 642, 643, 842, 644, 645, 647, 646, 648, 649,
-	0, 650, 0, 651, 652, 653, 0, 0, 0, 0,
-	0, 654, 655, 657, 0, 658, 659, 660, 661, 662,
-	656, 663, 664, 665, 666, 667, 668, 669, 0, 671,
-	672, 670, 673, 674, 890, 675, 676, 677, 678, 679,
-	843, 1530, 0, 681, 682, 690, 691, 692, 683, 684,
-	686, 693, 685, 694, 695, 696, 697, 699, 698, 0,
-	701, 702, 700, 703, 704, 705, 706, 1449, 707, 844,
-	708, 687, 688, 709, 710, 711, 891, 712, 713, 714,
-	715, 716, 717, 718, 719, 720, 845, 0, 721, 0,
-	722, 723, 724, 725, 726, 727, 729, 689, 730, 731,
-	732, 737, 738, 846, 733, 734, 735, 736, 1489, 740,
-	741, 742, 743, 0, 744, 745, 0, 739, 728, 0,
-	746, 747, 748, 749, 750, 751, 752, 753, 754, 755,
-	0, 756, 848, 849, 850, 851, 0, 768, 0, 757,
-	759, 760, 761, 762, 1490, 763, 1491, 0, 764, 765,
-	766, 767, 758, 769, 770, 0, 0, 771, 772, 773,
-	774, 776, 778, 779, 780, 775, 777, 781, 1450, 782,
-	0, 0, 783, 784, 785, 854, 855, 856, 0, 787,
-	788, 786, 789, 790, 793, 791, 792, 857, 796, 513,
-	797, 798, 799, 794, 795, 0, 0, 0, 868, 800,
-	801, 858, 802, 803, 804, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 345, 346, 348, 347, 349,
-	350, 351, 352, 0, 353, 354, 0, 0, 0, 0,
-	0, 1452, 0, 0, 0, 356, 1526, 355, 1524, 357,
-	358, 359, 874, 360, 361, 362, 363, 364, 365, 366,
-	367, 806, 807, 0, 368, 808, 369, 809, 0, 810,
-	370, 371, 372, 373, 374, 375, 376, 377, 378, 379,
-	0, 1451, 0, 380, 811, 812, 813, 0, 381, 382,
-	383, 384, 1458, 0, 1439, 0, 385, 386, 387, 388,
-	389, 390, 391, 392, 0, 0, 394, 395, 396, 393,
-	397, 398, 0, 399, 0, 400, 401, 402, 403, 404,
-	405, 406, 0, 407, 408, 409, 876, 410, 411, 412,
-	1442, 1440, 1441, 1448, 1444, 1443, 1447, 413, 414, 415,
-	416, 417, 0, 418, 420, 421, 815, 422, 816, 0,
-	425, 427, 419, 423, 0, 426, 424, 428, 429, 0,
-	430, 431, 432, 433, 0, 0, 434, 435, 436, 0,
-	437, 438, 440, 439, 0, 441, 442, 443, 0, 444,
-	445, 817, 446, 447, 448, 450, 452, 449, 451, 453,
-	454, 455, 456, 457, 1485, 1486, 458, 459, 0, 340,
-	0, 0, 0, 0, 0, 460, 461, 462, 820, 0,
-	0, 0, 463, 0, 465, 469, 466, 467, 468, 470,
-	0, 464, 471, 472, 0, 877, 473, 474, 475, 821,
-	822, 476, 477, 478, 479, 480, 481, 482, 483, 484,
-	0, 485, 486, 1492, 0, 824, 487, 0, 488, 489,
-	490, 491, 492, 493, 494, 1453, 1454, 1457, 595, 879,
-	495, 496, 497, 0, 498, 499, 500, 501, 502, 503,
-	504, 0, 0, 0, 505, 506, 507, 508, 0, 867,
-	341, 343, 878, 828, 509, 596, 510, 829, 830, 0,
-	831, 0, 511, 512, 515, 880, 1455, 881, 514, 516,
-	517, 882, 518, 0, 0, 0, 519, 520, 521, 522,
-	523, 524, 525, 0, 526, 528, 527, 0, 530, 1493,
-	529, 883, 531, 532, 884, 0, 533, 534, 535, 536,
-	537, 538, 541, 1446, 1445, 539, 540, 542, 543, 0,
-	544, 545, 547, 550, 546, 548, 549, 551, 552, 565,
-	566, 553, 554, 555, 556, 557, 558, 559, 560, 561,
-	562, 563, 564, 568, 0, 567, 885, 569, 570, 571,
-	572, 573, 581, 583, 584, 579, 580, 582, 585, 586,
-	588, 589, 576, 577, 578, 886, 587, 574, 0, 575,
-	344, 887, 590, 591, 592, 593, 0, 1456, 594, 835,
-	597, 598, 0, 0, 599, 0, 600, 0, 0, 602,
-	603, 604, 0, 0, 605, 606, 836, 888, 607, 889,
-	1487, 608, 609, 601, 610, 611, 612, 613, 614, 615,
-	616, 617, 618, 619, 0, 620, 621, 838, 622, 623,
-	624, 839, 625, 626, 627, 1488, 628, 841, 629, 630,
-	0, 631, 632, 633, 0, 634, 635, 636, 637, 638,
-	639, 640, 641, 642, 643, 842, 644, 645, 647, 646,
-	648, 649, 0, 650, 0, 651, 652, 653, 0, 0,
-	0, 0, 0, 654, 655, 657, 0, 658, 659, 660,
-	661, 662, 656, 663, 664, 665, 666, 667, 668, 669,
-	0, 671, 672, 670, 673, 674, 890, 675, 676, 677,
-	678, 679, 843, 680, 0, 681, 682, 690, 691, 692,
-	683, 684, 686, 693, 685, 694, 695, 696, 697, 699,
-	698, 0, 701, 702, 700, 703, 704, 705, 706, 1449,
-	707, 844, 708, 687, 688, 709, 710, 711, 891, 712,
-	713, 714, 715, 716, 717, 718, 719, 720, 845, 0,
-	721, 0, 722, 723, 724, 725, 726, 727, 729, 689,
-	730, 731, 732, 737, 738, 846, 733, 734, 735, 736,
-	1489, 740, 741, 742, 743, 0, 744, 745, 0, 739,
-	728, 0, 746, 747, 748, 749, 750, 751, 752, 753,
-	754, 755, 0, 756, 848, 849, 850, 851, 0, 768,
-	0, 757, 759, 760, 761, 762, 1490, 763, 1491, 0,
-	764, 765, 766, 767, 758, 769, 770, 0, 0, 771,
-	772, 773, 774, 776, 778, 779, 780, 775, 777, 781,
-	1450, 782, 0, 0, 783, 784, 785, 854, 855, 856,
-	0, 787, 788, 786, 789, 790, 793, 791, 792, 857,
-	796, 513, 797, 798, 799, 794, 795, 0, 0, 0,
-	868, 800, 801, 858, 802, 803, 804, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 345, 346, 348,
-	347, 349, 350, 351, 352, 0, 353, 354, 0, 0,
-	0, 0, 0, 1452, 0, 0, 0, 356, 864, 355,
-	5856, 357, 358, 359, 874, 360, 361, 362, 363, 364,
-	365, 366, 367, 806, 807, 0, 368, 808, 369, 809,
-	0, 810, 370, 371, 372, 373, 374, 375, 376, 377,
-	378, 379, 0, 1451, 0, 380, 811, 812, 813, 0,
-	381, 382, 383, 384, 1458, 0, 1439, 0, 385, 386,
-	387, 388, 389, 390, 391, 392, 0, 0, 394, 395,
-	396, 393, 397, 398, 0, 399, 0, 400, 401, 402,
-	403, 404, 405, 406, 0, 407, 408, 409, 876, 410,
-	411, 412, 1442, 1440, 1441, 1448, 1444, 1443, 1447, 413,
-	414, 415, 416, 417, 0, 418, 420, 421, 815, 422,
-	816, 0, 425, 427, 419, 423, 0, 426, 424, 428,
-	429, 0, 430, 431, 432, 433, 0, 0, 434, 435,
-	436, 0, 437, 438, 440, 439, 0, 441, 442, 443,
-	0, 444, 445, 817, 446, 447, 448, 450, 452, 449,
-	451, 453, 454, 455, 456, 457, 1485, 1486, 458, 459,
-	0, 340, 0, 0, 0, 0, 0, 460, 461, 462,
-	820, 0, 0, 0, 463, 0, 465, 469, 466, 467,
-	468, 470, 0, 464, 471, 472, 0, 877, 473, 474,
-	475, 821, 822, 476, 477, 478, 479, 480, 481, 482,
-	483, 484, 0, 485, 486, 1492, 0, 824, 487, 0,
-	488, 489, 490, 491, 492, 493, 494, 1453, 1454, 1457,
-	595, 879, 495, 496, 497, 0, 498, 499, 500, 501,
-	502, 503, 504, 0, 0, 0, 505, 506, 507, 508,
-	0, 867, 341, 343, 878, 828, 509, 596, 510, 829,
-	830, 0, 831, 0, 511, 512, 515, 880, 1455, 881,
-	514, 516, 517, 882, 518, 0, 0, 0, 519, 520,
-	521, 522, 523, 524, 525, 0, 526, 528, 527, 0,
-	530, 1493, 529, 883, 531, 532, 884, 0, 533, 534,
-	535, 536, 537, 538, 541, 1446, 1445, 539, 540, 542,
-	543, 0, 544, 545, 547, 550, 546, 548, 549, 551,
-	552, 565, 566, 553, 554, 555, 556, 557, 558, 559,
-	560, 561, 562, 563, 564, 568, 0, 567, 885, 569,
-	570, 571, 572, 573, 581, 583, 584, 579, 580, 582,
-	585, 586, 588, 589, 576, 577, 578, 886, 587, 574,
-	0, 575, 344, 887, 590, 591, 592, 593, 0, 1456,
-	594, 835, 597, 598, 0, 0, 599, 0, 600, 0,
-	0, 602, 603, 604, 0, 0, 605, 606, 836, 888,
-	607, 889, 1487, 608, 609, 601, 610, 611, 612, 613,
-	614, 615, 616, 617, 618, 619, 0, 620, 621, 838,
-	622, 623, 624, 839, 625, 626, 627, 1488, 628, 841,
-	629, 630, 0, 631, 632, 633, 0, 634, 635, 636,
-	637, 638, 639, 640, 641, 642, 643, 842, 644, 645,
-	647, 646, 648, 649, 0, 650, 0, 651, 652, 653,
-	0, 0, 0, 0, 0, 654, 655, 657, 0, 658,
-	659, 660, 661, 662, 656, 663, 664, 665, 666, 667,
-	668, 669, 0, 671, 672, 670, 673, 674, 890, 675,
-	676, 677, 678, 679, 843, 1530, 0, 681, 682, 690,
-	691, 692, 683, 684, 686, 693, 685, 694, 695, 696,
-	697, 699, 698, 0, 701, 702, 700, 703, 704, 705,
-	706, 1449, 707, 844, 708, 687, 688, 709, 710, 711,
-	891, 712, 713, 714, 715, 716, 717, 718, 719, 720,
-	845, 0, 721, 0, 722, 723, 724, 725, 726, 727,
-	729, 689, 730, 731, 732, 737, 738, 846, 733, 734,
-	735, 736, 1489, 740, 741, 742, 743, 0, 744, 745,
-	0, 739, 728, 0, 746, 747, 748, 749, 750, 751,
-	752, 753, 754, 755, 0, 756, 848, 849, 850, 851,
-	0, 768, 0, 757, 759, 760, 761, 762, 1490, 763,
-	1491, 0, 764, 765, 766, 767, 758, 769, 770, 0,
-	0, 771, 772, 773, 774, 776, 778, 779, 780, 775,
-	777, 781, 1450, 782, 0, 0, 783, 784, 785, 854,
-	855, 856, 0, 787, 788, 786, 789, 790, 793, 791,
-	792, 857, 796, 513, 797, 798, 799, 794, 795, 0,
-	0, 0, 868, 800, 801, 858, 802, 803, 804, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 345,
-	346, 348, 347, 349, 350, 351, 352, 0, 353, 354,
-	0, 0, 0, 0, 0, 1452, 0, 0, 0, 356,
-	864, 355, 2259, 357, 358, 359, 874, 360, 361, 362,
-	363, 364, 365, 366, 367, 806, 807, 0, 368, 808,
-	369, 809, 0, 810, 370, 371, 372, 373, 374, 375,
-	376, 377, 378, 379, 0, 1451, 0, 380, 811, 812,
-	813, 0, 381, 382, 383, 384, 1458, 0, 1439, 0,
-	385, 386, 387, 388, 389, 390, 391, 392, 0, 0,
-	394, 395, 396, 393, 397, 398, 0, 399, 0, 400,
-	401, 402, 403, 404, 405, 406, 0, 407, 408, 409,
-	876, 410, 411, 412, 1442, 1440, 1441, 1448, 1444, 1443,
-	1447, 413, 414, 415, 416, 417, 0, 418, 420, 421,
-	815, 422, 816, 0, 425, 427, 419, 423, 0, 426,
-	424, 428, 429, 0, 430, 431, 432, 433, 0, 0,
-	434, 435, 436, 0, 437, 438, 440, 439, 0, 441,
-	442, 443, 0, 444, 445, 817, 446, 447, 448, 450,
-	452, 449, 451, 453, 454, 455, 456, 457, 1485, 1486,
-	458, 459, 0, 340, 0, 0, 0, 0, 0, 460,
-	461, 462, 820, 0, 0, 0, 463, 0, 465, 469,
-	466, 467, 468, 470, 0, 464, 471, 472, 0, 877,
-	473, 474, 475, 821, 822, 476, 477, 478, 479, 480,
-	481, 482, 483, 484, 0, 485, 486, 1492, 0, 824,
-	487, 0, 488, 489, 490, 491, 492, 493, 494, 1453,
-	1454, 1457, 595, 879, 495, 496, 497, 0, 498, 499,
-	500, 501, 502, 503, 504, 0, 0, 0, 505, 506,
-	507, 508, 0, 867, 341, 343, 878, 828, 509, 596,
-	510, 829, 830, 0, 831, 0, 511, 512, 515, 880,
-	1455, 881, 514, 516, 517, 882, 518, 0, 0, 0,
-	519, 520, 521, 522, 523, 524, 525, 0, 526, 528,
-	527, 0, 530, 1493, 529, 883, 531, 532, 884, 0,
-	533, 534, 535, 536, 537, 538, 541, 1446, 1445, 539,
-	540, 542, 543, 0, 544, 545, 547, 550, 546, 548,
-	549, 551, 552, 565, 566, 553, 554, 555, 556, 557,
-	558, 559, 560, 561, 562, 563, 564, 568, 0, 567,
-	885, 569, 570, 571, 572, 573, 581, 583, 584, 579,
-	580, 582, 585, 586, 588, 589, 576, 577, 578, 886,
-	587, 574, 0, 575, 344, 887, 590, 591, 592, 593,
-	0, 1456, 594, 835, 597, 598, 0, 0, 599, 0,
-	600, 0, 0, 602, 603, 604, 0, 0, 605, 606,
-	836, 888, 607, 889, 1487, 608, 609, 601, 610, 611,
-	612, 613, 614, 615, 616, 617, 618, 619, 0, 620,
-	621, 838, 622, 623, 624, 839, 625, 626, 627, 1488,
-	628, 841, 629, 630, 0, 631, 632, 633, 0, 634,
-	635, 636, 637, 638, 639, 640, 641, 642, 643, 842,
-	644, 645, 647, 646, 648, 649, 0, 650, 0, 651,
-	652, 653, 0, 0, 0, 0, 0, 654, 655, 657,
-	0, 658, 659, 660, 661, 662, 656, 663, 664, 665,
-	666, 667, 668, 669, 0, 671, 672, 670, 673, 674,
-	890, 675, 676, 677, 678, 679, 843, 680, 0, 681,
-	682, 690, 691, 692, 683, 684, 686, 693, 685, 694,
-	695, 696, 697, 699, 698, 0, 701, 702, 700, 703,
-	704, 705, 706, 1449, 707, 844, 708, 687, 688, 709,
-	710, 711, 891, 712, 713, 714, 715, 716, 717, 718,
-	719, 720, 845, 0, 721, 0, 722, 723, 724, 725,
-	726, 727, 729, 689, 730, 731, 732, 737, 738, 846,
-	733, 734, 735, 736, 1489, 740, 741, 742, 743, 0,
-	744, 745, 0, 739, 728, 0, 746, 747, 748, 749,
-	750, 751, 752, 753, 754, 755, 0, 756, 848, 849,
-	850, 851, 0, 768, 0, 757, 759, 760, 761, 762,
-	1490, 763, 1491, 0, 764, 765, 766, 767, 758, 769,
-	770, 0, 0, 771, 772, 773, 774, 776, 778, 779,
-	780, 775, 777, 781, 1450, 782, 0, 0, 783, 784,
-	785, 854, 855, 856, 0, 787, 788, 786, 789, 790,
-	793, 791, 792, 857, 796, 513, 797, 798, 799, 794,
-	795, 0, 337, 0, 0, 800, 801, 858, 802, 803,
-	804, 0, 3132, 3133, 3134, 3151, 3152, 3153, 0, 345,
-	346, 348, 347, 349, 350, 351, 352, 0, 353, 354,
-	0, 0, 0, 3154, 0, 805, 0, 0, 0, 356,
-	3155, 355, 864, 357, 358, 359, 0, 360, 361, 362,
-	363, 364, 365, 366, 367, 806, 807, 0, 368, 808,
-	369, 809, 0, 810, 370, 371, 372, 373, 374, 375,
-	376, 377, 378, 379, 0, 0, 2244, 380, 811, 812,
-	813, 0, 381, 382, 383, 384, 814, 0, 0, 0,
-	385, 386, 387, 388, 389, 390, 391, 392, 3144, 0,
-	394, 395, 396, 393, 397, 398, 0, 399, 3140, 400,
-	401, 402, 403, 404, 405, 406, 0, 407, 408, 409,
-	0, 410, 411, 412, 0, 0, 0, 0, 0, 0,
-	0, 413, 414, 415, 416, 417, 0, 418, 420, 421,
-	815, 422, 816, 0, 425, 427, 419, 423, 0, 426,
-	424, 428, 429, 0, 430, 431, 432, 433, 0, 0,
-	434, 435, 436, 0, 437, 438, 440, 439, 0, 441,
-	442, 443, 0, 444, 445, 817, 446, 447, 448, 450,
-	452, 449, 451, 453, 454, 455, 456, 457, 818, 819,
-	458, 459, 0, 0, 0, 3145, 3146, 3147, 3148, 460,
-	461, 462, 820, 0, 0, 3139, 463, 0, 465, 469,
-	466, 467, 468, 470, 0, 464, 471, 472, 0, 0,
-	473, 474, 475, 821, 822, 476, 477, 478, 479, 480,
-	481, 482, 483, 484, 0, 485, 486, 823, 0, 824,
-	487, 0, 488, 489, 490, 491, 492, 493, 494, 825,
-	826, 827, 595, 0, 495, 496, 497, 0, 498, 499,
-	500, 501, 502, 503, 504, 0, 0, 0, 505, 506,
-	507, 508, 0, 0, 0, 0, 0, 828, 509, 596,
-	510, 829, 830, 0, 831, 0, 511, 512, 515, 0,
-	832, 0, 514, 516, 517, 0, 518, 0, 3149, 3150,
-	519, 520, 521, 522, 523, 524, 525, 0, 526, 528,
-	527, 0, 530, 833, 529, 0, 531, 532, 0, 0,
-	533, 534, 535, 536, 537, 538, 541, 0, 0, 539,
-	540, 542, 543, 3142, 544, 545, 547, 550, 546, 548,
-	549, 551, 552, 565, 566, 553, 554, 555, 556, 557,
-	558, 559, 560, 561, 562, 563, 564, 568, 0, 567,
-	0, 569, 570, 571, 572, 573, 581, 583, 584, 579,
-	580, 582, 585, 586, 588, 589, 576, 577, 578, 0,
-	587, 574, 0, 575, 0, 0, 590, 591, 592, 593,
-	0, 834, 594, 835, 597, 598, 0, 0, 599, 0,
-	600, 0, 0, 602, 603, 604, 0, 0, 605, 606,
-	836, 0, 607, 0, 837, 608, 609, 601, 610, 611,
-	612, 613, 614, 615, 616, 617, 618, 619, 0, 620,
-	621, 838, 622, 623, 624, 839, 625, 626, 627, 840,
-	628, 841, 629, 630, 0, 631, 632, 633, 0, 634,
-	635, 636, 637, 638, 639, 640, 641, 642, 643, 842,
-	644, 645, 647, 646, 648, 649, 0, 650, 0, 651,
-	652, 653, 0, 0, 0, 0, 0, 654, 655, 657,
-	0, 658, 659, 660, 661, 662, 656, 663, 664, 665,
-	666, 667, 668, 669, 0, 671, 672, 670, 673, 674,
-	0, 675, 676, 677, 678, 679, 843, 680, 3143, 681,
-	682, 690, 691, 692, 683, 684, 686, 693, 685, 694,
-	695, 696, 697, 699, 698, 0, 701, 702, 700, 703,
-	704, 705, 706, 0, 707, 844, 708, 687, 688, 709,
-	710, 711, 0, 712, 713, 714, 715, 716, 717, 718,
-	719, 720, 845, 0, 721, 0, 722, 723, 724, 725,
-	726, 727, 729, 689, 730, 731, 732, 737, 738, 846,
-	733, 734, 735, 736, 847, 740, 741, 742, 743, 0,
-	744, 745, 2243, 739, 728, 0, 746, 747, 748, 749,
-	750, 751, 752, 753, 754, 755, 0, 756, 848, 849,
-	850, 851, 0, 768, 0, 757, 759, 760, 761, 762,
-	852, 763, 853, 0, 764, 765, 766, 767, 758, 769,
-	770, 0, 0, 771, 772, 773, 774, 776, 778, 779,
-	780, 775, 777, 781, 0, 782, 0, 0, 783, 784,
-	785, 854, 855, 856, 0, 787, 788, 786, 789, 790,
-	793, 791, 792, 857, 796, 513, 797, 798, 799, 794,
-	795, 0, 0, 0, 0, 800, 801, 858, 802, 803,
-	804, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 1372, 0, 1733, 3129, 3130, 3131, 3156, 3141, 3135,
-	0, 3137, 3138, 3136, 3123, 3124, 3125, 3126, 3127, 3128,
-	345, 346, 348, 347, 349, 350, 351, 352, 0, 353,
-	354, 0, 0, 0, 0, 0, 805, 0, 0, 0,
-	356, 0, 355, 0, 357, 358, 359, 874, 360, 361,
-	362, 363, 364, 365, 366, 367, 806, 807, 0, 368,
-	808, 369, 809, 0, 810, 370, 371, 372, 373, 374,
-	375, 376, 377, 378, 379, 0, 0, 0, 380, 811,
-	812, 813, 0, 381, 382, 383, 384, 814, 0, 875,
-	0, 385, 386, 387, 388, 389, 390, 391, 392, 0,
-	0, 394, 395, 396, 393, 397, 398, 0, 399, 0,
-	400, 401, 402, 403, 404, 405, 406, 0, 407, 408,
-	409, 876, 410, 411, 412, 0, 0, 0, 0, 0,
-	0, 0, 413, 414, 415, 416, 417, 0, 418, 420,
-	421, 815, 422, 816, 0, 425, 427, 419, 423, 0,
-	426, 424, 428, 429, 0, 430, 431, 432, 433, 0,
-	0, 434, 435, 436, 0, 437, 438, 440, 439, 0,
-	441, 442, 443, 0, 444, 445, 817, 446, 447, 448,
-	450, 452, 449, 451, 453, 454, 455, 456, 457, 818,
-	819, 458, 459, 0, 340, 0, 0, 0, 0, 0,
-	460, 461, 462, 820, 0, 0, 0, 463, 0, 465,
-	469, 466, 467, 468, 470, 0, 464, 471, 472, 0,
-	877, 473, 474, 475, 821, 822, 476, 477, 478, 479,
-	480, 481, 482, 483, 484, 0, 485, 486, 823, 0,
-	824, 487, 0, 488, 489, 490, 491, 492, 493, 494,
-	825, 826, 827, 595, 879, 495, 496, 497, 0, 498,
-	499, 500, 501, 502, 503, 504, 0, 0, 0, 505,
-	506, 507, 508, 0, 0, 0, 0, 878, 828, 509,
-	596, 510, 829, 830, 0, 831, 0, 511, 512, 515,
-	880, 832, 881, 514, 516, 517, 882, 518, 0, 0,
-	0, 519, 520, 521, 522, 523, 524, 525, 0, 526,
-	528, 527, 0, 530, 833, 529, 883, 531, 532, 884,
-	0, 533, 534, 535, 536, 537, 538, 541, 0, 0,
-	539, 540, 542, 543, 0, 544, 545, 547, 550, 546,
-	548, 549, 551, 552, 565, 566, 553, 554, 555, 556,
-	557, 558, 559, 560, 561, 562, 563, 564, 568, 0,
-	567, 885, 569, 570, 571, 572, 573, 581, 583, 584,
-	579, 580, 582, 585, 586, 588, 589, 576, 577, 578,
-	886, 587, 574, 0, 575, 0, 887, 590, 591, 592,
-	593, 0, 834, 594, 835, 597, 598, 0, 0, 599,
-	0, 600, 0, 0, 602, 603, 604, 0, 0, 605,
-	606, 836, 888, 607, 889, 837, 608, 609, 601, 610,
-	611, 612, 613, 614, 615, 616, 617, 618, 619, 0,
-	620, 621, 838, 622, 623, 624, 839, 625, 626, 627,
-	840, 628, 841, 629, 630, 0, 631, 632, 633, 0,
-	634, 635, 636, 637, 638, 639, 640, 641, 642, 643,
-	842, 644, 645, 647, 646, 648, 649, 0, 650, 0,
-	651, 652, 653, 0, 0, 0, 0, 0, 654, 655,
-	657, 0, 658, 659, 660, 661, 662, 656, 663, 664,
-	665, 666, 667, 668, 669, 0, 671, 672, 670, 673,
-	674, 890, 675, 676, 677, 678, 679, 843, 680, 0,
-	681, 682, 690, 691, 692, 683, 684, 686, 693, 685,
-	694, 695, 696, 697, 699, 698, 295, 701, 702, 700,
-	703, 704, 705, 706, 0, 707, 844, 708, 687, 688,
-	709, 710, 711, 891, 712, 713, 714, 715, 716, 717,
-	718, 719, 720, 845, 0, 721, 0, 722, 723, 724,
-	725, 726, 727, 729, 689, 730, 731, 732, 737, 738,
-	846, 733, 734, 735, 736, 847, 740, 741, 742, 743,
-	0, 744, 745, 0, 739, 728, 297, 746, 747, 748,
-	749, 750, 751, 752, 753, 754, 755, 0, 756, 848,
-	849, 850, 851, 0, 768, 0, 757, 759, 760, 761,
-	762, 852, 763, 853, 0, 764, 765, 766, 767, 758,
-	769, 770, 0, 0, 771, 772, 773, 774, 776, 778,
-	779, 780, 775, 777, 781, 0, 782, 0, 0, 783,
-	784, 785, 2114, 855, 856, 0, 787, 788, 786, 789,
-	790, 793, 791, 792, 857, 796, 513, 797, 798, 799,
-	794, 795, 0, 0, 0, 289, 800, 801, 858, 802,
-	803, 804, 0, 2111, 290, 1733, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 345, 346, 348, 347, 349, 350, 351, 352,
-	0, 353, 354, 0, 0, 233, 0, 0, 805, 0,
-	0, 0, 356, 0, 355, 0, 357, 358, 359, 874,
-	360, 361, 362, 363, 364, 365, 366, 367, 806, 807,
-	0, 368, 808, 369, 809, 0, 810, 370, 371, 372,
-	373, 374, 375, 376, 377, 378, 379, 0, 0, 0,
-	380, 811, 812, 813, 0, 381, 382, 383, 384, 814,
-	0, 875, 0, 385, 386, 387, 388, 389, 390, 391,
-	392, 0, 0, 394, 395, 396, 393, 397, 398, 0,
-	399, 0, 400, 401, 402, 403, 404, 405, 406, 0,
-	407, 408, 409, 876, 410, 411, 412, 0, 0, 0,
-	0, 0, 0, 0, 413, 414, 415, 416, 417, 0,
-	418, 420, 421, 815, 422, 816, 0, 425, 427, 419,
-	423, 0, 426, 424, 428, 429, 0, 430, 431, 432,
-	433, 0, 0, 434, 435, 436, 0, 437, 438, 440,
-	439, 0, 441, 442, 443, 0, 444, 445, 817, 446,
-	447, 448, 450, 452, 449, 451, 453, 454, 455, 456,
-	457, 818, 819, 458, 459, 0, 340, 0, 0, 0,
-	0, 0, 460, 461, 462, 820, 0, 0, 0, 463,
-	0, 465, 469, 466, 467, 468, 470, 0, 464, 471,
-	472, 0, 877, 473, 474, 475, 821, 822, 476, 477,
-	478, 479, 480, 481, 482, 483, 484, 0, 485, 486,
-	823, 0, 824, 487, 0, 488, 489, 490, 491, 492,
-	493, 494, 825, 826, 827, 595, 879, 495, 496, 497,
-	0, 498, 499, 500, 501, 502, 503, 504, 0, 0,
-	0, 505, 506, 507, 508, 0, 0, 0, 0, 878,
-	828, 509, 596, 510, 829, 830, 0, 831, 0, 511,
-	512, 515, 880, 832, 881, 514, 516, 517, 882, 518,
-	0, 0, 0, 519, 520, 521, 522, 523, 524, 525,
-	0, 526, 528, 527, 0, 530, 833, 529, 883, 531,
-	532, 884, 0, 533, 534, 535, 536, 537, 538, 541,
-	0, 0, 539, 540, 542, 543, 0, 544, 545, 547,
-	550, 546, 548, 549, 551, 552, 565, 566, 553, 554,
-	555, 556, 557, 558, 559, 560, 561, 562, 563, 564,
-	568, 0, 567, 885, 569, 570, 571, 572, 573, 581,
-	583, 584, 579, 580, 582, 585, 586, 588, 589, 576,
-	577, 578, 886, 587, 574, 0, 575, 0, 887, 590,
-	591, 592, 593, 0, 834, 594, 835, 597, 598, 0,
-	0, 599, 0, 600, 0, 0, 602, 603, 604, 0,
-	0, 605, 606, 836, 888, 607, 889, 837, 608, 609,
-	601, 610, 611, 612, 613, 614, 615, 616, 617, 618,
-	619, 0, 620, 621, 838, 622, 623, 624, 839, 625,
-	626, 627, 840, 628, 841, 629, 630, 0, 631, 632,
-	633, 0, 634, 635, 636, 637, 638, 639, 640, 641,
-	642, 643, 842, 644, 645, 647, 646, 648, 649, 0,
-	650, 0, 651, 652, 653, 0, 0, 0, 0, 0,
-	654, 655, 657, 0, 658, 659, 660, 661, 662, 656,
-	663, 664, 665, 666, 667, 668, 669, 0, 671, 672,
-	670, 673, 674, 890, 675, 676, 677, 678, 679, 843,
-	680, 0, 681, 682, 690, 691, 692, 683, 684, 686,
-	693, 685, 694, 695, 696, 697, 699, 698, 295, 701,
-	702, 700, 703, 704, 705, 706, 0, 707, 844, 708,
-	687, 688, 709, 710, 711, 891, 712, 713, 714, 715,
-	716, 717, 718, 719, 720, 845, 0, 721, 0, 722,
-	723, 724, 725, 726, 727, 729, 689, 730, 731, 732,
-	737, 738, 846, 733, 734, 735, 736, 847, 740, 741,
-	742, 743, 0, 744, 745, 0, 739, 728, 297, 746,
-	747, 748, 749, 750, 751, 752, 753, 754, 755, 0,
-	756, 848, 849, 850, 851, 0, 768, 0, 757, 759,
-	760, 761, 762, 852, 763, 853, 0, 764, 765, 766,
-	767, 758, 769, 770, 0, 0, 771, 772, 773, 774,
-	776, 778, 779, 780, 775, 777, 781, 0, 782, 0,
-	0, 783, 784, 785, 2114, 855, 856, 0, 787, 788,
-	786, 789, 790, 793, 791, 792, 857, 796, 513, 797,
-	798, 799, 794, 795, 0, 0, 0, 289, 800, 801,
-	858, 802, 803, 804, 0, 0, 290, 1733, 1732, 0,
-	0, 0, 0, 1730, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 345, 346, 348, 347, 349, 350,
-	351, 352, 0, 353, 354, 0, 0, 233, 0, 0,
-	805, 0, 0, 0, 356, 0, 355, 0, 357, 358,
-	359, 874, 360, 361, 362, 363, 364, 365, 366, 367,
-	806, 807, 0, 368, 808, 369, 809, 0, 810, 370,
-	371, 372, 373, 374, 375, 376, 377, 378, 379, 0,
-	0, 0, 380, 811, 812, 813, 0, 381, 382, 383,
-	384, 814, 0, 875, 0, 385, 386, 387, 388, 389,
-	390, 391, 392, 0, 0, 394, 395, 396, 393, 397,
-	398, 0, 399, 0, 400, 401, 402, 403, 404, 405,
-	406, 0, 407, 408, 409, 876, 410, 411, 412, 0,
-	0, 0, 0, 0, 0, 0, 413, 414, 415, 416,
-	417, 0, 418, 420, 421, 815, 422, 816, 0, 425,
-	427, 419, 423, 0, 426, 424, 428, 429, 0, 430,
-	431, 432, 433, 0, 0, 434, 435, 436, 0, 437,
-	438, 440, 439, 0, 441, 442, 443, 0, 444, 445,
-	817, 446, 447, 448, 450, 452, 449, 451, 453, 454,
-	455, 456, 457, 818, 819, 458, 459, 0, 340, 0,
-	0, 0, 0, 0, 460, 461, 462, 820, 0, 0,
-	0, 463, 0, 465, 469, 466, 467, 468, 470, 0,
-	464, 471, 472, 0, 877, 473, 474, 475, 821, 822,
-	476, 477, 478, 479, 480, 481, 482, 483, 484, 0,
-	485, 486, 823, 0, 824, 487, 0, 488, 489, 490,
-	491, 492, 493, 494, 825, 826, 827, 595, 879, 495,
-	496, 497, 0, 498, 499, 500, 501, 502, 503, 504,
-	0, 0, 0, 505, 506, 507, 508, 0, 0, 0,
-	0, 878, 828, 509, 596, 510, 829, 830, 0, 831,
-	0, 511, 512, 515, 880, 832, 881, 514, 516, 517,
-	882, 518, 0, 0, 0, 519, 520, 521, 522, 523,
-	524, 525, 0, 526, 528, 527, 0, 530, 833, 529,
-	883, 531, 532, 884, 0, 533, 534, 535, 536, 537,
-	538, 541, 0, 0, 539, 540, 542, 543, 0, 544,
-	545, 547, 550, 546, 548, 549, 551, 552, 565, 566,
-	553, 554, 555, 556, 557, 558, 559, 560, 561, 562,
-	563, 564, 568, 0, 567, 885, 569, 570, 571, 572,
-	573, 581, 583, 584, 579, 580, 582, 585, 586, 588,
-	589, 576, 577, 578, 886, 587, 574, 0, 575, 0,
-	887, 590, 591, 592, 593, 0, 834, 594, 835, 597,
-	598, 0, 0, 599, 0, 600, 0, 0, 602, 603,
-	604, 0, 0, 605, 606, 836, 888, 607, 889, 837,
-	608, 609, 601, 610, 611, 612, 613, 614, 615, 616,
-	617, 618, 619, 0, 620, 621, 838, 622, 623, 624,
-	839, 625, 626, 627, 840, 628, 841, 629, 630, 0,
-	631, 632, 633, 0, 634, 635, 636, 637, 638, 639,
-	640, 641, 642, 643, 842, 644, 645, 647, 646, 648,
-	649, 0, 650, 0, 651, 652, 653, 0, 0, 0,
-	0, 0, 654, 655, 657, 0, 658, 659, 660, 661,
-	662, 656, 663, 664, 665, 666, 667, 668, 669, 0,
-	671, 672, 670, 673, 674, 890, 675, 676, 677, 678,
-	679, 843, 680, 0, 681, 682, 690, 691, 692, 683,
-	684, 686, 693, 685, 694, 695, 696, 697, 699, 698,
-	0, 701, 702, 700, 703, 704, 705, 706, 0, 707,
-	844, 708, 687, 688, 709, 710, 711, 891, 712, 713,
-	714, 715, 716, 717, 718, 719, 720, 845, 0, 721,
-	0, 722, 723, 724, 725, 726, 727, 729, 689, 730,
-	731, 732, 737, 738, 846, 733, 734, 735, 736, 847,
-	740, 741, 742, 743, 0, 744, 745, 0, 739, 728,
-	0, 746, 747, 748, 749, 750, 751, 752, 753, 754,
-	755, 0, 756, 848, 849, 850, 851, 0, 768, 0,
-	757, 759, 760, 761, 762, 852, 763, 853, 0, 764,
-	765, 766, 767, 758, 769, 770, 0, 0, 771, 772,
-	773, 774, 776, 778, 779, 780, 775, 777, 781, 0,
-	782, 0, 0, 783, 784, 785, 854, 855, 856, 0,
-	787, 788, 786, 789, 790, 793, 791, 792, 857, 796,
-	513, 797, 798, 799, 794, 795, 0, 0, 0, 0,
-	800, 801, 858, 802, 803, 804, 0, 1733, 1732, 0,
-	0, 0, 0, 1730, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 345, 346, 348, 347, 349, 350,
-	351, 352, 0, 353, 354, 0, 0, 0, 0, 2138,
-	805, 0, 0, 0, 356, 0, 355, 0, 357, 358,
-	359, 874, 360, 361, 362, 363, 364, 365, 366, 367,
-	806, 807, 0, 368, 808, 369, 809, 0, 810, 370,
-	371, 372, 373, 374, 375, 376, 377, 378, 379, 0,
-	0, 0, 380, 811, 812, 813, 0, 381, 382, 383,
-	384, 814, 0, 875, 0, 385, 386, 387, 388, 389,
-	390, 391, 392, 0, 0, 394, 395, 396, 393, 397,
-	398, 0, 399, 0, 400, 401, 402, 403, 404, 405,
-	406, 0, 407, 408, 409, 876, 410, 411, 412, 0,
-	0, 0, 0, 0, 0, 0, 413, 414, 415, 416,
-	417, 0, 418, 420, 421, 815, 422, 816, 0, 425,
-	427, 419, 423, 0, 426, 424, 428, 429, 0, 430,
-	431, 432, 433, 0, 0, 434, 435, 436, 0, 437,
-	438, 440, 439, 0, 441, 442, 443, 0, 444, 445,
-	817, 446, 447, 448, 450, 452, 449, 451, 453, 454,
-	455, 456, 457, 818, 819, 458, 459, 0, 340, 0,
-	0, 0, 0, 0, 460, 461, 462, 820, 0, 0,
-	0, 463, 0, 465, 469, 466, 467, 468, 470, 0,
-	464, 471, 472, 0, 877, 473, 474, 475, 821, 822,
-	476, 477, 478, 479, 480, 481, 482, 483, 484, 0,
-	485, 486, 823, 0, 824, 487, 0, 488, 489, 490,
-	491, 492, 493, 494, 825, 826, 827, 595, 879, 495,
-	496, 497, 0, 498, 499, 500, 501, 502, 503, 504,
-	0, 0, 0, 505, 506, 507, 508, 0, 0, 0,
-	0, 878, 828, 509, 596, 510, 829, 830, 0, 831,
-	0, 511, 512, 515, 880, 832, 881, 514, 516, 517,
-	882, 518, 0, 0, 0, 519, 520, 521, 522, 523,
-	524, 525, 0, 526, 528, 527, 0, 530, 833, 529,
-	883, 531, 532, 884, 0, 533, 534, 535, 536, 537,
-	538, 541, 0, 0, 539, 540, 542, 543, 0, 544,
-	545, 547, 550, 546, 548, 549, 551, 552, 565, 566,
-	553, 554, 555, 556, 557, 558, 559, 560, 561, 562,
-	563, 564, 568, 0, 567, 885, 569, 570, 571, 572,
-	573, 581, 583, 584, 579, 580, 582, 585, 586, 588,
-	589, 576, 577, 578, 886, 587, 574, 0, 575, 0,
-	887, 590, 591, 592, 593, 0, 834, 594, 835, 597,
-	598, 0, 0, 599, 0, 600, 0, 0, 602, 603,
-	604, 0, 0, 605, 606, 836, 888, 607, 889, 837,
-	608, 609, 601, 610, 611, 612, 613, 614, 615, 616,
-	617, 618, 619, 0, 620, 621, 838, 622, 623, 624,
-	839, 625, 626, 627, 840, 628, 841, 629, 630, 0,
-	631, 632, 633, 0, 634, 635, 636, 637, 638, 639,
-	640, 641, 642, 643, 842, 644, 645, 647, 646, 648,
-	649, 0, 650, 0, 651, 652, 653, 0, 0, 0,
-	0, 0, 654, 655, 657, 0, 658, 659, 660, 661,
-	662, 656, 663, 664, 665, 666, 667, 668, 669, 0,
-	671, 672, 670, 673, 674, 890, 675, 676, 677, 678,
-	679, 843, 680, 0, 681, 682, 690, 691, 692, 683,
-	684, 686, 693, 685, 694, 695, 696, 697, 699, 698,
-	0, 701, 702, 700, 703, 704, 705, 706, 0, 707,
-	844, 708, 687, 688, 709, 710, 711, 891, 712, 713,
-	714, 715, 716, 717, 718, 719, 720, 845, 0, 721,
-	0, 722, 723, 724, 725, 726, 727, 729, 689, 730,
-	731, 732, 737, 738, 846, 733, 734, 735, 736, 847,
-	740, 741, 742, 743, 0, 744, 745, 0, 739, 728,
-	0, 746, 747, 748, 749, 750, 751, 752, 753, 754,
-	755, 0, 756, 848, 849, 850, 851, 0, 768, 0,
-	757, 759, 760, 761, 762, 852, 763, 853, 0, 764,
-	765, 766, 767, 758, 769, 770, 0, 0, 771, 772,
-	773, 774, 776, 778, 779, 780, 775, 777, 781, 0,
-	782, 0, 0, 783, 784, 785, 854, 855, 856, 0,
-	787, 788, 786, 789, 790, 793, 791, 792, 857, 796,
-	513, 797, 798, 799, 794, 795, 0, 0, 0, 0,
-	800, 801, 858, 802, 803, 804, 0, 1733, 2891, 0,
-	0, 0, 0, 2892, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 345, 346, 348, 347, 349, 350,
-	351, 352, 0, 353, 354, 0, 0, 0, 0, 5148,
-	805, 0, 0, 0, 356, 0, 355, 0, 357, 358,
-	359, 874, 360, 361, 362, 363, 364, 365, 366, 367,
-	806, 807, 0, 368, 808, 369, 809, 0, 810, 370,
-	371, 372, 373, 374, 375, 376, 377, 378, 379, 0,
-	0, 0, 380, 811, 812, 813, 0, 381, 382, 383,
-	384, 814, 0, 875, 0, 385, 386, 387, 388, 389,
-	390, 391, 392, 0, 0, 394, 395, 396, 393, 397,
-	398, 0, 399, 0, 400, 401, 402, 403, 404, 405,
-	406, 0, 407, 408, 409, 876, 410, 411, 412, 0,
-	0, 0, 0, 0, 0, 0, 413, 414, 415, 416,
-	417, 0, 418, 420, 421, 815, 422, 816, 0, 425,
-	427, 419, 423, 0, 426, 424, 428, 429, 0, 430,
-	431, 432, 433, 0, 0, 434, 435, 436, 0, 437,
-	438, 440, 439, 0, 441, 442, 443, 0, 444, 445,
-	817, 446, 447, 448, 450, 452, 449, 451, 453, 454,
-	455, 456, 457, 818, 819, 458, 459, 0, 340, 0,
-	0, 0, 0, 0, 460, 461, 462, 820, 0, 0,
-	0, 463, 0, 465, 469, 466, 467, 468, 470, 0,
-	464, 471, 472, 0, 877, 473, 474, 475, 821, 822,
-	476, 477, 478, 479, 480, 481, 482, 483, 484, 0,
-	485, 486, 823, 0, 824, 487, 0, 488, 489, 490,
-	491, 492, 493, 494, 825, 826, 827, 595, 879, 495,
-	496, 497, 0, 498, 499, 500, 501, 502, 503, 504,
-	0, 0, 0, 505, 506, 507, 508, 0, 0, 0,
-	0, 878, 828, 509, 596, 510, 829, 830, 0, 831,
-	0, 511, 512, 515, 880, 832, 881, 514, 516, 517,
-	882, 518, 0, 0, 0, 519, 520, 521, 522, 523,
-	524, 525, 0, 2890, 528, 527, 0, 530, 833, 529,
-	883, 531, 532, 884, 0, 533, 534, 535, 536, 537,
-	538, 541, 0, 0, 539, 540, 542, 543, 0, 544,
-	545, 547, 550, 546, 548, 549, 551, 552, 565, 566,
-	553, 554, 555, 556, 557, 558, 559, 560, 561, 562,
-	563, 564, 568, 0, 567, 885, 569, 570, 571, 572,
-	573, 581, 583, 584, 579, 580, 582, 585, 586, 588,
-	589, 576, 577, 578, 886, 587, 574, 0, 575, 0,
-	887, 590, 591, 592, 593, 0, 834, 594, 835, 597,
-	598, 0, 0, 599, 0, 600, 0, 0, 602, 603,
-	604, 0, 0, 605, 606, 836, 888, 607, 889, 837,
-	608, 609, 601, 610, 611, 612, 613, 614, 615, 616,
-	617, 618, 619, 0, 620, 621, 838, 622, 623, 624,
-	839, 625, 626, 627, 840, 628, 841, 629, 630, 0,
-	631, 632, 633, 0, 634, 635, 636, 637, 638, 639,
-	640, 641, 642, 643, 842, 644, 645, 647, 646, 648,
-	649, 0, 650, 0, 651, 652, 653, 0, 0, 0,
-	0, 0, 654, 655, 657, 0, 658, 659, 660, 661,
-	662, 656, 663, 664, 665, 666, 667, 668, 669, 0,
-	671, 672, 670, 673, 674, 890, 675, 676, 677, 678,
-	679, 843, 680, 0, 681, 682, 690, 691, 692, 683,
-	684, 686, 693, 685, 694, 695, 696, 697, 699, 698,
-	0, 701, 702, 700, 703, 704, 705, 706, 0, 707,
-	844, 708, 687, 688, 709, 710, 711, 891, 712, 713,
-	714, 715, 716, 717, 718, 719, 720, 845, 0, 721,
-	0, 722, 723, 724, 725, 726, 727, 729, 689, 730,
-	731, 732, 737, 738, 846, 733, 734, 735, 736, 847,
-	740, 741, 742, 743, 0, 744, 745, 0, 739, 728,
-	0, 746, 747, 748, 749, 750, 751, 752, 753, 754,
-	755, 0, 756, 848, 849, 850, 851, 0, 768, 0,
-	757, 759, 760, 761, 762, 852, 763, 853, 0, 764,
-	765, 766, 767, 758, 769, 770, 0, 0, 771, 772,
-	773, 774, 776, 778, 779, 780, 775, 777, 781, 0,
-	782, 0, 0, 783, 784, 785, 854, 855, 856, 0,
-	787, 788, 786, 789, 790, 793, 791, 792, 857, 796,
-	513, 797, 798, 799, 794, 795, 0, 0, 0, 0,
-	800, 801, 858, 802, 803, 804, 0, 1733, 1732, 0,
-	0, 0, 0, 1730, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 345, 346, 348, 347, 349, 350,
-	351, 352, 0, 353, 354, 0, 0, 0, 0, 2138,
-	805, 0, 0, 0, 356, 0, 355, 0, 357, 358,
-	359, 874, 360, 361, 362, 363, 364, 365, 366, 367,
-	806, 807, 0, 368, 808, 369, 809, 0, 810, 370,
-	371, 372, 373, 374, 375, 376, 377, 378, 379, 0,
-	0, 0, 380, 811, 812, 813, 0, 381, 382, 383,
-	384, 814, 0, 875, 0, 385, 386, 387, 388, 389,
-	390, 391, 392, 0, 0, 394, 395, 396, 393, 397,
-	398, 0, 399, 0, 400, 401, 402, 403, 404, 405,
-	406, 0, 407, 408, 409, 876, 410, 411, 412, 0,
-	0, 0, 0, 0, 0, 0, 413, 414, 415, 416,
-	417, 0, 418, 420, 421, 815, 422, 816, 0, 425,
-	427, 419, 423, 0, 426, 424, 428, 429, 0, 430,
-	431, 432, 433, 0, 0, 434, 435, 436, 0, 437,
-	438, 440, 439, 0, 441, 442, 443, 0, 444, 445,
-	817, 446, 447, 448, 450, 452, 449, 451, 453, 454,
-	455, 456, 457, 818, 819, 458, 459, 0, 340, 0,
-	0, 0, 0, 0, 460, 461, 462, 820, 0, 0,
-	0, 463, 0, 465, 469, 466, 467, 468, 470, 0,
-	464, 471, 472, 0, 877, 473, 474, 475, 821, 822,
-	476, 477, 478, 479, 480, 481, 482, 483, 484, 0,
-	485, 486, 823, 0, 824, 487, 0, 488, 489, 490,
-	491, 492, 493, 494, 825, 826, 827, 595, 879, 495,
-	496, 497, 0, 498, 499, 500, 501, 502, 503, 504,
-	0, 0, 0, 505, 506, 507, 508, 0, 0, 0,
-	0, 878, 828, 509, 596, 510, 829, 830, 0, 831,
-	0, 511, 512, 515, 880, 832, 881, 514, 516, 517,
-	882, 518, 0, 0, 0, 519, 520, 521, 522, 523,
-	524, 525, 0, 526, 528, 527, 0, 530, 833, 529,
-	883, 531, 532, 884, 0, 533, 534, 535, 536, 537,
-	538, 541, 0, 0, 539, 540, 542, 543, 0, 544,
-	545, 547, 550, 546, 548, 549, 551, 552, 565, 566,
-	553, 554, 555, 556, 557, 558, 559, 560, 561, 562,
-	563, 564, 568, 0, 567, 885, 569, 570, 571, 572,
-	573, 581, 583, 584, 579, 580, 582, 585, 586, 588,
-	589, 576, 577, 578, 886, 587, 574, 0, 575, 0,
-	887, 590, 591, 592, 593, 0, 834, 594, 835, 597,
-	598, 0, 0, 599, 0, 600, 0, 0, 602, 603,
-	604, 0, 0, 605, 606, 836, 888, 607, 889, 837,
-	608, 609, 601, 610, 611, 612, 613, 614, 615, 616,
-	617, 618, 619, 0, 620, 621, 838, 622, 623, 624,
-	839, 625, 626, 627, 840, 628, 841, 629, 630, 0,
-	631, 632, 633, 0, 634, 635, 636, 637, 638, 639,
-	640, 641, 642, 643, 842, 644, 645, 647, 646, 648,
-	649, 0, 650, 0, 651, 652, 653, 0, 0, 0,
-	0, 0, 654, 655, 657, 0, 658, 659, 660, 661,
-	662, 656, 663, 664, 665, 666, 667, 668, 669, 0,
-	671, 672, 670, 673, 674, 890, 675, 676, 677, 678,
-	679, 843, 680, 0, 681, 682, 690, 691, 692, 683,
-	684, 686, 693, 685, 694, 695, 696, 697, 699, 698,
-	0, 701, 702, 700, 703, 704, 705, 706, 0, 707,
-	844, 708, 687, 688, 709, 710, 711, 891, 712, 713,
-	714, 715, 716, 717, 718, 719, 720, 845, 0, 721,
-	0, 722, 723, 724, 725, 726, 727, 729, 689, 730,
-	731, 732, 737, 738, 846, 733, 734, 735, 736, 847,
-	740, 741, 742, 743, 0, 744, 745, 0, 739, 728,
-	0, 746, 747, 748, 749, 750, 751, 752, 753, 754,
-	755, 0, 756, 848, 849, 850, 851, 0, 768, 0,
-	757, 759, 760, 761, 762, 852, 763, 853, 0, 764,
-	765, 766, 767, 758, 769, 770, 0, 0, 771, 772,
-	773, 774, 776, 778, 779, 780, 775, 777, 781, 0,
-	782, 0, 0, 783, 784, 785, 854, 855, 856, 0,
-	787, 788, 786, 789, 790, 793, 791, 792, 857, 796,
-	513, 797, 798, 799, 794, 795, 0, 0, 0, 868,
-	800, 801, 858, 802, 803, 804, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 345, 346, 348, 347,
-	349, 350, 351, 352, 0, 353, 354, 0, 0, 0,
-	0, 0, 805, 0, 0, 0, 356, 0, 355, 2120,
-	357, 358, 359, 874, 360, 361, 362, 363, 364, 365,
-	366, 367, 806, 807, 0, 368, 808, 369, 809, 0,
-	810, 370, 371, 372, 373, 374, 375, 376, 377, 378,
-	379, 0, 0, 0, 380, 811, 812, 813, 0, 381,
-	382, 383, 384, 814, 0, 875, 0, 385, 386, 387,
-	388, 389, 390, 391, 392, 0, 0, 394, 395, 396,
-	393, 397, 398, 0, 399, 0, 400, 401, 402, 403,
-	404, 405, 406, 0, 407, 408, 409, 876, 410, 411,
-	412, 0, 0, 0, 0, 0, 0, 0, 413, 414,
-	415, 416, 417, 0, 418, 420, 421, 815, 422, 816,
-	0, 425, 427, 419, 423, 0, 426, 424, 428, 429,
-	0, 430, 431, 432, 433, 0, 0, 434, 435, 436,
-	0, 437, 438, 440, 439, 0, 441, 442, 443, 0,
-	444, 445, 817, 446, 447, 448, 450, 452, 449, 451,
-	453, 454, 455, 456, 457, 818, 819, 458, 459, 0,
-	340, 0, 0, 0, 0, 0, 460, 461, 462, 820,
-	0, 0, 0, 463, 0, 465, 469, 466, 467, 468,
-	470, 0, 464, 471, 472, 0, 877, 473, 474, 475,
-	821, 822, 476, 477, 478, 479, 480, 481, 482, 483,
-	484, 0, 485, 486, 823, 0, 824, 487, 0, 488,
-	489, 490, 491, 492, 493, 494, 825, 826, 827, 595,
-	879, 495, 496, 497, 0, 498, 499, 500, 501, 502,
-	503, 504, 0, 0, 0, 505, 506, 507, 508, 0,
-	867, 341, 343, 878, 828, 509, 596, 510, 829, 830,
-	0, 831, 0, 511, 512, 515, 880, 832, 881, 514,
-	516, 517, 882, 518, 0, 0, 0, 519, 520, 521,
-	522, 523, 524, 525, 0, 526, 528, 527, 0, 530,
-	833, 529, 883, 531, 532, 884, 0, 533, 534, 535,
-	536, 537, 538, 541, 0, 0, 539, 540, 542, 543,
-	0, 544, 545, 547, 550, 546, 548, 549, 551, 552,
-	565, 566, 553, 554, 555, 556, 557, 558, 559, 560,
-	561, 562, 563, 564, 568, 0, 567, 885, 569, 570,
-	571, 572, 573, 581, 583, 584, 579, 580, 582, 585,
-	586, 588, 589, 576, 577, 578, 886, 587, 574, 0,
-	575, 344, 887, 590, 591, 592, 593, 0, 834, 594,
-	835, 597, 598, 0, 0, 599, 0, 600, 0, 0,
-	602, 603, 604, 0, 0, 605, 606, 836, 888, 607,
-	889, 837, 608, 609, 601, 610, 611, 612, 613, 614,
-	615, 616, 617, 618, 619, 0, 620, 621, 838, 622,
-	623, 624, 839, 625, 626, 627, 840, 628, 841, 629,
-	630, 0, 631, 632, 633, 0, 634, 635, 636, 637,
-	638, 639, 640, 641, 642, 643, 842, 644, 645, 647,
-	646, 648, 649, 0, 650, 0, 651, 652, 653, 0,
-	0, 0, 0, 0, 654, 655, 657, 0, 658, 659,
-	660, 661, 662, 656, 663, 664, 665, 666, 667, 668,
-	669, 0, 671, 672, 670, 673, 674, 890, 675, 676,
-	677, 678, 679, 843, 680, 0, 681, 682, 690, 691,
-	692, 683, 684, 686, 693, 685, 694, 695, 696, 697,
-	699, 698, 0, 701, 702, 700, 703, 704, 705, 706,
-	0, 707, 844, 708, 687, 688, 709, 710, 711, 891,
-	712, 713, 714, 715, 716, 717, 718, 719, 720, 845,
-	0, 721, 0, 722, 723, 724, 725, 726, 727, 729,
-	689, 730, 731, 732, 737, 738, 846, 733, 734, 735,
-	736, 847, 740, 741, 742, 743, 0, 744, 745, 0,
-	739, 728, 0, 746, 747, 748, 749, 750, 751, 752,
-	753, 754, 755, 0, 756, 848, 849, 850, 851, 0,
-	768, 0, 757, 759, 760, 761, 762, 852, 763, 853,
-	0, 764, 765, 766, 767, 758, 769, 770, 0, 0,
-	771, 772, 773, 774, 776, 778, 779, 780, 775, 777,
-	781, 0, 782, 0, 0, 783, 784, 785, 854, 855,
-	856, 0, 787, 788, 786, 789, 790, 793, 791, 792,
-	857, 796, 513, 797, 798, 799, 794, 795, 0, 1372,
-	0, 337, 800, 801, 858, 802, 803, 804, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 345, 346,
-	348, 347, 349, 350, 351, 352, 0, 353, 354, 0,
-	0, 0, 0, 0, 805, 0, 0, 0, 356, 864,
-	355, 0, 357, 358, 359, 0, 360, 361, 362, 363,
-	364, 365, 366, 367, 806, 807, 0, 368, 808, 369,
-	809, 0, 810, 370, 371, 372, 373, 374, 375, 376,
-	377, 378, 379, 0, 0, 0, 380, 811, 812, 813,
-	0, 381, 382, 383, 384, 814, 0, 0, 0, 385,
-	386, 387, 388, 389, 390, 391, 392, 0, 0, 394,
-	395, 396, 393, 397, 398, 0, 399, 0, 400, 401,
-	402, 403, 404, 405, 406, 0, 407, 408, 409, 0,
-	410, 411, 412, 0, 0, 0, 0, 0, 0, 0,
-	413, 414, 415, 416, 417, 0, 418, 420, 421, 815,
-	422, 816, 0, 425, 427, 419, 423, 0, 426, 424,
-	428, 429, 0, 430, 431, 432, 433, 0, 0, 434,
-	435, 436, 0, 437, 438, 440, 439, 0, 441, 442,
-	443, 0, 444, 445, 817, 446, 447, 448, 450, 452,
-	449, 451, 453, 454, 455, 456, 457, 818, 819, 458,
-	459, 0, 0, 0, 0, 0, 0, 0, 460, 461,
-	462, 820, 0, 0, 0, 463, 0, 465, 469, 466,
-	467, 468, 470, 0, 464, 471, 472, 0, 0, 473,
-	474, 475, 821, 822, 476, 477, 478, 479, 480, 481,
-	482, 483, 484, 0, 485, 486, 823, 0, 824, 487,
-	0, 488, 489, 490, 491, 492, 493, 494, 825, 826,
-	827, 595, 0, 495, 496, 497, 0, 498, 499, 500,
-	501, 502, 503, 504, 0, 0, 0, 505, 506, 507,
-	508, 0, 0, 0, 0, 0, 828, 509, 596, 510,
-	829, 830, 0, 831, 0, 511, 512, 515, 0, 832,
-	0, 514, 516, 517, 0, 518, 0, 0, 0, 519,
-	520, 521, 522, 523, 524, 525, 0, 526, 528, 527,
-	0, 530, 833, 529, 0, 531, 532, 0, 0, 533,
-	534, 535, 536, 537, 538, 541, 0, 0, 539, 540,
-	542, 543, 0, 544, 545, 547, 550, 546, 548, 549,
-	551, 552, 565, 566, 553, 554, 555, 556, 557, 558,
-	559, 560, 561, 562, 563, 564, 568, 0, 567, 0,
-	569, 570, 571, 572, 573, 581, 583, 584, 579, 580,
-	582, 585, 586, 588, 589, 576, 577, 578, 0, 587,
-	574, 0, 575, 0, 0, 590, 591, 592, 593, 0,
-	834, 594, 835, 597, 598, 0, 0, 599, 0, 600,
-	0, 0, 602, 603, 604, 0, 0, 605, 606, 836,
-	0, 607, 0, 837, 608, 609, 601, 610, 611, 612,
-	613, 614, 615, 616, 617, 618, 619, 0, 620, 621,
-	838, 622, 623, 624, 839, 625, 626, 627, 840, 628,
-	841, 629, 630, 0, 631, 632, 633, 0, 634, 635,
-	636, 637, 638, 639, 640, 641, 642, 643, 842, 644,
-	645, 647, 646, 648, 649, 0, 650, 0, 651, 652,
-	653, 0, 0, 0, 0, 0, 654, 655, 657, 0,
-	658, 659, 660, 661, 662, 656, 663, 664, 665, 666,
-	667, 668, 669, 0, 671, 672, 670, 673, 674, 0,
-	675, 676, 677, 678, 679, 843, 680, 0, 681, 682,
-	690, 691, 692, 683, 684, 686, 693, 685, 694, 695,
-	696, 697, 699, 698, 295, 701, 702, 700, 703, 704,
-	705, 706, 0, 707, 844, 708, 687, 688, 709, 710,
-	711, 0, 712, 713, 714, 715, 716, 717, 718, 719,
-	720, 845, 0, 721, 0, 722, 723, 724, 725, 726,
-	727, 729, 689, 730, 731, 732, 737, 738, 846, 733,
-	734, 735, 736, 847, 740, 741, 742, 743, 0, 744,
-	745, 0, 739, 728, 297, 746, 747, 748, 749, 750,
-	751, 752, 753, 754, 755, 0, 756, 848, 849, 850,
-	851, 0, 768, 0, 757, 759, 760, 761, 762, 852,
-	763, 853, 0, 764, 765, 766, 767, 758, 769, 770,
-	0, 0, 771, 772, 773, 774, 776, 778, 779, 780,
-	775, 777, 781, 0, 782, 0, 0, 783, 784, 785,
-	2114, 855, 856, 0, 787, 788, 786, 789, 790, 793,
-	791, 792, 857, 796, 513, 797, 798, 799, 794, 795,
-	0, 0, 0, 289, 800, 801, 858, 802, 803, 804,
-	0, 337, 290, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 345, 346,
-	348, 347, 349, 350, 351, 352, 0, 353, 354, 0,
-	0, 0, 0, 233, 805, 0, 0, 0, 356, 0,
-	355, 0, 357, 358, 359, 0, 360, 361, 362, 363,
-	364, 365, 366, 367, 806, 807, 0, 368, 808, 369,
-	809, 0, 810, 370, 371, 372, 373, 374, 375, 376,
-	377, 378, 379, 0, 0, 0, 380, 811, 812, 813,
-	0, 381, 382, 383, 384, 814, 0, 0, 0, 385,
-	386, 387, 388, 389, 390, 391, 392, 0, 0, 394,
-	395, 396, 393, 397, 398, 0, 399, 0, 400, 401,
-	402, 403, 404, 405, 406, 0, 407, 408, 409, 0,
-	410, 411, 412, 0, 0, 0, 0, 0, 0, 0,
-	413, 414, 415, 416, 417, 0, 418, 420, 421, 815,
-	422, 816, 0, 425, 427, 419, 423, 0, 426, 424,
-	428, 429, 0, 430, 431, 432, 433, 0, 0, 434,
-	435, 436, 0, 437, 438, 440, 439, 0, 441, 442,
-	443, 0, 444, 445, 817, 446, 447, 448, 450, 452,
-	449, 451, 453, 454, 455, 456, 457, 818, 819, 458,
-	459, 0, 340, 0, 0, 0, 0, 0, 460, 461,
-	462, 820, 0, 0, 0, 463, 0, 465, 469, 466,
-	467, 468, 470, 0, 464, 471, 472, 0, 0, 473,
-	474, 475, 821, 822, 476, 477, 478, 479, 480, 481,
-	482, 483, 484, 0, 485, 486, 823, 0, 824, 487,
-	0, 488, 489, 490, 491, 492, 493, 494, 825, 826,
-	827, 595, 0, 495, 496, 497, 0, 498, 499, 500,
-	501, 502, 503, 504, 0, 0, 0, 505, 506, 507,
-	508, 0, 342, 341, 343, 0, 828, 509, 596, 510,
-	829, 830, 0, 831, 0, 511, 512, 515, 0, 832,
-	0, 514, 516, 517, 0, 518, 0, 0, 0, 519,
-	520, 521, 522, 523, 524, 525, 0, 526, 528, 527,
-	0, 530, 833, 529, 0, 531, 532, 0, 0, 533,
-	534, 535, 536, 537, 538, 541, 0, 0, 539, 540,
-	542, 543, 0, 544, 545, 547, 550, 546, 548, 549,
-	551, 552, 565, 566, 553, 554, 555, 556, 557, 558,
-	559, 560, 561, 562, 563, 564, 568, 0, 567, 0,
-	569, 570, 571, 572, 573, 581, 583, 584, 579, 580,
-	582, 585, 586, 588, 589, 576, 577, 578, 0, 587,
-	574, 0, 575, 344, 0, 590, 591, 592, 593, 0,
-	834, 594, 835, 597, 598, 0, 0, 599, 0, 600,
-	0, 0, 602, 603, 604, 0, 0, 605, 606, 836,
-	0, 607, 0, 837, 608, 609, 601, 610, 611, 612,
-	613, 614, 615, 616, 617, 618, 619, 0, 620, 621,
-	838, 622, 623, 624, 839, 625, 626, 627, 840, 628,
-	841, 629, 630, 0, 631, 632, 633, 0, 634, 635,
-	636, 637, 638, 639, 640, 641, 642, 643, 842, 644,
-	645, 647, 646, 648, 649, 0, 650, 0, 651, 652,
-	653, 0, 0, 0, 0, 0, 654, 655, 657, 0,
-	658, 659, 660, 661, 662, 656, 663, 664, 665, 666,
-	667, 668, 669, 0, 671, 672, 670, 673, 674, 0,
-	675, 676, 677, 678, 679, 843, 680, 0, 681, 682,
-	690, 691, 692, 683, 684, 686, 693, 685, 694, 695,
-	696, 697, 699, 698, 0, 701, 702, 700, 703, 704,
-	705, 706, 0, 707, 844, 708, 687, 688, 709, 710,
-	711, 0, 712, 713, 714, 715, 716, 717, 718, 719,
-	720, 845, 0, 721, 0, 722, 723, 724, 725, 726,
-	727, 729, 689, 730, 731, 732, 737, 738, 846, 733,
-	734, 735, 736, 847, 740, 741, 742, 743, 0, 744,
-	745, 0, 739, 728, 0, 746, 747, 748, 749, 750,
-	751, 752, 753, 754, 755, 0, 756, 848, 849, 850,
-	851, 0, 768, 0, 757, 759, 760, 761, 762, 852,
-	763, 853, 0, 764, 765, 766, 767, 758, 769, 770,
-	0, 0, 771, 772, 773, 774, 776, 778, 779, 780,
-	775, 777, 781, 0, 782, 0, 0, 783, 784, 785,
-	854, 855, 856, 0, 787, 788, 786, 789, 790, 793,
-	791, 792, 857, 796, 513, 797, 798, 799, 794, 795,
-	0, 0, 0, 337, 800, 801, 858, 802, 803, 804,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	345, 346, 348, 347, 349, 350, 351, 352, 0, 353,
-	354, 0, 0, 0, 0, 0, 805, 0, 0, 0,
-	356, 0, 355, 2380, 357, 358, 359, 0, 360, 361,
-	362, 363, 364, 365, 366, 367, 806, 807, 0, 368,
-	808, 369, 809, 0, 810, 370, 371, 372, 373, 374,
-	375, 376, 377, 378, 379, 0, 0, 0, 380, 811,
-	812, 813, 0, 381, 382, 383, 384, 814, 0, 0,
-	0, 385, 386, 387, 388, 389, 390, 391, 392, 0,
-	0, 394, 395, 396, 393, 397, 398, 0, 399, 0,
-	400, 401, 402, 403, 404, 405, 406, 0, 407, 408,
-	409, 0, 410, 411, 412, 0, 0, 0, 0, 0,
-	0, 0, 413, 414, 415, 416, 417, 0, 418, 420,
-	421, 815, 422, 816, 0, 425, 427, 419, 423, 0,
-	426, 424, 428, 429, 0, 430, 431, 432, 433, 0,
-	0, 434, 435, 436, 0, 437, 438, 440, 439, 0,
-	441, 442, 443, 0, 444, 445, 817, 446, 447, 448,
-	450, 452, 449, 451, 453, 454, 455, 456, 457, 818,
-	819, 458, 459, 0, 340, 0, 0, 0, 0, 0,
-	460, 461, 462, 820, 0, 0, 0, 463, 0, 465,
-	469, 466, 467, 468, 470, 0, 464, 471, 472, 0,
-	0, 473, 474, 475, 821, 822, 476, 477, 478, 479,
-	480, 481, 482, 483, 484, 0, 485, 486, 823, 0,
-	824, 487, 0, 488, 489, 490, 491, 492, 493, 494,
-	825, 826, 827, 595, 0, 495, 496, 497, 0, 498,
-	499, 500, 501, 502, 503, 504, 0, 0, 0, 505,
-	506, 507, 508, 0, 342, 341, 343, 0, 828, 509,
-	596, 510, 829, 830, 0, 831, 0, 511, 512, 515,
-	0, 832, 0, 514, 516, 517, 0, 518, 0, 0,
-	0, 519, 520, 521, 522, 523, 524, 525, 0, 526,
-	528, 527, 0, 530, 833, 529, 0, 531, 532, 0,
-	0, 533, 534, 535, 536, 537, 538, 541, 0, 0,
-	539, 540, 542, 543, 0, 544, 545, 547, 550, 546,
-	548, 549, 551, 552, 565, 566, 553, 554, 555, 556,
-	557, 558, 559, 560, 561, 562, 563, 564, 568, 0,
-	567, 0, 569, 570, 571, 572, 573, 581, 583, 584,
-	579, 580, 582, 585, 586, 588, 589, 576, 577, 578,
-	0, 587, 574, 0, 575, 344, 0, 590, 591, 592,
-	593, 0, 834, 594, 835, 597, 598, 0, 0, 599,
-	0, 600, 0, 0, 602, 603, 604, 0, 0, 605,
-	606, 836, 0, 607, 0, 837, 608, 609, 601, 610,
-	611, 612, 613, 614, 615, 616, 617, 618, 619, 0,
-	620, 621, 838, 622, 623, 624, 839, 625, 626, 627,
-	840, 628, 841, 629, 630, 0, 631, 632, 633, 0,
-	634, 635, 636, 637, 638, 639, 640, 641, 642, 643,
-	842, 644, 645, 647, 646, 648, 649, 0, 650, 0,
-	651, 652, 653, 0, 0, 0, 0, 0, 654, 655,
-	657, 0, 658, 659, 660, 661, 662, 656, 663, 664,
-	665, 666, 667, 668, 669, 0, 671, 672, 670, 673,
-	674, 0, 675, 676, 677, 678, 679, 843, 680, 0,
-	681, 682, 690, 691, 692, 683, 684, 686, 693, 685,
-	694, 695, 696, 697, 699, 698, 0, 701, 702, 700,
-	703, 704, 705, 706, 0, 707, 844, 708, 687, 688,
-	709, 710, 711, 0, 712, 713, 714, 715, 716, 717,
-	718, 719, 720, 845, 0, 721, 0, 722, 723, 724,
-	725, 726, 727, 729, 689, 730, 731, 732, 737, 738,
-	846, 733, 734, 735, 736, 847, 740, 741, 742, 743,
-	0, 744, 745, 0, 739, 728, 0, 746, 747, 748,
-	749, 750, 751, 752, 753, 754, 755, 0, 756, 848,
-	849, 850, 851, 0, 768, 0, 757, 759, 760, 761,
-	762, 852, 763, 853, 0, 764, 765, 766, 767, 758,
-	769, 770, 0, 0, 771, 772, 773, 774, 776, 778,
-	779, 780, 775, 777, 781, 0, 782, 0, 0, 783,
-	784, 785, 854, 855, 856, 0, 787, 788, 786, 789,
-	790, 793, 791, 792, 857, 796, 513, 797, 798, 799,
-	794, 795, 0, 0, 0, 337, 800, 801, 858, 802,
-	803, 804, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 345, 346, 348, 347, 349, 350, 351, 352,
-	0, 353, 354, 0, 0, 0, 0, 0, 805, 0,
-	0, 0, 356, 0, 355, 893, 357, 358, 359, 0,
-	360, 361, 362, 363, 364, 365, 366, 367, 806, 807,
-	0, 368, 808, 369, 809, 0, 810, 370, 371, 372,
-	373, 374, 375, 376, 377, 378, 379, 0, 0, 0,
-	380, 811, 812, 813, 0, 381, 382, 383, 384, 814,
-	0, 0, 0, 385, 386, 387, 388, 389, 390, 391,
-	392, 0, 0, 394, 395, 396, 393, 397, 398, 0,
-	399, 0, 400, 401, 402, 403, 404, 405, 406, 0,
-	407, 408, 409, 0, 410, 411, 412, 0, 0, 0,
-	0, 0, 0, 0, 413, 414, 415, 416, 417, 0,
-	418, 420, 421, 815, 422, 816, 0, 425, 427, 419,
-	423, 0, 426, 424, 428, 429, 0, 430, 431, 432,
-	433, 0, 0, 434, 435, 436, 0, 437, 438, 440,
-	439, 0, 441, 442, 443, 0, 444, 445, 817, 446,
-	447, 448, 450, 452, 449, 451, 453, 454, 455, 456,
-	457, 818, 819, 458, 459, 0, 340, 0, 0, 0,
-	0, 0, 460, 461, 462, 820, 0, 0, 0, 463,
-	0, 465, 469, 466, 467, 468, 470, 0, 464, 471,
-	472, 0, 0, 473, 474, 475, 821, 822, 476, 477,
-	478, 479, 480, 481, 482, 483, 484, 0, 485, 486,
-	823, 0, 824, 487, 0, 488, 489, 490, 491, 492,
-	493, 494, 825, 826, 827, 595, 0, 495, 496, 497,
-	0, 498, 499, 500, 501, 502, 503, 504, 0, 0,
-	0, 505, 506, 507, 508, 0, 342, 341, 343, 0,
-	828, 509, 596, 510, 829, 830, 0, 831, 0, 511,
-	512, 515, 0, 832, 0, 514, 516, 517, 0, 518,
-	0, 0, 0, 519, 520, 521, 522, 523, 524, 525,
-	0, 526, 528, 527, 0, 530, 833, 529, 0, 531,
-	532, 0, 0, 533, 534, 535, 536, 537, 538, 541,
-	0, 0, 539, 540, 542, 543, 0, 544, 545, 547,
-	550, 546, 548, 549, 551, 552, 565, 566, 553, 554,
-	555, 556, 557, 558, 559, 560, 561, 562, 563, 564,
-	568, 0, 567, 0, 569, 570, 571, 572, 573, 581,
-	583, 584, 579, 580, 582, 585, 586, 588, 589, 576,
-	577, 578, 0, 587, 574, 0, 575, 344, 0, 590,
-	591, 592, 593, 0, 834, 594, 835, 597, 598, 0,
-	0, 599, 0, 600, 0, 0, 602, 603, 604, 0,
-	0, 605, 606, 836, 0, 607, 0, 837, 608, 609,
-	601, 610, 611, 612, 613, 614, 615, 616, 617, 618,
-	619, 0, 620, 621, 838, 622, 623, 624, 839, 625,
-	626, 627, 840, 628, 841, 629, 630, 0, 631, 632,
-	633, 0, 634, 635, 636, 637, 638, 639, 640, 641,
-	642, 643, 842, 644, 645, 647, 646, 648, 649, 0,
-	650, 0, 651, 652, 653, 0, 0, 0, 0, 0,
-	654, 655, 657, 0, 658, 659, 660, 661, 662, 656,
-	663, 664, 665, 666, 667, 668, 669, 0, 671, 672,
-	670, 673, 674, 0, 675, 676, 677, 678, 679, 843,
-	680, 0, 681, 682, 690, 691, 692, 683, 684, 686,
-	693, 685, 694, 695, 696, 697, 699, 698, 0, 701,
-	702, 700, 703, 704, 705, 706, 0, 707, 844, 708,
-	687, 688, 709, 710, 711, 0, 712, 713, 714, 715,
-	716, 717, 718, 719, 720, 845, 0, 721, 0, 722,
-	723, 724, 725, 726, 727, 729, 689, 730, 731, 732,
-	737, 738, 846, 733, 734, 735, 736, 847, 740, 741,
-	742, 743, 0, 744, 745, 0, 739, 728, 0, 746,
-	747, 748, 749, 750, 751, 752, 753, 754, 755, 0,
-	756, 848, 849, 850, 851, 0, 768, 0, 757, 759,
-	760, 761, 762, 852, 763, 853, 0, 764, 765, 766,
-	767, 758, 769, 770, 0, 0, 771, 772, 773, 774,
-	776, 778, 779, 780, 775, 777, 781, 0, 782, 0,
-	0, 783, 784, 785, 854, 855, 856, 0, 787, 788,
-	786, 789, 790, 793, 791, 792, 857, 796, 513, 797,
-	798, 799, 794, 795, 0, 337, 0, 0, 800, 801,
-	858, 802, 803, 804, 0, 0, 0, 0, 0, 0,
-	0, 0, 345, 346, 348, 347, 349, 350, 351, 352,
-	0, 353, 354, 0, 0, 0, 0, 0, 805, 0,
-	0, 0, 356, 0, 355, 2108, 357, 358, 359, 0,
-	360, 361, 362, 363, 364, 365, 366, 367, 806, 807,
-	0, 368, 808, 369, 809, 0, 810, 370, 371, 372,
-	373, 374, 375, 376, 377, 378, 379, 0, 0, 0,
-	380, 811, 812, 813, 0, 381, 382, 383, 384, 814,
-	0, 0, 0, 385, 386, 387, 388, 389, 390, 391,
-	392, 0, 0, 394, 395, 396, 393, 397, 398, 0,
-	399, 0, 400, 401, 402, 403, 404, 405, 406, 0,
-	407, 408, 409, 0, 410, 411, 412, 0, 0, 0,
-	0, 0, 0, 0, 413, 414, 415, 416, 417, 0,
-	418, 420, 421, 815, 422, 816, 0, 425, 427, 419,
-	423, 0, 426, 424, 428, 429, 0, 430, 431, 432,
-	433, 0, 0, 434, 435, 436, 0, 437, 438, 440,
-	439, 0, 441, 442, 443, 0, 444, 445, 817, 446,
-	447, 448, 450, 452, 449, 451, 453, 454, 455, 456,
-	457, 818, 819, 458, 459, 0, 340, 0, 0, 0,
-	0, 0, 460, 461, 462, 820, 0, 0, 0, 463,
-	0, 465, 469, 466, 467, 468, 470, 0, 464, 471,
-	472, 0, 0, 473, 474, 475, 821, 822, 476, 477,
-	478, 479, 480, 481, 482, 483, 484, 0, 485, 486,
-	823, 0, 824, 487, 0, 488, 489, 490, 491, 492,
-	493, 494, 825, 826, 827, 595, 0, 495, 496, 497,
-	0, 498, 499, 500, 501, 502, 503, 504, 0, 0,
-	0, 505, 506, 507, 508, 0, 342, 341, 343, 0,
-	828, 509, 596, 510, 829, 830, 0, 831, 0, 511,
-	512, 515, 0, 832, 0, 514, 516, 517, 0, 518,
-	0, 0, 0, 519, 520, 521, 522, 523, 524, 525,
-	0, 526, 528, 527, 0, 530, 833, 529, 0, 531,
-	532, 0, 0, 533, 534, 535, 536, 537, 538, 541,
-	0, 0, 539, 540, 542, 543, 0, 544, 545, 547,
-	550, 546, 548, 549, 551, 552, 565, 566, 553, 554,
-	555, 556, 557, 558, 559, 560, 561, 562, 563, 564,
-	568, 0, 567, 0, 569, 570, 571, 572, 573, 581,
-	583, 584, 579, 580, 582, 585, 586, 588, 589, 576,
-	577, 578, 0, 587, 574, 0, 575, 344, 0, 590,
-	591, 592, 593, 0, 834, 594, 835, 597, 598, 0,
-	0, 599, 0, 600, 0, 0, 602, 603, 604, 0,
-	0, 605, 606, 836, 0, 607, 0, 837, 608, 609,
-	601, 610, 611, 612, 613, 614, 615, 616, 617, 618,
-	619, 0, 620, 621, 838, 622, 623, 624, 839, 625,
-	626, 627, 840, 628, 841, 629, 630, 0, 631, 632,
-	633, 0, 634, 635, 636, 637, 638, 639, 640, 641,
-	642, 643, 842, 644, 645, 647, 646, 648, 649, 0,
-	650, 0, 651, 652, 653, 0, 0, 0, 0, 0,
-	654, 655, 657, 0, 658, 659, 660, 661, 662, 656,
-	663, 664, 665, 666, 667, 668, 669, 0, 671, 672,
-	670, 673, 674, 0, 675, 676, 677, 678, 679, 843,
-	680, 0, 681, 682, 690, 691, 692, 683, 684, 686,
-	693, 685, 694, 695, 696, 697, 699, 698, 0, 701,
-	702, 700, 703, 704, 705, 706, 0, 707, 844, 708,
-	687, 688, 709, 710, 711, 0, 712, 713, 714, 715,
-	716, 717, 718, 719, 720, 845, 0, 721, 0, 722,
-	723, 724, 725, 726, 727, 729, 689, 730, 731, 732,
-	737, 738, 846, 733, 734, 735, 736, 847, 740, 741,
-	742, 743, 0, 744, 745, 0, 739, 728, 0, 746,
-	747, 748, 749, 750, 751, 752, 753, 754, 755, 0,
-	756, 848, 849, 850, 851, 0, 768, 0, 757, 759,
-	760, 761, 762, 852, 763, 853, 0, 764, 765, 766,
-	767, 758, 769, 770, 0, 0, 771, 772, 773, 774,
-	776, 778, 779, 780, 775, 777, 781, 0, 782, 0,
-	0, 783, 784, 785, 854, 855, 856, 0, 787, 788,
-	786, 789, 790, 793, 791, 792, 857, 796, 513, 797,
-	798, 799, 794, 795, 0, 337, 4327, 0, 800, 801,
-	858, 802, 803, 804, 0, 0, 0, 0, 0, 0,
-	0, 0, 345, 346, 348, 347, 349, 350, 351, 352,
-	0, 353, 354, 0, 0, 0, 0, 0, 805, 0,
-	0, 0, 356, 0, 355, 5094, 357, 358, 359, 0,
-	360, 361, 362, 363, 364, 365, 366, 367, 806, 807,
-	0, 368, 808, 369, 809, 0, 810, 370, 371, 372,
-	373, 374, 375, 376, 377, 378, 379, 0, 0, 0,
-	380, 811, 812, 813, 0, 381, 382, 383, 384, 814,
-	0, 0, 0, 385, 386, 387, 388, 389, 390, 391,
-	392, 0, 0, 394, 395, 396, 393, 397, 398, 0,
-	399, 0, 400, 401, 402, 403, 404, 405, 406, 0,
-	407, 408, 409, 0, 410, 411, 412, 0, 0, 0,
-	0, 0, 0, 0, 413, 414, 415, 416, 417, 0,
-	418, 420, 421, 815, 422, 816, 0, 425, 427, 419,
-	423, 0, 426, 424, 428, 429, 0, 430, 431, 432,
-	433, 0, 0, 434, 435, 436, 0, 437, 438, 440,
-	439, 0, 441, 442, 443, 0, 444, 445, 817, 446,
-	447, 448, 450, 452, 449, 451, 453, 454, 455, 456,
-	457, 818, 819, 458, 459, 0, 0, 0, 0, 0,
-	0, 0, 460, 461, 462, 820, 0, 0, 0, 463,
-	0, 465, 469, 466, 467, 468, 470, 0, 464, 471,
-	472, 0, 0, 473, 474, 475, 821, 822, 476, 477,
-	478, 479, 480, 481, 482, 483, 484, 0, 485, 486,
-	823, 0, 824, 487, 0, 488, 489, 490, 491, 492,
-	493, 494, 825, 826, 827, 595, 0, 495, 496, 497,
-	0, 498, 499, 500, 501, 502, 503, 504, 0, 0,
-	0, 505, 506, 507, 508, 0, 0, 0, 0, 0,
-	828, 509, 596, 510, 829, 830, 0, 831, 0, 511,
-	512, 515, 0, 832, 0, 514, 516, 517, 0, 518,
-	0, 0, 0, 519, 520, 521, 522, 523, 524, 525,
-	0, 526, 528, 527, 0, 530, 833, 529, 0, 531,
-	532, 0, 0, 533, 534, 535, 536, 537, 538, 541,
-	0, 0, 539, 540, 542, 543, 0, 544, 545, 547,
-	550, 546, 548, 549, 551, 552, 565, 566, 553, 554,
-	555, 556, 557, 558, 559, 560, 561, 562, 563, 564,
-	568, 0, 567, 0, 569, 570, 571, 572, 573, 581,
-	583, 584, 579, 580, 582, 585, 586, 588, 589, 576,
-	577, 578, 0, 587, 574, 0, 575, 0, 0, 590,
-	591, 592, 593, 0, 834, 594, 835, 597, 598, 0,
-	0, 599, 0, 600, 0, 0, 602, 603, 604, 0,
-	0, 605, 606, 836, 0, 607, 0, 837, 608, 609,
-	601, 610, 611, 612, 613, 614, 615, 616, 617, 618,
-	619, 0, 620, 621, 838, 622, 623, 624, 839, 625,
-	626, 627, 840, 628, 841, 629, 630, 0, 631, 632,
-	633, 0, 634, 635, 636, 637, 638, 639, 640, 641,
-	642, 643, 842, 644, 645, 647, 646, 648, 649, 0,
-	650, 0, 651, 652, 653, 0, 0, 0, 0, 0,
-	654, 655, 657, 0, 658, 659, 660, 661, 662, 656,
-	663, 664, 665, 666, 667, 668, 669, 0, 671, 672,
-	670, 673, 674, 0, 675, 676, 677, 678, 679, 843,
-	680, 0, 681, 682, 690, 691, 692, 683, 684, 686,
-	693, 685, 694, 695, 696, 697, 699, 698, 0, 701,
-	702, 700, 703, 704, 705, 706, 0, 707, 844, 708,
-	687, 688, 709, 710, 711, 0, 712, 713, 714, 715,
-	716, 717, 718, 719, 720, 845, 0, 721, 0, 722,
-	723, 724, 725, 726, 727, 729, 689, 730, 731, 732,
-	737, 738, 846, 733, 734, 735, 736, 847, 740, 741,
-	742, 743, 0, 744, 745, 0, 739, 728, 0, 746,
-	747, 748, 749, 750, 751, 752, 753, 754, 755, 0,
-	756, 848, 849, 850, 851, 0, 768, 0, 757, 759,
-	760, 761, 762, 852, 763, 853, 0, 764, 765, 766,
-	767, 758, 769, 770, 0, 0, 771, 772, 773, 774,
-	776, 778, 779, 780, 775, 777, 781, 0, 782, 0,
-	0, 783, 784, 785, 854, 855, 856, 0, 787, 788,
-	786, 789, 790, 793, 791, 792, 857, 796, 513, 797,
-	798, 799, 794, 795, 0, 0, 0, 4022, 800, 801,
-	858, 802, 803, 804, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 345, 346, 348, 347, 349, 350,
-	351, 352, 0, 353, 354, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 356, 0, 355, 6694, 357, 358,
-	359, 874, 360, 361, 362, 363, 364, 365, 366, 367,
-	0, 2451, 0, 368, 2458, 369, 2457, 0, 2466, 370,
-	371, 372, 373, 374, 375, 376, 377, 378, 379, 0,
-	0, 0, 380, 2469, 2470, 0, 0, 381, 382, 383,
-	384, 0, 0, 875, 0, 385, 386, 387, 388, 389,
-	390, 391, 392, 0, 0, 394, 395, 396, 393, 397,
-	398, 0, 399, 0, 400, 401, 402, 403, 404, 405,
-	406, 0, 407, 408, 409, 876, 410, 411, 412, 0,
-	0, 0, 0, 0, 0, 0, 413, 414, 415, 416,
-	417, 1477, 418, 420, 421, 2455, 422, 2454, 0, 425,
-	427, 419, 423, 0, 426, 424, 428, 429, 0, 430,
-	431, 432, 433, 0, 0, 434, 1469, 436, 0, 437,
-	438, 440, 439, 0, 441, 442, 443, 0, 444, 445,
-	0, 446, 447, 448, 450, 452, 449, 451, 453, 454,
-	455, 456, 457, 0, 0, 458, 459, 0, 340, 0,
-	0, 0, 0, 0, 460, 461, 462, 2453, 0, 0,
-	0, 463, 0, 465, 469, 466, 467, 468, 470, 0,
-	464, 471, 472, 0, 877, 473, 474, 475, 2464, 2465,
-	476, 477, 478, 479, 480, 481, 482, 483, 484, 0,
-	485, 486, 0, 0, 0, 487, 0, 488, 489, 490,
-	491, 492, 493, 494, 0, 0, 0, 595, 879, 495,
-	496, 497, 4016, 498, 499, 500, 501, 502, 503, 504,
-	0, 0, 0, 505, 506, 507, 508, 0, 0, 0,
-	0, 878, 4018, 509, 596, 510, 2448, 2449, 0, 2444,
-	0, 511, 512, 515, 880, 0, 881, 514, 516, 517,
-	882, 518, 0, 0, 0, 519, 520, 521, 522, 523,
-	524, 525, 0, 526, 528, 527, 0, 530, 0, 529,
-	883, 531, 532, 884, 0, 533, 534, 535, 536, 537,
-	538, 541, 0, 0, 539, 540, 542, 543, 0, 544,
-	545, 547, 550, 546, 548, 549, 551, 552, 565, 566,
-	553, 554, 555, 556, 557, 558, 559, 560, 561, 562,
-	563, 564, 568, 0, 567, 885, 569, 570, 571, 572,
-	573, 581, 583, 584, 579, 580, 582, 585, 586, 588,
-	589, 576, 577, 578, 886, 587, 574, 0, 575, 0,
-	887, 590, 591, 592, 593, 0, 0, 594, 2456, 597,
-	598, 0, 0, 599, 0, 600, 0, 0, 602, 603,
-	604, 0, 0, 605, 606, 4017, 888, 607, 889, 0,
-	608, 609, 601, 610, 611, 612, 613, 614, 615, 616,
-	617, 618, 619, 0, 620, 621, 2441, 622, 623, 624,
-	2442, 625, 626, 627, 0, 628, 0, 629, 630, 0,
-	631, 632, 633, 0, 634, 635, 636, 637, 638, 639,
-	640, 641, 642, 643, 2452, 644, 645, 647, 646, 648,
-	649, 0, 650, 0, 651, 652, 653, 0, 0, 0,
-	0, 0, 654, 655, 657, 0, 658, 659, 660, 661,
-	662, 656, 663, 664, 665, 666, 667, 668, 669, 0,
-	671, 672, 670, 673, 674, 890, 675, 676, 677, 678,
-	679, 0, 680, 0, 681, 682, 690, 691, 692, 683,
-	684, 686, 693, 685, 694, 695, 696, 697, 699, 698,
-	0, 701, 702, 700, 703, 704, 705, 706, 0, 707,
-	0, 708, 687, 688, 709, 710, 711, 891, 712, 713,
-	714, 715, 716, 717, 718, 719, 720, 2450, 0, 721,
-	0, 722, 723, 724, 725, 726, 727, 729, 689, 730,
-	731, 732, 737, 738, 2468, 733, 734, 735, 736, 0,
-	740, 741, 742, 743, 0, 744, 745, 0, 739, 728,
-	0, 746, 747, 748, 749, 750, 751, 752, 753, 754,
-	755, 0, 756, 2460, 2461, 2462, 2463, 0, 768, 0,
-	757, 759, 760, 761, 762, 0, 763, 0, 0, 764,
-	765, 766, 767, 758, 769, 770, 0, 0, 771, 772,
-	773, 774, 776, 778, 779, 780, 775, 777, 781, 0,
-	782, 0, 0, 783, 784, 785, 0, 2459, 2467, 4019,
-	787, 788, 786, 789, 790, 793, 791, 792, 0, 796,
-	513, 797, 798, 799, 794, 795, 0, 0, 0, 0,
-	800, 801, 0, 802, 803, 804, 0, 0, 337, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 345, 346, 348, 347, 349,
-	350, 351, 352, 0, 353, 354, 0, 0, 0, 0,
-	4011, 805, 0, 2437, 0, 356, 0, 355, 0, 357,
-	358, 359, 0, 360, 361, 362, 363, 364, 365, 366,
-	367, 806, 807, 0, 368, 808, 369, 809, 0, 810,
-	370, 371, 372, 373, 374, 375, 376, 377, 378, 379,
-	0, 0, 0, 380, 811, 812, 813, 0, 381, 382,
-	383, 384, 814, 0, 0, 0, 385, 386, 387, 388,
-	389, 390, 391, 392, 0, 0, 394, 395, 396, 393,
-	397, 398, 0, 399, 0, 400, 401, 402, 403, 404,
-	405, 406, 0, 407, 408, 409, 0, 410, 411, 412,
-	0, 0, 0, 0, 0, 0, 0, 413, 414, 415,
-	416, 417, 0, 418, 420, 421, 815, 422, 816, 0,
-	425, 427, 419, 423, 0, 426, 424, 428, 429, 0,
-	430, 431, 432, 433, 0, 0, 434, 435, 436, 0,
-	437, 438, 440, 439, 0, 441, 442, 443, 0, 444,
-	445, 817, 446, 447, 448, 450, 452, 449, 451, 453,
-	454, 455, 456, 457, 818, 819, 458, 459, 0, 0,
-	0, 0, 0, 0, 0, 460, 461, 462, 820, 0,
-	0, 0, 463, 0, 465, 469, 466, 467, 468, 470,
-	0, 464, 471, 472, 0, 0, 473, 474, 475, 821,
-	822, 476, 477, 478, 479, 480, 481, 482, 483, 484,
-	0, 485, 486, 823, 0, 824, 487, 0, 488, 489,
-	490, 491, 492, 493, 494, 825, 826, 827, 595, 0,
-	495, 496, 497, 0, 498, 499, 500, 501, 502, 503,
-	504, 0, 0, 0, 505, 506, 507, 508, 0, 0,
-	0, 0, 0, 828, 509, 596, 510, 829, 830, 0,
-	831, 0, 511, 512, 515, 0, 832, 0, 514, 516,
-	517, 0, 518, 0, 0, 0, 519, 520, 521, 522,
-	523, 524, 525, 0, 526, 528, 527, 0, 530, 833,
-	529, 0, 531, 532, 0, 0, 533, 534, 535, 536,
-	537, 538, 541, 0, 0, 539, 540, 542, 543, 0,
-	544, 545, 547, 550, 546, 548, 549, 551, 552, 565,
-	566, 553, 554, 555, 556, 557, 558, 559, 560, 561,
-	562, 563, 564, 568, 0, 567, 0, 569, 570, 571,
-	572, 573, 581, 583, 584, 579, 580, 582, 585, 586,
-	588, 589, 576, 577, 578, 0, 587, 574, 0, 575,
-	0, 0, 590, 591, 592, 593, 0, 834, 594, 835,
-	597, 598, 0, 0, 599, 0, 600, 0, 0, 602,
-	603, 604, 0, 0, 605, 606, 836, 0, 607, 0,
-	837, 608, 609, 601, 610, 611, 612, 613, 614, 615,
-	616, 617, 618, 619, 0, 620, 621, 838, 622, 623,
-	624, 839, 625, 626, 627, 840, 628, 841, 629, 630,
-	0, 631, 632, 633, 0, 634, 635, 636, 637, 638,
-	639, 640, 641, 642, 643, 842, 644, 645, 647, 646,
-	648, 649, 0, 650, 0, 651, 652, 653, 0, 0,
-	0, 0, 0, 654, 655, 657, 0, 658, 659, 660,
-	661, 662, 656, 663, 664, 665, 666, 667, 668, 669,
-	0, 671, 672, 670, 673, 674, 0, 675, 676, 677,
-	678, 679, 843, 680, 0, 681, 682, 690, 691, 692,
-	683, 684, 686, 693, 685, 694, 695, 696, 697, 699,
-	698, 0, 701, 702, 700, 703, 704, 705, 706, 0,
-	707, 844, 708, 687, 688, 709, 710, 711, 0, 712,
-	713, 714, 715, 716, 717, 718, 719, 720, 845, 0,
-	721, 0, 722, 723, 724, 725, 726, 727, 729, 689,
-	730, 731, 732, 737, 738, 846, 733, 734, 735, 736,
-	847, 740, 741, 742, 743, 0, 744, 745, 0, 739,
-	728, 0, 746, 747, 748, 749, 750, 751, 752, 753,
-	754, 755, 0, 756, 848, 849, 850, 851, 0, 768,
-	0, 757, 759, 760, 761, 762, 852, 763, 853, 0,
-	764, 765, 766, 767, 758, 769, 770, 0, 0, 771,
-	772, 773, 774, 776, 778, 779, 780, 775, 777, 781,
-	0, 782, 0, 0, 783, 784, 785, 854, 855, 856,
-	0, 787, 788, 786, 789, 790, 793, 791, 792, 857,
-	796, 513, 797, 798, 799, 794, 795, 0, 0, 0,
-	4022, 800, 801, 858, 802, 803, 804, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 345, 346, 348,
-	347, 349, 350, 351, 352, 0, 353, 354, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 356, 0, 355,
-	4469, 357, 358, 359, 874, 360, 361, 362, 363, 364,
-	365, 366, 367, 0, 2451, 0, 368, 2458, 369, 2457,
-	0, 2466, 370, 371, 372, 373, 374, 375, 376, 377,
-	378, 379, 0, 0, 0, 380, 2469, 2470, 0, 0,
-	381, 382, 383, 384, 0, 0, 875, 0, 385, 386,
-	387, 388, 389, 390, 391, 392, 0, 0, 394, 395,
-	396, 393, 397, 398, 0, 399, 0, 400, 401, 402,
-	403, 404, 405, 406, 0, 407, 408, 409, 876, 410,
-	411, 412, 0, 0, 0, 0, 0, 0, 0, 413,
-	414, 415, 416, 417, 1477, 418, 420, 421, 2455, 422,
-	2454, 0, 425, 427, 419, 423, 0, 426, 424, 428,
-	429, 0, 430, 431, 432, 433, 0, 0, 434, 1469,
-	436, 0, 437, 438, 440, 439, 0, 441, 442, 443,
-	0, 444, 445, 0, 446, 447, 448, 450, 452, 449,
-	451, 453, 454, 455, 456, 457, 0, 0, 458, 459,
-	0, 340, 0, 0, 0, 0, 0, 460, 461, 462,
-	2453, 0, 0, 0, 463, 0, 465, 469, 466, 467,
-	468, 470, 0, 464, 471, 472, 0, 877, 473, 474,
-	475, 2464, 2465, 476, 477, 478, 479, 480, 481, 482,
-	483, 484, 0, 485, 486, 0, 0, 0, 487, 0,
-	488, 489, 490, 491, 492, 493, 494, 0, 0, 0,
-	595, 879, 495, 496, 497, 4016, 498, 499, 500, 501,
-	502, 503, 504, 0, 0, 0, 505, 506, 507, 508,
-	0, 0, 0, 0, 878, 4018, 509, 596, 510, 2448,
-	2449, 0, 2444, 0, 511, 512, 515, 880, 0, 881,
-	514, 516, 517, 882, 518, 0, 0, 0, 519, 520,
-	521, 522, 523, 524, 525, 0, 526, 528, 527, 0,
-	530, 0, 529, 883, 531, 532, 884, 0, 533, 534,
-	535, 536, 537, 538, 541, 0, 0, 539, 540, 542,
-	543, 0, 544, 545, 547, 550, 546, 548, 549, 551,
-	552, 565, 566, 553, 554, 555, 556, 557, 558, 559,
-	560, 561, 562, 563, 564, 568, 0, 567, 885, 569,
-	570, 571, 572, 573, 581, 583, 584, 579, 580, 582,
-	585, 586, 588, 589, 576, 577, 578, 886, 587, 574,
-	0, 575, 0, 887, 590, 591, 592, 593, 0, 0,
-	594, 2456, 597, 598, 0, 0, 599, 0, 600, 0,
-	0, 602, 603, 604, 0, 0, 605, 606, 4017, 888,
-	607, 889, 0, 608, 609, 601, 610, 611, 612, 613,
-	614, 615, 616, 617, 618, 619, 0, 620, 621, 2441,
-	622, 623, 624, 2442, 625, 626, 627, 0, 628, 0,
-	629, 630, 0, 631, 632, 633, 0, 634, 635, 636,
-	637, 638, 639, 640, 641, 642, 643, 2452, 644, 645,
-	647, 646, 648, 649, 0, 650, 0, 651, 652, 653,
-	0, 0, 0, 0, 0, 654, 655, 657, 0, 658,
-	659, 660, 661, 662, 656, 663, 664, 665, 666, 667,
-	668, 669, 0, 671, 672, 670, 673, 674, 890, 675,
-	676, 677, 678, 679, 0, 680, 0, 681, 682, 690,
-	691, 692, 683, 684, 686, 693, 685, 694, 695, 696,
-	697, 699, 698, 0, 701, 702, 700, 703, 704, 705,
-	706, 0, 707, 0, 708, 687, 688, 709, 710, 711,
-	891, 712, 713, 714, 715, 716, 717, 718, 719, 720,
-	2450, 0, 721, 0, 722, 723, 724, 725, 726, 727,
-	729, 689, 730, 731, 732, 737, 738, 2468, 733, 734,
-	735, 736, 0, 740, 741, 742, 743, 0, 744, 745,
-	0, 739, 728, 0, 746, 747, 748, 749, 750, 751,
-	752, 753, 754, 755, 0, 756, 2460, 2461, 2462, 2463,
-	0, 768, 0, 757, 759, 760, 761, 762, 0, 763,
-	0, 0, 764, 765, 766, 767, 758, 769, 770, 0,
-	0, 771, 772, 773, 774, 776, 778, 779, 780, 775,
-	777, 781, 0, 782, 0, 0, 783, 784, 785, 0,
-	2459, 2467, 4019, 787, 788, 786, 789, 790, 793, 791,
-	792, 0, 796, 513, 797, 798, 799, 794, 795, 0,
-	0, 0, 337, 800, 801, 0, 802, 803, 804, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 345,
-	346, 348, 347, 349, 350, 351, 352, 0, 353, 354,
-	0, 0, 0, 0, 0, 805, 0, 0, 0, 356,
-	0, 355, 0, 357, 358, 359, 2437, 360, 361, 362,
-	363, 364, 365, 366, 367, 806, 807, 0, 368, 808,
-	369, 809, 0, 810, 370, 371, 372, 373, 374, 375,
-	376, 377, 378, 379, 0, 0, 0, 380, 811, 812,
-	813, 0, 381, 382, 383, 384, 814, 0, 0, 0,
-	385, 386, 387, 388, 389, 390, 391, 392, 0, 0,
-	394, 395, 396, 393, 397, 398, 0, 399, 0, 400,
-	401, 402, 403, 404, 405, 406, 0, 407, 408, 409,
-	0, 410, 411, 412, 0, 0, 0, 0, 0, 0,
-	0, 413, 414, 415, 416, 417, 0, 418, 420, 421,
-	815, 422, 816, 0, 425, 427, 419, 423, 0, 426,
-	424, 428, 429, 0, 430, 431, 432, 433, 0, 0,
-	434, 435, 436, 0, 437, 438, 440, 439, 0, 441,
-	442, 443, 0, 444, 445, 817, 446, 447, 448, 450,
-	452, 449, 451, 453, 454, 455, 456, 457, 818, 819,
-	458, 459, 0, 0, 0, 0, 0, 0, 0, 460,
-	461, 462, 820, 0, 0, 0, 463, 0, 465, 469,
-	466, 467, 468, 470, 0, 464, 471, 472, 0, 0,
-	473, 474, 475, 821, 822, 476, 477, 478, 479, 480,
-	481, 482, 483, 484, 0, 485, 486, 823, 0, 824,
-	487, 0, 488, 489, 490, 491, 492, 493, 494, 825,
-	826, 827, 595, 0, 495, 496, 497, 0, 498, 499,
-	500, 501, 502, 503, 504, 0, 0, 0, 505, 506,
-	507, 508, 0, 0, 0, 0, 0, 828, 509, 596,
-	510, 829, 830, 0, 831, 0, 511, 512, 515, 0,
-	832, 0, 514, 516, 517, 0, 518, 0, 0, 0,
-	519, 520, 521, 522, 523, 524, 525, 0, 526, 528,
-	527, 0, 530, 833, 529, 0, 531, 532, 0, 0,
-	533, 534, 535, 536, 537, 538, 541, 0, 0, 539,
-	540, 542, 543, 0, 544, 545, 547, 550, 546, 548,
-	549, 551, 552, 565, 566, 553, 554, 555, 556, 557,
-	558, 559, 560, 561, 562, 563, 564, 568, 0, 567,
-	0, 569, 570, 571, 572, 573, 581, 583, 584, 579,
-	580, 582, 585, 586, 588, 589, 576, 577, 578, 0,
-	587, 574, 0, 575, 0, 0, 590, 591, 592, 593,
-	0, 834, 594, 835, 597, 598, 0, 0, 599, 0,
-	600, 0, 0, 602, 603, 604, 0, 0, 605, 606,
-	836, 0, 607, 0, 837, 608, 609, 601, 610, 611,
-	612, 613, 614, 615, 616, 617, 618, 619, 0, 620,
-	621, 838, 622, 623, 624, 839, 625, 626, 627, 840,
-	628, 841, 629, 630, 0, 631, 632, 633, 0, 634,
-	635, 636, 637, 638, 639, 640, 641, 642, 643, 842,
-	644, 645, 647, 646, 648, 649, 0, 650, 0, 651,
-	652, 653, 0, 0, 0, 0, 0, 654, 655, 657,
-	0, 658, 659, 660, 661, 662, 656, 663, 664, 665,
-	666, 667, 668, 669, 0, 671, 672, 670, 673, 674,
-	0, 675, 676, 677, 678, 679, 843, 680, 0, 681,
-	682, 690, 691, 692, 683, 684, 686, 693, 685, 694,
-	695, 696, 697, 699, 698, 0, 701, 702, 700, 703,
-	704, 705, 706, 0, 707, 844, 708, 687, 688, 709,
-	710, 711, 0, 712, 713, 714, 715, 716, 717, 718,
-	719, 720, 845, 0, 721, 0, 722, 723, 724, 725,
-	726, 727, 729, 689, 730, 731, 732, 737, 738, 846,
-	733, 734, 735, 736, 847, 740, 741, 742, 743, 0,
-	744, 745, 0, 739, 728, 0, 746, 747, 748, 749,
-	750, 751, 752, 753, 754, 755, 0, 756, 848, 849,
-	850, 851, 0, 768, 0, 757, 759, 760, 761, 762,
-	852, 763, 853, 0, 764, 765, 766, 767, 758, 769,
-	770, 0, 0, 771, 772, 773, 774, 776, 778, 779,
-	780, 775, 777, 781, 0, 782, 0, 0, 783, 784,
-	785, 854, 855, 856, 0, 787, 788, 786, 789, 790,
-	793, 791, 792, 857, 796, 513, 797, 798, 799, 794,
-	795, 0, 0, 0, 337, 800, 801, 858, 802, 803,
-	804, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 345, 346, 348, 347, 349, 350, 351, 352, 0,
-	353, 354, 0, 0, 0, 0, 0, 805, 0, 0,
-	0, 356, 0, 355, 5248, 357, 358, 359, 0, 360,
-	361, 362, 363, 364, 365, 366, 367, 806, 807, 0,
-	368, 808, 369, 809, 0, 810, 370, 371, 372, 373,
-	374, 375, 376, 377, 378, 379, 0, 0, 0, 380,
-	811, 812, 813, 0, 381, 382, 383, 384, 814, 0,
-	0, 0, 385, 386, 387, 388, 389, 390, 391, 392,
-	0, 0, 394, 395, 396, 393, 397, 398, 0, 399,
-	0, 400, 401, 402, 403, 404, 405, 406, 0, 407,
-	408, 409, 0, 410, 411, 412, 0, 0, 0, 0,
-	0, 0, 0, 413, 414, 415, 416, 417, 0, 418,
-	420, 421, 815, 422, 816, 0, 425, 427, 419, 423,
-	0, 426, 424, 428, 429, 0, 430, 431, 432, 433,
-	0, 0, 434, 435, 436, 0, 437, 438, 440, 439,
-	0, 441, 442, 443, 0, 444, 445, 817, 446, 447,
-	448, 450, 452, 449, 451, 453, 454, 455, 456, 457,
-	818, 819, 458, 459, 0, 0, 0, 0, 0, 0,
-	0, 460, 461, 462, 820, 0, 0, 0, 463, 0,
-	465, 469, 466, 467, 468, 470, 0, 464, 471, 472,
-	0, 0, 473, 474, 475, 821, 822, 476, 477, 478,
-	479, 480, 481, 482, 483, 484, 0, 485, 486, 823,
-	0, 824, 487, 0, 488, 489, 490, 491, 492, 493,
-	494, 825, 826, 827, 595, 0, 495, 496, 497, 0,
-	498, 499, 500, 501, 502, 503, 504, 0, 0, 0,
-	505, 506, 507, 508, 0, 0, 0, 0, 0, 828,
-	509, 596, 510, 829, 830, 0, 831, 0, 511, 512,
-	515, 0, 832, 0, 514, 516, 517, 0, 518, 0,
-	0, 0, 519, 520, 521, 522, 523, 524, 525, 0,
-	526, 528, 527, 0, 530, 833, 529, 0, 531, 532,
-	0, 0, 533, 534, 535, 536, 537, 538, 541, 0,
-	0, 539, 540, 542, 543, 0, 544, 545, 547, 550,
-	546, 548, 549, 551, 552, 565, 566, 553, 554, 555,
-	556, 557, 558, 559, 560, 561, 562, 563, 564, 568,
-	0, 567, 0, 569, 570, 571, 572, 573, 581, 583,
-	584, 579, 580, 582, 585, 586, 588, 589, 576, 577,
-	578, 0, 587, 574, 0, 575, 0, 0, 590, 591,
-	592, 593, 0, 834, 594, 835, 597, 598, 0, 0,
-	599, 0, 600, 0, 0, 602, 603, 604, 0, 0,
-	605, 606, 836, 0, 607, 0, 837, 608, 609, 601,
-	610, 611, 612, 613, 614, 615, 616, 617, 618, 619,
-	0, 620, 621, 838, 622, 623, 624, 839, 625, 626,
-	627, 840, 628, 841, 629, 630, 0, 631, 632, 633,
-	0, 634, 635, 636, 637, 638, 639, 640, 641, 642,
-	643, 842, 644, 645, 647, 646, 648, 649, 0, 650,
-	0, 651, 652, 653, 0, 0, 0, 0, 0, 654,
-	655, 657, 0, 658, 659, 660, 661, 662, 656, 663,
-	664, 665, 666, 667, 668, 669, 0, 671, 672, 670,
-	673, 674, 0, 675, 676, 677, 678, 679, 843, 680,
-	0, 681, 682, 690, 691, 692, 683, 684, 686, 693,
-	685, 694, 695, 696, 697, 699, 698, 0, 701, 702,
-	700, 703, 704, 705, 706, 0, 707, 844, 708, 687,
-	688, 709, 710, 711, 0, 712, 713, 714, 715, 716,
-	717, 718, 719, 720, 845, 0, 721, 0, 722, 723,
-	724, 725, 726, 727, 729, 689, 730, 731, 732, 737,
-	738, 846, 733, 734, 735, 736, 847, 740, 741, 742,
-	743, 0, 744, 745, 0, 739, 728, 0, 746, 747,
-	748, 749, 750, 751, 752, 753, 754, 755, 0, 756,
-	848, 849, 850, 851, 0, 768, 0, 757, 759, 760,
-	761, 762, 852, 763, 853, 0, 764, 765, 766, 767,
-	758, 769, 770, 0, 0, 771, 772, 773, 774, 776,
-	778, 779, 780, 775, 777, 781, 0, 782, 0, 0,
-	783, 784, 785, 854, 855, 856, 0, 787, 788, 786,
-	789, 790, 793, 791, 792, 857, 796, 513, 797, 798,
-	799, 794, 795, 0, 1246, 0, 1137, 800, 801, 858,
-	802, 803, 804, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 345, 346, 348, 347, 349, 350, 351,
-	352, 0, 353, 354, 0, 0, 0, 0, 0, 805,
-	0, 0, 0, 356, 0, 355, 2976, 357, 358, 359,
-	0, 360, 361, 362, 363, 364, 365, 366, 367, 806,
-	807, 0, 368, 808, 369, 809, 0, 810, 370, 371,
-	372, 373, 374, 375, 376, 377, 378, 379, 0, 0,
-	0, 380, 811, 812, 813, 0, 381, 382, 383, 384,
-	814, 0, 0, 0, 385, 386, 387, 388, 389, 390,
-	391, 392, 0, 0, 394, 395, 396, 393, 397, 398,
-	0, 399, 0, 400, 401, 402, 403, 404, 405, 406,
-	0, 407, 408, 409, 0, 410, 411, 412, 0, 0,
-	0, 0, 0, 0, 0, 413, 414, 415, 1144, 417,
-	0, 418, 420, 421, 815, 422, 816, 0, 425, 427,
-	419, 423, 0, 426, 424, 428, 429, 0, 430, 431,
-	432, 433, 0, 0, 434, 435, 436, 0, 437, 438,
-	440, 439, 0, 441, 442, 443, 0, 444, 445, 817,
-	446, 447, 448, 450, 452, 449, 451, 453, 454, 455,
-	456, 457, 818, 819, 458, 459, 0, 340, 0, 0,
-	0, 0, 0, 460, 461, 462, 820, 0, 0, 0,
-	463, 0, 465, 469, 466, 467, 468, 470, 0, 464,
-	471, 472, 1243, 0, 473, 474, 475, 821, 822, 476,
-	477, 478, 479, 480, 481, 482, 483, 484, 0, 485,
-	486, 823, 0, 824, 487, 0, 488, 489, 490, 491,
-	492, 493, 494, 825, 826, 827, 595, 0, 495, 496,
-	497, 0, 498, 499, 500, 501, 502, 503, 504, 0,
-	0, 0, 505, 506, 507, 508, 0, 342, 341, 343,
-	0, 828, 509, 596, 510, 829, 830, 0, 831, 0,
-	511, 512, 515, 0, 832, 0, 514, 516, 517, 0,
-	518, 0, 0, 0, 519, 520, 521, 522, 523, 524,
-	525, 0, 526, 528, 527, 0, 530, 833, 529, 0,
-	531, 532, 0, 0, 533, 534, 535, 536, 537, 538,
-	541, 0, 0, 539, 540, 542, 543, 0, 544, 545,
-	547, 550, 546, 548, 549, 551, 552, 565, 566, 553,
-	554, 555, 556, 557, 558, 559, 560, 561, 562, 563,
-	564, 568, 0, 567, 0, 569, 570, 571, 572, 573,
-	581, 583, 584, 579, 580, 582, 585, 586, 588, 589,
-	576, 577, 578, 0, 587, 574, 0, 575, 344, 0,
-	590, 591, 592, 593, 0, 834, 594, 835, 597, 598,
-	0, 0, 599, 0, 600, 0, 0, 602, 603, 604,
-	0, 0, 605, 606, 836, 0, 607, 0, 837, 608,
-	609, 601, 610, 611, 612, 613, 614, 615, 616, 617,
-	618, 619, 0, 620, 621, 838, 622, 623, 624, 839,
-	625, 626, 627, 840, 628, 841, 629, 630, 0, 631,
-	632, 633, 0, 634, 635, 636, 637, 638, 639, 640,
-	641, 642, 643, 842, 644, 645, 647, 646, 648, 649,
-	0, 650, 0, 651, 652, 653, 0, 0, 0, 0,
-	0, 654, 655, 657, 0, 658, 659, 660, 661, 662,
-	656, 663, 664, 665, 666, 667, 668, 669, 0, 671,
-	672, 670, 673, 674, 0, 675, 676, 677, 678, 679,
-	843, 680, 0, 681, 682, 690, 691, 692, 683, 684,
-	686, 693, 685, 694, 695, 696, 697, 699, 698, 0,
-	701, 702, 700, 703, 704, 705, 706, 0, 707, 844,
-	708, 687, 688, 709, 710, 711, 0, 712, 713, 714,
-	715, 716, 717, 718, 719, 720, 845, 0, 721, 0,
-	722, 723, 724, 725, 726, 727, 729, 689, 730, 731,
-	732, 737, 738, 846, 733, 734, 735, 736, 847, 740,
-	741, 742, 743, 0, 744, 1245, 0, 739, 728, 1142,
-	746, 747, 748, 749, 750, 1146, 752, 753, 754, 755,
-	0, 756, 848, 849, 850, 851, 0, 768, 0, 757,
-	759, 760, 761, 762, 852, 763, 853, 0, 764, 765,
-	766, 767, 758, 769, 770, 0, 0, 771, 772, 773,
-	774, 776, 778, 779, 780, 775, 777, 781, 0, 782,
-	0, 0, 783, 784, 785, 854, 855, 856, 0, 787,
-	788, 786, 789, 790, 793, 791, 792, 1145, 796, 513,
-	797, 798, 799, 794, 795, 2418, 0, 0, 0, 800,
-	801, 858, 802, 803, 804, 0, 0, 0, 0, 0,
-	0, 0, 345, 346, 348, 347, 349, 350, 351, 352,
-	5389, 353, 354, 0, 0, 0, 0, 0, 805, 0,
-	1149, 0, 356, 0, 355, 0, 357, 358, 359, 0,
-	360, 361, 362, 363, 364, 365, 366, 367, 806, 807,
-	0, 368, 808, 369, 809, 0, 810, 370, 371, 372,
-	373, 374, 375, 376, 377, 378, 379, 0, 0, 0,
-	380, 811, 812, 813, 0, 381, 382, 383, 384, 814,
-	0, 0, 0, 385, 386, 387, 388, 389, 390, 391,
-	392, 0, 0, 394, 395, 396, 393, 397, 398, 0,
-	399, 0, 400, 401, 402, 403, 404, 405, 406, 0,
-	407, 408, 409, 0, 410, 411, 412, 0, 0, 0,
-	0, 0, 0, 0, 413, 414, 415, 2425, 417, 0,
-	418, 420, 421, 815, 422, 816, 0, 425, 427, 419,
-	423, 0, 426, 424, 428, 429, 0, 430, 431, 432,
-	433, 0, 0, 434, 435, 436, 0, 437, 438, 440,
-	439, 0, 441, 442, 443, 0, 444, 445, 817, 446,
-	447, 448, 450, 452, 449, 451, 453, 454, 455, 456,
-	2426, 818, 819, 458, 459, 0, 340, 0, 0, 0,
-	0, 0, 460, 461, 462, 820, 0, 0, 0, 463,
-	0, 465, 469, 466, 467, 468, 470, 0, 464, 471,
-	472, 0, 0, 2427, 474, 475, 821, 822, 476, 477,
-	478, 479, 480, 481, 482, 483, 484, 0, 485, 486,
-	823, 0, 824, 487, 0, 488, 489, 490, 491, 492,
-	493, 494, 825, 826, 827, 595, 0, 495, 496, 497,
-	0, 498, 499, 500, 501, 502, 503, 504, 0, 0,
-	0, 505, 506, 507, 508, 0, 342, 341, 343, 0,
-	828, 509, 596, 510, 829, 830, 0, 831, 0, 511,
-	512, 515, 0, 832, 0, 514, 516, 517, 0, 518,
-	0, 0, 0, 519, 520, 521, 522, 523, 524, 525,
-	0, 526, 528, 527, 0, 530, 833, 529, 0, 531,
-	532, 0, 0, 533, 534, 535, 536, 537, 538, 541,
-	0, 0, 539, 540, 542, 543, 0, 544, 545, 547,
-	550, 546, 548, 549, 551, 552, 565, 566, 553, 554,
-	555, 556, 557, 558, 559, 560, 561, 562, 563, 564,
-	568, 0, 567, 0, 569, 570, 571, 572, 573, 581,
-	583, 584, 579, 580, 582, 585, 586, 588, 589, 576,
-	577, 578, 0, 587, 574, 0, 575, 344, 0, 590,
-	591, 592, 593, 0, 834, 594, 835, 597, 598, 0,
-	0, 599, 0, 600, 0, 0, 602, 603, 604, 0,
-	0, 605, 606, 836, 0, 607, 0, 837, 608, 609,
-	601, 610, 611, 612, 613, 614, 615, 616, 617, 618,
-	619, 0, 620, 621, 838, 622, 623, 624, 839, 625,
-	626, 627, 840, 628, 841, 629, 630, 0, 631, 632,
-	633, 0, 2428, 635, 636, 637, 638, 639, 640, 641,
-	642, 643, 842, 644, 645, 647, 646, 648, 649, 0,
-	650, 0, 651, 652, 653, 0, 0, 0, 0, 0,
-	654, 655, 657, 0, 658, 659, 660, 661, 662, 656,
-	663, 664, 665, 666, 667, 668, 669, 0, 671, 672,
-	670, 673, 674, 0, 675, 676, 677, 678, 679, 843,
-	680, 0, 681, 682, 690, 691, 692, 683, 684, 686,
-	5388, 685, 694, 695, 696, 697, 699, 698, 0, 2422,
-	702, 700, 703, 704, 705, 706, 0, 707, 844, 708,
-	687, 688, 709, 710, 711, 0, 712, 713, 714, 715,
-	716, 717, 718, 719, 720, 845, 0, 721, 0, 722,
-	723, 724, 725, 726, 727, 729, 689, 730, 731, 732,
-	737, 738, 846, 733, 734, 735, 736, 847, 740, 741,
-	742, 743, 0, 744, 745, 0, 739, 728, 2424, 746,
-	747, 748, 749, 750, 751, 752, 753, 754, 755, 0,
-	756, 848, 849, 850, 851, 0, 768, 0, 757, 759,
-	760, 761, 762, 852, 763, 853, 0, 764, 765, 5387,
-	767, 758, 769, 770, 0, 0, 771, 772, 773, 774,
-	776, 778, 779, 780, 775, 777, 781, 0, 782, 0,
-	0, 783, 784, 785, 854, 855, 856, 0, 787, 788,
-	786, 789, 790, 793, 791, 792, 857, 796, 513, 797,
-	798, 799, 794, 795, 0, 5055, 0, 1137, 800, 801,
-	858, 802, 803, 804, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 345, 346, 348, 347, 349, 350,
-	351, 352, 0, 353, 354, 0, 0, 0, 0, 1149,
-	805, 0, 0, 0, 356, 0, 355, 0, 357, 358,
-	359, 0, 360, 361, 362, 363, 364, 365, 366, 367,
-	806, 807, 0, 368, 808, 369, 809, 0, 810, 370,
-	371, 372, 373, 374, 375, 376, 377, 378, 379, 0,
-	0, 0, 380, 811, 812, 813, 0, 381, 382, 383,
-	384, 814, 0, 0, 0, 385, 386, 387, 388, 389,
-	390, 391, 392, 0, 0, 394, 395, 396, 393, 397,
-	398, 0, 399, 0, 400, 401, 402, 403, 404, 405,
-	406, 0, 407, 408, 409, 0, 410, 411, 412, 0,
-	0, 0, 0, 0, 0, 0, 413, 414, 415, 1144,
-	417, 0, 418, 420, 421, 815, 422, 816, 0, 425,
-	427, 419, 423, 0, 426, 424, 428, 429, 0, 430,
-	431, 432, 433, 0, 0, 434, 435, 436, 0, 437,
-	438, 440, 439, 0, 441, 442, 443, 0, 444, 445,
-	817, 446, 447, 448, 450, 452, 449, 451, 453, 454,
-	455, 456, 457, 818, 819, 458, 459, 0, 340, 0,
-	0, 0, 0, 0, 460, 461, 462, 820, 0, 0,
-	0, 463, 0, 465, 469, 466, 467, 468, 470, 0,
-	464, 471, 472, 0, 0, 473, 474, 475, 821, 822,
-	476, 477, 478, 479, 480, 481, 482, 483, 484, 0,
-	485, 486, 823, 0, 824, 487, 0, 488, 489, 490,
-	491, 492, 493, 494, 825, 826, 827, 595, 0, 495,
-	496, 497, 0, 498, 499, 500, 501, 502, 503, 504,
-	0, 0, 0, 505, 506, 507, 508, 0, 342, 341,
-	343, 0, 828, 509, 596, 510, 829, 830, 0, 831,
-	0, 511, 512, 515, 0, 832, 0, 514, 516, 517,
-	0, 518, 0, 0, 0, 519, 520, 521, 522, 523,
-	524, 525, 0, 526, 528, 527, 0, 530, 833, 529,
-	0, 531, 532, 0, 0, 533, 534, 535, 536, 537,
-	538, 541, 0, 0, 539, 540, 542, 543, 0, 544,
-	545, 547, 550, 546, 548, 549, 551, 552, 565, 566,
-	553, 554, 555, 556, 557, 558, 559, 560, 561, 562,
-	563, 564, 568, 0, 567, 0, 569, 570, 571, 572,
-	573, 581, 583, 584, 579, 580, 582, 585, 586, 588,
-	589, 576, 577, 578, 0, 587, 574, 0, 575, 344,
-	0, 590, 591, 592, 593, 0, 834, 594, 835, 597,
-	598, 0, 0, 599, 0, 600, 0, 0, 602, 603,
-	604, 0, 0, 605, 606, 836, 0, 607, 0, 837,
-	608, 609, 601, 610, 611, 612, 613, 614, 615, 616,
-	617, 618, 619, 0, 620, 621, 838, 622, 623, 624,
-	839, 625, 626, 627, 840, 628, 841, 629, 630, 0,
-	631, 632, 633, 0, 634, 635, 636, 637, 638, 639,
-	640, 641, 642, 643, 842, 644, 645, 647, 646, 648,
-	649, 0, 650, 0, 651, 652, 653, 0, 0, 0,
-	0, 0, 654, 655, 657, 0, 658, 659, 660, 661,
-	662, 656, 663, 664, 665, 666, 667, 668, 669, 0,
-	671, 672, 670, 673, 674, 0, 675, 676, 677, 678,
-	679, 843, 680, 0, 681, 682, 690, 691, 692, 683,
-	684, 686, 693, 685, 694, 695, 696, 697, 699, 698,
-	0, 701, 702, 700, 703, 704, 705, 706, 0, 707,
-	844, 708, 687, 688, 709, 710, 711, 0, 712, 713,
-	714, 715, 716, 717, 718, 719, 720, 845, 0, 721,
-	0, 722, 723, 724, 725, 726, 727, 729, 689, 730,
-	731, 732, 737, 738, 846, 733, 734, 735, 736, 847,
-	740, 741, 742, 743, 0, 744, 745, 0, 739, 728,
-	1142, 746, 747, 748, 749, 750, 1146, 752, 753, 754,
-	755, 0, 756, 848, 849, 850, 851, 0, 768, 0,
-	757, 759, 760, 761, 762, 852, 763, 853, 0, 764,
-	765, 766, 767, 758, 769, 770, 0, 0, 771, 772,
-	773, 774, 776, 778, 779, 780, 775, 777, 781, 0,
-	782, 0, 0, 783, 784, 785, 854, 855, 856, 0,
-	787, 788, 786, 789, 790, 793, 791, 792, 1145, 796,
-	513, 797, 798, 799, 794, 795, 2445, 0, 0, 0,
-	800, 801, 858, 802, 803, 804, 0, 0, 0, 0,
-	0, 0, 0, 345, 346, 348, 347, 349, 350, 351,
-	352, 0, 353, 354, 0, 0, 0, 0, 0, 0,
-	0, 1149, 0, 356, 0, 355, 0, 357, 358, 359,
-	874, 360, 361, 362, 363, 364, 365, 366, 367, 0,
-	2451, 0, 368, 2458, 369, 2457, 0, 2466, 370, 371,
-	372, 373, 374, 375, 376, 377, 378, 379, 0, 0,
-	0, 380, 2469, 2470, 0, 0, 381, 382, 383, 384,
-	0, 0, 875, 0, 385, 386, 387, 388, 389, 390,
-	391, 392, 0, 0, 394, 395, 396, 393, 397, 398,
-	0, 399, 0, 400, 401, 402, 403, 404, 405, 406,
-	0, 407, 408, 409, 876, 410, 411, 412, 0, 0,
-	0, 0, 0, 0, 0, 413, 414, 415, 416, 417,
-	1477, 418, 420, 421, 2455, 422, 2454, 0, 425, 427,
-	419, 423, 0, 426, 424, 428, 429, 0, 430, 431,
-	432, 433, 0, 0, 434, 1469, 436, 0, 437, 438,
-	440, 439, 0, 441, 442, 443, 0, 444, 445, 0,
-	446, 447, 448, 450, 452, 449, 451, 453, 454, 455,
-	456, 457, 0, 0, 458, 459, 0, 0, 0, 0,
-	0, 0, 0, 460, 461, 462, 2453, 0, 0, 0,
-	463, 0, 465, 469, 466, 467, 468, 470, 0, 464,
-	471, 472, 0, 877, 473, 474, 475, 2464, 2465, 476,
-	477, 478, 479, 480, 481, 482, 483, 484, 0, 485,
-	486, 0, 0, 0, 487, 0, 488, 489, 490, 491,
-	492, 493, 494, 0, 0, 0, 595, 879, 495, 496,
-	497, 4016, 498, 499, 500, 501, 502, 503, 504, 0,
-	0, 0, 505, 506, 507, 508, 0, 0, 0, 0,
-	878, 4018, 509, 596, 510, 2448, 2449, 0, 2444, 0,
-	511, 512, 515, 880, 0, 881, 514, 516, 517, 882,
-	518, 0, 0, 0, 519, 520, 521, 522, 523, 524,
-	525, 0, 526, 528, 527, 0, 530, 0, 529, 883,
-	531, 532, 884, 0, 533, 534, 535, 536, 537, 538,
-	541, 0, 0, 539, 540, 542, 543, 0, 544, 545,
-	547, 550, 546, 548, 549, 551, 552, 565, 566, 553,
-	554, 555, 556, 557, 558, 559, 560, 561, 562, 563,
-	564, 568, 0, 567, 885, 569, 570, 571, 572, 573,
-	581, 583, 584, 579, 580, 582, 585, 586, 588, 589,
-	576, 577, 578, 886, 587, 574, 0, 575, 0, 887,
-	590, 591, 592, 593, 0, 0, 594, 2456, 597, 598,
-	0, 0, 599, 0, 600, 0, 0, 602, 603, 604,
-	0, 0, 605, 606, 4017, 888, 607, 889, 0, 608,
-	609, 601, 610, 611, 612, 613, 614, 615, 616, 617,
-	618, 619, 0, 620, 621, 2441, 622, 623, 624, 2442,
-	625, 626, 627, 0, 628, 0, 629, 630, 0, 631,
-	632, 633, 0, 634, 635, 636, 637, 638, 639, 640,
-	641, 642, 643, 2452, 644, 645, 647, 646, 648, 649,
-	0, 650, 0, 651, 652, 653, 0, 0, 0, 0,
-	0, 654, 655, 657, 0, 658, 659, 660, 661, 662,
-	656, 663, 664, 665, 666, 667, 668, 669, 0, 671,
-	672, 670, 673, 674, 890, 675, 676, 677, 678, 679,
-	0, 680, 0, 681, 682, 690, 691, 692, 683, 684,
-	686, 693, 685, 694, 695, 696, 697, 699, 698, 0,
-	701, 702, 700, 703, 704, 705, 706, 0, 707, 0,
-	708, 687, 688, 709, 710, 711, 891, 712, 713, 714,
-	715, 716, 717, 718, 719, 720, 2450, 0, 721, 0,
-	722, 723, 724, 725, 726, 727, 729, 689, 730, 731,
-	732, 737, 738, 2468, 733, 734, 735, 736, 0, 740,
-	741, 742, 743, 0, 744, 745, 0, 739, 728, 0,
-	746, 747, 748, 749, 750, 751, 752, 753, 754, 755,
-	0, 756, 2460, 2461, 2462, 2463, 0, 768, 0, 757,
-	759, 760, 761, 762, 0, 763, 0, 0, 764, 765,
-	766, 767, 758, 769, 770, 0, 0, 771, 772, 773,
-	774, 776, 778, 779, 780, 775, 777, 781, 0, 782,
-	0, 0, 783, 784, 785, 0, 2459, 2467, 4019, 787,
-	788, 786, 789, 790, 793, 791, 792, 0, 796, 513,
-	797, 798, 799, 794, 795, 0, 0, 0, 2418, 800,
-	801, 0, 802, 803, 804, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 345, 346, 348, 347, 349,
-	350, 351, 352, 2474, 353, 354, 0, 0, 0, 0,
-	0, 805, 0, 0, 0, 356, 0, 355, 0, 357,
-	358, 359, 2437, 360, 361, 362, 363, 364, 365, 366,
-	367, 806, 807, 0, 368, 808, 369, 809, 0, 810,
-	370, 371, 372, 373, 374, 375, 376, 377, 378, 379,
-	0, 0, 0, 380, 811, 812, 813, 0, 381, 382,
-	383, 384, 814, 0, 0, 0, 385, 386, 387, 388,
-	389, 390, 391, 392, 0, 0, 394, 395, 396, 393,
-	397, 398, 0, 399, 0, 400, 401, 402, 403, 404,
-	405, 406, 0, 407, 408, 409, 0, 410, 411, 412,
-	0, 0, 0, 0, 0, 0, 0, 413, 414, 415,
-	2425, 417, 0, 418, 420, 421, 815, 422, 816, 0,
-	425, 427, 419, 423, 0, 426, 424, 428, 429, 0,
-	430, 431, 432, 433, 0, 0, 434, 435, 436, 0,
-	437, 438, 440, 439, 0, 441, 442, 443, 0, 444,
-	445, 817, 446, 447, 448, 450, 452, 449, 451, 453,
-	454, 455, 456, 2426, 818, 819, 458, 459, 0, 340,
-	0, 0, 0, 0, 0, 460, 461, 462, 820, 0,
-	0, 0, 463, 0, 465, 469, 466, 467, 468, 470,
-	0, 464, 471, 472, 0, 0, 2427, 474, 475, 821,
-	822, 476, 477, 478, 479, 480, 481, 482, 483, 484,
-	0, 485, 486, 823, 0, 824, 487, 0, 488, 489,
-	490, 491, 492, 493, 494, 825, 826, 827, 595, 0,
-	495, 496, 497, 0, 498, 499, 500, 501, 502, 503,
-	504, 0, 0, 0, 505, 506, 507, 508, 0, 342,
-	341, 343, 0, 828, 509, 596, 510, 829, 830, 0,
-	831, 0, 511, 512, 515, 0, 832, 0, 514, 516,
-	517, 0, 518, 0, 0, 0, 519, 520, 521, 522,
-	523, 524, 525, 0, 526, 528, 527, 0, 530, 833,
-	529, 0, 531, 532, 0, 0, 533, 534, 535, 536,
-	537, 538, 541, 0, 0, 539, 540, 542, 543, 0,
-	544, 545, 547, 550, 546, 548, 549, 551, 552, 565,
-	566, 553, 554, 555, 556, 557, 558, 559, 560, 561,
-	562, 563, 564, 568, 0, 567, 0, 569, 570, 571,
-	572, 573, 581, 583, 584, 579, 580, 582, 585, 586,
-	588, 589, 576, 577, 578, 0, 587, 574, 0, 575,
-	344, 0, 590, 591, 592, 593, 0, 834, 594, 835,
-	597, 598, 0, 0, 599, 0, 600, 0, 0, 602,
-	603, 604, 0, 0, 605, 606, 836, 0, 607, 0,
-	837, 608, 609, 601, 610, 611, 612, 613, 614, 615,
-	616, 617, 618, 619, 0, 620, 621, 838, 622, 623,
-	624, 839, 625, 626, 627, 840, 628, 841, 629, 630,
-	0, 631, 632, 633, 0, 2428, 635, 636, 637, 638,
-	639, 640, 641, 642, 643, 842, 644, 645, 647, 646,
-	648, 649, 0, 650, 0, 651, 652, 653, 0, 0,
-	0, 0, 0, 654, 655, 657, 0, 658, 659, 660,
-	661, 662, 656, 663, 664, 665, 666, 667, 668, 669,
-	0, 671, 672, 670, 673, 674, 0, 675, 676, 677,
-	678, 679, 843, 680, 0, 681, 682, 690, 691, 692,
-	683, 684, 686, 2473, 685, 694, 695, 696, 697, 699,
-	698, 0, 2475, 702, 700, 703, 704, 705, 706, 0,
-	707, 844, 708, 687, 688, 709, 710, 711, 0, 712,
-	713, 714, 715, 716, 717, 718, 719, 720, 845, 0,
-	721, 0, 722, 723, 724, 725, 726, 727, 729, 689,
-	730, 731, 732, 737, 738, 846, 733, 734, 735, 736,
-	847, 740, 741, 742, 743, 0, 744, 745, 0, 739,
-	728, 2424, 746, 747, 748, 749, 750, 751, 752, 753,
-	754, 755, 0, 756, 848, 849, 850, 851, 0, 768,
-	0, 757, 759, 760, 761, 762, 852, 763, 853, 0,
-	764, 765, 2472, 767, 758, 769, 770, 0, 0, 771,
-	772, 773, 774, 776, 778, 779, 780, 775, 777, 781,
-	0, 782, 0, 0, 783, 784, 785, 854, 855, 856,
-	0, 787, 788, 786, 789, 790, 793, 791, 792, 857,
-	796, 513, 797, 798, 799, 794, 795, 2418, 0, 0,
-	0, 800, 801, 858, 802, 803, 804, 0, 0, 0,
-	0, 0, 0, 0, 345, 346, 348, 347, 349, 350,
-	351, 352, 2417, 353, 354, 0, 0, 0, 0, 0,
-	805, 0, 1149, 0, 356, 0, 355, 0, 357, 358,
-	359, 0, 360, 361, 362, 363, 364, 365, 366, 367,
-	806, 807, 0, 368, 808, 369, 809, 0, 810, 370,
-	371, 372, 373, 374, 375, 376, 377, 378, 379, 0,
-	0, 0, 380, 811, 812, 813, 0, 381, 382, 383,
-	384, 814, 0, 0, 0, 385, 386, 387, 388, 389,
-	390, 391, 392, 0, 0, 394, 395, 396, 393, 397,
-	398, 0, 399, 0, 400, 401, 402, 403, 404, 405,
-	406, 0, 407, 408, 409, 0, 410, 411, 412, 0,
-	0, 0, 0, 0, 0, 0, 413, 414, 415, 2425,
-	417, 0, 418, 420, 421, 815, 422, 816, 0, 425,
-	427, 419, 423, 0, 426, 424, 428, 429, 0, 430,
-	431, 432, 433, 0, 0, 434, 435, 436, 0, 437,
-	438, 440, 439, 0, 441, 442, 443, 0, 444, 445,
-	817, 446, 447, 448, 450, 452, 449, 451, 453, 454,
-	455, 456, 2426, 818, 819, 458, 459, 0, 340, 0,
-	0, 0, 0, 0, 460, 461, 462, 820, 0, 0,
-	0, 463, 0, 465, 469, 466, 467, 468, 470, 0,
-	464, 471, 472, 0, 0, 2427, 474, 475, 821, 822,
-	476, 477, 478, 479, 480, 481, 482, 483, 484, 0,
-	485, 486, 823, 0, 824, 487, 0, 488, 489, 490,
-	491, 492, 493, 494, 825, 826, 827, 595, 0, 495,
-	496, 497, 0, 498, 499, 500, 501, 502, 503, 504,
-	0, 0, 0, 505, 506, 507, 508, 0, 342, 341,
-	343, 0, 828, 509, 596, 510, 829, 830, 0, 831,
-	0, 511, 512, 515, 0, 832, 0, 514, 516, 517,
-	0, 518, 0, 0, 0, 519, 520, 521, 522, 523,
-	524, 525, 0, 526, 528, 527, 0, 530, 833, 529,
-	0, 531, 532, 0, 0, 533, 534, 535, 536, 537,
-	538, 541, 0, 0, 539, 540, 542, 543, 0, 544,
-	545, 547, 550, 546, 548, 549, 551, 552, 565, 566,
-	553, 554, 555, 556, 557, 558, 559, 560, 561, 562,
-	563, 564, 568, 0, 567, 0, 569, 570, 571, 572,
-	573, 581, 583, 584, 579, 580, 582, 585, 586, 588,
-	589, 576, 577, 578, 0, 587, 574, 0, 575, 344,
-	0, 590, 591, 592, 593, 0, 834, 594, 835, 597,
-	598, 0, 0, 599, 0, 600, 0, 0, 602, 603,
-	604, 0, 0, 605, 606, 836, 0, 607, 0, 837,
-	608, 609, 601, 610, 611, 612, 613, 614, 615, 616,
-	617, 618, 619, 0, 620, 621, 838, 622, 623, 624,
-	839, 625, 626, 627, 840, 628, 841, 629, 630, 0,
-	631, 632, 633, 0, 2428, 635, 636, 637, 638, 639,
-	640, 641, 642, 643, 842, 644, 645, 647, 646, 648,
-	649, 0, 650, 0, 651, 652, 653, 0, 0, 0,
-	0, 0, 654, 655, 657, 0, 658, 659, 660, 661,
-	662, 656, 663, 664, 665, 666, 667, 668, 669, 0,
-	671, 672, 670, 673, 674, 0, 675, 676, 677, 678,
-	679, 843, 680, 0, 681, 682, 690, 691, 692, 683,
-	684, 686, 2416, 685, 694, 695, 696, 697, 699, 698,
-	0, 2422, 702, 700, 703, 704, 705, 706, 0, 707,
-	844, 708, 687, 688, 709, 710, 711, 0, 712, 713,
-	714, 715, 716, 717, 718, 719, 720, 845, 0, 721,
-	0, 722, 723, 724, 725, 726, 727, 729, 689, 730,
-	731, 732, 737, 738, 846, 733, 734, 735, 736, 847,
-	740, 741, 742, 743, 0, 744, 745, 0, 739, 728,
-	2424, 746, 747, 748, 749, 750, 751, 752, 753, 754,
-	755, 0, 756, 848, 849, 850, 851, 0, 768, 0,
-	757, 759, 760, 761, 762, 852, 763, 853, 0, 764,
-	765, 2415, 767, 758, 769, 770, 0, 0, 771, 772,
-	773, 774, 776, 778, 779, 780, 775, 777, 781, 0,
-	782, 0, 0, 783, 784, 785, 854, 855, 856, 0,
-	787, 788, 786, 789, 790, 793, 791, 792, 857, 796,
-	513, 797, 798, 799, 794, 795, 0, 1135, 0, 1137,
-	800, 801, 858, 802, 803, 804, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 345, 346, 348, 347,
-	349, 350, 351, 352, 0, 353, 354, 0, 0, 0,
-	0, 1149, 805, 0, 0, 0, 356, 0, 355, 0,
-	357, 358, 359, 0, 360, 361, 362, 363, 364, 365,
-	366, 367, 806, 807, 0, 368, 808, 369, 809, 0,
-	810, 370, 371, 372, 373, 374, 375, 376, 377, 378,
-	379, 0, 0, 0, 380, 811, 812, 813, 0, 381,
-	382, 383, 384, 814, 0, 0, 0, 385, 386, 387,
-	388, 389, 390, 391, 392, 0, 0, 394, 395, 396,
-	393, 397, 398, 0, 399, 0, 400, 401, 402, 403,
-	404, 405, 406, 0, 407, 408, 409, 0, 410, 411,
-	412, 0, 0, 0, 0, 0, 0, 0, 413, 414,
-	415, 1144, 417, 0, 418, 420, 421, 815, 422, 816,
-	0, 425, 427, 419, 423, 0, 426, 424, 428, 429,
-	0, 430, 431, 432, 433, 0, 0, 434, 435, 436,
-	0, 437, 438, 440, 439, 0, 441, 442, 443, 0,
-	444, 445, 817, 446, 447, 448, 450, 452, 449, 451,
-	453, 454, 455, 456, 457, 818, 819, 458, 459, 0,
-	340, 0, 0, 0, 0, 0, 460, 461, 462, 820,
-	0, 0, 0, 463, 0, 465, 469, 466, 467, 468,
-	470, 0, 464, 471, 472, 0, 0, 473, 474, 475,
-	821, 822, 476, 477, 478, 479, 480, 481, 482, 483,
-	484, 0, 485, 486, 823, 0, 824, 487, 0, 488,
-	489, 490, 491, 492, 493, 494, 825, 826, 827, 595,
-	0, 495, 496, 497, 0, 498, 499, 500, 501, 502,
-	503, 504, 0, 0, 0, 505, 506, 507, 508, 0,
-	342, 341, 343, 0, 828, 509, 596, 510, 829, 830,
-	0, 831, 0, 511, 512, 515, 0, 832, 0, 514,
-	516, 517, 0, 518, 0, 0, 0, 519, 520, 521,
-	522, 523, 524, 525, 0, 526, 528, 527, 0, 530,
-	833, 529, 0, 531, 532, 0, 0, 533, 534, 535,
-	536, 537, 538, 541, 0, 0, 539, 540, 542, 543,
-	0, 544, 545, 547, 550, 546, 548, 549, 551, 552,
-	565, 566, 553, 554, 555, 556, 557, 558, 559, 560,
-	561, 562, 563, 564, 568, 0, 567, 0, 569, 570,
-	571, 572, 573, 581, 583, 584, 579, 580, 582, 585,
-	586, 588, 589, 576, 577, 578, 0, 587, 574, 0,
-	575, 344, 0, 590, 591, 592, 593, 0, 834, 594,
-	835, 597, 598, 0, 0, 599, 0, 600, 0, 0,
-	602, 603, 604, 0, 0, 605, 606, 836, 0, 607,
-	0, 837, 608, 609, 601, 610, 611, 612, 613, 614,
-	615, 616, 617, 618, 619, 0, 620, 621, 838, 622,
-	623, 624, 839, 625, 626, 627, 840, 628, 841, 629,
-	630, 0, 631, 632, 633, 0, 634, 635, 636, 637,
-	638, 639, 640, 641, 642, 643, 842, 644, 645, 647,
-	646, 648, 649, 0, 650, 0, 651, 652, 653, 0,
-	0, 0, 0, 0, 654, 655, 657, 0, 658, 659,
-	660, 661, 662, 656, 663, 664, 665, 666, 667, 668,
-	669, 0, 671, 672, 670, 673, 674, 0, 675, 676,
-	677, 678, 679, 843, 680, 0, 681, 682, 690, 691,
-	692, 683, 684, 686, 693, 685, 694, 695, 696, 697,
-	699, 698, 0, 701, 702, 700, 703, 704, 705, 706,
-	0, 707, 844, 708, 687, 688, 709, 710, 711, 0,
-	712, 713, 714, 715, 716, 717, 718, 719, 720, 845,
-	0, 721, 0, 722, 723, 724, 725, 726, 727, 729,
-	689, 730, 731, 732, 737, 738, 846, 733, 734, 735,
-	736, 847, 740, 741, 742, 743, 0, 744, 745, 0,
-	739, 728, 1142, 746, 747, 748, 749, 750, 1146, 752,
-	753, 754, 755, 0, 756, 848, 849, 850, 851, 0,
-	768, 0, 757, 759, 760, 761, 762, 852, 763, 853,
-	0, 764, 765, 766, 767, 758, 769, 770, 0, 0,
-	771, 772, 773, 774, 776, 778, 779, 780, 775, 777,
-	781, 0, 782, 0, 0, 783, 784, 785, 854, 855,
-	856, 0, 787, 788, 786, 789, 790, 793, 791, 792,
-	1145, 796, 513, 797, 798, 799, 794, 795, 0, 4002,
-	0, 337, 800, 801, 858, 802, 803, 804, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 345, 346,
-	348, 347, 349, 350, 351, 352, 0, 353, 354, 0,
-	0, 0, 0, 1149, 805, 0, 0, 0, 356, 0,
-	355, 0, 357, 358, 359, 0, 360, 361, 362, 363,
-	364, 365, 366, 367, 806, 807, 0, 368, 808, 369,
-	809, 0, 810, 370, 371, 372, 373, 374, 375, 376,
-	377, 378, 379, 0, 0, 0, 380, 811, 812, 813,
-	0, 381, 382, 383, 384, 814, 0, 0, 0, 385,
-	386, 387, 388, 389, 390, 391, 392, 0, 0, 394,
-	395, 396, 393, 397, 398, 0, 399, 0, 400, 401,
-	402, 403, 404, 405, 406, 0, 407, 408, 409, 0,
-	410, 411, 412, 0, 0, 0, 0, 0, 0, 0,
-	413, 414, 415, 416, 417, 0, 418, 420, 421, 815,
-	422, 816, 0, 425, 427, 419, 423, 0, 426, 424,
-	428, 429, 0, 430, 431, 432, 433, 0, 0, 434,
-	435, 436, 0, 437, 438, 440, 439, 0, 441, 442,
-	443, 0, 444, 445, 817, 446, 447, 448, 450, 452,
-	449, 451, 453, 454, 455, 456, 457, 818, 819, 458,
-	459, 0, 340, 0, 0, 0, 0, 0, 460, 461,
-	462, 820, 0, 0, 0, 463, 0, 465, 469, 466,
-	467, 468, 470, 0, 464, 471, 472, 0, 0, 473,
-	474, 475, 821, 822, 476, 477, 478, 479, 480, 481,
-	482, 483, 484, 0, 485, 486, 823, 0, 824, 487,
-	0, 488, 489, 490, 491, 492, 493, 494, 825, 826,
-	827, 595, 0, 495, 496, 497, 0, 498, 499, 500,
-	501, 502, 503, 504, 0, 0, 0, 505, 506, 507,
-	508, 0, 342, 341, 343, 0, 828, 509, 596, 510,
-	829, 830, 0, 831, 0, 511, 512, 515, 0, 832,
-	0, 514, 516, 517, 0, 518, 0, 0, 0, 519,
-	520, 521, 522, 523, 524, 525, 0, 526, 528, 527,
-	0, 530, 833, 529, 0, 531, 532, 0, 0, 533,
-	534, 535, 536, 537, 538, 541, 0, 0, 539, 540,
-	542, 543, 0, 544, 545, 547, 550, 546, 548, 549,
-	551, 552, 565, 566, 553, 554, 555, 556, 557, 558,
-	559, 560, 561, 562, 563, 564, 568, 0, 567, 0,
-	569, 570, 571, 572, 573, 581, 583, 584, 579, 580,
-	582, 585, 586, 588, 589, 576, 577, 578, 0, 587,
-	574, 0, 575, 344, 0, 590, 591, 592, 593, 0,
-	834, 594, 835, 597, 598, 0, 0, 599, 0, 600,
-	0, 0, 602, 603, 604, 0, 0, 605, 606, 836,
-	0, 607, 0, 837, 608, 609, 601, 610, 611, 612,
-	613, 614, 615, 616, 617, 618, 619, 0, 620, 621,
-	838, 622, 623, 624, 839, 625, 626, 627, 840, 628,
-	841, 629, 630, 0, 631, 632, 633, 0, 634, 635,
-	636, 637, 638, 639, 640, 641, 642, 643, 842, 644,
-	645, 647, 646, 648, 649, 0, 650, 0, 651, 652,
-	653, 0, 0, 0, 0, 0, 654, 655, 657, 0,
-	658, 659, 660, 661, 662, 656, 663, 664, 665, 666,
-	667, 668, 669, 0, 671, 672, 670, 673, 674, 0,
-	675, 676, 677, 678, 679, 843, 680, 0, 681, 682,
-	690, 691, 692, 683, 684, 686, 693, 685, 694, 695,
-	696, 697, 699, 698, 0, 701, 702, 700, 703, 704,
-	705, 706, 0, 707, 844, 708, 687, 688, 709, 710,
-	711, 0, 712, 713, 714, 715, 716, 717, 718, 719,
-	720, 845, 0, 721, 0, 722, 723, 724, 725, 726,
-	727, 729, 689, 730, 731, 732, 737, 738, 846, 733,
-	734, 735, 736, 847, 740, 741, 742, 743, 0, 744,
-	745, 0, 739, 728, 0, 746, 747, 748, 749, 750,
-	751, 752, 753, 754, 755, 0, 756, 848, 849, 850,
-	851, 0, 768, 0, 757, 759, 760, 761, 762, 852,
-	763, 853, 0, 764, 765, 766, 767, 758, 769, 770,
-	0, 0, 771, 772, 773, 774, 776, 778, 779, 780,
-	775, 777, 781, 0, 782, 0, 0, 783, 784, 785,
-	854, 855, 856, 0, 787, 788, 786, 789, 790, 793,
-	791, 792, 857, 796, 513, 797, 798, 799, 794, 795,
-	2418, 0, 0, 0, 800, 801, 858, 802, 803, 804,
-	0, 0, 0, 0, 0, 0, 0, 345, 346, 348,
-	347, 349, 350, 351, 352, 0, 353, 354, 0, 0,
-	0, 0, 0, 805, 0, 1149, 0, 356, 0, 355,
-	0, 357, 358, 359, 0, 360, 361, 362, 363, 364,
-	365, 366, 367, 806, 807, 0, 368, 808, 369, 809,
-	0, 810, 370, 371, 372, 373, 374, 375, 376, 377,
-	378, 379, 0, 0, 0, 380, 811, 812, 813, 0,
-	381, 382, 383, 384, 814, 0, 0, 0, 385, 386,
-	387, 388, 389, 390, 391, 392, 0, 0, 394, 395,
-	396, 393, 397, 398, 0, 399, 0, 400, 401, 402,
-	403, 404, 405, 406, 0, 407, 408, 409, 0, 410,
-	411, 412, 0, 0, 0, 0, 0, 0, 0, 413,
-	414, 415, 2425, 417, 0, 418, 420, 421, 815, 422,
-	816, 0, 425, 427, 419, 423, 0, 426, 424, 428,
-	429, 0, 430, 431, 432, 433, 0, 0, 434, 435,
-	436, 0, 437, 438, 440, 439, 0, 441, 442, 443,
-	0, 444, 445, 817, 446, 447, 448, 450, 452, 449,
-	451, 453, 454, 455, 456, 2426, 818, 819, 458, 459,
-	0, 340, 0, 0, 0, 0, 0, 460, 461, 462,
-	820, 0, 0, 0, 463, 0, 465, 469, 466, 467,
-	468, 470, 0, 464, 471, 472, 0, 0, 2427, 474,
-	475, 821, 822, 476, 477, 478, 479, 480, 481, 482,
-	483, 484, 0, 485, 486, 823, 0, 824, 487, 0,
-	488, 489, 490, 491, 492, 493, 494, 825, 826, 827,
-	595, 0, 495, 496, 497, 0, 498, 499, 500, 501,
-	502, 503, 504, 0, 0, 0, 505, 506, 507, 508,
-	0, 342, 341, 343, 0, 828, 509, 596, 510, 829,
-	830, 0, 831, 0, 511, 512, 515, 0, 832, 0,
-	514, 516, 517, 0, 518, 0, 0, 0, 519, 520,
-	521, 522, 523, 524, 525, 0, 526, 528, 527, 0,
-	530, 833, 529, 0, 531, 532, 0, 0, 533, 534,
-	535, 536, 537, 538, 541, 0, 0, 539, 540, 542,
-	543, 0, 544, 545, 547, 550, 546, 548, 549, 551,
-	552, 565, 566, 553, 554, 555, 556, 557, 558, 559,
-	560, 561, 562, 563, 564, 568, 0, 567, 0, 569,
-	570, 571, 572, 573, 581, 583, 584, 579, 580, 582,
-	585, 586, 588, 589, 576, 577, 578, 0, 587, 574,
-	0, 575, 344, 0, 590, 591, 592, 593, 0, 834,
-	594, 835, 597, 598, 0, 0, 599, 0, 600, 0,
-	0, 602, 603, 604, 0, 0, 605, 606, 836, 0,
-	607, 0, 837, 608, 609, 601, 610, 611, 612, 613,
-	614, 615, 616, 617, 618, 619, 0, 620, 621, 838,
-	622, 623, 624, 839, 625, 626, 627, 840, 628, 841,
-	629, 630, 0, 631, 632, 633, 0, 2428, 635, 636,
-	637, 638, 639, 640, 641, 642, 643, 842, 644, 645,
-	647, 646, 648, 649, 0, 650, 0, 651, 652, 653,
-	0, 0, 0, 0, 0, 654, 655, 657, 0, 658,
-	659, 660, 661, 662, 656, 663, 664, 665, 666, 667,
-	668, 669, 0, 671, 672, 670, 673, 674, 0, 2621,
-	676, 677, 678, 679, 843, 680, 0, 681, 682, 690,
-	691, 692, 683, 684, 686, 2622, 685, 694, 695, 696,
-	697, 699, 698, 0, 2422, 702, 700, 703, 704, 705,
-	706, 0, 707, 844, 708, 687, 688, 709, 710, 711,
-	0, 712, 713, 714, 715, 716, 717, 718, 719, 720,
-	845, 0, 721, 0, 722, 723, 724, 725, 726, 727,
-	729, 689, 730, 731, 732, 737, 738, 846, 733, 734,
-	735, 736, 847, 740, 741, 742, 743, 0, 744, 745,
-	0, 739, 728, 2424, 746, 747, 748, 749, 750, 751,
-	752, 753, 754, 755, 0, 756, 848, 849, 850, 851,
-	0, 768, 0, 757, 759, 760, 761, 762, 852, 763,
-	853, 0, 764, 765, 2623, 767, 758, 769, 770, 0,
-	0, 771, 772, 773, 774, 776, 778, 779, 780, 775,
-	777, 781, 0, 782, 0, 0, 783, 784, 785, 854,
-	855, 856, 0, 787, 788, 786, 789, 790, 793, 791,
-	792, 857, 796, 513, 797, 798, 799, 794, 795, 337,
-	0, 0, 0, 800, 801, 858, 802, 803, 804, 0,
-	0, 0, 0, 0, 0, 0, 345, 346, 348, 347,
-	349, 350, 351, 352, 0, 353, 354, 0, 0, 0,
-	0, 0, 805, 0, 1149, 0, 356, 0, 355, 0,
-	357, 358, 359, 0, 360, 361, 362, 363, 364, 365,
-	366, 367, 806, 807, 0, 368, 808, 369, 809, 0,
-	810, 370, 371, 372, 373, 374, 375, 376, 377, 378,
-	379, 0, 0, 0, 380, 811, 812, 813, 0, 381,
-	382, 383, 384, 814, 0, 0, 0, 385, 386, 387,
-	388, 389, 390, 391, 392, 0, 0, 394, 395, 396,
-	393, 397, 398, 0, 399, 0, 400, 401, 402, 403,
-	404, 405, 406, 0, 407, 408, 409, 0, 410, 411,
-	412, 0, 0, 0, 0, 0, 0, 0, 413, 414,
-	415, 416, 417, 0, 418, 420, 421, 815, 422, 816,
-	0, 425, 427, 419, 423, 0, 426, 424, 428, 429,
-	0, 430, 431, 432, 433, 0, 0, 434, 435, 436,
-	0, 437, 438, 440, 439, 0, 441, 442, 443, 0,
-	444, 445, 817, 446, 447, 448, 450, 452, 449, 451,
-	453, 454, 455, 456, 457, 818, 819, 458, 459, 0,
-	340, 0, 0, 0, 0, 0, 460, 461, 462, 820,
-	0, 0, 0, 463, 0, 465, 469, 466, 467, 468,
-	470, 0, 464, 471, 472, 0, 0, 473, 474, 475,
-	821, 822, 476, 477, 478, 479, 480, 481, 482, 483,
-	484, 0, 485, 486, 823, 0, 824, 487, 0, 488,
-	489, 490, 491, 492, 493, 494, 825, 826, 827, 595,
-	0, 495, 496, 497, 0, 498, 499, 500, 501, 502,
-	503, 504, 0, 0, 0, 505, 506, 507, 508, 0,
-	342, 341, 343, 0, 828, 509, 596, 510, 829, 830,
-	0, 831, 0, 511, 512, 515, 0, 832, 0, 514,
-	516, 517, 0, 518, 0, 0, 0, 519, 520, 521,
-	522, 523, 524, 525, 0, 526, 528, 527, 0, 530,
-	833, 529, 0, 531, 532, 0, 0, 533, 534, 535,
-	536, 537, 538, 541, 0, 0, 539, 540, 542, 543,
-	0, 544, 545, 547, 550, 546, 548, 549, 551, 552,
-	565, 566, 553, 554, 555, 556, 557, 558, 559, 560,
-	561, 562, 563, 564, 568, 0, 567, 0, 569, 570,
-	571, 572, 573, 581, 583, 584, 579, 580, 582, 585,
-	586, 588, 589, 576, 577, 578, 0, 587, 574, 0,
-	575, 344, 0, 590, 591, 592, 593, 0, 834, 594,
-	835, 597, 598, 0, 0, 599, 0, 600, 0, 0,
-	602, 603, 604, 0, 0, 605, 606, 836, 0, 607,
-	0, 837, 608, 609, 601, 610, 611, 612, 613, 614,
-	615, 616, 617, 618, 619, 0, 620, 621, 838, 622,
-	623, 624, 839, 625, 626, 627, 840, 628, 841, 629,
-	630, 0, 631, 632, 633, 0, 634, 635, 636, 637,
-	638, 639, 640, 641, 642, 643, 842, 644, 645, 647,
-	646, 648, 649, 0, 650, 0, 651, 652, 653, 0,
-	0, 0, 0, 0, 654, 655, 657, 0, 658, 659,
-	660, 661, 662, 656, 663, 664, 665, 666, 667, 668,
-	669, 0, 671, 672, 670, 673, 674, 0, 675, 676,
-	677, 678, 679, 843, 680, 0, 681, 682, 690, 691,
-	692, 683, 684, 686, 693, 685, 694, 695, 696, 697,
-	699, 698, 0, 701, 702, 700, 703, 704, 705, 706,
-	0, 707, 844, 708, 687, 688, 709, 710, 711, 0,
-	712, 713, 714, 715, 716, 717, 718, 719, 720, 845,
-	0, 721, 0, 722, 723, 724, 725, 726, 727, 729,
-	689, 730, 731, 732, 737, 738, 846, 733, 734, 735,
-	736, 847, 740, 741, 742, 743, 0, 744, 745, 0,
-	739, 728, 0, 746, 747, 748, 749, 750, 751, 752,
-	753, 754, 755, 0, 756, 848, 849, 850, 851, 0,
-	768, 0, 757, 759, 760, 761, 762, 852, 763, 853,
-	0, 764, 765, 766, 767, 758, 769, 770, 0, 0,
-	771, 772, 773, 774, 776, 778, 779, 780, 775, 777,
-	781, 0, 782, 0, 0, 783, 784, 785, 854, 855,
-	856, 0, 787, 788, 786, 789, 790, 793, 791, 792,
-	857, 796, 513, 797, 798, 799, 794, 795, 337, 0,
-	0, 0, 800, 801, 858, 802, 803, 804, 0, 0,
-	0, 0, 0, 0, 0, 345, 346, 348, 347, 349,
-	350, 351, 352, 0, 353, 354, 0, 0, 0, 0,
-	0, 805, 0, 1149, 0, 356, 0, 355, 0, 357,
-	358, 359, 0, 360, 361, 362, 363, 364, 365, 366,
-	367, 806, 807, 0, 368, 808, 369, 809, 0, 810,
-	370, 371, 372, 373, 374, 375, 376, 377, 378, 379,
-	0, 0, 0, 380, 811, 812, 813, 0, 381, 382,
-	383, 384, 814, 0, 0, 0, 385, 386, 387, 388,
-	389, 390, 391, 392, 0, 0, 394, 395, 396, 393,
-	397, 398, 0, 399, 0, 400, 401, 402, 403, 404,
-	405, 406, 0, 407, 408, 409, 0, 410, 411, 412,
-	0, 0, 0, 0, 0, 0, 0, 413, 414, 415,
-	416, 417, 0, 418, 420, 421, 815, 422, 816, 0,
-	425, 427, 419, 423, 0, 426, 424, 428, 429, 0,
-	430, 431, 432, 433, 0, 0, 434, 435, 436, 0,
-	437, 438, 440, 439, 0, 441, 442, 443, 0, 444,
-	445, 817, 446, 447, 448, 450, 452, 449, 451, 453,
-	454, 455, 456, 457, 818, 819, 458, 459, 0, 340,
-	0, 0, 0, 0, 0, 460, 461, 462, 820, 0,
-	0, 0, 463, 0, 465, 469, 466, 467, 468, 470,
-	0, 464, 471, 472, 0, 0, 473, 474, 475, 821,
-	822, 476, 477, 478, 479, 480, 481, 482, 483, 484,
-	0, 485, 486, 823, 0, 824, 487, 0, 488, 489,
-	490, 491, 492, 493, 494, 825, 826, 827, 595, 0,
-	495, 496, 497, 0, 498, 499, 500, 501, 502, 503,
-	504, 0, 0, 0, 505, 506, 507, 508, 0, 342,
-	341, 343, 0, 828, 509, 596, 510, 829, 830, 0,
-	831, 0, 511, 512, 515, 0, 832, 0, 514, 516,
-	517, 0, 518, 0, 0, 0, 519, 520, 521, 522,
-	523, 524, 525, 0, 526, 528, 527, 0, 530, 833,
-	529, 0, 531, 532, 0, 0, 533, 534, 535, 536,
-	537, 538, 541, 0, 0, 539, 540, 542, 543, 0,
-	544, 545, 547, 550, 546, 548, 549, 551, 552, 565,
-	566, 553, 554, 555, 556, 557, 558, 559, 560, 561,
-	562, 563, 564, 568, 0, 567, 0, 569, 570, 571,
-	572, 573, 581, 583, 584, 579, 580, 582, 585, 586,
-	588, 589, 576, 577, 578, 0, 587, 574, 0, 575,
-	344, 0, 590, 591, 592, 593, 0, 834, 594, 835,
-	597, 598, 0, 0, 599, 0, 600, 0, 0, 602,
-	603, 604, 0, 0, 605, 606, 836, 0, 607, 0,
-	837, 608, 609, 601, 610, 611, 612, 613, 614, 615,
-	616, 617, 618, 619, 0, 620, 621, 838, 622, 623,
-	624, 839, 625, 626, 627, 840, 628, 841, 629, 630,
-	0, 631, 632, 633, 0, 634, 635, 636, 637, 638,
-	639, 640, 641, 642, 643, 842, 644, 645, 647, 646,
-	648, 649, 0, 650, 0, 651, 652, 653, 0, 0,
-	0, 0, 0, 654, 655, 657, 0, 658, 659, 660,
-	661, 662, 656, 663, 664, 665, 666, 667, 668, 669,
-	0, 671, 672, 670, 673, 674, 0, 675, 676, 677,
-	678, 679, 843, 680, 0, 681, 682, 690, 691, 692,
-	683, 684, 686, 693, 685, 694, 695, 696, 697, 699,
-	698, 0, 701, 702, 700, 703, 704, 705, 706, 0,
-	707, 844, 708, 687, 688, 709, 710, 711, 0, 712,
-	713, 714, 715, 716, 717, 718, 719, 720, 845, 0,
-	721, 0, 722, 723, 724, 725, 726, 727, 729, 689,
-	730, 731, 732, 737, 738, 846, 733, 734, 735, 736,
-	847, 740, 741, 742, 743, 0, 744, 745, 0, 739,
-	728, 0, 746, 747, 748, 749, 750, 751, 752, 753,
-	754, 755, 0, 756, 848, 849, 850, 851, 0, 768,
-	0, 757, 759, 760, 761, 762, 852, 763, 853, 0,
-	764, 765, 766, 767, 758, 769, 770, 0, 0, 771,
-	772, 773, 774, 776, 778, 779, 780, 775, 777, 781,
-	0, 782, 0, 0, 783, 784, 785, 854, 855, 856,
-	0, 787, 788, 786, 789, 790, 793, 791, 792, 857,
-	796, 513, 797, 798, 799, 794, 795, 4022, 0, 0,
-	0, 800, 801, 858, 802, 803, 804, 0, 0, 0,
-	0, 0, 0, 0, 345, 346, 348, 347, 349, 350,
-	351, 352, 0, 353, 354, 0, 0, 0, 0, 0,
-	0, 0, 1026, 0, 356, 0, 355, 0, 357, 358,
-	359, 874, 360, 361, 362, 363, 364, 365, 366, 367,
-	0, 2451, 0, 368, 2458, 369, 2457, 0, 2466, 370,
-	371, 372, 373, 374, 375, 376, 377, 378, 379, 0,
-	0, 0, 380, 2469, 2470, 0, 0, 381, 382, 383,
-	384, 0, 0, 875, 0, 385, 386, 387, 388, 389,
-	390, 391, 392, 0, 0, 394, 395, 396, 393, 397,
-	398, 0, 399, 0, 400, 401, 402, 403, 404, 405,
-	406, 0, 407, 408, 409, 876, 410, 411, 412, 0,
-	0, 0, 0, 0, 0, 0, 413, 414, 415, 416,
-	417, 1477, 418, 420, 421, 2455, 422, 2454, 0, 425,
-	427, 419, 423, 0, 426, 424, 428, 429, 0, 430,
-	431, 432, 433, 0, 0, 434, 1469, 436, 0, 437,
-	438, 440, 439, 0, 441, 442, 443, 0, 444, 445,
-	0, 446, 447, 448, 450, 452, 449, 451, 453, 454,
-	455, 456, 457, 0, 0, 458, 459, 0, 340, 0,
-	0, 0, 0, 0, 460, 461, 462, 2453, 0, 0,
-	0, 463, 0, 465, 469, 466, 467, 468, 470, 0,
-	464, 471, 472, 0, 877, 473, 474, 475, 2464, 2465,
-	476, 477, 478, 479, 480, 481, 482, 483, 484, 0,
-	485, 486, 0, 0, 0, 487, 0, 488, 489, 490,
-	491, 492, 493, 494, 0, 0, 0, 595, 879, 495,
-	496, 497, 0, 498, 499, 500, 501, 502, 503, 504,
-	0, 0, 0, 505, 506, 507, 508, 0, 0, 0,
-	0, 878, 0, 509, 596, 510, 2448, 2449, 0, 2444,
-	0, 511, 512, 515, 880, 0, 881, 514, 516, 517,
-	882, 518, 0, 0, 0, 519, 520, 521, 522, 523,
-	524, 525, 0, 526, 528, 527, 0, 530, 0, 529,
-	883, 531, 532, 884, 0, 533, 534, 535, 536, 537,
-	538, 541, 0, 0, 539, 540, 542, 543, 0, 544,
-	545, 547, 550, 546, 548, 549, 551, 552, 565, 566,
-	553, 554, 555, 556, 557, 558, 559, 560, 561, 562,
-	563, 564, 568, 0, 567, 885, 569, 570, 571, 572,
-	573, 581, 583, 584, 579, 580, 582, 585, 586, 588,
-	589, 576, 577, 578, 886, 587, 574, 0, 575, 0,
-	887, 590, 591, 592, 593, 0, 0, 594, 2456, 597,
-	598, 0, 0, 599, 0, 600, 0, 0, 602, 603,
-	604, 0, 0, 605, 606, 0, 888, 607, 889, 0,
-	608, 609, 601, 610, 611, 612, 613, 614, 615, 616,
-	617, 618, 619, 0, 620, 621, 2441, 622, 623, 624,
-	2442, 625, 626, 627, 0, 628, 0, 629, 630, 0,
-	631, 632, 633, 0, 634, 635, 636, 637, 638, 639,
-	640, 641, 642, 643, 2452, 644, 645, 647, 646, 648,
-	649, 0, 650, 0, 651, 652, 653, 0, 0, 0,
-	0, 0, 654, 655, 657, 0, 658, 659, 660, 661,
-	662, 656, 663, 664, 665, 666, 667, 668, 669, 0,
-	671, 672, 670, 673, 674, 890, 675, 676, 677, 678,
-	679, 0, 680, 0, 681, 682, 690, 691, 692, 683,
-	684, 686, 693, 685, 694, 695, 696, 697, 699, 698,
-	0, 701, 702, 700, 703, 704, 705, 706, 0, 707,
-	0, 708, 687, 688, 709, 710, 711, 891, 712, 713,
-	714, 715, 716, 717, 718, 719, 720, 2450, 0, 721,
-	0, 722, 723, 724, 725, 726, 727, 729, 689, 730,
-	731, 732, 737, 738, 2468, 733, 734, 735, 736, 0,
-	740, 741, 742, 743, 0, 744, 745, 0, 739, 728,
-	0, 746, 747, 748, 749, 750, 751, 752, 753, 754,
-	755, 0, 756, 2460, 2461, 2462, 2463, 0, 768, 0,
-	757, 759, 760, 761, 762, 0, 763, 0, 0, 764,
-	765, 766, 767, 758, 769, 770, 0, 0, 771, 772,
-	773, 774, 776, 778, 779, 780, 775, 777, 781, 0,
-	782, 0, 0, 783, 784, 785, 0, 2459, 2467, 0,
-	787, 788, 786, 789, 790, 793, 791, 792, 0, 796,
-	513, 797, 798, 799, 794, 795, 0, 0, 0, 0,
-	800, 801, 0, 802, 803, 804, 0, 2445, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 345, 346, 348, 347, 349, 350,
-	351, 352, 0, 353, 354, 0, 0, 0, 0, 0,
-	0, 0, 0, 2437, 356, 0, 355, 0, 357, 358,
-	359, 874, 360, 361, 362, 363, 364, 365, 366, 367,
-	0, 2451, 0, 368, 2458, 369, 2457, 0, 2466, 370,
-	371, 372, 373, 374, 375, 376, 377, 378, 379, 0,
-	0, 0, 380, 2469, 2470, 0, 0, 381, 382, 383,
-	384, 0, 0, 875, 0, 385, 386, 387, 388, 389,
-	390, 391, 392, 0, 0, 394, 395, 396, 393, 397,
-	398, 0, 399, 0, 400, 401, 402, 403, 404, 405,
-	406, 0, 407, 408, 409, 876, 410, 411, 412, 0,
-	0, 0, 0, 0, 0, 0, 413, 414, 415, 416,
-	417, 1477, 418, 420, 421, 2455, 422, 2454, 0, 425,
-	427, 419, 423, 0, 426, 424, 428, 429, 0, 430,
-	431, 432, 433, 0, 0, 434, 1469, 436, 0, 437,
-	438, 440, 439, 0, 441, 442, 443, 0, 444, 445,
-	0, 446, 447, 448, 450, 452, 449, 451, 453, 454,
-	455, 456, 457, 0, 0, 458, 459, 0, 0, 0,
-	0, 0, 0, 0, 460, 461, 462, 2453, 0, 0,
-	0, 463, 0, 465, 469, 466, 467, 468, 470, 0,
-	464, 471, 472, 0, 877, 473, 474, 475, 2464, 2465,
-	476, 477, 478, 479, 480, 481, 482, 483, 484, 0,
-	485, 486, 0, 0, 0, 487, 0, 488, 489, 490,
-	491, 492, 493, 494, 0, 0, 0, 595, 879, 495,
-	496, 497, 0, 498, 499, 500, 501, 502, 503, 504,
-	0, 0, 0, 505, 506, 507, 508, 0, 0, 0,
-	0, 878, 0, 509, 596, 510, 2448, 2449, 0, 2444,
-	0, 511, 512, 515, 880, 0, 881, 514, 516, 517,
-	882, 518, 0, 0, 0, 519, 520, 521, 522, 523,
-	524, 525, 0, 526, 528, 527, 0, 530, 0, 529,
-	883, 531, 532, 884, 0, 533, 534, 535, 536, 537,
-	538, 541, 0, 0, 539, 540, 542, 543, 0, 544,
-	545, 547, 550, 546, 548, 549, 551, 552, 565, 566,
-	553, 554, 555, 556, 557, 558, 559, 560, 561, 562,
-	563, 564, 568, 0, 567, 885, 569, 570, 571, 572,
-	573, 581, 583, 584, 579, 580, 582, 585, 586, 588,
-	589, 576, 577, 578, 886, 587, 574, 0, 575, 0,
-	887, 590, 591, 592, 593, 0, 0, 594, 2456, 597,
-	598, 0, 0, 599, 0, 600, 0, 0, 602, 603,
-	604, 0, 0, 605, 606, 0, 888, 607, 889, 0,
-	608, 609, 601, 610, 611, 612, 613, 614, 615, 616,
-	617, 618, 619, 0, 620, 621, 2441, 622, 623, 624,
-	2442, 625, 626, 627, 0, 628, 0, 629, 630, 0,
-	631, 632, 633, 0, 634, 635, 636, 637, 638, 639,
-	640, 641, 642, 643, 2452, 644, 645, 647, 646, 648,
-	649, 0, 650, 0, 651, 652, 653, 0, 0, 0,
-	0, 0, 654, 655, 657, 0, 658, 659, 660, 661,
-	662, 656, 663, 664, 665, 666, 667, 668, 669, 0,
-	671, 672, 670, 673, 674, 890, 675, 676, 677, 678,
-	679, 0, 680, 0, 681, 682, 690, 691, 692, 683,
-	684, 686, 693, 685, 694, 695, 696, 697, 699, 698,
-	0, 701, 702, 700, 703, 704, 705, 706, 0, 707,
-	0, 708, 687, 688, 709, 710, 711, 891, 712, 713,
-	714, 715, 716, 717, 718, 719, 720, 2450, 0, 721,
-	0, 722, 723, 724, 725, 726, 727, 729, 689, 730,
-	731, 732, 737, 738, 2468, 733, 734, 735, 736, 0,
-	740, 741, 742, 743, 0, 744, 745, 0, 739, 728,
-	0, 746, 747, 748, 749, 750, 751, 752, 753, 754,
-	755, 0, 756, 2460, 2461, 2462, 2463, 0, 768, 0,
-	757, 759, 760, 761, 762, 0, 763, 0, 0, 764,
-	765, 766, 767, 758, 769, 770, 0, 0, 771, 772,
-	773, 774, 776, 778, 779, 780, 775, 777, 781, 0,
-	782, 0, 0, 783, 784, 785, 0, 2459, 2467, 0,
-	787, 788, 786, 789, 790, 793, 791, 792, 0, 796,
-	513, 797, 798, 799, 794, 795, 0, 0, 0, 337,
-	800, 801, 0, 802, 803, 804, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 345, 346, 348, 347,
-	349, 350, 351, 352, 0, 353, 354, 0, 0, 0,
-	0, 0, 805, 0, 0, 0, 356, 0, 355, 0,
-	357, 358, 359, 2437, 360, 361, 362, 363, 364, 365,
-	366, 367, 806, 807, 0, 368, 808, 369, 809, 0,
-	810, 370, 371, 372, 373, 374, 375, 376, 377, 378,
-	379, 0, 0, 0, 380, 811, 812, 813, 0, 381,
-	382, 383, 384, 814, 0, 0, 0, 385, 386, 387,
-	388, 389, 390, 391, 392, 0, 0, 394, 395, 396,
-	393, 397, 398, 0, 399, 0, 400, 401, 402, 403,
-	404, 405, 406, 0, 407, 408, 409, 0, 410, 411,
-	412, 0, 0, 0, 0, 0, 0, 0, 413, 414,
-	415, 416, 417, 0, 418, 420, 421, 815, 422, 816,
-	0, 425, 427, 419, 423, 0, 426, 424, 428, 429,
-	0, 430, 431, 432, 433, 0, 0, 434, 435, 436,
-	0, 437, 438, 440, 439, 0, 441, 442, 443, 0,
-	444, 445, 817, 446, 447, 448, 450, 452, 449, 451,
-	453, 454, 455, 456, 457, 818, 819, 458, 459, 0,
-	0, 0, 0, 0, 0, 0, 460, 461, 462, 820,
-	0, 0, 0, 463, 0, 465, 469, 466, 467, 468,
-	470, 0, 464, 471, 472, 0, 0, 473, 474, 475,
-	821, 822, 476, 477, 478, 479, 480, 481, 482, 483,
-	484, 0, 485, 486, 823, 0, 824, 487, 0, 488,
-	489, 490, 491, 492, 493, 494, 825, 826, 827, 595,
-	0, 495, 496, 497, 0, 498, 499, 500, 501, 502,
-	503, 504, 0, 0, 0, 505, 506, 507, 508, 0,
-	0, 0, 0, 0, 828, 509, 596, 510, 829, 830,
-	0, 831, 0, 511, 512, 515, 0, 832, 0, 514,
-	516, 517, 0, 518, 0, 0, 0, 519, 520, 521,
-	522, 523, 524, 525, 0, 526, 528, 527, 0, 530,
-	833, 529, 0, 531, 532, 0, 0, 533, 534, 535,
-	536, 537, 538, 541, 0, 0, 539, 540, 542, 543,
-	0, 544, 545, 547, 550, 546, 548, 549, 551, 552,
-	565, 566, 553, 554, 555, 556, 557, 558, 559, 560,
-	561, 562, 563, 564, 568, 0, 567, 0, 569, 570,
-	571, 572, 573, 581, 583, 584, 579, 580, 582, 585,
-	586, 588, 589, 576, 577, 578, 0, 587, 574, 0,
-	575, 0, 0, 590, 591, 592, 593, 0, 834, 594,
-	835, 597, 598, 0, 0, 599, 0, 600, 0, 0,
-	602, 603, 604, 0, 0, 605, 606, 836, 0, 607,
-	0, 837, 608, 609, 601, 610, 611, 612, 613, 614,
-	615, 616, 617, 618, 619, 0, 620, 621, 838, 622,
-	623, 624, 839, 625, 626, 627, 840, 628, 841, 629,
-	630, 0, 631, 632, 633, 0, 634, 635, 636, 637,
-	638, 639, 640, 641, 642, 643, 842, 644, 645, 647,
-	646, 648, 649, 0, 650, 0, 651, 652, 653, 0,
-	0, 0, 0, 0, 654, 655, 657, 0, 658, 659,
-	660, 661, 662, 656, 663, 664, 665, 666, 667, 668,
-	669, 0, 671, 672, 670, 673, 674, 0, 675, 676,
-	677, 678, 679, 843, 680, 0, 681, 682, 690, 691,
-	692, 683, 684, 686, 693, 685, 694, 695, 696, 697,
-	699, 698, 0, 701, 702, 700, 703, 704, 705, 706,
-	0, 707, 844, 708, 687, 688, 709, 710, 711, 0,
-	712, 713, 714, 715, 716, 717, 718, 719, 720, 845,
-	0, 721, 0, 722, 723, 724, 725, 726, 727, 729,
-	689, 730, 731, 732, 737, 738, 846, 733, 734, 735,
-	736, 847, 740, 741, 742, 743, 0, 744, 745, 0,
-	739, 728, 0, 746, 747, 748, 749, 750, 751, 752,
-	753, 754, 755, 0, 756, 848, 849, 850, 851, 0,
-	768, 0, 757, 759, 760, 761, 762, 852, 763, 853,
-	0, 764, 765, 766, 767, 758, 769, 770, 0, 0,
-	771, 772, 773, 774, 776, 778, 779, 780, 775, 777,
-	781, 0, 782, 0, 0, 783, 784, 785, 854, 855,
-	856, 0, 787, 788, 786, 789, 790, 793, 791, 792,
-	857, 796, 513, 797, 798, 799, 794, 795, 0, 0,
-	0, 0, 800, 801, 858, 802, 803, 804, 1733, 1732,
-	0, 0, 0, 0, 1730, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 345, 346, 348, 347, 349,
-	350, 351, 352, 5421, 353, 354, 0, 0, 0, 0,
-	0, 805, 0, 0, 0, 356, 0, 355, 0, 357,
-	358, 359, 874, 360, 361, 362, 363, 364, 365, 366,
-	367, 806, 807, 0, 368, 808, 369, 809, 0, 810,
-	370, 371, 372, 373, 374, 375, 376, 377, 378, 379,
-	0, 0, 0, 380, 811, 812, 813, 0, 381, 382,
-	383, 384, 814, 0, 875, 0, 385, 386, 387, 388,
-	389, 390, 391, 392, 0, 0, 394, 395, 396, 393,
-	397, 398, 0, 399, 0, 400, 401, 402, 403, 404,
-	405, 406, 0, 407, 408, 409, 876, 410, 411, 412,
-	0, 0, 0, 0, 0, 0, 0, 413, 414, 415,
-	416, 417, 0, 418, 420, 421, 815, 422, 816, 0,
-	425, 427, 419, 423, 0, 426, 424, 428, 429, 0,
-	430, 431, 432, 433, 0, 0, 434, 435, 436, 0,
-	437, 438, 440, 439, 0, 441, 442, 443, 0, 444,
-	445, 817, 446, 447, 448, 450, 452, 449, 451, 453,
-	454, 455, 456, 457, 818, 819, 458, 459, 0, 340,
-	0, 0, 0, 0, 0, 460, 461, 462, 820, 0,
-	0, 0, 463, 0, 465, 469, 466, 467, 468, 470,
-	0, 464, 471, 472, 0, 877, 473, 474, 475, 821,
-	822, 476, 477, 478, 479, 480, 481, 482, 483, 484,
-	0, 485, 486, 823, 0, 824, 487, 0, 488, 489,
-	490, 491, 492, 493, 494, 825, 826, 827, 595, 879,
-	495, 496, 497, 0, 498, 499, 500, 501, 502, 503,
-	504, 0, 0, 0, 505, 506, 507, 508, 0, 0,
-	0, 0, 878, 828, 509, 596, 510, 829, 830, 0,
-	831, 0, 511, 512, 515, 880, 832, 881, 514, 516,
-	517, 882, 518, 0, 0, 0, 519, 520, 521, 522,
-	523, 524, 525, 0, 526, 528, 527, 0, 530, 833,
-	529, 883, 531, 532, 884, 0, 533, 534, 535, 536,
-	537, 538, 541, 0, 0, 539, 540, 542, 543, 0,
-	544, 545, 547, 550, 546, 548, 549, 551, 552, 565,
-	566, 553, 554, 555, 556, 557, 558, 559, 560, 561,
-	562, 563, 564, 568, 0, 567, 885, 569, 570, 571,
-	572, 573, 581, 583, 584, 579, 580, 582, 585, 586,
-	588, 589, 576, 577, 578, 886, 587, 574, 0, 575,
-	0, 887, 590, 591, 592, 593, 5554, 834, 594, 835,
-	597, 598, 0, 0, 599, 0, 600, 0, 0, 602,
-	603, 604, 0, 0, 605, 606, 836, 888, 607, 889,
-	837, 608, 609, 601, 610, 611, 612, 613, 614, 615,
-	616, 617, 618, 619, 0, 620, 621, 838, 622, 623,
-	624, 839, 625, 626, 627, 840, 628, 841, 629, 630,
-	0, 631, 632, 633, 0, 634, 635, 636, 637, 638,
-	639, 640, 641, 642, 643, 842, 644, 645, 647, 646,
-	648, 649, 0, 650, 0, 651, 652, 653, 0, 0,
-	0, 0, 0, 654, 655, 657, 0, 658, 659, 660,
-	661, 662, 656, 663, 664, 665, 666, 667, 668, 669,
-	0, 671, 672, 670, 673, 674, 890, 675, 676, 677,
-	678, 679, 843, 680, 0, 681, 682, 690, 691, 692,
-	683, 684, 686, 693, 685, 694, 695, 696, 697, 699,
-	698, 0, 701, 702, 700, 703, 704, 705, 706, 0,
-	707, 844, 708, 687, 688, 709, 710, 711, 891, 712,
-	713, 714, 715, 716, 717, 718, 719, 720, 845, 0,
-	721, 0, 722, 723, 724, 725, 726, 727, 729, 689,
-	730, 731, 732, 737, 738, 846, 733, 734, 735, 736,
-	847, 740, 741, 742, 743, 0, 744, 745, 0, 739,
-	728, 0, 746, 747, 748, 749, 750, 751, 752, 753,
-	754, 755, 0, 756, 848, 849, 850, 851, 0, 768,
-	0, 757, 759, 760, 761, 762, 852, 763, 853, 0,
-	764, 765, 766, 767, 758, 769, 770, 0, 0, 771,
-	772, 773, 774, 776, 778, 779, 780, 775, 777, 781,
-	0, 782, 0, 0, 783, 784, 785, 854, 855, 856,
-	0, 787, 788, 786, 789, 790, 793, 791, 792, 857,
-	796, 513, 797, 798, 799, 794, 795, 0, 0, 0,
-	0, 800, 801, 858, 802, 803, 804, 4155, 0, 1733,
-	1732, 0, 0, 0, 0, 1730, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 345, 346, 348, 347,
-	349, 350, 351, 352, 0, 353, 354, 0, 0, 0,
-	0, 0, 805, 0, 0, 0, 356, 0, 355, 0,
-	357, 358, 359, 874, 360, 361, 362, 363, 364, 365,
-	366, 367, 806, 807, 0, 368, 808, 369, 809, 0,
-	810, 370, 371, 372, 373, 374, 375, 376, 377, 378,
-	379, 0, 0, 0, 380, 811, 812, 813, 0, 381,
-	382, 383, 384, 814, 0, 875, 0, 385, 386, 387,
-	388, 389, 390, 391, 392, 0, 0, 394, 395, 396,
-	393, 397, 398, 0, 399, 0, 400, 401, 402, 403,
-	404, 405, 406, 0, 407, 408, 409, 876, 410, 411,
-	412, 0, 0, 0, 0, 0, 0, 0, 413, 414,
-	415, 416, 417, 0, 418, 420, 421, 815, 422, 816,
-	0, 425, 427, 419, 423, 0, 426, 424, 428, 429,
-	0, 430, 431, 432, 433, 0, 0, 434, 435, 436,
-	0, 437, 438, 440, 439, 0, 441, 442, 443, 0,
-	444, 445, 817, 446, 447, 448, 450, 452, 449, 451,
-	453, 454, 455, 456, 457, 818, 819, 458, 459, 0,
-	340, 0, 0, 0, 0, 0, 460, 461, 462, 820,
-	0, 0, 0, 463, 0, 465, 469, 466, 467, 468,
-	470, 0, 464, 471, 472, 0, 877, 473, 474, 475,
-	821, 822, 476, 477, 478, 479, 480, 481, 482, 483,
-	484, 0, 485, 486, 823, 0, 824, 487, 0, 488,
-	489, 490, 491, 492, 493, 494, 825, 826, 827, 595,
-	879, 495, 496, 497, 0, 498, 499, 500, 501, 502,
-	503, 504, 0, 0, 0, 505, 506, 507, 508, 0,
-	0, 0, 0, 878, 828, 509, 596, 510, 829, 830,
-	0, 831, 0, 511, 512, 515, 880, 832, 881, 514,
-	516, 517, 882, 518, 0, 0, 0, 519, 520, 521,
-	522, 523, 524, 525, 0, 526, 528, 527, 0, 530,
-	833, 529, 883, 531, 532, 884, 0, 533, 534, 535,
-	536, 537, 538, 541, 0, 0, 539, 540, 542, 543,
-	0, 544, 545, 547, 550, 546, 548, 549, 551, 552,
-	565, 566, 553, 554, 555, 556, 557, 558, 559, 560,
-	561, 562, 563, 564, 568, 0, 567, 885, 569, 570,
-	571, 572, 573, 581, 583, 584, 579, 580, 582, 585,
-	586, 588, 589, 576, 577, 578, 886, 587, 574, 0,
-	575, 0, 887, 590, 591, 592, 593, 0, 834, 594,
-	835, 597, 598, 0, 0, 599, 0, 600, 0, 0,
-	602, 603, 604, 0, 0, 605, 606, 836, 888, 607,
-	889, 837, 608, 609, 601, 610, 611, 612, 613, 614,
-	615, 616, 617, 618, 619, 0, 620, 621, 838, 622,
-	623, 624, 839, 625, 626, 627, 840, 628, 841, 629,
-	630, 0, 631, 632, 633, 0, 634, 635, 636, 637,
-	638, 639, 640, 641, 642, 643, 842, 644, 645, 647,
-	646, 648, 649, 0, 650, 0, 651, 652, 653, 0,
-	0, 0, 0, 0, 654, 655, 657, 0, 658, 659,
-	660, 661, 662, 656, 663, 664, 665, 666, 667, 668,
-	669, 0, 671, 672, 670, 673, 674, 890, 675, 676,
-	677, 678, 679, 843, 680, 0, 681, 682, 690, 691,
-	692, 683, 684, 686, 693, 685, 694, 695, 696, 697,
-	699, 698, 0, 701, 702, 700, 703, 704, 705, 706,
-	0, 707, 844, 708, 687, 688, 709, 710, 711, 891,
-	712, 713, 714, 715, 716, 717, 718, 719, 720, 845,
-	0, 721, 0, 722, 723, 724, 725, 726, 727, 729,
-	689, 730, 731, 732, 737, 738, 846, 733, 734, 735,
-	736, 847, 740, 741, 742, 743, 0, 744, 745, 0,
-	739, 728, 0, 746, 747, 748, 749, 750, 751, 752,
-	753, 754, 755, 0, 756, 848, 849, 850, 851, 0,
-	768, 0, 757, 759, 760, 761, 762, 852, 763, 853,
-	0, 764, 765, 766, 767, 758, 769, 770, 0, 0,
-	771, 772, 773, 774, 776, 778, 779, 780, 775, 777,
-	781, 0, 782, 0, 0, 783, 784, 785, 854, 855,
-	856, 0, 787, 788, 786, 789, 790, 793, 791, 792,
-	857, 796, 513, 797, 798, 799, 794, 795, 0, 0,
-	0, 0, 800, 801, 858, 802, 803, 804, 2907, 0,
-	1733, 1732, 0, 0, 0, 0, 1730, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 345, 346, 348,
-	347, 349, 350, 351, 352, 0, 353, 354, 0, 0,
-	0, 0, 0, 805, 0, 0, 0, 356, 0, 355,
-	0, 357, 358, 359, 874, 360, 361, 362, 363, 364,
-	365, 366, 367, 806, 807, 0, 368, 808, 369, 809,
-	0, 810, 370, 371, 372, 373, 374, 375, 376, 377,
-	378, 379, 0, 0, 0, 380, 811, 812, 813, 0,
-	381, 382, 383, 384, 814, 0, 875, 0, 385, 386,
-	387, 388, 389, 390, 391, 392, 0, 0, 394, 395,
-	396, 393, 397, 398, 0, 399, 0, 400, 401, 402,
-	403, 404, 405, 406, 0, 407, 408, 409, 876, 410,
-	411, 412, 0, 0, 0, 0, 0, 0, 0, 413,
-	414, 415, 416, 417, 0, 418, 420, 421, 815, 422,
-	816, 0, 425, 427, 419, 423, 0, 426, 424, 428,
-	429, 0, 430, 431, 432, 433, 0, 0, 434, 435,
-	436, 0, 437, 438, 440, 439, 0, 441, 442, 443,
-	0, 444, 445, 817, 446, 447, 448, 450, 452, 449,
-	451, 453, 454, 455, 456, 457, 818, 819, 458, 459,
-	0, 340, 0, 0, 0, 0, 0, 460, 461, 462,
-	820, 0, 0, 0, 463, 0, 465, 469, 466, 467,
-	468, 470, 0, 464, 471, 472, 0, 877, 473, 474,
-	475, 821, 822, 476, 477, 478, 479, 480, 481, 482,
-	483, 484, 0, 485, 486, 823, 0, 824, 487, 0,
-	488, 489, 490, 491, 492, 493, 494, 2036, 826, 827,
-	595, 879, 495, 496, 497, 0, 498, 499, 500, 501,
-	502, 503, 504, 0, 0, 0, 505, 506, 507, 508,
-	0, 0, 0, 0, 878, 828, 509, 596, 510, 829,
-	830, 0, 831, 0, 511, 512, 515, 880, 832, 881,
-	514, 516, 517, 882, 518, 0, 0, 0, 519, 520,
-	521, 522, 523, 524, 525, 0, 526, 528, 527, 0,
-	530, 833, 529, 883, 531, 532, 884, 0, 533, 534,
-	535, 536, 537, 538, 541, 0, 0, 539, 540, 542,
-	543, 0, 544, 545, 547, 550, 546, 548, 549, 551,
-	552, 565, 566, 553, 554, 555, 556, 557, 558, 559,
-	560, 561, 562, 563, 564, 568, 0, 567, 885, 569,
-	570, 571, 572, 573, 581, 583, 584, 579, 580, 582,
-	585, 586, 588, 589, 576, 577, 578, 886, 587, 574,
-	0, 575, 0, 887, 590, 591, 592, 593, 0, 834,
-	594, 835, 597, 598, 0, 0, 599, 0, 600, 0,
-	0, 602, 603, 604, 0, 0, 605, 606, 836, 888,
-	607, 889, 837, 608, 609, 601, 610, 611, 612, 613,
-	614, 615, 616, 617, 618, 619, 0, 620, 621, 838,
-	622, 623, 624, 839, 625, 626, 627, 840, 628, 841,
-	629, 630, 0, 631, 632, 633, 0, 634, 635, 636,
-	637, 638, 639, 640, 641, 642, 643, 842, 644, 645,
-	647, 646, 648, 649, 0, 650, 0, 651, 652, 653,
-	0, 0, 0, 0, 0, 654, 655, 657, 0, 658,
-	659, 660, 661, 662, 656, 663, 664, 665, 666, 667,
-	668, 669, 0, 671, 672, 670, 673, 674, 890, 675,
-	676, 677, 678, 679, 843, 680, 0, 681, 682, 690,
-	691, 692, 683, 684, 686, 693, 685, 694, 695, 696,
-	697, 699, 698, 0, 701, 702, 700, 703, 704, 705,
-	706, 0, 707, 844, 708, 687, 688, 709, 710, 711,
-	891, 712, 713, 714, 715, 716, 717, 718, 719, 720,
-	845, 0, 721, 0, 722, 723, 724, 725, 726, 727,
-	729, 689, 730, 731, 732, 737, 738, 846, 733, 734,
-	735, 736, 847, 740, 741, 742, 743, 0, 744, 745,
-	0, 739, 728, 0, 746, 747, 748, 749, 750, 751,
-	752, 753, 754, 755, 0, 756, 848, 849, 850, 851,
-	0, 768, 0, 757, 759, 760, 761, 762, 852, 763,
-	853, 0, 764, 765, 766, 767, 758, 769, 770, 0,
-	0, 771, 772, 773, 774, 776, 778, 779, 780, 775,
-	777, 781, 0, 782, 0, 0, 783, 784, 785, 854,
-	855, 856, 0, 787, 788, 786, 789, 790, 793, 791,
-	792, 857, 796, 513, 797, 798, 799, 794, 795, 0,
-	0, 0, 0, 800, 801, 858, 802, 803, 804, 2483,
-	0, 1733, 1732, 0, 0, 0, 0, 1730, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 345, 346,
-	348, 347, 349, 350, 351, 352, 0, 353, 354, 0,
-	0, 0, 0, 0, 805, 0, 0, 0, 356, 0,
-	355, 0, 357, 358, 359, 874, 360, 361, 362, 363,
-	364, 365, 366, 367, 806, 807, 0, 368, 808, 369,
-	809, 0, 810, 370, 371, 372, 373, 374, 375, 376,
-	377, 378, 379, 0, 0, 0, 380, 811, 812, 813,
-	0, 381, 382, 383, 384, 814, 0, 875, 0, 385,
-	386, 387, 388, 389, 390, 391, 392, 0, 0, 394,
-	395, 396, 393, 397, 398, 0, 399, 0, 400, 401,
-	402, 403, 404, 405, 406, 0, 407, 408, 409, 876,
-	410, 411, 412, 0, 0, 0, 0, 0, 0, 0,
-	413, 414, 415, 416, 417, 0, 418, 420, 421, 815,
-	422, 816, 0, 425, 427, 419, 423, 0, 426, 424,
-	428, 429, 0, 430, 431, 432, 433, 0, 0, 434,
-	435, 436, 0, 437, 438, 440, 439, 0, 441, 442,
-	443, 0, 444, 445, 817, 446, 447, 448, 450, 452,
-	449, 451, 453, 454, 455, 456, 457, 818, 819, 458,
-	459, 0, 340, 0, 0, 0, 0, 0, 460, 461,
-	462, 820, 0, 0, 0, 463, 0, 465, 469, 466,
-	467, 468, 470, 0, 464, 471, 472, 0, 877, 473,
-	474, 475, 821, 822, 476, 477, 478, 479, 480, 481,
-	482, 483, 484, 0, 485, 486, 823, 0, 824, 487,
-	0, 488, 489, 490, 491, 492, 493, 494, 825, 826,
-	827, 595, 879, 495, 496, 497, 0, 498, 499, 500,
-	501, 502, 503, 504, 0, 0, 0, 505, 506, 507,
-	508, 0, 0, 0, 0, 878, 828, 509, 596, 510,
-	829, 830, 0, 831, 0, 511, 512, 515, 880, 832,
-	881, 514, 516, 517, 882, 518, 0, 0, 0, 519,
-	520, 521, 522, 523, 524, 525, 0, 526, 528, 527,
-	0, 530, 833, 529, 883, 531, 532, 884, 0, 533,
-	534, 535, 536, 537, 538, 541, 0, 0, 539, 540,
-	542, 543, 0, 544, 545, 547, 550, 546, 548, 549,
-	551, 552, 565, 566, 553, 554, 555, 556, 557, 558,
-	559, 560, 561, 562, 563, 564, 568, 0, 567, 885,
-	569, 570, 571, 572, 573, 581, 583, 584, 579, 580,
-	582, 585, 586, 588, 589, 576, 577, 578, 886, 587,
-	574, 0, 575, 0, 887, 590, 591, 592, 593, 0,
-	834, 594, 835, 597, 598, 0, 0, 599, 0, 600,
-	0, 0, 602, 603, 604, 0, 0, 605, 606, 836,
-	888, 607, 889, 837, 608, 609, 601, 610, 611, 612,
-	613, 614, 615, 616, 617, 618, 619, 0, 620, 621,
-	838, 622, 623, 624, 839, 625, 626, 627, 840, 628,
-	841, 629, 630, 0, 631, 632, 633, 0, 634, 635,
-	636, 637, 638, 639, 640, 641, 642, 643, 842, 644,
-	645, 647, 646, 648, 649, 0, 650, 0, 651, 652,
-	653, 0, 0, 0, 0, 0, 654, 655, 657, 0,
-	658, 659, 660, 661, 662, 656, 663, 664, 665, 666,
-	667, 668, 669, 0, 671, 672, 670, 673, 674, 890,
-	675, 676, 677, 678, 679, 843, 680, 0, 681, 682,
-	690, 691, 692, 683, 684, 686, 693, 685, 694, 695,
-	696, 697, 699, 698, 0, 701, 702, 700, 703, 704,
-	705, 706, 0, 707, 844, 708, 687, 688, 709, 710,
-	711, 891, 712, 713, 714, 715, 716, 717, 718, 719,
-	720, 845, 0, 721, 0, 722, 723, 724, 725, 726,
-	727, 729, 689, 730, 731, 732, 737, 738, 846, 733,
-	734, 735, 736, 847, 740, 741, 742, 743, 0, 744,
-	745, 0, 739, 728, 0, 746, 747, 748, 749, 750,
-	751, 752, 753, 754, 755, 0, 756, 848, 849, 850,
-	851, 0, 768, 0, 757, 759, 760, 761, 762, 852,
-	763, 853, 0, 764, 765, 766, 767, 758, 769, 770,
-	0, 0, 771, 772, 773, 774, 776, 778, 779, 780,
-	775, 777, 781, 0, 782, 0, 0, 783, 784, 785,
-	854, 855, 856, 0, 787, 788, 786, 789, 790, 793,
-	791, 792, 857, 796, 513, 797, 798, 799, 794, 795,
-	0, 0, 0, 0, 800, 801, 858, 802, 803, 804,
-	2033, 0, 1733, 1732, 0, 0, 0, 0, 1730, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 345,
-	346, 348, 347, 349, 350, 351, 352, 0, 353, 354,
-	0, 0, 0, 0, 0, 805, 0, 0, 0, 356,
-	0, 355, 0, 357, 358, 359, 874, 360, 361, 362,
-	363, 364, 365, 366, 367, 806, 807, 0, 368, 808,
-	369, 809, 0, 810, 370, 371, 372, 373, 374, 375,
-	376, 377, 378, 379, 0, 0, 0, 380, 811, 812,
-	813, 0, 381, 382, 383, 384, 814, 0, 875, 0,
-	385, 386, 387, 388, 389, 390, 391, 392, 0, 0,
-	394, 395, 396, 393, 397, 398, 0, 399, 0, 400,
-	401, 402, 403, 404, 405, 406, 0, 407, 408, 409,
-	876, 410, 411, 412, 0, 0, 0, 0, 0, 0,
-	0, 413, 414, 415, 416, 417, 0, 418, 420, 421,
-	815, 422, 816, 0, 425, 427, 419, 423, 0, 426,
-	424, 428, 429, 0, 430, 431, 432, 433, 0, 0,
-	434, 435, 436, 0, 437, 438, 440, 439, 0, 441,
-	442, 443, 0, 444, 445, 817, 446, 447, 448, 450,
-	452, 449, 451, 453, 454, 455, 456, 457, 818, 819,
-	458, 459, 0, 340, 0, 0, 0, 0, 0, 460,
-	461, 462, 820, 0, 0, 0, 463, 0, 465, 469,
-	466, 467, 468, 470, 0, 464, 471, 472, 0, 877,
-	473, 474, 475, 821, 822, 476, 477, 478, 479, 480,
-	481, 482, 483, 484, 0, 485, 486, 823, 0, 824,
-	487, 0, 488, 489, 490, 491, 492, 493, 494, 2036,
-	826, 827, 595, 879, 495, 496, 497, 0, 498, 499,
-	500, 501, 502, 503, 504, 0, 0, 0, 505, 506,
-	507, 508, 0, 0, 0, 0, 878, 828, 509, 596,
-	510, 829, 830, 0, 831, 0, 511, 512, 515, 880,
-	832, 881, 514, 516, 517, 882, 518, 0, 0, 0,
-	519, 520, 521, 522, 523, 524, 525, 0, 526, 528,
-	527, 0, 530, 833, 529, 883, 531, 532, 884, 0,
-	533, 534, 535, 536, 537, 538, 541, 0, 0, 539,
-	540, 542, 543, 0, 544, 545, 547, 550, 546, 548,
-	549, 551, 552, 565, 566, 553, 554, 555, 556, 557,
-	558, 559, 560, 561, 562, 563, 564, 568, 0, 567,
-	885, 569, 570, 571, 572, 573, 581, 583, 584, 579,
-	580, 582, 585, 586, 588, 589, 576, 577, 578, 886,
-	587, 574, 0, 575, 0, 887, 590, 591, 592, 593,
-	0, 834, 594, 835, 597, 598, 0, 0, 599, 0,
-	600, 0, 0, 602, 603, 604, 0, 0, 605, 606,
-	836, 888, 607, 889, 837, 608, 609, 601, 610, 611,
-	612, 613, 614, 615, 616, 617, 618, 619, 0, 620,
-	621, 838, 622, 623, 624, 839, 625, 626, 627, 840,
-	628, 841, 629, 630, 0, 631, 632, 633, 0, 634,
-	635, 636, 637, 638, 639, 640, 641, 642, 643, 842,
-	644, 645, 647, 646, 648, 649, 0, 650, 0, 651,
-	652, 653, 0, 0, 0, 0, 0, 654, 655, 657,
-	0, 658, 659, 660, 661, 662, 656, 663, 664, 665,
-	666, 667, 668, 669, 0, 671, 672, 670, 673, 674,
-	890, 675, 676, 677, 678, 679, 843, 680, 0, 681,
-	682, 690, 691, 692, 683, 684, 686, 693, 685, 694,
-	695, 696, 697, 699, 698, 0, 701, 702, 700, 703,
-	704, 705, 706, 0, 707, 844, 708, 687, 688, 709,
-	710, 711, 891, 712, 713, 714, 715, 716, 717, 718,
-	719, 720, 845, 0, 721, 0, 722, 723, 724, 725,
-	726, 727, 729, 689, 730, 731, 732, 737, 738, 846,
-	733, 734, 735, 736, 847, 740, 741, 742, 743, 0,
-	744, 745, 0, 739, 728, 0, 746, 747, 748, 749,
-	750, 751, 752, 753, 754, 755, 0, 756, 848, 849,
-	850, 851, 0, 768, 0, 757, 759, 760, 761, 762,
-	852, 763, 853, 0, 764, 765, 766, 767, 758, 769,
-	770, 0, 0, 771, 772, 773, 774, 776, 778, 779,
-	780, 775, 777, 781, 0, 782, 0, 0, 783, 784,
-	785, 854, 855, 856, 0, 787, 788, 786, 789, 790,
-	793, 791, 792, 857, 796, 513, 797, 798, 799, 794,
-	795, 0, 0, 0, 0, 800, 801, 858, 802, 803,
-	804, 1983, 0, 1733, 1732, 0, 0, 0, 0, 1730,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	345, 346, 348, 347, 349, 350, 351, 352, 0, 353,
-	354, 0, 0, 0, 0, 0, 805, 0, 0, 0,
-	356, 0, 355, 0, 357, 358, 359, 874, 360, 361,
-	362, 363, 364, 365, 366, 367, 806, 807, 0, 368,
-	808, 369, 809, 0, 810, 370, 371, 372, 373, 374,
-	375, 376, 377, 378, 379, 0, 0, 0, 380, 811,
-	812, 813, 0, 381, 382, 383, 384, 814, 0, 875,
-	0, 385, 386, 387, 388, 389, 390, 391, 392, 0,
-	0, 394, 395, 396, 393, 397, 398, 0, 399, 0,
-	400, 401, 402, 403, 404, 405, 406, 0, 407, 408,
-	409, 876, 410, 411, 412, 0, 0, 0, 0, 0,
-	0, 0, 413, 414, 415, 416, 417, 0, 418, 420,
-	421, 815, 422, 816, 0, 425, 427, 419, 423, 0,
-	426, 424, 428, 429, 0, 430, 431, 432, 433, 0,
-	0, 434, 435, 436, 0, 437, 438, 440, 439, 0,
-	441, 442, 443, 0, 444, 445, 817, 446, 447, 448,
-	450, 452, 449, 451, 453, 454, 455, 456, 457, 818,
-	819, 458, 459, 0, 340, 0, 0, 0, 0, 0,
-	460, 461, 462, 820, 0, 0, 0, 463, 0, 465,
-	469, 466, 467, 468, 470, 0, 464, 471, 472, 0,
-	877, 473, 474, 475, 821, 822, 476, 477, 478, 479,
-	480, 481, 482, 483, 484, 0, 485, 486, 823, 0,
-	824, 487, 0, 488, 489, 490, 491, 492, 493, 494,
-	825, 826, 827, 595, 879, 495, 496, 497, 0, 498,
-	499, 500, 501, 502, 503, 504, 0, 0, 0, 505,
-	506, 507, 508, 0, 0, 0, 0, 878, 828, 509,
-	596, 510, 829, 830, 0, 831, 0, 511, 512, 515,
-	880, 832, 881, 514, 516, 517, 882, 518, 0, 0,
-	0, 519, 520, 521, 522, 523, 524, 525, 0, 526,
-	528, 527, 0, 530, 833, 529, 883, 531, 532, 884,
-	0, 533, 534, 535, 536, 537, 538, 541, 0, 0,
-	539, 540, 542, 543, 0, 544, 545, 547, 550, 546,
-	548, 549, 551, 552, 565, 566, 553, 554, 555, 556,
-	557, 558, 559, 560, 561, 562, 563, 564, 568, 0,
-	567, 885, 569, 570, 571, 572, 573, 581, 583, 584,
-	579, 580, 582, 585, 586, 588, 589, 576, 577, 578,
-	886, 587, 574, 0, 575, 0, 887, 590, 591, 592,
-	593, 0, 834, 594, 835, 597, 598, 0, 0, 599,
-	0, 600, 0, 0, 602, 603, 604, 0, 0, 605,
-	606, 836, 888, 607, 889, 837, 608, 609, 601, 610,
-	611, 612, 613, 614, 615, 616, 617, 618, 619, 0,
-	620, 621, 838, 622, 623, 624, 839, 625, 626, 627,
-	840, 628, 841, 629, 630, 0, 631, 632, 633, 0,
-	634, 635, 636, 637, 638, 639, 640, 641, 642, 643,
-	842, 644, 645, 647, 646, 648, 649, 0, 650, 0,
-	651, 652, 653, 0, 0, 0, 0, 0, 654, 655,
-	657, 0, 658, 659, 660, 661, 662, 656, 663, 664,
-	665, 666, 667, 668, 669, 0, 671, 672, 670, 673,
-	674, 890, 675, 676, 677, 678, 679, 843, 680, 0,
-	681, 682, 690, 691, 692, 1981, 684, 686, 693, 685,
-	694, 695, 696, 697, 699, 698, 0, 701, 702, 700,
-	703, 704, 705, 706, 0, 707, 844, 708, 687, 688,
-	709, 710, 711, 891, 712, 713, 714, 715, 716, 717,
-	718, 719, 720, 845, 0, 721, 0, 722, 723, 724,
-	725, 726, 727, 729, 689, 730, 731, 732, 737, 738,
-	846, 733, 734, 735, 736, 847, 740, 741, 742, 743,
-	0, 744, 745, 0, 739, 728, 0, 746, 747, 748,
-	749, 750, 751, 752, 753, 754, 755, 0, 756, 848,
-	849, 850, 851, 0, 768, 0, 757, 759, 760, 761,
-	762, 852, 763, 853, 0, 764, 765, 766, 767, 758,
-	769, 770, 0, 0, 771, 772, 773, 774, 776, 778,
-	779, 780, 775, 777, 781, 0, 782, 0, 0, 783,
-	784, 785, 854, 855, 856, 0, 787, 788, 786, 789,
-	790, 793, 791, 792, 857, 796, 513, 797, 798, 799,
-	794, 795, 0, 0, 0, 0, 800, 801, 858, 802,
-	803, 804, 1728, 0, 1733, 1732, 0, 0, 0, 0,
-	1730, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 345, 346, 348, 347, 349, 350, 351, 352, 0,
-	353, 354, 0, 0, 0, 0, 0, 805, 0, 0,
-	0, 356, 0, 355, 0, 357, 358, 359, 874, 360,
-	361, 362, 363, 364, 365, 366, 367, 806, 807, 0,
-	368, 808, 369, 809, 0, 810, 370, 371, 372, 373,
-	374, 375, 376, 377, 378, 379, 0, 0, 0, 380,
-	811, 812, 813, 0, 381, 382, 383, 384, 814, 0,
-	875, 0, 385, 386, 387, 388, 389, 390, 391, 392,
-	0, 0, 394, 395, 396, 393, 1727, 398, 0, 399,
-	0, 400, 401, 402, 403, 404, 405, 406, 0, 407,
-	408, 409, 876, 410, 411, 412, 0, 0, 0, 0,
-	0, 0, 0, 413, 414, 415, 416, 417, 0, 418,
-	420, 421, 815, 422, 816, 0, 425, 427, 419, 423,
-	0, 426, 424, 428, 429, 0, 430, 431, 432, 433,
-	0, 0, 434, 435, 436, 0, 437, 438, 440, 439,
-	0, 441, 442, 443, 0, 444, 445, 817, 446, 447,
-	448, 450, 452, 449, 451, 453, 454, 455, 456, 457,
-	818, 819, 458, 459, 0, 340, 0, 0, 0, 0,
-	0, 1724, 461, 462, 820, 0, 0, 0, 463, 0,
-	465, 469, 466, 467, 468, 470, 0, 464, 471, 472,
-	0, 877, 473, 474, 475, 821, 822, 476, 477, 478,
-	479, 480, 481, 482, 483, 484, 0, 485, 486, 823,
-	0, 824, 487, 0, 488, 489, 490, 491, 492, 493,
-	494, 825, 826, 827, 595, 879, 495, 496, 497, 0,
-	498, 499, 500, 501, 502, 503, 504, 0, 0, 0,
-	505, 506, 507, 508, 0, 0, 0, 0, 878, 828,
-	509, 596, 510, 829, 830, 0, 831, 0, 511, 512,
-	515, 880, 832, 881, 514, 516, 517, 882, 518, 0,
-	0, 0, 519, 520, 521, 522, 523, 524, 525, 0,
-	526, 528, 527, 0, 530, 833, 529, 883, 531, 532,
-	884, 0, 533, 534, 535, 536, 537, 538, 541, 0,
-	0, 539, 540, 542, 543, 0, 544, 545, 547, 550,
-	546, 548, 549, 551, 552, 565, 566, 553, 554, 555,
-	556, 557, 558, 559, 560, 561, 562, 563, 564, 568,
-	0, 567, 885, 569, 570, 571, 572, 573, 581, 583,
-	584, 579, 580, 582, 585, 586, 588, 589, 576, 577,
-	578, 886, 587, 574, 0, 575, 0, 887, 590, 591,
-	592, 593, 0, 834, 594, 835, 597, 598, 0, 0,
-	599, 0, 600, 0, 0, 602, 603, 604, 0, 0,
-	605, 606, 836, 888, 607, 889, 837, 608, 609, 601,
-	610, 611, 612, 613, 614, 615, 616, 617, 618, 619,
-	0, 620, 621, 838, 622, 623, 624, 839, 625, 626,
-	627, 840, 628, 841, 629, 630, 0, 631, 632, 633,
-	0, 634, 635, 636, 637, 638, 639, 640, 641, 1725,
-	643, 842, 644, 645, 647, 646, 648, 649, 0, 650,
-	0, 651, 652, 653, 0, 0, 0, 0, 0, 654,
-	655, 657, 0, 658, 659, 660, 661, 662, 656, 663,
-	664, 665, 666, 667, 668, 669, 0, 671, 672, 670,
-	673, 674, 890, 675, 676, 677, 678, 679, 843, 680,
-	0, 681, 682, 690, 691, 692, 683, 684, 686, 693,
-	685, 1723, 695, 696, 697, 699, 698, 0, 701, 702,
-	700, 703, 704, 705, 706, 0, 707, 844, 708, 687,
-	688, 709, 710, 711, 891, 712, 713, 714, 715, 716,
-	717, 718, 719, 720, 845, 0, 721, 0, 722, 723,
-	724, 725, 726, 727, 729, 689, 730, 731, 732, 737,
-	738, 846, 733, 734, 735, 736, 847, 740, 741, 742,
-	743, 0, 744, 745, 0, 739, 728, 0, 746, 747,
-	748, 749, 750, 751, 752, 753, 754, 755, 0, 756,
-	848, 849, 850, 851, 0, 768, 0, 757, 759, 760,
-	761, 762, 852, 763, 853, 0, 764, 765, 766, 767,
-	758, 769, 770, 0, 0, 771, 772, 773, 774, 776,
-	778, 779, 780, 775, 777, 781, 0, 782, 0, 0,
-	783, 1726, 785, 854, 855, 856, 0, 787, 788, 786,
-	789, 790, 793, 791, 792, 857, 796, 513, 797, 798,
-	799, 794, 795, 0, 0, 0, 0, 800, 801, 858,
-	802, 803, 804, 1733, 1732, 0, 0, 0, 0, 1730,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	345, 346, 348, 347, 349, 350, 351, 352, 0, 353,
-	354, 0, 0, 0, 0, 0, 805, 0, 0, 0,
-	356, 0, 355, 0, 357, 358, 359, 874, 360, 361,
-	362, 363, 364, 365, 366, 367, 806, 807, 0, 368,
-	808, 369, 809, 0, 810, 370, 371, 372, 373, 374,
-	375, 376, 377, 378, 379, 0, 0, 0, 380, 811,
-	812, 813, 0, 381, 382, 383, 384, 814, 0, 875,
-	0, 385, 386, 387, 388, 389, 390, 391, 392, 0,
-	0, 394, 395, 396, 393, 397, 398, 0, 399, 0,
-	400, 401, 402, 403, 404, 405, 406, 0, 407, 408,
-	409, 876, 410, 411, 412, 0, 0, 0, 0, 0,
-	0, 0, 413, 414, 415, 416, 417, 0, 418, 420,
-	421, 815, 422, 816, 0, 425, 427, 419, 423, 0,
-	426, 424, 428, 429, 0, 430, 431, 432, 433, 0,
-	0, 434, 435, 436, 0, 437, 438, 440, 439, 0,
-	441, 442, 443, 0, 444, 445, 817, 446, 447, 448,
-	450, 452, 449, 451, 453, 454, 455, 456, 457, 818,
-	819, 458, 459, 0, 340, 0, 0, 0, 0, 0,
-	460, 461, 462, 820, 0, 0, 0, 463, 0, 465,
-	469, 466, 467, 468, 470, 0, 464, 471, 472, 0,
-	877, 473, 474, 475, 821, 822, 476, 477, 478, 479,
-	480, 481, 482, 483, 484, 0, 485, 486, 823, 0,
-	824, 487, 0, 488, 489, 490, 491, 492, 493, 494,
-	825, 826, 827, 595, 879, 495, 496, 497, 0, 498,
-	499, 500, 501, 502, 503, 504, 0, 0, 0, 505,
-	506, 507, 508, 0, 0, 0, 0, 878, 828, 509,
-	596, 510, 829, 830, 0, 831, 0, 511, 512, 515,
-	880, 832, 881, 514, 516, 517, 882, 518, 0, 0,
-	0, 519, 520, 521, 522, 523, 524, 525, 0, 526,
-	528, 527, 0, 530, 833, 529, 883, 531, 532, 884,
-	0, 533, 534, 535, 536, 537, 538, 541, 0, 0,
-	539, 540, 542, 543, 0, 544, 545, 547, 550, 546,
-	548, 549, 551, 552, 565, 566, 553, 554, 555, 556,
-	557, 558, 559, 560, 561, 562, 563, 564, 568, 0,
-	567, 885, 569, 570, 571, 572, 573, 581, 583, 584,
-	579, 580, 582, 585, 586, 588, 589, 576, 577, 578,
-	886, 587, 574, 0, 575, 0, 887, 590, 591, 592,
-	593, 0, 834, 594, 835, 597, 598, 0, 0, 599,
-	0, 600, 0, 0, 602, 603, 604, 0, 0, 605,
-	606, 836, 888, 607, 889, 837, 608, 609, 601, 610,
-	611, 612, 613, 614, 615, 616, 617, 618, 619, 0,
-	620, 621, 838, 622, 623, 624, 839, 625, 626, 627,
-	840, 628, 841, 629, 630, 0, 631, 632, 633, 0,
-	634, 635, 636, 637, 638, 639, 640, 641, 642, 643,
-	842, 644, 645, 647, 646, 648, 649, 0, 650, 0,
-	651, 652, 653, 0, 0, 0, 0, 0, 654, 655,
-	657, 0, 658, 659, 660, 661, 662, 656, 663, 664,
-	665, 666, 667, 668, 669, 0, 671, 672, 670, 673,
-	674, 890, 675, 676, 677, 678, 679, 843, 680, 0,
-	681, 682, 690, 691, 692, 683, 684, 686, 693, 685,
-	694, 695, 696, 697, 699, 698, 0, 701, 702, 700,
-	703, 704, 705, 706, 0, 707, 844, 708, 687, 688,
-	709, 710, 711, 891, 712, 713, 714, 715, 716, 717,
-	718, 719, 720, 845, 0, 721, 0, 722, 723, 724,
-	725, 726, 727, 729, 689, 730, 731, 732, 737, 738,
-	846, 733, 734, 735, 736, 847, 740, 741, 742, 743,
-	0, 744, 745, 0, 739, 728, 0, 746, 747, 748,
-	749, 750, 751, 752, 753, 754, 755, 0, 756, 848,
-	849, 850, 851, 0, 768, 0, 757, 759, 760, 761,
-	762, 852, 763, 853, 0, 764, 765, 766, 767, 758,
-	769, 770, 0, 0, 771, 772, 773, 774, 776, 778,
-	779, 780, 775, 777, 781, 0, 782, 0, 0, 783,
-	784, 785, 854, 855, 856, 0, 787, 788, 786, 789,
-	790, 793, 791, 792, 857, 796, 513, 797, 798, 799,
-	794, 795, 1733, 1732, 0, 0, 800, 801, 858, 802,
-	803, 804, 0, 0, 0, 0, 0, 0, 0, 345,
-	346, 348, 347, 349, 350, 351, 352, 0, 353, 354,
-	0, 0, 0, 0, 0, 805, 0, 0, 0, 356,
-	0, 355, 0, 357, 358, 359, 874, 360, 361, 362,
-	363, 364, 365, 366, 367, 806, 807, 0, 368, 808,
-	369, 809, 0, 810, 370, 371, 372, 373, 374, 375,
-	376, 377, 378, 379, 0, 0, 0, 380, 811, 812,
-	813, 0, 381, 382, 383, 384, 814, 0, 875, 0,
-	385, 386, 387, 388, 389, 390, 391, 392, 0, 0,
-	394, 395, 396, 393, 397, 398, 0, 399, 0, 400,
-	401, 402, 403, 404, 405, 406, 0, 407, 408, 409,
-	876, 410, 411, 412, 0, 0, 0, 0, 0, 0,
-	0, 413, 414, 415, 416, 417, 0, 418, 420, 421,
-	815, 422, 816, 0, 425, 427, 419, 423, 0, 426,
-	424, 428, 429, 0, 430, 431, 432, 433, 0, 0,
-	434, 435, 436, 0, 437, 438, 440, 439, 0, 441,
-	442, 443, 0, 444, 445, 817, 446, 447, 448, 450,
-	452, 449, 451, 453, 454, 455, 456, 457, 818, 819,
-	458, 459, 0, 340, 0, 0, 0, 0, 0, 460,
-	461, 462, 820, 0, 0, 0, 463, 0, 465, 469,
-	466, 467, 468, 470, 0, 464, 471, 472, 0, 877,
-	473, 474, 475, 821, 822, 476, 477, 478, 479, 480,
-	481, 482, 483, 484, 0, 485, 486, 823, 0, 824,
-	487, 0, 488, 489, 490, 491, 492, 493, 494, 825,
-	826, 827, 595, 879, 495, 496, 497, 0, 498, 499,
-	500, 501, 502, 503, 504, 0, 0, 0, 505, 506,
-	507, 508, 0, 0, 0, 0, 878, 828, 509, 596,
-	510, 829, 830, 0, 831, 0, 511, 512, 515, 880,
-	832, 881, 514, 516, 517, 882, 518, 0, 0, 0,
-	519, 520, 521, 522, 523, 524, 525, 0, 526, 528,
-	527, 0, 530, 833, 529, 883, 531, 532, 884, 0,
-	533, 534, 535, 536, 537, 538, 541, 0, 0, 539,
-	540, 542, 543, 0, 544, 545, 547, 550, 546, 548,
-	549, 551, 552, 565, 566, 553, 554, 555, 556, 557,
-	558, 559, 560, 561, 562, 563, 564, 568, 0, 567,
-	885, 569, 570, 571, 572, 573, 581, 583, 584, 579,
-	580, 582, 585, 586, 588, 589, 576, 577, 578, 886,
-	587, 574, 0, 575, 0, 887, 590, 591, 592, 593,
-	0, 834, 594, 835, 597, 598, 0, 0, 599, 0,
-	600, 0, 0, 602, 603, 604, 0, 0, 605, 606,
-	836, 888, 607, 889, 837, 608, 609, 601, 610, 611,
-	612, 613, 614, 615, 616, 617, 618, 619, 0, 620,
-	621, 838, 622, 623, 624, 839, 625, 626, 627, 840,
-	628, 841, 629, 630, 0, 631, 632, 633, 0, 634,
-	635, 636, 637, 638, 639, 640, 641, 642, 643, 842,
-	644, 645, 647, 646, 648, 649, 0, 650, 0, 651,
-	652, 653, 0, 0, 0, 0, 0, 654, 655, 657,
-	0, 658, 659, 660, 661, 662, 656, 663, 664, 665,
-	666, 667, 668, 669, 0, 671, 672, 670, 673, 674,
-	890, 675, 676, 677, 678, 679, 843, 680, 0, 681,
-	682, 690, 691, 692, 683, 684, 686, 693, 685, 694,
-	695, 696, 697, 699, 698, 0, 701, 702, 700, 703,
-	704, 705, 706, 0, 707, 844, 708, 687, 688, 709,
-	710, 711, 891, 712, 713, 714, 715, 716, 717, 718,
-	719, 720, 845, 0, 721, 0, 722, 723, 724, 725,
-	726, 727, 729, 689, 730, 731, 732, 737, 738, 846,
-	733, 734, 735, 736, 847, 740, 741, 742, 743, 0,
-	744, 745, 0, 739, 728, 0, 746, 747, 748, 749,
-	750, 751, 752, 753, 754, 755, 0, 756, 848, 849,
-	850, 851, 0, 768, 0, 757, 759, 760, 761, 762,
-	852, 763, 853, 0, 764, 765, 766, 767, 758, 769,
-	770, 0, 0, 771, 772, 773, 774, 776, 778, 779,
-	780, 775, 777, 781, 0, 782, 0, 0, 783, 784,
-	785, 854, 855, 856, 0, 787, 788, 786, 789, 790,
-	793, 791, 792, 857, 796, 513, 797, 798, 799, 794,
-	795, 1733, 0, 0, 0, 800, 801, 858, 802, 803,
-	804, 0, 0, 0, 0, 0, 0, 0, 345, 346,
-	348, 347, 349, 350, 351, 352, 0, 353, 354, 0,
-	0, 0, 0, 0, 805, 0, 0, 0, 356, 0,
-	355, 0, 357, 358, 359, 874, 360, 361, 362, 363,
-	364, 365, 366, 367, 806, 807, 0, 368, 808, 369,
-	809, 0, 810, 370, 371, 372, 373, 374, 375, 376,
-	377, 378, 379, 0, 0, 0, 380, 811, 812, 813,
-	0, 381, 382, 383, 384, 814, 0, 875, 0, 385,
-	386, 387, 388, 389, 390, 391, 392, 0, 0, 394,
-	395, 396, 393, 397, 398, 0, 399, 0, 400, 401,
-	402, 403, 404, 405, 406, 0, 407, 408, 409, 876,
-	410, 411, 412, 0, 0, 0, 0, 0, 0, 0,
-	413, 414, 415, 416, 417, 0, 418, 420, 421, 815,
-	422, 816, 0, 425, 427, 419, 423, 0, 426, 424,
-	428, 429, 0, 430, 431, 432, 433, 0, 0, 434,
-	435, 436, 0, 437, 438, 440, 439, 0, 441, 442,
-	443, 0, 444, 445, 817, 446, 447, 448, 450, 452,
-	449, 451, 453, 454, 455, 456, 457, 818, 819, 458,
-	459, 0, 340, 0, 0, 0, 0, 0, 460, 461,
-	462, 820, 0, 0, 0, 463, 0, 465, 469, 466,
-	467, 468, 470, 0, 464, 471, 472, 0, 877, 473,
-	474, 475, 821, 822, 476, 477, 478, 479, 480, 481,
-	482, 483, 484, 0, 485, 486, 823, 0, 824, 487,
-	0, 488, 489, 490, 491, 492, 493, 494, 825, 826,
-	827, 595, 879, 495, 496, 497, 0, 498, 499, 500,
-	501, 502, 503, 504, 0, 0, 0, 505, 506, 507,
-	508, 0, 0, 0, 0, 878, 828, 509, 596, 510,
-	829, 830, 0, 831, 0, 511, 512, 515, 880, 832,
-	881, 514, 516, 517, 882, 518, 0, 0, 0, 519,
-	520, 521, 522, 523, 524, 525, 0, 526, 528, 527,
-	0, 530, 833, 529, 883, 531, 532, 884, 0, 533,
-	534, 535, 536, 537, 538, 541, 0, 0, 539, 540,
-	542, 543, 0, 544, 545, 547, 550, 546, 548, 549,
-	551, 552, 565, 566, 553, 554, 555, 556, 557, 558,
-	559, 560, 561, 562, 563, 564, 568, 0, 567, 885,
-	569, 570, 571, 572, 573, 581, 583, 584, 579, 580,
-	582, 585, 586, 588, 589, 576, 577, 578, 886, 587,
-	574, 0, 575, 0, 887, 590, 591, 592, 593, 0,
-	834, 594, 835, 597, 598, 0, 0, 599, 0, 600,
-	0, 0, 602, 603, 604, 0, 0, 605, 606, 836,
-	888, 607, 889, 837, 608, 609, 601, 610, 611, 612,
-	613, 614, 615, 616, 617, 618, 619, 0, 620, 621,
-	838, 622, 623, 624, 839, 625, 626, 627, 840, 628,
-	841, 629, 630, 0, 631, 632, 633, 0, 634, 635,
-	636, 637, 638, 639, 640, 641, 642, 643, 842, 644,
-	645, 647, 646, 648, 649, 0, 650, 0, 651, 652,
-	653, 0, 0, 0, 0, 0, 654, 655, 657, 0,
-	658, 659, 660, 661, 662, 656, 663, 664, 665, 666,
-	667, 668, 669, 0, 671, 672, 670, 673, 674, 890,
-	675, 676, 677, 678, 679, 843, 680, 0, 681, 682,
-	690, 691, 692, 683, 684, 686, 693, 685, 694, 695,
-	696, 697, 699, 698, 0, 701, 702, 700, 703, 704,
-	705, 706, 0, 707, 844, 708, 687, 688, 709, 710,
-	711, 891, 712, 713, 714, 715, 716, 717, 718, 719,
-	720, 845, 0, 721, 0, 722, 723, 724, 725, 726,
-	727, 729, 689, 730, 731, 732, 737, 738, 846, 733,
-	734, 735, 736, 847, 740, 741, 742, 743, 0, 744,
-	745, 0, 739, 728, 0, 746, 747, 748, 749, 750,
-	751, 752, 753, 754, 755, 0, 756, 848, 849, 850,
-	851, 0, 768, 0, 757, 759, 760, 761, 762, 852,
-	763, 853, 0, 764, 765, 766, 767, 758, 769, 770,
-	0, 0, 771, 772, 773, 774, 776, 778, 779, 780,
-	775, 777, 781, 0, 782, 0, 0, 783, 784, 785,
-	854, 855, 856, 0, 787, 788, 786, 789, 790, 793,
-	791, 792, 857, 796, 513, 797, 798, 799, 794, 795,
-	337, 0, 0, 0, 800, 801, 858, 802, 803, 804,
-	0, 0, 0, 0, 0, 0, 0, 345, 346, 348,
-	347, 349, 350, 351, 352, 0, 353, 354, 0, 0,
-	0, 0, 0, 805, 0, 0, 0, 356, 0, 355,
-	0, 357, 358, 359, 0, 360, 361, 362, 363, 364,
-	365, 366, 367, 806, 807, 0, 368, 808, 369, 809,
-	0, 810, 370, 371, 372, 373, 374, 375, 376, 377,
-	378, 379, 0, 0, 0, 380, 811, 812, 813, 4193,
-	381, 382, 383, 384, 814, 0, 0, 0, 385, 386,
-	387, 388, 389, 390, 391, 392, 0, 0, 394, 395,
-	396, 393, 397, 398, 5086, 399, 0, 400, 401, 402,
-	403, 404, 405, 406, 0, 407, 408, 409, 0, 410,
-	411, 412, 0, 0, 0, 0, 0, 0, 0, 413,
-	414, 415, 416, 417, 0, 418, 420, 421, 815, 422,
-	816, 0, 425, 427, 419, 423, 0, 426, 424, 428,
-	429, 0, 430, 431, 432, 433, 0, 0, 434, 435,
-	436, 0, 437, 438, 440, 439, 0, 441, 442, 443,
-	0, 4197, 445, 817, 446, 447, 448, 450, 452, 449,
-	451, 453, 454, 455, 456, 457, 818, 819, 458, 459,
-	0, 5085, 0, 0, 0, 0, 0, 460, 461, 462,
-	820, 0, 0, 0, 463, 0, 465, 469, 466, 467,
-	468, 470, 4196, 464, 471, 472, 0, 0, 473, 474,
-	475, 821, 822, 476, 477, 478, 479, 480, 481, 482,
-	483, 484, 0, 485, 486, 823, 0, 824, 487, 0,
-	488, 489, 490, 491, 492, 493, 494, 825, 826, 827,
-	595, 0, 495, 496, 497, 0, 498, 499, 500, 501,
-	502, 503, 504, 0, 0, 0, 505, 506, 507, 508,
-	0, 5081, 5082, 0, 0, 828, 509, 596, 510, 829,
-	830, 0, 831, 0, 511, 5084, 515, 0, 832, 0,
-	514, 516, 517, 0, 518, 0, 0, 0, 519, 520,
-	521, 522, 523, 524, 525, 0, 526, 528, 527, 0,
-	530, 833, 529, 0, 531, 532, 5080, 0, 533, 534,
-	535, 536, 537, 538, 541, 0, 0, 539, 540, 542,
-	543, 0, 544, 545, 547, 550, 546, 548, 549, 551,
-	552, 565, 566, 553, 554, 555, 556, 557, 558, 559,
-	560, 561, 562, 563, 564, 568, 0, 567, 0, 569,
-	570, 571, 572, 573, 581, 583, 584, 579, 580, 582,
-	585, 586, 588, 589, 576, 577, 578, 0, 587, 574,
-	0, 575, 0, 0, 590, 591, 592, 593, 0, 834,
-	594, 835, 597, 598, 0, 0, 599, 0, 600, 0,
-	0, 602, 603, 604, 0, 0, 605, 606, 836, 0,
-	607, 0, 837, 608, 609, 601, 610, 611, 612, 613,
-	614, 615, 616, 617, 618, 619, 0, 620, 621, 838,
-	622, 623, 624, 839, 625, 626, 627, 840, 628, 841,
-	629, 630, 4195, 631, 632, 633, 0, 634, 635, 636,
-	637, 638, 639, 640, 641, 642, 643, 842, 644, 645,
-	647, 646, 648, 649, 0, 650, 0, 651, 652, 653,
-	0, 0, 0, 0, 0, 654, 655, 657, 0, 658,
-	659, 660, 661, 662, 656, 663, 664, 665, 666, 667,
-	668, 669, 0, 671, 672, 670, 673, 674, 0, 675,
-	676, 677, 678, 679, 843, 680, 0, 681, 682, 690,
-	691, 692, 683, 684, 686, 693, 685, 694, 695, 696,
-	697, 699, 698, 0, 701, 702, 700, 703, 704, 705,
-	706, 0, 707, 844, 708, 687, 688, 709, 710, 711,
-	0, 712, 713, 714, 715, 716, 717, 718, 719, 720,
-	845, 0, 721, 0, 722, 723, 724, 725, 726, 727,
-	729, 689, 730, 731, 732, 737, 738, 846, 733, 734,
-	735, 736, 847, 740, 741, 742, 743, 0, 744, 745,
-	0, 739, 728, 0, 746, 747, 748, 749, 750, 751,
-	752, 753, 754, 755, 0, 756, 848, 849, 850, 851,
-	0, 768, 0, 757, 759, 760, 761, 762, 852, 763,
-	853, 0, 764, 765, 766, 767, 758, 769, 770, 0,
-	5083, 771, 772, 773, 774, 776, 778, 779, 780, 775,
-	777, 781, 0, 782, 0, 0, 783, 784, 785, 854,
-	855, 856, 0, 787, 788, 786, 789, 790, 793, 791,
-	792, 857, 796, 513, 797, 798, 799, 794, 795, 1830,
-	0, 337, 0, 800, 801, 858, 802, 803, 804, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 345, 346,
-	348, 347, 349, 350, 351, 352, 1829, 353, 354, 0,
-	0, 0, 0, 0, 805, 0, 0, 0, 356, 0,
-	355, 0, 357, 358, 359, 0, 360, 361, 362, 363,
-	364, 365, 366, 367, 806, 807, 0, 368, 808, 369,
-	809, 0, 810, 370, 371, 372, 373, 374, 375, 376,
-	377, 378, 379, 0, 0, 0, 380, 811, 812, 813,
-	0, 381, 382, 383, 384, 814, 0, 0, 0, 385,
-	386, 387, 388, 389, 390, 391, 392, 0, 0, 394,
-	395, 396, 393, 397, 398, 0, 399, 0, 400, 401,
-	402, 403, 404, 405, 406, 0, 407, 408, 409, 0,
-	410, 411, 412, 0, 0, 0, 0, 0, 0, 0,
-	413, 414, 415, 1824, 417, 0, 418, 420, 421, 815,
-	422, 816, 0, 425, 427, 419, 423, 0, 426, 424,
-	428, 429, 0, 430, 431, 432, 433, 0, 0, 434,
-	435, 436, 0, 437, 438, 440, 439, 0, 441, 442,
-	443, 0, 444, 445, 817, 446, 447, 448, 450, 452,
-	449, 451, 453, 454, 455, 456, 1832, 818, 819, 458,
-	459, 0, 340, 0, 0, 0, 0, 0, 460, 461,
-	462, 820, 0, 0, 0, 463, 0, 465, 469, 466,
-	467, 468, 470, 0, 464, 471, 472, 0, 0, 1827,
-	474, 475, 821, 822, 476, 477, 478, 479, 480, 481,
-	482, 483, 484, 0, 485, 486, 823, 0, 824, 487,
-	0, 488, 489, 490, 491, 492, 493, 494, 825, 826,
-	827, 595, 0, 495, 496, 497, 0, 498, 499, 500,
-	501, 502, 503, 504, 0, 0, 0, 505, 1825, 507,
-	508, 0, 342, 341, 343, 0, 828, 509, 596, 510,
-	829, 830, 0, 831, 0, 511, 512, 515, 0, 832,
-	0, 514, 516, 517, 0, 518, 0, 0, 0, 519,
-	520, 521, 522, 523, 524, 525, 0, 526, 528, 527,
-	0, 530, 833, 529, 0, 531, 532, 0, 0, 533,
-	534, 535, 536, 537, 538, 541, 0, 0, 539, 540,
-	542, 543, 0, 544, 545, 547, 550, 546, 548, 549,
-	551, 552, 565, 566, 553, 554, 555, 556, 557, 558,
-	559, 560, 561, 562, 563, 564, 568, 0, 567, 0,
-	569, 570, 571, 572, 573, 581, 583, 584, 579, 580,
-	582, 585, 586, 588, 589, 576, 577, 578, 0, 587,
-	574, 0, 575, 344, 0, 590, 591, 592, 593, 0,
-	834, 594, 835, 597, 598, 0, 0, 599, 0, 600,
-	0, 0, 602, 603, 604, 0, 0, 605, 606, 836,
-	0, 607, 0, 837, 608, 609, 601, 610, 611, 612,
-	613, 614, 615, 616, 617, 618, 619, 0, 620, 621,
-	838, 622, 623, 624, 839, 625, 626, 627, 840, 628,
-	841, 629, 630, 0, 631, 632, 633, 0, 1828, 635,
-	636, 637, 638, 639, 640, 641, 642, 643, 842, 644,
-	645, 647, 646, 648, 649, 0, 650, 0, 651, 652,
-	653, 0, 0, 0, 0, 0, 654, 655, 657, 0,
-	658, 659, 660, 661, 662, 656, 663, 664, 665, 666,
-	667, 668, 669, 0, 671, 672, 670, 673, 674, 0,
-	675, 676, 677, 678, 679, 843, 680, 0, 681, 682,
-	690, 691, 692, 1831, 684, 686, 693, 685, 694, 695,
-	696, 697, 1826, 698, 0, 1823, 702, 700, 703, 704,
-	705, 706, 0, 707, 844, 708, 687, 688, 709, 710,
-	711, 0, 712, 713, 714, 715, 716, 717, 718, 719,
-	720, 845, 0, 721, 0, 722, 723, 724, 725, 726,
-	727, 729, 689, 730, 731, 732, 737, 738, 846, 733,
-	734, 735, 736, 847, 740, 741, 742, 743, 0, 744,
-	745, 0, 739, 728, 1821, 746, 747, 748, 749, 750,
-	751, 752, 753, 754, 755, 0, 756, 848, 849, 850,
-	851, 0, 768, 0, 757, 759, 760, 761, 762, 852,
-	763, 853, 0, 764, 765, 766, 767, 758, 769, 770,
-	0, 0, 771, 772, 773, 774, 776, 778, 779, 780,
-	775, 777, 781, 0, 782, 0, 0, 783, 784, 785,
-	854, 855, 856, 0, 787, 1822, 786, 789, 790, 793,
-	791, 792, 857, 796, 513, 797, 798, 799, 794, 795,
-	1956, 0, 337, 0, 800, 801, 858, 802, 803, 804,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 345,
-	346, 348, 347, 349, 350, 351, 352, 0, 353, 354,
-	0, 0, 0, 0, 0, 805, 0, 0, 0, 356,
-	0, 355, 0, 357, 358, 359, 0, 360, 361, 362,
-	363, 364, 365, 366, 367, 806, 807, 0, 368, 808,
-	369, 809, 0, 810, 370, 371, 372, 373, 374, 375,
-	376, 377, 378, 379, 0, 0, 0, 380, 811, 812,
-	813, 0, 381, 382, 383, 384, 814, 0, 0, 0,
-	385, 386, 387, 388, 389, 390, 391, 392, 0, 0,
-	394, 395, 396, 393, 397, 398, 0, 399, 0, 400,
-	401, 402, 403, 404, 405, 406, 0, 407, 408, 409,
-	0, 410, 411, 412, 0, 0, 0, 0, 0, 0,
-	0, 413, 414, 415, 416, 417, 0, 418, 420, 421,
-	815, 422, 816, 0, 425, 427, 419, 423, 0, 426,
-	424, 428, 429, 0, 430, 431, 432, 433, 0, 0,
-	434, 435, 436, 0, 437, 438, 440, 439, 0, 441,
-	442, 443, 0, 444, 445, 817, 446, 447, 448, 450,
-	452, 449, 451, 453, 454, 455, 456, 457, 818, 819,
-	458, 459, 0, 340, 0, 0, 0, 0, 0, 460,
-	461, 462, 820, 0, 0, 0, 463, 0, 465, 469,
-	466, 467, 468, 470, 0, 464, 471, 472, 0, 0,
-	473, 474, 475, 821, 822, 476, 477, 478, 479, 480,
-	481, 482, 483, 484, 0, 485, 486, 823, 0, 824,
-	487, 0, 488, 489, 490, 491, 492, 493, 494, 1958,
-	826, 827, 595, 0, 495, 496, 497, 0, 498, 499,
-	500, 501, 502, 503, 504, 0, 0, 0, 505, 506,
-	507, 508, 0, 342, 341, 343, 0, 828, 509, 596,
-	510, 829, 830, 0, 831, 0, 511, 512, 515, 0,
-	832, 0, 514, 516, 517, 0, 518, 0, 0, 0,
-	519, 520, 521, 522, 523, 524, 525, 0, 526, 528,
-	527, 0, 530, 833, 529, 0, 531, 532, 0, 0,
-	533, 534, 535, 536, 537, 538, 541, 0, 0, 539,
-	540, 542, 543, 0, 544, 545, 547, 550, 546, 548,
-	549, 551, 552, 565, 566, 553, 554, 555, 556, 557,
-	558, 559, 560, 561, 562, 563, 564, 568, 0, 567,
-	0, 569, 570, 571, 572, 573, 581, 583, 584, 579,
-	580, 582, 585, 586, 588, 589, 576, 577, 578, 0,
-	587, 574, 0, 575, 344, 0, 590, 591, 592, 593,
-	0, 834, 594, 835, 597, 598, 0, 0, 599, 0,
-	600, 0, 1528, 602, 603, 604, 0, 0, 605, 606,
-	836, 0, 607, 0, 837, 608, 609, 601, 610, 611,
-	612, 613, 614, 615, 616, 617, 618, 619, 0, 620,
-	621, 838, 622, 623, 624, 839, 625, 626, 627, 840,
-	628, 841, 629, 630, 0, 631, 632, 633, 0, 634,
-	635, 636, 637, 638, 639, 640, 641, 642, 643, 842,
-	644, 645, 647, 646, 648, 649, 0, 650, 0, 651,
-	652, 653, 0, 0, 0, 0, 0, 654, 655, 657,
-	0, 658, 659, 660, 661, 662, 656, 663, 664, 665,
-	666, 667, 668, 669, 0, 671, 672, 670, 673, 674,
-	0, 675, 676, 677, 678, 679, 843, 680, 0, 681,
-	682, 690, 691, 692, 683, 684, 686, 693, 685, 694,
-	695, 696, 697, 699, 698, 0, 701, 702, 700, 703,
-	704, 705, 706, 0, 707, 844, 708, 687, 688, 709,
-	710, 711, 0, 712, 713, 714, 715, 716, 717, 718,
-	719, 720, 845, 0, 721, 0, 722, 723, 724, 725,
-	726, 727, 729, 689, 730, 731, 732, 737, 738, 846,
-	733, 734, 735, 736, 847, 740, 741, 742, 743, 0,
-	744, 745, 0, 739, 728, 0, 746, 747, 748, 749,
-	750, 751, 752, 753, 754, 755, 0, 756, 848, 849,
-	850, 851, 0, 768, 0, 757, 759, 760, 761, 762,
-	852, 763, 853, 0, 764, 765, 766, 767, 758, 769,
-	770, 0, 0, 771, 772, 773, 774, 776, 778, 779,
-	780, 775, 777, 781, 0, 782, 0, 0, 783, 784,
-	785, 854, 855, 856, 0, 787, 788, 786, 789, 790,
-	793, 791, 792, 857, 796, 513, 797, 798, 799, 794,
-	795, 1953, 0, 337, 0, 800, 801, 858, 802, 803,
-	804, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	345, 346, 348, 347, 349, 350, 351, 352, 0, 353,
-	354, 0, 0, 0, 0, 0, 805, 0, 0, 0,
-	356, 0, 355, 0, 357, 358, 359, 0, 360, 361,
-	362, 363, 364, 365, 366, 367, 806, 807, 0, 368,
-	808, 369, 809, 0, 810, 370, 371, 372, 373, 374,
-	375, 376, 377, 378, 379, 0, 0, 0, 380, 811,
-	812, 813, 0, 381, 382, 383, 384, 814, 0, 0,
-	0, 385, 386, 387, 388, 389, 390, 391, 392, 0,
-	0, 394, 395, 396, 393, 397, 398, 0, 399, 0,
-	400, 401, 402, 403, 404, 405, 406, 0, 407, 408,
-	409, 0, 410, 411, 412, 0, 0, 0, 0, 0,
-	0, 0, 413, 414, 415, 416, 417, 0, 418, 420,
-	421, 815, 422, 816, 0, 425, 427, 419, 423, 0,
-	426, 424, 428, 429, 0, 430, 431, 432, 433, 0,
-	0, 434, 435, 436, 0, 437, 438, 440, 439, 0,
-	441, 442, 443, 0, 444, 445, 817, 446, 447, 448,
-	450, 452, 449, 451, 453, 454, 455, 456, 457, 818,
-	819, 458, 459, 0, 340, 0, 0, 0, 0, 0,
-	460, 461, 462, 820, 0, 0, 0, 463, 0, 465,
-	469, 466, 467, 468, 470, 0, 464, 471, 472, 0,
-	0, 473, 474, 475, 821, 822, 476, 477, 478, 479,
-	480, 481, 482, 483, 484, 0, 485, 486, 823, 0,
-	824, 487, 0, 488, 489, 490, 491, 492, 493, 494,
-	1955, 826, 827, 595, 0, 495, 496, 497, 0, 498,
-	499, 500, 501, 502, 503, 504, 0, 0, 0, 505,
-	506, 507, 508, 0, 342, 341, 343, 0, 828, 509,
-	596, 510, 829, 830, 0, 831, 0, 511, 512, 515,
-	0, 832, 0, 514, 516, 517, 0, 518, 0, 0,
-	0, 519, 520, 521, 522, 523, 524, 525, 0, 526,
-	528, 527, 0, 530, 833, 529, 0, 531, 532, 0,
-	0, 533, 534, 535, 536, 537, 538, 541, 0, 0,
-	539, 540, 542, 543, 0, 544, 545, 547, 550, 546,
-	548, 549, 551, 552, 565, 566, 553, 554, 555, 556,
-	557, 558, 559, 560, 561, 562, 563, 564, 568, 0,
-	567, 0, 569, 570, 571, 572, 573, 581, 583, 584,
-	579, 580, 582, 585, 586, 588, 589, 576, 577, 578,
-	0, 587, 574, 0, 575, 344, 0, 590, 591, 592,
-	593, 0, 834, 594, 835, 597, 598, 0, 0, 599,
-	0, 600, 0, 1528, 602, 603, 604, 0, 0, 605,
-	606, 836, 0, 607, 0, 837, 608, 609, 601, 610,
-	611, 612, 613, 614, 615, 616, 617, 618, 619, 0,
-	620, 621, 838, 622, 623, 624, 839, 625, 626, 627,
-	840, 628, 841, 629, 630, 0, 631, 632, 633, 0,
-	634, 635, 636, 637, 638, 639, 640, 641, 642, 643,
-	842, 644, 645, 647, 646, 648, 649, 0, 650, 0,
-	651, 652, 653, 0, 0, 0, 0, 0, 654, 655,
-	657, 0, 658, 659, 660, 661, 662, 656, 663, 664,
-	665, 666, 667, 668, 669, 0, 671, 672, 670, 673,
-	674, 0, 675, 676, 677, 678, 679, 843, 680, 0,
-	681, 682, 690, 691, 692, 683, 684, 686, 693, 685,
-	694, 695, 696, 697, 699, 698, 0, 701, 702, 700,
-	703, 704, 705, 706, 0, 707, 844, 708, 687, 688,
-	709, 710, 711, 0, 712, 713, 714, 715, 716, 717,
-	718, 719, 720, 845, 0, 721, 0, 722, 723, 724,
-	725, 726, 727, 729, 689, 730, 731, 732, 737, 738,
-	846, 733, 734, 735, 736, 847, 740, 741, 742, 743,
-	0, 744, 745, 0, 739, 728, 0, 746, 747, 748,
-	749, 750, 751, 752, 753, 754, 755, 0, 756, 848,
-	849, 850, 851, 0, 768, 0, 757, 759, 760, 761,
-	762, 852, 763, 853, 0, 764, 765, 766, 767, 758,
-	769, 770, 0, 0, 771, 772, 773, 774, 776, 778,
-	779, 780, 775, 777, 781, 0, 782, 0, 0, 783,
-	784, 785, 854, 855, 856, 0, 787, 788, 786, 789,
-	790, 793, 791, 792, 857, 796, 513, 797, 798, 799,
-	794, 795, 1861, 0, 337, 0, 800, 801, 858, 802,
-	803, 804, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 345, 346, 348, 347, 349, 350, 351, 352, 0,
-	353, 354, 0, 0, 0, 0, 0, 805, 0, 0,
-	0, 356, 0, 355, 0, 357, 358, 359, 0, 360,
-	361, 362, 363, 364, 365, 366, 367, 806, 807, 0,
-	368, 808, 369, 809, 0, 810, 370, 371, 372, 373,
-	374, 375, 376, 377, 378, 379, 0, 0, 0, 380,
-	811, 812, 813, 0, 381, 382, 383, 384, 814, 0,
-	0, 0, 385, 386, 387, 388, 389, 390, 391, 392,
-	0, 0, 394, 395, 396, 393, 397, 398, 0, 399,
-	0, 400, 401, 402, 403, 404, 405, 406, 0, 407,
-	408, 409, 0, 410, 411, 412, 0, 0, 0, 0,
-	0, 0, 0, 413, 414, 415, 416, 417, 0, 418,
-	420, 421, 815, 422, 816, 0, 425, 427, 419, 423,
-	0, 426, 424, 428, 429, 0, 430, 431, 432, 433,
-	0, 0, 434, 435, 436, 0, 437, 438, 440, 439,
-	0, 441, 442, 443, 0, 444, 445, 817, 446, 447,
-	448, 450, 452, 449, 451, 453, 454, 455, 456, 457,
-	818, 819, 458, 459, 0, 340, 0, 0, 0, 0,
-	0, 460, 461, 462, 820, 0, 0, 0, 463, 0,
-	465, 469, 466, 467, 468, 470, 0, 464, 471, 472,
-	0, 0, 473, 474, 475, 821, 822, 476, 477, 478,
-	479, 480, 481, 482, 483, 484, 0, 485, 486, 823,
-	0, 824, 487, 0, 488, 489, 490, 491, 492, 493,
-	494, 1863, 826, 827, 595, 0, 495, 496, 497, 0,
-	498, 499, 500, 501, 502, 503, 504, 0, 0, 0,
-	505, 506, 507, 508, 0, 342, 341, 343, 0, 828,
-	509, 596, 510, 829, 830, 0, 831, 0, 511, 512,
-	515, 0, 832, 0, 514, 516, 517, 0, 518, 0,
-	0, 0, 519, 520, 521, 522, 523, 524, 525, 0,
-	526, 528, 527, 0, 530, 833, 529, 0, 531, 532,
-	0, 0, 533, 534, 535, 536, 537, 538, 541, 0,
-	0, 539, 540, 542, 543, 0, 544, 545, 547, 550,
-	546, 548, 549, 551, 552, 565, 566, 553, 554, 555,
-	556, 557, 558, 559, 560, 561, 562, 563, 564, 568,
-	0, 567, 0, 569, 570, 571, 572, 573, 581, 583,
-	584, 579, 580, 582, 585, 586, 588, 589, 576, 577,
-	578, 0, 587, 574, 0, 575, 344, 0, 590, 591,
-	592, 593, 0, 834, 594, 835, 597, 598, 0, 0,
-	599, 0, 600, 0, 1528, 602, 603, 604, 0, 0,
-	605, 606, 836, 0, 607, 0, 837, 608, 609, 601,
-	610, 611, 612, 613, 614, 615, 616, 617, 618, 619,
-	0, 620, 621, 838, 622, 623, 624, 839, 625, 626,
-	627, 840, 628, 841, 629, 630, 0, 631, 632, 633,
-	0, 634, 635, 636, 637, 638, 639, 640, 641, 642,
-	643, 842, 644, 645, 647, 646, 648, 649, 0, 650,
-	0, 651, 652, 653, 0, 0, 0, 0, 0, 654,
-	655, 657, 0, 658, 659, 660, 661, 662, 656, 663,
-	664, 665, 666, 667, 668, 669, 0, 671, 672, 670,
-	673, 674, 0, 675, 676, 677, 678, 679, 843, 680,
-	0, 681, 682, 690, 691, 692, 683, 684, 686, 693,
-	685, 694, 695, 696, 697, 699, 698, 0, 701, 702,
-	700, 703, 704, 705, 706, 0, 707, 844, 708, 687,
-	688, 709, 710, 711, 0, 712, 713, 714, 715, 716,
-	717, 718, 719, 720, 845, 0, 721, 0, 722, 723,
-	724, 725, 726, 727, 729, 689, 730, 731, 732, 737,
-	738, 846, 733, 734, 735, 736, 847, 740, 741, 742,
-	743, 0, 744, 745, 0, 739, 728, 0, 746, 747,
-	748, 749, 750, 751, 752, 753, 754, 755, 0, 756,
-	848, 849, 850, 851, 0, 768, 0, 757, 759, 760,
-	761, 762, 852, 763, 853, 0, 764, 765, 766, 767,
-	758, 769, 770, 0, 0, 771, 772, 773, 774, 776,
-	778, 779, 780, 775, 777, 781, 0, 782, 0, 0,
-	783, 784, 785, 854, 855, 856, 0, 787, 788, 786,
-	789, 790, 793, 791, 792, 857, 796, 513, 797, 798,
-	799, 794, 795, 337, 0, 0, 0, 800, 801, 858,
-	802, 803, 804, 0, 0, 0, 0, 0, 0, 0,
-	345, 346, 348, 347, 349, 350, 351, 352, 0, 353,
-	354, 0, 0, 0, 0, 0, 805, 0, 0, 0,
-	356, 0, 355, 0, 357, 358, 359, 0, 360, 361,
-	362, 363, 364, 365, 366, 367, 806, 807, 0, 368,
-	808, 369, 809, 0, 810, 370, 371, 372, 373, 374,
-	375, 376, 377, 378, 379, 0, 0, 0, 380, 811,
-	812, 813, 0, 381, 382, 383, 384, 814, 0, 0,
-	0, 385, 386, 387, 388, 389, 390, 391, 392, 0,
-	0, 394, 395, 396, 393, 397, 398, 0, 399, 0,
-	400, 401, 402, 403, 404, 405, 406, 0, 407, 408,
-	409, 0, 410, 411, 412, 0, 0, 0, 0, 0,
-	0, 0, 413, 414, 415, 416, 417, 0, 418, 420,
-	421, 815, 422, 816, 0, 425, 427, 419, 423, 0,
-	426, 424, 428, 429, 0, 430, 431, 432, 433, 0,
-	0, 434, 435, 436, 0, 437, 438, 440, 439, 0,
-	441, 442, 443, 0, 444, 445, 817, 446, 447, 448,
-	450, 452, 449, 451, 453, 454, 455, 456, 457, 818,
-	819, 458, 459, 0, 340, 0, 0, 0, 0, 0,
-	460, 461, 462, 820, 0, 0, 0, 463, 0, 465,
-	469, 466, 467, 468, 470, 0, 464, 471, 472, 0,
-	0, 473, 474, 475, 821, 822, 476, 477, 478, 479,
-	480, 481, 482, 483, 484, 0, 485, 486, 823, 0,
-	824, 487, 0, 488, 489, 490, 491, 492, 493, 494,
-	825, 826, 827, 595, 0, 495, 496, 497, 0, 498,
-	499, 500, 501, 502, 503, 504, 0, 0, 0, 505,
-	506, 507, 508, 0, 342, 341, 343, 0, 828, 509,
-	596, 510, 829, 830, 0, 831, 0, 511, 512, 515,
-	0, 832, 0, 514, 516, 517, 0, 518, 0, 0,
-	0, 519, 520, 521, 522, 523, 524, 525, 0, 526,
-	528, 527, 0, 530, 833, 529, 0, 531, 532, 0,
-	0, 533, 534, 535, 536, 537, 538, 541, 0, 0,
-	539, 540, 542, 543, 0, 544, 545, 547, 550, 546,
-	548, 549, 551, 552, 565, 566, 553, 554, 555, 556,
-	557, 558, 559, 560, 561, 562, 563, 564, 568, 0,
-	567, 0, 569, 570, 571, 572, 573, 581, 583, 584,
-	579, 580, 582, 585, 586, 588, 589, 576, 577, 578,
-	0, 587, 574, 0, 575, 344, 0, 590, 591, 592,
-	593, 0, 834, 594, 835, 597, 598, 0, 0, 599,
-	0, 600, 0, 1528, 602, 603, 604, 0, 0, 605,
-	606, 836, 0, 607, 0, 837, 608, 609, 601, 610,
-	611, 612, 613, 614, 615, 616, 617, 618, 619, 0,
-	620, 621, 838, 622, 623, 624, 839, 625, 626, 627,
-	840, 628, 841, 629, 630, 0, 631, 632, 633, 0,
-	634, 635, 636, 637, 638, 639, 640, 641, 642, 643,
-	842, 644, 645, 647, 646, 648, 649, 0, 650, 0,
-	651, 652, 653, 0, 0, 0, 0, 0, 654, 655,
-	657, 0, 658, 659, 660, 661, 662, 656, 663, 664,
-	665, 666, 667, 668, 669, 0, 671, 672, 670, 673,
-	674, 0, 675, 676, 677, 678, 679, 843, 680, 0,
-	681, 682, 690, 691, 692, 683, 684, 686, 693, 685,
-	694, 695, 696, 697, 699, 698, 0, 701, 702, 700,
-	703, 704, 705, 706, 0, 707, 844, 708, 687, 688,
-	709, 710, 711, 0, 712, 713, 714, 715, 716, 717,
-	718, 719, 720, 845, 0, 721, 0, 722, 723, 724,
-	725, 726, 727, 729, 689, 730, 731, 732, 737, 738,
-	846, 733, 734, 735, 736, 847, 740, 741, 742, 743,
-	0, 744, 745, 0, 739, 728, 0, 746, 747, 748,
-	749, 750, 751, 752, 753, 754, 755, 0, 756, 848,
-	849, 850, 851, 0, 768, 0, 757, 759, 760, 761,
-	762, 852, 763, 853, 0, 764, 765, 766, 767, 758,
-	769, 770, 0, 0, 771, 772, 773, 774, 776, 778,
-	779, 780, 775, 777, 781, 0, 782, 0, 0, 783,
-	784, 785, 854, 855, 856, 0, 787, 788, 786, 789,
-	790, 793, 791, 792, 857, 796, 513, 797, 798, 799,
-	794, 795, 337, 0, 0, 0, 800, 801, 858, 802,
-	803, 804, 0, 0, 0, 0, 0, 0, 0, 345,
-	346, 348, 347, 349, 350, 351, 352, 0, 353, 354,
-	0, 0, 0, 0, 0, 805, 0, 0, 0, 356,
-	0, 355, 0, 357, 358, 359, 0, 360, 361, 362,
-	363, 364, 365, 366, 367, 806, 807, 0, 368, 808,
-	369, 809, 0, 810, 370, 371, 372, 373, 374, 375,
-	376, 377, 378, 379, 0, 0, 0, 380, 811, 812,
-	813, 0, 381, 382, 383, 384, 814, 0, 0, 0,
-	385, 386, 387, 388, 389, 390, 391, 392, 0, 0,
-	394, 395, 396, 393, 397, 398, 0, 399, 0, 400,
-	401, 402, 403, 404, 405, 406, 0, 407, 408, 409,
-	0, 410, 411, 412, 0, 0, 0, 0, 0, 0,
-	0, 413, 414, 415, 416, 417, 0, 418, 420, 421,
-	815, 422, 816, 0, 425, 427, 419, 423, 0, 426,
-	424, 428, 429, 0, 430, 431, 432, 433, 0, 0,
-	434, 435, 436, 0, 437, 438, 440, 439, 0, 441,
-	442, 443, 0, 444, 445, 817, 446, 447, 448, 450,
-	452, 449, 451, 453, 454, 455, 456, 457, 818, 819,
-	458, 459, 0, 340, 0, 0, 0, 0, 0, 460,
-	461, 462, 820, 0, 0, 0, 463, 0, 465, 469,
-	466, 467, 468, 470, 0, 464, 471, 472, 0, 0,
-	473, 474, 475, 821, 822, 476, 477, 478, 479, 480,
-	481, 482, 483, 484, 0, 485, 486, 823, 0, 824,
-	487, 0, 488, 489, 490, 491, 492, 493, 494, 825,
-	826, 827, 595, 0, 495, 496, 497, 0, 498, 499,
-	500, 501, 502, 503, 504, 0, 0, 0, 505, 506,
-	507, 508, 0, 342, 341, 343, 0, 828, 509, 596,
-	510, 829, 830, 0, 831, 0, 511, 512, 515, 0,
-	832, 0, 514, 516, 517, 0, 518, 0, 0, 0,
-	519, 520, 521, 522, 523, 524, 525, 0, 526, 528,
-	527, 0, 530, 833, 529, 0, 531, 532, 0, 0,
-	533, 534, 535, 536, 537, 538, 541, 0, 0, 539,
-	540, 542, 543, 0, 544, 545, 547, 550, 546, 548,
-	549, 551, 552, 565, 566, 553, 554, 555, 556, 557,
-	558, 559, 560, 561, 562, 563, 564, 568, 0, 567,
-	0, 569, 570, 571, 572, 573, 581, 583, 584, 579,
-	580, 582, 585, 586, 588, 589, 576, 577, 578, 4926,
-	587, 574, 0, 575, 344, 0, 590, 591, 592, 593,
-	0, 834, 594, 835, 597, 598, 0, 0, 599, 0,
-	600, 0, 0, 602, 603, 604, 0, 0, 605, 606,
-	836, 0, 607, 0, 837, 608, 609, 601, 610, 611,
-	612, 613, 614, 615, 616, 617, 618, 619, 0, 620,
-	621, 838, 622, 623, 624, 839, 625, 626, 627, 840,
-	628, 841, 629, 630, 0, 631, 632, 633, 0, 634,
-	635, 636, 637, 638, 639, 640, 641, 642, 643, 842,
-	644, 645, 647, 646, 648, 649, 0, 650, 0, 651,
-	652, 653, 0, 0, 0, 0, 0, 654, 655, 657,
-	0, 658, 659, 660, 661, 662, 656, 663, 664, 665,
-	666, 667, 668, 669, 0, 671, 672, 670, 673, 674,
-	0, 675, 676, 677, 678, 679, 843, 680, 0, 681,
-	682, 690, 691, 692, 683, 684, 686, 693, 685, 694,
-	695, 696, 697, 699, 698, 0, 701, 702, 700, 703,
-	704, 705, 706, 0, 707, 844, 708, 687, 688, 709,
-	710, 711, 0, 712, 713, 714, 715, 716, 717, 718,
-	719, 720, 845, 0, 721, 0, 722, 723, 724, 725,
-	726, 727, 729, 689, 730, 731, 732, 737, 738, 846,
-	733, 734, 735, 736, 847, 740, 741, 742, 743, 0,
-	744, 745, 0, 739, 728, 0, 746, 747, 748, 749,
-	750, 751, 752, 753, 754, 755, 0, 756, 848, 849,
-	850, 851, 0, 768, 0, 757, 759, 760, 761, 762,
-	852, 763, 853, 0, 764, 765, 766, 767, 758, 769,
-	770, 0, 0, 771, 772, 773, 774, 776, 778, 779,
-	780, 775, 777, 781, 0, 782, 0, 0, 783, 784,
-	785, 854, 855, 856, 0, 787, 788, 786, 789, 790,
-	793, 791, 792, 857, 796, 513, 797, 798, 799, 794,
-	795, 4436, 0, 337, 0, 800, 801, 858, 802, 803,
-	804, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	345, 346, 348, 347, 349, 350, 351, 352, 0, 353,
-	354, 0, 0, 0, 0, 0, 805, 0, 0, 0,
-	356, 0, 355, 0, 357, 358, 359, 0, 360, 361,
-	362, 363, 364, 365, 366, 367, 806, 807, 0, 368,
-	808, 369, 809, 0, 810, 370, 371, 372, 373, 374,
-	375, 376, 377, 378, 379, 0, 0, 0, 380, 811,
-	812, 813, 0, 381, 382, 383, 384, 814, 0, 0,
-	0, 385, 386, 387, 388, 389, 390, 391, 392, 0,
-	0, 394, 395, 396, 393, 397, 398, 0, 399, 0,
-	400, 401, 402, 403, 404, 405, 406, 0, 407, 408,
-	409, 0, 410, 411, 412, 0, 0, 0, 0, 0,
-	0, 0, 413, 414, 415, 416, 417, 0, 418, 420,
-	421, 815, 422, 816, 0, 425, 427, 419, 423, 0,
-	426, 424, 428, 429, 0, 430, 431, 432, 433, 0,
-	0, 434, 435, 436, 0, 437, 438, 440, 439, 0,
-	441, 442, 443, 0, 444, 445, 817, 446, 447, 448,
-	450, 452, 449, 451, 453, 454, 455, 456, 457, 818,
-	819, 458, 459, 0, 340, 0, 0, 0, 0, 0,
-	460, 461, 462, 820, 0, 0, 0, 463, 0, 465,
-	469, 466, 467, 468, 470, 0, 464, 471, 472, 0,
-	0, 473, 474, 475, 821, 822, 476, 477, 478, 479,
-	480, 481, 482, 483, 484, 0, 485, 486, 823, 0,
-	824, 487, 0, 488, 489, 490, 491, 492, 493, 494,
-	4435, 826, 827, 595, 0, 495, 496, 497, 0, 498,
-	499, 500, 501, 502, 503, 504, 0, 0, 0, 505,
-	506, 507, 508, 0, 342, 341, 343, 0, 828, 509,
-	596, 510, 829, 830, 0, 831, 0, 511, 512, 515,
-	0, 832, 0, 514, 516, 517, 0, 518, 0, 0,
-	0, 519, 520, 521, 522, 523, 524, 525, 0, 526,
-	528, 527, 0, 530, 833, 529, 0, 531, 532, 0,
-	0, 533, 534, 535, 536, 537, 538, 541, 0, 0,
-	539, 540, 542, 543, 0, 544, 545, 547, 550, 546,
-	548, 549, 551, 552, 565, 566, 553, 554, 555, 556,
-	557, 558, 559, 560, 561, 562, 563, 564, 568, 0,
-	567, 0, 569, 570, 571, 572, 573, 581, 583, 584,
-	579, 580, 582, 585, 586, 588, 589, 576, 577, 578,
-	0, 587, 574, 0, 575, 344, 0, 590, 591, 592,
-	593, 0, 834, 594, 835, 597, 598, 0, 0, 599,
-	0, 600, 0, 0, 602, 603, 604, 0, 0, 605,
-	606, 836, 0, 607, 0, 837, 608, 609, 601, 610,
-	611, 612, 613, 614, 615, 616, 617, 618, 619, 0,
-	620, 621, 838, 622, 623, 624, 839, 625, 626, 627,
-	840, 628, 841, 629, 630, 0, 631, 632, 633, 0,
-	634, 635, 636, 637, 638, 639, 640, 641, 642, 643,
-	842, 644, 645, 647, 646, 648, 649, 0, 650, 0,
-	651, 652, 653, 0, 0, 0, 0, 0, 654, 655,
-	657, 0, 658, 659, 660, 661, 662, 656, 663, 664,
-	665, 666, 667, 668, 669, 0, 671, 672, 670, 673,
-	674, 0, 675, 676, 677, 678, 679, 843, 680, 0,
-	681, 682, 690, 691, 692, 683, 684, 686, 693, 685,
-	694, 695, 696, 697, 699, 698, 0, 701, 702, 700,
-	703, 704, 705, 706, 0, 707, 844, 708, 687, 688,
-	709, 710, 711, 0, 712, 713, 714, 715, 716, 717,
-	718, 719, 720, 845, 0, 721, 0, 722, 723, 724,
-	725, 726, 727, 729, 689, 730, 731, 732, 737, 738,
-	846, 733, 734, 735, 736, 847, 740, 741, 742, 743,
-	0, 744, 745, 0, 739, 728, 0, 746, 747, 748,
-	749, 750, 751, 752, 753, 754, 755, 0, 756, 848,
-	849, 850, 851, 0, 768, 0, 757, 759, 760, 761,
-	762, 852, 763, 853, 0, 764, 765, 766, 767, 758,
-	769, 770, 0, 0, 771, 772, 773, 774, 776, 778,
-	779, 780, 775, 777, 781, 0, 782, 0, 0, 783,
-	784, 785, 854, 855, 856, 0, 787, 788, 786, 789,
-	790, 793, 791, 792, 857, 796, 513, 797, 798, 799,
-	794, 795, 337, 0, 0, 0, 800, 801, 858, 802,
-	803, 804, 0, 0, 0, 0, 0, 0, 0, 345,
-	346, 348, 347, 349, 350, 351, 352, 0, 353, 354,
-	0, 0, 0, 0, 0, 805, 0, 0, 0, 356,
-	0, 355, 0, 357, 358, 359, 0, 360, 361, 362,
-	363, 364, 365, 366, 367, 806, 807, 0, 368, 808,
-	369, 809, 0, 810, 370, 371, 372, 373, 374, 375,
-	376, 377, 378, 379, 0, 0, 0, 380, 811, 812,
-	813, 4193, 381, 382, 383, 384, 814, 0, 0, 4187,
-	385, 386, 387, 388, 389, 390, 391, 392, 0, 0,
-	394, 395, 396, 393, 397, 398, 4189, 399, 0, 400,
-	401, 402, 403, 404, 405, 406, 0, 407, 408, 409,
-	0, 410, 411, 412, 0, 0, 0, 0, 0, 0,
-	0, 413, 414, 415, 416, 417, 0, 418, 420, 421,
-	815, 422, 816, 0, 425, 427, 419, 423, 0, 426,
-	424, 428, 429, 0, 430, 431, 432, 433, 0, 0,
-	434, 435, 436, 0, 437, 438, 440, 439, 0, 441,
-	442, 443, 0, 4197, 445, 817, 446, 447, 448, 450,
-	452, 449, 451, 453, 454, 455, 456, 457, 818, 819,
-	458, 459, 0, 0, 0, 0, 0, 0, 0, 460,
-	461, 462, 820, 0, 0, 0, 463, 0, 465, 469,
-	466, 467, 468, 470, 4196, 464, 471, 472, 0, 0,
-	473, 474, 475, 821, 822, 476, 477, 478, 479, 480,
-	481, 482, 483, 484, 0, 485, 486, 823, 0, 824,
-	487, 0, 488, 489, 490, 491, 492, 493, 494, 4186,
-	826, 827, 595, 0, 495, 496, 497, 0, 498, 499,
-	500, 501, 502, 503, 504, 0, 0, 0, 505, 506,
-	507, 508, 0, 0, 0, 0, 0, 828, 509, 596,
-	510, 829, 830, 0, 831, 0, 511, 512, 515, 0,
-	832, 0, 514, 516, 517, 0, 518, 0, 0, 0,
-	519, 520, 521, 522, 523, 524, 525, 0, 526, 528,
-	527, 0, 530, 833, 529, 0, 531, 532, 0, 0,
-	533, 534, 535, 536, 537, 538, 541, 0, 0, 539,
-	540, 542, 543, 0, 544, 545, 547, 550, 546, 548,
-	549, 551, 552, 565, 566, 553, 554, 555, 556, 557,
-	558, 559, 560, 561, 562, 563, 564, 568, 0, 567,
-	0, 569, 570, 571, 572, 573, 581, 583, 584, 579,
-	580, 582, 585, 586, 588, 589, 576, 577, 578, 0,
-	587, 574, 0, 575, 0, 0, 590, 591, 592, 593,
-	0, 834, 594, 835, 597, 598, 0, 0, 599, 0,
-	600, 0, 0, 602, 603, 604, 0, 0, 605, 606,
-	836, 0, 607, 0, 837, 608, 609, 601, 610, 611,
-	612, 613, 614, 615, 616, 617, 618, 619, 0, 620,
-	621, 838, 622, 623, 624, 839, 625, 626, 627, 840,
-	628, 841, 629, 630, 4195, 631, 632, 633, 0, 634,
-	635, 636, 637, 638, 639, 640, 641, 642, 643, 842,
-	644, 645, 647, 646, 648, 649, 0, 650, 0, 651,
-	652, 653, 0, 0, 0, 0, 0, 654, 655, 657,
-	0, 658, 659, 660, 661, 662, 656, 663, 664, 665,
-	666, 667, 668, 669, 0, 671, 672, 670, 673, 674,
-	0, 675, 676, 677, 678, 679, 843, 680, 0, 681,
-	682, 690, 691, 692, 683, 684, 686, 693, 685, 694,
-	695, 696, 697, 699, 698, 0, 701, 702, 700, 703,
-	704, 705, 706, 0, 707, 844, 708, 687, 688, 709,
-	710, 711, 0, 712, 713, 714, 715, 716, 717, 718,
-	719, 720, 845, 0, 721, 0, 722, 723, 724, 725,
-	726, 727, 729, 689, 730, 731, 732, 737, 738, 846,
-	733, 734, 735, 736, 847, 740, 741, 742, 743, 0,
-	744, 745, 0, 739, 728, 0, 746, 747, 748, 749,
-	750, 751, 752, 753, 754, 755, 0, 756, 848, 849,
-	850, 851, 0, 768, 0, 757, 759, 760, 761, 762,
-	852, 763, 853, 0, 764, 765, 766, 767, 758, 769,
-	770, 0, 4194, 771, 772, 773, 774, 776, 778, 779,
-	780, 775, 777, 781, 0, 782, 0, 0, 783, 784,
-	785, 854, 855, 856, 0, 787, 788, 786, 789, 790,
-	793, 791, 792, 857, 796, 513, 797, 798, 799, 794,
-	795, 2996, 0, 337, 0, 800, 801, 858, 802, 803,
-	804, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	345, 346, 348, 347, 349, 350, 351, 352, 0, 353,
-	354, 0, 0, 0, 0, 0, 805, 0, 0, 0,
-	356, 0, 355, 0, 357, 358, 359, 0, 360, 361,
-	362, 363, 364, 365, 366, 367, 806, 807, 0, 368,
-	808, 369, 809, 0, 810, 370, 371, 372, 373, 374,
-	375, 376, 377, 378, 379, 0, 0, 0, 380, 811,
-	812, 813, 0, 381, 382, 383, 384, 814, 0, 0,
-	0, 385, 386, 387, 388, 389, 390, 391, 392, 0,
-	0, 394, 395, 396, 393, 397, 398, 0, 399, 0,
-	400, 401, 402, 403, 404, 405, 406, 0, 407, 408,
-	409, 0, 410, 411, 412, 0, 0, 0, 0, 0,
-	0, 0, 413, 414, 415, 416, 417, 0, 418, 420,
-	421, 815, 422, 816, 0, 425, 427, 419, 423, 0,
-	426, 424, 428, 429, 0, 430, 431, 432, 433, 0,
-	0, 434, 435, 436, 0, 437, 438, 440, 439, 0,
-	441, 442, 443, 0, 444, 445, 817, 446, 447, 448,
-	450, 452, 449, 451, 453, 454, 455, 456, 457, 818,
-	819, 458, 459, 0, 340, 0, 0, 0, 0, 0,
-	460, 461, 462, 820, 0, 0, 0, 463, 0, 465,
-	469, 466, 467, 468, 470, 0, 464, 471, 472, 0,
-	0, 473, 474, 475, 821, 822, 476, 477, 478, 479,
-	480, 481, 482, 483, 484, 0, 485, 486, 823, 0,
-	824, 487, 0, 488, 489, 490, 491, 492, 493, 494,
-	825, 826, 827, 595, 0, 495, 496, 497, 0, 498,
-	499, 500, 501, 502, 503, 504, 0, 0, 0, 505,
-	506, 507, 508, 0, 342, 341, 343, 0, 828, 509,
-	596, 510, 829, 830, 0, 831, 0, 511, 512, 515,
-	0, 832, 0, 514, 516, 517, 0, 518, 0, 0,
-	0, 519, 520, 521, 522, 523, 524, 525, 0, 526,
-	528, 527, 0, 530, 833, 529, 0, 531, 532, 0,
-	0, 533, 534, 535, 536, 537, 538, 541, 0, 0,
-	539, 540, 542, 543, 0, 544, 545, 547, 550, 546,
-	548, 549, 551, 552, 565, 566, 553, 554, 555, 556,
-	557, 558, 559, 560, 561, 562, 563, 564, 568, 0,
-	567, 0, 569, 570, 571, 572, 573, 581, 583, 584,
-	579, 580, 582, 585, 586, 588, 589, 576, 577, 578,
-	0, 587, 574, 0, 575, 344, 0, 590, 591, 592,
-	593, 0, 834, 594, 835, 597, 598, 0, 0, 599,
-	0, 600, 0, 0, 602, 603, 604, 0, 0, 605,
-	606, 836, 0, 607, 0, 837, 608, 609, 601, 610,
-	611, 612, 613, 614, 615, 616, 617, 618, 619, 0,
-	620, 621, 838, 622, 623, 624, 839, 625, 626, 627,
-	840, 628, 841, 629, 630, 0, 631, 632, 633, 0,
-	634, 635, 636, 637, 638, 639, 640, 641, 642, 643,
-	842, 644, 645, 647, 646, 648, 649, 0, 650, 0,
-	651, 652, 653, 0, 0, 0, 0, 0, 654, 655,
-	657, 0, 658, 659, 660, 661, 662, 656, 663, 664,
-	665, 666, 667, 668, 669, 0, 671, 672, 670, 673,
-	674, 0, 675, 676, 677, 678, 679, 843, 680, 0,
-	681, 682, 690, 691, 692, 683, 684, 686, 693, 685,
-	694, 695, 696, 697, 699, 698, 0, 701, 702, 700,
-	703, 704, 705, 706, 0, 707, 844, 708, 687, 688,
-	709, 710, 711, 0, 712, 713, 714, 715, 716, 717,
-	718, 719, 720, 845, 0, 721, 0, 722, 723, 724,
-	725, 726, 727, 729, 689, 730, 731, 732, 737, 738,
-	846, 733, 734, 735, 736, 847, 740, 741, 742, 743,
-	0, 744, 745, 0, 739, 728, 0, 746, 747, 748,
-	749, 750, 751, 752, 753, 754, 755, 0, 756, 848,
-	849, 850, 851, 0, 768, 0, 757, 759, 760, 761,
-	762, 852, 763, 853, 0, 764, 765, 766, 767, 758,
-	769, 770, 0, 0, 771, 772, 773, 774, 776, 778,
-	779, 780, 775, 777, 781, 0, 782, 0, 0, 783,
-	784, 785, 854, 855, 856, 0, 787, 788, 786, 789,
-	790, 793, 791, 792, 857, 796, 513, 797, 798, 799,
-	794, 795, 2941, 0, 337, 0, 800, 801, 858, 802,
-	803, 804, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 345, 346, 348, 347, 349, 350, 351, 352, 0,
-	353, 354, 0, 0, 0, 0, 0, 805, 0, 0,
-	0, 356, 0, 355, 0, 357, 358, 359, 0, 360,
-	361, 362, 363, 364, 365, 366, 367, 806, 807, 0,
-	368, 808, 369, 809, 0, 810, 370, 371, 372, 373,
-	374, 375, 376, 377, 378, 379, 0, 0, 0, 380,
-	811, 812, 813, 0, 381, 382, 383, 384, 814, 0,
-	0, 0, 385, 386, 387, 388, 389, 390, 391, 392,
-	0, 0, 394, 395, 396, 393, 397, 398, 0, 399,
-	0, 400, 401, 402, 403, 404, 405, 406, 0, 407,
-	408, 409, 0, 410, 411, 412, 0, 0, 0, 0,
-	0, 0, 0, 413, 414, 415, 416, 417, 0, 418,
-	420, 421, 815, 422, 816, 0, 425, 427, 419, 423,
-	0, 426, 424, 428, 429, 0, 430, 431, 432, 433,
-	0, 0, 434, 435, 436, 0, 437, 438, 440, 439,
-	0, 441, 442, 443, 0, 444, 445, 817, 446, 447,
-	448, 450, 452, 449, 451, 453, 454, 455, 456, 457,
-	818, 819, 458, 459, 0, 340, 0, 0, 0, 0,
-	0, 460, 461, 462, 820, 0, 0, 0, 463, 0,
-	465, 469, 466, 467, 468, 470, 0, 464, 471, 472,
-	0, 0, 473, 474, 475, 821, 822, 476, 477, 478,
-	479, 480, 481, 482, 483, 484, 0, 485, 486, 823,
-	0, 824, 487, 0, 488, 489, 490, 491, 492, 493,
-	494, 2940, 826, 827, 595, 0, 495, 496, 497, 0,
-	498, 499, 500, 501, 502, 503, 504, 0, 0, 0,
-	505, 506, 507, 508, 0, 342, 341, 343, 0, 828,
-	509, 596, 510, 829, 830, 0, 831, 0, 511, 512,
-	515, 0, 832, 0, 514, 516, 517, 0, 518, 0,
-	0, 0, 519, 520, 521, 522, 523, 524, 525, 0,
-	526, 528, 527, 0, 530, 833, 529, 0, 531, 532,
-	0, 0, 533, 534, 535, 536, 537, 538, 541, 0,
-	0, 539, 540, 542, 543, 0, 544, 545, 547, 550,
-	546, 548, 549, 551, 552, 565, 566, 553, 554, 555,
-	556, 557, 558, 559, 560, 561, 562, 563, 564, 568,
-	0, 567, 0, 569, 570, 571, 572, 573, 581, 583,
-	584, 579, 580, 582, 585, 586, 588, 589, 576, 577,
-	578, 0, 587, 574, 0, 575, 344, 0, 590, 591,
-	592, 593, 0, 834, 594, 835, 597, 598, 0, 0,
-	599, 0, 600, 0, 0, 602, 603, 604, 0, 0,
-	605, 606, 836, 0, 607, 0, 837, 608, 609, 601,
-	610, 611, 612, 613, 614, 615, 616, 617, 618, 619,
-	0, 620, 621, 838, 622, 623, 624, 839, 625, 626,
-	627, 840, 628, 841, 629, 630, 0, 631, 632, 633,
-	0, 634, 635, 636, 637, 638, 639, 640, 641, 642,
-	643, 842, 644, 645, 647, 646, 648, 649, 0, 650,
-	0, 651, 652, 653, 0, 0, 0, 0, 0, 654,
-	655, 657, 0, 658, 659, 660, 661, 662, 656, 663,
-	664, 665, 666, 667, 668, 669, 0, 671, 672, 670,
-	673, 674, 0, 675, 676, 677, 678, 679, 843, 680,
-	0, 681, 682, 690, 691, 692, 683, 684, 686, 693,
-	685, 694, 695, 696, 697, 699, 698, 0, 701, 702,
-	700, 703, 704, 705, 706, 0, 707, 844, 708, 687,
-	688, 709, 710, 711, 0, 712, 713, 714, 715, 716,
-	717, 718, 719, 720, 845, 0, 721, 0, 722, 723,
-	724, 725, 726, 727, 729, 689, 730, 731, 732, 737,
-	738, 846, 733, 734, 735, 736, 847, 740, 741, 742,
-	743, 0, 744, 745, 0, 739, 728, 0, 746, 747,
-	748, 749, 750, 751, 752, 753, 754, 755, 0, 756,
-	848, 849, 850, 851, 0, 768, 0, 757, 759, 760,
-	761, 762, 852, 763, 853, 0, 764, 765, 766, 767,
-	758, 769, 770, 0, 0, 771, 772, 773, 774, 776,
-	778, 779, 780, 775, 777, 781, 0, 782, 0, 0,
-	783, 784, 785, 854, 855, 856, 0, 787, 788, 786,
-	789, 790, 793, 791, 792, 857, 796, 513, 797, 798,
-	799, 794, 795, 2925, 0, 337, 0, 800, 801, 858,
-	802, 803, 804, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 345, 346, 348, 347, 349, 350, 351, 352,
-	0, 353, 354, 0, 0, 0, 0, 0, 805, 0,
-	0, 0, 356, 0, 355, 0, 357, 358, 359, 0,
-	360, 361, 362, 363, 364, 365, 366, 367, 806, 807,
-	0, 368, 808, 369, 809, 0, 810, 370, 371, 372,
-	373, 374, 375, 376, 377, 378, 379, 0, 0, 0,
-	380, 811, 812, 813, 0, 381, 382, 383, 384, 814,
-	0, 0, 0, 385, 386, 387, 388, 389, 390, 391,
-	392, 0, 0, 394, 395, 396, 393, 397, 398, 0,
-	399, 0, 400, 401, 402, 403, 404, 405, 406, 0,
-	407, 408, 409, 0, 410, 411, 412, 0, 0, 0,
-	0, 0, 0, 0, 413, 414, 415, 416, 417, 0,
-	418, 420, 421, 815, 422, 816, 0, 425, 427, 419,
-	423, 0, 426, 424, 428, 429, 0, 430, 431, 432,
-	433, 0, 0, 434, 435, 436, 0, 437, 438, 440,
-	439, 0, 441, 442, 443, 0, 444, 445, 817, 446,
-	447, 448, 450, 452, 449, 451, 453, 454, 455, 456,
-	457, 818, 819, 458, 459, 0, 340, 0, 0, 0,
-	0, 0, 460, 461, 462, 820, 0, 0, 0, 463,
-	0, 465, 469, 466, 467, 468, 470, 0, 464, 471,
-	472, 0, 0, 473, 474, 475, 821, 822, 476, 477,
-	478, 479, 480, 481, 482, 483, 484, 0, 485, 486,
-	823, 0, 824, 487, 0, 488, 489, 490, 491, 492,
-	493, 494, 2927, 826, 827, 595, 0, 495, 496, 497,
-	0, 498, 499, 500, 501, 502, 503, 504, 0, 0,
-	0, 505, 506, 507, 508, 0, 342, 341, 343, 0,
-	828, 509, 596, 510, 829, 830, 0, 831, 0, 511,
-	512, 515, 0, 832, 0, 514, 516, 517, 0, 518,
-	0, 0, 0, 519, 520, 521, 522, 523, 524, 525,
-	0, 526, 528, 527, 0, 530, 833, 529, 0, 531,
-	532, 0, 0, 533, 534, 535, 536, 537, 538, 541,
-	0, 0, 539, 540, 542, 543, 0, 544, 545, 547,
-	550, 546, 548, 549, 551, 552, 565, 566, 553, 554,
-	555, 556, 557, 558, 559, 560, 561, 562, 563, 564,
-	568, 0, 567, 0, 569, 570, 571, 572, 573, 581,
-	583, 584, 579, 580, 582, 585, 586, 588, 589, 576,
-	577, 578, 0, 587, 574, 0, 575, 344, 0, 590,
-	591, 592, 593, 0, 834, 594, 835, 597, 598, 0,
-	0, 599, 0, 600, 0, 0, 602, 603, 604, 0,
-	0, 605, 606, 836, 0, 607, 0, 837, 608, 609,
-	601, 610, 611, 612, 613, 614, 615, 616, 617, 618,
-	619, 0, 620, 621, 838, 622, 623, 624, 839, 625,
-	626, 627, 840, 628, 841, 629, 630, 0, 631, 632,
-	633, 0, 634, 635, 636, 637, 638, 639, 640, 641,
-	642, 643, 842, 644, 645, 647, 646, 648, 649, 0,
-	650, 0, 651, 652, 653, 0, 0, 0, 0, 0,
-	654, 655, 657, 0, 658, 659, 660, 661, 662, 656,
-	663, 664, 665, 666, 667, 668, 669, 0, 671, 672,
-	670, 673, 674, 0, 675, 676, 677, 678, 679, 843,
-	680, 0, 681, 682, 690, 691, 692, 683, 684, 686,
-	693, 685, 694, 695, 696, 697, 699, 698, 0, 701,
-	702, 700, 703, 704, 705, 706, 0, 707, 844, 708,
-	687, 688, 709, 710, 711, 0, 712, 713, 714, 715,
-	716, 717, 718, 719, 720, 845, 0, 721, 0, 722,
-	723, 724, 725, 726, 727, 729, 689, 730, 731, 732,
-	737, 738, 846, 733, 734, 735, 736, 847, 740, 741,
-	742, 743, 0, 744, 745, 0, 739, 728, 0, 746,
-	747, 748, 749, 750, 751, 752, 753, 754, 755, 0,
-	756, 848, 849, 850, 851, 0, 768, 0, 757, 759,
-	760, 761, 762, 852, 763, 853, 0, 764, 765, 766,
-	767, 758, 769, 770, 0, 0, 771, 772, 773, 774,
-	776, 778, 779, 780, 775, 777, 781, 0, 782, 0,
-	0, 783, 784, 785, 854, 855, 856, 0, 787, 788,
-	786, 789, 790, 793, 791, 792, 857, 796, 513, 797,
-	798, 799, 794, 795, 2917, 0, 337, 0, 800, 801,
-	858, 802, 803, 804, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 345, 346, 348, 347, 349, 350, 351,
-	352, 0, 353, 354, 0, 0, 0, 0, 0, 805,
-	0, 0, 0, 356, 0, 355, 0, 357, 358, 359,
-	0, 360, 361, 362, 363, 364, 365, 366, 367, 806,
-	807, 0, 368, 808, 369, 809, 0, 810, 370, 371,
-	372, 373, 374, 375, 376, 377, 378, 379, 0, 0,
-	0, 380, 811, 812, 813, 0, 381, 382, 383, 384,
-	814, 0, 0, 0, 385, 386, 387, 388, 389, 390,
-	391, 392, 0, 0, 394, 395, 396, 393, 397, 398,
-	0, 399, 0, 400, 401, 402, 403, 404, 405, 406,
-	0, 407, 408, 409, 0, 410, 411, 412, 0, 0,
-	0, 0, 0, 0, 0, 413, 414, 415, 416, 417,
-	0, 418, 420, 421, 815, 422, 816, 0, 425, 427,
-	419, 423, 0, 426, 424, 428, 429, 0, 430, 431,
-	432, 433, 0, 0, 434, 435, 436, 0, 437, 438,
-	440, 439, 0, 441, 442, 443, 0, 444, 445, 817,
-	446, 447, 448, 450, 452, 449, 451, 453, 454, 455,
-	456, 457, 818, 819, 458, 459, 0, 340, 0, 0,
-	0, 0, 0, 460, 461, 462, 820, 0, 0, 0,
-	463, 0, 465, 469, 466, 467, 468, 470, 0, 464,
-	471, 472, 0, 0, 473, 474, 475, 821, 822, 476,
-	477, 478, 479, 480, 481, 482, 483, 484, 0, 485,
-	486, 823, 0, 824, 487, 0, 488, 489, 490, 491,
-	492, 493, 494, 825, 826, 827, 595, 0, 495, 496,
-	497, 0, 498, 499, 500, 501, 502, 503, 504, 0,
-	0, 0, 505, 506, 507, 508, 0, 342, 341, 343,
-	0, 828, 509, 596, 510, 829, 830, 0, 831, 0,
-	511, 512, 515, 0, 832, 0, 514, 516, 517, 0,
-	518, 0, 0, 0, 519, 520, 521, 522, 523, 524,
-	525, 0, 526, 528, 527, 0, 530, 833, 529, 0,
-	531, 532, 0, 0, 533, 534, 535, 536, 537, 538,
-	541, 0, 0, 539, 540, 542, 543, 0, 544, 545,
-	547, 550, 546, 548, 549, 551, 552, 565, 566, 553,
-	554, 555, 556, 557, 558, 559, 560, 561, 562, 563,
-	564, 568, 0, 567, 0, 569, 570, 571, 572, 573,
-	581, 583, 584, 579, 580, 582, 585, 586, 588, 589,
-	576, 577, 578, 0, 587, 574, 0, 575, 344, 0,
-	590, 591, 592, 593, 0, 834, 594, 835, 597, 598,
-	0, 0, 599, 0, 600, 0, 0, 602, 603, 604,
-	0, 0, 605, 606, 836, 0, 607, 0, 837, 608,
-	609, 601, 610, 611, 612, 613, 614, 615, 616, 617,
-	618, 619, 0, 620, 621, 838, 622, 623, 624, 839,
-	625, 626, 627, 840, 628, 841, 629, 630, 0, 631,
-	632, 633, 0, 634, 635, 636, 637, 638, 639, 640,
-	641, 642, 643, 842, 644, 645, 647, 646, 648, 649,
-	0, 650, 0, 651, 652, 653, 0, 0, 0, 0,
-	0, 654, 655, 657, 0, 658, 659, 660, 661, 662,
-	656, 663, 664, 665, 666, 667, 668, 669, 0, 671,
-	672, 670, 673, 674, 0, 675, 676, 677, 678, 679,
-	843, 680, 0, 681, 682, 690, 691, 692, 683, 684,
-	686, 693, 685, 694, 695, 696, 697, 699, 698, 0,
-	701, 702, 700, 703, 704, 705, 706, 0, 707, 844,
-	708, 687, 688, 709, 710, 711, 0, 712, 713, 714,
-	715, 716, 717, 718, 719, 720, 845, 0, 721, 0,
-	722, 723, 724, 725, 726, 727, 729, 689, 730, 731,
-	732, 737, 738, 846, 733, 734, 735, 736, 847, 740,
-	741, 742, 743, 0, 744, 745, 0, 739, 728, 0,
-	746, 747, 748, 749, 750, 751, 752, 753, 754, 755,
-	0, 756, 848, 849, 850, 851, 0, 768, 0, 757,
-	759, 760, 761, 762, 852, 763, 853, 0, 764, 765,
-	766, 767, 758, 769, 770, 0, 0, 771, 772, 773,
-	774, 776, 778, 779, 780, 775, 777, 781, 0, 782,
-	0, 0, 783, 784, 785, 854, 855, 856, 0, 787,
-	788, 786, 789, 790, 793, 791, 792, 857, 796, 513,
-	797, 798, 799, 794, 795, 2914, 0, 337, 0, 800,
-	801, 858, 802, 803, 804, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 345, 346, 348, 347, 349, 350,
-	351, 352, 0, 353, 354, 0, 0, 0, 0, 0,
-	805, 0, 0, 0, 356, 0, 355, 0, 357, 358,
-	359, 0, 360, 361, 362, 363, 364, 365, 366, 367,
-	806, 807, 0, 368, 808, 369, 809, 0, 810, 370,
-	371, 372, 373, 374, 375, 376, 377, 378, 379, 0,
-	0, 0, 380, 811, 812, 813, 0, 381, 382, 383,
-	384, 814, 0, 0, 0, 385, 386, 387, 388, 389,
-	390, 391, 392, 0, 0, 394, 395, 396, 393, 397,
-	398, 0, 399, 0, 400, 401, 402, 403, 404, 405,
-	406, 0, 407, 408, 409, 0, 410, 411, 412, 0,
-	0, 0, 0, 0, 0, 0, 413, 414, 415, 416,
-	417, 0, 418, 420, 421, 815, 422, 816, 0, 425,
-	427, 419, 423, 0, 426, 424, 428, 429, 0, 430,
-	431, 432, 433, 0, 0, 434, 435, 436, 0, 437,
-	438, 440, 439, 0, 441, 442, 443, 0, 444, 445,
-	817, 446, 447, 448, 450, 452, 449, 451, 453, 454,
-	455, 456, 457, 818, 819, 458, 459, 0, 340, 0,
-	0, 0, 0, 0, 460, 461, 462, 820, 0, 0,
-	0, 463, 0, 465, 469, 466, 467, 468, 470, 0,
-	464, 471, 472, 0, 0, 473, 474, 475, 821, 822,
-	476, 477, 478, 479, 480, 481, 482, 483, 484, 0,
-	485, 486, 823, 0, 824, 487, 0, 488, 489, 490,
-	491, 492, 493, 494, 825, 826, 827, 595, 0, 495,
-	496, 497, 0, 498, 499, 500, 501, 502, 503, 504,
-	0, 0, 0, 505, 506, 507, 508, 0, 342, 341,
-	343, 0, 828, 509, 596, 510, 829, 830, 0, 831,
-	0, 511, 512, 515, 0, 832, 0, 514, 516, 517,
-	0, 518, 0, 0, 0, 519, 520, 521, 522, 523,
-	524, 525, 0, 526, 528, 527, 0, 530, 833, 529,
-	0, 531, 532, 0, 0, 533, 534, 535, 536, 537,
-	538, 541, 0, 0, 539, 540, 542, 543, 0, 544,
-	545, 547, 550, 546, 548, 549, 551, 552, 565, 566,
-	553, 554, 555, 556, 557, 558, 559, 560, 561, 562,
-	563, 564, 568, 0, 567, 0, 569, 570, 571, 572,
-	573, 581, 583, 584, 579, 580, 582, 585, 586, 588,
-	589, 576, 577, 578, 0, 587, 574, 0, 575, 344,
-	0, 590, 591, 592, 593, 0, 834, 594, 835, 597,
-	598, 0, 0, 599, 0, 600, 0, 0, 602, 603,
-	604, 0, 0, 605, 606, 836, 0, 607, 0, 837,
-	608, 609, 601, 610, 611, 612, 613, 614, 615, 616,
-	617, 618, 619, 0, 620, 621, 838, 622, 623, 624,
-	839, 625, 626, 627, 840, 628, 841, 629, 630, 0,
-	631, 632, 633, 0, 634, 635, 636, 637, 638, 639,
-	640, 641, 642, 643, 842, 644, 645, 647, 646, 648,
-	649, 0, 650, 0, 651, 652, 653, 0, 0, 0,
-	0, 0, 654, 655, 657, 0, 658, 659, 660, 661,
-	662, 656, 663, 664, 665, 666, 667, 668, 669, 0,
-	671, 672, 670, 673, 674, 0, 675, 676, 677, 678,
-	679, 843, 680, 0, 681, 682, 690, 691, 692, 683,
-	684, 686, 693, 685, 694, 695, 696, 697, 699, 698,
-	0, 701, 702, 700, 703, 704, 705, 706, 0, 707,
-	844, 708, 687, 688, 709, 710, 711, 0, 712, 713,
-	714, 715, 716, 717, 718, 719, 720, 845, 0, 721,
-	0, 722, 723, 724, 725, 726, 727, 729, 689, 730,
-	731, 732, 737, 738, 846, 733, 734, 735, 736, 847,
-	740, 741, 742, 743, 0, 744, 745, 0, 739, 728,
-	0, 746, 747, 748, 749, 750, 751, 752, 753, 754,
-	755, 0, 756, 848, 849, 850, 851, 0, 768, 0,
-	757, 759, 760, 761, 762, 852, 763, 853, 0, 764,
-	765, 766, 767, 758, 769, 770, 0, 0, 771, 772,
-	773, 774, 776, 778, 779, 780, 775, 777, 781, 0,
-	782, 0, 0, 783, 784, 785, 854, 855, 856, 0,
-	787, 788, 786, 789, 790, 793, 791, 792, 857, 796,
-	513, 797, 798, 799, 794, 795, 337, 0, 0, 0,
-	800, 801, 858, 802, 803, 804, 0, 0, 0, 0,
-	0, 0, 0, 345, 346, 348, 347, 349, 350, 351,
-	352, 0, 353, 354, 0, 0, 0, 0, 0, 805,
-	0, 0, 0, 356, 0, 355, 0, 357, 358, 359,
-	0, 360, 361, 362, 363, 364, 365, 366, 367, 806,
-	807, 0, 368, 808, 369, 809, 0, 810, 370, 371,
-	372, 373, 374, 375, 376, 377, 378, 379, 0, 0,
-	0, 380, 811, 812, 813, 0, 381, 382, 383, 384,
-	814, 0, 0, 0, 385, 386, 387, 388, 389, 390,
-	391, 392, 0, 0, 394, 395, 396, 393, 397, 398,
-	0, 399, 0, 400, 401, 402, 403, 404, 405, 406,
-	0, 407, 408, 409, 0, 410, 411, 412, 0, 0,
-	0, 0, 0, 0, 0, 413, 414, 415, 416, 417,
-	0, 418, 420, 421, 815, 422, 816, 0, 425, 427,
-	419, 423, 0, 426, 424, 428, 429, 0, 430, 431,
-	432, 433, 0, 0, 434, 435, 436, 0, 437, 438,
-	440, 439, 0, 441, 442, 443, 0, 444, 445, 817,
-	446, 447, 448, 450, 452, 449, 451, 453, 454, 455,
-	456, 457, 818, 819, 458, 459, 0, 340, 0, 0,
-	0, 0, 0, 460, 461, 462, 820, 0, 0, 0,
-	463, 0, 465, 469, 466, 467, 468, 470, 0, 464,
-	471, 472, 0, 0, 473, 474, 475, 821, 822, 476,
-	477, 478, 479, 480, 481, 482, 483, 484, 0, 485,
-	486, 823, 0, 824, 487, 0, 488, 489, 490, 491,
-	492, 493, 494, 2884, 826, 827, 595, 0, 495, 496,
-	497, 0, 498, 499, 500, 501, 502, 503, 504, 0,
-	0, 0, 505, 506, 507, 508, 0, 342, 341, 343,
-	0, 828, 509, 596, 510, 829, 830, 0, 831, 0,
-	511, 512, 515, 0, 832, 0, 514, 516, 517, 0,
-	518, 0, 0, 0, 519, 520, 521, 522, 523, 524,
-	525, 0, 526, 528, 527, 0, 530, 833, 529, 0,
-	531, 532, 0, 0, 533, 534, 535, 536, 537, 538,
-	541, 0, 0, 539, 540, 542, 543, 0, 544, 545,
-	547, 550, 546, 548, 549, 551, 552, 565, 566, 553,
-	554, 555, 556, 557, 558, 559, 560, 561, 562, 563,
-	564, 568, 0, 567, 0, 569, 570, 571, 572, 573,
-	581, 583, 584, 579, 580, 582, 585, 586, 588, 589,
-	576, 577, 578, 0, 587, 574, 0, 575, 344, 0,
-	590, 591, 592, 593, 0, 834, 594, 835, 597, 598,
-	0, 0, 599, 0, 600, 0, 1528, 602, 603, 604,
-	0, 0, 605, 606, 836, 0, 607, 0, 837, 608,
-	609, 601, 610, 611, 612, 613, 614, 615, 616, 617,
-	618, 619, 0, 620, 621, 838, 622, 623, 624, 839,
-	625, 626, 627, 840, 628, 841, 629, 630, 0, 631,
-	632, 633, 0, 634, 635, 636, 637, 638, 639, 640,
-	641, 642, 643, 842, 644, 645, 647, 646, 648, 649,
-	0, 650, 0, 651, 652, 653, 0, 0, 0, 0,
-	0, 654, 655, 657, 0, 658, 659, 660, 661, 662,
-	656, 663, 664, 665, 666, 667, 668, 669, 0, 671,
-	672, 670, 673, 674, 0, 675, 676, 677, 678, 679,
-	843, 680, 0, 681, 682, 690, 691, 692, 683, 684,
-	686, 693, 685, 694, 695, 696, 697, 699, 698, 0,
-	701, 702, 700, 703, 704, 705, 706, 0, 707, 844,
-	708, 687, 688, 709, 710, 711, 0, 712, 713, 714,
-	715, 716, 717, 718, 719, 720, 845, 0, 721, 0,
-	722, 723, 724, 725, 726, 727, 729, 689, 730, 731,
-	732, 737, 738, 846, 733, 734, 735, 736, 847, 740,
-	741, 742, 743, 0, 744, 745, 0, 739, 728, 0,
-	746, 747, 748, 749, 750, 751, 752, 753, 754, 755,
-	0, 756, 848, 849, 850, 851, 0, 768, 0, 757,
-	759, 760, 761, 762, 852, 763, 853, 0, 764, 765,
-	766, 767, 758, 769, 770, 0, 0, 771, 772, 773,
-	774, 776, 778, 779, 780, 775, 777, 781, 0, 782,
-	0, 0, 783, 784, 785, 854, 855, 856, 0, 787,
-	788, 786, 789, 790, 793, 791, 792, 857, 796, 513,
-	797, 798, 799, 794, 795, 2085, 0, 337, 0, 800,
-	801, 858, 802, 803, 804, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 345, 346, 348, 347, 349, 350,
-	351, 352, 0, 353, 354, 0, 0, 0, 0, 0,
-	805, 0, 0, 0, 356, 0, 355, 0, 357, 358,
-	359, 0, 360, 361, 362, 363, 364, 365, 366, 367,
-	806, 807, 0, 368, 808, 369, 809, 0, 810, 370,
-	371, 372, 373, 374, 375, 376, 377, 378, 379, 0,
-	0, 0, 380, 811, 812, 813, 0, 381, 382, 383,
-	384, 814, 0, 0, 0, 385, 386, 387, 388, 389,
-	390, 391, 392, 0, 0, 394, 395, 396, 393, 397,
-	398, 0, 399, 0, 400, 401, 402, 403, 404, 405,
-	406, 0, 407, 408, 409, 0, 410, 411, 412, 0,
-	0, 0, 0, 0, 0, 0, 413, 414, 415, 416,
-	417, 0, 418, 420, 421, 815, 422, 816, 0, 425,
-	427, 419, 423, 0, 426, 424, 428, 429, 0, 430,
-	431, 432, 433, 0, 0, 434, 435, 436, 0, 437,
-	438, 440, 439, 0, 441, 442, 443, 0, 444, 445,
-	817, 446, 447, 448, 450, 452, 449, 451, 453, 454,
-	455, 456, 457, 818, 819, 458, 459, 0, 340, 0,
-	0, 0, 0, 0, 460, 461, 462, 820, 0, 0,
-	0, 463, 0, 465, 469, 466, 467, 468, 470, 0,
-	464, 471, 472, 0, 0, 473, 474, 475, 821, 822,
-	476, 477, 478, 479, 480, 481, 482, 483, 484, 0,
-	485, 486, 823, 0, 824, 487, 0, 488, 489, 490,
-	491, 492, 493, 494, 2084, 826, 827, 595, 0, 495,
-	496, 497, 0, 498, 499, 500, 501, 502, 503, 504,
-	0, 0, 0, 505, 506, 507, 508, 0, 342, 341,
-	343, 0, 828, 509, 596, 510, 829, 830, 0, 831,
-	0, 511, 512, 515, 0, 832, 0, 514, 516, 517,
-	0, 518, 0, 0, 0, 519, 520, 521, 522, 523,
-	524, 525, 0, 526, 528, 527, 0, 530, 833, 529,
-	0, 531, 532, 0, 0, 533, 534, 535, 536, 537,
-	538, 541, 0, 0, 539, 540, 542, 543, 0, 544,
-	545, 547, 550, 546, 548, 549, 551, 552, 565, 566,
-	553, 554, 555, 556, 557, 558, 559, 560, 561, 562,
-	563, 564, 568, 0, 567, 0, 569, 570, 571, 572,
-	573, 581, 583, 584, 579, 580, 582, 585, 586, 588,
-	589, 576, 577, 578, 0, 587, 574, 0, 575, 344,
-	0, 590, 591, 592, 593, 0, 834, 594, 835, 597,
-	598, 0, 0, 599, 0, 600, 0, 0, 602, 603,
-	604, 0, 0, 605, 606, 836, 0, 607, 0, 837,
-	608, 609, 601, 610, 611, 612, 613, 614, 615, 616,
-	617, 618, 619, 0, 620, 621, 838, 622, 623, 624,
-	839, 625, 626, 627, 840, 628, 841, 629, 630, 0,
-	631, 632, 633, 0, 634, 635, 636, 637, 638, 639,
-	640, 641, 642, 643, 842, 644, 645, 647, 646, 648,
-	649, 0, 650, 0, 651, 652, 653, 0, 0, 0,
-	0, 0, 654, 655, 657, 0, 658, 659, 660, 661,
-	662, 656, 663, 664, 665, 666, 667, 668, 669, 0,
-	671, 672, 670, 673, 674, 0, 675, 676, 677, 678,
-	679, 843, 680, 0, 681, 682, 690, 691, 692, 683,
-	684, 686, 693, 685, 694, 695, 696, 697, 699, 698,
-	0, 701, 702, 700, 703, 704, 705, 706, 0, 707,
-	844, 708, 687, 688, 709, 710, 711, 0, 712, 713,
-	714, 715, 716, 717, 718, 719, 720, 845, 0, 721,
-	0, 722, 723, 724, 725, 726, 727, 729, 689, 730,
-	731, 732, 737, 738, 846, 733, 734, 735, 736, 847,
-	740, 741, 742, 743, 0, 744, 745, 0, 739, 728,
-	0, 746, 747, 748, 749, 750, 751, 752, 753, 754,
-	755, 0, 756, 848, 849, 850, 851, 0, 768, 0,
-	757, 759, 760, 761, 762, 852, 763, 853, 0, 764,
-	765, 766, 767, 758, 769, 770, 0, 0, 771, 772,
-	773, 774, 776, 778, 779, 780, 775, 777, 781, 0,
-	782, 0, 0, 783, 784, 785, 854, 855, 856, 0,
-	787, 788, 786, 789, 790, 793, 791, 792, 857, 796,
-	513, 797, 798, 799, 794, 795, 1980, 0, 337, 0,
-	800, 801, 858, 802, 803, 804, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 345, 346, 348, 347, 349,
-	350, 351, 352, 0, 353, 354, 0, 0, 0, 0,
-	0, 805, 0, 0, 0, 356, 0, 355, 0, 357,
-	358, 359, 0, 360, 361, 362, 363, 364, 365, 366,
-	367, 806, 807, 0, 368, 808, 369, 809, 0, 810,
-	370, 371, 372, 373, 374, 375, 376, 377, 378, 379,
-	0, 0, 0, 380, 811, 812, 813, 0, 381, 382,
-	383, 384, 814, 0, 0, 0, 385, 386, 387, 388,
-	389, 390, 391, 392, 0, 0, 394, 395, 396, 393,
-	397, 398, 0, 399, 0, 400, 401, 402, 403, 404,
-	405, 406, 0, 407, 408, 409, 0, 410, 411, 412,
-	0, 0, 0, 0, 0, 0, 0, 413, 414, 415,
-	416, 417, 0, 418, 420, 421, 815, 422, 816, 0,
-	425, 427, 419, 423, 0, 426, 424, 428, 429, 0,
-	430, 431, 432, 433, 0, 0, 434, 435, 436, 0,
-	437, 438, 440, 439, 0, 441, 442, 443, 0, 444,
-	445, 817, 446, 447, 448, 450, 452, 449, 451, 453,
-	454, 455, 456, 457, 818, 819, 458, 459, 0, 340,
-	0, 0, 0, 0, 0, 460, 461, 462, 820, 0,
-	0, 0, 463, 0, 465, 469, 466, 467, 468, 470,
-	0, 464, 471, 472, 0, 0, 473, 474, 475, 821,
-	822, 476, 477, 478, 479, 480, 481, 482, 483, 484,
-	0, 485, 486, 823, 0, 824, 487, 0, 488, 489,
-	490, 491, 492, 493, 494, 825, 826, 827, 595, 0,
-	495, 496, 497, 0, 498, 499, 500, 501, 502, 503,
-	504, 0, 0, 0, 505, 506, 507, 508, 0, 342,
-	341, 343, 0, 828, 509, 596, 510, 829, 830, 0,
-	831, 0, 511, 512, 515, 0, 832, 0, 514, 516,
-	517, 0, 518, 0, 0, 0, 519, 520, 521, 522,
-	523, 524, 525, 0, 526, 528, 527, 0, 530, 833,
-	529, 0, 531, 532, 0, 0, 533, 534, 535, 536,
-	537, 538, 541, 0, 0, 539, 540, 542, 543, 0,
-	544, 545, 547, 550, 546, 548, 549, 551, 552, 565,
-	566, 553, 554, 555, 556, 557, 558, 559, 560, 561,
-	562, 563, 564, 568, 0, 567, 0, 569, 570, 571,
-	572, 573, 581, 583, 584, 579, 580, 582, 585, 586,
-	588, 589, 576, 577, 578, 0, 587, 574, 0, 575,
-	344, 0, 590, 591, 592, 593, 0, 834, 594, 835,
-	597, 598, 0, 0, 599, 0, 600, 0, 0, 602,
-	603, 604, 0, 0, 605, 606, 836, 0, 607, 0,
-	837, 608, 609, 601, 610, 611, 612, 613, 614, 615,
-	616, 617, 618, 619, 0, 620, 621, 838, 622, 623,
-	624, 839, 625, 626, 627, 840, 628, 841, 629, 630,
-	0, 631, 632, 633, 0, 634, 635, 636, 637, 638,
-	639, 640, 641, 642, 643, 842, 644, 645, 647, 646,
-	648, 649, 0, 650, 0, 651, 652, 653, 0, 0,
-	0, 0, 0, 654, 655, 657, 0, 658, 659, 660,
-	661, 662, 656, 663, 664, 665, 666, 667, 668, 669,
-	0, 671, 672, 670, 673, 674, 0, 675, 676, 677,
-	678, 679, 843, 680, 0, 681, 682, 690, 691, 692,
-	683, 684, 686, 693, 685, 694, 695, 696, 697, 699,
-	698, 0, 701, 702, 700, 703, 704, 705, 706, 0,
-	707, 844, 708, 687, 688, 709, 710, 711, 0, 712,
-	713, 714, 715, 716, 717, 718, 719, 720, 845, 0,
-	721, 0, 722, 723, 724, 725, 726, 727, 729, 689,
-	730, 731, 732, 737, 738, 846, 733, 734, 735, 736,
-	847, 740, 741, 742, 743, 0, 744, 745, 0, 739,
-	728, 0, 746, 747, 748, 749, 750, 751, 752, 753,
-	754, 755, 0, 756, 848, 849, 850, 851, 0, 768,
-	0, 757, 759, 760, 761, 762, 852, 763, 853, 0,
-	764, 765, 766, 767, 758, 769, 770, 0, 0, 771,
-	772, 773, 774, 776, 778, 779, 780, 775, 777, 781,
-	0, 782, 0, 0, 783, 784, 785, 854, 855, 856,
-	0, 787, 788, 786, 789, 790, 793, 791, 792, 857,
-	796, 513, 797, 798, 799, 794, 795, 1973, 0, 337,
-	0, 800, 801, 858, 802, 803, 804, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 345, 346, 348, 347,
-	349, 350, 351, 352, 0, 353, 354, 0, 0, 0,
-	0, 0, 805, 0, 0, 0, 356, 0, 355, 0,
-	357, 358, 359, 0, 360, 361, 362, 363, 364, 365,
-	366, 367, 806, 807, 0, 368, 808, 369, 809, 0,
-	810, 370, 371, 372, 373, 374, 375, 376, 377, 378,
-	379, 0, 0, 0, 380, 811, 812, 813, 0, 381,
-	382, 383, 384, 814, 0, 0, 0, 385, 386, 387,
-	388, 389, 390, 391, 392, 0, 0, 394, 395, 396,
-	393, 397, 398, 0, 399, 0, 400, 401, 402, 403,
-	404, 405, 406, 0, 407, 408, 409, 0, 410, 411,
-	412, 0, 0, 0, 0, 0, 0, 0, 413, 414,
-	415, 416, 417, 0, 418, 420, 421, 815, 422, 816,
-	0, 425, 427, 419, 423, 0, 426, 424, 428, 429,
-	0, 430, 431, 432, 433, 0, 0, 434, 435, 436,
-	0, 437, 438, 440, 439, 0, 441, 442, 443, 0,
-	444, 445, 817, 446, 447, 448, 450, 452, 449, 451,
-	453, 454, 455, 456, 457, 818, 819, 458, 459, 0,
-	340, 0, 0, 0, 0, 0, 460, 461, 462, 820,
-	0, 0, 0, 463, 0, 465, 469, 466, 467, 468,
-	470, 0, 464, 471, 472, 0, 0, 473, 474, 475,
-	821, 822, 476, 477, 478, 479, 480, 481, 482, 483,
-	484, 0, 485, 486, 823, 0, 824, 487, 0, 488,
-	489, 490, 491, 492, 493, 494, 1975, 826, 827, 595,
-	0, 495, 496, 497, 0, 498, 499, 500, 501, 502,
-	503, 504, 0, 0, 0, 505, 506, 507, 508, 0,
-	342, 341, 343, 0, 828, 509, 596, 510, 829, 830,
-	0, 831, 0, 511, 512, 515, 0, 832, 0, 514,
-	516, 517, 0, 518, 0, 0, 0, 519, 520, 521,
-	522, 523, 524, 525, 0, 526, 528, 527, 0, 530,
-	833, 529, 0, 531, 532, 0, 0, 533, 534, 535,
-	536, 537, 538, 541, 0, 0, 539, 540, 542, 543,
-	0, 544, 545, 547, 550, 546, 548, 549, 551, 552,
-	565, 566, 553, 554, 555, 556, 557, 558, 559, 560,
-	561, 562, 563, 564, 568, 0, 567, 0, 569, 570,
-	571, 572, 573, 581, 583, 584, 579, 580, 582, 585,
-	586, 588, 589, 576, 577, 578, 0, 587, 574, 0,
-	575, 344, 0, 590, 591, 592, 593, 0, 834, 594,
-	835, 597, 598, 0, 0, 599, 0, 600, 0, 0,
-	602, 603, 604, 0, 0, 605, 606, 836, 0, 607,
-	0, 837, 608, 609, 601, 610, 611, 612, 613, 614,
-	615, 616, 617, 618, 619, 0, 620, 621, 838, 622,
-	623, 624, 839, 625, 626, 627, 840, 628, 841, 629,
-	630, 0, 631, 632, 633, 0, 634, 635, 636, 637,
-	638, 639, 640, 641, 642, 643, 842, 644, 645, 647,
-	646, 648, 649, 0, 650, 0, 651, 652, 653, 0,
-	0, 0, 0, 0, 654, 655, 657, 0, 658, 659,
-	660, 661, 662, 656, 663, 664, 665, 666, 667, 668,
-	669, 0, 671, 672, 670, 673, 674, 0, 675, 676,
-	677, 678, 679, 843, 680, 0, 681, 682, 690, 691,
-	692, 683, 684, 686, 693, 685, 694, 695, 696, 697,
-	699, 698, 0, 701, 702, 700, 703, 704, 705, 706,
-	0, 707, 844, 708, 687, 688, 709, 710, 711, 0,
-	712, 713, 714, 715, 716, 717, 718, 719, 720, 845,
-	0, 721, 0, 722, 723, 724, 725, 726, 727, 729,
-	689, 730, 731, 732, 737, 738, 846, 733, 734, 735,
-	736, 847, 740, 741, 742, 743, 0, 744, 745, 0,
-	739, 728, 0, 746, 747, 748, 749, 750, 751, 752,
-	753, 754, 755, 0, 756, 848, 849, 850, 851, 0,
-	768, 0, 757, 759, 760, 761, 762, 852, 763, 853,
-	0, 764, 765, 766, 767, 758, 769, 770, 0, 0,
-	771, 772, 773, 774, 776, 778, 779, 780, 775, 777,
-	781, 0, 782, 0, 0, 783, 784, 785, 854, 855,
-	856, 0, 787, 788, 786, 789, 790, 793, 791, 792,
-	857, 796, 513, 797, 798, 799, 794, 795, 1963, 0,
-	337, 0, 800, 801, 858, 802, 803, 804, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 345, 346, 348,
-	347, 349, 350, 351, 352, 0, 353, 354, 0, 0,
-	0, 0, 0, 805, 0, 0, 0, 356, 0, 355,
-	0, 357, 358, 359, 0, 360, 361, 362, 363, 364,
-	365, 366, 367, 806, 807, 0, 368, 808, 369, 809,
-	0, 810, 370, 371, 372, 373, 374, 375, 376, 377,
-	378, 379, 0, 0, 0, 380, 811, 812, 813, 0,
-	381, 382, 383, 384, 814, 0, 0, 0, 385, 386,
-	387, 388, 389, 390, 391, 392, 0, 0, 394, 395,
-	396, 393, 397, 398, 0, 399, 0, 400, 401, 402,
-	403, 404, 405, 406, 0, 407, 408, 409, 0, 410,
-	411, 412, 0, 0, 0, 0, 0, 0, 0, 413,
-	414, 415, 416, 417, 0, 418, 420, 421, 815, 422,
-	816, 0, 425, 427, 419, 423, 0, 426, 424, 428,
-	429, 0, 430, 431, 432, 433, 0, 0, 434, 435,
-	436, 0, 437, 438, 440, 439, 0, 441, 442, 443,
-	0, 444, 445, 817, 446, 447, 448, 450, 452, 449,
-	451, 453, 454, 455, 456, 457, 818, 819, 458, 459,
-	0, 340, 0, 0, 0, 0, 0, 460, 461, 462,
-	820, 0, 0, 0, 463, 0, 465, 469, 466, 467,
-	468, 470, 0, 464, 471, 472, 0, 0, 473, 474,
-	475, 821, 822, 476, 477, 478, 479, 480, 481, 482,
-	483, 484, 0, 485, 486, 823, 0, 824, 487, 0,
-	488, 489, 490, 491, 492, 493, 494, 825, 826, 827,
-	595, 0, 495, 496, 497, 0, 498, 499, 500, 501,
-	502, 503, 504, 0, 0, 0, 505, 506, 507, 508,
-	0, 342, 341, 343, 0, 828, 509, 596, 510, 829,
-	830, 0, 831, 0, 511, 512, 515, 0, 832, 0,
-	514, 516, 517, 0, 518, 0, 0, 0, 519, 520,
-	521, 522, 523, 524, 525, 0, 526, 528, 527, 0,
-	530, 833, 529, 0, 531, 532, 0, 0, 533, 534,
-	535, 536, 537, 538, 541, 0, 0, 539, 540, 542,
-	543, 0, 544, 545, 547, 550, 546, 548, 549, 551,
-	552, 565, 566, 553, 554, 555, 556, 557, 558, 559,
-	560, 561, 562, 563, 564, 568, 0, 567, 0, 569,
-	570, 571, 572, 573, 581, 583, 584, 579, 580, 582,
-	585, 586, 588, 589, 576, 577, 578, 0, 587, 574,
-	0, 575, 344, 0, 590, 591, 592, 593, 0, 834,
-	594, 835, 597, 598, 0, 0, 599, 0, 600, 0,
-	0, 602, 603, 604, 0, 0, 605, 606, 836, 0,
-	607, 0, 837, 608, 609, 601, 610, 611, 612, 613,
-	614, 615, 616, 617, 618, 619, 0, 620, 621, 838,
-	622, 623, 624, 839, 625, 626, 627, 840, 628, 841,
-	629, 630, 0, 631, 632, 633, 0, 634, 635, 636,
-	637, 638, 639, 640, 641, 642, 643, 842, 644, 645,
-	647, 646, 648, 649, 0, 650, 0, 651, 652, 653,
-	0, 0, 0, 0, 0, 654, 655, 657, 0, 658,
-	659, 660, 661, 662, 656, 663, 664, 665, 666, 667,
-	668, 669, 0, 671, 672, 670, 673, 674, 0, 675,
-	676, 677, 678, 679, 843, 680, 0, 681, 682, 690,
-	691, 692, 683, 684, 686, 693, 685, 694, 695, 696,
-	697, 699, 698, 0, 701, 702, 700, 703, 704, 705,
-	706, 0, 707, 844, 708, 687, 688, 709, 710, 711,
-	0, 712, 713, 714, 715, 716, 717, 718, 719, 720,
-	845, 0, 721, 0, 722, 723, 724, 725, 726, 727,
-	729, 689, 730, 731, 732, 737, 738, 846, 733, 734,
-	735, 736, 847, 740, 741, 742, 743, 0, 744, 745,
-	0, 739, 728, 0, 746, 747, 748, 749, 750, 751,
-	752, 753, 754, 755, 0, 756, 848, 849, 850, 851,
-	0, 768, 0, 757, 759, 760, 761, 762, 852, 763,
-	853, 0, 764, 765, 766, 767, 758, 769, 770, 0,
-	0, 771, 772, 773, 774, 776, 778, 779, 780, 775,
-	777, 781, 0, 782, 0, 0, 783, 784, 785, 854,
-	855, 856, 0, 787, 788, 786, 789, 790, 793, 791,
-	792, 857, 796, 513, 797, 798, 799, 794, 795, 1961,
-	0, 337, 0, 800, 801, 858, 802, 803, 804, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 345, 346,
-	348, 347, 349, 350, 351, 352, 0, 353, 354, 0,
-	0, 0, 0, 0, 805, 0, 0, 0, 356, 0,
-	355, 0, 357, 358, 359, 0, 360, 361, 362, 363,
-	364, 365, 366, 367, 806, 807, 0, 368, 808, 369,
-	809, 0, 810, 370, 371, 372, 373, 374, 375, 376,
-	377, 378, 379, 0, 0, 0, 380, 811, 812, 813,
-	0, 381, 382, 383, 384, 814, 0, 0, 0, 385,
-	386, 387, 388, 389, 390, 391, 392, 0, 0, 394,
-	395, 396, 393, 397, 398, 0, 399, 0, 400, 401,
-	402, 403, 404, 405, 406, 0, 407, 408, 409, 0,
-	410, 411, 412, 0, 0, 0, 0, 0, 0, 0,
-	413, 414, 415, 416, 417, 0, 418, 420, 421, 815,
-	422, 816, 0, 425, 427, 419, 423, 0, 426, 424,
-	428, 429, 0, 430, 431, 432, 433, 0, 0, 434,
-	435, 436, 0, 437, 438, 440, 439, 0, 441, 442,
-	443, 0, 444, 445, 817, 446, 447, 448, 450, 452,
-	449, 451, 453, 454, 455, 456, 457, 818, 819, 458,
-	459, 0, 340, 0, 0, 0, 0, 0, 460, 461,
-	462, 820, 0, 0, 0, 463, 0, 465, 469, 466,
-	467, 468, 470, 0, 464, 471, 472, 0, 0, 473,
-	474, 475, 821, 822, 476, 477, 478, 479, 480, 481,
-	482, 483, 484, 0, 485, 486, 823, 0, 824, 487,
-	0, 488, 489, 490, 491, 492, 493, 494, 825, 826,
-	827, 595, 0, 495, 496, 497, 0, 498, 499, 500,
-	501, 502, 503, 504, 0, 0, 0, 505, 506, 507,
-	508, 0, 342, 341, 343, 0, 828, 509, 596, 510,
-	829, 830, 0, 831, 0, 511, 512, 515, 0, 832,
-	0, 514, 516, 517, 0, 518, 0, 0, 0, 519,
-	520, 521, 522, 523, 524, 525, 0, 526, 528, 527,
-	0, 530, 833, 529, 0, 531, 532, 0, 0, 533,
-	534, 535, 536, 537, 538, 541, 0, 0, 539, 540,
-	542, 543, 0, 544, 545, 547, 550, 546, 548, 549,
-	551, 552, 565, 566, 553, 554, 555, 556, 557, 558,
-	559, 560, 561, 562, 563, 564, 568, 0, 567, 0,
-	569, 570, 571, 572, 573, 581, 583, 584, 579, 580,
-	582, 585, 586, 588, 589, 576, 577, 578, 0, 587,
-	574, 0, 575, 344, 0, 590, 591, 592, 593, 0,
-	834, 594, 835, 597, 598, 0, 0, 599, 0, 600,
-	0, 0, 602, 603, 604, 0, 0, 605, 606, 836,
-	0, 607, 0, 837, 608, 609, 601, 610, 611, 612,
-	613, 614, 615, 616, 617, 618, 619, 0, 620, 621,
-	838, 622, 623, 624, 839, 625, 626, 627, 840, 628,
-	841, 629, 630, 0, 631, 632, 633, 0, 634, 635,
-	636, 637, 638, 639, 640, 641, 642, 643, 842, 644,
-	645, 647, 646, 648, 649, 0, 650, 0, 651, 652,
-	653, 0, 0, 0, 0, 0, 654, 655, 657, 0,
-	658, 659, 660, 661, 662, 656, 663, 664, 665, 666,
-	667, 668, 669, 0, 671, 672, 670, 673, 674, 0,
-	675, 676, 677, 678, 679, 843, 680, 0, 681, 682,
-	690, 691, 692, 683, 684, 686, 693, 685, 694, 695,
-	696, 697, 699, 698, 0, 701, 702, 700, 703, 704,
-	705, 706, 0, 707, 844, 708, 687, 688, 709, 710,
-	711, 0, 712, 713, 714, 715, 716, 717, 718, 719,
-	720, 845, 0, 721, 0, 722, 723, 724, 725, 726,
-	727, 729, 689, 730, 731, 732, 737, 738, 846, 733,
-	734, 735, 736, 847, 740, 741, 742, 743, 0, 744,
-	745, 0, 739, 728, 0, 746, 747, 748, 749, 750,
-	751, 752, 753, 754, 755, 0, 756, 848, 849, 850,
-	851, 0, 768, 0, 757, 759, 760, 761, 762, 852,
-	763, 853, 0, 764, 765, 766, 767, 758, 769, 770,
-	0, 0, 771, 772, 773, 774, 776, 778, 779, 780,
-	775, 777, 781, 0, 782, 0, 0, 783, 784, 785,
-	854, 855, 856, 0, 787, 788, 786, 789, 790, 793,
-	791, 792, 857, 796, 513, 797, 798, 799, 794, 795,
-	1623, 0, 337, 0, 800, 801, 858, 802, 803, 804,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 345,
-	346, 348, 347, 349, 350, 351, 352, 0, 353, 354,
-	0, 0, 0, 0, 0, 805, 0, 0, 0, 356,
-	0, 355, 0, 357, 358, 359, 0, 360, 361, 362,
-	363, 364, 365, 366, 367, 806, 807, 0, 368, 808,
-	369, 809, 0, 810, 370, 371, 372, 373, 374, 375,
-	376, 377, 378, 379, 0, 0, 0, 380, 811, 812,
-	813, 0, 381, 382, 383, 384, 814, 0, 0, 0,
-	385, 386, 387, 388, 389, 390, 391, 392, 0, 0,
-	394, 395, 396, 393, 397, 398, 0, 399, 0, 400,
-	401, 402, 403, 404, 405, 406, 0, 407, 408, 409,
-	0, 410, 411, 412, 0, 0, 0, 0, 0, 0,
-	0, 413, 414, 415, 416, 417, 0, 418, 420, 421,
-	815, 422, 816, 0, 425, 427, 419, 423, 0, 426,
-	424, 428, 429, 0, 430, 431, 432, 433, 0, 0,
-	434, 435, 436, 0, 437, 438, 440, 439, 0, 441,
-	442, 443, 0, 444, 445, 817, 446, 447, 448, 450,
-	452, 449, 451, 453, 454, 455, 456, 457, 818, 819,
-	458, 459, 0, 340, 0, 0, 0, 0, 0, 460,
-	461, 462, 820, 0, 0, 0, 463, 0, 465, 469,
-	466, 467, 468, 470, 0, 464, 471, 472, 0, 0,
-	473, 474, 475, 821, 822, 476, 477, 478, 479, 480,
-	481, 482, 483, 484, 0, 485, 486, 823, 0, 824,
-	487, 0, 488, 489, 490, 491, 492, 493, 494, 1622,
-	826, 827, 595, 0, 495, 496, 497, 0, 498, 499,
-	500, 501, 502, 503, 504, 0, 0, 0, 505, 506,
-	507, 508, 0, 342, 341, 343, 0, 828, 509, 596,
-	510, 829, 830, 0, 831, 0, 511, 512, 515, 0,
-	832, 0, 514, 516, 517, 0, 518, 0, 0, 0,
-	519, 520, 521, 522, 523, 524, 525, 0, 526, 528,
-	527, 0, 530, 833, 529, 0, 531, 532, 0, 0,
-	533, 534, 535, 536, 537, 538, 541, 0, 0, 539,
-	540, 542, 543, 0, 544, 545, 547, 550, 546, 548,
-	549, 551, 552, 565, 566, 553, 554, 555, 556, 557,
-	558, 559, 560, 561, 562, 563, 564, 568, 0, 567,
-	0, 569, 570, 571, 572, 573, 581, 583, 584, 579,
-	580, 582, 585, 586, 588, 589, 576, 577, 578, 0,
-	587, 574, 0, 575, 344, 0, 590, 591, 592, 593,
-	0, 834, 594, 835, 597, 598, 0, 0, 599, 0,
-	600, 0, 0, 602, 603, 604, 0, 0, 605, 606,
-	836, 0, 607, 0, 837, 608, 609, 601, 610, 611,
-	612, 613, 614, 615, 616, 617, 618, 619, 0, 620,
-	621, 838, 622, 623, 624, 839, 625, 626, 627, 840,
-	628, 841, 629, 630, 0, 631, 632, 633, 0, 634,
-	635, 636, 637, 638, 639, 640, 641, 642, 643, 842,
-	644, 645, 647, 646, 648, 649, 0, 650, 0, 651,
-	652, 653, 0, 0, 0, 0, 0, 654, 655, 657,
-	0, 658, 659, 660, 661, 662, 656, 663, 664, 665,
-	666, 667, 668, 669, 0, 671, 672, 670, 673, 674,
-	0, 675, 676, 677, 678, 679, 843, 680, 0, 681,
-	682, 690, 691, 692, 683, 684, 686, 693, 685, 694,
-	695, 696, 697, 699, 698, 0, 701, 702, 700, 703,
-	704, 705, 706, 0, 707, 844, 708, 687, 688, 709,
-	710, 711, 0, 712, 713, 714, 715, 716, 717, 718,
-	719, 720, 845, 0, 721, 0, 722, 723, 724, 725,
-	726, 727, 729, 689, 730, 731, 732, 737, 738, 846,
-	733, 734, 735, 736, 847, 740, 741, 742, 743, 0,
-	744, 745, 0, 739, 728, 0, 746, 747, 748, 749,
-	750, 751, 752, 753, 754, 755, 0, 756, 848, 849,
-	850, 851, 0, 768, 0, 757, 759, 760, 761, 762,
-	852, 763, 853, 0, 764, 765, 766, 767, 758, 769,
-	770, 0, 0, 771, 772, 773, 774, 776, 778, 779,
-	780, 775, 777, 781, 0, 782, 0, 0, 783, 784,
-	785, 854, 855, 856, 0, 787, 788, 786, 789, 790,
-	793, 791, 792, 857, 796, 513, 797, 798, 799, 794,
-	795, 1612, 0, 337, 0, 800, 801, 858, 802, 803,
-	804, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	345, 346, 348, 347, 349, 350, 351, 352, 0, 353,
-	354, 0, 0, 0, 0, 0, 805, 0, 0, 0,
-	356, 0, 355, 0, 357, 358, 359, 0, 360, 361,
-	362, 363, 364, 365, 366, 367, 806, 807, 0, 368,
-	808, 369, 809, 0, 810, 370, 371, 372, 373, 374,
-	375, 376, 377, 378, 379, 0, 0, 0, 380, 811,
-	812, 813, 0, 381, 382, 383, 384, 814, 0, 0,
-	0, 385, 386, 387, 388, 389, 390, 391, 392, 0,
-	0, 394, 395, 396, 393, 397, 398, 0, 399, 0,
-	400, 401, 402, 403, 404, 405, 406, 0, 407, 408,
-	409, 0, 410, 411, 412, 0, 0, 0, 0, 0,
-	0, 0, 413, 414, 415, 416, 417, 0, 418, 420,
-	421, 815, 422, 816, 0, 425, 427, 419, 423, 0,
-	426, 424, 428, 429, 0, 430, 431, 432, 433, 0,
-	0, 434, 435, 436, 0, 437, 438, 440, 439, 0,
-	441, 442, 443, 0, 444, 445, 817, 446, 447, 448,
-	450, 452, 449, 451, 453, 454, 455, 456, 457, 818,
-	819, 458, 459, 0, 340, 0, 0, 0, 0, 0,
-	460, 461, 462, 820, 0, 0, 0, 463, 0, 465,
-	469, 466, 467, 468, 470, 0, 464, 471, 472, 0,
-	0, 473, 474, 475, 821, 822, 476, 477, 478, 479,
-	480, 481, 482, 483, 484, 0, 485, 486, 823, 0,
-	824, 487, 0, 488, 489, 490, 491, 492, 493, 494,
-	1611, 826, 827, 595, 0, 495, 496, 497, 0, 498,
-	499, 500, 501, 502, 503, 504, 0, 0, 0, 505,
-	506, 507, 508, 0, 342, 341, 343, 0, 828, 509,
-	596, 510, 829, 830, 0, 831, 0, 511, 512, 515,
-	0, 832, 0, 514, 516, 517, 0, 518, 0, 0,
-	0, 519, 520, 521, 522, 523, 524, 525, 0, 526,
-	528, 527, 0, 530, 833, 529, 0, 531, 532, 0,
-	0, 533, 534, 535, 536, 537, 538, 541, 0, 0,
-	539, 540, 542, 543, 0, 544, 545, 547, 550, 546,
-	548, 549, 551, 552, 565, 566, 553, 554, 555, 556,
-	557, 558, 559, 560, 561, 562, 563, 564, 568, 0,
-	567, 0, 569, 570, 571, 572, 573, 581, 583, 584,
-	579, 580, 582, 585, 586, 588, 589, 576, 577, 578,
-	0, 587, 574, 0, 575, 344, 0, 590, 591, 592,
-	593, 0, 834, 594, 835, 597, 598, 0, 0, 599,
-	0, 600, 0, 0, 602, 603, 604, 0, 0, 605,
-	606, 836, 0, 607, 0, 837, 608, 609, 601, 610,
-	611, 612, 613, 614, 615, 616, 617, 618, 619, 0,
-	620, 621, 838, 622, 623, 624, 839, 625, 626, 627,
-	840, 628, 841, 629, 630, 0, 631, 632, 633, 0,
-	634, 635, 636, 637, 638, 639, 640, 641, 642, 643,
-	842, 644, 645, 647, 646, 648, 649, 0, 650, 0,
-	651, 652, 653, 0, 0, 0, 0, 0, 654, 655,
-	657, 0, 658, 659, 660, 661, 662, 656, 663, 664,
-	665, 666, 667, 668, 669, 0, 671, 672, 670, 673,
-	674, 0, 675, 676, 677, 678, 679, 843, 680, 0,
-	681, 682, 690, 691, 692, 683, 684, 686, 693, 685,
-	694, 695, 696, 697, 699, 698, 0, 701, 702, 700,
-	703, 704, 705, 706, 0, 707, 844, 708, 687, 688,
-	709, 710, 711, 0, 712, 713, 714, 715, 716, 717,
-	718, 719, 720, 845, 0, 721, 0, 722, 723, 724,
-	725, 726, 727, 729, 689, 730, 731, 732, 737, 738,
-	846, 733, 734, 735, 736, 847, 740, 741, 742, 743,
-	0, 744, 745, 0, 739, 728, 0, 746, 747, 748,
-	749, 750, 751, 752, 753, 754, 755, 0, 756, 848,
-	849, 850, 851, 0, 768, 0, 757, 759, 760, 761,
-	762, 852, 763, 853, 0, 764, 765, 766, 767, 758,
-	769, 770, 0, 0, 771, 772, 773, 774, 776, 778,
-	779, 780, 775, 777, 781, 0, 782, 0, 0, 783,
-	784, 785, 854, 855, 856, 0, 787, 788, 786, 789,
-	790, 793, 791, 792, 857, 796, 513, 797, 798, 799,
-	794, 795, 1608, 0, 337, 0, 800, 801, 858, 802,
-	803, 804, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 345, 346, 348, 347, 349, 350, 351, 352, 0,
-	353, 354, 0, 0, 0, 0, 0, 805, 0, 0,
-	0, 356, 0, 355, 0, 357, 358, 359, 0, 360,
-	361, 362, 363, 364, 365, 366, 367, 806, 807, 0,
-	368, 808, 369, 809, 0, 810, 370, 371, 372, 373,
-	374, 375, 376, 377, 378, 379, 0, 0, 0, 380,
-	811, 812, 813, 0, 381, 382, 383, 384, 814, 0,
-	0, 0, 385, 386, 387, 388, 389, 390, 391, 392,
-	0, 0, 394, 395, 396, 393, 397, 398, 0, 399,
-	0, 400, 401, 402, 403, 404, 405, 406, 0, 407,
-	408, 409, 0, 410, 411, 412, 0, 0, 0, 0,
-	0, 0, 0, 413, 414, 415, 416, 417, 0, 418,
-	420, 421, 815, 422, 816, 0, 425, 427, 419, 423,
-	0, 426, 424, 428, 429, 0, 430, 431, 432, 433,
-	0, 0, 434, 435, 436, 0, 437, 438, 440, 439,
-	0, 441, 442, 443, 0, 444, 445, 817, 446, 447,
-	448, 450, 452, 449, 451, 453, 454, 455, 456, 457,
-	818, 819, 458, 459, 0, 340, 0, 0, 0, 0,
-	0, 460, 461, 462, 820, 0, 0, 0, 463, 0,
-	465, 469, 466, 467, 468, 470, 0, 464, 471, 472,
-	0, 0, 473, 474, 475, 821, 822, 476, 477, 478,
-	479, 480, 481, 482, 483, 484, 0, 485, 486, 823,
-	0, 824, 487, 0, 488, 489, 490, 491, 492, 493,
-	494, 1607, 826, 827, 595, 0, 495, 496, 497, 0,
-	498, 499, 500, 501, 502, 503, 504, 0, 0, 0,
-	505, 506, 507, 508, 0, 342, 341, 343, 0, 828,
-	509, 596, 510, 829, 830, 0, 831, 0, 511, 512,
-	515, 0, 832, 0, 514, 516, 517, 0, 518, 0,
-	0, 0, 519, 520, 521, 522, 523, 524, 525, 0,
-	526, 528, 527, 0, 530, 833, 529, 0, 531, 532,
-	0, 0, 533, 534, 535, 536, 537, 538, 541, 0,
-	0, 539, 540, 542, 543, 0, 544, 545, 547, 550,
-	546, 548, 549, 551, 552, 565, 566, 553, 554, 555,
-	556, 557, 558, 559, 560, 561, 562, 563, 564, 568,
-	0, 567, 0, 569, 570, 571, 572, 573, 581, 583,
-	584, 579, 580, 582, 585, 586, 588, 589, 576, 577,
-	578, 0, 587, 574, 0, 575, 344, 0, 590, 591,
-	592, 593, 0, 834, 594, 835, 597, 598, 0, 0,
-	599, 0, 600, 0, 0, 602, 603, 604, 0, 0,
-	605, 606, 836, 0, 607, 0, 837, 608, 609, 601,
-	610, 611, 612, 613, 614, 615, 616, 617, 618, 619,
-	0, 620, 621, 838, 622, 623, 624, 839, 625, 626,
-	627, 840, 628, 841, 629, 630, 0, 631, 632, 633,
-	0, 634, 635, 636, 637, 638, 639, 640, 641, 642,
-	643, 842, 644, 645, 647, 646, 648, 649, 0, 650,
-	0, 651, 652, 653, 0, 0, 0, 0, 0, 654,
-	655, 657, 0, 658, 659, 660, 661, 662, 656, 663,
-	664, 665, 666, 667, 668, 669, 0, 671, 672, 670,
-	673, 674, 0, 675, 676, 677, 678, 679, 843, 680,
-	0, 681, 682, 690, 691, 692, 683, 684, 686, 693,
-	685, 694, 695, 696, 697, 699, 698, 0, 701, 702,
-	700, 703, 704, 705, 706, 0, 707, 844, 708, 687,
-	688, 709, 710, 711, 0, 712, 713, 714, 715, 716,
-	717, 718, 719, 720, 845, 0, 721, 0, 722, 723,
-	724, 725, 726, 727, 729, 689, 730, 731, 732, 737,
-	738, 846, 733, 734, 735, 736, 847, 740, 741, 742,
-	743, 0, 744, 745, 0, 739, 728, 0, 746, 747,
-	748, 749, 750, 751, 752, 753, 754, 755, 0, 756,
-	848, 849, 850, 851, 0, 768, 0, 757, 759, 760,
-	761, 762, 852, 763, 853, 0, 764, 765, 766, 767,
-	758, 769, 770, 0, 0, 771, 772, 773, 774, 776,
-	778, 779, 780, 775, 777, 781, 0, 782, 0, 0,
-	783, 784, 785, 854, 855, 856, 0, 787, 788, 786,
-	789, 790, 793, 791, 792, 857, 796, 513, 797, 798,
-	799, 794, 795, 1602, 0, 337, 0, 800, 801, 858,
-	802, 803, 804, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 345, 346, 348, 347, 349, 350, 351, 352,
-	0, 353, 354, 0, 0, 0, 0, 0, 805, 0,
-	0, 0, 356, 0, 355, 0, 357, 358, 359, 0,
-	360, 361, 362, 363, 364, 365, 366, 367, 806, 807,
-	0, 368, 808, 369, 809, 0, 810, 370, 371, 372,
-	373, 374, 375, 376, 377, 378, 379, 0, 0, 0,
-	380, 811, 812, 813, 0, 381, 382, 383, 384, 814,
-	0, 0, 0, 385, 386, 387, 388, 389, 390, 391,
-	392, 0, 0, 394, 395, 396, 393, 397, 398, 0,
-	399, 0, 400, 401, 402, 403, 404, 405, 406, 0,
-	407, 408, 409, 0, 410, 411, 412, 0, 0, 0,
-	0, 0, 0, 0, 413, 414, 415, 416, 417, 0,
-	418, 420, 421, 815, 422, 816, 0, 425, 427, 419,
-	423, 0, 426, 424, 428, 429, 0, 430, 431, 432,
-	433, 0, 0, 434, 435, 436, 0, 437, 438, 440,
-	439, 0, 441, 442, 443, 0, 444, 445, 817, 446,
-	447, 448, 450, 452, 449, 451, 453, 454, 455, 456,
-	457, 818, 819, 458, 459, 0, 340, 0, 0, 0,
-	0, 0, 460, 461, 462, 820, 0, 0, 0, 463,
-	0, 465, 469, 466, 467, 468, 470, 0, 464, 471,
-	472, 0, 0, 473, 474, 475, 821, 822, 476, 477,
-	478, 479, 480, 481, 482, 483, 484, 0, 485, 486,
-	823, 0, 824, 487, 0, 488, 489, 490, 491, 492,
-	493, 494, 1601, 826, 827, 595, 0, 495, 496, 497,
-	0, 498, 499, 500, 501, 502, 503, 504, 0, 0,
-	0, 505, 506, 507, 508, 0, 342, 341, 343, 0,
-	828, 509, 596, 510, 829, 830, 0, 831, 0, 511,
-	512, 515, 0, 832, 0, 514, 516, 517, 0, 518,
-	0, 0, 0, 519, 520, 521, 522, 523, 524, 525,
-	0, 526, 528, 527, 0, 530, 833, 529, 0, 531,
-	532, 0, 0, 533, 534, 535, 536, 537, 538, 541,
-	0, 0, 539, 540, 542, 543, 0, 544, 545, 547,
-	550, 546, 548, 549, 551, 552, 565, 566, 553, 554,
-	555, 556, 557, 558, 559, 560, 561, 562, 563, 564,
-	568, 0, 567, 0, 569, 570, 571, 572, 573, 581,
-	583, 584, 579, 580, 582, 585, 586, 588, 589, 576,
-	577, 578, 0, 587, 574, 0, 575, 344, 0, 590,
-	591, 592, 593, 0, 834, 594, 835, 597, 598, 0,
-	0, 599, 0, 600, 0, 0, 602, 603, 604, 0,
-	0, 605, 606, 836, 0, 607, 0, 837, 608, 609,
-	601, 610, 611, 612, 613, 614, 615, 616, 617, 618,
-	619, 0, 620, 621, 838, 622, 623, 624, 839, 625,
-	626, 627, 840, 628, 841, 629, 630, 0, 631, 632,
-	633, 0, 634, 635, 636, 637, 638, 639, 640, 641,
-	642, 643, 842, 644, 645, 647, 646, 648, 649, 0,
-	650, 0, 651, 652, 653, 0, 0, 0, 0, 0,
-	654, 655, 657, 0, 658, 659, 660, 661, 662, 656,
-	663, 664, 665, 666, 667, 668, 669, 0, 671, 672,
-	670, 673, 674, 0, 675, 676, 677, 678, 679, 843,
-	680, 0, 681, 682, 690, 691, 692, 683, 684, 686,
-	693, 685, 694, 695, 696, 697, 699, 698, 0, 701,
-	702, 700, 703, 704, 705, 706, 0, 707, 844, 708,
-	687, 688, 709, 710, 711, 0, 712, 713, 714, 715,
-	716, 717, 718, 719, 720, 845, 0, 721, 0, 722,
-	723, 724, 725, 726, 727, 729, 689, 730, 731, 732,
-	737, 738, 846, 733, 734, 735, 736, 847, 740, 741,
-	742, 743, 0, 744, 745, 0, 739, 728, 0, 746,
-	747, 748, 749, 750, 751, 752, 753, 754, 755, 0,
-	756, 848, 849, 850, 851, 0, 768, 0, 757, 759,
-	760, 761, 762, 852, 763, 853, 0, 764, 765, 766,
-	767, 758, 769, 770, 0, 0, 771, 772, 773, 774,
-	776, 778, 779, 780, 775, 777, 781, 0, 782, 0,
-	0, 783, 784, 785, 854, 855, 856, 0, 787, 788,
-	786, 789, 790, 793, 791, 792, 857, 796, 513, 797,
-	798, 799, 794, 795, 1581, 0, 337, 0, 800, 801,
-	858, 802, 803, 804, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 345, 346, 348, 347, 349, 350, 351,
-	352, 0, 353, 354, 0, 0, 0, 0, 0, 805,
-	0, 0, 0, 356, 0, 355, 0, 357, 358, 359,
-	0, 360, 361, 362, 363, 364, 365, 366, 367, 806,
-	807, 0, 368, 808, 369, 809, 0, 810, 370, 371,
-	372, 373, 374, 375, 376, 377, 378, 379, 0, 0,
-	0, 380, 811, 812, 813, 0, 381, 382, 383, 384,
-	814, 0, 0, 0, 385, 386, 387, 388, 389, 390,
-	391, 392, 0, 0, 394, 395, 396, 393, 397, 398,
-	0, 399, 0, 400, 401, 402, 403, 404, 405, 406,
-	0, 407, 408, 409, 0, 410, 411, 412, 0, 0,
-	0, 0, 0, 0, 0, 413, 414, 415, 416, 417,
-	0, 418, 420, 421, 815, 422, 816, 0, 425, 427,
-	419, 423, 0, 426, 424, 428, 429, 0, 430, 431,
-	432, 433, 0, 0, 434, 435, 436, 0, 437, 438,
-	440, 439, 0, 441, 442, 443, 0, 444, 445, 817,
-	446, 447, 448, 450, 452, 449, 451, 453, 454, 455,
-	456, 457, 818, 819, 458, 459, 0, 340, 0, 0,
-	0, 0, 0, 460, 461, 462, 820, 0, 0, 0,
-	463, 0, 465, 469, 466, 467, 468, 470, 0, 464,
-	471, 472, 0, 0, 473, 474, 475, 821, 822, 476,
-	477, 478, 479, 480, 481, 482, 483, 484, 0, 485,
-	486, 823, 0, 824, 487, 0, 488, 489, 490, 491,
-	492, 493, 494, 1580, 826, 827, 595, 0, 495, 496,
-	497, 0, 498, 499, 500, 501, 502, 503, 504, 0,
-	0, 0, 505, 506, 507, 508, 0, 342, 341, 343,
-	0, 828, 509, 596, 510, 829, 830, 0, 831, 0,
-	511, 512, 515, 0, 832, 0, 514, 516, 517, 0,
-	518, 0, 0, 0, 519, 520, 521, 522, 523, 524,
-	525, 0, 526, 528, 527, 0, 530, 833, 529, 0,
-	531, 532, 0, 0, 533, 534, 535, 536, 537, 538,
-	541, 0, 0, 539, 540, 542, 543, 0, 544, 545,
-	547, 550, 546, 548, 549, 551, 552, 565, 566, 553,
-	554, 555, 556, 557, 558, 559, 560, 561, 562, 563,
-	564, 568, 0, 567, 0, 569, 570, 571, 572, 573,
-	581, 583, 584, 579, 580, 582, 585, 586, 588, 589,
-	576, 577, 578, 0, 587, 574, 0, 575, 344, 0,
-	590, 591, 592, 593, 0, 834, 594, 835, 597, 598,
-	0, 0, 599, 0, 600, 0, 0, 602, 603, 604,
-	0, 0, 605, 606, 836, 0, 607, 0, 837, 608,
-	609, 601, 610, 611, 612, 613, 614, 615, 616, 617,
-	618, 619, 0, 620, 621, 838, 622, 623, 624, 839,
-	625, 626, 627, 840, 628, 841, 629, 630, 0, 631,
-	632, 633, 0, 634, 635, 636, 637, 638, 639, 640,
-	641, 642, 643, 842, 644, 645, 647, 646, 648, 649,
-	0, 650, 0, 651, 652, 653, 0, 0, 0, 0,
-	0, 654, 655, 657, 0, 658, 659, 660, 661, 662,
-	656, 663, 664, 665, 666, 667, 668, 669, 0, 671,
-	672, 670, 673, 674, 0, 675, 676, 677, 678, 679,
-	843, 680, 0, 681, 682, 690, 691, 692, 683, 684,
-	686, 693, 685, 694, 695, 696, 697, 699, 698, 0,
-	701, 702, 700, 703, 704, 705, 706, 0, 707, 844,
-	708, 687, 688, 709, 710, 711, 0, 712, 713, 714,
-	715, 716, 717, 718, 719, 720, 845, 0, 721, 0,
-	722, 723, 724, 725, 726, 727, 729, 689, 730, 731,
-	732, 737, 738, 846, 733, 734, 735, 736, 847, 740,
-	741, 742, 743, 0, 744, 745, 0, 739, 728, 0,
-	746, 747, 748, 749, 750, 751, 752, 753, 754, 755,
-	0, 756, 848, 849, 850, 851, 0, 768, 0, 757,
-	759, 760, 761, 762, 852, 763, 853, 0, 764, 765,
-	766, 767, 758, 769, 770, 0, 0, 771, 772, 773,
-	774, 776, 778, 779, 780, 775, 777, 781, 0, 782,
-	0, 0, 783, 784, 785, 854, 855, 856, 0, 787,
-	788, 786, 789, 790, 793, 791, 792, 857, 796, 513,
-	797, 798, 799, 794, 795, 1576, 0, 337, 0, 800,
-	801, 858, 802, 803, 804, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 345, 346, 348, 347, 349, 350,
-	351, 352, 0, 353, 354, 0, 0, 0, 0, 0,
-	805, 0, 0, 0, 356, 0, 355, 0, 357, 358,
-	359, 0, 360, 361, 362, 363, 364, 365, 366, 367,
-	806, 807, 0, 368, 808, 369, 809, 0, 810, 370,
-	371, 372, 373, 374, 375, 376, 377, 378, 379, 0,
-	0, 0, 380, 811, 812, 813, 0, 381, 382, 383,
-	384, 814, 0, 0, 0, 385, 386, 387, 388, 389,
-	390, 391, 392, 0, 0, 394, 395, 396, 393, 397,
-	398, 0, 399, 0, 400, 401, 402, 403, 404, 405,
-	406, 0, 407, 408, 409, 0, 410, 411, 412, 0,
-	0, 0, 0, 0, 0, 0, 413, 414, 415, 416,
-	417, 0, 418, 420, 421, 815, 422, 816, 0, 425,
-	427, 419, 423, 0, 426, 424, 428, 429, 0, 430,
-	431, 432, 433, 0, 0, 434, 435, 436, 0, 437,
-	438, 440, 439, 0, 441, 442, 443, 0, 444, 445,
-	817, 446, 447, 448, 450, 452, 449, 451, 453, 454,
-	455, 456, 457, 818, 819, 458, 459, 0, 340, 0,
-	0, 0, 0, 0, 460, 461, 462, 820, 0, 0,
-	0, 463, 0, 465, 469, 466, 467, 468, 470, 0,
-	464, 471, 472, 0, 0, 473, 474, 475, 821, 822,
-	476, 477, 478, 479, 480, 481, 482, 483, 484, 0,
-	485, 486, 823, 0, 824, 487, 0, 488, 489, 490,
-	491, 492, 493, 494, 1575, 826, 827, 595, 0, 495,
-	496, 497, 0, 498, 499, 500, 501, 502, 503, 504,
-	0, 0, 0, 505, 506, 507, 508, 0, 342, 341,
-	343, 0, 828, 509, 596, 510, 829, 830, 0, 831,
-	0, 511, 512, 515, 0, 832, 0, 514, 516, 517,
-	0, 518, 0, 0, 0, 519, 520, 521, 522, 523,
-	524, 525, 0, 526, 528, 527, 0, 530, 833, 529,
-	0, 531, 532, 0, 0, 533, 534, 535, 536, 537,
-	538, 541, 0, 0, 539, 540, 542, 543, 0, 544,
-	545, 547, 550, 546, 548, 549, 551, 552, 565, 566,
-	553, 554, 555, 556, 557, 558, 559, 560, 561, 562,
-	563, 564, 568, 0, 567, 0, 569, 570, 571, 572,
-	573, 581, 583, 584, 579, 580, 582, 585, 586, 588,
-	589, 576, 577, 578, 0, 587, 574, 0, 575, 344,
-	0, 590, 591, 592, 593, 0, 834, 594, 835, 597,
-	598, 0, 0, 599, 0, 600, 0, 0, 602, 603,
-	604, 0, 0, 605, 606, 836, 0, 607, 0, 837,
-	608, 609, 601, 610, 611, 612, 613, 614, 615, 616,
-	617, 618, 619, 0, 620, 621, 838, 622, 623, 624,
-	839, 625, 626, 627, 840, 628, 841, 629, 630, 0,
-	631, 632, 633, 0, 634, 635, 636, 637, 638, 639,
-	640, 641, 642, 643, 842, 644, 645, 647, 646, 648,
-	649, 0, 650, 0, 651, 652, 653, 0, 0, 0,
-	0, 0, 654, 655, 657, 0, 658, 659, 660, 661,
-	662, 656, 663, 664, 665, 666, 667, 668, 669, 0,
-	671, 672, 670, 673, 674, 0, 675, 676, 677, 678,
-	679, 843, 680, 0, 681, 682, 690, 691, 692, 683,
-	684, 686, 693, 685, 694, 695, 696, 697, 699, 698,
-	0, 701, 702, 700, 703, 704, 705, 706, 0, 707,
-	844, 708, 687, 688, 709, 710, 711, 0, 712, 713,
-	714, 715, 716, 717, 718, 719, 720, 845, 0, 721,
-	0, 722, 723, 724, 725, 726, 727, 729, 689, 730,
-	731, 732, 737, 738, 846, 733, 734, 735, 736, 847,
-	740, 741, 742, 743, 0, 744, 745, 0, 739, 728,
-	0, 746, 747, 748, 749, 750, 751, 752, 753, 754,
-	755, 0, 756, 848, 849, 850, 851, 0, 768, 0,
-	757, 759, 760, 761, 762, 852, 763, 853, 0, 764,
-	765, 766, 767, 758, 769, 770, 0, 0, 771, 772,
-	773, 774, 776, 778, 779, 780, 775, 777, 781, 0,
-	782, 0, 0, 783, 784, 785, 854, 855, 856, 0,
-	787, 788, 786, 789, 790, 793, 791, 792, 857, 796,
-	513, 797, 798, 799, 794, 795, 860, 0, 337, 0,
-	800, 801, 858, 802, 803, 804, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 345, 346, 348, 347, 349,
-	350, 351, 352, 0, 353, 354, 0, 0, 0, 0,
-	0, 805, 0, 0, 0, 356, 0, 355, 0, 357,
-	358, 359, 0, 360, 361, 362, 363, 364, 365, 366,
-	367, 806, 807, 0, 368, 808, 369, 809, 0, 810,
-	370, 371, 372, 373, 374, 375, 376, 377, 378, 379,
-	0, 0, 0, 380, 811, 812, 813, 0, 381, 382,
-	383, 384, 814, 0, 0, 0, 385, 386, 387, 388,
-	389, 390, 391, 392, 0, 0, 394, 395, 396, 393,
-	397, 398, 0, 399, 0, 400, 401, 402, 403, 404,
-	405, 406, 0, 407, 408, 409, 0, 410, 411, 412,
-	0, 0, 0, 0, 0, 0, 0, 413, 414, 415,
-	416, 417, 0, 418, 420, 421, 815, 422, 816, 0,
-	425, 427, 419, 423, 0, 426, 424, 428, 429, 0,
-	430, 431, 432, 433, 0, 0, 434, 435, 436, 0,
-	437, 438, 440, 439, 0, 441, 442, 443, 0, 444,
-	445, 817, 446, 447, 448, 450, 452, 449, 451, 453,
-	454, 455, 456, 457, 818, 819, 458, 459, 0, 340,
-	0, 0, 0, 0, 0, 460, 461, 462, 820, 0,
-	0, 0, 463, 0, 465, 469, 466, 467, 468, 470,
-	0, 464, 471, 472, 0, 0, 473, 474, 475, 821,
-	822, 476, 477, 478, 479, 480, 481, 482, 483, 484,
-	0, 485, 486, 823, 0, 824, 487, 0, 488, 489,
-	490, 491, 492, 493, 494, 825, 826, 827, 595, 0,
-	495, 496, 497, 0, 498, 499, 500, 501, 502, 503,
-	504, 0, 0, 0, 505, 506, 507, 508, 0, 342,
-	341, 343, 0, 828, 509, 596, 510, 829, 830, 0,
-	831, 0, 511, 512, 515, 0, 832, 0, 514, 516,
-	517, 0, 518, 0, 0, 0, 519, 520, 521, 522,
-	523, 524, 525, 0, 526, 528, 527, 0, 530, 833,
-	529, 0, 531, 532, 0, 0, 533, 534, 535, 536,
-	537, 538, 541, 0, 0, 539, 540, 542, 543, 0,
-	544, 545, 547, 550, 546, 548, 549, 551, 552, 565,
-	566, 553, 554, 555, 556, 557, 558, 559, 560, 561,
-	562, 563, 564, 568, 0, 567, 0, 569, 570, 571,
-	572, 573, 581, 583, 584, 579, 580, 582, 585, 586,
-	588, 589, 576, 577, 578, 0, 587, 574, 0, 575,
-	344, 0, 590, 591, 592, 593, 0, 834, 594, 835,
-	597, 598, 0, 0, 599, 0, 600, 0, 0, 602,
-	603, 604, 0, 0, 605, 606, 836, 0, 607, 0,
-	837, 608, 609, 601, 610, 611, 612, 613, 614, 615,
-	616, 617, 618, 619, 0, 620, 621, 838, 622, 623,
-	624, 839, 625, 626, 627, 840, 628, 841, 629, 630,
-	0, 631, 632, 633, 0, 634, 635, 636, 637, 638,
-	639, 640, 641, 642, 643, 842, 644, 645, 647, 646,
-	648, 649, 0, 650, 0, 651, 652, 653, 0, 0,
-	0, 0, 0, 654, 655, 657, 0, 658, 659, 660,
-	661, 662, 656, 663, 664, 665, 666, 667, 668, 669,
-	0, 671, 672, 670, 673, 674, 0, 675, 676, 677,
-	678, 679, 843, 680, 0, 681, 682, 690, 691, 692,
-	683, 684, 686, 693, 685, 694, 695, 696, 697, 699,
-	698, 0, 701, 702, 700, 703, 704, 705, 706, 0,
-	707, 844, 708, 687, 688, 709, 710, 711, 0, 712,
-	713, 714, 715, 716, 717, 718, 719, 720, 845, 0,
-	721, 0, 722, 723, 724, 725, 726, 727, 729, 689,
-	730, 731, 732, 737, 738, 846, 733, 734, 735, 736,
-	847, 740, 741, 742, 743, 0, 744, 745, 0, 739,
-	728, 0, 746, 747, 748, 749, 750, 751, 752, 753,
-	754, 755, 0, 756, 848, 849, 850, 851, 0, 768,
-	0, 757, 759, 760, 761, 762, 852, 763, 853, 0,
-	764, 765, 766, 767, 758, 769, 770, 0, 0, 771,
-	772, 773, 774, 776, 778, 779, 780, 775, 777, 781,
-	0, 782, 0, 0, 783, 784, 785, 854, 855, 856,
-	0, 787, 788, 786, 789, 790, 793, 791, 792, 857,
-	796, 513, 797, 798, 799, 794, 795, 328, 0, 337,
-	0, 800, 801, 858, 802, 803, 804, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 345, 346, 348, 347,
-	349, 350, 351, 352, 0, 353, 354, 0, 0, 0,
-	0, 0, 805, 0, 0, 0, 356, 0, 355, 0,
-	357, 358, 359, 0, 360, 361, 362, 363, 364, 365,
-	366, 367, 806, 807, 0, 368, 808, 369, 809, 0,
-	810, 370, 371, 372, 373, 374, 375, 376, 377, 378,
-	379, 0, 0, 0, 380, 811, 812, 813, 0, 381,
-	382, 383, 384, 814, 0, 0, 0, 385, 386, 387,
-	388, 389, 390, 391, 392, 0, 0, 394, 395, 396,
-	393, 397, 398, 0, 399, 0, 400, 401, 402, 403,
-	404, 405, 406, 0, 407, 408, 409, 0, 410, 411,
-	412, 0, 0, 0, 0, 0, 0, 0, 413, 414,
-	415, 416, 417, 0, 418, 420, 421, 815, 422, 816,
-	0, 425, 427, 419, 423, 0, 426, 424, 428, 429,
-	0, 430, 431, 432, 433, 0, 0, 434, 435, 436,
-	0, 437, 438, 440, 439, 0, 441, 442, 443, 0,
-	444, 445, 817, 446, 447, 448, 450, 452, 449, 451,
-	453, 454, 455, 456, 457, 818, 819, 458, 459, 0,
-	340, 0, 0, 0, 0, 0, 460, 461, 462, 820,
-	0, 0, 0, 463, 0, 465, 469, 466, 467, 468,
-	470, 0, 464, 471, 472, 0, 0, 473, 474, 475,
-	821, 822, 476, 477, 478, 479, 480, 481, 482, 483,
-	484, 0, 485, 486, 823, 0, 824, 487, 0, 488,
-	489, 490, 491, 492, 493, 494, 825, 826, 827, 595,
-	0, 495, 496, 497, 0, 498, 499, 500, 501, 502,
-	503, 504, 0, 0, 0, 505, 506, 507, 508, 0,
-	342, 341, 343, 0, 828, 509, 596, 510, 829, 830,
-	0, 831, 0, 511, 512, 515, 0, 832, 0, 514,
-	516, 517, 0, 518, 0, 0, 0, 519, 520, 521,
-	522, 523, 524, 525, 0, 526, 528, 527, 0, 530,
-	833, 529, 0, 531, 532, 0, 0, 533, 534, 535,
-	536, 537, 538, 541, 0, 0, 539, 540, 542, 543,
-	0, 544, 545, 547, 550, 546, 548, 549, 551, 552,
-	565, 566, 553, 554, 555, 556, 557, 558, 559, 560,
-	561, 562, 563, 564, 568, 0, 567, 0, 569, 570,
-	571, 572, 573, 581, 583, 584, 579, 580, 582, 585,
-	586, 588, 589, 576, 577, 578, 0, 587, 574, 0,
-	575, 344, 0, 590, 591, 592, 593, 0, 834, 594,
-	835, 597, 598, 0, 0, 599, 0, 600, 0, 0,
-	602, 603, 604, 0, 0, 605, 606, 836, 0, 607,
-	0, 837, 608, 609, 601, 610, 611, 612, 613, 614,
-	615, 616, 617, 618, 619, 0, 620, 621, 838, 622,
-	623, 624, 839, 625, 626, 627, 840, 628, 841, 629,
-	630, 0, 631, 632, 633, 0, 634, 635, 636, 637,
-	638, 639, 640, 641, 642, 643, 842, 644, 645, 647,
-	646, 648, 649, 0, 650, 0, 651, 652, 653, 0,
-	0, 0, 0, 0, 654, 655, 657, 0, 658, 659,
-	660, 661, 662, 656, 663, 664, 665, 666, 667, 668,
-	669, 0, 671, 672, 670, 673, 674, 0, 675, 676,
-	677, 678, 679, 843, 680, 0, 681, 682, 690, 691,
-	692, 683, 684, 686, 693, 685, 694, 695, 696, 697,
-	699, 698, 0, 701, 702, 700, 703, 704, 705, 706,
-	0, 707, 844, 708, 687, 688, 709, 710, 711, 0,
-	712, 713, 714, 715, 716, 717, 718, 719, 720, 845,
-	0, 721, 0, 722, 723, 724, 725, 726, 727, 729,
-	689, 730, 731, 732, 737, 738, 846, 733, 734, 735,
-	736, 847, 740, 741, 742, 743, 0, 744, 745, 0,
-	739, 728, 0, 746, 747, 748, 749, 750, 751, 752,
-	753, 754, 755, 0, 756, 848, 849, 850, 851, 0,
-	768, 0, 757, 759, 760, 761, 762, 852, 763, 853,
-	0, 764, 765, 766, 767, 758, 769, 770, 0, 0,
-	771, 772, 773, 774, 776, 778, 779, 780, 775, 777,
-	781, 0, 782, 0, 0, 783, 784, 785, 854, 855,
-	856, 0, 787, 788, 786, 789, 790, 793, 791, 792,
-	857, 796, 513, 797, 798, 799, 794, 795, 337, 0,
-	0, 0, 800, 801, 858, 802, 803, 804, 0, 0,
-	0, 0, 0, 0, 0, 345, 346, 348, 347, 349,
-	350, 351, 352, 0, 353, 354, 0, 0, 0, 0,
-	0, 805, 0, 0, 0, 356, 0, 355, 0, 357,
-	358, 359, 0, 360, 361, 362, 363, 364, 365, 366,
-	367, 806, 807, 0, 368, 808, 369, 809, 0, 810,
-	370, 371, 372, 373, 374, 375, 376, 377, 378, 379,
-	0, 0, 0, 380, 811, 812, 813, 0, 381, 382,
-	383, 384, 814, 0, 0, 0, 385, 386, 387, 388,
-	389, 390, 391, 392, 0, 0, 394, 395, 396, 393,
-	397, 398, 0, 399, 0, 400, 401, 402, 403, 404,
-	405, 406, 0, 407, 408, 409, 0, 410, 411, 412,
-	0, 0, 0, 0, 0, 0, 0, 413, 414, 415,
-	416, 417, 0, 418, 420, 421, 815, 422, 816, 0,
-	425, 427, 419, 423, 0, 426, 424, 428, 429, 0,
-	430, 431, 432, 433, 0, 0, 434, 435, 436, 0,
-	437, 438, 440, 439, 0, 441, 442, 443, 0, 444,
-	445, 817, 446, 447, 448, 450, 452, 449, 451, 453,
-	454, 455, 456, 457, 818, 819, 458, 459, 0, 340,
-	0, 0, 0, 0, 0, 460, 461, 462, 820, 0,
-	0, 0, 463, 0, 465, 469, 466, 467, 468, 470,
-	0, 464, 471, 472, 0, 0, 473, 474, 475, 821,
-	822, 476, 477, 478, 479, 480, 481, 482, 483, 484,
-	0, 485, 486, 823, 0, 824, 487, 0, 488, 489,
-	490, 491, 492, 493, 494, 825, 826, 827, 595, 0,
-	495, 496, 497, 0, 498, 499, 500, 501, 502, 503,
-	504, 0, 0, 0, 505, 506, 507, 508, 0, 342,
-	341, 343, 0, 828, 509, 596, 510, 829, 830, 0,
-	831, 0, 511, 512, 515, 0, 832, 0, 514, 516,
-	517, 0, 518, 0, 0, 0, 519, 520, 521, 522,
-	523, 524, 525, 0, 526, 528, 527, 0, 530, 833,
-	529, 0, 531, 532, 0, 0, 533, 534, 535, 536,
-	537, 538, 541, 0, 0, 539, 540, 542, 543, 0,
-	544, 545, 547, 550, 546, 548, 549, 551, 552, 565,
-	566, 553, 554, 555, 556, 557, 558, 559, 560, 561,
-	562, 563, 564, 568, 0, 567, 0, 569, 570, 571,
-	572, 573, 581, 583, 584, 579, 580, 582, 585, 586,
-	588, 589, 576, 577, 578, 0, 587, 574, 0, 575,
-	344, 0, 590, 591, 592, 593, 0, 834, 594, 835,
-	597, 598, 0, 0, 599, 0, 600, 0, 0, 602,
-	603, 604, 0, 0, 605, 606, 836, 0, 607, 0,
-	837, 608, 609, 601, 610, 611, 612, 613, 614, 615,
-	616, 617, 618, 619, 0, 620, 621, 838, 622, 623,
-	624, 839, 625, 626, 627, 840, 628, 841, 629, 630,
-	0, 631, 632, 633, 0, 634, 635, 636, 637, 638,
-	639, 640, 641, 642, 643, 842, 644, 645, 647, 646,
-	648, 649, 0, 650, 0, 651, 652, 653, 0, 0,
-	0, 0, 0, 654, 655, 657, 0, 658, 659, 660,
-	661, 662, 656, 663, 664, 665, 666, 667, 668, 669,
-	0, 671, 672, 670, 673, 674, 0, 675, 676, 677,
-	678, 679, 843, 680, 0, 681, 682, 690, 691, 692,
-	683, 684, 686, 693, 685, 694, 695, 696, 697, 699,
-	698, 0, 701, 702, 700, 703, 704, 705, 706, 0,
-	707, 844, 708, 687, 688, 709, 710, 711, 0, 712,
-	713, 714, 715, 716, 717, 718, 719, 720, 845, 0,
-	721, 0, 722, 723, 724, 725, 726, 727, 729, 689,
-	730, 731, 732, 737, 738, 846, 733, 734, 735, 736,
-	847, 740, 741, 742, 743, 0, 744, 745, 0, 739,
-	728, 0, 746, 747, 748, 749, 750, 751, 752, 753,
-	754, 755, 0, 756, 848, 849, 850, 851, 0, 768,
-	0, 757, 759, 760, 761, 762, 852, 763, 853, 0,
-	764, 765, 766, 767, 758, 769, 770, 0, 0, 771,
-	772, 773, 774, 776, 778, 779, 780, 775, 777, 781,
-	0, 782, 0, 0, 783, 784, 785, 854, 855, 856,
-	0, 787, 788, 786, 789, 790, 793, 791, 792, 857,
-	796, 513, 797, 798, 799, 794, 795, 337, 0, 0,
-	0, 800, 801, 858, 802, 803, 804, 0, 0, 0,
-	0, 0, 0, 0, 345, 346, 348, 347, 349, 350,
-	351, 352, 0, 353, 354, 0, 0, 0, 0, 0,
-	805, 0, 0, 0, 356, 0, 355, 0, 357, 358,
-	359, 0, 360, 361, 362, 363, 364, 365, 366, 367,
-	806, 807, 0, 368, 808, 369, 809, 0, 810, 370,
-	371, 372, 373, 374, 375, 376, 377, 378, 379, 0,
-	0, 0, 380, 811, 812, 813, 0, 381, 382, 383,
-	384, 814, 0, 0, 0, 385, 386, 387, 388, 389,
-	390, 391, 392, 0, 0, 394, 395, 396, 393, 397,
-	398, 0, 399, 0, 400, 401, 402, 403, 404, 405,
-	406, 0, 407, 408, 409, 0, 410, 411, 412, 0,
-	0, 0, 0, 0, 0, 0, 413, 414, 415, 416,
-	417, 0, 418, 420, 421, 815, 422, 816, 0, 425,
-	427, 419, 423, 0, 426, 424, 428, 429, 0, 430,
-	431, 432, 433, 0, 0, 434, 435, 436, 0, 437,
-	438, 440, 439, 0, 441, 442, 443, 0, 444, 445,
-	817, 446, 447, 448, 450, 452, 449, 451, 453, 454,
-	455, 456, 457, 818, 819, 458, 459, 0, 340, 0,
-	0, 0, 0, 0, 460, 461, 462, 820, 0, 0,
-	0, 463, 0, 465, 469, 466, 467, 468, 470, 0,
-	464, 471, 472, 0, 0, 473, 474, 475, 821, 822,
-	476, 477, 478, 479, 480, 481, 482, 483, 484, 0,
-	485, 486, 823, 0, 824, 487, 0, 488, 489, 490,
-	491, 492, 493, 494, 2947, 826, 827, 595, 0, 495,
-	496, 497, 0, 498, 499, 500, 501, 502, 503, 504,
-	0, 0, 0, 505, 506, 507, 508, 0, 342, 341,
-	343, 0, 828, 509, 596, 510, 829, 830, 0, 831,
-	0, 511, 512, 515, 0, 832, 0, 514, 516, 517,
-	0, 518, 0, 0, 0, 519, 520, 521, 522, 523,
-	524, 525, 0, 526, 528, 527, 0, 530, 833, 529,
-	0, 531, 532, 0, 0, 533, 534, 535, 536, 537,
-	538, 541, 0, 0, 539, 540, 542, 543, 0, 544,
-	545, 547, 550, 546, 548, 549, 551, 552, 565, 566,
-	553, 554, 555, 556, 557, 558, 559, 560, 561, 562,
-	563, 564, 568, 0, 567, 0, 569, 570, 571, 572,
-	573, 581, 583, 584, 579, 580, 582, 585, 586, 588,
-	589, 576, 577, 578, 0, 587, 574, 0, 575, 344,
-	0, 590, 591, 592, 593, 0, 834, 594, 835, 597,
-	598, 0, 0, 599, 0, 600, 0, 0, 602, 603,
-	604, 0, 0, 605, 606, 836, 0, 607, 0, 837,
-	608, 609, 601, 610, 611, 612, 613, 614, 615, 616,
-	617, 618, 619, 0, 620, 621, 838, 622, 623, 624,
-	839, 625, 626, 627, 840, 628, 841, 629, 630, 0,
-	631, 632, 633, 0, 634, 635, 636, 637, 638, 639,
-	640, 641, 642, 643, 842, 644, 645, 647, 646, 648,
-	649, 0, 650, 0, 651, 652, 653, 0, 0, 0,
-	0, 0, 654, 655, 657, 0, 658, 659, 660, 661,
-	662, 656, 663, 664, 665, 666, 667, 668, 669, 0,
-	671, 672, 670, 673, 674, 0, 675, 676, 677, 678,
-	679, 843, 680, 0, 681, 682, 690, 691, 692, 683,
-	684, 686, 693, 685, 694, 695, 696, 697, 699, 698,
-	0, 701, 702, 700, 703, 704, 705, 706, 0, 707,
-	844, 708, 687, 688, 709, 710, 711, 0, 712, 713,
-	714, 715, 716, 717, 718, 719, 720, 845, 0, 721,
-	0, 722, 723, 724, 725, 726, 727, 729, 689, 730,
-	731, 732, 737, 738, 846, 733, 734, 735, 736, 847,
-	740, 741, 742, 743, 0, 744, 745, 0, 739, 728,
-	0, 746, 747, 748, 749, 750, 751, 752, 753, 754,
-	755, 0, 756, 848, 849, 850, 851, 0, 768, 0,
-	757, 759, 760, 761, 762, 852, 763, 853, 0, 764,
-	765, 766, 767, 758, 769, 770, 0, 0, 771, 772,
-	773, 774, 776, 778, 779, 780, 775, 777, 781, 0,
-	782, 0, 0, 783, 784, 785, 854, 855, 856, 0,
-	787, 788, 786, 789, 790, 793, 791, 792, 857, 796,
-	513, 797, 798, 799, 794, 795, 337, 0, 0, 0,
-	800, 801, 858, 802, 803, 804, 0, 0, 0, 0,
-	0, 0, 0, 345, 346, 348, 347, 349, 350, 351,
-	352, 0, 353, 354, 0, 0, 0, 0, 0, 805,
-	0, 0, 0, 356, 0, 355, 0, 357, 358, 359,
-	0, 360, 361, 362, 363, 364, 365, 366, 367, 806,
-	807, 0, 368, 808, 369, 809, 0, 810, 370, 371,
-	372, 373, 374, 375, 376, 377, 378, 379, 0, 0,
-	0, 380, 811, 812, 813, 0, 381, 382, 383, 384,
-	814, 0, 0, 0, 385, 386, 387, 388, 389, 390,
-	391, 392, 0, 0, 394, 395, 396, 393, 397, 398,
-	0, 399, 0, 400, 401, 402, 403, 404, 405, 406,
-	0, 407, 408, 409, 0, 410, 411, 412, 0, 0,
-	0, 0, 0, 0, 0, 413, 414, 415, 2631, 417,
-	0, 418, 420, 421, 815, 422, 816, 0, 425, 427,
-	419, 423, 0, 426, 424, 428, 429, 0, 430, 431,
-	432, 433, 0, 0, 434, 435, 436, 0, 437, 438,
-	440, 439, 0, 441, 442, 443, 0, 444, 445, 817,
-	446, 447, 448, 450, 452, 449, 451, 453, 454, 455,
-	456, 457, 818, 819, 458, 459, 0, 340, 0, 0,
-	0, 0, 0, 460, 461, 462, 820, 0, 0, 0,
-	463, 0, 465, 469, 466, 467, 468, 470, 0, 464,
-	471, 472, 0, 0, 473, 474, 475, 821, 822, 476,
-	477, 478, 479, 480, 481, 482, 483, 484, 0, 485,
-	486, 823, 0, 824, 487, 0, 488, 489, 490, 491,
-	492, 493, 494, 825, 826, 827, 595, 0, 495, 496,
-	497, 0, 498, 499, 500, 501, 502, 503, 504, 0,
-	0, 0, 505, 506, 507, 508, 0, 342, 341, 343,
-	0, 828, 509, 596, 510, 829, 830, 0, 831, 0,
-	511, 512, 515, 0, 832, 0, 514, 516, 517, 0,
-	518, 0, 0, 0, 519, 520, 521, 522, 523, 524,
-	525, 0, 526, 528, 527, 0, 530, 833, 529, 0,
-	531, 532, 0, 0, 533, 534, 535, 536, 537, 538,
-	541, 0, 0, 539, 540, 542, 543, 0, 544, 545,
-	547, 550, 546, 548, 549, 551, 552, 565, 566, 553,
-	554, 555, 556, 557, 558, 559, 560, 561, 562, 563,
-	564, 568, 0, 567, 0, 569, 570, 571, 572, 573,
-	581, 583, 584, 579, 580, 582, 585, 586, 588, 589,
-	576, 577, 578, 0, 587, 574, 0, 575, 344, 0,
-	590, 591, 592, 593, 0, 834, 594, 835, 597, 598,
-	0, 0, 599, 0, 600, 0, 0, 602, 603, 604,
-	0, 0, 605, 606, 836, 0, 607, 0, 837, 608,
-	609, 601, 610, 611, 612, 613, 614, 615, 616, 617,
-	618, 619, 0, 620, 621, 838, 622, 623, 624, 839,
-	625, 626, 627, 840, 628, 841, 629, 630, 0, 631,
-	632, 633, 0, 634, 635, 636, 637, 638, 639, 640,
-	641, 642, 643, 842, 644, 645, 647, 646, 648, 649,
-	0, 650, 0, 651, 652, 653, 0, 0, 0, 0,
-	0, 654, 655, 657, 0, 658, 659, 660, 661, 662,
-	656, 663, 664, 665, 666, 667, 668, 669, 0, 671,
-	672, 670, 673, 674, 0, 675, 676, 677, 678, 679,
-	843, 680, 0, 681, 682, 690, 691, 692, 683, 684,
-	686, 693, 685, 694, 695, 696, 697, 699, 698, 0,
-	701, 702, 700, 703, 704, 705, 706, 0, 707, 844,
-	708, 687, 688, 709, 710, 711, 0, 712, 713, 714,
-	715, 716, 717, 718, 719, 720, 845, 0, 721, 0,
-	722, 723, 724, 725, 726, 727, 729, 689, 730, 731,
-	732, 737, 738, 846, 733, 734, 735, 736, 847, 740,
-	741, 742, 743, 0, 744, 745, 0, 739, 728, 0,
-	746, 747, 748, 749, 750, 751, 752, 753, 754, 755,
-	0, 756, 848, 849, 850, 851, 0, 768, 0, 757,
-	759, 760, 761, 762, 852, 763, 853, 0, 764, 765,
-	766, 767, 758, 769, 770, 0, 0, 771, 772, 773,
-	774, 776, 778, 779, 780, 775, 777, 781, 0, 782,
-	0, 0, 783, 784, 785, 854, 855, 856, 0, 787,
-	788, 786, 789, 790, 793, 791, 792, 857, 796, 513,
-	797, 798, 799, 794, 795, 337, 0, 0, 0, 800,
-	801, 858, 802, 803, 804, 0, 0, 0, 0, 0,
-	0, 0, 345, 346, 348, 347, 349, 350, 351, 352,
-	0, 353, 354, 0, 0, 0, 0, 0, 805, 0,
-	0, 0, 356, 0, 355, 0, 357, 358, 359, 0,
-	360, 361, 362, 363, 364, 365, 366, 367, 806, 807,
-	0, 368, 808, 369, 809, 0, 810, 370, 371, 372,
-	373, 374, 375, 376, 377, 378, 379, 0, 0, 0,
-	380, 811, 812, 813, 0, 381, 382, 383, 384, 814,
-	0, 0, 0, 385, 386, 387, 388, 389, 390, 391,
-	392, 0, 0, 394, 395, 396, 393, 397, 398, 0,
-	399, 0, 400, 401, 402, 403, 404, 405, 406, 0,
-	407, 408, 409, 0, 410, 411, 412, 0, 0, 0,
-	0, 0, 0, 0, 413, 414, 415, 2629, 417, 0,
-	418, 420, 421, 815, 422, 816, 0, 425, 427, 419,
-	423, 0, 426, 424, 428, 429, 0, 430, 431, 432,
-	433, 0, 0, 434, 435, 436, 0, 437, 438, 440,
-	439, 0, 441, 442, 443, 0, 444, 445, 817, 446,
-	447, 448, 450, 452, 449, 451, 453, 454, 455, 456,
-	457, 818, 819, 458, 459, 0, 340, 0, 0, 0,
-	0, 0, 460, 461, 462, 820, 0, 0, 0, 463,
-	0, 465, 469, 466, 467, 468, 470, 0, 464, 471,
-	472, 0, 0, 473, 474, 475, 821, 822, 476, 477,
-	478, 479, 480, 481, 482, 483, 484, 0, 485, 486,
-	823, 0, 824, 487, 0, 488, 489, 490, 491, 492,
-	493, 494, 825, 826, 827, 595, 0, 495, 496, 497,
-	0, 498, 499, 500, 501, 502, 503, 504, 0, 0,
-	0, 505, 506, 507, 508, 0, 342, 341, 343, 0,
-	828, 509, 596, 510, 829, 830, 0, 831, 0, 511,
-	512, 515, 0, 832, 0, 514, 516, 517, 0, 518,
-	0, 0, 0, 519, 520, 521, 522, 523, 524, 525,
-	0, 526, 528, 527, 0, 530, 833, 529, 0, 531,
-	532, 0, 0, 533, 534, 535, 536, 537, 538, 541,
-	0, 0, 539, 540, 542, 543, 0, 544, 545, 547,
-	550, 546, 548, 549, 551, 552, 565, 566, 553, 554,
-	555, 556, 557, 558, 559, 560, 561, 562, 563, 564,
-	568, 0, 567, 0, 569, 570, 571, 572, 573, 581,
-	583, 584, 579, 580, 582, 585, 586, 588, 589, 576,
-	577, 578, 0, 587, 574, 0, 575, 344, 0, 590,
-	591, 592, 593, 0, 834, 594, 835, 597, 598, 0,
-	0, 599, 0, 600, 0, 0, 602, 603, 604, 0,
-	0, 605, 606, 836, 0, 607, 0, 837, 608, 609,
-	601, 610, 611, 612, 613, 614, 615, 616, 617, 618,
-	619, 0, 620, 621, 838, 622, 623, 624, 839, 625,
-	626, 627, 840, 628, 841, 629, 630, 0, 631, 632,
-	633, 0, 634, 635, 636, 637, 638, 639, 640, 641,
-	642, 643, 842, 644, 645, 647, 646, 648, 649, 0,
-	650, 0, 651, 652, 653, 0, 0, 0, 0, 0,
-	654, 655, 657, 0, 658, 659, 660, 661, 662, 656,
-	663, 664, 665, 666, 667, 668, 669, 0, 671, 672,
-	670, 673, 674, 0, 675, 676, 677, 678, 679, 843,
-	680, 0, 681, 682, 690, 691, 692, 683, 684, 686,
-	693, 685, 694, 695, 696, 697, 699, 698, 0, 701,
-	702, 700, 703, 704, 705, 706, 0, 707, 844, 708,
-	687, 688, 709, 710, 711, 0, 712, 713, 714, 715,
-	716, 717, 718, 719, 720, 845, 0, 721, 0, 722,
-	723, 724, 725, 726, 727, 729, 689, 730, 731, 732,
-	737, 738, 846, 733, 734, 735, 736, 847, 740, 741,
-	742, 743, 0, 744, 745, 0, 739, 728, 0, 746,
-	747, 748, 749, 750, 751, 752, 753, 754, 755, 0,
-	756, 848, 849, 850, 851, 0, 768, 0, 757, 759,
-	760, 761, 762, 852, 763, 853, 0, 764, 765, 766,
-	767, 758, 769, 770, 0, 0, 771, 772, 773, 774,
-	776, 778, 779, 780, 775, 777, 781, 0, 782, 0,
-	0, 783, 784, 785, 854, 855, 856, 0, 787, 788,
-	786, 789, 790, 793, 791, 792, 857, 796, 513, 797,
-	798, 799, 794, 795, 337, 0, 0, 0, 800, 801,
-	858, 802, 803, 804, 0, 0, 0, 0, 0, 0,
-	0, 345, 346, 348, 347, 349, 350, 351, 352, 0,
-	353, 354, 0, 0, 0, 0, 0, 805, 0, 0,
-	0, 356, 0, 355, 0, 357, 358, 359, 0, 360,
-	361, 362, 363, 364, 365, 366, 367, 806, 807, 0,
-	368, 808, 369, 809, 0, 810, 370, 371, 372, 373,
-	374, 375, 376, 377, 378, 379, 0, 0, 0, 380,
-	811, 812, 813, 0, 381, 382, 383, 384, 814, 0,
-	0, 0, 385, 386, 387, 388, 389, 390, 391, 392,
-	0, 0, 394, 395, 396, 393, 397, 398, 0, 399,
-	0, 400, 401, 402, 403, 404, 405, 406, 0, 407,
-	408, 409, 0, 410, 411, 412, 0, 0, 0, 0,
-	0, 0, 0, 413, 414, 415, 2627, 417, 0, 418,
-	420, 421, 815, 422, 816, 0, 425, 427, 419, 423,
-	0, 426, 424, 428, 429, 0, 430, 431, 432, 433,
-	0, 0, 434, 435, 436, 0, 437, 438, 440, 439,
-	0, 441, 442, 443, 0, 444, 445, 817, 446, 447,
-	448, 450, 452, 449, 451, 453, 454, 455, 456, 457,
-	818, 819, 458, 459, 0, 340, 0, 0, 0, 0,
-	0, 460, 461, 462, 820, 0, 0, 0, 463, 0,
-	465, 469, 466, 467, 468, 470, 0, 464, 471, 472,
-	0, 0, 473, 474, 475, 821, 822, 476, 477, 478,
-	479, 480, 481, 482, 483, 484, 0, 485, 486, 823,
-	0, 824, 487, 0, 488, 489, 490, 491, 492, 493,
-	494, 825, 826, 827, 595, 0, 495, 496, 497, 0,
-	498, 499, 500, 501, 502, 503, 504, 0, 0, 0,
-	505, 506, 507, 508, 0, 342, 341, 343, 0, 828,
-	509, 596, 510, 829, 830, 0, 831, 0, 511, 512,
-	515, 0, 832, 0, 514, 516, 517, 0, 518, 0,
-	0, 0, 519, 520, 521, 522, 523, 524, 525, 0,
-	526, 528, 527, 0, 530, 833, 529, 0, 531, 532,
-	0, 0, 533, 534, 535, 536, 537, 538, 541, 0,
-	0, 539, 540, 542, 543, 0, 544, 545, 547, 550,
-	546, 548, 549, 551, 552, 565, 566, 553, 554, 555,
-	556, 557, 558, 559, 560, 561, 562, 563, 564, 568,
-	0, 567, 0, 569, 570, 571, 572, 573, 581, 583,
-	584, 579, 580, 582, 585, 586, 588, 589, 576, 577,
-	578, 0, 587, 574, 0, 575, 344, 0, 590, 591,
-	592, 593, 0, 834, 594, 835, 597, 598, 0, 0,
-	599, 0, 600, 0, 0, 602, 603, 604, 0, 0,
-	605, 606, 836, 0, 607, 0, 837, 608, 609, 601,
-	610, 611, 612, 613, 614, 615, 616, 617, 618, 619,
-	0, 620, 621, 838, 622, 623, 624, 839, 625, 626,
-	627, 840, 628, 841, 629, 630, 0, 631, 632, 633,
-	0, 634, 635, 636, 637, 638, 639, 640, 641, 642,
-	643, 842, 644, 645, 647, 646, 648, 649, 0, 650,
-	0, 651, 652, 653, 0, 0, 0, 0, 0, 654,
-	655, 657, 0, 658, 659, 660, 661, 662, 656, 663,
-	664, 665, 666, 667, 668, 669, 0, 671, 672, 670,
-	673, 674, 0, 675, 676, 677, 678, 679, 843, 680,
-	0, 681, 682, 690, 691, 692, 683, 684, 686, 693,
-	685, 694, 695, 696, 697, 699, 698, 0, 701, 702,
-	700, 703, 704, 705, 706, 0, 707, 844, 708, 687,
-	688, 709, 710, 711, 0, 712, 713, 714, 715, 716,
-	717, 718, 719, 720, 845, 0, 721, 0, 722, 723,
-	724, 725, 726, 727, 729, 689, 730, 731, 732, 737,
-	738, 846, 733, 734, 735, 736, 847, 740, 741, 742,
-	743, 0, 744, 745, 0, 739, 728, 0, 746, 747,
-	748, 749, 750, 751, 752, 753, 754, 755, 0, 756,
-	848, 849, 850, 851, 0, 768, 0, 757, 759, 760,
-	761, 762, 852, 763, 853, 0, 764, 765, 766, 767,
-	758, 769, 770, 0, 0, 771, 772, 773, 774, 776,
-	778, 779, 780, 775, 777, 781, 0, 782, 0, 0,
-	783, 784, 785, 854, 855, 856, 0, 787, 788, 786,
-	789, 790, 793, 791, 792, 857, 796, 513, 797, 798,
-	799, 794, 795, 337, 0, 0, 0, 800, 801, 858,
-	802, 803, 804, 0, 0, 0, 0, 0, 0, 0,
-	345, 346, 348, 347, 349, 350, 351, 352, 0, 353,
-	354, 0, 0, 0, 0, 0, 805, 0, 0, 0,
-	356, 0, 355, 0, 357, 358, 359, 0, 360, 361,
-	362, 363, 364, 365, 366, 367, 806, 807, 0, 368,
-	808, 369, 809, 0, 810, 370, 371, 372, 373, 374,
-	375, 376, 377, 378, 379, 0, 0, 0, 380, 811,
-	812, 813, 0, 381, 382, 383, 384, 814, 0, 0,
-	0, 385, 386, 387, 388, 389, 390, 391, 392, 0,
-	0, 394, 395, 396, 393, 397, 398, 0, 399, 0,
-	400, 401, 402, 403, 404, 405, 406, 0, 407, 408,
-	409, 0, 410, 411, 412, 0, 0, 0, 0, 0,
-	0, 0, 413, 414, 415, 416, 417, 0, 418, 420,
-	421, 815, 422, 816, 0, 425, 427, 419, 423, 0,
-	426, 424, 428, 429, 0, 430, 431, 432, 433, 0,
-	0, 434, 435, 436, 0, 437, 438, 440, 439, 0,
-	441, 442, 443, 0, 444, 445, 817, 446, 447, 448,
-	450, 452, 449, 451, 453, 454, 455, 456, 457, 818,
-	819, 458, 459, 0, 340, 0, 0, 0, 0, 0,
-	460, 461, 462, 820, 0, 0, 0, 463, 0, 465,
-	469, 466, 467, 468, 470, 0, 464, 471, 472, 0,
-	0, 473, 474, 475, 821, 822, 476, 477, 478, 479,
-	480, 481, 482, 483, 484, 0, 485, 486, 823, 0,
-	824, 487, 0, 488, 489, 490, 491, 492, 493, 494,
-	2509, 826, 827, 595, 0, 495, 496, 497, 0, 498,
-	499, 500, 501, 502, 503, 504, 0, 0, 0, 505,
-	506, 507, 508, 0, 342, 341, 343, 0, 828, 509,
-	596, 510, 829, 830, 0, 831, 0, 511, 512, 515,
-	0, 832, 0, 514, 516, 517, 0, 518, 0, 0,
-	0, 519, 520, 521, 522, 523, 524, 525, 0, 526,
-	528, 527, 0, 530, 833, 529, 0, 531, 532, 0,
-	0, 533, 534, 535, 536, 537, 538, 541, 0, 0,
-	539, 540, 542, 543, 0, 544, 545, 547, 550, 546,
-	548, 549, 551, 552, 565, 566, 553, 554, 555, 556,
-	557, 558, 559, 560, 561, 562, 563, 564, 568, 0,
-	567, 0, 569, 570, 571, 572, 573, 581, 583, 584,
-	579, 580, 582, 585, 586, 588, 589, 576, 577, 578,
-	0, 587, 574, 0, 575, 344, 0, 590, 591, 592,
-	593, 0, 834, 594, 835, 597, 598, 0, 0, 599,
-	0, 600, 0, 0, 602, 603, 604, 0, 0, 605,
-	606, 836, 0, 607, 0, 837, 608, 609, 601, 610,
-	611, 612, 613, 614, 615, 616, 617, 618, 619, 0,
-	620, 621, 838, 622, 623, 624, 839, 625, 626, 627,
-	840, 628, 841, 629, 630, 0, 631, 632, 633, 0,
-	634, 635, 636, 637, 638, 639, 640, 641, 642, 643,
-	842, 644, 645, 647, 646, 648, 649, 0, 650, 0,
-	651, 652, 653, 0, 0, 0, 0, 0, 654, 655,
-	657, 0, 658, 659, 660, 661, 662, 656, 663, 664,
-	665, 666, 667, 668, 669, 0, 671, 672, 670, 673,
-	674, 0, 675, 676, 677, 678, 679, 843, 680, 0,
-	681, 682, 690, 691, 692, 683, 684, 686, 693, 685,
-	694, 695, 696, 697, 699, 698, 0, 701, 702, 700,
-	703, 704, 705, 706, 0, 707, 844, 708, 687, 688,
-	709, 710, 711, 0, 712, 713, 714, 715, 716, 717,
-	718, 719, 720, 845, 0, 721, 0, 722, 723, 724,
-	725, 726, 727, 729, 689, 730, 731, 732, 737, 738,
-	846, 733, 734, 735, 736, 847, 740, 741, 742, 743,
-	0, 744, 745, 0, 739, 728, 0, 746, 747, 748,
-	749, 750, 751, 752, 753, 754, 755, 0, 756, 848,
-	849, 850, 851, 0, 768, 0, 757, 759, 760, 761,
-	762, 852, 763, 853, 0, 764, 765, 766, 767, 758,
-	769, 770, 0, 0, 771, 772, 773, 774, 776, 778,
-	779, 780, 775, 777, 781, 0, 782, 0, 0, 783,
-	784, 785, 854, 855, 856, 0, 787, 788, 786, 789,
-	790, 793, 791, 792, 857, 796, 513, 797, 798, 799,
-	794, 795, 337, 0, 0, 0, 800, 801, 858, 802,
-	803, 804, 0, 0, 0, 0, 0, 0, 0, 345,
-	346, 348, 347, 349, 350, 351, 352, 0, 353, 354,
-	0, 0, 0, 0, 0, 805, 0, 0, 0, 356,
-	0, 355, 0, 357, 358, 359, 0, 360, 361, 362,
-	363, 364, 365, 366, 367, 806, 807, 0, 368, 808,
-	369, 809, 0, 810, 370, 371, 372, 373, 374, 375,
-	376, 377, 378, 379, 0, 0, 0, 380, 811, 812,
-	813, 0, 381, 382, 383, 384, 814, 0, 0, 0,
-	385, 386, 387, 388, 389, 390, 391, 392, 0, 0,
-	394, 395, 396, 393, 397, 398, 0, 399, 0, 400,
-	401, 402, 403, 404, 405, 406, 0, 407, 408, 409,
-	0, 410, 411, 412, 0, 0, 0, 0, 0, 0,
-	0, 413, 414, 415, 416, 417, 0, 418, 420, 421,
-	815, 422, 816, 0, 425, 427, 419, 423, 0, 426,
-	424, 428, 429, 0, 430, 431, 432, 433, 0, 0,
-	434, 435, 436, 0, 437, 438, 440, 439, 0, 441,
-	442, 443, 0, 444, 445, 817, 446, 447, 448, 450,
-	452, 449, 451, 453, 454, 455, 456, 457, 818, 819,
-	458, 459, 0, 340, 0, 0, 0, 0, 0, 460,
-	461, 462, 820, 0, 0, 0, 463, 0, 465, 469,
-	466, 467, 468, 470, 0, 464, 471, 472, 0, 0,
-	473, 474, 475, 821, 822, 476, 477, 478, 479, 480,
-	481, 482, 483, 484, 0, 485, 486, 823, 0, 824,
-	487, 0, 488, 489, 490, 491, 492, 493, 494, 2503,
-	826, 827, 595, 0, 495, 496, 497, 0, 498, 499,
-	500, 501, 502, 503, 504, 0, 0, 0, 505, 506,
-	507, 508, 0, 342, 341, 343, 0, 828, 509, 596,
-	510, 829, 830, 0, 831, 0, 511, 512, 515, 0,
-	832, 0, 514, 516, 517, 0, 518, 0, 0, 0,
-	519, 520, 521, 522, 523, 524, 525, 0, 526, 528,
-	527, 0, 530, 833, 529, 0, 531, 532, 0, 0,
-	533, 534, 535, 536, 537, 538, 541, 0, 0, 539,
-	540, 542, 543, 0, 544, 545, 547, 550, 546, 548,
-	549, 551, 552, 565, 566, 553, 554, 555, 556, 557,
-	558, 559, 560, 561, 562, 563, 564, 568, 0, 567,
-	0, 569, 570, 571, 572, 573, 581, 583, 584, 579,
-	580, 582, 585, 586, 588, 589, 576, 577, 578, 0,
-	587, 574, 0, 575, 344, 0, 590, 591, 592, 593,
-	0, 834, 594, 835, 597, 598, 0, 0, 599, 0,
-	600, 0, 0, 602, 603, 604, 0, 0, 605, 606,
-	836, 0, 607, 0, 837, 608, 609, 601, 610, 611,
-	612, 613, 614, 615, 616, 617, 618, 619, 0, 620,
-	621, 838, 622, 623, 624, 839, 625, 626, 627, 840,
-	628, 841, 629, 630, 0, 631, 632, 633, 0, 634,
-	635, 636, 637, 638, 639, 640, 641, 642, 643, 842,
-	644, 645, 647, 646, 648, 649, 0, 650, 0, 651,
-	652, 653, 0, 0, 0, 0, 0, 654, 655, 657,
-	0, 658, 659, 660, 661, 662, 656, 663, 664, 665,
-	666, 667, 668, 669, 0, 671, 672, 670, 673, 674,
-	0, 675, 676, 677, 678, 679, 843, 680, 0, 681,
-	682, 690, 691, 692, 683, 684, 686, 693, 685, 694,
-	695, 696, 697, 699, 698, 0, 701, 702, 700, 703,
-	704, 705, 706, 0, 707, 844, 708, 687, 688, 709,
-	710, 711, 0, 712, 713, 714, 715, 716, 717, 718,
-	719, 720, 845, 0, 721, 0, 722, 723, 724, 725,
-	726, 727, 729, 689, 730, 731, 732, 737, 738, 846,
-	733, 734, 735, 736, 847, 740, 741, 742, 743, 0,
-	744, 745, 0, 739, 728, 0, 746, 747, 748, 749,
-	750, 751, 752, 753, 754, 755, 0, 756, 848, 849,
-	850, 851, 0, 768, 0, 757, 759, 760, 761, 762,
-	852, 763, 853, 0, 764, 765, 766, 767, 758, 769,
-	770, 0, 0, 771, 772, 773, 774, 776, 778, 779,
-	780, 775, 777, 781, 0, 782, 0, 0, 783, 784,
-	785, 854, 855, 856, 0, 787, 788, 786, 789, 790,
-	793, 791, 792, 857, 796, 513, 797, 798, 799, 794,
-	795, 925, 0, 337, 0, 800, 801, 858, 802, 803,
-	804, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	345, 346, 348, 347, 349, 923, 351, 352, 912, 353,
-	354, 0, 0, 0, 0, 0, 805, 0, 0, 0,
-	356, 0, 355, 0, 357, 358, 359, 0, 360, 361,
-	362, 363, 364, 365, 366, 367, 806, 807, 0, 368,
-	808, 369, 809, 0, 810, 370, 371, 372, 373, 374,
-	375, 376, 377, 378, 379, 0, 0, 0, 380, 811,
-	812, 813, 0, 381, 382, 383, 384, 814, 0, 0,
-	0, 385, 386, 387, 388, 389, 390, 391, 392, 0,
-	0, 394, 395, 396, 393, 397, 398, 0, 399, 0,
-	400, 401, 402, 403, 404, 405, 406, 915, 407, 408,
-	409, 0, 410, 411, 412, 0, 0, 0, 0, 0,
-	0, 0, 413, 414, 415, 416, 417, 0, 418, 420,
-	421, 815, 422, 816, 0, 425, 427, 419, 423, 0,
-	426, 424, 428, 429, 0, 430, 431, 432, 433, 0,
-	0, 434, 435, 436, 0, 437, 438, 440, 439, 0,
-	441, 442, 443, 0, 444, 445, 817, 446, 447, 448,
-	450, 452, 449, 451, 453, 454, 455, 456, 457, 818,
-	819, 458, 459, 0, 0, 0, 0, 0, 0, 0,
-	460, 461, 462, 820, 0, 0, 0, 463, 0, 465,
-	469, 466, 467, 468, 470, 0, 464, 471, 472, 0,
-	0, 473, 474, 475, 821, 822, 476, 477, 478, 479,
-	480, 481, 482, 483, 484, 921, 485, 486, 823, 0,
-	824, 487, 0, 488, 489, 490, 491, 492, 493, 494,
-	825, 826, 827, 595, 0, 495, 496, 497, 0, 498,
-	499, 500, 501, 502, 503, 504, 0, 0, 0, 505,
-	506, 507, 508, 0, 0, 0, 0, 0, 828, 509,
-	596, 510, 829, 830, 0, 831, 0, 511, 512, 515,
-	0, 832, 0, 514, 516, 517, 0, 518, 0, 0,
-	0, 519, 520, 521, 522, 523, 524, 525, 0, 526,
-	528, 527, 0, 530, 833, 529, 0, 531, 532, 0,
-	0, 533, 534, 535, 536, 537, 538, 541, 0, 0,
-	539, 540, 542, 543, 0, 544, 545, 547, 550, 546,
-	548, 549, 551, 552, 565, 566, 553, 554, 555, 556,
-	557, 558, 559, 560, 561, 562, 563, 564, 568, 0,
-	567, 0, 569, 570, 571, 572, 573, 581, 583, 584,
-	579, 580, 582, 585, 586, 588, 589, 576, 577, 578,
-	0, 587, 574, 0, 575, 0, 0, 590, 591, 592,
-	593, 0, 834, 594, 835, 597, 598, 0, 0, 599,
-	0, 600, 0, 0, 602, 603, 604, 0, 0, 605,
-	606, 836, 0, 607, 0, 837, 608, 609, 601, 610,
-	611, 612, 613, 614, 615, 616, 617, 618, 619, 0,
-	620, 621, 838, 622, 623, 624, 839, 625, 626, 627,
-	840, 628, 841, 629, 630, 0, 631, 632, 633, 0,
-	634, 635, 636, 637, 638, 639, 640, 641, 642, 643,
-	842, 644, 645, 647, 646, 648, 649, 0, 650, 0,
-	651, 652, 653, 0, 0, 0, 0, 0, 654, 655,
-	657, 0, 658, 659, 660, 661, 662, 656, 663, 664,
-	665, 666, 667, 668, 669, 0, 671, 672, 670, 673,
-	674, 0, 675, 676, 677, 678, 679, 843, 680, 0,
-	681, 682, 690, 691, 692, 683, 684, 686, 693, 685,
-	694, 695, 696, 697, 699, 698, 917, 701, 702, 700,
-	703, 704, 705, 706, 0, 707, 844, 708, 687, 688,
-	709, 710, 711, 0, 712, 713, 714, 715, 716, 717,
-	718, 719, 720, 845, 0, 721, 0, 722, 723, 724,
-	725, 726, 727, 729, 689, 730, 731, 732, 737, 738,
-	846, 733, 734, 735, 736, 847, 740, 741, 742, 743,
-	0, 744, 924, 0, 739, 728, 0, 746, 747, 748,
-	749, 750, 751, 752, 753, 754, 755, 0, 756, 848,
-	849, 850, 851, 0, 768, 0, 757, 759, 760, 761,
-	762, 852, 763, 853, 0, 764, 765, 766, 767, 758,
-	769, 770, 0, 0, 771, 772, 773, 774, 776, 778,
-	779, 780, 775, 777, 781, 0, 782, 0, 0, 783,
-	784, 785, 854, 855, 856, 0, 787, 788, 786, 789,
-	790, 793, 791, 792, 857, 796, 513, 797, 798, 799,
-	794, 795, 911, 0, 337, 0, 800, 801, 858, 802,
-	803, 804, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 345, 346, 348, 347, 349, 350, 351, 352, 912,
-	353, 354, 0, 0, 0, 0, 0, 805, 0, 0,
-	0, 356, 0, 355, 0, 357, 358, 359, 0, 360,
-	361, 362, 363, 364, 365, 366, 367, 806, 807, 0,
-	368, 808, 369, 809, 0, 810, 370, 371, 372, 373,
-	374, 375, 376, 377, 378, 379, 0, 0, 0, 380,
-	811, 812, 813, 0, 381, 382, 383, 384, 814, 0,
-	0, 0, 385, 386, 387, 388, 389, 390, 391, 392,
-	0, 0, 394, 395, 396, 393, 397, 398, 0, 399,
-	0, 400, 401, 402, 403, 404, 405, 406, 915, 407,
-	408, 409, 0, 410, 411, 412, 0, 0, 0, 0,
-	0, 0, 0, 413, 414, 415, 416, 417, 0, 418,
-	420, 421, 815, 422, 816, 0, 425, 427, 419, 423,
-	0, 426, 424, 428, 429, 0, 430, 431, 432, 433,
-	0, 0, 434, 435, 436, 0, 437, 438, 440, 439,
-	0, 441, 442, 443, 0, 444, 445, 817, 446, 447,
-	448, 450, 452, 449, 451, 453, 454, 455, 456, 457,
-	818, 819, 458, 459, 0, 0, 0, 0, 0, 0,
-	0, 460, 461, 462, 820, 0, 0, 0, 463, 0,
-	465, 469, 466, 467, 468, 470, 0, 464, 471, 472,
-	0, 0, 473, 474, 475, 821, 822, 476, 477, 478,
-	479, 480, 481, 482, 483, 484, 916, 485, 486, 823,
-	0, 824, 487, 0, 488, 489, 490, 491, 492, 493,
-	494, 825, 826, 827, 595, 0, 495, 496, 497, 0,
-	498, 499, 500, 501, 502, 503, 504, 0, 0, 0,
-	505, 506, 507, 508, 0, 0, 0, 0, 0, 828,
-	509, 596, 510, 829, 830, 0, 831, 0, 511, 512,
-	515, 0, 832, 0, 514, 516, 517, 0, 518, 0,
-	0, 0, 519, 520, 521, 522, 523, 524, 525, 0,
-	526, 528, 527, 0, 530, 833, 529, 0, 531, 532,
-	0, 0, 533, 534, 535, 536, 537, 538, 541, 0,
-	0, 539, 540, 542, 543, 0, 544, 545, 547, 550,
-	546, 548, 549, 551, 552, 565, 566, 553, 554, 555,
-	556, 557, 558, 559, 560, 561, 562, 563, 564, 568,
-	0, 567, 0, 569, 570, 571, 572, 573, 581, 583,
-	584, 579, 580, 582, 585, 586, 588, 589, 576, 577,
-	578, 0, 587, 574, 0, 575, 0, 0, 590, 591,
-	592, 593, 0, 834, 594, 835, 597, 598, 0, 0,
-	599, 0, 600, 0, 0, 602, 603, 604, 0, 0,
-	605, 606, 836, 0, 607, 0, 837, 608, 609, 601,
-	610, 611, 612, 613, 614, 615, 616, 617, 618, 619,
-	0, 620, 621, 838, 622, 623, 624, 839, 625, 626,
-	627, 840, 628, 841, 629, 630, 0, 631, 632, 633,
-	0, 634, 635, 636, 637, 638, 639, 640, 641, 642,
-	643, 842, 644, 645, 647, 646, 648, 649, 0, 650,
-	0, 651, 652, 653, 0, 0, 0, 0, 0, 654,
-	655, 657, 0, 658, 659, 660, 661, 662, 656, 663,
-	664, 665, 666, 667, 668, 669, 0, 671, 672, 670,
-	673, 674, 0, 675, 676, 677, 678, 679, 843, 680,
-	0, 681, 682, 690, 691, 692, 683, 684, 686, 693,
-	685, 694, 695, 696, 697, 699, 698, 917, 701, 702,
-	700, 703, 704, 705, 706, 0, 707, 844, 708, 687,
-	688, 709, 710, 711, 0, 712, 713, 714, 715, 716,
-	717, 718, 719, 720, 845, 0, 721, 0, 722, 723,
-	724, 725, 726, 727, 729, 689, 730, 731, 732, 737,
-	738, 846, 733, 734, 735, 736, 847, 740, 741, 742,
-	743, 0, 744, 910, 0, 739, 728, 0, 746, 747,
-	748, 749, 750, 751, 752, 753, 754, 755, 0, 756,
-	848, 849, 850, 851, 0, 768, 0, 757, 759, 760,
-	761, 762, 852, 763, 853, 0, 764, 765, 766, 767,
-	758, 769, 770, 0, 0, 771, 772, 773, 774, 776,
-	778, 779, 780, 775, 777, 781, 0, 782, 0, 0,
-	783, 784, 785, 854, 855, 856, 0, 787, 788, 786,
-	789, 790, 793, 791, 792, 857, 796, 513, 797, 798,
-	799, 794, 795, 337, 0, 0, 0, 800, 801, 858,
-	802, 803, 804, 0, 0, 0, 0, 0, 0, 0,
-	345, 346, 348, 347, 349, 350, 351, 352, 912, 353,
-	354, 0, 0, 0, 0, 0, 805, 0, 0, 0,
-	356, 0, 355, 0, 357, 358, 359, 0, 360, 361,
-	362, 363, 364, 365, 366, 367, 806, 807, 0, 368,
-	808, 369, 809, 0, 810, 370, 371, 372, 373, 374,
-	375, 376, 377, 378, 379, 0, 0, 0, 380, 811,
-	812, 813, 0, 381, 382, 383, 384, 814, 0, 0,
-	0, 385, 386, 387, 388, 389, 390, 391, 392, 0,
-	0, 394, 395, 396, 393, 397, 398, 0, 399, 0,
-	400, 401, 402, 403, 404, 405, 406, 915, 407, 408,
-	409, 0, 410, 411, 412, 0, 0, 0, 0, 0,
-	0, 0, 413, 414, 415, 416, 417, 0, 418, 420,
-	421, 815, 422, 816, 0, 425, 427, 419, 423, 0,
-	426, 424, 428, 429, 0, 430, 431, 432, 433, 0,
-	0, 434, 435, 436, 0, 437, 438, 440, 439, 0,
-	441, 442, 443, 0, 444, 445, 817, 446, 447, 448,
-	450, 452, 449, 451, 453, 454, 455, 456, 457, 818,
-	819, 458, 459, 0, 0, 0, 0, 0, 0, 0,
-	460, 461, 462, 820, 0, 0, 0, 463, 0, 465,
-	469, 466, 467, 468, 470, 0, 464, 471, 472, 0,
-	0, 473, 474, 475, 821, 822, 476, 477, 478, 479,
-	480, 481, 482, 483, 484, 916, 485, 486, 823, 0,
-	824, 487, 0, 488, 489, 490, 491, 492, 493, 494,
-	825, 826, 827, 595, 0, 495, 496, 497, 0, 498,
-	499, 500, 501, 502, 503, 504, 0, 0, 0, 505,
-	506, 507, 508, 0, 0, 0, 0, 0, 828, 509,
-	596, 510, 829, 830, 0, 831, 0, 511, 512, 515,
-	0, 832, 0, 514, 516, 517, 0, 518, 0, 0,
-	0, 519, 520, 521, 522, 523, 524, 525, 0, 526,
-	528, 527, 0, 530, 833, 529, 0, 531, 532, 0,
-	0, 533, 534, 535, 536, 537, 538, 541, 0, 0,
-	539, 540, 542, 543, 0, 544, 545, 547, 550, 546,
-	548, 549, 551, 552, 565, 566, 553, 554, 555, 556,
-	557, 558, 559, 560, 561, 562, 563, 564, 568, 0,
-	567, 0, 569, 570, 571, 572, 573, 581, 583, 584,
-	579, 580, 582, 585, 586, 588, 589, 576, 577, 578,
-	0, 587, 574, 0, 575, 0, 0, 590, 591, 592,
-	593, 0, 834, 594, 835, 597, 598, 0, 0, 599,
-	0, 600, 0, 0, 602, 603, 604, 0, 0, 605,
-	606, 836, 0, 607, 0, 837, 608, 609, 601, 610,
-	611, 612, 613, 614, 615, 616, 617, 618, 619, 0,
-	620, 621, 838, 622, 623, 624, 839, 625, 626, 627,
-	840, 628, 841, 629, 630, 0, 631, 632, 633, 0,
-	634, 635, 636, 637, 638, 639, 640, 641, 642, 643,
-	842, 644, 645, 647, 646, 648, 649, 0, 650, 0,
-	651, 652, 653, 0, 0, 0, 0, 0, 654, 655,
-	657, 0, 658, 659, 660, 661, 662, 656, 663, 664,
-	665, 666, 667, 668, 669, 0, 671, 672, 670, 673,
-	674, 0, 675, 676, 677, 678, 679, 843, 680, 0,
-	681, 682, 690, 691, 692, 683, 684, 686, 693, 685,
-	694, 695, 696, 697, 699, 698, 917, 701, 702, 700,
-	703, 704, 705, 706, 0, 707, 844, 708, 687, 688,
-	709, 710, 711, 0, 712, 713, 714, 715, 716, 717,
-	718, 719, 720, 845, 0, 721, 0, 722, 723, 724,
-	725, 726, 727, 729, 689, 730, 731, 732, 737, 738,
-	846, 733, 734, 735, 736, 847, 740, 741, 742, 743,
-	0, 744, 745, 0, 739, 728, 0, 746, 747, 748,
-	749, 750, 751, 752, 753, 754, 755, 0, 756, 848,
-	849, 850, 851, 0, 768, 0, 757, 759, 760, 761,
-	762, 852, 763, 853, 0, 764, 765, 766, 767, 758,
-	769, 770, 0, 0, 771, 772, 773, 774, 776, 778,
-	779, 780, 775, 777, 781, 0, 782, 0, 0, 783,
-	784, 785, 854, 855, 856, 0, 787, 788, 786, 789,
-	790, 793, 791, 792, 857, 796, 513, 797, 798, 799,
-	794, 795, 337, 0, 0, 0, 800, 801, 858, 802,
-	803, 804, 0, 0, 0, 0, 0, 0, 0, 345,
-	346, 348, 347, 349, 350, 351, 352, 912, 353, 354,
-	0, 0, 0, 0, 0, 805, 0, 0, 0, 356,
-	0, 355, 0, 357, 358, 359, 0, 360, 361, 362,
-	363, 364, 365, 366, 367, 806, 807, 0, 368, 808,
-	369, 809, 0, 810, 370, 371, 372, 373, 374, 375,
-	376, 377, 378, 379, 0, 0, 0, 380, 811, 812,
-	813, 0, 381, 382, 383, 384, 814, 0, 0, 0,
-	385, 386, 387, 388, 389, 390, 391, 392, 0, 0,
-	394, 395, 396, 393, 397, 398, 0, 399, 0, 400,
-	401, 402, 403, 404, 405, 406, 915, 407, 408, 409,
-	0, 410, 411, 412, 0, 0, 0, 0, 0, 0,
-	0, 413, 414, 415, 416, 417, 0, 418, 420, 421,
-	815, 422, 816, 0, 425, 427, 419, 423, 0, 426,
-	424, 428, 429, 0, 430, 431, 432, 433, 0, 0,
-	434, 435, 436, 0, 437, 438, 440, 439, 0, 441,
-	442, 443, 0, 444, 445, 817, 446, 447, 448, 450,
-	452, 449, 451, 453, 454, 455, 456, 457, 818, 819,
-	458, 459, 0, 0, 0, 0, 0, 0, 0, 460,
-	461, 462, 820, 0, 0, 0, 463, 0, 465, 469,
-	466, 467, 468, 470, 0, 464, 471, 472, 0, 0,
-	473, 474, 475, 821, 822, 476, 477, 478, 479, 480,
-	481, 482, 483, 484, 5564, 485, 486, 823, 0, 824,
-	487, 0, 488, 489, 490, 491, 492, 493, 494, 825,
-	826, 827, 595, 0, 495, 496, 497, 0, 498, 499,
-	500, 501, 502, 503, 504, 0, 0, 0, 505, 506,
-	507, 508, 0, 0, 0, 0, 0, 828, 509, 596,
-	510, 829, 830, 0, 831, 0, 511, 512, 515, 0,
-	832, 0, 514, 516, 517, 0, 518, 0, 0, 0,
-	519, 520, 521, 522, 523, 524, 525, 0, 526, 528,
-	527, 0, 530, 833, 529, 0, 531, 532, 0, 0,
-	533, 534, 535, 536, 537, 538, 541, 0, 0, 539,
-	540, 542, 543, 0, 544, 545, 547, 550, 546, 548,
-	549, 551, 552, 565, 566, 553, 554, 555, 556, 557,
-	558, 559, 560, 561, 562, 563, 564, 568, 0, 567,
-	0, 569, 570, 571, 572, 573, 581, 583, 584, 579,
-	580, 582, 585, 586, 588, 589, 576, 577, 578, 0,
-	587, 574, 0, 575, 0, 0, 590, 591, 592, 593,
-	0, 834, 594, 835, 597, 598, 0, 0, 599, 0,
-	600, 0, 0, 602, 603, 604, 0, 0, 605, 606,
-	836, 0, 607, 0, 837, 608, 609, 601, 610, 611,
-	612, 613, 614, 615, 616, 617, 618, 619, 0, 620,
-	621, 838, 622, 623, 624, 839, 625, 626, 627, 840,
-	628, 841, 629, 630, 0, 631, 632, 633, 0, 634,
-	635, 636, 637, 638, 639, 640, 641, 642, 643, 842,
-	644, 645, 647, 646, 648, 649, 0, 650, 0, 651,
-	652, 653, 0, 0, 0, 0, 0, 654, 655, 657,
-	0, 658, 659, 660, 661, 662, 656, 663, 664, 665,
-	666, 667, 668, 669, 0, 671, 672, 670, 673, 674,
-	0, 675, 676, 677, 678, 679, 843, 680, 0, 681,
-	682, 690, 691, 692, 683, 684, 686, 693, 685, 694,
-	695, 696, 697, 699, 698, 917, 701, 702, 700, 703,
-	704, 705, 706, 0, 707, 844, 708, 687, 688, 709,
-	710, 711, 0, 712, 713, 714, 715, 716, 717, 718,
-	719, 720, 845, 0, 721, 0, 722, 723, 724, 725,
-	726, 727, 729, 689, 730, 731, 732, 737, 738, 846,
-	733, 734, 735, 736, 847, 740, 741, 742, 743, 0,
-	744, 745, 0, 739, 728, 0, 746, 747, 748, 749,
-	750, 751, 752, 753, 754, 755, 0, 756, 848, 849,
-	850, 851, 0, 768, 0, 757, 759, 760, 761, 762,
-	852, 763, 853, 0, 764, 765, 766, 767, 758, 769,
-	770, 0, 0, 771, 772, 773, 774, 776, 778, 779,
-	780, 775, 777, 781, 0, 782, 0, 0, 783, 784,
-	785, 854, 855, 856, 0, 787, 788, 786, 789, 790,
-	793, 791, 792, 857, 796, 513, 797, 798, 799, 794,
-	795, 337, 0, 0, 0, 800, 801, 858, 802, 803,
-	804, 0, 0, 0, 0, 0, 0, 0, 345, 346,
-	348, 347, 349, 350, 351, 352, 912, 353, 354, 0,
-	0, 0, 0, 0, 805, 0, 0, 0, 356, 0,
-	355, 0, 357, 358, 359, 0, 360, 361, 362, 363,
-	364, 365, 366, 367, 806, 807, 0, 368, 808, 369,
-	809, 0, 810, 370, 371, 372, 373, 374, 375, 376,
-	377, 378, 379, 0, 0, 0, 380, 811, 812, 813,
-	0, 381, 382, 383, 384, 814, 0, 0, 0, 385,
-	386, 387, 388, 389, 390, 391, 392, 0, 0, 394,
-	395, 396, 393, 397, 398, 0, 399, 0, 400, 401,
-	402, 403, 404, 405, 406, 915, 407, 408, 409, 0,
-	410, 411, 412, 0, 0, 0, 0, 0, 0, 0,
-	413, 414, 415, 416, 417, 0, 418, 420, 421, 815,
-	422, 816, 0, 425, 427, 419, 423, 0, 426, 424,
-	428, 429, 0, 430, 431, 432, 433, 0, 0, 434,
-	435, 436, 0, 437, 438, 440, 439, 0, 441, 442,
-	443, 0, 444, 445, 817, 446, 447, 448, 450, 452,
-	449, 451, 453, 454, 455, 456, 457, 818, 819, 458,
-	459, 0, 0, 0, 0, 0, 0, 0, 460, 461,
-	462, 820, 0, 0, 0, 463, 0, 465, 469, 466,
-	467, 468, 470, 0, 464, 471, 472, 0, 0, 473,
-	474, 475, 821, 822, 476, 477, 478, 479, 480, 481,
-	482, 483, 484, 916, 485, 486, 823, 0, 824, 487,
-	0, 488, 489, 490, 491, 492, 493, 494, 825, 826,
-	827, 595, 0, 495, 496, 497, 0, 498, 499, 500,
-	501, 502, 503, 504, 0, 0, 0, 505, 506, 507,
-	508, 0, 0, 0, 0, 0, 828, 509, 596, 510,
-	829, 830, 0, 831, 0, 511, 512, 515, 0, 832,
-	0, 514, 516, 517, 0, 518, 0, 0, 0, 519,
-	520, 521, 522, 523, 524, 525, 0, 526, 528, 527,
-	0, 530, 833, 529, 0, 531, 532, 0, 0, 533,
-	534, 535, 536, 537, 538, 541, 0, 0, 539, 540,
-	542, 543, 0, 544, 545, 547, 550, 546, 548, 549,
-	551, 552, 565, 566, 553, 554, 555, 556, 557, 558,
-	559, 560, 561, 562, 563, 564, 568, 0, 567, 0,
-	569, 570, 571, 572, 573, 581, 583, 584, 579, 580,
-	582, 585, 586, 588, 589, 576, 577, 578, 0, 587,
-	574, 0, 575, 0, 0, 590, 591, 592, 593, 0,
-	834, 594, 835, 597, 598, 0, 0, 599, 0, 600,
-	0, 0, 602, 603, 604, 0, 0, 605, 606, 836,
-	0, 607, 0, 837, 608, 609, 601, 610, 611, 612,
-	613, 614, 615, 616, 617, 618, 619, 0, 620, 621,
-	838, 622, 623, 624, 839, 625, 626, 627, 840, 628,
-	841, 629, 630, 0, 631, 632, 633, 0, 634, 635,
-	636, 637, 638, 639, 640, 641, 642, 643, 842, 644,
-	645, 647, 646, 648, 649, 0, 650, 0, 651, 652,
-	653, 0, 0, 0, 0, 0, 654, 655, 657, 0,
-	658, 659, 660, 661, 662, 656, 663, 664, 665, 666,
-	667, 668, 669, 0, 671, 672, 670, 673, 674, 0,
-	675, 676, 677, 678, 679, 843, 680, 0, 681, 682,
-	690, 691, 692, 683, 684, 686, 693, 685, 694, 695,
-	696, 697, 699, 698, 917, 701, 702, 700, 703, 704,
-	705, 706, 0, 707, 844, 708, 687, 688, 709, 710,
-	711, 0, 712, 713, 714, 715, 716, 717, 718, 719,
-	720, 845, 0, 721, 0, 722, 723, 724, 725, 726,
-	727, 729, 689, 730, 731, 732, 737, 738, 846, 733,
-	734, 735, 736, 847, 740, 741, 742, 743, 0, 744,
-	4004, 0, 739, 728, 0, 746, 747, 748, 749, 750,
-	751, 752, 753, 754, 755, 0, 756, 848, 849, 850,
-	851, 0, 768, 0, 757, 759, 760, 761, 762, 852,
-	763, 853, 0, 764, 765, 766, 767, 758, 769, 770,
-	0, 0, 771, 772, 773, 774, 776, 778, 779, 780,
-	775, 777, 781, 0, 782, 0, 0, 783, 784, 785,
-	854, 855, 856, 0, 787, 788, 786, 789, 790, 793,
-	791, 792, 857, 796, 513, 797, 798, 799, 794, 795,
-	337, 0, 0, 0, 800, 801, 858, 802, 803, 804,
-	0, 0, 0, 0, 0, 0, 0, 345, 346, 348,
-	347, 349, 350, 351, 352, 0, 353, 354, 0, 0,
-	0, 0, 0, 805, 0, 0, 0, 356, 0, 355,
-	0, 357, 358, 359, 0, 360, 361, 362, 363, 364,
-	365, 366, 367, 806, 807, 0, 368, 808, 369, 809,
-	0, 810, 370, 371, 372, 373, 374, 375, 376, 377,
-	378, 379, 0, 0, 0, 380, 811, 812, 813, 0,
-	381, 382, 383, 384, 814, 0, 0, 0, 385, 386,
-	387, 388, 389, 390, 391, 392, 0, 0, 394, 395,
-	396, 393, 397, 398, 0, 399, 0, 400, 401, 402,
-	403, 404, 405, 406, 915, 407, 408, 409, 0, 410,
-	411, 412, 0, 0, 0, 0, 0, 0, 0, 413,
-	414, 415, 416, 417, 0, 418, 420, 421, 815, 422,
-	816, 0, 425, 427, 419, 423, 0, 426, 424, 428,
-	429, 0, 430, 431, 432, 433, 0, 0, 434, 435,
-	436, 0, 437, 438, 440, 439, 0, 441, 442, 443,
-	0, 444, 445, 817, 446, 447, 448, 450, 452, 449,
-	451, 453, 454, 455, 456, 457, 818, 819, 458, 459,
-	0, 0, 0, 0, 0, 0, 0, 460, 461, 462,
-	820, 0, 0, 0, 463, 0, 465, 469, 466, 467,
-	468, 470, 0, 464, 471, 472, 0, 0, 473, 474,
-	475, 821, 822, 476, 477, 478, 479, 480, 481, 482,
-	483, 484, 916, 485, 486, 823, 0, 824, 487, 0,
-	488, 489, 490, 491, 492, 493, 494, 825, 826, 827,
-	595, 0, 495, 496, 497, 0, 498, 499, 500, 501,
-	502, 503, 504, 0, 0, 0, 505, 506, 507, 508,
-	0, 0, 0, 0, 0, 828, 509, 596, 510, 829,
-	830, 0, 831, 0, 511, 512, 515, 0, 832, 0,
-	514, 516, 517, 0, 518, 0, 0, 0, 519, 520,
-	521, 522, 523, 524, 525, 0, 526, 528, 527, 0,
-	530, 833, 529, 0, 531, 532, 0, 0, 533, 534,
-	535, 536, 537, 538, 541, 0, 0, 539, 540, 542,
-	543, 0, 544, 545, 547, 550, 546, 548, 549, 551,
-	552, 565, 566, 553, 554, 555, 556, 557, 558, 559,
-	560, 561, 562, 563, 564, 568, 0, 567, 0, 569,
-	570, 571, 572, 573, 581, 583, 584, 579, 580, 582,
-	585, 586, 588, 589, 576, 577, 578, 0, 587, 574,
-	0, 575, 0, 0, 590, 591, 592, 593, 0, 834,
-	594, 835, 597, 598, 0, 0, 599, 0, 600, 0,
-	0, 602, 603, 604, 0, 0, 605, 606, 836, 0,
-	607, 0, 837, 608, 609, 601, 610, 611, 612, 613,
-	614, 615, 616, 617, 618, 619, 0, 620, 621, 838,
-	622, 623, 624, 839, 625, 626, 627, 840, 628, 841,
-	629, 630, 0, 631, 632, 633, 0, 634, 635, 636,
-	637, 638, 639, 640, 641, 642, 643, 842, 644, 645,
-	647, 646, 648, 649, 0, 650, 0, 651, 652, 653,
-	0, 0, 0, 0, 0, 654, 655, 657, 0, 658,
-	659, 660, 661, 662, 656, 663, 664, 665, 666, 667,
-	668, 669, 0, 671, 672, 670, 673, 674, 0, 675,
-	676, 677, 678, 679, 843, 680, 0, 681, 682, 690,
-	691, 692, 683, 684, 686, 693, 685, 694, 695, 696,
-	697, 699, 698, 917, 701, 702, 700, 703, 704, 705,
-	706, 0, 707, 844, 708, 687, 688, 709, 710, 711,
-	0, 712, 713, 714, 715, 716, 717, 718, 719, 720,
-	845, 0, 721, 0, 722, 723, 724, 725, 726, 727,
-	729, 689, 730, 731, 732, 737, 738, 846, 733, 734,
-	735, 736, 847, 740, 741, 742, 743, 0, 744, 745,
-	0, 739, 728, 0, 746, 747, 748, 749, 750, 751,
-	752, 753, 754, 755, 0, 756, 848, 849, 850, 851,
-	0, 768, 0, 757, 759, 760, 761, 762, 852, 763,
-	853, 0, 764, 765, 766, 767, 758, 769, 770, 0,
-	0, 771, 772, 773, 774, 776, 778, 779, 780, 775,
-	777, 781, 0, 782, 0, 0, 783, 784, 785, 854,
-	855, 856, 0, 787, 788, 786, 789, 790, 793, 791,
-	792, 857, 796, 513, 797, 798, 799, 794, 795, 1230,
-	0, 337, 0, 800, 801, 858, 802, 803, 804, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 345, 346,
-	348, 347, 349, 350, 351, 352, 0, 353, 354, 0,
-	0, 0, 0, 0, 805, 0, 0, 0, 356, 0,
-	355, 0, 357, 358, 359, 0, 360, 361, 362, 363,
-	364, 365, 366, 367, 806, 807, 0, 368, 808, 369,
-	809, 0, 810, 370, 371, 372, 373, 374, 375, 376,
-	377, 378, 379, 0, 0, 0, 380, 811, 812, 813,
-	0, 381, 382, 383, 384, 814, 0, 0, 0, 385,
-	386, 387, 388, 389, 390, 391, 392, 0, 0, 394,
-	395, 396, 393, 397, 398, 0, 399, 0, 400, 401,
-	402, 403, 404, 405, 406, 0, 407, 408, 409, 0,
-	410, 411, 412, 0, 0, 0, 0, 0, 0, 0,
-	413, 414, 415, 416, 417, 0, 418, 420, 421, 815,
-	422, 816, 0, 425, 427, 419, 423, 0, 426, 424,
-	428, 429, 0, 430, 431, 432, 433, 0, 0, 434,
-	435, 436, 0, 437, 438, 440, 439, 0, 441, 442,
-	443, 0, 444, 445, 817, 446, 447, 448, 450, 452,
-	449, 451, 453, 454, 455, 456, 457, 818, 819, 458,
-	459, 0, 0, 0, 0, 0, 0, 0, 460, 461,
-	462, 820, 0, 0, 0, 463, 0, 465, 469, 466,
-	467, 468, 470, 0, 464, 471, 472, 0, 0, 473,
-	474, 475, 821, 822, 476, 477, 478, 479, 480, 481,
-	482, 483, 484, 0, 485, 486, 823, 0, 824, 487,
-	0, 488, 489, 490, 491, 492, 493, 494, 825, 826,
-	827, 595, 0, 495, 496, 497, 0, 498, 499, 500,
-	501, 502, 503, 504, 0, 0, 0, 505, 506, 507,
-	508, 0, 0, 0, 0, 0, 828, 509, 596, 510,
-	829, 830, 0, 831, 1229, 511, 512, 515, 0, 832,
-	0, 514, 516, 517, 0, 518, 0, 0, 0, 519,
-	520, 521, 522, 523, 524, 525, 0, 526, 528, 527,
-	0, 530, 833, 529, 0, 531, 532, 0, 0, 533,
-	534, 535, 536, 537, 538, 541, 0, 0, 539, 540,
-	542, 543, 0, 544, 545, 547, 550, 546, 548, 549,
-	551, 552, 565, 566, 553, 554, 555, 556, 557, 558,
-	559, 560, 561, 562, 563, 564, 568, 0, 567, 0,
-	569, 570, 571, 572, 573, 581, 583, 584, 579, 580,
-	582, 585, 586, 588, 589, 576, 577, 578, 0, 587,
-	574, 0, 575, 0, 0, 590, 591, 592, 593, 0,
-	834, 594, 835, 597, 598, 0, 0, 599, 0, 600,
-	0, 0, 602, 603, 604, 0, 0, 605, 606, 836,
-	0, 607, 0, 837, 608, 609, 601, 610, 611, 612,
-	613, 614, 615, 616, 617, 618, 619, 0, 620, 621,
-	838, 622, 623, 624, 839, 625, 626, 627, 840, 628,
-	841, 629, 630, 0, 631, 632, 633, 0, 634, 635,
-	636, 637, 638, 639, 640, 641, 642, 643, 842, 644,
-	645, 647, 646, 648, 649, 0, 650, 0, 651, 652,
-	653, 0, 0, 0, 0, 0, 654, 655, 657, 0,
-	658, 659, 660, 661, 662, 656, 663, 664, 665, 666,
-	667, 668, 669, 0, 671, 672, 670, 673, 674, 0,
-	675, 676, 677, 678, 679, 843, 680, 0, 681, 682,
-	690, 691, 692, 683, 684, 686, 693, 685, 694, 695,
-	696, 697, 699, 698, 0, 701, 702, 700, 703, 704,
-	705, 706, 0, 707, 844, 708, 687, 688, 709, 710,
-	711, 0, 712, 713, 714, 715, 716, 717, 718, 719,
-	720, 845, 0, 721, 0, 722, 723, 724, 725, 726,
-	727, 729, 689, 730, 731, 732, 737, 738, 846, 733,
-	734, 735, 736, 847, 740, 741, 742, 743, 0, 744,
-	745, 0, 739, 728, 1228, 746, 747, 748, 749, 750,
-	751, 752, 753, 754, 755, 0, 756, 848, 849, 850,
-	851, 0, 768, 0, 757, 759, 760, 761, 762, 852,
-	763, 853, 0, 764, 765, 766, 767, 758, 769, 770,
-	0, 0, 771, 772, 773, 774, 776, 778, 779, 780,
-	775, 777, 781, 0, 782, 0, 0, 783, 784, 785,
-	854, 855, 856, 0, 787, 788, 786, 789, 790, 793,
-	791, 792, 857, 796, 513, 797, 798, 799, 794, 795,
-	1019, 0, 337, 0, 800, 801, 858, 802, 803, 804,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 345,
-	1008, 348, 347, 349, 350, 351, 352, 0, 353, 354,
-	0, 0, 0, 0, 0, 805, 0, 0, 0, 356,
-	0, 355, 0, 357, 358, 359, 0, 360, 361, 362,
-	363, 1017, 365, 366, 367, 806, 807, 0, 368, 808,
-	369, 809, 0, 810, 370, 371, 372, 373, 374, 375,
-	376, 377, 378, 379, 0, 0, 0, 380, 811, 812,
-	813, 0, 381, 382, 383, 384, 814, 0, 0, 0,
-	385, 386, 387, 388, 389, 390, 391, 392, 0, 0,
-	394, 395, 396, 393, 397, 398, 0, 399, 0, 400,
-	401, 402, 403, 404, 405, 406, 0, 407, 408, 409,
-	0, 410, 411, 412, 0, 0, 0, 0, 0, 0,
-	0, 413, 414, 415, 416, 417, 0, 418, 420, 421,
-	815, 422, 816, 0, 425, 427, 419, 423, 0, 426,
-	424, 428, 429, 0, 430, 431, 432, 433, 0, 0,
-	434, 435, 436, 0, 437, 438, 440, 439, 0, 441,
-	442, 443, 0, 444, 445, 817, 446, 447, 448, 450,
-	452, 449, 451, 453, 454, 455, 456, 457, 818, 819,
-	458, 459, 0, 0, 0, 0, 0, 0, 0, 460,
-	461, 1010, 820, 0, 0, 0, 463, 0, 465, 469,
-	466, 467, 468, 470, 0, 464, 1016, 472, 1012, 0,
-	473, 474, 475, 821, 822, 476, 477, 478, 479, 480,
-	481, 482, 483, 484, 0, 485, 486, 823, 0, 824,
-	487, 0, 488, 489, 490, 491, 492, 493, 494, 825,
-	826, 827, 595, 0, 495, 496, 497, 1013, 498, 499,
-	500, 501, 502, 503, 504, 0, 0, 0, 505, 506,
-	507, 508, 0, 0, 0, 0, 0, 828, 509, 596,
-	510, 829, 830, 0, 831, 0, 511, 512, 515, 0,
-	832, 0, 514, 516, 517, 0, 518, 0, 0, 0,
-	519, 520, 521, 522, 523, 524, 1011, 0, 526, 528,
-	527, 0, 530, 833, 529, 0, 531, 532, 0, 0,
-	533, 534, 535, 536, 537, 538, 541, 0, 0, 539,
-	540, 542, 543, 0, 544, 545, 547, 550, 546, 548,
-	549, 551, 552, 565, 566, 553, 554, 555, 556, 557,
-	558, 559, 560, 561, 562, 563, 564, 568, 0, 567,
-	0, 569, 570, 571, 1014, 573, 581, 583, 584, 579,
-	580, 582, 585, 586, 588, 589, 576, 577, 578, 0,
-	587, 574, 0, 575, 0, 0, 590, 591, 592, 593,
-	0, 834, 594, 835, 597, 598, 0, 0, 599, 0,
-	600, 0, 0, 602, 603, 604, 0, 0, 605, 606,
-	836, 0, 607, 0, 837, 608, 609, 601, 610, 611,
-	612, 613, 614, 615, 616, 617, 618, 619, 0, 620,
-	621, 838, 622, 623, 624, 839, 625, 626, 627, 840,
-	628, 841, 629, 630, 0, 1015, 632, 633, 0, 634,
-	635, 636, 637, 638, 639, 640, 641, 642, 643, 842,
-	644, 645, 647, 646, 648, 649, 0, 650, 0, 651,
-	652, 653, 0, 0, 0, 0, 0, 654, 1009, 657,
-	0, 658, 659, 660, 661, 662, 656, 663, 664, 665,
-	666, 667, 668, 669, 0, 671, 672, 670, 673, 674,
-	0, 675, 676, 677, 678, 679, 843, 680, 0, 681,
-	682, 690, 691, 692, 683, 684, 686, 693, 685, 694,
-	695, 696, 697, 699, 698, 0, 701, 702, 700, 703,
-	704, 705, 706, 0, 707, 844, 708, 687, 688, 709,
-	710, 711, 0, 712, 713, 714, 715, 716, 717, 718,
-	719, 720, 845, 0, 721, 0, 722, 723, 724, 725,
-	726, 727, 729, 689, 730, 731, 732, 737, 738, 846,
-	733, 734, 735, 736, 847, 740, 741, 742, 743, 0,
-	744, 745, 0, 739, 728, 0, 746, 747, 748, 749,
-	750, 751, 752, 753, 754, 755, 0, 756, 848, 849,
-	850, 851, 0, 768, 0, 757, 759, 760, 761, 762,
-	852, 763, 853, 0, 764, 765, 766, 767, 758, 769,
-	770, 0, 0, 771, 772, 773, 774, 776, 778, 779,
-	780, 775, 777, 781, 0, 782, 0, 0, 783, 784,
-	785, 854, 855, 856, 0, 787, 788, 786, 789, 790,
-	793, 791, 792, 857, 796, 513, 797, 798, 799, 794,
-	795, 1002, 0, 337, 0, 800, 801, 858, 802, 803,
-	804, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	345, 1008, 348, 347, 349, 350, 351, 352, 0, 353,
-	354, 0, 0, 0, 0, 0, 805, 0, 0, 0,
-	356, 0, 355, 0, 357, 358, 359, 0, 360, 361,
-	362, 363, 1017, 365, 366, 367, 806, 807, 0, 368,
-	808, 369, 809, 0, 810, 370, 371, 372, 373, 374,
-	375, 376, 377, 378, 379, 0, 0, 0, 380, 811,
-	812, 813, 0, 381, 382, 383, 384, 814, 0, 0,
-	0, 385, 386, 387, 388, 389, 390, 391, 392, 0,
-	0, 394, 395, 396, 393, 397, 398, 0, 399, 0,
-	400, 401, 402, 403, 404, 405, 406, 0, 407, 408,
-	409, 0, 410, 411, 412, 0, 0, 0, 0, 0,
-	0, 0, 413, 414, 415, 416, 417, 0, 418, 420,
-	421, 815, 422, 816, 0, 425, 427, 419, 423, 0,
-	426, 424, 428, 429, 0, 430, 431, 432, 433, 0,
-	0, 434, 435, 436, 0, 437, 438, 440, 439, 0,
-	441, 442, 443, 0, 444, 445, 817, 446, 447, 448,
-	450, 452, 449, 451, 453, 454, 455, 456, 457, 818,
-	819, 458, 459, 0, 0, 0, 0, 0, 0, 0,
-	460, 461, 1010, 820, 0, 0, 0, 463, 0, 465,
-	469, 466, 467, 468, 470, 0, 464, 1016, 472, 1012,
-	0, 473, 474, 475, 821, 822, 476, 477, 478, 479,
-	480, 481, 482, 483, 484, 0, 485, 486, 823, 0,
-	824, 487, 0, 488, 489, 490, 491, 492, 493, 494,
-	825, 826, 827, 595, 0, 495, 496, 497, 1013, 498,
-	499, 500, 501, 502, 503, 504, 0, 0, 0, 505,
-	506, 507, 508, 0, 0, 0, 0, 0, 828, 509,
-	596, 510, 829, 830, 0, 831, 0, 511, 512, 515,
-	0, 832, 0, 514, 516, 517, 0, 518, 0, 0,
-	0, 519, 520, 521, 522, 523, 524, 1011, 0, 526,
-	528, 527, 0, 530, 833, 529, 0, 531, 532, 0,
-	0, 533, 534, 535, 536, 537, 538, 541, 0, 0,
-	539, 540, 542, 543, 0, 544, 545, 547, 550, 546,
-	548, 549, 551, 552, 565, 566, 553, 554, 555, 556,
-	557, 558, 559, 560, 561, 562, 563, 564, 568, 0,
-	567, 0, 569, 570, 571, 1014, 573, 581, 583, 584,
-	579, 580, 582, 585, 586, 588, 589, 576, 577, 578,
-	0, 587, 574, 0, 575, 0, 0, 590, 591, 592,
-	593, 0, 834, 594, 835, 597, 598, 0, 0, 599,
-	0, 600, 0, 0, 602, 603, 604, 0, 0, 605,
-	606, 836, 0, 607, 0, 837, 608, 609, 601, 610,
-	611, 612, 613, 614, 615, 616, 617, 618, 619, 0,
-	620, 621, 838, 622, 623, 624, 839, 625, 626, 627,
-	840, 628, 841, 629, 630, 0, 1015, 632, 633, 0,
-	634, 635, 636, 637, 638, 639, 640, 641, 642, 643,
-	842, 644, 645, 647, 646, 648, 649, 0, 650, 0,
-	651, 652, 653, 0, 0, 0, 0, 0, 654, 1009,
-	657, 0, 658, 659, 660, 661, 662, 656, 663, 664,
-	665, 666, 667, 668, 669, 0, 671, 672, 670, 673,
-	674, 0, 675, 676, 677, 678, 679, 843, 680, 0,
-	681, 682, 690, 691, 692, 683, 684, 686, 693, 685,
-	694, 695, 696, 697, 699, 698, 0, 701, 702, 700,
-	703, 704, 705, 706, 0, 707, 844, 708, 687, 688,
-	709, 710, 711, 0, 712, 713, 714, 715, 716, 717,
-	718, 719, 720, 845, 0, 721, 0, 722, 723, 724,
-	725, 726, 727, 729, 689, 730, 731, 732, 737, 738,
-	846, 733, 734, 735, 736, 847, 740, 741, 742, 743,
-	0, 744, 745, 0, 739, 728, 0, 746, 747, 748,
-	749, 750, 751, 752, 753, 754, 755, 0, 756, 848,
-	849, 850, 851, 0, 768, 0, 757, 759, 760, 761,
-	762, 852, 763, 853, 0, 764, 765, 766, 767, 758,
-	769, 770, 0, 0, 771, 772, 773, 774, 776, 778,
-	779, 780, 775, 777, 781, 0, 782, 0, 0, 783,
-	784, 785, 854, 855, 856, 0, 787, 788, 786, 789,
-	790, 793, 791, 792, 857, 796, 513, 797, 798, 799,
-	794, 795, 337, 4953, 0, 0, 800, 801, 858, 802,
-	803, 804, 0, 0, 0, 0, 0, 0, 0, 345,
-	346, 348, 347, 349, 350, 351, 352, 0, 353, 354,
-	0, 0, 0, 0, 0, 805, 0, 0, 0, 356,
-	0, 355, 0, 357, 358, 359, 0, 360, 361, 362,
-	363, 364, 365, 366, 367, 806, 807, 0, 368, 808,
-	369, 809, 0, 810, 370, 371, 372, 373, 374, 375,
-	376, 377, 378, 379, 0, 0, 0, 380, 811, 812,
-	813, 0, 381, 382, 383, 384, 814, 0, 0, 0,
-	385, 386, 387, 388, 389, 390, 391, 392, 0, 0,
-	394, 395, 396, 393, 397, 398, 0, 399, 0, 400,
-	401, 402, 403, 404, 405, 406, 0, 407, 408, 409,
-	0, 410, 411, 412, 0, 0, 0, 0, 0, 0,
-	0, 413, 414, 415, 416, 417, 0, 418, 420, 421,
-	815, 422, 816, 0, 425, 427, 419, 423, 0, 426,
-	424, 428, 429, 0, 430, 431, 432, 433, 0, 0,
-	434, 435, 436, 0, 437, 438, 440, 439, 0, 441,
-	442, 443, 0, 444, 445, 817, 446, 447, 448, 450,
-	452, 449, 451, 453, 454, 455, 456, 457, 818, 819,
-	458, 459, 0, 0, 0, 0, 0, 0, 0, 460,
-	461, 462, 820, 0, 0, 0, 463, 0, 465, 469,
-	466, 467, 468, 470, 0, 464, 471, 472, 0, 0,
-	473, 474, 475, 821, 822, 476, 477, 478, 479, 480,
-	481, 482, 483, 484, 0, 485, 486, 823, 0, 824,
-	487, 0, 488, 489, 490, 491, 492, 493, 494, 825,
-	826, 827, 595, 0, 495, 496, 497, 0, 498, 499,
-	500, 501, 502, 503, 504, 0, 0, 0, 505, 506,
-	507, 508, 0, 0, 0, 0, 0, 828, 509, 596,
-	510, 829, 830, 0, 831, 0, 511, 512, 515, 0,
-	832, 0, 514, 516, 517, 0, 518, 0, 0, 0,
-	519, 520, 521, 522, 523, 524, 525, 0, 526, 528,
-	527, 0, 530, 833, 529, 0, 531, 532, 0, 0,
-	533, 534, 535, 536, 537, 538, 541, 0, 0, 539,
-	540, 542, 543, 0, 544, 545, 547, 550, 546, 548,
-	549, 551, 552, 565, 566, 553, 554, 555, 556, 557,
-	558, 559, 560, 561, 562, 563, 564, 568, 0, 567,
-	0, 569, 570, 571, 572, 573, 581, 583, 584, 579,
-	580, 582, 585, 586, 588, 589, 576, 577, 578, 0,
-	587, 574, 0, 575, 0, 0, 590, 591, 592, 593,
-	0, 834, 594, 835, 597, 598, 0, 0, 599, 0,
-	600, 0, 0, 602, 603, 604, 0, 0, 605, 606,
-	836, 0, 607, 0, 837, 608, 609, 601, 610, 611,
-	612, 613, 614, 615, 616, 617, 618, 619, 0, 620,
-	621, 838, 622, 623, 624, 839, 625, 626, 627, 840,
-	628, 841, 629, 630, 6351, 631, 632, 633, 0, 634,
-	635, 636, 637, 638, 639, 640, 641, 642, 643, 842,
-	644, 645, 647, 646, 648, 649, 0, 650, 0, 651,
-	652, 653, 0, 0, 0, 0, 0, 654, 655, 657,
-	0, 658, 659, 660, 661, 662, 656, 663, 664, 665,
-	666, 667, 668, 669, 0, 671, 672, 670, 673, 674,
-	0, 675, 676, 677, 678, 679, 843, 680, 0, 681,
-	682, 690, 691, 692, 683, 684, 686, 693, 685, 694,
-	695, 696, 697, 699, 698, 0, 701, 702, 700, 703,
-	704, 705, 706, 0, 707, 844, 708, 687, 688, 709,
-	710, 711, 0, 712, 713, 714, 715, 716, 717, 718,
-	719, 720, 845, 0, 721, 0, 722, 723, 724, 725,
-	726, 727, 729, 689, 730, 731, 732, 737, 738, 846,
-	733, 734, 735, 736, 847, 740, 741, 742, 743, 0,
-	744, 745, 0, 739, 728, 0, 746, 747, 748, 749,
-	750, 751, 752, 753, 754, 755, 0, 756, 848, 849,
-	850, 851, 0, 768, 0, 757, 759, 760, 761, 762,
-	852, 763, 853, 0, 764, 765, 766, 767, 758, 769,
-	770, 0, 0, 771, 772, 773, 774, 776, 778, 779,
-	780, 775, 777, 781, 0, 782, 0, 0, 783, 784,
-	785, 854, 855, 856, 0, 787, 788, 786, 789, 790,
-	793, 791, 792, 857, 796, 513, 797, 798, 799, 794,
-	795, 337, 0, 0, 0, 800, 801, 858, 802, 803,
-	804, 0, 0, 0, 0, 0, 0, 0, 345, 346,
-	348, 347, 349, 350, 351, 352, 0, 353, 354, 0,
-	0, 0, 0, 0, 805, 0, 0, 0, 356, 0,
-	355, 0, 357, 358, 359, 0, 360, 361, 362, 363,
-	364, 365, 366, 367, 806, 807, 0, 368, 808, 369,
-	809, 0, 810, 370, 371, 372, 373, 374, 375, 376,
-	377, 378, 379, 0, 0, 0, 380, 811, 812, 813,
-	0, 381, 382, 383, 384, 814, 0, 0, 0, 385,
-	386, 387, 388, 389, 390, 391, 392, 0, 0, 394,
-	395, 396, 393, 397, 398, 0, 399, 0, 400, 401,
-	402, 403, 404, 405, 406, 0, 407, 408, 409, 0,
-	410, 411, 412, 0, 0, 0, 0, 0, 0, 0,
-	413, 414, 415, 416, 417, 0, 418, 420, 421, 815,
-	422, 816, 0, 425, 427, 419, 423, 0, 426, 424,
-	428, 429, 0, 430, 431, 432, 433, 0, 0, 434,
-	435, 436, 0, 437, 438, 440, 439, 0, 441, 442,
-	443, 0, 444, 445, 817, 446, 447, 448, 450, 452,
-	449, 451, 453, 454, 455, 456, 457, 818, 819, 458,
-	459, 0, 5085, 0, 0, 0, 0, 0, 460, 461,
-	462, 820, 0, 0, 0, 463, 0, 465, 469, 466,
-	467, 468, 470, 0, 464, 471, 472, 0, 0, 473,
-	474, 475, 821, 822, 476, 477, 478, 479, 480, 481,
-	482, 483, 484, 0, 485, 486, 823, 0, 824, 487,
-	0, 488, 489, 490, 491, 492, 493, 494, 825, 826,
-	827, 595, 0, 495, 496, 497, 0, 498, 499, 500,
-	501, 502, 503, 504, 0, 0, 0, 505, 506, 507,
-	508, 0, 0, 0, 0, 0, 828, 509, 596, 510,
-	829, 830, 0, 831, 0, 511, 512, 515, 0, 832,
-	0, 514, 516, 517, 0, 518, 0, 0, 0, 519,
-	520, 521, 522, 523, 524, 525, 0, 526, 528, 527,
-	0, 530, 833, 529, 0, 531, 532, 0, 0, 533,
-	534, 535, 536, 537, 538, 541, 0, 0, 539, 540,
-	542, 543, 0, 544, 545, 547, 550, 546, 548, 549,
-	551, 552, 565, 566, 553, 554, 555, 556, 557, 558,
-	559, 560, 561, 562, 563, 564, 568, 0, 567, 0,
-	569, 570, 571, 572, 573, 581, 583, 584, 579, 580,
-	582, 585, 586, 588, 589, 576, 577, 578, 0, 587,
-	574, 0, 575, 0, 0, 590, 591, 592, 593, 0,
-	834, 594, 835, 597, 598, 0, 0, 599, 0, 600,
-	0, 0, 602, 603, 604, 0, 0, 605, 606, 836,
-	0, 607, 0, 837, 608, 609, 601, 610, 611, 612,
-	613, 614, 615, 616, 617, 618, 619, 0, 620, 621,
-	838, 622, 623, 624, 839, 625, 626, 627, 840, 628,
-	841, 629, 630, 5975, 631, 632, 633, 0, 634, 635,
-	636, 637, 638, 639, 640, 641, 642, 643, 842, 644,
-	645, 647, 646, 648, 649, 0, 650, 0, 651, 652,
-	653, 0, 0, 0, 0, 0, 654, 655, 657, 0,
-	658, 659, 660, 661, 662, 656, 663, 664, 665, 666,
-	667, 668, 669, 0, 671, 672, 670, 673, 674, 0,
-	675, 676, 677, 678, 679, 843, 680, 0, 681, 682,
-	690, 691, 692, 683, 684, 686, 693, 685, 694, 695,
-	696, 697, 699, 698, 0, 701, 702, 700, 703, 704,
-	705, 706, 0, 707, 844, 708, 687, 688, 709, 710,
-	711, 0, 712, 713, 714, 715, 716, 717, 718, 719,
-	720, 845, 0, 721, 0, 722, 723, 724, 725, 726,
-	727, 729, 689, 730, 731, 732, 737, 738, 846, 733,
-	734, 735, 736, 847, 740, 741, 742, 743, 0, 744,
-	745, 0, 739, 728, 0, 746, 747, 748, 749, 750,
-	751, 752, 753, 754, 755, 0, 756, 848, 849, 850,
-	851, 0, 768, 0, 757, 759, 760, 761, 762, 852,
-	763, 853, 0, 764, 765, 766, 767, 758, 769, 770,
-	0, 0, 771, 772, 773, 774, 776, 778, 779, 780,
-	775, 777, 781, 0, 782, 0, 0, 783, 784, 785,
-	854, 855, 856, 0, 787, 788, 786, 789, 790, 793,
-	791, 792, 857, 796, 513, 797, 798, 799, 794, 795,
-	337, 4953, 0, 0, 800, 801, 858, 802, 803, 804,
-	0, 0, 0, 0, 0, 0, 0, 345, 346, 348,
-	347, 349, 350, 351, 352, 0, 353, 354, 0, 0,
-	0, 0, 0, 805, 0, 0, 0, 356, 0, 355,
-	0, 357, 358, 359, 0, 360, 361, 362, 363, 364,
-	365, 366, 367, 806, 807, 0, 368, 808, 369, 809,
-	0, 810, 370, 371, 372, 373, 374, 375, 376, 377,
-	378, 379, 0, 0, 0, 380, 811, 812, 813, 0,
-	381, 382, 383, 384, 814, 0, 0, 0, 385, 386,
-	387, 388, 389, 390, 391, 392, 0, 0, 394, 395,
-	396, 393, 397, 398, 0, 399, 0, 400, 401, 402,
-	403, 404, 405, 406, 0, 407, 408, 409, 0, 410,
-	411, 412, 0, 0, 0, 0, 0, 0, 0, 413,
-	414, 415, 416, 417, 0, 418, 420, 421, 815, 422,
-	816, 0, 425, 427, 419, 423, 0, 426, 424, 428,
-	429, 0, 430, 431, 432, 433, 0, 0, 434, 435,
-	436, 0, 437, 438, 440, 439, 0, 441, 442, 443,
-	0, 444, 445, 817, 446, 447, 448, 450, 452, 449,
-	451, 453, 454, 455, 456, 457, 818, 819, 458, 459,
-	0, 0, 0, 0, 0, 0, 0, 460, 461, 462,
-	820, 0, 0, 0, 463, 0, 465, 469, 466, 467,
-	468, 470, 0, 464, 471, 472, 0, 0, 473, 474,
-	475, 821, 822, 476, 477, 478, 479, 480, 481, 482,
-	483, 484, 0, 485, 486, 823, 0, 824, 487, 0,
-	488, 489, 490, 491, 492, 493, 494, 825, 826, 827,
-	595, 0, 495, 496, 497, 0, 498, 499, 500, 501,
-	502, 503, 504, 0, 0, 0, 505, 506, 507, 508,
-	0, 0, 0, 0, 0, 828, 509, 596, 510, 829,
-	830, 0, 831, 0, 511, 512, 515, 0, 832, 0,
-	514, 516, 517, 0, 518, 0, 0, 0, 519, 520,
-	521, 522, 523, 524, 525, 0, 526, 528, 527, 0,
-	530, 833, 529, 0, 531, 532, 0, 0, 533, 534,
-	535, 536, 537, 538, 541, 0, 0, 539, 540, 542,
-	543, 0, 544, 545, 547, 550, 546, 548, 549, 551,
-	552, 565, 566, 553, 554, 555, 556, 557, 558, 559,
-	560, 561, 562, 563, 564, 568, 0, 567, 0, 569,
-	570, 571, 572, 573, 581, 583, 584, 579, 580, 582,
-	585, 586, 588, 589, 576, 577, 578, 0, 587, 574,
-	0, 575, 0, 0, 590, 591, 592, 593, 0, 834,
-	594, 835, 597, 598, 0, 0, 599, 0, 600, 0,
-	0, 602, 603, 604, 0, 0, 605, 606, 836, 0,
-	607, 0, 837, 608, 609, 601, 610, 611, 612, 613,
-	614, 615, 616, 617, 618, 619, 0, 620, 621, 838,
-	622, 623, 624, 839, 625, 626, 627, 840, 628, 841,
-	629, 630, 5828, 631, 632, 633, 0, 634, 635, 636,
-	637, 638, 639, 640, 641, 642, 643, 842, 644, 645,
-	647, 646, 648, 649, 0, 650, 0, 651, 652, 653,
-	0, 0, 0, 0, 0, 654, 655, 657, 0, 658,
-	659, 660, 661, 662, 656, 663, 664, 665, 666, 667,
-	668, 669, 0, 671, 672, 670, 673, 674, 0, 675,
-	676, 677, 678, 679, 843, 680, 0, 681, 682, 690,
-	691, 692, 683, 684, 686, 693, 685, 694, 695, 696,
-	697, 699, 698, 0, 701, 702, 700, 703, 704, 705,
-	706, 0, 707, 844, 708, 687, 688, 709, 710, 711,
-	0, 712, 713, 714, 715, 716, 717, 718, 719, 720,
-	845, 0, 721, 0, 722, 723, 724, 725, 726, 727,
-	729, 689, 730, 731, 732, 737, 738, 846, 733, 734,
-	735, 736, 847, 740, 741, 742, 743, 0, 744, 745,
-	0, 739, 728, 0, 746, 747, 748, 749, 750, 751,
-	752, 753, 754, 755, 0, 756, 848, 849, 850, 851,
-	0, 768, 0, 757, 759, 760, 761, 762, 852, 763,
-	853, 0, 764, 765, 766, 767, 758, 769, 770, 0,
-	0, 771, 772, 773, 774, 776, 778, 779, 780, 775,
-	777, 781, 0, 782, 0, 0, 783, 784, 785, 854,
-	855, 856, 0, 787, 788, 786, 789, 790, 793, 791,
-	792, 857, 796, 513, 797, 798, 799, 794, 795, 1657,
-	0, 337, 0, 800, 801, 858, 802, 803, 804, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 345, 346,
-	348, 347, 349, 350, 351, 352, 0, 353, 354, 0,
-	0, 0, 0, 0, 805, 0, 0, 0, 356, 0,
-	355, 0, 357, 358, 359, 1660, 360, 361, 362, 363,
-	364, 365, 366, 367, 806, 807, 0, 368, 808, 369,
-	809, 0, 810, 370, 371, 372, 373, 374, 375, 376,
-	377, 378, 379, 0, 0, 0, 380, 811, 812, 1658,
-	0, 381, 382, 383, 384, 814, 0, 0, 0, 385,
-	386, 387, 388, 389, 390, 391, 392, 0, 0, 394,
-	395, 396, 393, 397, 398, 0, 399, 0, 400, 401,
-	402, 403, 404, 405, 406, 0, 407, 408, 409, 0,
-	410, 411, 412, 0, 0, 0, 0, 0, 0, 0,
-	413, 414, 415, 416, 417, 0, 418, 420, 421, 815,
-	422, 816, 0, 425, 427, 419, 423, 0, 426, 424,
-	428, 429, 0, 430, 431, 432, 433, 0, 0, 434,
-	435, 436, 0, 437, 438, 440, 439, 0, 441, 442,
-	443, 0, 444, 445, 817, 446, 447, 448, 450, 452,
-	449, 451, 453, 454, 455, 456, 457, 818, 819, 458,
-	459, 0, 0, 0, 0, 0, 0, 0, 460, 461,
-	462, 820, 0, 0, 0, 463, 0, 465, 469, 466,
-	467, 468, 470, 0, 464, 471, 472, 0, 0, 473,
-	474, 475, 821, 822, 476, 477, 478, 479, 480, 481,
-	482, 483, 484, 0, 485, 486, 823, 0, 824, 487,
-	0, 488, 489, 490, 491, 492, 493, 494, 825, 826,
-	827, 595, 0, 495, 496, 497, 0, 498, 499, 500,
-	501, 502, 503, 504, 0, 0, 0, 505, 506, 507,
-	508, 0, 0, 0, 0, 0, 828, 509, 596, 510,
-	829, 830, 0, 831, 0, 511, 512, 515, 0, 832,
-	0, 514, 516, 517, 0, 518, 0, 0, 0, 519,
-	520, 521, 522, 523, 524, 525, 0, 526, 528, 527,
-	0, 530, 833, 529, 0, 531, 532, 0, 0, 533,
-	534, 535, 536, 537, 538, 541, 0, 0, 539, 540,
-	542, 543, 0, 544, 545, 547, 550, 546, 548, 549,
-	551, 552, 565, 566, 553, 554, 555, 556, 557, 558,
-	559, 560, 561, 562, 563, 564, 568, 0, 990, 0,
-	569, 570, 571, 572, 573, 581, 583, 584, 579, 580,
-	582, 585, 586, 588, 589, 576, 577, 578, 0, 587,
-	574, 0, 575, 0, 0, 590, 591, 592, 593, 0,
-	834, 594, 835, 597, 598, 0, 0, 599, 0, 600,
-	0, 0, 602, 603, 604, 0, 0, 605, 606, 836,
-	0, 607, 0, 837, 608, 609, 601, 610, 611, 612,
-	613, 614, 615, 616, 617, 618, 619, 0, 620, 621,
-	838, 622, 623, 624, 839, 625, 626, 627, 840, 628,
-	841, 629, 630, 0, 631, 632, 633, 0, 634, 635,
-	636, 637, 638, 639, 640, 641, 642, 643, 842, 644,
-	645, 647, 646, 648, 649, 0, 650, 0, 651, 652,
-	653, 0, 0, 0, 0, 0, 654, 655, 657, 0,
-	658, 659, 660, 661, 662, 656, 663, 664, 665, 666,
-	667, 668, 669, 0, 671, 672, 670, 673, 674, 0,
-	989, 676, 677, 678, 679, 843, 680, 0, 681, 682,
-	690, 691, 692, 683, 684, 686, 988, 685, 694, 695,
-	696, 697, 699, 698, 0, 701, 702, 700, 703, 704,
-	1661, 706, 0, 707, 844, 708, 687, 688, 709, 710,
-	711, 0, 712, 713, 714, 715, 716, 717, 718, 719,
-	720, 845, 0, 721, 0, 722, 723, 724, 725, 726,
-	727, 729, 689, 730, 731, 732, 737, 738, 846, 733,
-	734, 735, 736, 847, 740, 741, 742, 743, 0, 744,
-	745, 0, 739, 728, 0, 746, 747, 748, 749, 750,
-	751, 752, 753, 754, 755, 0, 756, 986, 849, 850,
-	851, 0, 768, 0, 757, 759, 760, 761, 762, 852,
-	763, 853, 0, 764, 765, 766, 767, 758, 769, 770,
-	0, 0, 771, 772, 773, 774, 776, 778, 779, 780,
-	775, 777, 781, 0, 782, 0, 0, 783, 784, 785,
-	854, 855, 856, 0, 787, 788, 786, 789, 790, 793,
-	791, 792, 857, 796, 513, 797, 798, 799, 794, 795,
-	1657, 0, 337, 0, 800, 801, 858, 802, 803, 804,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 345,
-	346, 348, 347, 349, 350, 351, 352, 0, 353, 354,
-	0, 0, 0, 0, 0, 805, 0, 0, 0, 356,
-	0, 355, 0, 357, 358, 359, 1660, 360, 361, 362,
-	363, 364, 365, 366, 367, 806, 807, 0, 368, 808,
-	369, 809, 0, 810, 370, 371, 372, 373, 374, 375,
-	376, 377, 378, 379, 0, 0, 0, 380, 811, 812,
-	1658, 0, 381, 382, 383, 384, 814, 0, 0, 0,
-	385, 386, 387, 388, 389, 390, 391, 392, 0, 0,
-	394, 395, 396, 393, 397, 398, 0, 399, 0, 400,
-	401, 402, 403, 404, 405, 406, 0, 407, 408, 409,
-	0, 410, 411, 412, 0, 0, 0, 0, 0, 0,
-	0, 413, 414, 415, 416, 417, 0, 418, 420, 421,
-	815, 422, 816, 0, 425, 427, 419, 423, 0, 426,
-	424, 428, 429, 0, 430, 431, 432, 433, 0, 0,
-	434, 435, 436, 0, 437, 438, 440, 439, 0, 441,
-	442, 443, 0, 444, 445, 817, 446, 447, 448, 450,
-	452, 449, 451, 453, 454, 455, 456, 457, 818, 819,
-	458, 459, 0, 0, 0, 0, 0, 0, 0, 460,
-	461, 462, 820, 0, 0, 0, 463, 0, 465, 469,
-	466, 467, 468, 470, 0, 464, 471, 472, 0, 0,
-	473, 474, 475, 821, 822, 476, 477, 478, 479, 480,
-	481, 482, 483, 484, 0, 485, 486, 823, 0, 824,
-	487, 0, 488, 489, 490, 491, 492, 493, 494, 825,
-	826, 827, 595, 0, 495, 496, 497, 0, 498, 499,
-	500, 501, 502, 503, 504, 0, 0, 0, 505, 506,
-	507, 508, 0, 0, 0, 0, 0, 828, 509, 596,
-	510, 829, 830, 0, 831, 0, 511, 512, 515, 0,
-	832, 0, 514, 516, 517, 0, 518, 0, 0, 0,
-	519, 520, 521, 522, 523, 524, 525, 0, 526, 528,
-	527, 0, 530, 833, 529, 0, 531, 532, 0, 0,
-	533, 534, 535, 536, 537, 538, 541, 0, 0, 539,
-	540, 542, 543, 0, 544, 545, 547, 550, 546, 548,
-	549, 551, 552, 565, 566, 553, 554, 555, 556, 557,
-	558, 559, 560, 561, 562, 563, 564, 568, 0, 990,
-	0, 569, 570, 571, 572, 573, 581, 583, 584, 579,
-	580, 582, 585, 586, 588, 589, 576, 577, 578, 0,
-	587, 574, 0, 575, 0, 0, 590, 591, 592, 593,
-	0, 834, 594, 835, 597, 598, 0, 0, 599, 0,
-	600, 0, 0, 602, 603, 604, 0, 0, 605, 606,
-	836, 0, 607, 0, 837, 608, 609, 601, 610, 611,
-	612, 613, 614, 615, 616, 617, 618, 619, 0, 620,
-	621, 838, 622, 623, 624, 839, 625, 626, 627, 840,
-	628, 841, 629, 630, 0, 631, 632, 633, 0, 634,
-	635, 636, 637, 638, 639, 640, 641, 642, 643, 842,
-	644, 645, 647, 646, 648, 649, 0, 650, 0, 651,
-	652, 653, 0, 0, 0, 0, 0, 654, 655, 657,
-	0, 658, 659, 660, 661, 662, 656, 663, 664, 665,
-	666, 667, 668, 669, 0, 671, 672, 670, 673, 674,
-	0, 989, 676, 677, 678, 679, 843, 680, 0, 681,
-	682, 690, 691, 692, 683, 684, 686, 988, 685, 694,
-	695, 696, 697, 699, 698, 0, 701, 702, 700, 703,
-	704, 1661, 706, 0, 707, 844, 708, 687, 688, 709,
-	710, 711, 0, 712, 713, 714, 715, 716, 717, 718,
-	719, 720, 845, 0, 721, 0, 722, 723, 724, 725,
-	726, 727, 729, 689, 730, 731, 732, 737, 738, 846,
-	733, 734, 735, 736, 847, 740, 741, 742, 743, 0,
-	744, 745, 0, 739, 728, 0, 746, 747, 748, 749,
-	750, 751, 752, 753, 754, 755, 0, 756, 986, 849,
-	850, 851, 0, 768, 0, 757, 1659, 760, 761, 762,
-	852, 763, 853, 0, 764, 765, 766, 767, 758, 769,
-	770, 0, 0, 771, 772, 773, 774, 776, 778, 779,
-	780, 775, 777, 781, 0, 782, 0, 0, 783, 784,
-	785, 854, 855, 856, 0, 787, 788, 786, 789, 790,
-	793, 791, 792, 857, 796, 513, 797, 798, 799, 794,
-	795, 997, 0, 337, 0, 800, 801, 858, 802, 803,
-	804, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	345, 346, 348, 347, 349, 350, 351, 352, 995, 353,
-	354, 0, 0, 0, 0, 0, 805, 0, 0, 0,
-	356, 0, 355, 0, 357, 358, 359, 0, 360, 361,
-	362, 363, 364, 365, 366, 367, 806, 807, 0, 368,
-	808, 369, 809, 0, 810, 370, 371, 372, 373, 374,
-	375, 376, 377, 378, 379, 0, 0, 0, 380, 811,
-	812, 813, 0, 381, 382, 383, 384, 814, 0, 0,
-	0, 385, 386, 387, 388, 389, 390, 391, 392, 0,
-	0, 394, 395, 396, 393, 397, 398, 0, 399, 0,
-	400, 401, 402, 403, 404, 405, 406, 0, 407, 408,
-	409, 0, 410, 411, 412, 0, 0, 0, 0, 0,
-	0, 0, 413, 414, 415, 416, 417, 0, 418, 420,
-	421, 815, 422, 816, 0, 425, 427, 419, 423, 0,
-	426, 424, 428, 429, 0, 430, 431, 432, 433, 0,
-	0, 434, 435, 436, 0, 437, 438, 440, 439, 0,
-	441, 442, 443, 0, 444, 445, 817, 446, 447, 448,
-	450, 452, 449, 451, 453, 454, 455, 456, 457, 818,
-	819, 458, 459, 0, 0, 0, 0, 0, 0, 0,
-	460, 461, 462, 820, 0, 0, 0, 463, 0, 465,
-	469, 466, 467, 468, 470, 0, 464, 471, 472, 0,
-	0, 473, 474, 475, 821, 822, 476, 477, 478, 479,
-	480, 481, 482, 483, 484, 0, 485, 486, 823, 0,
-	824, 487, 0, 488, 489, 490, 491, 492, 493, 494,
-	825, 826, 827, 595, 0, 495, 496, 497, 0, 498,
-	499, 500, 501, 502, 503, 504, 0, 0, 0, 505,
-	506, 507, 508, 0, 0, 0, 0, 0, 828, 509,
-	596, 510, 829, 830, 0, 831, 0, 511, 512, 515,
-	0, 832, 0, 514, 516, 517, 0, 518, 0, 0,
-	0, 519, 520, 521, 522, 523, 524, 525, 0, 526,
-	528, 527, 0, 530, 833, 529, 0, 531, 532, 0,
-	0, 533, 534, 535, 536, 537, 538, 541, 0, 0,
-	539, 540, 542, 543, 0, 544, 545, 547, 550, 546,
-	548, 549, 551, 552, 565, 566, 553, 554, 555, 556,
-	557, 558, 559, 560, 561, 562, 563, 564, 568, 0,
-	567, 0, 569, 570, 571, 572, 573, 581, 583, 584,
-	579, 580, 582, 585, 586, 588, 589, 576, 577, 578,
-	0, 587, 574, 0, 575, 0, 0, 590, 591, 592,
-	593, 0, 834, 594, 835, 597, 598, 0, 0, 599,
-	0, 600, 0, 0, 602, 603, 604, 0, 0, 605,
-	606, 836, 0, 607, 0, 837, 608, 609, 601, 610,
-	611, 612, 613, 614, 615, 616, 617, 618, 619, 0,
-	620, 621, 838, 622, 623, 624, 839, 625, 626, 627,
-	840, 628, 841, 629, 630, 0, 631, 632, 633, 0,
-	634, 635, 636, 637, 638, 639, 640, 641, 642, 643,
-	842, 644, 645, 647, 646, 648, 649, 0, 650, 0,
-	651, 652, 653, 0, 0, 0, 0, 0, 654, 655,
-	657, 0, 658, 659, 660, 661, 662, 656, 663, 664,
-	665, 666, 667, 668, 669, 0, 671, 672, 670, 673,
-	674, 0, 675, 676, 677, 678, 679, 843, 680, 0,
-	681, 682, 690, 691, 692, 683, 684, 686, 693, 685,
-	694, 695, 696, 697, 699, 698, 0, 701, 702, 700,
-	703, 704, 705, 706, 0, 707, 844, 708, 687, 688,
-	709, 710, 711, 0, 712, 713, 714, 715, 716, 717,
-	718, 719, 720, 845, 0, 721, 0, 722, 723, 724,
-	725, 726, 727, 729, 689, 730, 731, 732, 737, 738,
-	846, 733, 734, 735, 736, 847, 740, 741, 742, 743,
-	0, 744, 745, 0, 739, 728, 0, 746, 747, 748,
-	749, 750, 751, 752, 753, 754, 755, 0, 756, 848,
-	849, 850, 851, 0, 768, 0, 757, 759, 760, 761,
-	762, 852, 763, 853, 0, 764, 765, 766, 767, 758,
-	769, 770, 0, 0, 771, 772, 773, 774, 776, 778,
-	779, 780, 775, 777, 781, 0, 782, 0, 0, 783,
-	784, 785, 854, 855, 856, 0, 787, 788, 786, 789,
-	790, 793, 791, 792, 857, 796, 513, 797, 798, 799,
-	794, 795, 901, 0, 337, 0, 800, 801, 858, 802,
-	803, 804, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 345, 346, 348, 347, 349, 350, 351, 352, 900,
-	353, 354, 0, 0, 0, 0, 0, 805, 0, 0,
-	0, 356, 0, 355, 0, 357, 358, 359, 0, 360,
-	361, 362, 363, 364, 365, 366, 367, 806, 807, 0,
-	368, 808, 369, 809, 0, 810, 370, 371, 372, 373,
-	374, 375, 376, 377, 378, 379, 0, 0, 0, 380,
-	811, 812, 813, 0, 381, 382, 383, 384, 814, 0,
-	0, 0, 385, 386, 387, 388, 389, 390, 391, 392,
-	0, 0, 394, 395, 396, 393, 397, 398, 0, 399,
-	0, 400, 401, 402, 403, 404, 405, 406, 0, 407,
-	408, 409, 0, 410, 411, 412, 0, 0, 0, 0,
-	0, 0, 0, 413, 414, 415, 416, 417, 0, 418,
-	420, 421, 815, 422, 816, 0, 425, 427, 419, 423,
-	0, 426, 424, 428, 429, 0, 430, 431, 432, 433,
-	0, 0, 434, 435, 436, 0, 437, 438, 440, 439,
-	0, 441, 442, 443, 0, 444, 445, 817, 446, 447,
-	448, 450, 452, 449, 451, 453, 454, 455, 456, 457,
-	818, 819, 458, 459, 0, 0, 0, 0, 0, 0,
-	0, 460, 461, 462, 820, 0, 0, 0, 463, 0,
-	465, 469, 466, 467, 468, 470, 0, 464, 471, 472,
-	0, 0, 473, 474, 475, 821, 822, 476, 477, 478,
-	479, 480, 481, 482, 483, 484, 0, 485, 486, 823,
-	0, 824, 487, 0, 488, 489, 490, 491, 492, 493,
-	494, 825, 826, 827, 595, 0, 495, 496, 497, 0,
-	498, 499, 500, 501, 502, 503, 504, 0, 0, 0,
-	505, 506, 507, 508, 0, 0, 0, 0, 0, 828,
-	509, 596, 510, 829, 830, 0, 831, 0, 511, 512,
-	515, 0, 832, 0, 514, 516, 517, 0, 518, 0,
-	0, 0, 519, 520, 521, 522, 523, 524, 525, 0,
-	526, 528, 527, 0, 530, 833, 529, 0, 531, 532,
-	0, 0, 533, 534, 535, 536, 537, 538, 541, 0,
-	0, 539, 540, 542, 543, 0, 544, 545, 547, 550,
-	546, 548, 549, 551, 552, 565, 566, 553, 554, 555,
-	556, 557, 558, 559, 560, 561, 562, 563, 564, 568,
-	0, 567, 0, 569, 570, 571, 572, 573, 581, 583,
-	584, 579, 580, 582, 585, 586, 588, 589, 576, 577,
-	578, 0, 587, 574, 0, 575, 0, 0, 590, 591,
-	592, 593, 0, 834, 594, 835, 597, 598, 0, 0,
-	599, 0, 600, 0, 0, 602, 603, 604, 0, 0,
-	605, 606, 836, 0, 607, 0, 837, 608, 609, 601,
-	610, 611, 612, 613, 614, 615, 616, 617, 618, 619,
-	0, 620, 621, 838, 622, 623, 624, 839, 625, 626,
-	627, 840, 628, 841, 899, 630, 0, 631, 632, 633,
-	0, 634, 635, 636, 637, 638, 639, 640, 641, 642,
-	643, 842, 644, 645, 647, 646, 648, 649, 0, 650,
-	0, 651, 652, 653, 0, 0, 0, 0, 0, 654,
-	655, 657, 0, 658, 659, 660, 661, 662, 656, 663,
-	664, 665, 666, 667, 668, 669, 0, 671, 672, 670,
-	673, 674, 0, 675, 676, 677, 678, 679, 843, 680,
-	0, 681, 682, 690, 691, 692, 683, 684, 686, 693,
-	685, 694, 695, 696, 697, 699, 698, 0, 701, 702,
-	700, 703, 704, 705, 706, 0, 707, 844, 708, 687,
-	688, 709, 710, 711, 0, 712, 713, 714, 715, 716,
-	717, 718, 719, 720, 845, 0, 721, 0, 722, 723,
-	724, 725, 726, 727, 729, 689, 730, 731, 732, 737,
-	738, 846, 733, 734, 735, 736, 847, 740, 741, 742,
-	743, 0, 744, 745, 0, 739, 728, 0, 746, 747,
-	748, 749, 750, 751, 752, 753, 754, 755, 0, 756,
-	848, 849, 850, 851, 0, 768, 0, 757, 759, 760,
-	761, 762, 852, 763, 853, 0, 764, 765, 766, 767,
-	758, 769, 770, 0, 0, 771, 772, 773, 774, 776,
-	778, 779, 780, 775, 777, 781, 0, 782, 0, 0,
-	783, 784, 785, 854, 855, 856, 0, 787, 788, 786,
-	789, 790, 793, 791, 792, 857, 796, 513, 797, 798,
-	799, 794, 795, 337, 4953, 0, 0, 800, 801, 858,
-	802, 803, 804, 0, 0, 0, 0, 0, 0, 0,
-	345, 346, 348, 347, 349, 350, 351, 352, 0, 353,
-	354, 0, 0, 0, 0, 0, 805, 0, 0, 0,
-	356, 0, 355, 0, 357, 358, 359, 0, 360, 361,
-	362, 363, 364, 365, 366, 367, 806, 807, 0, 368,
-	808, 369, 809, 0, 810, 370, 371, 372, 373, 374,
-	375, 376, 377, 378, 379, 0, 0, 0, 380, 811,
-	812, 813, 0, 381, 382, 383, 384, 814, 0, 0,
-	0, 385, 386, 387, 388, 389, 390, 391, 392, 0,
-	0, 394, 395, 396, 393, 397, 398, 0, 399, 0,
-	400, 401, 402, 403, 404, 405, 406, 0, 407, 408,
-	409, 0, 410, 411, 412, 0, 0, 0, 0, 0,
-	0, 0, 413, 414, 415, 416, 417, 0, 418, 420,
-	421, 815, 422, 816, 0, 425, 427, 419, 423, 0,
-	426, 424, 428, 429, 0, 430, 431, 432, 433, 0,
-	0, 434, 435, 436, 0, 437, 438, 440, 439, 0,
-	441, 442, 443, 0, 444, 445, 817, 446, 447, 448,
-	450, 452, 449, 451, 453, 454, 455, 456, 457, 818,
-	819, 458, 459, 0, 0, 0, 0, 0, 0, 0,
-	460, 461, 462, 820, 0, 0, 0, 463, 0, 465,
-	469, 466, 467, 468, 470, 0, 464, 471, 472, 0,
-	0, 473, 474, 475, 821, 822, 476, 477, 478, 479,
-	480, 481, 482, 483, 484, 0, 485, 486, 823, 0,
-	824, 487, 0, 488, 489, 490, 491, 492, 493, 494,
-	825, 826, 827, 595, 0, 495, 496, 497, 0, 498,
-	499, 500, 501, 502, 503, 504, 0, 0, 0, 505,
-	506, 507, 508, 0, 0, 0, 0, 0, 828, 509,
-	596, 510, 829, 830, 0, 831, 0, 511, 512, 515,
-	0, 832, 0, 514, 516, 517, 0, 518, 0, 0,
-	0, 519, 520, 521, 522, 523, 524, 525, 0, 526,
-	528, 527, 0, 530, 833, 529, 0, 531, 532, 0,
-	0, 533, 534, 535, 536, 537, 538, 541, 0, 0,
-	539, 540, 542, 543, 0, 544, 545, 547, 550, 546,
-	548, 549, 551, 552, 565, 566, 553, 554, 555, 556,
-	557, 558, 559, 560, 561, 562, 563, 564, 568, 0,
-	567, 0, 569, 570, 571, 572, 573, 581, 583, 584,
-	579, 580, 582, 585, 586, 588, 589, 576, 577, 578,
-	0, 587, 574, 0, 575, 0, 0, 590, 591, 592,
-	593, 0, 834, 594, 835, 597, 598, 0, 0, 599,
-	0, 600, 0, 0, 602, 603, 604, 0, 0, 605,
-	606, 836, 0, 607, 0, 837, 608, 609, 601, 610,
-	611, 612, 613, 614, 615, 616, 617, 618, 619, 0,
-	620, 621, 838, 622, 623, 624, 839, 625, 626, 627,
-	840, 628, 841, 629, 630, 0, 631, 632, 633, 0,
-	634, 635, 636, 637, 638, 639, 640, 641, 642, 643,
-	842, 644, 645, 647, 646, 648, 649, 0, 650, 0,
-	651, 652, 653, 0, 0, 0, 0, 0, 654, 655,
-	657, 0, 658, 659, 660, 661, 662, 656, 663, 664,
-	665, 666, 667, 668, 669, 0, 671, 672, 670, 673,
-	674, 0, 675, 676, 677, 678, 679, 843, 680, 0,
-	681, 682, 690, 691, 692, 683, 684, 686, 693, 685,
-	694, 695, 696, 697, 699, 698, 0, 701, 702, 700,
-	703, 704, 705, 706, 0, 707, 844, 708, 687, 688,
-	709, 710, 711, 0, 712, 713, 714, 715, 716, 717,
-	718, 719, 720, 845, 0, 721, 0, 722, 723, 724,
-	725, 726, 727, 729, 689, 730, 731, 732, 737, 738,
-	846, 733, 734, 735, 736, 847, 740, 741, 742, 743,
-	0, 744, 745, 0, 739, 728, 0, 746, 747, 748,
-	749, 750, 751, 752, 753, 754, 755, 0, 756, 848,
-	849, 850, 851, 0, 768, 0, 757, 759, 760, 761,
-	762, 852, 763, 853, 0, 764, 765, 766, 767, 758,
-	769, 770, 0, 0, 771, 772, 773, 774, 776, 778,
-	779, 780, 775, 777, 781, 0, 782, 0, 0, 783,
-	784, 785, 854, 855, 856, 0, 787, 788, 786, 789,
-	790, 793, 791, 792, 857, 796, 513, 797, 798, 799,
-	794, 795, 337, 4327, 0, 0, 800, 801, 858, 802,
-	803, 804, 0, 0, 0, 0, 0, 0, 0, 345,
-	346, 348, 347, 349, 350, 351, 352, 0, 353, 354,
-	0, 0, 0, 0, 0, 805, 0, 0, 0, 356,
-	0, 355, 0, 357, 358, 359, 0, 360, 361, 362,
-	363, 364, 365, 366, 367, 806, 807, 0, 368, 808,
-	369, 809, 0, 810, 370, 371, 372, 373, 374, 375,
-	376, 377, 378, 379, 0, 0, 0, 380, 811, 812,
-	813, 0, 381, 382, 383, 384, 814, 0, 0, 0,
-	385, 386, 387, 388, 389, 390, 391, 392, 0, 0,
-	394, 395, 396, 393, 397, 398, 0, 399, 0, 400,
-	401, 402, 403, 404, 405, 406, 0, 407, 408, 409,
-	0, 410, 411, 412, 0, 0, 0, 0, 0, 0,
-	0, 413, 414, 415, 416, 417, 0, 418, 420, 421,
-	815, 422, 816, 0, 425, 427, 419, 423, 0, 426,
-	424, 428, 429, 0, 430, 431, 432, 433, 0, 0,
-	434, 435, 436, 0, 437, 438, 440, 439, 0, 441,
-	442, 443, 0, 444, 445, 817, 446, 447, 448, 450,
-	452, 449, 451, 453, 454, 455, 456, 457, 818, 819,
-	458, 459, 0, 0, 0, 0, 0, 0, 0, 460,
-	461, 462, 820, 0, 0, 0, 463, 0, 465, 469,
-	466, 467, 468, 470, 0, 464, 471, 472, 0, 0,
-	473, 474, 475, 821, 822, 476, 477, 478, 479, 480,
-	481, 482, 483, 484, 0, 485, 486, 823, 0, 824,
-	487, 0, 488, 489, 490, 491, 492, 493, 494, 825,
-	826, 827, 595, 0, 495, 496, 497, 0, 498, 499,
-	500, 501, 502, 503, 504, 0, 0, 0, 505, 506,
-	507, 508, 0, 0, 0, 0, 0, 828, 509, 596,
-	510, 829, 830, 0, 831, 0, 511, 512, 515, 0,
-	832, 0, 514, 516, 517, 0, 518, 0, 0, 0,
-	519, 520, 521, 522, 523, 524, 525, 0, 526, 528,
-	527, 0, 530, 833, 529, 0, 531, 532, 0, 0,
-	533, 534, 535, 536, 537, 538, 541, 0, 0, 539,
-	540, 542, 543, 0, 544, 545, 547, 550, 546, 548,
-	549, 551, 552, 565, 566, 553, 554, 555, 556, 557,
-	558, 559, 560, 561, 562, 563, 564, 568, 0, 567,
-	0, 569, 570, 571, 572, 573, 581, 583, 584, 579,
-	580, 582, 585, 586, 588, 589, 576, 577, 578, 0,
-	587, 574, 0, 575, 0, 0, 590, 591, 592, 593,
-	0, 834, 594, 835, 597, 598, 0, 0, 599, 0,
-	600, 0, 0, 602, 603, 604, 0, 0, 605, 606,
-	836, 0, 607, 0, 837, 608, 609, 601, 610, 611,
-	612, 613, 614, 615, 616, 617, 618, 619, 0, 620,
-	621, 838, 622, 623, 624, 839, 625, 626, 627, 840,
-	628, 841, 629, 630, 0, 631, 632, 633, 0, 634,
-	635, 636, 637, 638, 639, 640, 641, 642, 643, 842,
-	644, 645, 647, 646, 648, 649, 0, 650, 0, 651,
-	652, 653, 0, 0, 0, 0, 0, 654, 655, 657,
-	0, 658, 659, 660, 661, 662, 656, 663, 664, 665,
-	666, 667, 668, 669, 0, 671, 672, 670, 673, 674,
-	0, 675, 676, 677, 678, 679, 843, 680, 0, 681,
-	682, 690, 691, 692, 683, 684, 686, 693, 685, 694,
-	695, 696, 697, 699, 698, 0, 701, 702, 700, 703,
-	704, 705, 706, 0, 707, 844, 708, 687, 688, 709,
-	710, 711, 0, 712, 713, 714, 715, 716, 717, 718,
-	719, 720, 845, 0, 721, 0, 722, 723, 724, 725,
-	726, 727, 729, 689, 730, 731, 732, 737, 738, 846,
-	733, 734, 735, 736, 847, 740, 741, 742, 743, 0,
-	744, 745, 0, 739, 728, 0, 746, 747, 748, 749,
-	750, 751, 752, 753, 754, 755, 0, 756, 848, 849,
-	850, 851, 0, 768, 0, 757, 759, 760, 761, 762,
-	852, 763, 853, 0, 764, 765, 766, 767, 758, 769,
-	770, 0, 0, 771, 772, 773, 774, 776, 778, 779,
-	780, 775, 777, 781, 0, 782, 0, 0, 783, 784,
-	785, 854, 855, 856, 0, 787, 788, 786, 789, 790,
-	793, 791, 792, 857, 796, 513, 797, 798, 799, 794,
-	795, 337, 4866, 0, 0, 800, 801, 858, 802, 803,
-	804, 0, 0, 0, 0, 0, 0, 0, 345, 346,
-	348, 347, 349, 350, 351, 352, 0, 353, 354, 0,
-	0, 0, 0, 0, 805, 0, 0, 0, 356, 0,
-	355, 0, 357, 358, 359, 0, 360, 361, 362, 363,
-	364, 365, 366, 367, 806, 807, 0, 368, 808, 369,
-	809, 0, 810, 370, 371, 372, 373, 374, 375, 376,
-	377, 378, 379, 0, 0, 0, 380, 811, 812, 813,
-	0, 381, 382, 383, 384, 814, 0, 0, 0, 385,
-	386, 387, 388, 389, 390, 391, 392, 0, 0, 394,
-	395, 396, 393, 397, 398, 0, 399, 0, 400, 401,
-	402, 403, 404, 405, 406, 0, 407, 408, 409, 0,
-	410, 411, 412, 0, 0, 0, 0, 0, 0, 0,
-	413, 414, 415, 416, 417, 0, 418, 420, 421, 815,
-	422, 816, 0, 425, 427, 419, 423, 0, 426, 424,
-	428, 429, 0, 430, 431, 432, 433, 0, 0, 434,
-	435, 436, 0, 437, 438, 440, 439, 0, 441, 442,
-	443, 0, 444, 445, 817, 446, 447, 448, 450, 452,
-	449, 451, 453, 454, 455, 456, 457, 818, 819, 458,
-	459, 0, 0, 0, 0, 0, 0, 0, 460, 461,
-	462, 820, 0, 0, 0, 463, 0, 465, 469, 466,
-	467, 468, 470, 0, 464, 471, 472, 0, 0, 473,
-	474, 475, 821, 822, 476, 477, 478, 479, 480, 481,
-	482, 483, 484, 0, 485, 486, 823, 0, 824, 487,
-	0, 488, 489, 490, 491, 492, 493, 494, 825, 826,
-	827, 595, 0, 495, 496, 497, 0, 498, 499, 500,
-	501, 502, 503, 504, 0, 0, 0, 505, 506, 507,
-	508, 0, 0, 0, 0, 0, 828, 509, 596, 510,
-	829, 830, 0, 831, 0, 511, 512, 515, 0, 832,
-	0, 514, 516, 517, 0, 518, 0, 0, 0, 519,
-	520, 521, 522, 523, 524, 525, 0, 526, 528, 527,
-	0, 530, 833, 529, 0, 531, 532, 0, 0, 533,
-	534, 535, 536, 537, 538, 541, 0, 0, 539, 540,
-	542, 543, 0, 544, 545, 547, 550, 546, 548, 549,
-	551, 552, 565, 566, 553, 554, 555, 556, 557, 558,
-	559, 560, 561, 562, 563, 564, 568, 0, 567, 0,
-	569, 570, 571, 572, 573, 581, 583, 584, 579, 580,
-	582, 585, 586, 588, 589, 576, 577, 578, 0, 587,
-	574, 0, 575, 0, 0, 590, 591, 592, 593, 0,
-	834, 594, 835, 597, 598, 0, 0, 599, 0, 600,
-	0, 0, 602, 603, 604, 0, 0, 605, 606, 836,
-	0, 607, 0, 837, 608, 609, 601, 610, 611, 612,
-	613, 614, 615, 616, 617, 618, 619, 0, 620, 621,
-	838, 622, 623, 624, 839, 625, 626, 627, 840, 628,
-	841, 629, 630, 0, 631, 632, 633, 0, 634, 635,
-	636, 637, 638, 639, 640, 641, 642, 643, 842, 644,
-	645, 647, 646, 648, 649, 0, 650, 0, 651, 652,
-	653, 0, 0, 0, 0, 0, 654, 655, 657, 0,
-	658, 659, 660, 661, 662, 656, 663, 664, 665, 666,
-	667, 668, 669, 0, 671, 672, 670, 673, 674, 0,
-	675, 676, 677, 678, 679, 843, 680, 0, 681, 682,
-	690, 691, 692, 683, 684, 686, 693, 685, 694, 695,
-	696, 697, 699, 698, 0, 701, 702, 700, 703, 704,
-	705, 706, 0, 707, 844, 708, 687, 688, 709, 710,
-	711, 0, 712, 713, 714, 715, 716, 717, 718, 719,
-	720, 845, 0, 721, 0, 722, 723, 724, 725, 726,
-	727, 729, 689, 730, 731, 732, 737, 738, 846, 733,
-	734, 735, 736, 847, 740, 741, 742, 743, 0, 744,
-	745, 0, 739, 728, 0, 746, 747, 748, 749, 750,
-	751, 752, 753, 754, 755, 0, 756, 848, 849, 850,
-	851, 0, 768, 0, 757, 759, 760, 761, 762, 852,
-	763, 853, 0, 764, 765, 766, 767, 758, 769, 770,
-	0, 0, 771, 772, 773, 774, 776, 778, 779, 780,
-	775, 777, 781, 0, 782, 0, 0, 783, 784, 785,
-	854, 855, 856, 0, 787, 788, 786, 789, 790, 793,
-	791, 792, 857, 796, 513, 797, 798, 799, 794, 795,
-	337, 0, 0, 0, 800, 801, 858, 802, 803, 804,
-	0, 0, 0, 0, 0, 0, 0, 345, 346, 348,
-	347, 349, 350, 351, 352, 0, 353, 354, 0, 0,
-	0, 0, 0, 805, 0, 0, 0, 356, 0, 355,
-	0, 357, 358, 359, 0, 360, 361, 362, 363, 364,
-	365, 366, 367, 806, 807, 0, 368, 808, 369, 809,
-	0, 810, 370, 371, 372, 373, 374, 375, 376, 377,
-	378, 379, 0, 0, 0, 380, 811, 812, 813, 0,
-	381, 382, 383, 384, 814, 0, 0, 0, 385, 386,
-	387, 388, 389, 390, 391, 392, 0, 0, 394, 395,
-	396, 393, 397, 398, 0, 399, 0, 400, 401, 402,
-	403, 404, 405, 406, 0, 407, 408, 409, 0, 410,
-	411, 412, 0, 0, 0, 0, 0, 0, 0, 413,
-	414, 415, 416, 417, 0, 418, 420, 421, 815, 422,
-	816, 5478, 425, 427, 419, 423, 0, 426, 424, 428,
-	429, 0, 430, 431, 432, 433, 0, 0, 434, 435,
-	436, 0, 437, 438, 440, 439, 0, 441, 442, 443,
-	0, 444, 445, 817, 446, 447, 448, 450, 452, 449,
-	451, 453, 454, 455, 456, 457, 818, 819, 458, 459,
-	0, 0, 0, 0, 0, 0, 0, 460, 461, 462,
-	820, 0, 0, 0, 463, 0, 465, 469, 466, 467,
-	468, 470, 0, 464, 471, 472, 0, 0, 473, 474,
-	475, 821, 822, 476, 477, 478, 479, 480, 481, 482,
-	483, 484, 0, 485, 486, 823, 0, 824, 487, 0,
-	488, 489, 490, 491, 492, 493, 494, 825, 826, 827,
-	595, 0, 495, 496, 497, 0, 498, 499, 500, 501,
-	502, 503, 504, 0, 0, 0, 505, 506, 507, 508,
-	0, 0, 0, 0, 0, 828, 509, 596, 510, 829,
-	830, 0, 831, 0, 511, 512, 515, 0, 832, 0,
-	514, 516, 517, 0, 518, 0, 0, 0, 519, 520,
-	521, 522, 523, 524, 525, 0, 526, 528, 527, 0,
-	530, 833, 529, 0, 531, 532, 0, 0, 533, 534,
-	535, 536, 537, 538, 541, 0, 0, 539, 540, 542,
-	543, 0, 544, 545, 547, 550, 546, 548, 549, 551,
-	552, 565, 566, 553, 554, 555, 556, 557, 558, 559,
-	560, 561, 562, 563, 564, 568, 0, 567, 0, 569,
-	570, 571, 572, 573, 581, 583, 584, 579, 580, 582,
-	585, 586, 588, 589, 576, 577, 578, 0, 587, 574,
-	0, 575, 0, 0, 590, 591, 592, 593, 0, 834,
-	594, 835, 597, 598, 0, 0, 599, 0, 600, 0,
-	0, 602, 603, 604, 0, 0, 605, 606, 836, 0,
-	607, 0, 837, 608, 609, 601, 610, 611, 612, 613,
-	614, 615, 616, 617, 618, 619, 0, 620, 621, 838,
-	622, 623, 624, 839, 625, 626, 627, 840, 628, 841,
-	629, 630, 0, 631, 632, 633, 0, 634, 635, 636,
-	637, 638, 639, 640, 641, 642, 643, 842, 644, 645,
-	647, 646, 648, 649, 0, 650, 0, 651, 652, 653,
-	0, 0, 0, 0, 0, 654, 655, 657, 0, 658,
-	659, 660, 661, 662, 656, 663, 664, 665, 666, 667,
-	668, 669, 0, 671, 672, 670, 673, 674, 0, 675,
-	676, 677, 678, 679, 843, 680, 0, 681, 682, 690,
-	691, 692, 683, 684, 686, 693, 685, 694, 695, 696,
-	697, 699, 698, 0, 701, 702, 700, 703, 704, 705,
-	706, 0, 707, 844, 708, 687, 688, 709, 710, 711,
-	0, 712, 713, 714, 715, 716, 717, 718, 719, 720,
-	845, 0, 721, 0, 722, 723, 724, 725, 726, 727,
-	729, 689, 730, 731, 732, 737, 738, 846, 733, 734,
-	735, 736, 847, 740, 741, 742, 743, 0, 744, 745,
-	0, 739, 728, 0, 746, 747, 748, 749, 750, 751,
-	752, 753, 754, 755, 0, 756, 848, 849, 850, 851,
-	0, 768, 0, 757, 759, 760, 761, 762, 852, 763,
-	853, 0, 764, 765, 766, 767, 758, 769, 770, 0,
-	0, 771, 772, 773, 774, 776, 778, 779, 780, 775,
-	777, 781, 0, 782, 0, 0, 783, 784, 785, 854,
-	855, 856, 0, 787, 788, 786, 789, 790, 793, 791,
-	792, 857, 796, 513, 797, 798, 799, 794, 795, 337,
-	0, 0, 0, 800, 801, 858, 802, 803, 804, 0,
-	0, 0, 0, 0, 0, 0, 345, 346, 348, 347,
-	349, 350, 351, 352, 0, 353, 354, 0, 0, 0,
-	0, 0, 805, 0, 3927, 0, 356, 0, 355, 0,
-	357, 358, 359, 0, 360, 361, 362, 363, 364, 365,
-	366, 367, 806, 807, 0, 368, 808, 369, 809, 0,
-	810, 370, 371, 372, 373, 374, 375, 376, 377, 378,
-	379, 0, 0, 0, 380, 811, 812, 813, 0, 381,
-	382, 383, 384, 814, 0, 0, 0, 385, 386, 387,
-	388, 389, 390, 391, 392, 0, 0, 394, 395, 396,
-	393, 397, 398, 0, 399, 0, 400, 401, 402, 403,
-	404, 405, 406, 0, 407, 408, 409, 0, 410, 411,
-	412, 0, 0, 0, 0, 0, 0, 0, 413, 414,
-	415, 416, 417, 0, 418, 420, 421, 815, 422, 816,
-	0, 425, 427, 419, 423, 0, 426, 424, 428, 429,
-	0, 430, 431, 432, 433, 0, 0, 434, 435, 436,
-	0, 437, 438, 440, 439, 0, 441, 442, 443, 0,
-	444, 445, 817, 446, 447, 448, 450, 452, 449, 451,
-	453, 454, 455, 456, 457, 818, 819, 458, 459, 0,
-	0, 0, 0, 0, 0, 0, 460, 461, 462, 820,
-	0, 0, 0, 463, 0, 465, 469, 466, 467, 468,
-	470, 0, 464, 471, 472, 0, 0, 473, 474, 475,
-	821, 822, 476, 477, 478, 479, 480, 481, 482, 483,
-	484, 0, 485, 486, 823, 0, 824, 487, 0, 488,
-	489, 490, 491, 492, 493, 494, 825, 826, 827, 595,
-	0, 495, 496, 497, 0, 498, 499, 500, 501, 502,
-	503, 504, 0, 0, 0, 505, 506, 507, 508, 0,
-	0, 0, 0, 0, 828, 509, 596, 510, 829, 830,
-	0, 831, 0, 511, 512, 515, 0, 832, 0, 514,
-	516, 517, 0, 518, 0, 0, 0, 519, 520, 521,
-	522, 523, 524, 525, 0, 526, 528, 527, 0, 530,
-	833, 529, 0, 531, 532, 0, 0, 533, 534, 535,
-	536, 537, 538, 541, 0, 0, 539, 540, 542, 543,
-	0, 544, 545, 547, 550, 546, 548, 549, 551, 552,
-	565, 566, 553, 554, 555, 556, 557, 558, 559, 560,
-	561, 562, 563, 564, 568, 0, 567, 0, 569, 570,
-	571, 572, 573, 581, 583, 584, 579, 580, 582, 585,
-	586, 588, 589, 576, 577, 578, 0, 587, 574, 0,
-	575, 0, 0, 590, 591, 592, 593, 0, 834, 594,
-	835, 597, 598, 0, 0, 599, 0, 600, 0, 0,
-	602, 603, 604, 0, 0, 605, 606, 836, 0, 607,
-	0, 837, 608, 609, 601, 610, 611, 612, 613, 614,
-	615, 616, 617, 618, 619, 0, 620, 621, 838, 622,
-	623, 624, 839, 625, 626, 627, 840, 628, 841, 629,
-	630, 0, 631, 632, 633, 0, 634, 635, 636, 637,
-	638, 639, 640, 641, 642, 643, 842, 644, 645, 647,
-	646, 648, 649, 0, 650, 0, 651, 652, 653, 0,
-	0, 0, 0, 0, 654, 655, 657, 0, 658, 659,
-	660, 661, 662, 656, 663, 664, 665, 666, 667, 668,
-	669, 0, 671, 672, 670, 673, 674, 0, 675, 676,
-	677, 678, 679, 843, 680, 0, 681, 682, 690, 691,
-	692, 683, 684, 686, 693, 685, 694, 695, 696, 697,
-	699, 698, 0, 701, 702, 700, 703, 704, 705, 706,
-	0, 707, 844, 708, 687, 688, 709, 710, 711, 0,
-	712, 713, 714, 715, 716, 717, 718, 719, 720, 845,
-	0, 721, 0, 722, 723, 724, 725, 726, 727, 729,
-	689, 730, 731, 732, 737, 738, 846, 733, 734, 735,
-	736, 847, 740, 741, 742, 743, 0, 744, 745, 0,
-	739, 728, 0, 746, 747, 748, 749, 750, 751, 752,
-	753, 754, 755, 0, 756, 848, 849, 850, 851, 0,
-	768, 0, 757, 759, 760, 761, 762, 852, 763, 853,
-	0, 764, 765, 766, 767, 758, 769, 770, 0, 0,
-	771, 772, 773, 774, 776, 778, 779, 780, 775, 777,
-	781, 0, 782, 0, 0, 783, 784, 785, 854, 855,
-	856, 0, 787, 788, 786, 789, 790, 793, 791, 792,
-	857, 796, 513, 797, 798, 799, 794, 795, 337, 0,
-	0, 0, 800, 801, 858, 802, 803, 804, 0, 0,
-	0, 0, 0, 0, 0, 345, 346, 348, 347, 349,
-	350, 351, 352, 0, 353, 354, 0, 0, 0, 0,
-	0, 805, 0, 3919, 0, 356, 0, 355, 0, 357,
-	358, 359, 0, 360, 361, 362, 363, 364, 365, 366,
-	367, 806, 807, 0, 368, 808, 369, 809, 0, 810,
-	370, 371, 372, 373, 374, 375, 376, 377, 378, 379,
-	0, 0, 0, 380, 811, 812, 813, 0, 381, 382,
-	383, 384, 814, 0, 0, 0, 385, 386, 387, 388,
-	389, 390, 391, 392, 0, 0, 394, 395, 396, 393,
-	397, 398, 0, 399, 0, 400, 401, 402, 403, 404,
-	405, 406, 0, 407, 408, 409, 0, 410, 411, 412,
-	0, 0, 0, 0, 0, 0, 0, 413, 414, 415,
-	416, 417, 0, 418, 420, 421, 815, 422, 816, 0,
-	425, 427, 419, 423, 0, 426, 424, 428, 429, 0,
-	430, 431, 432, 433, 0, 0, 434, 435, 436, 0,
-	437, 438, 440, 439, 0, 441, 442, 443, 0, 444,
-	445, 817, 446, 447, 448, 450, 452, 449, 451, 453,
-	454, 455, 456, 457, 818, 819, 458, 459, 0, 0,
-	0, 0, 0, 0, 0, 460, 461, 462, 820, 0,
-	0, 0, 463, 0, 465, 469, 466, 467, 468, 470,
-	0, 464, 471, 472, 0, 0, 473, 474, 475, 821,
-	822, 476, 477, 478, 479, 480, 481, 482, 483, 484,
-	0, 485, 486, 823, 0, 824, 487, 0, 488, 489,
-	490, 491, 492, 493, 494, 825, 826, 827, 595, 0,
-	495, 496, 497, 0, 498, 499, 500, 501, 502, 503,
-	504, 0, 0, 0, 505, 506, 507, 508, 0, 0,
-	0, 0, 0, 828, 509, 596, 510, 829, 830, 0,
-	831, 0, 511, 512, 515, 0, 832, 0, 514, 516,
-	517, 0, 518, 0, 0, 0, 519, 520, 521, 522,
-	523, 524, 525, 0, 526, 528, 527, 0, 530, 833,
-	529, 0, 531, 532, 0, 0, 533, 534, 535, 536,
-	537, 538, 541, 0, 0, 539, 540, 542, 543, 0,
-	544, 545, 547, 550, 546, 548, 549, 551, 552, 565,
-	566, 553, 554, 555, 556, 557, 558, 559, 560, 561,
-	562, 563, 564, 568, 0, 567, 0, 569, 570, 571,
-	572, 573, 581, 583, 584, 579, 580, 582, 585, 586,
-	588, 589, 576, 577, 578, 0, 587, 574, 0, 575,
-	0, 0, 590, 591, 592, 593, 0, 834, 594, 835,
-	597, 598, 0, 0, 599, 0, 600, 0, 0, 602,
-	603, 604, 0, 0, 605, 606, 836, 0, 607, 0,
-	837, 608, 609, 601, 610, 611, 612, 613, 614, 615,
-	616, 617, 618, 619, 0, 620, 621, 838, 622, 623,
-	624, 839, 625, 626, 627, 840, 628, 841, 629, 630,
-	0, 631, 632, 633, 0, 634, 635, 636, 637, 638,
-	639, 640, 641, 642, 643, 842, 644, 645, 647, 646,
-	648, 649, 0, 650, 0, 651, 652, 653, 0, 0,
-	0, 0, 0, 654, 655, 657, 0, 658, 659, 660,
-	661, 662, 656, 663, 664, 665, 666, 667, 668, 669,
-	0, 671, 672, 670, 673, 674, 0, 675, 676, 677,
-	678, 679, 843, 680, 0, 681, 682, 690, 691, 692,
-	683, 684, 686, 693, 685, 694, 695, 696, 697, 699,
-	698, 0, 701, 702, 700, 703, 704, 705, 706, 0,
-	707, 844, 708, 687, 688, 709, 710, 711, 0, 712,
-	713, 714, 715, 716, 717, 718, 719, 720, 845, 0,
-	721, 0, 722, 723, 724, 725, 726, 727, 729, 689,
-	730, 731, 732, 737, 738, 846, 733, 734, 735, 736,
-	847, 740, 741, 742, 743, 0, 744, 745, 0, 739,
-	728, 0, 746, 747, 748, 749, 750, 751, 752, 753,
-	754, 755, 0, 756, 848, 849, 850, 851, 0, 768,
-	0, 757, 759, 760, 761, 762, 852, 763, 853, 0,
-	764, 765, 766, 767, 758, 769, 770, 0, 0, 771,
-	772, 773, 774, 776, 778, 779, 780, 775, 777, 781,
-	0, 782, 0, 0, 783, 784, 785, 854, 855, 856,
-	0, 787, 788, 786, 789, 790, 793, 791, 792, 857,
-	796, 513, 797, 798, 799, 794, 795, 337, 4953, 0,
-	0, 800, 801, 858, 802, 803, 804, 0, 0, 0,
-	0, 0, 0, 0, 345, 346, 348, 347, 349, 350,
-	351, 352, 0, 353, 354, 0, 0, 0, 0, 0,
-	805, 0, 0, 0, 356, 0, 355, 0, 357, 358,
-	359, 0, 360, 361, 362, 363, 364, 365, 366, 367,
-	806, 807, 0, 368, 808, 369, 809, 0, 810, 370,
-	371, 372, 373, 374, 375, 376, 377, 378, 379, 0,
-	0, 0, 380, 811, 812, 813, 0, 381, 382, 383,
-	384, 814, 0, 0, 0, 385, 386, 387, 388, 389,
-	390, 391, 392, 0, 0, 394, 395, 396, 393, 397,
-	398, 0, 399, 0, 400, 401, 402, 403, 404, 405,
-	406, 0, 407, 408, 409, 0, 410, 411, 412, 0,
-	0, 0, 0, 0, 0, 0, 413, 414, 415, 416,
-	417, 0, 418, 420, 421, 815, 422, 816, 0, 425,
-	427, 419, 423, 0, 426, 424, 428, 429, 0, 430,
-	431, 432, 433, 0, 0, 434, 435, 436, 0, 437,
-	438, 440, 439, 0, 441, 442, 443, 0, 444, 445,
-	817, 446, 447, 448, 450, 452, 449, 451, 453, 454,
-	455, 456, 457, 818, 819, 458, 459, 0, 0, 0,
-	0, 0, 0, 0, 460, 461, 462, 820, 0, 0,
-	0, 463, 0, 465, 469, 466, 467, 468, 470, 0,
-	464, 471, 472, 0, 0, 473, 474, 475, 821, 822,
-	476, 477, 478, 479, 480, 481, 482, 483, 484, 0,
-	485, 486, 823, 0, 824, 487, 0, 488, 489, 490,
-	491, 492, 493, 494, 4956, 826, 827, 595, 0, 495,
-	496, 497, 0, 498, 499, 500, 501, 502, 503, 504,
-	0, 0, 0, 505, 506, 507, 508, 0, 0, 0,
-	0, 0, 828, 509, 596, 510, 829, 830, 0, 831,
-	0, 511, 512, 515, 0, 832, 0, 514, 516, 517,
-	0, 518, 0, 0, 0, 519, 520, 521, 522, 523,
-	524, 525, 0, 526, 528, 527, 0, 530, 833, 529,
-	0, 531, 532, 0, 0, 533, 534, 535, 536, 537,
-	538, 541, 0, 0, 539, 540, 542, 543, 0, 544,
-	545, 547, 550, 546, 548, 549, 551, 552, 565, 566,
-	553, 554, 555, 556, 557, 558, 559, 560, 561, 562,
-	563, 564, 568, 0, 567, 0, 569, 570, 571, 572,
-	573, 581, 583, 584, 579, 580, 582, 585, 586, 588,
-	589, 576, 577, 578, 0, 587, 574, 0, 575, 0,
-	0, 590, 591, 592, 593, 0, 834, 594, 835, 597,
-	598, 0, 0, 599, 0, 600, 0, 0, 602, 603,
-	604, 0, 0, 605, 606, 836, 0, 607, 0, 837,
-	608, 609, 601, 610, 611, 612, 613, 614, 615, 616,
-	617, 618, 619, 0, 620, 621, 838, 622, 623, 624,
-	839, 625, 626, 627, 840, 628, 841, 629, 630, 0,
-	631, 632, 633, 0, 634, 635, 636, 637, 638, 639,
-	640, 641, 642, 643, 842, 644, 645, 647, 646, 648,
-	649, 0, 650, 0, 651, 652, 653, 0, 0, 0,
-	0, 0, 654, 655, 657, 0, 658, 659, 660, 661,
-	662, 656, 663, 664, 665, 666, 667, 668, 669, 0,
-	671, 672, 670, 673, 674, 0, 675, 676, 677, 678,
-	679, 843, 680, 0, 681, 682, 690, 691, 692, 683,
-	684, 686, 693, 685, 694, 695, 696, 697, 699, 698,
-	0, 701, 702, 700, 703, 704, 705, 706, 0, 707,
-	844, 708, 687, 688, 709, 710, 711, 0, 712, 713,
-	714, 715, 716, 717, 718, 719, 720, 845, 0, 721,
-	0, 722, 723, 724, 725, 726, 727, 729, 689, 730,
-	731, 732, 737, 738, 846, 733, 734, 735, 736, 847,
-	740, 741, 742, 743, 0, 744, 745, 0, 739, 728,
-	0, 746, 747, 748, 749, 750, 751, 752, 753, 754,
-	755, 0, 756, 848, 849, 850, 851, 0, 768, 0,
-	757, 759, 760, 761, 762, 852, 763, 853, 0, 764,
-	765, 766, 767, 758, 769, 770, 0, 0, 771, 772,
-	773, 774, 776, 778, 779, 780, 775, 777, 781, 0,
-	782, 0, 0, 783, 784, 785, 854, 855, 856, 0,
-	787, 788, 786, 789, 790, 793, 791, 792, 857, 796,
-	513, 797, 798, 799, 794, 795, 337, 4953, 0, 0,
-	800, 801, 858, 802, 803, 804, 0, 0, 0, 0,
-	0, 0, 0, 345, 346, 348, 347, 349, 350, 351,
-	352, 0, 353, 354, 0, 0, 0, 0, 0, 805,
-	0, 0, 0, 356, 0, 355, 0, 357, 358, 359,
-	0, 360, 361, 362, 363, 364, 365, 366, 367, 806,
-	807, 0, 368, 808, 369, 809, 0, 810, 370, 371,
-	372, 373, 374, 375, 376, 377, 378, 379, 0, 0,
-	0, 380, 811, 812, 813, 0, 381, 382, 383, 384,
-	814, 0, 0, 0, 385, 386, 387, 388, 389, 390,
-	391, 392, 0, 0, 394, 395, 396, 393, 397, 398,
-	0, 399, 0, 400, 401, 402, 403, 404, 405, 406,
-	0, 407, 408, 409, 0, 410, 411, 412, 0, 0,
-	0, 0, 0, 0, 0, 413, 414, 415, 416, 417,
-	0, 418, 420, 421, 815, 422, 816, 0, 425, 427,
-	419, 423, 0, 426, 424, 428, 429, 0, 430, 431,
-	432, 433, 0, 0, 434, 435, 436, 0, 437, 438,
-	440, 439, 0, 441, 442, 443, 0, 444, 445, 817,
-	446, 447, 448, 450, 452, 449, 451, 453, 454, 455,
-	456, 457, 818, 819, 458, 459, 0, 0, 0, 0,
-	0, 0, 0, 460, 461, 462, 820, 0, 0, 0,
-	463, 0, 465, 469, 466, 467, 468, 470, 0, 464,
-	471, 472, 0, 0, 473, 474, 475, 821, 822, 476,
-	477, 478, 479, 480, 481, 482, 483, 484, 0, 485,
-	486, 823, 0, 824, 487, 0, 488, 489, 490, 491,
-	492, 493, 494, 4951, 826, 827, 595, 0, 495, 496,
-	497, 0, 498, 499, 500, 501, 502, 503, 504, 0,
-	0, 0, 505, 506, 507, 508, 0, 0, 0, 0,
-	0, 828, 509, 596, 510, 829, 830, 0, 831, 0,
-	511, 512, 515, 0, 832, 0, 514, 516, 517, 0,
-	518, 0, 0, 0, 519, 520, 521, 522, 523, 524,
-	525, 0, 526, 528, 527, 0, 530, 833, 529, 0,
-	531, 532, 0, 0, 533, 534, 535, 536, 537, 538,
-	541, 0, 0, 539, 540, 542, 543, 0, 544, 545,
-	547, 550, 546, 548, 549, 551, 552, 565, 566, 553,
-	554, 555, 556, 557, 558, 559, 560, 561, 562, 563,
-	564, 568, 0, 567, 0, 569, 570, 571, 572, 573,
-	581, 583, 584, 579, 580, 582, 585, 586, 588, 589,
-	576, 577, 578, 0, 587, 574, 0, 575, 0, 0,
-	590, 591, 592, 593, 0, 834, 594, 835, 597, 598,
-	0, 0, 599, 0, 600, 0, 0, 602, 603, 604,
-	0, 0, 605, 606, 836, 0, 607, 0, 837, 608,
-	609, 601, 610, 611, 612, 613, 614, 615, 616, 617,
-	618, 619, 0, 620, 621, 838, 622, 623, 624, 839,
-	625, 626, 627, 840, 628, 841, 629, 630, 0, 631,
-	632, 633, 0, 634, 635, 636, 637, 638, 639, 640,
-	641, 642, 643, 842, 644, 645, 647, 646, 648, 649,
-	0, 650, 0, 651, 652, 653, 0, 0, 0, 0,
-	0, 654, 655, 657, 0, 658, 659, 660, 661, 662,
-	656, 663, 664, 665, 666, 667, 668, 669, 0, 671,
-	672, 670, 673, 674, 0, 675, 676, 677, 678, 679,
-	843, 680, 0, 681, 682, 690, 691, 692, 683, 684,
-	686, 693, 685, 694, 695, 696, 697, 699, 698, 0,
-	701, 702, 700, 703, 704, 705, 706, 0, 707, 844,
-	708, 687, 688, 709, 710, 711, 0, 712, 713, 714,
-	715, 716, 717, 718, 719, 720, 845, 0, 721, 0,
-	722, 723, 724, 725, 726, 727, 729, 689, 730, 731,
-	732, 737, 738, 846, 733, 734, 735, 736, 847, 740,
-	741, 742, 743, 0, 744, 745, 0, 739, 728, 0,
-	746, 747, 748, 749, 750, 751, 752, 753, 754, 755,
-	0, 756, 848, 849, 850, 851, 0, 768, 0, 757,
-	759, 760, 761, 762, 852, 763, 853, 0, 764, 765,
-	766, 767, 758, 769, 770, 0, 0, 771, 772, 773,
-	774, 776, 778, 779, 780, 775, 777, 781, 0, 782,
-	0, 0, 783, 784, 785, 854, 855, 856, 0, 787,
-	788, 786, 789, 790, 793, 791, 792, 857, 796, 513,
-	797, 798, 799, 794, 795, 337, 4327, 0, 0, 800,
-	801, 858, 802, 803, 804, 0, 0, 0, 0, 0,
-	0, 0, 345, 346, 348, 347, 349, 350, 351, 352,
-	0, 353, 354, 0, 0, 0, 0, 0, 805, 0,
-	0, 0, 356, 0, 355, 0, 357, 358, 359, 0,
-	360, 361, 362, 363, 364, 365, 366, 367, 806, 807,
-	0, 368, 808, 369, 809, 0, 810, 370, 371, 372,
-	373, 374, 375, 376, 377, 378, 379, 0, 0, 0,
-	380, 811, 812, 813, 0, 381, 382, 383, 384, 814,
-	0, 0, 0, 385, 386, 387, 388, 389, 390, 391,
-	392, 0, 0, 394, 395, 396, 393, 397, 398, 0,
-	399, 0, 400, 401, 402, 403, 404, 405, 406, 0,
-	407, 408, 409, 0, 410, 411, 412, 0, 0, 0,
-	0, 0, 0, 0, 413, 414, 415, 416, 417, 0,
-	418, 420, 421, 815, 422, 816, 0, 425, 427, 419,
-	423, 0, 426, 424, 428, 429, 0, 430, 431, 432,
-	433, 0, 0, 434, 435, 436, 0, 437, 438, 440,
-	439, 0, 441, 442, 443, 0, 444, 445, 817, 446,
-	447, 448, 450, 452, 449, 451, 453, 454, 455, 456,
-	457, 818, 819, 458, 459, 0, 0, 0, 0, 0,
-	0, 0, 460, 461, 462, 820, 0, 0, 0, 463,
-	0, 465, 469, 466, 467, 468, 470, 0, 464, 471,
-	472, 0, 0, 473, 474, 475, 821, 822, 476, 477,
-	478, 479, 480, 481, 482, 483, 484, 0, 485, 486,
-	823, 0, 824, 487, 0, 488, 489, 490, 491, 492,
-	493, 494, 825, 826, 827, 595, 0, 495, 496, 497,
-	0, 498, 499, 500, 501, 502, 503, 504, 0, 0,
-	0, 505, 506, 507, 508, 0, 0, 0, 0, 0,
-	828, 509, 596, 510, 829, 830, 0, 831, 0, 511,
-	512, 515, 0, 832, 0, 514, 516, 517, 0, 518,
-	0, 0, 0, 519, 520, 521, 522, 523, 524, 525,
-	0, 526, 528, 527, 0, 530, 833, 529, 0, 531,
-	532, 0, 0, 533, 534, 535, 536, 537, 538, 541,
-	0, 0, 539, 540, 542, 543, 0, 544, 545, 547,
-	550, 546, 548, 549, 551, 552, 565, 566, 553, 554,
-	555, 556, 557, 558, 559, 560, 561, 562, 563, 564,
-	568, 0, 567, 0, 569, 570, 571, 572, 573, 581,
-	583, 584, 579, 580, 582, 585, 586, 588, 589, 576,
-	577, 578, 0, 587, 574, 0, 575, 0, 0, 590,
-	591, 592, 593, 0, 834, 594, 835, 597, 598, 0,
-	0, 599, 0, 600, 0, 0, 602, 603, 4428, 0,
-	0, 605, 606, 836, 0, 607, 0, 837, 608, 609,
-	601, 610, 611, 612, 613, 614, 615, 616, 617, 618,
-	619, 0, 620, 621, 838, 622, 623, 624, 839, 625,
-	626, 627, 840, 628, 841, 629, 630, 0, 631, 632,
-	633, 0, 634, 635, 636, 637, 638, 639, 640, 641,
-	642, 643, 842, 644, 645, 647, 646, 648, 649, 0,
-	650, 0, 651, 652, 653, 0, 0, 0, 0, 0,
-	654, 655, 657, 0, 658, 659, 660, 661, 662, 656,
-	663, 664, 665, 666, 667, 668, 669, 0, 671, 672,
-	670, 673, 674, 0, 675, 676, 677, 678, 679, 843,
-	680, 0, 681, 682, 690, 691, 692, 683, 684, 686,
-	693, 685, 694, 695, 696, 697, 699, 698, 0, 701,
-	702, 700, 703, 704, 705, 706, 0, 707, 844, 708,
-	687, 688, 709, 710, 711, 0, 712, 713, 714, 715,
-	716, 717, 718, 719, 720, 845, 0, 721, 0, 722,
-	723, 724, 725, 726, 727, 729, 689, 730, 731, 732,
-	737, 738, 846, 733, 734, 735, 736, 847, 740, 741,
-	742, 743, 0, 744, 745, 0, 739, 728, 0, 746,
-	747, 748, 749, 750, 751, 752, 753, 754, 755, 0,
-	756, 848, 849, 850, 851, 0, 768, 0, 757, 759,
-	760, 761, 762, 852, 763, 853, 0, 764, 765, 766,
-	767, 758, 769, 770, 0, 0, 771, 772, 773, 774,
-	776, 778, 779, 780, 775, 777, 781, 0, 782, 0,
-	0, 783, 784, 785, 854, 855, 856, 0, 787, 788,
-	786, 789, 790, 793, 791, 792, 857, 796, 513, 797,
-	798, 799, 794, 795, 337, 0, 0, 0, 800, 801,
-	858, 802, 803, 804, 0, 0, 0, 0, 0, 0,
-	0, 345, 346, 348, 347, 349, 350, 351, 352, 0,
-	353, 354, 0, 0, 0, 0, 0, 805, 0, 0,
-	0, 356, 0, 355, 0, 357, 358, 359, 0, 360,
-	361, 362, 363, 364, 365, 366, 367, 806, 807, 0,
-	368, 808, 369, 809, 0, 810, 370, 371, 372, 373,
-	374, 375, 376, 377, 378, 379, 0, 0, 0, 380,
-	811, 812, 813, 0, 381, 382, 383, 384, 814, 0,
-	0, 0, 385, 386, 387, 388, 389, 390, 391, 392,
-	0, 0, 394, 395, 396, 393, 397, 398, 0, 399,
-	0, 400, 401, 402, 403, 404, 405, 406, 0, 407,
-	408, 409, 0, 410, 411, 412, 0, 0, 0, 0,
-	0, 0, 0, 413, 414, 415, 416, 417, 0, 418,
-	420, 421, 815, 422, 816, 0, 425, 427, 419, 423,
-	0, 426, 424, 428, 429, 0, 430, 431, 432, 433,
-	0, 0, 434, 435, 436, 0, 437, 438, 440, 439,
-	0, 441, 442, 443, 0, 444, 445, 817, 446, 447,
-	448, 450, 452, 449, 451, 453, 454, 455, 456, 457,
-	818, 819, 458, 459, 0, 0, 0, 0, 0, 0,
-	0, 460, 461, 462, 820, 0, 0, 0, 463, 0,
-	465, 469, 466, 467, 468, 470, 0, 464, 471, 472,
-	0, 0, 473, 474, 475, 821, 822, 476, 477, 478,
-	479, 480, 481, 482, 483, 484, 0, 485, 486, 823,
-	0, 824, 487, 0, 488, 489, 490, 491, 492, 493,
-	494, 825, 826, 827, 595, 0, 495, 496, 497, 0,
-	498, 499, 500, 501, 502, 503, 504, 0, 0, 0,
-	505, 506, 507, 508, 0, 0, 0, 0, 0, 828,
-	509, 596, 510, 829, 830, 0, 831, 0, 511, 512,
-	515, 0, 832, 0, 514, 516, 517, 0, 518, 0,
-	0, 0, 519, 520, 521, 522, 523, 524, 525, 0,
-	526, 528, 527, 0, 530, 833, 529, 0, 531, 532,
-	0, 0, 533, 534, 535, 536, 537, 538, 541, 0,
-	0, 539, 540, 542, 543, 0, 544, 545, 547, 550,
-	546, 548, 549, 551, 552, 565, 566, 553, 554, 555,
-	556, 557, 558, 559, 560, 561, 562, 563, 564, 568,
-	0, 567, 0, 569, 570, 571, 572, 573, 581, 583,
-	584, 579, 580, 582, 585, 586, 588, 589, 576, 577,
-	578, 0, 587, 574, 0, 575, 0, 0, 590, 591,
-	592, 593, 0, 834, 594, 835, 597, 598, 0, 0,
-	599, 0, 600, 0, 0, 602, 603, 604, 0, 0,
-	605, 606, 836, 0, 607, 0, 837, 608, 609, 601,
-	610, 611, 612, 613, 614, 615, 616, 617, 618, 619,
-	0, 620, 621, 838, 622, 623, 624, 839, 625, 626,
-	627, 840, 628, 841, 629, 630, 2811, 631, 632, 633,
-	0, 634, 635, 636, 637, 638, 639, 640, 641, 642,
-	643, 842, 644, 645, 647, 646, 648, 649, 0, 650,
-	0, 651, 652, 653, 0, 0, 0, 0, 0, 654,
-	655, 657, 0, 658, 659, 660, 661, 662, 656, 663,
-	664, 665, 666, 667, 668, 669, 0, 671, 672, 670,
-	673, 674, 0, 989, 676, 677, 678, 679, 843, 680,
-	0, 681, 682, 690, 691, 692, 683, 684, 686, 988,
-	685, 694, 695, 696, 697, 4275, 698, 0, 701, 702,
-	700, 703, 704, 705, 706, 0, 707, 844, 708, 687,
-	688, 709, 710, 711, 0, 712, 713, 714, 715, 716,
-	717, 718, 719, 720, 845, 0, 721, 0, 722, 723,
-	724, 725, 726, 727, 729, 689, 730, 731, 732, 737,
-	738, 846, 733, 734, 735, 736, 847, 740, 741, 742,
-	743, 0, 744, 745, 0, 739, 728, 0, 746, 747,
-	748, 749, 750, 751, 752, 753, 754, 755, 0, 756,
-	986, 849, 850, 851, 0, 768, 0, 757, 759, 760,
-	761, 762, 852, 763, 853, 0, 764, 765, 766, 767,
-	758, 769, 770, 0, 0, 771, 772, 773, 774, 776,
-	778, 779, 780, 775, 777, 781, 0, 782, 0, 0,
-	783, 784, 785, 854, 855, 856, 0, 787, 788, 786,
-	789, 790, 793, 791, 792, 857, 796, 513, 797, 798,
-	799, 794, 795, 2994, 0, 337, 0, 800, 801, 858,
-	802, 803, 804, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 345, 346, 348, 347, 349, 350, 351, 352,
-	0, 353, 354, 0, 0, 0, 0, 0, 805, 0,
-	0, 0, 356, 0, 355, 0, 357, 358, 359, 0,
-	360, 361, 362, 363, 364, 365, 366, 367, 806, 807,
-	0, 368, 808, 369, 809, 0, 810, 370, 371, 372,
-	373, 374, 375, 376, 377, 378, 379, 0, 0, 0,
-	380, 811, 812, 813, 0, 381, 382, 383, 384, 814,
-	0, 0, 0, 385, 386, 387, 388, 389, 390, 391,
-	392, 0, 0, 394, 395, 396, 393, 397, 398, 0,
-	399, 0, 400, 401, 402, 403, 404, 405, 406, 0,
-	407, 408, 409, 0, 410, 411, 412, 0, 0, 0,
-	0, 0, 0, 0, 413, 414, 415, 416, 417, 0,
-	418, 420, 421, 815, 422, 816, 0, 425, 427, 419,
-	423, 0, 426, 424, 428, 429, 0, 430, 431, 432,
-	433, 0, 0, 434, 435, 436, 0, 437, 438, 440,
-	439, 0, 441, 442, 443, 0, 444, 445, 817, 446,
-	447, 448, 450, 452, 449, 451, 453, 454, 455, 456,
-	457, 818, 819, 458, 459, 0, 0, 0, 0, 0,
-	0, 0, 460, 461, 462, 820, 0, 0, 0, 463,
-	0, 465, 469, 466, 467, 468, 470, 0, 464, 471,
-	472, 0, 0, 473, 474, 475, 821, 822, 476, 477,
-	478, 479, 480, 481, 482, 483, 484, 0, 485, 486,
-	823, 0, 824, 487, 0, 488, 489, 490, 491, 492,
-	493, 494, 825, 826, 827, 595, 0, 495, 496, 497,
-	0, 498, 499, 500, 501, 502, 503, 504, 0, 0,
-	0, 505, 506, 507, 508, 0, 0, 0, 0, 0,
-	828, 509, 596, 510, 829, 830, 0, 831, 0, 511,
-	512, 515, 0, 832, 0, 514, 516, 517, 0, 518,
-	0, 0, 0, 519, 520, 521, 522, 523, 524, 525,
-	0, 526, 528, 527, 0, 530, 833, 529, 0, 531,
-	532, 0, 0, 533, 534, 535, 536, 537, 538, 541,
-	0, 0, 539, 540, 542, 543, 0, 544, 545, 547,
-	550, 546, 548, 549, 551, 552, 565, 566, 553, 554,
-	555, 556, 557, 558, 559, 560, 561, 562, 563, 564,
-	568, 0, 567, 0, 569, 570, 571, 572, 573, 581,
-	583, 584, 579, 580, 582, 585, 586, 588, 589, 576,
-	577, 578, 0, 587, 574, 0, 575, 0, 0, 590,
-	591, 592, 593, 0, 834, 594, 835, 597, 598, 0,
-	0, 599, 0, 600, 0, 0, 602, 603, 604, 0,
-	0, 605, 606, 836, 0, 607, 0, 837, 608, 609,
-	601, 610, 611, 612, 613, 614, 615, 616, 617, 618,
-	619, 0, 620, 621, 838, 622, 623, 624, 839, 625,
-	626, 627, 840, 628, 841, 629, 630, 0, 631, 632,
-	633, 0, 634, 635, 636, 637, 638, 639, 640, 641,
-	642, 643, 842, 644, 645, 647, 646, 648, 649, 0,
-	650, 0, 651, 652, 653, 0, 0, 0, 0, 0,
-	654, 655, 657, 0, 658, 659, 660, 661, 662, 656,
-	663, 664, 665, 666, 667, 668, 669, 0, 671, 672,
-	670, 673, 674, 0, 675, 676, 677, 678, 679, 843,
-	680, 0, 681, 682, 690, 691, 692, 683, 684, 686,
-	693, 685, 694, 695, 696, 697, 699, 698, 0, 701,
-	702, 700, 703, 704, 705, 706, 0, 707, 844, 708,
-	687, 688, 709, 710, 711, 0, 712, 713, 714, 715,
-	716, 717, 718, 719, 720, 845, 0, 721, 0, 722,
-	723, 724, 725, 726, 727, 729, 689, 730, 731, 732,
-	737, 738, 846, 733, 734, 735, 736, 847, 740, 741,
-	742, 743, 0, 744, 745, 0, 739, 728, 0, 746,
-	747, 748, 749, 750, 751, 752, 753, 754, 755, 0,
-	756, 848, 849, 850, 851, 0, 768, 0, 757, 759,
-	760, 761, 762, 852, 763, 853, 0, 764, 765, 766,
-	767, 758, 769, 770, 0, 0, 771, 772, 773, 774,
-	776, 778, 779, 780, 775, 777, 781, 0, 782, 0,
-	0, 783, 784, 785, 854, 855, 856, 0, 787, 788,
-	786, 789, 790, 793, 791, 792, 857, 796, 513, 797,
-	798, 799, 794, 795, 337, 0, 0, 0, 800, 801,
-	858, 802, 803, 804, 0, 0, 0, 0, 0, 0,
-	0, 345, 346, 348, 347, 349, 350, 351, 352, 2598,
-	353, 354, 0, 0, 0, 0, 0, 805, 0, 0,
-	0, 356, 0, 355, 0, 357, 358, 359, 0, 360,
-	361, 362, 363, 364, 365, 366, 367, 806, 807, 0,
-	368, 808, 369, 809, 0, 810, 370, 371, 372, 373,
-	374, 375, 376, 377, 378, 379, 0, 0, 0, 380,
-	811, 812, 813, 0, 381, 382, 383, 384, 814, 0,
-	0, 0, 385, 386, 387, 388, 389, 390, 391, 392,
-	0, 0, 394, 395, 396, 393, 397, 398, 0, 399,
-	0, 400, 401, 402, 403, 404, 405, 406, 0, 407,
-	408, 409, 0, 410, 411, 412, 0, 0, 0, 0,
-	0, 0, 0, 413, 414, 415, 416, 417, 0, 418,
-	420, 421, 815, 422, 816, 0, 425, 427, 419, 423,
-	0, 426, 424, 428, 429, 0, 430, 431, 432, 433,
-	0, 0, 434, 435, 436, 0, 437, 438, 440, 439,
-	0, 441, 442, 443, 0, 444, 445, 817, 446, 447,
-	448, 450, 452, 449, 451, 453, 454, 455, 456, 457,
-	818, 819, 458, 459, 0, 0, 0, 0, 0, 0,
-	0, 460, 461, 462, 820, 0, 0, 0, 463, 0,
-	465, 469, 466, 467, 468, 470, 0, 464, 471, 472,
-	0, 0, 473, 474, 475, 821, 822, 476, 477, 478,
-	479, 480, 481, 482, 483, 484, 0, 485, 486, 823,
-	0, 824, 487, 0, 488, 489, 490, 491, 492, 493,
-	494, 825, 826, 827, 595, 0, 495, 496, 497, 0,
-	498, 499, 500, 501, 502, 503, 504, 0, 0, 0,
-	505, 506, 507, 508, 0, 0, 0, 0, 0, 828,
-	509, 596, 510, 829, 830, 0, 831, 0, 511, 512,
-	515, 0, 832, 0, 514, 516, 517, 0, 518, 0,
-	0, 0, 519, 520, 521, 522, 523, 524, 525, 0,
-	526, 528, 527, 0, 530, 833, 529, 0, 531, 532,
-	0, 0, 533, 534, 535, 536, 537, 538, 541, 0,
-	0, 539, 540, 542, 543, 0, 544, 545, 547, 550,
-	546, 548, 549, 551, 552, 565, 566, 553, 554, 555,
-	556, 557, 558, 559, 560, 561, 562, 563, 564, 568,
-	0, 567, 0, 569, 570, 571, 572, 573, 581, 583,
-	584, 579, 580, 582, 585, 586, 588, 589, 576, 577,
-	578, 0, 587, 574, 0, 575, 0, 0, 590, 591,
-	592, 593, 0, 834, 594, 835, 597, 598, 0, 0,
-	599, 0, 600, 0, 0, 602, 603, 604, 0, 0,
-	605, 606, 836, 0, 607, 0, 837, 608, 609, 601,
-	610, 611, 612, 613, 614, 615, 616, 617, 618, 619,
-	0, 620, 621, 838, 622, 623, 624, 839, 625, 626,
-	627, 840, 628, 841, 629, 630, 0, 631, 632, 633,
-	0, 634, 635, 636, 637, 638, 639, 640, 641, 642,
-	643, 842, 644, 645, 647, 646, 648, 649, 0, 650,
-	0, 651, 652, 653, 0, 0, 0, 0, 0, 654,
-	655, 657, 0, 658, 659, 660, 661, 662, 656, 663,
-	664, 665, 666, 667, 668, 669, 0, 671, 672, 670,
-	673, 674, 0, 675, 676, 677, 678, 679, 843, 680,
-	0, 681, 682, 690, 691, 692, 683, 684, 686, 693,
-	685, 694, 695, 696, 697, 699, 698, 0, 701, 702,
-	700, 703, 704, 705, 706, 0, 707, 844, 708, 687,
-	688, 709, 710, 711, 0, 712, 713, 714, 715, 716,
-	717, 718, 719, 720, 845, 0, 721, 0, 722, 723,
-	724, 725, 726, 727, 729, 689, 730, 731, 732, 737,
-	738, 846, 733, 734, 735, 736, 847, 740, 741, 742,
-	743, 0, 744, 745, 0, 739, 728, 0, 746, 747,
-	748, 749, 750, 751, 752, 753, 754, 755, 0, 756,
-	848, 849, 850, 851, 0, 768, 0, 757, 759, 760,
-	761, 762, 852, 763, 853, 0, 764, 765, 766, 767,
-	758, 769, 770, 0, 0, 771, 772, 773, 774, 776,
-	778, 779, 780, 775, 777, 781, 0, 782, 0, 0,
-	783, 784, 785, 854, 855, 856, 0, 787, 788, 786,
-	789, 790, 793, 791, 792, 857, 796, 513, 797, 798,
-	799, 794, 795, 2142, 0, 337, 0, 800, 801, 858,
-	802, 803, 804, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 345, 346, 348, 347, 349, 350, 351, 352,
-	0, 353, 354, 0, 0, 0, 0, 0, 805, 0,
-	0, 0, 356, 0, 355, 0, 357, 358, 359, 0,
-	360, 361, 362, 363, 364, 365, 366, 367, 806, 807,
-	0, 368, 808, 369, 809, 0, 810, 370, 371, 372,
-	373, 374, 375, 376, 377, 378, 379, 0, 0, 0,
-	380, 811, 812, 813, 0, 381, 382, 383, 384, 814,
-	0, 0, 0, 385, 386, 387, 388, 389, 390, 391,
-	392, 0, 0, 394, 395, 396, 393, 397, 398, 0,
-	399, 0, 400, 401, 402, 403, 404, 405, 406, 0,
-	407, 408, 409, 0, 410, 411, 412, 0, 0, 0,
-	0, 0, 0, 0, 413, 414, 415, 416, 417, 0,
-	418, 420, 421, 815, 422, 816, 0, 425, 427, 419,
-	423, 0, 426, 424, 428, 429, 0, 430, 431, 432,
-	433, 0, 0, 434, 435, 436, 0, 437, 438, 440,
-	439, 0, 441, 442, 443, 0, 444, 445, 817, 446,
-	447, 448, 450, 452, 449, 451, 453, 454, 455, 456,
-	457, 818, 819, 458, 459, 0, 0, 0, 0, 0,
-	0, 0, 460, 461, 462, 820, 0, 0, 0, 463,
-	0, 465, 469, 466, 467, 468, 470, 0, 464, 471,
-	472, 0, 0, 473, 474, 475, 821, 822, 476, 477,
-	478, 479, 480, 481, 482, 483, 484, 0, 485, 486,
-	823, 0, 824, 487, 0, 488, 489, 490, 491, 492,
-	493, 494, 825, 826, 827, 595, 0, 495, 496, 497,
-	0, 498, 499, 500, 501, 502, 503, 504, 0, 0,
-	0, 505, 506, 507, 508, 0, 0, 0, 0, 0,
-	828, 509, 596, 510, 829, 830, 0, 831, 0, 511,
-	512, 515, 0, 832, 0, 514, 516, 517, 0, 518,
-	0, 0, 0, 519, 520, 521, 522, 523, 524, 525,
-	0, 526, 528, 527, 0, 530, 833, 529, 0, 531,
-	532, 0, 0, 533, 534, 535, 536, 537, 538, 541,
-	0, 0, 539, 540, 542, 543, 0, 544, 545, 547,
-	550, 546, 548, 549, 551, 552, 565, 566, 553, 554,
-	555, 556, 557, 558, 559, 560, 561, 562, 563, 564,
-	568, 0, 567, 0, 569, 570, 571, 572, 573, 581,
-	583, 584, 579, 580, 582, 585, 586, 588, 589, 576,
-	577, 578, 0, 587, 574, 0, 575, 0, 0, 590,
-	591, 592, 593, 0, 834, 594, 835, 597, 598, 0,
-	0, 599, 0, 600, 0, 0, 602, 603, 604, 0,
-	0, 605, 606, 836, 0, 607, 0, 837, 608, 609,
-	601, 610, 611, 612, 613, 614, 615, 616, 617, 618,
-	619, 0, 620, 621, 838, 622, 623, 624, 839, 625,
-	626, 627, 840, 628, 841, 629, 630, 0, 631, 632,
-	633, 0, 634, 635, 636, 637, 638, 639, 640, 641,
-	642, 643, 842, 644, 645, 647, 646, 648, 649, 0,
-	650, 0, 651, 652, 653, 0, 0, 0, 0, 0,
-	654, 655, 657, 0, 658, 659, 660, 661, 662, 656,
-	663, 664, 665, 666, 667, 668, 669, 0, 671, 672,
-	670, 673, 674, 0, 675, 676, 677, 678, 679, 843,
-	680, 0, 681, 682, 690, 691, 692, 683, 684, 686,
-	693, 685, 694, 695, 696, 697, 699, 698, 0, 701,
-	702, 700, 703, 704, 705, 706, 0, 707, 844, 708,
-	687, 688, 709, 710, 711, 0, 712, 713, 714, 715,
-	716, 717, 718, 719, 720, 845, 0, 721, 0, 722,
-	723, 724, 725, 726, 727, 729, 689, 730, 731, 732,
-	737, 738, 846, 733, 734, 735, 736, 847, 740, 741,
-	742, 743, 0, 744, 745, 0, 739, 728, 0, 746,
-	747, 748, 749, 750, 751, 752, 753, 754, 755, 0,
-	756, 848, 849, 850, 851, 0, 768, 0, 757, 759,
-	760, 761, 762, 852, 763, 853, 0, 764, 765, 766,
-	767, 758, 769, 770, 0, 0, 771, 772, 773, 774,
-	776, 778, 779, 780, 775, 777, 781, 0, 782, 0,
-	0, 783, 784, 785, 854, 855, 856, 0, 787, 788,
-	786, 789, 790, 793, 791, 792, 857, 796, 513, 797,
-	798, 799, 794, 795, 2134, 0, 337, 0, 800, 801,
-	858, 802, 803, 804, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 345, 346, 348, 347, 349, 350, 351,
-	352, 0, 353, 354, 0, 0, 0, 0, 0, 805,
-	0, 0, 0, 356, 0, 355, 0, 357, 358, 359,
-	0, 360, 361, 362, 363, 364, 365, 366, 367, 806,
-	807, 0, 368, 808, 369, 809, 0, 810, 370, 371,
-	372, 373, 374, 375, 376, 377, 378, 379, 0, 0,
-	0, 380, 811, 812, 813, 0, 381, 382, 383, 384,
-	814, 0, 0, 0, 385, 386, 387, 388, 389, 390,
-	391, 392, 0, 0, 394, 395, 396, 393, 397, 398,
-	0, 399, 0, 400, 401, 402, 403, 404, 405, 406,
-	0, 407, 408, 409, 0, 410, 411, 412, 0, 0,
-	0, 0, 0, 0, 0, 413, 414, 415, 416, 417,
-	0, 418, 420, 421, 815, 422, 816, 0, 425, 427,
-	419, 423, 0, 426, 424, 428, 429, 0, 430, 431,
-	432, 433, 0, 0, 434, 435, 436, 0, 437, 438,
-	440, 439, 0, 441, 442, 443, 0, 444, 445, 817,
-	446, 447, 448, 450, 452, 449, 451, 453, 454, 455,
-	456, 457, 818, 819, 458, 459, 0, 0, 0, 0,
-	0, 0, 0, 460, 461, 462, 820, 0, 0, 0,
-	463, 0, 465, 469, 466, 467, 468, 470, 0, 464,
-	471, 472, 0, 0, 473, 474, 475, 821, 822, 476,
-	477, 478, 479, 480, 481, 482, 483, 484, 0, 485,
-	486, 823, 0, 824, 487, 0, 488, 489, 490, 491,
-	492, 493, 494, 825, 826, 827, 595, 0, 495, 496,
-	497, 0, 498, 499, 500, 501, 502, 503, 504, 0,
-	0, 0, 505, 506, 507, 508, 0, 0, 0, 0,
-	0, 828, 509, 596, 510, 829, 830, 0, 831, 0,
-	511, 512, 515, 0, 832, 0, 514, 516, 517, 0,
-	518, 0, 0, 0, 519, 520, 521, 522, 523, 524,
-	525, 0, 526, 528, 527, 0, 530, 833, 529, 0,
-	531, 532, 0, 0, 533, 534, 535, 536, 537, 538,
-	541, 0, 0, 539, 540, 542, 543, 0, 544, 545,
-	547, 550, 546, 548, 549, 551, 552, 565, 566, 553,
-	554, 555, 556, 557, 558, 559, 560, 561, 562, 563,
-	564, 568, 0, 567, 0, 569, 570, 571, 572, 573,
-	581, 583, 584, 579, 580, 582, 585, 586, 588, 589,
-	576, 577, 578, 0, 587, 574, 0, 575, 0, 0,
-	590, 591, 592, 593, 0, 834, 594, 835, 597, 598,
-	0, 0, 599, 0, 600, 0, 0, 602, 603, 604,
-	0, 0, 605, 606, 836, 0, 607, 0, 837, 608,
-	609, 601, 610, 611, 612, 613, 614, 615, 616, 617,
-	618, 619, 0, 620, 621, 838, 622, 623, 624, 839,
-	625, 626, 627, 840, 628, 841, 629, 630, 0, 631,
-	632, 633, 0, 634, 635, 636, 637, 638, 639, 640,
-	641, 642, 643, 842, 644, 645, 647, 646, 648, 649,
-	0, 650, 0, 651, 652, 653, 0, 0, 0, 0,
-	0, 654, 655, 657, 0, 658, 659, 660, 661, 662,
-	656, 663, 664, 665, 666, 667, 668, 669, 0, 671,
-	672, 670, 673, 674, 0, 675, 676, 677, 678, 679,
-	843, 680, 0, 681, 682, 690, 691, 692, 683, 684,
-	686, 693, 685, 694, 695, 696, 697, 699, 698, 0,
-	701, 702, 700, 703, 704, 705, 706, 0, 707, 844,
-	708, 687, 688, 709, 710, 711, 0, 712, 713, 714,
-	715, 716, 717, 718, 719, 720, 845, 0, 721, 0,
-	722, 723, 724, 725, 726, 727, 729, 689, 730, 731,
-	732, 737, 738, 846, 733, 734, 735, 736, 847, 740,
-	741, 742, 743, 0, 744, 745, 0, 739, 728, 0,
-	746, 747, 748, 749, 750, 751, 752, 753, 754, 755,
-	0, 756, 848, 849, 850, 851, 0, 768, 0, 757,
-	759, 760, 761, 762, 852, 763, 853, 0, 764, 765,
-	766, 767, 758, 769, 770, 0, 0, 771, 772, 773,
-	774, 776, 778, 779, 780, 775, 777, 781, 0, 782,
-	0, 0, 783, 784, 785, 854, 855, 856, 0, 787,
-	788, 786, 789, 790, 793, 791, 792, 857, 796, 513,
-	797, 798, 799, 794, 795, 980, 0, 337, 0, 800,
-	801, 858, 802, 803, 804, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 345, 346, 348, 347, 349, 350,
-	351, 352, 0, 353, 354, 0, 0, 0, 0, 0,
-	805, 0, 0, 0, 356, 0, 355, 0, 357, 358,
-	359, 0, 360, 361, 362, 363, 364, 365, 366, 367,
-	806, 807, 0, 368, 808, 369, 809, 0, 810, 370,
-	371, 372, 373, 374, 375, 376, 377, 378, 379, 0,
-	0, 0, 380, 811, 812, 813, 0, 381, 382, 976,
-	384, 814, 0, 0, 0, 385, 386, 387, 388, 389,
-	390, 391, 392, 0, 0, 394, 395, 396, 393, 397,
-	398, 0, 399, 0, 400, 401, 402, 403, 404, 405,
-	406, 0, 407, 408, 409, 0, 410, 411, 412, 0,
-	0, 0, 0, 0, 0, 0, 413, 414, 415, 416,
-	417, 0, 418, 420, 421, 815, 422, 816, 0, 425,
-	427, 419, 423, 0, 426, 424, 428, 429, 0, 430,
-	431, 432, 433, 0, 0, 434, 435, 436, 0, 437,
-	438, 440, 439, 0, 441, 442, 443, 0, 444, 445,
-	817, 446, 447, 448, 450, 452, 449, 451, 453, 454,
-	455, 456, 457, 818, 819, 458, 459, 0, 0, 0,
-	0, 0, 0, 0, 460, 461, 462, 820, 0, 0,
-	0, 463, 0, 465, 469, 466, 467, 468, 470, 0,
-	464, 471, 472, 0, 0, 473, 474, 475, 821, 822,
-	476, 477, 478, 479, 480, 481, 482, 483, 484, 0,
-	485, 486, 823, 0, 824, 487, 0, 488, 489, 490,
-	491, 492, 493, 494, 825, 826, 827, 595, 0, 495,
-	496, 497, 0, 498, 499, 500, 501, 502, 503, 504,
-	0, 0, 0, 505, 506, 507, 508, 0, 0, 0,
-	0, 0, 828, 509, 596, 510, 829, 830, 0, 831,
-	0, 511, 512, 515, 0, 832, 0, 514, 516, 517,
-	0, 518, 0, 0, 0, 519, 520, 521, 522, 523,
-	524, 525, 0, 526, 528, 527, 0, 530, 833, 529,
-	0, 531, 532, 0, 0, 533, 534, 535, 536, 537,
-	981, 541, 0, 0, 539, 540, 542, 543, 0, 544,
-	545, 547, 550, 546, 548, 549, 551, 552, 565, 566,
-	553, 554, 555, 556, 557, 558, 559, 560, 561, 562,
-	563, 564, 568, 0, 990, 0, 569, 570, 571, 572,
-	573, 581, 583, 584, 579, 580, 582, 585, 586, 588,
-	589, 576, 577, 578, 0, 587, 574, 0, 575, 0,
-	0, 590, 591, 592, 593, 0, 834, 594, 835, 597,
-	598, 0, 0, 599, 0, 600, 0, 0, 602, 603,
-	604, 0, 0, 605, 606, 836, 0, 607, 0, 837,
-	608, 609, 601, 610, 611, 612, 613, 614, 615, 616,
-	617, 618, 619, 0, 620, 621, 838, 622, 623, 624,
-	839, 625, 626, 627, 840, 628, 841, 629, 630, 0,
-	631, 632, 633, 0, 634, 635, 636, 637, 638, 639,
-	640, 641, 642, 643, 842, 644, 645, 647, 646, 648,
-	649, 0, 650, 0, 651, 652, 653, 0, 0, 0,
-	0, 0, 654, 655, 657, 0, 658, 659, 660, 661,
-	662, 656, 663, 664, 665, 666, 667, 668, 669, 0,
-	671, 672, 670, 673, 674, 0, 989, 676, 677, 678,
-	679, 843, 680, 0, 681, 682, 690, 691, 692, 683,
-	684, 686, 988, 685, 694, 695, 696, 697, 699, 698,
-	0, 701, 702, 700, 703, 704, 2119, 706, 0, 707,
-	844, 708, 687, 688, 709, 710, 711, 0, 712, 713,
-	714, 715, 716, 717, 718, 719, 720, 845, 0, 721,
-	0, 722, 723, 724, 725, 726, 727, 729, 689, 730,
-	731, 732, 737, 738, 846, 733, 734, 735, 736, 847,
-	740, 741, 742, 743, 0, 744, 745, 0, 739, 728,
-	0, 746, 747, 748, 749, 750, 751, 752, 753, 754,
-	755, 0, 756, 986, 849, 850, 851, 0, 768, 0,
-	757, 759, 760, 761, 762, 852, 763, 853, 0, 764,
-	765, 766, 767, 758, 769, 770, 0, 0, 771, 772,
-	773, 774, 776, 778, 779, 780, 775, 777, 781, 0,
-	782, 0, 0, 783, 784, 785, 854, 855, 856, 0,
-	787, 788, 786, 789, 790, 793, 791, 792, 857, 796,
-	513, 797, 798, 799, 794, 795, 2091, 0, 337, 0,
-	800, 801, 858, 802, 803, 804, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 345, 346, 348, 347, 349,
-	350, 351, 352, 0, 353, 354, 0, 0, 0, 0,
-	0, 805, 0, 0, 0, 356, 0, 355, 0, 357,
-	358, 359, 0, 360, 361, 362, 363, 364, 365, 366,
-	367, 806, 807, 0, 368, 808, 369, 809, 0, 810,
-	370, 371, 372, 373, 374, 375, 376, 377, 378, 379,
-	0, 0, 0, 380, 811, 812, 813, 0, 381, 382,
-	383, 384, 814, 0, 0, 0, 385, 386, 387, 388,
-	389, 390, 391, 392, 0, 0, 394, 395, 396, 393,
-	397, 398, 0, 399, 0, 400, 401, 402, 403, 404,
-	405, 406, 0, 407, 408, 409, 0, 410, 411, 412,
-	0, 0, 0, 0, 0, 0, 0, 413, 414, 415,
-	416, 417, 0, 418, 420, 421, 815, 422, 816, 0,
-	425, 427, 419, 423, 0, 426, 424, 428, 429, 0,
-	430, 431, 432, 433, 0, 0, 434, 435, 436, 0,
-	437, 438, 440, 439, 0, 441, 442, 443, 0, 444,
-	445, 817, 446, 447, 448, 450, 452, 449, 451, 453,
-	454, 455, 456, 457, 818, 819, 458, 459, 0, 0,
-	0, 0, 0, 0, 0, 460, 461, 462, 820, 0,
-	0, 0, 463, 0, 465, 469, 466, 467, 468, 470,
-	0, 464, 471, 472, 0, 0, 473, 474, 475, 821,
-	822, 476, 477, 478, 479, 480, 481, 482, 483, 484,
-	0, 485, 486, 823, 0, 824, 487, 0, 488, 489,
-	490, 491, 492, 493, 494, 2090, 826, 827, 595, 0,
-	495, 496, 497, 0, 498, 499, 500, 501, 502, 503,
-	504, 0, 0, 0, 505, 506, 507, 508, 0, 0,
-	0, 0, 0, 828, 509, 596, 510, 829, 830, 0,
-	831, 0, 511, 512, 515, 0, 832, 0, 514, 516,
-	517, 0, 518, 0, 0, 0, 519, 520, 521, 522,
-	523, 524, 525, 0, 526, 528, 527, 0, 530, 833,
-	529, 0, 531, 532, 0, 0, 533, 534, 535, 536,
-	537, 538, 541, 0, 0, 539, 540, 542, 543, 0,
-	544, 545, 547, 550, 546, 548, 549, 551, 552, 565,
-	566, 553, 554, 555, 556, 557, 558, 559, 560, 561,
-	562, 563, 564, 568, 0, 567, 0, 569, 570, 571,
-	572, 573, 581, 583, 584, 579, 580, 582, 585, 586,
-	588, 589, 576, 577, 578, 0, 587, 574, 0, 575,
-	0, 0, 590, 591, 592, 593, 0, 834, 594, 835,
-	597, 598, 0, 0, 599, 0, 600, 0, 0, 602,
-	603, 604, 0, 0, 605, 606, 836, 0, 607, 0,
-	837, 608, 609, 601, 610, 611, 612, 613, 614, 615,
-	616, 617, 618, 619, 0, 620, 621, 838, 622, 623,
-	624, 839, 625, 626, 627, 840, 628, 841, 629, 630,
-	0, 631, 632, 633, 0, 634, 635, 636, 637, 638,
-	639, 640, 641, 642, 643, 842, 644, 645, 647, 646,
-	648, 649, 0, 650, 0, 651, 652, 653, 0, 0,
-	0, 0, 0, 654, 655, 657, 0, 658, 659, 660,
-	661, 662, 656, 663, 664, 665, 666, 667, 668, 669,
-	0, 671, 672, 670, 673, 674, 0, 675, 676, 677,
-	678, 679, 843, 680, 0, 681, 682, 690, 691, 692,
-	683, 684, 686, 693, 685, 694, 695, 696, 697, 699,
-	698, 0, 701, 702, 700, 703, 704, 705, 706, 0,
-	707, 844, 708, 687, 688, 709, 710, 711, 0, 712,
-	713, 714, 715, 716, 717, 718, 719, 720, 845, 0,
-	721, 0, 722, 723, 724, 725, 726, 727, 729, 689,
-	730, 731, 732, 737, 738, 846, 733, 734, 735, 736,
-	847, 740, 741, 742, 743, 0, 744, 745, 0, 739,
-	728, 0, 746, 747, 748, 749, 750, 751, 752, 753,
-	754, 755, 0, 756, 848, 849, 850, 851, 0, 768,
-	0, 757, 759, 760, 761, 762, 852, 763, 853, 0,
-	764, 765, 766, 767, 758, 769, 770, 0, 0, 771,
-	772, 773, 774, 776, 778, 779, 780, 775, 777, 781,
-	0, 782, 0, 0, 783, 784, 785, 854, 855, 856,
-	0, 787, 788, 786, 789, 790, 793, 791, 792, 857,
-	796, 513, 797, 798, 799, 794, 795, 2074, 0, 337,
-	0, 800, 801, 858, 802, 803, 804, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 345, 346, 348, 347,
-	349, 350, 351, 352, 0, 353, 354, 0, 0, 0,
-	0, 0, 805, 0, 0, 0, 356, 0, 355, 0,
-	357, 358, 359, 0, 360, 361, 362, 363, 364, 365,
-	366, 367, 806, 807, 0, 368, 808, 369, 809, 0,
-	810, 370, 371, 372, 373, 374, 375, 376, 377, 378,
-	379, 0, 0, 0, 380, 811, 812, 813, 0, 381,
-	382, 383, 384, 814, 0, 0, 0, 385, 386, 387,
-	388, 389, 390, 391, 392, 0, 0, 394, 395, 396,
-	393, 397, 398, 0, 399, 0, 400, 401, 402, 403,
-	404, 405, 406, 0, 407, 408, 409, 0, 410, 411,
-	412, 0, 0, 0, 0, 0, 0, 0, 413, 414,
-	415, 416, 417, 0, 418, 420, 421, 815, 422, 816,
-	0, 425, 427, 419, 423, 0, 426, 424, 428, 429,
-	0, 430, 431, 432, 433, 0, 0, 434, 435, 436,
-	0, 437, 438, 440, 439, 0, 441, 442, 443, 0,
-	444, 445, 817, 446, 447, 448, 450, 452, 449, 451,
-	453, 454, 455, 456, 457, 818, 819, 458, 459, 0,
-	0, 0, 0, 0, 0, 0, 460, 461, 462, 820,
-	0, 0, 0, 463, 0, 465, 469, 466, 467, 468,
-	470, 0, 464, 471, 472, 0, 0, 473, 474, 475,
-	821, 822, 476, 477, 478, 479, 480, 481, 482, 483,
-	484, 0, 485, 486, 823, 0, 824, 487, 0, 488,
-	489, 490, 491, 492, 493, 494, 2072, 826, 827, 595,
-	0, 495, 496, 497, 0, 498, 499, 500, 501, 502,
-	503, 504, 0, 0, 0, 505, 506, 507, 508, 0,
-	0, 0, 0, 0, 828, 509, 596, 510, 829, 830,
-	0, 831, 0, 511, 512, 515, 0, 832, 0, 514,
-	516, 517, 0, 518, 0, 0, 0, 519, 520, 521,
-	522, 523, 524, 525, 0, 526, 528, 527, 0, 530,
-	833, 529, 0, 531, 532, 0, 0, 533, 534, 535,
-	536, 537, 538, 541, 0, 0, 539, 540, 542, 543,
-	0, 544, 545, 547, 550, 546, 548, 549, 551, 552,
-	565, 566, 553, 554, 555, 556, 557, 558, 559, 560,
-	561, 562, 563, 564, 568, 0, 567, 0, 569, 570,
-	571, 572, 573, 581, 583, 584, 579, 580, 582, 585,
-	586, 588, 589, 576, 577, 578, 0, 587, 574, 0,
-	575, 0, 0, 590, 591, 592, 593, 0, 834, 594,
-	835, 597, 598, 0, 0, 599, 0, 600, 0, 0,
-	602, 603, 604, 0, 0, 605, 606, 836, 0, 607,
-	0, 837, 608, 609, 601, 610, 611, 612, 613, 614,
-	615, 616, 617, 618, 619, 0, 620, 621, 838, 622,
-	623, 624, 839, 625, 626, 627, 840, 628, 841, 629,
-	630, 0, 631, 632, 633, 0, 634, 635, 636, 637,
-	638, 639, 640, 641, 642, 643, 842, 644, 645, 647,
-	646, 648, 649, 0, 650, 0, 651, 652, 653, 0,
-	0, 0, 0, 0, 654, 655, 657, 0, 658, 659,
-	660, 661, 662, 656, 663, 664, 665, 666, 667, 668,
-	669, 0, 671, 672, 670, 673, 674, 0, 675, 676,
-	677, 678, 679, 843, 680, 0, 681, 682, 690, 691,
-	692, 683, 684, 686, 693, 685, 694, 695, 696, 697,
-	699, 698, 0, 701, 702, 700, 703, 704, 705, 706,
-	0, 707, 844, 708, 687, 688, 709, 710, 711, 0,
-	712, 713, 714, 715, 716, 717, 718, 719, 720, 845,
-	0, 721, 0, 722, 723, 724, 725, 726, 727, 729,
-	689, 730, 731, 732, 737, 738, 846, 733, 734, 735,
-	736, 847, 740, 741, 742, 743, 0, 744, 745, 0,
-	739, 728, 0, 746, 747, 748, 749, 750, 751, 752,
-	753, 754, 755, 0, 756, 848, 849, 850, 851, 0,
-	768, 0, 757, 759, 760, 761, 762, 852, 763, 853,
-	0, 764, 765, 766, 767, 758, 769, 770, 0, 0,
-	771, 772, 773, 774, 776, 778, 779, 780, 775, 777,
-	781, 0, 782, 0, 0, 783, 784, 785, 854, 855,
-	856, 0, 787, 788, 786, 789, 790, 793, 791, 792,
-	857, 796, 513, 797, 798, 799, 794, 795, 2066, 0,
-	337, 0, 800, 801, 858, 802, 803, 804, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 345, 346, 348,
-	347, 349, 350, 351, 352, 0, 353, 354, 0, 0,
-	0, 0, 0, 805, 0, 0, 0, 356, 0, 355,
-	0, 357, 358, 359, 0, 360, 361, 362, 363, 364,
-	365, 366, 367, 806, 807, 0, 368, 808, 369, 809,
-	0, 810, 370, 371, 372, 373, 374, 375, 376, 377,
-	378, 379, 0, 0, 0, 380, 811, 812, 813, 0,
-	381, 382, 383, 384, 814, 0, 0, 0, 385, 386,
-	387, 388, 389, 390, 391, 392, 0, 0, 394, 395,
-	396, 393, 397, 398, 0, 399, 0, 400, 401, 402,
-	403, 404, 405, 406, 0, 407, 408, 409, 0, 410,
-	411, 412, 0, 0, 0, 0, 0, 0, 0, 413,
-	414, 415, 416, 417, 0, 418, 420, 421, 815, 422,
-	816, 0, 425, 427, 419, 423, 0, 426, 424, 428,
-	429, 0, 430, 431, 432, 433, 0, 0, 434, 435,
-	436, 0, 437, 438, 440, 439, 0, 441, 442, 443,
-	0, 444, 445, 817, 446, 447, 448, 450, 452, 449,
-	451, 453, 454, 455, 456, 457, 818, 819, 458, 459,
-	0, 0, 0, 0, 0, 0, 0, 460, 461, 462,
-	820, 0, 0, 0, 463, 0, 465, 469, 466, 467,
-	468, 470, 0, 464, 471, 472, 0, 0, 473, 474,
-	475, 821, 822, 476, 477, 478, 479, 480, 481, 482,
-	483, 484, 0, 485, 486, 823, 0, 824, 487, 0,
-	488, 489, 490, 491, 492, 493, 494, 825, 826, 827,
-	595, 0, 495, 496, 497, 0, 498, 499, 500, 501,
-	502, 503, 504, 0, 0, 0, 505, 506, 507, 508,
-	0, 0, 0, 0, 0, 828, 509, 596, 510, 829,
-	830, 0, 831, 0, 511, 512, 515, 0, 832, 0,
-	514, 516, 517, 0, 518, 0, 0, 0, 519, 520,
-	521, 522, 523, 524, 525, 0, 526, 528, 527, 0,
-	530, 833, 529, 0, 531, 532, 0, 0, 533, 534,
-	535, 536, 537, 538, 541, 0, 0, 539, 540, 542,
-	543, 0, 544, 545, 547, 550, 546, 548, 549, 551,
-	552, 565, 566, 553, 554, 555, 556, 557, 558, 559,
-	560, 561, 562, 563, 564, 568, 0, 567, 0, 569,
-	570, 571, 572, 573, 581, 583, 584, 579, 580, 582,
-	585, 586, 588, 589, 576, 577, 578, 0, 587, 574,
-	0, 575, 0, 0, 590, 591, 592, 593, 0, 834,
-	594, 835, 597, 598, 0, 0, 599, 0, 600, 0,
-	0, 602, 603, 604, 0, 0, 605, 606, 836, 0,
-	607, 0, 837, 608, 609, 601, 610, 611, 612, 613,
-	614, 615, 616, 617, 618, 619, 0, 620, 621, 838,
-	622, 623, 624, 839, 625, 626, 627, 840, 628, 841,
-	629, 630, 0, 631, 632, 633, 0, 634, 635, 636,
-	637, 638, 639, 640, 641, 642, 643, 842, 644, 645,
-	647, 646, 648, 649, 0, 650, 0, 651, 652, 653,
-	0, 0, 0, 0, 0, 654, 655, 657, 0, 658,
-	659, 660, 661, 662, 656, 663, 664, 665, 666, 667,
-	668, 669, 0, 671, 672, 670, 673, 674, 0, 675,
-	676, 677, 678, 679, 843, 680, 0, 681, 682, 690,
-	691, 692, 683, 684, 686, 693, 685, 694, 695, 696,
-	697, 699, 698, 0, 701, 702, 700, 703, 704, 705,
-	706, 0, 707, 844, 708, 687, 688, 709, 710, 711,
-	0, 712, 713, 714, 715, 716, 717, 718, 719, 720,
-	845, 0, 721, 0, 722, 723, 724, 725, 726, 727,
-	729, 689, 730, 731, 732, 737, 738, 846, 733, 734,
-	735, 736, 847, 740, 741, 742, 743, 0, 744, 745,
-	0, 739, 728, 0, 746, 747, 748, 749, 750, 751,
-	752, 753, 754, 755, 0, 756, 848, 849, 850, 851,
-	0, 768, 0, 757, 759, 760, 761, 762, 852, 763,
-	853, 0, 764, 765, 766, 767, 758, 769, 770, 0,
-	0, 771, 772, 773, 774, 776, 778, 779, 780, 775,
-	777, 781, 0, 782, 0, 0, 783, 784, 785, 854,
-	855, 856, 0, 787, 788, 786, 789, 790, 793, 791,
-	792, 857, 796, 513, 797, 798, 799, 794, 795, 2043,
-	0, 337, 0, 800, 801, 858, 802, 803, 804, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 345, 346,
-	348, 347, 349, 350, 351, 352, 0, 353, 354, 0,
-	0, 0, 0, 0, 805, 0, 0, 0, 356, 0,
-	355, 0, 357, 358, 359, 0, 360, 361, 362, 363,
-	364, 365, 366, 367, 806, 807, 0, 368, 808, 369,
-	809, 0, 810, 370, 371, 372, 373, 374, 375, 376,
-	377, 378, 379, 0, 0, 0, 380, 811, 812, 813,
-	0, 381, 382, 383, 384, 814, 0, 0, 0, 385,
-	386, 387, 388, 389, 390, 391, 392, 0, 0, 394,
-	395, 396, 393, 397, 398, 0, 399, 0, 400, 401,
-	402, 403, 404, 405, 406, 0, 407, 408, 409, 0,
-	410, 411, 412, 0, 0, 0, 0, 0, 0, 0,
-	413, 414, 415, 416, 417, 0, 418, 420, 421, 815,
-	422, 816, 0, 425, 427, 419, 423, 0, 426, 424,
-	428, 429, 0, 430, 431, 432, 433, 0, 0, 434,
-	435, 436, 0, 437, 438, 440, 439, 0, 441, 442,
-	443, 0, 444, 445, 817, 446, 447, 448, 450, 452,
-	449, 451, 453, 454, 455, 456, 457, 818, 819, 458,
-	459, 0, 0, 0, 0, 0, 0, 0, 460, 461,
-	462, 820, 0, 0, 0, 463, 0, 465, 469, 466,
-	467, 468, 470, 0, 464, 471, 472, 0, 0, 473,
-	474, 475, 821, 822, 476, 477, 478, 479, 480, 481,
-	482, 483, 484, 0, 485, 486, 823, 0, 824, 487,
-	0, 488, 489, 490, 491, 492, 493, 494, 2041, 826,
-	827, 595, 0, 495, 496, 497, 0, 498, 499, 500,
-	501, 502, 503, 504, 0, 0, 0, 505, 506, 507,
-	508, 0, 0, 0, 0, 0, 828, 509, 596, 510,
-	829, 830, 0, 831, 0, 511, 512, 515, 0, 832,
-	0, 514, 516, 517, 0, 518, 0, 0, 0, 519,
-	520, 521, 522, 523, 524, 525, 0, 526, 528, 527,
-	0, 530, 833, 529, 0, 531, 532, 0, 0, 533,
-	534, 535, 536, 537, 538, 541, 0, 0, 539, 540,
-	542, 543, 0, 544, 545, 547, 550, 546, 548, 549,
-	551, 552, 565, 566, 553, 554, 555, 556, 557, 558,
-	559, 560, 561, 562, 563, 564, 568, 0, 567, 0,
-	569, 570, 571, 572, 573, 581, 583, 584, 579, 580,
-	582, 585, 586, 588, 589, 576, 577, 578, 0, 587,
-	574, 0, 575, 0, 0, 590, 591, 592, 593, 0,
-	834, 594, 835, 597, 598, 0, 0, 599, 0, 600,
-	0, 0, 602, 603, 604, 0, 0, 605, 606, 836,
-	0, 607, 0, 837, 608, 609, 601, 610, 611, 612,
-	613, 614, 615, 616, 617, 618, 619, 0, 620, 621,
-	838, 622, 623, 624, 839, 625, 626, 627, 840, 628,
-	841, 629, 630, 0, 631, 632, 633, 0, 634, 635,
-	636, 637, 638, 639, 640, 641, 642, 643, 842, 644,
-	645, 647, 646, 648, 649, 0, 650, 0, 651, 652,
-	653, 0, 0, 0, 0, 0, 654, 655, 657, 0,
-	658, 659, 660, 661, 662, 656, 663, 664, 665, 666,
-	667, 668, 669, 0, 671, 672, 670, 673, 674, 0,
-	675, 676, 677, 678, 679, 843, 680, 0, 681, 682,
-	690, 691, 692, 683, 684, 686, 693, 685, 694, 695,
-	696, 697, 699, 698, 0, 701, 702, 700, 703, 704,
-	705, 706, 0, 707, 844, 708, 687, 688, 709, 710,
-	711, 0, 712, 713, 714, 715, 716, 717, 718, 719,
-	720, 845, 0, 721, 0, 722, 723, 724, 725, 726,
-	727, 729, 689, 730, 731, 732, 737, 738, 846, 733,
-	734, 735, 736, 847, 740, 741, 742, 743, 0, 744,
-	745, 0, 739, 728, 0, 746, 747, 748, 749, 750,
-	751, 752, 753, 754, 755, 0, 756, 848, 849, 850,
-	851, 0, 768, 0, 757, 759, 760, 761, 762, 852,
-	763, 853, 0, 764, 765, 766, 767, 758, 769, 770,
-	0, 0, 771, 772, 773, 774, 776, 778, 779, 780,
-	775, 777, 781, 0, 782, 0, 0, 783, 784, 785,
-	854, 855, 856, 0, 787, 788, 786, 789, 790, 793,
-	791, 792, 857, 796, 513, 797, 798, 799, 794, 795,
-	2031, 0, 337, 0, 800, 801, 858, 802, 803, 804,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 345,
-	346, 348, 347, 349, 350, 351, 352, 0, 353, 354,
-	0, 0, 0, 0, 0, 805, 0, 0, 0, 356,
-	0, 355, 0, 357, 358, 359, 0, 360, 361, 362,
-	363, 364, 365, 366, 367, 806, 807, 0, 368, 808,
-	369, 809, 0, 810, 370, 371, 372, 373, 374, 375,
-	376, 377, 378, 379, 0, 0, 0, 380, 811, 812,
-	813, 0, 381, 382, 383, 384, 814, 0, 0, 0,
-	385, 386, 387, 388, 389, 390, 391, 392, 0, 0,
-	394, 395, 396, 393, 397, 398, 0, 399, 0, 400,
-	401, 402, 403, 404, 405, 406, 0, 407, 408, 409,
-	0, 410, 411, 412, 0, 0, 0, 0, 0, 0,
-	0, 413, 414, 415, 416, 417, 0, 418, 420, 421,
-	815, 422, 816, 0, 425, 427, 419, 423, 0, 426,
-	424, 428, 429, 0, 430, 431, 432, 433, 0, 0,
-	434, 435, 436, 0, 437, 438, 440, 439, 0, 441,
-	442, 443, 0, 444, 445, 817, 446, 447, 448, 450,
-	452, 449, 451, 453, 454, 455, 456, 457, 818, 819,
-	458, 459, 0, 0, 0, 0, 0, 0, 0, 460,
-	461, 462, 820, 0, 0, 0, 463, 0, 465, 469,
-	466, 467, 468, 470, 0, 464, 471, 472, 0, 0,
-	473, 474, 475, 821, 822, 476, 477, 478, 479, 480,
-	481, 482, 483, 484, 0, 485, 486, 823, 0, 824,
-	487, 0, 488, 489, 490, 491, 492, 493, 494, 825,
-	826, 827, 595, 0, 495, 496, 497, 0, 498, 499,
-	500, 501, 502, 503, 504, 0, 0, 0, 505, 506,
-	507, 508, 0, 0, 0, 0, 0, 828, 509, 596,
-	510, 829, 830, 0, 831, 0, 511, 512, 515, 0,
-	832, 0, 514, 516, 517, 0, 518, 0, 0, 0,
-	519, 520, 521, 522, 523, 524, 525, 0, 526, 528,
-	527, 0, 530, 833, 529, 0, 531, 532, 0, 0,
-	533, 534, 535, 536, 537, 538, 541, 0, 0, 539,
-	540, 542, 543, 0, 544, 545, 547, 550, 546, 548,
-	549, 551, 552, 565, 566, 553, 554, 555, 556, 557,
-	558, 559, 560, 561, 562, 563, 564, 568, 0, 567,
-	0, 569, 570, 571, 572, 573, 581, 583, 584, 579,
-	580, 582, 585, 586, 588, 589, 576, 577, 578, 0,
-	587, 574, 0, 575, 0, 0, 590, 591, 592, 593,
-	0, 834, 594, 835, 597, 598, 0, 0, 599, 0,
-	600, 0, 0, 602, 603, 604, 0, 0, 605, 606,
-	836, 0, 607, 0, 837, 608, 609, 601, 610, 611,
-	612, 613, 614, 615, 616, 617, 618, 619, 0, 620,
-	621, 838, 622, 623, 624, 839, 625, 626, 627, 840,
-	628, 841, 629, 630, 0, 631, 632, 633, 0, 634,
-	635, 636, 637, 638, 639, 640, 641, 642, 643, 842,
-	644, 645, 647, 646, 648, 649, 0, 650, 0, 651,
-	652, 653, 0, 0, 0, 0, 0, 654, 655, 657,
-	0, 658, 659, 660, 661, 662, 656, 663, 664, 665,
-	666, 667, 668, 669, 0, 671, 672, 670, 673, 674,
-	0, 675, 676, 677, 678, 679, 843, 680, 0, 681,
-	682, 690, 691, 692, 683, 684, 686, 693, 685, 694,
-	695, 696, 697, 699, 698, 0, 701, 702, 700, 703,
-	704, 705, 706, 0, 707, 844, 708, 687, 688, 709,
-	710, 711, 0, 712, 713, 714, 715, 716, 717, 718,
-	719, 720, 845, 0, 721, 0, 722, 723, 724, 725,
-	726, 727, 729, 689, 730, 731, 732, 737, 738, 846,
-	733, 734, 735, 736, 847, 740, 741, 742, 743, 0,
-	744, 745, 0, 739, 728, 0, 746, 747, 748, 749,
-	750, 751, 752, 753, 754, 755, 0, 756, 848, 849,
-	850, 851, 0, 768, 0, 757, 759, 760, 761, 762,
-	852, 763, 853, 0, 764, 765, 766, 767, 758, 769,
-	770, 0, 0, 771, 772, 773, 774, 776, 778, 779,
-	780, 775, 777, 781, 0, 782, 0, 0, 783, 784,
-	785, 854, 855, 856, 0, 787, 788, 786, 789, 790,
-	793, 791, 792, 857, 796, 513, 797, 798, 799, 794,
-	795, 1993, 0, 337, 0, 800, 801, 858, 802, 803,
-	804, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	345, 346, 348, 347, 349, 350, 351, 352, 0, 353,
-	354, 0, 0, 0, 0, 0, 805, 0, 0, 0,
-	356, 0, 355, 0, 357, 358, 359, 0, 360, 361,
-	362, 363, 364, 365, 366, 367, 806, 807, 0, 368,
-	808, 369, 809, 0, 810, 370, 371, 372, 373, 374,
-	375, 376, 377, 378, 379, 0, 0, 0, 380, 811,
-	812, 813, 0, 381, 382, 383, 384, 814, 0, 0,
-	0, 385, 386, 387, 388, 389, 390, 391, 392, 0,
-	0, 394, 395, 396, 393, 397, 398, 0, 399, 0,
-	400, 401, 402, 403, 404, 405, 406, 0, 407, 408,
-	409, 0, 410, 411, 412, 0, 0, 0, 0, 0,
-	0, 0, 413, 414, 415, 416, 417, 0, 418, 420,
-	421, 815, 422, 816, 0, 425, 427, 419, 423, 0,
-	426, 424, 428, 429, 0, 430, 431, 432, 433, 0,
-	0, 434, 435, 436, 0, 437, 438, 440, 439, 0,
-	441, 442, 443, 0, 444, 445, 817, 446, 447, 448,
-	450, 452, 449, 451, 453, 454, 455, 456, 457, 818,
-	819, 458, 459, 0, 0, 0, 0, 0, 0, 0,
-	460, 461, 462, 820, 0, 0, 0, 463, 0, 465,
-	469, 466, 467, 468, 470, 0, 464, 471, 472, 0,
-	0, 473, 474, 475, 821, 822, 476, 477, 478, 479,
-	480, 481, 482, 483, 484, 0, 485, 486, 823, 0,
-	824, 487, 0, 488, 489, 490, 491, 492, 493, 494,
-	825, 826, 827, 595, 0, 495, 496, 497, 0, 498,
-	499, 500, 501, 502, 503, 504, 0, 0, 0, 505,
-	506, 507, 508, 0, 0, 0, 0, 0, 828, 509,
-	596, 510, 829, 830, 0, 831, 0, 511, 512, 515,
-	0, 832, 0, 514, 516, 517, 0, 518, 0, 0,
-	0, 519, 520, 521, 522, 523, 524, 525, 0, 526,
-	528, 527, 0, 530, 833, 529, 0, 531, 532, 0,
-	0, 533, 534, 535, 536, 537, 538, 541, 0, 0,
-	539, 540, 542, 543, 0, 544, 545, 547, 550, 546,
-	548, 549, 551, 552, 565, 566, 553, 554, 555, 556,
-	557, 558, 559, 560, 561, 562, 563, 564, 568, 0,
-	567, 0, 569, 570, 571, 572, 573, 581, 583, 584,
-	579, 580, 582, 585, 586, 588, 589, 576, 577, 578,
-	0, 587, 574, 0, 575, 0, 0, 590, 591, 592,
-	593, 0, 834, 594, 835, 597, 598, 0, 0, 599,
-	0, 600, 0, 0, 602, 603, 604, 0, 0, 605,
-	606, 836, 0, 607, 0, 837, 608, 609, 601, 610,
-	611, 612, 613, 614, 615, 616, 617, 618, 619, 0,
-	620, 621, 838, 622, 623, 624, 839, 625, 626, 627,
-	840, 628, 841, 629, 630, 0, 631, 632, 633, 0,
-	634, 635, 636, 637, 638, 639, 640, 641, 642, 643,
-	842, 644, 645, 647, 646, 648, 649, 0, 650, 0,
-	651, 652, 653, 0, 0, 0, 0, 0, 654, 655,
-	657, 0, 658, 659, 660, 661, 662, 656, 663, 664,
-	665, 666, 667, 668, 669, 0, 671, 672, 670, 673,
-	674, 0, 675, 676, 677, 678, 679, 843, 680, 0,
-	681, 682, 690, 691, 692, 683, 684, 686, 693, 685,
-	694, 695, 696, 697, 699, 698, 0, 701, 702, 700,
-	703, 704, 705, 706, 0, 707, 844, 708, 687, 688,
-	709, 710, 711, 0, 712, 713, 714, 715, 716, 717,
-	718, 719, 720, 845, 0, 721, 0, 722, 723, 724,
-	725, 726, 727, 729, 689, 730, 731, 732, 737, 738,
-	846, 733, 734, 735, 736, 847, 740, 741, 742, 743,
-	0, 744, 745, 0, 739, 728, 0, 746, 747, 748,
-	749, 750, 751, 752, 753, 754, 755, 0, 756, 848,
-	849, 850, 851, 0, 768, 0, 757, 759, 760, 761,
-	762, 852, 763, 853, 0, 764, 765, 766, 767, 758,
-	769, 770, 0, 0, 771, 772, 773, 774, 776, 778,
-	779, 780, 775, 777, 781, 0, 782, 0, 0, 783,
-	784, 785, 854, 855, 856, 0, 787, 788, 786, 789,
-	790, 793, 791, 792, 857, 796, 513, 797, 798, 799,
-	794, 795, 1965, 0, 337, 0, 800, 801, 858, 802,
-	803, 804, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 345, 346, 348, 347, 349, 350, 351, 352, 0,
-	353, 354, 0, 0, 0, 0, 0, 805, 0, 0,
-	0, 356, 0, 355, 0, 357, 358, 359, 0, 360,
-	361, 362, 363, 364, 365, 366, 367, 806, 807, 0,
-	368, 808, 369, 809, 0, 810, 370, 371, 372, 373,
-	374, 375, 376, 377, 378, 379, 0, 0, 0, 380,
-	811, 812, 813, 0, 381, 382, 383, 384, 814, 0,
-	0, 0, 385, 386, 387, 388, 389, 390, 391, 392,
-	0, 0, 394, 395, 396, 393, 397, 398, 0, 399,
-	0, 400, 401, 402, 403, 404, 405, 406, 0, 407,
-	408, 409, 0, 410, 411, 412, 0, 0, 0, 0,
-	0, 0, 0, 413, 414, 415, 416, 417, 0, 418,
-	420, 421, 815, 422, 816, 0, 425, 427, 419, 423,
-	0, 426, 424, 428, 429, 0, 430, 431, 432, 433,
-	0, 0, 434, 435, 436, 0, 437, 438, 440, 439,
-	0, 441, 442, 443, 0, 444, 445, 817, 446, 447,
-	448, 450, 452, 449, 451, 453, 454, 455, 456, 457,
-	818, 819, 458, 459, 0, 0, 0, 0, 0, 0,
-	0, 460, 461, 462, 820, 0, 0, 0, 463, 0,
-	465, 469, 466, 467, 468, 470, 0, 464, 471, 472,
-	0, 0, 473, 474, 475, 821, 822, 476, 477, 478,
-	479, 480, 481, 482, 483, 484, 0, 485, 486, 823,
-	0, 824, 487, 0, 488, 489, 490, 491, 492, 493,
-	494, 825, 826, 827, 595, 0, 495, 496, 497, 0,
-	498, 499, 500, 501, 502, 503, 504, 0, 0, 0,
-	505, 506, 507, 508, 0, 0, 0, 0, 0, 828,
-	509, 596, 510, 829, 830, 0, 831, 0, 511, 512,
-	515, 0, 832, 0, 514, 516, 517, 0, 518, 0,
-	0, 0, 519, 520, 521, 522, 523, 524, 525, 0,
-	526, 528, 527, 0, 530, 833, 529, 0, 531, 532,
-	0, 0, 533, 534, 535, 536, 537, 538, 541, 0,
-	0, 539, 540, 542, 543, 0, 544, 545, 547, 550,
-	546, 548, 549, 551, 552, 565, 566, 553, 554, 555,
-	556, 557, 558, 559, 560, 561, 562, 563, 564, 568,
-	0, 567, 0, 569, 570, 571, 572, 573, 581, 583,
-	584, 579, 580, 582, 585, 586, 588, 589, 576, 577,
-	578, 0, 587, 574, 0, 575, 0, 0, 590, 591,
-	592, 593, 0, 834, 594, 835, 597, 598, 0, 0,
-	599, 0, 600, 0, 0, 602, 603, 604, 0, 0,
-	605, 606, 836, 0, 607, 0, 837, 608, 609, 601,
-	610, 611, 612, 613, 614, 615, 616, 617, 618, 619,
-	0, 620, 621, 838, 622, 623, 624, 839, 625, 626,
-	627, 840, 628, 841, 629, 630, 0, 631, 632, 633,
-	0, 634, 635, 636, 637, 638, 639, 640, 641, 642,
-	643, 842, 644, 645, 647, 646, 648, 649, 0, 650,
-	0, 651, 652, 653, 0, 0, 0, 0, 0, 654,
-	655, 657, 0, 658, 659, 660, 661, 662, 656, 663,
-	664, 665, 666, 667, 668, 669, 0, 671, 672, 670,
-	673, 674, 0, 675, 676, 677, 678, 679, 843, 680,
-	0, 681, 682, 690, 691, 692, 683, 684, 686, 693,
-	685, 694, 695, 696, 697, 699, 698, 0, 701, 702,
-	700, 703, 704, 705, 706, 0, 707, 844, 708, 687,
-	688, 709, 710, 711, 0, 712, 713, 714, 715, 716,
-	717, 718, 719, 720, 845, 0, 721, 0, 722, 723,
-	724, 725, 726, 727, 729, 689, 730, 731, 732, 737,
-	738, 846, 733, 734, 735, 736, 847, 740, 741, 742,
-	743, 0, 744, 745, 0, 739, 728, 0, 746, 747,
-	748, 749, 750, 751, 752, 753, 754, 755, 0, 756,
-	848, 849, 850, 851, 0, 768, 0, 757, 759, 760,
-	761, 762, 852, 763, 853, 0, 764, 765, 766, 767,
-	758, 769, 770, 0, 0, 771, 772, 773, 774, 776,
-	778, 779, 780, 775, 777, 781, 0, 782, 0, 0,
-	783, 784, 785, 854, 855, 856, 0, 787, 788, 786,
-	789, 790, 793, 791, 792, 857, 796, 513, 797, 798,
-	799, 794, 795, 1663, 0, 337, 0, 800, 801, 858,
-	802, 803, 804, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 345, 346, 348, 347, 349, 350, 351, 352,
-	0, 353, 354, 0, 0, 0, 0, 0, 805, 0,
-	0, 0, 356, 0, 355, 0, 357, 358, 359, 0,
-	360, 361, 362, 363, 364, 365, 366, 367, 806, 807,
-	0, 368, 808, 369, 809, 0, 810, 370, 371, 372,
-	373, 374, 375, 376, 377, 378, 379, 0, 0, 0,
-	380, 811, 812, 813, 0, 381, 382, 383, 384, 814,
-	0, 0, 0, 385, 386, 387, 388, 389, 390, 391,
-	392, 0, 0, 394, 395, 396, 393, 397, 398, 0,
-	399, 0, 400, 401, 402, 403, 404, 405, 406, 0,
-	407, 408, 409, 0, 410, 411, 412, 0, 0, 0,
-	0, 0, 0, 0, 413, 414, 415, 416, 417, 0,
-	418, 420, 421, 815, 422, 816, 0, 425, 427, 419,
-	423, 0, 426, 424, 428, 429, 0, 430, 431, 432,
-	433, 0, 0, 434, 435, 436, 0, 437, 438, 440,
-	439, 0, 441, 442, 443, 0, 444, 445, 817, 446,
-	447, 448, 450, 452, 449, 451, 453, 454, 455, 456,
-	457, 818, 819, 458, 459, 0, 0, 0, 0, 0,
-	0, 0, 460, 461, 462, 820, 0, 0, 0, 463,
-	0, 465, 469, 466, 467, 468, 470, 0, 464, 471,
-	472, 0, 0, 473, 474, 475, 821, 822, 476, 477,
-	478, 479, 480, 481, 482, 483, 484, 0, 485, 486,
-	823, 0, 824, 487, 0, 488, 489, 490, 491, 492,
-	493, 494, 825, 826, 827, 595, 0, 495, 496, 497,
-	0, 498, 499, 500, 501, 502, 503, 504, 0, 0,
-	0, 505, 506, 507, 508, 0, 0, 0, 0, 0,
-	828, 509, 596, 510, 829, 830, 0, 831, 0, 511,
-	512, 515, 0, 832, 0, 514, 516, 517, 0, 518,
-	0, 0, 0, 519, 520, 521, 522, 523, 524, 525,
-	0, 526, 528, 527, 0, 530, 833, 529, 0, 531,
-	532, 0, 0, 533, 534, 535, 536, 537, 538, 541,
-	0, 0, 539, 540, 542, 543, 0, 544, 545, 547,
-	550, 546, 548, 549, 551, 552, 565, 566, 553, 554,
-	555, 556, 557, 558, 559, 560, 561, 562, 563, 564,
-	568, 0, 567, 0, 569, 570, 571, 572, 573, 581,
-	583, 584, 579, 580, 582, 585, 586, 588, 589, 576,
-	577, 578, 0, 587, 574, 0, 575, 0, 0, 590,
-	591, 592, 593, 0, 834, 594, 835, 597, 598, 0,
-	0, 599, 0, 600, 0, 0, 602, 603, 604, 0,
-	0, 605, 606, 836, 0, 607, 0, 837, 608, 609,
-	601, 610, 611, 612, 613, 614, 615, 616, 617, 618,
-	619, 0, 620, 621, 838, 622, 623, 624, 839, 625,
-	626, 627, 840, 628, 841, 629, 630, 0, 631, 632,
-	633, 0, 634, 635, 636, 637, 638, 639, 640, 641,
-	642, 643, 842, 644, 645, 647, 646, 648, 649, 0,
-	650, 0, 651, 652, 653, 0, 0, 0, 0, 0,
-	654, 655, 657, 0, 658, 659, 660, 661, 662, 656,
-	663, 664, 665, 666, 667, 668, 669, 0, 671, 672,
-	670, 673, 674, 0, 989, 676, 677, 678, 679, 843,
-	680, 0, 681, 682, 690, 691, 692, 683, 684, 686,
-	988, 685, 694, 695, 696, 697, 699, 698, 0, 701,
-	702, 700, 703, 704, 705, 706, 0, 707, 844, 708,
-	687, 688, 709, 710, 711, 0, 712, 713, 714, 715,
-	716, 717, 718, 719, 720, 845, 0, 721, 0, 722,
-	723, 724, 725, 726, 727, 729, 689, 730, 731, 732,
-	737, 738, 846, 733, 734, 735, 736, 847, 740, 741,
-	742, 743, 0, 744, 745, 0, 739, 728, 0, 746,
-	747, 748, 749, 750, 751, 752, 753, 754, 755, 0,
-	756, 986, 849, 850, 851, 0, 768, 0, 757, 759,
-	760, 761, 762, 852, 763, 853, 0, 764, 765, 766,
-	767, 758, 769, 770, 0, 0, 771, 772, 773, 774,
-	776, 778, 779, 780, 775, 777, 781, 0, 782, 0,
-	0, 783, 784, 785, 854, 855, 856, 0, 787, 788,
-	786, 789, 790, 793, 791, 792, 857, 796, 513, 797,
-	798, 799, 794, 795, 1633, 0, 337, 0, 800, 801,
-	858, 802, 803, 804, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 345, 346, 348, 347, 349, 350, 351,
-	352, 0, 353, 354, 0, 0, 0, 0, 0, 805,
-	0, 0, 0, 356, 0, 355, 0, 357, 358, 359,
-	0, 360, 361, 362, 363, 364, 365, 366, 367, 806,
-	807, 0, 368, 808, 369, 809, 0, 810, 370, 371,
-	372, 373, 374, 375, 376, 377, 378, 379, 0, 0,
-	0, 380, 811, 812, 813, 0, 381, 382, 383, 384,
-	814, 0, 0, 0, 385, 386, 387, 388, 389, 390,
-	391, 392, 0, 0, 394, 395, 396, 393, 397, 398,
-	0, 399, 0, 400, 401, 402, 403, 404, 405, 406,
-	0, 407, 408, 409, 0, 410, 411, 412, 0, 0,
-	0, 0, 0, 0, 0, 413, 414, 415, 416, 417,
-	0, 418, 420, 421, 815, 422, 816, 0, 425, 427,
-	419, 423, 0, 426, 424, 428, 429, 0, 430, 431,
-	432, 433, 0, 0, 434, 435, 436, 0, 437, 438,
-	440, 439, 0, 441, 442, 443, 0, 444, 445, 817,
-	446, 447, 448, 450, 452, 449, 451, 453, 454, 455,
-	456, 457, 818, 819, 458, 459, 0, 0, 0, 0,
-	0, 0, 0, 460, 461, 462, 820, 0, 0, 0,
-	463, 0, 465, 469, 466, 467, 468, 470, 0, 464,
-	471, 472, 0, 0, 473, 474, 475, 821, 822, 476,
-	477, 478, 479, 480, 481, 482, 483, 484, 0, 485,
-	486, 823, 0, 824, 487, 0, 488, 489, 490, 491,
-	492, 493, 494, 1632, 826, 827, 595, 0, 495, 496,
-	497, 0, 498, 499, 500, 501, 502, 503, 504, 0,
-	0, 0, 505, 506, 507, 508, 0, 0, 0, 0,
-	0, 828, 509, 596, 510, 829, 830, 0, 831, 0,
-	511, 512, 515, 0, 832, 0, 514, 516, 517, 0,
-	518, 0, 0, 0, 519, 520, 521, 522, 523, 524,
-	525, 0, 526, 528, 527, 0, 530, 833, 529, 0,
-	531, 532, 0, 0, 533, 534, 535, 536, 537, 538,
-	541, 0, 0, 539, 540, 542, 543, 0, 544, 545,
-	547, 550, 546, 548, 549, 551, 552, 565, 566, 553,
-	554, 555, 556, 557, 558, 559, 560, 561, 562, 563,
-	564, 568, 0, 567, 0, 569, 570, 571, 572, 573,
-	581, 583, 584, 579, 580, 582, 585, 586, 588, 589,
-	576, 577, 578, 0, 587, 574, 0, 575, 0, 0,
-	590, 591, 592, 593, 0, 834, 594, 835, 597, 598,
-	0, 0, 599, 0, 600, 0, 0, 602, 603, 604,
-	0, 0, 605, 606, 836, 0, 607, 0, 837, 608,
-	609, 601, 610, 611, 612, 613, 614, 615, 616, 617,
-	618, 619, 0, 620, 621, 838, 622, 623, 624, 839,
-	625, 626, 627, 840, 628, 841, 629, 630, 0, 631,
-	632, 633, 0, 634, 635, 636, 637, 638, 639, 640,
-	641, 642, 643, 842, 644, 645, 647, 646, 648, 649,
-	0, 650, 0, 651, 652, 653, 0, 0, 0, 0,
-	0, 654, 655, 657, 0, 658, 659, 660, 661, 662,
-	656, 663, 664, 665, 666, 667, 668, 669, 0, 671,
-	672, 670, 673, 674, 0, 675, 676, 677, 678, 679,
-	843, 680, 0, 681, 682, 690, 691, 692, 683, 684,
-	686, 693, 685, 694, 695, 696, 697, 699, 698, 0,
-	701, 702, 700, 703, 704, 705, 706, 0, 707, 844,
-	708, 687, 688, 709, 710, 711, 0, 712, 713, 714,
-	715, 716, 717, 718, 719, 720, 845, 0, 721, 0,
-	722, 723, 724, 725, 726, 727, 729, 689, 730, 731,
-	732, 737, 738, 846, 733, 734, 735, 736, 847, 740,
-	741, 742, 743, 0, 744, 745, 0, 739, 728, 0,
-	746, 747, 748, 749, 750, 751, 752, 753, 754, 755,
-	0, 756, 848, 849, 850, 851, 0, 768, 0, 757,
-	759, 760, 761, 762, 852, 763, 853, 0, 764, 765,
-	766, 767, 758, 769, 770, 0, 0, 771, 772, 773,
-	774, 776, 778, 779, 780, 775, 777, 781, 0, 782,
-	0, 0, 783, 784, 785, 854, 855, 856, 0, 787,
-	788, 786, 789, 790, 793, 791, 792, 857, 796, 513,
-	797, 798, 799, 794, 795, 1619, 0, 337, 0, 800,
-	801, 858, 802, 803, 804, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 345, 346, 348, 347, 349, 350,
-	351, 352, 0, 353, 354, 0, 0, 0, 0, 0,
-	805, 0, 0, 0, 356, 0, 355, 0, 357, 358,
-	359, 0, 360, 361, 362, 363, 364, 365, 366, 367,
-	806, 807, 0, 368, 808, 369, 809, 0, 810, 370,
-	371, 372, 373, 374, 375, 376, 377, 378, 379, 0,
-	0, 0, 380, 811, 812, 813, 0, 381, 382, 383,
-	384, 814, 0, 0, 0, 385, 386, 387, 388, 389,
-	390, 391, 392, 0, 0, 394, 395, 396, 393, 397,
-	398, 0, 399, 0, 400, 401, 402, 403, 404, 405,
-	406, 0, 407, 408, 409, 0, 410, 411, 412, 0,
-	0, 0, 0, 0, 0, 0, 413, 414, 415, 416,
-	417, 0, 418, 420, 421, 815, 422, 816, 0, 425,
-	427, 419, 423, 0, 426, 424, 428, 429, 0, 430,
-	431, 432, 433, 0, 0, 434, 435, 436, 0, 437,
-	438, 440, 439, 0, 441, 442, 443, 0, 444, 445,
-	817, 446, 447, 448, 450, 452, 449, 451, 453, 454,
-	455, 456, 457, 818, 819, 458, 459, 0, 0, 0,
-	0, 0, 0, 0, 460, 461, 462, 820, 0, 0,
-	0, 463, 0, 465, 469, 466, 467, 468, 470, 0,
-	464, 471, 472, 0, 0, 473, 474, 475, 821, 822,
-	476, 477, 478, 479, 480, 481, 482, 483, 484, 0,
-	485, 486, 823, 0, 824, 487, 0, 488, 489, 490,
-	491, 492, 493, 494, 1618, 826, 827, 595, 0, 495,
-	496, 497, 0, 498, 499, 500, 501, 502, 503, 504,
-	0, 0, 0, 505, 506, 507, 508, 0, 0, 0,
-	0, 0, 828, 509, 596, 510, 829, 830, 0, 831,
-	0, 511, 512, 515, 0, 832, 0, 514, 516, 517,
-	0, 518, 0, 0, 0, 519, 520, 521, 522, 523,
-	524, 525, 0, 526, 528, 527, 0, 530, 833, 529,
-	0, 531, 532, 0, 0, 533, 534, 535, 536, 537,
-	538, 541, 0, 0, 539, 540, 542, 543, 0, 544,
-	545, 547, 550, 546, 548, 549, 551, 552, 565, 566,
-	553, 554, 555, 556, 557, 558, 559, 560, 561, 562,
-	563, 564, 568, 0, 567, 0, 569, 570, 571, 572,
-	573, 581, 583, 584, 579, 580, 582, 585, 586, 588,
-	589, 576, 577, 578, 0, 587, 574, 0, 575, 0,
-	0, 590, 591, 592, 593, 0, 834, 594, 835, 597,
-	598, 0, 0, 599, 0, 600, 0, 0, 602, 603,
-	604, 0, 0, 605, 606, 836, 0, 607, 0, 837,
-	608, 609, 601, 610, 611, 612, 613, 614, 615, 616,
-	617, 618, 619, 0, 620, 621, 838, 622, 623, 624,
-	839, 625, 626, 627, 840, 628, 841, 629, 630, 0,
-	631, 632, 633, 0, 634, 635, 636, 637, 638, 639,
-	640, 641, 642, 643, 842, 644, 645, 647, 646, 648,
-	649, 0, 650, 0, 651, 652, 653, 0, 0, 0,
-	0, 0, 654, 655, 657, 0, 658, 659, 660, 661,
-	662, 656, 663, 664, 665, 666, 667, 668, 669, 0,
-	671, 672, 670, 673, 674, 0, 675, 676, 677, 678,
-	679, 843, 680, 0, 681, 682, 690, 691, 692, 683,
-	684, 686, 693, 685, 694, 695, 696, 697, 699, 698,
-	0, 701, 702, 700, 703, 704, 705, 706, 0, 707,
-	844, 708, 687, 688, 709, 710, 711, 0, 712, 713,
-	714, 715, 716, 717, 718, 719, 720, 845, 0, 721,
-	0, 722, 723, 724, 725, 726, 727, 729, 689, 730,
-	731, 732, 737, 738, 846, 733, 734, 735, 736, 847,
-	740, 741, 742, 743, 0, 744, 745, 0, 739, 728,
-	0, 746, 747, 748, 749, 750, 751, 752, 753, 754,
-	755, 0, 756, 848, 849, 850, 851, 0, 768, 0,
-	757, 759, 760, 761, 762, 852, 763, 853, 0, 764,
-	765, 766, 767, 758, 769, 770, 0, 0, 771, 772,
-	773, 774, 776, 778, 779, 780, 775, 777, 781, 0,
-	782, 0, 0, 783, 784, 785, 854, 855, 856, 0,
-	787, 788, 786, 789, 790, 793, 791, 792, 857, 796,
-	513, 797, 798, 799, 794, 795, 337, 0, 0, 0,
-	800, 801, 858, 802, 803, 804, 0, 0, 0, 0,
-	0, 0, 0, 345, 346, 348, 347, 349, 350, 351,
-	352, 1557, 353, 354, 0, 0, 0, 0, 0, 805,
-	0, 0, 0, 356, 0, 355, 0, 357, 358, 359,
-	0, 360, 361, 362, 363, 364, 365, 366, 367, 806,
-	807, 0, 368, 808, 369, 809, 0, 810, 370, 371,
-	372, 373, 374, 375, 376, 377, 378, 379, 0, 0,
-	0, 380, 811, 812, 813, 0, 381, 382, 383, 384,
-	814, 0, 0, 0, 385, 386, 387, 388, 389, 390,
-	391, 392, 0, 0, 394, 395, 396, 393, 397, 398,
-	0, 399, 0, 400, 401, 402, 403, 404, 405, 406,
-	0, 407, 408, 409, 0, 410, 411, 412, 0, 0,
-	0, 0, 0, 0, 0, 413, 414, 415, 416, 417,
-	0, 418, 420, 421, 815, 422, 816, 0, 425, 427,
-	419, 423, 0, 426, 424, 428, 429, 0, 430, 431,
-	432, 433, 0, 0, 434, 435, 436, 0, 437, 438,
-	440, 439, 0, 441, 442, 443, 0, 444, 445, 817,
-	446, 447, 448, 450, 452, 449, 451, 453, 454, 455,
-	456, 457, 818, 819, 458, 459, 0, 0, 0, 0,
-	0, 0, 0, 460, 461, 462, 820, 0, 0, 0,
-	463, 0, 465, 469, 466, 467, 468, 470, 0, 464,
-	471, 472, 0, 0, 473, 474, 475, 821, 822, 476,
-	477, 478, 479, 480, 481, 482, 483, 484, 0, 485,
-	486, 823, 0, 824, 487, 0, 488, 489, 490, 491,
-	492, 493, 494, 825, 826, 827, 595, 0, 495, 496,
-	497, 0, 498, 499, 500, 501, 502, 503, 504, 0,
-	0, 0, 505, 506, 507, 508, 0, 0, 0, 0,
-	0, 828, 509, 596, 510, 829, 830, 0, 831, 0,
-	511, 512, 515, 0, 832, 0, 514, 516, 517, 0,
-	518, 0, 0, 0, 519, 520, 521, 522, 523, 524,
-	525, 0, 526, 528, 527, 0, 530, 833, 529, 0,
-	531, 532, 0, 0, 533, 534, 535, 536, 537, 538,
-	541, 0, 0, 539, 540, 542, 543, 0, 544, 545,
-	547, 550, 546, 548, 549, 551, 552, 565, 566, 553,
-	554, 555, 556, 557, 558, 559, 560, 561, 562, 563,
-	564, 568, 0, 567, 0, 569, 570, 571, 572, 573,
-	581, 583, 584, 579, 580, 582, 585, 586, 588, 589,
-	576, 577, 578, 0, 587, 574, 0, 575, 0, 0,
-	590, 591, 592, 593, 0, 834, 594, 835, 597, 598,
-	0, 0, 599, 0, 600, 0, 0, 602, 603, 604,
-	0, 0, 605, 606, 836, 0, 607, 0, 837, 608,
-	609, 601, 610, 611, 612, 613, 614, 615, 616, 617,
-	618, 619, 0, 620, 621, 838, 622, 623, 624, 839,
-	625, 626, 627, 840, 628, 841, 629, 630, 0, 631,
-	632, 633, 0, 634, 635, 636, 637, 638, 639, 640,
-	641, 642, 643, 842, 644, 645, 647, 646, 648, 649,
-	0, 650, 0, 651, 652, 653, 0, 0, 0, 0,
-	0, 654, 655, 657, 0, 658, 659, 660, 661, 662,
-	656, 663, 664, 665, 666, 667, 668, 669, 0, 671,
-	672, 670, 673, 674, 0, 675, 676, 677, 678, 679,
-	843, 680, 0, 681, 682, 690, 691, 692, 683, 684,
-	686, 693, 685, 694, 695, 696, 697, 699, 698, 0,
-	701, 702, 700, 703, 704, 705, 706, 0, 707, 844,
-	708, 687, 688, 709, 710, 711, 0, 712, 713, 714,
-	715, 716, 717, 718, 719, 720, 845, 0, 721, 0,
-	722, 723, 724, 725, 726, 727, 729, 689, 730, 731,
-	732, 737, 738, 846, 733, 734, 735, 736, 847, 740,
-	741, 742, 743, 0, 744, 745, 0, 739, 728, 0,
-	746, 747, 748, 749, 750, 751, 752, 753, 754, 755,
-	0, 756, 848, 849, 850, 851, 0, 768, 0, 757,
-	759, 760, 761, 762, 852, 763, 853, 0, 764, 765,
-	766, 767, 758, 769, 770, 0, 0, 771, 772, 773,
-	774, 776, 778, 779, 780, 775, 777, 781, 0, 782,
-	0, 0, 783, 784, 785, 854, 855, 856, 0, 787,
-	788, 786, 789, 790, 793, 791, 792, 857, 796, 513,
-	797, 798, 799, 794, 795, 1000, 0, 337, 0, 800,
-	801, 858, 802, 803, 804, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 345, 346, 348, 347, 349, 350,
-	351, 352, 0, 353, 354, 0, 0, 0, 0, 0,
-	805, 0, 0, 0, 356, 0, 355, 0, 357, 358,
-	359, 0, 360, 361, 362, 363, 364, 365, 366, 367,
-	806, 807, 0, 368, 808, 369, 809, 0, 810, 370,
-	371, 372, 373, 374, 375, 376, 377, 378, 379, 0,
-	0, 0, 380, 811, 812, 813, 0, 381, 382, 383,
-	384, 814, 0, 0, 0, 385, 386, 387, 388, 389,
-	390, 391, 392, 0, 0, 394, 395, 396, 393, 397,
-	398, 0, 399, 0, 400, 401, 402, 403, 404, 405,
-	406, 0, 407, 408, 409, 0, 410, 411, 412, 0,
-	0, 0, 0, 0, 0, 0, 413, 414, 415, 416,
-	417, 0, 418, 420, 421, 815, 422, 816, 0, 425,
-	427, 419, 423, 0, 426, 424, 428, 429, 0, 430,
-	431, 432, 433, 0, 0, 434, 435, 436, 0, 437,
-	438, 440, 439, 0, 441, 442, 443, 0, 444, 445,
-	817, 446, 447, 448, 450, 452, 449, 451, 453, 454,
-	455, 456, 457, 818, 819, 458, 459, 0, 0, 0,
-	0, 0, 0, 0, 460, 461, 462, 820, 0, 0,
-	0, 463, 0, 465, 469, 466, 467, 468, 470, 0,
-	464, 471, 472, 0, 0, 473, 474, 475, 821, 822,
-	476, 477, 478, 479, 480, 481, 482, 483, 484, 0,
-	485, 486, 823, 0, 824, 487, 0, 488, 489, 490,
-	491, 492, 493, 494, 825, 826, 827, 595, 0, 495,
-	496, 497, 0, 498, 499, 500, 501, 502, 503, 504,
-	0, 0, 0, 505, 506, 507, 508, 0, 0, 0,
-	0, 0, 828, 509, 596, 510, 829, 830, 0, 831,
-	0, 511, 512, 515, 0, 832, 0, 514, 516, 517,
-	0, 518, 0, 0, 0, 519, 520, 521, 522, 523,
-	524, 525, 0, 526, 528, 527, 0, 530, 833, 529,
-	0, 531, 532, 0, 0, 533, 534, 535, 536, 537,
-	538, 541, 0, 0, 539, 540, 542, 543, 0, 544,
-	545, 547, 550, 546, 548, 549, 551, 552, 565, 566,
-	553, 554, 555, 556, 557, 558, 559, 560, 561, 562,
-	563, 564, 568, 0, 567, 0, 569, 570, 571, 572,
-	573, 581, 583, 584, 579, 580, 582, 585, 586, 588,
-	589, 576, 577, 578, 0, 587, 574, 0, 575, 0,
-	0, 590, 591, 592, 593, 0, 834, 594, 835, 597,
-	598, 0, 0, 599, 0, 600, 0, 0, 602, 603,
-	604, 0, 0, 605, 606, 836, 0, 607, 0, 837,
-	608, 609, 601, 610, 611, 612, 613, 614, 615, 616,
-	617, 618, 619, 0, 620, 621, 838, 622, 623, 624,
-	839, 625, 626, 627, 840, 628, 841, 629, 630, 0,
-	631, 632, 633, 0, 634, 635, 636, 637, 638, 639,
-	640, 641, 642, 643, 842, 644, 645, 647, 646, 648,
-	649, 0, 650, 0, 651, 652, 653, 0, 0, 0,
-	0, 0, 654, 655, 657, 0, 658, 659, 660, 661,
-	662, 656, 663, 664, 665, 666, 667, 668, 669, 0,
-	671, 672, 670, 673, 674, 0, 675, 676, 677, 678,
-	679, 843, 680, 0, 681, 682, 690, 691, 692, 683,
-	684, 686, 693, 685, 694, 695, 696, 697, 699, 698,
-	0, 701, 702, 700, 703, 704, 705, 706, 0, 707,
-	844, 708, 687, 688, 709, 710, 711, 0, 712, 713,
-	714, 715, 716, 717, 718, 719, 720, 845, 0, 721,
-	0, 722, 723, 724, 725, 726, 727, 729, 689, 730,
-	731, 732, 737, 738, 846, 733, 734, 735, 736, 847,
-	740, 741, 742, 743, 0, 744, 745, 0, 739, 728,
-	0, 746, 747, 748, 749, 750, 751, 752, 753, 754,
-	755, 0, 756, 848, 849, 850, 851, 0, 768, 0,
-	757, 759, 760, 761, 762, 852, 763, 853, 0, 764,
-	765, 766, 767, 758, 769, 770, 0, 0, 771, 772,
-	773, 774, 776, 778, 779, 780, 775, 777, 781, 0,
-	782, 0, 0, 783, 784, 785, 854, 855, 856, 0,
-	787, 788, 786, 789, 790, 793, 791, 792, 857, 796,
-	513, 797, 798, 799, 794, 795, 980, 0, 337, 0,
-	800, 801, 858, 802, 803, 804, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 345, 346, 348, 347, 349,
-	350, 351, 352, 0, 353, 354, 0, 0, 0, 0,
-	0, 805, 0, 0, 0, 356, 0, 355, 0, 357,
-	358, 359, 0, 360, 361, 362, 363, 364, 365, 366,
-	367, 806, 807, 0, 368, 808, 369, 809, 0, 810,
-	370, 371, 372, 373, 374, 375, 376, 377, 378, 379,
-	0, 0, 0, 380, 811, 812, 813, 0, 381, 382,
-	976, 384, 814, 0, 0, 0, 385, 386, 387, 388,
-	389, 390, 391, 392, 0, 0, 394, 395, 396, 393,
-	397, 398, 0, 975, 0, 400, 401, 402, 403, 404,
-	405, 406, 0, 407, 408, 409, 0, 410, 411, 412,
-	0, 0, 0, 0, 0, 0, 0, 413, 414, 415,
-	416, 417, 0, 418, 420, 421, 815, 422, 816, 0,
-	425, 427, 419, 423, 0, 426, 424, 428, 429, 0,
-	430, 431, 432, 433, 0, 0, 434, 435, 436, 0,
-	437, 438, 440, 439, 0, 441, 442, 443, 0, 444,
-	445, 817, 446, 447, 448, 450, 452, 449, 451, 453,
-	454, 455, 456, 457, 818, 819, 458, 459, 0, 0,
-	0, 0, 0, 0, 0, 460, 461, 462, 820, 0,
-	0, 0, 463, 0, 465, 469, 466, 467, 468, 470,
-	0, 464, 471, 472, 0, 0, 473, 474, 475, 821,
-	822, 476, 477, 478, 479, 480, 481, 482, 483, 484,
-	0, 485, 486, 823, 0, 824, 487, 0, 488, 489,
-	490, 491, 492, 493, 494, 825, 826, 827, 595, 0,
-	495, 496, 497, 0, 498, 499, 500, 501, 502, 503,
-	504, 0, 0, 0, 505, 506, 507, 508, 0, 0,
-	0, 0, 0, 828, 509, 596, 510, 829, 830, 0,
-	831, 0, 511, 512, 515, 0, 832, 0, 514, 516,
-	517, 0, 518, 0, 0, 0, 519, 520, 521, 522,
-	523, 524, 525, 0, 526, 528, 527, 0, 530, 833,
-	529, 0, 531, 532, 0, 0, 533, 534, 535, 536,
-	537, 981, 541, 0, 0, 539, 540, 542, 543, 0,
-	544, 545, 547, 550, 546, 548, 549, 551, 552, 565,
-	566, 553, 554, 555, 556, 557, 558, 559, 560, 561,
-	562, 563, 564, 568, 0, 990, 0, 569, 570, 571,
-	572, 573, 581, 583, 584, 579, 580, 582, 585, 586,
-	588, 589, 576, 577, 578, 0, 587, 574, 0, 575,
-	0, 0, 590, 591, 592, 593, 0, 834, 594, 835,
-	597, 598, 0, 0, 599, 0, 600, 0, 0, 602,
-	603, 604, 0, 0, 605, 606, 836, 0, 607, 0,
-	837, 608, 609, 601, 610, 611, 612, 613, 614, 615,
-	616, 617, 618, 619, 0, 620, 621, 838, 622, 623,
-	624, 839, 625, 626, 627, 840, 628, 841, 629, 630,
-	0, 631, 632, 633, 0, 634, 635, 636, 637, 638,
-	639, 640, 641, 642, 643, 842, 644, 645, 647, 646,
-	648, 649, 0, 650, 0, 651, 652, 653, 0, 0,
-	0, 0, 0, 654, 655, 657, 0, 658, 659, 660,
-	661, 662, 656, 663, 664, 665, 666, 667, 668, 669,
-	0, 671, 672, 670, 673, 674, 0, 989, 676, 677,
-	678, 679, 977, 680, 0, 681, 682, 690, 691, 692,
-	683, 684, 686, 988, 685, 694, 695, 696, 697, 699,
-	698, 0, 701, 702, 700, 703, 704, 978, 706, 0,
-	707, 844, 708, 687, 688, 709, 710, 711, 0, 712,
-	713, 714, 715, 716, 717, 718, 719, 720, 845, 0,
-	721, 0, 722, 723, 724, 725, 726, 727, 729, 689,
-	730, 731, 732, 737, 738, 846, 733, 734, 735, 736,
-	847, 740, 741, 742, 743, 0, 744, 745, 0, 739,
-	728, 0, 746, 747, 748, 749, 750, 751, 752, 753,
-	754, 755, 0, 756, 986, 849, 850, 851, 0, 768,
-	0, 757, 982, 760, 761, 762, 852, 763, 853, 0,
-	764, 765, 766, 767, 758, 769, 770, 0, 0, 771,
-	772, 773, 774, 776, 778, 779, 780, 775, 777, 781,
-	0, 782, 0, 0, 783, 784, 785, 854, 855, 856,
-	0, 787, 788, 786, 789, 790, 793, 791, 792, 857,
-	796, 513, 797, 798, 799, 794, 795, 969, 0, 337,
-	0, 800, 801, 858, 802, 803, 804, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 345, 346, 348, 347,
-	349, 350, 351, 352, 0, 353, 354, 0, 0, 0,
-	0, 0, 805, 0, 0, 0, 356, 0, 355, 0,
-	357, 358, 359, 0, 360, 361, 362, 363, 364, 365,
-	366, 367, 806, 807, 0, 368, 808, 369, 809, 0,
-	810, 370, 371, 372, 373, 374, 375, 376, 377, 378,
-	379, 0, 0, 0, 380, 811, 812, 813, 0, 381,
-	382, 383, 384, 814, 0, 0, 0, 385, 386, 387,
-	388, 389, 390, 391, 392, 0, 0, 394, 395, 396,
-	393, 397, 398, 0, 399, 0, 400, 401, 402, 403,
-	404, 405, 406, 0, 407, 408, 409, 0, 410, 411,
-	412, 0, 0, 0, 0, 0, 0, 0, 413, 414,
-	415, 416, 417, 0, 418, 420, 421, 815, 422, 816,
-	0, 425, 427, 419, 423, 0, 426, 424, 428, 429,
-	0, 430, 431, 432, 433, 0, 0, 434, 435, 436,
-	0, 437, 438, 440, 439, 0, 441, 442, 443, 0,
-	444, 445, 817, 446, 447, 448, 450, 452, 449, 451,
-	453, 454, 455, 456, 457, 818, 819, 458, 459, 0,
-	0, 0, 0, 0, 0, 0, 460, 461, 462, 820,
-	0, 0, 0, 463, 0, 465, 469, 466, 467, 468,
-	470, 0, 464, 471, 472, 0, 0, 473, 474, 475,
-	821, 822, 476, 477, 478, 479, 480, 481, 482, 483,
-	484, 0, 485, 486, 823, 0, 824, 487, 0, 488,
-	489, 490, 491, 492, 493, 494, 825, 826, 827, 595,
-	0, 495, 496, 497, 0, 498, 499, 500, 501, 502,
-	503, 504, 0, 0, 0, 505, 506, 507, 508, 0,
-	0, 0, 0, 0, 828, 509, 596, 510, 829, 830,
-	0, 831, 0, 511, 512, 515, 0, 832, 0, 514,
-	516, 517, 0, 518, 0, 0, 0, 519, 520, 521,
-	522, 523, 524, 525, 0, 526, 528, 527, 0, 530,
-	833, 529, 0, 531, 532, 0, 0, 533, 534, 535,
-	536, 537, 538, 541, 0, 0, 539, 540, 542, 543,
-	0, 544, 545, 547, 550, 546, 548, 549, 551, 552,
-	565, 566, 553, 554, 555, 556, 557, 558, 559, 560,
-	561, 562, 563, 564, 568, 0, 567, 0, 569, 570,
-	571, 572, 573, 581, 583, 584, 579, 580, 582, 585,
-	586, 588, 589, 576, 577, 578, 0, 587, 574, 0,
-	575, 0, 0, 590, 591, 592, 593, 0, 834, 594,
-	835, 597, 598, 0, 0, 599, 0, 600, 0, 0,
-	602, 603, 604, 0, 0, 605, 606, 836, 0, 607,
-	0, 837, 608, 609, 601, 610, 611, 612, 613, 614,
-	615, 616, 617, 618, 619, 0, 620, 621, 838, 622,
-	623, 624, 839, 625, 626, 627, 840, 628, 841, 629,
-	630, 0, 631, 632, 633, 0, 634, 635, 636, 637,
-	638, 639, 640, 641, 642, 643, 842, 644, 645, 647,
-	646, 648, 649, 0, 650, 0, 651, 652, 653, 0,
-	0, 0, 0, 0, 654, 655, 657, 0, 658, 659,
-	660, 661, 662, 656, 663, 664, 665, 666, 667, 668,
-	669, 0, 671, 672, 670, 673, 674, 0, 675, 676,
-	677, 678, 679, 843, 680, 0, 681, 682, 970, 691,
-	692, 683, 684, 686, 693, 685, 694, 695, 696, 697,
-	699, 698, 0, 701, 702, 700, 703, 704, 705, 706,
-	0, 707, 844, 708, 687, 688, 709, 710, 711, 0,
-	712, 713, 714, 715, 716, 717, 718, 719, 720, 845,
-	0, 721, 0, 722, 723, 724, 725, 726, 727, 729,
-	689, 730, 731, 732, 737, 738, 846, 733, 734, 735,
-	736, 847, 740, 741, 742, 743, 0, 744, 745, 0,
-	739, 728, 0, 746, 747, 748, 749, 750, 751, 752,
-	753, 754, 755, 0, 756, 848, 849, 850, 851, 0,
-	768, 0, 757, 759, 760, 761, 762, 852, 763, 853,
-	0, 764, 765, 766, 767, 758, 769, 770, 0, 0,
-	771, 772, 773, 774, 776, 778, 779, 780, 775, 777,
-	781, 0, 782, 0, 0, 783, 784, 785, 854, 855,
-	856, 0, 787, 788, 786, 789, 790, 793, 791, 792,
-	857, 796, 513, 797, 798, 799, 794, 795, 927, 0,
-	337, 0, 800, 801, 858, 802, 803, 804, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 345, 346, 348,
-	347, 349, 350, 351, 352, 0, 353, 354, 0, 0,
-	0, 0, 0, 805, 0, 0, 0, 356, 0, 355,
-	0, 357, 358, 359, 0, 360, 361, 362, 363, 364,
-	365, 366, 367, 806, 807, 0, 368, 808, 369, 809,
-	0, 810, 370, 371, 372, 373, 374, 375, 376, 377,
-	378, 379, 0, 0, 0, 380, 811, 812, 813, 0,
-	381, 382, 383, 384, 814, 0, 0, 0, 385, 386,
-	387, 388, 389, 390, 391, 392, 0, 0, 394, 395,
-	396, 393, 397, 398, 0, 399, 0, 400, 401, 402,
-	403, 404, 405, 406, 0, 407, 408, 409, 0, 410,
-	411, 412, 0, 0, 0, 0, 0, 0, 0, 413,
-	414, 415, 416, 417, 0, 418, 420, 421, 815, 422,
-	816, 0, 425, 427, 419, 423, 0, 426, 424, 428,
-	429, 0, 430, 431, 432, 433, 0, 0, 434, 435,
-	436, 0, 437, 438, 440, 439, 0, 441, 442, 443,
-	0, 444, 445, 817, 446, 447, 448, 450, 452, 449,
-	451, 453, 454, 455, 456, 457, 818, 819, 458, 459,
-	0, 0, 0, 0, 0, 0, 0, 460, 461, 462,
-	820, 0, 0, 0, 463, 0, 465, 469, 466, 467,
-	468, 470, 0, 464, 471, 472, 0, 0, 473, 474,
-	475, 821, 822, 476, 477, 478, 479, 480, 481, 482,
-	483, 484, 0, 485, 486, 823, 0, 824, 487, 0,
-	488, 489, 490, 491, 492, 493, 494, 825, 826, 827,
-	595, 0, 495, 496, 497, 0, 498, 499, 500, 501,
-	502, 503, 504, 0, 0, 0, 505, 506, 507, 508,
-	0, 0, 0, 0, 0, 828, 509, 596, 510, 829,
-	830, 0, 831, 0, 511, 512, 515, 0, 832, 0,
-	514, 516, 517, 0, 518, 0, 0, 0, 519, 520,
-	521, 522, 523, 524, 525, 0, 526, 528, 527, 0,
-	530, 833, 529, 0, 531, 532, 0, 0, 533, 534,
-	535, 536, 537, 538, 541, 0, 0, 539, 540, 542,
-	543, 0, 544, 545, 547, 550, 546, 548, 549, 551,
-	552, 565, 566, 553, 554, 555, 556, 557, 558, 559,
-	560, 561, 562, 563, 564, 568, 0, 567, 0, 569,
-	570, 571, 572, 573, 581, 583, 584, 579, 580, 582,
-	585, 586, 588, 589, 576, 577, 578, 0, 587, 574,
-	0, 575, 0, 0, 590, 591, 592, 593, 0, 834,
-	594, 835, 597, 598, 0, 0, 599, 0, 600, 0,
-	0, 602, 603, 604, 0, 0, 605, 606, 836, 0,
-	607, 0, 837, 608, 609, 601, 610, 611, 612, 613,
-	614, 615, 616, 617, 618, 619, 0, 620, 621, 838,
-	622, 623, 624, 839, 625, 626, 627, 840, 628, 841,
-	629, 630, 0, 631, 632, 633, 0, 634, 635, 636,
-	637, 638, 639, 640, 641, 642, 643, 842, 644, 645,
-	647, 646, 648, 649, 0, 650, 0, 651, 652, 653,
-	0, 0, 0, 0, 0, 654, 655, 657, 0, 658,
-	659, 660, 661, 662, 656, 663, 664, 665, 666, 667,
-	668, 669, 0, 671, 672, 670, 673, 674, 0, 675,
-	676, 677, 678, 679, 843, 680, 0, 681, 682, 690,
-	691, 692, 683, 684, 686, 693, 685, 694, 695, 696,
-	697, 699, 698, 0, 701, 702, 700, 703, 704, 705,
-	706, 0, 707, 844, 708, 687, 688, 709, 710, 711,
-	0, 712, 713, 714, 715, 716, 717, 718, 719, 720,
-	845, 0, 721, 0, 722, 723, 724, 725, 726, 727,
-	729, 689, 730, 731, 732, 737, 738, 846, 733, 734,
-	735, 736, 847, 740, 741, 742, 743, 0, 744, 745,
-	0, 739, 728, 0, 746, 747, 748, 749, 750, 751,
-	752, 753, 754, 755, 0, 756, 848, 849, 850, 851,
-	0, 768, 0, 757, 759, 760, 761, 762, 852, 763,
-	853, 0, 764, 765, 766, 767, 758, 769, 770, 0,
-	0, 771, 772, 773, 774, 776, 778, 779, 780, 775,
-	777, 781, 0, 782, 0, 0, 783, 784, 785, 854,
-	855, 856, 0, 787, 788, 786, 789, 790, 793, 791,
-	792, 857, 796, 513, 797, 798, 799, 794, 795, 919,
-	0, 337, 0, 800, 801, 858, 802, 803, 804, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 345, 346,
-	348, 347, 349, 350, 351, 352, 0, 353, 354, 0,
-	0, 0, 0, 0, 805, 0, 0, 0, 356, 0,
-	355, 0, 357, 358, 359, 0, 360, 361, 362, 363,
-	364, 365, 366, 367, 806, 807, 0, 368, 808, 369,
-	809, 0, 810, 370, 371, 372, 373, 374, 375, 376,
-	377, 378, 379, 0, 0, 0, 380, 811, 812, 813,
-	0, 381, 382, 383, 384, 814, 0, 0, 0, 385,
-	386, 387, 388, 389, 390, 391, 392, 0, 0, 394,
-	395, 396, 393, 397, 398, 0, 399, 0, 400, 401,
-	402, 403, 404, 405, 406, 0, 407, 408, 409, 0,
-	410, 411, 412, 0, 0, 0, 0, 0, 0, 0,
-	413, 414, 415, 416, 417, 0, 418, 420, 421, 815,
-	422, 816, 0, 425, 427, 419, 423, 0, 426, 424,
-	428, 429, 0, 430, 431, 432, 433, 0, 0, 434,
-	435, 436, 0, 437, 438, 440, 439, 0, 441, 442,
-	443, 0, 444, 445, 817, 446, 447, 448, 450, 452,
-	449, 451, 453, 454, 455, 456, 457, 818, 819, 458,
-	459, 0, 0, 0, 0, 0, 0, 0, 460, 461,
-	462, 820, 0, 0, 0, 463, 0, 465, 469, 466,
-	467, 468, 470, 0, 464, 471, 472, 0, 0, 473,
-	474, 475, 821, 822, 476, 477, 478, 479, 480, 481,
-	482, 483, 484, 0, 485, 486, 823, 0, 824, 487,
-	0, 488, 489, 490, 491, 492, 493, 494, 825, 826,
-	827, 595, 0, 495, 496, 497, 0, 498, 499, 500,
-	501, 502, 503, 504, 0, 0, 0, 505, 506, 507,
-	508, 0, 0, 0, 0, 0, 828, 509, 596, 510,
-	829, 830, 0, 831, 0, 511, 512, 515, 0, 832,
-	0, 514, 516, 517, 0, 518, 0, 0, 0, 519,
-	520, 521, 522, 523, 524, 525, 0, 526, 528, 527,
-	0, 530, 833, 529, 0, 531, 532, 0, 0, 533,
-	534, 535, 536, 537, 538, 541, 0, 0, 539, 540,
-	542, 543, 0, 544, 545, 547, 550, 546, 548, 549,
-	551, 552, 565, 566, 553, 554, 555, 556, 557, 558,
-	559, 560, 561, 562, 563, 564, 568, 0, 567, 0,
-	569, 570, 571, 572, 573, 581, 583, 584, 579, 580,
-	582, 585, 586, 588, 589, 576, 577, 578, 0, 587,
-	574, 0, 575, 0, 0, 590, 591, 592, 593, 0,
-	834, 594, 835, 597, 598, 0, 0, 599, 0, 600,
-	0, 0, 602, 603, 604, 0, 0, 605, 606, 836,
-	0, 607, 0, 837, 608, 609, 601, 610, 611, 612,
-	613, 614, 615, 616, 617, 618, 619, 0, 620, 621,
-	838, 622, 623, 624, 839, 625, 626, 627, 840, 628,
-	841, 629, 630, 0, 631, 632, 633, 0, 634, 635,
-	636, 637, 638, 639, 640, 641, 642, 643, 842, 644,
-	645, 647, 646, 648, 649, 0, 650, 0, 651, 652,
-	653, 0, 0, 0, 0, 0, 654, 655, 657, 0,
-	658, 659, 660, 661, 662, 656, 663, 664, 665, 666,
-	667, 668, 669, 0, 671, 672, 670, 673, 674, 0,
-	675, 676, 677, 678, 679, 843, 680, 0, 681, 682,
-	690, 691, 692, 683, 684, 686, 693, 685, 694, 695,
-	696, 697, 699, 698, 0, 701, 702, 700, 703, 704,
-	705, 706, 0, 707, 844, 708, 687, 688, 709, 710,
-	711, 0, 712, 713, 714, 715, 716, 717, 718, 719,
-	720, 845, 0, 721, 0, 722, 723, 724, 725, 726,
-	727, 729, 689, 730, 731, 732, 737, 738, 846, 733,
-	734, 735, 736, 847, 740, 741, 742, 743, 0, 744,
-	745, 0, 739, 728, 0, 746, 747, 748, 749, 750,
-	751, 752, 753, 754, 755, 0, 756, 848, 849, 850,
-	851, 0, 768, 0, 757, 759, 760, 761, 762, 852,
-	763, 853, 0, 764, 765, 766, 767, 758, 769, 770,
-	0, 0, 771, 772, 773, 774, 776, 778, 779, 780,
-	775, 777, 781, 0, 782, 0, 0, 783, 784, 785,
-	854, 855, 856, 0, 787, 788, 786, 789, 790, 793,
-	791, 792, 857, 796, 513, 797, 798, 799, 794, 795,
-	896, 0, 337, 0, 800, 801, 858, 802, 803, 804,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 345,
-	346, 348, 347, 349, 350, 351, 352, 0, 353, 354,
-	0, 0, 0, 0, 0, 805, 0, 0, 0, 356,
-	0, 355, 0, 357, 358, 359, 0, 360, 361, 362,
-	363, 364, 365, 366, 367, 806, 807, 0, 368, 808,
-	369, 809, 0, 810, 370, 371, 372, 373, 374, 375,
-	376, 377, 378, 379, 0, 0, 0, 380, 811, 812,
-	813, 0, 381, 382, 383, 384, 814, 0, 0, 0,
-	385, 386, 387, 388, 389, 390, 391, 392, 0, 0,
-	394, 395, 396, 393, 397, 398, 0, 399, 0, 400,
-	401, 402, 403, 404, 405, 406, 0, 407, 408, 409,
-	0, 410, 411, 412, 0, 0, 0, 0, 0, 0,
-	0, 413, 414, 415, 416, 417, 0, 418, 420, 421,
-	815, 422, 816, 0, 425, 427, 419, 423, 0, 426,
-	424, 428, 429, 0, 430, 431, 432, 433, 0, 0,
-	434, 435, 436, 0, 437, 438, 440, 439, 0, 441,
-	442, 443, 0, 444, 445, 817, 446, 447, 448, 450,
-	452, 449, 451, 453, 454, 455, 456, 457, 818, 819,
-	458, 459, 0, 0, 0, 0, 0, 0, 0, 460,
-	461, 462, 820, 0, 0, 0, 463, 0, 465, 469,
-	466, 467, 468, 470, 0, 464, 471, 472, 0, 0,
-	473, 474, 475, 821, 822, 476, 477, 478, 479, 480,
-	481, 482, 483, 484, 0, 485, 486, 823, 0, 824,
-	487, 0, 488, 489, 490, 491, 492, 493, 494, 825,
-	826, 827, 595, 0, 495, 496, 497, 0, 498, 499,
-	500, 501, 502, 503, 504, 0, 0, 0, 505, 506,
-	507, 508, 0, 0, 0, 0, 0, 828, 509, 596,
-	510, 829, 830, 0, 831, 0, 511, 512, 515, 0,
-	832, 0, 514, 516, 517, 0, 518, 0, 0, 0,
-	519, 520, 521, 522, 523, 524, 525, 0, 526, 528,
-	527, 0, 530, 833, 529, 0, 531, 532, 0, 0,
-	533, 534, 535, 536, 537, 538, 541, 0, 0, 539,
-	540, 542, 543, 0, 544, 545, 547, 550, 546, 548,
-	549, 551, 552, 565, 566, 553, 554, 555, 556, 557,
-	558, 559, 560, 561, 562, 563, 564, 568, 0, 567,
-	0, 569, 570, 571, 572, 573, 581, 583, 584, 579,
-	580, 582, 585, 586, 588, 589, 576, 577, 578, 0,
-	587, 574, 0, 575, 0, 0, 590, 591, 592, 593,
-	0, 834, 594, 835, 597, 598, 0, 0, 599, 0,
-	600, 0, 0, 602, 603, 604, 0, 0, 605, 606,
-	836, 0, 607, 0, 837, 608, 609, 601, 610, 611,
-	612, 613, 614, 615, 616, 617, 618, 619, 0, 620,
-	621, 838, 622, 623, 624, 839, 625, 626, 627, 840,
-	628, 841, 629, 630, 0, 631, 632, 633, 0, 634,
-	635, 636, 637, 638, 639, 640, 641, 642, 643, 842,
-	644, 645, 647, 646, 648, 649, 0, 650, 0, 651,
-	652, 653, 0, 0, 0, 0, 0, 654, 655, 657,
-	0, 658, 659, 660, 661, 662, 656, 663, 664, 665,
-	666, 667, 668, 669, 0, 671, 672, 670, 673, 674,
-	0, 675, 676, 677, 678, 679, 843, 680, 0, 681,
-	682, 690, 691, 692, 683, 684, 686, 693, 685, 694,
-	695, 696, 697, 699, 698, 0, 701, 702, 700, 703,
-	704, 705, 706, 0, 707, 844, 708, 687, 688, 709,
-	710, 711, 0, 712, 713, 714, 715, 716, 717, 718,
-	719, 720, 845, 0, 721, 0, 722, 723, 724, 725,
-	726, 727, 729, 689, 730, 731, 732, 737, 738, 846,
-	733, 734, 735, 736, 847, 740, 741, 742, 743, 0,
-	744, 745, 0, 739, 728, 0, 746, 747, 748, 749,
-	750, 751, 752, 753, 754, 755, 0, 756, 848, 849,
-	850, 851, 0, 768, 0, 757, 759, 760, 761, 762,
-	852, 763, 853, 0, 764, 765, 766, 767, 758, 769,
-	770, 0, 0, 771, 772, 773, 774, 776, 778, 779,
-	780, 775, 777, 781, 0, 782, 0, 0, 783, 784,
-	785, 854, 855, 856, 0, 787, 788, 786, 789, 790,
-	793, 791, 792, 857, 796, 513, 797, 798, 799, 794,
-	795, 337, 0, 0, 0, 800, 801, 858, 802, 803,
-	804, 0, 0, 0, 0, 0, 0, 0, 345, 346,
-	348, 347, 349, 350, 351, 352, 0, 353, 354, 0,
-	0, 0, 0, 0, 805, 0, 0, 0, 356, 0,
-	355, 0, 357, 358, 359, 0, 360, 361, 362, 363,
-	364, 365, 366, 367, 806, 807, 0, 368, 808, 369,
-	809, 0, 810, 370, 371, 372, 373, 374, 375, 376,
-	377, 378, 379, 0, 0, 0, 380, 811, 812, 813,
-	0, 381, 382, 383, 384, 814, 0, 0, 0, 385,
-	386, 387, 388, 389, 390, 391, 392, 0, 0, 394,
-	395, 396, 393, 397, 398, 0, 399, 0, 400, 401,
-	402, 403, 404, 405, 406, 0, 407, 408, 409, 0,
-	410, 411, 412, 0, 0, 0, 0, 0, 0, 0,
-	413, 414, 415, 416, 417, 0, 418, 420, 421, 815,
-	422, 816, 0, 425, 427, 419, 423, 0, 426, 424,
-	428, 429, 0, 430, 431, 432, 433, 0, 0, 434,
-	435, 436, 0, 437, 438, 440, 439, 0, 441, 442,
-	443, 0, 444, 445, 817, 446, 447, 448, 450, 452,
-	449, 451, 453, 454, 455, 456, 457, 818, 819, 458,
-	459, 0, 0, 0, 0, 0, 0, 0, 460, 461,
-	462, 820, 0, 0, 0, 463, 0, 465, 469, 466,
-	467, 468, 470, 0, 464, 471, 472, 0, 0, 473,
-	474, 475, 821, 822, 476, 477, 478, 479, 480, 481,
-	482, 483, 484, 0, 485, 486, 823, 0, 824, 487,
-	0, 488, 489, 490, 491, 492, 493, 494, 825, 826,
-	827, 595, 0, 495, 496, 497, 0, 498, 499, 500,
-	501, 502, 503, 504, 0, 0, 0, 505, 506, 507,
-	508, 0, 0, 0, 0, 0, 828, 509, 596, 510,
-	829, 830, 0, 831, 0, 511, 512, 515, 0, 832,
-	0, 514, 516, 517, 0, 518, 0, 0, 0, 519,
-	520, 521, 522, 523, 524, 525, 0, 526, 528, 527,
-	0, 530, 833, 529, 0, 531, 532, 0, 0, 533,
-	534, 535, 536, 537, 538, 541, 0, 0, 539, 540,
-	542, 543, 0, 544, 545, 547, 550, 546, 548, 549,
-	551, 552, 565, 566, 553, 554, 555, 556, 557, 558,
-	559, 560, 561, 562, 563, 564, 568, 0, 567, 0,
-	569, 570, 571, 572, 573, 581, 583, 584, 579, 580,
-	582, 585, 586, 588, 589, 576, 577, 578, 0, 587,
-	574, 0, 575, 0, 0, 590, 591, 592, 593, 0,
-	834, 594, 835, 597, 598, 0, 0, 599, 0, 600,
-	0, 0, 602, 603, 604, 0, 0, 605, 606, 836,
-	0, 607, 0, 837, 608, 609, 601, 610, 611, 612,
-	613, 614, 615, 616, 617, 618, 619, 0, 620, 621,
-	838, 622, 623, 624, 839, 625, 626, 627, 840, 628,
-	841, 629, 630, 0, 631, 632, 633, 0, 634, 635,
-	636, 637, 638, 639, 640, 641, 642, 643, 842, 644,
-	645, 647, 646, 648, 649, 0, 650, 0, 651, 652,
-	653, 0, 0, 0, 0, 0, 654, 655, 657, 0,
-	658, 659, 660, 661, 662, 656, 663, 664, 665, 666,
-	667, 668, 669, 0, 671, 672, 670, 673, 674, 0,
-	675, 676, 677, 678, 679, 843, 680, 0, 681, 682,
-	690, 691, 692, 683, 684, 686, 693, 685, 694, 695,
-	696, 697, 699, 698, 0, 701, 702, 700, 703, 704,
-	705, 706, 0, 707, 844, 708, 687, 688, 709, 710,
-	711, 0, 712, 713, 714, 715, 716, 717, 718, 719,
-	720, 845, 0, 721, 0, 722, 723, 724, 725, 726,
-	727, 729, 689, 730, 731, 732, 737, 738, 846, 733,
-	734, 735, 736, 847, 740, 741, 742, 743, 0, 744,
-	745, 0, 739, 728, 0, 746, 747, 748, 749, 750,
-	751, 752, 753, 754, 755, 0, 756, 848, 849, 850,
-	851, 0, 768, 0, 757, 759, 760, 761, 762, 852,
-	763, 853, 0, 764, 765, 766, 767, 758, 769, 770,
-	0, 0, 771, 772, 773, 774, 776, 778, 779, 780,
-	775, 777, 781, 0, 782, 0, 0, 783, 784, 785,
-	854, 855, 856, 0, 787, 788, 786, 789, 790, 793,
-	791, 792, 857, 796, 513, 797, 798, 799, 794, 795,
-	337, 0, 0, 0, 800, 801, 858, 802, 803, 804,
-	0, 0, 0, 0, 0, 0, 0, 345, 346, 348,
-	347, 349, 350, 351, 352, 0, 353, 354, 0, 0,
-	0, 0, 0, 805, 0, 0, 0, 356, 0, 355,
-	0, 357, 358, 359, 0, 360, 361, 362, 363, 364,
-	365, 366, 367, 806, 807, 0, 368, 808, 369, 809,
-	0, 810, 370, 371, 372, 373, 374, 375, 376, 377,
-	378, 379, 0, 0, 0, 380, 811, 812, 813, 0,
-	381, 382, 383, 384, 814, 0, 0, 0, 385, 386,
-	387, 388, 389, 390, 391, 392, 0, 0, 394, 395,
-	396, 393, 397, 398, 0, 399, 0, 400, 401, 402,
-	403, 404, 405, 406, 0, 407, 408, 409, 0, 410,
-	411, 412, 0, 0, 0, 0, 0, 0, 0, 413,
-	414, 415, 416, 417, 0, 418, 420, 421, 815, 422,
-	816, 0, 425, 427, 419, 423, 0, 426, 424, 428,
-	429, 0, 430, 431, 432, 433, 0, 0, 434, 435,
-	436, 0, 437, 438, 440, 439, 0, 441, 442, 443,
-	0, 444, 445, 817, 446, 447, 448, 450, 452, 449,
-	451, 453, 454, 455, 456, 457, 818, 819, 458, 459,
-	0, 0, 0, 0, 0, 0, 0, 460, 461, 462,
-	820, 0, 0, 0, 463, 0, 465, 469, 466, 467,
-	468, 470, 0, 464, 471, 472, 0, 0, 473, 474,
-	475, 821, 822, 476, 477, 478, 479, 480, 481, 482,
-	483, 484, 0, 485, 486, 823, 0, 824, 487, 0,
-	488, 489, 490, 491, 492, 493, 494, 5119, 826, 827,
-	595, 0, 495, 496, 497, 0, 498, 499, 500, 501,
-	502, 503, 504, 0, 0, 0, 505, 506, 507, 508,
-	0, 0, 0, 0, 0, 828, 509, 596, 510, 829,
-	830, 0, 831, 0, 511, 512, 515, 0, 832, 0,
-	514, 516, 517, 0, 518, 0, 0, 0, 519, 520,
-	521, 522, 523, 524, 525, 0, 526, 528, 527, 0,
-	530, 833, 529, 0, 531, 532, 0, 0, 533, 534,
-	535, 536, 537, 538, 541, 0, 0, 539, 540, 542,
-	543, 0, 544, 545, 547, 550, 546, 548, 549, 551,
-	552, 565, 566, 553, 554, 555, 556, 557, 558, 559,
-	560, 561, 562, 563, 564, 568, 0, 567, 0, 569,
-	570, 571, 572, 573, 581, 583, 584, 579, 580, 582,
-	585, 586, 588, 589, 576, 577, 578, 0, 587, 574,
-	0, 575, 0, 0, 590, 591, 592, 593, 0, 834,
-	594, 835, 597, 598, 0, 0, 599, 0, 600, 0,
-	0, 602, 603, 604, 0, 0, 605, 606, 836, 0,
-	607, 0, 837, 608, 609, 601, 610, 611, 612, 613,
-	614, 615, 616, 617, 618, 619, 0, 620, 621, 838,
-	622, 623, 624, 839, 625, 626, 627, 840, 628, 841,
-	629, 630, 0, 631, 632, 633, 0, 634, 635, 636,
-	637, 638, 639, 640, 641, 642, 643, 842, 644, 645,
-	647, 646, 648, 649, 0, 650, 0, 651, 652, 653,
-	0, 0, 0, 0, 0, 654, 655, 657, 0, 658,
-	659, 660, 661, 662, 656, 663, 664, 665, 666, 667,
-	668, 669, 0, 671, 672, 670, 673, 674, 0, 675,
-	676, 677, 678, 679, 843, 680, 0, 681, 682, 690,
-	691, 692, 683, 684, 686, 693, 685, 694, 695, 696,
-	697, 699, 698, 0, 701, 702, 700, 703, 704, 705,
-	706, 0, 707, 844, 708, 687, 688, 709, 710, 711,
-	0, 712, 713, 714, 715, 716, 717, 718, 719, 720,
-	845, 0, 721, 0, 722, 723, 724, 725, 726, 727,
-	729, 689, 730, 731, 732, 737, 738, 846, 733, 734,
-	735, 736, 847, 740, 741, 742, 743, 0, 744, 745,
-	0, 739, 728, 0, 746, 747, 748, 749, 750, 751,
-	752, 753, 754, 755, 0, 756, 848, 849, 850, 851,
-	0, 768, 0, 757, 759, 760, 761, 762, 852, 763,
-	853, 0, 764, 765, 766, 767, 758, 769, 770, 0,
-	0, 771, 772, 773, 774, 776, 778, 779, 780, 775,
-	777, 781, 0, 782, 0, 0, 783, 784, 785, 854,
-	855, 856, 0, 787, 788, 786, 789, 790, 793, 791,
-	792, 857, 796, 513, 797, 798, 799, 794, 795, 337,
-	0, 0, 0, 800, 801, 858, 802, 803, 804, 0,
-	0, 0, 0, 0, 0, 0, 345, 346, 348, 347,
-	349, 350, 351, 352, 0, 353, 354, 0, 0, 0,
-	0, 0, 805, 0, 0, 0, 356, 0, 355, 0,
-	357, 358, 359, 0, 360, 361, 362, 363, 364, 365,
-	366, 367, 806, 807, 0, 368, 808, 369, 809, 0,
-	810, 370, 371, 372, 373, 374, 375, 376, 377, 378,
-	379, 0, 0, 0, 380, 811, 812, 813, 0, 381,
-	382, 383, 384, 814, 0, 0, 0, 385, 386, 387,
-	388, 389, 390, 391, 392, 0, 0, 394, 395, 396,
-	393, 397, 398, 0, 399, 0, 400, 401, 402, 403,
-	404, 405, 406, 0, 407, 408, 409, 0, 410, 411,
-	412, 0, 0, 0, 0, 0, 0, 0, 413, 414,
-	415, 416, 417, 0, 418, 420, 421, 815, 422, 816,
-	0, 425, 427, 419, 423, 0, 426, 424, 428, 429,
-	0, 430, 431, 432, 433, 0, 0, 434, 435, 436,
-	0, 437, 438, 440, 439, 0, 441, 442, 443, 0,
-	444, 445, 817, 446, 447, 448, 450, 452, 449, 451,
-	453, 454, 455, 456, 457, 818, 819, 458, 459, 0,
-	0, 0, 0, 0, 0, 0, 460, 461, 462, 820,
-	0, 0, 0, 463, 0, 465, 469, 466, 467, 468,
-	470, 0, 464, 471, 472, 0, 0, 473, 474, 475,
-	821, 822, 476, 477, 478, 479, 480, 481, 482, 483,
-	484, 0, 485, 486, 823, 0, 824, 487, 0, 488,
-	489, 490, 491, 492, 493, 494, 825, 826, 827, 595,
-	0, 495, 496, 497, 0, 498, 499, 500, 501, 502,
-	503, 504, 0, 0, 0, 505, 506, 507, 508, 0,
-	0, 0, 0, 0, 828, 509, 596, 510, 829, 830,
-	0, 831, 0, 511, 512, 515, 0, 832, 0, 514,
-	516, 517, 0, 518, 0, 0, 0, 519, 520, 521,
-	522, 523, 524, 525, 0, 526, 528, 527, 0, 530,
-	833, 529, 0, 531, 532, 0, 0, 533, 534, 535,
-	536, 537, 538, 541, 0, 0, 539, 540, 542, 543,
-	0, 544, 545, 547, 550, 546, 548, 549, 551, 552,
-	565, 566, 553, 554, 555, 556, 557, 558, 559, 560,
-	561, 562, 563, 564, 568, 0, 567, 0, 569, 570,
-	571, 572, 573, 581, 583, 584, 579, 580, 582, 585,
-	586, 588, 589, 576, 577, 578, 0, 587, 574, 0,
-	575, 0, 0, 590, 591, 592, 593, 0, 834, 594,
-	835, 597, 598, 0, 0, 599, 0, 600, 0, 0,
-	602, 603, 604, 0, 0, 605, 606, 836, 0, 607,
-	0, 837, 608, 609, 601, 610, 611, 612, 613, 614,
-	615, 616, 617, 618, 619, 0, 620, 621, 838, 622,
-	623, 624, 839, 625, 626, 627, 840, 628, 841, 629,
-	630, 0, 631, 632, 633, 0, 634, 635, 636, 637,
-	638, 639, 640, 641, 642, 643, 842, 644, 645, 647,
-	646, 648, 649, 0, 650, 0, 651, 652, 653, 0,
-	0, 0, 0, 0, 654, 655, 657, 0, 658, 659,
-	660, 661, 662, 656, 663, 664, 665, 666, 667, 668,
-	669, 0, 671, 672, 670, 673, 674, 0, 989, 676,
-	677, 678, 679, 843, 680, 0, 681, 682, 690, 691,
-	692, 683, 684, 686, 988, 685, 694, 695, 696, 697,
-	699, 698, 0, 701, 702, 700, 703, 704, 705, 706,
-	0, 707, 844, 708, 687, 688, 709, 710, 711, 0,
-	712, 713, 714, 715, 716, 717, 718, 719, 720, 845,
-	0, 721, 0, 722, 723, 724, 725, 726, 727, 729,
-	689, 730, 731, 732, 737, 738, 846, 733, 734, 735,
-	736, 847, 740, 741, 742, 743, 0, 744, 745, 0,
-	739, 728, 0, 746, 747, 748, 749, 750, 751, 752,
-	753, 754, 755, 0, 756, 986, 849, 850, 851, 0,
-	768, 0, 757, 759, 760, 761, 762, 852, 763, 853,
-	0, 764, 765, 766, 767, 758, 769, 770, 0, 0,
-	771, 772, 773, 774, 776, 778, 779, 780, 775, 777,
-	781, 0, 782, 0, 0, 783, 784, 785, 854, 855,
-	856, 0, 787, 788, 786, 789, 790, 793, 791, 792,
-	857, 796, 513, 797, 798, 799, 794, 795, 337, 0,
-	0, 0, 800, 801, 858, 802, 803, 804, 0, 0,
-	0, 0, 0, 0, 0, 345, 346, 348, 347, 349,
-	350, 351, 352, 0, 353, 354, 0, 0, 0, 0,
-	0, 805, 0, 0, 0, 356, 0, 355, 0, 357,
-	358, 359, 0, 360, 361, 362, 363, 364, 365, 366,
-	367, 806, 807, 0, 368, 808, 369, 809, 0, 810,
-	370, 371, 372, 373, 374, 375, 376, 377, 378, 379,
-	0, 0, 0, 380, 811, 812, 813, 0, 381, 382,
-	383, 384, 814, 0, 0, 0, 385, 386, 387, 388,
-	389, 390, 391, 392, 0, 0, 394, 395, 396, 393,
-	397, 398, 0, 399, 0, 400, 401, 402, 403, 404,
-	405, 406, 0, 407, 408, 409, 0, 410, 411, 412,
-	0, 0, 0, 0, 0, 0, 0, 413, 414, 415,
-	416, 417, 0, 418, 420, 421, 815, 422, 816, 0,
-	425, 427, 419, 423, 0, 426, 424, 428, 429, 0,
-	430, 431, 432, 433, 0, 0, 434, 435, 436, 0,
-	437, 438, 440, 439, 0, 441, 442, 443, 0, 444,
-	445, 817, 446, 447, 448, 450, 452, 449, 451, 453,
-	454, 455, 456, 457, 818, 819, 458, 459, 0, 0,
-	0, 0, 0, 0, 0, 460, 461, 462, 820, 0,
-	0, 0, 463, 0, 465, 469, 466, 467, 468, 470,
-	0, 464, 471, 472, 0, 0, 473, 474, 475, 821,
-	822, 476, 477, 478, 479, 480, 481, 482, 483, 484,
-	0, 485, 486, 823, 0, 824, 487, 0, 488, 489,
-	490, 491, 492, 493, 494, 4987, 826, 827, 595, 0,
-	495, 496, 497, 0, 498, 499, 500, 501, 502, 503,
-	504, 0, 0, 0, 505, 506, 507, 508, 0, 0,
-	0, 0, 0, 828, 509, 596, 510, 829, 830, 0,
-	831, 0, 511, 512, 515, 0, 832, 0, 514, 516,
-	517, 0, 518, 0, 0, 0, 519, 520, 521, 522,
-	523, 524, 525, 0, 526, 528, 527, 0, 530, 833,
-	529, 0, 531, 532, 0, 0, 533, 534, 535, 536,
-	537, 538, 541, 0, 0, 539, 540, 542, 543, 0,
-	544, 545, 547, 550, 546, 548, 549, 551, 552, 565,
-	566, 553, 554, 555, 556, 557, 558, 559, 560, 561,
-	562, 563, 564, 568, 0, 567, 0, 569, 570, 571,
-	572, 573, 581, 583, 584, 579, 580, 582, 585, 586,
-	588, 589, 576, 577, 578, 0, 587, 574, 0, 575,
-	0, 0, 590, 591, 592, 593, 0, 834, 594, 835,
-	597, 598, 0, 0, 599, 0, 600, 0, 0, 602,
-	603, 604, 0, 0, 605, 606, 836, 0, 607, 0,
-	837, 608, 609, 601, 610, 611, 612, 613, 614, 615,
-	616, 617, 618, 619, 0, 620, 621, 838, 622, 623,
-	624, 839, 625, 626, 627, 840, 628, 841, 629, 630,
-	0, 631, 632, 633, 0, 634, 635, 636, 637, 638,
-	639, 640, 641, 642, 643, 842, 644, 645, 647, 646,
-	648, 649, 0, 650, 0, 651, 652, 653, 0, 0,
-	0, 0, 0, 654, 655, 657, 0, 658, 659, 660,
-	661, 662, 656, 663, 664, 665, 666, 667, 668, 669,
-	0, 671, 672, 670, 673, 674, 0, 675, 676, 677,
-	678, 679, 843, 680, 0, 681, 682, 690, 691, 692,
-	683, 684, 686, 693, 685, 694, 695, 696, 697, 699,
-	698, 0, 701, 702, 700, 703, 704, 705, 706, 0,
-	707, 844, 708, 687, 688, 709, 710, 711, 0, 712,
-	713, 714, 715, 716, 717, 718, 719, 720, 845, 0,
-	721, 0, 722, 723, 724, 725, 726, 727, 729, 689,
-	730, 731, 732, 737, 738, 846, 733, 734, 735, 736,
-	847, 740, 741, 742, 743, 0, 744, 745, 0, 739,
-	728, 0, 746, 747, 748, 749, 750, 751, 752, 753,
-	754, 755, 0, 756, 848, 849, 850, 851, 0, 768,
-	0, 757, 759, 760, 761, 762, 852, 763, 853, 0,
-	764, 765, 766, 767, 758, 769, 770, 0, 0, 771,
-	772, 773, 774, 776, 778, 779, 780, 775, 777, 781,
-	0, 782, 0, 0, 783, 784, 785, 854, 855, 856,
-	0, 787, 788, 786, 789, 790, 793, 791, 792, 857,
-	796, 513, 797, 798, 799, 794, 795, 337, 0, 0,
-	0, 800, 801, 858, 802, 803, 804, 0, 0, 0,
-	0, 0, 0, 0, 345, 346, 348, 347, 349, 350,
-	351, 352, 0, 353, 354, 0, 0, 0, 0, 0,
-	805, 0, 0, 0, 356, 0, 355, 0, 357, 358,
-	359, 0, 360, 361, 362, 363, 364, 365, 366, 367,
-	806, 807, 0, 368, 808, 369, 809, 0, 810, 370,
-	371, 372, 373, 374, 375, 376, 377, 378, 379, 0,
-	0, 0, 380, 811, 812, 813, 0, 381, 382, 383,
-	384, 814, 0, 0, 0, 385, 386, 387, 388, 389,
-	390, 391, 392, 0, 0, 394, 395, 396, 393, 397,
-	398, 0, 399, 0, 400, 401, 402, 403, 404, 405,
-	406, 0, 407, 408, 409, 0, 410, 411, 412, 0,
-	0, 0, 0, 0, 0, 0, 413, 414, 415, 416,
-	417, 0, 418, 420, 421, 815, 422, 816, 0, 425,
-	427, 419, 423, 0, 426, 424, 428, 429, 0, 430,
-	431, 432, 433, 0, 0, 434, 435, 436, 0, 437,
-	438, 440, 439, 0, 441, 442, 443, 0, 444, 445,
-	817, 446, 447, 448, 450, 452, 449, 451, 453, 454,
-	455, 456, 457, 818, 819, 458, 459, 0, 0, 0,
-	0, 0, 0, 0, 460, 461, 462, 820, 0, 0,
-	0, 463, 0, 465, 469, 466, 467, 468, 470, 0,
-	464, 471, 472, 0, 0, 473, 474, 475, 821, 822,
-	476, 477, 478, 479, 480, 481, 482, 483, 484, 0,
-	485, 486, 823, 0, 824, 487, 0, 488, 489, 490,
-	491, 492, 493, 494, 4891, 826, 827, 595, 0, 495,
-	496, 497, 0, 498, 499, 500, 501, 502, 503, 504,
-	0, 0, 0, 505, 506, 507, 508, 0, 0, 0,
-	0, 0, 828, 509, 596, 510, 829, 830, 0, 831,
-	0, 511, 512, 515, 0, 832, 0, 514, 516, 517,
-	0, 518, 0, 0, 0, 519, 520, 521, 522, 523,
-	524, 525, 0, 526, 528, 527, 0, 530, 833, 529,
-	0, 531, 532, 0, 0, 533, 534, 535, 536, 537,
-	538, 541, 0, 0, 539, 540, 542, 543, 0, 544,
-	545, 547, 550, 546, 548, 549, 551, 552, 565, 566,
-	553, 554, 555, 556, 557, 558, 559, 560, 561, 562,
-	563, 564, 568, 0, 567, 0, 569, 570, 571, 572,
-	573, 581, 583, 584, 579, 580, 582, 585, 586, 588,
-	589, 576, 577, 578, 0, 587, 574, 0, 575, 0,
-	0, 590, 591, 592, 593, 0, 834, 594, 835, 597,
-	598, 0, 0, 599, 0, 600, 0, 0, 602, 603,
-	604, 0, 0, 605, 606, 836, 0, 607, 0, 837,
-	608, 609, 601, 610, 611, 612, 613, 614, 615, 616,
-	617, 618, 619, 0, 620, 621, 838, 622, 623, 624,
-	839, 625, 626, 627, 840, 628, 841, 629, 630, 0,
-	631, 632, 633, 0, 634, 635, 636, 637, 638, 639,
-	640, 641, 642, 643, 842, 644, 645, 647, 646, 648,
-	649, 0, 650, 0, 651, 652, 653, 0, 0, 0,
-	0, 0, 654, 655, 657, 0, 658, 659, 660, 661,
-	662, 656, 663, 664, 665, 666, 667, 668, 669, 0,
-	671, 672, 670, 673, 674, 0, 675, 676, 677, 678,
-	679, 843, 680, 0, 681, 682, 690, 691, 692, 683,
-	684, 686, 693, 685, 694, 695, 696, 697, 699, 698,
-	0, 701, 702, 700, 703, 704, 705, 706, 0, 707,
-	844, 708, 687, 688, 709, 710, 711, 0, 712, 713,
-	714, 715, 716, 717, 718, 719, 720, 845, 0, 721,
-	0, 722, 723, 724, 725, 726, 727, 729, 689, 730,
-	731, 732, 737, 738, 846, 733, 734, 735, 736, 847,
-	740, 741, 742, 743, 0, 744, 745, 0, 739, 728,
-	0, 746, 747, 748, 749, 750, 751, 752, 753, 754,
-	755, 0, 756, 848, 849, 850, 851, 0, 768, 0,
-	757, 759, 760, 761, 762, 852, 763, 853, 0, 764,
-	765, 766, 767, 758, 769, 770, 0, 0, 771, 772,
-	773, 774, 776, 778, 779, 780, 775, 777, 781, 0,
-	782, 0, 0, 783, 784, 785, 854, 855, 856, 0,
-	787, 788, 786, 789, 790, 793, 791, 792, 857, 796,
-	513, 797, 798, 799, 794, 795, 337, 0, 0, 0,
-	800, 801, 858, 802, 803, 804, 0, 0, 0, 0,
-	0, 0, 0, 345, 346, 348, 347, 349, 350, 351,
-	352, 0, 353, 354, 0, 0, 0, 0, 0, 805,
-	0, 0, 0, 356, 0, 355, 0, 357, 358, 359,
-	0, 360, 361, 362, 363, 364, 365, 366, 367, 806,
-	807, 0, 368, 808, 369, 809, 0, 810, 370, 371,
-	372, 373, 374, 375, 376, 377, 378, 379, 0, 0,
-	0, 380, 811, 812, 813, 0, 381, 382, 383, 384,
-	814, 0, 0, 0, 385, 386, 387, 388, 389, 390,
-	391, 392, 0, 0, 394, 395, 396, 393, 397, 398,
-	0, 399, 0, 400, 401, 402, 403, 404, 405, 406,
-	0, 407, 408, 409, 0, 410, 411, 412, 0, 0,
-	0, 0, 0, 0, 0, 413, 414, 415, 416, 417,
-	0, 418, 420, 421, 815, 422, 816, 0, 425, 427,
-	419, 423, 0, 426, 424, 428, 429, 0, 430, 431,
-	432, 433, 0, 0, 434, 435, 436, 0, 437, 438,
-	440, 439, 0, 441, 442, 443, 0, 444, 445, 817,
-	446, 447, 448, 450, 452, 449, 451, 453, 454, 455,
-	456, 457, 818, 819, 458, 459, 0, 0, 0, 0,
-	0, 0, 0, 460, 461, 462, 820, 0, 0, 0,
-	463, 0, 465, 469, 466, 467, 468, 470, 0, 464,
-	471, 472, 0, 0, 473, 474, 475, 821, 822, 476,
-	477, 478, 479, 480, 481, 482, 483, 484, 0, 485,
-	486, 823, 0, 824, 487, 0, 488, 489, 490, 491,
-	492, 493, 494, 4889, 826, 827, 595, 0, 495, 496,
-	497, 0, 498, 499, 500, 501, 502, 503, 504, 0,
-	0, 0, 505, 506, 507, 508, 0, 0, 0, 0,
-	0, 828, 509, 596, 510, 829, 830, 0, 831, 0,
-	511, 512, 515, 0, 832, 0, 514, 516, 517, 0,
-	518, 0, 0, 0, 519, 520, 521, 522, 523, 524,
-	525, 0, 526, 528, 527, 0, 530, 833, 529, 0,
-	531, 532, 0, 0, 533, 534, 535, 536, 537, 538,
-	541, 0, 0, 539, 540, 542, 543, 0, 544, 545,
-	547, 550, 546, 548, 549, 551, 552, 565, 566, 553,
-	554, 555, 556, 557, 558, 559, 560, 561, 562, 563,
-	564, 568, 0, 567, 0, 569, 570, 571, 572, 573,
-	581, 583, 584, 579, 580, 582, 585, 586, 588, 589,
-	576, 577, 578, 0, 587, 574, 0, 575, 0, 0,
-	590, 591, 592, 593, 0, 834, 594, 835, 597, 598,
-	0, 0, 599, 0, 600, 0, 0, 602, 603, 604,
-	0, 0, 605, 606, 836, 0, 607, 0, 837, 608,
-	609, 601, 610, 611, 612, 613, 614, 615, 616, 617,
-	618, 619, 0, 620, 621, 838, 622, 623, 624, 839,
-	625, 626, 627, 840, 628, 841, 629, 630, 0, 631,
-	632, 633, 0, 634, 635, 636, 637, 638, 639, 640,
-	641, 642, 643, 842, 644, 645, 647, 646, 648, 649,
-	0, 650, 0, 651, 652, 653, 0, 0, 0, 0,
-	0, 654, 655, 657, 0, 658, 659, 660, 661, 662,
-	656, 663, 664, 665, 666, 667, 668, 669, 0, 671,
-	672, 670, 673, 674, 0, 675, 676, 677, 678, 679,
-	843, 680, 0, 681, 682, 690, 691, 692, 683, 684,
-	686, 693, 685, 694, 695, 696, 697, 699, 698, 0,
-	701, 702, 700, 703, 704, 705, 706, 0, 707, 844,
-	708, 687, 688, 709, 710, 711, 0, 712, 713, 714,
-	715, 716, 717, 718, 719, 720, 845, 0, 721, 0,
-	722, 723, 724, 725, 726, 727, 729, 689, 730, 731,
-	732, 737, 738, 846, 733, 734, 735, 736, 847, 740,
-	741, 742, 743, 0, 744, 745, 0, 739, 728, 0,
-	746, 747, 748, 749, 750, 751, 752, 753, 754, 755,
-	0, 756, 848, 849, 850, 851, 0, 768, 0, 757,
-	759, 760, 761, 762, 852, 763, 853, 0, 764, 765,
-	766, 767, 758, 769, 770, 0, 0, 771, 772, 773,
-	774, 776, 778, 779, 780, 775, 777, 781, 0, 782,
-	0, 0, 783, 784, 785, 854, 855, 856, 0, 787,
-	788, 786, 789, 790, 793, 791, 792, 857, 796, 513,
-	797, 798, 799, 794, 795, 337, 0, 0, 0, 800,
-	801, 858, 802, 803, 804, 0, 0, 0, 0, 0,
-	0, 0, 345, 346, 348, 347, 349, 350, 351, 352,
-	0, 353, 354, 0, 0, 0, 0, 0, 805, 0,
-	0, 0, 356, 0, 355, 0, 357, 358, 359, 0,
-	360, 361, 362, 363, 364, 365, 366, 367, 806, 807,
-	0, 368, 808, 369, 809, 0, 810, 370, 371, 372,
-	373, 374, 375, 376, 377, 378, 379, 0, 0, 0,
-	380, 811, 812, 813, 0, 381, 382, 383, 384, 814,
-	0, 0, 0, 385, 386, 387, 388, 389, 390, 391,
-	392, 0, 0, 394, 395, 396, 393, 397, 398, 0,
-	399, 0, 400, 401, 402, 403, 404, 405, 406, 0,
-	407, 408, 409, 0, 410, 411, 412, 0, 0, 0,
-	0, 0, 0, 0, 413, 414, 415, 416, 417, 0,
-	418, 420, 421, 815, 422, 816, 0, 425, 427, 419,
-	423, 0, 426, 424, 428, 429, 0, 430, 431, 432,
-	433, 0, 0, 434, 435, 436, 0, 437, 438, 440,
-	439, 0, 441, 442, 443, 0, 444, 445, 817, 446,
-	447, 448, 450, 452, 449, 451, 453, 454, 455, 456,
-	457, 818, 819, 458, 459, 0, 0, 0, 0, 0,
-	0, 0, 460, 461, 462, 820, 0, 0, 0, 463,
-	0, 465, 469, 466, 467, 468, 470, 0, 464, 471,
-	472, 0, 0, 473, 474, 475, 821, 822, 476, 477,
-	478, 479, 480, 481, 482, 483, 484, 0, 485, 486,
-	823, 0, 824, 487, 0, 488, 489, 490, 491, 492,
-	493, 494, 4877, 826, 827, 595, 0, 495, 496, 497,
-	0, 498, 499, 500, 501, 502, 503, 504, 0, 0,
-	0, 505, 506, 507, 508, 0, 0, 0, 0, 0,
-	828, 509, 596, 510, 829, 830, 0, 831, 0, 511,
-	512, 515, 0, 832, 0, 514, 516, 517, 0, 518,
-	0, 0, 0, 519, 520, 521, 522, 523, 524, 525,
-	0, 526, 528, 527, 0, 530, 833, 529, 0, 531,
-	532, 0, 0, 533, 534, 535, 536, 537, 538, 541,
-	0, 0, 539, 540, 542, 543, 0, 544, 545, 547,
-	550, 546, 548, 549, 551, 552, 565, 566, 553, 554,
-	555, 556, 557, 558, 559, 560, 561, 562, 563, 564,
-	568, 0, 567, 0, 569, 570, 571, 572, 573, 581,
-	583, 584, 579, 580, 582, 585, 586, 588, 589, 576,
-	577, 578, 0, 587, 574, 0, 575, 0, 0, 590,
-	591, 592, 593, 0, 834, 594, 835, 597, 598, 0,
-	0, 599, 0, 600, 0, 0, 602, 603, 604, 0,
-	0, 605, 606, 836, 0, 607, 0, 837, 608, 609,
-	601, 610, 611, 612, 613, 614, 615, 616, 617, 618,
-	619, 0, 620, 621, 838, 622, 623, 624, 839, 625,
-	626, 627, 840, 628, 841, 629, 630, 0, 631, 632,
-	633, 0, 634, 635, 636, 637, 638, 639, 640, 641,
-	642, 643, 842, 644, 645, 647, 646, 648, 649, 0,
-	650, 0, 651, 652, 653, 0, 0, 0, 0, 0,
-	654, 655, 657, 0, 658, 659, 660, 661, 662, 656,
-	663, 664, 665, 666, 667, 668, 669, 0, 671, 672,
-	670, 673, 674, 0, 675, 676, 677, 678, 679, 843,
-	680, 0, 681, 682, 690, 691, 692, 683, 684, 686,
-	693, 685, 694, 695, 696, 697, 699, 698, 0, 701,
-	702, 700, 703, 704, 705, 706, 0, 707, 844, 708,
-	687, 688, 709, 710, 711, 0, 712, 713, 714, 715,
-	716, 717, 718, 719, 720, 845, 0, 721, 0, 722,
-	723, 724, 725, 726, 727, 729, 689, 730, 731, 732,
-	737, 738, 846, 733, 734, 735, 736, 847, 740, 741,
-	742, 743, 0, 744, 745, 0, 739, 728, 0, 746,
-	747, 748, 749, 750, 751, 752, 753, 754, 755, 0,
-	756, 848, 849, 850, 851, 0, 768, 0, 757, 759,
-	760, 761, 762, 852, 763, 853, 0, 764, 765, 766,
-	767, 758, 769, 770, 0, 0, 771, 772, 773, 774,
-	776, 778, 779, 780, 775, 777, 781, 0, 782, 0,
-	0, 783, 784, 785, 854, 855, 856, 0, 787, 788,
-	786, 789, 790, 793, 791, 792, 857, 796, 513, 797,
-	798, 799, 794, 795, 337, 0, 0, 0, 800, 801,
-	858, 802, 803, 804, 0, 0, 0, 0, 0, 0,
-	0, 345, 346, 348, 347, 349, 350, 351, 352, 0,
-	353, 354, 0, 0, 0, 0, 0, 805, 0, 0,
-	0, 356, 0, 355, 0, 357, 358, 359, 0, 360,
-	361, 362, 363, 364, 365, 366, 367, 806, 807, 0,
-	368, 808, 369, 809, 0, 810, 370, 371, 372, 373,
-	374, 375, 376, 377, 378, 379, 0, 0, 0, 380,
-	811, 812, 813, 0, 381, 382, 383, 384, 814, 0,
-	0, 0, 385, 386, 387, 388, 389, 390, 391, 392,
-	0, 0, 394, 395, 396, 393, 397, 398, 0, 399,
-	0, 400, 401, 402, 403, 404, 405, 406, 0, 407,
-	408, 409, 0, 410, 411, 412, 0, 0, 0, 0,
-	0, 0, 0, 413, 414, 415, 416, 417, 0, 418,
-	420, 421, 815, 422, 816, 0, 425, 427, 419, 423,
-	0, 426, 424, 428, 429, 0, 430, 431, 432, 433,
-	0, 0, 434, 435, 436, 0, 437, 438, 440, 439,
-	0, 441, 442, 443, 0, 444, 445, 817, 446, 447,
-	448, 450, 452, 449, 451, 453, 454, 455, 456, 457,
-	818, 819, 458, 459, 0, 0, 0, 0, 0, 0,
-	0, 460, 461, 462, 820, 0, 0, 0, 463, 0,
-	465, 469, 466, 467, 468, 470, 0, 464, 471, 472,
-	0, 0, 473, 474, 475, 821, 822, 476, 477, 478,
-	479, 480, 481, 482, 483, 484, 0, 485, 486, 823,
-	0, 824, 487, 0, 488, 489, 490, 491, 492, 493,
-	494, 4874, 826, 827, 595, 0, 495, 496, 497, 0,
-	498, 499, 500, 501, 502, 503, 504, 0, 0, 0,
-	505, 506, 507, 508, 0, 0, 0, 0, 0, 828,
-	509, 596, 510, 829, 830, 0, 831, 0, 511, 512,
-	515, 0, 832, 0, 514, 516, 517, 0, 518, 0,
-	0, 0, 519, 520, 521, 522, 523, 524, 525, 0,
-	526, 528, 527, 0, 530, 833, 529, 0, 531, 532,
-	0, 0, 533, 534, 535, 536, 537, 538, 541, 0,
-	0, 539, 540, 542, 543, 0, 544, 545, 547, 550,
-	546, 548, 549, 551, 552, 565, 566, 553, 554, 555,
-	556, 557, 558, 559, 560, 561, 562, 563, 564, 568,
-	0, 567, 0, 569, 570, 571, 572, 573, 581, 583,
-	584, 579, 580, 582, 585, 586, 588, 589, 576, 577,
-	578, 0, 587, 574, 0, 575, 0, 0, 590, 591,
-	592, 593, 0, 834, 594, 835, 597, 598, 0, 0,
-	599, 0, 600, 0, 0, 602, 603, 604, 0, 0,
-	605, 606, 836, 0, 607, 0, 837, 608, 609, 601,
-	610, 611, 612, 613, 614, 615, 616, 617, 618, 619,
-	0, 620, 621, 838, 622, 623, 624, 839, 625, 626,
-	627, 840, 628, 841, 629, 630, 0, 631, 632, 633,
-	0, 634, 635, 636, 637, 638, 639, 640, 641, 642,
-	643, 842, 644, 645, 647, 646, 648, 649, 0, 650,
-	0, 651, 652, 653, 0, 0, 0, 0, 0, 654,
-	655, 657, 0, 658, 659, 660, 661, 662, 656, 663,
-	664, 665, 666, 667, 668, 669, 0, 671, 672, 670,
-	673, 674, 0, 675, 676, 677, 678, 679, 843, 680,
-	0, 681, 682, 690, 691, 692, 683, 684, 686, 693,
-	685, 694, 695, 696, 697, 699, 698, 0, 701, 702,
-	700, 703, 704, 705, 706, 0, 707, 844, 708, 687,
-	688, 709, 710, 711, 0, 712, 713, 714, 715, 716,
-	717, 718, 719, 720, 845, 0, 721, 0, 722, 723,
-	724, 725, 726, 727, 729, 689, 730, 731, 732, 737,
-	738, 846, 733, 734, 735, 736, 847, 740, 741, 742,
-	743, 0, 744, 745, 0, 739, 728, 0, 746, 747,
-	748, 749, 750, 751, 752, 753, 754, 755, 0, 756,
-	848, 849, 850, 851, 0, 768, 0, 757, 759, 760,
-	761, 762, 852, 763, 853, 0, 764, 765, 766, 767,
-	758, 769, 770, 0, 0, 771, 772, 773, 774, 776,
-	778, 779, 780, 775, 777, 781, 0, 782, 0, 0,
-	783, 784, 785, 854, 855, 856, 0, 787, 788, 786,
-	789, 790, 793, 791, 792, 857, 796, 513, 797, 798,
-	799, 794, 795, 337, 0, 0, 0, 800, 801, 858,
-	802, 803, 804, 0, 0, 0, 0, 0, 0, 0,
-	345, 346, 348, 347, 349, 350, 351, 352, 0, 353,
-	354, 0, 0, 0, 0, 0, 805, 0, 0, 0,
-	356, 0, 355, 0, 357, 358, 359, 0, 360, 361,
-	362, 363, 364, 365, 366, 367, 806, 807, 0, 368,
-	808, 369, 809, 0, 810, 370, 371, 372, 373, 374,
-	375, 376, 377, 378, 379, 0, 0, 0, 380, 811,
-	812, 813, 0, 381, 382, 383, 384, 814, 0, 0,
-	0, 385, 386, 387, 388, 389, 390, 391, 392, 0,
-	0, 394, 395, 396, 393, 397, 398, 0, 399, 0,
-	400, 401, 402, 403, 404, 405, 406, 0, 407, 408,
-	409, 0, 410, 411, 412, 0, 0, 0, 0, 0,
-	0, 0, 413, 414, 415, 416, 417, 0, 418, 420,
-	421, 815, 422, 816, 0, 425, 427, 419, 423, 0,
-	426, 424, 428, 429, 0, 430, 431, 432, 433, 0,
-	0, 434, 435, 436, 0, 437, 438, 440, 439, 0,
-	441, 442, 443, 0, 444, 445, 817, 446, 447, 448,
-	450, 452, 449, 451, 453, 454, 455, 456, 457, 818,
-	819, 458, 459, 0, 0, 0, 0, 0, 0, 0,
-	460, 461, 462, 820, 0, 0, 0, 463, 0, 465,
-	469, 466, 467, 468, 470, 0, 464, 471, 472, 0,
-	0, 473, 474, 475, 821, 822, 476, 477, 478, 479,
-	480, 481, 482, 483, 484, 0, 485, 486, 823, 0,
-	824, 487, 0, 488, 489, 490, 491, 492, 493, 494,
-	4447, 826, 827, 595, 0, 495, 496, 497, 0, 498,
-	499, 500, 501, 502, 503, 504, 0, 0, 0, 505,
-	506, 507, 508, 0, 0, 0, 0, 0, 828, 509,
-	596, 510, 829, 830, 0, 831, 0, 511, 512, 515,
-	0, 832, 0, 514, 516, 517, 0, 518, 0, 0,
-	0, 519, 520, 521, 522, 523, 524, 525, 0, 526,
-	528, 527, 0, 530, 833, 529, 0, 531, 532, 0,
-	0, 533, 534, 535, 536, 537, 538, 541, 0, 0,
-	539, 540, 542, 543, 0, 544, 545, 547, 550, 546,
-	548, 549, 551, 552, 565, 566, 553, 554, 555, 556,
-	557, 558, 559, 560, 561, 562, 563, 564, 568, 0,
-	567, 0, 569, 570, 571, 572, 573, 581, 583, 584,
-	579, 580, 582, 585, 586, 588, 589, 576, 577, 578,
-	0, 587, 574, 0, 575, 0, 0, 590, 591, 592,
-	593, 0, 834, 594, 835, 597, 598, 0, 0, 599,
-	0, 600, 0, 0, 602, 603, 604, 0, 0, 605,
-	606, 836, 0, 607, 0, 837, 608, 609, 601, 610,
-	611, 612, 613, 614, 615, 616, 617, 618, 619, 0,
-	620, 621, 838, 622, 623, 624, 839, 625, 626, 627,
-	840, 628, 841, 629, 630, 0, 631, 632, 633, 0,
-	634, 635, 636, 637, 638, 639, 640, 641, 642, 643,
-	842, 644, 645, 647, 646, 648, 649, 0, 650, 0,
-	651, 652, 653, 0, 0, 0, 0, 0, 654, 655,
-	657, 0, 658, 659, 660, 661, 662, 656, 663, 664,
-	665, 666, 667, 668, 669, 0, 671, 672, 670, 673,
-	674, 0, 675, 676, 677, 678, 679, 843, 680, 0,
-	681, 682, 690, 691, 692, 683, 684, 686, 693, 685,
-	694, 695, 696, 697, 699, 698, 0, 701, 702, 700,
-	703, 704, 705, 706, 0, 707, 844, 708, 687, 688,
-	709, 710, 711, 0, 712, 713, 714, 715, 716, 717,
-	718, 719, 720, 845, 0, 721, 0, 722, 723, 724,
-	725, 726, 727, 729, 689, 730, 731, 732, 737, 738,
-	846, 733, 734, 735, 736, 847, 740, 741, 742, 743,
-	0, 744, 745, 0, 739, 728, 0, 746, 747, 748,
-	749, 750, 751, 752, 753, 754, 755, 0, 756, 848,
-	849, 850, 851, 0, 768, 0, 757, 759, 760, 761,
-	762, 852, 763, 853, 0, 764, 765, 766, 767, 758,
-	769, 770, 0, 0, 771, 772, 773, 774, 776, 778,
-	779, 780, 775, 777, 781, 0, 782, 0, 0, 783,
-	784, 785, 854, 855, 856, 0, 787, 788, 786, 789,
-	790, 793, 791, 792, 857, 796, 513, 797, 798, 799,
-	794, 795, 337, 0, 0, 0, 800, 801, 858, 802,
-	803, 804, 0, 0, 0, 0, 0, 0, 0, 345,
-	346, 348, 347, 349, 350, 351, 352, 0, 353, 354,
-	0, 0, 0, 0, 0, 805, 0, 0, 0, 356,
-	0, 355, 0, 357, 358, 359, 0, 360, 361, 362,
-	363, 364, 365, 366, 367, 806, 807, 0, 368, 808,
-	369, 809, 0, 810, 370, 371, 372, 373, 374, 375,
-	376, 377, 378, 379, 0, 0, 0, 380, 811, 812,
-	813, 0, 381, 382, 383, 384, 814, 0, 0, 0,
-	385, 386, 387, 388, 389, 390, 391, 392, 0, 0,
-	394, 395, 396, 393, 397, 398, 0, 399, 0, 400,
-	401, 402, 403, 404, 405, 406, 0, 407, 408, 409,
-	0, 410, 411, 412, 0, 0, 0, 0, 0, 0,
-	0, 413, 414, 415, 416, 417, 0, 418, 420, 421,
-	815, 422, 816, 0, 425, 427, 419, 423, 0, 426,
-	424, 428, 429, 0, 430, 431, 432, 433, 0, 0,
-	434, 435, 436, 0, 437, 438, 440, 439, 0, 441,
-	442, 443, 0, 444, 445, 817, 446, 447, 448, 450,
-	452, 449, 451, 453, 454, 455, 456, 457, 818, 819,
-	458, 459, 0, 0, 0, 0, 0, 0, 0, 460,
-	461, 462, 820, 0, 0, 0, 463, 0, 465, 469,
-	466, 467, 468, 470, 0, 464, 471, 472, 0, 0,
-	473, 474, 475, 821, 822, 476, 477, 478, 479, 480,
-	481, 482, 483, 484, 0, 485, 486, 823, 0, 824,
-	487, 0, 488, 489, 490, 491, 492, 493, 494, 825,
-	826, 827, 595, 0, 495, 496, 497, 0, 498, 499,
-	500, 501, 502, 503, 504, 0, 0, 0, 505, 506,
-	507, 508, 0, 0, 0, 0, 0, 828, 509, 596,
-	510, 829, 830, 0, 831, 0, 511, 512, 515, 0,
-	832, 0, 514, 516, 517, 0, 518, 0, 0, 0,
-	519, 520, 521, 522, 523, 524, 525, 0, 526, 528,
-	527, 0, 530, 833, 529, 0, 531, 532, 0, 0,
-	533, 534, 535, 536, 537, 538, 541, 0, 0, 539,
-	540, 542, 543, 0, 544, 545, 547, 550, 546, 548,
-	549, 551, 552, 565, 566, 553, 554, 555, 556, 557,
-	558, 559, 560, 561, 562, 563, 564, 568, 0, 567,
-	0, 569, 570, 571, 572, 573, 581, 583, 584, 579,
-	580, 582, 585, 586, 588, 589, 576, 577, 578, 0,
-	587, 574, 0, 575, 0, 0, 590, 591, 592, 593,
-	0, 834, 594, 835, 597, 598, 0, 0, 599, 0,
-	600, 0, 0, 602, 603, 604, 0, 0, 605, 606,
-	836, 0, 607, 0, 837, 608, 609, 601, 610, 611,
-	612, 613, 614, 615, 616, 617, 618, 619, 0, 620,
-	621, 838, 622, 623, 624, 839, 625, 626, 627, 840,
-	628, 841, 629, 630, 0, 631, 632, 633, 0, 634,
-	635, 636, 637, 638, 639, 640, 641, 642, 643, 842,
-	644, 645, 647, 646, 648, 649, 0, 650, 0, 651,
-	652, 653, 0, 0, 0, 0, 0, 654, 655, 657,
-	0, 658, 659, 660, 661, 662, 656, 663, 664, 665,
-	666, 667, 668, 669, 0, 671, 672, 670, 673, 674,
-	0, 675, 676, 677, 678, 679, 843, 680, 0, 681,
-	682, 970, 691, 692, 683, 684, 686, 693, 685, 694,
-	695, 696, 697, 699, 698, 0, 701, 702, 700, 703,
-	704, 705, 706, 0, 707, 844, 708, 687, 688, 709,
-	710, 711, 0, 712, 713, 714, 715, 716, 717, 718,
-	719, 720, 845, 0, 721, 0, 722, 723, 724, 725,
-	726, 727, 729, 689, 730, 731, 732, 737, 738, 846,
-	733, 734, 735, 736, 847, 740, 741, 742, 743, 0,
-	744, 745, 0, 739, 728, 0, 746, 747, 748, 749,
-	750, 751, 752, 753, 754, 755, 0, 756, 848, 849,
-	850, 851, 0, 768, 0, 757, 759, 760, 761, 762,
-	852, 763, 853, 0, 764, 765, 766, 767, 758, 769,
-	770, 0, 0, 771, 772, 773, 774, 776, 778, 779,
-	780, 775, 777, 781, 0, 782, 0, 0, 783, 784,
-	785, 854, 855, 856, 0, 787, 788, 786, 789, 790,
-	793, 791, 792, 857, 796, 513, 797, 798, 799, 794,
-	795, 337, 0, 0, 0, 800, 801, 858, 802, 803,
-	804, 0, 0, 0, 0, 0, 0, 0, 345, 346,
-	348, 347, 349, 350, 351, 352, 0, 353, 354, 0,
-	0, 0, 0, 0, 805, 0, 2966, 0, 356, 0,
-	355, 0, 357, 358, 359, 0, 360, 361, 362, 363,
-	364, 365, 366, 367, 806, 807, 0, 368, 808, 369,
-	809, 0, 810, 370, 371, 372, 373, 374, 375, 376,
-	377, 378, 379, 0, 0, 0, 380, 811, 812, 813,
-	0, 381, 382, 383, 384, 814, 0, 0, 0, 385,
-	386, 387, 388, 389, 390, 391, 392, 0, 0, 394,
-	395, 396, 393, 397, 398, 0, 399, 0, 400, 401,
-	402, 403, 404, 405, 406, 0, 407, 408, 409, 0,
-	410, 411, 412, 0, 0, 0, 0, 0, 0, 0,
-	413, 414, 415, 416, 417, 0, 418, 420, 421, 815,
-	422, 816, 0, 425, 427, 419, 423, 0, 426, 424,
-	428, 429, 0, 430, 431, 432, 433, 0, 0, 434,
-	435, 436, 0, 437, 438, 440, 439, 0, 441, 442,
-	443, 0, 444, 445, 817, 446, 447, 448, 450, 452,
-	449, 451, 453, 454, 455, 456, 457, 818, 819, 458,
-	459, 0, 0, 0, 0, 0, 0, 0, 460, 461,
-	462, 820, 0, 0, 0, 463, 0, 465, 469, 466,
-	467, 468, 470, 0, 464, 471, 472, 0, 0, 473,
-	474, 475, 821, 822, 476, 477, 478, 479, 480, 481,
-	482, 483, 484, 0, 485, 486, 823, 0, 824, 487,
-	0, 488, 489, 490, 491, 492, 493, 494, 825, 826,
-	827, 595, 0, 495, 496, 497, 0, 498, 499, 500,
-	501, 502, 503, 504, 0, 0, 0, 505, 506, 507,
-	508, 0, 0, 0, 0, 0, 828, 509, 596, 510,
-	829, 830, 0, 831, 0, 511, 512, 515, 0, 832,
-	0, 514, 516, 517, 0, 518, 0, 0, 0, 519,
-	520, 521, 522, 523, 524, 525, 0, 526, 528, 527,
-	0, 530, 833, 529, 0, 531, 532, 0, 0, 533,
-	534, 535, 536, 537, 538, 541, 0, 0, 539, 540,
-	542, 543, 0, 544, 545, 547, 550, 546, 548, 549,
-	551, 552, 565, 566, 553, 554, 555, 556, 557, 558,
-	559, 560, 561, 562, 563, 564, 568, 0, 567, 0,
-	569, 570, 571, 572, 573, 581, 583, 584, 579, 580,
-	582, 585, 586, 588, 589, 576, 577, 578, 0, 587,
-	574, 0, 575, 0, 0, 590, 591, 592, 593, 0,
-	834, 594, 835, 597, 598, 0, 0, 599, 0, 600,
-	0, 0, 602, 603, 604, 0, 0, 605, 606, 836,
-	0, 607, 0, 837, 608, 609, 601, 610, 611, 612,
-	613, 614, 615, 616, 617, 618, 619, 0, 620, 621,
-	838, 622, 623, 624, 839, 625, 626, 627, 840, 628,
-	841, 629, 630, 0, 631, 632, 633, 0, 634, 635,
-	636, 637, 638, 639, 640, 641, 642, 643, 842, 644,
-	645, 647, 646, 648, 649, 0, 650, 0, 651, 652,
-	653, 0, 0, 0, 0, 0, 654, 655, 657, 0,
-	658, 659, 660, 661, 662, 656, 663, 664, 665, 666,
-	667, 668, 669, 0, 671, 672, 670, 673, 674, 0,
-	675, 676, 677, 678, 679, 843, 680, 0, 681, 682,
-	690, 691, 692, 683, 684, 686, 693, 685, 694, 695,
-	696, 697, 699, 698, 0, 701, 702, 700, 703, 704,
-	705, 706, 0, 0, 844, 708, 687, 688, 709, 710,
-	711, 0, 712, 713, 714, 715, 716, 717, 718, 719,
-	720, 845, 0, 721, 0, 722, 723, 724, 725, 726,
-	727, 729, 689, 730, 731, 732, 737, 738, 846, 733,
-	734, 735, 736, 847, 740, 741, 742, 743, 0, 744,
-	745, 0, 739, 728, 0, 746, 747, 748, 749, 750,
-	751, 752, 753, 754, 755, 0, 756, 848, 849, 850,
-	851, 0, 768, 0, 757, 759, 760, 761, 762, 852,
-	763, 853, 0, 764, 765, 766, 767, 758, 769, 770,
-	0, 0, 771, 772, 773, 774, 776, 778, 779, 780,
-	775, 777, 781, 0, 782, 0, 0, 783, 784, 785,
-	854, 855, 856, 0, 787, 788, 786, 789, 790, 793,
-	791, 792, 857, 796, 513, 797, 798, 799, 794, 795,
-	337, 0, 0, 0, 800, 801, 858, 802, 803, 804,
-	0, 0, 0, 0, 0, 0, 0, 345, 346, 348,
-	347, 349, 350, 351, 352, 0, 353, 354, 0, 0,
-	0, 0, 0, 805, 0, 0, 0, 356, 0, 355,
-	0, 357, 358, 359, 0, 360, 361, 362, 363, 364,
-	365, 366, 367, 806, 807, 0, 368, 808, 369, 809,
-	0, 810, 370, 371, 372, 373, 374, 375, 376, 377,
-	378, 379, 0, 0, 0, 380, 811, 812, 813, 0,
-	381, 382, 383, 384, 814, 0, 0, 0, 385, 386,
-	387, 388, 389, 390, 391, 392, 0, 0, 394, 395,
-	396, 393, 397, 398, 0, 399, 0, 400, 401, 402,
-	403, 404, 405, 406, 0, 407, 408, 409, 0, 410,
-	411, 412, 0, 0, 0, 0, 0, 0, 0, 413,
-	414, 415, 416, 417, 0, 418, 420, 421, 815, 422,
-	816, 0, 425, 427, 419, 423, 0, 426, 424, 428,
-	429, 0, 430, 431, 432, 433, 0, 0, 434, 435,
-	436, 0, 437, 438, 440, 439, 0, 441, 442, 443,
-	0, 444, 445, 817, 446, 2640, 448, 450, 452, 449,
-	451, 453, 454, 455, 456, 457, 818, 819, 458, 459,
-	0, 0, 0, 0, 0, 0, 0, 460, 461, 462,
-	820, 0, 0, 0, 463, 0, 465, 469, 466, 467,
-	468, 470, 0, 464, 471, 472, 0, 0, 473, 474,
-	475, 821, 822, 476, 477, 478, 479, 480, 481, 482,
-	483, 484, 0, 485, 486, 823, 0, 824, 487, 0,
-	488, 489, 490, 491, 492, 493, 494, 825, 826, 827,
-	595, 0, 495, 496, 497, 0, 498, 499, 500, 501,
-	502, 503, 504, 0, 0, 0, 505, 506, 507, 508,
-	0, 0, 0, 0, 0, 828, 509, 596, 510, 829,
-	830, 0, 831, 0, 511, 512, 515, 0, 832, 0,
-	514, 516, 517, 0, 518, 0, 0, 0, 519, 520,
-	521, 522, 523, 524, 525, 0, 526, 528, 527, 0,
-	530, 833, 529, 0, 531, 532, 0, 0, 533, 534,
-	535, 536, 537, 538, 541, 0, 0, 539, 540, 542,
-	543, 0, 544, 545, 547, 550, 546, 548, 549, 551,
-	552, 565, 566, 553, 554, 555, 556, 557, 558, 559,
-	560, 561, 562, 563, 564, 568, 0, 567, 0, 569,
-	570, 571, 572, 573, 581, 583, 584, 579, 580, 582,
-	585, 586, 588, 589, 576, 577, 578, 0, 587, 574,
-	0, 575, 0, 0, 590, 591, 592, 593, 0, 834,
-	594, 835, 597, 598, 0, 0, 599, 0, 600, 0,
-	0, 602, 603, 604, 0, 0, 605, 606, 836, 0,
-	607, 0, 837, 608, 609, 601, 610, 611, 612, 613,
-	614, 615, 616, 617, 618, 619, 0, 620, 621, 838,
-	622, 623, 624, 839, 625, 626, 627, 840, 628, 841,
-	629, 630, 0, 631, 632, 633, 0, 634, 635, 636,
-	637, 638, 639, 640, 641, 642, 643, 842, 644, 645,
-	1501, 646, 648, 649, 0, 650, 0, 651, 652, 653,
-	0, 0, 0, 0, 0, 654, 655, 657, 0, 658,
-	659, 660, 661, 662, 656, 663, 664, 665, 666, 667,
-	668, 669, 0, 671, 672, 670, 673, 674, 0, 675,
-	676, 677, 678, 679, 843, 680, 0, 681, 682, 690,
-	691, 692, 683, 684, 686, 693, 685, 694, 695, 696,
-	697, 699, 698, 0, 701, 702, 700, 703, 704, 705,
-	706, 0, 707, 844, 708, 687, 688, 709, 710, 711,
-	0, 712, 713, 714, 715, 716, 717, 718, 719, 720,
-	845, 0, 721, 0, 722, 723, 724, 725, 726, 727,
-	729, 689, 730, 731, 732, 737, 738, 846, 733, 734,
-	735, 736, 847, 740, 741, 742, 743, 0, 744, 745,
-	0, 739, 728, 0, 746, 747, 748, 749, 750, 751,
-	752, 753, 754, 755, 0, 756, 848, 849, 850, 851,
-	0, 768, 0, 757, 759, 760, 761, 762, 852, 763,
-	853, 0, 764, 765, 766, 767, 758, 769, 770, 0,
-	0, 771, 772, 773, 774, 776, 778, 779, 780, 775,
-	777, 781, 0, 782, 0, 0, 783, 784, 785, 854,
-	855, 856, 0, 787, 788, 786, 789, 790, 793, 791,
-	792, 857, 796, 513, 797, 798, 799, 794, 795, 337,
-	0, 0, 0, 800, 801, 858, 802, 803, 804, 0,
-	0, 0, 0, 0, 0, 0, 345, 346, 348, 347,
-	349, 350, 351, 352, 0, 353, 354, 0, 0, 0,
-	0, 0, 805, 0, 0, 0, 356, 0, 355, 0,
-	357, 358, 359, 0, 360, 361, 362, 363, 364, 365,
-	366, 367, 806, 807, 0, 368, 808, 369, 809, 0,
-	810, 370, 371, 372, 373, 374, 375, 376, 377, 378,
-	379, 0, 0, 0, 380, 811, 812, 813, 0, 381,
-	382, 383, 384, 814, 0, 0, 0, 385, 386, 387,
-	388, 389, 390, 391, 392, 0, 0, 394, 395, 396,
-	393, 397, 398, 0, 399, 0, 400, 401, 402, 403,
-	404, 405, 406, 0, 407, 408, 409, 0, 410, 411,
-	412, 0, 0, 0, 0, 0, 0, 0, 413, 414,
-	415, 416, 417, 0, 418, 420, 421, 815, 422, 816,
-	0, 425, 427, 419, 423, 0, 426, 424, 428, 429,
-	0, 430, 431, 432, 433, 0, 0, 434, 435, 436,
-	0, 437, 438, 440, 439, 0, 441, 442, 443, 0,
-	444, 445, 817, 446, 447, 448, 450, 452, 449, 451,
-	453, 454, 455, 456, 457, 818, 819, 458, 459, 0,
-	0, 0, 0, 0, 0, 0, 460, 461, 462, 820,
-	0, 0, 0, 463, 0, 465, 469, 466, 467, 468,
-	470, 0, 464, 471, 472, 0, 0, 473, 474, 475,
-	821, 822, 476, 477, 478, 479, 480, 481, 482, 483,
-	484, 0, 485, 486, 823, 0, 824, 487, 0, 488,
-	489, 490, 491, 492, 493, 494, 1588, 826, 827, 595,
-	0, 495, 496, 497, 0, 498, 499, 500, 501, 502,
-	503, 504, 0, 0, 0, 505, 506, 507, 508, 0,
-	0, 0, 0, 0, 828, 509, 596, 510, 829, 830,
-	0, 831, 0, 511, 512, 515, 0, 832, 0, 514,
-	516, 517, 0, 518, 0, 0, 0, 519, 520, 521,
-	522, 523, 524, 525, 0, 526, 528, 527, 0, 530,
-	833, 529, 0, 531, 532, 0, 0, 533, 534, 535,
-	536, 537, 538, 541, 0, 0, 539, 540, 542, 543,
-	0, 544, 545, 547, 550, 546, 548, 549, 551, 552,
-	565, 566, 553, 554, 555, 556, 557, 558, 559, 560,
-	561, 562, 563, 564, 568, 0, 567, 0, 569, 570,
-	571, 572, 573, 581, 583, 584, 579, 580, 582, 585,
-	586, 588, 589, 576, 577, 578, 0, 587, 574, 0,
-	575, 0, 0, 590, 591, 592, 593, 0, 834, 594,
-	835, 597, 598, 0, 0, 599, 0, 600, 0, 0,
-	602, 603, 604, 0, 0, 605, 606, 836, 0, 607,
-	0, 837, 608, 609, 601, 610, 611, 612, 613, 614,
-	615, 616, 617, 618, 619, 0, 620, 621, 838, 622,
-	623, 624, 839, 625, 626, 627, 840, 628, 841, 629,
-	630, 0, 631, 632, 633, 0, 634, 635, 636, 637,
-	638, 639, 640, 641, 642, 643, 842, 644, 645, 647,
-	646, 648, 649, 0, 650, 0, 651, 652, 653, 0,
-	0, 0, 0, 0, 654, 655, 657, 0, 658, 659,
-	660, 661, 662, 656, 663, 664, 665, 666, 667, 668,
-	669, 0, 671, 672, 670, 673, 674, 0, 675, 676,
-	677, 678, 679, 843, 680, 0, 681, 682, 690, 691,
-	692, 683, 684, 686, 693, 685, 694, 695, 696, 697,
-	699, 698, 0, 701, 702, 700, 703, 704, 705, 706,
-	0, 707, 844, 708, 687, 688, 709, 710, 711, 0,
-	712, 713, 714, 715, 716, 717, 718, 719, 720, 845,
-	0, 721, 0, 722, 723, 724, 725, 726, 727, 729,
-	689, 730, 731, 732, 737, 738, 846, 733, 734, 735,
-	736, 847, 740, 741, 742, 743, 0, 744, 745, 0,
-	739, 728, 0, 746, 747, 748, 749, 750, 751, 752,
-	753, 754, 755, 0, 756, 848, 849, 850, 851, 0,
-	768, 0, 757, 759, 760, 761, 762, 852, 763, 853,
-	0, 764, 765, 766, 767, 758, 769, 770, 0, 0,
-	771, 772, 773, 774, 776, 778, 779, 780, 775, 777,
-	781, 0, 782, 0, 0, 783, 784, 785, 854, 855,
-	856, 0, 787, 788, 786, 789, 790, 793, 791, 792,
-	857, 796, 513, 797, 798, 799, 794, 795, 337, 0,
-	0, 0, 800, 801, 858, 802, 803, 804, 0, 0,
-	0, 0, 0, 0, 0, 345, 346, 348, 347, 349,
-	350, 351, 352, 0, 353, 354, 0, 0, 0, 0,
-	0, 805, 0, 0, 0, 356, 0, 355, 0, 357,
-	358, 359, 0, 360, 361, 362, 363, 364, 365, 366,
-	367, 806, 807, 0, 368, 808, 369, 809, 0, 810,
-	370, 371, 372, 373, 374, 375, 376, 377, 378, 379,
-	0, 0, 0, 380, 811, 812, 813, 0, 381, 382,
-	383, 384, 814, 0, 0, 0, 385, 386, 387, 388,
-	389, 390, 391, 392, 0, 0, 394, 395, 396, 393,
-	397, 398, 0, 399, 0, 400, 401, 402, 403, 404,
-	405, 406, 0, 407, 408, 409, 0, 410, 411, 412,
-	0, 0, 0, 0, 0, 0, 0, 413, 414, 415,
-	416, 417, 0, 418, 420, 421, 815, 422, 816, 0,
-	425, 427, 419, 423, 0, 426, 424, 428, 429, 0,
-	430, 431, 432, 433, 0, 0, 434, 435, 436, 0,
-	437, 438, 440, 439, 0, 441, 442, 443, 0, 444,
-	445, 817, 446, 447, 448, 450, 452, 449, 451, 453,
-	454, 455, 456, 457, 818, 819, 458, 459, 0, 0,
-	0, 0, 0, 0, 0, 460, 461, 462, 820, 0,
-	0, 0, 463, 0, 465, 469, 466, 467, 468, 470,
-	0, 464, 471, 472, 0, 0, 473, 474, 475, 821,
-	822, 476, 477, 478, 479, 480, 481, 482, 483, 484,
-	0, 485, 486, 823, 0, 824, 487, 0, 488, 489,
-	490, 491, 492, 493, 494, 825, 826, 827, 595, 0,
-	495, 496, 497, 0, 498, 499, 500, 501, 502, 503,
-	504, 0, 0, 0, 505, 506, 507, 508, 0, 0,
-	0, 0, 0, 828, 509, 596, 510, 829, 830, 0,
-	831, 0, 511, 512, 515, 0, 832, 0, 514, 516,
-	517, 0, 518, 0, 0, 0, 519, 520, 521, 522,
-	523, 524, 525, 0, 526, 528, 527, 0, 530, 833,
-	529, 0, 531, 532, 0, 0, 533, 534, 535, 536,
-	537, 538, 541, 0, 0, 539, 540, 542, 543, 0,
-	544, 545, 547, 550, 546, 548, 549, 551, 552, 565,
-	566, 553, 554, 555, 556, 557, 558, 559, 560, 561,
-	562, 563, 564, 568, 0, 567, 0, 569, 570, 571,
-	572, 573, 581, 583, 584, 579, 580, 582, 585, 586,
-	588, 589, 576, 577, 578, 0, 587, 574, 0, 575,
-	0, 0, 590, 591, 592, 593, 0, 834, 594, 835,
-	597, 598, 0, 0, 599, 0, 600, 0, 0, 602,
-	603, 604, 0, 0, 605, 606, 836, 0, 607, 0,
-	837, 608, 609, 601, 610, 611, 612, 613, 614, 615,
-	616, 617, 618, 619, 0, 620, 621, 838, 622, 623,
-	624, 839, 625, 626, 627, 840, 628, 841, 629, 630,
-	0, 631, 632, 633, 0, 634, 635, 636, 637, 638,
-	639, 640, 641, 642, 643, 842, 644, 645, 1501, 646,
-	648, 649, 0, 650, 0, 651, 652, 653, 0, 0,
-	0, 0, 0, 654, 655, 657, 0, 658, 659, 660,
-	661, 662, 656, 663, 664, 665, 666, 667, 668, 669,
-	0, 671, 672, 670, 673, 674, 0, 675, 676, 677,
-	678, 679, 843, 680, 0, 681, 682, 690, 691, 692,
-	683, 684, 686, 693, 685, 694, 695, 696, 697, 699,
-	698, 0, 701, 702, 700, 703, 704, 705, 706, 0,
-	707, 844, 708, 687, 688, 709, 710, 711, 0, 712,
-	713, 714, 715, 716, 717, 718, 719, 720, 845, 0,
-	721, 0, 722, 723, 724, 725, 726, 727, 729, 689,
-	730, 731, 732, 737, 738, 846, 733, 734, 735, 736,
-	847, 740, 741, 742, 743, 0, 744, 745, 0, 739,
-	728, 0, 746, 747, 748, 749, 750, 751, 752, 753,
-	754, 755, 0, 756, 848, 849, 850, 851, 0, 768,
-	0, 757, 759, 760, 761, 762, 852, 763, 853, 0,
-	764, 765, 766, 767, 758, 769, 770, 0, 0, 771,
-	772, 773, 774, 776, 778, 779, 780, 775, 777, 781,
-	0, 782, 0, 0, 783, 784, 785, 854, 855, 856,
-	0, 787, 788, 786, 789, 790, 793, 791, 792, 857,
-	796, 513, 797, 798, 799, 794, 795, 337, 0, 0,
-	0, 800, 801, 858, 802, 803, 804, 0, 0, 0,
-	0, 0, 0, 0, 345, 346, 348, 347, 349, 350,
-	351, 352, 0, 353, 354, 0, 0, 0, 0, 0,
-	805, 0, 0, 0, 356, 0, 355, 0, 357, 358,
-	359, 0, 360, 361, 362, 363, 364, 365, 366, 367,
-	806, 807, 0, 368, 808, 369, 809, 0, 810, 370,
-	371, 372, 373, 374, 375, 376, 377, 378, 379, 0,
-	0, 0, 380, 811, 812, 813, 0, 381, 382, 383,
-	384, 814, 0, 0, 0, 385, 386, 387, 388, 389,
-	390, 391, 392, 0, 0, 394, 395, 396, 393, 397,
-	398, 0, 399, 0, 400, 401, 402, 403, 404, 405,
-	406, 0, 407, 408, 409, 0, 410, 411, 412, 0,
-	0, 0, 0, 0, 0, 0, 413, 414, 415, 416,
-	417, 0, 418, 420, 421, 815, 422, 816, 0, 425,
-	427, 419, 423, 0, 426, 424, 428, 429, 0, 430,
-	431, 432, 433, 0, 0, 434, 435, 436, 0, 437,
-	438, 440, 439, 0, 441, 442, 443, 0, 444, 445,
-	817, 446, 447, 448, 450, 452, 449, 451, 453, 454,
-	455, 456, 457, 818, 819, 458, 459, 0, 0, 0,
-	0, 0, 0, 0, 460, 461, 462, 820, 0, 0,
-	0, 463, 0, 465, 469, 466, 467, 468, 470, 0,
-	464, 471, 472, 0, 0, 473, 474, 475, 821, 822,
-	476, 477, 478, 479, 480, 481, 482, 483, 484, 0,
-	485, 486, 823, 0, 824, 0, 0, 488, 489, 490,
-	491, 492, 493, 494, 825, 826, 827, 595, 0, 495,
-	496, 497, 0, 498, 499, 500, 501, 502, 503, 504,
-	0, 0, 0, 505, 506, 507, 508, 0, 0, 0,
-	0, 0, 828, 509, 596, 510, 829, 830, 0, 831,
-	0, 511, 512, 515, 0, 832, 0, 514, 516, 517,
-	0, 518, 0, 0, 0, 519, 520, 521, 522, 523,
-	524, 525, 0, 526, 528, 527, 0, 530, 833, 529,
-	0, 531, 532, 0, 0, 533, 534, 535, 536, 537,
-	538, 541, 0, 0, 539, 540, 542, 543, 0, 544,
-	545, 547, 550, 546, 548, 549, 551, 552, 565, 566,
-	553, 554, 555, 556, 557, 558, 559, 560, 561, 562,
-	563, 564, 568, 0, 567, 0, 569, 570, 571, 572,
-	573, 581, 583, 584, 579, 580, 582, 585, 586, 588,
-	589, 576, 577, 578, 0, 587, 574, 0, 575, 0,
-	0, 590, 591, 592, 593, 0, 834, 594, 835, 597,
-	598, 0, 0, 599, 0, 600, 0, 0, 602, 603,
-	604, 0, 0, 605, 606, 836, 0, 607, 0, 837,
-	608, 609, 601, 610, 611, 612, 0, 614, 615, 616,
-	617, 618, 619, 0, 620, 621, 838, 622, 623, 624,
-	839, 625, 626, 627, 840, 628, 841, 629, 630, 0,
-	631, 632, 633, 0, 634, 635, 636, 637, 638, 639,
-	640, 0, 642, 643, 842, 644, 645, 647, 646, 648,
-	649, 0, 650, 0, 651, 652, 653, 0, 0, 0,
-	0, 0, 654, 655, 657, 0, 658, 659, 660, 661,
-	662, 656, 663, 664, 665, 666, 667, 668, 669, 0,
-	671, 672, 670, 673, 674, 0, 675, 676, 677, 678,
-	679, 843, 0, 0, 681, 682, 690, 691, 692, 683,
-	684, 686, 693, 685, 694, 695, 696, 697, 699, 698,
-	0, 701, 702, 700, 703, 704, 705, 706, 0, 707,
-	844, 708, 687, 688, 709, 710, 711, 0, 712, 713,
-	714, 715, 716, 717, 718, 719, 720, 845, 0, 721,
-	0, 722, 723, 724, 725, 726, 727, 729, 689, 730,
-	731, 732, 737, 738, 846, 733, 734, 735, 736, 847,
-	740, 741, 742, 743, 0, 744, 745, 0, 739, 728,
-	0, 746, 747, 748, 749, 750, 751, 752, 753, 754,
-	755, 0, 756, 848, 849, 850, 851, 0, 768, 0,
-	757, 759, 760, 761, 762, 852, 763, 853, 0, 764,
-	765, 766, 767, 758, 769, 770, 0, 0, 771, 772,
-	773, 774, 776, 778, 779, 780, 775, 777, 781, 0,
-	782, 0, 0, 783, 784, 785, 854, 855, 856, 0,
-	787, 788, 786, 789, 790, 793, 791, 792, 857, 796,
-	513, 797, 798, 799, 794, 795, 2080, 0, 1640, 0,
-	800, 801, 858, 802, 803, 804, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 345, 346, 348, 347, 349,
-	350, 351, 352, 0, 353, 354, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 356, 0, 355, 0, 357,
-	358, 359, 0, 360, 361, 362, 363, 364, 365, 366,
-	367, 0, 0, 0, 368, 0, 369, 0, 0, 0,
-	370, 371, 372, 373, 374, 375, 376, 377, 378, 379,
-	0, 0, 0, 380, 0, 0, 0, 0, 381, 382,
-	383, 384, 0, 0, 0, 0, 385, 386, 387, 388,
-	389, 390, 391, 392, 0, 0, 394, 395, 396, 393,
-	397, 398, 0, 399, 0, 400, 401, 402, 403, 404,
-	405, 406, 0, 407, 408, 409, 0, 410, 411, 412,
-	0, 0, 0, 0, 0, 0, 1642, 413, 414, 415,
-	416, 417, 0, 418, 420, 421, 0, 422, 0, 0,
-	425, 427, 419, 423, 0, 426, 424, 428, 429, 0,
-	430, 431, 432, 433, 0, 0, 434, 435, 436, 0,
-	437, 438, 440, 439, 0, 441, 442, 443, 0, 444,
-	445, 0, 446, 447, 448, 450, 452, 449, 451, 453,
-	454, 455, 456, 457, 0, 0, 458, 459, 0, 0,
-	0, 0, 0, 0, 0, 460, 461, 462, 0, 0,
-	0, 0, 463, 0, 465, 469, 466, 467, 468, 470,
-	0, 464, 471, 472, 0, 0, 473, 474, 475, 0,
-	0, 476, 477, 478, 479, 480, 481, 482, 483, 484,
-	0, 485, 486, 0, 0, 0, 487, 0, 488, 489,
-	490, 491, 492, 493, 494, 2079, 0, 0, 595, 0,
-	495, 496, 497, 0, 498, 499, 500, 501, 502, 503,
-	504, 0, 0, 0, 505, 506, 507, 508, 0, 0,
-	0, 0, 0, 0, 509, 596, 510, 0, 0, 0,
-	0, 0, 511, 512, 515, 0, 0, 0, 514, 516,
-	517, 0, 518, 0, 0, 0, 519, 520, 521, 522,
-	523, 524, 525, 0, 526, 528, 527, 0, 530, 0,
-	529, 0, 531, 532, 0, 0, 533, 534, 535, 536,
-	537, 538, 541, 0, 0, 539, 540, 542, 543, 0,
-	544, 545, 547, 550, 546, 548, 549, 551, 552, 565,
-	566, 553, 554, 555, 556, 557, 558, 559, 560, 561,
-	562, 563, 564, 568, 0, 567, 0, 569, 570, 571,
-	572, 573, 581, 583, 584, 579, 580, 582, 585, 586,
-	588, 589, 576, 577, 578, 0, 587, 574, 0, 575,
-	0, 0, 590, 591, 592, 593, 0, 0, 594, 0,
-	597, 598, 0, 0, 599, 0, 600, 0, 0, 602,
-	603, 604, 0, 0, 605, 606, 0, 0, 607, 0,
-	0, 608, 609, 601, 610, 611, 612, 613, 614, 615,
-	616, 617, 618, 619, 0, 620, 621, 0, 622, 623,
-	624, 0, 625, 626, 627, 0, 628, 0, 629, 630,
-	0, 631, 632, 633, 0, 634, 635, 636, 637, 638,
-	639, 640, 641, 642, 643, 0, 644, 645, 647, 646,
-	648, 649, 0, 650, 0, 651, 652, 653, 0, 0,
-	0, 0, 0, 654, 655, 657, 0, 658, 659, 660,
-	661, 662, 656, 663, 664, 665, 666, 667, 668, 669,
-	0, 671, 672, 670, 673, 674, 0, 675, 676, 677,
-	678, 679, 0, 680, 0, 681, 682, 690, 691, 692,
-	683, 684, 686, 693, 685, 694, 695, 696, 697, 699,
-	698, 0, 701, 702, 700, 703, 704, 705, 706, 1643,
-	707, 0, 708, 687, 688, 709, 710, 711, 0, 712,
-	713, 714, 715, 716, 717, 718, 719, 720, 0, 0,
-	721, 0, 722, 723, 724, 725, 726, 727, 729, 689,
-	730, 731, 732, 737, 738, 0, 733, 734, 735, 736,
-	0, 740, 741, 742, 743, 0, 744, 745, 0, 739,
-	728, 0, 746, 747, 748, 749, 750, 751, 752, 753,
-	754, 755, 0, 756, 0, 0, 0, 0, 0, 768,
-	0, 757, 759, 760, 761, 762, 0, 763, 0, 0,
-	764, 765, 766, 767, 758, 769, 770, 0, 0, 771,
-	772, 773, 774, 776, 778, 779, 780, 775, 777, 781,
-	0, 782, 0, 0, 783, 784, 785, 0, 0, 0,
-	0, 787, 788, 786, 789, 790, 793, 791, 792, 0,
-	796, 513, 797, 798, 799, 794, 795, 1996, 0, 1640,
-	0, 800, 801, 0, 802, 803, 804, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 345, 346, 348, 347,
-	349, 350, 351, 352, 0, 353, 354, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 356, 0, 355, 0,
-	357, 358, 359, 0, 360, 361, 362, 363, 364, 365,
-	366, 367, 0, 0, 0, 368, 0, 369, 0, 0,
-	0, 370, 371, 372, 373, 374, 375, 376, 377, 378,
-	379, 0, 0, 0, 380, 0, 0, 0, 0, 381,
-	382, 383, 384, 0, 0, 0, 0, 385, 386, 387,
-	388, 389, 390, 391, 392, 0, 0, 394, 395, 396,
-	393, 397, 398, 0, 399, 0, 400, 401, 402, 403,
-	404, 405, 406, 0, 407, 408, 409, 0, 410, 411,
-	412, 0, 0, 0, 0, 0, 0, 1642, 413, 414,
-	415, 416, 417, 0, 418, 420, 421, 0, 422, 0,
-	0, 425, 427, 419, 423, 0, 426, 424, 428, 429,
-	0, 430, 431, 432, 433, 0, 0, 434, 435, 436,
-	0, 437, 438, 440, 439, 0, 441, 442, 443, 0,
-	444, 445, 0, 446, 447, 448, 450, 452, 449, 451,
-	453, 454, 455, 456, 457, 0, 0, 458, 459, 0,
-	0, 0, 0, 0, 0, 0, 460, 461, 462, 0,
-	0, 0, 0, 463, 0, 465, 469, 466, 467, 468,
-	470, 0, 464, 471, 472, 0, 0, 473, 474, 475,
-	0, 0, 476, 477, 478, 479, 480, 481, 482, 483,
-	484, 0, 485, 486, 0, 0, 0, 487, 0, 488,
-	489, 490, 491, 492, 493, 494, 1995, 0, 0, 595,
-	0, 495, 496, 497, 0, 498, 499, 500, 501, 502,
-	503, 504, 0, 0, 0, 505, 506, 507, 508, 0,
-	0, 0, 0, 0, 0, 509, 596, 510, 0, 0,
-	0, 0, 0, 511, 512, 515, 0, 0, 0, 514,
-	516, 517, 0, 518, 0, 0, 0, 519, 520, 521,
-	522, 523, 524, 525, 0, 526, 528, 527, 0, 530,
-	0, 529, 0, 531, 532, 0, 0, 533, 534, 535,
-	536, 537, 538, 541, 0, 0, 539, 540, 542, 543,
-	0, 544, 545, 547, 550, 546, 548, 549, 551, 552,
-	565, 566, 553, 554, 555, 556, 557, 558, 559, 560,
-	561, 562, 563, 564, 568, 0, 567, 0, 569, 570,
-	571, 572, 573, 581, 583, 584, 579, 580, 582, 585,
-	586, 588, 589, 576, 577, 578, 0, 587, 574, 0,
-	575, 0, 0, 590, 591, 592, 593, 0, 0, 594,
-	0, 597, 598, 0, 0, 599, 0, 600, 0, 0,
-	602, 603, 604, 0, 0, 605, 606, 0, 0, 607,
-	0, 0, 608, 609, 601, 610, 611, 612, 613, 614,
-	615, 616, 617, 618, 619, 0, 620, 621, 0, 622,
-	623, 624, 0, 625, 626, 627, 0, 628, 0, 629,
-	630, 0, 631, 632, 633, 0, 634, 635, 636, 637,
-	638, 639, 640, 641, 642, 643, 0, 644, 645, 647,
-	646, 648, 649, 0, 650, 0, 651, 652, 653, 0,
-	0, 0, 0, 0, 654, 655, 657, 0, 658, 659,
-	660, 661, 662, 656, 663, 664, 665, 666, 667, 668,
-	669, 0, 671, 672, 670, 673, 674, 0, 675, 676,
-	677, 678, 679, 0, 680, 0, 681, 682, 690, 691,
-	692, 683, 684, 686, 693, 685, 694, 695, 696, 697,
-	699, 698, 0, 701, 702, 700, 703, 704, 705, 706,
-	1643, 707, 0, 708, 687, 688, 709, 710, 711, 0,
-	712, 713, 714, 715, 716, 717, 718, 719, 720, 0,
-	0, 721, 0, 722, 723, 724, 725, 726, 727, 729,
-	689, 730, 731, 732, 737, 738, 0, 733, 734, 735,
-	736, 0, 740, 741, 742, 743, 0, 744, 745, 0,
-	739, 728, 0, 746, 747, 748, 749, 750, 751, 752,
-	753, 754, 755, 0, 756, 0, 0, 0, 0, 0,
-	768, 0, 757, 759, 760, 761, 762, 0, 763, 0,
-	0, 764, 765, 766, 767, 758, 769, 770, 0, 0,
-	771, 772, 773, 774, 776, 778, 779, 780, 775, 777,
-	781, 0, 782, 0, 0, 783, 784, 785, 0, 0,
-	0, 0, 787, 788, 786, 789, 790, 793, 791, 792,
-	0, 796, 513, 797, 798, 799, 794, 795, 1638, 0,
-	1640, 0, 800, 801, 0, 802, 803, 804, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 345, 346, 348,
-	347, 349, 350, 351, 352, 0, 353, 354, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 356, 0, 355,
-	0, 357, 358, 359, 0, 360, 361, 362, 363, 364,
-	365, 366, 367, 0, 0, 0, 368, 0, 369, 0,
-	0, 0, 370, 371, 372, 373, 374, 375, 376, 377,
-	378, 379, 0, 0, 0, 380, 0, 0, 0, 0,
-	381, 382, 383, 384, 0, 0, 0, 0, 385, 386,
-	387, 388, 389, 390, 391, 392, 0, 0, 394, 395,
-	396, 393, 397, 398, 0, 399, 0, 400, 401, 402,
-	403, 404, 405, 406, 0, 407, 408, 409, 0, 410,
-	411, 412, 0, 0, 0, 0, 0, 0, 1642, 413,
-	414, 415, 416, 417, 0, 418, 420, 421, 0, 422,
-	0, 0, 425, 427, 419, 423, 0, 426, 424, 428,
-	429, 0, 430, 431, 432, 433, 0, 0, 434, 435,
-	436, 0, 437, 438, 440, 439, 0, 441, 442, 443,
-	0, 444, 445, 0, 446, 447, 448, 450, 452, 449,
-	451, 453, 454, 455, 456, 457, 0, 0, 458, 459,
-	0, 0, 0, 0, 0, 0, 0, 460, 461, 462,
-	0, 0, 0, 0, 463, 0, 465, 469, 466, 467,
-	468, 470, 0, 464, 471, 472, 0, 0, 473, 474,
-	475, 0, 0, 476, 477, 478, 479, 480, 481, 482,
-	483, 484, 0, 485, 486, 0, 0, 0, 487, 0,
-	488, 489, 490, 491, 492, 493, 494, 1637, 0, 0,
-	595, 0, 495, 496, 497, 0, 498, 499, 500, 501,
-	502, 503, 504, 0, 0, 0, 505, 506, 507, 508,
-	0, 0, 0, 0, 0, 0, 509, 596, 510, 0,
-	0, 0, 0, 0, 511, 512, 515, 0, 0, 0,
-	514, 516, 517, 0, 518, 0, 0, 0, 519, 520,
-	521, 522, 523, 524, 525, 0, 526, 528, 527, 0,
-	530, 0, 529, 0, 531, 532, 0, 0, 533, 534,
-	535, 536, 537, 538, 541, 0, 0, 539, 540, 542,
-	543, 0, 544, 545, 547, 550, 546, 548, 549, 551,
-	552, 565, 566, 553, 554, 555, 556, 557, 558, 559,
-	560, 561, 562, 563, 564, 568, 0, 567, 0, 569,
-	570, 571, 572, 573, 581, 583, 584, 579, 580, 582,
-	585, 586, 588, 589, 576, 577, 578, 0, 587, 574,
-	0, 575, 0, 0, 590, 591, 592, 593, 0, 0,
-	594, 0, 597, 598, 0, 0, 599, 0, 600, 0,
-	0, 602, 603, 604, 0, 0, 605, 606, 0, 0,
-	607, 0, 0, 608, 609, 601, 610, 611, 612, 613,
-	614, 615, 616, 617, 618, 619, 0, 620, 621, 0,
-	622, 623, 624, 0, 625, 626, 627, 0, 628, 0,
-	629, 630, 0, 631, 632, 633, 0, 634, 635, 636,
-	637, 638, 639, 640, 641, 642, 643, 0, 644, 645,
-	647, 646, 648, 649, 0, 650, 0, 651, 652, 653,
-	0, 0, 0, 0, 0, 654, 655, 657, 0, 658,
-	659, 660, 661, 662, 656, 663, 664, 665, 666, 667,
-	668, 669, 0, 671, 672, 670, 673, 674, 0, 675,
-	676, 677, 678, 679, 0, 680, 0, 681, 682, 690,
-	691, 692, 683, 684, 686, 693, 685, 694, 695, 696,
-	697, 699, 698, 0, 701, 702, 700, 703, 704, 705,
-	706, 1643, 707, 0, 708, 687, 688, 709, 710, 711,
-	0, 712, 713, 714, 715, 716, 717, 718, 719, 720,
-	0, 0, 721, 0, 722, 723, 724, 725, 726, 727,
-	729, 689, 730, 731, 732, 737, 738, 0, 733, 734,
-	735, 736, 0, 740, 741, 742, 743, 0, 744, 745,
-	0, 739, 728, 0, 746, 747, 748, 749, 750, 751,
-	752, 753, 754, 755, 0, 756, 0, 0, 0, 0,
-	0, 768, 0, 757, 759, 760, 761, 762, 0, 763,
-	0, 0, 764, 765, 766, 767, 758, 769, 770, 0,
-	0, 771, 772, 773, 774, 776, 778, 779, 780, 775,
-	777, 781, 0, 782, 0, 0, 783, 784, 785, 0,
-	0, 0, 0, 787, 788, 786, 789, 790, 793, 791,
-	792, 0, 796, 513, 797, 798, 799, 794, 795, 2528,
-	0, 1640, 0, 800, 801, 0, 802, 803, 804, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 345, 346,
-	348, 347, 349, 350, 351, 352, 0, 353, 354, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 356, 0,
-	355, 0, 357, 358, 359, 0, 360, 361, 362, 363,
-	364, 365, 366, 367, 0, 0, 0, 368, 0, 369,
-	0, 0, 0, 370, 371, 372, 373, 374, 375, 376,
-	377, 378, 379, 0, 0, 0, 380, 0, 0, 0,
-	0, 381, 382, 383, 384, 0, 0, 0, 0, 385,
-	386, 387, 388, 389, 390, 391, 392, 0, 0, 394,
-	395, 396, 393, 397, 398, 0, 399, 0, 400, 401,
-	402, 403, 404, 405, 406, 0, 407, 408, 409, 0,
-	410, 411, 412, 0, 0, 0, 0, 0, 0, 1642,
-	413, 414, 415, 416, 417, 0, 418, 420, 421, 0,
-	422, 0, 0, 425, 427, 419, 423, 0, 426, 424,
-	428, 429, 0, 430, 431, 432, 433, 0, 0, 434,
-	435, 436, 0, 437, 438, 440, 439, 0, 441, 442,
-	443, 0, 444, 445, 0, 446, 447, 448, 450, 452,
-	449, 451, 453, 454, 455, 456, 457, 0, 0, 458,
-	459, 0, 0, 0, 0, 0, 0, 0, 460, 461,
-	462, 0, 0, 0, 0, 463, 0, 465, 469, 466,
-	467, 468, 470, 0, 464, 471, 472, 0, 0, 473,
-	474, 475, 0, 0, 476, 477, 478, 479, 480, 481,
-	482, 483, 484, 0, 485, 486, 0, 0, 0, 487,
-	0, 488, 489, 490, 491, 492, 493, 494, 0, 0,
-	0, 595, 0, 495, 496, 497, 0, 498, 499, 500,
-	501, 502, 503, 504, 0, 0, 0, 505, 506, 507,
-	508, 0, 0, 0, 0, 0, 0, 509, 596, 510,
-	0, 0, 0, 0, 0, 511, 512, 515, 0, 0,
-	0, 514, 516, 517, 0, 518, 0, 0, 0, 519,
-	520, 521, 522, 523, 524, 525, 0, 526, 528, 527,
-	0, 530, 0, 529, 0, 531, 532, 0, 0, 533,
-	534, 535, 536, 537, 538, 541, 0, 0, 539, 540,
-	542, 543, 0, 544, 545, 547, 550, 546, 548, 549,
-	551, 552, 565, 566, 553, 554, 555, 556, 557, 558,
-	559, 560, 561, 562, 563, 564, 568, 0, 567, 0,
-	569, 570, 571, 572, 573, 581, 583, 584, 579, 580,
-	582, 585, 586, 588, 589, 576, 577, 578, 0, 587,
-	574, 0, 575, 0, 0, 590, 591, 592, 593, 0,
-	0, 594, 0, 597, 598, 0, 0, 599, 0, 600,
-	0, 0, 602, 603, 604, 0, 0, 605, 606, 0,
-	0, 607, 0, 0, 608, 609, 601, 610, 611, 612,
-	613, 614, 615, 616, 617, 618, 619, 0, 620, 621,
-	0, 622, 623, 624, 0, 625, 626, 627, 0, 628,
-	0, 629, 630, 0, 631, 632, 633, 0, 634, 635,
-	636, 637, 638, 639, 640, 641, 642, 643, 0, 644,
-	645, 647, 646, 648, 649, 0, 650, 0, 651, 652,
-	653, 0, 0, 0, 0, 0, 654, 655, 657, 0,
-	658, 659, 660, 661, 662, 656, 663, 664, 665, 666,
-	667, 668, 669, 0, 671, 672, 670, 673, 674, 0,
-	675, 676, 677, 678, 679, 0, 680, 0, 681, 682,
-	690, 691, 692, 683, 684, 686, 693, 685, 694, 695,
-	696, 697, 699, 698, 0, 701, 702, 700, 703, 704,
-	705, 706, 1643, 707, 0, 708, 687, 688, 709, 710,
-	711, 0, 712, 713, 714, 715, 716, 717, 718, 719,
-	720, 0, 0, 721, 0, 722, 723, 724, 725, 726,
-	727, 729, 689, 730, 731, 732, 737, 738, 0, 733,
-	734, 735, 736, 0, 740, 741, 742, 743, 0, 744,
-	745, 0, 739, 728, 0, 746, 747, 748, 749, 750,
-	751, 752, 753, 754, 755, 0, 756, 0, 0, 0,
-	0, 0, 768, 0, 757, 759, 760, 761, 762, 0,
-	763, 0, 0, 764, 765, 766, 767, 758, 769, 770,
-	0, 0, 771, 772, 773, 774, 776, 778, 779, 780,
-	775, 777, 781, 0, 782, 0, 0, 783, 784, 785,
-	0, 0, 0, 0, 787, 788, 786, 789, 790, 793,
-	791, 792, 0, 796, 513, 797, 798, 799, 794, 795,
-	2481, 0, 1640, 0, 800, 801, 0, 802, 803, 804,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 345,
-	346, 348, 347, 349, 350, 351, 352, 0, 353, 354,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 356,
-	0, 355, 0, 357, 358, 359, 0, 360, 361, 362,
-	363, 364, 365, 366, 367, 0, 0, 0, 368, 0,
-	369, 0, 0, 0, 370, 371, 372, 373, 374, 375,
-	376, 377, 378, 379, 0, 0, 0, 380, 0, 0,
-	0, 0, 381, 382, 383, 384, 0, 0, 0, 0,
-	385, 386, 387, 388, 389, 390, 391, 392, 0, 0,
-	394, 395, 396, 393, 397, 398, 0, 399, 0, 400,
-	401, 402, 403, 404, 405, 406, 0, 407, 408, 409,
-	0, 410, 411, 412, 0, 0, 0, 0, 0, 0,
-	1642, 413, 414, 415, 416, 417, 0, 418, 420, 421,
-	0, 422, 0, 0, 425, 427, 419, 423, 0, 426,
-	424, 428, 429, 0, 430, 431, 432, 433, 0, 0,
-	434, 435, 436, 0, 437, 438, 440, 439, 0, 441,
-	442, 443, 0, 444, 445, 0, 446, 447, 448, 450,
-	452, 449, 451, 453, 454, 455, 456, 457, 0, 0,
-	458, 459, 0, 0, 0, 0, 0, 0, 0, 460,
-	461, 462, 0, 0, 0, 0, 463, 0, 465, 469,
-	466, 467, 468, 470, 0, 464, 471, 472, 0, 0,
-	473, 474, 475, 0, 0, 476, 477, 478, 479, 480,
-	481, 482, 483, 484, 0, 485, 486, 0, 0, 0,
-	487, 0, 488, 489, 490, 491, 492, 493, 494, 0,
-	0, 0, 595, 0, 495, 496, 497, 0, 498, 499,
-	500, 501, 502, 503, 504, 0, 0, 0, 505, 506,
-	507, 508, 0, 0, 0, 0, 0, 0, 509, 596,
-	510, 0, 0, 0, 0, 0, 511, 512, 515, 0,
-	0, 0, 514, 516, 517, 0, 518, 0, 0, 0,
-	519, 520, 521, 522, 523, 524, 525, 0, 526, 528,
-	527, 0, 530, 0, 529, 0, 531, 532, 0, 0,
-	533, 534, 535, 536, 537, 538, 541, 0, 0, 539,
-	540, 542, 543, 0, 544, 545, 547, 550, 546, 548,
-	549, 551, 552, 565, 566, 553, 554, 555, 556, 557,
-	558, 559, 560, 561, 562, 563, 564, 568, 0, 567,
-	0, 569, 570, 571, 572, 573, 581, 583, 584, 579,
-	580, 582, 585, 586, 588, 589, 576, 577, 578, 0,
-	587, 574, 0, 575, 0, 0, 590, 591, 592, 593,
-	0, 0, 594, 0, 597, 598, 0, 0, 599, 0,
-	600, 0, 0, 602, 603, 604, 0, 0, 605, 606,
-	0, 0, 607, 0, 0, 608, 609, 601, 610, 611,
-	612, 613, 614, 615, 616, 617, 618, 619, 0, 620,
-	621, 0, 622, 623, 624, 0, 625, 626, 627, 0,
-	628, 0, 629, 630, 0, 631, 632, 633, 0, 634,
-	635, 636, 637, 638, 639, 640, 641, 642, 643, 0,
-	644, 645, 647, 646, 648, 649, 0, 650, 0, 651,
-	652, 653, 0, 0, 0, 0, 0, 654, 655, 657,
-	0, 658, 659, 660, 661, 662, 656, 663, 664, 665,
-	666, 667, 668, 669, 0, 671, 672, 670, 673, 674,
-	0, 675, 676, 677, 678, 679, 0, 680, 0, 681,
-	682, 690, 691, 692, 683, 684, 686, 693, 685, 694,
-	695, 696, 697, 699, 698, 0, 701, 702, 700, 703,
-	704, 705, 706, 1643, 707, 0, 708, 687, 688, 709,
-	710, 711, 0, 712, 713, 714, 715, 716, 717, 718,
-	719, 720, 0, 0, 721, 0, 722, 723, 724, 725,
-	726, 727, 729, 689, 730, 731, 732, 737, 738, 0,
-	733, 734, 735, 736, 0, 740, 741, 742, 743, 0,
-	744, 745, 0, 739, 728, 0, 746, 747, 748, 749,
-	750, 751, 752, 753, 754, 755, 0, 756, 0, 0,
-	0, 0, 0, 768, 0, 757, 759, 760, 761, 762,
-	0, 763, 0, 0, 764, 765, 766, 767, 758, 769,
-	770, 0, 0, 771, 772, 773, 774, 776, 778, 779,
-	780, 775, 777, 781, 0, 782, 0, 0, 783, 784,
-	785, 0, 0, 0, 0, 787, 788, 786, 789, 790,
-	793, 791, 792, 0, 796, 513, 797, 798, 799, 794,
-	795, 1640, 0, 0, 0, 800, 801, 0, 802, 803,
-	804, 0, 0, 0, 0, 0, 0, 0, 345, 346,
-	348, 347, 349, 350, 351, 352, 0, 353, 354, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 356, 0,
-	355, 0, 357, 358, 359, 0, 360, 361, 362, 363,
-	364, 365, 366, 367, 0, 0, 0, 368, 0, 369,
-	0, 0, 0, 370, 371, 372, 373, 374, 375, 376,
-	377, 378, 379, 0, 0, 0, 380, 0, 0, 0,
-	0, 381, 382, 383, 384, 0, 0, 0, 0, 385,
-	386, 387, 388, 389, 390, 391, 392, 0, 0, 394,
-	395, 396, 393, 397, 398, 0, 399, 0, 400, 401,
-	402, 403, 404, 405, 406, 0, 407, 408, 409, 0,
-	410, 411, 412, 0, 0, 0, 0, 0, 0, 1642,
-	413, 414, 415, 416, 417, 0, 418, 420, 421, 0,
-	422, 0, 0, 425, 427, 419, 423, 0, 426, 424,
-	428, 429, 0, 430, 431, 432, 433, 0, 0, 434,
-	435, 436, 0, 437, 438, 440, 439, 0, 441, 442,
-	443, 0, 444, 445, 0, 446, 447, 448, 450, 452,
-	449, 451, 453, 454, 455, 456, 457, 0, 0, 458,
-	459, 0, 0, 0, 0, 0, 0, 0, 460, 461,
-	462, 0, 0, 0, 0, 463, 0, 465, 469, 466,
-	467, 468, 470, 0, 464, 471, 472, 0, 0, 473,
-	474, 475, 0, 0, 476, 477, 478, 479, 480, 481,
-	482, 483, 484, 0, 485, 486, 0, 0, 0, 487,
-	0, 488, 489, 490, 491, 492, 493, 494, 0, 0,
-	0, 595, 0, 495, 496, 497, 0, 498, 499, 500,
-	501, 502, 503, 504, 0, 0, 0, 505, 506, 507,
-	508, 0, 0, 0, 0, 0, 0, 509, 596, 510,
-	0, 0, 0, 0, 0, 511, 512, 515, 0, 0,
-	0, 514, 516, 517, 0, 518, 0, 0, 0, 519,
-	520, 521, 522, 523, 524, 525, 0, 526, 528, 527,
-	0, 530, 0, 529, 0, 531, 532, 0, 0, 533,
-	534, 535, 536, 537, 538, 541, 0, 0, 539, 540,
-	542, 543, 0, 544, 545, 547, 550, 546, 548, 549,
-	551, 552, 565, 566, 553, 554, 555, 556, 557, 558,
-	559, 560, 561, 562, 563, 564, 568, 0, 567, 0,
-	569, 570, 571, 572, 573, 581, 583, 584, 579, 580,
-	582, 585, 586, 588, 589, 576, 577, 578, 0, 587,
-	574, 0, 575, 0, 0, 590, 591, 592, 593, 0,
-	0, 594, 0, 597, 598, 0, 0, 599, 0, 600,
-	0, 0, 602, 603, 604, 0, 0, 605, 606, 0,
-	0, 607, 0, 0, 608, 609, 601, 610, 611, 612,
-	613, 614, 615, 616, 617, 618, 619, 0, 620, 621,
-	0, 622, 623, 624, 0, 625, 626, 627, 0, 628,
-	0, 629, 630, 0, 631, 632, 633, 0, 634, 635,
-	636, 637, 638, 639, 640, 641, 642, 643, 0, 644,
-	645, 647, 646, 648, 649, 0, 650, 0, 651, 652,
-	653, 0, 0, 0, 0, 0, 654, 655, 657, 0,
-	658, 659, 660, 661, 662, 656, 663, 664, 665, 666,
-	667, 668, 669, 0, 671, 672, 670, 673, 674, 0,
-	675, 676, 677, 678, 679, 0, 680, 0, 681, 682,
-	690, 691, 692, 683, 684, 686, 693, 685, 694, 695,
-	696, 697, 699, 698, 0, 701, 702, 700, 703, 704,
-	705, 706, 1643, 707, 0, 708, 687, 688, 709, 710,
-	711, 0, 712, 713, 714, 715, 716, 717, 718, 719,
-	720, 0, 0, 721, 0, 722, 723, 724, 725, 726,
-	727, 729, 689, 730, 731, 732, 737, 738, 0, 733,
-	734, 735, 736, 0, 740, 741, 742, 743, 0, 744,
-	745, 0, 739, 728, 0, 746, 747, 748, 749, 750,
-	751, 752, 753, 754, 755, 0, 756, 0, 0, 0,
-	0, 0, 768, 0, 757, 759, 760, 761, 762, 0,
-	763, 0, 0, 764, 765, 766, 767, 758, 769, 770,
-	0, 0, 771, 772, 773, 774, 776, 778, 779, 780,
-	775, 777, 781, 0, 782, 0, 0, 783, 784, 785,
-	0, 0, 0, 0, 787, 788, 786, 789, 790, 793,
-	791, 792, 0, 796, 513, 797, 798, 799, 794, 795,
-	0, 0, 0, 0, 800, 801, 0, 802, 803, 804,
-	2187, 2188, 0, 2221, 2222, 2223, 2232, 2233, 2234, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 2225, 2218, 0, 0, 0, 0, 0,
-	0, 2219, 0, 0, 2190, 0, 0, 2187, 2188, 0,
-	2221, 2222, 2223, 2232, 2233, 2234, 2238, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	2225, 2218, 0, 0, 0, 0, 0, 2244, 2219, 0,
-	0, 2190, 0, 0, 0, 0, 0, 0, 2189, 0,
-	0, 0, 0, 2238, 0, 0, 0, 0, 0, 2209,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 2206,
-	0, 0, 0, 0, 2244, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 2189, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 2209, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 2206, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 2187, 2188, 0, 2221, 2222, 2223, 2232, 2233, 2234,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 2225, 2218, 2212, 2213, 2214, 2215,
-	0, 0, 2219, 0, 0, 2190, 2195, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 2238, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 2212, 2213, 2214, 2215, 0, 2244, 0,
-	0, 0, 0, 2195, 0, 0, 0, 0, 0, 2189,
-	0, 0, 0, 0, 2229, 0, 0, 0, 2239, 0,
-	2209, 0, 0, 0, 0, 0, 0, 2217, 2220, 0,
-	2206, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	2235, 2229, 2236, 0, 0, 2239, 0, 0, 0, 2204,
-	2205, 0, 0, 0, 2217, 2220, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 2227,
-	0, 0, 0, 0, 0, 0, 0, 2235, 0, 2236,
-	0, 0, 0, 0, 2210, 0, 2204, 2205, 0, 0,
-	0, 0, 2187, 2188, 0, 2221, 2222, 2223, 2232, 2233,
-	2234, 0, 0, 0, 0, 0, 2227, 2212, 2213, 2214,
-	2215, 0, 0, 0, 0, 2225, 2218, 2195, 0, 0,
-	0, 2210, 0, 2219, 0, 0, 2190, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 2237, 0, 2238, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 2226, 0, 2244,
-	0, 0, 0, 0, 0, 2229, 0, 0, 2241, 2239,
-	2189, 0, 0, 2237, 0, 0, 0, 0, 2217, 2220,
-	0, 2209, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 2206, 0, 0, 2226, 0, 0, 0, 0, 0,
-	0, 2235, 0, 2236, 0, 2241, 0, 0, 0, 0,
-	2204, 2205, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	2227, 2216, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 2210, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 2211,
-	0, 0, 0, 0, 0, 0, 0, 0, 2216, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 2212, 2213,
-	2214, 2215, 0, 0, 0, 0, 0, 0, 2195, 0,
-	0, 0, 0, 2230, 0, 0, 2211, 2237, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 2226, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 2241,
-	2230, 0, 0, 2243, 0, 0, 2229, 0, 0, 0,
-	2239, 0, 0, 0, 0, 0, 0, 0, 0, 2217,
-	2220, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	2243, 0, 2235, 0, 2236, 0, 0, 0, 0, 0,
-	0, 2204, 2205, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 2216, 0, 0, 0, 0, 0, 0, 0,
-	0, 2227, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 2210, 0, 0, 0,
-	2211, 0, 2228, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 2201, 2202, 2208, 2231, 2207,
-	2203, 0, 2200, 2198, 2199, 2191, 2192, 2193, 2194, 2196,
-	2197, 0, 0, 0, 2230, 0, 5718, 0, 0, 2228,
-	0, 0, 0, 0, 0, 0, 0, 0, 2237, 0,
-	0, 0, 2201, 2202, 2208, 2231, 2207, 2203, 0, 2200,
-	2198, 2199, 2191, 2192, 2193, 2194, 2196, 2197, 0, 2226,
-	0, 0, 0, 5717, 2243, 0, 0, 0, 0, 0,
-	2241, 0, 0, 2187, 2188, 0, 2221, 2222, 2223, 2232,
-	2233, 2234, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 2225, 2218, 0, 0,
-	0, 0, 0, 0, 2219, 0, 0, 2190, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 2238,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 2216, 0, 0, 0, 0, 0, 0,
-	2244, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 2189, 0, 2228, 0, 0, 0, 0, 0, 0,
-	0, 2211, 2209, 0, 0, 0, 2201, 2202, 2208, 2231,
-	2207, 2203, 2206, 2200, 2198, 2199, 2191, 2192, 2193, 2194,
-	2196, 2197, 0, 0, 0, 0, 0, 5253, 0, 0,
-	0, 0, 0, 0, 0, 2230, 0, 2187, 2188, 0,
-	2221, 2222, 2223, 2232, 2233, 2234, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	2225, 2218, 0, 0, 0, 0, 0, 0, 2219, 0,
-	0, 2190, 0, 0, 0, 2243, 0, 0, 0, 0,
-	0, 0, 0, 2238, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 2212,
-	2213, 2214, 2215, 0, 2244, 0, 0, 0, 0, 2195,
-	0, 0, 0, 0, 0, 2189, 2187, 2188, 0, 2221,
-	2222, 2223, 2232, 2233, 2234, 0, 2209, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 2206, 0, 0, 2225,
-	2218, 0, 0, 0, 0, 0, 0, 2219, 0, 0,
-	2190, 0, 0, 0, 0, 0, 0, 2229, 0, 0,
-	0, 2239, 2238, 0, 2228, 0, 0, 0, 0, 0,
-	2217, 2220, 0, 0, 0, 0, 0, 2201, 2202, 2208,
-	2231, 2207, 2203, 2244, 2200, 2198, 2199, 2191, 2192, 2193,
-	2194, 2196, 2197, 2235, 2189, 2236, 0, 0, 4584, 0,
-	0, 0, 2204, 2205, 0, 2209, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 2206, 0, 0, 0, 0,
-	0, 0, 2227, 2212, 2213, 2214, 2215, 0, 0, 0,
-	0, 0, 0, 2195, 0, 0, 0, 2210, 0, 0,
-	2187, 2188, 0, 2221, 2222, 2223, 2232, 2233, 2234, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 2225, 2218, 0, 0, 0, 0, 0,
-	0, 2219, 0, 0, 2190, 0, 0, 0, 0, 0,
-	0, 2229, 0, 0, 0, 2239, 2238, 0, 0, 2237,
-	0, 0, 0, 0, 2217, 2220, 0, 0, 0, 0,
-	0, 0, 2212, 2213, 2214, 2215, 0, 2244, 0, 0,
-	2226, 0, 2195, 0, 0, 0, 0, 2235, 2189, 2236,
-	0, 2241, 0, 0, 0, 0, 2204, 2205, 0, 2209,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 2206,
-	0, 0, 0, 0, 0, 0, 2227, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	2229, 2210, 0, 0, 2239, 0, 0, 0, 0, 0,
-	0, 0, 0, 2217, 2220, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 2216, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 2235, 0, 2236, 0,
-	0, 0, 0, 0, 0, 2204, 2205, 0, 0, 0,
-	0, 0, 2211, 2237, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 2227, 2212, 2213, 2214, 2215,
-	0, 0, 0, 0, 2226, 0, 2195, 0, 0, 0,
-	2210, 0, 0, 0, 0, 2241, 2230, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 2229, 0, 2243, 0, 2239, 0,
-	0, 0, 2237, 0, 0, 0, 0, 2217, 2220, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 2216, 0,
-	0, 0, 0, 2226, 0, 0, 0, 0, 0, 0,
-	2235, 0, 2236, 0, 2241, 0, 0, 0, 0, 2204,
-	2205, 0, 0, 0, 0, 0, 2211, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 2227,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 2210, 0, 0, 0, 0, 0,
-	2230, 0, 0, 0, 0, 2228, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 2216, 2201, 2202,
-	2208, 2231, 2207, 2203, 0, 2200, 2198, 2199, 2191, 2192,
-	2193, 2194, 2196, 2197, 0, 0, 0, 0, 0, 4583,
-	2243, 0, 0, 0, 0, 2211, 2237, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 2226, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 2241, 2230,
-	0, 2187, 2188, 0, 2221, 2222, 2223, 2232, 2233, 2234,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 2225, 2218, 0, 0, 0, 0,
-	0, 0, 2219, 0, 0, 2190, 0, 0, 0, 2243,
-	0, 0, 0, 0, 0, 0, 0, 2238, 0, 2228,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 2216, 2201, 2202, 2208, 2231, 2207, 2203, 2244, 2200,
-	2198, 2199, 2191, 2192, 2193, 2194, 2196, 2197, 0, 2189,
-	0, 0, 0, 4582, 0, 0, 0, 0, 0, 2211,
-	2209, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	2206, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 2230, 0, 0, 0, 0, 2228, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 2201, 2202, 2208, 2231, 2207, 2203, 0, 2200, 2198,
-	2199, 2191, 2192, 2193, 2194, 2196, 2197, 0, 0, 0,
-	0, 0, 4581, 2243, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 2212, 2213, 2214,
-	2215, 0, 0, 0, 0, 0, 0, 2195, 0, 0,
-	0, 0, 0, 0, 2187, 2188, 0, 2221, 2222, 2223,
-	2232, 2233, 2234, 0, 0, 0, 0, 0, 2852, 0,
-	0, 0, 0, 0, 0, 0, 0, 2225, 2218, 0,
-	0, 0, 0, 0, 0, 2219, 0, 0, 2190, 0,
-	0, 0, 0, 0, 0, 2229, 0, 0, 0, 2239,
-	2238, 0, 2228, 0, 0, 0, 0, 0, 2217, 2220,
-	0, 0, 0, 0, 0, 2201, 2202, 2208, 2231, 2207,
-	2203, 2244, 2200, 2198, 2199, 2191, 2192, 2193, 2194, 2196,
-	2197, 2235, 2189, 2236, 4552, 0, 0, 0, 0, 0,
-	2204, 2205, 0, 2209, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 2206, 0, 0, 0, 0, 0, 0,
-	2227, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 2210, 0, 0, 2187, 2188,
-	0, 2221, 2222, 2223, 2232, 2233, 2234, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 2225, 2218, 0, 0, 0, 0, 2853, 0, 2219,
-	0, 0, 2190, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 2238, 0, 0, 2237, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	2212, 2213, 2214, 2215, 0, 2244, 0, 0, 2226, 0,
-	2195, 0, 0, 0, 0, 0, 2189, 0, 0, 2241,
-	0, 0, 0, 0, 0, 0, 0, 2209, 0, 0,
-	0, 2747, 0, 0, 0, 0, 0, 2206, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 2229, 0,
-	0, 0, 2239, 0, 0, 0, 0, 0, 0, 0,
-	0, 2217, 2220, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 2216, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 2235, 0, 2236, 0, 0, 0,
-	0, 0, 0, 2204, 2205, 0, 0, 0, 0, 0,
-	2211, 2745, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 2227, 2212, 2213, 2214, 2215, 0, 0,
-	0, 0, 0, 0, 2195, 0, 0, 0, 2210, 0,
-	0, 0, 0, 0, 2230, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 2229, 0, 2243, 0, 2239, 0, 0, 0,
-	2237, 0, 0, 0, 0, 2217, 2220, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 2226, 0, 0, 0, 0, 0, 0, 2235, 0,
-	2236, 0, 2241, 0, 0, 0, 0, 2204, 2205, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 2227, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 2210, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 2228, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 2216, 2201, 2202, 2208, 2231,
-	2207, 2203, 0, 2200, 2198, 2199, 2191, 2192, 2193, 2194,
-	2196, 2197, 0, 0, 0, 4040, 0, 0, 0, 0,
-	0, 0, 0, 2211, 2237, 0, 0, 0, 0, 0,
-	0, 2187, 2188, 0, 2221, 2222, 2223, 2232, 2233, 2234,
-	0, 0, 0, 0, 0, 2226, 0, 0, 0, 2854,
-	0, 0, 0, 0, 2225, 2218, 2241, 2230, 0, 0,
-	0, 0, 2219, 0, 0, 2190, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 2238, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 2243, 2244, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 2189,
-	0, 0, 0, 0, 0, 0, 0, 0, 2746, 2216,
-	2209, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	2206, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 2855, 2211, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 2230, 0, 0, 0, 0, 2228, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 2201,
-	2202, 2208, 2231, 2207, 2203, 0, 2200, 2198, 2199, 2191,
-	2192, 2193, 2194, 2196, 2197, 0, 0, 2212, 2213, 2214,
-	2215, 2243, 0, 0, 0, 0, 0, 2195, 6666, 0,
-	0, 0, 0, 2744, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 2229, 0, 0, 0, 2239,
-	0, 0, 0, 0, 0, 0, 0, 0, 2217, 2220,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	2228, 2235, 0, 2236, 0, 0, 0, 0, 0, 0,
-	2204, 2205, 0, 2201, 2202, 2208, 2231, 2207, 2203, 0,
-	2200, 2198, 2199, 2191, 2192, 2193, 2194, 2196, 2197, 186,
-	2227, 0, 0, 0, 0, 0, 0, 0, 90, 0,
-	55, 54, 0, 0, 0, 2210, 0, 0, 0, 2187,
-	2188, 0, 2221, 2222, 2223, 2232, 2233, 2234, 0, 91,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 2225, 2218, 0, 0, 0, 56, 0, 96,
-	2219, 0, 0, 2190, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 77, 0, 2238, 0, 2237, 0, 0,
-	0, 58, 0, 184, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 2244, 0, 2226, 0,
-	0, 0, 0, 57, 0, 0, 106, 2189, 0, 2241,
-	0, 0, 0, 0, 0, 0, 0, 0, 2209, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 2206, 0,
-	0, 0, 6665, 0, 0, 0, 60, 78, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 61, 0, 0,
-	0, 0, 67, 0, 0, 0, 0, 0, 6629, 0,
-	0, 0, 0, 0, 0, 0, 59, 0, 130, 0,
-	0, 0, 2216, 0, 114, 127, 0, 0, 0, 0,
-	0, 0, 0, 0, 79, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	2211, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 2212, 2213, 2214, 2215, 0,
-	0, 0, 0, 0, 62, 2195, 0, 4649, 0, 0,
-	0, 0, 0, 0, 2230, 0, 0, 0, 4648, 0,
-	0, 0, 0, 0, 0, 0, 115, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 2229, 2243, 0, 0, 2239, 0, 0,
-	0, 0, 0, 0, 0, 0, 2217, 2220, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 2235,
-	0, 2236, 0, 0, 0, 0, 0, 0, 2204, 2205,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 80, 0, 0, 0, 2227, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 2210, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 2228, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 2201, 2202, 2208, 2231,
-	2207, 2203, 0, 2200, 2198, 2199, 2191, 2192, 2193, 2194,
-	2196, 2197, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 2237, 0, 0, 0, 0,
-	0, 0, 0, 0, 119, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 2226, 0, 0, 0,
-	0, 0, 63, 0, 0, 0, 0, 2241, 0, 0,
-	2187, 2188, 0, 2221, 2222, 2223, 2232, 2233, 2234, 0,
-	0, 66, 0, 0, 0, 0, 0, 69, 0, 0,
-	0, 0, 0, 2225, 2218, 0, 0, 81, 0, 4522,
-	0, 2219, 0, 0, 2190, 0, 68, 229, 0, 122,
-	0, 0, 126, 0, 0, 6247, 2238, 0, 0, 64,
-	0, 0, 0, 185, 0, 0, 0, 0, 0, 0,
-	2216, 65, 0, 0, 0, 0, 0, 2244, 0, 0,
-	0, 0, 0, 0, 0, 295, 0, 0, 2189, 0,
-	0, 0, 0, 0, 72, 0, 0, 0, 2211, 2209,
-	0, 83, 0, 0, 0, 0, 0, 0, 0, 2206,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	183, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 2230, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 297, 0, 0, 0, 0,
-	0, 0, 0, 0, 4523, 0, 0, 0, 2187, 2188,
-	0, 2221, 2222, 2223, 2232, 2233, 2234, 0, 0, 0,
-	0, 0, 2243, 0, 182, 0, 0, 0, 0, 0,
-	0, 2225, 2218, 0, 82, 0, 0, 0, 0, 2219,
-	0, 0, 2190, 235, 0, 0, 2212, 2213, 2214, 2215,
-	0, 296, 0, 0, 2238, 0, 2195, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 289, 2244, 0, 0, 0, 0,
-	0, 0, 0, 290, 0, 0, 2189, 230, 0, 0,
-	0, 0, 0, 234, 0, 0, 0, 2209, 0, 0,
-	0, 0, 0, 0, 2229, 0, 0, 2206, 2239, 0,
-	0, 2228, 0, 0, 233, 0, 0, 2217, 2220, 0,
-	0, 0, 0, 0, 2201, 2202, 2208, 2231, 2207, 2203,
-	0, 2200, 2198, 2199, 2191, 2192, 2193, 2194, 2196, 2197,
-	2235, 0, 2236, 0, 0, 0, 0, 0, 0, 2204,
-	2205, 0, 0, 0, 0, 0, 2187, 2188, 0, 2221,
-	2222, 2223, 2232, 2233, 2234, 0, 0, 0, 0, 2227,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 2225,
-	2218, 0, 0, 0, 2210, 0, 0, 2219, 0, 0,
-	2190, 0, 0, 0, 2212, 2213, 2214, 2215, 0, 0,
-	0, 0, 2238, 0, 2195, 0, 6201, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 2244, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 2189, 0, 2237, 0, 0, 0,
-	0, 0, 0, 0, 0, 2209, 0, 0, 0, 0,
-	0, 0, 2229, 0, 0, 2206, 2239, 2226, 0, 0,
-	0, 0, 0, 0, 0, 2217, 2220, 0, 2241, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 2235, 0,
-	2236, 0, 0, 0, 0, 0, 0, 2204, 2205, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 2227, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 2216, 2210, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 2212, 2213, 2214, 2215, 0, 0, 0, 0,
-	0, 0, 2195, 0, 0, 0, 0, 0, 0, 2211,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 2237, 0, 0, 0, 0, 0,
-	0, 0, 0, 2230, 0, 0, 0, 0, 0, 0,
-	2229, 0, 0, 0, 2239, 2226, 0, 0, 0, 0,
-	0, 0, 0, 2217, 2220, 0, 2241, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 2243, 0, 0, 2235, 0, 2236, 0,
-	0, 0, 0, 0, 0, 2204, 2205, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 2227, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 2216,
-	2210, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 2211, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 2228, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 2237, 0, 0, 2201, 2202, 2208, 2231, 2207,
-	2203, 2230, 2200, 2198, 2199, 2191, 2192, 2193, 2194, 2196,
-	2197, 0, 0, 2226, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 2241, 0, 0, 2187, 2188, 0,
-	2221, 2222, 2223, 2232, 2233, 2234, 0, 0, 0, 0,
-	0, 2243, 0, 0, 0, 0, 0, 0, 0, 0,
-	2225, 2218, 0, 0, 0, 0, 0, 0, 2219, 0,
-	0, 2190, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 2238, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 2216, 0, 0,
-	0, 0, 0, 0, 2244, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 2189, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 2211, 2209, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 2206, 0, 0, 0,
-	2228, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 2201, 2202, 2208, 2231, 2207, 2203, 2230,
-	2200, 2198, 2199, 2191, 2192, 2193, 2194, 2196, 2197, 0,
-	2187, 2188, 0, 2221, 2222, 2223, 2232, 2233, 2234, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 2225, 2218, 0, 0, 0, 0, 2243,
-	0, 2219, 0, 0, 2190, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 2238, 0, 0, 5904,
-	0, 0, 0, 2212, 2213, 2214, 2215, 0, 0, 0,
-	0, 0, 0, 2195, 0, 0, 0, 2244, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 2189, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 2209,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 2206,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 2229, 0, 0, 0, 2239, 0, 0, 2228, 0,
-	0, 0, 0, 0, 2217, 2220, 0, 0, 0, 0,
-	0, 2201, 2202, 2208, 2231, 2207, 2203, 0, 2200, 2198,
-	2199, 2191, 2192, 2193, 2194, 2196, 2197, 2235, 0, 2236,
-	0, 0, 0, 0, 0, 0, 2204, 2205, 0, 0,
-	0, 2187, 2188, 0, 2221, 2222, 2223, 2232, 2233, 2234,
-	0, 0, 0, 0, 0, 0, 2227, 0, 0, 0,
-	0, 0, 0, 0, 2225, 2218, 2212, 2213, 2214, 2215,
-	0, 2210, 2219, 0, 0, 2190, 2195, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 2238, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 2244, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 2189,
-	0, 0, 0, 2237, 2229, 0, 0, 0, 2239, 0,
-	2209, 0, 0, 0, 0, 0, 0, 2217, 2220, 0,
-	2206, 0, 0, 0, 2226, 3944, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 2241, 0, 0, 0, 0,
-	2235, 0, 2236, 0, 0, 0, 0, 0, 0, 2204,
-	2205, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 2227,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 2210, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 2216, 0,
-	0, 0, 0, 0, 0, 0, 0, 2212, 2213, 2214,
-	2215, 0, 0, 0, 0, 0, 0, 2195, 0, 5510,
-	0, 0, 0, 0, 0, 0, 2211, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 2237, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 2226, 0, 0,
-	2230, 0, 0, 0, 0, 2229, 0, 0, 2241, 2239,
-	0, 0, 0, 0, 0, 0, 0, 0, 2217, 2220,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	2243, 2235, 0, 2236, 0, 0, 0, 0, 0, 0,
-	2204, 2205, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	2227, 2216, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 2210, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 2211,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 2228,
-	0, 0, 0, 2230, 0, 0, 0, 2237, 0, 0,
-	0, 0, 2201, 2202, 2208, 2231, 2207, 2203, 0, 2200,
-	2198, 2199, 2191, 2192, 2193, 2194, 2196, 2197, 2226, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 2241,
-	0, 0, 0, 2243, 2187, 2188, 0, 2221, 2222, 2223,
-	2232, 2233, 2234, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 5511, 0, 0, 0, 2225, 2218, 0,
-	0, 0, 0, 0, 0, 2219, 0, 0, 2190, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	2238, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 2216, 0, 0, 0, 0, 0, 0, 0,
-	0, 2244, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 2189, 0, 0, 0, 0, 0, 0, 0,
-	2211, 0, 2228, 2209, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 2206, 0, 2201, 2202, 2208, 2231, 2207,
-	2203, 0, 2200, 2198, 2199, 2191, 2192, 2193, 2194, 2196,
-	2197, 0, 0, 0, 2230, 0, 0, 0, 2187, 2188,
-	0, 2221, 2222, 2223, 2232, 2233, 2234, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 2225, 2218, 0, 0, 0, 0, 0, 0, 2219,
-	0, 0, 2190, 0, 2243, 2187, 2188, 0, 2221, 2222,
-	2223, 2232, 2233, 2234, 2238, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 2225, 2218,
-	2212, 2213, 2214, 2215, 0, 2244, 2219, 0, 0, 2190,
-	2195, 0, 0, 0, 0, 0, 2189, 0, 0, 0,
-	0, 2238, 0, 0, 0, 0, 0, 2209, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 2206, 0, 0,
-	0, 0, 2244, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 2189, 0, 0, 0, 0, 2229, 0,
-	0, 0, 2239, 2228, 2209, 0, 0, 0, 0, 0,
-	0, 2217, 2220, 0, 2206, 0, 2201, 2202, 2208, 2231,
-	2207, 2203, 0, 2200, 2198, 2199, 2191, 2192, 2193, 2194,
-	2196, 2197, 0, 0, 2235, 0, 2236, 0, 0, 0,
-	0, 0, 0, 2204, 2205, 0, 0, 0, 0, 2187,
-	2188, 0, 2221, 2222, 2223, 2232, 2233, 2234, 0, 0,
-	0, 0, 0, 2227, 2212, 2213, 2214, 2215, 0, 0,
-	0, 0, 2225, 2218, 2195, 0, 0, 4650, 2210, 0,
-	2219, 0, 0, 2190, 0, 0, 0, 4655, 0, 0,
-	0, 0, 0, 0, 0, 2238, 0, 0, 0, 0,
-	0, 2212, 2213, 2214, 2215, 0, 0, 0, 0, 0,
-	0, 2195, 0, 0, 0, 0, 2244, 0, 0, 0,
-	0, 0, 2229, 0, 0, 0, 2239, 2189, 0, 0,
-	2237, 0, 0, 0, 0, 2217, 2220, 0, 2209, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 2206, 0,
-	0, 2226, 0, 0, 0, 0, 0, 0, 2235, 2229,
-	2236, 0, 2241, 2239, 0, 0, 0, 2204, 2205, 0,
-	0, 0, 2217, 2220, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 2227, 0, 0,
-	0, 0, 0, 0, 0, 2235, 0, 2236, 0, 0,
-	0, 0, 2210, 0, 2204, 2205, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 2227, 2216, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 2212, 2213, 2214, 2215, 2210,
-	0, 0, 0, 0, 0, 2195, 0, 0, 0, 0,
-	0, 0, 0, 2211, 2237, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 2226, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 2241, 2230, 0, 0,
-	0, 2237, 0, 2229, 0, 0, 0, 2239, 0, 0,
-	0, 0, 0, 0, 0, 0, 2217, 2220, 0, 0,
-	0, 0, 2226, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 2241, 0, 0, 0, 2243, 0, 2235,
-	0, 2236, 0, 0, 4615, 0, 0, 0, 2204, 2205,
-	0, 5234, 0, 0, 0, 0, 0, 0, 0, 2216,
-	0, 0, 0, 0, 0, 0, 0, 0, 2227, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 2210, 0, 0, 0, 2211, 0, 0,
-	0, 0, 0, 0, 0, 0, 2216, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 2230, 0, 0, 2211, 0, 2228, 0, 0, 0,
-	0, 0, 0, 0, 0, 2237, 0, 0, 0, 2201,
-	2202, 2208, 2231, 2207, 2203, 0, 2200, 2198, 2199, 2191,
-	2192, 2193, 2194, 2196, 2197, 0, 2226, 0, 2230, 0,
-	0, 2243, 0, 0, 0, 0, 0, 2241, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 2243, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	2216, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	2228, 0, 0, 0, 0, 0, 0, 0, 2211, 0,
-	0, 0, 0, 2201, 2202, 2208, 2231, 2207, 2203, 0,
-	2200, 2198, 2199, 2191, 2192, 2193, 2194, 2196, 2197, 0,
-	0, 0, 0, 0, 0, 0, 0, 2228, 0, 0,
-	0, 0, 2230, 0, 0, 0, 0, 0, 0, 0,
-	2201, 2202, 2208, 2231, 2207, 2203, 0, 2200, 2198, 2199,
-	2191, 2192, 2193, 2194, 2196, 2197, 2187, 2188, 0, 2221,
-	2222, 2223, 2232, 2233, 2234, 0, 0, 0, 0, 0,
-	0, 0, 2243, 0, 0, 0, 0, 0, 0, 2225,
-	2218, 0, 0, 0, 4585, 0, 0, 2219, 0, 0,
-	2190, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 2238, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 2244, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 2189, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 2209, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 2206, 0, 0, 0, 0,
-	0, 2228, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 2201, 2202, 2208, 2231, 2207, 2203,
-	0, 2200, 2198, 2199, 2191, 2192, 2193, 2194, 2196, 2197,
-	2187, 2188, 0, 2221, 2222, 2223, 2232, 2233, 2234, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 2225, 2218, 0, 0, 0, 0, 0,
-	0, 2219, 0, 0, 2190, 0, 0, 2187, 2188, 0,
-	2221, 2222, 2223, 2232, 2233, 2234, 2238, 0, 0, 0,
-	0, 0, 2212, 2213, 2214, 2215, 0, 0, 0, 0,
-	2225, 2218, 2195, 0, 0, 0, 0, 2244, 2219, 0,
-	0, 2190, 0, 0, 0, 0, 0, 0, 2189, 0,
-	0, 0, 0, 2238, 0, 0, 0, 0, 0, 2209,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 2206,
-	0, 0, 0, 0, 2244, 0, 0, 0, 0, 0,
-	2229, 0, 0, 0, 2239, 2189, 0, 0, 0, 0,
-	0, 0, 0, 2217, 2220, 0, 2209, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 2206, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 2235, 0, 2236, 0,
-	0, 0, 0, 0, 0, 2204, 2205, 0, 0, 0,
-	0, 2187, 2188, 0, 2221, 2222, 2223, 2232, 2233, 2234,
-	0, 0, 0, 0, 0, 2227, 0, 0, 0, 0,
-	0, 0, 0, 0, 2225, 2218, 2212, 2213, 2214, 2215,
-	2210, 0, 2219, 0, 0, 2190, 2195, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 2238, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 2212, 2213, 2214, 2215, 0, 2244, 0,
-	0, 0, 0, 2195, 0, 0, 0, 0, 0, 2189,
-	0, 0, 2237, 0, 2229, 0, 0, 0, 2239, 0,
-	2209, 0, 0, 0, 0, 0, 0, 2217, 2220, 0,
-	2206, 0, 0, 2226, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 2241, 0, 0, 0, 0, 0,
-	2235, 2229, 2236, 0, 0, 2239, 0, 0, 0, 2204,
-	2205, 0, 0, 0, 2217, 2220, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 2227,
-	0, 0, 0, 0, 0, 0, 0, 2235, 0, 2236,
-	0, 0, 0, 0, 2210, 0, 2204, 2205, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 2216, 0, 0,
-	0, 0, 0, 0, 0, 0, 2227, 2212, 2213, 2214,
-	2215, 0, 0, 0, 0, 0, 0, 2195, 0, 0,
-	0, 2210, 0, 0, 0, 2211, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 2237, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 2226, 0, 2230,
-	0, 0, 0, 0, 0, 2229, 0, 0, 2241, 2239,
-	0, 0, 0, 2237, 0, 0, 0, 0, 2217, 2220,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 2226, 0, 0, 0, 0, 2243,
-	0, 2235, 0, 2236, 0, 2241, 0, 0, 0, 0,
-	2204, 2205, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	2227, 2216, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 2210, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 2211,
-	0, 0, 0, 0, 0, 0, 0, 0, 2216, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 2228, 0,
-	0, 0, 0, 2230, 0, 0, 2211, 2237, 0, 0,
-	0, 2201, 2202, 2208, 2231, 2207, 2203, 0, 2200, 2198,
-	2199, 2191, 2192, 2193, 2194, 2196, 2197, 0, 2226, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 2241,
-	2230, 0, 0, 2243, 2187, 2188, 0, 2221, 2222, 2223,
-	2232, 2233, 2234, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 2218, 0,
-	0, 0, 0, 0, 0, 2219, 0, 0, 2190, 0,
-	2243, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	2238, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 2216, 0, 0, 0, 0, 0, 0, 0,
-	0, 2244, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 2189, 0, 0, 2978, 0, 0, 0, 0,
-	2211, 0, 2228, 2209, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 2206, 0, 2201, 2202, 2208, 2231, 2207,
-	2203, 0, 2200, 2198, 2199, 2191, 2192, 2193, 2194, 2196,
-	2197, 0, 2650, 0, 2230, 0, 0, 0, 0, 2228,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 2201, 2202, 2208, 2231, 2207, 2203, 0, 2200,
-	2198, 2199, 2191, 2192, 2193, 2194, 2196, 2197, 0, 0,
-	0, 0, 0, 0, 2243, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	2212, 2213, 2214, 2215, 0, 0, 0, 0, 0, 0,
-	2195, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 2229, 0,
-	0, 0, 2239, 2228, 0, 0, 0, 0, 0, 0,
-	0, 2217, 2220, 0, 0, 0, 2201, 2202, 2208, 2231,
-	2207, 2203, 0, 2200, 2198, 2199, 2191, 2192, 2193, 2194,
-	2196, 2197, 0, 0, 2235, 0, 2236, 0, 1030, 0,
-	1090, 0, 0, 2204, 2205, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 2227, 0, 1038, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 2210, 0,
-	0, 0, 0, 0, 0, 1055, 0, 1036, 1035, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 1057, 0, 0, 0, 0,
-	0, 0, 1037, 0, 0, 0, 0, 0, 1040, 0,
-	2237, 1051, 0, 1103, 0, 1069, 0, 0, 0, 0,
-	0, 0, 0, 0, 1052, 1053, 0, 0, 0, 0,
-	0, 0, 0, 0, 1074, 0, 0, 0, 0, 0,
-	0, 0, 2241, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 1091, 1042, 0, 0, 0, 0, 0, 0,
-	0, 1043, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 1044, 0,
-	0, 0, 0, 0, 0, 0, 0, 1084, 0, 0,
-	0, 0, 0, 0, 0, 2216, 0, 0, 0, 0,
+	0, 2356, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 2355, 0, 0, 0, 0, 2365, 0, 0,
+	0, 0, 0, 0, 0, 2369, 2340, 2346, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	2361, 0, 2362, 0, 0, 0, 0, 0, 0, 2327,
+	2328, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 2353,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 2333, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 2354, 0,
+	0, 0, 0, 0, 0, 2345, 0, 0, 0, 0,
+	0, 2324, 2325, 2331, 2357, 2330, 2326, 0, 2323, 2321,
+	2322, 2314, 2315, 2316, 2317, 2319, 2320, 0, 5411, 0,
+	0, 0, 6712, 2363, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 2352, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 2367, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 3194, 0, 0, 0,
+	0, 0, 0, 5455, 5456, 0, 0, 5459, 0, 0,
+	0, 5462, 0, 0, 0, 0, 0, 0, 0, 0,
+	5466, 0, 0, 0, 0, 0, 0, 0, 0, 5473,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 5482, 0, 2339, 0, 0, 2310, 2311,
+	0, 2347, 2348, 2349, 2358, 2359, 2360, 0, 0, 0,
+	0, 0, 0, 5505, 5506, 0, 5507, 5508, 5509, 0,
+	0, 2351, 2341, 0, 0, 2334, 0, 0, 0, 2342,
+	0, 0, 2313, 0, 0, 0, 0, 0, 5516, 0,
+	0, 0, 5518, 0, 0, 2364, 0, 0, 0, 2310,
+	2311, 0, 2347, 2348, 2349, 2358, 2359, 2360, 0, 2356,
+	0, 0, 0, 0, 0, 0, 0, 0, 2370, 0,
+	0, 0, 2351, 2341, 0, 5547, 5548, 0, 0, 2312,
+	2342, 0, 0, 2313, 0, 0, 0, 0, 0, 0,
+	2332, 0, 0, 0, 5559, 0, 2364, 0, 0, 0,
+	2329, 0, 0, 2369, 0, 0, 2344, 0, 0, 5568,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 2370,
 	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	2312, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 2332, 0, 0, 0, 0, 0, 0, 5590, 3194,
+	2343, 2329, 0, 0, 0, 0, 0, 2344, 0, 0,
 	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 2211, 0, 0, 0, 1085, 0, 1064,
 	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 1046, 0, 0, 0, 0, 0,
-	0, 0, 0, 1034, 0, 0, 0, 2230, 0, 0,
 	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 1048, 1049, 0, 0,
+	2335, 2336, 2337, 2338, 0, 0, 2354, 0, 0, 0,
+	2318, 2343, 0, 0, 0, 0, 0, 0, 0, 2324,
+	2325, 2331, 2357, 2330, 2326, 0, 2323, 2321, 2322, 2314,
+	2315, 2316, 2317, 2319, 2320, 0, 0, 0, 5650, 0,
+	6711, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 2335, 2336, 2337, 2338, 0, 0, 0, 0, 2355,
+	0, 2318, 0, 0, 2365, 0, 0, 0, 0, 0,
+	0, 0, 0, 2340, 2346, 0, 0, 0, 0, 0,
 	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 2243, 0, 0,
-	0, 1058, 1056, 0, 0, 0, 0, 0, 0, 1050,
-	0, 0, 0, 0, 1070, 0, 0, 1096, 1095, 0,
+	0, 0, 0, 0, 0, 0, 0, 2361, 0, 2362,
+	0, 0, 0, 0, 0, 0, 2327, 2328, 0, 0,
+	2355, 0, 0, 0, 0, 2365, 0, 0, 0, 0,
+	0, 0, 0, 0, 2340, 2346, 2353, 0, 0, 0,
+	0, 0, 0, 0, 5702, 0, 0, 0, 0, 0,
+	0, 0, 0, 2333, 0, 0, 0, 0, 2361, 0,
+	2362, 0, 0, 0, 0, 0, 0, 2327, 2328, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 5739,
+	0, 0, 2345, 0, 0, 0, 0, 2353, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 2333, 0, 0, 0, 0, 0,
+	2363, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 2352, 2345, 0, 5772, 5773, 0, 0, 0,
+	0, 0, 0, 2367, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 2363, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 2352, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 2367, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 2339, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 2334, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 2339, 0, 0, 0, 2310, 2311, 0,
+	2347, 2348, 2349, 2358, 2359, 2360, 2356, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 2470,
+	2351, 2341, 0, 2334, 0, 0, 0, 0, 2342, 0,
+	0, 2313, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 2364, 0, 0, 0, 0, 0,
+	2369, 0, 0, 0, 0, 0, 0, 2356, 0, 2470,
+	0, 0, 0, 0, 0, 0, 0, 2370, 5950, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 2312, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 2332,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 2329,
+	0, 2369, 5972, 5973, 0, 2344, 0, 0, 5977, 5978,
+	0, 0, 0, 5981, 5982, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 5987, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 2354, 5992, 0, 0, 0, 0, 2343,
+	0, 0, 0, 0, 0, 0, 2324, 2325, 2331, 2357,
+	2330, 2326, 0, 2323, 2321, 2322, 2314, 2315, 2316, 2317,
+	2319, 2320, 0, 0, 0, 0, 0, 6409, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 2335,
+	2336, 2337, 2338, 0, 2354, 0, 0, 0, 0, 2318,
+	0, 0, 0, 0, 0, 0, 0, 2324, 2325, 2331,
+	2357, 2330, 2326, 0, 2323, 2321, 2322, 2314, 2315, 2316,
+	2317, 2319, 2320, 0, 0, 0, 0, 0, 6138, 0,
+	0, 0, 0, 2310, 2311, 0, 2347, 2348, 2349, 2358,
+	2359, 2360, 0, 0, 0, 0, 0, 0, 2355, 0,
+	0, 0, 0, 2365, 0, 0, 2351, 2341, 0, 0,
+	0, 0, 2340, 2346, 2342, 0, 0, 2313, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	2364, 0, 0, 0, 0, 0, 2361, 0, 2362, 0,
+	0, 0, 0, 0, 0, 2327, 2328, 0, 0, 0,
+	0, 0, 0, 2370, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 2312, 2353, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 2332, 0, 0, 0, 0,
+	0, 0, 2333, 0, 0, 2329, 0, 1468, 0, 0,
+	0, 2344, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 2345, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 2343, 0, 0, 0, 2363,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 2352, 0, 0, 0, 0, 0, 0, 0, 0,
+	6209, 0, 2367, 0, 0, 2335, 2336, 2337, 2338, 0,
+	0, 0, 0, 0, 0, 2318, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 1468, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 2355, 0, 0, 0, 0, 2365,
+	0, 2339, 0, 0, 0, 0, 0, 0, 2340, 2346,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 6286, 6287, 0, 0, 0, 0, 0, 0,
+	0, 2334, 2361, 0, 2362, 0, 0, 0, 0, 0,
+	0, 2327, 2328, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 2353, 0, 0, 0, 2356, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 2333, 0,
 	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 1100, 1083, 0, 0, 0, 0, 0,
+	0, 0, 0, 6354, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 2345, 0, 2369,
 	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 6402,
+	6403, 6404, 0, 0, 0, 2363, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 3194,
+	0, 0, 6412, 6413, 0, 0, 0, 2352, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 2367, 6421,
+	6424, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 3194,
 	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 1092, 0, 0,
+	0, 0, 2354, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 2324, 2325, 2331, 2357, 2330,
+	2326, 0, 2323, 2321, 2322, 2314, 2315, 2316, 2317, 2319,
+	2320, 0, 0, 0, 0, 0, 6002, 2339, 0, 0,
+	2310, 2311, 0, 2347, 2348, 2349, 2358, 2359, 2360, 0,
 	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 2228, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 2201,
-	2202, 2208, 2231, 2207, 2203, 0, 2200, 2198, 2199, 2191,
-	2192, 2193, 2194, 2196, 2197, 0, 0, 0, 0, 0,
+	0, 0, 0, 2351, 2341, 0, 0, 2334, 0, 0,
+	0, 2342, 0, 0, 2313, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 2364, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 6520, 0, 0,
+	0, 2356, 0, 0, 0, 0, 0, 0, 0, 0,
+	2370, 0, 6531, 0, 0, 0, 0, 0, 0, 0,
+	0, 2312, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 2332, 0, 0, 0, 0, 0, 6553, 0,
+	0, 1468, 2329, 0, 0, 2369, 0, 0, 2344, 0,
 	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	1041, 0, 0, 1102, 0, 0, 0, 0, 0, 0,
+	0, 0, 6566, 0, 0, 6568, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 6578,
+	0, 0, 0, 0, 6584, 6585, 0, 0, 0, 0,
+	0, 6587, 2343, 6589, 0, 6591, 0, 0, 0, 0,
 	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 1065, 1039,
-	0, 0, 0, 0, 1078, 1079, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 1081,
-	0, 0, 0, 0, 1030, 0, 1090, 0, 0, 0,
 	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 1093,
-	1076, 1038, 0, 0, 0, 0, 0, 0, 1101, 1071,
-	0, 0, 1061, 1059, 0, 0, 0, 1066, 0, 0,
-	0, 1055, 0, 1036, 1035, 1067, 0, 0, 0, 1032,
-	0, 1094, 0, 0, 0, 0, 0, 0, 0, 0,
 	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 1057, 0, 0, 0, 0, 0, 0, 1037, 0,
-	1033, 0, 0, 0, 1040, 0, 0, 0, 0, 1103,
-	0, 1069, 0, 1082, 0, 0, 1080, 0, 1068, 1047,
-	1052, 1053, 0, 0, 1063, 0, 0, 0, 0, 1088,
-	1074, 1087, 0, 0, 0, 0, 1098, 0, 0, 0,
-	0, 0, 0, 0, 1072, 0, 1073, 0, 1091, 1042,
-	0, 0, 0, 0, 0, 1045, 1097, 1043, 0, 0,
+	0, 0, 2335, 2336, 2337, 2338, 0, 0, 2354, 0,
+	0, 0, 2318, 0, 0, 0, 0, 0, 0, 0,
+	0, 2324, 2325, 2331, 2357, 2330, 2326, 0, 2323, 2321,
+	2322, 2314, 2315, 2316, 2317, 2319, 2320, 0, 0, 0,
+	0, 0, 6001, 0, 0, 0, 0, 0, 0, 0,
 	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 1075, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 1044, 0, 0, 0, 0, 0,
-	0, 1089, 0, 1084, 0, 0, 0, 1099, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 1077, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 1086,
+	0, 2355, 0, 0, 0, 0, 2365, 0, 0, 0,
+	0, 0, 0, 0, 0, 2340, 2346, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 2310, 2311, 0,
+	2347, 2348, 2349, 2358, 2359, 2360, 0, 0, 0, 2361,
+	0, 2362, 0, 0, 0, 0, 0, 0, 2327, 2328,
+	2351, 2341, 0, 0, 0, 0, 0, 0, 2342, 0,
+	0, 2313, 0, 0, 0, 0, 0, 0, 2353, 0,
+	0, 0, 0, 0, 2364, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 2333, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 2370, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 2312, 0,
+	0, 0, 0, 0, 2345, 0, 0, 0, 0, 2332,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 2329,
+	0, 0, 0, 0, 0, 2344, 0, 0, 0, 0,
+	0, 0, 2363, 0, 0, 0, 0, 0, 0, 0,
 	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 1085, 0, 1064, 0, 0, 0, 0,
+	0, 0, 0, 0, 2352, 0, 0, 6757, 0, 0,
+	0, 6761, 0, 0, 0, 2367, 0, 0, 0, 2343,
 	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	1046, 0, 0, 0, 0, 0, 0, 0, 0, 1034,
+	0, 0, 0, 0, 0, 0, 0, 6783, 0, 0,
 	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 2335,
+	2336, 2337, 2338, 0, 0, 0, 0, 0, 0, 2318,
 	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 1048, 1049, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 2339, 0, 0, 0, 0, 0,
+	0, 0, 0, 6803, 0, 0, 0, 0, 0, 0,
 	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 1058, 1056, 0,
-	0, 0, 0, 0, 0, 1050, 0, 0, 0, 0,
-	1070, 0, 0, 1096, 1095, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 1100,
-	1083, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 2334, 2470, 0, 0, 2355, 0,
+	0, 0, 0, 2365, 0, 0, 0, 0, 0, 6832,
+	0, 0, 2340, 2346, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 2356, 0,
+	0, 0, 0, 0, 0, 0, 2361, 0, 2362, 0,
+	0, 0, 0, 0, 0, 2327, 2328, 0, 0, 0,
 	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 2353, 0, 0, 0, 0,
+	0, 0, 2369, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 2333, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 3194, 3194, 0, 0, 0, 0,
+	0, 0, 0, 0, 6424, 0, 0, 0, 0, 0,
+	0, 2345, 0, 0, 0, 0, 0, 0, 0, 0,
 	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 1092, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 2363,
 	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 2352, 0, 0, 0, 2354, 0, 0, 0, 0,
+	0, 0, 2367, 0, 0, 0, 0, 1468, 2324, 2325,
+	2331, 2357, 2330, 2326, 0, 2323, 2321, 2322, 2314, 2315,
+	2316, 2317, 2319, 2320, 0, 0, 0, 0, 0, 6000,
 	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 1041, 0, 0, 1102,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 2339, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 2334, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 7050, 7050, 7050, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 2356, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 7079, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 2369,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 7129, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 7050, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 2354, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 2324, 2325, 2331, 2357, 2330,
+	2326, 0, 2323, 2321, 2322, 2314, 2315, 2316, 2317, 2319,
+	2320, 0, 0, 0, 0, 0, 5502, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 7267, 7268, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 1980, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 7050, 7312, 367, 368, 370, 369, 371, 372, 373,
+	374, 1985, 375, 376, 1986, 1987, 1988, 0, 1989, 856,
+	1990, 1991, 1992, 378, 0, 377, 1993, 379, 380, 381,
+	926, 382, 383, 384, 385, 386, 387, 388, 389, 390,
+	857, 391, 858, 0, 392, 859, 393, 860, 1994, 861,
+	394, 395, 396, 397, 398, 399, 400, 401, 402, 403,
+	404, 1995, 1996, 0, 405, 862, 863, 864, 1997, 406,
+	407, 408, 409, 865, 1998, 927, 1999, 410, 411, 412,
+	413, 414, 415, 416, 417, 0, 2000, 419, 420, 421,
+	418, 422, 423, 2001, 424, 0, 425, 426, 427, 428,
+	429, 0, 430, 431, 2002, 432, 433, 434, 928, 435,
+	436, 437, 2003, 2004, 2006, 2005, 2007, 2008, 2009, 438,
+	439, 440, 441, 442, 0, 443, 445, 866, 867, 2010,
+	448, 450, 444, 446, 2011, 449, 447, 451, 452, 2012,
+	453, 454, 455, 456, 457, 0, 2013, 2014, 458, 459,
+	460, 461, 2015, 462, 463, 464, 466, 465, 2016, 467,
+	468, 469, 2017, 470, 471, 868, 472, 473, 474, 476,
+	478, 475, 477, 479, 480, 481, 482, 483, 869, 870,
+	484, 485, 2018, 362, 2019, 0, 0, 0, 0, 486,
+	487, 488, 871, 0, 0, 0, 489, 2020, 491, 495,
+	496, 492, 493, 494, 497, 2021, 490, 498, 499, 2022,
+	929, 500, 501, 502, 872, 873, 503, 504, 505, 506,
+	507, 508, 509, 510, 511, 2023, 512, 513, 874, 2024,
+	875, 514, 2025, 515, 516, 517, 518, 519, 520, 521,
+	876, 877, 878, 630, 931, 522, 523, 524, 525, 2026,
+	526, 527, 528, 529, 530, 531, 532, 0, 0, 0,
+	533, 534, 535, 536, 2027, 364, 363, 365, 930, 879,
+	537, 631, 538, 539, 880, 881, 2028, 882, 2029, 540,
+	541, 544, 932, 883, 933, 543, 545, 546, 934, 547,
+	0, 0, 0, 548, 549, 550, 551, 552, 553, 554,
+	2030, 555, 557, 556, 2031, 559, 884, 558, 935, 560,
+	561, 936, 2032, 562, 563, 564, 565, 566, 567, 572,
+	2033, 2034, 568, 569, 570, 571, 573, 574, 0, 575,
+	576, 578, 581, 577, 579, 580, 582, 583, 596, 597,
+	598, 584, 585, 586, 587, 588, 589, 590, 591, 592,
+	593, 594, 595, 600, 0, 599, 937, 0, 601, 602,
+	603, 604, 605, 606, 612, 615, 617, 618, 613, 614,
+	616, 619, 620, 621, 623, 624, 609, 610, 611, 938,
+	622, 607, 2035, 608, 366, 939, 625, 626, 627, 628,
+	2036, 885, 629, 886, 632, 633, 2037, 0, 634, 0,
+	635, 636, 2038, 2039, 638, 639, 640, 2040, 2041, 641,
+	642, 887, 940, 643, 941, 888, 644, 645, 637, 646,
+	647, 648, 649, 650, 651, 652, 653, 654, 655, 656,
+	657, 2042, 658, 659, 889, 660, 661, 662, 663, 664,
+	890, 665, 666, 667, 891, 668, 892, 669, 670, 671,
+	2043, 672, 673, 674, 0, 675, 676, 677, 678, 679,
+	680, 681, 682, 683, 684, 893, 685, 686, 688, 687,
+	689, 690, 2044, 691, 692, 0, 693, 694, 695, 0,
+	0, 0, 0, 0, 696, 697, 699, 0, 700, 701,
+	702, 703, 704, 705, 698, 706, 707, 708, 709, 710,
+	711, 712, 713, 2045, 715, 716, 714, 717, 718, 942,
+	719, 720, 721, 722, 723, 894, 724, 0, 725, 726,
+	734, 735, 736, 727, 728, 730, 737, 729, 738, 739,
+	740, 741, 743, 742, 2046, 745, 746, 744, 747, 748,
+	749, 750, 2047, 751, 895, 752, 731, 732, 753, 754,
+	755, 943, 756, 757, 758, 759, 760, 761, 762, 763,
+	764, 896, 0, 766, 2048, 765, 767, 768, 769, 770,
+	771, 772, 773, 775, 733, 776, 777, 778, 783, 784,
+	785, 897, 779, 780, 781, 782, 787, 898, 788, 789,
+	790, 791, 2049, 792, 793, 0, 786, 774, 2050, 794,
+	795, 796, 797, 798, 799, 800, 801, 802, 803, 2051,
+	804, 899, 900, 901, 902, 2052, 817, 2053, 805, 807,
+	808, 809, 810, 903, 811, 812, 904, 2054, 813, 814,
+	815, 816, 806, 819, 820, 818, 2055, 2056, 821, 822,
+	823, 824, 826, 828, 829, 830, 825, 827, 831, 2057,
+	832, 2058, 0, 833, 834, 835, 905, 906, 907, 2059,
+	908, 838, 839, 836, 837, 840, 841, 844, 842, 843,
+	909, 847, 542, 848, 849, 850, 845, 846, 2060, 2061,
+	2062, 2063, 851, 852, 910, 853, 854, 855, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 1980, 0, 0, 0, 0, 0, 0, 4109,
+	0, 0, 0, 0, 0, 0, 0, 0, 4110, 367,
+	368, 370, 369, 371, 372, 373, 374, 1985, 375, 376,
+	1986, 1987, 1988, 0, 1989, 856, 1990, 1991, 1992, 378,
+	0, 377, 1993, 379, 380, 381, 926, 382, 383, 384,
+	385, 386, 387, 388, 389, 390, 857, 391, 858, 0,
+	392, 859, 393, 860, 1994, 861, 394, 395, 396, 397,
+	398, 399, 400, 401, 402, 403, 404, 1995, 1996, 0,
+	405, 862, 863, 864, 1997, 406, 407, 408, 409, 865,
+	1998, 927, 1999, 410, 411, 412, 413, 414, 415, 416,
+	417, 0, 2000, 419, 420, 421, 418, 422, 423, 2001,
+	424, 0, 425, 426, 427, 428, 429, 0, 430, 431,
+	2002, 432, 433, 434, 928, 435, 436, 437, 2003, 2004,
+	2006, 2005, 2007, 2008, 2009, 438, 439, 440, 441, 442,
+	0, 443, 445, 866, 867, 2010, 448, 450, 444, 446,
+	2011, 449, 447, 451, 452, 2012, 453, 454, 455, 456,
+	457, 0, 2013, 2014, 458, 459, 460, 461, 2015, 462,
+	463, 464, 466, 465, 2016, 467, 468, 469, 2017, 470,
+	471, 868, 472, 473, 474, 476, 478, 475, 477, 479,
+	480, 481, 482, 483, 869, 870, 484, 485, 2018, 362,
+	2019, 0, 0, 0, 0, 486, 487, 488, 871, 0,
+	0, 0, 489, 2020, 491, 495, 496, 492, 493, 494,
+	497, 2021, 490, 498, 499, 2022, 929, 500, 501, 502,
+	872, 873, 503, 504, 505, 506, 507, 508, 509, 510,
+	511, 2023, 512, 513, 874, 2024, 875, 514, 2025, 515,
+	516, 517, 518, 519, 520, 521, 876, 877, 878, 630,
+	931, 522, 523, 524, 525, 2026, 526, 527, 528, 529,
+	530, 531, 532, 0, 0, 0, 533, 534, 535, 536,
+	2027, 364, 363, 365, 930, 879, 537, 631, 538, 539,
+	880, 881, 2028, 882, 2029, 540, 541, 544, 932, 883,
+	933, 543, 545, 546, 934, 547, 0, 0, 0, 548,
+	549, 550, 551, 552, 553, 554, 2030, 555, 557, 556,
+	2031, 559, 884, 558, 935, 560, 561, 936, 2032, 562,
+	563, 564, 565, 566, 567, 572, 2033, 2034, 568, 569,
+	570, 571, 573, 574, 0, 575, 576, 578, 581, 577,
+	579, 580, 582, 583, 596, 597, 598, 584, 585, 586,
+	587, 588, 589, 590, 591, 592, 593, 594, 595, 600,
+	0, 599, 937, 0, 601, 602, 603, 604, 605, 606,
+	612, 615, 617, 618, 613, 614, 616, 619, 620, 621,
+	623, 624, 609, 610, 611, 938, 622, 607, 2035, 608,
+	366, 939, 625, 626, 627, 628, 2036, 885, 629, 886,
+	632, 633, 2037, 0, 634, 0, 635, 636, 2038, 2039,
+	638, 639, 640, 2040, 2041, 641, 642, 887, 940, 643,
+	941, 888, 644, 645, 637, 646, 647, 648, 649, 650,
+	651, 652, 653, 654, 655, 656, 657, 2042, 658, 659,
+	889, 660, 661, 662, 663, 664, 890, 665, 666, 667,
+	891, 668, 892, 669, 670, 671, 2043, 672, 673, 674,
+	0, 675, 676, 677, 678, 679, 680, 681, 682, 683,
+	684, 893, 685, 686, 688, 687, 689, 690, 2044, 691,
+	692, 0, 693, 694, 695, 0, 0, 0, 0, 0,
+	696, 697, 699, 0, 700, 701, 702, 703, 704, 705,
+	698, 706, 707, 708, 709, 710, 711, 712, 713, 2045,
+	715, 716, 714, 717, 718, 942, 719, 720, 721, 722,
+	723, 894, 724, 0, 725, 726, 734, 735, 736, 727,
+	728, 730, 737, 729, 738, 739, 740, 741, 743, 742,
+	2046, 745, 746, 744, 747, 748, 749, 750, 2047, 751,
+	895, 752, 731, 732, 753, 754, 755, 943, 756, 757,
+	758, 759, 760, 761, 762, 763, 764, 896, 0, 766,
+	2048, 765, 767, 768, 769, 770, 771, 772, 773, 775,
+	733, 776, 777, 778, 783, 784, 785, 897, 779, 780,
+	781, 782, 787, 898, 788, 789, 790, 791, 2049, 792,
+	793, 0, 786, 774, 2050, 794, 795, 796, 797, 798,
+	799, 800, 801, 802, 803, 2051, 804, 899, 900, 901,
+	902, 2052, 817, 2053, 805, 807, 808, 809, 810, 903,
+	811, 812, 904, 2054, 813, 814, 815, 816, 806, 819,
+	820, 818, 2055, 2056, 821, 822, 823, 824, 826, 828,
+	829, 830, 825, 827, 831, 2057, 832, 2058, 0, 833,
+	834, 835, 905, 906, 907, 2059, 908, 838, 839, 836,
+	837, 840, 841, 844, 842, 843, 909, 847, 542, 848,
+	849, 850, 845, 846, 2060, 2061, 2062, 2063, 851, 852,
+	910, 853, 854, 855, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 3490, 0, 0, 0, 5476,
+	0, 0, 2310, 2311, 0, 2347, 2348, 2349, 2358, 2359,
+	2360, 5478, 3492, 3493, 3494, 3495, 3496, 3497, 3498, 3499,
+	3500, 3501, 3502, 3503, 3504, 3479, 2341, 3506, 3505, 0,
+	3487, 3507, 3510, 2342, 3508, 3509, 3478, 3511, 3512, 3513,
+	3514, 3515, 3516, 3517, 3518, 3519, 3520, 3521, 3522, 3485,
+	3523, 3524, 0, 3525, 3526, 3530, 3527, 3528, 3529, 3531,
+	3532, 3533, 3534, 3535, 3536, 3537, 3538, 3539, 3540, 3541,
+	3542, 3543, 2370, 3544, 0, 0, 3545, 3546, 3547, 3548,
+	3549, 3550, 3551, 2312, 3552, 3553, 3554, 3555, 3556, 3557,
+	3558, 3559, 3560, 3561, 2332, 3562, 3563, 3564, 3565, 3566,
+	3567, 3568, 3569, 3570, 2329, 3571, 3572, 3573, 3574, 3575,
+	2344, 3576, 3577, 0, 3578, 3579, 3580, 3581, 3582, 3583,
+	3584, 3585, 3586, 3588, 3587, 3589, 3590, 3591, 3592, 3593,
+	3594, 3595, 3596, 0, 0, 3598, 3599, 3600, 3602, 3603,
+	3606, 3597, 3601, 3604, 3605, 3607, 3608, 3609, 3610, 3611,
+	3612, 3613, 3614, 3615, 2343, 3616, 3617, 3618, 3619, 3620,
+	3621, 3622, 3623, 3624, 3625, 3626, 3627, 3628, 3629, 3630,
+	3631, 0, 3632, 3633, 3636, 3634, 3635, 3637, 3639, 3641,
+	3638, 3640, 3642, 3643, 3644, 3645, 3646, 3647, 3648, 3649,
+	3650, 3651, 3652, 0, 2335, 2336, 2337, 2338, 3653, 0,
+	3654, 3655, 0, 0, 2318, 3656, 0, 3657, 3661, 3662,
+	3658, 3659, 3660, 3663, 3664, 3665, 3666, 3667, 0, 3668,
+	3669, 3670, 3671, 3672, 3673, 3678, 3679, 3680, 3674, 3675,
+	3676, 3677, 3681, 3682, 0, 3683, 3684, 3685, 0, 3686,
+	3687, 0, 3688, 3689, 3690, 3691, 3692, 0, 3693, 3694,
+	3695, 3696, 3697, 3482, 3698, 3699, 3700, 3701, 3486, 3702,
+	3705, 3703, 3704, 3706, 3707, 3708, 0, 2340, 2346, 3709,
+	3710, 3714, 3716, 3715, 3713, 3712, 3711, 3717, 3718, 3719,
+	3720, 3721, 3722, 3723, 3724, 0, 3725, 0, 3726, 3727,
+	3729, 3484, 3730, 2362, 3731, 3732, 3733, 3734, 3735, 0,
+	2327, 2328, 3736, 3737, 3738, 3739, 3740, 3741, 3742, 3743,
+	3744, 3746, 3745, 3747, 3749, 3750, 3748, 3751, 3752, 3753,
+	3481, 0, 3754, 3755, 3756, 3757, 3758, 3759, 3760, 3761,
+	3762, 3763, 3764, 3765, 3766, 3767, 3768, 2333, 3769, 3770,
+	3772, 3774, 3771, 3773, 0, 3776, 3777, 3775, 0, 3778,
+	3779, 3780, 3781, 3782, 3783, 3784, 3785, 3786, 3787, 3788,
+	3789, 3790, 3792, 0, 3791, 3793, 2345, 3794, 3795, 3796,
+	3797, 3798, 3799, 3800, 3801, 3802, 3803, 3804, 3805, 3806,
+	3807, 3808, 3809, 3813, 3814, 3823, 3824, 3822, 3810, 3811,
+	3812, 3815, 3816, 3817, 2363, 3818, 3819, 3820, 3821, 3825,
+	3826, 3827, 3828, 3829, 3830, 0, 0, 3831, 0, 3832,
+	3833, 0, 3834, 3835, 3836, 3837, 3480, 0, 3838, 3839,
+	3840, 3841, 0, 0, 3842, 3843, 3844, 3489, 3845, 3846,
+	3847, 3848, 3849, 3850, 3851, 3852, 3853, 3854, 3855, 3856,
+	3857, 3858, 3859, 3860, 3861, 3862, 3863, 3864, 3865, 3866,
+	3867, 3868, 3869, 3870, 3871, 0, 3872, 3873, 3874, 3875,
+	3876, 3877, 3878, 0, 3879, 3880, 3881, 3882, 3883, 3884,
+	3885, 3886, 3887, 3888, 3889, 3890, 3891, 3893, 3892, 3894,
+	3895, 3896, 3897, 3898, 0, 3899, 3900, 3901, 0, 0,
+	0, 0, 0, 3902, 3903, 3905, 2339, 3906, 3907, 3908,
+	3909, 3910, 3911, 3904, 3912, 3913, 3914, 3915, 3916, 3917,
+	3918, 3919, 0, 3921, 3922, 3920, 3923, 3924, 3925, 3926,
+	3927, 3928, 3929, 3930, 3931, 3932, 2334, 3933, 3934, 3935,
+	3936, 3937, 3938, 3939, 3943, 3940, 3942, 3941, 3944, 3945,
+	0, 3946, 3947, 3948, 3949, 3950, 3951, 3952, 3953, 3954,
+	3955, 3956, 3957, 3958, 3959, 3960, 3961, 3962, 3963, 3964,
+	3483, 3965, 3966, 3967, 3968, 3969, 3970, 3971, 3973, 3972,
+	3974, 0, 3975, 3976, 3977, 3978, 3979, 3980, 3981, 3982,
+	3983, 3984, 3986, 3987, 3988, 3989, 3990, 3995, 3996, 3997,
+	3998, 3991, 3992, 3993, 3994, 4001, 4000, 4002, 4003, 4005,
+	4004, 4006, 4007, 4008, 2369, 3999, 3985, 4009, 4010, 4011,
+	4012, 4013, 4014, 4015, 4017, 4016, 4018, 4019, 4020, 4022,
+	4023, 4026, 4024, 4025, 0, 4021, 4029, 4027, 4030, 4031,
+	4032, 4033, 4034, 4035, 4036, 4037, 4038, 4039, 4040, 4041,
+	4042, 4028, 4043, 4044, 4045, 0, 4046, 4047, 4048, 4049,
+	4050, 4052, 4054, 4055, 4056, 4051, 4053, 4057, 4058, 4059,
+	4060, 0, 4061, 4062, 4063, 4064, 4065, 4066, 4068, 4069,
+	4070, 4071, 4067, 0, 4072, 4073, 4076, 4074, 4075, 4077,
+	4080, 3728, 4081, 4082, 4083, 4078, 4079, 4084, 0, 0,
+	0, 0, 0, 4085, 4086, 0, 4087, 2354, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 1980,
+	2324, 2325, 2331, 2357, 2330, 2326, 0, 2323, 2321, 2322,
+	2314, 2315, 2316, 2317, 2319, 2320, 367, 368, 370, 369,
+	371, 372, 373, 374, 1985, 375, 376, 1986, 1987, 1988,
+	0, 1989, 856, 1990, 1991, 1992, 378, 0, 377, 1993,
+	379, 380, 381, 926, 382, 383, 384, 385, 386, 387,
+	388, 389, 390, 857, 391, 858, 0, 392, 859, 393,
+	860, 1994, 861, 394, 395, 396, 397, 398, 399, 400,
+	401, 402, 403, 404, 1995, 1996, 0, 405, 862, 863,
+	864, 1997, 406, 407, 408, 409, 865, 1998, 927, 1999,
+	410, 411, 412, 413, 414, 415, 416, 417, 0, 2000,
+	419, 420, 421, 418, 422, 423, 2001, 424, 0, 425,
+	426, 427, 428, 429, 0, 430, 431, 2002, 432, 433,
+	434, 928, 435, 436, 437, 2003, 2004, 2006, 2005, 2007,
+	2008, 2009, 438, 439, 440, 441, 442, 0, 443, 445,
+	866, 867, 2010, 448, 450, 444, 446, 2011, 449, 447,
+	451, 452, 2012, 453, 454, 455, 456, 457, 0, 2013,
+	2014, 458, 459, 460, 461, 2015, 462, 463, 464, 466,
+	465, 2016, 467, 468, 469, 2017, 470, 471, 868, 472,
+	473, 474, 476, 478, 475, 477, 479, 480, 481, 482,
+	483, 869, 870, 484, 485, 2018, 362, 2019, 0, 0,
+	0, 0, 486, 487, 488, 871, 0, 0, 0, 489,
+	2020, 491, 495, 496, 492, 493, 494, 497, 2021, 490,
+	498, 499, 2022, 929, 500, 501, 502, 872, 873, 503,
+	504, 505, 506, 507, 508, 509, 510, 511, 2023, 512,
+	513, 874, 2024, 875, 514, 2025, 515, 516, 517, 518,
+	519, 520, 521, 876, 877, 878, 630, 931, 522, 523,
+	524, 525, 2026, 526, 527, 528, 529, 530, 531, 532,
+	0, 0, 0, 533, 534, 535, 536, 2027, 364, 363,
+	365, 930, 879, 537, 631, 538, 539, 880, 881, 2028,
+	882, 2029, 540, 541, 544, 932, 883, 933, 543, 545,
+	546, 934, 547, 0, 0, 0, 548, 549, 550, 551,
+	552, 553, 554, 2030, 555, 557, 556, 2031, 559, 884,
+	558, 935, 560, 561, 936, 2032, 562, 563, 564, 565,
+	566, 567, 572, 2033, 2034, 568, 569, 570, 571, 573,
+	574, 0, 575, 576, 578, 581, 577, 579, 580, 582,
+	583, 596, 597, 598, 584, 585, 586, 587, 588, 589,
+	590, 591, 592, 593, 594, 595, 600, 0, 599, 937,
+	0, 601, 602, 603, 604, 605, 606, 612, 615, 617,
+	618, 613, 614, 616, 619, 620, 621, 623, 624, 609,
+	610, 611, 938, 622, 607, 2035, 608, 366, 939, 625,
+	626, 627, 628, 2036, 885, 629, 886, 632, 633, 2037,
+	0, 634, 0, 635, 636, 2038, 2039, 638, 639, 640,
+	2040, 2041, 641, 642, 887, 940, 643, 941, 888, 644,
+	645, 637, 646, 647, 648, 649, 650, 651, 652, 653,
+	654, 655, 656, 657, 2042, 658, 659, 889, 660, 661,
+	662, 663, 664, 890, 665, 666, 667, 891, 668, 892,
+	669, 670, 671, 2043, 672, 673, 674, 0, 675, 676,
+	677, 678, 679, 680, 681, 682, 683, 684, 893, 685,
+	686, 688, 687, 689, 690, 2044, 691, 692, 0, 693,
+	694, 695, 0, 0, 0, 0, 0, 696, 697, 699,
+	0, 700, 701, 702, 703, 704, 705, 698, 706, 707,
+	708, 709, 710, 711, 712, 713, 2045, 715, 716, 714,
+	717, 718, 942, 719, 720, 721, 722, 723, 894, 724,
+	0, 725, 726, 734, 735, 736, 727, 728, 730, 737,
+	729, 738, 739, 740, 741, 743, 742, 2046, 745, 746,
+	744, 747, 748, 749, 750, 2047, 751, 895, 752, 731,
+	732, 753, 754, 755, 943, 756, 757, 758, 759, 760,
+	761, 762, 763, 764, 896, 0, 766, 2048, 765, 767,
+	768, 769, 770, 771, 772, 773, 775, 733, 776, 777,
+	778, 783, 784, 785, 897, 779, 780, 781, 782, 787,
+	898, 788, 789, 790, 791, 2049, 792, 793, 0, 786,
+	774, 2050, 794, 795, 796, 797, 798, 799, 800, 801,
+	802, 803, 2051, 804, 899, 900, 901, 902, 2052, 817,
+	2053, 805, 807, 808, 809, 810, 903, 811, 812, 904,
+	2054, 813, 814, 815, 816, 806, 819, 820, 818, 2055,
+	2056, 821, 822, 823, 824, 826, 828, 829, 830, 825,
+	827, 831, 2057, 832, 2058, 0, 833, 834, 835, 905,
+	906, 907, 2059, 908, 838, 839, 836, 837, 840, 841,
+	844, 842, 843, 909, 847, 542, 848, 849, 850, 845,
+	846, 2060, 2061, 2062, 2063, 851, 852, 910, 853, 854,
+	855, 1980, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 367, 368,
+	370, 369, 371, 372, 373, 374, 1985, 375, 376, 1986,
+	1987, 1988, 6026, 1989, 856, 1990, 1991, 1992, 378, 0,
+	377, 1993, 379, 380, 381, 926, 382, 383, 384, 385,
+	386, 387, 388, 389, 390, 857, 391, 858, 0, 392,
+	859, 393, 860, 1994, 861, 394, 395, 396, 397, 398,
+	399, 400, 401, 402, 403, 404, 1995, 1996, 0, 405,
+	862, 863, 864, 1997, 406, 407, 408, 409, 865, 1998,
+	927, 1999, 410, 411, 412, 413, 414, 415, 416, 417,
+	0, 2000, 419, 420, 421, 418, 422, 423, 2001, 424,
+	0, 425, 426, 427, 428, 429, 0, 430, 431, 2002,
+	432, 433, 434, 928, 435, 436, 437, 2003, 2004, 2006,
+	2005, 2007, 2008, 2009, 438, 439, 440, 441, 442, 0,
+	443, 445, 866, 867, 2010, 448, 450, 444, 446, 2011,
+	449, 447, 451, 452, 2012, 453, 454, 455, 456, 457,
+	0, 2013, 2014, 458, 459, 460, 461, 2015, 462, 463,
+	464, 466, 465, 2016, 467, 468, 469, 2017, 470, 471,
+	868, 472, 473, 474, 476, 478, 475, 477, 479, 480,
+	481, 482, 483, 869, 870, 484, 485, 2018, 362, 2019,
+	0, 0, 0, 0, 486, 487, 488, 871, 0, 0,
+	0, 489, 2020, 491, 495, 496, 492, 493, 494, 497,
+	2021, 490, 498, 499, 2022, 929, 500, 501, 502, 872,
+	873, 503, 504, 505, 506, 507, 508, 509, 510, 511,
+	2023, 512, 513, 874, 2024, 875, 514, 2025, 515, 516,
+	517, 518, 519, 520, 521, 876, 877, 878, 630, 931,
+	522, 523, 524, 525, 2026, 526, 527, 528, 529, 530,
+	531, 532, 0, 0, 0, 533, 534, 535, 536, 2027,
+	364, 363, 365, 930, 879, 537, 631, 538, 539, 880,
+	881, 2028, 882, 2029, 540, 541, 544, 932, 883, 933,
+	543, 545, 546, 934, 547, 0, 0, 0, 548, 549,
+	550, 551, 552, 553, 554, 2030, 555, 557, 556, 2031,
+	559, 884, 558, 935, 560, 561, 936, 2032, 562, 563,
+	564, 565, 566, 567, 572, 2033, 2034, 568, 569, 570,
+	571, 573, 574, 0, 575, 576, 578, 581, 577, 579,
+	580, 582, 583, 596, 597, 598, 584, 585, 586, 587,
+	588, 589, 590, 591, 592, 593, 594, 595, 600, 0,
+	599, 937, 0, 601, 602, 603, 604, 605, 606, 612,
+	615, 617, 618, 613, 614, 616, 619, 620, 621, 623,
+	624, 609, 610, 611, 938, 622, 607, 2035, 608, 366,
+	939, 625, 626, 627, 628, 2036, 885, 629, 886, 632,
+	633, 2037, 0, 634, 0, 635, 636, 2038, 2039, 638,
+	639, 640, 2040, 2041, 641, 642, 887, 940, 643, 941,
+	888, 644, 645, 637, 646, 647, 648, 649, 650, 651,
+	652, 653, 654, 655, 656, 657, 2042, 658, 659, 889,
+	660, 661, 662, 663, 664, 890, 665, 666, 667, 891,
+	668, 892, 669, 670, 671, 2043, 672, 673, 674, 0,
+	675, 676, 677, 678, 679, 680, 681, 682, 683, 684,
+	893, 685, 686, 688, 687, 689, 690, 2044, 691, 692,
+	0, 693, 694, 695, 0, 0, 0, 0, 0, 696,
+	697, 699, 0, 700, 701, 702, 703, 704, 705, 698,
+	706, 707, 708, 709, 710, 711, 712, 713, 2045, 715,
+	716, 714, 717, 718, 942, 719, 720, 721, 722, 723,
+	894, 724, 0, 725, 726, 734, 735, 736, 727, 728,
+	730, 737, 729, 738, 739, 740, 741, 743, 742, 2046,
+	745, 746, 744, 747, 748, 749, 750, 2047, 751, 895,
+	752, 731, 732, 753, 754, 755, 943, 756, 757, 758,
+	759, 760, 761, 762, 763, 764, 896, 0, 766, 2048,
+	765, 767, 768, 769, 770, 771, 772, 773, 775, 733,
+	776, 777, 778, 783, 784, 785, 897, 779, 780, 781,
+	782, 787, 898, 788, 789, 790, 791, 2049, 792, 793,
+	0, 786, 774, 2050, 794, 795, 796, 797, 798, 799,
+	800, 801, 802, 803, 2051, 804, 899, 900, 901, 902,
+	2052, 817, 2053, 805, 807, 808, 809, 810, 903, 811,
+	812, 904, 2054, 813, 814, 815, 816, 806, 819, 820,
+	818, 2055, 2056, 821, 822, 823, 824, 826, 828, 829,
+	830, 825, 827, 831, 2057, 832, 2058, 0, 833, 834,
+	835, 905, 906, 907, 2059, 908, 838, 839, 836, 837,
+	840, 841, 844, 842, 843, 909, 847, 542, 848, 849,
+	850, 845, 846, 2060, 2061, 2062, 2063, 851, 852, 910,
+	853, 854, 855, 1980, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	367, 368, 370, 369, 371, 372, 373, 374, 1985, 375,
+	376, 1986, 1987, 1988, 6024, 1989, 856, 1990, 1991, 1992,
+	378, 0, 377, 1993, 379, 380, 381, 926, 382, 383,
+	384, 385, 386, 387, 388, 389, 390, 857, 391, 858,
+	0, 392, 859, 393, 860, 1994, 861, 394, 395, 396,
+	397, 398, 399, 400, 401, 402, 403, 404, 1995, 1996,
+	0, 405, 862, 863, 864, 1997, 406, 407, 408, 409,
+	865, 1998, 927, 1999, 410, 411, 412, 413, 414, 415,
+	416, 417, 0, 2000, 419, 420, 421, 418, 422, 423,
+	2001, 424, 0, 425, 426, 427, 428, 429, 0, 430,
+	431, 2002, 432, 433, 434, 928, 435, 436, 437, 2003,
+	2004, 2006, 2005, 2007, 2008, 2009, 438, 439, 440, 441,
+	442, 0, 443, 445, 866, 867, 2010, 448, 450, 444,
+	446, 2011, 449, 447, 451, 452, 2012, 453, 454, 455,
+	456, 457, 0, 2013, 2014, 458, 459, 460, 461, 2015,
+	462, 463, 464, 466, 465, 2016, 467, 468, 469, 2017,
+	470, 471, 868, 472, 473, 474, 476, 478, 475, 477,
+	479, 480, 481, 482, 483, 869, 870, 484, 485, 2018,
+	362, 2019, 0, 0, 0, 0, 486, 487, 488, 871,
+	0, 0, 0, 489, 2020, 491, 495, 496, 492, 493,
+	494, 497, 2021, 490, 498, 499, 2022, 929, 500, 501,
+	502, 872, 873, 503, 504, 505, 506, 507, 508, 509,
+	510, 511, 2023, 512, 513, 874, 2024, 875, 514, 2025,
+	515, 516, 517, 518, 519, 520, 521, 876, 877, 878,
+	630, 931, 522, 523, 524, 525, 2026, 526, 527, 528,
+	529, 530, 531, 532, 0, 0, 0, 533, 534, 535,
+	536, 2027, 364, 363, 365, 930, 879, 537, 631, 538,
+	539, 880, 881, 2028, 882, 2029, 540, 541, 544, 932,
+	883, 933, 543, 545, 546, 934, 547, 0, 0, 0,
+	548, 549, 550, 551, 552, 553, 554, 2030, 555, 557,
+	556, 2031, 559, 884, 558, 935, 560, 561, 936, 2032,
+	562, 563, 564, 565, 566, 567, 572, 2033, 2034, 568,
+	569, 570, 571, 573, 574, 0, 575, 576, 578, 581,
+	577, 579, 580, 582, 583, 596, 597, 598, 584, 585,
+	586, 587, 588, 589, 590, 591, 592, 593, 594, 595,
+	600, 0, 599, 937, 0, 601, 602, 603, 604, 605,
+	606, 612, 615, 617, 618, 613, 614, 616, 619, 620,
+	621, 623, 624, 609, 610, 611, 938, 622, 607, 2035,
+	608, 366, 939, 625, 626, 627, 628, 2036, 885, 629,
+	886, 632, 633, 2037, 0, 634, 0, 635, 636, 2038,
+	2039, 638, 639, 640, 2040, 2041, 641, 642, 887, 940,
+	643, 941, 888, 644, 645, 637, 646, 647, 648, 649,
+	650, 651, 652, 653, 654, 655, 656, 657, 2042, 658,
+	659, 889, 660, 661, 662, 663, 664, 890, 665, 666,
+	667, 891, 668, 892, 669, 670, 671, 2043, 672, 673,
+	674, 0, 675, 676, 677, 678, 679, 680, 681, 682,
+	683, 684, 893, 685, 686, 688, 687, 689, 690, 2044,
+	691, 692, 0, 693, 694, 695, 0, 0, 0, 0,
+	0, 696, 697, 699, 0, 700, 701, 702, 703, 704,
+	705, 698, 706, 707, 708, 709, 710, 711, 712, 713,
+	2045, 715, 716, 714, 717, 718, 942, 719, 720, 721,
+	722, 723, 894, 724, 0, 725, 726, 734, 735, 736,
+	727, 728, 730, 737, 729, 738, 739, 740, 741, 743,
+	742, 2046, 745, 746, 744, 747, 748, 749, 750, 2047,
+	751, 895, 752, 731, 732, 753, 754, 755, 943, 756,
+	757, 758, 759, 760, 761, 762, 763, 764, 896, 0,
+	766, 2048, 765, 767, 768, 769, 770, 771, 772, 773,
+	775, 733, 776, 777, 778, 783, 784, 785, 897, 779,
+	780, 781, 782, 787, 898, 788, 789, 790, 791, 2049,
+	792, 793, 0, 786, 774, 2050, 794, 795, 796, 797,
+	798, 799, 800, 801, 802, 803, 2051, 804, 899, 900,
+	901, 902, 2052, 817, 2053, 805, 807, 808, 809, 810,
+	903, 811, 812, 904, 2054, 813, 814, 815, 816, 806,
+	819, 820, 818, 2055, 2056, 821, 822, 823, 824, 826,
+	828, 829, 830, 825, 827, 831, 2057, 832, 2058, 0,
+	833, 834, 835, 905, 906, 907, 2059, 908, 838, 839,
+	836, 837, 840, 841, 844, 842, 843, 909, 847, 542,
+	848, 849, 850, 845, 846, 2060, 2061, 2062, 2063, 851,
+	852, 910, 853, 854, 855, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 1980, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	6406, 367, 368, 370, 369, 371, 372, 373, 374, 1985,
+	375, 376, 1986, 1987, 1988, 0, 1989, 856, 1990, 1991,
+	1992, 378, 0, 377, 1993, 379, 380, 381, 926, 382,
+	383, 384, 385, 386, 387, 388, 389, 390, 857, 391,
+	858, 0, 392, 859, 393, 860, 1994, 861, 394, 395,
+	396, 397, 398, 399, 400, 401, 402, 403, 404, 1995,
+	1996, 0, 405, 862, 863, 864, 1997, 406, 407, 408,
+	409, 865, 1998, 927, 1999, 410, 411, 412, 413, 414,
+	415, 416, 417, 0, 2000, 419, 420, 421, 418, 422,
+	423, 2001, 424, 0, 425, 426, 427, 428, 429, 0,
+	430, 431, 2002, 432, 433, 434, 928, 435, 436, 437,
+	2003, 2004, 2006, 2005, 2007, 2008, 2009, 438, 439, 440,
+	441, 442, 0, 443, 445, 866, 867, 2010, 448, 450,
+	444, 446, 2011, 449, 447, 451, 452, 2012, 453, 454,
+	455, 456, 457, 0, 2013, 2014, 458, 459, 460, 461,
+	2015, 462, 463, 464, 466, 465, 2016, 467, 468, 469,
+	2017, 470, 471, 868, 472, 473, 474, 476, 478, 475,
+	477, 479, 480, 481, 482, 483, 869, 870, 484, 485,
+	2018, 362, 2019, 0, 0, 0, 0, 486, 487, 488,
+	871, 0, 0, 0, 489, 2020, 491, 495, 496, 492,
+	493, 494, 497, 2021, 490, 498, 499, 2022, 929, 500,
+	501, 502, 872, 873, 503, 504, 505, 506, 507, 508,
+	509, 510, 511, 2023, 512, 513, 874, 2024, 875, 514,
+	2025, 515, 516, 517, 518, 519, 520, 521, 876, 877,
+	878, 630, 931, 522, 523, 524, 525, 2026, 526, 527,
+	528, 529, 530, 531, 532, 0, 0, 0, 533, 534,
+	535, 536, 2027, 364, 363, 365, 930, 879, 537, 631,
+	538, 539, 880, 881, 2028, 882, 2029, 540, 541, 544,
+	932, 883, 933, 543, 545, 546, 934, 547, 0, 0,
+	0, 548, 549, 550, 551, 552, 553, 554, 2030, 555,
+	557, 556, 2031, 559, 884, 558, 935, 560, 561, 936,
+	2032, 562, 563, 564, 565, 566, 567, 572, 2033, 2034,
+	568, 569, 570, 571, 573, 574, 0, 575, 576, 578,
+	581, 577, 579, 580, 582, 583, 596, 597, 598, 584,
+	585, 586, 587, 588, 589, 590, 591, 592, 593, 594,
+	595, 600, 0, 599, 937, 0, 601, 602, 603, 604,
+	605, 606, 612, 615, 617, 618, 613, 614, 616, 619,
+	620, 621, 623, 624, 609, 610, 611, 938, 622, 607,
+	2035, 608, 366, 939, 625, 626, 627, 628, 2036, 885,
+	629, 886, 632, 633, 2037, 0, 634, 0, 635, 636,
+	2038, 2039, 638, 639, 640, 2040, 2041, 641, 642, 887,
+	940, 643, 941, 888, 644, 645, 637, 646, 647, 648,
+	649, 650, 651, 652, 653, 654, 655, 656, 657, 2042,
+	658, 659, 889, 660, 661, 662, 663, 664, 890, 665,
+	666, 667, 891, 668, 892, 669, 670, 671, 2043, 672,
+	673, 674, 0, 675, 676, 677, 678, 679, 680, 681,
+	682, 683, 684, 893, 685, 686, 688, 687, 689, 690,
+	2044, 691, 692, 0, 693, 694, 695, 0, 0, 0,
+	0, 0, 696, 697, 699, 0, 700, 701, 702, 703,
+	704, 705, 698, 706, 707, 708, 709, 710, 711, 712,
+	713, 2045, 715, 716, 714, 717, 718, 942, 719, 720,
+	721, 722, 723, 894, 724, 0, 725, 726, 734, 735,
+	736, 727, 728, 730, 737, 729, 738, 739, 740, 741,
+	743, 742, 2046, 745, 746, 744, 747, 748, 749, 750,
+	2047, 751, 895, 752, 731, 732, 753, 754, 755, 943,
+	756, 757, 758, 759, 760, 761, 762, 763, 764, 896,
+	0, 766, 2048, 765, 767, 768, 769, 770, 771, 772,
+	773, 775, 733, 776, 777, 778, 783, 784, 785, 897,
+	779, 780, 781, 782, 787, 898, 788, 789, 790, 791,
+	2049, 792, 793, 0, 786, 774, 2050, 794, 795, 796,
+	797, 798, 799, 800, 801, 802, 803, 2051, 804, 899,
+	900, 901, 902, 2052, 817, 2053, 805, 807, 808, 809,
+	810, 903, 811, 812, 904, 2054, 813, 814, 815, 816,
+	806, 819, 820, 818, 2055, 2056, 821, 822, 823, 824,
+	826, 828, 829, 830, 825, 827, 831, 2057, 832, 2058,
+	0, 833, 834, 835, 905, 906, 907, 2059, 908, 838,
+	839, 836, 837, 840, 841, 844, 842, 843, 909, 847,
+	542, 848, 849, 850, 845, 846, 2060, 2061, 2062, 2063,
+	851, 852, 910, 853, 854, 855, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 1980, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 6189, 367, 368, 370, 369, 371, 372, 373, 374,
+	1985, 375, 376, 1986, 1987, 1988, 0, 1989, 856, 1990,
+	1991, 1992, 378, 0, 377, 1993, 379, 380, 381, 926,
+	382, 383, 384, 385, 386, 387, 388, 389, 390, 857,
+	391, 858, 0, 392, 859, 393, 860, 1994, 861, 394,
+	395, 396, 397, 398, 399, 400, 401, 402, 403, 404,
+	1995, 1996, 0, 405, 862, 863, 864, 1997, 406, 407,
+	408, 409, 865, 1998, 927, 1999, 410, 411, 412, 413,
+	414, 415, 416, 417, 0, 2000, 419, 420, 421, 418,
+	422, 423, 2001, 424, 0, 425, 426, 427, 428, 429,
+	0, 430, 431, 2002, 432, 433, 434, 928, 435, 436,
+	437, 2003, 2004, 2006, 2005, 2007, 2008, 2009, 438, 439,
+	440, 441, 442, 0, 443, 445, 866, 867, 2010, 448,
+	450, 444, 446, 2011, 449, 447, 451, 452, 2012, 453,
+	454, 455, 456, 457, 0, 2013, 2014, 458, 459, 460,
+	461, 2015, 462, 463, 464, 466, 465, 2016, 467, 468,
+	469, 2017, 470, 471, 868, 472, 473, 474, 476, 478,
+	475, 477, 479, 480, 481, 482, 483, 869, 870, 484,
+	485, 2018, 362, 2019, 0, 0, 0, 0, 486, 487,
+	488, 871, 0, 0, 0, 489, 2020, 491, 495, 496,
+	492, 493, 494, 497, 2021, 490, 498, 499, 2022, 929,
+	500, 501, 502, 872, 873, 503, 504, 505, 506, 507,
+	508, 509, 510, 511, 2023, 512, 513, 874, 2024, 875,
+	514, 2025, 515, 516, 517, 518, 519, 520, 521, 876,
+	877, 878, 630, 931, 522, 523, 524, 525, 2026, 526,
+	527, 528, 529, 530, 531, 532, 0, 0, 0, 533,
+	534, 535, 536, 2027, 364, 363, 365, 930, 879, 537,
+	631, 538, 539, 880, 881, 2028, 882, 2029, 540, 541,
+	544, 932, 883, 933, 543, 545, 546, 934, 547, 0,
+	0, 0, 548, 549, 550, 551, 552, 553, 554, 2030,
+	555, 557, 556, 2031, 559, 884, 558, 935, 560, 561,
+	936, 2032, 562, 563, 564, 565, 566, 567, 572, 2033,
+	2034, 568, 569, 570, 571, 573, 574, 0, 575, 576,
+	578, 581, 577, 579, 580, 582, 583, 596, 597, 598,
+	584, 585, 586, 587, 588, 589, 590, 591, 592, 593,
+	594, 595, 600, 0, 599, 937, 0, 601, 602, 603,
+	604, 605, 606, 612, 615, 617, 618, 613, 614, 616,
+	619, 620, 621, 623, 624, 609, 610, 611, 938, 622,
+	607, 2035, 608, 366, 939, 625, 626, 627, 628, 2036,
+	885, 629, 886, 632, 633, 2037, 0, 634, 0, 635,
+	636, 2038, 2039, 638, 639, 640, 2040, 2041, 641, 642,
+	887, 940, 643, 941, 888, 644, 645, 637, 646, 647,
+	648, 649, 650, 651, 652, 653, 654, 655, 656, 657,
+	2042, 658, 659, 889, 660, 661, 662, 663, 664, 890,
+	665, 666, 667, 891, 668, 892, 669, 670, 671, 2043,
+	672, 673, 674, 0, 675, 676, 677, 678, 679, 680,
+	681, 682, 683, 684, 893, 685, 686, 688, 687, 689,
+	690, 2044, 691, 692, 0, 693, 694, 695, 0, 0,
+	0, 0, 0, 696, 697, 699, 0, 700, 701, 702,
+	703, 704, 705, 698, 706, 707, 708, 709, 710, 711,
+	712, 713, 2045, 715, 716, 714, 717, 718, 942, 719,
+	720, 721, 722, 723, 894, 724, 0, 725, 726, 734,
+	735, 736, 727, 728, 730, 737, 729, 738, 739, 740,
+	741, 743, 742, 2046, 745, 746, 744, 747, 748, 749,
+	750, 2047, 751, 895, 752, 731, 732, 753, 754, 755,
+	943, 756, 757, 758, 759, 760, 761, 762, 763, 764,
+	896, 0, 766, 2048, 765, 767, 768, 769, 770, 771,
+	772, 773, 775, 733, 776, 777, 778, 783, 784, 785,
+	897, 779, 780, 781, 782, 787, 898, 788, 789, 790,
+	791, 2049, 792, 793, 0, 786, 774, 2050, 794, 795,
+	796, 797, 798, 799, 800, 801, 802, 803, 2051, 804,
+	899, 900, 901, 902, 2052, 817, 2053, 805, 807, 808,
+	809, 810, 903, 811, 812, 904, 2054, 813, 814, 815,
+	816, 806, 819, 820, 818, 2055, 2056, 821, 822, 823,
+	824, 826, 828, 829, 830, 825, 827, 831, 2057, 832,
+	2058, 0, 833, 834, 835, 905, 906, 907, 2059, 908,
+	838, 839, 836, 837, 840, 841, 844, 842, 843, 909,
+	847, 542, 848, 849, 850, 845, 846, 2060, 2061, 2062,
+	2063, 851, 852, 910, 853, 854, 855, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 1980, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 5665, 367, 368, 370, 369, 371, 372, 373,
+	374, 1985, 375, 376, 1986, 1987, 1988, 0, 1989, 856,
+	1990, 1991, 1992, 378, 0, 377, 1993, 379, 380, 381,
+	926, 382, 383, 384, 385, 386, 387, 388, 389, 390,
+	857, 391, 858, 0, 392, 859, 393, 860, 1994, 861,
+	394, 395, 396, 397, 398, 399, 400, 401, 402, 403,
+	404, 1995, 1996, 0, 405, 862, 863, 864, 1997, 406,
+	407, 408, 409, 865, 1998, 927, 1999, 410, 411, 412,
+	413, 414, 415, 416, 417, 0, 2000, 419, 420, 421,
+	418, 422, 423, 2001, 424, 0, 425, 426, 427, 428,
+	429, 0, 430, 431, 2002, 432, 433, 434, 928, 435,
+	436, 437, 2003, 2004, 2006, 2005, 2007, 2008, 2009, 438,
+	439, 440, 441, 442, 0, 443, 445, 866, 867, 2010,
+	448, 450, 444, 446, 2011, 449, 447, 451, 452, 2012,
+	453, 454, 455, 456, 457, 0, 2013, 2014, 458, 459,
+	460, 461, 2015, 462, 463, 464, 466, 465, 2016, 467,
+	468, 469, 2017, 470, 471, 868, 472, 473, 474, 476,
+	478, 475, 477, 479, 480, 481, 482, 483, 869, 870,
+	484, 485, 2018, 362, 2019, 0, 0, 0, 0, 486,
+	487, 488, 871, 0, 0, 0, 489, 2020, 491, 495,
+	496, 492, 493, 494, 497, 2021, 490, 498, 499, 2022,
+	929, 500, 501, 502, 872, 873, 503, 504, 505, 506,
+	507, 508, 509, 510, 511, 2023, 512, 513, 874, 2024,
+	875, 514, 2025, 515, 516, 517, 518, 519, 520, 521,
+	876, 877, 878, 630, 931, 522, 523, 524, 525, 2026,
+	526, 527, 528, 529, 530, 531, 532, 0, 0, 0,
+	533, 534, 535, 536, 2027, 364, 363, 365, 930, 879,
+	537, 631, 538, 539, 880, 881, 2028, 882, 2029, 540,
+	541, 544, 932, 883, 933, 543, 545, 546, 934, 547,
+	0, 0, 0, 548, 549, 550, 551, 552, 553, 554,
+	2030, 555, 557, 556, 2031, 559, 884, 558, 935, 560,
+	561, 936, 2032, 562, 563, 564, 565, 566, 567, 572,
+	2033, 2034, 568, 569, 570, 571, 573, 574, 0, 575,
+	576, 578, 581, 577, 579, 580, 582, 583, 596, 597,
+	598, 584, 585, 586, 587, 588, 589, 590, 591, 592,
+	593, 594, 595, 600, 0, 599, 937, 0, 601, 602,
+	603, 604, 605, 606, 612, 615, 617, 618, 613, 614,
+	616, 619, 620, 621, 623, 624, 609, 610, 611, 938,
+	622, 607, 2035, 608, 366, 939, 625, 626, 627, 628,
+	2036, 885, 629, 886, 632, 633, 2037, 0, 634, 0,
+	635, 636, 2038, 2039, 638, 639, 640, 2040, 2041, 641,
+	642, 887, 940, 643, 941, 888, 644, 645, 637, 646,
+	647, 648, 649, 650, 651, 652, 653, 654, 655, 656,
+	657, 2042, 658, 659, 889, 660, 661, 662, 663, 664,
+	890, 665, 666, 667, 891, 668, 892, 669, 670, 671,
+	2043, 672, 673, 674, 0, 675, 676, 677, 678, 679,
+	680, 681, 682, 683, 684, 893, 685, 686, 688, 687,
+	689, 690, 2044, 691, 692, 0, 693, 694, 695, 0,
+	0, 0, 0, 0, 696, 697, 699, 0, 700, 701,
+	702, 703, 704, 705, 698, 706, 707, 708, 709, 710,
+	711, 712, 713, 2045, 715, 716, 714, 717, 718, 942,
+	719, 720, 721, 722, 723, 894, 724, 0, 725, 726,
+	734, 735, 736, 727, 728, 730, 737, 729, 738, 739,
+	740, 741, 743, 742, 2046, 745, 746, 744, 747, 748,
+	749, 750, 2047, 751, 895, 752, 731, 732, 753, 754,
+	755, 943, 756, 757, 758, 759, 760, 761, 762, 763,
+	764, 896, 0, 766, 2048, 765, 767, 768, 769, 770,
+	771, 772, 773, 775, 733, 776, 777, 778, 783, 784,
+	785, 897, 779, 780, 781, 782, 787, 898, 788, 789,
+	790, 791, 2049, 792, 793, 0, 786, 774, 2050, 794,
+	795, 796, 797, 798, 799, 800, 801, 802, 803, 2051,
+	804, 899, 900, 901, 902, 2052, 817, 2053, 805, 807,
+	808, 809, 810, 903, 811, 812, 904, 2054, 813, 814,
+	815, 816, 806, 819, 820, 818, 2055, 2056, 821, 822,
+	823, 824, 826, 828, 829, 830, 825, 827, 831, 2057,
+	832, 2058, 0, 833, 834, 835, 905, 906, 907, 2059,
+	908, 838, 839, 836, 837, 840, 841, 844, 842, 843,
+	909, 847, 542, 848, 849, 850, 845, 846, 2060, 2061,
+	2062, 2063, 851, 852, 910, 853, 854, 855, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 1980, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 5494, 367, 368, 370, 369, 371, 372,
+	373, 374, 1985, 375, 376, 1986, 1987, 1988, 0, 1989,
+	856, 1990, 1991, 1992, 378, 0, 377, 1993, 379, 380,
+	381, 926, 382, 383, 384, 385, 386, 387, 388, 389,
+	390, 857, 391, 858, 0, 392, 859, 393, 860, 1994,
+	861, 394, 395, 396, 397, 398, 399, 400, 401, 402,
+	403, 404, 1995, 1996, 0, 405, 862, 863, 864, 1997,
+	406, 407, 408, 409, 865, 1998, 927, 1999, 410, 411,
+	412, 413, 414, 415, 416, 417, 0, 2000, 419, 420,
+	421, 418, 422, 423, 2001, 424, 0, 425, 426, 427,
+	428, 429, 0, 430, 431, 2002, 432, 433, 434, 928,
+	435, 436, 437, 2003, 2004, 2006, 2005, 2007, 2008, 2009,
+	438, 439, 440, 441, 442, 0, 443, 445, 866, 867,
+	2010, 448, 450, 444, 446, 2011, 449, 447, 451, 452,
+	2012, 453, 454, 455, 456, 457, 0, 2013, 2014, 458,
+	459, 460, 461, 2015, 462, 463, 464, 466, 465, 2016,
+	467, 468, 469, 2017, 470, 471, 868, 472, 473, 474,
+	476, 478, 475, 477, 479, 480, 481, 482, 483, 869,
+	870, 484, 485, 2018, 362, 2019, 0, 0, 0, 0,
+	486, 487, 488, 871, 0, 0, 0, 489, 2020, 491,
+	495, 496, 492, 493, 494, 497, 2021, 490, 498, 499,
+	2022, 929, 500, 501, 502, 872, 873, 503, 504, 505,
+	506, 507, 508, 509, 510, 511, 2023, 512, 513, 874,
+	2024, 875, 514, 2025, 515, 516, 517, 518, 519, 520,
+	521, 876, 877, 878, 630, 931, 522, 523, 524, 525,
+	2026, 526, 527, 528, 529, 530, 531, 532, 0, 0,
+	0, 533, 534, 535, 536, 2027, 364, 363, 365, 930,
+	879, 537, 631, 538, 539, 880, 881, 2028, 882, 2029,
+	540, 541, 544, 932, 883, 933, 543, 545, 546, 934,
+	547, 0, 0, 0, 548, 549, 550, 551, 552, 553,
+	554, 2030, 555, 557, 556, 2031, 559, 884, 558, 935,
+	560, 561, 936, 2032, 562, 563, 564, 565, 566, 567,
+	572, 2033, 2034, 568, 569, 570, 571, 573, 574, 0,
+	575, 576, 578, 581, 577, 579, 580, 582, 583, 596,
+	597, 598, 584, 585, 586, 587, 588, 589, 590, 591,
+	592, 593, 594, 595, 600, 0, 599, 937, 0, 601,
+	602, 603, 604, 605, 606, 612, 615, 617, 618, 613,
+	614, 616, 619, 620, 621, 623, 624, 609, 610, 611,
+	938, 622, 607, 2035, 608, 366, 939, 625, 626, 627,
+	628, 2036, 885, 629, 886, 632, 633, 2037, 0, 634,
+	0, 635, 636, 2038, 2039, 638, 639, 640, 2040, 2041,
+	641, 642, 887, 940, 643, 941, 888, 644, 645, 637,
+	646, 647, 648, 649, 650, 651, 652, 653, 654, 655,
+	656, 657, 2042, 658, 659, 889, 660, 661, 662, 663,
+	664, 890, 665, 666, 667, 891, 668, 892, 669, 670,
+	671, 2043, 672, 673, 674, 0, 675, 676, 677, 678,
+	679, 680, 681, 682, 683, 684, 893, 685, 686, 688,
+	687, 689, 690, 2044, 691, 692, 0, 693, 694, 695,
+	0, 0, 0, 0, 0, 696, 697, 699, 0, 700,
+	701, 702, 703, 704, 705, 698, 706, 707, 708, 709,
+	710, 711, 712, 713, 2045, 715, 716, 714, 717, 718,
+	942, 719, 720, 721, 722, 723, 894, 724, 0, 725,
+	726, 734, 735, 736, 727, 728, 730, 737, 729, 738,
+	739, 740, 741, 743, 742, 2046, 745, 746, 744, 747,
+	748, 749, 750, 2047, 751, 895, 752, 731, 732, 753,
+	754, 755, 943, 756, 757, 758, 759, 760, 761, 762,
+	763, 764, 896, 0, 766, 2048, 765, 767, 768, 769,
+	770, 771, 772, 773, 775, 733, 776, 777, 778, 783,
+	784, 785, 897, 779, 780, 781, 782, 787, 898, 788,
+	789, 790, 791, 2049, 792, 793, 0, 786, 774, 2050,
+	794, 795, 796, 797, 798, 799, 800, 801, 802, 803,
+	2051, 804, 899, 900, 901, 902, 2052, 817, 2053, 805,
+	807, 808, 809, 810, 903, 811, 812, 904, 2054, 813,
+	814, 815, 816, 806, 819, 820, 818, 2055, 2056, 821,
+	822, 823, 824, 826, 828, 829, 830, 825, 827, 831,
+	2057, 832, 2058, 0, 833, 834, 835, 905, 906, 907,
+	2059, 908, 838, 839, 836, 837, 840, 841, 844, 842,
+	843, 909, 847, 542, 848, 849, 850, 845, 846, 2060,
+	2061, 2062, 2063, 851, 852, 910, 853, 854, 855, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 1980, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 5313, 367, 368, 370, 369, 371,
+	372, 373, 374, 1985, 375, 376, 1986, 1987, 1988, 0,
+	1989, 856, 1990, 1991, 1992, 378, 0, 377, 1993, 379,
+	380, 381, 926, 382, 383, 384, 385, 386, 387, 388,
+	389, 390, 857, 391, 858, 0, 392, 859, 393, 860,
+	1994, 861, 394, 395, 396, 397, 398, 399, 400, 401,
+	402, 403, 404, 1995, 1996, 0, 405, 862, 863, 864,
+	1997, 406, 407, 408, 409, 865, 1998, 927, 1999, 410,
+	411, 412, 413, 414, 415, 416, 417, 0, 2000, 419,
+	420, 421, 418, 422, 423, 2001, 424, 0, 425, 426,
+	427, 428, 429, 0, 430, 431, 2002, 432, 433, 434,
+	928, 435, 436, 437, 2003, 2004, 2006, 2005, 2007, 2008,
+	2009, 438, 439, 440, 441, 442, 0, 443, 445, 866,
+	867, 2010, 448, 450, 444, 446, 2011, 449, 447, 451,
+	452, 2012, 453, 454, 455, 456, 457, 0, 2013, 2014,
+	458, 459, 460, 461, 2015, 462, 463, 464, 466, 465,
+	2016, 467, 468, 469, 2017, 470, 471, 868, 472, 473,
+	474, 476, 478, 475, 477, 479, 480, 481, 482, 483,
+	869, 870, 484, 485, 2018, 362, 2019, 0, 0, 0,
+	0, 486, 487, 488, 871, 0, 0, 0, 489, 2020,
+	491, 495, 496, 492, 493, 494, 497, 2021, 490, 498,
+	499, 2022, 929, 500, 501, 502, 872, 873, 503, 504,
+	505, 506, 507, 508, 509, 510, 511, 2023, 512, 513,
+	874, 2024, 875, 514, 2025, 515, 516, 517, 518, 519,
+	520, 521, 876, 877, 878, 630, 931, 522, 523, 524,
+	525, 2026, 526, 527, 528, 529, 530, 531, 532, 0,
+	0, 0, 533, 534, 535, 536, 2027, 364, 363, 365,
+	930, 879, 537, 631, 538, 539, 880, 881, 2028, 882,
+	2029, 540, 541, 544, 932, 883, 933, 543, 545, 546,
+	934, 547, 0, 0, 0, 548, 549, 550, 551, 552,
+	553, 554, 2030, 555, 557, 556, 2031, 559, 884, 558,
+	935, 560, 561, 936, 2032, 562, 563, 564, 565, 566,
+	567, 572, 2033, 2034, 568, 569, 570, 571, 573, 574,
+	0, 575, 576, 578, 581, 577, 579, 580, 582, 583,
+	596, 597, 598, 584, 585, 586, 587, 588, 589, 590,
+	591, 592, 593, 594, 595, 600, 0, 599, 937, 0,
+	601, 602, 603, 604, 605, 606, 612, 615, 617, 618,
+	613, 614, 616, 619, 620, 621, 623, 624, 609, 610,
+	611, 938, 622, 607, 2035, 608, 366, 939, 625, 626,
+	627, 628, 2036, 885, 629, 886, 632, 633, 2037, 0,
+	634, 0, 635, 636, 2038, 2039, 638, 639, 640, 2040,
+	2041, 641, 642, 887, 940, 643, 941, 888, 644, 645,
+	637, 646, 647, 648, 649, 650, 651, 652, 653, 654,
+	655, 656, 657, 2042, 658, 659, 889, 660, 661, 662,
+	663, 664, 890, 665, 666, 667, 891, 668, 892, 669,
+	670, 671, 2043, 672, 673, 674, 0, 675, 676, 677,
+	678, 679, 680, 681, 682, 683, 684, 893, 685, 686,
+	688, 687, 689, 690, 2044, 691, 692, 0, 693, 694,
+	695, 0, 0, 0, 0, 0, 696, 697, 699, 0,
+	700, 701, 702, 703, 704, 705, 698, 706, 707, 708,
+	709, 710, 711, 712, 713, 2045, 715, 716, 714, 717,
+	718, 942, 719, 720, 721, 722, 723, 894, 724, 0,
+	725, 726, 734, 735, 736, 727, 728, 730, 737, 729,
+	738, 739, 740, 741, 743, 742, 2046, 745, 746, 744,
+	747, 748, 749, 750, 2047, 751, 895, 752, 731, 732,
+	753, 754, 755, 943, 756, 757, 758, 759, 760, 761,
+	762, 763, 764, 896, 0, 766, 2048, 765, 767, 768,
+	769, 770, 771, 772, 773, 775, 733, 776, 777, 778,
+	783, 784, 785, 897, 779, 780, 781, 782, 787, 898,
+	788, 789, 790, 791, 2049, 792, 793, 0, 786, 774,
+	2050, 794, 795, 796, 797, 798, 799, 800, 801, 802,
+	803, 2051, 804, 899, 900, 901, 902, 2052, 817, 2053,
+	805, 807, 808, 809, 810, 903, 811, 812, 904, 2054,
+	813, 814, 815, 816, 806, 819, 820, 818, 2055, 2056,
+	821, 822, 823, 824, 826, 828, 829, 830, 825, 827,
+	831, 2057, 832, 2058, 0, 833, 834, 835, 905, 906,
+	907, 2059, 908, 838, 839, 836, 837, 840, 841, 844,
+	842, 843, 909, 847, 542, 848, 849, 850, 845, 846,
+	2060, 2061, 2062, 2063, 851, 852, 910, 853, 854, 855,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 1980,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 3348, 367, 368, 370, 369,
+	371, 372, 373, 374, 1985, 375, 376, 1986, 1987, 1988,
+	0, 1989, 856, 1990, 1991, 1992, 378, 0, 377, 1993,
+	379, 380, 381, 926, 382, 383, 384, 385, 386, 387,
+	388, 389, 390, 857, 391, 858, 0, 392, 859, 393,
+	860, 1994, 861, 394, 395, 396, 397, 398, 399, 400,
+	401, 402, 403, 404, 1995, 1996, 0, 405, 862, 863,
+	864, 1997, 406, 407, 408, 409, 865, 1998, 927, 1999,
+	410, 411, 412, 413, 414, 415, 416, 417, 0, 2000,
+	419, 420, 421, 418, 422, 423, 2001, 424, 0, 425,
+	426, 427, 428, 429, 0, 430, 431, 2002, 432, 433,
+	434, 928, 435, 436, 437, 2003, 2004, 2006, 2005, 2007,
+	2008, 2009, 438, 439, 440, 441, 442, 0, 443, 445,
+	866, 867, 2010, 448, 450, 444, 446, 2011, 449, 447,
+	451, 452, 2012, 453, 454, 455, 456, 457, 0, 2013,
+	2014, 458, 459, 460, 461, 2015, 462, 463, 464, 466,
+	465, 2016, 467, 468, 469, 2017, 470, 471, 868, 472,
+	473, 474, 476, 478, 475, 477, 479, 480, 481, 482,
+	483, 869, 870, 484, 485, 2018, 362, 2019, 0, 0,
+	0, 0, 486, 487, 488, 871, 0, 0, 0, 489,
+	2020, 491, 495, 496, 492, 493, 494, 497, 2021, 490,
+	498, 499, 2022, 929, 500, 501, 502, 872, 873, 503,
+	504, 505, 506, 507, 508, 509, 510, 511, 2023, 512,
+	513, 874, 2024, 875, 514, 2025, 515, 516, 517, 518,
+	519, 520, 521, 876, 877, 878, 630, 931, 522, 523,
+	524, 525, 2026, 526, 527, 528, 529, 530, 531, 532,
+	0, 0, 0, 533, 534, 535, 536, 2027, 364, 363,
+	365, 930, 879, 537, 631, 538, 539, 880, 881, 2028,
+	882, 2029, 540, 541, 544, 932, 883, 933, 543, 545,
+	546, 934, 547, 0, 0, 0, 548, 549, 550, 551,
+	552, 553, 554, 2030, 555, 557, 556, 2031, 559, 884,
+	558, 935, 560, 561, 936, 2032, 562, 563, 564, 565,
+	566, 567, 572, 2033, 2034, 568, 569, 570, 571, 573,
+	574, 0, 575, 576, 578, 581, 577, 579, 580, 582,
+	583, 596, 597, 598, 584, 585, 586, 587, 588, 589,
+	590, 591, 592, 593, 594, 595, 600, 0, 599, 937,
+	0, 601, 602, 603, 604, 605, 606, 612, 615, 617,
+	618, 613, 614, 616, 619, 620, 621, 623, 624, 609,
+	610, 611, 938, 622, 607, 2035, 608, 366, 939, 625,
+	626, 627, 628, 2036, 885, 629, 886, 632, 633, 2037,
+	0, 634, 0, 635, 636, 2038, 2039, 638, 639, 640,
+	2040, 2041, 641, 642, 887, 940, 643, 941, 888, 644,
+	645, 637, 646, 647, 648, 649, 650, 651, 652, 653,
+	654, 655, 656, 657, 2042, 658, 659, 889, 660, 661,
+	662, 663, 664, 890, 665, 666, 667, 891, 668, 892,
+	669, 670, 671, 2043, 672, 673, 674, 0, 675, 676,
+	677, 678, 679, 680, 681, 682, 683, 684, 893, 685,
+	686, 688, 687, 689, 690, 2044, 691, 692, 0, 693,
+	694, 695, 0, 0, 0, 0, 0, 696, 697, 699,
+	0, 700, 701, 702, 703, 704, 705, 698, 706, 707,
+	708, 709, 710, 711, 712, 713, 2045, 715, 716, 714,
+	717, 718, 942, 719, 720, 721, 722, 723, 894, 724,
+	0, 725, 726, 734, 735, 736, 727, 728, 730, 737,
+	729, 738, 739, 740, 741, 743, 742, 2046, 745, 746,
+	744, 747, 748, 749, 750, 2047, 751, 895, 752, 731,
+	732, 753, 754, 755, 943, 756, 757, 758, 759, 760,
+	761, 762, 763, 764, 896, 0, 766, 2048, 765, 767,
+	768, 769, 770, 771, 772, 773, 775, 733, 776, 777,
+	778, 783, 784, 785, 897, 779, 780, 781, 782, 787,
+	898, 788, 789, 790, 791, 2049, 792, 793, 0, 786,
+	774, 2050, 794, 795, 796, 797, 798, 799, 800, 801,
+	802, 803, 2051, 804, 899, 900, 901, 902, 2052, 817,
+	2053, 805, 807, 808, 809, 810, 903, 811, 812, 904,
+	2054, 813, 814, 815, 816, 806, 819, 820, 818, 2055,
+	2056, 821, 822, 823, 824, 826, 828, 829, 830, 825,
+	827, 831, 2057, 832, 2058, 0, 833, 834, 835, 905,
+	906, 907, 2059, 908, 838, 839, 836, 837, 840, 841,
+	844, 842, 843, 909, 847, 542, 848, 849, 850, 845,
+	846, 2060, 2061, 2062, 2063, 851, 852, 910, 853, 854,
+	855, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	1980, 7356, 0, 0, 7354, 7355, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 3050, 367, 368, 370,
+	369, 371, 372, 373, 374, 1985, 375, 376, 1986, 1987,
+	1988, 0, 1989, 856, 1990, 1991, 1992, 378, 0, 377,
+	1993, 379, 380, 381, 926, 382, 383, 384, 385, 386,
+	387, 388, 389, 390, 857, 391, 858, 0, 392, 859,
+	393, 860, 1994, 861, 394, 395, 396, 397, 398, 399,
+	400, 401, 402, 403, 404, 1995, 1996, 0, 405, 862,
+	863, 864, 1997, 406, 407, 408, 409, 865, 1998, 927,
+	1999, 410, 411, 412, 413, 414, 415, 416, 417, 0,
+	2000, 419, 420, 421, 418, 422, 423, 2001, 424, 0,
+	425, 426, 427, 428, 429, 0, 430, 431, 2002, 432,
+	433, 434, 928, 435, 436, 437, 2003, 2004, 2006, 2005,
+	2007, 2008, 2009, 438, 439, 440, 441, 442, 0, 443,
+	445, 866, 867, 2010, 448, 450, 444, 446, 2011, 449,
+	447, 451, 452, 2012, 453, 454, 455, 456, 457, 0,
+	2013, 2014, 458, 459, 460, 461, 2015, 462, 463, 464,
+	466, 465, 2016, 467, 468, 469, 2017, 470, 471, 868,
+	472, 473, 474, 476, 478, 475, 477, 479, 480, 481,
+	482, 483, 869, 870, 484, 485, 2018, 362, 2019, 0,
+	0, 0, 0, 486, 487, 488, 871, 0, 0, 0,
+	489, 2020, 491, 495, 496, 492, 493, 494, 497, 2021,
+	490, 498, 499, 2022, 929, 500, 501, 502, 872, 873,
+	503, 504, 505, 506, 507, 508, 509, 510, 511, 2023,
+	512, 513, 874, 2024, 875, 514, 2025, 515, 516, 517,
+	518, 519, 520, 521, 876, 877, 878, 630, 931, 522,
+	523, 524, 525, 2026, 526, 527, 528, 529, 530, 531,
+	532, 0, 0, 0, 533, 534, 535, 536, 2027, 364,
+	363, 365, 930, 879, 537, 631, 538, 539, 880, 881,
+	2028, 882, 2029, 540, 541, 544, 932, 883, 933, 543,
+	545, 546, 934, 547, 0, 0, 0, 548, 549, 550,
+	551, 552, 553, 554, 2030, 555, 557, 556, 2031, 559,
+	884, 558, 935, 560, 561, 936, 2032, 562, 563, 564,
+	565, 566, 567, 572, 2033, 2034, 568, 569, 570, 571,
+	573, 574, 0, 575, 576, 578, 581, 577, 579, 580,
+	582, 583, 596, 597, 598, 584, 585, 586, 587, 588,
+	589, 590, 591, 592, 593, 594, 595, 600, 0, 599,
+	937, 0, 601, 602, 603, 604, 605, 606, 612, 615,
+	617, 618, 613, 614, 616, 619, 620, 621, 623, 624,
+	609, 610, 611, 938, 622, 607, 2035, 608, 366, 939,
+	625, 626, 627, 628, 2036, 885, 629, 886, 632, 633,
+	2037, 0, 634, 0, 635, 636, 2038, 2039, 638, 639,
+	640, 2040, 2041, 641, 642, 887, 940, 643, 941, 888,
+	644, 645, 637, 646, 647, 648, 649, 650, 651, 652,
+	653, 654, 655, 656, 657, 2042, 658, 659, 889, 660,
+	661, 662, 663, 664, 890, 665, 666, 667, 891, 668,
+	892, 669, 670, 671, 2043, 672, 673, 674, 0, 675,
+	676, 677, 678, 679, 680, 681, 682, 683, 684, 893,
+	685, 686, 688, 687, 689, 690, 2044, 691, 692, 0,
+	693, 694, 695, 0, 0, 0, 0, 0, 696, 697,
+	699, 0, 700, 701, 702, 703, 704, 705, 698, 706,
+	707, 708, 709, 710, 711, 712, 713, 2045, 715, 716,
+	714, 717, 718, 942, 719, 720, 721, 722, 723, 894,
+	724, 0, 725, 726, 734, 735, 736, 727, 728, 730,
+	737, 729, 738, 739, 740, 741, 743, 742, 2046, 745,
+	746, 744, 747, 748, 749, 750, 2047, 751, 895, 752,
+	731, 732, 753, 754, 755, 943, 756, 757, 758, 759,
+	760, 761, 762, 763, 764, 896, 0, 766, 2048, 765,
+	767, 768, 769, 770, 771, 772, 773, 775, 733, 776,
+	777, 778, 783, 784, 785, 897, 779, 780, 781, 782,
+	787, 898, 788, 789, 790, 791, 2049, 792, 793, 0,
+	786, 774, 2050, 794, 795, 796, 797, 798, 799, 800,
+	801, 802, 803, 2051, 804, 899, 900, 901, 902, 2052,
+	817, 2053, 805, 807, 808, 809, 810, 903, 811, 812,
+	904, 2054, 813, 814, 815, 816, 806, 819, 820, 818,
+	2055, 2056, 821, 822, 823, 824, 826, 828, 829, 830,
+	825, 827, 831, 2057, 832, 2058, 0, 833, 834, 835,
+	905, 906, 907, 2059, 908, 838, 839, 836, 837, 840,
+	841, 844, 842, 843, 909, 847, 542, 848, 849, 850,
+	845, 846, 2060, 2061, 2062, 2063, 851, 852, 910, 853,
+	854, 855, 1462, 0, 1551, 1493, 1494, 1495, 1491, 1492,
+	1504, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 367, 368, 370, 369, 371, 372, 373, 374, 0,
+	375, 376, 0, 0, 0, 0, 0, 1543, 1509, 0,
+	0, 378, 0, 377, 0, 379, 380, 381, 926, 382,
+	383, 384, 385, 386, 387, 388, 389, 390, 857, 391,
+	1557, 0, 392, 1565, 393, 1564, 0, 1575, 394, 395,
+	396, 397, 398, 399, 400, 401, 402, 403, 404, 1511,
+	1542, 1475, 405, 1589, 1590, 864, 0, 406, 407, 408,
+	409, 1549, 0, 1530, 0, 410, 411, 412, 413, 414,
+	415, 416, 417, 0, 0, 419, 420, 421, 418, 422,
+	423, 0, 424, 0, 425, 426, 427, 428, 429, 0,
+	430, 431, 0, 432, 433, 434, 928, 435, 436, 437,
+	1533, 1531, 1532, 1539, 1535, 1534, 1538, 438, 439, 440,
+	441, 442, 1568, 443, 445, 1562, 1561, 1480, 448, 450,
+	444, 446, 0, 449, 447, 451, 452, 0, 453, 454,
+	455, 456, 457, 0, 0, 0, 458, 1560, 460, 461,
+	0, 462, 463, 464, 466, 465, 0, 467, 468, 469,
+	0, 470, 471, 1487, 472, 473, 474, 476, 478, 475,
+	477, 479, 480, 481, 482, 483, 1577, 1578, 484, 485,
+	1500, 362, 0, 0, 0, 0, 0, 486, 487, 488,
+	1559, 0, 0, 0, 489, 0, 491, 495, 496, 492,
+	493, 494, 497, 0, 490, 498, 499, 0, 929, 500,
+	501, 502, 1573, 1574, 503, 504, 505, 506, 507, 508,
+	509, 510, 511, 0, 512, 513, 1584, 0, 1510, 514,
+	0, 515, 516, 517, 518, 519, 520, 521, 1544, 1545,
+	1548, 630, 931, 522, 523, 524, 525, 0, 526, 527,
+	528, 529, 530, 531, 532, 0, 0, 0, 533, 534,
+	535, 536, 0, 919, 363, 365, 930, 879, 537, 631,
+	538, 539, 1554, 1555, 0, 1514, 0, 540, 541, 544,
+	932, 1546, 933, 543, 545, 546, 934, 547, 0, 0,
+	0, 548, 549, 550, 551, 552, 553, 554, 0, 555,
+	557, 556, 0, 559, 1585, 558, 935, 560, 561, 936,
+	0, 562, 563, 564, 565, 566, 567, 572, 1537, 1536,
+	568, 569, 570, 571, 573, 574, 0, 575, 576, 578,
+	581, 577, 579, 580, 582, 583, 596, 597, 598, 584,
+	585, 586, 587, 588, 589, 590, 591, 592, 593, 594,
+	595, 600, 0, 599, 937, 0, 601, 602, 603, 604,
+	605, 606, 612, 615, 617, 618, 613, 614, 616, 619,
+	620, 621, 623, 624, 609, 610, 611, 938, 622, 607,
+	1477, 608, 366, 939, 625, 626, 627, 628, 1501, 1547,
+	629, 1563, 632, 633, 0, 0, 634, 0, 635, 636,
+	0, 0, 638, 639, 640, 0, 0, 641, 642, 887,
+	940, 643, 941, 1579, 644, 645, 1488, 646, 647, 648,
+	649, 650, 651, 652, 653, 654, 655, 656, 657, 0,
+	658, 659, 889, 660, 661, 662, 663, 664, 890, 665,
+	666, 667, 1580, 668, 892, 669, 670, 671, 0, 672,
+	673, 674, 0, 675, 676, 677, 678, 679, 680, 681,
+	682, 683, 684, 1558, 685, 686, 688, 687, 689, 690,
+	0, 691, 692, 0, 693, 694, 695, 0, 0, 0,
+	0, 0, 696, 697, 699, 0, 700, 701, 702, 703,
+	704, 705, 698, 706, 707, 708, 709, 710, 711, 712,
+	713, 0, 715, 716, 714, 717, 718, 942, 719, 720,
+	721, 722, 723, 1489, 724, 0, 725, 726, 734, 735,
+	736, 727, 728, 730, 737, 729, 738, 739, 740, 741,
+	743, 742, 316, 745, 746, 744, 747, 748, 749, 750,
+	1540, 751, 895, 752, 731, 732, 753, 754, 755, 943,
+	756, 757, 758, 759, 760, 761, 762, 763, 764, 1556,
+	0, 766, 0, 765, 767, 768, 769, 770, 771, 772,
+	773, 775, 733, 776, 777, 778, 783, 784, 785, 1588,
+	779, 780, 781, 782, 787, 1581, 788, 789, 790, 791,
+	0, 792, 793, 1474, 786, 774, 318, 794, 795, 796,
+	797, 798, 799, 800, 801, 802, 803, 0, 804, 1569,
+	1570, 1571, 1572, 0, 817, 0, 805, 807, 808, 809,
+	810, 1582, 811, 812, 1583, 1499, 813, 814, 815, 816,
+	806, 819, 820, 818, 0, 1481, 821, 822, 823, 824,
+	826, 828, 829, 830, 825, 827, 831, 1541, 832, 0,
+	0, 833, 834, 835, 2237, 1566, 1587, 0, 1576, 838,
+	839, 836, 837, 840, 841, 844, 842, 843, 909, 847,
+	542, 848, 849, 850, 845, 846, 0, 0, 0, 310,
+	851, 852, 910, 853, 854, 855, 1478, 0, 311, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 1473, 0, 0, 0, 0, 0, 0, 1471,
+	1472, 0, 0, 0, 0, 0, 0, 916, 0, 2395,
+	2393, 0, 2518, 1503, 1551, 1493, 1494, 1495, 1491, 1492,
+	1504, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 367, 368, 370, 369, 371, 372, 373, 374, 2515,
+	375, 376, 0, 0, 0, 0, 0, 1543, 1509, 0,
+	0, 378, 0, 377, 0, 379, 380, 381, 926, 382,
+	383, 384, 385, 386, 387, 388, 389, 390, 857, 391,
+	1557, 0, 392, 1565, 393, 1564, 0, 1575, 394, 395,
+	396, 397, 398, 399, 400, 401, 402, 403, 404, 1511,
+	1542, 1475, 405, 1589, 1590, 864, 0, 406, 407, 408,
+	409, 1549, 0, 1530, 0, 410, 411, 412, 413, 414,
+	415, 416, 417, 0, 0, 419, 420, 421, 418, 422,
+	423, 0, 424, 0, 425, 426, 427, 428, 429, 0,
+	430, 431, 0, 432, 433, 434, 928, 435, 436, 437,
+	1533, 1531, 1532, 1539, 1535, 1534, 1538, 438, 439, 440,
+	441, 442, 1568, 443, 445, 1562, 1561, 1480, 448, 450,
+	444, 446, 0, 449, 447, 451, 452, 0, 453, 454,
+	455, 456, 457, 0, 2516, 0, 458, 1560, 460, 461,
+	0, 462, 463, 464, 466, 465, 0, 467, 468, 469,
+	0, 470, 471, 1487, 472, 473, 474, 476, 478, 475,
+	477, 479, 480, 481, 482, 483, 1577, 1578, 484, 485,
+	1500, 362, 0, 0, 0, 0, 0, 486, 487, 488,
+	1559, 0, 0, 0, 489, 0, 491, 495, 496, 492,
+	493, 494, 497, 0, 490, 498, 499, 0, 929, 500,
+	501, 502, 1573, 1574, 503, 504, 505, 506, 507, 508,
+	509, 510, 511, 0, 512, 513, 1584, 0, 1510, 514,
+	0, 515, 516, 517, 518, 519, 520, 521, 1544, 1545,
+	1548, 630, 931, 522, 523, 524, 525, 0, 526, 527,
+	528, 529, 530, 531, 532, 0, 0, 0, 533, 534,
+	535, 536, 0, 919, 363, 365, 930, 879, 537, 631,
+	538, 539, 1554, 1555, 0, 1514, 0, 540, 541, 544,
+	932, 1546, 933, 543, 545, 546, 934, 547, 0, 0,
+	0, 548, 549, 550, 551, 552, 553, 554, 0, 555,
+	557, 556, 0, 559, 1585, 558, 935, 560, 561, 936,
+	0, 562, 563, 564, 565, 566, 567, 572, 1537, 1536,
+	568, 569, 570, 571, 573, 574, 0, 575, 576, 578,
+	581, 577, 579, 580, 582, 583, 596, 597, 598, 584,
+	585, 586, 587, 588, 589, 590, 591, 592, 593, 594,
+	595, 600, 0, 599, 937, 0, 601, 602, 603, 604,
+	605, 606, 612, 615, 617, 618, 613, 614, 616, 619,
+	620, 621, 623, 624, 609, 610, 611, 938, 622, 607,
+	1477, 608, 366, 939, 625, 626, 627, 628, 1501, 1547,
+	629, 1563, 632, 633, 0, 0, 634, 0, 635, 636,
+	0, 0, 638, 639, 640, 0, 0, 641, 642, 887,
+	940, 643, 941, 1579, 644, 645, 1488, 646, 647, 648,
+	649, 650, 651, 652, 653, 654, 655, 656, 657, 0,
+	658, 659, 889, 660, 661, 662, 663, 664, 890, 665,
+	666, 667, 1580, 668, 892, 669, 670, 671, 0, 672,
+	673, 674, 0, 675, 676, 677, 678, 679, 680, 681,
+	682, 683, 684, 1558, 685, 686, 688, 687, 689, 690,
+	0, 691, 692, 0, 693, 694, 695, 0, 0, 0,
+	0, 0, 696, 697, 699, 0, 700, 701, 702, 703,
+	704, 705, 698, 706, 707, 708, 709, 710, 711, 712,
+	713, 0, 715, 716, 714, 717, 718, 942, 719, 720,
+	721, 722, 723, 1489, 724, 0, 725, 726, 734, 735,
+	736, 727, 728, 730, 737, 729, 738, 739, 740, 741,
+	743, 742, 0, 745, 746, 744, 747, 748, 749, 750,
+	1540, 751, 895, 752, 731, 732, 753, 754, 755, 943,
+	756, 757, 758, 759, 760, 761, 762, 763, 764, 1556,
+	0, 766, 0, 765, 767, 768, 769, 770, 771, 772,
+	773, 775, 733, 776, 777, 778, 783, 784, 785, 1588,
+	779, 780, 781, 782, 787, 1581, 788, 789, 790, 791,
+	0, 792, 793, 1474, 786, 774, 0, 794, 795, 796,
+	797, 798, 799, 800, 801, 802, 803, 0, 804, 1569,
+	1570, 1571, 1572, 0, 817, 0, 805, 807, 808, 809,
+	810, 1582, 811, 812, 1583, 1499, 813, 814, 815, 816,
+	806, 819, 820, 818, 0, 1481, 821, 822, 823, 824,
+	826, 828, 829, 830, 825, 827, 831, 1541, 832, 0,
+	0, 833, 834, 835, 905, 1566, 1587, 2514, 1576, 838,
+	839, 836, 837, 840, 841, 844, 842, 843, 909, 847,
+	542, 848, 849, 850, 845, 846, 0, 0, 0, 0,
+	851, 852, 910, 853, 854, 855, 1478, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 1473, 0, 0, 1977, 0, 1980, 0, 1471,
+	1472, 2517, 0, 0, 0, 0, 0, 916, 0, 1505,
+	2512, 0, 0, 1503, 367, 368, 370, 369, 371, 372,
+	373, 374, 1985, 375, 376, 1986, 1987, 1988, 0, 1989,
+	856, 1990, 1991, 1992, 378, 0, 377, 1993, 379, 380,
+	381, 926, 382, 383, 384, 385, 386, 387, 388, 389,
+	390, 857, 391, 858, 0, 392, 859, 393, 860, 1994,
+	861, 394, 395, 396, 397, 398, 399, 400, 401, 402,
+	403, 404, 1995, 1996, 0, 405, 862, 863, 864, 1997,
+	406, 407, 408, 409, 865, 1998, 927, 1999, 410, 411,
+	412, 413, 414, 415, 416, 417, 0, 2000, 419, 420,
+	421, 418, 422, 423, 2001, 424, 0, 425, 426, 427,
+	428, 429, 0, 430, 431, 2002, 432, 433, 434, 928,
+	435, 436, 437, 2003, 2004, 2006, 2005, 2007, 2008, 2009,
+	438, 439, 440, 441, 442, 0, 443, 445, 866, 867,
+	2010, 448, 450, 444, 446, 2011, 449, 447, 451, 452,
+	2012, 453, 454, 455, 456, 457, 0, 2013, 2014, 458,
+	459, 460, 461, 2015, 462, 463, 464, 466, 465, 2016,
+	467, 468, 469, 2017, 470, 471, 868, 472, 473, 474,
+	476, 478, 475, 477, 479, 480, 481, 482, 483, 869,
+	870, 484, 485, 2018, 362, 2019, 0, 0, 0, 0,
+	486, 487, 488, 871, 0, 0, 0, 489, 2020, 491,
+	495, 496, 492, 493, 494, 497, 2021, 490, 498, 499,
+	2022, 929, 500, 501, 502, 872, 873, 503, 504, 505,
+	506, 507, 508, 509, 510, 511, 2023, 512, 513, 874,
+	2024, 875, 514, 2025, 515, 516, 517, 518, 519, 520,
+	521, 876, 877, 878, 630, 931, 522, 523, 524, 525,
+	2026, 526, 527, 528, 529, 530, 531, 532, 0, 0,
+	0, 533, 534, 535, 536, 2027, 364, 363, 365, 930,
+	879, 537, 631, 538, 539, 880, 881, 2028, 882, 2029,
+	540, 541, 544, 932, 883, 933, 543, 545, 546, 934,
+	547, 0, 0, 0, 548, 549, 550, 551, 552, 553,
+	554, 2030, 555, 557, 556, 2031, 559, 884, 558, 935,
+	560, 561, 936, 2032, 562, 563, 564, 565, 566, 567,
+	572, 2033, 2034, 568, 569, 570, 571, 573, 574, 0,
+	575, 576, 578, 581, 577, 579, 580, 582, 583, 596,
+	597, 598, 584, 585, 586, 587, 588, 589, 590, 591,
+	592, 593, 594, 595, 600, 0, 599, 937, 0, 601,
+	602, 603, 604, 605, 606, 612, 615, 617, 618, 613,
+	614, 616, 619, 620, 621, 623, 624, 609, 610, 611,
+	938, 622, 607, 2035, 608, 366, 939, 625, 626, 627,
+	628, 2036, 885, 629, 886, 632, 633, 2037, 0, 634,
+	0, 635, 636, 2038, 2039, 638, 639, 640, 2040, 2041,
+	641, 642, 887, 940, 643, 941, 888, 644, 645, 637,
+	646, 647, 648, 649, 650, 651, 652, 653, 654, 655,
+	656, 657, 2042, 658, 659, 889, 660, 661, 662, 663,
+	664, 890, 665, 666, 667, 891, 668, 892, 669, 670,
+	671, 2043, 672, 673, 674, 0, 675, 676, 677, 678,
+	679, 680, 681, 682, 683, 684, 893, 685, 686, 688,
+	687, 689, 690, 2044, 691, 692, 0, 693, 694, 695,
+	0, 0, 0, 0, 0, 696, 697, 699, 0, 700,
+	701, 702, 703, 704, 705, 698, 706, 707, 708, 709,
+	710, 711, 712, 713, 2045, 715, 716, 714, 717, 718,
+	942, 719, 720, 721, 722, 723, 894, 724, 0, 725,
+	726, 734, 735, 736, 727, 728, 730, 737, 729, 738,
+	739, 740, 741, 743, 742, 2046, 745, 746, 744, 747,
+	748, 749, 750, 2047, 751, 895, 752, 731, 732, 753,
+	754, 755, 943, 756, 757, 758, 759, 760, 761, 762,
+	763, 764, 896, 0, 766, 2048, 765, 767, 768, 769,
+	770, 771, 772, 773, 775, 733, 776, 777, 778, 783,
+	784, 785, 897, 779, 780, 781, 782, 787, 898, 788,
+	789, 790, 791, 2049, 792, 793, 0, 786, 774, 2050,
+	794, 795, 796, 797, 798, 799, 800, 801, 802, 803,
+	2051, 804, 899, 900, 901, 902, 2052, 817, 2053, 805,
+	807, 808, 809, 810, 903, 811, 812, 904, 2054, 813,
+	814, 815, 816, 806, 819, 820, 818, 2055, 2056, 821,
+	822, 823, 824, 826, 828, 829, 830, 825, 827, 831,
+	2057, 832, 2058, 0, 833, 834, 835, 905, 906, 907,
+	2059, 908, 838, 839, 836, 837, 840, 841, 844, 842,
+	843, 909, 847, 542, 848, 849, 850, 845, 846, 2060,
+	2061, 2062, 2063, 851, 852, 910, 853, 854, 855, 1980,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 367, 368, 370, 369,
+	371, 372, 373, 374, 1985, 375, 376, 1986, 1987, 1988,
+	0, 1989, 856, 1990, 1991, 1992, 378, 0, 377, 1993,
+	379, 380, 381, 926, 382, 383, 384, 385, 386, 387,
+	388, 389, 390, 857, 391, 858, 0, 392, 859, 393,
+	860, 1994, 861, 394, 395, 396, 397, 398, 399, 400,
+	401, 402, 403, 404, 1995, 1996, 0, 405, 862, 863,
+	864, 1997, 406, 407, 408, 409, 865, 1998, 927, 1999,
+	410, 411, 412, 413, 414, 415, 416, 417, 0, 2000,
+	419, 420, 421, 418, 422, 423, 2001, 424, 0, 425,
+	426, 427, 428, 429, 0, 430, 431, 2002, 432, 433,
+	434, 928, 435, 436, 437, 2003, 2004, 2006, 2005, 2007,
+	2008, 2009, 438, 439, 440, 441, 442, 0, 443, 445,
+	866, 867, 2010, 448, 450, 444, 446, 2011, 449, 447,
+	451, 452, 2012, 453, 454, 455, 456, 457, 0, 2013,
+	2014, 458, 459, 460, 461, 2015, 462, 463, 464, 466,
+	465, 2016, 467, 468, 469, 2017, 470, 471, 868, 472,
+	473, 474, 476, 478, 475, 477, 479, 480, 481, 482,
+	483, 869, 870, 484, 485, 2018, 362, 2019, 0, 0,
+	0, 0, 486, 487, 488, 871, 0, 0, 0, 489,
+	2020, 491, 495, 496, 492, 493, 494, 497, 2021, 490,
+	498, 499, 2022, 929, 500, 501, 502, 872, 873, 503,
+	504, 505, 506, 507, 508, 509, 510, 511, 2023, 512,
+	513, 874, 2024, 875, 514, 2025, 515, 516, 517, 518,
+	519, 520, 521, 876, 877, 878, 630, 931, 522, 523,
+	524, 525, 2026, 526, 527, 528, 529, 530, 531, 532,
+	0, 0, 0, 533, 534, 535, 536, 2027, 364, 363,
+	365, 930, 879, 537, 631, 538, 539, 880, 881, 2028,
+	882, 2029, 540, 541, 544, 932, 883, 933, 543, 545,
+	546, 934, 547, 0, 0, 0, 548, 549, 550, 551,
+	552, 553, 554, 2030, 555, 557, 556, 2031, 559, 884,
+	558, 935, 560, 561, 936, 2032, 562, 563, 564, 565,
+	566, 567, 572, 2033, 2034, 568, 569, 570, 571, 573,
+	574, 0, 575, 576, 578, 581, 577, 579, 580, 582,
+	583, 596, 597, 598, 584, 585, 586, 587, 588, 589,
+	590, 591, 592, 593, 594, 595, 600, 0, 599, 937,
+	0, 601, 602, 603, 604, 605, 606, 612, 615, 617,
+	618, 613, 614, 616, 619, 620, 621, 623, 624, 609,
+	610, 611, 938, 622, 607, 2035, 608, 366, 939, 625,
+	626, 627, 628, 2036, 885, 629, 886, 632, 633, 2037,
+	0, 634, 0, 635, 636, 2038, 2039, 638, 639, 640,
+	2040, 2041, 641, 642, 887, 940, 643, 941, 888, 644,
+	645, 637, 646, 647, 648, 649, 650, 651, 652, 653,
+	654, 655, 656, 657, 2042, 658, 659, 889, 660, 661,
+	662, 663, 664, 890, 665, 666, 667, 891, 668, 892,
+	669, 670, 671, 2043, 672, 673, 674, 0, 675, 676,
+	677, 678, 679, 680, 681, 682, 683, 684, 893, 685,
+	686, 688, 687, 689, 690, 2044, 691, 692, 0, 693,
+	694, 695, 0, 0, 0, 0, 0, 696, 697, 699,
+	0, 700, 701, 702, 703, 704, 705, 698, 706, 707,
+	708, 709, 710, 711, 712, 713, 2045, 715, 716, 714,
+	717, 718, 942, 719, 720, 721, 722, 723, 894, 724,
+	0, 725, 726, 734, 735, 736, 727, 728, 730, 737,
+	729, 738, 739, 740, 741, 743, 742, 2046, 745, 746,
+	744, 747, 748, 749, 750, 2047, 751, 895, 752, 731,
+	732, 753, 754, 755, 943, 756, 757, 758, 759, 760,
+	761, 762, 763, 764, 896, 0, 766, 2048, 765, 767,
+	768, 769, 770, 771, 772, 773, 775, 733, 776, 777,
+	778, 783, 784, 785, 897, 779, 780, 781, 782, 787,
+	898, 788, 789, 790, 791, 2049, 792, 793, 0, 786,
+	774, 2050, 794, 795, 796, 797, 798, 799, 800, 801,
+	802, 803, 2051, 804, 899, 900, 901, 902, 2052, 817,
+	2053, 805, 807, 808, 809, 810, 903, 811, 812, 904,
+	2054, 813, 814, 815, 816, 806, 819, 820, 818, 2055,
+	2056, 821, 822, 823, 824, 826, 828, 829, 830, 825,
+	827, 831, 2057, 832, 2058, 0, 833, 834, 835, 905,
+	906, 907, 2059, 908, 838, 839, 836, 837, 840, 841,
+	844, 842, 843, 909, 847, 542, 848, 849, 850, 845,
+	846, 2060, 2061, 2062, 2063, 851, 852, 910, 853, 854,
+	855, 1551, 1493, 1494, 1495, 1491, 1492, 1504, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 367, 368,
+	370, 369, 371, 372, 373, 374, 0, 375, 376, 0,
+	0, 0, 0, 0, 1543, 1509, 0, 0, 378, 0,
+	377, 0, 379, 380, 381, 926, 382, 383, 384, 385,
+	386, 387, 388, 389, 390, 857, 391, 1557, 0, 392,
+	1565, 393, 1564, 0, 1575, 394, 395, 396, 397, 398,
+	399, 400, 401, 402, 403, 404, 1511, 1542, 1475, 405,
+	1589, 1590, 864, 0, 406, 407, 408, 409, 1549, 0,
+	1530, 0, 410, 411, 412, 413, 414, 415, 416, 417,
+	0, 0, 419, 420, 421, 418, 422, 423, 0, 424,
+	0, 425, 426, 427, 428, 429, 0, 430, 431, 0,
+	432, 433, 434, 928, 435, 436, 437, 1533, 1531, 1532,
+	1539, 1535, 1534, 1538, 438, 439, 440, 441, 442, 1568,
+	443, 445, 1562, 1561, 1480, 448, 450, 444, 446, 0,
+	449, 447, 451, 452, 0, 453, 454, 455, 456, 457,
+	0, 0, 0, 458, 1560, 460, 461, 0, 462, 463,
+	464, 466, 465, 0, 467, 468, 469, 0, 470, 471,
+	1487, 472, 473, 474, 476, 478, 475, 477, 479, 480,
+	481, 482, 483, 1577, 1578, 484, 485, 1500, 362, 0,
+	0, 0, 0, 0, 486, 487, 488, 1559, 0, 0,
+	0, 489, 0, 491, 495, 496, 492, 493, 494, 497,
+	0, 490, 498, 499, 0, 929, 500, 501, 502, 1573,
+	1574, 503, 504, 505, 506, 507, 508, 509, 510, 511,
+	0, 512, 513, 1584, 0, 1510, 514, 0, 515, 516,
+	517, 518, 519, 520, 521, 1544, 1545, 1548, 630, 931,
+	522, 523, 524, 525, 0, 526, 527, 528, 529, 530,
+	531, 532, 0, 0, 0, 533, 534, 535, 536, 0,
+	919, 363, 365, 930, 879, 537, 631, 538, 539, 1554,
+	1555, 0, 1514, 0, 540, 541, 544, 932, 1546, 933,
+	543, 545, 546, 934, 547, 0, 0, 0, 548, 549,
+	550, 551, 552, 553, 554, 0, 555, 557, 556, 0,
+	559, 1585, 558, 935, 560, 561, 936, 0, 562, 563,
+	564, 565, 566, 567, 572, 1537, 1536, 568, 569, 570,
+	571, 573, 574, 0, 575, 576, 578, 581, 577, 579,
+	580, 582, 583, 596, 597, 598, 584, 585, 586, 587,
+	588, 589, 590, 591, 592, 593, 594, 595, 600, 0,
+	599, 937, 0, 601, 602, 603, 604, 605, 606, 612,
+	615, 617, 618, 613, 614, 616, 619, 620, 621, 623,
+	624, 609, 610, 611, 938, 622, 607, 1477, 608, 366,
+	939, 625, 626, 627, 628, 1501, 1547, 629, 1563, 632,
+	633, 0, 0, 634, 0, 635, 636, 0, 0, 638,
+	639, 640, 0, 0, 641, 642, 887, 940, 643, 941,
+	1579, 644, 645, 1488, 646, 647, 648, 649, 650, 651,
+	652, 653, 654, 655, 656, 657, 0, 658, 659, 889,
+	660, 661, 662, 663, 664, 890, 665, 666, 667, 1580,
+	668, 892, 669, 670, 671, 0, 672, 673, 674, 0,
+	675, 676, 677, 678, 679, 680, 681, 682, 683, 684,
+	1558, 685, 686, 688, 687, 689, 690, 0, 691, 692,
+	0, 693, 694, 695, 0, 0, 0, 0, 0, 696,
+	697, 699, 0, 700, 701, 702, 703, 704, 705, 698,
+	706, 707, 708, 709, 710, 711, 712, 713, 0, 715,
+	716, 714, 717, 718, 942, 719, 720, 721, 722, 723,
+	1489, 724, 0, 725, 726, 734, 735, 736, 727, 728,
+	730, 737, 729, 738, 739, 740, 741, 743, 742, 316,
+	745, 746, 744, 747, 748, 749, 750, 1540, 751, 895,
+	752, 731, 732, 753, 754, 755, 943, 756, 757, 758,
+	759, 760, 761, 762, 763, 764, 1556, 0, 766, 0,
+	765, 767, 768, 769, 770, 771, 772, 773, 775, 733,
+	776, 777, 778, 783, 784, 785, 1588, 779, 780, 781,
+	782, 787, 1581, 788, 789, 790, 791, 0, 792, 793,
+	1474, 786, 774, 318, 794, 795, 796, 797, 798, 799,
+	800, 801, 802, 803, 0, 804, 1569, 1570, 1571, 1572,
+	0, 817, 0, 805, 807, 808, 809, 810, 1582, 811,
+	812, 1583, 1499, 813, 814, 815, 816, 806, 819, 820,
+	818, 0, 1481, 821, 822, 823, 824, 826, 828, 829,
+	830, 825, 827, 831, 1541, 832, 0, 0, 833, 834,
+	835, 2237, 1566, 1587, 0, 1576, 838, 839, 836, 837,
+	840, 841, 844, 842, 843, 909, 847, 542, 848, 849,
+	850, 845, 846, 0, 0, 0, 310, 851, 852, 910,
+	853, 854, 855, 1478, 0, 311, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 1473,
+	0, 0, 0, 0, 0, 0, 1471, 1472, 0, 0,
+	0, 0, 0, 0, 916, 0, 2395, 4779, 0, 0,
+	1503, 1551, 1493, 1494, 1495, 1491, 1492, 1504, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 367, 368,
+	370, 369, 371, 372, 373, 374, 0, 375, 376, 0,
+	0, 0, 0, 0, 1543, 1509, 0, 0, 378, 0,
+	377, 0, 379, 380, 381, 926, 382, 383, 384, 385,
+	386, 387, 388, 389, 390, 857, 391, 1557, 0, 392,
+	1565, 393, 1564, 0, 1575, 394, 395, 396, 397, 398,
+	399, 400, 401, 402, 403, 404, 1511, 1542, 1475, 405,
+	1589, 1590, 864, 0, 406, 407, 408, 409, 1549, 0,
+	1530, 0, 410, 411, 412, 413, 414, 415, 416, 417,
+	0, 0, 419, 420, 421, 418, 422, 423, 0, 424,
+	0, 425, 426, 427, 428, 429, 0, 430, 431, 0,
+	432, 433, 434, 928, 435, 436, 437, 1533, 1531, 1532,
+	1539, 1535, 1534, 1538, 438, 439, 440, 441, 442, 1568,
+	443, 445, 1562, 1561, 1480, 448, 450, 444, 446, 0,
+	449, 447, 451, 452, 0, 453, 454, 455, 456, 457,
+	0, 0, 0, 458, 1560, 460, 461, 0, 462, 463,
+	464, 466, 465, 0, 467, 468, 469, 0, 470, 471,
+	1487, 472, 473, 474, 476, 478, 475, 477, 479, 480,
+	481, 482, 483, 1577, 1578, 484, 485, 1500, 362, 0,
+	0, 0, 0, 0, 486, 487, 488, 1559, 0, 0,
+	0, 489, 0, 491, 495, 496, 492, 493, 494, 497,
+	0, 490, 498, 499, 0, 929, 500, 501, 502, 1573,
+	1574, 503, 504, 505, 506, 507, 508, 509, 510, 511,
+	0, 512, 513, 1584, 0, 1510, 514, 0, 515, 516,
+	517, 518, 519, 520, 521, 1544, 1545, 1548, 630, 931,
+	522, 523, 524, 525, 0, 526, 527, 528, 529, 530,
+	531, 532, 0, 0, 0, 533, 534, 535, 536, 0,
+	919, 363, 365, 930, 879, 537, 631, 538, 539, 1554,
+	1555, 0, 1514, 0, 540, 541, 544, 932, 1546, 933,
+	543, 545, 546, 934, 547, 0, 0, 0, 548, 549,
+	550, 551, 552, 553, 554, 0, 555, 557, 556, 0,
+	559, 1585, 558, 935, 560, 561, 936, 0, 562, 563,
+	564, 565, 566, 567, 572, 1537, 1536, 568, 569, 570,
+	571, 573, 574, 0, 575, 576, 578, 581, 577, 579,
+	580, 582, 583, 596, 597, 598, 584, 585, 586, 587,
+	588, 589, 590, 591, 592, 593, 594, 595, 600, 0,
+	599, 937, 0, 601, 602, 603, 604, 605, 606, 612,
+	615, 617, 618, 613, 614, 616, 619, 620, 621, 623,
+	624, 609, 610, 611, 938, 622, 607, 1477, 608, 366,
+	939, 625, 626, 627, 628, 1501, 1547, 629, 1563, 632,
+	633, 0, 0, 634, 0, 635, 636, 0, 0, 638,
+	639, 640, 0, 0, 641, 642, 887, 940, 643, 941,
+	1579, 644, 645, 1488, 646, 647, 648, 649, 650, 651,
+	652, 653, 654, 655, 656, 657, 0, 658, 659, 889,
+	660, 661, 662, 663, 664, 890, 665, 666, 667, 1580,
+	668, 892, 669, 670, 671, 0, 672, 673, 674, 0,
+	675, 676, 677, 678, 679, 680, 681, 682, 683, 684,
+	1558, 685, 686, 688, 687, 689, 690, 0, 691, 692,
+	0, 693, 694, 695, 0, 0, 0, 0, 0, 696,
+	697, 699, 0, 700, 701, 702, 703, 704, 705, 698,
+	706, 707, 708, 709, 710, 711, 712, 713, 0, 715,
+	716, 714, 717, 718, 942, 719, 720, 721, 722, 723,
+	1489, 724, 0, 725, 726, 734, 735, 736, 727, 728,
+	730, 737, 729, 738, 739, 740, 741, 743, 742, 316,
+	745, 746, 744, 747, 748, 749, 750, 1540, 751, 895,
+	752, 731, 732, 753, 754, 755, 943, 756, 757, 758,
+	759, 760, 761, 762, 763, 764, 1556, 0, 766, 0,
+	765, 767, 768, 769, 770, 771, 772, 773, 775, 733,
+	776, 777, 778, 783, 784, 785, 1588, 779, 780, 781,
+	782, 787, 1581, 788, 789, 790, 791, 0, 792, 793,
+	1474, 786, 774, 318, 794, 795, 796, 797, 798, 799,
+	800, 801, 802, 803, 0, 804, 1569, 1570, 1571, 1572,
+	0, 817, 0, 805, 807, 808, 809, 810, 1582, 811,
+	812, 1583, 1499, 813, 814, 815, 816, 806, 819, 820,
+	818, 0, 1481, 821, 822, 823, 824, 826, 828, 829,
+	830, 825, 827, 831, 1541, 832, 0, 0, 833, 834,
+	835, 2237, 1566, 1587, 0, 1576, 838, 839, 836, 837,
+	840, 841, 844, 842, 843, 909, 847, 542, 848, 849,
+	850, 845, 846, 0, 0, 0, 310, 851, 852, 910,
+	853, 854, 855, 1478, 0, 311, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 1473,
+	0, 0, 0, 0, 0, 0, 1471, 1472, 0, 0,
+	0, 0, 0, 0, 916, 0, 2395, 2393, 0, 0,
+	1503, 1551, 1493, 1494, 1495, 1491, 1492, 1504, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 367, 368,
+	370, 369, 371, 372, 373, 374, 0, 375, 376, 0,
+	0, 0, 0, 0, 1543, 1509, 0, 0, 378, 0,
+	377, 0, 379, 380, 381, 926, 382, 383, 384, 385,
+	386, 387, 388, 389, 390, 857, 391, 1557, 0, 392,
+	1565, 393, 1564, 3457, 1575, 394, 395, 396, 397, 398,
+	399, 400, 401, 402, 403, 404, 1511, 1542, 1475, 405,
+	1589, 1590, 864, 0, 406, 407, 408, 409, 1549, 0,
+	1530, 0, 410, 411, 412, 413, 414, 415, 416, 417,
+	0, 0, 419, 420, 421, 418, 422, 423, 0, 424,
+	0, 425, 426, 427, 428, 429, 0, 430, 431, 0,
+	432, 433, 434, 928, 435, 436, 437, 1533, 1531, 1532,
+	1539, 1535, 1534, 1538, 438, 439, 440, 441, 442, 1568,
+	443, 445, 1562, 1561, 1480, 448, 450, 444, 446, 0,
+	449, 447, 451, 452, 0, 453, 454, 455, 456, 457,
+	0, 0, 0, 458, 1560, 460, 461, 0, 462, 463,
+	464, 466, 465, 0, 467, 468, 469, 0, 470, 471,
+	1487, 472, 473, 474, 476, 478, 475, 477, 479, 480,
+	481, 482, 483, 1577, 1578, 484, 485, 1500, 362, 0,
+	0, 0, 0, 0, 486, 487, 488, 1559, 0, 0,
+	0, 489, 0, 491, 495, 496, 492, 493, 494, 497,
+	0, 490, 498, 499, 3462, 929, 500, 501, 502, 1573,
+	1574, 503, 504, 505, 506, 507, 508, 509, 510, 511,
+	0, 512, 513, 1584, 0, 1510, 514, 0, 515, 516,
+	517, 518, 519, 520, 521, 1544, 1545, 1548, 630, 931,
+	522, 523, 524, 525, 0, 526, 527, 528, 529, 530,
+	531, 532, 0, 0, 0, 533, 534, 535, 536, 0,
+	919, 363, 365, 930, 879, 537, 631, 538, 539, 1554,
+	1555, 0, 1514, 0, 540, 541, 544, 932, 1546, 933,
+	543, 545, 546, 934, 547, 0, 0, 0, 548, 549,
+	550, 551, 552, 553, 554, 0, 555, 557, 556, 3458,
+	559, 1585, 558, 935, 560, 561, 936, 0, 562, 563,
+	564, 565, 566, 567, 572, 1537, 1536, 568, 569, 570,
+	571, 573, 574, 0, 575, 576, 578, 581, 577, 579,
+	580, 582, 583, 596, 597, 598, 584, 585, 586, 587,
+	588, 589, 590, 591, 592, 593, 594, 595, 600, 0,
+	599, 937, 0, 601, 602, 603, 604, 605, 606, 612,
+	615, 617, 618, 613, 614, 616, 619, 620, 621, 623,
+	624, 609, 610, 611, 938, 622, 607, 1477, 608, 366,
+	939, 625, 626, 627, 628, 1501, 1547, 629, 1563, 632,
+	633, 0, 0, 634, 0, 635, 636, 0, 0, 638,
+	639, 640, 0, 0, 641, 642, 887, 940, 643, 941,
+	1579, 644, 645, 1488, 646, 647, 648, 649, 650, 651,
+	652, 653, 654, 655, 656, 657, 0, 658, 659, 889,
+	660, 661, 662, 663, 664, 890, 665, 666, 667, 1580,
+	668, 892, 669, 670, 671, 0, 672, 673, 674, 0,
+	675, 676, 677, 678, 679, 680, 681, 682, 683, 684,
+	1558, 685, 686, 688, 687, 689, 690, 0, 691, 692,
+	0, 693, 694, 695, 0, 0, 0, 0, 0, 696,
+	697, 699, 0, 700, 701, 702, 703, 704, 705, 698,
+	706, 707, 708, 709, 710, 711, 712, 713, 0, 715,
+	716, 714, 717, 718, 942, 719, 720, 721, 722, 723,
+	1489, 724, 0, 725, 726, 734, 735, 736, 727, 728,
+	730, 737, 729, 738, 739, 740, 741, 743, 742, 0,
+	745, 746, 744, 747, 748, 749, 750, 1540, 751, 895,
+	752, 731, 732, 753, 754, 755, 943, 756, 757, 758,
+	759, 760, 761, 762, 763, 764, 1556, 0, 766, 0,
+	765, 767, 768, 769, 770, 771, 772, 773, 775, 733,
+	776, 777, 778, 783, 784, 785, 1588, 779, 780, 781,
+	782, 787, 1581, 788, 789, 790, 791, 0, 792, 793,
+	1474, 786, 774, 0, 794, 795, 796, 797, 798, 799,
+	800, 801, 802, 803, 0, 804, 1569, 1570, 1571, 1572,
+	0, 817, 3459, 805, 807, 808, 809, 810, 1582, 811,
+	812, 1583, 1499, 813, 814, 815, 816, 806, 819, 820,
+	818, 0, 1481, 821, 822, 823, 824, 826, 828, 829,
+	830, 825, 827, 831, 1541, 832, 0, 0, 833, 834,
+	835, 905, 1566, 1587, 0, 1576, 838, 839, 836, 837,
+	840, 841, 844, 842, 843, 909, 847, 542, 848, 849,
+	850, 845, 846, 0, 0, 0, 0, 851, 852, 910,
+	853, 854, 855, 1478, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 1473,
+	0, 0, 0, 0, 0, 0, 1471, 1472, 0, 0,
+	0, 0, 0, 0, 916, 0, 1505, 0, 0, 3368,
+	1503, 1551, 1493, 1494, 1495, 1491, 1492, 1504, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 367, 368,
+	370, 369, 371, 372, 373, 374, 0, 375, 376, 0,
+	0, 0, 0, 0, 1543, 1509, 0, 0, 378, 0,
+	377, 0, 379, 380, 381, 926, 382, 383, 384, 385,
+	386, 387, 388, 389, 390, 857, 391, 1557, 0, 392,
+	1565, 393, 1564, 0, 1575, 394, 395, 396, 397, 398,
+	399, 400, 401, 402, 403, 404, 1511, 1542, 1475, 405,
+	1589, 1590, 864, 0, 406, 407, 408, 409, 1549, 0,
+	1530, 0, 410, 411, 412, 413, 414, 415, 416, 417,
+	0, 0, 419, 420, 421, 418, 422, 423, 0, 424,
+	0, 425, 426, 427, 428, 429, 0, 430, 431, 0,
+	432, 433, 434, 928, 435, 436, 437, 1533, 1531, 1532,
+	1539, 1535, 1534, 1538, 438, 439, 440, 441, 442, 1568,
+	443, 445, 1562, 1561, 1480, 448, 450, 444, 446, 0,
+	449, 447, 451, 452, 0, 453, 454, 455, 456, 457,
+	0, 0, 0, 458, 1560, 460, 461, 0, 462, 463,
+	464, 466, 465, 0, 467, 468, 469, 0, 470, 471,
+	1487, 472, 473, 474, 476, 478, 475, 477, 479, 480,
+	481, 482, 483, 1577, 1578, 484, 485, 1500, 362, 0,
+	0, 0, 0, 0, 486, 487, 488, 1559, 0, 0,
+	0, 489, 0, 491, 495, 496, 492, 493, 494, 497,
+	0, 490, 498, 499, 0, 929, 500, 501, 502, 1573,
+	1574, 503, 504, 505, 506, 507, 508, 509, 510, 511,
+	0, 512, 513, 1584, 0, 1510, 514, 0, 515, 516,
+	517, 518, 519, 520, 521, 1544, 1545, 1548, 630, 931,
+	522, 523, 524, 525, 0, 526, 527, 528, 529, 530,
+	531, 532, 0, 0, 0, 533, 534, 535, 536, 0,
+	919, 363, 365, 930, 879, 537, 631, 538, 539, 1554,
+	1555, 0, 1514, 0, 540, 541, 544, 932, 1546, 933,
+	543, 545, 546, 934, 547, 0, 0, 0, 548, 549,
+	550, 551, 552, 553, 554, 0, 555, 557, 556, 0,
+	559, 1585, 558, 935, 560, 561, 936, 0, 562, 563,
+	564, 565, 566, 567, 572, 1537, 1536, 568, 569, 570,
+	571, 573, 574, 0, 575, 576, 578, 581, 577, 579,
+	580, 582, 583, 596, 597, 598, 584, 585, 586, 587,
+	588, 589, 590, 591, 592, 593, 594, 595, 600, 0,
+	599, 937, 0, 601, 602, 603, 604, 605, 606, 612,
+	615, 617, 618, 613, 614, 616, 619, 620, 621, 623,
+	624, 609, 610, 611, 938, 622, 607, 1477, 608, 366,
+	939, 625, 626, 627, 628, 1501, 1547, 629, 1563, 632,
+	633, 0, 0, 634, 0, 635, 636, 0, 0, 638,
+	639, 640, 0, 0, 641, 642, 887, 940, 643, 941,
+	1579, 644, 645, 1488, 646, 647, 648, 649, 650, 651,
+	652, 653, 654, 655, 656, 657, 0, 658, 659, 889,
+	660, 661, 662, 663, 664, 890, 665, 666, 667, 1580,
+	668, 892, 669, 670, 671, 0, 672, 673, 674, 0,
+	675, 676, 677, 678, 679, 680, 681, 682, 683, 684,
+	1558, 685, 686, 688, 687, 689, 690, 0, 691, 692,
+	0, 693, 694, 695, 0, 0, 0, 0, 0, 696,
+	697, 699, 0, 700, 701, 702, 703, 704, 705, 698,
+	706, 707, 708, 709, 710, 711, 712, 713, 0, 715,
+	716, 714, 717, 718, 942, 719, 720, 721, 722, 723,
+	1489, 724, 0, 725, 726, 734, 735, 736, 727, 728,
+	730, 737, 729, 738, 739, 740, 741, 743, 742, 0,
+	745, 746, 744, 747, 748, 749, 750, 1540, 751, 895,
+	752, 731, 732, 753, 754, 755, 943, 756, 757, 758,
+	759, 760, 761, 762, 763, 764, 1556, 0, 766, 0,
+	765, 767, 768, 769, 770, 771, 772, 773, 775, 733,
+	776, 777, 778, 783, 784, 785, 1588, 779, 780, 781,
+	782, 787, 1581, 788, 789, 790, 791, 0, 792, 793,
+	1474, 786, 774, 0, 794, 795, 796, 797, 798, 799,
+	800, 801, 802, 803, 0, 804, 1569, 1570, 1571, 1572,
+	0, 817, 0, 805, 807, 808, 809, 810, 1582, 811,
+	812, 1583, 1499, 813, 814, 815, 816, 806, 819, 820,
+	818, 0, 1481, 821, 822, 823, 824, 826, 828, 829,
+	830, 825, 827, 831, 1541, 832, 0, 0, 833, 834,
+	835, 905, 1566, 1587, 0, 1576, 838, 839, 836, 837,
+	840, 841, 844, 842, 843, 909, 847, 542, 848, 849,
+	850, 845, 846, 0, 0, 0, 0, 851, 852, 910,
+	853, 854, 855, 1478, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 1473,
+	0, 0, 0, 0, 0, 0, 1471, 1472, 0, 0,
+	0, 0, 0, 0, 916, 0, 1505, 3366, 0, 3365,
+	1503, 1551, 1493, 1494, 1495, 1491, 1492, 1504, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 367, 368,
+	370, 369, 371, 372, 373, 374, 0, 375, 376, 0,
+	0, 0, 0, 0, 1543, 1509, 0, 0, 378, 0,
+	377, 0, 379, 380, 381, 926, 382, 383, 384, 385,
+	386, 387, 388, 389, 390, 857, 391, 1557, 0, 392,
+	1565, 393, 1564, 0, 1575, 394, 395, 396, 397, 398,
+	399, 400, 401, 402, 403, 404, 1511, 1542, 1475, 405,
+	1589, 1590, 864, 0, 406, 407, 408, 409, 1549, 0,
+	1530, 0, 410, 411, 412, 413, 414, 415, 416, 417,
+	0, 0, 419, 420, 421, 418, 422, 423, 0, 424,
+	0, 425, 426, 427, 428, 429, 0, 430, 431, 0,
+	432, 433, 434, 928, 435, 436, 437, 1533, 1531, 1532,
+	1539, 1535, 1534, 1538, 438, 439, 440, 441, 442, 1568,
+	443, 445, 1562, 1561, 1480, 448, 450, 444, 446, 0,
+	449, 447, 451, 452, 0, 453, 454, 455, 456, 457,
+	0, 0, 0, 458, 1560, 460, 461, 0, 462, 463,
+	464, 466, 465, 0, 467, 468, 469, 0, 470, 471,
+	1487, 472, 473, 474, 476, 478, 475, 477, 479, 480,
+	481, 482, 483, 1577, 1578, 484, 485, 1500, 362, 0,
+	0, 0, 0, 0, 486, 487, 488, 1559, 0, 0,
+	0, 489, 0, 491, 495, 496, 492, 493, 494, 497,
+	0, 490, 498, 499, 0, 929, 500, 501, 502, 1573,
+	1574, 503, 504, 505, 506, 507, 508, 509, 510, 511,
+	0, 512, 513, 1584, 0, 1510, 514, 0, 515, 516,
+	517, 518, 519, 520, 521, 1544, 1545, 1548, 630, 931,
+	522, 523, 524, 525, 0, 526, 527, 528, 529, 530,
+	531, 532, 0, 0, 0, 533, 534, 535, 536, 0,
+	919, 363, 365, 930, 879, 537, 631, 538, 539, 1554,
+	1555, 0, 1514, 0, 540, 541, 544, 932, 1546, 933,
+	543, 545, 546, 934, 547, 0, 0, 0, 548, 549,
+	550, 551, 552, 553, 554, 0, 555, 557, 556, 0,
+	559, 1585, 558, 935, 560, 561, 936, 0, 562, 563,
+	564, 565, 566, 567, 572, 1537, 1536, 568, 569, 570,
+	571, 573, 574, 0, 575, 576, 578, 581, 577, 579,
+	580, 582, 583, 596, 597, 598, 584, 585, 586, 587,
+	588, 589, 590, 591, 592, 593, 594, 595, 600, 0,
+	599, 937, 0, 601, 602, 603, 604, 605, 606, 612,
+	615, 617, 618, 613, 614, 616, 619, 620, 621, 623,
+	624, 609, 610, 611, 938, 622, 607, 1477, 608, 366,
+	939, 625, 626, 627, 628, 1501, 1547, 629, 1563, 632,
+	633, 0, 0, 634, 0, 635, 636, 0, 0, 638,
+	639, 640, 0, 0, 641, 642, 887, 940, 643, 941,
+	1579, 644, 645, 1488, 646, 647, 648, 649, 650, 651,
+	652, 653, 654, 655, 656, 657, 0, 658, 659, 889,
+	660, 661, 662, 663, 664, 890, 665, 666, 667, 1580,
+	668, 892, 669, 670, 671, 0, 672, 673, 674, 0,
+	675, 676, 677, 678, 679, 680, 681, 682, 683, 684,
+	1558, 685, 686, 688, 687, 689, 690, 0, 691, 692,
+	0, 693, 694, 695, 0, 0, 0, 0, 0, 696,
+	697, 699, 0, 700, 701, 702, 703, 704, 705, 698,
+	706, 707, 708, 709, 710, 711, 712, 713, 0, 715,
+	716, 714, 717, 718, 942, 719, 720, 721, 722, 723,
+	1489, 724, 0, 725, 726, 734, 735, 736, 727, 728,
+	730, 737, 729, 738, 739, 740, 741, 743, 742, 0,
+	745, 746, 744, 747, 748, 749, 750, 1540, 751, 895,
+	752, 731, 732, 753, 754, 755, 943, 756, 757, 758,
+	759, 760, 761, 762, 763, 764, 1556, 0, 766, 0,
+	765, 767, 768, 769, 770, 771, 772, 773, 775, 733,
+	776, 777, 778, 783, 784, 785, 1588, 779, 780, 781,
+	782, 787, 1581, 788, 789, 790, 791, 0, 792, 793,
+	1474, 786, 774, 0, 794, 795, 796, 797, 798, 799,
+	800, 801, 802, 803, 0, 804, 1569, 1570, 1571, 1572,
+	0, 817, 0, 805, 807, 808, 809, 810, 1582, 811,
+	812, 1583, 1499, 813, 814, 815, 816, 806, 819, 820,
+	818, 0, 1481, 821, 822, 823, 824, 826, 828, 829,
+	830, 825, 827, 831, 1541, 832, 0, 0, 833, 834,
+	835, 905, 1566, 1587, 0, 1576, 838, 839, 836, 837,
+	840, 841, 844, 842, 843, 909, 847, 542, 848, 849,
+	850, 845, 846, 0, 0, 0, 0, 851, 852, 910,
+	853, 854, 855, 1478, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 1473,
+	0, 0, 0, 0, 0, 0, 1471, 1472, 0, 0,
+	0, 0, 0, 0, 916, 0, 1505, 3363, 0, 3362,
+	1503, 1551, 1493, 1494, 1495, 1491, 1492, 1504, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 367, 368,
+	370, 369, 371, 372, 373, 374, 0, 375, 376, 0,
+	0, 0, 0, 0, 1543, 1509, 0, 0, 378, 0,
+	377, 0, 379, 380, 381, 926, 382, 383, 384, 385,
+	386, 387, 388, 389, 390, 857, 391, 1557, 0, 392,
+	1565, 393, 1564, 0, 1575, 394, 395, 396, 397, 398,
+	399, 400, 401, 402, 403, 404, 1511, 1542, 1475, 405,
+	1589, 1590, 864, 0, 406, 407, 408, 409, 1549, 0,
+	1530, 0, 410, 411, 412, 413, 414, 415, 416, 417,
+	0, 0, 419, 420, 421, 418, 422, 423, 0, 424,
+	0, 425, 426, 427, 428, 429, 0, 430, 431, 0,
+	432, 433, 434, 928, 435, 436, 437, 1533, 1531, 1532,
+	1539, 1535, 1534, 1538, 438, 439, 440, 441, 442, 1568,
+	443, 445, 1562, 1561, 1480, 448, 450, 444, 446, 0,
+	449, 447, 451, 452, 0, 453, 454, 455, 456, 457,
+	0, 0, 0, 458, 1560, 460, 461, 0, 462, 463,
+	464, 466, 465, 0, 467, 468, 469, 0, 470, 471,
+	1487, 472, 473, 474, 476, 478, 475, 477, 479, 480,
+	481, 482, 483, 1577, 1578, 484, 485, 1500, 362, 0,
+	0, 0, 0, 0, 486, 487, 488, 1559, 0, 0,
+	0, 489, 0, 491, 495, 496, 492, 493, 494, 497,
+	0, 490, 498, 499, 0, 929, 500, 501, 502, 1573,
+	1574, 503, 504, 505, 506, 507, 508, 509, 510, 511,
+	0, 512, 513, 1584, 0, 1510, 514, 0, 515, 516,
+	517, 518, 519, 520, 521, 1544, 1545, 1548, 630, 931,
+	522, 523, 524, 525, 0, 526, 527, 528, 529, 530,
+	531, 532, 0, 0, 0, 533, 534, 535, 536, 0,
+	919, 363, 365, 930, 879, 537, 631, 538, 539, 1554,
+	1555, 0, 1514, 0, 540, 541, 544, 932, 1546, 933,
+	543, 545, 546, 934, 547, 0, 0, 0, 548, 549,
+	550, 551, 552, 553, 554, 0, 555, 557, 556, 0,
+	559, 1585, 558, 935, 560, 561, 936, 0, 562, 563,
+	564, 565, 566, 567, 572, 1537, 1536, 568, 569, 570,
+	571, 573, 574, 0, 575, 576, 578, 581, 577, 579,
+	580, 582, 583, 596, 597, 598, 584, 585, 586, 587,
+	588, 589, 590, 591, 592, 593, 594, 595, 600, 0,
+	599, 937, 0, 601, 602, 603, 604, 605, 606, 612,
+	615, 617, 618, 613, 614, 616, 619, 620, 621, 623,
+	624, 609, 610, 611, 938, 622, 607, 1477, 608, 366,
+	939, 625, 626, 627, 628, 1501, 1547, 629, 1563, 632,
+	633, 0, 0, 634, 0, 635, 636, 0, 0, 638,
+	639, 640, 0, 0, 641, 642, 887, 940, 643, 941,
+	1579, 644, 645, 1488, 646, 647, 648, 649, 650, 651,
+	652, 653, 654, 655, 656, 657, 0, 658, 659, 889,
+	660, 661, 662, 663, 664, 890, 665, 666, 667, 1580,
+	668, 892, 669, 670, 671, 0, 672, 673, 674, 0,
+	675, 676, 677, 678, 679, 680, 681, 682, 683, 684,
+	1558, 685, 686, 688, 687, 689, 690, 0, 691, 692,
+	0, 693, 694, 695, 0, 0, 0, 0, 0, 696,
+	697, 699, 0, 700, 701, 702, 703, 704, 705, 698,
+	706, 707, 708, 709, 710, 711, 712, 713, 0, 715,
+	716, 714, 717, 718, 942, 719, 720, 721, 722, 723,
+	1489, 724, 0, 725, 726, 734, 735, 736, 727, 728,
+	730, 737, 729, 738, 739, 740, 741, 743, 742, 0,
+	745, 746, 744, 747, 748, 749, 750, 1540, 751, 895,
+	752, 731, 732, 753, 754, 755, 943, 756, 757, 758,
+	759, 760, 761, 762, 763, 764, 1556, 0, 766, 0,
+	765, 767, 768, 769, 770, 771, 772, 773, 775, 733,
+	776, 777, 778, 783, 784, 785, 1588, 779, 780, 781,
+	782, 787, 1581, 788, 789, 790, 791, 0, 792, 793,
+	1474, 786, 774, 0, 794, 795, 796, 797, 798, 799,
+	800, 801, 802, 803, 0, 804, 1569, 1570, 1571, 1572,
+	0, 817, 0, 805, 807, 808, 809, 810, 1582, 811,
+	812, 1583, 1499, 813, 814, 815, 816, 806, 819, 820,
+	818, 0, 1481, 821, 822, 823, 824, 826, 828, 829,
+	830, 825, 827, 831, 1541, 832, 0, 0, 833, 834,
+	835, 905, 1566, 1587, 0, 1576, 838, 839, 836, 837,
+	840, 841, 844, 842, 843, 909, 847, 542, 848, 849,
+	850, 845, 846, 0, 0, 0, 0, 851, 852, 910,
+	853, 854, 855, 1478, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 1473,
+	0, 0, 0, 0, 0, 0, 1471, 1472, 0, 0,
+	0, 0, 0, 0, 916, 0, 1505, 3360, 0, 3359,
+	1503, 1551, 1493, 1494, 1495, 1491, 1492, 1504, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 367, 368,
+	370, 369, 371, 372, 373, 374, 0, 375, 376, 0,
+	0, 0, 0, 0, 1543, 1509, 0, 0, 378, 0,
+	377, 0, 379, 380, 381, 926, 382, 383, 384, 385,
+	386, 387, 388, 389, 390, 857, 391, 1557, 0, 392,
+	1565, 393, 1564, 0, 1575, 394, 395, 396, 397, 398,
+	399, 400, 401, 402, 403, 404, 1511, 1542, 1475, 405,
+	1589, 1590, 864, 0, 406, 407, 408, 409, 1549, 0,
+	1530, 0, 410, 411, 412, 413, 414, 415, 416, 417,
+	0, 0, 419, 420, 421, 418, 422, 423, 0, 424,
+	0, 425, 426, 427, 428, 429, 0, 430, 431, 0,
+	432, 433, 434, 928, 435, 436, 437, 1533, 1531, 1532,
+	1539, 1535, 1534, 1538, 438, 439, 440, 441, 442, 1568,
+	443, 445, 1562, 1561, 1480, 448, 450, 444, 446, 0,
+	449, 447, 451, 452, 0, 453, 454, 455, 456, 457,
+	0, 0, 0, 458, 1560, 460, 461, 0, 462, 463,
+	464, 466, 465, 0, 467, 468, 469, 0, 470, 471,
+	1487, 472, 473, 474, 476, 478, 475, 477, 479, 480,
+	481, 482, 483, 1577, 1578, 484, 485, 1500, 362, 0,
+	0, 0, 0, 0, 486, 487, 488, 1559, 0, 0,
+	0, 489, 0, 491, 495, 496, 492, 493, 494, 497,
+	0, 490, 498, 499, 0, 929, 500, 501, 502, 1573,
+	1574, 503, 504, 505, 506, 507, 508, 509, 510, 511,
+	0, 512, 513, 1584, 0, 1510, 514, 0, 515, 516,
+	517, 518, 519, 520, 521, 1544, 1545, 1548, 630, 931,
+	522, 523, 524, 525, 0, 526, 527, 528, 529, 530,
+	531, 532, 0, 0, 0, 533, 534, 535, 536, 0,
+	919, 363, 365, 930, 879, 537, 631, 538, 539, 1554,
+	1555, 0, 1514, 0, 540, 541, 544, 932, 1546, 933,
+	543, 545, 546, 934, 547, 0, 0, 0, 548, 549,
+	550, 551, 552, 553, 554, 0, 555, 557, 556, 0,
+	559, 1585, 558, 935, 560, 561, 936, 0, 562, 563,
+	564, 565, 566, 567, 572, 1537, 1536, 568, 569, 570,
+	571, 573, 574, 0, 575, 576, 578, 581, 577, 579,
+	580, 582, 583, 596, 597, 598, 584, 585, 586, 587,
+	588, 589, 590, 591, 592, 593, 594, 595, 600, 0,
+	599, 937, 0, 601, 602, 603, 604, 605, 606, 612,
+	615, 617, 618, 613, 614, 616, 619, 620, 621, 623,
+	624, 609, 610, 611, 938, 622, 607, 1477, 608, 366,
+	939, 625, 626, 627, 628, 1501, 1547, 629, 1563, 632,
+	633, 0, 0, 634, 0, 635, 636, 0, 0, 638,
+	639, 640, 0, 0, 641, 642, 887, 940, 643, 941,
+	1579, 644, 645, 1488, 646, 647, 648, 649, 650, 651,
+	652, 653, 654, 655, 656, 657, 0, 658, 659, 889,
+	660, 661, 662, 663, 664, 890, 665, 666, 667, 1580,
+	668, 892, 669, 670, 671, 0, 672, 673, 674, 0,
+	675, 676, 677, 678, 679, 680, 681, 682, 683, 684,
+	1558, 685, 686, 688, 687, 689, 690, 0, 691, 692,
+	0, 693, 694, 695, 0, 0, 0, 0, 0, 696,
+	697, 699, 0, 700, 701, 702, 703, 704, 705, 698,
+	706, 707, 708, 709, 710, 711, 712, 713, 0, 715,
+	716, 714, 717, 718, 942, 719, 720, 721, 722, 723,
+	1489, 724, 0, 725, 726, 734, 735, 736, 727, 728,
+	730, 737, 729, 738, 739, 740, 741, 743, 742, 0,
+	745, 746, 744, 747, 748, 749, 750, 1540, 751, 895,
+	752, 731, 732, 753, 754, 755, 943, 756, 757, 758,
+	759, 760, 761, 762, 763, 764, 1556, 0, 766, 0,
+	765, 767, 768, 769, 770, 771, 772, 773, 775, 733,
+	776, 777, 778, 783, 784, 785, 1588, 779, 780, 781,
+	782, 787, 1581, 788, 789, 790, 791, 0, 792, 793,
+	1474, 786, 774, 0, 794, 795, 796, 797, 798, 799,
+	800, 801, 802, 803, 0, 804, 1569, 1570, 1571, 1572,
+	0, 817, 0, 805, 807, 808, 809, 810, 1582, 811,
+	812, 1583, 1499, 813, 814, 815, 816, 806, 819, 820,
+	818, 0, 1481, 821, 822, 823, 824, 826, 828, 829,
+	830, 825, 827, 831, 1541, 832, 0, 0, 833, 834,
+	835, 905, 1566, 1587, 0, 1576, 838, 839, 836, 837,
+	840, 841, 844, 842, 843, 909, 847, 542, 848, 849,
+	850, 845, 846, 0, 0, 0, 0, 851, 852, 910,
+	853, 854, 855, 1478, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 1473,
+	0, 0, 0, 0, 0, 0, 1471, 1472, 0, 0,
+	0, 0, 0, 0, 916, 0, 1505, 3357, 0, 1896,
+	1503, 1551, 1493, 1494, 1495, 1491, 1492, 1504, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 367, 368,
+	370, 369, 371, 372, 373, 374, 0, 375, 376, 0,
+	0, 0, 0, 0, 1543, 1509, 0, 0, 378, 0,
+	377, 0, 379, 380, 381, 926, 382, 383, 384, 385,
+	386, 387, 388, 389, 390, 857, 391, 1557, 0, 392,
+	1565, 393, 1564, 0, 1575, 394, 395, 396, 397, 398,
+	399, 400, 401, 402, 403, 404, 1511, 1542, 1475, 405,
+	1589, 1590, 864, 0, 406, 407, 408, 409, 1549, 0,
+	1530, 0, 410, 411, 412, 413, 414, 415, 416, 417,
+	0, 0, 419, 420, 421, 418, 422, 423, 0, 424,
+	0, 425, 426, 427, 428, 429, 0, 430, 431, 0,
+	432, 433, 434, 928, 435, 436, 437, 1533, 1531, 1532,
+	1539, 1535, 1534, 1538, 438, 439, 440, 441, 442, 1568,
+	443, 445, 1562, 1561, 1480, 448, 450, 444, 446, 0,
+	449, 447, 451, 452, 0, 453, 454, 455, 456, 457,
+	0, 0, 0, 458, 1560, 460, 461, 0, 462, 463,
+	464, 466, 465, 0, 467, 468, 469, 0, 470, 471,
+	1487, 472, 473, 474, 476, 478, 475, 477, 479, 480,
+	481, 482, 483, 1577, 1578, 484, 485, 1500, 362, 0,
+	0, 0, 0, 0, 486, 487, 488, 1559, 0, 0,
+	0, 489, 0, 491, 495, 496, 492, 493, 494, 497,
+	0, 490, 498, 499, 0, 929, 500, 501, 502, 1573,
+	1574, 503, 504, 505, 506, 507, 508, 509, 510, 511,
+	0, 512, 513, 1584, 0, 1510, 514, 0, 515, 516,
+	517, 518, 519, 520, 521, 1544, 1545, 1548, 630, 931,
+	522, 523, 524, 525, 0, 526, 527, 528, 529, 530,
+	531, 532, 0, 0, 0, 533, 534, 535, 536, 0,
+	919, 363, 365, 930, 879, 537, 631, 538, 539, 1554,
+	1555, 0, 1514, 0, 540, 541, 544, 932, 1546, 933,
+	543, 545, 546, 934, 547, 0, 0, 0, 548, 549,
+	550, 551, 552, 553, 554, 0, 555, 557, 556, 0,
+	559, 1585, 558, 935, 560, 561, 936, 0, 562, 563,
+	564, 565, 566, 567, 572, 1537, 1536, 568, 569, 570,
+	571, 573, 574, 0, 575, 576, 578, 581, 577, 579,
+	580, 582, 583, 596, 597, 598, 584, 585, 586, 587,
+	588, 589, 590, 591, 592, 593, 594, 595, 600, 0,
+	599, 937, 0, 601, 602, 603, 604, 605, 606, 612,
+	615, 617, 618, 613, 614, 616, 619, 620, 621, 623,
+	624, 609, 610, 611, 938, 622, 607, 1477, 608, 366,
+	939, 625, 626, 627, 628, 1501, 1547, 629, 1563, 632,
+	633, 0, 0, 634, 0, 635, 636, 0, 0, 638,
+	639, 640, 0, 0, 641, 642, 887, 940, 643, 941,
+	1579, 644, 645, 1488, 646, 647, 648, 649, 650, 651,
+	652, 653, 654, 655, 656, 657, 0, 658, 659, 889,
+	660, 661, 662, 663, 664, 890, 665, 666, 667, 1580,
+	668, 892, 669, 670, 671, 0, 672, 673, 674, 0,
+	675, 676, 677, 678, 679, 680, 681, 682, 683, 684,
+	1558, 685, 686, 688, 687, 689, 690, 0, 691, 692,
+	0, 693, 694, 695, 0, 0, 0, 0, 0, 696,
+	697, 699, 0, 700, 701, 702, 703, 704, 705, 698,
+	706, 707, 708, 709, 710, 711, 712, 713, 0, 715,
+	716, 714, 717, 718, 942, 719, 720, 721, 722, 723,
+	1489, 724, 0, 725, 726, 734, 735, 736, 727, 728,
+	730, 737, 729, 738, 739, 740, 741, 743, 742, 0,
+	745, 746, 744, 747, 748, 749, 750, 1540, 751, 895,
+	752, 731, 732, 753, 754, 755, 943, 756, 757, 758,
+	759, 760, 761, 762, 763, 764, 1556, 0, 766, 0,
+	765, 767, 768, 769, 770, 771, 772, 773, 775, 733,
+	776, 777, 778, 783, 784, 785, 1588, 779, 780, 781,
+	782, 787, 1581, 788, 789, 790, 791, 0, 792, 793,
+	1474, 786, 774, 0, 794, 795, 796, 797, 798, 799,
+	800, 801, 802, 803, 0, 804, 1569, 1570, 1571, 1572,
+	0, 817, 0, 805, 807, 808, 809, 810, 1582, 811,
+	812, 1583, 1499, 813, 814, 815, 816, 806, 819, 820,
+	818, 0, 1481, 821, 822, 823, 824, 826, 828, 829,
+	830, 825, 827, 831, 1541, 832, 0, 0, 833, 834,
+	835, 905, 1566, 1587, 0, 1576, 838, 839, 836, 837,
+	840, 841, 844, 842, 843, 909, 847, 542, 848, 849,
+	850, 845, 846, 1895, 0, 0, 0, 851, 852, 910,
+	853, 854, 855, 1478, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 1473,
+	0, 0, 0, 0, 0, 0, 1471, 1472, 0, 0,
+	0, 0, 0, 0, 916, 0, 1505, 0, 0, 1467,
+	1503, 1551, 1493, 1494, 1495, 1491, 1492, 1504, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 367, 368,
+	370, 369, 371, 372, 373, 374, 0, 375, 376, 0,
+	0, 0, 0, 0, 1543, 1509, 0, 0, 378, 0,
+	377, 0, 379, 380, 381, 926, 382, 383, 384, 385,
+	386, 387, 388, 389, 390, 857, 391, 1557, 0, 392,
+	1565, 393, 1564, 0, 1575, 394, 395, 396, 397, 398,
+	399, 400, 401, 402, 403, 404, 1511, 1542, 1475, 405,
+	1589, 1590, 864, 0, 406, 407, 408, 409, 1549, 0,
+	1530, 0, 410, 411, 412, 413, 414, 415, 416, 417,
+	0, 0, 419, 420, 421, 418, 422, 423, 0, 424,
+	0, 425, 426, 427, 428, 429, 0, 430, 431, 0,
+	432, 433, 434, 928, 435, 436, 437, 1533, 1531, 1532,
+	1539, 1535, 1534, 1538, 438, 439, 440, 441, 442, 1568,
+	443, 445, 1562, 1561, 1480, 448, 450, 444, 446, 0,
+	449, 447, 451, 452, 0, 453, 454, 455, 456, 457,
+	0, 0, 0, 458, 1560, 460, 461, 0, 462, 463,
+	464, 466, 465, 0, 467, 468, 469, 0, 470, 471,
+	1487, 472, 473, 474, 476, 478, 475, 477, 479, 480,
+	481, 482, 483, 1577, 1578, 484, 485, 1500, 362, 0,
+	0, 0, 0, 0, 486, 487, 488, 1559, 0, 0,
+	0, 489, 0, 491, 495, 496, 492, 493, 494, 497,
+	0, 490, 498, 499, 0, 929, 500, 501, 502, 1573,
+	1574, 503, 504, 505, 506, 507, 508, 509, 510, 511,
+	0, 512, 513, 1584, 0, 1510, 514, 0, 515, 516,
+	517, 518, 519, 520, 521, 1544, 1545, 1548, 630, 931,
+	522, 523, 524, 525, 0, 526, 527, 528, 529, 530,
+	531, 532, 0, 0, 0, 533, 534, 535, 536, 0,
+	919, 363, 365, 930, 879, 537, 631, 538, 539, 1554,
+	1555, 0, 1514, 0, 540, 541, 544, 932, 1546, 933,
+	543, 545, 546, 934, 547, 0, 0, 0, 548, 549,
+	550, 551, 552, 553, 554, 0, 555, 557, 556, 0,
+	559, 1585, 558, 935, 560, 561, 936, 0, 562, 563,
+	564, 565, 566, 567, 572, 1537, 1536, 568, 569, 570,
+	571, 573, 574, 0, 575, 576, 578, 581, 577, 579,
+	580, 582, 583, 596, 597, 598, 584, 585, 586, 587,
+	588, 589, 590, 591, 592, 593, 594, 595, 600, 0,
+	599, 937, 0, 601, 602, 603, 604, 605, 606, 612,
+	615, 617, 618, 613, 614, 616, 619, 620, 621, 623,
+	624, 609, 610, 611, 1483, 622, 607, 1477, 608, 366,
+	939, 625, 626, 627, 628, 1501, 1547, 629, 1563, 632,
+	633, 0, 0, 634, 0, 635, 636, 1482, 0, 638,
+	639, 640, 0, 0, 641, 642, 887, 940, 643, 941,
+	1579, 644, 645, 1488, 646, 647, 648, 649, 650, 651,
+	652, 653, 654, 655, 656, 657, 0, 658, 659, 889,
+	660, 661, 662, 663, 664, 890, 665, 666, 667, 1580,
+	668, 892, 669, 670, 671, 0, 672, 673, 674, 0,
+	675, 676, 677, 678, 679, 680, 681, 682, 683, 684,
+	1558, 685, 686, 688, 687, 689, 690, 0, 691, 692,
+	0, 693, 694, 695, 0, 0, 0, 0, 0, 696,
+	697, 699, 0, 700, 701, 702, 703, 704, 705, 698,
+	706, 707, 708, 709, 710, 711, 712, 713, 0, 715,
+	716, 714, 717, 718, 942, 719, 720, 721, 722, 723,
+	1489, 724, 0, 725, 726, 734, 735, 736, 727, 728,
+	730, 737, 729, 738, 739, 740, 741, 743, 742, 0,
+	745, 746, 744, 747, 748, 749, 750, 1540, 751, 895,
+	752, 731, 732, 753, 754, 755, 943, 756, 757, 758,
+	759, 760, 761, 762, 763, 764, 1556, 0, 766, 0,
+	765, 767, 768, 769, 770, 771, 772, 773, 775, 733,
+	776, 777, 778, 783, 784, 785, 1588, 779, 780, 781,
+	782, 787, 1581, 788, 789, 790, 791, 0, 792, 793,
+	1474, 786, 774, 0, 794, 795, 796, 797, 798, 799,
+	800, 801, 802, 803, 0, 804, 1569, 1570, 1571, 1572,
+	0, 817, 0, 805, 807, 808, 809, 810, 1582, 811,
+	812, 1583, 1499, 813, 814, 815, 816, 806, 819, 820,
+	818, 0, 1481, 821, 822, 823, 824, 826, 828, 829,
+	830, 825, 827, 831, 1541, 832, 0, 0, 833, 834,
+	835, 905, 1566, 1587, 0, 1576, 838, 839, 836, 837,
+	840, 841, 844, 842, 843, 909, 847, 542, 848, 849,
+	850, 845, 846, 0, 0, 0, 0, 851, 852, 910,
+	853, 854, 855, 1478, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 1473,
+	0, 0, 0, 0, 0, 0, 1471, 1472, 0, 0,
+	0, 0, 0, 0, 916, 0, 1505, 0, 0, 0,
+	1503, 1551, 1493, 1494, 1495, 1491, 1492, 1504, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 367, 368,
+	370, 369, 371, 372, 373, 374, 0, 375, 376, 0,
+	0, 0, 0, 0, 1543, 1509, 0, 0, 378, 0,
+	377, 0, 379, 380, 381, 926, 382, 383, 384, 385,
+	386, 387, 388, 389, 390, 857, 391, 1557, 0, 392,
+	1565, 393, 1564, 0, 1575, 394, 395, 396, 397, 398,
+	399, 400, 401, 402, 403, 404, 1511, 1542, 1475, 405,
+	1589, 1590, 864, 0, 406, 407, 408, 409, 1549, 0,
+	1530, 0, 410, 411, 412, 413, 414, 415, 416, 417,
+	0, 0, 419, 420, 421, 418, 422, 423, 0, 424,
+	0, 425, 426, 427, 428, 6963, 0, 430, 431, 0,
+	432, 433, 434, 928, 435, 436, 437, 1533, 1531, 1532,
+	1539, 1535, 1534, 1538, 438, 439, 440, 441, 442, 1568,
+	443, 445, 1562, 1561, 1480, 448, 450, 444, 446, 0,
+	449, 447, 451, 452, 0, 453, 454, 455, 456, 457,
+	0, 0, 0, 458, 1560, 460, 461, 0, 462, 463,
+	464, 466, 465, 0, 467, 468, 469, 0, 470, 471,
+	1487, 472, 473, 474, 476, 478, 475, 477, 479, 480,
+	481, 482, 483, 1577, 1578, 484, 485, 1500, 362, 0,
+	0, 0, 0, 0, 486, 487, 488, 1559, 0, 0,
+	0, 489, 0, 491, 495, 496, 492, 493, 494, 497,
+	0, 490, 498, 499, 0, 929, 500, 501, 502, 1573,
+	1574, 503, 504, 505, 506, 507, 508, 509, 510, 511,
+	0, 512, 513, 1584, 0, 1510, 514, 0, 515, 516,
+	517, 518, 519, 520, 521, 1544, 1545, 1548, 630, 931,
+	522, 523, 524, 525, 0, 526, 527, 528, 529, 530,
+	531, 532, 0, 0, 0, 533, 534, 535, 536, 0,
+	919, 363, 365, 930, 879, 537, 631, 538, 539, 1554,
+	1555, 0, 1514, 0, 540, 541, 544, 932, 1546, 933,
+	543, 545, 546, 934, 547, 0, 0, 0, 548, 549,
+	550, 551, 552, 553, 554, 0, 555, 557, 556, 0,
+	559, 1585, 558, 935, 560, 561, 936, 0, 562, 563,
+	564, 565, 566, 567, 572, 1537, 1536, 568, 569, 570,
+	571, 573, 574, 0, 575, 576, 578, 581, 577, 579,
+	580, 582, 583, 596, 597, 598, 584, 585, 586, 587,
+	588, 589, 590, 591, 592, 593, 594, 595, 600, 0,
+	599, 937, 0, 601, 602, 603, 604, 605, 606, 612,
+	615, 617, 618, 613, 614, 616, 619, 620, 621, 623,
+	624, 609, 610, 611, 1483, 622, 607, 1477, 608, 366,
+	939, 625, 626, 627, 628, 1501, 1547, 629, 1563, 632,
+	633, 0, 0, 634, 0, 635, 636, 1482, 0, 638,
+	639, 640, 0, 0, 641, 642, 887, 940, 643, 941,
+	1579, 644, 645, 1488, 646, 647, 648, 649, 650, 651,
+	652, 653, 654, 655, 656, 657, 0, 658, 659, 889,
+	660, 661, 662, 663, 664, 890, 665, 666, 667, 1580,
+	668, 892, 669, 670, 671, 0, 672, 673, 674, 0,
+	675, 676, 677, 678, 679, 680, 681, 682, 683, 684,
+	1558, 685, 686, 688, 687, 689, 690, 0, 691, 692,
+	0, 693, 694, 695, 0, 0, 0, 0, 0, 696,
+	697, 699, 0, 700, 701, 702, 703, 704, 705, 698,
+	706, 707, 708, 709, 710, 711, 712, 713, 0, 715,
+	716, 714, 717, 718, 942, 719, 720, 721, 722, 723,
+	1489, 724, 0, 725, 726, 734, 735, 736, 727, 728,
+	730, 737, 729, 738, 739, 740, 741, 743, 742, 0,
+	745, 746, 744, 747, 748, 749, 750, 1540, 751, 895,
+	752, 731, 732, 753, 754, 755, 943, 756, 757, 758,
+	759, 760, 761, 762, 763, 764, 1556, 0, 766, 0,
+	765, 767, 768, 769, 770, 771, 772, 773, 775, 733,
+	776, 777, 778, 783, 784, 785, 1588, 779, 780, 781,
+	782, 787, 1581, 788, 789, 790, 791, 0, 792, 793,
+	1474, 786, 774, 0, 794, 795, 796, 797, 798, 799,
+	800, 801, 802, 803, 0, 804, 1569, 1570, 1571, 1572,
+	0, 817, 0, 805, 807, 808, 809, 810, 1582, 811,
+	812, 1583, 1499, 813, 814, 815, 816, 806, 819, 820,
+	818, 0, 1481, 821, 822, 823, 824, 826, 828, 829,
+	830, 825, 827, 831, 1541, 832, 0, 0, 833, 834,
+	835, 905, 1566, 1587, 0, 1576, 838, 839, 836, 837,
+	840, 841, 844, 842, 843, 909, 847, 542, 848, 849,
+	850, 845, 846, 0, 0, 0, 0, 851, 852, 910,
+	853, 854, 855, 1478, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 1473,
+	0, 0, 0, 0, 0, 0, 1471, 1472, 0, 0,
+	0, 0, 0, 0, 916, 0, 1505, 0, 0, 0,
+	1503, 1551, 1493, 1494, 1495, 1491, 1492, 1504, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 367, 368,
+	370, 369, 371, 372, 373, 374, 0, 375, 376, 0,
+	0, 0, 0, 0, 1543, 1509, 0, 0, 378, 0,
+	377, 0, 379, 380, 381, 926, 382, 383, 384, 385,
+	386, 387, 388, 389, 390, 857, 391, 1557, 0, 392,
+	1565, 393, 1564, 0, 1575, 394, 395, 396, 397, 398,
+	399, 400, 401, 402, 403, 404, 1511, 1542, 1475, 405,
+	1589, 1590, 864, 0, 406, 407, 408, 409, 1549, 0,
+	1530, 0, 410, 411, 412, 413, 414, 415, 416, 417,
+	0, 0, 419, 420, 421, 418, 422, 423, 0, 424,
+	0, 425, 426, 427, 428, 429, 0, 430, 431, 0,
+	432, 433, 434, 928, 435, 436, 437, 1533, 1531, 1532,
+	1539, 1535, 1534, 1538, 438, 439, 440, 441, 442, 1568,
+	443, 445, 1562, 1561, 1480, 448, 450, 444, 446, 0,
+	449, 447, 451, 452, 0, 453, 454, 455, 456, 457,
+	0, 0, 0, 458, 1560, 460, 461, 0, 462, 463,
+	464, 466, 465, 0, 467, 468, 469, 0, 470, 471,
+	1487, 472, 473, 474, 476, 478, 475, 477, 479, 480,
+	481, 482, 483, 1577, 1578, 484, 485, 1500, 362, 0,
+	0, 0, 0, 0, 486, 487, 488, 1559, 0, 0,
+	0, 489, 0, 491, 495, 496, 492, 493, 494, 497,
+	0, 490, 498, 499, 0, 929, 500, 501, 502, 1573,
+	1574, 503, 504, 505, 506, 507, 508, 509, 510, 511,
+	0, 512, 513, 1584, 0, 1510, 514, 0, 515, 516,
+	517, 518, 519, 520, 521, 1544, 1545, 1548, 630, 931,
+	522, 523, 524, 525, 0, 526, 527, 528, 529, 530,
+	531, 532, 0, 0, 0, 533, 534, 535, 536, 0,
+	919, 363, 3196, 930, 879, 537, 631, 538, 539, 1554,
+	1555, 0, 1514, 0, 540, 541, 544, 932, 1546, 933,
+	543, 545, 546, 934, 547, 0, 0, 0, 548, 549,
+	550, 551, 552, 553, 554, 0, 555, 557, 556, 0,
+	559, 1585, 558, 935, 560, 561, 936, 0, 562, 563,
+	564, 565, 566, 567, 572, 1537, 1536, 568, 569, 570,
+	571, 573, 574, 0, 575, 576, 578, 581, 577, 579,
+	580, 582, 583, 596, 597, 598, 584, 585, 586, 587,
+	588, 589, 590, 591, 592, 593, 594, 595, 600, 0,
+	599, 937, 0, 601, 602, 603, 604, 605, 606, 612,
+	615, 617, 618, 613, 614, 616, 619, 620, 621, 623,
+	624, 609, 610, 611, 938, 622, 607, 1477, 608, 366,
+	939, 625, 626, 627, 628, 1501, 1547, 629, 1563, 632,
+	633, 0, 0, 634, 0, 635, 636, 0, 0, 638,
+	639, 640, 0, 0, 641, 642, 887, 940, 643, 941,
+	1579, 644, 645, 1488, 646, 647, 648, 649, 650, 651,
+	652, 653, 654, 655, 656, 657, 0, 658, 659, 889,
+	660, 661, 662, 663, 664, 890, 665, 666, 667, 1580,
+	668, 892, 669, 670, 671, 3195, 672, 673, 674, 0,
+	675, 676, 677, 678, 679, 680, 681, 682, 683, 684,
+	1558, 685, 686, 688, 687, 689, 690, 0, 691, 692,
+	0, 693, 694, 695, 0, 0, 0, 0, 0, 696,
+	697, 699, 0, 700, 701, 702, 703, 704, 705, 698,
+	706, 707, 708, 709, 710, 711, 712, 713, 0, 715,
+	716, 714, 717, 718, 942, 719, 720, 721, 722, 723,
+	1489, 724, 0, 725, 726, 734, 735, 736, 727, 728,
+	730, 737, 729, 738, 739, 740, 741, 743, 742, 0,
+	745, 746, 744, 747, 748, 749, 750, 1540, 751, 895,
+	752, 731, 732, 753, 754, 755, 943, 756, 757, 758,
+	759, 760, 761, 762, 763, 764, 1556, 0, 766, 0,
+	765, 767, 768, 769, 770, 771, 772, 773, 775, 733,
+	776, 777, 778, 783, 784, 785, 1588, 779, 780, 781,
+	782, 787, 1581, 788, 789, 790, 791, 0, 792, 793,
+	1474, 786, 774, 0, 794, 795, 796, 797, 798, 799,
+	800, 801, 802, 803, 0, 804, 1569, 1570, 1571, 1572,
+	0, 817, 0, 805, 807, 808, 809, 810, 1582, 811,
+	812, 1583, 1499, 813, 814, 815, 816, 806, 819, 820,
+	818, 0, 1481, 821, 822, 823, 824, 826, 828, 829,
+	830, 825, 827, 831, 1541, 832, 0, 0, 833, 834,
+	835, 905, 1566, 1587, 0, 1576, 838, 839, 836, 837,
+	840, 841, 844, 842, 843, 909, 847, 542, 848, 849,
+	850, 845, 846, 0, 0, 0, 0, 851, 852, 910,
+	853, 854, 855, 1478, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 1473,
+	0, 0, 0, 0, 0, 0, 1471, 1472, 0, 0,
+	0, 0, 0, 0, 916, 0, 1505, 0, 0, 0,
+	1503, 1551, 1493, 1494, 1495, 1491, 1492, 1504, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 367, 368,
+	370, 369, 371, 372, 373, 374, 0, 375, 376, 0,
+	0, 0, 0, 0, 1543, 1509, 0, 0, 378, 0,
+	377, 0, 379, 380, 381, 926, 382, 383, 384, 385,
+	386, 387, 388, 389, 390, 857, 391, 1557, 0, 392,
+	1565, 393, 1564, 0, 1575, 394, 395, 396, 397, 398,
+	399, 400, 401, 402, 403, 404, 1511, 1542, 1475, 405,
+	1589, 1590, 864, 0, 406, 407, 408, 409, 1549, 0,
+	1530, 0, 410, 411, 412, 413, 414, 415, 416, 417,
+	0, 0, 419, 420, 421, 418, 422, 423, 0, 424,
+	0, 425, 426, 427, 428, 429, 0, 430, 431, 0,
+	432, 433, 434, 928, 435, 436, 437, 1533, 1531, 1532,
+	1539, 1535, 1534, 1538, 438, 439, 440, 441, 442, 1568,
+	443, 445, 1562, 1561, 1480, 448, 450, 444, 446, 0,
+	449, 447, 451, 452, 0, 453, 454, 455, 456, 457,
+	0, 0, 0, 458, 1560, 460, 461, 0, 462, 463,
+	464, 466, 465, 0, 467, 468, 469, 0, 470, 471,
+	1487, 472, 473, 474, 476, 478, 475, 477, 479, 480,
+	481, 482, 483, 1577, 1578, 484, 485, 1500, 362, 0,
+	0, 0, 0, 0, 486, 487, 488, 1559, 0, 0,
+	0, 489, 0, 491, 495, 496, 492, 493, 494, 497,
+	0, 490, 498, 499, 0, 929, 500, 501, 502, 1573,
+	1574, 503, 504, 505, 506, 507, 508, 509, 510, 511,
+	0, 512, 513, 1584, 0, 1510, 514, 0, 515, 516,
+	517, 518, 519, 520, 521, 1544, 1545, 1548, 630, 931,
+	522, 523, 524, 525, 0, 526, 527, 528, 529, 530,
+	531, 532, 0, 0, 0, 533, 534, 535, 536, 0,
+	919, 363, 365, 930, 879, 537, 631, 538, 539, 1554,
+	1555, 0, 1514, 0, 540, 541, 544, 932, 1546, 933,
+	543, 545, 546, 934, 547, 0, 0, 0, 548, 549,
+	550, 551, 552, 553, 554, 0, 555, 557, 556, 0,
+	559, 1585, 558, 935, 560, 561, 936, 0, 562, 563,
+	564, 565, 566, 567, 572, 1537, 1536, 568, 569, 570,
+	571, 573, 574, 0, 575, 576, 578, 581, 577, 579,
+	580, 582, 583, 596, 597, 598, 584, 585, 586, 587,
+	588, 589, 590, 591, 592, 593, 594, 595, 600, 0,
+	599, 937, 0, 601, 602, 603, 604, 605, 606, 612,
+	615, 617, 618, 613, 614, 616, 619, 620, 621, 623,
+	624, 609, 610, 611, 938, 622, 607, 1477, 608, 366,
+	939, 625, 626, 627, 628, 1501, 1547, 629, 1563, 632,
+	633, 0, 0, 634, 0, 635, 636, 0, 0, 638,
+	639, 640, 0, 0, 641, 642, 887, 940, 643, 941,
+	1579, 644, 645, 1488, 646, 647, 648, 649, 650, 651,
+	652, 653, 654, 655, 656, 657, 0, 658, 659, 889,
+	660, 661, 662, 663, 664, 890, 665, 666, 667, 1580,
+	668, 892, 669, 670, 671, 0, 672, 673, 674, 0,
+	675, 676, 677, 678, 679, 680, 681, 682, 683, 684,
+	1558, 685, 686, 688, 687, 689, 690, 0, 691, 692,
+	0, 693, 694, 695, 0, 0, 0, 0, 0, 696,
+	697, 699, 0, 700, 701, 702, 703, 704, 705, 698,
+	706, 707, 708, 709, 710, 711, 712, 713, 0, 715,
+	716, 714, 717, 718, 942, 719, 720, 721, 722, 723,
+	1489, 724, 0, 725, 726, 734, 735, 736, 727, 728,
+	730, 737, 729, 738, 739, 740, 741, 743, 742, 0,
+	745, 746, 744, 747, 748, 749, 750, 1540, 751, 895,
+	752, 731, 732, 753, 754, 755, 943, 756, 757, 758,
+	759, 760, 761, 762, 763, 764, 1556, 0, 766, 0,
+	765, 767, 768, 769, 770, 771, 772, 773, 775, 733,
+	776, 777, 778, 783, 784, 785, 1588, 779, 780, 781,
+	782, 787, 1581, 788, 789, 790, 791, 0, 792, 793,
+	1474, 786, 774, 0, 794, 795, 796, 797, 798, 799,
+	800, 801, 802, 803, 0, 804, 1569, 1570, 1571, 1572,
+	0, 817, 0, 805, 807, 808, 809, 810, 1582, 811,
+	812, 1583, 1499, 813, 814, 815, 816, 806, 819, 820,
+	818, 0, 1481, 821, 822, 823, 824, 826, 828, 829,
+	830, 825, 827, 831, 1541, 832, 0, 0, 833, 834,
+	835, 905, 1566, 1587, 0, 1576, 838, 839, 836, 837,
+	840, 841, 844, 842, 843, 909, 847, 542, 848, 849,
+	850, 845, 846, 0, 0, 0, 0, 851, 852, 910,
+	853, 854, 855, 1478, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 1473,
+	0, 0, 0, 0, 0, 0, 1471, 1472, 2471, 0,
+	0, 0, 0, 0, 916, 0, 1505, 0, 0, 0,
+	1503, 1551, 1493, 1494, 1495, 1491, 1492, 1504, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 367, 368,
+	370, 369, 371, 372, 373, 374, 0, 375, 376, 0,
+	0, 0, 0, 0, 1543, 1509, 0, 0, 378, 0,
+	377, 0, 379, 380, 381, 926, 382, 383, 384, 385,
+	386, 387, 388, 389, 390, 857, 391, 1557, 0, 392,
+	1565, 393, 1564, 0, 1575, 394, 395, 396, 397, 398,
+	399, 400, 401, 402, 403, 404, 1511, 1542, 1475, 405,
+	1589, 1590, 864, 0, 406, 407, 408, 409, 1549, 0,
+	1530, 0, 410, 411, 412, 413, 414, 415, 416, 417,
+	0, 0, 419, 420, 421, 418, 422, 423, 0, 424,
+	0, 425, 426, 427, 428, 6556, 0, 430, 431, 0,
+	432, 433, 434, 928, 435, 436, 437, 1533, 1531, 1532,
+	1539, 1535, 1534, 1538, 438, 439, 440, 441, 442, 1568,
+	443, 445, 1562, 1561, 1480, 448, 450, 444, 446, 0,
+	449, 447, 451, 452, 0, 453, 454, 455, 456, 457,
+	0, 0, 0, 458, 1560, 460, 461, 0, 462, 463,
+	464, 466, 465, 0, 467, 468, 469, 0, 470, 471,
+	1487, 472, 473, 474, 476, 478, 475, 477, 479, 480,
+	481, 482, 483, 1577, 1578, 484, 485, 1500, 362, 0,
+	0, 0, 0, 0, 486, 487, 488, 1559, 0, 0,
+	0, 489, 0, 491, 495, 496, 492, 493, 494, 497,
+	0, 490, 498, 499, 0, 929, 500, 501, 502, 1573,
+	1574, 503, 504, 505, 506, 507, 508, 509, 510, 511,
+	0, 512, 513, 1584, 0, 1510, 514, 0, 515, 516,
+	517, 518, 519, 520, 521, 1544, 1545, 1548, 630, 931,
+	522, 523, 524, 525, 0, 526, 527, 528, 529, 530,
+	531, 532, 0, 0, 0, 533, 534, 535, 536, 0,
+	919, 363, 365, 930, 879, 537, 631, 538, 539, 1554,
+	1555, 0, 1514, 0, 540, 541, 544, 932, 1546, 933,
+	543, 545, 546, 934, 547, 0, 0, 0, 548, 549,
+	550, 551, 552, 553, 554, 0, 555, 557, 556, 0,
+	559, 1585, 558, 935, 560, 561, 936, 0, 562, 563,
+	564, 565, 566, 567, 572, 1537, 1536, 568, 569, 570,
+	571, 573, 574, 0, 575, 576, 578, 581, 577, 579,
+	580, 582, 583, 596, 597, 598, 584, 585, 586, 587,
+	588, 589, 590, 591, 592, 593, 594, 595, 600, 0,
+	599, 937, 0, 601, 602, 603, 604, 605, 606, 612,
+	615, 617, 618, 613, 614, 616, 619, 620, 621, 623,
+	624, 609, 610, 611, 1483, 622, 607, 1477, 608, 366,
+	939, 625, 626, 627, 628, 1501, 1547, 629, 1563, 632,
+	633, 0, 0, 634, 0, 635, 636, 1482, 0, 638,
+	639, 640, 0, 0, 641, 642, 887, 940, 643, 941,
+	1579, 644, 645, 1488, 646, 647, 648, 649, 650, 651,
+	652, 653, 654, 655, 656, 657, 0, 658, 659, 889,
+	660, 661, 662, 663, 664, 890, 665, 666, 667, 1580,
+	668, 892, 669, 670, 671, 0, 672, 673, 674, 0,
+	675, 676, 677, 678, 679, 680, 681, 682, 683, 684,
+	1558, 685, 686, 688, 687, 689, 690, 0, 691, 692,
+	0, 693, 694, 695, 0, 0, 0, 0, 0, 696,
+	697, 699, 0, 700, 701, 702, 703, 704, 705, 698,
+	706, 707, 708, 709, 710, 711, 712, 713, 0, 715,
+	716, 714, 717, 718, 942, 719, 720, 721, 722, 723,
+	1489, 724, 0, 725, 726, 734, 735, 736, 727, 728,
+	730, 737, 729, 738, 739, 740, 741, 743, 742, 0,
+	745, 746, 744, 747, 748, 749, 750, 1540, 751, 895,
+	752, 731, 732, 753, 754, 755, 943, 756, 757, 758,
+	759, 760, 761, 762, 763, 764, 1556, 0, 766, 0,
+	765, 767, 768, 769, 770, 771, 772, 773, 775, 733,
+	776, 777, 778, 783, 784, 785, 1588, 779, 780, 781,
+	782, 787, 1581, 788, 789, 790, 791, 0, 792, 793,
+	1474, 786, 774, 0, 794, 795, 796, 797, 798, 799,
+	800, 801, 802, 803, 0, 804, 1569, 1570, 1571, 1572,
+	0, 817, 0, 805, 807, 808, 809, 810, 1582, 811,
+	812, 1583, 1499, 813, 814, 815, 816, 806, 819, 820,
+	818, 0, 1481, 821, 822, 823, 824, 826, 828, 829,
+	830, 825, 827, 831, 1541, 832, 0, 0, 833, 834,
+	835, 905, 1566, 1587, 0, 1576, 838, 839, 836, 837,
+	840, 841, 844, 842, 843, 909, 847, 542, 848, 849,
+	850, 845, 846, 0, 0, 0, 0, 851, 852, 910,
+	853, 854, 855, 1478, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 1473,
+	0, 0, 0, 0, 0, 0, 1471, 1472, 0, 0,
+	0, 0, 0, 0, 916, 0, 1505, 0, 0, 0,
+	1503, 1551, 1493, 1494, 1495, 1491, 1492, 1504, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 367, 368,
+	370, 369, 371, 372, 373, 374, 0, 375, 376, 0,
+	0, 0, 0, 0, 1543, 1509, 0, 0, 378, 0,
+	377, 0, 379, 380, 381, 926, 382, 383, 384, 385,
+	386, 387, 388, 389, 390, 857, 391, 1557, 0, 392,
+	1565, 393, 1564, 0, 1575, 394, 395, 396, 397, 398,
+	399, 400, 401, 402, 403, 404, 1511, 1542, 1475, 405,
+	1589, 1590, 864, 0, 406, 407, 408, 409, 1549, 0,
+	1530, 0, 410, 411, 412, 413, 414, 415, 416, 417,
+	0, 0, 419, 420, 421, 418, 422, 423, 0, 424,
+	0, 425, 426, 427, 428, 429, 0, 430, 431, 0,
+	432, 433, 434, 928, 435, 436, 437, 1533, 1531, 1532,
+	1539, 1535, 1534, 1538, 438, 439, 440, 441, 442, 1568,
+	443, 445, 1562, 1561, 1480, 448, 450, 444, 446, 0,
+	449, 447, 451, 452, 0, 453, 454, 455, 456, 457,
+	0, 0, 0, 458, 1560, 460, 461, 0, 462, 463,
+	464, 466, 465, 0, 467, 468, 469, 0, 470, 471,
+	1487, 472, 473, 474, 476, 478, 475, 477, 479, 480,
+	481, 482, 483, 1577, 1578, 484, 485, 1500, 362, 0,
+	0, 0, 0, 0, 486, 487, 488, 1559, 0, 0,
+	0, 489, 0, 491, 495, 496, 492, 493, 494, 497,
+	0, 490, 498, 499, 0, 929, 500, 501, 502, 1573,
+	1574, 503, 504, 505, 506, 507, 508, 509, 510, 511,
+	0, 512, 513, 1584, 0, 1510, 514, 0, 515, 516,
+	517, 518, 519, 520, 521, 1544, 1545, 1548, 630, 931,
+	522, 523, 524, 525, 0, 526, 527, 528, 529, 530,
+	531, 532, 0, 0, 0, 533, 534, 535, 536, 0,
+	919, 363, 365, 930, 879, 537, 631, 538, 539, 1554,
+	1555, 0, 1514, 0, 540, 541, 544, 932, 1546, 933,
+	543, 545, 546, 934, 547, 0, 0, 0, 548, 549,
+	550, 551, 552, 553, 554, 0, 555, 557, 556, 0,
+	559, 1585, 558, 935, 560, 561, 936, 0, 562, 563,
+	564, 565, 566, 567, 572, 1537, 1536, 568, 569, 570,
+	571, 573, 574, 0, 575, 576, 578, 581, 577, 579,
+	580, 582, 583, 596, 597, 598, 584, 585, 586, 587,
+	588, 589, 590, 591, 592, 593, 594, 595, 600, 0,
+	599, 937, 0, 601, 602, 603, 604, 605, 606, 612,
+	615, 617, 618, 613, 614, 616, 619, 620, 621, 623,
+	624, 609, 610, 611, 1483, 622, 607, 1477, 608, 366,
+	939, 625, 626, 627, 628, 1501, 1547, 629, 1563, 632,
+	633, 0, 0, 634, 0, 635, 636, 1482, 0, 638,
+	639, 640, 0, 0, 641, 642, 887, 940, 643, 941,
+	1579, 644, 645, 1488, 646, 647, 648, 649, 650, 651,
+	652, 653, 654, 655, 656, 657, 0, 658, 659, 889,
+	660, 661, 662, 663, 664, 890, 665, 666, 667, 1580,
+	668, 892, 669, 670, 671, 0, 672, 673, 674, 0,
+	675, 676, 677, 678, 679, 680, 681, 682, 683, 684,
+	1558, 685, 686, 688, 687, 689, 690, 0, 691, 692,
+	0, 693, 694, 695, 0, 0, 0, 0, 0, 696,
+	697, 699, 0, 700, 701, 702, 703, 704, 705, 698,
+	706, 707, 708, 709, 710, 711, 712, 713, 0, 715,
+	716, 714, 717, 718, 942, 719, 720, 721, 722, 723,
+	1489, 724, 0, 725, 726, 734, 735, 736, 727, 728,
+	730, 737, 729, 738, 739, 740, 741, 743, 742, 0,
+	745, 746, 744, 747, 748, 749, 750, 1540, 751, 895,
+	752, 731, 732, 753, 754, 755, 943, 756, 757, 758,
+	759, 760, 761, 762, 763, 764, 1556, 0, 766, 0,
+	765, 767, 768, 769, 770, 771, 772, 773, 775, 733,
+	776, 777, 778, 783, 784, 785, 1588, 779, 780, 781,
+	782, 787, 1581, 788, 789, 790, 791, 0, 792, 793,
+	1474, 786, 774, 0, 794, 795, 796, 797, 798, 799,
+	800, 801, 802, 803, 0, 804, 1569, 1570, 1571, 1572,
+	0, 817, 0, 805, 807, 808, 809, 810, 1582, 811,
+	812, 1583, 1499, 813, 814, 815, 816, 806, 819, 820,
+	818, 0, 1481, 821, 822, 823, 824, 826, 828, 829,
+	830, 825, 827, 831, 1541, 832, 0, 0, 833, 834,
+	835, 905, 1566, 1587, 0, 1576, 838, 839, 836, 837,
+	840, 841, 844, 842, 843, 909, 847, 542, 848, 849,
+	850, 845, 846, 0, 0, 0, 0, 851, 852, 910,
+	853, 854, 855, 1478, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 1473,
+	0, 0, 0, 0, 0, 0, 1471, 1472, 0, 0,
+	0, 0, 0, 0, 916, 0, 1505, 0, 0, 0,
+	1503, 1551, 1493, 1494, 1495, 1491, 1492, 1504, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 367, 368,
+	370, 369, 371, 372, 373, 374, 0, 375, 376, 0,
+	0, 0, 0, 0, 1543, 1509, 0, 0, 378, 0,
+	377, 0, 379, 380, 381, 926, 382, 383, 384, 385,
+	386, 387, 388, 389, 390, 857, 391, 1557, 0, 392,
+	1565, 393, 1564, 0, 1575, 394, 395, 396, 397, 398,
+	399, 400, 401, 402, 403, 404, 1511, 1542, 1475, 405,
+	1589, 1590, 864, 0, 406, 407, 408, 409, 1549, 0,
+	1530, 0, 410, 411, 412, 413, 414, 415, 416, 417,
+	0, 0, 419, 420, 421, 418, 422, 423, 0, 424,
+	0, 425, 426, 427, 428, 429, 0, 430, 431, 0,
+	432, 433, 434, 928, 435, 436, 437, 1533, 1531, 1532,
+	1539, 1535, 1534, 1538, 438, 439, 440, 441, 442, 1568,
+	443, 445, 1562, 1561, 1480, 448, 450, 444, 446, 0,
+	449, 447, 451, 452, 0, 453, 454, 455, 456, 457,
+	0, 0, 0, 458, 1560, 460, 461, 0, 462, 463,
+	464, 466, 465, 0, 467, 468, 469, 0, 470, 471,
+	1487, 472, 473, 474, 476, 478, 475, 477, 479, 480,
+	481, 482, 483, 1577, 1578, 484, 485, 1500, 362, 0,
+	0, 0, 0, 0, 486, 487, 488, 1559, 0, 0,
+	0, 489, 0, 491, 495, 496, 492, 493, 494, 497,
+	0, 490, 498, 499, 0, 929, 500, 501, 502, 1573,
+	1574, 503, 504, 505, 506, 507, 508, 509, 510, 511,
+	0, 512, 513, 1584, 0, 1510, 514, 0, 515, 516,
+	517, 518, 519, 520, 521, 1544, 1545, 1548, 630, 931,
+	522, 523, 524, 525, 0, 526, 527, 528, 529, 530,
+	531, 532, 0, 0, 0, 533, 534, 535, 536, 0,
+	919, 363, 365, 930, 879, 537, 631, 538, 539, 1554,
+	1555, 0, 1514, 0, 540, 541, 544, 932, 1546, 933,
+	543, 545, 546, 934, 547, 0, 0, 0, 548, 549,
+	550, 551, 552, 553, 554, 0, 555, 557, 556, 0,
+	559, 1585, 558, 935, 560, 561, 936, 0, 562, 563,
+	564, 565, 566, 567, 572, 1537, 1536, 568, 569, 570,
+	571, 573, 574, 0, 575, 576, 578, 581, 577, 579,
+	580, 582, 583, 596, 597, 598, 584, 585, 586, 587,
+	588, 589, 590, 591, 592, 593, 594, 595, 600, 0,
+	599, 937, 0, 601, 602, 603, 604, 605, 606, 612,
+	615, 617, 618, 613, 614, 616, 619, 620, 621, 623,
+	624, 609, 610, 611, 938, 622, 607, 1477, 608, 5944,
+	939, 625, 626, 627, 628, 1501, 1547, 629, 1563, 632,
+	633, 0, 0, 634, 0, 635, 636, 0, 0, 638,
+	639, 640, 0, 0, 641, 642, 887, 940, 643, 941,
+	1579, 644, 645, 1488, 646, 647, 648, 649, 650, 651,
+	652, 653, 654, 655, 656, 657, 0, 658, 659, 889,
+	660, 661, 662, 663, 664, 890, 665, 666, 667, 1580,
+	668, 892, 669, 670, 671, 0, 672, 673, 674, 0,
+	675, 676, 677, 678, 679, 680, 681, 682, 683, 684,
+	1558, 685, 686, 688, 687, 689, 690, 0, 691, 692,
+	0, 693, 694, 695, 0, 0, 0, 0, 0, 696,
+	697, 699, 0, 700, 701, 702, 703, 704, 705, 698,
+	706, 707, 708, 709, 710, 711, 712, 713, 0, 715,
+	716, 714, 717, 718, 942, 719, 720, 721, 722, 723,
+	1489, 724, 0, 725, 726, 734, 735, 736, 727, 728,
+	730, 737, 729, 738, 739, 740, 741, 743, 742, 0,
+	745, 746, 744, 747, 748, 749, 750, 1540, 751, 895,
+	752, 731, 732, 753, 754, 755, 943, 756, 757, 758,
+	759, 760, 761, 762, 763, 764, 1556, 0, 766, 0,
+	765, 767, 768, 769, 770, 771, 772, 773, 775, 733,
+	776, 777, 778, 783, 784, 785, 1588, 779, 780, 781,
+	782, 787, 1581, 788, 789, 790, 791, 0, 792, 793,
+	1474, 786, 774, 0, 794, 795, 796, 797, 798, 799,
+	800, 801, 802, 803, 0, 804, 1569, 1570, 1571, 1572,
+	0, 817, 0, 805, 807, 808, 809, 810, 1582, 811,
+	812, 1583, 1499, 813, 814, 815, 816, 806, 819, 820,
+	818, 0, 1481, 821, 822, 823, 824, 826, 828, 829,
+	830, 825, 827, 831, 1541, 832, 0, 0, 833, 834,
+	835, 905, 1566, 1587, 0, 1576, 838, 839, 836, 837,
+	840, 841, 844, 842, 843, 909, 847, 542, 848, 849,
+	850, 845, 846, 0, 0, 0, 0, 851, 852, 910,
+	853, 854, 855, 1478, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 1473,
+	0, 0, 0, 0, 0, 0, 1471, 1472, 2471, 0,
+	0, 0, 0, 0, 916, 0, 1505, 0, 0, 0,
+	1503, 1551, 1493, 1494, 1495, 1491, 1492, 1504, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 367, 368,
+	370, 369, 371, 372, 373, 374, 0, 375, 376, 0,
+	0, 0, 0, 0, 1543, 1509, 0, 0, 378, 0,
+	377, 0, 379, 380, 381, 926, 382, 383, 384, 385,
+	386, 387, 388, 389, 390, 857, 391, 1557, 0, 392,
+	1565, 393, 1564, 0, 1575, 394, 395, 396, 397, 398,
+	399, 400, 401, 402, 403, 404, 1511, 1542, 1475, 405,
+	1589, 1590, 864, 0, 406, 407, 408, 409, 1549, 0,
+	1530, 0, 410, 411, 412, 413, 414, 415, 416, 417,
+	0, 0, 419, 420, 421, 418, 422, 423, 0, 424,
+	0, 425, 426, 427, 428, 429, 0, 430, 431, 0,
+	432, 433, 434, 928, 435, 436, 437, 1533, 1531, 1532,
+	1539, 1535, 1534, 1538, 438, 439, 440, 441, 442, 1568,
+	443, 445, 1562, 1561, 1480, 448, 450, 444, 446, 0,
+	449, 447, 451, 452, 0, 453, 454, 455, 456, 457,
+	0, 0, 0, 458, 1560, 460, 461, 0, 462, 463,
+	464, 466, 465, 0, 467, 468, 469, 0, 470, 471,
+	1487, 472, 473, 474, 476, 478, 475, 477, 479, 480,
+	481, 482, 483, 1577, 1578, 484, 485, 1500, 362, 0,
+	0, 0, 0, 0, 486, 487, 488, 1559, 0, 0,
+	0, 489, 0, 491, 495, 496, 492, 493, 494, 497,
+	0, 490, 498, 499, 0, 929, 500, 501, 502, 1573,
+	1574, 503, 504, 505, 506, 507, 508, 509, 510, 511,
+	0, 512, 513, 1584, 0, 1510, 514, 0, 515, 516,
+	517, 518, 519, 520, 521, 1544, 1545, 1548, 630, 931,
+	522, 523, 524, 525, 0, 526, 527, 528, 529, 530,
+	531, 532, 0, 0, 0, 533, 534, 535, 536, 0,
+	919, 363, 365, 930, 879, 537, 631, 538, 539, 1554,
+	1555, 0, 1514, 0, 540, 541, 544, 932, 1546, 933,
+	543, 545, 546, 934, 547, 0, 0, 0, 548, 549,
+	550, 551, 552, 553, 554, 0, 555, 557, 556, 0,
+	559, 1585, 558, 935, 560, 561, 936, 0, 562, 563,
+	564, 565, 566, 567, 572, 1537, 1536, 568, 569, 570,
+	571, 573, 574, 0, 575, 576, 578, 581, 577, 579,
+	580, 582, 583, 596, 597, 598, 584, 585, 586, 587,
+	588, 589, 590, 591, 592, 593, 594, 595, 600, 0,
+	599, 937, 0, 601, 602, 603, 604, 605, 606, 612,
+	615, 617, 618, 613, 614, 616, 619, 620, 621, 623,
+	624, 609, 610, 611, 938, 622, 607, 1477, 608, 366,
+	939, 625, 626, 627, 628, 1501, 1547, 629, 1563, 632,
+	633, 0, 0, 634, 0, 635, 636, 0, 0, 638,
+	639, 640, 0, 0, 641, 642, 887, 940, 643, 941,
+	1579, 644, 645, 1488, 646, 647, 648, 649, 650, 651,
+	652, 653, 654, 655, 656, 657, 0, 658, 659, 889,
+	660, 661, 662, 663, 664, 890, 665, 666, 667, 1580,
+	668, 892, 669, 670, 671, 0, 672, 673, 674, 0,
+	675, 676, 677, 678, 679, 680, 681, 682, 683, 684,
+	1558, 685, 686, 688, 687, 689, 690, 0, 691, 692,
+	0, 693, 694, 695, 0, 0, 0, 0, 0, 696,
+	697, 699, 0, 700, 701, 702, 703, 704, 705, 698,
+	706, 707, 708, 709, 710, 711, 712, 713, 0, 715,
+	716, 714, 717, 718, 942, 719, 720, 721, 722, 723,
+	1489, 724, 0, 725, 726, 734, 735, 736, 727, 728,
+	730, 737, 729, 738, 739, 740, 741, 743, 742, 0,
+	745, 746, 744, 747, 748, 749, 750, 1540, 751, 895,
+	752, 731, 732, 753, 754, 755, 943, 756, 757, 758,
+	759, 760, 761, 762, 763, 764, 1556, 0, 766, 0,
+	765, 767, 768, 769, 770, 771, 772, 773, 775, 733,
+	776, 777, 778, 783, 784, 785, 1588, 779, 780, 781,
+	782, 787, 1581, 788, 789, 790, 791, 0, 792, 793,
+	1474, 786, 774, 0, 794, 795, 796, 797, 798, 799,
+	800, 801, 802, 803, 0, 804, 1569, 1570, 1571, 1572,
+	0, 817, 0, 805, 807, 808, 809, 810, 1582, 811,
+	812, 1583, 1499, 813, 814, 815, 816, 806, 819, 820,
+	818, 0, 1481, 821, 822, 823, 824, 826, 828, 829,
+	830, 825, 827, 831, 1541, 832, 0, 0, 833, 834,
+	835, 905, 1566, 1587, 4953, 1576, 838, 839, 836, 837,
+	840, 841, 844, 842, 843, 909, 847, 542, 848, 849,
+	850, 845, 846, 0, 0, 0, 0, 851, 852, 910,
+	853, 854, 855, 1478, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 1473,
+	0, 0, 0, 0, 0, 0, 1471, 1472, 0, 0,
+	0, 0, 0, 0, 916, 0, 1505, 0, 0, 0,
+	1503, 1551, 1493, 1494, 1495, 1491, 1492, 1504, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 367, 368,
+	370, 369, 371, 372, 373, 374, 0, 375, 376, 0,
+	0, 0, 0, 0, 1543, 1509, 0, 0, 378, 0,
+	377, 0, 379, 380, 381, 926, 382, 383, 384, 385,
+	386, 387, 388, 389, 390, 857, 391, 1557, 0, 392,
+	1565, 393, 1564, 0, 1575, 394, 395, 396, 397, 398,
+	399, 400, 401, 402, 403, 404, 1511, 1542, 1475, 405,
+	1589, 1590, 864, 0, 406, 407, 408, 409, 1549, 0,
+	1530, 0, 410, 411, 412, 413, 414, 415, 416, 417,
+	0, 0, 419, 420, 421, 418, 422, 423, 0, 424,
+	0, 425, 426, 427, 428, 429, 0, 430, 431, 0,
+	432, 433, 434, 928, 435, 436, 437, 1533, 1531, 1532,
+	1539, 1535, 1534, 1538, 438, 439, 440, 441, 442, 1568,
+	443, 445, 1562, 1561, 1480, 448, 450, 444, 446, 0,
+	449, 447, 451, 452, 0, 453, 454, 455, 456, 457,
+	0, 0, 0, 458, 1560, 460, 461, 0, 462, 463,
+	464, 466, 465, 0, 467, 468, 469, 0, 470, 471,
+	1487, 472, 473, 474, 476, 478, 475, 477, 479, 480,
+	481, 482, 483, 1577, 1578, 484, 485, 1500, 362, 0,
+	0, 0, 0, 0, 486, 487, 488, 1559, 0, 0,
+	0, 489, 0, 491, 495, 496, 492, 493, 494, 497,
+	0, 490, 498, 499, 3462, 929, 500, 501, 502, 1573,
+	1574, 503, 504, 505, 506, 507, 508, 509, 510, 511,
+	0, 512, 513, 1584, 0, 1510, 514, 0, 515, 516,
+	517, 518, 519, 520, 521, 1544, 1545, 1548, 630, 931,
+	522, 523, 524, 525, 0, 526, 527, 528, 529, 530,
+	531, 532, 0, 0, 0, 533, 534, 535, 536, 0,
+	919, 363, 365, 930, 879, 537, 631, 538, 539, 1554,
+	1555, 0, 1514, 0, 540, 541, 544, 932, 1546, 933,
+	543, 545, 546, 934, 547, 0, 0, 0, 548, 549,
+	550, 551, 552, 553, 554, 0, 555, 557, 556, 0,
+	559, 1585, 558, 935, 560, 561, 936, 0, 562, 563,
+	564, 565, 566, 567, 572, 1537, 1536, 568, 569, 570,
+	571, 573, 574, 0, 575, 576, 578, 581, 577, 579,
+	580, 582, 583, 596, 597, 598, 584, 585, 586, 587,
+	588, 589, 590, 591, 592, 593, 594, 595, 600, 0,
+	599, 937, 0, 601, 602, 603, 604, 605, 606, 612,
+	615, 617, 618, 613, 614, 616, 619, 620, 621, 623,
+	624, 609, 610, 611, 938, 622, 607, 1477, 608, 366,
+	939, 625, 626, 627, 628, 1501, 1547, 629, 1563, 632,
+	633, 0, 0, 634, 0, 635, 636, 0, 0, 638,
+	639, 640, 0, 0, 641, 642, 887, 940, 643, 941,
+	1579, 644, 645, 1488, 646, 647, 648, 649, 650, 651,
+	652, 653, 654, 655, 656, 657, 0, 658, 659, 889,
+	660, 661, 662, 663, 664, 890, 665, 666, 667, 1580,
+	668, 892, 669, 670, 671, 0, 672, 673, 674, 0,
+	675, 676, 677, 678, 679, 680, 681, 682, 683, 684,
+	1558, 685, 686, 688, 687, 689, 690, 0, 691, 692,
+	0, 693, 694, 695, 0, 0, 0, 0, 0, 696,
+	697, 699, 0, 700, 701, 702, 703, 704, 705, 698,
+	706, 707, 708, 709, 710, 711, 712, 713, 0, 715,
+	716, 714, 717, 718, 942, 719, 720, 721, 722, 723,
+	1489, 724, 0, 725, 726, 734, 735, 736, 727, 728,
+	730, 737, 729, 738, 739, 740, 741, 743, 742, 0,
+	745, 746, 744, 747, 748, 749, 750, 1540, 751, 895,
+	752, 731, 732, 753, 754, 755, 943, 756, 757, 758,
+	759, 760, 761, 762, 763, 764, 1556, 0, 766, 0,
+	765, 767, 768, 769, 770, 771, 772, 773, 775, 733,
+	776, 777, 778, 783, 784, 785, 1588, 779, 780, 781,
+	782, 787, 1581, 788, 789, 790, 791, 0, 792, 793,
+	1474, 786, 774, 0, 794, 795, 796, 797, 798, 799,
+	800, 801, 802, 803, 0, 804, 1569, 1570, 1571, 1572,
+	0, 817, 0, 805, 807, 808, 809, 810, 1582, 811,
+	812, 1583, 1499, 813, 814, 815, 816, 806, 819, 820,
+	818, 0, 1481, 821, 822, 823, 824, 826, 828, 829,
+	830, 825, 827, 831, 1541, 832, 0, 0, 833, 834,
+	835, 905, 1566, 1587, 0, 1576, 838, 839, 836, 837,
+	840, 841, 844, 842, 843, 909, 847, 542, 848, 849,
+	850, 845, 846, 0, 0, 0, 0, 851, 852, 910,
+	853, 854, 855, 1478, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 1473,
+	0, 0, 0, 0, 0, 0, 1471, 1472, 0, 0,
+	0, 0, 0, 0, 916, 0, 1505, 0, 0, 0,
+	1503, 1551, 1493, 1494, 1495, 1491, 1492, 1504, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 367, 368,
+	370, 369, 371, 372, 373, 374, 0, 375, 376, 0,
+	0, 0, 0, 0, 1543, 1509, 0, 0, 378, 0,
+	377, 0, 379, 380, 381, 926, 382, 383, 384, 385,
+	386, 387, 388, 389, 390, 857, 391, 1557, 0, 392,
+	1565, 393, 1564, 0, 1575, 394, 395, 396, 397, 398,
+	399, 400, 401, 402, 403, 404, 1511, 1542, 1475, 405,
+	1589, 1590, 864, 0, 406, 407, 408, 409, 1549, 0,
+	1530, 0, 410, 411, 412, 413, 414, 415, 416, 417,
+	0, 0, 419, 420, 421, 418, 422, 423, 0, 424,
+	0, 425, 426, 427, 428, 429, 0, 430, 431, 0,
+	432, 433, 434, 928, 435, 436, 437, 1533, 1531, 1532,
+	1539, 1535, 1534, 1538, 438, 439, 440, 441, 442, 1568,
+	443, 445, 1562, 1561, 1480, 448, 450, 444, 446, 0,
+	449, 447, 451, 452, 0, 453, 454, 455, 456, 457,
+	0, 0, 0, 458, 1560, 460, 461, 0, 462, 463,
+	464, 466, 465, 0, 467, 468, 469, 0, 470, 471,
+	1487, 472, 473, 474, 476, 478, 475, 477, 479, 480,
+	481, 482, 483, 1577, 1578, 484, 485, 1500, 362, 0,
+	0, 0, 0, 0, 486, 487, 488, 1559, 0, 0,
+	0, 489, 0, 491, 495, 496, 492, 493, 494, 497,
+	0, 490, 498, 499, 0, 929, 500, 501, 502, 1573,
+	1574, 503, 504, 505, 506, 507, 508, 509, 510, 511,
+	0, 512, 513, 1584, 0, 1510, 514, 0, 515, 516,
+	517, 518, 519, 520, 521, 1544, 1545, 1548, 630, 931,
+	522, 523, 524, 525, 0, 526, 527, 528, 529, 530,
+	531, 532, 0, 0, 0, 533, 534, 535, 536, 0,
+	919, 363, 365, 930, 879, 537, 631, 538, 539, 1554,
+	1555, 0, 1514, 0, 540, 541, 544, 932, 1546, 933,
+	543, 545, 546, 934, 547, 0, 0, 0, 548, 549,
+	550, 551, 552, 553, 554, 0, 555, 557, 556, 0,
+	559, 1585, 558, 935, 560, 561, 936, 0, 562, 563,
+	564, 565, 566, 567, 572, 1537, 1536, 568, 569, 570,
+	571, 573, 574, 0, 575, 576, 578, 581, 577, 579,
+	580, 582, 583, 596, 597, 598, 584, 585, 586, 587,
+	588, 589, 590, 591, 592, 593, 594, 595, 600, 0,
+	599, 937, 0, 601, 602, 603, 604, 605, 606, 612,
+	615, 617, 618, 613, 614, 616, 619, 620, 621, 623,
+	624, 609, 610, 611, 938, 622, 607, 1477, 608, 366,
+	939, 625, 626, 627, 628, 1501, 1547, 629, 1563, 632,
+	633, 0, 0, 634, 0, 635, 636, 0, 0, 638,
+	639, 640, 0, 0, 641, 642, 887, 940, 643, 941,
+	1579, 644, 645, 1488, 646, 647, 648, 649, 650, 651,
+	652, 653, 654, 655, 656, 657, 0, 658, 659, 889,
+	660, 661, 662, 663, 664, 890, 665, 666, 667, 1580,
+	668, 892, 669, 670, 671, 0, 672, 673, 674, 0,
+	675, 676, 677, 678, 679, 680, 681, 682, 683, 684,
+	1558, 685, 686, 688, 687, 689, 690, 0, 691, 692,
+	0, 693, 694, 695, 0, 0, 0, 0, 0, 696,
+	697, 699, 0, 700, 701, 702, 703, 704, 705, 698,
+	706, 707, 708, 709, 710, 711, 712, 713, 0, 715,
+	716, 714, 717, 718, 942, 719, 720, 721, 722, 723,
+	1489, 724, 0, 725, 726, 734, 735, 736, 727, 728,
+	730, 737, 729, 738, 739, 740, 741, 743, 742, 0,
+	745, 746, 744, 747, 748, 749, 750, 1540, 751, 895,
+	752, 731, 732, 753, 754, 755, 943, 756, 757, 758,
+	759, 760, 761, 762, 763, 764, 1556, 0, 766, 0,
+	765, 767, 768, 769, 770, 771, 772, 773, 775, 733,
+	776, 777, 778, 783, 784, 785, 1588, 779, 780, 781,
+	782, 787, 1581, 788, 789, 790, 791, 0, 792, 793,
+	1474, 786, 774, 0, 794, 795, 796, 797, 798, 799,
+	800, 801, 802, 803, 0, 804, 1569, 1570, 1571, 1572,
+	0, 817, 0, 805, 807, 808, 809, 810, 1582, 811,
+	812, 1583, 1499, 813, 814, 815, 816, 806, 819, 820,
+	818, 0, 1481, 821, 822, 823, 824, 826, 828, 829,
+	830, 825, 827, 831, 1541, 832, 0, 0, 833, 834,
+	835, 905, 1566, 1587, 0, 1576, 838, 839, 836, 837,
+	840, 841, 844, 842, 843, 909, 847, 542, 848, 849,
+	850, 845, 846, 0, 0, 0, 0, 851, 852, 910,
+	853, 854, 855, 1478, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 1473,
+	0, 0, 0, 0, 0, 0, 1471, 1472, 0, 0,
+	0, 0, 0, 0, 916, 0, 1505, 2393, 0, 3467,
+	1503, 1551, 1493, 1494, 1495, 1491, 1492, 1504, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 367, 368,
+	370, 369, 371, 372, 373, 374, 0, 375, 376, 0,
+	0, 0, 0, 0, 1543, 1509, 0, 0, 378, 0,
+	377, 0, 379, 380, 381, 926, 382, 383, 384, 385,
+	386, 387, 388, 389, 390, 857, 391, 1557, 0, 392,
+	1565, 393, 1564, 0, 1575, 394, 395, 396, 397, 398,
+	399, 400, 401, 402, 403, 404, 1511, 1542, 1475, 405,
+	1589, 1590, 864, 0, 406, 407, 408, 409, 1549, 0,
+	1530, 0, 410, 411, 412, 413, 414, 415, 416, 417,
+	0, 0, 419, 420, 421, 418, 422, 423, 0, 424,
+	0, 425, 426, 427, 428, 429, 0, 430, 431, 0,
+	432, 433, 434, 928, 435, 436, 437, 1533, 1531, 1532,
+	1539, 1535, 1534, 1538, 438, 439, 440, 441, 442, 1568,
+	443, 445, 1562, 1561, 1480, 448, 450, 444, 446, 0,
+	449, 447, 451, 452, 0, 453, 454, 455, 456, 457,
+	0, 0, 0, 458, 1560, 460, 461, 0, 462, 463,
+	464, 466, 465, 0, 467, 468, 469, 0, 470, 471,
+	1487, 472, 473, 474, 476, 478, 475, 477, 479, 480,
+	481, 482, 483, 1577, 1578, 484, 485, 1500, 362, 0,
+	0, 0, 0, 0, 486, 487, 488, 1559, 0, 0,
+	0, 489, 0, 491, 495, 496, 492, 493, 494, 497,
+	0, 490, 498, 499, 0, 929, 500, 501, 502, 1573,
+	1574, 503, 504, 505, 506, 507, 508, 509, 510, 511,
+	0, 512, 513, 1584, 0, 1510, 514, 0, 515, 516,
+	517, 518, 519, 520, 521, 1544, 1545, 1548, 630, 931,
+	522, 523, 524, 525, 0, 526, 527, 528, 529, 530,
+	531, 532, 0, 0, 0, 533, 534, 535, 536, 0,
+	919, 363, 365, 930, 879, 537, 631, 538, 539, 1554,
+	1555, 0, 1514, 0, 540, 541, 544, 932, 1546, 933,
+	543, 545, 546, 934, 547, 0, 0, 0, 548, 549,
+	550, 551, 552, 553, 554, 0, 555, 557, 556, 0,
+	559, 1585, 558, 935, 560, 561, 936, 0, 562, 563,
+	564, 565, 566, 567, 572, 1537, 1536, 568, 569, 570,
+	571, 573, 574, 0, 575, 576, 578, 581, 577, 579,
+	580, 582, 583, 596, 597, 598, 584, 585, 586, 587,
+	588, 589, 590, 591, 592, 593, 594, 595, 600, 0,
+	599, 937, 0, 601, 602, 603, 604, 605, 606, 612,
+	615, 617, 618, 613, 614, 616, 619, 620, 621, 623,
+	624, 609, 610, 611, 938, 622, 607, 1477, 608, 366,
+	939, 625, 626, 627, 628, 1501, 1547, 629, 1563, 632,
+	633, 0, 0, 634, 0, 635, 636, 0, 0, 638,
+	639, 640, 0, 0, 641, 642, 887, 940, 643, 941,
+	1579, 644, 645, 1488, 646, 647, 648, 649, 650, 651,
+	652, 653, 654, 655, 656, 657, 0, 658, 659, 889,
+	660, 661, 662, 663, 664, 890, 665, 666, 667, 1580,
+	668, 892, 669, 670, 671, 0, 672, 673, 674, 0,
+	675, 676, 677, 678, 679, 680, 681, 682, 683, 684,
+	1558, 685, 686, 688, 687, 689, 690, 0, 691, 692,
+	0, 693, 694, 695, 0, 0, 0, 0, 0, 696,
+	697, 699, 0, 700, 701, 702, 703, 704, 705, 698,
+	706, 707, 708, 709, 710, 711, 712, 713, 0, 715,
+	716, 714, 717, 718, 942, 719, 720, 721, 722, 723,
+	1489, 724, 0, 725, 726, 734, 735, 736, 727, 728,
+	730, 737, 729, 738, 739, 740, 741, 743, 742, 0,
+	745, 746, 744, 747, 748, 749, 750, 1540, 751, 895,
+	752, 731, 732, 753, 754, 755, 943, 756, 757, 758,
+	759, 760, 761, 762, 763, 764, 1556, 0, 766, 0,
+	765, 767, 768, 769, 770, 771, 772, 773, 775, 733,
+	776, 777, 778, 783, 784, 785, 1588, 779, 780, 781,
+	782, 787, 1581, 788, 789, 790, 791, 0, 792, 793,
+	1474, 786, 774, 0, 794, 795, 796, 797, 798, 799,
+	800, 801, 802, 803, 0, 804, 1569, 1570, 1571, 1572,
+	0, 817, 0, 805, 807, 808, 809, 810, 1582, 811,
+	812, 1583, 1499, 813, 814, 815, 816, 806, 819, 820,
+	818, 0, 1481, 821, 822, 823, 824, 826, 828, 829,
+	830, 825, 827, 831, 1541, 832, 0, 0, 833, 834,
+	835, 905, 1566, 1587, 0, 1576, 838, 839, 836, 837,
+	840, 841, 844, 842, 843, 909, 847, 542, 848, 849,
+	850, 845, 846, 0, 0, 0, 0, 851, 852, 910,
+	853, 854, 855, 1478, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 1473,
+	0, 0, 0, 0, 0, 0, 1471, 1472, 0, 0,
+	0, 0, 0, 0, 916, 0, 1505, 0, 0, 3465,
+	1503, 1551, 1493, 1494, 1495, 1491, 1492, 1504, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 367, 368,
+	370, 369, 371, 372, 373, 374, 0, 375, 376, 0,
+	0, 0, 0, 0, 1543, 1509, 0, 0, 378, 0,
+	377, 0, 379, 380, 381, 926, 382, 383, 384, 385,
+	386, 387, 388, 389, 390, 857, 391, 1557, 0, 392,
+	1565, 393, 1564, 0, 1575, 394, 395, 396, 397, 398,
+	399, 400, 401, 402, 403, 404, 1511, 1542, 1475, 405,
+	1589, 1590, 864, 0, 406, 407, 408, 409, 1549, 0,
+	1530, 0, 410, 411, 412, 413, 414, 415, 416, 417,
+	0, 0, 419, 420, 421, 418, 422, 423, 0, 424,
+	0, 425, 426, 427, 428, 429, 0, 430, 431, 0,
+	432, 433, 434, 928, 435, 436, 437, 1533, 1531, 1532,
+	1539, 1535, 1534, 1538, 438, 439, 440, 441, 442, 1568,
+	443, 445, 1562, 1561, 1480, 448, 450, 444, 446, 0,
+	449, 447, 451, 452, 0, 453, 454, 455, 456, 457,
+	0, 0, 0, 458, 1560, 460, 461, 0, 462, 463,
+	464, 466, 465, 0, 467, 468, 469, 0, 470, 471,
+	1487, 472, 473, 474, 476, 478, 475, 477, 479, 480,
+	481, 482, 483, 1577, 1578, 484, 485, 1500, 362, 0,
+	0, 0, 0, 0, 486, 487, 488, 1559, 0, 0,
+	0, 489, 0, 491, 495, 496, 492, 493, 494, 497,
+	0, 490, 498, 499, 0, 929, 500, 501, 502, 1573,
+	1574, 503, 504, 505, 506, 507, 508, 509, 510, 511,
+	0, 512, 513, 1584, 0, 1510, 514, 0, 515, 516,
+	517, 518, 519, 520, 521, 1544, 1545, 1548, 630, 931,
+	522, 523, 524, 525, 0, 526, 527, 528, 529, 530,
+	531, 532, 0, 0, 0, 533, 534, 535, 536, 0,
+	919, 363, 365, 930, 879, 537, 631, 538, 539, 1554,
+	1555, 0, 1514, 0, 540, 541, 544, 932, 1546, 933,
+	543, 545, 546, 934, 547, 0, 0, 0, 548, 549,
+	550, 551, 552, 553, 554, 0, 555, 557, 556, 0,
+	559, 1585, 558, 935, 560, 561, 936, 0, 562, 563,
+	564, 565, 566, 567, 572, 1537, 1536, 568, 569, 570,
+	571, 573, 574, 0, 575, 576, 578, 581, 577, 579,
+	580, 582, 583, 596, 597, 598, 584, 585, 586, 587,
+	588, 589, 590, 591, 592, 593, 594, 595, 600, 0,
+	599, 937, 0, 601, 602, 603, 604, 605, 606, 612,
+	615, 617, 618, 613, 614, 616, 619, 620, 621, 623,
+	624, 609, 610, 611, 938, 622, 607, 1477, 608, 366,
+	939, 625, 626, 627, 628, 1501, 1547, 629, 1563, 632,
+	633, 0, 0, 634, 0, 635, 636, 0, 0, 638,
+	639, 640, 0, 0, 641, 642, 887, 940, 643, 941,
+	1579, 644, 645, 1488, 646, 647, 648, 649, 650, 651,
+	652, 653, 654, 655, 656, 657, 0, 658, 659, 889,
+	660, 661, 662, 663, 664, 890, 665, 666, 667, 1580,
+	668, 892, 669, 670, 671, 0, 672, 673, 674, 0,
+	675, 676, 677, 678, 679, 680, 681, 682, 683, 684,
+	1558, 685, 686, 688, 687, 689, 690, 0, 691, 692,
+	0, 693, 694, 695, 0, 0, 0, 0, 0, 696,
+	697, 699, 0, 700, 701, 702, 703, 704, 705, 698,
+	706, 707, 708, 709, 710, 711, 712, 713, 0, 715,
+	716, 714, 717, 718, 942, 719, 720, 721, 722, 723,
+	1489, 724, 0, 725, 726, 734, 735, 736, 727, 728,
+	730, 737, 729, 738, 739, 740, 741, 743, 742, 0,
+	745, 746, 744, 747, 748, 749, 750, 1540, 751, 895,
+	752, 731, 732, 753, 754, 755, 943, 756, 757, 758,
+	759, 760, 761, 762, 763, 764, 1556, 0, 766, 0,
+	765, 767, 768, 769, 770, 771, 772, 773, 775, 733,
+	776, 777, 778, 783, 784, 785, 1588, 779, 780, 781,
+	782, 787, 1581, 788, 789, 790, 791, 0, 792, 793,
+	1474, 786, 774, 0, 794, 795, 796, 797, 798, 799,
+	800, 801, 802, 803, 0, 804, 1569, 1570, 1571, 1572,
+	0, 817, 0, 805, 807, 808, 809, 810, 1582, 811,
+	812, 1583, 1499, 813, 814, 815, 816, 806, 819, 820,
+	818, 0, 1481, 821, 822, 823, 824, 826, 828, 829,
+	830, 825, 827, 831, 1541, 832, 0, 0, 833, 834,
+	835, 905, 1566, 1587, 0, 1576, 838, 839, 836, 837,
+	840, 841, 844, 842, 843, 909, 847, 542, 848, 849,
+	850, 845, 846, 0, 0, 0, 0, 851, 852, 910,
+	853, 854, 855, 1478, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 1473,
+	0, 0, 0, 0, 0, 0, 1471, 1472, 0, 0,
+	0, 0, 0, 0, 916, 0, 1505, 0, 0, 3453,
+	1503, 1551, 1493, 1494, 1495, 1491, 1492, 1504, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 367, 368,
+	370, 369, 371, 372, 373, 374, 0, 375, 376, 0,
+	0, 0, 0, 0, 1543, 1509, 0, 0, 378, 0,
+	377, 0, 379, 380, 381, 926, 382, 383, 384, 385,
+	386, 387, 388, 389, 390, 857, 391, 1557, 0, 392,
+	1565, 393, 1564, 0, 1575, 394, 395, 396, 397, 398,
+	399, 400, 401, 402, 403, 404, 1511, 1542, 1475, 405,
+	1589, 1590, 864, 0, 406, 407, 408, 409, 1549, 0,
+	1530, 0, 410, 411, 412, 413, 414, 415, 416, 417,
+	0, 0, 419, 420, 421, 418, 422, 423, 0, 424,
+	0, 425, 426, 427, 428, 429, 0, 430, 431, 0,
+	432, 433, 434, 928, 435, 436, 437, 1533, 1531, 1532,
+	1539, 1535, 1534, 1538, 438, 439, 440, 441, 442, 1568,
+	443, 445, 1562, 1561, 1480, 448, 450, 444, 446, 0,
+	449, 447, 451, 452, 0, 453, 454, 455, 456, 457,
+	0, 0, 0, 458, 1560, 460, 461, 0, 462, 463,
+	464, 466, 465, 0, 467, 468, 469, 0, 470, 471,
+	1487, 472, 473, 474, 476, 478, 475, 477, 479, 480,
+	481, 482, 483, 1577, 1578, 484, 485, 1500, 362, 0,
+	0, 0, 0, 0, 486, 487, 488, 1559, 0, 0,
+	0, 489, 0, 491, 495, 496, 492, 493, 494, 497,
+	0, 490, 498, 499, 0, 929, 500, 501, 502, 1573,
+	1574, 503, 504, 505, 506, 507, 508, 509, 510, 511,
+	0, 512, 513, 1584, 0, 1510, 514, 0, 515, 516,
+	517, 518, 519, 520, 521, 1544, 1545, 1548, 630, 931,
+	522, 523, 524, 525, 0, 526, 527, 528, 529, 530,
+	531, 532, 0, 0, 0, 533, 534, 535, 536, 0,
+	919, 363, 365, 930, 879, 537, 631, 538, 539, 1554,
+	1555, 0, 1514, 0, 540, 541, 544, 932, 1546, 933,
+	543, 545, 546, 934, 547, 0, 0, 0, 548, 549,
+	550, 551, 552, 553, 554, 0, 555, 557, 556, 0,
+	559, 1585, 558, 935, 560, 561, 936, 0, 562, 563,
+	564, 565, 566, 567, 572, 1537, 1536, 568, 569, 570,
+	571, 573, 574, 0, 575, 576, 578, 581, 577, 579,
+	580, 582, 583, 596, 597, 598, 584, 585, 586, 587,
+	588, 589, 590, 591, 592, 593, 594, 595, 600, 0,
+	599, 937, 0, 601, 602, 603, 604, 605, 606, 612,
+	615, 617, 618, 613, 614, 616, 619, 620, 621, 623,
+	624, 609, 610, 611, 938, 622, 607, 1477, 608, 366,
+	939, 625, 626, 627, 628, 1501, 1547, 629, 1563, 632,
+	633, 0, 0, 634, 0, 635, 636, 0, 0, 638,
+	639, 640, 0, 0, 641, 642, 887, 940, 643, 941,
+	1579, 644, 645, 1488, 646, 647, 648, 649, 650, 651,
+	652, 653, 654, 655, 656, 657, 0, 658, 659, 889,
+	660, 661, 662, 663, 664, 890, 665, 666, 667, 1580,
+	668, 892, 669, 670, 671, 0, 672, 673, 674, 0,
+	675, 676, 677, 678, 679, 680, 681, 682, 683, 684,
+	1558, 685, 686, 688, 687, 689, 690, 0, 691, 692,
+	0, 693, 694, 695, 0, 0, 0, 0, 0, 696,
+	697, 699, 0, 700, 701, 702, 703, 704, 705, 698,
+	706, 707, 708, 709, 710, 711, 712, 713, 0, 715,
+	716, 714, 717, 718, 942, 719, 720, 721, 722, 723,
+	1489, 724, 0, 725, 726, 734, 735, 736, 727, 728,
+	730, 737, 729, 738, 739, 740, 741, 743, 742, 0,
+	745, 746, 744, 747, 748, 749, 750, 1540, 751, 895,
+	752, 731, 732, 753, 754, 755, 943, 756, 757, 758,
+	759, 760, 761, 762, 763, 764, 1556, 0, 766, 0,
+	765, 767, 768, 769, 770, 771, 772, 773, 775, 733,
+	776, 777, 778, 783, 784, 785, 1588, 779, 780, 781,
+	782, 787, 1581, 788, 789, 790, 791, 0, 792, 793,
+	1474, 786, 774, 0, 794, 795, 796, 797, 798, 799,
+	800, 801, 802, 803, 0, 804, 1569, 1570, 1571, 1572,
+	0, 817, 0, 805, 807, 808, 809, 810, 1582, 811,
+	812, 1583, 1499, 813, 814, 815, 816, 806, 819, 820,
+	818, 0, 1481, 821, 822, 823, 824, 826, 828, 829,
+	830, 825, 827, 831, 1541, 832, 0, 0, 833, 834,
+	835, 905, 1566, 1587, 0, 1576, 838, 839, 836, 837,
+	840, 841, 844, 842, 843, 909, 847, 542, 848, 849,
+	850, 845, 846, 0, 0, 0, 0, 851, 852, 910,
+	853, 854, 855, 1478, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 1473,
+	0, 0, 0, 0, 0, 0, 1471, 1472, 0, 0,
+	0, 0, 0, 0, 916, 0, 1505, 0, 0, 3442,
+	1503, 1551, 1493, 1494, 1495, 1491, 1492, 1504, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 367, 368,
+	370, 369, 371, 372, 373, 374, 0, 375, 376, 0,
+	0, 0, 0, 0, 1543, 1509, 0, 0, 378, 0,
+	377, 0, 379, 380, 381, 926, 382, 383, 384, 385,
+	386, 387, 388, 389, 390, 857, 391, 1557, 0, 392,
+	1565, 393, 1564, 0, 1575, 394, 395, 396, 397, 398,
+	399, 400, 401, 402, 403, 404, 1511, 1542, 1475, 405,
+	1589, 1590, 864, 0, 406, 407, 408, 409, 1549, 0,
+	1530, 0, 410, 411, 412, 413, 414, 415, 416, 417,
+	0, 0, 419, 420, 421, 418, 422, 423, 0, 424,
+	0, 425, 426, 427, 428, 429, 0, 430, 431, 0,
+	432, 433, 434, 928, 435, 436, 437, 1533, 1531, 1532,
+	1539, 1535, 1534, 1538, 438, 439, 440, 441, 442, 1568,
+	443, 445, 1562, 1561, 1480, 448, 450, 444, 446, 0,
+	449, 447, 451, 452, 0, 453, 454, 455, 456, 457,
+	0, 0, 0, 458, 1560, 460, 461, 0, 462, 463,
+	464, 466, 465, 0, 467, 468, 469, 0, 470, 471,
+	1487, 472, 473, 474, 476, 478, 475, 477, 479, 480,
+	481, 482, 483, 1577, 1578, 484, 485, 1500, 362, 0,
+	0, 0, 0, 0, 486, 487, 488, 1559, 0, 0,
+	0, 489, 0, 491, 495, 496, 492, 493, 494, 497,
+	0, 490, 498, 499, 0, 929, 500, 501, 502, 1573,
+	1574, 503, 504, 505, 506, 507, 508, 509, 510, 511,
+	0, 512, 513, 1584, 0, 1510, 514, 0, 515, 516,
+	517, 518, 519, 520, 521, 1544, 1545, 1548, 630, 931,
+	522, 523, 524, 525, 0, 526, 527, 528, 529, 530,
+	531, 532, 0, 0, 0, 533, 534, 535, 536, 0,
+	919, 363, 365, 930, 879, 537, 631, 538, 539, 1554,
+	1555, 0, 1514, 0, 540, 541, 544, 932, 1546, 933,
+	543, 545, 546, 934, 547, 0, 0, 0, 548, 549,
+	550, 551, 552, 553, 554, 0, 555, 557, 556, 0,
+	559, 1585, 558, 935, 560, 561, 936, 0, 562, 563,
+	564, 565, 566, 567, 572, 1537, 1536, 568, 569, 570,
+	571, 573, 574, 0, 575, 576, 578, 581, 577, 579,
+	580, 582, 583, 596, 597, 598, 584, 585, 586, 587,
+	588, 589, 590, 591, 592, 593, 594, 595, 600, 0,
+	599, 937, 0, 601, 602, 603, 604, 605, 606, 612,
+	615, 617, 618, 613, 614, 616, 619, 620, 621, 623,
+	624, 609, 610, 611, 938, 622, 607, 1477, 608, 366,
+	939, 625, 626, 627, 628, 1501, 1547, 629, 1563, 632,
+	633, 0, 0, 634, 0, 635, 636, 0, 0, 638,
+	639, 640, 0, 0, 641, 642, 887, 940, 643, 941,
+	1579, 644, 645, 1488, 646, 647, 648, 649, 650, 651,
+	652, 653, 654, 655, 656, 657, 0, 658, 659, 889,
+	660, 661, 662, 663, 664, 890, 665, 666, 667, 1580,
+	668, 892, 669, 670, 671, 0, 672, 673, 674, 0,
+	675, 676, 677, 678, 679, 680, 681, 682, 683, 684,
+	1558, 685, 686, 688, 687, 689, 690, 0, 691, 692,
+	0, 693, 694, 695, 0, 0, 0, 0, 0, 696,
+	697, 699, 0, 700, 701, 702, 703, 704, 705, 698,
+	706, 707, 708, 709, 710, 711, 712, 713, 0, 715,
+	716, 714, 717, 718, 942, 719, 720, 721, 722, 723,
+	1489, 724, 0, 725, 726, 734, 735, 736, 727, 728,
+	730, 737, 729, 738, 739, 740, 741, 743, 742, 0,
+	745, 746, 744, 747, 748, 749, 750, 1540, 751, 895,
+	752, 731, 732, 753, 754, 755, 943, 756, 757, 758,
+	759, 760, 761, 762, 763, 764, 1556, 0, 766, 0,
+	765, 767, 768, 769, 770, 771, 772, 773, 775, 733,
+	776, 777, 778, 783, 784, 785, 1588, 779, 780, 781,
+	782, 787, 1581, 788, 789, 790, 791, 0, 792, 793,
+	1474, 786, 774, 0, 794, 795, 796, 797, 798, 799,
+	800, 801, 802, 803, 0, 804, 1569, 1570, 1571, 1572,
+	0, 817, 0, 805, 807, 808, 809, 810, 1582, 811,
+	812, 1583, 1499, 813, 814, 815, 816, 806, 819, 820,
+	818, 0, 1481, 821, 822, 823, 824, 826, 828, 829,
+	830, 825, 827, 831, 1541, 832, 0, 0, 833, 834,
+	835, 905, 1566, 1587, 0, 1576, 838, 839, 836, 837,
+	840, 841, 844, 842, 843, 909, 847, 542, 848, 849,
+	850, 845, 846, 0, 0, 0, 0, 851, 852, 910,
+	853, 854, 855, 1478, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 1473,
+	0, 0, 0, 0, 0, 0, 1471, 1472, 0, 0,
+	0, 0, 0, 0, 916, 0, 1505, 0, 0, 3440,
+	1503, 3431, 3438, 1494, 1495, 1491, 1492, 1504, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 367, 368,
+	370, 369, 371, 372, 373, 374, 0, 375, 376, 0,
+	0, 0, 0, 0, 1543, 1509, 0, 0, 378, 0,
+	377, 0, 379, 380, 381, 926, 382, 383, 384, 385,
+	386, 387, 388, 389, 390, 857, 391, 1557, 0, 392,
+	1565, 393, 1564, 0, 1575, 394, 395, 396, 397, 398,
+	399, 400, 401, 402, 403, 404, 1511, 1542, 1475, 405,
+	1589, 1590, 864, 0, 406, 407, 408, 409, 1549, 0,
+	1530, 0, 410, 411, 412, 413, 414, 415, 416, 417,
+	0, 0, 419, 420, 421, 418, 422, 423, 0, 424,
+	0, 425, 426, 427, 428, 429, 0, 430, 431, 0,
+	432, 433, 434, 928, 435, 436, 437, 1533, 1531, 1532,
+	1539, 1535, 1534, 1538, 438, 439, 440, 441, 442, 1568,
+	3434, 445, 1562, 1561, 1480, 448, 450, 444, 446, 0,
+	449, 447, 451, 452, 0, 453, 454, 455, 456, 457,
+	0, 0, 0, 458, 1560, 460, 461, 0, 462, 463,
+	464, 466, 465, 0, 467, 468, 469, 0, 470, 471,
+	1487, 472, 473, 474, 476, 478, 475, 477, 479, 480,
+	481, 482, 483, 1577, 1578, 484, 485, 1500, 362, 0,
+	0, 0, 0, 0, 486, 487, 488, 1559, 0, 0,
+	0, 489, 0, 491, 495, 496, 492, 493, 494, 497,
+	0, 490, 498, 499, 0, 929, 500, 501, 502, 1573,
+	1574, 503, 504, 505, 506, 507, 508, 509, 510, 511,
+	0, 512, 513, 1584, 0, 1510, 514, 0, 515, 516,
+	517, 518, 519, 3435, 521, 1544, 1545, 1548, 630, 931,
+	522, 523, 524, 525, 0, 526, 527, 528, 529, 530,
+	531, 532, 0, 0, 0, 533, 534, 535, 536, 0,
+	919, 363, 365, 930, 879, 537, 631, 538, 539, 1554,
+	1555, 0, 1514, 0, 540, 541, 544, 932, 1546, 933,
+	543, 545, 546, 934, 547, 0, 0, 0, 548, 549,
+	550, 551, 552, 553, 554, 0, 555, 557, 556, 0,
+	559, 1585, 558, 935, 560, 561, 936, 0, 562, 563,
+	564, 565, 566, 567, 572, 1537, 1536, 568, 569, 570,
+	571, 573, 574, 0, 575, 576, 578, 581, 577, 579,
+	3436, 582, 583, 596, 3433, 598, 584, 585, 586, 587,
+	588, 589, 590, 591, 592, 593, 594, 595, 600, 0,
+	599, 937, 0, 601, 602, 603, 604, 605, 606, 612,
+	615, 617, 618, 613, 614, 616, 619, 620, 621, 623,
+	624, 609, 610, 611, 938, 622, 607, 1477, 608, 366,
+	939, 625, 626, 627, 628, 1501, 1547, 629, 1563, 632,
+	633, 0, 0, 634, 0, 635, 636, 0, 0, 638,
+	639, 640, 0, 0, 641, 642, 887, 940, 643, 941,
+	1579, 644, 645, 1488, 646, 647, 648, 649, 650, 651,
+	652, 653, 654, 655, 656, 657, 0, 658, 659, 889,
+	660, 661, 662, 663, 664, 890, 665, 666, 667, 1580,
+	668, 892, 669, 670, 671, 0, 672, 673, 674, 0,
+	675, 676, 677, 678, 679, 680, 681, 682, 683, 684,
+	1558, 685, 686, 688, 687, 689, 690, 0, 691, 692,
+	0, 693, 694, 695, 0, 0, 0, 0, 0, 696,
+	697, 699, 0, 700, 701, 702, 703, 704, 705, 698,
+	706, 707, 708, 709, 710, 711, 712, 713, 0, 715,
+	716, 714, 717, 718, 942, 719, 720, 721, 722, 723,
+	1489, 724, 0, 725, 726, 734, 735, 736, 727, 728,
+	730, 737, 729, 738, 739, 740, 3437, 743, 742, 0,
+	745, 746, 744, 747, 748, 749, 750, 1540, 751, 895,
+	752, 731, 732, 753, 754, 755, 943, 756, 757, 758,
+	759, 760, 761, 762, 763, 764, 1556, 0, 766, 0,
+	765, 767, 768, 769, 770, 771, 772, 773, 775, 733,
+	776, 777, 778, 783, 784, 785, 1588, 779, 780, 781,
+	782, 787, 1581, 788, 789, 790, 791, 0, 792, 793,
+	1474, 786, 774, 0, 794, 795, 796, 797, 798, 799,
+	800, 801, 802, 803, 0, 804, 1569, 1570, 1571, 1572,
+	0, 817, 0, 805, 807, 808, 809, 810, 1582, 811,
+	812, 1583, 1499, 813, 814, 815, 816, 806, 819, 820,
+	818, 0, 1481, 821, 822, 823, 824, 826, 828, 829,
+	830, 825, 827, 831, 1541, 832, 0, 0, 833, 834,
+	835, 905, 1566, 1587, 0, 1576, 838, 839, 836, 837,
+	840, 841, 844, 842, 843, 909, 847, 542, 848, 849,
+	850, 845, 846, 0, 0, 0, 0, 851, 852, 910,
+	853, 3432, 855, 1478, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 1473,
+	0, 0, 0, 0, 0, 0, 1471, 1472, 0, 0,
+	0, 0, 0, 0, 916, 0, 1505, 0, 0, 3428,
+	1503, 3431, 3438, 1494, 1495, 1491, 1492, 1504, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 367, 368,
+	370, 369, 371, 372, 373, 374, 0, 375, 376, 0,
+	0, 0, 0, 0, 1543, 1509, 0, 0, 378, 0,
+	377, 0, 379, 380, 381, 926, 382, 383, 384, 385,
+	386, 387, 388, 389, 390, 857, 391, 1557, 0, 392,
+	1565, 393, 1564, 0, 1575, 394, 395, 396, 397, 398,
+	399, 400, 401, 402, 403, 404, 1511, 1542, 1475, 405,
+	1589, 1590, 864, 0, 406, 407, 408, 409, 1549, 0,
+	1530, 0, 410, 411, 412, 413, 414, 415, 416, 417,
+	0, 0, 419, 420, 421, 418, 422, 423, 0, 424,
+	0, 425, 426, 427, 428, 429, 0, 430, 431, 0,
+	432, 433, 434, 928, 435, 436, 437, 1533, 1531, 1532,
+	1539, 1535, 1534, 1538, 438, 439, 440, 441, 442, 1568,
+	3434, 445, 1562, 1561, 1480, 448, 450, 444, 446, 0,
+	449, 447, 451, 452, 0, 453, 454, 455, 456, 457,
+	0, 0, 0, 458, 1560, 460, 461, 0, 462, 463,
+	464, 466, 465, 0, 467, 468, 469, 0, 470, 471,
+	1487, 472, 473, 474, 476, 478, 475, 477, 479, 480,
+	481, 482, 483, 1577, 1578, 484, 485, 1500, 362, 0,
+	0, 0, 0, 0, 486, 487, 488, 1559, 0, 0,
+	0, 489, 0, 491, 495, 496, 492, 493, 494, 497,
+	0, 490, 498, 499, 0, 929, 500, 501, 502, 1573,
+	1574, 503, 504, 505, 506, 507, 508, 509, 510, 511,
+	0, 512, 513, 1584, 0, 1510, 514, 0, 515, 516,
+	517, 518, 519, 3435, 521, 1544, 1545, 1548, 630, 931,
+	522, 523, 524, 525, 0, 526, 527, 528, 529, 530,
+	531, 532, 0, 0, 0, 533, 534, 535, 536, 0,
+	919, 363, 365, 930, 879, 537, 631, 538, 539, 1554,
+	1555, 0, 1514, 0, 540, 541, 544, 932, 1546, 933,
+	543, 545, 546, 934, 547, 0, 0, 0, 548, 549,
+	550, 551, 552, 553, 554, 0, 555, 557, 556, 0,
+	559, 1585, 558, 935, 560, 561, 936, 0, 562, 563,
+	564, 565, 566, 567, 572, 1537, 1536, 568, 569, 570,
+	571, 573, 574, 0, 575, 576, 578, 581, 577, 579,
+	3436, 582, 583, 596, 3433, 598, 584, 585, 586, 587,
+	588, 589, 590, 591, 592, 593, 594, 595, 600, 0,
+	599, 937, 0, 601, 602, 603, 604, 605, 606, 612,
+	615, 617, 618, 613, 614, 616, 619, 620, 621, 623,
+	624, 609, 610, 611, 938, 622, 607, 1477, 608, 366,
+	939, 625, 626, 627, 628, 1501, 1547, 629, 1563, 632,
+	633, 0, 0, 634, 0, 635, 636, 0, 0, 638,
+	639, 640, 0, 0, 641, 642, 887, 940, 643, 941,
+	1579, 644, 645, 1488, 646, 647, 648, 649, 650, 651,
+	652, 653, 654, 655, 656, 657, 0, 658, 659, 889,
+	660, 661, 662, 663, 664, 890, 665, 666, 667, 1580,
+	668, 892, 669, 670, 671, 0, 672, 673, 674, 0,
+	675, 676, 677, 678, 679, 680, 681, 682, 683, 684,
+	1558, 685, 686, 688, 687, 689, 690, 0, 691, 692,
+	0, 693, 694, 695, 0, 0, 0, 0, 0, 696,
+	697, 699, 0, 700, 701, 702, 703, 704, 705, 698,
+	706, 707, 708, 709, 710, 711, 712, 713, 0, 715,
+	716, 714, 717, 718, 942, 719, 720, 721, 722, 723,
+	1489, 724, 0, 725, 726, 734, 735, 736, 727, 728,
+	730, 737, 729, 738, 739, 740, 3437, 743, 742, 0,
+	745, 746, 744, 747, 748, 749, 750, 1540, 751, 895,
+	752, 731, 732, 753, 754, 755, 943, 756, 757, 758,
+	759, 760, 761, 762, 763, 764, 1556, 0, 766, 0,
+	765, 767, 768, 769, 770, 771, 772, 773, 775, 733,
+	776, 777, 778, 783, 784, 785, 1588, 779, 780, 781,
+	782, 787, 1581, 788, 789, 790, 791, 0, 792, 793,
+	1474, 786, 774, 0, 794, 795, 796, 797, 798, 799,
+	800, 801, 802, 803, 0, 804, 1569, 1570, 1571, 1572,
+	0, 817, 0, 805, 807, 808, 809, 810, 1582, 811,
+	812, 1583, 1499, 813, 814, 815, 816, 806, 819, 820,
+	818, 0, 1481, 821, 822, 823, 824, 826, 828, 829,
+	830, 825, 827, 831, 1541, 832, 0, 0, 833, 834,
+	835, 905, 1566, 1587, 0, 1576, 838, 839, 836, 837,
+	840, 841, 844, 842, 843, 909, 847, 542, 848, 849,
+	850, 845, 846, 0, 0, 0, 0, 851, 852, 910,
+	853, 3432, 855, 1478, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 1473,
+	0, 0, 0, 0, 0, 0, 1471, 1472, 0, 0,
+	0, 0, 0, 0, 916, 0, 1505, 0, 0, 0,
+	1503, 1551, 1493, 1494, 1495, 1491, 1492, 1504, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 367, 368,
+	370, 369, 371, 372, 373, 374, 3174, 375, 376, 0,
+	0, 0, 0, 0, 1543, 1509, 0, 0, 378, 0,
+	377, 0, 379, 380, 381, 926, 382, 383, 384, 385,
+	386, 387, 388, 389, 390, 857, 391, 1557, 0, 392,
+	1565, 393, 1564, 0, 1575, 394, 395, 396, 397, 398,
+	399, 400, 401, 402, 403, 404, 1511, 1542, 1475, 405,
+	1589, 1590, 864, 0, 406, 407, 408, 409, 1549, 0,
+	1530, 0, 410, 411, 412, 413, 414, 415, 416, 417,
+	0, 0, 419, 420, 421, 418, 422, 423, 0, 424,
+	0, 425, 426, 427, 428, 429, 0, 430, 431, 0,
+	432, 433, 434, 928, 435, 436, 437, 1533, 1531, 1532,
+	1539, 1535, 1534, 1538, 438, 439, 440, 441, 442, 1568,
+	443, 445, 1562, 1561, 1480, 448, 450, 444, 446, 0,
+	449, 447, 451, 452, 0, 453, 454, 455, 456, 457,
+	0, 0, 0, 458, 1560, 460, 461, 0, 462, 463,
+	464, 466, 465, 0, 467, 468, 469, 0, 470, 471,
+	1487, 472, 473, 474, 476, 478, 475, 477, 479, 480,
+	481, 482, 483, 1577, 1578, 484, 485, 1500, 362, 0,
+	0, 0, 0, 0, 486, 487, 488, 1559, 0, 0,
+	0, 489, 0, 491, 495, 496, 492, 493, 494, 497,
+	0, 490, 498, 499, 0, 929, 500, 501, 502, 1573,
+	1574, 503, 504, 505, 506, 507, 508, 509, 510, 511,
+	0, 512, 513, 1584, 0, 1510, 514, 0, 515, 516,
+	517, 518, 519, 520, 521, 1544, 1545, 1548, 630, 931,
+	522, 523, 524, 525, 0, 526, 527, 528, 529, 530,
+	531, 532, 0, 0, 0, 533, 534, 535, 536, 0,
+	919, 363, 365, 930, 879, 537, 631, 538, 539, 1554,
+	1555, 0, 1514, 0, 540, 541, 544, 932, 1546, 933,
+	543, 545, 546, 934, 547, 0, 0, 0, 548, 549,
+	550, 551, 552, 553, 554, 0, 555, 557, 556, 0,
+	559, 1585, 558, 935, 560, 561, 936, 0, 562, 563,
+	564, 565, 566, 567, 572, 1537, 1536, 568, 569, 570,
+	571, 573, 574, 0, 575, 576, 578, 581, 577, 579,
+	580, 582, 583, 596, 597, 598, 584, 585, 586, 587,
+	588, 589, 590, 591, 592, 593, 594, 595, 600, 0,
+	599, 937, 0, 601, 602, 603, 604, 605, 606, 612,
+	615, 617, 618, 613, 614, 616, 619, 620, 621, 623,
+	624, 609, 610, 611, 938, 622, 607, 1477, 608, 366,
+	939, 625, 626, 627, 628, 1501, 1547, 629, 1563, 632,
+	633, 0, 0, 634, 0, 635, 636, 0, 0, 638,
+	639, 640, 0, 0, 641, 642, 887, 940, 643, 941,
+	1579, 644, 645, 1488, 646, 647, 648, 649, 650, 651,
+	652, 653, 654, 655, 656, 657, 0, 658, 659, 889,
+	660, 661, 662, 663, 664, 890, 665, 666, 667, 1580,
+	668, 892, 669, 670, 671, 0, 672, 673, 674, 0,
+	675, 676, 677, 678, 679, 680, 681, 682, 683, 684,
+	1558, 685, 686, 688, 687, 689, 690, 0, 691, 692,
+	0, 693, 694, 695, 0, 0, 0, 0, 0, 696,
+	697, 699, 0, 700, 701, 702, 703, 704, 705, 698,
+	706, 707, 708, 709, 710, 711, 712, 713, 0, 715,
+	716, 714, 717, 718, 942, 719, 720, 721, 722, 723,
+	1489, 724, 0, 725, 726, 734, 735, 736, 727, 728,
+	730, 737, 729, 738, 739, 740, 741, 743, 742, 0,
+	745, 746, 744, 747, 748, 749, 750, 1540, 751, 895,
+	752, 731, 732, 753, 754, 755, 943, 756, 757, 758,
+	759, 760, 761, 762, 763, 764, 1556, 0, 766, 0,
+	765, 767, 768, 769, 770, 771, 772, 773, 775, 733,
+	776, 777, 778, 783, 784, 785, 1588, 779, 780, 781,
+	782, 787, 1581, 788, 789, 790, 791, 0, 792, 793,
+	1474, 786, 774, 0, 794, 795, 796, 797, 798, 799,
+	800, 801, 802, 803, 0, 804, 1569, 1570, 1571, 1572,
+	0, 817, 0, 805, 807, 808, 809, 810, 1582, 811,
+	812, 1583, 1499, 813, 814, 815, 816, 806, 819, 820,
+	818, 0, 1481, 821, 822, 823, 824, 826, 828, 829,
+	830, 825, 827, 831, 1541, 832, 0, 0, 833, 834,
+	835, 905, 1566, 1587, 0, 1576, 838, 839, 836, 837,
+	840, 841, 844, 842, 843, 909, 847, 542, 848, 849,
+	850, 845, 846, 0, 0, 0, 0, 851, 852, 910,
+	853, 854, 855, 1478, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 1473,
+	0, 0, 0, 0, 0, 0, 1471, 1472, 0, 0,
+	0, 0, 0, 0, 916, 0, 1505, 0, 0, 2834,
+	1503, 1551, 1493, 1494, 1495, 1491, 1492, 1504, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 367, 368,
+	370, 369, 371, 372, 373, 374, 0, 375, 376, 0,
+	0, 0, 0, 0, 1543, 1509, 0, 0, 378, 0,
+	377, 0, 379, 380, 381, 926, 382, 383, 384, 385,
+	386, 387, 388, 389, 390, 857, 391, 1557, 0, 392,
+	1565, 393, 1564, 0, 1575, 394, 395, 396, 397, 398,
+	399, 400, 401, 402, 403, 404, 1511, 1542, 1475, 405,
+	1589, 1590, 864, 0, 406, 407, 408, 409, 1549, 0,
+	1530, 0, 410, 411, 412, 413, 414, 415, 416, 417,
+	0, 0, 419, 420, 421, 418, 422, 423, 0, 424,
+	0, 425, 426, 427, 428, 429, 0, 430, 431, 0,
+	432, 433, 434, 928, 435, 436, 437, 1533, 1531, 1532,
+	1539, 1535, 1534, 1538, 438, 439, 440, 441, 442, 1568,
+	443, 445, 1562, 1561, 1480, 448, 450, 444, 446, 0,
+	449, 447, 451, 452, 0, 453, 454, 455, 456, 457,
+	0, 0, 0, 458, 1560, 460, 461, 0, 462, 463,
+	464, 466, 465, 0, 467, 468, 469, 0, 470, 471,
+	1487, 472, 473, 474, 476, 478, 475, 477, 479, 480,
+	481, 482, 483, 1577, 1578, 484, 485, 1500, 362, 0,
+	0, 0, 0, 0, 486, 487, 488, 1559, 0, 0,
+	0, 489, 0, 491, 495, 496, 492, 493, 494, 497,
+	0, 490, 498, 499, 0, 929, 500, 501, 502, 1573,
+	1574, 503, 504, 505, 506, 507, 508, 509, 510, 511,
+	0, 512, 513, 1584, 0, 1510, 514, 0, 515, 516,
+	517, 518, 519, 520, 521, 1544, 1545, 1548, 630, 931,
+	522, 523, 524, 525, 0, 526, 527, 528, 529, 530,
+	531, 532, 0, 0, 0, 533, 534, 535, 536, 0,
+	919, 363, 365, 930, 879, 537, 631, 538, 539, 1554,
+	1555, 0, 1514, 0, 540, 541, 544, 932, 1546, 933,
+	543, 545, 546, 934, 547, 0, 0, 0, 548, 549,
+	550, 551, 552, 553, 554, 0, 555, 557, 556, 0,
+	559, 1585, 558, 935, 560, 561, 936, 0, 562, 563,
+	564, 565, 566, 567, 572, 1537, 1536, 568, 569, 570,
+	571, 573, 574, 0, 575, 576, 578, 581, 577, 579,
+	580, 582, 583, 596, 597, 598, 584, 585, 586, 587,
+	588, 589, 590, 591, 592, 593, 594, 595, 600, 0,
+	599, 937, 0, 601, 602, 603, 604, 605, 606, 612,
+	615, 617, 618, 613, 614, 616, 619, 620, 621, 623,
+	624, 609, 610, 611, 938, 622, 607, 1477, 608, 366,
+	939, 625, 626, 627, 628, 1501, 1547, 629, 1563, 632,
+	633, 0, 0, 634, 0, 635, 636, 0, 0, 638,
+	639, 640, 0, 0, 641, 642, 887, 940, 643, 941,
+	1579, 644, 645, 1488, 646, 647, 648, 649, 650, 651,
+	652, 653, 654, 655, 656, 657, 0, 658, 659, 889,
+	660, 661, 662, 663, 664, 890, 665, 666, 667, 1580,
+	668, 892, 669, 670, 671, 0, 672, 673, 674, 0,
+	675, 676, 677, 678, 679, 680, 681, 682, 683, 684,
+	1558, 685, 686, 688, 687, 689, 690, 0, 691, 692,
+	0, 693, 694, 695, 0, 0, 0, 0, 0, 696,
+	697, 699, 0, 700, 701, 702, 703, 704, 705, 698,
+	706, 707, 708, 709, 710, 711, 712, 713, 0, 715,
+	716, 714, 717, 718, 942, 719, 720, 721, 722, 723,
+	1489, 724, 0, 725, 726, 734, 735, 736, 727, 728,
+	730, 737, 729, 738, 739, 740, 741, 743, 742, 0,
+	745, 746, 744, 747, 748, 749, 750, 1540, 751, 895,
+	752, 731, 732, 753, 754, 755, 943, 756, 757, 758,
+	759, 760, 761, 762, 763, 764, 1556, 0, 766, 0,
+	765, 767, 768, 769, 770, 771, 772, 773, 775, 733,
+	776, 777, 778, 783, 784, 785, 1588, 779, 780, 781,
+	782, 787, 1581, 788, 789, 790, 791, 0, 792, 793,
+	1474, 786, 774, 0, 794, 795, 796, 797, 798, 799,
+	800, 801, 802, 803, 0, 804, 1569, 1570, 1571, 1572,
+	0, 817, 0, 805, 807, 808, 809, 810, 1582, 811,
+	812, 1583, 1499, 813, 814, 815, 816, 806, 819, 820,
+	818, 0, 1481, 821, 822, 823, 824, 826, 828, 829,
+	830, 825, 827, 831, 1541, 832, 0, 0, 833, 834,
+	835, 905, 1566, 1587, 0, 1576, 838, 839, 836, 837,
+	840, 841, 844, 842, 843, 909, 847, 542, 848, 849,
+	850, 845, 846, 0, 0, 0, 0, 851, 852, 910,
+	853, 854, 855, 1478, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 1473,
+	0, 0, 0, 0, 0, 0, 1471, 1472, 0, 0,
+	0, 0, 0, 0, 916, 0, 1505, 0, 0, 2791,
+	1503, 1551, 1493, 1494, 1495, 1491, 1492, 1504, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 367, 368,
+	370, 369, 371, 372, 373, 374, 0, 375, 376, 0,
+	0, 0, 0, 0, 1543, 1509, 0, 0, 378, 0,
+	377, 0, 379, 380, 381, 926, 382, 383, 384, 385,
+	386, 387, 388, 389, 390, 857, 391, 1557, 0, 392,
+	1565, 393, 1564, 0, 1575, 394, 395, 396, 397, 398,
+	399, 400, 401, 402, 403, 404, 1511, 1542, 1475, 405,
+	1589, 1590, 864, 0, 406, 407, 408, 409, 1549, 0,
+	1530, 0, 410, 411, 412, 413, 414, 415, 416, 417,
+	0, 0, 419, 420, 421, 418, 422, 423, 0, 424,
+	0, 425, 426, 427, 428, 429, 0, 430, 431, 0,
+	432, 433, 434, 928, 435, 436, 437, 1533, 1531, 1532,
+	1539, 1535, 1534, 1538, 438, 439, 440, 441, 442, 1568,
+	443, 445, 1562, 1561, 1480, 448, 450, 444, 446, 0,
+	449, 447, 451, 452, 0, 453, 454, 455, 456, 457,
+	0, 0, 0, 458, 1560, 460, 461, 0, 462, 463,
+	464, 466, 465, 0, 467, 468, 469, 0, 470, 471,
+	1487, 472, 473, 474, 476, 478, 475, 477, 479, 480,
+	481, 482, 483, 1577, 1578, 484, 485, 1500, 362, 0,
+	0, 0, 0, 0, 486, 487, 488, 1559, 0, 0,
+	0, 489, 0, 491, 495, 496, 492, 493, 494, 497,
+	0, 490, 498, 499, 0, 929, 500, 501, 502, 1573,
+	1574, 503, 504, 505, 506, 507, 508, 509, 510, 511,
+	0, 512, 513, 1584, 0, 1510, 514, 0, 515, 516,
+	517, 518, 519, 520, 521, 1544, 1545, 1548, 630, 931,
+	522, 523, 524, 525, 0, 526, 527, 528, 529, 530,
+	531, 532, 0, 0, 0, 533, 534, 535, 536, 0,
+	919, 363, 365, 930, 879, 537, 631, 538, 539, 1554,
+	1555, 0, 1514, 0, 540, 541, 544, 932, 1546, 933,
+	543, 545, 546, 934, 547, 0, 0, 0, 548, 549,
+	550, 551, 552, 553, 554, 0, 555, 557, 556, 0,
+	559, 1585, 558, 935, 560, 561, 936, 0, 562, 563,
+	564, 565, 566, 567, 572, 1537, 1536, 568, 569, 570,
+	571, 573, 574, 0, 575, 576, 578, 581, 577, 579,
+	580, 582, 583, 596, 597, 598, 584, 585, 586, 587,
+	588, 589, 590, 591, 592, 593, 594, 595, 600, 0,
+	599, 937, 0, 601, 602, 603, 604, 605, 606, 612,
+	615, 617, 618, 613, 614, 616, 619, 620, 621, 623,
+	624, 609, 610, 611, 938, 622, 607, 1477, 608, 366,
+	939, 625, 626, 627, 628, 1501, 1547, 629, 1563, 632,
+	633, 0, 0, 634, 0, 635, 636, 0, 0, 638,
+	639, 640, 0, 0, 641, 642, 887, 940, 643, 941,
+	1579, 644, 645, 1488, 646, 647, 648, 649, 650, 651,
+	652, 653, 654, 655, 656, 657, 0, 658, 659, 889,
+	660, 661, 662, 663, 664, 890, 665, 666, 667, 1580,
+	668, 892, 669, 670, 671, 0, 672, 673, 674, 0,
+	675, 676, 677, 678, 679, 680, 681, 682, 683, 684,
+	1558, 685, 686, 688, 687, 689, 690, 0, 691, 692,
+	0, 693, 694, 695, 0, 0, 0, 0, 0, 696,
+	697, 699, 0, 700, 701, 702, 703, 704, 705, 698,
+	706, 707, 708, 709, 710, 711, 712, 713, 0, 715,
+	716, 714, 717, 718, 942, 719, 720, 721, 722, 723,
+	1489, 724, 0, 725, 726, 734, 735, 736, 727, 728,
+	730, 737, 729, 738, 739, 740, 741, 743, 742, 0,
+	745, 746, 744, 747, 748, 749, 750, 1540, 751, 895,
+	752, 731, 732, 753, 754, 755, 943, 756, 757, 758,
+	759, 760, 761, 762, 763, 764, 1556, 0, 766, 0,
+	765, 767, 768, 769, 770, 771, 772, 773, 775, 733,
+	776, 777, 778, 783, 784, 785, 1588, 779, 780, 781,
+	782, 787, 1581, 788, 789, 790, 791, 0, 792, 793,
+	1474, 786, 774, 0, 794, 795, 796, 797, 798, 799,
+	800, 801, 802, 803, 0, 804, 1569, 1570, 1571, 1572,
+	0, 817, 0, 805, 807, 808, 809, 810, 1582, 811,
+	812, 1583, 1499, 813, 814, 815, 816, 806, 819, 820,
+	818, 0, 1481, 821, 822, 823, 824, 826, 828, 829,
+	830, 825, 827, 831, 1541, 832, 0, 0, 833, 834,
+	835, 905, 1566, 1587, 0, 1576, 838, 839, 836, 837,
+	840, 841, 844, 842, 843, 909, 847, 542, 848, 849,
+	850, 845, 846, 0, 0, 0, 0, 851, 852, 910,
+	853, 854, 855, 1478, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 1473,
+	0, 0, 0, 0, 0, 0, 1471, 1472, 0, 0,
+	0, 0, 0, 0, 916, 0, 1505, 0, 0, 2270,
+	1503, 1551, 1493, 1494, 1495, 1491, 1492, 1504, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 367, 368,
+	370, 369, 371, 372, 373, 374, 0, 375, 376, 0,
+	0, 0, 0, 0, 1543, 1509, 0, 0, 378, 0,
+	377, 0, 379, 380, 381, 926, 382, 383, 384, 385,
+	386, 387, 388, 389, 390, 857, 391, 1557, 0, 392,
+	1565, 393, 1564, 0, 1575, 394, 395, 396, 397, 398,
+	399, 400, 401, 402, 403, 404, 1511, 1542, 1475, 405,
+	1589, 1590, 864, 0, 406, 407, 408, 409, 1549, 0,
+	1530, 0, 410, 411, 412, 413, 414, 415, 416, 417,
+	0, 0, 419, 420, 421, 418, 422, 423, 0, 424,
+	0, 425, 426, 427, 428, 429, 0, 430, 431, 0,
+	432, 433, 434, 928, 435, 436, 437, 1533, 1531, 1532,
+	1539, 1535, 1534, 1538, 438, 439, 440, 441, 442, 1568,
+	443, 445, 1562, 1561, 1480, 448, 450, 444, 446, 0,
+	449, 447, 451, 452, 0, 453, 454, 455, 456, 457,
+	0, 0, 0, 458, 1560, 460, 461, 0, 462, 463,
+	464, 466, 465, 0, 467, 468, 469, 0, 470, 471,
+	1487, 472, 473, 474, 476, 478, 475, 477, 479, 480,
+	481, 482, 483, 1577, 1578, 484, 485, 1500, 362, 0,
+	0, 0, 0, 0, 486, 487, 488, 1559, 0, 0,
+	0, 489, 0, 491, 495, 496, 492, 493, 494, 497,
+	0, 490, 498, 499, 0, 929, 500, 501, 502, 1573,
+	1574, 503, 504, 505, 506, 507, 508, 509, 510, 511,
+	0, 512, 513, 1584, 0, 1510, 514, 0, 515, 516,
+	517, 518, 519, 520, 521, 1544, 1545, 1548, 630, 931,
+	522, 523, 524, 525, 0, 526, 527, 528, 529, 530,
+	531, 532, 0, 0, 0, 533, 534, 535, 536, 0,
+	919, 363, 365, 930, 879, 537, 631, 538, 539, 1554,
+	1555, 0, 1514, 0, 540, 541, 544, 932, 1546, 933,
+	543, 545, 546, 934, 547, 0, 0, 0, 548, 549,
+	550, 551, 552, 553, 554, 0, 555, 557, 556, 0,
+	559, 1585, 558, 935, 560, 561, 936, 0, 562, 563,
+	564, 565, 566, 567, 572, 1537, 1536, 568, 569, 570,
+	571, 573, 574, 0, 575, 576, 578, 581, 577, 579,
+	580, 582, 583, 596, 597, 598, 584, 585, 586, 587,
+	588, 589, 590, 591, 592, 593, 594, 595, 600, 0,
+	599, 937, 0, 601, 602, 603, 604, 605, 606, 612,
+	615, 617, 618, 613, 614, 616, 619, 620, 621, 623,
+	624, 609, 610, 611, 938, 622, 607, 1477, 608, 366,
+	939, 625, 626, 627, 628, 1501, 1547, 629, 1563, 632,
+	633, 0, 0, 634, 0, 635, 636, 0, 0, 638,
+	639, 640, 0, 0, 641, 642, 887, 940, 643, 941,
+	1579, 644, 645, 1488, 646, 647, 648, 649, 650, 651,
+	652, 653, 654, 655, 656, 657, 0, 658, 659, 889,
+	660, 661, 662, 663, 664, 890, 665, 666, 667, 1580,
+	668, 892, 669, 670, 671, 0, 672, 673, 674, 0,
+	675, 676, 677, 678, 679, 680, 681, 682, 683, 684,
+	1558, 685, 686, 688, 687, 689, 690, 0, 691, 692,
+	0, 693, 694, 695, 0, 0, 0, 0, 0, 696,
+	697, 699, 0, 700, 701, 702, 703, 704, 705, 698,
+	706, 707, 708, 709, 710, 711, 712, 713, 0, 715,
+	716, 714, 717, 718, 942, 719, 720, 721, 722, 723,
+	1489, 724, 0, 725, 726, 734, 735, 736, 727, 728,
+	730, 737, 729, 738, 739, 740, 741, 743, 742, 0,
+	745, 746, 744, 747, 748, 749, 750, 1540, 751, 895,
+	752, 731, 732, 753, 754, 755, 943, 756, 757, 758,
+	759, 760, 761, 762, 763, 764, 1556, 0, 766, 0,
+	765, 767, 768, 769, 770, 771, 772, 773, 775, 733,
+	776, 777, 778, 783, 784, 785, 1588, 779, 780, 781,
+	782, 787, 1581, 788, 789, 790, 791, 0, 792, 793,
+	1474, 786, 774, 0, 794, 795, 796, 797, 798, 799,
+	800, 801, 802, 803, 0, 804, 1569, 1570, 1571, 1572,
+	0, 817, 0, 805, 807, 808, 809, 810, 1582, 811,
+	812, 1583, 1499, 813, 814, 815, 816, 806, 819, 820,
+	818, 0, 1481, 821, 822, 823, 824, 826, 828, 829,
+	830, 825, 827, 831, 1541, 832, 0, 0, 833, 834,
+	835, 905, 1566, 1587, 0, 1576, 838, 839, 836, 837,
+	840, 841, 844, 842, 843, 909, 847, 542, 848, 849,
+	850, 845, 846, 0, 0, 0, 0, 851, 852, 910,
+	853, 854, 855, 1478, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 1473,
+	0, 0, 0, 0, 0, 0, 1471, 1472, 0, 0,
+	0, 0, 0, 0, 916, 0, 1505, 0, 0, 2265,
+	1503, 1551, 1493, 1494, 1495, 1491, 1492, 1504, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 367, 368,
+	370, 369, 371, 372, 373, 374, 0, 375, 376, 0,
+	0, 0, 0, 0, 1543, 1509, 0, 0, 378, 0,
+	377, 0, 379, 380, 381, 926, 382, 383, 384, 385,
+	386, 387, 388, 389, 390, 857, 391, 1557, 0, 392,
+	1565, 393, 1564, 0, 1575, 394, 395, 396, 397, 398,
+	399, 400, 401, 402, 403, 404, 1511, 1542, 1475, 405,
+	1589, 1590, 864, 0, 406, 407, 408, 409, 1549, 0,
+	1530, 0, 410, 411, 412, 413, 414, 415, 416, 417,
+	0, 0, 419, 420, 421, 418, 422, 423, 0, 424,
+	0, 425, 426, 427, 428, 429, 0, 430, 431, 0,
+	432, 433, 434, 928, 435, 436, 437, 1533, 1531, 1532,
+	1539, 1535, 1534, 1538, 438, 439, 440, 441, 442, 1568,
+	443, 445, 1562, 1561, 1480, 448, 450, 444, 446, 0,
+	449, 447, 451, 452, 0, 453, 454, 455, 456, 457,
+	0, 0, 0, 458, 1560, 460, 461, 0, 462, 463,
+	464, 466, 465, 0, 467, 468, 469, 0, 470, 471,
+	1487, 472, 473, 474, 476, 478, 475, 477, 479, 480,
+	481, 482, 483, 1577, 1578, 484, 485, 1500, 362, 0,
+	0, 0, 0, 0, 486, 487, 488, 1559, 0, 0,
+	0, 489, 0, 491, 495, 496, 492, 493, 494, 497,
+	0, 490, 498, 499, 0, 929, 500, 501, 502, 1573,
+	1574, 503, 504, 505, 506, 507, 508, 509, 510, 511,
+	0, 512, 513, 1584, 0, 1510, 514, 0, 515, 516,
+	517, 518, 519, 520, 521, 1544, 1545, 1548, 630, 931,
+	522, 523, 524, 525, 0, 526, 527, 528, 529, 530,
+	531, 532, 0, 0, 0, 533, 534, 535, 536, 0,
+	919, 363, 365, 930, 879, 537, 631, 538, 539, 1554,
+	1555, 0, 1514, 0, 540, 541, 544, 932, 1546, 933,
+	543, 545, 546, 934, 547, 0, 0, 0, 548, 549,
+	550, 551, 552, 553, 554, 0, 555, 557, 556, 0,
+	559, 1585, 558, 935, 560, 561, 936, 0, 562, 563,
+	564, 565, 566, 567, 572, 1537, 1536, 568, 569, 570,
+	571, 573, 574, 0, 575, 576, 578, 581, 577, 579,
+	580, 582, 583, 596, 597, 598, 584, 585, 586, 587,
+	588, 589, 590, 591, 592, 593, 594, 595, 600, 0,
+	599, 937, 0, 601, 602, 603, 604, 605, 606, 612,
+	615, 617, 618, 613, 614, 616, 619, 620, 621, 623,
+	624, 609, 610, 611, 938, 622, 607, 1477, 608, 366,
+	939, 625, 626, 627, 628, 1501, 1547, 629, 1563, 632,
+	633, 0, 0, 634, 0, 635, 636, 0, 0, 638,
+	639, 640, 0, 0, 641, 642, 887, 940, 643, 941,
+	1579, 644, 645, 1488, 646, 647, 648, 649, 650, 651,
+	652, 653, 654, 655, 656, 657, 0, 658, 659, 889,
+	660, 661, 662, 663, 664, 890, 665, 666, 667, 1580,
+	668, 892, 669, 670, 671, 0, 672, 673, 674, 0,
+	675, 676, 677, 678, 679, 680, 681, 682, 683, 684,
+	1558, 685, 686, 688, 687, 689, 690, 0, 691, 692,
+	0, 693, 694, 695, 0, 0, 0, 0, 0, 696,
+	697, 699, 0, 700, 701, 702, 703, 704, 705, 698,
+	706, 707, 708, 709, 710, 711, 712, 713, 0, 715,
+	716, 714, 717, 718, 942, 719, 720, 721, 722, 723,
+	1489, 724, 0, 725, 726, 734, 735, 736, 727, 728,
+	730, 737, 729, 738, 739, 740, 741, 743, 742, 0,
+	745, 746, 744, 747, 748, 749, 750, 1540, 751, 895,
+	752, 731, 732, 753, 754, 755, 943, 756, 757, 758,
+	759, 760, 761, 762, 763, 764, 1556, 0, 766, 0,
+	765, 767, 768, 769, 770, 771, 772, 773, 775, 733,
+	776, 777, 778, 783, 784, 785, 1588, 779, 780, 781,
+	782, 787, 1581, 788, 789, 790, 791, 0, 792, 793,
+	1474, 786, 774, 0, 794, 795, 796, 797, 798, 799,
+	800, 801, 802, 803, 0, 804, 1569, 1570, 1571, 1572,
+	0, 817, 0, 805, 807, 808, 809, 810, 1582, 811,
+	812, 1583, 1499, 813, 814, 815, 816, 806, 819, 820,
+	818, 0, 1481, 821, 822, 823, 824, 826, 828, 829,
+	830, 825, 827, 831, 1541, 832, 0, 0, 833, 834,
+	835, 905, 1566, 1587, 0, 1576, 838, 839, 836, 837,
+	840, 841, 844, 842, 843, 909, 847, 542, 848, 849,
+	850, 845, 846, 0, 0, 0, 0, 851, 852, 910,
+	853, 854, 855, 1478, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 1473,
+	0, 0, 0, 0, 0, 0, 1471, 1472, 0, 0,
+	0, 0, 0, 0, 916, 0, 1505, 0, 0, 2253,
+	1503, 1551, 1493, 1494, 1495, 1491, 1492, 1504, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 367, 368,
+	370, 369, 371, 372, 373, 374, 0, 375, 376, 0,
+	0, 0, 0, 0, 1543, 1509, 0, 0, 378, 0,
+	377, 0, 379, 380, 381, 926, 382, 383, 384, 385,
+	386, 387, 388, 389, 390, 857, 391, 1557, 0, 392,
+	1565, 393, 1564, 0, 1575, 394, 395, 396, 397, 398,
+	399, 400, 401, 402, 403, 404, 1511, 1542, 1475, 405,
+	1589, 1590, 864, 0, 406, 407, 408, 409, 1549, 0,
+	1530, 0, 410, 411, 412, 413, 414, 415, 416, 417,
+	0, 0, 419, 420, 421, 418, 422, 423, 0, 424,
+	0, 425, 426, 427, 428, 429, 0, 430, 431, 0,
+	432, 433, 434, 928, 435, 436, 437, 1533, 1531, 1532,
+	1539, 1535, 1534, 1538, 438, 439, 440, 441, 442, 1568,
+	443, 445, 1562, 1561, 1480, 448, 450, 444, 446, 0,
+	449, 447, 451, 452, 0, 453, 454, 455, 456, 457,
+	0, 0, 0, 458, 1560, 460, 461, 0, 462, 463,
+	464, 466, 465, 0, 467, 468, 469, 0, 470, 471,
+	1487, 472, 473, 474, 476, 478, 475, 477, 479, 480,
+	481, 482, 483, 1577, 1578, 484, 485, 1500, 362, 0,
+	0, 0, 0, 0, 486, 487, 488, 1559, 0, 0,
+	0, 489, 0, 491, 495, 496, 492, 493, 494, 497,
+	0, 490, 498, 499, 0, 929, 500, 501, 502, 1573,
+	1574, 503, 504, 505, 506, 507, 508, 509, 510, 511,
+	0, 512, 513, 1584, 0, 1510, 514, 0, 515, 516,
+	517, 518, 519, 520, 521, 1544, 1545, 1548, 630, 931,
+	522, 523, 524, 525, 0, 526, 527, 528, 529, 530,
+	531, 532, 0, 0, 0, 533, 534, 535, 536, 0,
+	919, 363, 365, 930, 879, 537, 631, 538, 539, 1554,
+	1555, 0, 1514, 0, 540, 541, 544, 932, 1546, 933,
+	543, 545, 546, 934, 547, 0, 0, 0, 548, 549,
+	550, 551, 552, 553, 554, 0, 555, 557, 556, 0,
+	559, 1585, 558, 935, 560, 561, 936, 0, 562, 563,
+	564, 565, 566, 567, 572, 1537, 1536, 568, 569, 570,
+	571, 573, 574, 0, 575, 576, 578, 581, 577, 579,
+	580, 582, 583, 596, 597, 598, 584, 585, 586, 587,
+	588, 589, 590, 591, 592, 593, 594, 595, 600, 0,
+	599, 937, 0, 601, 602, 603, 604, 605, 606, 612,
+	615, 617, 618, 613, 614, 616, 619, 620, 621, 623,
+	624, 609, 610, 611, 938, 622, 607, 1477, 608, 366,
+	939, 625, 626, 627, 628, 1501, 1547, 629, 1563, 632,
+	633, 0, 0, 634, 0, 635, 636, 0, 0, 638,
+	639, 640, 0, 0, 641, 642, 887, 940, 643, 941,
+	1579, 644, 645, 1488, 646, 647, 648, 649, 650, 651,
+	652, 653, 654, 655, 656, 657, 0, 658, 659, 889,
+	660, 661, 662, 663, 664, 890, 665, 666, 667, 1580,
+	668, 892, 669, 670, 671, 0, 672, 673, 674, 0,
+	675, 676, 677, 678, 679, 680, 681, 682, 683, 684,
+	1558, 685, 686, 688, 687, 689, 690, 0, 691, 692,
+	0, 693, 694, 695, 0, 0, 0, 0, 0, 696,
+	697, 699, 0, 700, 701, 702, 703, 704, 705, 698,
+	706, 707, 708, 709, 710, 711, 712, 713, 0, 715,
+	716, 714, 717, 718, 942, 719, 720, 721, 722, 723,
+	1489, 724, 0, 725, 726, 734, 735, 736, 727, 728,
+	730, 737, 729, 738, 739, 740, 741, 743, 742, 0,
+	745, 746, 744, 747, 748, 749, 750, 1540, 751, 895,
+	752, 731, 732, 753, 754, 755, 943, 756, 757, 758,
+	759, 760, 761, 762, 763, 764, 1556, 0, 766, 0,
+	765, 767, 768, 769, 770, 771, 772, 773, 775, 733,
+	776, 777, 778, 783, 784, 785, 1588, 779, 780, 781,
+	782, 787, 1581, 788, 789, 790, 791, 0, 792, 793,
+	1474, 786, 774, 0, 794, 795, 796, 797, 798, 799,
+	800, 801, 802, 803, 0, 804, 1569, 1570, 1571, 1572,
+	0, 817, 0, 805, 807, 808, 809, 810, 1582, 811,
+	812, 1583, 1499, 813, 814, 815, 816, 806, 819, 820,
+	818, 0, 1481, 821, 822, 823, 824, 826, 828, 829,
+	830, 825, 827, 831, 1541, 832, 0, 0, 833, 834,
+	835, 905, 1566, 1587, 0, 1576, 838, 839, 836, 837,
+	840, 841, 844, 842, 843, 909, 847, 542, 848, 849,
+	850, 845, 846, 0, 0, 0, 0, 851, 852, 910,
+	853, 854, 855, 1478, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 1473,
+	0, 0, 0, 0, 0, 0, 1471, 1472, 0, 0,
+	0, 0, 0, 0, 916, 0, 1505, 0, 0, 2248,
+	1503, 1551, 1493, 1494, 1495, 1491, 1492, 1504, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 367, 368,
+	370, 369, 371, 372, 373, 374, 0, 375, 376, 0,
+	0, 0, 0, 0, 1543, 1509, 0, 0, 378, 0,
+	377, 0, 379, 380, 381, 926, 382, 383, 384, 385,
+	386, 387, 388, 389, 390, 857, 391, 1557, 0, 392,
+	1565, 393, 1564, 0, 1575, 394, 395, 396, 397, 398,
+	399, 400, 401, 402, 403, 404, 1511, 1542, 1475, 405,
+	1589, 1590, 864, 0, 406, 407, 408, 409, 1549, 0,
+	1530, 0, 410, 411, 412, 413, 414, 415, 416, 417,
+	0, 0, 419, 420, 421, 418, 422, 423, 0, 424,
+	0, 425, 426, 427, 428, 429, 0, 430, 431, 0,
+	432, 433, 434, 928, 435, 436, 437, 1533, 1531, 1532,
+	1539, 1535, 1534, 1538, 438, 439, 440, 441, 442, 1568,
+	443, 445, 1562, 1561, 1480, 448, 450, 444, 446, 0,
+	449, 447, 451, 452, 0, 453, 454, 455, 456, 457,
+	0, 0, 0, 458, 1560, 460, 461, 0, 462, 463,
+	464, 466, 465, 0, 467, 468, 469, 0, 470, 471,
+	1487, 472, 473, 474, 476, 478, 475, 477, 479, 480,
+	481, 482, 483, 1577, 1578, 484, 485, 1500, 362, 0,
+	0, 0, 0, 0, 486, 487, 488, 1559, 0, 0,
+	0, 489, 0, 491, 495, 496, 492, 493, 494, 497,
+	0, 490, 498, 499, 0, 929, 500, 501, 502, 1573,
+	1574, 503, 504, 505, 506, 507, 508, 509, 510, 511,
+	0, 512, 513, 1584, 0, 1510, 514, 0, 515, 516,
+	517, 518, 519, 520, 521, 1544, 1545, 1548, 630, 931,
+	522, 523, 524, 525, 0, 526, 527, 528, 529, 530,
+	531, 532, 0, 0, 0, 533, 534, 535, 536, 0,
+	919, 363, 365, 930, 879, 537, 631, 538, 539, 1554,
+	1555, 0, 1514, 0, 540, 541, 544, 932, 1546, 933,
+	543, 545, 546, 934, 547, 0, 0, 0, 548, 549,
+	550, 551, 552, 553, 554, 0, 555, 557, 556, 0,
+	559, 1585, 558, 935, 560, 561, 936, 0, 562, 563,
+	564, 565, 566, 567, 572, 1537, 1536, 568, 569, 570,
+	571, 573, 574, 0, 575, 576, 578, 581, 577, 579,
+	580, 582, 583, 596, 597, 598, 584, 585, 586, 587,
+	588, 589, 590, 591, 592, 593, 594, 595, 600, 0,
+	599, 937, 0, 601, 602, 603, 604, 605, 606, 612,
+	615, 617, 618, 613, 614, 616, 619, 620, 621, 623,
+	624, 609, 610, 611, 938, 622, 607, 1477, 608, 366,
+	939, 625, 626, 627, 628, 1501, 1547, 629, 1563, 632,
+	633, 0, 0, 634, 0, 635, 636, 0, 0, 638,
+	639, 640, 0, 0, 641, 642, 887, 940, 643, 941,
+	1579, 644, 645, 1488, 646, 647, 648, 649, 650, 651,
+	652, 653, 654, 655, 656, 657, 0, 658, 659, 889,
+	660, 661, 662, 663, 664, 890, 665, 666, 667, 1580,
+	668, 892, 669, 670, 671, 0, 672, 673, 674, 0,
+	675, 676, 677, 678, 679, 680, 681, 682, 683, 684,
+	1558, 685, 686, 688, 687, 689, 690, 0, 691, 692,
+	0, 693, 694, 695, 0, 0, 0, 0, 0, 696,
+	697, 699, 0, 700, 701, 702, 703, 704, 705, 698,
+	706, 707, 708, 709, 710, 711, 712, 713, 0, 715,
+	716, 714, 717, 718, 942, 719, 720, 721, 722, 723,
+	1489, 724, 0, 725, 726, 734, 735, 736, 727, 728,
+	730, 737, 729, 738, 739, 740, 741, 743, 742, 0,
+	745, 746, 744, 747, 748, 749, 750, 1540, 751, 895,
+	752, 731, 732, 753, 754, 755, 943, 756, 757, 758,
+	759, 760, 761, 762, 763, 764, 1556, 0, 766, 0,
+	765, 767, 768, 769, 770, 771, 772, 773, 775, 733,
+	776, 777, 778, 783, 784, 785, 1588, 779, 780, 781,
+	782, 787, 1581, 788, 789, 790, 791, 0, 792, 793,
+	1474, 786, 774, 0, 794, 795, 796, 797, 798, 799,
+	800, 801, 802, 803, 0, 804, 1569, 1570, 1571, 1572,
+	0, 817, 0, 805, 807, 808, 809, 810, 1582, 811,
+	812, 1583, 1499, 813, 814, 815, 816, 806, 819, 820,
+	818, 0, 1481, 821, 822, 823, 824, 826, 828, 829,
+	830, 825, 827, 831, 1541, 832, 0, 0, 833, 834,
+	835, 905, 1566, 1587, 0, 1576, 838, 839, 836, 837,
+	840, 841, 844, 842, 843, 909, 847, 542, 848, 849,
+	850, 845, 846, 0, 0, 0, 0, 851, 852, 910,
+	853, 854, 855, 1478, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 1473,
+	0, 0, 0, 0, 0, 0, 1471, 1472, 0, 0,
+	0, 0, 0, 0, 916, 0, 1505, 0, 0, 2142,
+	1503, 1551, 1493, 1494, 1495, 1491, 1492, 1504, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 367, 368,
+	370, 369, 371, 372, 373, 374, 0, 375, 376, 0,
+	0, 0, 0, 0, 1543, 1509, 0, 0, 378, 0,
+	377, 0, 379, 380, 381, 926, 382, 383, 384, 385,
+	386, 387, 388, 389, 390, 857, 391, 1557, 0, 392,
+	1565, 393, 1564, 0, 1575, 394, 395, 396, 397, 398,
+	399, 400, 401, 402, 403, 404, 1511, 1542, 1475, 405,
+	1589, 1590, 864, 0, 406, 407, 408, 409, 1549, 0,
+	1530, 0, 410, 411, 412, 413, 414, 415, 416, 417,
+	0, 0, 419, 420, 421, 418, 422, 423, 0, 424,
+	0, 425, 426, 427, 428, 429, 0, 430, 431, 0,
+	432, 433, 434, 928, 435, 436, 437, 1533, 1531, 1532,
+	1539, 1535, 1534, 1538, 438, 439, 440, 441, 442, 1568,
+	443, 445, 1562, 1561, 1480, 448, 450, 444, 446, 0,
+	449, 447, 451, 452, 0, 453, 454, 455, 456, 457,
+	0, 0, 0, 458, 1560, 460, 461, 0, 462, 463,
+	464, 466, 465, 0, 467, 468, 469, 0, 470, 471,
+	1487, 472, 473, 474, 476, 478, 475, 477, 479, 480,
+	481, 482, 483, 1577, 1578, 484, 485, 1500, 362, 0,
+	0, 0, 0, 0, 486, 487, 488, 1559, 0, 0,
+	0, 489, 0, 491, 495, 496, 492, 493, 494, 497,
+	0, 490, 498, 499, 0, 929, 500, 501, 502, 1573,
+	1574, 503, 504, 505, 506, 507, 508, 509, 510, 511,
+	0, 512, 513, 1584, 0, 1510, 514, 0, 515, 516,
+	517, 518, 519, 520, 521, 2141, 1545, 1548, 630, 931,
+	522, 523, 524, 525, 0, 526, 527, 528, 529, 530,
+	531, 532, 0, 0, 0, 533, 534, 535, 536, 0,
+	919, 363, 365, 930, 879, 537, 631, 538, 539, 1554,
+	1555, 0, 1514, 0, 540, 541, 544, 932, 1546, 933,
+	543, 545, 546, 934, 547, 0, 0, 0, 548, 549,
+	550, 551, 552, 553, 554, 0, 555, 557, 556, 0,
+	559, 1585, 558, 935, 560, 561, 936, 0, 562, 563,
+	564, 565, 566, 567, 572, 1537, 1536, 568, 569, 570,
+	571, 573, 574, 0, 575, 576, 578, 581, 577, 579,
+	580, 582, 583, 596, 597, 598, 584, 585, 586, 587,
+	588, 589, 590, 591, 592, 593, 594, 595, 600, 0,
+	599, 937, 0, 601, 602, 603, 604, 605, 606, 612,
+	615, 617, 618, 613, 614, 616, 619, 620, 621, 623,
+	624, 609, 610, 611, 938, 622, 607, 1477, 608, 366,
+	939, 625, 626, 627, 628, 1501, 1547, 629, 1563, 632,
+	633, 0, 0, 634, 0, 635, 636, 0, 0, 638,
+	639, 640, 0, 0, 641, 642, 887, 940, 643, 941,
+	1579, 644, 645, 1488, 646, 647, 648, 649, 650, 651,
+	652, 653, 654, 655, 656, 657, 0, 658, 659, 889,
+	660, 661, 662, 663, 664, 890, 665, 666, 667, 1580,
+	668, 892, 669, 670, 671, 0, 672, 673, 674, 0,
+	675, 676, 677, 678, 679, 680, 681, 682, 683, 684,
+	1558, 685, 686, 688, 687, 689, 690, 0, 691, 692,
+	0, 693, 694, 695, 0, 0, 0, 0, 0, 696,
+	697, 699, 0, 700, 701, 702, 703, 704, 705, 698,
+	706, 707, 708, 709, 710, 711, 712, 713, 0, 715,
+	716, 714, 717, 718, 942, 719, 720, 721, 722, 723,
+	1489, 724, 0, 725, 726, 734, 735, 736, 727, 728,
+	730, 737, 729, 738, 739, 740, 741, 743, 742, 0,
+	745, 746, 744, 747, 748, 749, 750, 1540, 751, 895,
+	752, 731, 732, 753, 754, 755, 943, 756, 757, 758,
+	759, 760, 761, 762, 763, 764, 1556, 0, 766, 0,
+	765, 767, 768, 769, 770, 771, 772, 773, 775, 733,
+	776, 777, 778, 783, 784, 785, 1588, 779, 780, 781,
+	782, 787, 1581, 788, 789, 790, 791, 0, 792, 793,
+	1474, 786, 774, 0, 794, 795, 796, 797, 798, 799,
+	800, 801, 802, 803, 0, 804, 1569, 1570, 1571, 1572,
+	0, 817, 0, 805, 807, 808, 809, 810, 1582, 811,
+	812, 1583, 1499, 813, 814, 815, 816, 806, 819, 820,
+	818, 0, 1481, 821, 822, 823, 824, 826, 828, 829,
+	830, 825, 827, 831, 1541, 832, 0, 0, 833, 834,
+	835, 905, 1566, 1587, 0, 1576, 838, 839, 836, 837,
+	840, 841, 844, 842, 843, 909, 847, 542, 848, 849,
+	850, 845, 846, 0, 0, 0, 0, 851, 852, 910,
+	853, 854, 855, 1478, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 1473,
+	0, 0, 0, 0, 0, 0, 1471, 1472, 0, 0,
+	0, 0, 0, 0, 916, 0, 1505, 0, 0, 2136,
+	1503, 1551, 1493, 1494, 1495, 1491, 1492, 1504, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 367, 368,
+	370, 369, 371, 372, 373, 374, 0, 375, 376, 0,
+	0, 0, 0, 0, 1543, 1509, 0, 0, 378, 0,
+	377, 0, 379, 380, 381, 926, 382, 383, 384, 385,
+	386, 387, 388, 389, 390, 857, 391, 1557, 0, 392,
+	1565, 393, 1564, 0, 1575, 394, 395, 396, 397, 398,
+	399, 400, 401, 402, 403, 404, 1511, 1542, 1475, 405,
+	1589, 1590, 864, 0, 406, 407, 408, 409, 1549, 0,
+	1530, 0, 410, 411, 412, 413, 414, 415, 416, 417,
+	0, 0, 419, 420, 421, 418, 422, 423, 0, 424,
+	0, 425, 426, 427, 428, 429, 0, 430, 431, 0,
+	432, 433, 434, 928, 435, 436, 437, 1533, 1531, 1532,
+	1539, 1535, 1534, 1538, 438, 439, 440, 441, 442, 1568,
+	443, 445, 1562, 1561, 1480, 448, 450, 444, 446, 0,
+	449, 447, 451, 452, 0, 453, 454, 455, 456, 457,
+	0, 0, 0, 458, 1560, 460, 461, 0, 462, 463,
+	464, 466, 465, 0, 467, 468, 469, 0, 470, 471,
+	1487, 472, 473, 474, 476, 478, 475, 477, 479, 480,
+	481, 482, 483, 1577, 1578, 484, 485, 1500, 362, 0,
+	0, 0, 0, 0, 486, 487, 488, 1559, 0, 0,
+	0, 489, 0, 491, 495, 496, 492, 493, 494, 497,
+	0, 490, 498, 499, 0, 929, 500, 501, 502, 1573,
+	1574, 503, 504, 505, 506, 507, 508, 509, 510, 511,
+	0, 512, 513, 1584, 0, 1510, 514, 0, 515, 516,
+	517, 518, 519, 520, 521, 2135, 1545, 1548, 630, 931,
+	522, 523, 524, 525, 0, 526, 527, 528, 529, 530,
+	531, 532, 0, 0, 0, 533, 534, 535, 536, 0,
+	919, 363, 365, 930, 879, 537, 631, 538, 539, 1554,
+	1555, 0, 1514, 0, 540, 541, 544, 932, 1546, 933,
+	543, 545, 546, 934, 547, 0, 0, 0, 548, 549,
+	550, 551, 552, 553, 554, 0, 555, 557, 556, 0,
+	559, 1585, 558, 935, 560, 561, 936, 0, 562, 563,
+	564, 565, 566, 567, 572, 1537, 1536, 568, 569, 570,
+	571, 573, 574, 0, 575, 576, 578, 581, 577, 579,
+	580, 582, 583, 596, 597, 598, 584, 585, 586, 587,
+	588, 589, 590, 591, 592, 593, 594, 595, 600, 0,
+	599, 937, 0, 601, 602, 603, 604, 605, 606, 612,
+	615, 617, 618, 613, 614, 616, 619, 620, 621, 623,
+	624, 609, 610, 611, 938, 622, 607, 1477, 608, 366,
+	939, 625, 626, 627, 628, 1501, 1547, 629, 1563, 632,
+	633, 0, 0, 634, 0, 635, 636, 0, 0, 638,
+	639, 640, 0, 0, 641, 642, 887, 940, 643, 941,
+	1579, 644, 645, 1488, 646, 647, 648, 649, 650, 651,
+	652, 653, 654, 655, 656, 657, 0, 658, 659, 889,
+	660, 661, 662, 663, 664, 890, 665, 666, 667, 1580,
+	668, 892, 669, 670, 671, 0, 672, 673, 674, 0,
+	675, 676, 677, 678, 679, 680, 681, 682, 683, 684,
+	1558, 685, 686, 688, 687, 689, 690, 0, 691, 692,
+	0, 693, 694, 695, 0, 0, 0, 0, 0, 696,
+	697, 699, 0, 700, 701, 702, 703, 704, 705, 698,
+	706, 707, 708, 709, 710, 711, 712, 713, 0, 715,
+	716, 714, 717, 718, 942, 719, 720, 721, 722, 723,
+	1489, 724, 0, 725, 726, 734, 735, 736, 727, 728,
+	730, 737, 729, 738, 739, 740, 741, 743, 742, 0,
+	745, 746, 744, 747, 748, 749, 750, 1540, 751, 895,
+	752, 731, 732, 753, 754, 755, 943, 756, 757, 758,
+	759, 760, 761, 762, 763, 764, 1556, 0, 766, 0,
+	765, 767, 768, 769, 770, 771, 772, 773, 775, 733,
+	776, 777, 778, 783, 784, 785, 1588, 779, 780, 781,
+	782, 787, 1581, 788, 789, 790, 791, 0, 792, 793,
+	1474, 786, 774, 0, 794, 795, 796, 797, 798, 799,
+	800, 801, 802, 803, 0, 804, 1569, 1570, 1571, 1572,
+	0, 817, 0, 805, 807, 808, 809, 810, 1582, 811,
+	812, 1583, 1499, 813, 814, 815, 816, 806, 819, 820,
+	818, 0, 1481, 821, 822, 823, 824, 826, 828, 829,
+	830, 825, 827, 831, 1541, 832, 0, 0, 833, 834,
+	835, 905, 1566, 1587, 0, 1576, 838, 839, 836, 837,
+	840, 841, 844, 842, 843, 909, 847, 542, 848, 849,
+	850, 845, 846, 0, 0, 0, 0, 851, 852, 910,
+	853, 854, 855, 1478, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 1473,
+	0, 0, 0, 0, 0, 0, 1471, 1472, 0, 0,
+	0, 0, 0, 0, 916, 0, 1505, 0, 0, 2130,
+	1503, 1551, 1493, 1494, 1495, 1491, 1492, 1504, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 367, 368,
+	370, 369, 371, 372, 373, 374, 0, 375, 376, 0,
+	0, 0, 0, 0, 1543, 1509, 0, 0, 378, 0,
+	377, 0, 379, 380, 381, 926, 382, 383, 384, 385,
+	386, 387, 388, 389, 390, 857, 391, 1557, 0, 392,
+	1565, 393, 1564, 0, 1575, 394, 395, 396, 397, 398,
+	399, 400, 401, 402, 403, 404, 1511, 1542, 1475, 405,
+	1589, 1590, 864, 0, 406, 407, 408, 409, 1549, 0,
+	1530, 0, 410, 411, 412, 413, 414, 415, 416, 417,
+	0, 0, 419, 420, 421, 418, 422, 423, 0, 424,
+	0, 425, 426, 427, 428, 429, 0, 430, 431, 0,
+	432, 433, 434, 928, 435, 436, 437, 1533, 1531, 1532,
+	1539, 1535, 1534, 1538, 438, 439, 440, 441, 442, 1568,
+	443, 445, 1562, 1561, 1480, 448, 450, 444, 446, 0,
+	449, 447, 451, 452, 0, 453, 454, 455, 456, 457,
+	0, 0, 0, 458, 1560, 460, 461, 0, 462, 463,
+	464, 466, 465, 0, 467, 468, 469, 0, 470, 471,
+	1487, 472, 473, 474, 476, 478, 475, 477, 479, 480,
+	481, 482, 483, 1577, 1578, 484, 485, 1500, 362, 0,
+	0, 0, 0, 0, 486, 487, 488, 1559, 0, 0,
+	0, 489, 0, 491, 495, 496, 492, 493, 494, 497,
+	0, 490, 498, 499, 0, 929, 500, 501, 502, 1573,
+	1574, 503, 504, 505, 506, 507, 508, 509, 510, 511,
+	0, 512, 513, 1584, 0, 1510, 514, 0, 515, 516,
+	517, 518, 519, 520, 521, 1544, 1545, 1548, 630, 931,
+	522, 523, 524, 525, 0, 526, 527, 528, 529, 530,
+	531, 532, 0, 0, 0, 533, 534, 535, 536, 0,
+	919, 363, 365, 930, 879, 537, 631, 538, 539, 1554,
+	1555, 0, 1514, 0, 540, 541, 544, 932, 1546, 933,
+	543, 545, 546, 934, 547, 0, 0, 0, 548, 549,
+	550, 551, 552, 553, 554, 0, 555, 557, 556, 0,
+	559, 1585, 558, 935, 560, 561, 936, 0, 562, 563,
+	564, 565, 566, 567, 572, 1537, 1536, 568, 569, 570,
+	571, 573, 574, 0, 575, 576, 578, 581, 577, 579,
+	580, 582, 583, 596, 597, 598, 584, 585, 586, 587,
+	588, 589, 590, 591, 592, 593, 594, 595, 600, 0,
+	599, 937, 0, 601, 602, 603, 604, 605, 606, 612,
+	615, 617, 618, 613, 614, 616, 619, 620, 621, 623,
+	624, 609, 610, 611, 938, 622, 607, 1477, 608, 366,
+	939, 625, 626, 627, 628, 1501, 1547, 629, 1563, 632,
+	633, 0, 0, 634, 0, 635, 636, 0, 0, 638,
+	639, 640, 0, 0, 641, 642, 887, 940, 643, 941,
+	1579, 644, 645, 1488, 646, 647, 648, 649, 650, 651,
+	652, 653, 654, 655, 656, 657, 0, 658, 659, 889,
+	660, 661, 662, 663, 664, 890, 665, 666, 667, 1580,
+	668, 892, 669, 670, 671, 0, 672, 673, 674, 0,
+	675, 676, 677, 678, 679, 680, 681, 682, 683, 684,
+	1558, 685, 686, 688, 687, 689, 690, 0, 691, 692,
+	0, 693, 694, 695, 0, 0, 0, 0, 0, 696,
+	697, 699, 0, 700, 701, 702, 703, 704, 705, 698,
+	706, 707, 708, 709, 710, 711, 712, 713, 0, 715,
+	716, 714, 717, 718, 942, 719, 720, 721, 722, 723,
+	1489, 724, 0, 725, 726, 734, 735, 736, 727, 728,
+	730, 737, 729, 738, 739, 740, 741, 743, 742, 0,
+	745, 746, 744, 747, 748, 749, 750, 1540, 751, 895,
+	752, 731, 732, 753, 754, 755, 943, 756, 757, 758,
+	759, 760, 761, 762, 763, 764, 1556, 0, 766, 0,
+	765, 767, 768, 769, 770, 771, 772, 773, 775, 733,
+	776, 777, 778, 783, 784, 785, 1588, 779, 780, 781,
+	782, 787, 1581, 788, 789, 790, 791, 0, 792, 793,
+	1474, 786, 774, 0, 794, 795, 796, 797, 798, 799,
+	800, 801, 802, 803, 0, 804, 1569, 1570, 1571, 1572,
+	0, 817, 0, 805, 807, 808, 809, 810, 1582, 811,
+	812, 1583, 1499, 813, 814, 815, 816, 806, 819, 820,
+	818, 0, 1481, 821, 822, 823, 824, 826, 828, 829,
+	830, 825, 827, 831, 1541, 832, 0, 0, 833, 834,
+	835, 905, 1566, 1587, 0, 1576, 838, 839, 836, 837,
+	840, 841, 844, 842, 843, 909, 847, 542, 848, 849,
+	850, 845, 846, 0, 0, 0, 0, 851, 852, 910,
+	853, 854, 855, 1478, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 1473,
+	0, 0, 0, 0, 0, 0, 1471, 1472, 0, 0,
+	0, 0, 0, 0, 916, 0, 1505, 0, 0, 2103,
+	1503, 1551, 1493, 1494, 1495, 1491, 1492, 1504, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 367, 368,
+	370, 369, 371, 372, 373, 374, 0, 375, 376, 0,
+	0, 0, 0, 0, 1543, 1509, 0, 0, 378, 0,
+	377, 0, 379, 380, 381, 926, 382, 383, 384, 385,
+	386, 387, 388, 389, 390, 857, 391, 1557, 0, 392,
+	1565, 393, 1564, 0, 1575, 394, 395, 396, 397, 398,
+	399, 400, 401, 402, 403, 404, 1511, 1542, 1475, 405,
+	1589, 1590, 864, 0, 406, 407, 408, 409, 1549, 0,
+	1530, 0, 410, 411, 412, 413, 414, 415, 416, 417,
+	0, 0, 419, 420, 421, 418, 422, 423, 0, 424,
+	0, 425, 426, 427, 428, 429, 0, 430, 431, 0,
+	432, 433, 434, 928, 435, 436, 437, 1533, 1531, 1532,
+	1539, 1535, 1534, 1538, 438, 439, 440, 441, 442, 1568,
+	443, 445, 1562, 1561, 1480, 448, 450, 444, 446, 0,
+	449, 447, 451, 452, 0, 453, 454, 455, 456, 457,
+	0, 0, 0, 458, 1560, 460, 461, 0, 462, 463,
+	464, 466, 465, 0, 467, 468, 469, 0, 470, 471,
+	1487, 472, 473, 474, 476, 478, 475, 477, 479, 480,
+	481, 482, 483, 1577, 1578, 484, 485, 1500, 362, 0,
+	0, 0, 0, 0, 486, 487, 488, 1559, 0, 0,
+	0, 489, 0, 491, 495, 496, 492, 493, 494, 497,
+	0, 490, 498, 499, 0, 929, 500, 501, 502, 1573,
+	1574, 503, 504, 505, 506, 507, 508, 509, 510, 511,
+	0, 512, 513, 1584, 0, 1510, 514, 0, 515, 516,
+	517, 518, 519, 520, 521, 1544, 1545, 1548, 630, 931,
+	522, 523, 524, 525, 0, 526, 527, 528, 529, 530,
+	531, 532, 0, 0, 0, 533, 534, 535, 536, 0,
+	919, 363, 365, 930, 879, 537, 631, 538, 539, 1554,
+	1555, 0, 1514, 0, 540, 541, 544, 932, 1546, 933,
+	543, 545, 546, 934, 547, 0, 0, 0, 548, 549,
+	550, 551, 552, 553, 554, 0, 555, 557, 556, 0,
+	559, 1585, 558, 935, 560, 561, 936, 0, 562, 563,
+	564, 565, 566, 567, 572, 1537, 1536, 568, 569, 570,
+	571, 573, 574, 0, 575, 576, 578, 581, 577, 579,
+	580, 582, 583, 596, 597, 598, 584, 585, 586, 587,
+	588, 589, 590, 591, 592, 593, 594, 595, 600, 0,
+	599, 937, 0, 601, 602, 603, 604, 605, 606, 612,
+	615, 617, 618, 613, 614, 616, 619, 620, 621, 623,
+	624, 609, 610, 611, 938, 622, 607, 1477, 608, 366,
+	939, 625, 626, 627, 628, 1501, 1547, 629, 1563, 632,
+	633, 0, 0, 634, 0, 635, 636, 0, 0, 638,
+	639, 640, 0, 0, 641, 642, 887, 940, 643, 941,
+	1579, 644, 645, 1488, 646, 647, 648, 649, 650, 651,
+	652, 653, 654, 655, 656, 657, 0, 658, 659, 889,
+	660, 661, 662, 663, 664, 890, 665, 666, 667, 1580,
+	668, 892, 669, 670, 671, 0, 672, 673, 674, 0,
+	675, 676, 677, 678, 679, 680, 681, 682, 683, 684,
+	1558, 685, 686, 688, 687, 689, 690, 0, 691, 692,
+	0, 693, 694, 695, 0, 0, 0, 0, 0, 696,
+	697, 699, 0, 700, 701, 702, 703, 704, 705, 698,
+	706, 707, 708, 709, 710, 711, 712, 713, 0, 715,
+	716, 714, 717, 718, 942, 719, 720, 721, 722, 723,
+	1489, 724, 0, 725, 726, 734, 735, 736, 727, 728,
+	730, 737, 729, 738, 739, 740, 741, 743, 742, 0,
+	745, 746, 744, 747, 748, 749, 750, 1540, 751, 895,
+	752, 731, 732, 753, 754, 755, 943, 756, 757, 758,
+	759, 760, 761, 762, 763, 764, 1556, 0, 766, 0,
+	765, 767, 768, 769, 770, 771, 772, 773, 775, 733,
+	776, 777, 778, 783, 784, 785, 1588, 779, 780, 781,
+	782, 787, 1581, 788, 789, 790, 791, 0, 792, 793,
+	1474, 786, 774, 0, 794, 795, 796, 797, 798, 799,
+	800, 801, 802, 803, 0, 804, 1569, 1570, 1571, 1572,
+	0, 817, 0, 805, 807, 808, 809, 810, 1582, 811,
+	812, 1583, 1499, 813, 814, 815, 816, 806, 819, 820,
+	818, 0, 1481, 821, 822, 823, 824, 826, 828, 829,
+	830, 825, 827, 831, 1541, 832, 0, 0, 833, 834,
+	835, 905, 1566, 1587, 0, 1576, 838, 839, 836, 837,
+	840, 841, 844, 842, 843, 909, 847, 542, 848, 849,
+	850, 845, 846, 0, 0, 0, 0, 851, 852, 910,
+	853, 854, 855, 1478, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 1473,
+	0, 0, 0, 0, 0, 0, 1471, 1472, 0, 0,
+	0, 0, 0, 0, 916, 0, 1505, 0, 0, 2101,
+	1503, 1551, 1493, 1494, 1495, 1491, 1492, 1504, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 367, 368,
+	370, 369, 371, 372, 373, 374, 0, 375, 376, 0,
+	0, 0, 0, 0, 1543, 1509, 0, 0, 378, 0,
+	377, 0, 379, 380, 381, 926, 382, 383, 384, 385,
+	386, 387, 388, 389, 390, 857, 391, 1557, 0, 392,
+	1565, 393, 1564, 0, 1575, 394, 395, 396, 397, 398,
+	399, 400, 401, 402, 403, 404, 1511, 1542, 1475, 405,
+	1589, 1590, 864, 0, 406, 407, 408, 409, 1549, 0,
+	1530, 0, 410, 411, 412, 413, 414, 415, 416, 417,
+	0, 0, 419, 420, 421, 418, 422, 423, 0, 424,
+	0, 425, 426, 427, 428, 429, 0, 430, 431, 0,
+	432, 433, 434, 928, 435, 436, 437, 1533, 1531, 1532,
+	1539, 1535, 1534, 1538, 438, 439, 440, 441, 442, 1568,
+	443, 445, 1562, 1561, 1480, 448, 450, 444, 446, 0,
+	449, 447, 451, 452, 0, 453, 454, 455, 456, 457,
+	0, 0, 0, 458, 1560, 460, 461, 0, 462, 463,
+	464, 466, 465, 0, 467, 468, 469, 0, 470, 471,
+	1487, 472, 473, 474, 476, 478, 475, 477, 479, 480,
+	481, 482, 483, 1577, 1578, 484, 485, 1500, 362, 0,
+	0, 0, 0, 0, 486, 487, 488, 1559, 0, 0,
+	0, 489, 0, 491, 495, 496, 492, 493, 494, 497,
+	0, 490, 498, 499, 0, 929, 500, 501, 502, 1573,
+	1574, 503, 504, 505, 506, 507, 508, 509, 510, 511,
+	0, 512, 513, 1584, 0, 1510, 514, 0, 515, 516,
+	517, 518, 519, 520, 521, 1544, 1545, 1548, 630, 931,
+	522, 523, 524, 525, 0, 526, 527, 528, 529, 530,
+	531, 532, 0, 0, 0, 533, 534, 535, 536, 0,
+	919, 363, 365, 930, 879, 537, 631, 538, 539, 1554,
+	1555, 0, 1514, 0, 540, 541, 544, 932, 1546, 933,
+	543, 545, 546, 934, 547, 0, 0, 0, 548, 549,
+	550, 551, 552, 553, 554, 0, 555, 557, 556, 0,
+	559, 1585, 558, 935, 560, 561, 936, 0, 562, 563,
+	564, 565, 566, 567, 572, 1537, 1536, 568, 569, 570,
+	571, 573, 574, 0, 575, 576, 578, 581, 577, 579,
+	580, 582, 583, 596, 597, 598, 584, 585, 586, 587,
+	588, 589, 590, 591, 592, 593, 594, 595, 600, 0,
+	599, 937, 0, 601, 602, 603, 604, 605, 606, 612,
+	615, 617, 618, 613, 614, 616, 619, 620, 621, 623,
+	624, 609, 610, 611, 938, 622, 607, 1477, 608, 366,
+	939, 625, 626, 627, 628, 1501, 1547, 629, 1563, 632,
+	633, 0, 0, 634, 0, 635, 636, 0, 0, 638,
+	639, 640, 0, 0, 641, 642, 887, 940, 643, 941,
+	1579, 644, 645, 1488, 646, 647, 648, 649, 650, 651,
+	652, 653, 654, 655, 656, 657, 0, 658, 659, 889,
+	660, 661, 662, 663, 664, 890, 665, 666, 667, 1580,
+	668, 892, 669, 670, 671, 0, 672, 673, 674, 0,
+	675, 676, 677, 678, 679, 680, 681, 682, 683, 684,
+	1558, 685, 686, 688, 687, 689, 690, 0, 691, 692,
+	0, 693, 694, 695, 0, 0, 0, 0, 0, 696,
+	697, 699, 0, 700, 701, 702, 703, 704, 705, 698,
+	706, 707, 708, 709, 710, 711, 712, 713, 0, 715,
+	716, 714, 717, 718, 942, 719, 720, 721, 722, 723,
+	1489, 724, 0, 725, 726, 734, 735, 736, 727, 728,
+	730, 737, 729, 738, 739, 740, 741, 743, 742, 0,
+	745, 746, 744, 747, 748, 749, 750, 1540, 751, 895,
+	752, 731, 732, 753, 754, 755, 943, 756, 757, 758,
+	759, 760, 761, 762, 763, 764, 1556, 0, 766, 0,
+	765, 767, 768, 769, 770, 771, 772, 773, 775, 733,
+	776, 777, 778, 783, 784, 785, 1588, 779, 780, 781,
+	782, 787, 1581, 788, 789, 790, 791, 0, 792, 793,
+	1474, 786, 774, 0, 794, 795, 796, 797, 798, 799,
+	800, 801, 802, 803, 0, 804, 1569, 1570, 1571, 1572,
+	0, 817, 0, 805, 807, 808, 809, 810, 1582, 811,
+	812, 1583, 1499, 813, 814, 815, 816, 806, 819, 820,
+	818, 0, 1481, 821, 822, 823, 824, 826, 828, 829,
+	830, 825, 827, 831, 1541, 832, 0, 0, 833, 834,
+	835, 905, 1566, 1587, 0, 1576, 838, 839, 836, 837,
+	840, 841, 844, 842, 843, 909, 847, 542, 848, 849,
+	850, 845, 846, 0, 0, 0, 0, 851, 852, 910,
+	853, 854, 855, 1478, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 1473,
+	0, 0, 0, 0, 0, 0, 1471, 1472, 0, 0,
+	0, 0, 0, 0, 916, 0, 1505, 0, 0, 2079,
+	1503, 1551, 1493, 1494, 1495, 1491, 1492, 1504, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 367, 368,
+	370, 369, 371, 372, 373, 374, 0, 375, 376, 0,
+	0, 0, 0, 0, 1543, 1509, 0, 0, 378, 0,
+	377, 0, 379, 380, 381, 926, 382, 383, 384, 385,
+	386, 387, 388, 389, 390, 857, 391, 1557, 0, 392,
+	1565, 393, 1564, 0, 1575, 394, 395, 396, 397, 398,
+	399, 400, 401, 402, 403, 404, 1511, 1542, 1475, 405,
+	1589, 1590, 864, 0, 406, 407, 408, 409, 1549, 0,
+	1530, 0, 410, 411, 412, 413, 414, 415, 416, 417,
+	0, 0, 419, 420, 421, 418, 422, 423, 0, 424,
+	0, 425, 426, 427, 428, 429, 0, 430, 431, 0,
+	432, 433, 434, 928, 435, 436, 437, 1533, 1531, 1532,
+	1539, 1535, 1534, 1538, 438, 439, 440, 441, 442, 1568,
+	443, 445, 1562, 1561, 1480, 448, 450, 444, 446, 0,
+	449, 447, 451, 452, 0, 453, 454, 455, 456, 457,
+	0, 0, 0, 458, 1560, 460, 461, 0, 462, 463,
+	464, 466, 465, 0, 467, 468, 469, 0, 470, 471,
+	1487, 472, 473, 474, 476, 478, 475, 2083, 479, 480,
+	481, 482, 483, 1577, 1578, 484, 485, 1500, 362, 0,
+	0, 0, 0, 0, 486, 487, 488, 1559, 0, 0,
+	0, 489, 0, 491, 495, 496, 492, 493, 494, 497,
+	0, 490, 498, 499, 0, 929, 500, 501, 502, 1573,
+	1574, 503, 504, 505, 506, 507, 508, 509, 510, 511,
+	0, 512, 513, 1584, 0, 1510, 514, 0, 515, 516,
+	517, 518, 519, 520, 521, 1544, 1545, 1548, 630, 931,
+	522, 523, 524, 525, 0, 526, 527, 528, 529, 530,
+	531, 532, 0, 0, 0, 533, 534, 535, 536, 0,
+	919, 363, 365, 930, 879, 537, 631, 538, 539, 1554,
+	1555, 0, 1514, 0, 540, 541, 544, 932, 1546, 933,
+	543, 545, 546, 934, 547, 0, 0, 0, 548, 549,
+	550, 551, 552, 553, 554, 0, 555, 557, 556, 0,
+	559, 1585, 558, 935, 560, 561, 936, 0, 562, 563,
+	564, 565, 566, 567, 572, 1537, 1536, 568, 569, 570,
+	571, 573, 574, 0, 575, 576, 578, 581, 577, 579,
+	580, 582, 583, 596, 597, 598, 584, 585, 586, 587,
+	588, 589, 590, 591, 592, 593, 594, 595, 600, 0,
+	599, 937, 0, 601, 602, 603, 604, 605, 606, 612,
+	615, 617, 618, 613, 614, 616, 619, 620, 621, 623,
+	624, 609, 610, 611, 938, 622, 607, 1477, 608, 366,
+	939, 625, 626, 627, 628, 1501, 1547, 629, 1563, 632,
+	633, 0, 0, 634, 0, 635, 636, 0, 0, 638,
+	639, 640, 0, 0, 641, 642, 887, 940, 643, 941,
+	1579, 644, 645, 1488, 646, 647, 648, 649, 650, 651,
+	652, 653, 654, 655, 656, 657, 0, 658, 659, 889,
+	660, 661, 662, 663, 664, 890, 665, 666, 667, 1580,
+	668, 892, 669, 670, 671, 0, 672, 673, 674, 0,
+	675, 676, 677, 678, 679, 680, 681, 682, 683, 684,
+	1558, 685, 686, 688, 687, 689, 690, 0, 691, 692,
+	0, 693, 694, 695, 0, 0, 0, 0, 0, 696,
+	697, 2084, 0, 700, 701, 702, 703, 704, 705, 698,
+	706, 707, 708, 709, 710, 711, 712, 713, 0, 715,
+	716, 714, 717, 718, 942, 719, 720, 721, 722, 723,
+	1489, 724, 0, 725, 726, 734, 735, 736, 727, 728,
+	730, 737, 729, 738, 739, 740, 741, 743, 742, 0,
+	745, 746, 744, 747, 748, 749, 750, 1540, 751, 895,
+	752, 731, 732, 753, 754, 755, 943, 756, 757, 758,
+	759, 760, 761, 762, 763, 764, 1556, 0, 766, 0,
+	765, 767, 768, 769, 770, 771, 772, 773, 775, 733,
+	776, 777, 778, 783, 784, 785, 1588, 779, 780, 781,
+	782, 787, 1581, 788, 789, 790, 791, 0, 792, 793,
+	1474, 786, 774, 0, 794, 795, 796, 797, 798, 799,
+	800, 801, 2082, 803, 0, 804, 1569, 1570, 1571, 1572,
+	0, 817, 0, 805, 807, 808, 809, 810, 1582, 811,
+	812, 1583, 1499, 813, 814, 815, 816, 806, 819, 820,
+	818, 0, 1481, 821, 822, 823, 824, 826, 828, 829,
+	830, 825, 827, 831, 1541, 832, 0, 0, 833, 834,
+	835, 905, 1566, 1587, 0, 1576, 838, 839, 836, 837,
+	840, 841, 844, 842, 843, 909, 847, 542, 848, 849,
+	850, 845, 846, 0, 0, 0, 0, 851, 852, 910,
+	853, 854, 855, 1478, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 1473,
+	0, 0, 0, 0, 0, 0, 1471, 1472, 0, 0,
+	0, 0, 0, 0, 916, 0, 1505, 0, 0, 1901,
+	1503, 1551, 1493, 1494, 1495, 1491, 1492, 1504, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 367, 368,
+	370, 369, 371, 372, 373, 374, 0, 375, 376, 0,
+	0, 0, 0, 0, 1543, 1509, 0, 0, 378, 0,
+	377, 0, 379, 380, 381, 926, 382, 383, 384, 385,
+	386, 387, 388, 389, 390, 857, 391, 1557, 0, 392,
+	1565, 393, 1564, 0, 1575, 394, 395, 396, 397, 398,
+	399, 400, 401, 402, 403, 404, 1511, 1542, 1475, 405,
+	1589, 1590, 864, 0, 406, 407, 408, 409, 1549, 0,
+	1530, 0, 410, 411, 412, 413, 414, 415, 416, 417,
+	0, 0, 419, 420, 421, 418, 422, 423, 0, 424,
+	0, 425, 426, 427, 428, 429, 0, 430, 431, 0,
+	432, 433, 434, 928, 435, 436, 437, 1533, 1531, 1532,
+	1539, 1535, 1534, 1538, 438, 439, 440, 441, 442, 1568,
+	443, 445, 1562, 1561, 1480, 448, 450, 444, 446, 0,
+	449, 447, 451, 452, 0, 453, 454, 455, 456, 457,
+	0, 0, 0, 458, 1560, 460, 461, 0, 462, 463,
+	464, 466, 465, 0, 467, 468, 469, 0, 470, 471,
+	1487, 472, 473, 474, 476, 478, 475, 477, 479, 480,
+	481, 482, 483, 1577, 1578, 484, 485, 1500, 362, 0,
+	0, 0, 0, 0, 486, 487, 488, 1559, 0, 0,
+	0, 489, 0, 491, 495, 496, 492, 493, 494, 497,
+	0, 490, 498, 499, 0, 929, 500, 501, 502, 1573,
+	1574, 503, 504, 505, 506, 507, 508, 509, 510, 511,
+	0, 512, 513, 1584, 0, 1510, 514, 0, 515, 516,
+	517, 518, 519, 520, 521, 1544, 1545, 1548, 630, 931,
+	522, 523, 524, 525, 0, 526, 527, 528, 529, 530,
+	531, 532, 0, 0, 0, 533, 534, 535, 536, 0,
+	919, 363, 365, 930, 879, 537, 631, 538, 539, 1554,
+	1555, 0, 1514, 0, 540, 541, 544, 932, 1546, 933,
+	543, 545, 546, 934, 547, 0, 0, 0, 548, 549,
+	550, 551, 552, 553, 554, 0, 555, 557, 556, 0,
+	559, 1585, 558, 935, 560, 561, 936, 0, 562, 563,
+	564, 565, 566, 567, 572, 1537, 1536, 568, 569, 570,
+	571, 573, 574, 0, 575, 576, 578, 581, 577, 579,
+	580, 582, 583, 596, 597, 598, 584, 585, 586, 587,
+	588, 589, 590, 591, 592, 593, 594, 595, 600, 0,
+	599, 937, 0, 601, 602, 603, 604, 605, 606, 612,
+	615, 617, 618, 613, 614, 616, 619, 620, 621, 623,
+	624, 609, 610, 611, 938, 622, 607, 1477, 608, 366,
+	939, 625, 626, 627, 628, 1501, 1547, 629, 1563, 632,
+	633, 0, 0, 634, 0, 635, 636, 0, 0, 638,
+	639, 640, 0, 0, 641, 642, 887, 940, 643, 941,
+	1579, 644, 645, 1488, 646, 647, 648, 649, 650, 651,
+	652, 653, 654, 655, 656, 657, 0, 658, 659, 889,
+	660, 661, 662, 663, 664, 890, 665, 666, 667, 1580,
+	668, 892, 669, 670, 671, 0, 672, 673, 674, 0,
+	675, 676, 677, 678, 679, 680, 681, 682, 683, 684,
+	1558, 685, 686, 688, 687, 689, 690, 0, 691, 692,
+	0, 693, 694, 695, 0, 0, 0, 0, 0, 696,
+	697, 699, 0, 700, 701, 702, 703, 704, 705, 698,
+	706, 707, 708, 709, 710, 711, 712, 713, 0, 715,
+	716, 714, 717, 718, 942, 719, 720, 721, 722, 723,
+	1489, 724, 0, 725, 726, 734, 735, 736, 727, 728,
+	730, 737, 729, 738, 739, 740, 741, 743, 742, 0,
+	745, 746, 744, 747, 748, 749, 750, 1540, 751, 895,
+	752, 731, 732, 753, 754, 755, 943, 756, 757, 758,
+	759, 760, 761, 762, 763, 764, 1556, 0, 766, 0,
+	765, 767, 768, 769, 770, 771, 772, 773, 775, 733,
+	776, 777, 778, 783, 784, 785, 1588, 779, 780, 781,
+	782, 787, 1581, 788, 789, 790, 791, 0, 792, 793,
+	1474, 786, 774, 0, 794, 795, 796, 797, 798, 799,
+	800, 801, 802, 803, 0, 804, 1569, 1570, 1571, 1572,
+	0, 817, 0, 805, 807, 808, 809, 810, 1582, 811,
+	812, 1583, 1499, 813, 814, 815, 816, 806, 819, 820,
+	818, 0, 1481, 821, 822, 823, 824, 826, 828, 829,
+	830, 825, 827, 831, 1541, 832, 0, 0, 833, 834,
+	835, 905, 1566, 1587, 0, 1576, 838, 839, 836, 837,
+	840, 841, 844, 842, 843, 909, 847, 542, 848, 849,
+	850, 845, 846, 0, 0, 0, 0, 851, 852, 910,
+	853, 854, 855, 1478, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 1473,
+	0, 0, 0, 0, 0, 0, 1471, 1472, 0, 0,
+	0, 0, 0, 0, 916, 0, 1505, 0, 0, 1752,
+	1503, 1551, 1493, 1494, 1495, 1491, 1492, 1504, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 367, 368,
+	370, 369, 371, 372, 373, 374, 0, 375, 376, 0,
+	0, 0, 0, 0, 1543, 1509, 0, 0, 378, 0,
+	377, 0, 379, 380, 381, 926, 382, 383, 384, 385,
+	386, 387, 388, 389, 390, 857, 391, 1557, 0, 392,
+	1565, 393, 1564, 0, 1575, 394, 395, 396, 397, 398,
+	399, 400, 401, 402, 403, 404, 1511, 1542, 1475, 405,
+	1589, 1590, 864, 0, 406, 407, 408, 409, 1549, 0,
+	1530, 0, 410, 411, 412, 413, 414, 415, 416, 417,
+	0, 0, 419, 420, 421, 418, 422, 423, 0, 424,
+	0, 425, 426, 427, 428, 429, 0, 430, 431, 0,
+	432, 433, 434, 928, 435, 436, 437, 1533, 1531, 1532,
+	1539, 1535, 1534, 1538, 438, 439, 440, 441, 442, 1568,
+	443, 445, 1562, 1561, 1480, 448, 450, 444, 446, 0,
+	449, 447, 451, 452, 0, 453, 454, 455, 456, 457,
+	0, 0, 0, 458, 1560, 460, 461, 0, 462, 463,
+	464, 466, 465, 0, 467, 468, 469, 0, 470, 471,
+	1487, 472, 473, 474, 476, 478, 475, 477, 479, 480,
+	481, 482, 483, 1577, 1578, 484, 485, 1500, 362, 0,
+	0, 0, 0, 0, 486, 487, 488, 1559, 0, 0,
+	0, 489, 0, 491, 495, 496, 492, 493, 494, 497,
+	0, 490, 498, 499, 0, 929, 500, 501, 502, 1573,
+	1574, 503, 504, 505, 506, 507, 508, 509, 510, 511,
+	0, 512, 513, 1584, 0, 1510, 514, 0, 515, 516,
+	517, 518, 519, 520, 521, 1544, 1545, 1548, 630, 931,
+	522, 523, 524, 525, 0, 526, 527, 528, 529, 530,
+	531, 532, 0, 0, 0, 533, 534, 535, 536, 0,
+	919, 363, 365, 930, 879, 537, 631, 538, 539, 1554,
+	1555, 0, 1514, 0, 540, 541, 544, 932, 1546, 933,
+	543, 545, 546, 934, 547, 0, 0, 0, 548, 549,
+	550, 551, 552, 553, 554, 0, 555, 557, 556, 0,
+	559, 1585, 558, 935, 560, 561, 936, 0, 562, 563,
+	564, 565, 566, 567, 572, 1537, 1536, 568, 569, 570,
+	571, 573, 574, 0, 575, 576, 578, 581, 577, 579,
+	580, 582, 583, 596, 597, 598, 584, 585, 586, 587,
+	588, 589, 590, 591, 592, 593, 594, 595, 600, 0,
+	599, 937, 0, 601, 602, 603, 604, 605, 606, 612,
+	615, 617, 618, 613, 614, 616, 619, 620, 621, 623,
+	624, 609, 610, 611, 938, 622, 607, 1477, 608, 366,
+	939, 625, 626, 627, 628, 1501, 1547, 629, 1563, 632,
+	633, 0, 0, 634, 0, 635, 636, 0, 0, 638,
+	639, 640, 0, 0, 641, 642, 887, 940, 643, 941,
+	1579, 644, 645, 1488, 646, 647, 648, 649, 650, 651,
+	652, 653, 654, 655, 656, 657, 0, 658, 659, 889,
+	660, 661, 662, 663, 664, 890, 665, 666, 667, 1580,
+	668, 892, 669, 670, 671, 0, 672, 673, 674, 0,
+	675, 676, 677, 678, 679, 680, 681, 682, 683, 684,
+	1558, 685, 686, 688, 687, 689, 690, 0, 691, 692,
+	0, 693, 694, 695, 0, 0, 0, 0, 0, 696,
+	697, 699, 0, 700, 701, 702, 703, 704, 705, 698,
+	706, 707, 708, 709, 710, 711, 712, 713, 0, 715,
+	716, 714, 717, 718, 942, 719, 720, 721, 722, 723,
+	1489, 724, 0, 725, 726, 734, 735, 736, 727, 728,
+	730, 737, 729, 738, 739, 740, 741, 743, 742, 0,
+	745, 746, 744, 747, 748, 749, 750, 1540, 751, 895,
+	752, 731, 732, 753, 754, 755, 943, 756, 757, 758,
+	759, 760, 761, 762, 763, 764, 1556, 0, 766, 0,
+	765, 767, 768, 769, 770, 771, 772, 773, 775, 733,
+	776, 777, 778, 783, 784, 785, 1588, 779, 780, 781,
+	782, 787, 1581, 788, 789, 790, 791, 0, 792, 793,
+	1474, 786, 774, 0, 794, 795, 796, 797, 798, 799,
+	800, 801, 802, 803, 0, 804, 1569, 1570, 1571, 1572,
+	0, 817, 0, 805, 807, 808, 809, 810, 1582, 811,
+	812, 1583, 1499, 813, 814, 815, 816, 806, 819, 820,
+	818, 0, 1481, 821, 822, 823, 824, 826, 828, 829,
+	830, 825, 827, 831, 1541, 832, 0, 0, 833, 834,
+	835, 905, 1566, 1587, 0, 1576, 838, 839, 836, 837,
+	840, 841, 844, 842, 843, 909, 847, 542, 848, 849,
+	850, 845, 846, 0, 0, 0, 0, 851, 852, 910,
+	853, 854, 855, 1478, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 1473,
+	0, 0, 0, 0, 0, 0, 1471, 1472, 0, 0,
+	0, 0, 0, 0, 916, 0, 1505, 0, 0, 0,
+	1503, 1551, 1493, 1494, 1495, 1491, 1492, 1504, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 367, 368,
+	370, 369, 371, 372, 373, 374, 0, 375, 376, 0,
+	0, 0, 0, 0, 1543, 1509, 0, 0, 378, 0,
+	377, 0, 379, 380, 381, 926, 382, 383, 384, 385,
+	386, 387, 388, 389, 390, 857, 391, 1557, 0, 392,
+	1565, 393, 1564, 0, 1575, 394, 395, 396, 397, 398,
+	399, 400, 401, 402, 403, 404, 1511, 1542, 1475, 405,
+	1589, 1590, 864, 0, 406, 407, 408, 409, 1549, 0,
+	1530, 0, 410, 411, 412, 413, 414, 415, 416, 417,
+	0, 0, 419, 420, 421, 418, 422, 423, 0, 424,
+	0, 425, 426, 427, 428, 429, 0, 430, 431, 0,
+	432, 433, 434, 928, 435, 436, 437, 1533, 1531, 1532,
+	1539, 1535, 1534, 1538, 438, 439, 440, 441, 442, 1568,
+	443, 445, 1562, 1561, 1480, 448, 450, 444, 446, 0,
+	449, 447, 451, 452, 0, 453, 454, 455, 456, 457,
+	0, 0, 0, 458, 1560, 460, 461, 0, 462, 463,
+	464, 466, 465, 0, 467, 468, 469, 0, 470, 471,
+	1487, 472, 473, 474, 476, 478, 475, 477, 479, 480,
+	481, 482, 483, 1577, 1578, 484, 485, 1500, 362, 0,
+	0, 0, 0, 0, 486, 487, 488, 1559, 0, 0,
+	0, 489, 0, 491, 495, 496, 492, 493, 494, 497,
+	0, 490, 498, 499, 0, 929, 500, 501, 502, 1573,
+	1574, 503, 504, 505, 506, 507, 508, 509, 510, 511,
+	0, 512, 513, 1584, 0, 1510, 514, 0, 515, 516,
+	517, 518, 519, 520, 521, 1544, 1545, 1548, 630, 931,
+	522, 523, 524, 525, 0, 526, 527, 528, 529, 530,
+	531, 532, 0, 0, 0, 533, 534, 535, 536, 0,
+	919, 363, 365, 930, 879, 537, 631, 538, 539, 1554,
+	1555, 0, 1514, 0, 540, 541, 544, 932, 1546, 933,
+	543, 545, 546, 934, 547, 0, 0, 0, 548, 549,
+	550, 551, 552, 553, 554, 0, 555, 557, 556, 0,
+	559, 1585, 558, 935, 560, 561, 936, 0, 562, 563,
+	564, 565, 566, 567, 572, 1537, 1536, 568, 569, 570,
+	571, 573, 574, 0, 575, 576, 578, 581, 577, 579,
+	580, 582, 583, 596, 597, 598, 584, 585, 586, 587,
+	588, 589, 590, 591, 592, 593, 594, 595, 600, 0,
+	599, 937, 0, 601, 602, 603, 604, 605, 606, 612,
+	615, 617, 618, 613, 614, 616, 619, 620, 621, 623,
+	624, 609, 610, 611, 938, 622, 607, 1477, 608, 366,
+	939, 625, 626, 627, 628, 1501, 1547, 629, 1563, 632,
+	633, 0, 0, 634, 0, 635, 636, 0, 0, 638,
+	639, 640, 0, 0, 641, 642, 887, 940, 643, 941,
+	1579, 644, 645, 1488, 646, 647, 648, 649, 650, 651,
+	652, 653, 654, 655, 656, 657, 0, 658, 659, 889,
+	660, 661, 662, 663, 664, 890, 665, 666, 667, 1580,
+	668, 892, 669, 670, 671, 0, 672, 673, 674, 0,
+	675, 676, 677, 678, 679, 680, 681, 682, 683, 684,
+	1558, 685, 686, 688, 687, 689, 690, 0, 691, 692,
+	0, 693, 694, 695, 0, 0, 0, 0, 0, 696,
+	697, 699, 0, 700, 701, 702, 703, 704, 705, 698,
+	706, 707, 708, 709, 710, 711, 712, 713, 0, 715,
+	716, 714, 717, 718, 942, 719, 720, 721, 722, 723,
+	1489, 724, 0, 725, 726, 734, 735, 736, 727, 728,
+	730, 737, 729, 738, 739, 740, 741, 743, 742, 0,
+	745, 746, 744, 747, 748, 749, 750, 1540, 751, 895,
+	752, 731, 732, 753, 754, 755, 943, 756, 757, 758,
+	759, 760, 761, 762, 763, 764, 1556, 0, 766, 0,
+	765, 767, 768, 769, 770, 771, 772, 773, 775, 733,
+	776, 777, 778, 783, 784, 785, 1588, 779, 780, 781,
+	782, 787, 1581, 788, 789, 790, 791, 0, 792, 793,
+	1474, 786, 774, 0, 794, 795, 796, 797, 798, 799,
+	800, 801, 802, 803, 0, 804, 1569, 1570, 1571, 1572,
+	0, 817, 0, 805, 807, 808, 809, 810, 1582, 811,
+	812, 1583, 1499, 813, 814, 815, 816, 806, 819, 820,
+	818, 0, 1481, 821, 822, 823, 824, 826, 828, 829,
+	830, 825, 827, 831, 1541, 832, 0, 0, 833, 834,
+	835, 905, 1566, 1587, 0, 1576, 838, 839, 836, 837,
+	840, 841, 844, 842, 843, 909, 847, 542, 848, 849,
+	850, 845, 846, 0, 0, 0, 0, 851, 852, 910,
+	853, 854, 855, 1478, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 1473,
+	0, 0, 0, 0, 0, 0, 1471, 1472, 0, 0,
+	0, 0, 0, 0, 916, 0, 1505, 0, 0, 0,
+	1503, 1551, 1493, 1494, 1495, 1491, 1492, 1504, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 367, 368,
+	370, 369, 371, 372, 373, 374, 0, 375, 376, 0,
+	0, 0, 0, 0, 1543, 1509, 0, 0, 378, 0,
+	377, 0, 379, 380, 381, 926, 382, 383, 384, 385,
+	386, 387, 388, 389, 390, 857, 391, 1557, 0, 392,
+	1565, 393, 1564, 0, 1575, 394, 395, 396, 397, 398,
+	399, 400, 401, 402, 403, 404, 1511, 1542, 1475, 405,
+	1589, 1590, 864, 0, 406, 407, 408, 409, 1549, 0,
+	1530, 0, 410, 411, 412, 413, 414, 415, 416, 417,
+	0, 0, 419, 420, 421, 418, 422, 423, 0, 424,
+	0, 425, 426, 427, 428, 429, 0, 430, 431, 0,
+	432, 433, 434, 928, 435, 436, 7049, 1533, 1531, 1532,
+	1539, 1535, 1534, 1538, 438, 439, 440, 441, 442, 1568,
+	443, 445, 1562, 1561, 1480, 448, 450, 444, 446, 0,
+	449, 447, 451, 452, 0, 453, 454, 455, 456, 457,
+	0, 0, 0, 458, 1560, 460, 461, 0, 462, 463,
+	464, 466, 465, 0, 467, 468, 469, 0, 470, 471,
+	1487, 472, 473, 474, 476, 478, 475, 477, 479, 480,
+	481, 482, 483, 1577, 1578, 484, 485, 1500, 362, 0,
+	0, 0, 0, 0, 486, 487, 488, 1559, 0, 0,
+	0, 489, 0, 491, 495, 496, 492, 493, 494, 497,
+	0, 490, 498, 499, 0, 929, 500, 501, 502, 1573,
+	1574, 503, 504, 505, 506, 507, 508, 509, 510, 511,
+	0, 512, 513, 1584, 0, 1510, 514, 0, 515, 516,
+	517, 518, 519, 520, 521, 1544, 1545, 1548, 630, 931,
+	522, 523, 524, 525, 0, 526, 527, 528, 529, 530,
+	531, 532, 0, 0, 0, 533, 534, 535, 536, 0,
+	919, 363, 365, 930, 879, 537, 631, 538, 539, 1554,
+	1555, 0, 1514, 0, 540, 541, 544, 932, 1546, 933,
+	543, 545, 546, 934, 547, 0, 0, 0, 548, 549,
+	550, 551, 552, 553, 554, 0, 555, 557, 556, 0,
+	559, 1585, 558, 935, 560, 561, 936, 0, 562, 563,
+	564, 565, 566, 567, 572, 1537, 1536, 568, 569, 570,
+	571, 573, 574, 0, 575, 576, 578, 581, 577, 579,
+	580, 582, 583, 596, 597, 598, 584, 585, 586, 587,
+	588, 589, 590, 591, 592, 593, 594, 595, 600, 0,
+	599, 937, 0, 601, 602, 603, 604, 605, 606, 612,
+	615, 617, 618, 613, 614, 616, 619, 620, 621, 623,
+	624, 609, 610, 611, 938, 622, 607, 1477, 608, 366,
+	939, 625, 626, 627, 628, 1501, 1547, 629, 1563, 632,
+	633, 0, 0, 634, 0, 635, 636, 0, 0, 638,
+	639, 640, 0, 0, 641, 642, 887, 940, 643, 941,
+	1579, 644, 645, 1488, 646, 647, 648, 649, 650, 651,
+	652, 653, 654, 655, 656, 657, 0, 658, 659, 889,
+	660, 661, 662, 663, 664, 890, 665, 666, 667, 1580,
+	668, 892, 669, 670, 671, 0, 672, 673, 674, 0,
+	675, 676, 677, 678, 679, 680, 681, 682, 683, 684,
+	1558, 685, 686, 688, 687, 689, 690, 0, 691, 692,
+	0, 693, 694, 695, 0, 0, 0, 0, 0, 696,
+	697, 699, 0, 700, 701, 702, 703, 704, 705, 698,
+	706, 707, 708, 709, 710, 711, 712, 713, 0, 715,
+	716, 714, 717, 718, 942, 719, 720, 721, 722, 723,
+	1489, 724, 0, 725, 726, 734, 735, 736, 727, 728,
+	730, 737, 729, 738, 739, 740, 741, 743, 742, 0,
+	745, 746, 744, 747, 748, 749, 750, 1540, 751, 895,
+	752, 731, 732, 753, 754, 755, 943, 756, 757, 758,
+	759, 760, 761, 762, 763, 764, 1556, 0, 766, 0,
+	765, 767, 768, 769, 770, 771, 772, 773, 775, 733,
+	776, 777, 778, 783, 784, 785, 1588, 779, 780, 781,
+	782, 787, 1581, 788, 789, 790, 791, 0, 792, 793,
+	1474, 786, 774, 0, 794, 795, 796, 797, 798, 799,
+	800, 801, 802, 803, 0, 804, 1569, 1570, 1571, 1572,
+	0, 817, 0, 805, 807, 808, 809, 810, 1582, 811,
+	812, 1583, 1499, 813, 814, 815, 816, 806, 7048, 820,
+	818, 0, 1481, 821, 822, 823, 824, 826, 828, 829,
+	830, 825, 827, 831, 1541, 832, 0, 0, 833, 834,
+	835, 905, 1566, 1587, 0, 1576, 838, 839, 836, 837,
+	840, 841, 844, 842, 843, 909, 847, 542, 848, 849,
+	850, 845, 846, 0, 0, 0, 0, 851, 852, 910,
+	853, 854, 855, 1478, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 1473,
+	0, 0, 0, 0, 0, 0, 1471, 1472, 0, 0,
+	0, 0, 0, 0, 916, 0, 1505, 0, 0, 0,
+	1503, 1551, 1493, 1494, 1495, 1491, 1492, 1504, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 367, 368,
+	370, 369, 371, 372, 373, 374, 0, 375, 376, 0,
+	0, 0, 0, 0, 1543, 1509, 0, 0, 378, 0,
+	377, 0, 379, 380, 381, 926, 382, 383, 384, 385,
+	386, 387, 388, 389, 390, 7047, 391, 1557, 0, 392,
+	1565, 393, 1564, 0, 1575, 394, 395, 396, 397, 398,
+	399, 400, 401, 402, 403, 404, 1511, 1542, 1475, 405,
+	1589, 1590, 864, 0, 406, 407, 408, 409, 1549, 0,
+	1530, 0, 410, 411, 412, 413, 414, 415, 416, 417,
+	0, 0, 419, 420, 421, 418, 422, 423, 0, 424,
+	0, 425, 426, 427, 428, 429, 0, 430, 431, 0,
+	432, 433, 434, 928, 435, 436, 7049, 1533, 1531, 1532,
+	1539, 1535, 1534, 1538, 438, 439, 440, 441, 442, 1568,
+	443, 445, 1562, 1561, 1480, 448, 450, 444, 446, 0,
+	449, 447, 451, 452, 0, 453, 454, 455, 456, 457,
+	0, 0, 0, 458, 1560, 460, 461, 0, 462, 463,
+	464, 466, 465, 0, 467, 468, 469, 0, 470, 471,
+	1487, 472, 473, 474, 476, 478, 475, 477, 479, 480,
+	481, 482, 483, 1577, 1578, 484, 485, 1500, 362, 0,
+	0, 0, 0, 0, 486, 487, 488, 1559, 0, 0,
+	0, 489, 0, 491, 495, 496, 492, 493, 494, 497,
+	0, 490, 498, 499, 0, 929, 500, 501, 502, 1573,
+	1574, 503, 504, 505, 506, 507, 508, 509, 510, 511,
+	0, 512, 513, 1584, 0, 1510, 514, 0, 515, 516,
+	517, 518, 519, 520, 521, 1544, 1545, 1548, 630, 931,
+	522, 523, 524, 525, 0, 526, 527, 528, 529, 530,
+	531, 532, 0, 0, 0, 533, 534, 535, 536, 0,
+	919, 363, 365, 930, 879, 537, 631, 538, 539, 1554,
+	1555, 0, 1514, 0, 540, 541, 544, 932, 1546, 933,
+	543, 545, 546, 934, 547, 0, 0, 0, 548, 549,
+	550, 551, 552, 553, 554, 0, 555, 557, 556, 0,
+	559, 1585, 558, 935, 560, 561, 936, 0, 562, 563,
+	564, 565, 566, 567, 572, 1537, 1536, 568, 569, 570,
+	571, 573, 574, 0, 575, 576, 578, 581, 577, 579,
+	580, 582, 583, 596, 597, 598, 584, 585, 586, 587,
+	588, 589, 590, 591, 592, 593, 594, 595, 600, 0,
+	599, 937, 0, 601, 602, 603, 604, 605, 606, 612,
+	615, 617, 618, 613, 614, 616, 619, 620, 621, 623,
+	624, 609, 610, 611, 938, 622, 607, 1477, 608, 366,
+	939, 625, 626, 627, 628, 1501, 1547, 629, 1563, 632,
+	633, 0, 0, 634, 0, 635, 636, 0, 0, 638,
+	639, 640, 0, 0, 641, 642, 887, 940, 643, 941,
+	1579, 644, 645, 1488, 646, 647, 648, 649, 650, 651,
+	652, 653, 654, 655, 656, 657, 0, 658, 659, 889,
+	660, 661, 662, 663, 664, 890, 665, 666, 667, 1580,
+	668, 892, 669, 670, 671, 0, 672, 673, 674, 0,
+	675, 676, 677, 678, 679, 680, 681, 682, 683, 684,
+	1558, 685, 686, 688, 687, 689, 690, 0, 691, 692,
+	0, 693, 694, 695, 0, 0, 0, 0, 0, 696,
+	697, 699, 0, 700, 701, 702, 703, 704, 705, 698,
+	706, 707, 708, 709, 710, 711, 712, 713, 0, 715,
+	716, 714, 717, 718, 942, 719, 720, 721, 722, 723,
+	1489, 724, 0, 725, 726, 734, 735, 736, 727, 728,
+	730, 737, 729, 738, 739, 740, 741, 743, 742, 0,
+	745, 746, 744, 747, 748, 749, 750, 1540, 751, 895,
+	752, 731, 732, 753, 754, 755, 943, 756, 757, 758,
+	759, 760, 761, 762, 763, 764, 1556, 0, 766, 0,
+	765, 767, 768, 769, 770, 771, 772, 773, 775, 733,
+	776, 777, 778, 783, 784, 785, 1588, 779, 780, 781,
+	782, 787, 1581, 788, 789, 790, 791, 0, 792, 793,
+	1474, 786, 774, 0, 794, 795, 796, 797, 798, 799,
+	800, 801, 802, 803, 0, 804, 1569, 1570, 1571, 1572,
+	0, 817, 0, 805, 807, 808, 809, 810, 1582, 811,
+	812, 1583, 1499, 813, 814, 815, 816, 806, 7048, 820,
+	818, 0, 1481, 821, 822, 823, 824, 826, 828, 829,
+	830, 825, 827, 831, 1541, 832, 0, 0, 833, 834,
+	835, 905, 1566, 1587, 0, 1576, 838, 839, 836, 837,
+	840, 841, 844, 842, 843, 909, 847, 542, 848, 849,
+	850, 845, 846, 0, 0, 0, 0, 851, 852, 910,
+	853, 854, 855, 1478, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 1473,
+	0, 0, 0, 0, 0, 0, 1471, 1472, 0, 0,
+	0, 0, 0, 0, 916, 0, 1505, 0, 0, 0,
+	1503, 1551, 1493, 1494, 1495, 1491, 1492, 1504, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 367, 368,
+	370, 369, 371, 372, 373, 374, 0, 375, 376, 0,
+	0, 0, 0, 0, 1543, 1509, 0, 0, 378, 0,
+	377, 0, 379, 380, 381, 926, 382, 383, 384, 385,
+	386, 387, 388, 389, 390, 857, 391, 1557, 0, 392,
+	1565, 393, 1564, 0, 1575, 394, 395, 396, 397, 398,
+	399, 400, 401, 402, 403, 404, 1511, 1542, 1475, 405,
+	1589, 1590, 864, 0, 406, 407, 408, 409, 1549, 0,
+	1530, 0, 410, 411, 412, 413, 414, 415, 416, 417,
+	0, 0, 419, 420, 421, 418, 422, 423, 0, 424,
+	0, 425, 426, 427, 428, 429, 0, 430, 431, 0,
+	432, 433, 434, 928, 435, 6426, 437, 1533, 1531, 1532,
+	1539, 1535, 1534, 1538, 438, 439, 440, 441, 442, 1568,
+	443, 445, 1562, 1561, 1480, 448, 450, 444, 446, 0,
+	449, 447, 451, 452, 0, 453, 454, 455, 456, 457,
+	0, 0, 0, 458, 1560, 460, 461, 0, 462, 463,
+	464, 466, 465, 0, 467, 468, 469, 0, 470, 471,
+	1487, 472, 473, 474, 476, 478, 475, 477, 479, 480,
+	481, 482, 483, 1577, 1578, 484, 485, 1500, 362, 0,
+	0, 0, 0, 0, 486, 487, 488, 1559, 0, 0,
+	0, 489, 0, 491, 495, 496, 492, 493, 494, 497,
+	0, 490, 498, 499, 0, 929, 500, 501, 502, 1573,
+	1574, 503, 504, 505, 506, 507, 508, 509, 510, 511,
+	0, 512, 513, 1584, 0, 6427, 514, 0, 515, 516,
+	517, 518, 519, 520, 521, 1544, 1545, 1548, 630, 931,
+	522, 523, 524, 525, 0, 526, 527, 528, 529, 530,
+	531, 532, 0, 0, 0, 533, 534, 535, 536, 0,
+	919, 363, 365, 930, 879, 537, 631, 538, 539, 1554,
+	1555, 0, 1514, 0, 540, 541, 544, 932, 1546, 933,
+	543, 545, 546, 934, 547, 0, 0, 0, 548, 549,
+	550, 551, 552, 553, 554, 0, 555, 557, 556, 0,
+	559, 1585, 558, 935, 560, 561, 936, 0, 562, 563,
+	564, 565, 566, 567, 572, 1537, 1536, 568, 569, 570,
+	571, 573, 574, 0, 575, 576, 578, 581, 577, 579,
+	580, 582, 583, 596, 597, 598, 584, 585, 586, 587,
+	588, 589, 590, 591, 592, 593, 594, 595, 600, 0,
+	599, 937, 0, 601, 602, 603, 604, 605, 606, 612,
+	615, 617, 618, 613, 614, 616, 619, 620, 621, 623,
+	624, 609, 610, 611, 938, 622, 607, 1477, 608, 366,
+	939, 625, 626, 627, 628, 1501, 1547, 629, 1563, 632,
+	633, 0, 0, 634, 0, 635, 636, 0, 0, 638,
+	639, 640, 0, 0, 641, 642, 887, 940, 643, 941,
+	1579, 644, 645, 1488, 646, 647, 648, 649, 650, 651,
+	652, 653, 654, 655, 656, 657, 0, 658, 659, 889,
+	660, 661, 662, 663, 664, 890, 665, 666, 667, 1580,
+	668, 892, 669, 670, 671, 0, 672, 673, 674, 0,
+	675, 676, 677, 678, 679, 680, 681, 682, 683, 684,
+	1558, 685, 686, 688, 687, 689, 690, 0, 691, 692,
+	0, 693, 694, 695, 0, 0, 0, 0, 0, 696,
+	697, 699, 0, 700, 701, 702, 703, 704, 705, 698,
+	706, 707, 708, 709, 710, 711, 712, 713, 0, 715,
+	716, 714, 717, 718, 942, 719, 720, 721, 6425, 723,
+	1489, 724, 0, 725, 726, 734, 735, 736, 727, 728,
+	730, 737, 729, 738, 739, 740, 741, 743, 742, 0,
+	745, 746, 744, 747, 748, 749, 750, 1540, 751, 895,
+	752, 731, 732, 753, 754, 755, 943, 756, 757, 758,
+	759, 760, 761, 762, 763, 764, 1556, 0, 766, 0,
+	765, 767, 768, 769, 770, 771, 772, 773, 775, 733,
+	776, 777, 778, 783, 784, 785, 1588, 779, 780, 781,
+	782, 787, 1581, 788, 789, 790, 791, 0, 792, 793,
+	1474, 786, 774, 0, 794, 795, 796, 797, 798, 799,
+	800, 801, 802, 803, 0, 804, 1569, 1570, 1571, 1572,
+	0, 817, 0, 805, 807, 808, 809, 810, 1582, 811,
+	812, 1583, 1499, 813, 814, 815, 816, 806, 819, 820,
+	818, 0, 1481, 821, 822, 823, 824, 826, 828, 829,
+	830, 825, 827, 831, 1541, 832, 0, 0, 833, 834,
+	835, 905, 1566, 1587, 0, 1576, 838, 839, 836, 837,
+	840, 841, 844, 842, 843, 909, 847, 542, 848, 849,
+	850, 845, 846, 0, 0, 0, 0, 851, 852, 910,
+	853, 854, 855, 1478, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 1473,
+	0, 0, 0, 0, 0, 0, 1471, 1472, 0, 0,
+	0, 0, 0, 0, 916, 0, 1505, 0, 0, 0,
+	1503, 1551, 1493, 1494, 1495, 1491, 1492, 1504, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 367, 368,
+	370, 369, 371, 372, 373, 374, 0, 375, 376, 0,
+	0, 0, 0, 0, 1543, 1509, 0, 0, 378, 0,
+	377, 0, 379, 380, 381, 926, 382, 383, 384, 385,
+	386, 387, 388, 389, 390, 857, 391, 1557, 0, 392,
+	1565, 393, 1564, 0, 1575, 394, 395, 396, 397, 398,
+	399, 400, 401, 402, 403, 404, 1511, 1542, 1475, 405,
+	1589, 1590, 864, 0, 406, 407, 408, 409, 1549, 0,
+	1530, 0, 410, 411, 412, 413, 414, 415, 416, 417,
+	0, 0, 419, 420, 421, 418, 422, 423, 0, 424,
+	0, 425, 426, 427, 428, 429, 0, 430, 431, 0,
+	432, 433, 434, 928, 435, 436, 437, 1533, 1531, 1532,
+	1539, 1535, 1534, 1538, 438, 439, 440, 441, 442, 1568,
+	443, 445, 1562, 1561, 1480, 448, 450, 444, 446, 0,
+	449, 447, 451, 452, 0, 453, 454, 455, 456, 457,
+	0, 0, 0, 458, 1560, 460, 461, 0, 462, 463,
+	464, 466, 465, 0, 467, 468, 469, 0, 470, 471,
+	1487, 472, 473, 474, 476, 478, 475, 477, 479, 480,
+	481, 482, 483, 1577, 1578, 484, 485, 1500, 362, 0,
+	0, 0, 0, 0, 486, 487, 488, 1559, 0, 0,
+	0, 489, 0, 491, 495, 496, 492, 493, 494, 497,
+	0, 490, 498, 499, 0, 929, 2654, 501, 502, 1573,
+	1574, 503, 504, 505, 506, 507, 508, 509, 510, 511,
+	0, 512, 513, 1584, 0, 1510, 514, 0, 515, 516,
+	517, 518, 519, 520, 521, 1544, 1545, 1548, 630, 931,
+	522, 523, 524, 525, 0, 526, 527, 528, 529, 530,
+	531, 532, 0, 0, 0, 533, 534, 535, 536, 0,
+	919, 363, 365, 930, 879, 537, 631, 538, 539, 1554,
+	1555, 0, 1514, 0, 540, 541, 544, 932, 1546, 933,
+	543, 545, 546, 934, 547, 0, 0, 0, 548, 549,
+	550, 551, 552, 553, 554, 0, 555, 557, 556, 0,
+	559, 1585, 558, 935, 560, 561, 936, 0, 562, 563,
+	564, 565, 566, 567, 572, 1537, 1536, 568, 569, 570,
+	571, 573, 574, 0, 575, 576, 578, 581, 577, 579,
+	580, 582, 583, 596, 597, 598, 584, 585, 586, 587,
+	588, 589, 590, 591, 592, 593, 594, 595, 600, 0,
+	599, 937, 0, 601, 602, 603, 604, 605, 606, 612,
+	615, 617, 618, 613, 614, 616, 619, 620, 621, 623,
+	624, 609, 610, 611, 938, 622, 607, 1477, 608, 366,
+	939, 625, 626, 627, 628, 1501, 1547, 629, 1563, 632,
+	633, 0, 0, 634, 0, 635, 636, 0, 0, 638,
+	639, 640, 0, 0, 641, 642, 887, 940, 643, 941,
+	1579, 644, 645, 1488, 646, 647, 648, 649, 650, 651,
+	652, 653, 654, 655, 656, 657, 0, 658, 659, 889,
+	660, 661, 662, 663, 664, 890, 665, 666, 667, 1580,
+	668, 892, 669, 670, 671, 0, 672, 673, 674, 0,
+	675, 676, 677, 678, 679, 680, 681, 682, 683, 684,
+	1558, 685, 686, 688, 687, 689, 690, 0, 691, 692,
+	0, 693, 694, 695, 0, 0, 0, 0, 0, 696,
+	697, 699, 0, 700, 701, 702, 703, 704, 705, 698,
+	706, 707, 708, 709, 710, 711, 712, 713, 0, 715,
+	716, 714, 717, 718, 942, 719, 720, 721, 722, 723,
+	1489, 724, 0, 725, 726, 734, 735, 736, 727, 728,
+	730, 737, 729, 738, 739, 740, 741, 743, 742, 0,
+	745, 746, 744, 747, 748, 749, 750, 1540, 751, 895,
+	752, 731, 732, 753, 754, 755, 943, 756, 757, 758,
+	759, 760, 761, 762, 763, 764, 1556, 0, 766, 0,
+	765, 767, 768, 769, 770, 771, 772, 773, 775, 733,
+	776, 777, 778, 783, 784, 785, 1588, 779, 780, 781,
+	782, 787, 1581, 788, 789, 790, 791, 0, 792, 793,
+	1474, 786, 774, 0, 794, 795, 796, 797, 798, 799,
+	800, 801, 802, 803, 0, 804, 1569, 1570, 1571, 1572,
+	0, 817, 0, 805, 807, 808, 809, 810, 1582, 811,
+	812, 1583, 1499, 813, 814, 815, 816, 806, 819, 820,
+	818, 0, 1481, 821, 822, 823, 824, 826, 828, 829,
+	830, 825, 827, 831, 1541, 832, 0, 0, 833, 834,
+	835, 905, 1566, 1587, 0, 1576, 838, 839, 836, 837,
+	840, 841, 844, 842, 843, 909, 847, 542, 848, 849,
+	850, 845, 846, 0, 0, 0, 0, 851, 852, 910,
+	853, 854, 855, 1478, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 1473,
+	0, 0, 0, 0, 0, 0, 1471, 1472, 0, 0,
+	0, 0, 0, 0, 3332, 0, 1505, 0, 0, 0,
+	1503, 1551, 1493, 1494, 1495, 4745, 4746, 1504, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 367, 368,
+	370, 369, 371, 372, 373, 374, 0, 375, 376, 0,
+	0, 0, 0, 0, 1543, 1509, 0, 0, 378, 0,
+	377, 0, 379, 380, 381, 926, 382, 383, 384, 385,
+	386, 387, 388, 389, 390, 857, 391, 1557, 0, 392,
+	1565, 393, 1564, 0, 1575, 394, 395, 396, 397, 398,
+	399, 400, 401, 402, 403, 404, 1511, 1542, 1475, 405,
+	1589, 1590, 864, 0, 406, 407, 408, 409, 1549, 0,
+	1530, 0, 410, 411, 412, 413, 414, 415, 416, 417,
+	0, 0, 419, 420, 421, 418, 422, 423, 0, 424,
+	0, 425, 426, 427, 428, 429, 0, 430, 431, 0,
+	432, 433, 434, 928, 435, 436, 437, 1533, 1531, 1532,
+	1539, 1535, 1534, 1538, 438, 439, 440, 441, 442, 1568,
+	443, 445, 1562, 1561, 1480, 448, 450, 444, 446, 0,
+	449, 447, 451, 452, 0, 453, 454, 455, 456, 457,
+	0, 0, 0, 458, 1560, 460, 461, 0, 462, 463,
+	464, 466, 465, 0, 467, 468, 469, 0, 470, 471,
+	1487, 472, 473, 474, 476, 478, 475, 477, 479, 480,
+	481, 482, 483, 1577, 1578, 484, 485, 1500, 362, 0,
+	0, 0, 0, 0, 486, 487, 488, 1559, 0, 0,
+	0, 489, 0, 491, 495, 496, 492, 493, 494, 497,
+	0, 490, 498, 499, 0, 929, 500, 501, 502, 1573,
+	1574, 503, 504, 505, 506, 507, 508, 509, 510, 511,
+	0, 512, 513, 1584, 0, 1510, 514, 0, 515, 516,
+	517, 518, 519, 520, 521, 1544, 1545, 1548, 630, 931,
+	522, 523, 524, 525, 0, 526, 527, 528, 529, 530,
+	531, 532, 0, 0, 0, 533, 534, 535, 536, 0,
+	919, 363, 365, 930, 879, 537, 631, 538, 539, 1554,
+	1555, 0, 1514, 0, 540, 541, 544, 932, 1546, 933,
+	543, 545, 546, 934, 547, 0, 0, 0, 548, 549,
+	550, 551, 552, 553, 554, 0, 555, 557, 556, 0,
+	559, 1585, 558, 935, 560, 561, 936, 0, 562, 563,
+	564, 565, 566, 567, 572, 1537, 1536, 568, 569, 570,
+	571, 573, 574, 0, 575, 576, 578, 581, 577, 579,
+	580, 582, 583, 596, 597, 598, 584, 585, 586, 587,
+	588, 589, 590, 591, 592, 593, 594, 595, 600, 0,
+	599, 937, 0, 601, 602, 603, 604, 605, 606, 612,
+	615, 617, 618, 613, 614, 616, 619, 620, 621, 623,
+	624, 609, 610, 611, 938, 622, 607, 1477, 608, 366,
+	939, 625, 626, 627, 628, 1501, 1547, 629, 1563, 632,
+	633, 0, 0, 634, 0, 635, 636, 0, 0, 638,
+	639, 640, 0, 0, 641, 642, 887, 940, 643, 941,
+	1579, 644, 645, 1488, 646, 647, 648, 649, 650, 651,
+	652, 653, 654, 655, 656, 657, 0, 658, 659, 889,
+	660, 661, 662, 663, 664, 890, 665, 666, 667, 1580,
+	668, 892, 669, 670, 671, 0, 672, 673, 674, 0,
+	675, 676, 677, 678, 679, 680, 681, 682, 683, 684,
+	1558, 685, 686, 688, 687, 689, 690, 0, 691, 692,
+	0, 693, 694, 695, 0, 0, 0, 0, 0, 696,
+	697, 699, 0, 700, 701, 702, 703, 704, 705, 698,
+	706, 707, 708, 709, 710, 711, 712, 713, 0, 715,
+	716, 714, 717, 718, 942, 719, 720, 721, 722, 723,
+	1489, 724, 0, 725, 726, 734, 735, 736, 727, 728,
+	730, 737, 729, 738, 739, 740, 741, 743, 742, 0,
+	745, 746, 744, 747, 748, 749, 750, 1540, 751, 895,
+	752, 731, 732, 753, 754, 755, 943, 756, 757, 758,
+	759, 760, 761, 762, 763, 764, 1556, 0, 766, 0,
+	765, 767, 768, 769, 770, 771, 772, 773, 775, 733,
+	776, 777, 778, 783, 784, 785, 1588, 779, 780, 781,
+	782, 787, 1581, 788, 789, 790, 791, 0, 792, 793,
+	1474, 786, 774, 0, 794, 795, 796, 797, 798, 799,
+	800, 801, 802, 803, 0, 804, 1569, 1570, 1571, 1572,
+	0, 817, 0, 805, 807, 808, 809, 810, 1582, 811,
+	812, 1583, 1499, 813, 814, 815, 816, 806, 819, 820,
+	818, 0, 1481, 821, 822, 823, 824, 826, 828, 829,
+	830, 825, 827, 831, 1541, 832, 0, 0, 833, 834,
+	835, 905, 1566, 1587, 0, 1576, 838, 839, 836, 837,
+	840, 841, 844, 842, 843, 909, 847, 542, 848, 849,
+	850, 845, 846, 0, 0, 0, 0, 851, 852, 910,
+	853, 854, 855, 1478, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 1473,
+	0, 0, 0, 0, 0, 0, 1471, 1472, 0, 0,
+	0, 0, 0, 0, 916, 0, 1505, 0, 0, 0,
+	1503, 1551, 1493, 1494, 1495, 4743, 4744, 1504, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 367, 368,
+	370, 369, 371, 372, 373, 374, 0, 375, 376, 0,
+	0, 0, 0, 0, 1543, 1509, 0, 0, 378, 0,
+	377, 0, 379, 380, 381, 926, 382, 383, 384, 385,
+	386, 387, 388, 389, 390, 857, 391, 1557, 0, 392,
+	1565, 393, 1564, 0, 1575, 394, 395, 396, 397, 398,
+	399, 400, 401, 402, 403, 404, 1511, 1542, 1475, 405,
+	1589, 1590, 864, 0, 406, 407, 408, 409, 1549, 0,
+	1530, 0, 410, 411, 412, 413, 414, 415, 416, 417,
+	0, 0, 419, 420, 421, 418, 422, 423, 0, 424,
+	0, 425, 426, 427, 428, 429, 0, 430, 431, 0,
+	432, 433, 434, 928, 435, 436, 437, 1533, 1531, 1532,
+	1539, 1535, 1534, 1538, 438, 439, 440, 441, 442, 1568,
+	443, 445, 1562, 1561, 1480, 448, 450, 444, 446, 0,
+	449, 447, 451, 452, 0, 453, 454, 455, 456, 457,
+	0, 0, 0, 458, 1560, 460, 461, 0, 462, 463,
+	464, 466, 465, 0, 467, 468, 469, 0, 470, 471,
+	1487, 472, 473, 474, 476, 478, 475, 477, 479, 480,
+	481, 482, 483, 1577, 1578, 484, 485, 1500, 362, 0,
+	0, 0, 0, 0, 486, 487, 488, 1559, 0, 0,
+	0, 489, 0, 491, 495, 496, 492, 493, 494, 497,
+	0, 490, 498, 499, 0, 929, 500, 501, 502, 1573,
+	1574, 503, 504, 505, 506, 507, 508, 509, 510, 511,
+	0, 512, 513, 1584, 0, 1510, 514, 0, 515, 516,
+	517, 518, 519, 520, 521, 1544, 1545, 1548, 630, 931,
+	522, 523, 524, 525, 0, 526, 527, 528, 529, 530,
+	531, 532, 0, 0, 0, 533, 534, 535, 536, 0,
+	919, 363, 365, 930, 879, 537, 631, 538, 539, 1554,
+	1555, 0, 1514, 0, 540, 541, 544, 932, 1546, 933,
+	543, 545, 546, 934, 547, 0, 0, 0, 548, 549,
+	550, 551, 552, 553, 554, 0, 555, 557, 556, 0,
+	559, 1585, 558, 935, 560, 561, 936, 0, 562, 563,
+	564, 565, 566, 567, 572, 1537, 1536, 568, 569, 570,
+	571, 573, 574, 0, 575, 576, 578, 581, 577, 579,
+	580, 582, 583, 596, 597, 598, 584, 585, 586, 587,
+	588, 589, 590, 591, 592, 593, 594, 595, 600, 0,
+	599, 937, 0, 601, 602, 603, 604, 605, 606, 612,
+	615, 617, 618, 613, 614, 616, 619, 620, 621, 623,
+	624, 609, 610, 611, 938, 622, 607, 1477, 608, 366,
+	939, 625, 626, 627, 628, 1501, 1547, 629, 1563, 632,
+	633, 0, 0, 634, 0, 635, 636, 0, 0, 638,
+	639, 640, 0, 0, 641, 642, 887, 940, 643, 941,
+	1579, 644, 645, 1488, 646, 647, 648, 649, 650, 651,
+	652, 653, 654, 655, 656, 657, 0, 658, 659, 889,
+	660, 661, 662, 663, 664, 890, 665, 666, 667, 1580,
+	668, 892, 669, 670, 671, 0, 672, 673, 674, 0,
+	675, 676, 677, 678, 679, 680, 681, 682, 683, 684,
+	1558, 685, 686, 688, 687, 689, 690, 0, 691, 692,
+	0, 693, 694, 695, 0, 0, 0, 0, 0, 696,
+	697, 699, 0, 700, 701, 702, 703, 704, 705, 698,
+	706, 707, 708, 709, 710, 711, 712, 713, 0, 715,
+	716, 714, 717, 718, 942, 719, 720, 721, 722, 723,
+	1489, 724, 0, 725, 726, 734, 735, 736, 727, 728,
+	730, 737, 729, 738, 739, 740, 741, 743, 742, 0,
+	745, 746, 744, 747, 748, 749, 750, 1540, 751, 895,
+	752, 731, 732, 753, 754, 755, 943, 756, 757, 758,
+	759, 760, 761, 762, 763, 764, 1556, 0, 766, 0,
+	765, 767, 768, 769, 770, 771, 772, 773, 775, 733,
+	776, 777, 778, 783, 784, 785, 1588, 779, 780, 781,
+	782, 787, 1581, 788, 789, 790, 791, 0, 792, 793,
+	1474, 786, 774, 0, 794, 795, 796, 797, 798, 799,
+	800, 801, 802, 803, 0, 804, 1569, 1570, 1571, 1572,
+	0, 817, 0, 805, 807, 808, 809, 810, 1582, 811,
+	812, 1583, 1499, 813, 814, 815, 816, 806, 819, 820,
+	818, 0, 1481, 821, 822, 823, 824, 826, 828, 829,
+	830, 825, 827, 831, 1541, 832, 0, 0, 833, 834,
+	835, 905, 1566, 1587, 0, 1576, 838, 839, 836, 837,
+	840, 841, 844, 842, 843, 909, 847, 542, 848, 849,
+	850, 845, 846, 0, 0, 0, 0, 851, 852, 910,
+	853, 854, 855, 1478, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 1473,
+	0, 0, 0, 0, 0, 0, 1471, 1472, 0, 0,
+	0, 0, 0, 0, 916, 0, 1505, 0, 0, 0,
+	1503, 1551, 1493, 1494, 1495, 1491, 1492, 1504, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 367, 368,
+	370, 369, 371, 372, 373, 374, 0, 375, 376, 0,
+	0, 0, 0, 0, 1543, 1509, 0, 0, 378, 0,
+	377, 0, 379, 380, 381, 926, 382, 383, 384, 385,
+	386, 387, 388, 389, 390, 857, 391, 1557, 0, 392,
+	1565, 393, 1564, 0, 1575, 394, 395, 396, 397, 398,
+	399, 400, 401, 402, 403, 404, 1511, 1542, 1475, 405,
+	1589, 1590, 864, 0, 406, 407, 408, 409, 1549, 0,
+	1530, 0, 410, 411, 412, 413, 414, 415, 416, 417,
+	0, 0, 419, 420, 421, 418, 422, 423, 0, 424,
+	0, 425, 426, 427, 428, 429, 0, 430, 431, 0,
+	432, 433, 434, 928, 435, 436, 437, 1533, 1531, 1532,
+	1539, 1535, 1534, 1538, 438, 439, 440, 441, 442, 1568,
+	443, 445, 1562, 1561, 1480, 448, 450, 444, 446, 0,
+	449, 447, 451, 452, 0, 453, 454, 455, 456, 457,
+	0, 0, 0, 458, 1560, 460, 461, 0, 462, 463,
+	464, 466, 465, 0, 467, 468, 469, 0, 470, 471,
+	1487, 472, 473, 474, 476, 478, 475, 477, 479, 480,
+	481, 482, 483, 1577, 1578, 484, 485, 1500, 362, 0,
+	0, 0, 0, 0, 486, 487, 488, 1559, 0, 0,
+	0, 489, 0, 491, 495, 496, 492, 493, 494, 497,
+	0, 490, 498, 499, 0, 929, 500, 501, 502, 1573,
+	1574, 503, 504, 505, 506, 507, 508, 509, 510, 511,
+	0, 512, 513, 1584, 0, 1510, 514, 0, 515, 516,
+	517, 518, 519, 520, 521, 1544, 1545, 1548, 630, 931,
+	522, 523, 524, 525, 0, 526, 527, 528, 529, 530,
+	531, 532, 0, 0, 0, 533, 534, 535, 536, 0,
+	919, 363, 365, 930, 879, 537, 631, 538, 539, 1554,
+	1555, 0, 1514, 0, 540, 541, 544, 932, 1546, 933,
+	543, 545, 546, 934, 547, 0, 0, 0, 548, 549,
+	550, 551, 552, 553, 554, 0, 555, 557, 556, 0,
+	559, 1585, 558, 935, 560, 561, 936, 0, 562, 563,
+	564, 565, 566, 567, 572, 1537, 1536, 568, 569, 570,
+	571, 573, 574, 0, 575, 576, 578, 581, 577, 579,
+	580, 582, 583, 596, 597, 598, 584, 585, 586, 587,
+	588, 589, 590, 591, 592, 593, 594, 595, 600, 0,
+	599, 937, 0, 601, 602, 603, 604, 605, 606, 612,
+	615, 617, 618, 613, 614, 616, 619, 620, 621, 623,
+	624, 609, 610, 611, 938, 622, 607, 1477, 608, 366,
+	939, 625, 626, 627, 628, 1501, 1547, 629, 1563, 632,
+	633, 0, 0, 634, 0, 635, 636, 0, 0, 638,
+	639, 640, 0, 0, 641, 642, 887, 940, 643, 941,
+	1579, 644, 645, 1488, 646, 647, 648, 649, 650, 651,
+	652, 653, 654, 655, 656, 657, 0, 658, 659, 889,
+	660, 661, 662, 663, 664, 890, 665, 666, 667, 1580,
+	668, 892, 669, 670, 671, 0, 672, 673, 674, 0,
+	675, 676, 677, 678, 679, 680, 681, 682, 683, 684,
+	1558, 685, 686, 688, 687, 689, 690, 0, 691, 692,
+	0, 693, 694, 695, 0, 0, 0, 0, 0, 696,
+	697, 699, 0, 700, 701, 702, 703, 704, 705, 698,
+	706, 707, 708, 709, 710, 711, 712, 713, 0, 715,
+	716, 714, 717, 718, 942, 719, 720, 721, 722, 723,
+	1489, 724, 0, 725, 726, 734, 735, 736, 727, 728,
+	730, 737, 729, 738, 739, 740, 741, 743, 742, 0,
+	745, 746, 744, 747, 748, 749, 750, 1540, 751, 895,
+	752, 731, 732, 753, 754, 755, 943, 756, 757, 758,
+	759, 760, 761, 762, 763, 764, 1556, 0, 766, 0,
+	765, 767, 768, 769, 770, 771, 772, 773, 775, 733,
+	776, 777, 778, 783, 784, 785, 1588, 779, 780, 781,
+	782, 787, 1581, 788, 789, 790, 791, 0, 792, 793,
+	1474, 786, 774, 0, 794, 795, 796, 797, 798, 799,
+	800, 801, 802, 803, 0, 804, 1569, 1570, 1571, 1572,
+	0, 817, 0, 805, 807, 808, 809, 810, 1582, 811,
+	812, 1583, 1499, 813, 814, 815, 816, 806, 819, 820,
+	818, 0, 1481, 821, 822, 823, 824, 826, 828, 829,
+	830, 825, 827, 831, 1541, 832, 0, 0, 833, 834,
+	835, 905, 1566, 1587, 0, 1576, 838, 839, 836, 837,
+	840, 841, 844, 842, 843, 909, 847, 542, 848, 849,
+	850, 845, 846, 0, 0, 0, 0, 851, 852, 910,
+	853, 854, 855, 1478, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 1473,
+	0, 0, 0, 0, 0, 0, 1471, 1472, 0, 0,
+	0, 0, 0, 0, 3332, 0, 1505, 0, 0, 0,
+	1503, 1551, 1493, 1494, 1495, 1491, 1492, 1504, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 367, 368,
+	370, 369, 371, 372, 373, 374, 0, 375, 376, 0,
+	0, 0, 0, 0, 1543, 1509, 0, 0, 378, 0,
+	377, 0, 379, 380, 381, 926, 382, 383, 384, 385,
+	386, 387, 388, 389, 390, 857, 391, 1557, 0, 392,
+	1565, 393, 1564, 0, 1575, 394, 395, 396, 397, 398,
+	399, 400, 401, 402, 403, 404, 1511, 1542, 1475, 405,
+	1589, 1590, 864, 0, 406, 407, 408, 409, 1549, 0,
+	1530, 0, 410, 411, 412, 413, 414, 415, 416, 417,
+	0, 0, 419, 420, 421, 418, 422, 423, 0, 424,
+	0, 425, 426, 427, 428, 429, 0, 430, 431, 0,
+	432, 433, 434, 928, 435, 436, 437, 1533, 1531, 1532,
+	1539, 1535, 1534, 1538, 438, 439, 440, 441, 442, 1568,
+	443, 445, 1562, 1561, 1480, 448, 450, 444, 446, 0,
+	449, 447, 451, 452, 0, 453, 454, 455, 456, 457,
+	0, 0, 0, 458, 1560, 460, 461, 0, 462, 463,
+	464, 466, 465, 0, 467, 468, 469, 0, 470, 471,
+	1487, 472, 473, 474, 476, 478, 475, 477, 479, 480,
+	481, 482, 483, 1577, 1578, 484, 485, 1500, 362, 0,
+	0, 0, 0, 0, 486, 487, 488, 1559, 0, 0,
+	0, 489, 0, 491, 495, 496, 492, 493, 494, 497,
+	0, 490, 498, 499, 0, 929, 500, 501, 502, 1573,
+	1574, 503, 504, 505, 506, 507, 508, 509, 510, 511,
+	0, 512, 513, 1584, 0, 1510, 514, 0, 515, 516,
+	517, 518, 519, 520, 521, 1544, 1545, 1548, 630, 931,
+	522, 523, 524, 525, 0, 526, 527, 528, 529, 530,
+	531, 532, 0, 0, 0, 533, 534, 535, 536, 0,
+	919, 363, 365, 930, 879, 537, 631, 538, 539, 1554,
+	1555, 0, 1514, 0, 540, 541, 544, 932, 1546, 933,
+	543, 545, 546, 934, 547, 0, 0, 0, 548, 549,
+	550, 551, 552, 553, 554, 0, 555, 557, 556, 0,
+	559, 1585, 558, 935, 560, 561, 936, 0, 562, 563,
+	564, 565, 566, 567, 572, 1537, 1536, 568, 569, 570,
+	571, 573, 574, 0, 575, 576, 578, 581, 577, 579,
+	580, 582, 583, 596, 597, 598, 584, 585, 586, 587,
+	588, 589, 590, 591, 592, 593, 594, 595, 600, 0,
+	599, 937, 0, 601, 602, 603, 604, 605, 606, 612,
+	615, 617, 618, 613, 614, 616, 619, 620, 621, 623,
+	624, 609, 610, 611, 938, 622, 607, 1477, 608, 366,
+	939, 625, 626, 627, 628, 1501, 1547, 629, 1563, 632,
+	633, 0, 0, 634, 0, 635, 636, 0, 0, 638,
+	639, 640, 0, 0, 641, 642, 887, 940, 643, 941,
+	1579, 644, 645, 1488, 646, 647, 648, 649, 650, 651,
+	652, 653, 654, 655, 656, 657, 0, 658, 659, 889,
+	660, 661, 662, 663, 664, 890, 665, 666, 667, 1580,
+	668, 892, 669, 670, 671, 0, 672, 673, 674, 0,
+	675, 676, 677, 678, 679, 680, 681, 682, 683, 684,
+	1558, 685, 686, 688, 687, 689, 690, 0, 691, 692,
+	0, 693, 694, 695, 0, 0, 0, 0, 0, 696,
+	697, 699, 0, 700, 701, 702, 703, 704, 705, 698,
+	706, 707, 708, 709, 710, 711, 712, 713, 0, 715,
+	716, 714, 717, 718, 942, 719, 720, 721, 722, 723,
+	1489, 724, 0, 725, 726, 734, 735, 736, 727, 728,
+	730, 737, 729, 738, 739, 740, 741, 743, 742, 0,
+	745, 746, 744, 747, 748, 749, 750, 1540, 751, 895,
+	752, 731, 732, 753, 754, 755, 943, 756, 757, 758,
+	759, 760, 761, 762, 763, 764, 1556, 0, 766, 0,
+	765, 767, 768, 769, 770, 771, 772, 773, 775, 733,
+	776, 777, 778, 783, 784, 785, 1588, 779, 780, 781,
+	782, 787, 1581, 788, 789, 790, 791, 0, 792, 793,
+	1474, 786, 774, 0, 794, 795, 796, 797, 798, 799,
+	800, 801, 802, 803, 0, 804, 1569, 1570, 1571, 1572,
+	0, 817, 0, 805, 807, 808, 809, 810, 1582, 811,
+	812, 1583, 1499, 813, 814, 815, 816, 806, 819, 820,
+	818, 0, 1481, 821, 822, 823, 824, 826, 828, 829,
+	830, 825, 827, 831, 1541, 832, 0, 0, 833, 834,
+	835, 905, 1566, 1587, 0, 1576, 838, 839, 836, 837,
+	840, 841, 844, 842, 843, 909, 847, 542, 848, 849,
+	850, 845, 846, 0, 0, 0, 0, 851, 852, 910,
+	853, 854, 855, 1478, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 1473,
+	0, 0, 0, 0, 0, 0, 3182, 3183, 0, 0,
+	0, 0, 0, 0, 916, 0, 1505, 0, 0, 0,
+	1503, 1551, 1493, 1494, 1495, 1491, 1492, 1504, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 367, 368,
+	370, 369, 371, 372, 373, 374, 0, 375, 376, 0,
+	0, 0, 0, 0, 1543, 1509, 0, 0, 378, 0,
+	377, 0, 379, 380, 381, 926, 382, 383, 384, 385,
+	386, 387, 388, 389, 390, 857, 391, 1557, 0, 392,
+	1565, 393, 1564, 0, 1575, 394, 395, 396, 397, 398,
+	399, 400, 401, 402, 403, 404, 1511, 1542, 1475, 405,
+	1589, 1590, 864, 0, 406, 407, 408, 409, 1549, 0,
+	1530, 0, 410, 411, 412, 413, 414, 415, 416, 417,
+	0, 0, 419, 420, 421, 418, 422, 423, 0, 424,
+	0, 425, 426, 427, 428, 429, 0, 430, 431, 0,
+	432, 433, 434, 928, 435, 436, 437, 1533, 1531, 1532,
+	1539, 1535, 1534, 1538, 438, 439, 440, 441, 442, 1568,
+	443, 445, 1562, 1561, 1480, 448, 450, 444, 446, 0,
+	449, 447, 451, 452, 0, 453, 454, 455, 456, 457,
+	0, 0, 0, 458, 1560, 460, 461, 0, 462, 463,
+	464, 466, 465, 0, 467, 468, 469, 0, 470, 471,
+	1487, 472, 473, 474, 476, 478, 475, 477, 479, 480,
+	481, 482, 483, 1577, 1578, 484, 485, 1500, 362, 0,
+	0, 0, 0, 0, 486, 487, 488, 1559, 0, 0,
+	0, 489, 0, 491, 495, 496, 492, 493, 494, 497,
+	0, 490, 498, 499, 0, 929, 2654, 501, 502, 1573,
+	1574, 503, 504, 505, 506, 507, 508, 509, 510, 511,
+	0, 512, 513, 1584, 0, 1510, 514, 0, 515, 516,
+	517, 518, 519, 520, 521, 1544, 1545, 1548, 630, 931,
+	522, 523, 524, 525, 0, 526, 527, 528, 529, 530,
+	531, 532, 0, 0, 0, 533, 534, 535, 536, 0,
+	919, 363, 365, 930, 879, 537, 631, 538, 539, 1554,
+	1555, 0, 1514, 0, 540, 541, 544, 932, 1546, 933,
+	543, 545, 546, 934, 547, 0, 0, 0, 548, 549,
+	550, 551, 552, 553, 554, 0, 555, 557, 556, 0,
+	559, 1585, 558, 935, 560, 561, 936, 0, 562, 563,
+	564, 565, 566, 567, 572, 1537, 1536, 568, 569, 570,
+	571, 573, 574, 0, 575, 576, 578, 581, 577, 579,
+	580, 582, 583, 596, 597, 598, 584, 585, 586, 587,
+	588, 589, 590, 591, 592, 593, 594, 595, 600, 0,
+	599, 937, 0, 601, 602, 603, 604, 605, 606, 612,
+	615, 617, 618, 613, 614, 616, 619, 620, 621, 623,
+	624, 609, 610, 611, 938, 622, 607, 1477, 608, 366,
+	939, 625, 626, 627, 628, 1501, 1547, 629, 1563, 632,
+	633, 0, 0, 634, 0, 635, 636, 0, 0, 638,
+	639, 640, 0, 0, 641, 642, 887, 940, 643, 941,
+	1579, 644, 645, 1488, 646, 647, 648, 649, 650, 651,
+	652, 653, 654, 655, 656, 657, 0, 658, 659, 889,
+	660, 661, 662, 663, 664, 890, 665, 666, 667, 1580,
+	668, 892, 669, 670, 671, 0, 672, 673, 674, 0,
+	675, 676, 677, 678, 679, 680, 681, 682, 683, 684,
+	1558, 685, 686, 688, 687, 689, 690, 0, 691, 692,
+	0, 693, 694, 695, 0, 0, 0, 0, 0, 696,
+	697, 699, 0, 700, 701, 702, 703, 704, 705, 698,
+	706, 707, 708, 709, 710, 711, 712, 713, 0, 715,
+	716, 714, 717, 718, 942, 719, 720, 721, 722, 723,
+	1489, 724, 0, 725, 726, 734, 735, 736, 727, 728,
+	730, 737, 729, 738, 739, 740, 741, 743, 742, 0,
+	745, 746, 744, 747, 748, 749, 750, 1540, 751, 895,
+	752, 731, 732, 753, 754, 755, 943, 756, 757, 758,
+	759, 760, 761, 762, 763, 764, 1556, 0, 766, 0,
+	765, 767, 768, 769, 770, 771, 772, 773, 775, 733,
+	776, 777, 778, 783, 784, 785, 1588, 779, 780, 781,
+	782, 787, 1581, 788, 789, 790, 791, 0, 792, 793,
+	1474, 786, 774, 0, 794, 795, 796, 797, 798, 799,
+	800, 801, 802, 803, 0, 804, 1569, 1570, 1571, 1572,
+	0, 817, 0, 805, 807, 808, 809, 810, 1582, 811,
+	812, 1583, 1499, 813, 814, 815, 816, 806, 819, 820,
+	818, 0, 1481, 821, 822, 823, 824, 826, 828, 829,
+	830, 825, 827, 831, 1541, 832, 0, 0, 833, 834,
+	835, 905, 1566, 1587, 0, 1576, 838, 839, 836, 837,
+	840, 841, 844, 842, 843, 909, 847, 542, 848, 849,
+	850, 845, 846, 0, 0, 0, 0, 851, 852, 910,
+	853, 854, 855, 1478, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 1473,
+	0, 0, 0, 0, 0, 0, 1471, 1472, 0, 0,
+	0, 0, 0, 0, 916, 0, 1505, 0, 0, 0,
+	1503, 1551, 1493, 1494, 1495, 1491, 1492, 1504, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 367, 368,
+	370, 369, 371, 372, 373, 374, 0, 375, 376, 0,
+	0, 0, 0, 0, 1543, 1509, 0, 0, 378, 0,
+	377, 0, 379, 380, 381, 926, 382, 383, 384, 385,
+	386, 387, 388, 389, 390, 857, 391, 1557, 0, 392,
+	1565, 393, 1564, 0, 1575, 394, 395, 396, 397, 398,
+	399, 400, 401, 402, 403, 404, 1511, 1542, 0, 405,
+	1589, 1590, 864, 0, 406, 407, 408, 409, 1549, 0,
+	1530, 0, 410, 411, 412, 413, 414, 415, 416, 417,
+	0, 0, 419, 420, 421, 418, 422, 423, 0, 424,
+	0, 425, 426, 427, 428, 429, 0, 430, 431, 0,
+	432, 433, 434, 928, 435, 436, 437, 1533, 1531, 1532,
+	1539, 1535, 1534, 1538, 438, 439, 440, 441, 442, 1568,
+	443, 445, 1562, 1561, 0, 448, 450, 444, 446, 0,
+	449, 447, 451, 452, 0, 453, 454, 455, 456, 457,
+	0, 0, 0, 458, 1560, 460, 461, 0, 462, 463,
+	464, 466, 465, 0, 467, 468, 469, 0, 470, 471,
+	1487, 472, 473, 474, 476, 478, 475, 477, 479, 480,
+	481, 482, 483, 1577, 1578, 484, 485, 1500, 362, 0,
+	0, 0, 0, 0, 486, 487, 488, 1559, 0, 0,
+	0, 489, 0, 491, 495, 496, 492, 493, 494, 497,
+	0, 490, 498, 499, 0, 929, 500, 501, 502, 1573,
+	1574, 503, 504, 505, 506, 507, 508, 509, 510, 511,
+	0, 512, 513, 1584, 0, 1510, 514, 0, 515, 516,
+	517, 518, 519, 520, 521, 1544, 1545, 1548, 630, 931,
+	522, 523, 524, 525, 0, 526, 527, 528, 529, 530,
+	531, 532, 0, 0, 0, 533, 534, 535, 536, 0,
+	919, 363, 365, 930, 879, 537, 631, 538, 539, 1554,
+	1555, 0, 1514, 0, 540, 541, 544, 932, 1546, 933,
+	543, 545, 546, 934, 547, 0, 0, 0, 548, 549,
+	550, 551, 552, 553, 554, 0, 555, 557, 556, 0,
+	559, 1585, 558, 935, 560, 561, 936, 0, 562, 563,
+	564, 565, 566, 567, 572, 1537, 1536, 568, 569, 570,
+	571, 573, 574, 0, 575, 576, 578, 581, 577, 579,
+	580, 582, 583, 596, 597, 598, 584, 585, 586, 587,
+	588, 589, 590, 591, 592, 593, 594, 595, 600, 0,
+	599, 937, 0, 601, 602, 603, 604, 605, 606, 612,
+	615, 617, 618, 613, 614, 616, 619, 620, 621, 623,
+	624, 609, 610, 611, 938, 622, 607, 0, 608, 366,
+	939, 625, 626, 627, 628, 1501, 1547, 629, 1563, 632,
+	633, 0, 0, 634, 0, 635, 636, 0, 0, 638,
+	639, 640, 0, 0, 641, 642, 887, 940, 643, 941,
+	1579, 644, 645, 1488, 646, 647, 648, 649, 650, 651,
+	652, 653, 654, 655, 656, 657, 0, 658, 659, 889,
+	660, 661, 662, 663, 664, 890, 665, 666, 667, 1580,
+	668, 892, 669, 670, 671, 0, 672, 673, 674, 0,
+	675, 676, 677, 678, 679, 680, 681, 682, 683, 684,
+	1558, 685, 686, 688, 687, 689, 690, 0, 691, 692,
+	0, 693, 694, 695, 0, 0, 0, 0, 0, 696,
+	697, 699, 0, 700, 701, 702, 703, 704, 705, 698,
+	706, 707, 708, 709, 710, 711, 712, 713, 0, 715,
+	716, 714, 717, 718, 942, 719, 720, 721, 722, 723,
+	1489, 724, 0, 725, 726, 734, 735, 736, 727, 728,
+	730, 737, 729, 738, 739, 740, 741, 743, 742, 0,
+	745, 746, 744, 747, 748, 749, 750, 1540, 751, 895,
+	752, 731, 732, 753, 754, 755, 943, 756, 757, 758,
+	759, 760, 761, 762, 763, 764, 1556, 0, 766, 0,
+	765, 767, 768, 769, 770, 771, 772, 773, 775, 733,
+	776, 777, 778, 783, 784, 785, 1588, 779, 780, 781,
+	782, 787, 1581, 788, 789, 790, 791, 0, 792, 793,
+	0, 786, 774, 0, 794, 795, 796, 797, 798, 799,
+	800, 801, 802, 803, 0, 804, 1569, 1570, 1571, 1572,
+	0, 817, 0, 805, 807, 808, 809, 810, 1582, 811,
+	812, 1583, 1499, 813, 814, 815, 816, 806, 819, 820,
+	818, 0, 0, 821, 822, 823, 824, 826, 828, 829,
+	830, 825, 827, 831, 1541, 832, 0, 0, 833, 834,
+	835, 905, 1566, 1587, 0, 1576, 838, 839, 836, 837,
+	840, 841, 844, 842, 843, 909, 847, 542, 848, 849,
+	850, 845, 846, 0, 0, 0, 0, 851, 852, 910,
+	853, 854, 855, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 3450,
+	0, 0, 0, 0, 0, 0, 3448, 3449, 0, 0,
+	0, 0, 0, 0, 916, 0, 1505, 0, 0, 0,
+	1503, 1551, 1493, 1494, 1495, 1491, 1492, 1504, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 367, 368,
+	370, 369, 371, 372, 373, 374, 0, 375, 376, 0,
+	0, 0, 0, 0, 1543, 1509, 0, 0, 378, 0,
+	377, 0, 379, 380, 381, 926, 382, 383, 384, 385,
+	386, 387, 388, 389, 390, 857, 391, 1557, 0, 392,
+	1565, 393, 1564, 0, 1575, 394, 395, 396, 397, 398,
+	399, 400, 401, 402, 403, 404, 1511, 1542, 0, 405,
+	1589, 1590, 864, 0, 406, 407, 408, 409, 1549, 0,
+	1530, 0, 410, 411, 412, 413, 414, 415, 416, 417,
+	0, 0, 419, 420, 421, 418, 422, 423, 0, 424,
+	0, 425, 426, 427, 428, 429, 0, 430, 431, 0,
+	432, 433, 434, 928, 435, 436, 437, 1533, 1531, 1532,
+	1539, 1535, 1534, 1538, 438, 439, 440, 441, 442, 1568,
+	443, 445, 1562, 1561, 0, 448, 450, 444, 446, 0,
+	449, 447, 451, 452, 0, 453, 454, 455, 456, 457,
+	0, 0, 0, 458, 1560, 460, 461, 0, 462, 463,
+	464, 466, 465, 0, 467, 468, 469, 0, 470, 471,
+	1487, 472, 473, 474, 476, 478, 475, 477, 479, 480,
+	481, 482, 483, 1577, 1578, 484, 485, 1500, 362, 0,
+	0, 0, 0, 0, 486, 487, 488, 1559, 0, 0,
+	0, 489, 0, 491, 495, 496, 492, 493, 494, 497,
+	0, 490, 498, 499, 0, 929, 500, 501, 502, 1573,
+	1574, 503, 504, 505, 506, 507, 508, 509, 510, 511,
+	0, 512, 513, 1584, 0, 1510, 514, 0, 515, 516,
+	517, 518, 519, 520, 521, 1544, 1545, 1548, 630, 931,
+	522, 523, 524, 525, 0, 526, 527, 528, 529, 530,
+	531, 532, 0, 0, 0, 533, 534, 535, 536, 0,
+	919, 363, 365, 930, 879, 537, 631, 538, 539, 1554,
+	1555, 0, 1514, 0, 540, 541, 544, 932, 1546, 933,
+	543, 545, 546, 934, 547, 0, 0, 0, 548, 549,
+	550, 551, 552, 553, 554, 0, 555, 557, 556, 0,
+	559, 1585, 558, 935, 560, 561, 936, 0, 562, 563,
+	564, 565, 566, 567, 572, 1537, 1536, 568, 569, 570,
+	571, 573, 574, 0, 575, 576, 578, 581, 577, 579,
+	580, 582, 583, 596, 597, 598, 584, 585, 586, 587,
+	588, 589, 590, 591, 592, 593, 594, 595, 600, 0,
+	599, 937, 0, 601, 602, 603, 604, 605, 606, 612,
+	615, 617, 618, 613, 614, 616, 619, 620, 621, 623,
+	624, 609, 610, 611, 938, 622, 607, 0, 608, 366,
+	939, 625, 626, 627, 628, 1501, 1547, 629, 1563, 632,
+	633, 0, 0, 634, 0, 635, 636, 0, 0, 638,
+	639, 640, 0, 0, 641, 642, 887, 940, 643, 941,
+	1579, 644, 645, 637, 646, 647, 648, 649, 650, 651,
+	652, 653, 654, 655, 656, 657, 0, 658, 659, 889,
+	660, 661, 662, 663, 664, 890, 665, 666, 667, 1580,
+	668, 892, 669, 670, 671, 0, 672, 673, 674, 0,
+	675, 676, 677, 678, 679, 680, 681, 682, 683, 684,
+	1558, 685, 686, 688, 687, 689, 690, 0, 691, 692,
+	0, 693, 694, 695, 0, 0, 0, 0, 0, 696,
+	697, 699, 0, 700, 701, 702, 703, 704, 705, 698,
+	706, 707, 708, 709, 710, 711, 712, 713, 0, 715,
+	716, 714, 717, 718, 942, 719, 720, 721, 722, 723,
+	4738, 4739, 0, 725, 726, 734, 735, 736, 727, 728,
+	730, 737, 729, 738, 739, 740, 741, 743, 742, 0,
+	745, 746, 744, 747, 748, 749, 750, 1540, 751, 895,
+	752, 731, 732, 753, 754, 755, 943, 756, 757, 758,
+	759, 760, 761, 762, 763, 764, 1556, 0, 766, 0,
+	765, 767, 768, 769, 770, 771, 772, 773, 775, 733,
+	776, 777, 778, 783, 784, 785, 1588, 779, 780, 781,
+	782, 787, 1581, 788, 789, 790, 791, 0, 792, 793,
+	0, 786, 774, 0, 794, 795, 796, 797, 798, 799,
+	800, 801, 802, 803, 0, 804, 1569, 1570, 1571, 1572,
+	0, 817, 0, 805, 807, 808, 809, 810, 1582, 811,
+	812, 1583, 1499, 813, 814, 815, 816, 806, 819, 820,
+	818, 0, 0, 821, 822, 823, 824, 826, 828, 829,
+	830, 825, 827, 831, 1541, 832, 0, 0, 833, 834,
+	835, 905, 1566, 1587, 0, 1576, 838, 839, 836, 837,
+	840, 841, 844, 842, 843, 909, 847, 542, 848, 849,
+	850, 845, 846, 0, 0, 0, 0, 851, 852, 910,
+	853, 854, 855, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 2695, 2696, 0, 0,
+	0, 0, 0, 0, 916, 0, 1505, 0, 0, 0,
+	1503, 1551, 1493, 1494, 1495, 1491, 1492, 1504, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 367, 368,
+	370, 369, 371, 372, 373, 374, 0, 375, 376, 0,
+	0, 0, 0, 0, 1543, 1509, 0, 0, 378, 0,
+	377, 0, 379, 380, 381, 926, 382, 383, 384, 385,
+	386, 387, 388, 389, 390, 0, 391, 1557, 0, 392,
+	1565, 393, 1564, 0, 1575, 394, 395, 396, 397, 398,
+	399, 400, 401, 402, 403, 404, 1511, 1542, 1475, 405,
+	1589, 1590, 864, 0, 406, 407, 408, 409, 1549, 0,
+	1530, 0, 410, 411, 412, 413, 414, 415, 416, 417,
+	0, 0, 419, 420, 421, 418, 422, 423, 0, 424,
+	0, 425, 426, 427, 428, 429, 0, 430, 431, 0,
+	432, 433, 434, 928, 435, 436, 7049, 1533, 1531, 1532,
+	1539, 1535, 1534, 1538, 438, 439, 440, 441, 442, 1568,
+	443, 445, 1562, 1561, 1480, 448, 450, 444, 446, 0,
+	449, 447, 451, 452, 0, 453, 454, 455, 456, 457,
+	0, 0, 0, 458, 1560, 460, 461, 0, 462, 463,
+	464, 466, 465, 0, 467, 468, 469, 0, 470, 471,
+	1487, 472, 473, 474, 476, 478, 475, 477, 479, 480,
+	481, 482, 483, 1577, 1578, 484, 485, 1500, 362, 0,
+	0, 0, 0, 0, 486, 487, 488, 1559, 0, 0,
+	0, 489, 0, 491, 495, 496, 492, 493, 494, 497,
+	0, 490, 498, 499, 0, 929, 500, 501, 502, 1573,
+	1574, 503, 504, 505, 506, 507, 508, 509, 510, 511,
+	0, 512, 513, 1584, 0, 1510, 514, 0, 515, 516,
+	517, 518, 519, 520, 521, 1544, 1545, 1548, 630, 0,
+	522, 523, 524, 525, 0, 526, 527, 528, 529, 530,
+	531, 532, 0, 0, 0, 533, 534, 535, 536, 0,
+	919, 363, 365, 930, 879, 537, 631, 538, 539, 1554,
+	1555, 0, 1514, 0, 540, 541, 544, 0, 1546, 0,
+	543, 545, 546, 934, 547, 0, 0, 0, 548, 549,
+	550, 551, 552, 553, 554, 0, 555, 557, 556, 0,
+	559, 1585, 558, 935, 560, 561, 0, 0, 562, 563,
+	564, 565, 566, 567, 572, 1537, 1536, 568, 569, 570,
+	571, 573, 574, 0, 575, 576, 578, 581, 577, 579,
+	580, 582, 583, 596, 597, 598, 584, 585, 586, 587,
+	588, 589, 590, 591, 592, 593, 594, 595, 600, 0,
+	599, 937, 0, 601, 602, 603, 604, 605, 606, 612,
+	615, 617, 618, 613, 614, 616, 619, 620, 621, 623,
+	624, 609, 610, 611, 938, 622, 607, 1477, 608, 366,
+	0, 625, 626, 627, 628, 1501, 1547, 629, 1563, 632,
+	633, 0, 0, 634, 0, 635, 636, 0, 0, 638,
+	639, 640, 0, 0, 641, 642, 887, 940, 643, 941,
+	1579, 644, 645, 1488, 646, 647, 648, 649, 650, 651,
+	652, 653, 654, 655, 656, 657, 0, 658, 659, 889,
+	660, 661, 662, 663, 664, 890, 665, 666, 667, 1580,
+	668, 892, 669, 670, 671, 0, 672, 673, 674, 0,
+	675, 676, 677, 678, 679, 680, 681, 682, 683, 684,
+	1558, 685, 686, 688, 687, 689, 690, 0, 691, 692,
+	0, 693, 694, 695, 0, 0, 0, 0, 0, 696,
+	697, 699, 0, 700, 701, 702, 703, 704, 705, 698,
+	706, 707, 708, 709, 710, 711, 712, 713, 0, 715,
+	716, 714, 717, 718, 942, 719, 720, 721, 722, 723,
+	1489, 724, 0, 725, 726, 734, 735, 736, 727, 728,
+	730, 737, 729, 738, 739, 740, 741, 743, 742, 0,
+	745, 746, 744, 747, 748, 749, 750, 1540, 751, 895,
+	752, 731, 732, 753, 754, 755, 0, 756, 757, 758,
+	759, 760, 761, 762, 763, 764, 1556, 0, 766, 0,
+	765, 767, 768, 769, 770, 771, 772, 773, 775, 733,
+	776, 777, 778, 783, 784, 785, 1588, 779, 780, 781,
+	782, 787, 1581, 788, 789, 790, 791, 0, 792, 793,
+	1474, 786, 774, 0, 794, 795, 796, 797, 798, 799,
+	800, 801, 802, 803, 0, 804, 1569, 1570, 1571, 1572,
+	0, 817, 0, 805, 807, 808, 809, 810, 1582, 811,
+	812, 1583, 1499, 813, 814, 815, 816, 806, 7048, 820,
+	818, 0, 1481, 821, 822, 823, 824, 826, 828, 829,
+	830, 825, 827, 831, 1541, 832, 0, 0, 833, 834,
+	835, 905, 1566, 1587, 0, 1576, 838, 839, 836, 837,
+	840, 841, 844, 842, 843, 909, 847, 542, 848, 849,
+	850, 845, 846, 0, 0, 0, 0, 851, 852, 910,
+	853, 854, 855, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 1471, 1472, 0, 0,
+	0, 0, 0, 0, 916, 0, 1505, 0, 0, 3469,
+	1503, 1551, 1493, 1494, 1495, 1491, 1492, 1504, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 367, 368,
+	370, 369, 371, 372, 373, 374, 0, 375, 376, 0,
+	0, 0, 0, 0, 1543, 1509, 0, 0, 378, 0,
+	377, 0, 379, 380, 381, 926, 382, 383, 384, 385,
+	386, 387, 388, 389, 390, 857, 391, 1557, 0, 392,
+	1565, 393, 1564, 0, 1575, 394, 395, 396, 397, 398,
+	399, 400, 401, 402, 403, 404, 0, 1542, 0, 405,
+	1589, 1590, 864, 0, 406, 407, 408, 409, 1549, 0,
+	1530, 0, 410, 411, 412, 413, 414, 415, 416, 417,
+	0, 0, 419, 420, 421, 418, 422, 423, 0, 424,
+	0, 425, 426, 427, 428, 429, 0, 430, 431, 0,
+	432, 433, 434, 928, 435, 436, 437, 1533, 1531, 1532,
+	1539, 1535, 1534, 1538, 438, 439, 440, 441, 442, 1568,
+	443, 445, 1562, 1561, 0, 448, 450, 444, 446, 0,
+	449, 447, 451, 452, 0, 453, 454, 455, 456, 457,
+	0, 0, 0, 458, 1560, 460, 461, 0, 462, 463,
+	464, 466, 465, 0, 467, 468, 469, 0, 470, 471,
+	868, 472, 473, 474, 476, 478, 475, 477, 479, 480,
+	481, 482, 483, 1577, 1578, 484, 485, 1500, 362, 0,
+	0, 0, 0, 0, 486, 487, 488, 1559, 0, 0,
+	0, 489, 0, 491, 495, 496, 492, 493, 494, 497,
+	0, 490, 498, 499, 0, 929, 500, 501, 502, 1573,
+	1574, 503, 504, 505, 506, 507, 508, 509, 510, 511,
+	0, 512, 513, 1584, 0, 1510, 514, 0, 515, 516,
+	517, 518, 519, 520, 521, 1544, 1545, 1548, 630, 931,
+	522, 523, 524, 525, 0, 526, 527, 528, 529, 530,
+	531, 532, 0, 0, 0, 533, 534, 535, 536, 0,
+	919, 363, 365, 930, 879, 537, 631, 538, 539, 1554,
+	1555, 0, 1514, 0, 540, 541, 544, 932, 1546, 933,
+	543, 545, 546, 934, 547, 0, 0, 0, 548, 549,
+	550, 551, 552, 553, 554, 0, 555, 557, 556, 0,
+	559, 1585, 558, 935, 560, 561, 936, 0, 562, 563,
+	564, 565, 566, 567, 572, 1537, 1536, 568, 569, 570,
+	571, 573, 574, 0, 575, 576, 578, 581, 577, 579,
+	580, 582, 583, 596, 597, 598, 584, 585, 586, 587,
+	588, 589, 590, 591, 592, 593, 594, 595, 600, 0,
+	599, 937, 0, 601, 602, 603, 604, 605, 606, 612,
+	615, 617, 618, 613, 614, 616, 619, 620, 621, 623,
+	624, 609, 610, 611, 938, 622, 607, 0, 608, 366,
+	939, 625, 626, 627, 628, 1501, 1547, 629, 1563, 632,
+	633, 0, 0, 634, 0, 635, 636, 0, 0, 638,
+	639, 640, 0, 0, 641, 642, 887, 940, 643, 941,
+	1579, 644, 645, 637, 646, 647, 648, 649, 650, 651,
+	652, 653, 654, 655, 656, 657, 0, 658, 659, 889,
+	660, 661, 662, 663, 664, 890, 665, 666, 667, 1580,
+	668, 892, 669, 670, 671, 0, 672, 673, 674, 0,
+	675, 676, 677, 678, 679, 680, 681, 682, 683, 684,
+	1558, 685, 686, 688, 687, 689, 690, 0, 691, 692,
+	0, 693, 694, 695, 0, 0, 0, 0, 0, 696,
+	697, 699, 0, 700, 701, 702, 703, 704, 705, 698,
+	706, 707, 708, 709, 710, 711, 712, 713, 0, 715,
+	716, 714, 717, 718, 942, 719, 720, 721, 722, 723,
+	1489, 724, 0, 725, 726, 734, 735, 736, 727, 728,
+	730, 737, 729, 738, 739, 740, 741, 743, 742, 0,
+	745, 746, 744, 747, 748, 749, 750, 1540, 751, 895,
+	752, 731, 732, 753, 754, 755, 943, 756, 757, 758,
+	759, 760, 761, 762, 763, 764, 1556, 0, 766, 0,
+	765, 767, 768, 769, 770, 771, 772, 773, 775, 733,
+	776, 777, 778, 783, 784, 785, 1588, 779, 780, 781,
+	782, 787, 1581, 788, 789, 790, 791, 0, 792, 793,
+	0, 786, 774, 0, 794, 795, 796, 797, 798, 799,
+	800, 801, 802, 803, 0, 804, 1569, 1570, 1571, 1572,
+	0, 817, 0, 805, 807, 808, 809, 810, 1582, 811,
+	812, 1583, 1499, 813, 814, 815, 816, 806, 819, 820,
+	818, 0, 0, 821, 822, 823, 824, 826, 828, 829,
+	830, 825, 827, 831, 1541, 832, 0, 0, 833, 834,
+	835, 905, 1566, 1587, 0, 1576, 838, 839, 836, 837,
+	840, 841, 844, 842, 843, 909, 847, 542, 848, 849,
+	850, 845, 846, 0, 0, 0, 0, 851, 852, 910,
+	853, 854, 855, 2158, 0, 1551, 1493, 1494, 1495, 1491,
+	1492, 1504, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 367, 368, 370, 369, 371, 372, 373, 374,
+	0, 375, 376, 0, 1736, 0, 1505, 0, 1543, 1509,
+	1503, 0, 378, 0, 377, 0, 379, 380, 381, 926,
+	382, 383, 384, 385, 386, 387, 388, 389, 390, 857,
+	391, 1557, 0, 392, 1565, 393, 1564, 0, 1575, 394,
+	395, 396, 397, 398, 399, 400, 401, 402, 403, 404,
+	0, 1542, 0, 405, 1589, 1590, 864, 0, 406, 407,
+	408, 409, 1549, 0, 1530, 0, 410, 411, 412, 413,
+	414, 415, 416, 417, 0, 0, 419, 420, 421, 418,
+	422, 423, 0, 424, 0, 425, 426, 427, 428, 429,
+	0, 430, 431, 0, 432, 433, 434, 928, 435, 436,
+	437, 1533, 1531, 1532, 1539, 1535, 1534, 1538, 438, 439,
+	440, 441, 442, 1568, 443, 445, 1562, 1561, 0, 448,
+	450, 444, 446, 0, 449, 447, 451, 452, 0, 453,
+	454, 455, 456, 457, 0, 0, 0, 458, 1560, 460,
+	461, 0, 462, 463, 464, 466, 465, 0, 467, 468,
+	469, 0, 470, 471, 868, 472, 473, 474, 476, 478,
+	475, 477, 479, 480, 481, 482, 483, 1577, 1578, 484,
+	485, 1500, 362, 0, 0, 0, 0, 0, 486, 487,
+	488, 1559, 0, 0, 0, 489, 0, 491, 495, 496,
+	492, 493, 494, 497, 0, 490, 498, 499, 0, 929,
+	500, 501, 502, 1573, 1574, 503, 504, 505, 506, 507,
+	508, 509, 510, 511, 0, 512, 513, 1584, 0, 1510,
+	514, 0, 515, 516, 517, 518, 519, 520, 521, 2157,
+	1545, 1548, 630, 931, 522, 523, 524, 525, 0, 526,
+	527, 528, 529, 530, 531, 532, 0, 0, 0, 533,
+	534, 535, 536, 0, 919, 363, 365, 930, 879, 537,
+	631, 538, 539, 1554, 1555, 0, 1514, 0, 540, 541,
+	544, 932, 1546, 933, 543, 545, 546, 934, 547, 0,
+	0, 0, 548, 549, 550, 551, 552, 553, 554, 0,
+	555, 557, 556, 0, 559, 1585, 558, 935, 560, 561,
+	936, 0, 562, 563, 564, 565, 566, 567, 572, 1537,
+	1536, 568, 569, 570, 571, 573, 574, 0, 575, 576,
+	578, 581, 577, 579, 580, 582, 583, 596, 597, 598,
+	584, 585, 586, 587, 588, 589, 590, 591, 592, 593,
+	594, 595, 600, 0, 599, 937, 0, 601, 602, 603,
+	604, 605, 606, 612, 615, 617, 618, 613, 614, 616,
+	619, 620, 621, 623, 624, 609, 610, 611, 938, 622,
+	607, 0, 608, 366, 939, 625, 626, 627, 628, 1501,
+	1547, 629, 1563, 632, 633, 0, 0, 634, 0, 635,
+	636, 0, 0, 638, 639, 640, 0, 0, 641, 642,
+	887, 940, 643, 941, 1579, 644, 645, 637, 646, 647,
+	648, 649, 650, 651, 652, 653, 654, 655, 656, 657,
+	0, 658, 659, 889, 660, 661, 662, 663, 664, 890,
+	665, 666, 667, 1580, 668, 892, 669, 670, 671, 0,
+	672, 673, 674, 0, 675, 676, 677, 678, 679, 680,
+	681, 682, 683, 684, 1558, 685, 686, 688, 687, 689,
+	690, 0, 691, 692, 0, 693, 694, 695, 0, 0,
+	0, 0, 0, 696, 697, 699, 0, 700, 701, 702,
+	703, 704, 705, 698, 706, 707, 708, 709, 710, 711,
+	712, 713, 0, 715, 716, 714, 717, 718, 942, 719,
+	720, 721, 722, 723, 1489, 724, 0, 725, 726, 734,
+	735, 736, 727, 728, 730, 737, 729, 738, 739, 740,
+	741, 743, 742, 0, 745, 746, 744, 747, 748, 749,
+	750, 1540, 751, 895, 752, 731, 732, 753, 754, 755,
+	943, 756, 757, 758, 759, 760, 761, 762, 763, 764,
+	1556, 0, 766, 0, 765, 767, 768, 769, 770, 771,
+	772, 773, 775, 733, 776, 777, 778, 783, 784, 785,
+	1588, 779, 780, 781, 782, 787, 1581, 788, 789, 790,
+	791, 0, 792, 793, 0, 786, 774, 0, 794, 795,
+	796, 797, 798, 799, 800, 801, 802, 803, 0, 804,
+	1569, 1570, 1571, 1572, 0, 817, 0, 805, 807, 808,
+	809, 810, 1582, 811, 812, 1583, 1499, 813, 814, 815,
+	816, 806, 819, 820, 818, 0, 0, 821, 822, 823,
+	824, 826, 828, 829, 830, 825, 827, 831, 1541, 832,
+	0, 0, 833, 834, 835, 905, 1566, 1587, 0, 1576,
+	838, 839, 836, 837, 840, 841, 844, 842, 843, 909,
+	847, 542, 848, 849, 850, 845, 846, 0, 0, 0,
+	0, 851, 852, 910, 853, 854, 855, 2104, 0, 1551,
+	1493, 1494, 1495, 1491, 1492, 1504, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 367, 368, 370, 369,
+	371, 372, 373, 374, 0, 375, 376, 0, 1736, 0,
+	1505, 0, 1543, 1509, 1503, 0, 378, 0, 377, 0,
+	379, 380, 381, 926, 382, 383, 384, 385, 386, 387,
+	388, 389, 390, 857, 391, 1557, 0, 392, 1565, 393,
+	1564, 0, 1575, 394, 395, 396, 397, 398, 399, 400,
+	401, 402, 403, 404, 0, 1542, 0, 405, 1589, 1590,
+	864, 0, 406, 407, 408, 409, 1549, 0, 1530, 0,
+	410, 411, 412, 413, 414, 415, 416, 417, 0, 0,
+	419, 420, 421, 418, 422, 423, 0, 424, 0, 425,
+	426, 427, 428, 429, 0, 430, 431, 0, 432, 433,
+	434, 928, 435, 436, 437, 1533, 1531, 1532, 1539, 1535,
+	1534, 1538, 438, 439, 440, 441, 442, 1568, 443, 445,
+	1562, 1561, 0, 448, 450, 444, 446, 0, 449, 447,
+	451, 452, 0, 453, 454, 455, 456, 457, 0, 0,
+	0, 458, 1560, 460, 461, 0, 462, 463, 464, 466,
+	465, 0, 467, 468, 469, 0, 470, 471, 868, 472,
+	473, 474, 476, 478, 475, 477, 479, 480, 481, 482,
+	483, 1577, 1578, 484, 485, 1500, 362, 0, 0, 0,
+	0, 0, 486, 487, 488, 1559, 0, 0, 0, 489,
+	0, 491, 495, 496, 492, 493, 494, 497, 0, 490,
+	498, 499, 0, 929, 500, 501, 502, 1573, 1574, 503,
+	504, 505, 506, 507, 508, 509, 510, 511, 0, 512,
+	513, 1584, 0, 1510, 514, 0, 515, 516, 517, 518,
+	519, 520, 521, 1544, 1545, 1548, 630, 931, 522, 523,
+	524, 525, 0, 526, 527, 528, 529, 530, 531, 532,
+	0, 0, 0, 533, 534, 535, 536, 0, 919, 363,
+	365, 930, 879, 537, 631, 538, 539, 1554, 1555, 0,
+	1514, 0, 540, 541, 544, 932, 1546, 933, 543, 545,
+	546, 934, 547, 0, 0, 0, 548, 549, 550, 551,
+	552, 553, 554, 0, 555, 557, 556, 0, 559, 1585,
+	558, 935, 560, 561, 936, 0, 562, 563, 564, 565,
+	566, 567, 572, 1537, 1536, 568, 569, 570, 571, 573,
+	574, 0, 575, 576, 578, 581, 577, 579, 580, 582,
+	583, 596, 597, 598, 584, 585, 586, 587, 588, 589,
+	590, 591, 592, 593, 594, 595, 600, 0, 599, 937,
+	0, 601, 602, 603, 604, 605, 606, 612, 615, 617,
+	618, 613, 614, 616, 619, 620, 621, 623, 624, 609,
+	610, 611, 938, 622, 607, 0, 608, 366, 939, 625,
+	626, 627, 628, 1501, 1547, 629, 1563, 632, 633, 0,
+	0, 634, 0, 635, 636, 0, 0, 638, 639, 640,
+	0, 0, 641, 642, 887, 940, 643, 941, 1579, 644,
+	645, 637, 646, 647, 648, 649, 650, 651, 652, 653,
+	654, 655, 656, 657, 0, 658, 659, 889, 660, 661,
+	662, 663, 664, 890, 665, 666, 667, 1580, 668, 892,
+	669, 670, 671, 0, 672, 673, 674, 0, 675, 676,
+	677, 678, 679, 680, 681, 682, 683, 684, 1558, 685,
+	686, 688, 687, 689, 690, 0, 691, 692, 0, 693,
+	694, 695, 0, 0, 0, 0, 0, 696, 697, 699,
+	0, 700, 701, 702, 703, 704, 705, 698, 706, 707,
+	708, 709, 710, 711, 712, 713, 0, 715, 716, 714,
+	717, 718, 942, 719, 720, 721, 722, 723, 1489, 724,
+	0, 725, 726, 734, 735, 736, 727, 728, 730, 737,
+	729, 738, 739, 740, 741, 743, 742, 0, 745, 746,
+	744, 747, 748, 749, 750, 1540, 751, 895, 752, 731,
+	732, 753, 754, 755, 943, 756, 757, 758, 759, 760,
+	761, 762, 763, 764, 1556, 0, 766, 0, 765, 767,
+	768, 769, 770, 771, 772, 773, 775, 733, 776, 777,
+	778, 783, 784, 785, 1588, 779, 780, 781, 782, 787,
+	1581, 788, 789, 790, 791, 0, 792, 793, 0, 786,
+	774, 0, 794, 795, 796, 797, 798, 799, 800, 801,
+	802, 803, 0, 804, 1569, 1570, 1571, 1572, 0, 817,
+	0, 805, 807, 808, 809, 810, 1582, 811, 812, 1583,
+	1499, 813, 814, 815, 816, 806, 819, 820, 818, 0,
+	0, 821, 822, 823, 824, 826, 828, 829, 830, 825,
+	827, 831, 1541, 832, 0, 0, 833, 834, 835, 905,
+	1566, 1587, 0, 1576, 838, 839, 836, 837, 840, 841,
+	844, 842, 843, 909, 847, 542, 848, 849, 850, 845,
+	846, 0, 0, 0, 0, 851, 852, 910, 853, 854,
+	855, 1734, 0, 1551, 1493, 1494, 1495, 1491, 1492, 1504,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	367, 368, 370, 369, 371, 372, 373, 374, 0, 375,
+	376, 0, 1736, 0, 1505, 0, 1543, 1509, 1503, 0,
+	378, 0, 377, 0, 379, 380, 381, 926, 382, 383,
+	384, 385, 386, 387, 388, 389, 390, 857, 391, 1557,
+	0, 392, 1565, 393, 1564, 0, 1575, 394, 395, 396,
+	397, 398, 399, 400, 401, 402, 403, 404, 0, 1542,
+	0, 405, 1589, 1590, 864, 0, 406, 407, 408, 409,
+	1549, 0, 1530, 0, 410, 411, 412, 413, 414, 415,
+	416, 417, 0, 0, 419, 420, 421, 418, 422, 423,
+	0, 424, 0, 425, 426, 427, 428, 429, 0, 430,
+	431, 0, 432, 433, 434, 928, 435, 436, 437, 1533,
+	1531, 1532, 1539, 1535, 1534, 1538, 438, 439, 440, 441,
+	442, 1568, 443, 445, 1562, 1561, 0, 448, 450, 444,
+	446, 0, 449, 447, 451, 452, 0, 453, 454, 455,
+	456, 457, 0, 0, 0, 458, 1560, 460, 461, 0,
+	462, 463, 464, 466, 465, 0, 467, 468, 469, 0,
+	470, 471, 868, 472, 473, 474, 476, 478, 475, 477,
+	479, 480, 481, 482, 483, 1577, 1578, 484, 485, 1500,
+	362, 0, 0, 0, 0, 0, 486, 487, 488, 1559,
+	0, 0, 0, 489, 0, 491, 495, 496, 492, 493,
+	494, 497, 0, 490, 498, 499, 0, 929, 500, 501,
+	502, 1573, 1574, 503, 504, 505, 506, 507, 508, 509,
+	510, 511, 0, 512, 513, 1584, 0, 1510, 514, 0,
+	515, 516, 517, 518, 519, 520, 521, 1733, 1545, 1548,
+	630, 931, 522, 523, 524, 525, 0, 526, 527, 528,
+	529, 530, 531, 532, 0, 0, 0, 533, 534, 535,
+	536, 0, 919, 363, 365, 930, 879, 537, 631, 538,
+	539, 1554, 1555, 0, 1514, 0, 540, 541, 544, 932,
+	1546, 933, 543, 545, 546, 934, 547, 0, 0, 0,
+	548, 549, 550, 551, 552, 553, 554, 0, 555, 557,
+	556, 0, 559, 1585, 558, 935, 560, 561, 936, 0,
+	562, 563, 564, 565, 566, 567, 572, 1537, 1536, 568,
+	569, 570, 571, 573, 574, 0, 575, 576, 578, 581,
+	577, 579, 580, 582, 583, 596, 597, 598, 584, 585,
+	586, 587, 588, 589, 590, 591, 592, 593, 594, 595,
+	600, 0, 599, 937, 0, 601, 602, 603, 604, 605,
+	606, 612, 615, 617, 618, 613, 614, 616, 619, 620,
+	621, 623, 624, 609, 610, 611, 938, 622, 607, 0,
+	608, 366, 939, 625, 626, 627, 628, 1501, 1547, 629,
+	1563, 632, 633, 0, 0, 634, 0, 635, 636, 0,
+	0, 638, 639, 640, 0, 0, 641, 642, 887, 940,
+	643, 941, 1579, 644, 645, 637, 646, 647, 648, 649,
+	650, 651, 652, 653, 654, 655, 656, 657, 0, 658,
+	659, 889, 660, 661, 662, 663, 664, 890, 665, 666,
+	667, 1580, 668, 892, 669, 670, 671, 0, 672, 673,
+	674, 0, 675, 676, 677, 678, 679, 680, 681, 682,
+	683, 684, 1558, 685, 686, 688, 687, 689, 690, 0,
+	691, 692, 0, 693, 694, 695, 0, 0, 0, 0,
+	0, 696, 697, 699, 0, 700, 701, 702, 703, 704,
+	705, 698, 706, 707, 708, 709, 710, 711, 712, 713,
+	0, 715, 716, 714, 717, 718, 942, 719, 720, 721,
+	722, 723, 1489, 724, 0, 725, 726, 734, 735, 736,
+	727, 728, 730, 737, 729, 738, 739, 740, 741, 743,
+	742, 0, 745, 746, 744, 747, 748, 749, 750, 1540,
+	751, 895, 752, 731, 732, 753, 754, 755, 943, 756,
+	757, 758, 759, 760, 761, 762, 763, 764, 1556, 0,
+	766, 0, 765, 767, 768, 769, 770, 771, 772, 773,
+	775, 733, 776, 777, 778, 783, 784, 785, 1588, 779,
+	780, 781, 782, 787, 1581, 788, 789, 790, 791, 0,
+	792, 793, 0, 786, 774, 0, 794, 795, 796, 797,
+	798, 799, 800, 801, 802, 803, 0, 804, 1569, 1570,
+	1571, 1572, 0, 817, 0, 805, 807, 808, 809, 810,
+	1582, 811, 812, 1583, 1499, 813, 814, 815, 816, 806,
+	819, 820, 818, 0, 0, 821, 822, 823, 824, 826,
+	828, 829, 830, 825, 827, 831, 1541, 832, 0, 0,
+	833, 834, 835, 905, 1566, 1587, 0, 1576, 838, 839,
+	836, 837, 840, 841, 844, 842, 843, 909, 847, 542,
+	848, 849, 850, 845, 846, 0, 0, 0, 0, 851,
+	852, 910, 853, 854, 855, 0, 1551, 1493, 1494, 1495,
+	1491, 1492, 1504, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 367, 368, 370, 369, 371, 372, 373,
+	374, 0, 375, 376, 0, 0, 1736, 0, 1505, 1543,
+	1509, 0, 1503, 378, 0, 377, 0, 379, 380, 381,
+	926, 382, 383, 384, 385, 386, 387, 388, 389, 390,
+	857, 391, 1557, 0, 392, 1565, 393, 1564, 0, 1575,
+	394, 395, 396, 397, 398, 399, 400, 401, 402, 403,
+	404, 0, 1542, 0, 405, 1589, 1590, 864, 0, 406,
+	407, 408, 409, 1549, 0, 1530, 0, 410, 411, 412,
+	413, 414, 415, 416, 417, 0, 0, 419, 420, 421,
+	418, 422, 423, 0, 424, 0, 425, 426, 427, 428,
+	429, 0, 430, 431, 0, 432, 433, 434, 928, 435,
+	436, 437, 1533, 1531, 1532, 1539, 1535, 1534, 1538, 438,
+	439, 440, 441, 442, 1568, 443, 445, 1562, 1561, 0,
+	448, 450, 444, 446, 0, 449, 447, 451, 452, 0,
+	453, 454, 455, 456, 457, 0, 0, 0, 458, 1560,
+	460, 461, 0, 462, 463, 464, 466, 465, 0, 467,
+	468, 469, 0, 470, 471, 868, 472, 473, 474, 476,
+	478, 475, 477, 479, 480, 481, 482, 483, 1577, 1578,
+	484, 485, 1500, 362, 0, 0, 0, 0, 0, 486,
+	487, 488, 1559, 0, 0, 0, 489, 0, 491, 495,
+	496, 492, 493, 494, 497, 0, 490, 498, 499, 0,
+	929, 500, 501, 502, 1573, 1574, 503, 504, 505, 506,
+	507, 508, 509, 510, 511, 0, 512, 513, 1584, 0,
+	1510, 514, 0, 515, 516, 517, 518, 519, 520, 521,
+	1544, 1545, 1548, 630, 931, 522, 523, 524, 525, 0,
+	526, 527, 528, 529, 530, 531, 532, 0, 0, 0,
+	533, 534, 535, 536, 0, 919, 363, 365, 930, 879,
+	537, 631, 538, 539, 1554, 1555, 0, 1514, 0, 540,
+	541, 544, 932, 1546, 933, 543, 545, 546, 934, 547,
+	0, 0, 0, 548, 549, 550, 551, 552, 553, 554,
+	0, 555, 557, 556, 0, 559, 1585, 558, 935, 560,
+	561, 936, 0, 562, 563, 564, 565, 566, 567, 572,
+	1537, 1536, 568, 569, 570, 571, 573, 574, 0, 575,
+	576, 578, 581, 577, 579, 580, 582, 583, 596, 597,
+	598, 584, 585, 586, 587, 588, 589, 590, 591, 592,
+	593, 594, 595, 600, 0, 599, 937, 0, 601, 602,
+	603, 604, 605, 606, 612, 615, 617, 618, 613, 614,
+	616, 619, 620, 621, 623, 624, 609, 610, 611, 938,
+	622, 607, 0, 608, 366, 939, 625, 626, 627, 628,
+	1501, 1547, 629, 1563, 632, 633, 0, 0, 634, 0,
+	635, 636, 0, 0, 638, 639, 640, 0, 0, 641,
+	642, 887, 940, 643, 941, 1579, 644, 645, 637, 646,
+	647, 648, 649, 650, 651, 652, 653, 654, 655, 656,
+	657, 0, 658, 659, 889, 660, 661, 662, 663, 664,
+	890, 665, 666, 667, 1580, 668, 892, 669, 670, 671,
+	0, 672, 673, 674, 0, 675, 676, 677, 678, 679,
+	680, 681, 682, 683, 684, 1558, 685, 686, 688, 687,
+	689, 690, 0, 691, 692, 0, 693, 694, 695, 0,
+	0, 0, 0, 0, 696, 697, 699, 0, 700, 701,
+	702, 703, 704, 705, 698, 706, 707, 708, 709, 710,
+	711, 712, 713, 0, 715, 716, 714, 717, 718, 942,
+	719, 720, 721, 722, 723, 1489, 724, 0, 725, 726,
+	734, 735, 736, 727, 728, 730, 737, 729, 738, 739,
+	740, 741, 743, 742, 0, 745, 746, 744, 747, 748,
+	749, 750, 1540, 751, 895, 752, 731, 732, 753, 754,
+	755, 943, 756, 757, 758, 759, 760, 761, 762, 763,
+	764, 1556, 0, 766, 0, 765, 767, 768, 769, 770,
+	771, 772, 773, 775, 733, 776, 777, 778, 783, 784,
+	785, 1588, 779, 780, 781, 782, 787, 1581, 788, 789,
+	790, 791, 0, 792, 793, 0, 786, 774, 0, 794,
+	795, 796, 797, 798, 799, 800, 801, 802, 803, 0,
+	804, 1569, 1570, 1571, 1572, 0, 817, 0, 805, 807,
+	808, 809, 810, 1582, 811, 812, 1583, 1499, 813, 814,
+	815, 816, 806, 819, 820, 818, 0, 0, 821, 822,
+	823, 824, 826, 828, 829, 830, 825, 827, 831, 1541,
+	832, 0, 0, 833, 834, 835, 905, 1566, 1587, 0,
+	1576, 838, 839, 836, 837, 840, 841, 844, 842, 843,
+	909, 847, 542, 848, 849, 850, 845, 846, 0, 0,
+	0, 0, 851, 852, 910, 853, 854, 855, 0, 1551,
+	1493, 1494, 1495, 1491, 1492, 1504, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 367, 368, 370, 369,
+	371, 372, 373, 374, 0, 375, 376, 0, 0, 916,
+	0, 1505, 1543, 1509, 0, 1503, 378, 0, 377, 0,
+	379, 380, 381, 926, 382, 383, 384, 385, 386, 387,
+	388, 389, 390, 857, 391, 1557, 0, 392, 1565, 393,
+	1564, 0, 1575, 394, 395, 396, 397, 398, 399, 400,
+	401, 402, 403, 404, 0, 1542, 0, 405, 1589, 1590,
+	864, 0, 406, 407, 408, 409, 1549, 0, 1530, 0,
+	410, 411, 412, 413, 414, 415, 416, 417, 0, 0,
+	419, 420, 421, 418, 422, 423, 0, 424, 0, 425,
+	426, 427, 428, 429, 0, 430, 431, 0, 432, 433,
+	434, 928, 435, 436, 437, 1533, 1531, 1532, 1539, 1535,
+	1534, 1538, 438, 439, 440, 441, 442, 1568, 443, 445,
+	1562, 1561, 0, 448, 450, 444, 446, 0, 449, 447,
+	451, 452, 0, 453, 454, 455, 456, 457, 0, 0,
+	0, 458, 1560, 460, 461, 0, 462, 463, 464, 466,
+	465, 0, 467, 468, 469, 0, 470, 471, 868, 472,
+	473, 474, 476, 478, 475, 477, 479, 480, 481, 482,
+	483, 1577, 1578, 484, 485, 1500, 362, 0, 0, 0,
+	0, 0, 486, 487, 488, 1559, 0, 0, 0, 489,
+	0, 491, 495, 496, 492, 493, 494, 497, 0, 490,
+	498, 499, 0, 929, 500, 501, 502, 1573, 1574, 503,
+	504, 505, 506, 507, 508, 509, 510, 511, 0, 512,
+	513, 1584, 0, 1510, 514, 0, 515, 516, 517, 518,
+	519, 520, 521, 1544, 1545, 1548, 630, 931, 522, 523,
+	524, 525, 0, 526, 527, 528, 529, 530, 531, 532,
+	0, 0, 0, 533, 534, 535, 536, 0, 919, 363,
+	365, 930, 879, 537, 631, 538, 539, 1554, 1555, 0,
+	1514, 0, 540, 541, 544, 932, 1546, 933, 543, 545,
+	546, 934, 547, 0, 0, 0, 548, 549, 550, 551,
+	552, 553, 554, 0, 555, 557, 556, 0, 559, 1585,
+	558, 935, 560, 561, 936, 0, 562, 563, 564, 565,
+	566, 567, 572, 1537, 1536, 568, 569, 570, 571, 573,
+	574, 0, 575, 576, 578, 581, 577, 579, 580, 582,
+	583, 596, 597, 598, 584, 585, 586, 587, 588, 589,
+	590, 591, 592, 593, 594, 595, 600, 0, 599, 937,
+	0, 601, 602, 603, 604, 605, 606, 612, 615, 617,
+	618, 613, 614, 616, 619, 620, 621, 623, 624, 609,
+	610, 611, 938, 622, 607, 0, 608, 366, 939, 625,
+	626, 627, 628, 1501, 1547, 629, 1563, 632, 633, 0,
+	0, 634, 0, 635, 636, 0, 0, 638, 639, 640,
+	0, 0, 641, 642, 887, 940, 643, 941, 1579, 644,
+	645, 637, 646, 647, 648, 649, 650, 651, 652, 653,
+	654, 655, 656, 657, 0, 658, 659, 889, 660, 661,
+	662, 663, 664, 890, 665, 666, 667, 1580, 668, 892,
+	669, 670, 671, 0, 672, 673, 674, 0, 675, 676,
+	677, 678, 679, 680, 681, 682, 683, 684, 1558, 685,
+	686, 688, 687, 689, 690, 0, 691, 692, 0, 693,
+	694, 695, 0, 0, 0, 0, 0, 696, 697, 699,
+	0, 700, 701, 702, 703, 704, 705, 698, 706, 707,
+	708, 709, 710, 711, 712, 713, 0, 715, 716, 714,
+	717, 718, 942, 719, 720, 721, 722, 723, 1489, 724,
+	0, 725, 726, 734, 735, 736, 727, 728, 730, 737,
+	729, 738, 739, 740, 741, 743, 742, 0, 745, 746,
+	744, 747, 748, 749, 750, 1540, 751, 895, 752, 731,
+	732, 753, 754, 755, 943, 756, 757, 758, 759, 760,
+	761, 762, 763, 764, 1556, 0, 766, 0, 765, 767,
+	768, 769, 770, 771, 772, 773, 775, 733, 776, 777,
+	778, 783, 784, 785, 1588, 779, 780, 781, 782, 787,
+	1581, 788, 789, 790, 791, 0, 792, 793, 0, 786,
+	774, 0, 794, 795, 796, 797, 798, 799, 800, 801,
+	802, 803, 0, 804, 1569, 1570, 1571, 1572, 0, 817,
+	0, 805, 807, 808, 809, 810, 1582, 811, 812, 1583,
+	1499, 813, 814, 815, 816, 806, 819, 820, 818, 0,
+	0, 821, 822, 823, 824, 826, 828, 829, 830, 825,
+	827, 831, 1541, 832, 0, 0, 833, 834, 835, 905,
+	1566, 1587, 0, 1576, 838, 839, 836, 837, 840, 841,
+	844, 842, 843, 909, 847, 542, 848, 849, 850, 845,
+	846, 0, 0, 0, 0, 851, 852, 910, 853, 854,
+	855, 1462, 0, 920, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	367, 368, 370, 369, 371, 372, 373, 374, 0, 375,
+	376, 0, 1736, 0, 1505, 0, 1543, 0, 1503, 0,
+	378, 0, 377, 0, 379, 380, 381, 926, 382, 383,
+	384, 385, 386, 387, 388, 389, 390, 857, 391, 858,
+	0, 392, 859, 393, 860, 0, 861, 394, 395, 396,
+	397, 398, 399, 400, 401, 402, 403, 404, 0, 1542,
+	0, 405, 862, 863, 864, 0, 406, 407, 408, 409,
+	1549, 0, 1530, 0, 410, 411, 412, 413, 414, 415,
+	416, 417, 0, 0, 419, 420, 421, 418, 422, 423,
+	0, 424, 0, 425, 426, 427, 428, 429, 0, 430,
+	431, 0, 432, 433, 434, 928, 435, 436, 437, 1533,
+	1531, 1532, 1539, 1535, 1534, 1538, 438, 439, 440, 441,
+	442, 0, 443, 445, 866, 867, 0, 448, 450, 444,
+	446, 0, 449, 447, 451, 452, 0, 453, 454, 455,
+	456, 457, 0, 0, 0, 458, 459, 460, 461, 0,
+	462, 463, 464, 466, 465, 0, 467, 468, 469, 0,
+	470, 471, 868, 472, 473, 474, 476, 478, 475, 477,
+	479, 480, 481, 482, 483, 1577, 1578, 484, 485, 0,
+	362, 0, 0, 0, 0, 0, 486, 487, 488, 871,
+	0, 0, 0, 489, 0, 491, 495, 496, 492, 493,
+	494, 497, 0, 490, 498, 499, 0, 929, 500, 501,
+	502, 872, 873, 503, 504, 505, 506, 507, 508, 509,
+	510, 511, 0, 512, 513, 1584, 0, 875, 514, 0,
+	515, 516, 517, 518, 519, 520, 521, 1544, 1545, 1548,
+	630, 931, 522, 523, 524, 525, 0, 526, 527, 528,
+	529, 530, 531, 532, 0, 0, 0, 533, 534, 535,
+	536, 0, 919, 363, 365, 930, 879, 537, 631, 538,
+	539, 880, 881, 0, 882, 0, 540, 541, 544, 932,
+	1546, 933, 543, 545, 546, 934, 547, 0, 0, 0,
+	548, 549, 550, 551, 552, 553, 554, 1613, 555, 557,
+	556, 0, 559, 1585, 558, 935, 560, 561, 936, 0,
+	562, 563, 564, 565, 566, 567, 572, 1537, 1536, 568,
+	569, 570, 571, 573, 574, 0, 575, 576, 578, 581,
+	577, 579, 580, 582, 583, 596, 597, 598, 584, 585,
+	586, 587, 588, 589, 590, 591, 592, 593, 594, 595,
+	600, 0, 599, 937, 0, 601, 602, 603, 604, 605,
+	606, 612, 615, 617, 618, 613, 614, 616, 619, 620,
+	621, 623, 624, 609, 610, 611, 938, 622, 607, 0,
+	608, 366, 939, 625, 626, 627, 628, 0, 1547, 629,
+	886, 632, 633, 0, 0, 634, 0, 635, 636, 0,
+	1619, 638, 639, 640, 0, 0, 641, 642, 887, 940,
+	643, 941, 1579, 644, 645, 637, 646, 647, 648, 649,
+	650, 651, 652, 653, 654, 655, 656, 657, 0, 658,
+	659, 889, 660, 661, 662, 663, 664, 890, 665, 666,
+	667, 1580, 668, 892, 669, 670, 671, 0, 672, 673,
+	674, 0, 675, 676, 677, 678, 679, 680, 681, 682,
+	683, 684, 893, 685, 686, 688, 687, 689, 690, 0,
+	691, 692, 0, 693, 694, 695, 0, 0, 0, 0,
+	0, 696, 697, 699, 0, 700, 701, 702, 703, 704,
+	705, 698, 706, 707, 708, 709, 710, 711, 712, 713,
+	0, 715, 716, 714, 717, 718, 942, 719, 720, 721,
+	722, 723, 894, 1621, 0, 725, 726, 734, 735, 736,
+	727, 728, 730, 737, 729, 738, 739, 740, 741, 743,
+	742, 316, 745, 746, 744, 747, 748, 749, 750, 1540,
+	751, 895, 752, 731, 732, 753, 754, 755, 943, 756,
+	757, 758, 759, 760, 761, 762, 763, 764, 896, 0,
+	766, 0, 765, 767, 768, 769, 770, 771, 772, 773,
+	775, 733, 776, 777, 778, 783, 784, 785, 897, 779,
+	780, 781, 782, 787, 1581, 788, 789, 790, 791, 0,
+	792, 793, 0, 786, 774, 318, 794, 795, 796, 797,
+	798, 799, 800, 801, 802, 803, 0, 804, 899, 900,
+	901, 902, 0, 817, 0, 805, 807, 808, 809, 810,
+	1582, 811, 812, 1583, 0, 813, 814, 815, 816, 806,
+	819, 820, 818, 0, 0, 821, 822, 823, 824, 826,
+	828, 829, 830, 825, 827, 831, 1541, 832, 0, 0,
+	833, 834, 835, 2237, 906, 907, 0, 908, 838, 839,
+	836, 837, 840, 841, 844, 842, 843, 909, 847, 542,
+	848, 849, 850, 845, 846, 0, 0, 0, 310, 851,
+	852, 910, 853, 854, 855, 0, 920, 311, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 367, 368, 370, 369, 371, 372, 373,
+	374, 0, 375, 376, 0, 0, 1617, 0, 2494, 1543,
+	0, 0, 0, 378, 0, 377, 0, 379, 380, 381,
+	926, 382, 383, 384, 385, 386, 387, 388, 389, 390,
+	857, 391, 858, 0, 392, 859, 393, 860, 0, 861,
+	394, 395, 396, 397, 398, 399, 400, 401, 402, 403,
+	404, 0, 1542, 0, 405, 862, 863, 864, 0, 406,
+	407, 408, 409, 1549, 0, 1530, 0, 410, 411, 412,
+	413, 414, 415, 416, 417, 0, 0, 419, 420, 421,
+	418, 422, 423, 0, 424, 0, 425, 426, 427, 428,
+	429, 0, 430, 431, 0, 432, 433, 434, 928, 435,
+	436, 437, 1533, 1531, 1532, 1539, 1535, 1534, 1538, 438,
+	439, 440, 441, 442, 0, 443, 445, 866, 867, 0,
+	448, 450, 444, 446, 0, 449, 447, 451, 452, 0,
+	453, 454, 455, 456, 457, 0, 0, 0, 458, 459,
+	460, 461, 0, 462, 463, 464, 466, 465, 0, 467,
+	468, 469, 0, 470, 471, 868, 472, 473, 474, 476,
+	478, 475, 477, 479, 480, 481, 482, 483, 1577, 1578,
+	484, 485, 0, 362, 0, 0, 0, 0, 0, 486,
+	487, 488, 871, 0, 0, 0, 489, 0, 491, 495,
+	496, 492, 493, 494, 497, 0, 490, 498, 499, 0,
+	929, 500, 501, 502, 872, 873, 503, 504, 505, 506,
+	507, 508, 509, 510, 511, 0, 512, 513, 1584, 0,
+	875, 514, 0, 515, 516, 517, 518, 519, 520, 521,
+	1544, 1545, 1548, 630, 931, 522, 523, 524, 525, 0,
+	526, 527, 528, 529, 530, 531, 532, 0, 0, 0,
+	533, 534, 535, 536, 0, 919, 363, 365, 930, 879,
+	537, 631, 538, 539, 880, 881, 0, 882, 0, 540,
+	541, 544, 932, 1546, 933, 543, 545, 546, 934, 547,
+	0, 0, 0, 548, 549, 550, 551, 552, 553, 554,
+	1613, 555, 557, 556, 0, 559, 1585, 558, 935, 560,
+	561, 936, 0, 562, 563, 564, 565, 566, 567, 572,
+	1537, 1536, 568, 569, 570, 571, 573, 574, 0, 575,
+	576, 578, 581, 577, 579, 580, 582, 583, 596, 597,
+	598, 584, 585, 586, 587, 588, 589, 590, 591, 592,
+	593, 594, 595, 600, 0, 599, 937, 0, 601, 602,
+	603, 604, 605, 606, 612, 615, 617, 618, 613, 614,
+	616, 619, 620, 621, 623, 624, 609, 610, 611, 938,
+	622, 607, 0, 608, 366, 939, 625, 626, 627, 628,
+	0, 1547, 629, 886, 632, 633, 0, 0, 634, 0,
+	635, 636, 0, 1619, 638, 639, 640, 0, 0, 641,
+	642, 887, 940, 643, 941, 1579, 644, 645, 637, 646,
+	647, 648, 649, 650, 651, 652, 653, 654, 655, 656,
+	657, 0, 658, 659, 889, 660, 661, 662, 663, 664,
+	890, 665, 666, 667, 1580, 668, 892, 669, 670, 671,
+	0, 672, 673, 674, 0, 675, 676, 677, 678, 679,
+	680, 681, 682, 683, 684, 893, 685, 686, 688, 687,
+	689, 690, 0, 691, 692, 0, 693, 694, 695, 0,
+	0, 0, 0, 0, 696, 697, 699, 0, 700, 701,
+	702, 703, 704, 705, 698, 706, 707, 708, 709, 710,
+	711, 712, 713, 0, 715, 716, 714, 717, 718, 942,
+	719, 720, 721, 722, 723, 894, 1621, 0, 725, 726,
+	734, 735, 736, 727, 728, 730, 737, 729, 738, 739,
+	740, 741, 743, 742, 316, 745, 746, 744, 747, 748,
+	749, 750, 1540, 751, 895, 752, 731, 732, 753, 754,
+	755, 943, 756, 757, 758, 759, 760, 761, 762, 763,
+	764, 896, 0, 766, 0, 765, 767, 768, 769, 770,
+	771, 772, 773, 775, 733, 776, 777, 778, 783, 784,
+	785, 897, 779, 780, 781, 782, 787, 1581, 788, 789,
+	790, 791, 0, 792, 793, 0, 786, 774, 318, 794,
+	795, 796, 797, 798, 799, 800, 801, 802, 803, 0,
+	804, 899, 900, 901, 902, 0, 817, 0, 805, 807,
+	808, 809, 810, 1582, 811, 812, 1583, 0, 813, 814,
+	815, 816, 806, 819, 820, 818, 0, 0, 821, 822,
+	823, 824, 826, 828, 829, 830, 825, 827, 831, 1541,
+	832, 0, 0, 833, 834, 835, 2237, 906, 907, 0,
+	908, 838, 839, 836, 837, 840, 841, 844, 842, 843,
+	909, 847, 542, 848, 849, 850, 845, 846, 0, 0,
+	0, 310, 851, 852, 910, 853, 854, 855, 0, 4901,
+	311, 920, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 367, 368,
+	370, 369, 371, 372, 373, 374, 0, 375, 376, 1617,
+	0, 2494, 0, 0, 1543, 0, 0, 0, 378, 0,
+	377, 0, 379, 380, 381, 926, 382, 383, 384, 385,
+	386, 387, 388, 389, 390, 857, 391, 858, 0, 392,
+	859, 393, 860, 0, 861, 394, 395, 396, 397, 398,
+	399, 400, 401, 402, 403, 404, 0, 1542, 0, 405,
+	862, 863, 864, 0, 406, 407, 408, 409, 1549, 0,
+	1530, 0, 410, 411, 412, 413, 414, 415, 416, 417,
+	0, 0, 419, 420, 421, 418, 422, 423, 0, 424,
+	0, 425, 426, 427, 428, 429, 0, 430, 431, 0,
+	432, 433, 434, 928, 435, 436, 437, 1533, 1531, 1532,
+	1539, 1535, 1534, 1538, 438, 439, 440, 441, 442, 0,
+	443, 445, 866, 867, 0, 448, 450, 444, 446, 0,
+	449, 447, 451, 452, 0, 453, 454, 455, 456, 457,
+	0, 0, 0, 458, 459, 460, 461, 0, 462, 463,
+	464, 466, 465, 0, 467, 468, 469, 0, 470, 471,
+	868, 472, 473, 474, 476, 478, 475, 477, 479, 480,
+	481, 482, 483, 1577, 1578, 484, 485, 0, 362, 0,
+	0, 0, 0, 0, 486, 487, 488, 871, 0, 0,
+	0, 489, 0, 491, 495, 496, 492, 493, 494, 497,
+	0, 490, 498, 499, 0, 929, 500, 501, 502, 872,
+	873, 503, 504, 505, 506, 507, 508, 509, 510, 511,
+	0, 512, 513, 1584, 0, 875, 514, 0, 515, 516,
+	517, 518, 519, 520, 521, 1544, 1545, 1548, 630, 931,
+	522, 523, 524, 525, 0, 526, 527, 528, 529, 530,
+	531, 532, 0, 0, 0, 533, 534, 535, 536, 0,
+	919, 363, 365, 930, 879, 537, 631, 538, 539, 880,
+	881, 0, 882, 0, 540, 541, 544, 932, 1546, 933,
+	543, 545, 546, 934, 547, 0, 0, 0, 548, 549,
+	550, 551, 552, 553, 554, 1613, 555, 557, 556, 0,
+	559, 1585, 558, 935, 560, 561, 936, 0, 562, 563,
+	564, 565, 566, 567, 572, 1537, 1536, 568, 569, 570,
+	571, 573, 574, 0, 575, 576, 578, 581, 577, 579,
+	580, 582, 583, 596, 597, 598, 584, 585, 586, 587,
+	588, 589, 590, 591, 592, 593, 594, 595, 600, 0,
+	599, 937, 0, 601, 602, 603, 604, 605, 606, 612,
+	615, 617, 618, 613, 614, 616, 619, 620, 621, 623,
+	624, 609, 610, 611, 938, 622, 607, 0, 608, 366,
+	939, 625, 626, 627, 628, 0, 1547, 629, 886, 632,
+	633, 0, 0, 634, 0, 635, 636, 0, 1619, 638,
+	639, 640, 0, 0, 641, 642, 887, 940, 643, 941,
+	1579, 644, 645, 637, 646, 647, 648, 649, 650, 651,
+	652, 653, 654, 655, 656, 657, 0, 658, 659, 889,
+	660, 661, 662, 663, 664, 890, 665, 666, 667, 1580,
+	668, 892, 669, 670, 671, 0, 672, 673, 674, 0,
+	675, 676, 677, 678, 679, 680, 681, 682, 683, 684,
+	893, 685, 686, 688, 687, 689, 690, 0, 691, 692,
+	0, 693, 694, 695, 0, 0, 0, 0, 0, 696,
+	697, 699, 0, 700, 701, 702, 703, 704, 705, 698,
+	706, 707, 708, 709, 710, 711, 712, 713, 0, 715,
+	716, 714, 717, 718, 942, 719, 720, 721, 722, 723,
+	894, 1621, 0, 725, 726, 734, 735, 736, 727, 728,
+	730, 737, 729, 738, 739, 740, 741, 743, 742, 0,
+	745, 746, 744, 747, 748, 749, 750, 1540, 751, 895,
+	752, 731, 732, 753, 754, 755, 943, 756, 757, 758,
+	759, 760, 761, 762, 763, 764, 896, 0, 766, 0,
+	765, 767, 768, 769, 770, 771, 772, 773, 775, 733,
+	776, 777, 778, 783, 784, 785, 897, 779, 780, 781,
+	782, 787, 1581, 788, 789, 790, 791, 0, 792, 793,
+	0, 786, 774, 0, 794, 795, 796, 797, 798, 799,
+	800, 801, 802, 803, 0, 804, 899, 900, 901, 902,
+	0, 817, 0, 805, 807, 808, 809, 810, 1582, 811,
+	812, 1583, 0, 813, 814, 815, 816, 806, 819, 820,
+	818, 0, 0, 821, 822, 823, 824, 826, 828, 829,
+	830, 825, 827, 831, 1541, 832, 0, 0, 833, 834,
+	835, 905, 906, 907, 0, 908, 838, 839, 836, 837,
+	840, 841, 844, 842, 843, 909, 847, 542, 848, 849,
+	850, 845, 846, 0, 1609, 0, 920, 851, 852, 910,
+	853, 854, 855, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 367, 368, 370, 369, 371, 372, 373,
+	374, 0, 375, 376, 0, 0, 0, 0, 0, 1543,
+	0, 0, 0, 378, 1617, 377, 1615, 379, 380, 381,
+	926, 382, 383, 384, 385, 386, 387, 388, 389, 390,
+	857, 391, 858, 0, 392, 859, 393, 860, 0, 861,
+	394, 395, 396, 397, 398, 399, 400, 401, 402, 403,
+	404, 0, 1542, 0, 405, 862, 863, 864, 0, 406,
+	407, 408, 409, 1549, 0, 1530, 0, 410, 411, 412,
+	413, 414, 415, 416, 417, 0, 0, 419, 420, 421,
+	418, 422, 423, 0, 424, 0, 425, 426, 427, 428,
+	429, 0, 430, 431, 0, 432, 433, 434, 928, 435,
+	436, 437, 1533, 1531, 1532, 1539, 1535, 1534, 1538, 438,
+	439, 440, 441, 442, 0, 443, 445, 866, 867, 0,
+	448, 450, 444, 446, 0, 449, 447, 451, 452, 0,
+	453, 454, 455, 456, 457, 0, 0, 0, 458, 459,
+	460, 461, 0, 462, 463, 464, 466, 465, 0, 467,
+	468, 469, 0, 470, 471, 868, 472, 473, 474, 476,
+	478, 475, 477, 479, 480, 481, 482, 483, 1577, 1578,
+	484, 485, 0, 362, 0, 0, 0, 0, 0, 486,
+	487, 488, 871, 0, 0, 0, 489, 0, 491, 495,
+	496, 492, 493, 494, 497, 0, 490, 498, 499, 0,
+	929, 500, 501, 502, 872, 873, 503, 504, 505, 506,
+	507, 508, 509, 510, 511, 0, 512, 513, 1584, 0,
+	875, 514, 0, 515, 516, 517, 518, 519, 520, 521,
+	1544, 1545, 1548, 630, 931, 522, 523, 524, 525, 0,
+	526, 527, 528, 529, 530, 531, 532, 0, 0, 0,
+	533, 534, 535, 536, 0, 919, 363, 365, 930, 879,
+	537, 631, 538, 539, 880, 881, 0, 882, 0, 540,
+	541, 544, 932, 1546, 933, 543, 545, 546, 934, 547,
+	0, 0, 0, 548, 549, 550, 551, 552, 553, 554,
+	1613, 555, 557, 556, 0, 559, 1585, 558, 935, 560,
+	561, 936, 0, 562, 563, 564, 565, 566, 567, 572,
+	1537, 1536, 568, 569, 570, 571, 573, 574, 0, 575,
+	576, 578, 581, 577, 579, 580, 582, 583, 596, 597,
+	598, 584, 585, 586, 587, 588, 589, 590, 591, 592,
+	593, 594, 595, 600, 0, 599, 937, 0, 601, 602,
+	603, 604, 605, 606, 612, 615, 617, 618, 613, 614,
+	616, 619, 620, 621, 623, 624, 609, 610, 611, 938,
+	622, 607, 0, 608, 366, 939, 625, 626, 627, 628,
+	0, 1547, 629, 886, 632, 633, 0, 0, 634, 0,
+	635, 636, 0, 1619, 638, 639, 640, 0, 0, 641,
+	642, 887, 940, 643, 941, 1579, 644, 645, 637, 646,
+	647, 648, 649, 650, 651, 652, 653, 654, 655, 656,
+	657, 0, 658, 659, 889, 660, 661, 662, 663, 664,
+	890, 665, 666, 667, 1580, 668, 892, 669, 670, 671,
+	0, 672, 673, 674, 0, 675, 676, 677, 678, 679,
+	680, 681, 682, 683, 684, 893, 685, 686, 688, 687,
+	689, 690, 0, 691, 692, 0, 693, 694, 695, 0,
+	0, 0, 0, 0, 696, 697, 699, 0, 700, 701,
+	702, 703, 704, 705, 698, 706, 707, 708, 709, 710,
+	711, 712, 713, 0, 715, 716, 714, 717, 718, 942,
+	719, 720, 721, 722, 723, 894, 1621, 0, 725, 726,
+	734, 735, 736, 727, 728, 730, 737, 729, 738, 739,
+	740, 741, 743, 742, 0, 745, 746, 744, 747, 748,
+	749, 750, 1540, 751, 895, 752, 731, 732, 753, 754,
+	755, 943, 756, 757, 758, 759, 760, 761, 762, 763,
+	764, 896, 0, 766, 0, 765, 767, 768, 769, 770,
+	771, 772, 773, 775, 733, 776, 777, 778, 783, 784,
+	785, 897, 779, 780, 781, 782, 787, 1581, 788, 789,
+	790, 791, 0, 792, 793, 0, 786, 774, 0, 794,
+	795, 796, 797, 798, 799, 800, 801, 802, 803, 0,
+	804, 899, 900, 901, 902, 0, 817, 0, 805, 807,
+	808, 809, 810, 1582, 811, 812, 1583, 0, 813, 814,
+	815, 816, 806, 819, 820, 818, 0, 0, 821, 822,
+	823, 824, 826, 828, 829, 830, 825, 827, 831, 1541,
+	832, 0, 0, 833, 834, 835, 905, 906, 907, 0,
+	908, 838, 839, 836, 837, 840, 841, 844, 842, 843,
+	909, 847, 542, 848, 849, 850, 845, 846, 0, 0,
+	0, 920, 851, 852, 910, 853, 854, 855, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 367, 368,
+	370, 369, 371, 372, 373, 374, 0, 375, 376, 0,
+	0, 0, 0, 0, 1543, 0, 0, 0, 378, 1617,
+	377, 1615, 379, 380, 381, 926, 382, 383, 384, 385,
+	386, 387, 388, 389, 390, 857, 391, 858, 0, 392,
+	859, 393, 860, 0, 861, 394, 395, 396, 397, 398,
+	399, 400, 401, 402, 403, 404, 0, 1542, 0, 405,
+	862, 863, 864, 0, 406, 407, 408, 409, 1549, 0,
+	1530, 0, 410, 411, 412, 413, 414, 415, 416, 417,
+	0, 0, 419, 420, 421, 418, 422, 423, 0, 424,
+	0, 425, 426, 427, 428, 429, 0, 430, 431, 0,
+	432, 433, 434, 928, 435, 436, 437, 1533, 1531, 1532,
+	1539, 1535, 1534, 1538, 438, 439, 440, 441, 442, 0,
+	443, 445, 866, 867, 0, 448, 450, 444, 446, 0,
+	449, 447, 451, 452, 0, 453, 454, 455, 456, 457,
+	0, 0, 0, 458, 459, 460, 461, 0, 462, 463,
+	464, 466, 465, 0, 467, 468, 469, 0, 470, 471,
+	868, 472, 473, 474, 476, 478, 475, 477, 479, 480,
+	481, 482, 483, 1577, 1578, 484, 485, 0, 362, 0,
+	0, 0, 0, 0, 486, 487, 488, 871, 0, 0,
+	0, 489, 0, 491, 495, 496, 492, 493, 494, 497,
+	0, 490, 498, 499, 0, 929, 500, 501, 502, 872,
+	873, 503, 504, 505, 506, 507, 508, 509, 510, 511,
+	0, 512, 513, 1584, 0, 875, 514, 0, 515, 516,
+	517, 518, 519, 520, 521, 1544, 1545, 1548, 630, 931,
+	522, 523, 524, 525, 0, 526, 527, 528, 529, 530,
+	531, 532, 0, 0, 0, 533, 534, 535, 536, 0,
+	919, 363, 365, 930, 879, 537, 631, 538, 539, 880,
+	881, 0, 882, 0, 540, 541, 544, 932, 1546, 933,
+	543, 545, 546, 934, 547, 0, 0, 0, 548, 549,
+	550, 551, 552, 553, 554, 1613, 555, 557, 556, 0,
+	559, 1585, 558, 935, 560, 561, 936, 0, 562, 563,
+	564, 565, 566, 567, 572, 1537, 1536, 568, 569, 570,
+	571, 573, 574, 0, 575, 576, 578, 581, 577, 579,
+	580, 582, 583, 596, 597, 598, 584, 585, 586, 587,
+	588, 589, 590, 591, 592, 593, 594, 595, 600, 0,
+	599, 937, 0, 601, 602, 603, 604, 605, 606, 612,
+	615, 617, 618, 613, 614, 616, 619, 620, 621, 623,
+	624, 609, 610, 611, 938, 622, 607, 0, 608, 366,
+	939, 625, 626, 627, 628, 0, 1547, 629, 886, 632,
+	633, 0, 0, 634, 0, 635, 636, 0, 1619, 638,
+	639, 640, 0, 0, 641, 642, 887, 940, 643, 941,
+	1579, 644, 645, 637, 646, 647, 648, 649, 650, 651,
+	652, 653, 654, 655, 656, 657, 0, 658, 659, 889,
+	660, 661, 662, 663, 664, 890, 665, 666, 667, 1580,
+	668, 892, 669, 670, 671, 0, 672, 673, 674, 0,
+	675, 676, 677, 678, 679, 680, 681, 682, 683, 684,
+	893, 685, 686, 688, 687, 689, 690, 0, 691, 692,
+	0, 693, 694, 695, 0, 0, 0, 0, 0, 696,
+	697, 699, 0, 700, 701, 702, 703, 704, 705, 698,
+	706, 707, 708, 709, 710, 711, 712, 713, 0, 715,
+	716, 714, 717, 718, 942, 719, 720, 721, 722, 723,
+	894, 1621, 0, 725, 726, 734, 735, 736, 727, 728,
+	730, 737, 729, 738, 739, 740, 741, 743, 742, 0,
+	745, 746, 744, 747, 748, 749, 750, 1540, 751, 895,
+	752, 731, 732, 753, 754, 755, 943, 756, 757, 758,
+	759, 760, 761, 762, 763, 764, 896, 0, 766, 0,
+	765, 767, 768, 769, 770, 771, 772, 773, 775, 733,
+	776, 777, 778, 783, 784, 785, 897, 779, 780, 781,
+	782, 787, 1581, 788, 789, 790, 791, 0, 792, 793,
+	0, 786, 774, 0, 794, 795, 796, 797, 798, 799,
+	800, 801, 802, 803, 0, 804, 899, 900, 901, 902,
+	0, 817, 0, 805, 807, 808, 809, 810, 1582, 811,
+	812, 1583, 0, 813, 814, 815, 816, 806, 819, 820,
+	818, 0, 0, 821, 822, 823, 824, 826, 828, 829,
+	830, 825, 827, 831, 1541, 832, 0, 0, 833, 834,
+	835, 905, 906, 907, 0, 908, 838, 839, 836, 837,
+	840, 841, 844, 842, 843, 909, 847, 542, 848, 849,
+	850, 845, 846, 0, 0, 0, 920, 851, 852, 910,
+	853, 854, 855, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 367, 368, 370, 369, 371, 372, 373,
+	374, 0, 375, 376, 0, 0, 0, 0, 0, 1543,
+	0, 0, 0, 378, 1617, 377, 1615, 379, 380, 381,
+	926, 382, 383, 384, 385, 386, 387, 388, 389, 390,
+	857, 391, 858, 0, 392, 859, 393, 860, 0, 861,
+	394, 395, 396, 397, 398, 399, 400, 401, 402, 403,
+	404, 0, 1542, 0, 405, 862, 863, 864, 0, 406,
+	407, 408, 409, 1549, 0, 1530, 0, 410, 411, 412,
+	413, 414, 415, 416, 417, 0, 0, 419, 420, 421,
+	418, 422, 423, 0, 424, 0, 425, 426, 427, 428,
+	429, 0, 430, 431, 0, 432, 433, 434, 928, 435,
+	436, 437, 1533, 1531, 1532, 1539, 1535, 1534, 1538, 438,
+	439, 440, 441, 442, 0, 443, 445, 866, 867, 0,
+	448, 450, 444, 446, 0, 449, 447, 451, 452, 0,
+	453, 454, 455, 456, 457, 0, 0, 0, 458, 459,
+	460, 461, 0, 462, 463, 464, 466, 465, 0, 467,
+	468, 469, 0, 470, 471, 868, 472, 473, 474, 476,
+	478, 475, 477, 479, 480, 481, 482, 483, 1577, 1578,
+	484, 485, 0, 362, 0, 0, 0, 0, 0, 486,
+	487, 488, 871, 0, 0, 0, 489, 0, 491, 495,
+	496, 492, 493, 494, 497, 0, 490, 498, 499, 0,
+	929, 500, 501, 502, 872, 873, 503, 504, 505, 506,
+	507, 508, 509, 510, 511, 0, 512, 513, 1584, 0,
+	875, 514, 0, 515, 516, 517, 518, 519, 520, 521,
+	1544, 1545, 1548, 630, 931, 522, 523, 524, 525, 0,
+	526, 527, 528, 529, 530, 531, 532, 0, 0, 0,
+	533, 534, 535, 536, 0, 919, 363, 365, 930, 879,
+	537, 631, 538, 539, 880, 881, 0, 882, 0, 540,
+	541, 544, 932, 1546, 933, 543, 545, 546, 934, 547,
+	0, 0, 0, 548, 549, 550, 551, 552, 553, 554,
+	0, 555, 557, 556, 0, 559, 1585, 558, 935, 560,
+	561, 936, 0, 562, 563, 564, 565, 566, 567, 572,
+	1537, 1536, 568, 569, 570, 571, 573, 574, 0, 575,
+	576, 578, 581, 577, 579, 580, 582, 583, 596, 597,
+	598, 584, 585, 586, 587, 588, 589, 590, 591, 592,
+	593, 594, 595, 600, 0, 599, 937, 0, 601, 602,
+	603, 604, 605, 606, 612, 615, 617, 618, 613, 614,
+	616, 619, 620, 621, 623, 624, 609, 610, 611, 938,
+	622, 607, 0, 608, 366, 939, 625, 626, 627, 628,
+	0, 1547, 629, 886, 632, 633, 0, 0, 634, 0,
+	635, 636, 0, 0, 638, 639, 640, 0, 0, 641,
+	642, 887, 940, 643, 941, 1579, 644, 645, 637, 646,
+	647, 648, 649, 650, 651, 652, 653, 654, 655, 656,
+	657, 0, 658, 659, 889, 660, 661, 662, 663, 664,
+	890, 665, 666, 667, 1580, 668, 892, 669, 670, 671,
+	0, 672, 673, 674, 0, 675, 676, 677, 678, 679,
+	680, 681, 682, 683, 684, 893, 685, 686, 688, 687,
+	689, 690, 0, 691, 692, 0, 693, 694, 695, 0,
+	0, 0, 0, 0, 696, 697, 699, 0, 700, 701,
+	702, 703, 704, 705, 698, 706, 707, 708, 709, 710,
+	711, 712, 713, 0, 715, 716, 714, 717, 718, 942,
+	719, 720, 721, 722, 723, 894, 724, 0, 725, 726,
+	734, 735, 736, 727, 728, 730, 737, 729, 738, 739,
+	740, 741, 743, 742, 0, 745, 746, 744, 747, 748,
+	749, 750, 1540, 751, 895, 752, 731, 732, 753, 754,
+	755, 943, 756, 757, 758, 759, 760, 761, 762, 763,
+	764, 896, 0, 766, 0, 765, 767, 768, 769, 770,
+	771, 772, 773, 775, 733, 776, 777, 778, 783, 784,
+	785, 897, 779, 780, 781, 782, 787, 1581, 788, 789,
+	790, 791, 0, 792, 793, 0, 786, 774, 0, 794,
+	795, 796, 797, 798, 799, 800, 801, 802, 803, 0,
+	804, 899, 900, 901, 902, 0, 817, 0, 805, 807,
+	808, 809, 810, 1582, 811, 812, 1583, 0, 813, 814,
+	815, 816, 806, 819, 820, 818, 0, 0, 821, 822,
+	823, 824, 826, 828, 829, 830, 825, 827, 831, 1541,
+	832, 0, 0, 833, 834, 835, 905, 906, 907, 0,
+	908, 838, 839, 836, 837, 840, 841, 844, 842, 843,
+	909, 847, 542, 848, 849, 850, 845, 846, 0, 0,
+	0, 920, 851, 852, 910, 853, 854, 855, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 367, 368,
+	370, 369, 371, 372, 373, 374, 0, 375, 376, 0,
+	0, 0, 0, 0, 1543, 0, 0, 0, 378, 916,
+	377, 6142, 379, 380, 381, 926, 382, 383, 384, 385,
+	386, 387, 388, 389, 390, 857, 391, 858, 0, 392,
+	859, 393, 860, 0, 861, 394, 395, 396, 397, 398,
+	399, 400, 401, 402, 403, 404, 0, 1542, 0, 405,
+	862, 863, 864, 0, 406, 407, 408, 409, 1549, 0,
+	1530, 0, 410, 411, 412, 413, 414, 415, 416, 417,
+	0, 0, 419, 420, 421, 418, 422, 423, 0, 424,
+	0, 425, 426, 427, 428, 429, 0, 430, 431, 0,
+	432, 433, 434, 928, 435, 436, 437, 1533, 1531, 1532,
+	1539, 1535, 1534, 1538, 438, 439, 440, 441, 442, 0,
+	443, 445, 866, 867, 0, 448, 450, 444, 446, 0,
+	449, 447, 451, 452, 0, 453, 454, 455, 456, 457,
+	0, 0, 0, 458, 459, 460, 461, 0, 462, 463,
+	464, 466, 465, 0, 467, 468, 469, 0, 470, 471,
+	868, 472, 473, 474, 476, 478, 475, 477, 479, 480,
+	481, 482, 483, 1577, 1578, 484, 485, 0, 362, 0,
+	0, 0, 0, 0, 486, 487, 488, 871, 0, 0,
+	0, 489, 0, 491, 495, 496, 492, 493, 494, 497,
+	0, 490, 498, 499, 0, 929, 500, 501, 502, 872,
+	873, 503, 504, 505, 506, 507, 508, 509, 510, 511,
+	0, 512, 513, 1584, 0, 875, 514, 0, 515, 516,
+	517, 518, 519, 520, 521, 1544, 1545, 1548, 630, 931,
+	522, 523, 524, 525, 0, 526, 527, 528, 529, 530,
+	531, 532, 0, 0, 0, 533, 534, 535, 536, 0,
+	919, 363, 365, 930, 879, 537, 631, 538, 539, 880,
+	881, 0, 882, 0, 540, 541, 544, 932, 1546, 933,
+	543, 545, 546, 934, 547, 0, 0, 0, 548, 549,
+	550, 551, 552, 553, 554, 0, 555, 557, 556, 0,
+	559, 1585, 558, 935, 560, 561, 936, 0, 562, 563,
+	564, 565, 566, 567, 572, 1537, 1536, 568, 569, 570,
+	571, 573, 574, 0, 575, 576, 578, 581, 577, 579,
+	580, 582, 583, 596, 597, 598, 584, 585, 586, 587,
+	588, 589, 590, 591, 592, 593, 594, 595, 600, 0,
+	599, 937, 0, 601, 602, 603, 604, 605, 606, 612,
+	615, 617, 618, 613, 614, 616, 619, 620, 621, 623,
+	624, 609, 610, 611, 938, 622, 607, 0, 608, 366,
+	939, 625, 626, 627, 628, 0, 1547, 629, 886, 632,
+	633, 0, 0, 634, 0, 635, 636, 0, 0, 638,
+	639, 640, 0, 0, 641, 642, 887, 940, 643, 941,
+	1579, 644, 645, 637, 646, 647, 648, 649, 650, 651,
+	652, 653, 654, 655, 656, 657, 0, 658, 659, 889,
+	660, 661, 662, 663, 664, 890, 665, 666, 667, 1580,
+	668, 892, 669, 670, 671, 0, 672, 673, 674, 0,
+	675, 676, 677, 678, 679, 680, 681, 682, 683, 684,
+	893, 685, 686, 688, 687, 689, 690, 0, 691, 692,
+	0, 693, 694, 695, 0, 0, 0, 0, 0, 696,
+	697, 699, 0, 700, 701, 702, 703, 704, 705, 698,
+	706, 707, 708, 709, 710, 711, 712, 713, 0, 715,
+	716, 714, 717, 718, 942, 719, 720, 721, 722, 723,
+	894, 1621, 0, 725, 726, 734, 735, 736, 727, 728,
+	730, 737, 729, 738, 739, 740, 741, 743, 742, 0,
+	745, 746, 744, 747, 748, 749, 750, 1540, 751, 895,
+	752, 731, 732, 753, 754, 755, 943, 756, 757, 758,
+	759, 760, 761, 762, 763, 764, 896, 0, 766, 0,
+	765, 767, 768, 769, 770, 771, 772, 773, 775, 733,
+	776, 777, 778, 783, 784, 785, 897, 779, 780, 781,
+	782, 787, 1581, 788, 789, 790, 791, 0, 792, 793,
+	0, 786, 774, 0, 794, 795, 796, 797, 798, 799,
+	800, 801, 802, 803, 0, 804, 899, 900, 901, 902,
+	0, 817, 0, 805, 807, 808, 809, 810, 1582, 811,
+	812, 1583, 0, 813, 814, 815, 816, 806, 819, 820,
+	818, 0, 0, 821, 822, 823, 824, 826, 828, 829,
+	830, 825, 827, 831, 1541, 832, 0, 0, 833, 834,
+	835, 905, 906, 907, 0, 908, 838, 839, 836, 837,
+	840, 841, 844, 842, 843, 909, 847, 542, 848, 849,
+	850, 845, 846, 0, 0, 0, 920, 851, 852, 910,
+	853, 854, 855, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 367, 368, 370, 369, 371, 372, 373,
+	374, 0, 375, 376, 0, 0, 0, 0, 0, 1543,
+	0, 0, 0, 378, 916, 377, 2385, 379, 380, 381,
+	926, 382, 383, 384, 385, 386, 387, 388, 389, 390,
+	857, 391, 858, 0, 392, 859, 393, 860, 0, 861,
+	394, 395, 396, 397, 398, 399, 400, 401, 402, 403,
+	404, 0, 1542, 0, 405, 862, 863, 864, 0, 406,
+	407, 408, 409, 1549, 0, 1530, 0, 410, 411, 412,
+	413, 414, 415, 416, 417, 0, 0, 419, 420, 421,
+	418, 422, 423, 0, 424, 0, 425, 426, 427, 428,
+	429, 0, 430, 431, 0, 432, 433, 434, 928, 435,
+	436, 437, 1533, 1531, 1532, 1539, 1535, 1534, 1538, 438,
+	439, 440, 441, 442, 0, 443, 445, 866, 867, 0,
+	448, 450, 444, 446, 0, 449, 447, 451, 452, 0,
+	453, 454, 455, 456, 457, 0, 0, 0, 458, 459,
+	460, 461, 0, 462, 463, 464, 466, 465, 0, 467,
+	468, 469, 0, 470, 471, 868, 472, 473, 474, 476,
+	478, 475, 477, 479, 480, 481, 482, 483, 1577, 1578,
+	484, 485, 0, 362, 0, 0, 0, 0, 0, 486,
+	487, 488, 871, 0, 0, 0, 489, 0, 491, 495,
+	496, 492, 493, 494, 497, 0, 490, 498, 499, 0,
+	929, 500, 501, 502, 872, 873, 503, 504, 505, 506,
+	507, 508, 509, 510, 511, 0, 512, 513, 1584, 0,
+	875, 514, 0, 515, 516, 517, 518, 519, 520, 521,
+	1544, 1545, 1548, 630, 931, 522, 523, 524, 525, 0,
+	526, 527, 528, 529, 530, 531, 532, 0, 0, 0,
+	533, 534, 535, 536, 0, 919, 363, 365, 930, 879,
+	537, 631, 538, 539, 880, 881, 0, 882, 0, 540,
+	541, 544, 932, 1546, 933, 543, 545, 546, 934, 547,
+	0, 0, 0, 548, 549, 550, 551, 552, 553, 554,
+	0, 555, 557, 556, 0, 559, 1585, 558, 935, 560,
+	561, 936, 0, 562, 563, 564, 565, 566, 567, 572,
+	1537, 1536, 568, 569, 570, 571, 573, 574, 0, 575,
+	576, 578, 581, 577, 579, 580, 582, 583, 596, 597,
+	598, 584, 585, 586, 587, 588, 589, 590, 591, 592,
+	593, 594, 595, 600, 0, 599, 937, 0, 601, 602,
+	603, 604, 605, 606, 612, 615, 617, 618, 613, 614,
+	616, 619, 620, 621, 623, 624, 609, 610, 611, 938,
+	622, 607, 0, 608, 366, 939, 625, 626, 627, 628,
+	0, 1547, 629, 886, 632, 633, 0, 0, 634, 0,
+	635, 636, 0, 0, 638, 639, 640, 0, 0, 641,
+	642, 887, 940, 643, 941, 1579, 644, 645, 637, 646,
+	647, 648, 649, 650, 651, 652, 653, 654, 655, 656,
+	657, 0, 658, 659, 889, 660, 661, 662, 663, 664,
+	890, 665, 666, 667, 1580, 668, 892, 669, 670, 671,
+	0, 672, 673, 674, 0, 675, 676, 677, 678, 679,
+	680, 681, 682, 683, 684, 893, 685, 686, 688, 687,
+	689, 690, 0, 691, 692, 0, 693, 694, 695, 0,
+	0, 0, 0, 0, 696, 697, 699, 0, 700, 701,
+	702, 703, 704, 705, 698, 706, 707, 708, 709, 710,
+	711, 712, 713, 0, 715, 716, 714, 717, 718, 942,
+	719, 720, 721, 722, 723, 894, 724, 0, 725, 726,
+	734, 735, 736, 727, 728, 730, 737, 729, 738, 739,
+	740, 741, 743, 742, 0, 745, 746, 744, 747, 748,
+	749, 750, 1540, 751, 895, 752, 731, 732, 753, 754,
+	755, 943, 756, 757, 758, 759, 760, 761, 762, 763,
+	764, 896, 0, 766, 0, 765, 767, 768, 769, 770,
+	771, 772, 773, 775, 733, 776, 777, 778, 783, 784,
+	785, 897, 779, 780, 781, 782, 787, 1581, 788, 789,
+	790, 791, 0, 792, 793, 0, 786, 774, 0, 794,
+	795, 796, 797, 798, 799, 800, 801, 802, 803, 0,
+	804, 899, 900, 901, 902, 0, 817, 0, 805, 807,
+	808, 809, 810, 1582, 811, 812, 1583, 0, 813, 814,
+	815, 816, 806, 819, 820, 818, 0, 0, 821, 822,
+	823, 824, 826, 828, 829, 830, 825, 827, 831, 1541,
+	832, 0, 0, 833, 834, 835, 905, 906, 907, 0,
+	908, 838, 839, 836, 837, 840, 841, 844, 842, 843,
+	909, 847, 542, 848, 849, 850, 845, 846, 0, 359,
+	0, 0, 851, 852, 910, 853, 854, 855, 0, 3293,
+	3294, 3295, 3312, 3313, 3314, 0, 367, 368, 370, 369,
+	371, 372, 373, 374, 0, 375, 376, 0, 0, 0,
+	3315, 0, 856, 0, 0, 0, 378, 3316, 377, 916,
+	379, 380, 381, 0, 382, 383, 384, 385, 386, 387,
+	388, 389, 390, 857, 391, 858, 0, 392, 859, 393,
+	860, 0, 861, 394, 395, 396, 397, 398, 399, 400,
+	401, 402, 403, 404, 0, 0, 2370, 405, 862, 863,
+	864, 0, 406, 407, 408, 409, 865, 0, 0, 0,
+	410, 411, 412, 413, 414, 415, 416, 417, 3305, 0,
+	419, 420, 421, 418, 422, 423, 0, 424, 3301, 425,
+	426, 427, 428, 429, 3318, 430, 431, 0, 432, 433,
+	434, 0, 435, 436, 437, 0, 0, 0, 0, 0,
+	0, 0, 438, 439, 440, 441, 442, 0, 443, 445,
+	866, 867, 0, 448, 450, 444, 446, 0, 449, 447,
+	451, 452, 0, 453, 454, 455, 456, 457, 3317, 0,
+	0, 458, 459, 460, 461, 0, 462, 463, 464, 466,
+	465, 0, 467, 468, 469, 0, 470, 471, 868, 472,
+	473, 474, 476, 478, 475, 477, 479, 480, 481, 482,
+	483, 869, 870, 484, 485, 0, 0, 0, 3306, 3307,
+	3308, 3309, 486, 487, 488, 871, 0, 0, 3300, 489,
+	0, 491, 495, 496, 492, 493, 494, 497, 0, 490,
+	498, 499, 0, 0, 500, 501, 502, 872, 873, 503,
+	504, 505, 506, 507, 508, 509, 510, 511, 0, 512,
+	513, 874, 0, 875, 514, 0, 515, 516, 517, 518,
+	519, 520, 521, 876, 877, 878, 630, 0, 522, 523,
+	524, 525, 0, 526, 527, 528, 529, 530, 531, 532,
+	0, 0, 0, 533, 534, 535, 536, 0, 0, 0,
+	0, 0, 879, 537, 631, 538, 539, 880, 881, 0,
+	882, 0, 540, 541, 544, 0, 883, 0, 543, 545,
+	546, 0, 547, 0, 3310, 3311, 548, 549, 550, 551,
+	552, 553, 554, 0, 555, 557, 556, 0, 559, 884,
+	558, 0, 560, 561, 0, 0, 562, 563, 564, 565,
+	566, 567, 572, 0, 0, 568, 569, 570, 571, 573,
+	574, 3303, 575, 576, 578, 581, 577, 579, 580, 582,
+	583, 596, 597, 598, 584, 585, 586, 587, 588, 589,
+	590, 591, 592, 593, 594, 595, 600, 0, 599, 0,
+	3319, 601, 602, 603, 604, 605, 606, 612, 615, 617,
+	618, 613, 614, 616, 619, 620, 621, 623, 624, 609,
+	610, 611, 0, 622, 607, 0, 608, 0, 0, 625,
+	626, 627, 628, 0, 885, 629, 886, 632, 633, 0,
+	0, 634, 0, 635, 636, 0, 0, 638, 639, 640,
+	0, 0, 641, 642, 887, 0, 643, 0, 888, 644,
+	645, 637, 646, 647, 648, 649, 650, 651, 652, 653,
+	654, 655, 656, 657, 0, 658, 659, 889, 660, 661,
+	662, 663, 664, 890, 665, 666, 667, 891, 668, 892,
+	669, 670, 671, 0, 672, 673, 674, 0, 675, 676,
+	677, 678, 679, 680, 681, 682, 683, 684, 893, 685,
+	686, 688, 687, 689, 690, 0, 691, 692, 0, 693,
+	694, 695, 0, 0, 0, 0, 0, 696, 697, 699,
+	0, 700, 701, 702, 703, 704, 705, 698, 706, 707,
+	708, 709, 710, 711, 712, 713, 0, 715, 716, 714,
+	717, 718, 0, 719, 720, 721, 722, 723, 894, 724,
+	3304, 725, 726, 734, 735, 736, 727, 728, 730, 737,
+	729, 738, 739, 740, 741, 743, 742, 0, 745, 746,
+	744, 747, 748, 749, 750, 0, 751, 895, 752, 731,
+	732, 753, 754, 755, 0, 756, 757, 758, 759, 760,
+	761, 762, 763, 764, 896, 0, 766, 0, 765, 767,
+	768, 769, 770, 771, 772, 773, 775, 733, 776, 777,
+	778, 783, 784, 785, 897, 779, 780, 781, 782, 787,
+	898, 788, 789, 790, 791, 0, 792, 793, 2369, 786,
+	774, 0, 794, 795, 796, 797, 798, 799, 800, 801,
+	802, 803, 0, 804, 899, 900, 901, 902, 0, 817,
+	0, 805, 807, 808, 809, 810, 903, 811, 812, 904,
+	0, 813, 814, 815, 816, 806, 819, 820, 818, 0,
+	0, 821, 822, 823, 824, 826, 828, 829, 830, 825,
+	827, 831, 0, 832, 0, 0, 833, 834, 835, 905,
+	906, 907, 0, 908, 838, 839, 836, 837, 840, 841,
+	844, 842, 843, 909, 847, 542, 848, 849, 850, 845,
+	846, 0, 0, 0, 0, 851, 852, 910, 853, 854,
+	855, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 1462, 0, 1654, 3290, 3291, 3292, 3320, 3302, 3296,
+	0, 3298, 3299, 3297, 3284, 3285, 3286, 3287, 3288, 3289,
+	367, 368, 370, 369, 371, 372, 373, 374, 0, 375,
+	376, 0, 0, 0, 0, 0, 856, 0, 0, 0,
+	378, 0, 377, 0, 379, 380, 381, 926, 382, 383,
+	384, 385, 386, 387, 388, 389, 390, 857, 391, 858,
+	0, 392, 859, 393, 860, 0, 861, 394, 395, 396,
+	397, 398, 399, 400, 401, 402, 403, 404, 0, 0,
+	0, 405, 862, 863, 864, 0, 406, 407, 408, 409,
+	865, 0, 927, 0, 410, 411, 412, 413, 414, 415,
+	416, 417, 0, 0, 419, 420, 421, 418, 422, 423,
+	0, 424, 0, 425, 426, 427, 428, 429, 0, 430,
+	431, 0, 432, 433, 434, 928, 435, 436, 437, 0,
+	0, 0, 0, 0, 0, 0, 438, 439, 440, 441,
+	442, 0, 443, 445, 866, 867, 0, 448, 450, 444,
+	446, 0, 449, 447, 451, 452, 0, 453, 454, 455,
+	456, 457, 0, 0, 0, 458, 459, 460, 461, 0,
+	462, 463, 464, 466, 465, 0, 467, 468, 469, 0,
+	470, 471, 868, 472, 473, 474, 476, 478, 475, 477,
+	479, 480, 481, 482, 483, 869, 870, 484, 485, 0,
+	362, 0, 0, 0, 0, 0, 486, 487, 488, 871,
+	0, 0, 0, 489, 0, 491, 495, 496, 492, 493,
+	494, 497, 0, 490, 498, 499, 0, 929, 500, 501,
+	502, 872, 873, 503, 504, 505, 506, 507, 508, 509,
+	510, 511, 0, 512, 513, 874, 0, 875, 514, 0,
+	515, 516, 517, 518, 519, 520, 521, 876, 877, 878,
+	630, 931, 522, 523, 524, 525, 0, 526, 527, 528,
+	529, 530, 531, 532, 0, 0, 0, 533, 534, 535,
+	536, 0, 0, 0, 0, 930, 879, 537, 631, 538,
+	539, 880, 881, 0, 882, 0, 540, 541, 544, 932,
+	883, 933, 543, 545, 546, 934, 547, 0, 0, 0,
+	548, 549, 550, 551, 552, 553, 554, 0, 555, 557,
+	556, 0, 559, 884, 558, 935, 560, 561, 936, 0,
+	562, 563, 564, 565, 566, 567, 572, 0, 0, 568,
+	569, 570, 571, 573, 574, 0, 575, 576, 578, 581,
+	577, 579, 580, 582, 583, 596, 597, 598, 584, 585,
+	586, 587, 588, 589, 590, 591, 592, 593, 594, 595,
+	600, 0, 599, 937, 0, 601, 602, 603, 604, 605,
+	606, 612, 615, 617, 618, 613, 614, 616, 619, 620,
+	621, 623, 624, 609, 610, 611, 938, 622, 607, 0,
+	608, 0, 939, 625, 626, 627, 628, 0, 885, 629,
+	886, 632, 633, 0, 0, 634, 0, 635, 636, 0,
+	0, 638, 639, 640, 0, 0, 641, 642, 887, 940,
+	643, 941, 888, 644, 645, 637, 646, 647, 648, 649,
+	650, 651, 652, 653, 654, 655, 656, 657, 0, 658,
+	659, 889, 660, 661, 662, 663, 664, 890, 665, 666,
+	667, 891, 668, 892, 669, 670, 671, 0, 672, 673,
+	674, 0, 675, 676, 677, 678, 679, 680, 681, 682,
+	683, 684, 893, 685, 686, 688, 687, 689, 690, 0,
+	691, 692, 0, 693, 694, 695, 0, 0, 0, 0,
+	0, 696, 697, 699, 0, 700, 701, 702, 703, 704,
+	705, 698, 706, 707, 708, 709, 710, 711, 712, 713,
+	0, 715, 716, 714, 717, 718, 942, 719, 720, 721,
+	722, 723, 894, 724, 0, 725, 726, 734, 735, 736,
+	727, 728, 730, 737, 729, 738, 739, 740, 741, 743,
+	742, 316, 745, 746, 744, 747, 748, 749, 750, 0,
+	751, 895, 752, 731, 732, 753, 754, 755, 943, 756,
+	757, 758, 759, 760, 761, 762, 763, 764, 896, 0,
+	766, 0, 765, 767, 768, 769, 770, 771, 772, 773,
+	775, 733, 776, 777, 778, 783, 784, 785, 897, 779,
+	780, 781, 782, 787, 898, 788, 789, 790, 791, 0,
+	792, 793, 0, 786, 774, 318, 794, 795, 796, 797,
+	798, 799, 800, 801, 802, 803, 0, 804, 899, 900,
+	901, 902, 0, 817, 0, 805, 807, 808, 809, 810,
+	903, 811, 812, 904, 0, 813, 814, 815, 816, 806,
+	819, 820, 818, 0, 0, 821, 822, 823, 824, 826,
+	828, 829, 830, 825, 827, 831, 0, 832, 0, 0,
+	833, 834, 835, 2237, 906, 907, 0, 908, 838, 839,
+	836, 837, 840, 841, 844, 842, 843, 909, 847, 542,
+	848, 849, 850, 845, 846, 0, 0, 0, 310, 851,
+	852, 910, 853, 854, 855, 0, 2234, 311, 1654, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 367, 368, 370, 369, 371,
+	372, 373, 374, 0, 375, 376, 0, 0, 254, 0,
+	0, 856, 0, 0, 0, 378, 0, 377, 0, 379,
+	380, 381, 926, 382, 383, 384, 385, 386, 387, 388,
+	389, 390, 857, 391, 858, 0, 392, 859, 393, 860,
+	0, 861, 394, 395, 396, 397, 398, 399, 400, 401,
+	402, 403, 404, 0, 0, 0, 405, 862, 863, 864,
+	0, 406, 407, 408, 409, 865, 0, 927, 0, 410,
+	411, 412, 413, 414, 415, 416, 417, 0, 0, 419,
+	420, 421, 418, 422, 423, 0, 424, 0, 425, 426,
+	427, 428, 429, 0, 430, 431, 0, 432, 433, 434,
+	928, 435, 436, 437, 0, 0, 0, 0, 0, 0,
+	0, 438, 439, 440, 441, 442, 0, 443, 445, 866,
+	867, 0, 448, 450, 444, 446, 0, 449, 447, 451,
+	452, 0, 453, 454, 455, 456, 457, 0, 0, 0,
+	458, 459, 460, 461, 0, 462, 463, 464, 466, 465,
+	0, 467, 468, 469, 0, 470, 471, 868, 472, 473,
+	474, 476, 478, 475, 477, 479, 480, 481, 482, 483,
+	869, 870, 484, 485, 0, 362, 0, 0, 0, 0,
+	0, 486, 487, 488, 871, 0, 0, 0, 489, 0,
+	491, 495, 496, 492, 493, 494, 497, 0, 490, 498,
+	499, 0, 929, 500, 501, 502, 872, 873, 503, 504,
+	505, 506, 507, 508, 509, 510, 511, 0, 512, 513,
+	874, 0, 875, 514, 0, 515, 516, 517, 518, 519,
+	520, 521, 876, 877, 878, 630, 931, 522, 523, 524,
+	525, 0, 526, 527, 528, 529, 530, 531, 532, 0,
+	0, 0, 533, 534, 535, 536, 0, 0, 0, 0,
+	930, 879, 537, 631, 538, 539, 880, 881, 0, 882,
+	0, 540, 541, 544, 932, 883, 933, 543, 545, 546,
+	934, 547, 0, 0, 0, 548, 549, 550, 551, 552,
+	553, 554, 0, 555, 557, 556, 0, 559, 884, 558,
+	935, 560, 561, 936, 0, 562, 563, 564, 565, 566,
+	567, 572, 0, 0, 568, 569, 570, 571, 573, 574,
+	0, 575, 576, 578, 581, 577, 579, 580, 582, 583,
+	596, 597, 598, 584, 585, 586, 587, 588, 589, 590,
+	591, 592, 593, 594, 595, 600, 0, 599, 937, 0,
+	601, 602, 603, 604, 605, 606, 612, 615, 617, 618,
+	613, 614, 616, 619, 620, 621, 623, 624, 609, 610,
+	611, 938, 622, 607, 0, 608, 0, 939, 625, 626,
+	627, 628, 0, 885, 629, 886, 632, 633, 0, 0,
+	634, 0, 635, 636, 0, 0, 638, 639, 640, 0,
+	0, 641, 642, 887, 940, 643, 941, 888, 644, 645,
+	637, 646, 647, 648, 649, 650, 651, 652, 653, 654,
+	655, 656, 657, 0, 658, 659, 889, 660, 661, 662,
+	663, 664, 890, 665, 666, 667, 891, 668, 892, 669,
+	670, 671, 0, 672, 673, 674, 0, 675, 676, 677,
+	678, 679, 680, 681, 682, 683, 684, 893, 685, 686,
+	688, 687, 689, 690, 0, 691, 692, 0, 693, 694,
+	695, 0, 0, 0, 0, 0, 696, 697, 699, 0,
+	700, 701, 702, 703, 704, 705, 698, 706, 707, 708,
+	709, 710, 711, 712, 713, 0, 715, 716, 714, 717,
+	718, 942, 719, 720, 721, 722, 723, 894, 724, 0,
+	725, 726, 734, 735, 736, 727, 728, 730, 737, 729,
+	738, 739, 740, 741, 743, 742, 316, 745, 746, 744,
+	747, 748, 749, 750, 0, 751, 895, 752, 731, 732,
+	753, 754, 755, 943, 756, 757, 758, 759, 760, 761,
+	762, 763, 764, 896, 0, 766, 0, 765, 767, 768,
+	769, 770, 771, 772, 773, 775, 733, 776, 777, 778,
+	783, 784, 785, 897, 779, 780, 781, 782, 787, 898,
+	788, 789, 790, 791, 0, 792, 793, 0, 786, 774,
+	318, 794, 795, 796, 797, 798, 799, 800, 801, 802,
+	803, 0, 804, 899, 900, 901, 902, 0, 817, 0,
+	805, 807, 808, 809, 810, 903, 811, 812, 904, 0,
+	813, 814, 815, 816, 806, 819, 820, 818, 0, 0,
+	821, 822, 823, 824, 826, 828, 829, 830, 825, 827,
+	831, 0, 832, 0, 0, 833, 834, 835, 2237, 906,
+	907, 0, 908, 838, 839, 836, 837, 840, 841, 844,
+	842, 843, 909, 847, 542, 848, 849, 850, 845, 846,
+	0, 0, 0, 310, 851, 852, 910, 853, 854, 855,
+	0, 0, 311, 1654, 1653, 0, 0, 0, 0, 1838,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	367, 368, 370, 369, 371, 372, 373, 374, 0, 375,
+	376, 0, 0, 254, 0, 0, 856, 0, 0, 0,
+	378, 0, 377, 0, 379, 380, 381, 926, 382, 383,
+	384, 385, 386, 387, 388, 389, 390, 857, 391, 858,
+	0, 392, 859, 393, 860, 0, 861, 394, 395, 396,
+	397, 398, 399, 400, 401, 402, 403, 404, 0, 0,
+	0, 405, 862, 863, 864, 0, 406, 407, 408, 409,
+	865, 0, 927, 0, 410, 411, 412, 413, 414, 415,
+	416, 417, 0, 0, 419, 420, 421, 418, 422, 423,
+	0, 424, 0, 425, 426, 427, 428, 429, 0, 430,
+	431, 0, 432, 433, 434, 928, 435, 436, 437, 0,
+	0, 0, 0, 0, 0, 0, 438, 439, 440, 441,
+	442, 0, 443, 445, 866, 867, 0, 448, 450, 444,
+	446, 0, 449, 447, 451, 452, 0, 453, 454, 455,
+	456, 457, 0, 0, 0, 458, 459, 460, 461, 0,
+	462, 463, 464, 466, 465, 0, 467, 468, 469, 0,
+	470, 471, 868, 472, 473, 474, 476, 478, 475, 477,
+	479, 480, 481, 482, 483, 869, 870, 484, 485, 0,
+	362, 0, 0, 0, 0, 0, 486, 487, 488, 871,
+	0, 0, 0, 489, 0, 491, 495, 496, 492, 493,
+	494, 497, 0, 490, 498, 499, 0, 929, 500, 501,
+	502, 872, 873, 503, 504, 505, 506, 507, 508, 509,
+	510, 511, 0, 512, 513, 874, 0, 875, 514, 0,
+	515, 516, 517, 518, 519, 520, 521, 876, 877, 878,
+	630, 931, 522, 523, 524, 525, 0, 526, 527, 528,
+	529, 530, 531, 532, 0, 0, 0, 533, 534, 535,
+	536, 0, 0, 0, 0, 930, 879, 537, 631, 538,
+	539, 880, 881, 0, 882, 0, 540, 541, 544, 932,
+	883, 933, 543, 545, 546, 934, 547, 0, 0, 0,
+	548, 549, 550, 551, 552, 553, 554, 0, 555, 557,
+	556, 0, 559, 884, 558, 935, 560, 561, 936, 0,
+	562, 563, 564, 565, 566, 567, 572, 0, 0, 568,
+	569, 570, 571, 573, 574, 0, 575, 576, 578, 581,
+	577, 579, 580, 582, 583, 596, 597, 598, 584, 585,
+	586, 587, 588, 589, 590, 591, 592, 593, 594, 595,
+	600, 0, 599, 937, 0, 601, 602, 603, 604, 605,
+	606, 612, 615, 617, 618, 613, 614, 616, 619, 620,
+	621, 623, 624, 609, 610, 611, 938, 622, 607, 0,
+	608, 0, 939, 625, 626, 627, 628, 0, 885, 629,
+	886, 632, 633, 0, 0, 634, 0, 635, 636, 0,
+	0, 638, 639, 640, 0, 0, 641, 642, 887, 940,
+	643, 941, 888, 644, 645, 637, 646, 647, 648, 649,
+	650, 651, 652, 653, 654, 655, 656, 657, 0, 658,
+	659, 889, 660, 661, 662, 663, 664, 890, 665, 666,
+	667, 891, 668, 892, 669, 670, 671, 0, 672, 673,
+	674, 0, 675, 676, 677, 678, 679, 680, 681, 682,
+	683, 684, 893, 685, 686, 688, 687, 689, 690, 0,
+	691, 692, 0, 693, 694, 695, 0, 0, 0, 0,
+	0, 696, 697, 699, 0, 700, 701, 702, 703, 704,
+	705, 698, 706, 707, 708, 709, 710, 711, 712, 713,
+	0, 715, 716, 714, 717, 718, 942, 719, 720, 721,
+	722, 723, 894, 724, 0, 725, 726, 734, 735, 736,
+	727, 728, 730, 737, 729, 738, 739, 740, 741, 743,
+	742, 0, 745, 746, 744, 747, 748, 749, 750, 0,
+	751, 895, 752, 731, 732, 753, 754, 755, 943, 756,
+	757, 758, 759, 760, 761, 762, 763, 764, 896, 0,
+	766, 0, 765, 767, 768, 769, 770, 771, 772, 773,
+	775, 733, 776, 777, 778, 783, 784, 785, 897, 779,
+	780, 781, 782, 787, 898, 788, 789, 790, 791, 0,
+	792, 793, 0, 786, 774, 0, 794, 795, 796, 797,
+	798, 799, 800, 801, 802, 803, 0, 804, 899, 900,
+	901, 902, 0, 817, 0, 805, 807, 808, 809, 810,
+	903, 811, 812, 904, 0, 813, 814, 815, 816, 806,
+	819, 820, 818, 0, 0, 821, 822, 823, 824, 826,
+	828, 829, 830, 825, 827, 831, 0, 832, 0, 0,
+	833, 834, 835, 905, 906, 907, 0, 908, 838, 839,
+	836, 837, 840, 841, 844, 842, 843, 909, 847, 542,
+	848, 849, 850, 845, 846, 0, 0, 0, 0, 851,
+	852, 910, 853, 854, 855, 0, 1654, 1653, 0, 0,
+	0, 0, 1838, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 367, 368, 370, 369, 371, 372, 373,
+	374, 0, 375, 376, 0, 0, 0, 0, 2724, 856,
+	0, 0, 0, 378, 0, 377, 0, 379, 380, 381,
+	926, 382, 383, 384, 385, 386, 387, 388, 389, 390,
+	857, 391, 858, 0, 392, 859, 393, 860, 0, 861,
+	394, 395, 396, 397, 398, 399, 400, 401, 402, 403,
+	404, 0, 0, 0, 405, 862, 863, 864, 0, 406,
+	407, 408, 409, 865, 0, 927, 0, 410, 411, 412,
+	413, 414, 415, 416, 417, 0, 0, 419, 420, 421,
+	418, 422, 423, 0, 424, 0, 425, 426, 427, 428,
+	429, 0, 430, 431, 0, 432, 433, 434, 928, 435,
+	436, 437, 0, 0, 0, 0, 0, 0, 0, 438,
+	439, 440, 441, 442, 0, 443, 445, 866, 867, 0,
+	448, 450, 444, 446, 0, 449, 447, 451, 452, 0,
+	453, 454, 455, 456, 457, 0, 0, 0, 458, 459,
+	460, 461, 0, 462, 463, 464, 466, 465, 0, 467,
+	468, 469, 0, 470, 471, 868, 472, 473, 474, 476,
+	478, 475, 477, 479, 480, 481, 482, 483, 869, 870,
+	484, 485, 0, 362, 0, 0, 0, 0, 0, 486,
+	487, 488, 871, 0, 0, 0, 489, 0, 491, 495,
+	496, 492, 493, 494, 497, 0, 490, 498, 499, 0,
+	929, 500, 501, 502, 872, 873, 503, 504, 505, 506,
+	507, 508, 509, 510, 511, 0, 512, 513, 874, 0,
+	875, 514, 0, 515, 516, 517, 518, 519, 520, 521,
+	876, 877, 878, 630, 931, 522, 523, 524, 525, 0,
+	526, 527, 528, 529, 530, 531, 532, 0, 0, 0,
+	533, 534, 535, 536, 0, 0, 0, 0, 930, 879,
+	537, 631, 538, 539, 880, 881, 0, 882, 0, 540,
+	541, 544, 932, 883, 933, 543, 545, 546, 934, 547,
+	0, 0, 0, 548, 549, 550, 551, 552, 553, 554,
+	0, 555, 557, 556, 0, 559, 884, 558, 935, 560,
+	561, 936, 0, 562, 563, 564, 565, 566, 567, 572,
+	0, 0, 568, 569, 570, 571, 573, 574, 0, 575,
+	576, 578, 581, 577, 579, 580, 582, 583, 596, 597,
+	598, 584, 585, 586, 587, 588, 589, 590, 591, 592,
+	593, 594, 595, 600, 0, 599, 937, 0, 601, 602,
+	603, 604, 605, 606, 612, 615, 617, 618, 613, 614,
+	616, 619, 620, 621, 623, 624, 609, 610, 611, 938,
+	622, 607, 0, 608, 0, 939, 625, 626, 627, 628,
+	0, 885, 629, 886, 632, 633, 0, 0, 634, 0,
+	635, 636, 0, 0, 638, 639, 640, 0, 0, 641,
+	642, 887, 940, 643, 941, 888, 644, 645, 637, 646,
+	647, 648, 649, 650, 651, 652, 653, 654, 655, 656,
+	657, 0, 658, 659, 889, 660, 661, 662, 663, 664,
+	890, 665, 666, 667, 891, 668, 892, 669, 670, 671,
+	0, 672, 673, 674, 0, 675, 676, 677, 678, 679,
+	680, 681, 682, 683, 684, 893, 685, 686, 688, 687,
+	689, 690, 0, 691, 692, 0, 693, 694, 695, 0,
+	0, 0, 0, 0, 696, 697, 699, 0, 700, 701,
+	702, 703, 704, 705, 698, 706, 707, 708, 709, 710,
+	711, 712, 713, 0, 715, 716, 714, 717, 718, 942,
+	719, 720, 721, 722, 723, 894, 724, 0, 725, 726,
+	734, 735, 736, 727, 728, 730, 737, 729, 738, 739,
+	740, 741, 743, 742, 0, 745, 746, 744, 747, 748,
+	749, 750, 0, 751, 895, 752, 731, 732, 753, 754,
+	755, 943, 756, 757, 758, 759, 760, 761, 762, 763,
+	764, 896, 0, 766, 0, 765, 767, 768, 769, 770,
+	771, 772, 773, 775, 733, 776, 777, 778, 783, 784,
+	785, 897, 779, 780, 781, 782, 787, 898, 788, 789,
+	790, 791, 0, 792, 793, 0, 786, 774, 0, 794,
+	795, 796, 797, 798, 799, 800, 801, 802, 803, 0,
+	804, 899, 900, 901, 902, 0, 817, 0, 805, 807,
+	808, 809, 810, 903, 811, 812, 904, 0, 813, 814,
+	815, 816, 806, 819, 820, 818, 0, 0, 821, 822,
+	823, 824, 826, 828, 829, 830, 825, 827, 831, 0,
+	832, 0, 0, 833, 834, 835, 905, 906, 907, 0,
+	908, 838, 839, 836, 837, 840, 841, 844, 842, 843,
+	909, 847, 542, 848, 849, 850, 845, 846, 0, 0,
+	0, 0, 851, 852, 910, 853, 854, 855, 0, 1654,
+	3043, 0, 0, 0, 0, 3044, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 367, 368, 370, 369,
+	371, 372, 373, 374, 0, 375, 376, 0, 0, 0,
+	0, 5431, 856, 0, 0, 0, 378, 0, 377, 0,
+	379, 380, 381, 926, 382, 383, 384, 385, 386, 387,
+	388, 389, 390, 857, 391, 858, 0, 392, 859, 393,
+	860, 0, 861, 394, 395, 396, 397, 398, 399, 400,
+	401, 402, 403, 404, 0, 0, 0, 405, 862, 863,
+	864, 0, 406, 407, 408, 409, 865, 0, 927, 0,
+	410, 411, 412, 413, 414, 415, 416, 417, 0, 0,
+	419, 420, 421, 418, 422, 423, 0, 424, 0, 425,
+	426, 427, 428, 429, 0, 430, 431, 0, 432, 433,
+	434, 928, 435, 436, 437, 0, 0, 0, 0, 0,
+	0, 0, 438, 439, 440, 441, 442, 0, 443, 445,
+	866, 867, 0, 448, 450, 444, 446, 0, 449, 447,
+	451, 452, 0, 453, 454, 455, 456, 457, 0, 0,
+	0, 458, 459, 460, 461, 0, 462, 463, 464, 466,
+	465, 0, 467, 468, 469, 0, 470, 471, 868, 472,
+	473, 474, 476, 478, 475, 477, 479, 480, 481, 482,
+	483, 869, 870, 484, 485, 0, 362, 0, 0, 0,
+	0, 0, 486, 487, 488, 871, 0, 0, 0, 489,
+	0, 491, 495, 496, 492, 493, 494, 497, 0, 490,
+	498, 499, 0, 929, 500, 501, 502, 872, 873, 503,
+	504, 505, 506, 507, 508, 509, 510, 511, 0, 512,
+	513, 874, 0, 875, 514, 0, 515, 516, 517, 518,
+	519, 520, 521, 876, 877, 878, 630, 931, 522, 523,
+	524, 525, 0, 526, 527, 528, 529, 530, 531, 532,
+	0, 0, 0, 533, 534, 535, 536, 0, 0, 0,
+	0, 930, 879, 537, 631, 538, 539, 880, 881, 0,
+	882, 0, 540, 541, 544, 932, 883, 933, 543, 545,
+	546, 934, 547, 0, 0, 0, 548, 549, 550, 551,
+	552, 553, 554, 0, 3042, 557, 556, 0, 559, 884,
+	558, 935, 560, 561, 936, 0, 562, 563, 564, 565,
+	566, 567, 572, 0, 0, 568, 569, 570, 571, 573,
+	574, 0, 575, 576, 578, 581, 577, 579, 580, 582,
+	583, 596, 597, 598, 584, 585, 586, 587, 588, 589,
+	590, 591, 592, 593, 594, 595, 600, 0, 599, 937,
+	0, 601, 602, 603, 604, 605, 606, 612, 615, 617,
+	618, 613, 614, 616, 619, 620, 621, 623, 624, 609,
+	610, 611, 938, 622, 607, 0, 608, 0, 939, 625,
+	626, 627, 628, 0, 885, 629, 886, 632, 633, 0,
+	0, 634, 0, 635, 636, 0, 0, 638, 639, 640,
+	0, 0, 641, 642, 887, 940, 643, 941, 888, 644,
+	645, 637, 646, 647, 648, 649, 650, 651, 652, 653,
+	654, 655, 656, 657, 0, 658, 659, 889, 660, 661,
+	662, 663, 664, 890, 665, 666, 667, 891, 668, 892,
+	669, 670, 671, 0, 672, 673, 674, 0, 675, 676,
+	677, 678, 679, 680, 681, 682, 683, 684, 893, 685,
+	686, 688, 687, 689, 690, 0, 691, 692, 0, 693,
+	694, 695, 0, 0, 0, 0, 0, 696, 697, 699,
+	0, 700, 701, 702, 703, 704, 705, 698, 706, 707,
+	708, 709, 710, 711, 712, 713, 0, 715, 716, 714,
+	717, 718, 942, 719, 720, 721, 722, 723, 894, 724,
+	0, 725, 726, 734, 735, 736, 727, 728, 730, 737,
+	729, 738, 739, 740, 741, 743, 742, 0, 745, 746,
+	744, 747, 748, 749, 750, 0, 751, 895, 752, 731,
+	732, 753, 754, 755, 943, 756, 757, 758, 759, 760,
+	761, 762, 763, 764, 896, 0, 766, 0, 765, 767,
+	768, 769, 770, 771, 772, 773, 775, 733, 776, 777,
+	778, 783, 784, 785, 897, 779, 780, 781, 782, 787,
+	898, 788, 789, 790, 791, 0, 792, 793, 0, 786,
+	774, 0, 794, 795, 796, 797, 798, 799, 800, 801,
+	802, 803, 0, 804, 899, 900, 901, 902, 0, 817,
+	0, 805, 807, 808, 809, 810, 903, 811, 812, 904,
+	0, 813, 814, 815, 816, 806, 819, 820, 818, 0,
+	0, 821, 822, 823, 824, 826, 828, 829, 830, 825,
+	827, 831, 0, 832, 0, 0, 833, 834, 835, 905,
+	906, 907, 0, 908, 838, 839, 836, 837, 840, 841,
+	844, 842, 843, 909, 847, 542, 848, 849, 850, 845,
+	846, 0, 0, 0, 0, 851, 852, 910, 853, 854,
+	855, 0, 1654, 1653, 0, 0, 0, 0, 1838, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 367,
+	368, 370, 369, 371, 372, 373, 374, 0, 375, 376,
+	0, 0, 0, 0, 2724, 856, 0, 0, 0, 378,
+	0, 377, 0, 379, 380, 381, 926, 382, 383, 384,
+	385, 386, 387, 388, 389, 390, 857, 391, 858, 0,
+	392, 859, 393, 860, 0, 861, 394, 395, 396, 397,
+	398, 399, 400, 401, 402, 403, 404, 0, 0, 0,
+	405, 862, 863, 864, 0, 406, 407, 408, 409, 865,
+	0, 927, 0, 410, 411, 412, 413, 414, 415, 416,
+	417, 0, 0, 419, 420, 421, 418, 422, 423, 0,
+	424, 0, 425, 426, 427, 428, 429, 0, 430, 431,
+	0, 432, 433, 434, 928, 435, 436, 437, 0, 0,
+	0, 0, 0, 0, 0, 438, 439, 440, 441, 442,
+	0, 443, 445, 866, 867, 0, 448, 450, 444, 446,
+	0, 449, 447, 451, 452, 0, 453, 454, 455, 456,
+	457, 0, 0, 0, 458, 459, 460, 461, 0, 462,
+	463, 464, 466, 465, 0, 467, 468, 469, 0, 470,
+	471, 868, 472, 473, 474, 476, 478, 475, 477, 479,
+	480, 481, 482, 483, 869, 870, 484, 485, 0, 362,
+	0, 0, 0, 0, 0, 486, 487, 488, 871, 0,
+	0, 0, 489, 0, 491, 495, 496, 492, 493, 494,
+	497, 0, 490, 498, 499, 0, 929, 500, 501, 502,
+	872, 873, 503, 504, 505, 506, 507, 508, 509, 510,
+	511, 0, 512, 513, 874, 0, 875, 514, 0, 515,
+	516, 517, 518, 519, 520, 521, 876, 877, 878, 630,
+	931, 522, 523, 524, 525, 0, 526, 527, 528, 529,
+	530, 531, 532, 0, 0, 0, 533, 534, 535, 536,
+	0, 0, 0, 0, 930, 879, 537, 631, 538, 539,
+	880, 881, 0, 882, 0, 540, 541, 544, 932, 883,
+	933, 543, 545, 546, 934, 547, 0, 0, 0, 548,
+	549, 550, 551, 552, 553, 554, 0, 555, 557, 556,
+	0, 559, 884, 558, 935, 560, 561, 936, 0, 562,
+	563, 564, 565, 566, 567, 572, 0, 0, 568, 569,
+	570, 571, 573, 574, 0, 575, 576, 578, 581, 577,
+	579, 580, 582, 583, 596, 597, 598, 584, 585, 586,
+	587, 588, 589, 590, 591, 592, 593, 594, 595, 600,
+	0, 599, 937, 0, 601, 602, 603, 604, 605, 606,
+	612, 615, 617, 618, 613, 614, 616, 619, 620, 621,
+	623, 624, 609, 610, 611, 938, 622, 607, 0, 608,
+	0, 939, 625, 626, 627, 628, 0, 885, 629, 886,
+	632, 633, 0, 0, 634, 0, 635, 636, 0, 0,
+	638, 639, 640, 0, 0, 641, 642, 887, 940, 643,
+	941, 888, 644, 645, 637, 646, 647, 648, 649, 650,
+	651, 652, 653, 654, 655, 656, 657, 0, 658, 659,
+	889, 660, 661, 662, 663, 664, 890, 665, 666, 667,
+	891, 668, 892, 669, 670, 671, 0, 672, 673, 674,
+	0, 675, 676, 677, 678, 679, 680, 681, 682, 683,
+	684, 893, 685, 686, 688, 687, 689, 690, 0, 691,
+	692, 0, 693, 694, 695, 0, 0, 0, 0, 0,
+	696, 697, 699, 0, 700, 701, 702, 703, 704, 705,
+	698, 706, 707, 708, 709, 710, 711, 712, 713, 0,
+	715, 716, 714, 717, 718, 942, 719, 720, 721, 722,
+	723, 894, 724, 0, 725, 726, 734, 735, 736, 727,
+	728, 730, 737, 729, 738, 739, 740, 741, 743, 742,
+	0, 745, 746, 744, 747, 748, 749, 750, 0, 751,
+	895, 752, 731, 732, 753, 754, 755, 943, 756, 757,
+	758, 759, 760, 761, 762, 763, 764, 896, 0, 766,
+	0, 765, 767, 768, 769, 770, 771, 772, 773, 775,
+	733, 776, 777, 778, 783, 784, 785, 897, 779, 780,
+	781, 782, 787, 898, 788, 789, 790, 791, 0, 792,
+	793, 0, 786, 774, 0, 794, 795, 796, 797, 798,
+	799, 800, 801, 802, 803, 0, 804, 899, 900, 901,
+	902, 0, 817, 0, 805, 807, 808, 809, 810, 903,
+	811, 812, 904, 0, 813, 814, 815, 816, 806, 819,
+	820, 818, 0, 0, 821, 822, 823, 824, 826, 828,
+	829, 830, 825, 827, 831, 0, 832, 0, 0, 833,
+	834, 835, 905, 906, 907, 0, 908, 838, 839, 836,
+	837, 840, 841, 844, 842, 843, 909, 847, 542, 848,
+	849, 850, 845, 846, 0, 0, 0, 920, 851, 852,
+	910, 853, 854, 855, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 367, 368, 370, 369, 371, 372,
+	373, 374, 0, 375, 376, 0, 0, 0, 0, 0,
+	856, 0, 0, 0, 378, 0, 377, 2243, 379, 380,
+	381, 926, 382, 383, 384, 385, 386, 387, 388, 389,
+	390, 857, 391, 858, 0, 392, 859, 393, 860, 0,
+	861, 394, 395, 396, 397, 398, 399, 400, 401, 402,
+	403, 404, 0, 0, 0, 405, 862, 863, 864, 0,
+	406, 407, 408, 409, 865, 0, 927, 0, 410, 411,
+	412, 413, 414, 415, 416, 417, 0, 0, 419, 420,
+	421, 418, 422, 423, 0, 424, 0, 425, 426, 427,
+	428, 429, 0, 430, 431, 0, 432, 433, 434, 928,
+	435, 436, 437, 0, 0, 0, 0, 0, 0, 0,
+	438, 439, 440, 441, 442, 0, 443, 445, 866, 867,
+	0, 448, 450, 444, 446, 0, 449, 447, 451, 452,
+	0, 453, 454, 455, 456, 457, 0, 0, 0, 458,
+	459, 460, 461, 0, 462, 463, 464, 466, 465, 0,
+	467, 468, 469, 0, 470, 471, 868, 472, 473, 474,
+	476, 478, 475, 477, 479, 480, 481, 482, 483, 869,
+	870, 484, 485, 0, 362, 0, 0, 0, 0, 0,
+	486, 487, 488, 871, 0, 0, 0, 489, 0, 491,
+	495, 496, 492, 493, 494, 497, 0, 490, 498, 499,
+	0, 929, 500, 501, 502, 872, 873, 503, 504, 505,
+	506, 507, 508, 509, 510, 511, 0, 512, 513, 874,
+	0, 875, 514, 0, 515, 516, 517, 518, 519, 520,
+	521, 876, 877, 878, 630, 931, 522, 523, 524, 525,
+	0, 526, 527, 528, 529, 530, 531, 532, 0, 0,
+	0, 533, 534, 535, 536, 0, 919, 363, 365, 930,
+	879, 537, 631, 538, 539, 880, 881, 0, 882, 0,
+	540, 541, 544, 932, 883, 933, 543, 545, 546, 934,
+	547, 0, 0, 0, 548, 549, 550, 551, 552, 553,
+	554, 0, 555, 557, 556, 0, 559, 884, 558, 935,
+	560, 561, 936, 0, 562, 563, 564, 565, 566, 567,
+	572, 0, 0, 568, 569, 570, 571, 573, 574, 0,
+	575, 576, 578, 581, 577, 579, 580, 582, 583, 596,
+	597, 598, 584, 585, 586, 587, 588, 589, 590, 591,
+	592, 593, 594, 595, 600, 0, 599, 937, 0, 601,
+	602, 603, 604, 605, 606, 612, 615, 617, 618, 613,
+	614, 616, 619, 620, 621, 623, 624, 609, 610, 611,
+	938, 622, 607, 0, 608, 366, 939, 625, 626, 627,
+	628, 0, 885, 629, 886, 632, 633, 0, 0, 634,
+	0, 635, 636, 0, 0, 638, 639, 640, 0, 0,
+	641, 642, 887, 940, 643, 941, 888, 644, 645, 637,
+	646, 647, 648, 649, 650, 651, 652, 653, 654, 655,
+	656, 657, 0, 658, 659, 889, 660, 661, 662, 663,
+	664, 890, 665, 666, 667, 891, 668, 892, 669, 670,
+	671, 0, 672, 673, 674, 0, 675, 676, 677, 678,
+	679, 680, 681, 682, 683, 684, 893, 685, 686, 688,
+	687, 689, 690, 0, 691, 692, 0, 693, 694, 695,
+	0, 0, 0, 0, 0, 696, 697, 699, 0, 700,
+	701, 702, 703, 704, 705, 698, 706, 707, 708, 709,
+	710, 711, 712, 713, 0, 715, 716, 714, 717, 718,
+	942, 719, 720, 721, 722, 723, 894, 724, 0, 725,
+	726, 734, 735, 736, 727, 728, 730, 737, 729, 738,
+	739, 740, 741, 743, 742, 0, 745, 746, 744, 747,
+	748, 749, 750, 0, 751, 895, 752, 731, 732, 753,
+	754, 755, 943, 756, 757, 758, 759, 760, 761, 762,
+	763, 764, 896, 0, 766, 0, 765, 767, 768, 769,
+	770, 771, 772, 773, 775, 733, 776, 777, 778, 783,
+	784, 785, 897, 779, 780, 781, 782, 787, 898, 788,
+	789, 790, 791, 0, 792, 793, 0, 786, 774, 0,
+	794, 795, 796, 797, 798, 799, 800, 801, 802, 803,
+	0, 804, 899, 900, 901, 902, 0, 817, 0, 805,
+	807, 808, 809, 810, 903, 811, 812, 904, 0, 813,
+	814, 815, 816, 806, 819, 820, 818, 0, 0, 821,
+	822, 823, 824, 826, 828, 829, 830, 825, 827, 831,
+	0, 832, 0, 0, 833, 834, 835, 905, 906, 907,
+	0, 908, 838, 839, 836, 837, 840, 841, 844, 842,
+	843, 909, 847, 542, 848, 849, 850, 845, 846, 0,
+	1462, 0, 359, 851, 852, 910, 853, 854, 855, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 367,
+	368, 370, 369, 371, 372, 373, 374, 0, 375, 376,
+	0, 0, 0, 0, 0, 856, 0, 0, 0, 378,
+	916, 377, 0, 379, 380, 381, 0, 382, 383, 384,
+	385, 386, 387, 388, 389, 390, 857, 391, 858, 0,
+	392, 859, 393, 860, 0, 861, 394, 395, 396, 397,
+	398, 399, 400, 401, 402, 403, 404, 0, 0, 0,
+	405, 862, 863, 864, 0, 406, 407, 408, 409, 865,
+	0, 0, 0, 410, 411, 412, 413, 414, 415, 416,
+	417, 0, 0, 419, 420, 421, 418, 422, 423, 0,
+	424, 0, 425, 426, 427, 428, 429, 0, 430, 431,
+	0, 432, 433, 434, 0, 435, 436, 437, 0, 0,
+	0, 0, 0, 0, 0, 438, 439, 440, 441, 442,
+	0, 443, 445, 866, 867, 0, 448, 450, 444, 446,
+	0, 449, 447, 451, 452, 0, 453, 454, 455, 456,
+	457, 0, 0, 0, 458, 459, 460, 461, 0, 462,
+	463, 464, 466, 465, 0, 467, 468, 469, 0, 470,
+	471, 868, 472, 473, 474, 476, 478, 475, 477, 479,
+	480, 481, 482, 483, 869, 870, 484, 485, 0, 0,
+	0, 0, 0, 0, 0, 486, 487, 488, 871, 0,
+	0, 0, 489, 0, 491, 495, 496, 492, 493, 494,
+	497, 0, 490, 498, 499, 0, 0, 500, 501, 502,
+	872, 873, 503, 504, 505, 506, 507, 508, 509, 510,
+	511, 0, 512, 513, 874, 0, 875, 514, 0, 515,
+	516, 517, 518, 519, 520, 521, 876, 877, 878, 630,
+	0, 522, 523, 524, 525, 0, 526, 527, 528, 529,
+	530, 531, 532, 0, 0, 0, 533, 534, 535, 536,
+	0, 0, 0, 0, 0, 879, 537, 631, 538, 539,
+	880, 881, 0, 882, 0, 540, 541, 544, 0, 883,
+	0, 543, 545, 546, 0, 547, 0, 0, 0, 548,
+	549, 550, 551, 552, 553, 554, 0, 555, 557, 556,
+	0, 559, 884, 558, 0, 560, 561, 0, 0, 562,
+	563, 564, 565, 566, 567, 572, 0, 0, 568, 569,
+	570, 571, 573, 574, 0, 575, 576, 578, 581, 577,
+	579, 580, 582, 583, 596, 597, 598, 584, 585, 586,
+	587, 588, 589, 590, 591, 592, 593, 594, 595, 600,
+	0, 599, 0, 0, 601, 602, 603, 604, 605, 606,
+	612, 615, 617, 618, 613, 614, 616, 619, 620, 621,
+	623, 624, 609, 610, 611, 0, 622, 607, 0, 608,
+	0, 0, 625, 626, 627, 628, 0, 885, 629, 886,
+	632, 633, 0, 0, 634, 0, 635, 636, 0, 0,
+	638, 639, 640, 0, 0, 641, 642, 887, 0, 643,
+	0, 888, 644, 645, 637, 646, 647, 648, 649, 650,
+	651, 652, 653, 654, 655, 656, 657, 0, 658, 659,
+	889, 660, 661, 662, 663, 664, 890, 665, 666, 667,
+	891, 668, 892, 669, 670, 671, 0, 672, 673, 674,
+	0, 675, 676, 677, 678, 679, 680, 681, 682, 683,
+	684, 893, 685, 686, 688, 687, 689, 690, 0, 691,
+	692, 0, 693, 694, 695, 0, 0, 0, 0, 0,
+	696, 697, 699, 0, 700, 701, 702, 703, 704, 705,
+	698, 706, 707, 708, 709, 710, 711, 712, 713, 0,
+	715, 716, 714, 717, 718, 0, 719, 720, 721, 722,
+	723, 894, 724, 0, 725, 726, 734, 735, 736, 727,
+	728, 730, 737, 729, 738, 739, 740, 741, 743, 742,
+	316, 745, 746, 744, 747, 748, 749, 750, 0, 751,
+	895, 752, 731, 732, 753, 754, 755, 0, 756, 757,
+	758, 759, 760, 761, 762, 763, 764, 896, 0, 766,
+	0, 765, 767, 768, 769, 770, 771, 772, 773, 775,
+	733, 776, 777, 778, 783, 784, 785, 897, 779, 780,
+	781, 782, 787, 898, 788, 789, 790, 791, 0, 792,
+	793, 0, 786, 774, 318, 794, 795, 796, 797, 798,
+	799, 800, 801, 802, 803, 0, 804, 899, 900, 901,
+	902, 0, 817, 0, 805, 807, 808, 809, 810, 903,
+	811, 812, 904, 0, 813, 814, 815, 816, 806, 819,
+	820, 818, 0, 0, 821, 822, 823, 824, 826, 828,
+	829, 830, 825, 827, 831, 0, 832, 0, 0, 833,
+	834, 835, 2237, 906, 907, 0, 908, 838, 839, 836,
+	837, 840, 841, 844, 842, 843, 909, 847, 542, 848,
+	849, 850, 845, 846, 0, 0, 0, 310, 851, 852,
+	910, 853, 854, 855, 0, 359, 311, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 367, 368, 370, 369, 371, 372, 373, 374,
+	0, 375, 376, 0, 0, 0, 0, 254, 856, 0,
+	0, 0, 378, 0, 377, 0, 379, 380, 381, 0,
+	382, 383, 384, 385, 386, 387, 388, 389, 390, 857,
+	391, 858, 0, 392, 859, 393, 860, 0, 861, 394,
+	395, 396, 397, 398, 399, 400, 401, 402, 403, 404,
+	0, 0, 0, 405, 862, 863, 864, 0, 406, 407,
+	408, 409, 865, 0, 0, 0, 410, 411, 412, 413,
+	414, 415, 416, 417, 0, 0, 419, 420, 421, 418,
+	422, 423, 0, 424, 0, 425, 426, 427, 428, 429,
+	0, 430, 431, 0, 432, 433, 434, 0, 435, 436,
+	437, 0, 0, 0, 0, 0, 0, 0, 438, 439,
+	440, 441, 442, 0, 443, 445, 866, 867, 0, 448,
+	450, 444, 446, 0, 449, 447, 451, 452, 0, 453,
+	454, 455, 456, 457, 0, 0, 0, 458, 459, 460,
+	461, 0, 462, 463, 464, 466, 465, 0, 467, 468,
+	469, 0, 470, 471, 868, 472, 473, 474, 476, 478,
+	475, 477, 479, 480, 481, 482, 483, 869, 870, 484,
+	485, 0, 362, 0, 0, 0, 0, 0, 486, 487,
+	488, 871, 0, 0, 0, 489, 0, 491, 495, 496,
+	492, 493, 494, 497, 0, 490, 498, 499, 0, 0,
+	500, 501, 502, 872, 873, 503, 504, 505, 506, 507,
+	508, 509, 510, 511, 0, 512, 513, 874, 0, 875,
+	514, 0, 515, 516, 517, 518, 519, 520, 521, 876,
+	877, 878, 630, 0, 522, 523, 524, 525, 0, 526,
+	527, 528, 529, 530, 531, 532, 0, 0, 0, 533,
+	534, 535, 536, 0, 364, 363, 365, 0, 879, 537,
+	631, 538, 539, 880, 881, 0, 882, 0, 540, 541,
+	544, 0, 883, 0, 543, 545, 546, 0, 547, 0,
+	0, 0, 548, 549, 550, 551, 552, 553, 554, 0,
+	555, 557, 556, 0, 559, 884, 558, 0, 560, 561,
+	0, 0, 562, 563, 564, 565, 566, 567, 572, 0,
+	0, 568, 569, 570, 571, 573, 574, 0, 575, 576,
+	578, 581, 577, 579, 580, 582, 583, 596, 597, 598,
+	584, 585, 586, 587, 588, 589, 590, 591, 592, 593,
+	594, 595, 600, 0, 599, 0, 0, 601, 602, 603,
+	604, 605, 606, 612, 615, 617, 618, 613, 614, 616,
+	619, 620, 621, 623, 624, 609, 610, 611, 0, 622,
+	607, 0, 608, 366, 0, 625, 626, 627, 628, 0,
+	885, 629, 886, 632, 633, 0, 0, 634, 0, 635,
+	636, 0, 0, 638, 639, 640, 0, 0, 641, 642,
+	887, 0, 643, 0, 888, 644, 645, 637, 646, 647,
+	648, 649, 650, 651, 652, 653, 654, 655, 656, 657,
+	0, 658, 659, 889, 660, 661, 662, 663, 664, 890,
+	665, 666, 667, 891, 668, 892, 669, 670, 671, 0,
+	672, 673, 674, 0, 675, 676, 677, 678, 679, 680,
+	681, 682, 683, 684, 893, 685, 686, 688, 687, 689,
+	690, 0, 691, 692, 0, 693, 694, 695, 0, 0,
+	0, 0, 0, 696, 697, 699, 0, 700, 701, 702,
+	703, 704, 705, 698, 706, 707, 708, 709, 710, 711,
+	712, 713, 0, 715, 716, 714, 717, 718, 0, 719,
+	720, 721, 722, 723, 894, 724, 0, 725, 726, 734,
+	735, 736, 727, 728, 730, 737, 729, 738, 739, 740,
+	741, 743, 742, 0, 745, 746, 744, 747, 748, 749,
+	750, 0, 751, 895, 752, 731, 732, 753, 754, 755,
+	0, 756, 757, 758, 759, 760, 761, 762, 763, 764,
+	896, 0, 766, 0, 765, 767, 768, 769, 770, 771,
+	772, 773, 775, 733, 776, 777, 778, 783, 784, 785,
+	897, 779, 780, 781, 782, 787, 898, 788, 789, 790,
+	791, 0, 792, 793, 0, 786, 774, 0, 794, 795,
+	796, 797, 798, 799, 800, 801, 802, 803, 0, 804,
+	899, 900, 901, 902, 0, 817, 0, 805, 807, 808,
+	809, 810, 903, 811, 812, 904, 0, 813, 814, 815,
+	816, 806, 819, 820, 818, 0, 0, 821, 822, 823,
+	824, 826, 828, 829, 830, 825, 827, 831, 0, 832,
+	0, 0, 833, 834, 835, 905, 906, 907, 0, 908,
+	838, 839, 836, 837, 840, 841, 844, 842, 843, 909,
+	847, 542, 848, 849, 850, 845, 846, 0, 0, 0,
+	359, 851, 852, 910, 853, 854, 855, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 367, 368, 370,
+	369, 371, 372, 373, 374, 0, 375, 376, 0, 0,
+	0, 0, 0, 856, 0, 0, 0, 378, 0, 377,
+	2508, 379, 380, 381, 0, 382, 383, 384, 385, 386,
+	387, 388, 389, 390, 857, 391, 858, 0, 392, 859,
+	393, 860, 0, 861, 394, 395, 396, 397, 398, 399,
+	400, 401, 402, 403, 404, 0, 0, 0, 405, 862,
+	863, 864, 0, 406, 407, 408, 409, 865, 0, 0,
+	0, 410, 411, 412, 413, 414, 415, 416, 417, 0,
+	0, 419, 420, 421, 418, 422, 423, 0, 424, 0,
+	425, 426, 427, 428, 429, 0, 430, 431, 0, 432,
+	433, 434, 0, 435, 436, 437, 0, 0, 0, 0,
+	0, 0, 0, 438, 439, 440, 441, 442, 0, 443,
+	445, 866, 867, 0, 448, 450, 444, 446, 0, 449,
+	447, 451, 452, 0, 453, 454, 455, 456, 457, 0,
+	0, 0, 458, 459, 460, 461, 0, 462, 463, 464,
+	466, 465, 0, 467, 468, 469, 0, 470, 471, 868,
+	472, 473, 474, 476, 478, 475, 477, 479, 480, 481,
+	482, 483, 869, 870, 484, 485, 0, 362, 0, 0,
+	0, 0, 0, 486, 487, 488, 871, 0, 0, 0,
+	489, 0, 491, 495, 496, 492, 493, 494, 497, 0,
+	490, 498, 499, 0, 0, 500, 501, 502, 872, 873,
+	503, 504, 505, 506, 507, 508, 509, 510, 511, 0,
+	512, 513, 874, 0, 875, 514, 0, 515, 516, 517,
+	518, 519, 520, 521, 876, 877, 878, 630, 0, 522,
+	523, 524, 525, 0, 526, 527, 528, 529, 530, 531,
+	532, 0, 0, 0, 533, 534, 535, 536, 0, 364,
+	363, 365, 0, 879, 537, 631, 538, 539, 880, 881,
+	0, 882, 0, 540, 541, 544, 0, 883, 0, 543,
+	545, 546, 0, 547, 0, 0, 0, 548, 549, 550,
+	551, 552, 553, 554, 0, 555, 557, 556, 0, 559,
+	884, 558, 0, 560, 561, 0, 0, 562, 563, 564,
+	565, 566, 567, 572, 0, 0, 568, 569, 570, 571,
+	573, 574, 0, 575, 576, 578, 581, 577, 579, 580,
+	582, 583, 596, 597, 598, 584, 585, 586, 587, 588,
+	589, 590, 591, 592, 593, 594, 595, 600, 0, 599,
+	0, 0, 601, 602, 603, 604, 605, 606, 612, 615,
+	617, 618, 613, 614, 616, 619, 620, 621, 623, 624,
+	609, 610, 611, 0, 622, 607, 0, 608, 366, 0,
+	625, 626, 627, 628, 0, 885, 629, 886, 632, 633,
+	0, 0, 634, 0, 635, 636, 0, 0, 638, 639,
+	640, 0, 0, 641, 642, 887, 0, 643, 0, 888,
+	644, 645, 637, 646, 647, 648, 649, 650, 651, 652,
+	653, 654, 655, 656, 657, 0, 658, 659, 889, 660,
+	661, 662, 663, 664, 890, 665, 666, 667, 891, 668,
+	892, 669, 670, 671, 0, 672, 673, 674, 0, 675,
+	676, 677, 678, 679, 680, 681, 682, 683, 684, 893,
+	685, 686, 688, 687, 689, 690, 0, 691, 692, 0,
+	693, 694, 695, 0, 0, 0, 0, 0, 696, 697,
+	699, 0, 700, 701, 702, 703, 704, 705, 698, 706,
+	707, 708, 709, 710, 711, 712, 713, 0, 715, 716,
+	714, 717, 718, 0, 719, 720, 721, 722, 723, 894,
+	724, 0, 725, 726, 734, 735, 736, 727, 728, 730,
+	737, 729, 738, 739, 740, 741, 743, 742, 0, 745,
+	746, 744, 747, 748, 749, 750, 0, 751, 895, 752,
+	731, 732, 753, 754, 755, 0, 756, 757, 758, 759,
+	760, 761, 762, 763, 764, 896, 0, 766, 0, 765,
+	767, 768, 769, 770, 771, 772, 773, 775, 733, 776,
+	777, 778, 783, 784, 785, 897, 779, 780, 781, 782,
+	787, 898, 788, 789, 790, 791, 0, 792, 793, 0,
+	786, 774, 0, 794, 795, 796, 797, 798, 799, 800,
+	801, 802, 803, 0, 804, 899, 900, 901, 902, 0,
+	817, 0, 805, 807, 808, 809, 810, 903, 811, 812,
+	904, 0, 813, 814, 815, 816, 806, 819, 820, 818,
+	0, 0, 821, 822, 823, 824, 826, 828, 829, 830,
+	825, 827, 831, 0, 832, 0, 0, 833, 834, 835,
+	905, 906, 907, 0, 908, 838, 839, 836, 837, 840,
+	841, 844, 842, 843, 909, 847, 542, 848, 849, 850,
+	845, 846, 0, 0, 0, 359, 851, 852, 910, 853,
+	854, 855, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 367, 368, 370, 369, 371, 372, 373, 374,
+	0, 375, 376, 0, 0, 0, 0, 0, 856, 0,
+	0, 0, 378, 0, 377, 945, 379, 380, 381, 0,
+	382, 383, 384, 385, 386, 387, 388, 389, 390, 857,
+	391, 858, 0, 392, 859, 393, 860, 0, 861, 394,
+	395, 396, 397, 398, 399, 400, 401, 402, 403, 404,
+	0, 0, 0, 405, 862, 863, 864, 0, 406, 407,
+	408, 409, 865, 0, 0, 0, 410, 411, 412, 413,
+	414, 415, 416, 417, 0, 0, 419, 420, 421, 418,
+	422, 423, 0, 424, 0, 425, 426, 427, 428, 429,
+	0, 430, 431, 0, 432, 433, 434, 0, 435, 436,
+	437, 0, 0, 0, 0, 0, 0, 0, 438, 439,
+	440, 441, 442, 0, 443, 445, 866, 867, 0, 448,
+	450, 444, 446, 0, 449, 447, 451, 452, 0, 453,
+	454, 455, 456, 457, 0, 0, 0, 458, 459, 460,
+	461, 0, 462, 463, 464, 466, 465, 0, 467, 468,
+	469, 0, 470, 471, 868, 472, 473, 474, 476, 478,
+	475, 477, 479, 480, 481, 482, 483, 869, 870, 484,
+	485, 0, 362, 0, 0, 0, 0, 0, 486, 487,
+	488, 871, 0, 0, 0, 489, 0, 491, 495, 496,
+	492, 493, 494, 497, 0, 490, 498, 499, 0, 0,
+	500, 501, 502, 872, 873, 503, 504, 505, 506, 507,
+	508, 509, 510, 511, 0, 512, 513, 874, 0, 875,
+	514, 0, 515, 516, 517, 518, 519, 520, 521, 876,
+	877, 878, 630, 0, 522, 523, 524, 525, 0, 526,
+	527, 528, 529, 530, 531, 532, 0, 0, 0, 533,
+	534, 535, 536, 0, 364, 363, 365, 0, 879, 537,
+	631, 538, 539, 880, 881, 0, 882, 0, 540, 541,
+	544, 0, 883, 0, 543, 545, 546, 0, 547, 0,
+	0, 0, 548, 549, 550, 551, 552, 553, 554, 0,
+	555, 557, 556, 0, 559, 884, 558, 0, 560, 561,
+	0, 0, 562, 563, 564, 565, 566, 567, 572, 0,
+	0, 568, 569, 570, 571, 573, 574, 0, 575, 576,
+	578, 581, 577, 579, 580, 582, 583, 596, 597, 598,
+	584, 585, 586, 587, 588, 589, 590, 591, 592, 593,
+	594, 595, 600, 0, 599, 0, 0, 601, 602, 603,
+	604, 605, 606, 612, 615, 617, 618, 613, 614, 616,
+	619, 620, 621, 623, 624, 609, 610, 611, 0, 622,
+	607, 0, 608, 366, 0, 625, 626, 627, 628, 0,
+	885, 629, 886, 632, 633, 0, 0, 634, 0, 635,
+	636, 0, 0, 638, 639, 640, 0, 0, 641, 642,
+	887, 0, 643, 0, 888, 644, 645, 637, 646, 647,
+	648, 649, 650, 651, 652, 653, 654, 655, 656, 657,
+	0, 658, 659, 889, 660, 661, 662, 663, 664, 890,
+	665, 666, 667, 891, 668, 892, 669, 670, 671, 0,
+	672, 673, 674, 0, 675, 676, 677, 678, 679, 680,
+	681, 682, 683, 684, 893, 685, 686, 688, 687, 689,
+	690, 0, 691, 692, 0, 693, 694, 695, 0, 0,
+	0, 0, 0, 696, 697, 699, 0, 700, 701, 702,
+	703, 704, 705, 698, 706, 707, 708, 709, 710, 711,
+	712, 713, 0, 715, 716, 714, 717, 718, 0, 719,
+	720, 721, 722, 723, 894, 724, 0, 725, 726, 734,
+	735, 736, 727, 728, 730, 737, 729, 738, 739, 740,
+	741, 743, 742, 0, 745, 746, 744, 747, 748, 749,
+	750, 0, 751, 895, 752, 731, 732, 753, 754, 755,
+	0, 756, 757, 758, 759, 760, 761, 762, 763, 764,
+	896, 0, 766, 0, 765, 767, 768, 769, 770, 771,
+	772, 773, 775, 733, 776, 777, 778, 783, 784, 785,
+	897, 779, 780, 781, 782, 787, 898, 788, 789, 790,
+	791, 0, 792, 793, 0, 786, 774, 0, 794, 795,
+	796, 797, 798, 799, 800, 801, 802, 803, 0, 804,
+	899, 900, 901, 902, 0, 817, 0, 805, 807, 808,
+	809, 810, 903, 811, 812, 904, 0, 813, 814, 815,
+	816, 806, 819, 820, 818, 0, 0, 821, 822, 823,
+	824, 826, 828, 829, 830, 825, 827, 831, 0, 832,
+	0, 0, 833, 834, 835, 905, 906, 907, 0, 908,
+	838, 839, 836, 837, 840, 841, 844, 842, 843, 909,
+	847, 542, 848, 849, 850, 845, 846, 0, 359, 4543,
+	0, 851, 852, 910, 853, 854, 855, 0, 0, 0,
+	0, 0, 0, 0, 0, 367, 368, 370, 369, 371,
+	372, 373, 374, 0, 375, 376, 0, 0, 0, 0,
+	0, 856, 0, 0, 0, 378, 0, 377, 5369, 379,
+	380, 381, 0, 382, 383, 384, 385, 386, 387, 388,
+	389, 390, 857, 391, 858, 0, 392, 859, 393, 860,
+	0, 861, 394, 395, 396, 397, 398, 399, 400, 401,
+	402, 403, 404, 0, 0, 0, 405, 862, 863, 864,
+	0, 406, 407, 408, 409, 865, 0, 0, 0, 410,
+	411, 412, 413, 414, 415, 416, 417, 0, 0, 419,
+	420, 421, 418, 422, 423, 0, 424, 0, 425, 426,
+	427, 428, 429, 0, 430, 431, 0, 432, 433, 434,
+	0, 435, 436, 437, 0, 0, 0, 0, 0, 0,
+	0, 438, 439, 440, 441, 442, 0, 443, 445, 866,
+	867, 0, 448, 450, 444, 446, 0, 449, 447, 451,
+	452, 0, 453, 454, 455, 456, 457, 0, 0, 0,
+	458, 459, 460, 461, 0, 462, 463, 464, 466, 465,
+	0, 467, 468, 469, 0, 470, 471, 868, 472, 473,
+	474, 476, 478, 475, 477, 479, 480, 481, 482, 483,
+	869, 870, 484, 485, 0, 0, 0, 0, 0, 0,
+	0, 486, 487, 488, 871, 0, 0, 0, 489, 0,
+	491, 495, 496, 492, 493, 494, 497, 0, 490, 498,
+	499, 0, 0, 500, 501, 502, 872, 873, 503, 504,
+	505, 506, 507, 508, 509, 510, 511, 0, 512, 513,
+	874, 0, 875, 514, 0, 515, 516, 517, 518, 519,
+	520, 521, 876, 877, 878, 630, 0, 522, 523, 524,
+	525, 0, 526, 527, 528, 529, 530, 531, 532, 0,
+	0, 0, 533, 534, 535, 536, 0, 0, 0, 0,
+	0, 879, 537, 631, 538, 539, 880, 881, 0, 882,
+	0, 540, 541, 544, 0, 883, 0, 543, 545, 546,
+	0, 547, 0, 0, 0, 548, 549, 550, 551, 552,
+	553, 554, 0, 555, 557, 556, 0, 559, 884, 558,
+	0, 560, 561, 0, 0, 562, 563, 564, 565, 566,
+	567, 572, 0, 0, 568, 569, 570, 571, 573, 574,
+	0, 575, 576, 578, 581, 577, 579, 580, 582, 583,
+	596, 597, 598, 584, 585, 586, 587, 588, 589, 590,
+	591, 592, 593, 594, 595, 600, 0, 599, 0, 0,
+	601, 602, 603, 604, 605, 606, 612, 615, 617, 618,
+	613, 614, 616, 619, 620, 621, 623, 624, 609, 610,
+	611, 0, 622, 607, 0, 608, 0, 0, 625, 626,
+	627, 628, 0, 885, 629, 886, 632, 633, 0, 0,
+	634, 0, 635, 636, 0, 0, 638, 639, 640, 0,
+	0, 641, 642, 887, 0, 643, 0, 888, 644, 645,
+	637, 646, 647, 648, 649, 650, 651, 652, 653, 654,
+	655, 656, 657, 0, 658, 659, 889, 660, 661, 662,
+	663, 664, 890, 665, 666, 667, 891, 668, 892, 669,
+	670, 671, 0, 672, 673, 674, 0, 675, 676, 677,
+	678, 679, 680, 681, 682, 683, 684, 893, 685, 686,
+	688, 687, 689, 690, 0, 691, 692, 0, 693, 694,
+	695, 0, 0, 0, 0, 0, 696, 697, 699, 0,
+	700, 701, 702, 703, 704, 705, 698, 706, 707, 708,
+	709, 710, 711, 712, 713, 0, 715, 716, 714, 717,
+	718, 0, 719, 720, 721, 722, 723, 894, 724, 0,
+	725, 726, 734, 735, 736, 727, 728, 730, 737, 729,
+	738, 739, 740, 741, 743, 742, 0, 745, 746, 744,
+	747, 748, 749, 750, 0, 751, 895, 752, 731, 732,
+	753, 754, 755, 0, 756, 757, 758, 759, 760, 761,
+	762, 763, 764, 896, 0, 766, 0, 765, 767, 768,
+	769, 770, 771, 772, 773, 775, 733, 776, 777, 778,
+	783, 784, 785, 897, 779, 780, 781, 782, 787, 898,
+	788, 789, 790, 791, 0, 792, 793, 0, 786, 774,
+	0, 794, 795, 796, 797, 798, 799, 800, 801, 802,
+	803, 0, 804, 899, 900, 901, 902, 0, 817, 0,
+	805, 807, 808, 809, 810, 903, 811, 812, 904, 0,
+	813, 814, 815, 816, 806, 819, 820, 818, 0, 0,
+	821, 822, 823, 824, 826, 828, 829, 830, 825, 827,
+	831, 0, 832, 0, 0, 833, 834, 835, 905, 906,
+	907, 0, 908, 838, 839, 836, 837, 840, 841, 844,
+	842, 843, 909, 847, 542, 848, 849, 850, 845, 846,
+	0, 0, 0, 4221, 851, 852, 910, 853, 854, 855,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	367, 368, 370, 369, 371, 372, 373, 374, 0, 375,
+	376, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	378, 0, 377, 7204, 379, 380, 381, 926, 382, 383,
+	384, 385, 386, 387, 388, 389, 390, 0, 391, 2580,
+	0, 392, 2587, 393, 2586, 0, 2595, 394, 395, 396,
+	397, 398, 399, 400, 401, 402, 403, 404, 0, 0,
+	0, 405, 2599, 2600, 0, 0, 406, 407, 408, 409,
+	0, 0, 927, 0, 410, 411, 412, 413, 414, 415,
+	416, 417, 0, 0, 419, 420, 421, 418, 422, 423,
+	0, 424, 0, 425, 426, 427, 428, 429, 0, 430,
+	431, 0, 432, 433, 434, 928, 435, 436, 437, 0,
+	0, 0, 0, 0, 0, 0, 438, 439, 440, 441,
+	442, 1568, 443, 445, 2584, 2583, 0, 448, 450, 444,
+	446, 0, 449, 447, 451, 452, 0, 453, 454, 455,
+	456, 457, 0, 0, 0, 458, 1560, 460, 461, 0,
+	462, 463, 464, 466, 465, 0, 467, 468, 469, 0,
+	470, 471, 0, 472, 473, 474, 476, 478, 475, 477,
+	479, 480, 481, 482, 483, 0, 0, 484, 485, 0,
+	362, 0, 0, 0, 0, 0, 486, 487, 488, 2582,
+	0, 0, 0, 489, 0, 491, 495, 496, 492, 493,
+	494, 497, 0, 490, 498, 499, 0, 929, 500, 501,
+	502, 2593, 2594, 503, 504, 505, 506, 507, 508, 509,
+	510, 511, 0, 512, 513, 0, 0, 0, 514, 0,
+	515, 516, 517, 518, 519, 520, 521, 0, 0, 0,
+	630, 931, 522, 523, 524, 525, 4215, 526, 527, 528,
+	529, 530, 531, 532, 0, 0, 0, 533, 534, 535,
+	536, 0, 0, 0, 0, 930, 4217, 537, 631, 538,
+	539, 2577, 2578, 0, 2573, 0, 540, 541, 544, 932,
+	0, 933, 543, 545, 546, 934, 547, 0, 0, 0,
+	548, 549, 550, 551, 552, 553, 554, 0, 555, 557,
+	556, 0, 559, 0, 558, 935, 560, 561, 936, 0,
+	562, 563, 564, 565, 566, 567, 572, 0, 0, 568,
+	569, 570, 571, 573, 574, 0, 575, 576, 578, 581,
+	577, 579, 580, 582, 583, 596, 597, 598, 584, 585,
+	586, 587, 588, 589, 590, 591, 592, 593, 594, 595,
+	600, 0, 599, 937, 0, 601, 602, 603, 604, 605,
+	606, 612, 615, 617, 618, 613, 614, 616, 619, 620,
+	621, 623, 624, 609, 610, 611, 938, 622, 607, 0,
+	608, 0, 939, 625, 626, 627, 628, 0, 0, 629,
+	2585, 632, 633, 0, 0, 634, 0, 635, 636, 0,
+	0, 638, 639, 640, 0, 0, 641, 642, 4216, 940,
+	643, 941, 0, 644, 645, 637, 646, 647, 648, 649,
+	650, 651, 652, 653, 654, 655, 656, 657, 0, 658,
+	659, 2570, 660, 661, 662, 663, 664, 2571, 665, 666,
+	667, 0, 668, 0, 669, 670, 671, 0, 672, 673,
+	674, 0, 675, 676, 677, 678, 679, 680, 681, 682,
+	683, 684, 2581, 685, 686, 688, 687, 689, 690, 0,
+	691, 692, 0, 693, 694, 695, 0, 0, 0, 0,
+	0, 696, 697, 699, 0, 700, 701, 702, 703, 704,
+	705, 698, 706, 707, 708, 709, 710, 711, 712, 713,
+	0, 715, 716, 714, 717, 718, 942, 719, 720, 721,
+	722, 723, 0, 724, 0, 725, 726, 734, 735, 736,
+	727, 728, 730, 737, 729, 738, 739, 740, 741, 743,
+	742, 0, 745, 746, 744, 747, 748, 749, 750, 0,
+	751, 0, 752, 731, 732, 753, 754, 755, 943, 756,
+	757, 758, 759, 760, 761, 762, 763, 764, 2579, 0,
+	766, 0, 765, 767, 768, 769, 770, 771, 772, 773,
+	775, 733, 776, 777, 778, 783, 784, 785, 2598, 779,
+	780, 781, 782, 787, 0, 788, 789, 790, 791, 0,
+	792, 793, 0, 786, 774, 0, 794, 795, 796, 797,
+	798, 799, 800, 801, 802, 803, 0, 804, 2589, 2590,
+	2591, 2592, 0, 817, 0, 805, 807, 808, 809, 810,
+	0, 811, 812, 0, 0, 813, 814, 815, 816, 806,
+	819, 820, 818, 0, 0, 821, 822, 823, 824, 826,
+	828, 829, 830, 825, 827, 831, 0, 832, 0, 0,
+	833, 834, 835, 0, 2588, 2597, 4218, 2596, 838, 839,
+	836, 837, 840, 841, 844, 842, 843, 0, 847, 542,
+	848, 849, 850, 845, 846, 0, 0, 0, 0, 851,
+	852, 0, 853, 854, 855, 0, 0, 359, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 367, 368, 370, 369, 371, 372,
+	373, 374, 0, 375, 376, 0, 0, 0, 0, 4210,
+	856, 0, 2566, 0, 378, 0, 377, 0, 379, 380,
+	381, 0, 382, 383, 384, 385, 386, 387, 388, 389,
+	390, 857, 391, 858, 0, 392, 859, 393, 860, 0,
+	861, 394, 395, 396, 397, 398, 399, 400, 401, 402,
+	403, 404, 0, 0, 0, 405, 862, 863, 864, 0,
+	406, 407, 408, 409, 865, 0, 0, 0, 410, 411,
+	412, 413, 414, 415, 416, 417, 0, 0, 419, 420,
+	421, 418, 422, 423, 0, 424, 0, 425, 426, 427,
+	428, 429, 0, 430, 431, 0, 432, 433, 434, 0,
+	435, 436, 437, 0, 0, 0, 0, 0, 0, 0,
+	438, 439, 440, 441, 442, 0, 443, 445, 866, 867,
+	0, 448, 450, 444, 446, 0, 449, 447, 451, 452,
+	0, 453, 454, 455, 456, 457, 0, 0, 0, 458,
+	459, 460, 461, 0, 462, 463, 464, 466, 465, 0,
+	467, 468, 469, 0, 470, 471, 868, 472, 473, 474,
+	476, 478, 475, 477, 479, 480, 481, 482, 483, 869,
+	870, 484, 485, 0, 0, 0, 0, 0, 0, 0,
+	486, 487, 488, 871, 0, 0, 0, 489, 0, 491,
+	495, 496, 492, 493, 494, 497, 0, 490, 498, 499,
+	0, 0, 500, 501, 502, 872, 873, 503, 504, 505,
+	506, 507, 508, 509, 510, 511, 0, 512, 513, 874,
+	0, 875, 514, 0, 515, 516, 517, 518, 519, 520,
+	521, 876, 877, 878, 630, 0, 522, 523, 524, 525,
+	0, 526, 527, 528, 529, 530, 531, 532, 0, 0,
+	0, 533, 534, 535, 536, 0, 0, 0, 0, 0,
+	879, 537, 631, 538, 539, 880, 881, 0, 882, 0,
+	540, 541, 544, 0, 883, 0, 543, 545, 546, 0,
+	547, 0, 0, 0, 548, 549, 550, 551, 552, 553,
+	554, 0, 555, 557, 556, 0, 559, 884, 558, 0,
+	560, 561, 0, 0, 562, 563, 564, 565, 566, 567,
+	572, 0, 0, 568, 569, 570, 571, 573, 574, 0,
+	575, 576, 578, 581, 577, 579, 580, 582, 583, 596,
+	597, 598, 584, 585, 586, 587, 588, 589, 590, 591,
+	592, 593, 594, 595, 600, 0, 599, 0, 0, 601,
+	602, 603, 604, 605, 606, 612, 615, 617, 618, 613,
+	614, 616, 619, 620, 621, 623, 624, 609, 610, 611,
+	0, 622, 607, 0, 608, 0, 0, 625, 626, 627,
+	628, 0, 885, 629, 886, 632, 633, 0, 0, 634,
+	0, 635, 636, 0, 0, 638, 639, 640, 0, 0,
+	641, 642, 887, 0, 643, 0, 888, 644, 645, 637,
+	646, 647, 648, 649, 650, 651, 652, 653, 654, 655,
+	656, 657, 0, 658, 659, 889, 660, 661, 662, 663,
+	664, 890, 665, 666, 667, 891, 668, 892, 669, 670,
+	671, 0, 672, 673, 674, 0, 675, 676, 677, 678,
+	679, 680, 681, 682, 683, 684, 893, 685, 686, 688,
+	687, 689, 690, 0, 691, 692, 0, 693, 694, 695,
+	0, 0, 0, 0, 0, 696, 697, 699, 0, 700,
+	701, 702, 703, 704, 705, 698, 706, 707, 708, 709,
+	710, 711, 712, 713, 0, 715, 716, 714, 717, 718,
+	0, 719, 720, 721, 722, 723, 894, 724, 0, 725,
+	726, 734, 735, 736, 727, 728, 730, 737, 729, 738,
+	739, 740, 741, 743, 742, 0, 745, 746, 744, 747,
+	748, 749, 750, 0, 751, 895, 752, 731, 732, 753,
+	754, 755, 0, 756, 757, 758, 759, 760, 761, 762,
+	763, 764, 896, 0, 766, 0, 765, 767, 768, 769,
+	770, 771, 772, 773, 775, 733, 776, 777, 778, 783,
+	784, 785, 897, 779, 780, 781, 782, 787, 898, 788,
+	789, 790, 791, 0, 792, 793, 0, 786, 774, 0,
+	794, 795, 796, 797, 798, 799, 800, 801, 802, 803,
+	0, 804, 899, 900, 901, 902, 0, 817, 0, 805,
+	807, 808, 809, 810, 903, 811, 812, 904, 0, 813,
+	814, 815, 816, 806, 819, 820, 818, 0, 0, 821,
+	822, 823, 824, 826, 828, 829, 830, 825, 827, 831,
+	0, 832, 0, 0, 833, 834, 835, 905, 906, 907,
+	0, 908, 838, 839, 836, 837, 840, 841, 844, 842,
+	843, 909, 847, 542, 848, 849, 850, 845, 846, 0,
+	0, 0, 4221, 851, 852, 910, 853, 854, 855, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 367,
+	368, 370, 369, 371, 372, 373, 374, 0, 375, 376,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 378,
+	0, 377, 4706, 379, 380, 381, 926, 382, 383, 384,
+	385, 386, 387, 388, 389, 390, 0, 391, 2580, 0,
+	392, 2587, 393, 2586, 0, 2595, 394, 395, 396, 397,
+	398, 399, 400, 401, 402, 403, 404, 0, 0, 0,
+	405, 2599, 2600, 0, 0, 406, 407, 408, 409, 0,
+	0, 927, 0, 410, 411, 412, 413, 414, 415, 416,
+	417, 0, 0, 419, 420, 421, 418, 422, 423, 0,
+	424, 0, 425, 426, 427, 428, 429, 0, 430, 431,
+	0, 432, 433, 434, 928, 435, 436, 437, 0, 0,
+	0, 0, 0, 0, 0, 438, 439, 440, 441, 442,
+	1568, 443, 445, 2584, 2583, 0, 448, 450, 444, 446,
+	0, 449, 447, 451, 452, 0, 453, 454, 455, 456,
+	457, 0, 0, 0, 458, 1560, 460, 461, 0, 462,
+	463, 464, 466, 465, 0, 467, 468, 469, 0, 470,
+	471, 0, 472, 473, 474, 476, 478, 475, 477, 479,
+	480, 481, 482, 483, 0, 0, 484, 485, 0, 362,
+	0, 0, 0, 0, 0, 486, 487, 488, 2582, 0,
+	0, 0, 489, 0, 491, 495, 496, 492, 493, 494,
+	497, 0, 490, 498, 499, 0, 929, 500, 501, 502,
+	2593, 2594, 503, 504, 505, 506, 507, 508, 509, 510,
+	511, 0, 512, 513, 0, 0, 0, 514, 0, 515,
+	516, 517, 518, 519, 520, 521, 0, 0, 0, 630,
+	931, 522, 523, 524, 525, 4215, 526, 527, 528, 529,
+	530, 531, 532, 0, 0, 0, 533, 534, 535, 536,
+	0, 0, 0, 0, 930, 4217, 537, 631, 538, 539,
+	2577, 2578, 0, 2573, 0, 540, 541, 544, 932, 0,
+	933, 543, 545, 546, 934, 547, 0, 0, 0, 548,
+	549, 550, 551, 552, 553, 554, 0, 555, 557, 556,
+	0, 559, 0, 558, 935, 560, 561, 936, 0, 562,
+	563, 564, 565, 566, 567, 572, 0, 0, 568, 569,
+	570, 571, 573, 574, 0, 575, 576, 578, 581, 577,
+	579, 580, 582, 583, 596, 597, 598, 584, 585, 586,
+	587, 588, 589, 590, 591, 592, 593, 594, 595, 600,
+	0, 599, 937, 0, 601, 602, 603, 604, 605, 606,
+	612, 615, 617, 618, 613, 614, 616, 619, 620, 621,
+	623, 624, 609, 610, 611, 938, 622, 607, 0, 608,
+	0, 939, 625, 626, 627, 628, 0, 0, 629, 2585,
+	632, 633, 0, 0, 634, 0, 635, 636, 0, 0,
+	638, 639, 640, 0, 0, 641, 642, 4216, 940, 643,
+	941, 0, 644, 645, 637, 646, 647, 648, 649, 650,
+	651, 652, 653, 654, 655, 656, 657, 0, 658, 659,
+	2570, 660, 661, 662, 663, 664, 2571, 665, 666, 667,
+	0, 668, 0, 669, 670, 671, 0, 672, 673, 674,
+	0, 675, 676, 677, 678, 679, 680, 681, 682, 683,
+	684, 2581, 685, 686, 688, 687, 689, 690, 0, 691,
+	692, 0, 693, 694, 695, 0, 0, 0, 0, 0,
+	696, 697, 699, 0, 700, 701, 702, 703, 704, 705,
+	698, 706, 707, 708, 709, 710, 711, 712, 713, 0,
+	715, 716, 714, 717, 718, 942, 719, 720, 721, 722,
+	723, 0, 724, 0, 725, 726, 734, 735, 736, 727,
+	728, 730, 737, 729, 738, 739, 740, 741, 743, 742,
+	0, 745, 746, 744, 747, 748, 749, 750, 0, 751,
+	0, 752, 731, 732, 753, 754, 755, 943, 756, 757,
+	758, 759, 760, 761, 762, 763, 764, 2579, 0, 766,
+	0, 765, 767, 768, 769, 770, 771, 772, 773, 775,
+	733, 776, 777, 778, 783, 784, 785, 2598, 779, 780,
+	781, 782, 787, 0, 788, 789, 790, 791, 0, 792,
+	793, 0, 786, 774, 0, 794, 795, 796, 797, 798,
+	799, 800, 801, 802, 803, 0, 804, 2589, 2590, 2591,
+	2592, 0, 817, 0, 805, 807, 808, 809, 810, 0,
+	811, 812, 0, 0, 813, 814, 815, 816, 806, 819,
+	820, 818, 0, 0, 821, 822, 823, 824, 826, 828,
+	829, 830, 825, 827, 831, 0, 832, 0, 0, 833,
+	834, 835, 0, 2588, 2597, 4218, 2596, 838, 839, 836,
+	837, 840, 841, 844, 842, 843, 0, 847, 542, 848,
+	849, 850, 845, 846, 0, 0, 0, 359, 851, 852,
+	0, 853, 854, 855, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 367, 368, 370, 369, 371, 372,
+	373, 374, 0, 375, 376, 0, 0, 0, 0, 0,
+	856, 0, 0, 0, 378, 0, 377, 0, 379, 380,
+	381, 2566, 382, 383, 384, 385, 386, 387, 388, 389,
+	390, 857, 391, 858, 0, 392, 859, 393, 860, 0,
+	861, 394, 395, 396, 397, 398, 399, 400, 401, 402,
+	403, 404, 0, 0, 0, 405, 862, 863, 864, 0,
+	406, 407, 408, 409, 865, 0, 0, 0, 410, 411,
+	412, 413, 414, 415, 416, 417, 0, 0, 419, 420,
+	421, 418, 422, 423, 0, 424, 0, 425, 426, 427,
+	428, 429, 0, 430, 431, 0, 432, 433, 434, 0,
+	435, 436, 437, 0, 0, 0, 0, 0, 0, 0,
+	438, 439, 440, 441, 442, 0, 443, 445, 866, 867,
+	0, 448, 450, 444, 446, 0, 449, 447, 451, 452,
+	0, 453, 454, 455, 456, 457, 0, 0, 0, 458,
+	459, 460, 461, 0, 462, 463, 464, 466, 465, 0,
+	467, 468, 469, 0, 470, 471, 868, 472, 473, 474,
+	476, 478, 475, 477, 479, 480, 481, 482, 483, 869,
+	870, 484, 485, 0, 0, 0, 0, 0, 0, 0,
+	486, 487, 488, 871, 0, 0, 0, 489, 0, 491,
+	495, 496, 492, 493, 494, 497, 0, 490, 498, 499,
+	0, 0, 500, 501, 502, 872, 873, 503, 504, 505,
+	506, 507, 508, 509, 510, 511, 0, 512, 513, 874,
+	0, 875, 514, 0, 515, 516, 517, 518, 519, 520,
+	521, 876, 877, 878, 630, 0, 522, 523, 524, 525,
+	0, 526, 527, 528, 529, 530, 531, 532, 0, 0,
+	0, 533, 534, 535, 536, 0, 0, 0, 0, 0,
+	879, 537, 631, 538, 539, 880, 881, 0, 882, 0,
+	540, 541, 544, 0, 883, 0, 543, 545, 546, 0,
+	547, 0, 0, 0, 548, 549, 550, 551, 552, 553,
+	554, 0, 555, 557, 556, 0, 559, 884, 558, 0,
+	560, 561, 0, 0, 562, 563, 564, 565, 566, 567,
+	572, 0, 0, 568, 569, 570, 571, 573, 574, 0,
+	575, 576, 578, 581, 577, 579, 580, 582, 583, 596,
+	597, 598, 584, 585, 586, 587, 588, 589, 590, 591,
+	592, 593, 594, 595, 600, 0, 599, 0, 0, 601,
+	602, 603, 604, 605, 606, 612, 615, 617, 618, 613,
+	614, 616, 619, 620, 621, 623, 624, 609, 610, 611,
+	0, 622, 607, 0, 608, 0, 0, 625, 626, 627,
+	628, 0, 885, 629, 886, 632, 633, 0, 0, 634,
+	0, 635, 636, 0, 0, 638, 639, 640, 0, 0,
+	641, 642, 887, 0, 643, 0, 888, 644, 645, 637,
+	646, 647, 648, 649, 650, 651, 652, 653, 654, 655,
+	656, 657, 0, 658, 659, 889, 660, 661, 662, 663,
+	664, 890, 665, 666, 667, 891, 668, 892, 669, 670,
+	671, 0, 672, 673, 674, 0, 675, 676, 677, 678,
+	679, 680, 681, 682, 683, 684, 893, 685, 686, 688,
+	687, 689, 690, 0, 691, 692, 0, 693, 694, 695,
+	0, 0, 0, 0, 0, 696, 697, 699, 0, 700,
+	701, 702, 703, 704, 705, 698, 706, 707, 708, 709,
+	710, 711, 712, 713, 0, 715, 716, 714, 717, 718,
+	0, 719, 720, 721, 722, 723, 894, 724, 0, 725,
+	726, 734, 735, 736, 727, 728, 730, 737, 729, 738,
+	739, 740, 741, 743, 742, 0, 745, 746, 744, 747,
+	748, 749, 750, 0, 751, 895, 752, 731, 732, 753,
+	754, 755, 0, 756, 757, 758, 759, 760, 761, 762,
+	763, 764, 896, 0, 766, 0, 765, 767, 768, 769,
+	770, 771, 772, 773, 775, 733, 776, 777, 778, 783,
+	784, 785, 897, 779, 780, 781, 782, 787, 898, 788,
+	789, 790, 791, 0, 792, 793, 0, 786, 774, 0,
+	794, 795, 796, 797, 798, 799, 800, 801, 802, 803,
+	0, 804, 899, 900, 901, 902, 0, 817, 0, 805,
+	807, 808, 809, 810, 903, 811, 812, 904, 0, 813,
+	814, 815, 816, 806, 819, 820, 818, 0, 0, 821,
+	822, 823, 824, 826, 828, 829, 830, 825, 827, 831,
+	0, 832, 0, 0, 833, 834, 835, 905, 906, 907,
+	0, 908, 838, 839, 836, 837, 840, 841, 844, 842,
+	843, 909, 847, 542, 848, 849, 850, 845, 846, 0,
+	0, 0, 359, 851, 852, 910, 853, 854, 855, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 367,
+	368, 370, 369, 371, 372, 373, 374, 0, 375, 376,
+	0, 0, 0, 0, 0, 856, 0, 0, 0, 378,
+	0, 377, 5497, 379, 380, 381, 0, 382, 383, 384,
+	385, 386, 387, 388, 389, 390, 857, 391, 858, 0,
+	392, 859, 393, 860, 0, 861, 394, 395, 396, 397,
+	398, 399, 400, 401, 402, 403, 404, 0, 0, 0,
+	405, 862, 863, 864, 0, 406, 407, 408, 409, 865,
+	0, 0, 0, 410, 411, 412, 413, 414, 415, 416,
+	417, 0, 0, 419, 420, 421, 418, 422, 423, 0,
+	424, 0, 425, 426, 427, 428, 429, 0, 430, 431,
+	0, 432, 433, 434, 0, 435, 436, 437, 0, 0,
+	0, 0, 0, 0, 0, 438, 439, 440, 441, 442,
+	0, 443, 445, 866, 867, 0, 448, 450, 444, 446,
+	0, 449, 447, 451, 452, 0, 453, 454, 455, 456,
+	457, 0, 0, 0, 458, 459, 460, 461, 0, 462,
+	463, 464, 466, 465, 0, 467, 468, 469, 0, 470,
+	471, 868, 472, 473, 474, 476, 478, 475, 477, 479,
+	480, 481, 482, 483, 869, 870, 484, 485, 0, 0,
+	0, 0, 0, 0, 0, 486, 487, 488, 871, 0,
+	0, 0, 489, 0, 491, 495, 496, 492, 493, 494,
+	497, 0, 490, 498, 499, 0, 0, 500, 501, 502,
+	872, 873, 503, 504, 505, 506, 507, 508, 509, 510,
+	511, 0, 512, 513, 874, 0, 875, 514, 0, 515,
+	516, 517, 518, 519, 520, 521, 876, 877, 878, 630,
+	0, 522, 523, 524, 525, 0, 526, 527, 528, 529,
+	530, 531, 532, 0, 0, 0, 533, 534, 535, 536,
+	0, 0, 0, 0, 0, 879, 537, 631, 538, 539,
+	880, 881, 0, 882, 0, 540, 541, 544, 0, 883,
+	0, 543, 545, 546, 0, 547, 0, 0, 0, 548,
+	549, 550, 551, 552, 553, 554, 0, 555, 557, 556,
+	0, 559, 884, 558, 0, 560, 561, 0, 0, 562,
+	563, 564, 565, 566, 567, 572, 0, 0, 568, 569,
+	570, 571, 573, 574, 0, 575, 576, 578, 581, 577,
+	579, 580, 582, 583, 596, 597, 598, 584, 585, 586,
+	587, 588, 589, 590, 591, 592, 593, 594, 595, 600,
+	0, 599, 0, 0, 601, 602, 603, 604, 605, 606,
+	612, 615, 617, 618, 613, 614, 616, 619, 620, 621,
+	623, 624, 609, 610, 611, 0, 622, 607, 0, 608,
+	0, 0, 625, 626, 627, 628, 0, 885, 629, 886,
+	632, 633, 0, 0, 634, 0, 635, 636, 0, 0,
+	638, 639, 640, 0, 0, 641, 642, 887, 0, 643,
+	0, 888, 644, 645, 637, 646, 647, 648, 649, 650,
+	651, 652, 653, 654, 655, 656, 657, 0, 658, 659,
+	889, 660, 661, 662, 663, 664, 890, 665, 666, 667,
+	891, 668, 892, 669, 670, 671, 0, 672, 673, 674,
+	0, 675, 676, 677, 678, 679, 680, 681, 682, 683,
+	684, 893, 685, 686, 688, 687, 689, 690, 0, 691,
+	692, 0, 693, 694, 695, 0, 0, 0, 0, 0,
+	696, 697, 699, 0, 700, 701, 702, 703, 704, 705,
+	698, 706, 707, 708, 709, 710, 711, 712, 713, 0,
+	715, 716, 714, 717, 718, 0, 719, 720, 721, 722,
+	723, 894, 724, 0, 725, 726, 734, 735, 736, 727,
+	728, 730, 737, 729, 738, 739, 740, 741, 743, 742,
+	0, 745, 746, 744, 747, 748, 749, 750, 0, 751,
+	895, 752, 731, 732, 753, 754, 755, 0, 756, 757,
+	758, 759, 760, 761, 762, 763, 764, 896, 0, 766,
+	0, 765, 767, 768, 769, 770, 771, 772, 773, 775,
+	733, 776, 777, 778, 783, 784, 785, 897, 779, 780,
+	781, 782, 787, 898, 788, 789, 790, 791, 0, 792,
+	793, 0, 786, 774, 0, 794, 795, 796, 797, 798,
+	799, 800, 801, 802, 803, 0, 804, 899, 900, 901,
+	902, 0, 817, 0, 805, 807, 808, 809, 810, 903,
+	811, 812, 904, 0, 813, 814, 815, 816, 806, 819,
+	820, 818, 0, 0, 821, 822, 823, 824, 826, 828,
+	829, 830, 825, 827, 831, 0, 832, 0, 0, 833,
+	834, 835, 905, 906, 907, 0, 908, 838, 839, 836,
+	837, 840, 841, 844, 842, 843, 909, 847, 542, 848,
+	849, 850, 845, 846, 0, 1322, 0, 1206, 851, 852,
+	910, 853, 854, 855, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 367, 368, 370, 369, 371, 372,
+	373, 374, 0, 375, 376, 0, 0, 0, 0, 0,
+	856, 0, 0, 0, 378, 0, 377, 3139, 379, 380,
+	381, 0, 382, 383, 384, 385, 386, 387, 388, 389,
+	390, 857, 391, 858, 0, 392, 859, 393, 860, 0,
+	861, 394, 395, 396, 397, 398, 399, 400, 401, 402,
+	403, 404, 0, 0, 0, 405, 862, 863, 864, 0,
+	406, 407, 408, 409, 865, 0, 0, 0, 410, 411,
+	412, 413, 414, 415, 416, 417, 0, 0, 419, 420,
+	421, 418, 422, 423, 0, 424, 0, 425, 426, 427,
+	428, 429, 0, 430, 431, 0, 432, 433, 434, 0,
+	435, 436, 437, 0, 0, 0, 0, 0, 0, 0,
+	438, 439, 440, 1213, 442, 0, 443, 445, 866, 867,
+	0, 448, 450, 444, 446, 0, 449, 447, 451, 452,
+	0, 453, 454, 455, 456, 457, 0, 0, 0, 458,
+	459, 460, 461, 0, 462, 463, 464, 466, 465, 0,
+	467, 468, 469, 0, 470, 471, 868, 472, 473, 474,
+	476, 478, 475, 477, 479, 480, 481, 482, 483, 869,
+	870, 484, 485, 0, 362, 0, 0, 0, 0, 0,
+	486, 487, 488, 871, 0, 0, 0, 489, 0, 491,
+	495, 496, 492, 493, 494, 497, 0, 490, 498, 499,
+	1319, 0, 500, 501, 502, 872, 873, 503, 504, 505,
+	506, 507, 508, 509, 510, 511, 0, 512, 513, 874,
+	0, 875, 514, 0, 515, 516, 517, 518, 519, 520,
+	521, 876, 877, 878, 630, 0, 522, 523, 524, 525,
+	0, 526, 527, 528, 529, 530, 531, 532, 0, 0,
+	0, 533, 534, 535, 536, 0, 364, 363, 365, 0,
+	879, 537, 631, 538, 539, 880, 881, 0, 882, 0,
+	540, 541, 544, 0, 883, 0, 543, 545, 546, 0,
+	547, 0, 0, 0, 548, 549, 550, 551, 552, 553,
+	554, 0, 555, 557, 556, 0, 559, 884, 558, 0,
+	560, 561, 0, 0, 562, 563, 564, 565, 566, 567,
+	572, 0, 0, 568, 569, 570, 571, 573, 574, 0,
+	575, 576, 578, 581, 577, 579, 580, 582, 583, 596,
+	597, 598, 584, 585, 586, 587, 588, 589, 590, 591,
+	592, 593, 594, 595, 600, 0, 599, 0, 0, 601,
+	602, 603, 604, 605, 606, 612, 615, 617, 618, 613,
+	614, 616, 619, 620, 621, 623, 624, 609, 610, 611,
+	0, 622, 607, 0, 608, 366, 0, 625, 626, 627,
+	628, 0, 885, 629, 886, 632, 633, 0, 0, 634,
+	0, 635, 636, 0, 0, 638, 639, 640, 0, 0,
+	641, 642, 887, 0, 643, 0, 888, 644, 645, 637,
+	646, 647, 648, 649, 650, 651, 652, 653, 654, 655,
+	656, 657, 0, 658, 659, 889, 660, 661, 662, 663,
+	664, 890, 665, 666, 667, 891, 668, 892, 669, 670,
+	671, 0, 672, 673, 674, 0, 675, 676, 677, 678,
+	679, 680, 681, 682, 683, 684, 893, 685, 686, 688,
+	687, 689, 690, 0, 691, 692, 0, 693, 694, 695,
+	0, 0, 0, 0, 0, 696, 697, 699, 0, 700,
+	701, 702, 703, 704, 705, 698, 706, 707, 708, 709,
+	710, 711, 712, 713, 0, 715, 716, 714, 717, 718,
+	0, 719, 720, 721, 722, 723, 894, 724, 0, 725,
+	726, 734, 735, 736, 727, 728, 730, 737, 729, 738,
+	739, 740, 741, 743, 742, 0, 745, 746, 744, 747,
+	748, 749, 750, 0, 751, 895, 752, 731, 732, 753,
+	754, 755, 0, 756, 757, 758, 759, 760, 761, 762,
+	763, 764, 896, 0, 766, 0, 765, 767, 768, 769,
+	770, 771, 772, 773, 775, 733, 776, 777, 778, 783,
+	784, 785, 897, 779, 780, 781, 782, 787, 898, 788,
+	789, 790, 791, 0, 792, 1321, 0, 786, 774, 1211,
+	794, 795, 796, 797, 798, 1215, 800, 801, 802, 803,
+	0, 804, 899, 900, 901, 902, 0, 817, 0, 805,
+	807, 808, 809, 810, 903, 811, 812, 904, 0, 813,
+	814, 815, 816, 806, 819, 820, 818, 0, 0, 821,
+	822, 823, 824, 826, 828, 829, 830, 825, 827, 831,
+	0, 832, 0, 0, 833, 834, 835, 905, 906, 907,
+	0, 908, 838, 839, 836, 837, 840, 841, 844, 842,
+	843, 1214, 847, 542, 848, 849, 850, 845, 846, 2547,
+	0, 0, 0, 851, 852, 910, 853, 854, 855, 0,
+	0, 0, 0, 0, 0, 0, 367, 368, 370, 369,
+	371, 372, 373, 374, 5638, 375, 376, 0, 0, 0,
+	0, 0, 856, 0, 1218, 0, 378, 0, 377, 0,
+	379, 380, 381, 0, 382, 383, 384, 385, 386, 387,
+	388, 389, 390, 857, 391, 858, 0, 392, 859, 393,
+	860, 0, 861, 394, 395, 396, 397, 398, 399, 400,
+	401, 402, 403, 404, 0, 0, 0, 405, 862, 863,
+	864, 0, 406, 407, 408, 409, 865, 0, 0, 0,
+	410, 411, 412, 413, 414, 415, 416, 417, 0, 0,
+	419, 420, 421, 418, 422, 423, 0, 424, 0, 425,
+	426, 427, 428, 429, 0, 430, 431, 0, 432, 433,
+	434, 0, 435, 436, 437, 0, 0, 0, 0, 0,
+	0, 0, 438, 439, 440, 2554, 442, 0, 443, 445,
+	866, 867, 0, 448, 450, 444, 446, 0, 449, 447,
+	451, 452, 0, 453, 454, 455, 456, 457, 0, 0,
+	0, 458, 459, 460, 461, 0, 462, 463, 464, 466,
+	465, 0, 467, 468, 469, 0, 470, 471, 868, 472,
+	473, 474, 476, 478, 475, 477, 479, 480, 481, 482,
+	2555, 869, 870, 484, 485, 0, 362, 0, 0, 0,
+	0, 0, 486, 487, 488, 871, 0, 0, 0, 489,
+	0, 491, 495, 496, 492, 493, 494, 497, 0, 490,
+	498, 499, 0, 0, 2556, 501, 502, 872, 873, 503,
+	504, 505, 506, 507, 508, 509, 510, 511, 0, 512,
+	513, 874, 0, 875, 514, 0, 515, 516, 517, 518,
+	519, 520, 521, 876, 877, 878, 630, 0, 522, 523,
+	524, 525, 0, 526, 527, 528, 529, 530, 531, 532,
+	0, 0, 0, 533, 534, 535, 536, 0, 364, 363,
+	365, 0, 879, 537, 631, 538, 539, 880, 881, 0,
+	882, 0, 540, 541, 544, 0, 883, 0, 543, 545,
+	546, 0, 547, 0, 0, 0, 548, 549, 550, 551,
+	552, 553, 554, 0, 555, 557, 556, 0, 559, 884,
+	558, 0, 560, 561, 0, 0, 562, 563, 564, 565,
+	566, 567, 572, 0, 0, 568, 569, 570, 571, 573,
+	574, 0, 575, 576, 578, 581, 577, 579, 580, 582,
+	583, 596, 597, 598, 584, 585, 586, 587, 588, 589,
+	590, 591, 592, 593, 594, 595, 600, 0, 599, 0,
+	0, 601, 602, 603, 604, 605, 606, 612, 615, 617,
+	618, 613, 614, 616, 619, 620, 621, 623, 624, 609,
+	610, 611, 0, 622, 607, 0, 608, 366, 0, 625,
+	626, 627, 628, 0, 885, 629, 886, 632, 633, 0,
+	0, 634, 0, 635, 636, 0, 0, 638, 639, 640,
+	0, 0, 641, 642, 887, 0, 643, 0, 888, 644,
+	645, 637, 646, 647, 648, 649, 650, 651, 652, 653,
+	654, 655, 656, 657, 0, 658, 659, 889, 660, 661,
+	662, 663, 664, 890, 665, 666, 667, 891, 668, 892,
+	669, 670, 671, 0, 672, 673, 674, 0, 2557, 676,
+	677, 678, 679, 680, 681, 682, 683, 684, 893, 685,
+	686, 688, 687, 689, 690, 0, 691, 692, 0, 693,
+	694, 695, 0, 0, 0, 0, 0, 696, 697, 699,
+	0, 700, 701, 702, 703, 704, 705, 698, 706, 707,
+	708, 709, 710, 711, 712, 713, 0, 715, 716, 714,
+	717, 718, 0, 719, 720, 721, 722, 723, 894, 724,
+	0, 725, 726, 734, 735, 736, 727, 728, 730, 5637,
+	729, 738, 739, 740, 741, 743, 742, 0, 2551, 746,
+	744, 747, 748, 749, 750, 0, 751, 895, 752, 731,
+	732, 753, 754, 755, 0, 756, 757, 758, 759, 760,
+	761, 762, 763, 764, 896, 0, 766, 0, 765, 767,
+	768, 769, 770, 771, 772, 773, 775, 733, 776, 777,
+	778, 783, 784, 785, 897, 779, 780, 781, 782, 787,
+	898, 788, 789, 790, 791, 0, 792, 793, 0, 786,
+	774, 2553, 794, 795, 796, 797, 798, 799, 800, 801,
+	802, 803, 0, 804, 899, 900, 901, 902, 0, 817,
+	0, 805, 807, 808, 809, 810, 903, 811, 812, 904,
+	0, 813, 814, 5636, 816, 806, 819, 820, 818, 0,
+	0, 821, 822, 823, 824, 826, 828, 829, 830, 825,
+	827, 831, 0, 832, 0, 0, 833, 834, 835, 905,
+	906, 907, 0, 908, 838, 839, 836, 837, 840, 841,
+	844, 842, 843, 909, 847, 542, 848, 849, 850, 845,
+	846, 0, 5315, 0, 1206, 851, 852, 910, 853, 854,
+	855, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 367, 368, 370, 369, 371, 372, 373, 374, 0,
+	375, 376, 0, 0, 0, 0, 1218, 856, 0, 0,
+	0, 378, 0, 377, 0, 379, 380, 381, 0, 382,
+	383, 384, 385, 386, 387, 388, 389, 390, 857, 391,
+	858, 0, 392, 859, 393, 860, 0, 861, 394, 395,
+	396, 397, 398, 399, 400, 401, 402, 403, 404, 0,
+	0, 0, 405, 862, 863, 864, 0, 406, 407, 408,
+	409, 865, 0, 0, 0, 410, 411, 412, 413, 414,
+	415, 416, 417, 0, 0, 419, 420, 421, 418, 422,
+	423, 0, 424, 0, 425, 426, 427, 428, 429, 0,
+	430, 431, 0, 432, 433, 434, 0, 435, 436, 437,
+	0, 0, 0, 0, 0, 0, 0, 438, 439, 440,
+	1213, 442, 0, 443, 445, 866, 867, 0, 448, 450,
+	444, 446, 0, 449, 447, 451, 452, 0, 453, 454,
+	455, 456, 457, 0, 0, 0, 458, 459, 460, 461,
+	0, 462, 463, 464, 466, 465, 0, 467, 468, 469,
+	0, 470, 471, 868, 472, 473, 474, 476, 478, 475,
+	477, 479, 480, 481, 482, 483, 869, 870, 484, 485,
+	0, 362, 0, 0, 0, 0, 0, 486, 487, 488,
+	871, 0, 0, 0, 489, 0, 491, 495, 496, 492,
+	493, 494, 497, 0, 490, 498, 499, 0, 0, 500,
+	501, 502, 872, 873, 503, 504, 505, 506, 507, 508,
+	509, 510, 511, 0, 512, 513, 874, 0, 875, 514,
+	0, 515, 516, 517, 518, 519, 520, 521, 876, 877,
+	878, 630, 0, 522, 523, 524, 525, 0, 526, 527,
+	528, 529, 530, 531, 532, 0, 0, 0, 533, 534,
+	535, 536, 0, 364, 363, 365, 0, 879, 537, 631,
+	538, 539, 880, 881, 0, 882, 0, 540, 541, 544,
+	0, 883, 0, 543, 545, 546, 0, 547, 0, 0,
+	0, 548, 549, 550, 551, 552, 553, 554, 0, 555,
+	557, 556, 0, 559, 884, 558, 0, 560, 561, 0,
+	0, 562, 563, 564, 565, 566, 567, 572, 0, 0,
+	568, 569, 570, 571, 573, 574, 0, 575, 576, 578,
+	581, 577, 579, 580, 582, 583, 596, 597, 598, 584,
+	585, 586, 587, 588, 589, 590, 591, 592, 593, 594,
+	595, 600, 0, 599, 0, 0, 601, 602, 603, 604,
+	605, 606, 612, 615, 617, 618, 613, 614, 616, 619,
+	620, 621, 623, 624, 609, 610, 611, 0, 622, 607,
+	0, 608, 366, 0, 625, 626, 627, 628, 0, 885,
+	629, 886, 632, 633, 0, 0, 634, 0, 635, 636,
+	0, 0, 638, 639, 640, 0, 0, 641, 642, 887,
+	0, 643, 0, 888, 644, 645, 637, 646, 647, 648,
+	649, 650, 651, 652, 653, 654, 655, 656, 657, 0,
+	658, 659, 889, 660, 661, 662, 663, 664, 890, 665,
+	666, 667, 891, 668, 892, 669, 670, 671, 0, 672,
+	673, 674, 0, 675, 676, 677, 678, 679, 680, 681,
+	682, 683, 684, 893, 685, 686, 688, 687, 689, 690,
+	0, 691, 692, 0, 693, 694, 695, 0, 0, 0,
+	0, 0, 696, 697, 699, 0, 700, 701, 702, 703,
+	704, 705, 698, 706, 707, 708, 709, 710, 711, 712,
+	713, 0, 715, 716, 714, 717, 718, 0, 719, 720,
+	721, 722, 723, 894, 724, 0, 725, 726, 734, 735,
+	736, 727, 728, 730, 737, 729, 738, 739, 740, 741,
+	743, 742, 0, 745, 746, 744, 747, 748, 749, 750,
+	0, 751, 895, 752, 731, 732, 753, 754, 755, 0,
+	756, 757, 758, 759, 760, 761, 762, 763, 764, 896,
+	0, 766, 0, 765, 767, 768, 769, 770, 771, 772,
+	773, 775, 733, 776, 777, 778, 783, 784, 785, 897,
+	779, 780, 781, 782, 787, 898, 788, 789, 790, 791,
+	0, 792, 793, 0, 786, 774, 1211, 794, 795, 796,
+	797, 798, 1215, 800, 801, 802, 803, 0, 804, 899,
+	900, 901, 902, 0, 817, 0, 805, 807, 808, 809,
+	810, 903, 811, 812, 904, 0, 813, 814, 815, 816,
+	806, 819, 820, 818, 0, 0, 821, 822, 823, 824,
+	826, 828, 829, 830, 825, 827, 831, 0, 832, 0,
+	0, 833, 834, 835, 905, 906, 907, 0, 908, 838,
+	839, 836, 837, 840, 841, 844, 842, 843, 1214, 847,
+	542, 848, 849, 850, 845, 846, 2574, 0, 0, 0,
+	851, 852, 910, 853, 854, 855, 0, 0, 0, 0,
+	0, 0, 0, 367, 368, 370, 369, 371, 372, 373,
+	374, 0, 375, 376, 0, 0, 0, 0, 0, 0,
+	0, 1218, 0, 378, 0, 377, 0, 379, 380, 381,
+	926, 382, 383, 384, 385, 386, 387, 388, 389, 390,
+	0, 391, 2580, 0, 392, 2587, 393, 2586, 0, 2595,
+	394, 395, 396, 397, 398, 399, 400, 401, 402, 403,
+	404, 0, 0, 0, 405, 2599, 2600, 0, 0, 406,
+	407, 408, 409, 0, 0, 927, 0, 410, 411, 412,
+	413, 414, 415, 416, 417, 0, 0, 419, 420, 421,
+	418, 422, 423, 0, 424, 0, 425, 426, 427, 428,
+	429, 0, 430, 431, 0, 432, 433, 434, 928, 435,
+	436, 437, 0, 0, 0, 0, 0, 0, 0, 438,
+	439, 440, 441, 442, 1568, 443, 445, 2584, 2583, 0,
+	448, 450, 444, 446, 0, 449, 447, 451, 452, 0,
+	453, 454, 455, 456, 457, 0, 0, 0, 458, 1560,
+	460, 461, 0, 462, 463, 464, 466, 465, 0, 467,
+	468, 469, 0, 470, 471, 0, 472, 473, 474, 476,
+	478, 475, 477, 479, 480, 481, 482, 483, 0, 0,
+	484, 485, 0, 0, 0, 0, 0, 0, 0, 486,
+	487, 488, 2582, 0, 0, 0, 489, 0, 491, 495,
+	496, 492, 493, 494, 497, 0, 490, 498, 499, 0,
+	929, 500, 501, 502, 2593, 2594, 503, 504, 505, 506,
+	507, 508, 509, 510, 511, 0, 512, 513, 0, 0,
+	0, 514, 0, 515, 516, 517, 518, 519, 520, 521,
+	0, 0, 0, 630, 931, 522, 523, 524, 525, 4215,
+	526, 527, 528, 529, 530, 531, 532, 0, 0, 0,
+	533, 534, 535, 536, 0, 0, 0, 0, 930, 4217,
+	537, 631, 538, 539, 2577, 2578, 0, 2573, 0, 540,
+	541, 544, 932, 0, 933, 543, 545, 546, 934, 547,
+	0, 0, 0, 548, 549, 550, 551, 552, 553, 554,
+	0, 555, 557, 556, 0, 559, 0, 558, 935, 560,
+	561, 936, 0, 562, 563, 564, 565, 566, 567, 572,
+	0, 0, 568, 569, 570, 571, 573, 574, 0, 575,
+	576, 578, 581, 577, 579, 580, 582, 583, 596, 597,
+	598, 584, 585, 586, 587, 588, 589, 590, 591, 592,
+	593, 594, 595, 600, 0, 599, 937, 0, 601, 602,
+	603, 604, 605, 606, 612, 615, 617, 618, 613, 614,
+	616, 619, 620, 621, 623, 624, 609, 610, 611, 938,
+	622, 607, 0, 608, 0, 939, 625, 626, 627, 628,
+	0, 0, 629, 2585, 632, 633, 0, 0, 634, 0,
+	635, 636, 0, 0, 638, 639, 640, 0, 0, 641,
+	642, 4216, 940, 643, 941, 0, 644, 645, 637, 646,
+	647, 648, 649, 650, 651, 652, 653, 654, 655, 656,
+	657, 0, 658, 659, 2570, 660, 661, 662, 663, 664,
+	2571, 665, 666, 667, 0, 668, 0, 669, 670, 671,
+	0, 672, 673, 674, 0, 675, 676, 677, 678, 679,
+	680, 681, 682, 683, 684, 2581, 685, 686, 688, 687,
+	689, 690, 0, 691, 692, 0, 693, 694, 695, 0,
+	0, 0, 0, 0, 696, 697, 699, 0, 700, 701,
+	702, 703, 704, 705, 698, 706, 707, 708, 709, 710,
+	711, 712, 713, 0, 715, 716, 714, 717, 718, 942,
+	719, 720, 721, 722, 723, 0, 724, 0, 725, 726,
+	734, 735, 736, 727, 728, 730, 737, 729, 738, 739,
+	740, 741, 743, 742, 0, 745, 746, 744, 747, 748,
+	749, 750, 0, 751, 0, 752, 731, 732, 753, 754,
+	755, 943, 756, 757, 758, 759, 760, 761, 762, 763,
+	764, 2579, 0, 766, 0, 765, 767, 768, 769, 770,
+	771, 772, 773, 775, 733, 776, 777, 778, 783, 784,
+	785, 2598, 779, 780, 781, 782, 787, 0, 788, 789,
+	790, 791, 0, 792, 793, 0, 786, 774, 0, 794,
+	795, 796, 797, 798, 799, 800, 801, 802, 803, 0,
+	804, 2589, 2590, 2591, 2592, 0, 817, 0, 805, 807,
+	808, 809, 810, 0, 811, 812, 0, 0, 813, 814,
+	815, 816, 806, 819, 820, 818, 0, 0, 821, 822,
+	823, 824, 826, 828, 829, 830, 825, 827, 831, 0,
+	832, 0, 0, 833, 834, 835, 0, 2588, 2597, 4218,
+	2596, 838, 839, 836, 837, 840, 841, 844, 842, 843,
+	0, 847, 542, 848, 849, 850, 845, 846, 0, 0,
+	0, 2547, 851, 852, 0, 853, 854, 855, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 367, 368,
+	370, 369, 371, 372, 373, 374, 2604, 375, 376, 0,
+	0, 0, 0, 0, 856, 0, 0, 0, 378, 0,
+	377, 0, 379, 380, 381, 2566, 382, 383, 384, 385,
+	386, 387, 388, 389, 390, 857, 391, 858, 0, 392,
+	859, 393, 860, 0, 861, 394, 395, 396, 397, 398,
+	399, 400, 401, 402, 403, 404, 0, 0, 0, 405,
+	862, 863, 864, 0, 406, 407, 408, 409, 865, 0,
+	0, 0, 410, 411, 412, 413, 414, 415, 416, 417,
+	0, 0, 419, 420, 421, 418, 422, 423, 0, 424,
+	0, 425, 426, 427, 428, 429, 0, 430, 431, 0,
+	432, 433, 434, 0, 435, 436, 437, 0, 0, 0,
+	0, 0, 0, 0, 438, 439, 440, 2554, 442, 0,
+	443, 445, 866, 867, 0, 448, 450, 444, 446, 0,
+	449, 447, 451, 452, 0, 453, 454, 455, 456, 457,
+	0, 0, 0, 458, 459, 460, 461, 0, 462, 463,
+	464, 466, 465, 0, 467, 468, 469, 0, 470, 471,
+	868, 472, 473, 474, 476, 478, 475, 477, 479, 480,
+	481, 482, 2555, 869, 870, 484, 485, 0, 362, 0,
+	0, 0, 0, 0, 486, 487, 488, 871, 0, 0,
+	0, 489, 0, 491, 495, 496, 492, 493, 494, 497,
+	0, 490, 498, 499, 0, 0, 2556, 501, 502, 872,
+	873, 503, 504, 505, 506, 507, 508, 509, 510, 511,
+	0, 512, 513, 874, 0, 875, 514, 0, 515, 516,
+	517, 518, 519, 520, 521, 876, 877, 878, 630, 0,
+	522, 523, 524, 525, 0, 526, 527, 528, 529, 530,
+	531, 532, 0, 0, 0, 533, 534, 535, 536, 0,
+	364, 363, 365, 0, 879, 537, 631, 538, 539, 880,
+	881, 0, 882, 0, 540, 541, 544, 0, 883, 0,
+	543, 545, 546, 0, 547, 0, 0, 0, 548, 549,
+	550, 551, 552, 553, 554, 0, 555, 557, 556, 0,
+	559, 884, 558, 0, 560, 561, 0, 0, 562, 563,
+	564, 565, 566, 567, 572, 0, 0, 568, 569, 570,
+	571, 573, 574, 0, 575, 576, 578, 581, 577, 579,
+	580, 582, 583, 596, 597, 598, 584, 585, 586, 587,
+	588, 589, 590, 591, 592, 593, 594, 595, 600, 0,
+	599, 0, 0, 601, 602, 603, 604, 605, 606, 612,
+	615, 617, 618, 613, 614, 616, 619, 620, 621, 623,
+	624, 609, 610, 611, 0, 622, 607, 0, 608, 366,
+	0, 625, 626, 627, 628, 0, 885, 629, 886, 632,
+	633, 0, 0, 634, 0, 635, 636, 0, 0, 638,
+	639, 640, 0, 0, 641, 642, 887, 0, 643, 0,
+	888, 644, 645, 637, 646, 647, 648, 649, 650, 651,
+	652, 653, 654, 655, 656, 657, 0, 658, 659, 889,
+	660, 661, 662, 663, 664, 890, 665, 666, 667, 891,
+	668, 892, 669, 670, 671, 0, 672, 673, 674, 0,
+	2557, 676, 677, 678, 679, 680, 681, 682, 683, 684,
+	893, 685, 686, 688, 687, 689, 690, 0, 691, 692,
+	0, 693, 694, 695, 0, 0, 0, 0, 0, 696,
+	697, 699, 0, 700, 701, 702, 703, 704, 705, 698,
+	706, 707, 708, 709, 710, 711, 712, 713, 0, 715,
+	716, 714, 717, 718, 0, 719, 720, 721, 722, 723,
+	894, 724, 0, 725, 726, 734, 735, 736, 727, 728,
+	730, 2603, 729, 738, 739, 740, 741, 743, 742, 0,
+	2605, 746, 744, 747, 748, 749, 750, 0, 751, 895,
+	752, 731, 732, 753, 754, 755, 0, 756, 757, 758,
+	759, 760, 761, 762, 763, 764, 896, 0, 766, 0,
+	765, 767, 768, 769, 770, 771, 772, 773, 775, 733,
+	776, 777, 778, 783, 784, 785, 897, 779, 780, 781,
+	782, 787, 898, 788, 789, 790, 791, 0, 792, 793,
+	0, 786, 774, 2553, 794, 795, 796, 797, 798, 799,
+	800, 801, 802, 803, 0, 804, 899, 900, 901, 902,
+	0, 817, 0, 805, 807, 808, 809, 810, 903, 811,
+	812, 904, 0, 813, 814, 2602, 816, 806, 819, 820,
+	818, 0, 0, 821, 822, 823, 824, 826, 828, 829,
+	830, 825, 827, 831, 0, 832, 0, 0, 833, 834,
+	835, 905, 906, 907, 0, 908, 838, 839, 836, 837,
+	840, 841, 844, 842, 843, 909, 847, 542, 848, 849,
+	850, 845, 846, 2547, 0, 0, 0, 851, 852, 910,
+	853, 854, 855, 0, 0, 0, 0, 0, 0, 0,
+	367, 368, 370, 369, 371, 372, 373, 374, 2546, 375,
+	376, 0, 0, 0, 0, 0, 856, 0, 1218, 0,
+	378, 0, 377, 0, 379, 380, 381, 0, 382, 383,
+	384, 385, 386, 387, 388, 389, 390, 857, 391, 858,
+	0, 392, 859, 393, 860, 0, 861, 394, 395, 396,
+	397, 398, 399, 400, 401, 402, 403, 404, 0, 0,
+	0, 405, 862, 863, 864, 0, 406, 407, 408, 409,
+	865, 0, 0, 0, 410, 411, 412, 413, 414, 415,
+	416, 417, 0, 0, 419, 420, 421, 418, 422, 423,
+	0, 424, 0, 425, 426, 427, 428, 429, 0, 430,
+	431, 0, 432, 433, 434, 0, 435, 436, 437, 0,
+	0, 0, 0, 0, 0, 0, 438, 439, 440, 2554,
+	442, 0, 443, 445, 866, 867, 0, 448, 450, 444,
+	446, 0, 449, 447, 451, 452, 0, 453, 454, 455,
+	456, 457, 0, 0, 0, 458, 459, 460, 461, 0,
+	462, 463, 464, 466, 465, 0, 467, 468, 469, 0,
+	470, 471, 868, 472, 473, 474, 476, 478, 475, 477,
+	479, 480, 481, 482, 2555, 869, 870, 484, 485, 0,
+	362, 0, 0, 0, 0, 0, 486, 487, 488, 871,
+	0, 0, 0, 489, 0, 491, 495, 496, 492, 493,
+	494, 497, 0, 490, 498, 499, 0, 0, 2556, 501,
+	502, 872, 873, 503, 504, 505, 506, 507, 508, 509,
+	510, 511, 0, 512, 513, 874, 0, 875, 514, 0,
+	515, 516, 517, 518, 519, 520, 521, 876, 877, 878,
+	630, 0, 522, 523, 524, 525, 0, 526, 527, 528,
+	529, 530, 531, 532, 0, 0, 0, 533, 534, 535,
+	536, 0, 364, 363, 365, 0, 879, 537, 631, 538,
+	539, 880, 881, 0, 882, 0, 540, 541, 544, 0,
+	883, 0, 543, 545, 546, 0, 547, 0, 0, 0,
+	548, 549, 550, 551, 552, 553, 554, 0, 555, 557,
+	556, 0, 559, 884, 558, 0, 560, 561, 0, 0,
+	562, 563, 564, 565, 566, 567, 572, 0, 0, 568,
+	569, 570, 571, 573, 574, 0, 575, 576, 578, 581,
+	577, 579, 580, 582, 583, 596, 597, 598, 584, 585,
+	586, 587, 588, 589, 590, 591, 592, 593, 594, 595,
+	600, 0, 599, 0, 0, 601, 602, 603, 604, 605,
+	606, 612, 615, 617, 618, 613, 614, 616, 619, 620,
+	621, 623, 624, 609, 610, 611, 0, 622, 607, 0,
+	608, 366, 0, 625, 626, 627, 628, 0, 885, 629,
+	886, 632, 633, 0, 0, 634, 0, 635, 636, 0,
+	0, 638, 639, 640, 0, 0, 641, 642, 887, 0,
+	643, 0, 888, 644, 645, 637, 646, 647, 648, 649,
+	650, 651, 652, 653, 654, 655, 656, 657, 0, 658,
+	659, 889, 660, 661, 662, 663, 664, 890, 665, 666,
+	667, 891, 668, 892, 669, 670, 671, 0, 672, 673,
+	674, 0, 2557, 676, 677, 678, 679, 680, 681, 682,
+	683, 684, 893, 685, 686, 688, 687, 689, 690, 0,
+	691, 692, 0, 693, 694, 695, 0, 0, 0, 0,
+	0, 696, 697, 699, 0, 700, 701, 702, 703, 704,
+	705, 698, 706, 707, 708, 709, 710, 711, 712, 713,
+	0, 715, 716, 714, 717, 718, 0, 719, 720, 721,
+	722, 723, 894, 724, 0, 725, 726, 734, 735, 736,
+	727, 728, 730, 2545, 729, 738, 739, 740, 741, 743,
+	742, 0, 2551, 746, 744, 747, 748, 749, 750, 0,
+	751, 895, 752, 731, 732, 753, 754, 755, 0, 756,
+	757, 758, 759, 760, 761, 762, 763, 764, 896, 0,
+	766, 0, 765, 767, 768, 769, 770, 771, 772, 773,
+	775, 733, 776, 777, 778, 783, 784, 785, 897, 779,
+	780, 781, 782, 787, 898, 788, 789, 790, 791, 0,
+	792, 793, 0, 786, 774, 2553, 794, 795, 796, 797,
+	798, 799, 800, 801, 802, 803, 0, 804, 899, 900,
+	901, 902, 0, 817, 0, 805, 807, 808, 809, 810,
+	903, 811, 812, 904, 0, 813, 814, 2544, 816, 806,
+	819, 820, 818, 0, 0, 821, 822, 823, 824, 826,
+	828, 829, 830, 825, 827, 831, 0, 832, 0, 0,
+	833, 834, 835, 905, 906, 907, 0, 908, 838, 839,
+	836, 837, 840, 841, 844, 842, 843, 909, 847, 542,
+	848, 849, 850, 845, 846, 0, 1204, 0, 1206, 851,
+	852, 910, 853, 854, 855, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 367, 368, 370, 369, 371,
+	372, 373, 374, 0, 375, 376, 0, 0, 0, 0,
+	1218, 856, 0, 0, 0, 378, 0, 377, 0, 379,
+	380, 381, 0, 382, 383, 384, 385, 386, 387, 388,
+	389, 390, 857, 391, 858, 0, 392, 859, 393, 860,
+	0, 861, 394, 395, 396, 397, 398, 399, 400, 401,
+	402, 403, 404, 0, 0, 0, 405, 862, 863, 864,
+	0, 406, 407, 408, 409, 865, 0, 0, 0, 410,
+	411, 412, 413, 414, 415, 416, 417, 0, 0, 419,
+	420, 421, 418, 422, 423, 0, 424, 0, 425, 426,
+	427, 428, 429, 0, 430, 431, 0, 432, 433, 434,
+	0, 435, 436, 437, 0, 0, 0, 0, 0, 0,
+	0, 438, 439, 440, 1213, 442, 0, 443, 445, 866,
+	867, 0, 448, 450, 444, 446, 0, 449, 447, 451,
+	452, 0, 453, 454, 455, 456, 457, 0, 0, 0,
+	458, 459, 460, 461, 0, 462, 463, 464, 466, 465,
+	0, 467, 468, 469, 0, 470, 471, 868, 472, 473,
+	474, 476, 478, 475, 477, 479, 480, 481, 482, 483,
+	869, 870, 484, 485, 0, 362, 0, 0, 0, 0,
+	0, 486, 487, 488, 871, 0, 0, 0, 489, 0,
+	491, 495, 496, 492, 493, 494, 497, 0, 490, 498,
+	499, 0, 0, 500, 501, 502, 872, 873, 503, 504,
+	505, 506, 507, 508, 509, 510, 511, 0, 512, 513,
+	874, 0, 875, 514, 0, 515, 516, 517, 518, 519,
+	520, 521, 876, 877, 878, 630, 0, 522, 523, 524,
+	525, 0, 526, 527, 528, 529, 530, 531, 532, 0,
+	0, 0, 533, 534, 535, 536, 0, 364, 363, 365,
+	0, 879, 537, 631, 538, 539, 880, 881, 0, 882,
+	0, 540, 541, 544, 0, 883, 0, 543, 545, 546,
+	0, 547, 0, 0, 0, 548, 549, 550, 551, 552,
+	553, 554, 0, 555, 557, 556, 0, 559, 884, 558,
+	0, 560, 561, 0, 0, 562, 563, 564, 565, 566,
+	567, 572, 0, 0, 568, 569, 570, 571, 573, 574,
+	0, 575, 576, 578, 581, 577, 579, 580, 582, 583,
+	596, 597, 598, 584, 585, 586, 587, 588, 589, 590,
+	591, 592, 593, 594, 595, 600, 0, 599, 0, 0,
+	601, 602, 603, 604, 605, 606, 612, 615, 617, 618,
+	613, 614, 616, 619, 620, 621, 623, 624, 609, 610,
+	611, 0, 622, 607, 0, 608, 366, 0, 625, 626,
+	627, 628, 0, 885, 629, 886, 632, 633, 0, 0,
+	634, 0, 635, 636, 0, 0, 638, 639, 640, 0,
+	0, 641, 642, 887, 0, 643, 0, 888, 644, 645,
+	637, 646, 647, 648, 649, 650, 651, 652, 653, 654,
+	655, 656, 657, 0, 658, 659, 889, 660, 661, 662,
+	663, 664, 890, 665, 666, 667, 891, 668, 892, 669,
+	670, 671, 0, 672, 673, 674, 0, 675, 676, 677,
+	678, 679, 680, 681, 682, 683, 684, 893, 685, 686,
+	688, 687, 689, 690, 0, 691, 692, 0, 693, 694,
+	695, 0, 0, 0, 0, 0, 696, 697, 699, 0,
+	700, 701, 702, 703, 704, 705, 698, 706, 707, 708,
+	709, 710, 711, 712, 713, 0, 715, 716, 714, 717,
+	718, 0, 719, 720, 721, 722, 723, 894, 724, 0,
+	725, 726, 734, 735, 736, 727, 728, 730, 737, 729,
+	738, 739, 740, 741, 743, 742, 0, 745, 746, 744,
+	747, 748, 749, 750, 0, 751, 895, 752, 731, 732,
+	753, 754, 755, 0, 756, 757, 758, 759, 760, 761,
+	762, 763, 764, 896, 0, 766, 0, 765, 767, 768,
+	769, 770, 771, 772, 773, 775, 733, 776, 777, 778,
+	783, 784, 785, 897, 779, 780, 781, 782, 787, 898,
+	788, 789, 790, 791, 0, 792, 793, 0, 786, 774,
+	1211, 794, 795, 796, 797, 798, 1215, 800, 801, 802,
+	803, 0, 804, 899, 900, 901, 902, 0, 817, 0,
+	805, 807, 808, 809, 810, 903, 811, 812, 904, 0,
+	813, 814, 815, 816, 806, 819, 820, 818, 0, 0,
+	821, 822, 823, 824, 826, 828, 829, 830, 825, 827,
+	831, 0, 832, 0, 0, 833, 834, 835, 905, 906,
+	907, 0, 908, 838, 839, 836, 837, 840, 841, 844,
+	842, 843, 1214, 847, 542, 848, 849, 850, 845, 846,
+	0, 4199, 0, 359, 851, 852, 910, 853, 854, 855,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	367, 368, 370, 369, 371, 372, 373, 374, 0, 375,
+	376, 0, 0, 0, 0, 1218, 856, 0, 0, 0,
+	378, 0, 377, 0, 379, 380, 381, 0, 382, 383,
+	384, 385, 386, 387, 388, 389, 390, 857, 391, 858,
+	0, 392, 859, 393, 860, 0, 861, 394, 395, 396,
+	397, 398, 399, 400, 401, 402, 403, 404, 0, 0,
+	0, 405, 862, 863, 864, 0, 406, 407, 408, 409,
+	865, 0, 0, 0, 410, 411, 412, 413, 414, 415,
+	416, 417, 0, 0, 419, 420, 421, 418, 422, 423,
+	0, 424, 0, 425, 426, 427, 428, 429, 0, 430,
+	431, 0, 432, 433, 434, 0, 435, 436, 437, 0,
+	0, 0, 0, 0, 0, 0, 438, 439, 440, 441,
+	442, 0, 443, 445, 866, 867, 0, 448, 450, 444,
+	446, 0, 449, 447, 451, 452, 0, 453, 454, 455,
+	456, 457, 0, 0, 0, 458, 459, 460, 461, 0,
+	462, 463, 464, 466, 465, 0, 467, 468, 469, 0,
+	470, 471, 868, 472, 473, 474, 476, 478, 475, 477,
+	479, 480, 481, 482, 483, 869, 870, 484, 485, 0,
+	362, 0, 0, 0, 0, 0, 486, 487, 488, 871,
+	0, 0, 0, 489, 0, 491, 495, 496, 492, 493,
+	494, 497, 0, 490, 498, 499, 0, 0, 500, 501,
+	502, 872, 873, 503, 504, 505, 506, 507, 508, 509,
+	510, 511, 0, 512, 513, 874, 0, 875, 514, 0,
+	515, 516, 517, 518, 519, 520, 521, 876, 877, 878,
+	630, 0, 522, 523, 524, 525, 0, 526, 527, 528,
+	529, 530, 531, 532, 0, 0, 0, 533, 534, 535,
+	536, 0, 364, 363, 365, 0, 879, 537, 631, 538,
+	539, 880, 881, 0, 882, 0, 540, 541, 544, 0,
+	883, 0, 543, 545, 546, 0, 547, 0, 0, 0,
+	548, 549, 550, 551, 552, 553, 554, 0, 555, 557,
+	556, 0, 559, 884, 558, 0, 560, 561, 0, 0,
+	562, 563, 564, 565, 566, 567, 572, 0, 0, 568,
+	569, 570, 571, 573, 574, 0, 575, 576, 578, 581,
+	577, 579, 580, 582, 583, 596, 597, 598, 584, 585,
+	586, 587, 588, 589, 590, 591, 592, 593, 594, 595,
+	600, 0, 599, 0, 0, 601, 602, 603, 604, 605,
+	606, 612, 615, 617, 618, 613, 614, 616, 619, 620,
+	621, 623, 624, 609, 610, 611, 0, 622, 607, 0,
+	608, 366, 0, 625, 626, 627, 628, 0, 885, 629,
+	886, 632, 633, 0, 0, 634, 0, 635, 636, 0,
+	0, 638, 639, 640, 0, 0, 641, 642, 887, 0,
+	643, 0, 888, 644, 645, 637, 646, 647, 648, 649,
+	650, 651, 652, 653, 654, 655, 656, 657, 0, 658,
+	659, 889, 660, 661, 662, 663, 664, 890, 665, 666,
+	667, 891, 668, 892, 669, 670, 671, 0, 672, 673,
+	674, 0, 675, 676, 677, 678, 679, 680, 681, 682,
+	683, 684, 893, 685, 686, 688, 687, 689, 690, 0,
+	691, 692, 0, 693, 694, 695, 0, 0, 0, 0,
+	0, 696, 697, 699, 0, 700, 701, 702, 703, 704,
+	705, 698, 706, 707, 708, 709, 710, 711, 712, 713,
+	0, 715, 716, 714, 717, 718, 0, 719, 720, 721,
+	722, 723, 894, 724, 0, 725, 726, 734, 735, 736,
+	727, 728, 730, 737, 729, 738, 739, 740, 741, 743,
+	742, 0, 745, 746, 744, 747, 748, 749, 750, 0,
+	751, 895, 752, 731, 732, 753, 754, 755, 0, 756,
+	757, 758, 759, 760, 761, 762, 763, 764, 896, 0,
+	766, 0, 765, 767, 768, 769, 770, 771, 772, 773,
+	775, 733, 776, 777, 778, 783, 784, 785, 897, 779,
+	780, 781, 782, 787, 898, 788, 789, 790, 791, 0,
+	792, 793, 0, 786, 774, 0, 794, 795, 796, 797,
+	798, 799, 800, 801, 802, 803, 0, 804, 899, 900,
+	901, 902, 0, 817, 0, 805, 807, 808, 809, 810,
+	903, 811, 812, 904, 0, 813, 814, 815, 816, 806,
+	819, 820, 818, 0, 0, 821, 822, 823, 824, 826,
+	828, 829, 830, 825, 827, 831, 0, 832, 0, 0,
+	833, 834, 835, 905, 906, 907, 0, 908, 838, 839,
+	836, 837, 840, 841, 844, 842, 843, 909, 847, 542,
+	848, 849, 850, 845, 846, 2547, 0, 0, 0, 851,
+	852, 910, 853, 854, 855, 0, 0, 0, 0, 0,
+	0, 0, 367, 368, 370, 369, 371, 372, 373, 374,
+	0, 375, 376, 0, 0, 0, 0, 0, 856, 0,
+	1218, 0, 378, 0, 377, 0, 379, 380, 381, 0,
+	382, 383, 384, 385, 386, 387, 388, 389, 390, 857,
+	391, 858, 0, 392, 859, 393, 860, 0, 861, 394,
+	395, 396, 397, 398, 399, 400, 401, 402, 403, 404,
+	0, 0, 0, 405, 862, 863, 864, 0, 406, 407,
+	408, 409, 865, 0, 0, 0, 410, 411, 412, 413,
+	414, 415, 416, 417, 0, 0, 419, 420, 421, 418,
+	422, 423, 0, 424, 0, 425, 426, 427, 428, 429,
+	0, 430, 431, 0, 432, 433, 434, 0, 435, 436,
+	437, 0, 0, 0, 0, 0, 0, 0, 438, 439,
+	440, 2554, 442, 0, 443, 445, 866, 867, 0, 448,
+	450, 444, 446, 0, 449, 447, 451, 452, 0, 453,
+	454, 455, 456, 457, 0, 0, 0, 458, 459, 460,
+	461, 0, 462, 463, 464, 466, 465, 0, 467, 468,
+	469, 0, 470, 471, 868, 472, 473, 474, 476, 478,
+	475, 477, 479, 480, 481, 482, 2555, 869, 870, 484,
+	485, 0, 362, 0, 0, 0, 0, 0, 486, 487,
+	488, 871, 0, 0, 0, 489, 0, 491, 495, 496,
+	492, 493, 494, 497, 0, 490, 498, 499, 0, 0,
+	2556, 501, 502, 872, 873, 503, 504, 505, 506, 507,
+	508, 509, 510, 511, 0, 512, 513, 874, 0, 875,
+	514, 0, 515, 516, 517, 518, 519, 520, 521, 876,
+	877, 878, 630, 0, 522, 523, 524, 525, 0, 526,
+	527, 528, 529, 530, 531, 532, 0, 0, 0, 533,
+	534, 535, 536, 0, 364, 363, 365, 0, 879, 537,
+	631, 538, 539, 880, 881, 0, 882, 0, 540, 541,
+	544, 0, 883, 0, 543, 545, 546, 0, 547, 0,
+	0, 0, 548, 549, 550, 551, 552, 553, 554, 0,
+	555, 557, 556, 0, 559, 884, 558, 0, 560, 561,
+	0, 0, 562, 563, 564, 565, 566, 567, 572, 0,
+	0, 568, 569, 570, 571, 573, 574, 0, 575, 576,
+	578, 581, 577, 579, 580, 582, 583, 596, 597, 598,
+	584, 585, 586, 587, 588, 589, 590, 591, 592, 593,
+	594, 595, 600, 0, 599, 0, 0, 601, 602, 603,
+	604, 605, 606, 612, 615, 617, 618, 613, 614, 616,
+	619, 620, 621, 623, 624, 609, 610, 611, 0, 622,
+	607, 0, 608, 366, 0, 625, 626, 627, 628, 0,
+	885, 629, 886, 632, 633, 0, 0, 634, 0, 635,
+	636, 0, 0, 638, 639, 640, 0, 0, 641, 642,
+	887, 0, 643, 0, 888, 644, 645, 637, 646, 647,
+	648, 649, 650, 651, 652, 653, 654, 655, 656, 657,
+	0, 658, 659, 889, 660, 661, 662, 663, 664, 890,
+	665, 666, 667, 891, 668, 892, 669, 670, 671, 0,
+	672, 673, 674, 0, 2557, 676, 677, 678, 679, 680,
+	681, 682, 683, 684, 893, 685, 686, 688, 687, 689,
+	690, 0, 691, 692, 0, 693, 694, 695, 0, 0,
+	0, 0, 0, 696, 697, 699, 0, 700, 701, 702,
+	703, 704, 705, 698, 706, 707, 708, 709, 710, 711,
+	712, 713, 0, 715, 716, 714, 717, 718, 0, 2762,
+	720, 721, 722, 723, 894, 724, 0, 725, 726, 734,
+	735, 736, 727, 728, 730, 2763, 729, 738, 739, 740,
+	741, 743, 742, 0, 2551, 746, 744, 747, 748, 749,
+	750, 0, 751, 895, 752, 731, 732, 753, 754, 755,
+	0, 756, 757, 758, 759, 760, 761, 762, 763, 764,
+	896, 0, 766, 0, 765, 767, 768, 769, 770, 771,
+	772, 773, 775, 733, 776, 777, 778, 783, 784, 785,
+	897, 779, 780, 781, 782, 787, 898, 788, 789, 790,
+	791, 0, 792, 793, 0, 786, 774, 2553, 794, 795,
+	796, 797, 798, 799, 800, 801, 802, 803, 0, 804,
+	899, 900, 901, 902, 0, 817, 0, 805, 807, 808,
+	809, 810, 903, 811, 812, 904, 0, 813, 814, 2764,
+	816, 806, 819, 820, 818, 0, 0, 821, 822, 823,
+	824, 826, 828, 829, 830, 825, 827, 831, 0, 832,
+	0, 0, 833, 834, 835, 905, 906, 907, 0, 908,
+	838, 839, 836, 837, 840, 841, 844, 842, 843, 909,
+	847, 542, 848, 849, 850, 845, 846, 359, 0, 0,
+	0, 851, 852, 910, 853, 854, 855, 0, 0, 0,
+	0, 0, 0, 0, 367, 368, 370, 369, 371, 372,
+	373, 374, 0, 375, 376, 0, 0, 0, 0, 0,
+	856, 0, 1218, 0, 378, 0, 377, 0, 379, 380,
+	381, 0, 382, 383, 384, 385, 386, 387, 388, 389,
+	390, 857, 391, 858, 0, 392, 859, 393, 860, 0,
+	861, 394, 395, 396, 397, 398, 399, 400, 401, 402,
+	403, 404, 0, 0, 0, 405, 862, 863, 864, 0,
+	406, 407, 408, 409, 865, 0, 0, 0, 410, 411,
+	412, 413, 414, 415, 416, 417, 0, 0, 419, 420,
+	421, 418, 422, 423, 0, 424, 0, 425, 426, 427,
+	428, 429, 0, 430, 431, 0, 432, 433, 434, 0,
+	435, 436, 437, 0, 0, 0, 0, 0, 0, 0,
+	438, 439, 440, 441, 442, 0, 443, 445, 866, 867,
+	0, 448, 450, 444, 446, 0, 449, 447, 451, 452,
+	0, 453, 454, 455, 456, 457, 0, 0, 0, 458,
+	459, 460, 461, 0, 462, 463, 464, 466, 465, 0,
+	467, 468, 469, 0, 470, 471, 868, 472, 473, 474,
+	476, 478, 475, 477, 479, 480, 481, 482, 483, 869,
+	870, 484, 485, 0, 362, 0, 0, 0, 0, 0,
+	486, 487, 488, 871, 0, 0, 0, 489, 0, 491,
+	495, 496, 492, 493, 494, 497, 0, 490, 498, 499,
+	0, 0, 500, 501, 502, 872, 873, 503, 504, 505,
+	506, 507, 508, 509, 510, 511, 0, 512, 513, 874,
+	0, 875, 514, 0, 515, 516, 517, 518, 519, 520,
+	521, 876, 877, 878, 630, 0, 522, 523, 524, 525,
+	0, 526, 527, 528, 529, 530, 531, 532, 0, 0,
+	0, 533, 534, 535, 536, 0, 364, 363, 365, 0,
+	879, 537, 631, 538, 539, 880, 881, 0, 882, 0,
+	540, 541, 544, 0, 883, 0, 543, 545, 546, 0,
+	547, 0, 0, 0, 548, 549, 550, 551, 552, 553,
+	554, 0, 555, 557, 556, 0, 559, 884, 558, 0,
+	560, 561, 0, 0, 562, 563, 564, 565, 566, 567,
+	572, 0, 0, 568, 569, 570, 571, 573, 574, 0,
+	575, 576, 578, 581, 577, 579, 580, 582, 583, 596,
+	597, 598, 584, 585, 586, 587, 588, 589, 590, 591,
+	592, 593, 594, 595, 600, 0, 599, 0, 0, 601,
+	602, 603, 604, 605, 606, 612, 615, 617, 618, 613,
+	614, 616, 619, 620, 621, 623, 624, 609, 610, 611,
+	0, 622, 607, 0, 608, 366, 0, 625, 626, 627,
+	628, 0, 885, 629, 886, 632, 633, 0, 0, 634,
+	0, 635, 636, 0, 0, 638, 639, 640, 0, 0,
+	641, 642, 887, 0, 643, 0, 888, 644, 645, 637,
+	646, 647, 648, 649, 650, 651, 652, 653, 654, 655,
+	656, 657, 0, 658, 659, 889, 660, 661, 662, 663,
+	664, 890, 665, 666, 667, 891, 668, 892, 669, 670,
+	671, 0, 672, 673, 674, 0, 675, 676, 677, 678,
+	679, 680, 681, 682, 683, 684, 893, 685, 686, 688,
+	687, 689, 690, 0, 691, 692, 0, 693, 694, 695,
+	0, 0, 0, 0, 0, 696, 697, 699, 0, 700,
+	701, 702, 703, 704, 705, 698, 706, 707, 708, 709,
+	710, 711, 712, 713, 0, 715, 716, 714, 717, 718,
+	0, 719, 720, 721, 722, 723, 894, 724, 0, 725,
+	726, 734, 735, 736, 727, 728, 730, 737, 729, 738,
+	739, 740, 741, 743, 742, 0, 745, 746, 744, 747,
+	748, 749, 750, 0, 751, 895, 752, 731, 732, 753,
+	754, 755, 0, 756, 757, 758, 759, 760, 761, 762,
+	763, 764, 896, 0, 766, 0, 765, 767, 768, 769,
+	770, 771, 772, 773, 775, 733, 776, 777, 778, 783,
+	784, 785, 897, 779, 780, 781, 782, 787, 898, 788,
+	789, 790, 791, 0, 792, 793, 0, 786, 774, 0,
+	794, 795, 796, 797, 798, 799, 800, 801, 802, 803,
+	0, 804, 899, 900, 901, 902, 0, 817, 0, 805,
+	807, 808, 809, 810, 903, 811, 812, 904, 0, 813,
+	814, 815, 816, 806, 819, 820, 818, 0, 0, 821,
+	822, 823, 824, 826, 828, 829, 830, 825, 827, 831,
+	0, 832, 0, 0, 833, 834, 835, 905, 906, 907,
+	0, 908, 838, 839, 836, 837, 840, 841, 844, 842,
+	843, 909, 847, 542, 848, 849, 850, 845, 846, 359,
+	0, 0, 0, 851, 852, 910, 853, 854, 855, 0,
+	0, 0, 0, 0, 0, 0, 367, 368, 370, 369,
+	371, 372, 373, 374, 0, 375, 376, 0, 0, 0,
+	0, 0, 856, 0, 1218, 0, 378, 0, 377, 0,
+	379, 380, 381, 0, 382, 383, 384, 385, 386, 387,
+	388, 389, 390, 857, 391, 858, 0, 392, 859, 393,
+	860, 0, 861, 394, 395, 396, 397, 398, 399, 400,
+	401, 402, 403, 404, 0, 0, 0, 405, 862, 863,
+	864, 0, 406, 407, 408, 409, 865, 0, 0, 0,
+	410, 411, 412, 413, 414, 415, 416, 417, 0, 0,
+	419, 420, 421, 418, 422, 423, 0, 424, 0, 425,
+	426, 427, 428, 429, 0, 430, 431, 0, 432, 433,
+	434, 0, 435, 436, 437, 0, 0, 0, 0, 0,
+	0, 0, 438, 439, 440, 441, 442, 0, 443, 445,
+	866, 867, 0, 448, 450, 444, 446, 0, 449, 447,
+	451, 452, 0, 453, 454, 455, 456, 457, 0, 0,
+	0, 458, 459, 460, 461, 0, 462, 463, 464, 466,
+	465, 0, 467, 468, 469, 0, 470, 471, 868, 472,
+	473, 474, 476, 478, 475, 477, 479, 480, 481, 482,
+	483, 869, 870, 484, 485, 0, 362, 0, 0, 0,
+	0, 0, 486, 487, 488, 871, 0, 0, 0, 489,
+	0, 491, 495, 496, 492, 493, 494, 497, 0, 490,
+	498, 499, 0, 0, 500, 501, 502, 872, 873, 503,
+	504, 505, 506, 507, 508, 509, 510, 511, 0, 512,
+	513, 874, 0, 875, 514, 0, 515, 516, 517, 518,
+	519, 520, 521, 876, 877, 878, 630, 0, 522, 523,
+	524, 525, 0, 526, 527, 528, 529, 530, 531, 532,
+	0, 0, 0, 533, 534, 535, 536, 0, 364, 363,
+	365, 0, 879, 537, 631, 538, 539, 880, 881, 0,
+	882, 0, 540, 541, 544, 0, 883, 0, 543, 545,
+	546, 0, 547, 0, 0, 0, 548, 549, 550, 551,
+	552, 553, 554, 0, 555, 557, 556, 0, 559, 884,
+	558, 0, 560, 561, 0, 0, 562, 563, 564, 565,
+	566, 567, 572, 0, 0, 568, 569, 570, 571, 573,
+	574, 0, 575, 576, 578, 581, 577, 579, 580, 582,
+	583, 596, 597, 598, 584, 585, 586, 587, 588, 589,
+	590, 591, 592, 593, 594, 595, 600, 0, 599, 0,
+	0, 601, 602, 603, 604, 605, 606, 612, 615, 617,
+	618, 613, 614, 616, 619, 620, 621, 623, 624, 609,
+	610, 611, 0, 622, 607, 0, 608, 366, 0, 625,
+	626, 627, 628, 0, 885, 629, 886, 632, 633, 0,
+	0, 634, 0, 635, 636, 0, 0, 638, 639, 640,
+	0, 0, 641, 642, 887, 0, 643, 0, 888, 644,
+	645, 637, 646, 647, 648, 649, 650, 651, 652, 653,
+	654, 655, 656, 657, 0, 658, 659, 889, 660, 661,
+	662, 663, 664, 890, 665, 666, 667, 891, 668, 892,
+	669, 670, 671, 0, 672, 673, 674, 0, 675, 676,
+	677, 678, 679, 680, 681, 682, 683, 684, 893, 685,
+	686, 688, 687, 689, 690, 0, 691, 692, 0, 693,
+	694, 695, 0, 0, 0, 0, 0, 696, 697, 699,
+	0, 700, 701, 702, 703, 704, 705, 698, 706, 707,
+	708, 709, 710, 711, 712, 713, 0, 715, 716, 714,
+	717, 718, 0, 719, 720, 721, 722, 723, 894, 724,
+	0, 725, 726, 734, 735, 736, 727, 728, 730, 737,
+	729, 738, 739, 740, 741, 743, 742, 0, 745, 746,
+	744, 747, 748, 749, 750, 0, 751, 895, 752, 731,
+	732, 753, 754, 755, 0, 756, 757, 758, 759, 760,
+	761, 762, 763, 764, 896, 0, 766, 0, 765, 767,
+	768, 769, 770, 771, 772, 773, 775, 733, 776, 777,
+	778, 783, 784, 785, 897, 779, 780, 781, 782, 787,
+	898, 788, 789, 790, 791, 0, 792, 793, 0, 786,
+	774, 0, 794, 795, 796, 797, 798, 799, 800, 801,
+	802, 803, 0, 804, 899, 900, 901, 902, 0, 817,
+	0, 805, 807, 808, 809, 810, 903, 811, 812, 904,
+	0, 813, 814, 815, 816, 806, 819, 820, 818, 0,
+	0, 821, 822, 823, 824, 826, 828, 829, 830, 825,
+	827, 831, 0, 832, 0, 0, 833, 834, 835, 905,
+	906, 907, 0, 908, 838, 839, 836, 837, 840, 841,
+	844, 842, 843, 909, 847, 542, 848, 849, 850, 845,
+	846, 4221, 0, 0, 0, 851, 852, 910, 853, 854,
+	855, 0, 0, 0, 0, 0, 0, 0, 367, 368,
+	370, 369, 371, 372, 373, 374, 0, 375, 376, 0,
+	0, 0, 0, 0, 0, 0, 1088, 0, 378, 0,
+	377, 0, 379, 380, 381, 926, 382, 383, 384, 385,
+	386, 387, 388, 389, 390, 0, 391, 2580, 0, 392,
+	2587, 393, 2586, 0, 2595, 394, 395, 396, 397, 398,
+	399, 400, 401, 402, 403, 404, 0, 0, 0, 405,
+	2599, 2600, 0, 0, 406, 407, 408, 409, 0, 0,
+	927, 0, 410, 411, 412, 413, 414, 415, 416, 417,
+	0, 0, 419, 420, 421, 418, 422, 423, 0, 424,
+	0, 425, 426, 427, 428, 429, 0, 430, 431, 0,
+	432, 433, 434, 928, 435, 436, 437, 0, 0, 0,
+	0, 0, 0, 0, 438, 439, 440, 441, 442, 1568,
+	443, 445, 2584, 2583, 0, 448, 450, 444, 446, 0,
+	449, 447, 451, 452, 0, 453, 454, 455, 456, 457,
+	0, 0, 0, 458, 1560, 460, 461, 0, 462, 463,
+	464, 466, 465, 0, 467, 468, 469, 0, 470, 471,
+	0, 472, 473, 474, 476, 478, 475, 477, 479, 480,
+	481, 482, 483, 0, 0, 484, 485, 0, 362, 0,
+	0, 0, 0, 0, 486, 487, 488, 2582, 0, 0,
+	0, 489, 0, 491, 495, 496, 492, 493, 494, 497,
+	0, 490, 498, 499, 0, 929, 500, 501, 502, 2593,
+	2594, 503, 504, 505, 506, 507, 508, 509, 510, 511,
+	0, 512, 513, 0, 0, 0, 514, 0, 515, 516,
+	517, 518, 519, 520, 521, 0, 0, 0, 630, 931,
+	522, 523, 524, 525, 0, 526, 527, 528, 529, 530,
+	531, 532, 0, 0, 0, 533, 534, 535, 536, 0,
+	0, 0, 0, 930, 0, 537, 631, 538, 539, 2577,
+	2578, 0, 2573, 0, 540, 541, 544, 932, 0, 933,
+	543, 545, 546, 934, 547, 0, 0, 0, 548, 549,
+	550, 551, 552, 553, 554, 0, 555, 557, 556, 0,
+	559, 0, 558, 935, 560, 561, 936, 0, 562, 563,
+	564, 565, 566, 567, 572, 0, 0, 568, 569, 570,
+	571, 573, 574, 0, 575, 576, 578, 581, 577, 579,
+	580, 582, 583, 596, 597, 598, 584, 585, 586, 587,
+	588, 589, 590, 591, 592, 593, 594, 595, 600, 0,
+	599, 937, 0, 601, 602, 603, 604, 605, 606, 612,
+	615, 617, 618, 613, 614, 616, 619, 620, 621, 623,
+	624, 609, 610, 611, 938, 622, 607, 0, 608, 0,
+	939, 625, 626, 627, 628, 0, 0, 629, 2585, 632,
+	633, 0, 0, 634, 0, 635, 636, 0, 0, 638,
+	639, 640, 0, 0, 641, 642, 0, 940, 643, 941,
+	0, 644, 645, 637, 646, 647, 648, 649, 650, 651,
+	652, 653, 654, 655, 656, 657, 0, 658, 659, 2570,
+	660, 661, 662, 663, 664, 2571, 665, 666, 667, 0,
+	668, 0, 669, 670, 671, 0, 672, 673, 674, 0,
+	675, 676, 677, 678, 679, 680, 681, 682, 683, 684,
+	2581, 685, 686, 688, 687, 689, 690, 0, 691, 692,
+	0, 693, 694, 695, 0, 0, 0, 0, 0, 696,
+	697, 699, 0, 700, 701, 702, 703, 704, 705, 698,
+	706, 707, 708, 709, 710, 711, 712, 713, 0, 715,
+	716, 714, 717, 718, 942, 719, 720, 721, 722, 723,
+	0, 724, 0, 725, 726, 734, 735, 736, 727, 728,
+	730, 737, 729, 738, 739, 740, 741, 743, 742, 0,
+	745, 746, 744, 747, 748, 749, 750, 0, 751, 0,
+	752, 731, 732, 753, 754, 755, 943, 756, 757, 758,
+	759, 760, 761, 762, 763, 764, 2579, 0, 766, 0,
+	765, 767, 768, 769, 770, 771, 772, 773, 775, 733,
+	776, 777, 778, 783, 784, 785, 2598, 779, 780, 781,
+	782, 787, 0, 788, 789, 790, 791, 0, 792, 793,
+	0, 786, 774, 0, 794, 795, 796, 797, 798, 799,
+	800, 801, 802, 803, 0, 804, 2589, 2590, 2591, 2592,
+	0, 817, 0, 805, 807, 808, 809, 810, 0, 811,
+	812, 0, 0, 813, 814, 815, 816, 806, 819, 820,
+	818, 0, 0, 821, 822, 823, 824, 826, 828, 829,
+	830, 825, 827, 831, 0, 832, 0, 0, 833, 834,
+	835, 0, 2588, 2597, 0, 2596, 838, 839, 836, 837,
+	840, 841, 844, 842, 843, 0, 847, 542, 848, 849,
+	850, 845, 846, 0, 0, 0, 0, 851, 852, 0,
+	853, 854, 855, 0, 2574, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 367, 368, 370, 369, 371, 372, 373, 374, 0,
+	375, 376, 0, 0, 0, 0, 0, 0, 0, 0,
+	2566, 378, 0, 377, 0, 379, 380, 381, 926, 382,
+	383, 384, 385, 386, 387, 388, 389, 390, 0, 391,
+	2580, 0, 392, 2587, 393, 2586, 0, 2595, 394, 395,
+	396, 397, 398, 399, 400, 401, 402, 403, 404, 0,
+	0, 0, 405, 2599, 2600, 0, 0, 406, 407, 408,
+	409, 0, 0, 927, 0, 410, 411, 412, 413, 414,
+	415, 416, 417, 0, 0, 419, 420, 421, 418, 422,
+	423, 0, 424, 0, 425, 426, 427, 428, 429, 0,
+	430, 431, 0, 432, 433, 434, 928, 435, 436, 437,
+	0, 0, 0, 0, 0, 0, 0, 438, 439, 440,
+	441, 442, 1568, 443, 445, 2584, 2583, 0, 448, 450,
+	444, 446, 0, 449, 447, 451, 452, 0, 453, 454,
+	455, 456, 457, 0, 0, 0, 458, 1560, 460, 461,
+	0, 462, 463, 464, 466, 465, 0, 467, 468, 469,
+	0, 470, 471, 0, 472, 473, 474, 476, 478, 475,
+	477, 479, 480, 481, 482, 483, 0, 0, 484, 485,
+	0, 0, 0, 0, 0, 0, 0, 486, 487, 488,
+	2582, 0, 0, 0, 489, 0, 491, 495, 496, 492,
+	493, 494, 497, 0, 490, 498, 499, 0, 929, 500,
+	501, 502, 2593, 2594, 503, 504, 505, 506, 507, 508,
+	509, 510, 511, 0, 512, 513, 0, 0, 0, 514,
+	0, 515, 516, 517, 518, 519, 520, 521, 0, 0,
+	0, 630, 931, 522, 523, 524, 525, 0, 526, 527,
+	528, 529, 530, 531, 532, 0, 0, 0, 533, 534,
+	535, 536, 0, 0, 0, 0, 930, 0, 537, 631,
+	538, 539, 2577, 2578, 0, 2573, 0, 540, 541, 544,
+	932, 0, 933, 543, 545, 546, 934, 547, 0, 0,
+	0, 548, 549, 550, 551, 552, 553, 554, 0, 555,
+	557, 556, 0, 559, 0, 558, 935, 560, 561, 936,
+	0, 562, 563, 564, 565, 566, 567, 572, 0, 0,
+	568, 569, 570, 571, 573, 574, 0, 575, 576, 578,
+	581, 577, 579, 580, 582, 583, 596, 597, 598, 584,
+	585, 586, 587, 588, 589, 590, 591, 592, 593, 594,
+	595, 600, 0, 599, 937, 0, 601, 602, 603, 604,
+	605, 606, 612, 615, 617, 618, 613, 614, 616, 619,
+	620, 621, 623, 624, 609, 610, 611, 938, 622, 607,
+	0, 608, 0, 939, 625, 626, 627, 628, 0, 0,
+	629, 2585, 632, 633, 0, 0, 634, 0, 635, 636,
+	0, 0, 638, 639, 640, 0, 0, 641, 642, 0,
+	940, 643, 941, 0, 644, 645, 637, 646, 647, 648,
+	649, 650, 651, 652, 653, 654, 655, 656, 657, 0,
+	658, 659, 2570, 660, 661, 662, 663, 664, 2571, 665,
+	666, 667, 0, 668, 0, 669, 670, 671, 0, 672,
+	673, 674, 0, 675, 676, 677, 678, 679, 680, 681,
+	682, 683, 684, 2581, 685, 686, 688, 687, 689, 690,
+	0, 691, 692, 0, 693, 694, 695, 0, 0, 0,
+	0, 0, 696, 697, 699, 0, 700, 701, 702, 703,
+	704, 705, 698, 706, 707, 708, 709, 710, 711, 712,
+	713, 0, 715, 716, 714, 717, 718, 942, 719, 720,
+	721, 722, 723, 0, 724, 0, 725, 726, 734, 735,
+	736, 727, 728, 730, 737, 729, 738, 739, 740, 741,
+	743, 742, 0, 745, 746, 744, 747, 748, 749, 750,
+	0, 751, 0, 752, 731, 732, 753, 754, 755, 943,
+	756, 757, 758, 759, 760, 761, 762, 763, 764, 2579,
+	0, 766, 0, 765, 767, 768, 769, 770, 771, 772,
+	773, 775, 733, 776, 777, 778, 783, 784, 785, 2598,
+	779, 780, 781, 782, 787, 0, 788, 789, 790, 791,
+	0, 792, 793, 0, 786, 774, 0, 794, 795, 796,
+	797, 798, 799, 800, 801, 802, 803, 0, 804, 2589,
+	2590, 2591, 2592, 0, 817, 0, 805, 807, 808, 809,
+	810, 0, 811, 812, 0, 0, 813, 814, 815, 816,
+	806, 819, 820, 818, 0, 0, 821, 822, 823, 824,
+	826, 828, 829, 830, 825, 827, 831, 0, 832, 0,
+	0, 833, 834, 835, 0, 2588, 2597, 0, 2596, 838,
+	839, 836, 837, 840, 841, 844, 842, 843, 0, 847,
+	542, 848, 849, 850, 845, 846, 0, 0, 0, 359,
+	851, 852, 0, 853, 854, 855, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 367, 368, 370, 369,
+	371, 372, 373, 374, 0, 375, 376, 0, 0, 0,
+	0, 0, 856, 0, 0, 0, 378, 0, 377, 0,
+	379, 380, 381, 2566, 382, 383, 384, 385, 386, 387,
+	388, 389, 390, 857, 391, 858, 0, 392, 859, 393,
+	860, 0, 861, 394, 395, 396, 397, 398, 399, 400,
+	401, 402, 403, 404, 0, 0, 0, 405, 862, 863,
+	864, 0, 406, 407, 408, 409, 865, 0, 0, 0,
+	410, 411, 412, 413, 414, 415, 416, 417, 0, 0,
+	419, 420, 421, 418, 422, 423, 0, 424, 0, 425,
+	426, 427, 428, 429, 0, 430, 431, 0, 432, 433,
+	434, 0, 435, 436, 437, 0, 0, 0, 0, 0,
+	0, 0, 438, 439, 440, 441, 442, 0, 443, 445,
+	866, 867, 0, 448, 450, 444, 446, 0, 449, 447,
+	451, 452, 0, 453, 454, 455, 456, 457, 0, 0,
+	0, 458, 459, 460, 461, 0, 462, 463, 464, 466,
+	465, 0, 467, 468, 469, 0, 470, 471, 868, 472,
+	473, 474, 476, 478, 475, 477, 479, 480, 481, 482,
+	483, 869, 870, 484, 485, 0, 0, 0, 0, 0,
+	0, 0, 486, 487, 488, 871, 0, 0, 0, 489,
+	0, 491, 495, 496, 492, 493, 494, 497, 0, 490,
+	498, 499, 0, 0, 500, 501, 502, 872, 873, 503,
+	504, 505, 506, 507, 508, 509, 510, 511, 0, 512,
+	513, 874, 0, 875, 514, 0, 515, 516, 517, 518,
+	519, 520, 521, 876, 877, 878, 630, 0, 522, 523,
+	524, 525, 0, 526, 527, 528, 529, 530, 531, 532,
+	0, 0, 0, 533, 534, 535, 536, 0, 0, 0,
+	0, 0, 879, 537, 631, 538, 539, 880, 881, 0,
+	882, 0, 540, 541, 544, 0, 883, 0, 543, 545,
+	546, 0, 547, 0, 0, 0, 548, 549, 550, 551,
+	552, 553, 554, 0, 555, 557, 556, 0, 559, 884,
+	558, 0, 560, 561, 0, 0, 562, 563, 564, 565,
+	566, 567, 572, 0, 0, 568, 569, 570, 571, 573,
+	574, 0, 575, 576, 578, 581, 577, 579, 580, 582,
+	583, 596, 597, 598, 584, 585, 586, 587, 588, 589,
+	590, 591, 592, 593, 594, 595, 600, 0, 599, 0,
+	0, 601, 602, 603, 604, 605, 606, 612, 615, 617,
+	618, 613, 614, 616, 619, 620, 621, 623, 624, 609,
+	610, 611, 0, 622, 607, 0, 608, 0, 0, 625,
+	626, 627, 628, 0, 885, 629, 886, 632, 633, 0,
+	0, 634, 0, 635, 636, 0, 0, 638, 639, 640,
+	0, 0, 641, 642, 887, 0, 643, 0, 888, 644,
+	645, 637, 646, 647, 648, 649, 650, 651, 652, 653,
+	654, 655, 656, 657, 0, 658, 659, 889, 660, 661,
+	662, 663, 664, 890, 665, 666, 667, 891, 668, 892,
+	669, 670, 671, 0, 672, 673, 674, 0, 675, 676,
+	677, 678, 679, 680, 681, 682, 683, 684, 893, 685,
+	686, 688, 687, 689, 690, 0, 691, 692, 0, 693,
+	694, 695, 0, 0, 0, 0, 0, 696, 697, 699,
+	0, 700, 701, 702, 703, 704, 705, 698, 706, 707,
+	708, 709, 710, 711, 712, 713, 0, 715, 716, 714,
+	717, 718, 0, 719, 720, 721, 722, 723, 894, 724,
+	0, 725, 726, 734, 735, 736, 727, 728, 730, 737,
+	729, 738, 739, 740, 741, 743, 742, 0, 745, 746,
+	744, 747, 748, 749, 750, 0, 751, 895, 752, 731,
+	732, 753, 754, 755, 0, 756, 757, 758, 759, 760,
+	761, 762, 763, 764, 896, 0, 766, 0, 765, 767,
+	768, 769, 770, 771, 772, 773, 775, 733, 776, 777,
+	778, 783, 784, 785, 897, 779, 780, 781, 782, 787,
+	898, 788, 789, 790, 791, 0, 792, 793, 0, 786,
+	774, 0, 794, 795, 796, 797, 798, 799, 800, 801,
+	802, 803, 0, 804, 899, 900, 901, 902, 0, 817,
+	0, 805, 807, 808, 809, 810, 903, 811, 812, 904,
+	0, 813, 814, 815, 816, 806, 819, 820, 818, 0,
+	0, 821, 822, 823, 824, 826, 828, 829, 830, 825,
+	827, 831, 0, 832, 0, 0, 833, 834, 835, 905,
+	906, 907, 0, 908, 838, 839, 836, 837, 840, 841,
+	844, 842, 843, 909, 847, 542, 848, 849, 850, 845,
+	846, 920, 0, 0, 0, 851, 852, 910, 853, 854,
+	855, 0, 0, 0, 0, 0, 0, 0, 367, 368,
+	370, 369, 371, 372, 373, 374, 0, 375, 376, 0,
+	0, 0, 0, 0, 856, 0, 5673, 0, 378, 0,
+	377, 0, 379, 380, 381, 926, 382, 383, 384, 385,
+	386, 387, 388, 389, 390, 857, 391, 858, 0, 392,
+	859, 393, 860, 0, 861, 394, 395, 396, 397, 398,
+	399, 400, 401, 402, 403, 404, 0, 0, 0, 405,
+	862, 863, 864, 0, 406, 407, 408, 409, 865, 0,
+	927, 0, 410, 411, 412, 413, 414, 415, 416, 417,
+	0, 0, 419, 420, 421, 418, 422, 423, 0, 424,
+	0, 425, 426, 427, 428, 429, 0, 430, 431, 0,
+	432, 433, 434, 928, 435, 436, 437, 0, 0, 0,
+	0, 0, 0, 0, 438, 439, 440, 441, 442, 0,
+	443, 445, 866, 867, 0, 448, 450, 444, 446, 0,
+	449, 447, 451, 452, 0, 453, 454, 455, 456, 457,
+	0, 0, 0, 458, 459, 460, 461, 0, 462, 463,
+	464, 466, 465, 0, 467, 468, 469, 0, 470, 471,
+	868, 472, 473, 474, 476, 478, 475, 477, 479, 480,
+	481, 482, 483, 869, 870, 484, 485, 0, 362, 0,
+	0, 0, 0, 0, 486, 487, 488, 871, 0, 0,
+	0, 489, 0, 491, 495, 496, 492, 493, 494, 497,
+	0, 490, 498, 499, 0, 929, 500, 501, 502, 872,
+	873, 503, 504, 505, 506, 507, 508, 509, 510, 511,
+	0, 512, 513, 874, 0, 875, 514, 0, 515, 516,
+	517, 518, 519, 520, 521, 876, 877, 878, 630, 931,
+	522, 523, 524, 525, 0, 526, 527, 528, 529, 530,
+	531, 532, 0, 0, 0, 533, 534, 535, 536, 0,
+	919, 363, 365, 930, 879, 537, 631, 538, 539, 880,
+	881, 0, 882, 0, 540, 541, 544, 932, 883, 933,
+	543, 545, 546, 934, 547, 0, 0, 0, 548, 549,
+	550, 551, 552, 553, 554, 0, 555, 557, 556, 0,
+	559, 884, 558, 935, 560, 561, 936, 0, 562, 563,
+	564, 565, 566, 567, 572, 0, 0, 568, 569, 570,
+	571, 573, 574, 0, 575, 576, 578, 581, 577, 579,
+	580, 582, 583, 596, 597, 598, 584, 585, 586, 587,
+	588, 589, 590, 591, 592, 593, 594, 595, 600, 0,
+	599, 937, 0, 601, 602, 603, 604, 605, 606, 612,
+	615, 617, 618, 613, 614, 616, 619, 620, 621, 623,
+	624, 609, 610, 611, 938, 622, 607, 0, 608, 366,
+	939, 625, 626, 627, 628, 0, 885, 629, 886, 632,
+	633, 0, 0, 634, 0, 635, 636, 0, 0, 638,
+	639, 640, 0, 0, 641, 642, 887, 940, 643, 941,
+	888, 644, 645, 637, 646, 647, 648, 649, 650, 651,
+	652, 653, 654, 655, 656, 657, 0, 658, 659, 889,
+	660, 661, 662, 663, 664, 890, 665, 666, 667, 891,
+	668, 892, 669, 670, 671, 0, 672, 673, 674, 0,
+	675, 676, 677, 678, 679, 680, 681, 682, 683, 684,
+	893, 685, 686, 688, 687, 689, 690, 0, 691, 692,
+	0, 693, 694, 695, 0, 0, 0, 0, 0, 696,
+	697, 699, 0, 700, 701, 702, 703, 704, 705, 698,
+	706, 707, 708, 709, 710, 711, 712, 713, 0, 715,
+	716, 714, 717, 718, 942, 719, 720, 721, 722, 723,
+	894, 724, 0, 725, 726, 734, 735, 736, 727, 728,
+	730, 737, 729, 738, 739, 740, 741, 743, 742, 0,
+	745, 746, 744, 747, 748, 749, 750, 0, 751, 895,
+	752, 731, 732, 753, 754, 755, 943, 756, 757, 758,
+	759, 760, 761, 762, 763, 764, 896, 0, 766, 0,
+	765, 767, 768, 769, 770, 771, 772, 773, 775, 733,
+	776, 777, 778, 783, 784, 785, 897, 779, 780, 781,
+	782, 787, 898, 788, 789, 790, 791, 0, 792, 793,
+	0, 786, 774, 0, 794, 795, 796, 797, 798, 799,
+	800, 801, 802, 803, 0, 804, 899, 900, 901, 902,
+	0, 817, 0, 805, 807, 808, 809, 810, 903, 811,
+	812, 904, 0, 813, 814, 815, 816, 806, 819, 820,
+	818, 0, 0, 821, 822, 823, 824, 826, 828, 829,
+	830, 825, 827, 831, 0, 832, 0, 0, 833, 834,
+	835, 905, 906, 907, 0, 908, 838, 839, 836, 837,
+	840, 841, 844, 842, 843, 909, 847, 542, 848, 849,
+	850, 845, 846, 0, 0, 0, 0, 851, 852, 910,
+	853, 854, 855, 1654, 1653, 0, 0, 0, 0, 1838,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	367, 368, 370, 369, 371, 372, 373, 374, 0, 375,
+	376, 0, 0, 0, 0, 0, 856, 0, 0, 0,
+	378, 0, 377, 0, 379, 380, 381, 926, 382, 383,
+	384, 385, 386, 387, 388, 389, 390, 857, 391, 858,
+	0, 392, 859, 393, 860, 0, 861, 394, 395, 396,
+	397, 398, 399, 400, 401, 402, 403, 404, 0, 0,
+	0, 405, 862, 863, 864, 0, 406, 407, 408, 409,
+	865, 0, 927, 0, 410, 411, 412, 413, 414, 415,
+	416, 417, 0, 0, 419, 420, 421, 418, 422, 423,
+	0, 424, 0, 425, 426, 427, 428, 429, 0, 430,
+	431, 0, 432, 433, 434, 928, 435, 436, 437, 0,
+	0, 0, 0, 0, 0, 0, 438, 439, 440, 441,
+	442, 0, 443, 445, 866, 867, 0, 448, 450, 444,
+	446, 0, 449, 447, 451, 452, 0, 453, 454, 455,
+	456, 457, 0, 0, 0, 458, 459, 460, 461, 0,
+	462, 463, 464, 466, 465, 0, 467, 468, 469, 0,
+	470, 471, 868, 472, 473, 474, 476, 478, 475, 477,
+	479, 480, 481, 482, 483, 869, 870, 484, 485, 0,
+	362, 0, 0, 0, 0, 0, 486, 487, 488, 871,
+	0, 0, 0, 489, 0, 491, 495, 496, 492, 493,
+	494, 497, 0, 490, 498, 499, 0, 929, 500, 501,
+	502, 872, 873, 503, 504, 505, 506, 507, 508, 509,
+	510, 511, 0, 512, 513, 874, 0, 875, 514, 0,
+	515, 516, 517, 518, 519, 520, 521, 876, 877, 878,
+	630, 931, 522, 523, 524, 525, 0, 526, 527, 528,
+	529, 530, 531, 532, 0, 0, 0, 533, 534, 535,
+	536, 0, 0, 0, 0, 930, 879, 537, 631, 538,
+	539, 880, 881, 0, 882, 0, 540, 541, 544, 932,
+	883, 933, 543, 545, 546, 934, 547, 0, 0, 0,
+	548, 549, 550, 551, 552, 553, 554, 0, 555, 557,
+	556, 0, 559, 884, 558, 935, 560, 561, 936, 0,
+	562, 563, 564, 565, 566, 567, 572, 0, 0, 568,
+	569, 570, 571, 573, 574, 0, 575, 576, 578, 581,
+	577, 579, 580, 582, 583, 596, 597, 598, 584, 585,
+	586, 587, 588, 589, 590, 591, 592, 593, 594, 595,
+	600, 0, 599, 937, 0, 601, 602, 603, 604, 605,
+	606, 612, 615, 617, 618, 613, 614, 616, 619, 620,
+	621, 623, 624, 609, 610, 611, 938, 622, 607, 0,
+	608, 0, 939, 625, 626, 627, 628, 5831, 885, 629,
+	886, 632, 633, 0, 0, 634, 0, 635, 636, 0,
+	0, 638, 639, 640, 0, 0, 641, 642, 887, 940,
+	643, 941, 888, 644, 645, 637, 646, 647, 648, 649,
+	650, 651, 652, 653, 654, 655, 656, 657, 0, 658,
+	659, 889, 660, 661, 662, 663, 664, 890, 665, 666,
+	667, 891, 668, 892, 669, 670, 671, 0, 672, 673,
+	674, 0, 675, 676, 677, 678, 679, 680, 681, 682,
+	683, 684, 893, 685, 686, 688, 687, 689, 690, 0,
+	691, 692, 0, 693, 694, 695, 0, 0, 0, 0,
+	0, 696, 697, 699, 0, 700, 701, 702, 703, 704,
+	705, 698, 706, 707, 708, 709, 710, 711, 712, 713,
+	0, 715, 716, 714, 717, 718, 942, 719, 720, 721,
+	722, 723, 894, 724, 0, 725, 726, 734, 735, 736,
+	727, 728, 730, 737, 729, 738, 739, 740, 741, 743,
+	742, 0, 745, 746, 744, 747, 748, 749, 750, 0,
+	751, 895, 752, 731, 732, 753, 754, 755, 943, 756,
+	757, 758, 759, 760, 761, 762, 763, 764, 896, 0,
+	766, 0, 765, 767, 768, 769, 770, 771, 772, 773,
+	775, 733, 776, 777, 778, 783, 784, 785, 897, 779,
+	780, 781, 782, 787, 898, 788, 789, 790, 791, 0,
+	792, 793, 0, 786, 774, 0, 794, 795, 796, 797,
+	798, 799, 800, 801, 802, 803, 0, 804, 899, 900,
+	901, 902, 0, 817, 0, 805, 807, 808, 809, 810,
+	903, 811, 812, 904, 0, 813, 814, 815, 816, 806,
+	819, 820, 818, 0, 0, 821, 822, 823, 824, 826,
+	828, 829, 830, 825, 827, 831, 0, 832, 0, 0,
+	833, 834, 835, 905, 906, 907, 0, 908, 838, 839,
+	836, 837, 840, 841, 844, 842, 843, 909, 847, 542,
+	848, 849, 850, 845, 846, 0, 0, 0, 0, 851,
+	852, 910, 853, 854, 855, 1654, 1653, 0, 0, 0,
+	0, 1838, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 367, 368, 370, 369, 371, 372, 373, 374,
+	0, 375, 376, 0, 0, 0, 0, 0, 856, 0,
+	0, 0, 378, 0, 377, 0, 379, 380, 381, 926,
+	382, 383, 384, 385, 386, 387, 388, 389, 390, 857,
+	391, 858, 0, 392, 859, 393, 860, 0, 861, 394,
+	395, 396, 397, 398, 399, 400, 401, 402, 403, 404,
+	0, 0, 0, 405, 862, 863, 864, 0, 406, 407,
+	408, 409, 865, 0, 927, 0, 410, 411, 412, 413,
+	414, 415, 416, 417, 0, 0, 419, 420, 421, 418,
+	422, 423, 0, 424, 0, 425, 426, 427, 428, 429,
+	0, 430, 431, 0, 432, 433, 434, 928, 435, 436,
+	437, 0, 0, 0, 0, 0, 0, 0, 438, 439,
+	440, 441, 442, 0, 443, 445, 866, 867, 0, 448,
+	450, 444, 446, 0, 449, 447, 451, 452, 0, 453,
+	454, 455, 456, 457, 0, 0, 0, 458, 459, 460,
+	461, 0, 462, 463, 464, 466, 465, 0, 467, 468,
+	469, 0, 470, 471, 868, 472, 473, 474, 476, 478,
+	475, 477, 479, 480, 481, 482, 483, 869, 870, 484,
+	485, 0, 362, 0, 0, 0, 0, 0, 486, 487,
+	488, 871, 0, 0, 0, 489, 0, 491, 495, 496,
+	492, 493, 494, 497, 0, 490, 498, 499, 0, 929,
+	500, 501, 502, 872, 873, 503, 504, 505, 506, 507,
+	508, 509, 510, 511, 0, 512, 513, 874, 0, 875,
+	514, 0, 515, 516, 517, 518, 519, 520, 521, 876,
+	877, 878, 630, 931, 522, 523, 524, 525, 0, 526,
+	527, 528, 529, 530, 531, 532, 0, 0, 0, 533,
+	534, 535, 536, 0, 0, 0, 0, 930, 879, 537,
+	631, 538, 539, 880, 881, 0, 882, 0, 540, 541,
+	544, 932, 883, 933, 543, 545, 546, 934, 547, 0,
+	0, 0, 548, 549, 550, 551, 552, 553, 554, 0,
+	555, 557, 556, 0, 559, 884, 558, 935, 560, 561,
+	936, 0, 562, 563, 564, 565, 566, 567, 572, 0,
+	0, 568, 569, 570, 571, 573, 574, 0, 575, 576,
+	578, 581, 577, 579, 580, 582, 583, 596, 597, 598,
+	584, 585, 586, 587, 588, 589, 590, 591, 592, 593,
+	594, 595, 600, 0, 599, 937, 0, 601, 602, 603,
+	604, 605, 606, 612, 615, 617, 618, 613, 614, 616,
+	619, 620, 621, 623, 624, 609, 610, 611, 938, 622,
+	607, 0, 608, 0, 939, 625, 626, 627, 628, 5295,
+	885, 629, 886, 632, 633, 0, 0, 634, 0, 635,
+	636, 0, 0, 638, 639, 640, 0, 0, 641, 642,
+	887, 940, 643, 941, 888, 644, 645, 637, 646, 647,
+	648, 649, 650, 651, 652, 653, 654, 655, 656, 657,
+	0, 658, 659, 889, 660, 661, 662, 663, 664, 890,
+	665, 666, 667, 891, 668, 892, 669, 670, 671, 0,
+	672, 673, 674, 0, 675, 676, 677, 678, 679, 680,
+	681, 682, 683, 684, 893, 685, 686, 688, 687, 689,
+	690, 0, 691, 692, 0, 693, 694, 695, 0, 0,
+	0, 0, 0, 696, 697, 699, 0, 700, 701, 702,
+	703, 704, 705, 698, 706, 707, 708, 709, 710, 711,
+	712, 713, 0, 715, 716, 714, 717, 718, 942, 719,
+	720, 721, 722, 723, 894, 724, 0, 725, 726, 734,
+	735, 736, 727, 728, 730, 737, 729, 738, 739, 740,
+	741, 743, 742, 0, 745, 746, 744, 747, 748, 749,
+	750, 0, 751, 895, 752, 731, 732, 753, 754, 755,
+	943, 756, 757, 758, 759, 760, 761, 762, 763, 764,
+	896, 0, 766, 0, 765, 767, 768, 769, 770, 771,
+	772, 773, 775, 733, 776, 777, 778, 783, 784, 785,
+	897, 779, 780, 781, 782, 787, 898, 788, 789, 790,
+	791, 0, 792, 793, 0, 786, 774, 0, 794, 795,
+	796, 797, 798, 799, 800, 801, 802, 803, 0, 804,
+	899, 900, 901, 902, 0, 817, 0, 805, 807, 808,
+	809, 810, 903, 811, 812, 904, 0, 813, 814, 815,
+	816, 806, 819, 820, 818, 0, 0, 821, 822, 823,
+	824, 826, 828, 829, 830, 825, 827, 831, 0, 832,
+	0, 0, 833, 834, 835, 905, 906, 907, 0, 908,
+	838, 839, 836, 837, 840, 841, 844, 842, 843, 909,
+	847, 542, 848, 849, 850, 845, 846, 0, 0, 0,
+	0, 851, 852, 910, 853, 854, 855, 4723, 0, 1654,
+	1653, 0, 0, 0, 0, 1838, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 367, 368, 370, 369,
+	371, 372, 373, 374, 0, 375, 376, 0, 0, 0,
+	0, 0, 856, 0, 0, 0, 378, 0, 377, 0,
+	379, 380, 381, 926, 382, 383, 384, 385, 386, 387,
+	388, 389, 390, 857, 391, 858, 0, 392, 859, 393,
+	860, 0, 861, 394, 395, 396, 397, 398, 399, 400,
+	401, 402, 403, 404, 0, 0, 0, 405, 862, 863,
+	864, 0, 406, 407, 408, 409, 865, 0, 927, 0,
+	410, 411, 412, 413, 414, 415, 416, 417, 0, 0,
+	419, 420, 421, 418, 422, 423, 0, 424, 0, 425,
+	426, 427, 428, 429, 0, 430, 431, 0, 432, 433,
+	434, 928, 435, 436, 437, 0, 0, 0, 0, 0,
+	0, 0, 438, 439, 440, 441, 442, 0, 443, 445,
+	866, 867, 0, 448, 450, 444, 446, 0, 449, 447,
+	451, 452, 0, 453, 454, 455, 456, 457, 0, 0,
+	0, 458, 459, 460, 461, 0, 462, 463, 464, 466,
+	465, 0, 467, 468, 469, 0, 470, 471, 868, 472,
+	473, 474, 476, 478, 475, 477, 479, 480, 481, 482,
+	483, 869, 870, 484, 485, 0, 362, 0, 0, 0,
+	0, 0, 486, 487, 488, 871, 0, 0, 0, 489,
+	0, 491, 495, 496, 492, 493, 494, 497, 0, 490,
+	498, 499, 0, 929, 500, 501, 502, 872, 873, 503,
+	504, 505, 506, 507, 508, 509, 510, 511, 0, 512,
+	513, 874, 0, 875, 514, 0, 515, 516, 517, 518,
+	519, 520, 521, 876, 877, 878, 630, 931, 522, 523,
+	524, 525, 0, 526, 527, 528, 529, 530, 531, 532,
+	0, 0, 0, 533, 534, 535, 536, 0, 0, 0,
+	0, 930, 879, 537, 631, 538, 539, 880, 881, 0,
+	882, 0, 540, 541, 544, 932, 883, 933, 543, 545,
+	546, 934, 547, 0, 0, 0, 548, 549, 550, 551,
+	552, 553, 554, 0, 555, 557, 556, 0, 559, 884,
+	558, 935, 560, 561, 936, 0, 562, 563, 564, 565,
+	566, 567, 572, 0, 0, 568, 569, 570, 571, 573,
+	574, 0, 575, 576, 578, 581, 577, 579, 580, 582,
+	583, 596, 597, 598, 584, 585, 586, 587, 588, 589,
+	590, 591, 592, 593, 594, 595, 600, 0, 599, 937,
+	0, 601, 602, 603, 604, 605, 606, 612, 615, 617,
+	618, 613, 614, 616, 619, 620, 621, 623, 624, 609,
+	610, 611, 938, 622, 607, 0, 608, 0, 939, 625,
+	626, 627, 628, 0, 885, 629, 886, 632, 633, 0,
+	0, 634, 0, 635, 636, 0, 0, 638, 639, 640,
+	0, 0, 641, 642, 887, 940, 643, 941, 888, 644,
+	645, 637, 646, 647, 648, 649, 650, 651, 652, 653,
+	654, 655, 656, 657, 0, 658, 659, 889, 660, 661,
+	662, 663, 664, 890, 665, 666, 667, 891, 668, 892,
+	669, 670, 671, 0, 672, 673, 674, 0, 675, 676,
+	677, 678, 679, 680, 681, 682, 683, 684, 893, 685,
+	686, 688, 687, 689, 690, 0, 691, 692, 0, 693,
+	694, 695, 0, 0, 0, 0, 0, 696, 697, 699,
+	0, 700, 701, 702, 703, 704, 705, 698, 706, 707,
+	708, 709, 710, 711, 712, 713, 0, 715, 716, 714,
+	717, 718, 942, 719, 720, 721, 722, 723, 894, 724,
+	0, 725, 726, 734, 735, 736, 727, 728, 730, 737,
+	729, 738, 739, 740, 741, 743, 742, 0, 745, 746,
+	744, 747, 748, 749, 750, 0, 751, 895, 752, 731,
+	732, 753, 754, 755, 943, 756, 757, 758, 759, 760,
+	761, 762, 763, 764, 896, 0, 766, 0, 765, 767,
+	768, 769, 770, 771, 772, 773, 775, 733, 776, 777,
+	778, 783, 784, 785, 897, 779, 780, 781, 782, 787,
+	898, 788, 789, 790, 791, 0, 792, 793, 0, 786,
+	774, 0, 794, 795, 796, 797, 798, 799, 800, 801,
+	802, 803, 0, 804, 899, 900, 901, 902, 0, 817,
+	0, 805, 807, 808, 809, 810, 903, 811, 812, 904,
+	0, 813, 814, 815, 816, 806, 819, 820, 818, 0,
+	0, 821, 822, 823, 824, 826, 828, 829, 830, 825,
+	827, 831, 0, 832, 0, 0, 833, 834, 835, 905,
+	906, 907, 0, 908, 838, 839, 836, 837, 840, 841,
+	844, 842, 843, 909, 847, 542, 848, 849, 850, 845,
+	846, 0, 0, 0, 0, 851, 852, 910, 853, 854,
+	855, 4365, 0, 1654, 1653, 0, 0, 0, 0, 1838,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	367, 368, 370, 369, 371, 372, 373, 374, 0, 375,
+	376, 0, 0, 0, 0, 0, 856, 0, 0, 0,
+	378, 0, 377, 0, 379, 380, 381, 926, 382, 383,
+	384, 385, 386, 387, 388, 389, 390, 857, 391, 858,
+	0, 392, 859, 393, 860, 0, 861, 394, 395, 396,
+	397, 398, 399, 400, 401, 402, 403, 404, 0, 0,
+	0, 405, 862, 863, 864, 0, 406, 407, 408, 409,
+	865, 0, 927, 0, 410, 411, 412, 413, 414, 415,
+	416, 417, 0, 0, 419, 420, 421, 418, 422, 423,
+	0, 424, 0, 425, 426, 427, 428, 429, 0, 430,
+	431, 0, 432, 433, 434, 928, 435, 436, 437, 0,
+	0, 0, 0, 0, 0, 0, 438, 439, 440, 441,
+	442, 0, 443, 445, 866, 867, 0, 448, 450, 444,
+	446, 0, 449, 447, 451, 452, 0, 453, 454, 455,
+	456, 457, 0, 0, 0, 458, 459, 460, 461, 0,
+	462, 463, 464, 466, 465, 0, 467, 468, 469, 0,
+	470, 471, 868, 472, 473, 474, 476, 478, 475, 477,
+	479, 480, 481, 482, 483, 869, 870, 484, 485, 0,
+	362, 0, 0, 0, 0, 0, 486, 487, 488, 871,
+	0, 0, 0, 489, 0, 491, 495, 496, 492, 493,
+	494, 497, 0, 490, 498, 499, 0, 929, 500, 501,
+	502, 872, 873, 503, 504, 505, 506, 507, 508, 509,
+	510, 511, 0, 512, 513, 874, 0, 875, 514, 0,
+	515, 516, 517, 518, 519, 520, 521, 876, 877, 878,
+	630, 931, 522, 523, 524, 525, 0, 526, 527, 528,
+	529, 530, 531, 532, 0, 0, 0, 533, 534, 535,
+	536, 0, 0, 0, 0, 930, 879, 537, 631, 538,
+	539, 880, 881, 0, 882, 0, 540, 541, 544, 932,
+	883, 933, 543, 545, 546, 934, 547, 0, 0, 0,
+	548, 549, 550, 551, 552, 553, 554, 0, 555, 557,
+	556, 0, 559, 884, 558, 935, 560, 561, 936, 0,
+	562, 563, 564, 565, 566, 567, 572, 0, 0, 568,
+	569, 570, 571, 573, 574, 0, 575, 576, 578, 581,
+	577, 579, 580, 582, 583, 596, 597, 598, 584, 585,
+	586, 587, 588, 589, 590, 591, 592, 593, 594, 595,
+	600, 0, 599, 937, 0, 601, 602, 603, 604, 605,
+	606, 612, 615, 617, 618, 613, 614, 616, 619, 620,
+	621, 623, 624, 609, 610, 611, 938, 622, 607, 0,
+	608, 0, 939, 625, 626, 627, 628, 0, 885, 629,
+	886, 632, 633, 0, 0, 634, 0, 635, 636, 0,
+	0, 638, 639, 640, 0, 0, 641, 642, 887, 940,
+	643, 941, 888, 644, 645, 637, 646, 647, 648, 649,
+	650, 651, 652, 653, 654, 655, 656, 657, 0, 658,
+	659, 889, 660, 661, 662, 663, 664, 890, 665, 666,
+	667, 891, 668, 892, 669, 670, 671, 0, 672, 673,
+	674, 0, 675, 676, 677, 678, 679, 680, 681, 682,
+	683, 684, 893, 685, 686, 688, 687, 689, 690, 0,
+	691, 692, 0, 693, 694, 695, 0, 0, 0, 0,
+	0, 696, 697, 699, 0, 700, 701, 702, 703, 704,
+	705, 698, 706, 707, 708, 709, 710, 711, 712, 713,
+	0, 715, 716, 714, 717, 718, 942, 719, 720, 721,
+	722, 723, 894, 724, 0, 725, 726, 734, 735, 736,
+	727, 728, 730, 737, 729, 738, 739, 740, 741, 743,
+	742, 0, 745, 746, 744, 747, 748, 749, 750, 0,
+	751, 895, 752, 731, 732, 753, 754, 755, 943, 756,
+	757, 758, 759, 760, 761, 762, 763, 764, 896, 0,
+	766, 0, 765, 767, 768, 769, 770, 771, 772, 773,
+	775, 733, 776, 777, 778, 783, 784, 785, 897, 779,
+	780, 781, 782, 787, 898, 788, 789, 790, 791, 0,
+	792, 793, 0, 786, 774, 0, 794, 795, 796, 797,
+	798, 799, 800, 801, 802, 803, 0, 804, 899, 900,
+	901, 902, 0, 817, 0, 805, 807, 808, 809, 810,
+	903, 811, 812, 904, 0, 813, 814, 815, 816, 806,
+	819, 820, 818, 0, 0, 821, 822, 823, 824, 826,
+	828, 829, 830, 825, 827, 831, 0, 832, 0, 0,
+	833, 834, 835, 905, 906, 907, 0, 908, 838, 839,
+	836, 837, 840, 841, 844, 842, 843, 909, 847, 542,
+	848, 849, 850, 845, 846, 0, 0, 0, 0, 851,
+	852, 910, 853, 854, 855, 3145, 0, 1654, 1653, 0,
+	0, 0, 0, 1838, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 367, 368, 370, 369, 371, 372,
+	373, 374, 0, 375, 376, 0, 0, 0, 0, 0,
+	856, 0, 0, 0, 378, 0, 377, 0, 379, 380,
+	381, 926, 382, 383, 384, 385, 386, 387, 388, 389,
+	390, 857, 391, 858, 0, 392, 859, 393, 860, 0,
+	861, 394, 395, 396, 397, 398, 399, 400, 401, 402,
+	403, 404, 0, 0, 0, 405, 862, 863, 864, 0,
+	406, 407, 408, 409, 865, 0, 927, 0, 410, 411,
+	412, 413, 414, 415, 416, 417, 0, 0, 419, 420,
+	421, 418, 422, 423, 0, 424, 0, 425, 426, 427,
+	428, 429, 0, 430, 431, 0, 432, 433, 434, 928,
+	435, 436, 437, 0, 0, 0, 0, 0, 0, 0,
+	438, 439, 440, 441, 442, 0, 443, 445, 866, 867,
+	0, 448, 450, 444, 446, 0, 449, 447, 451, 452,
+	0, 453, 454, 455, 456, 457, 0, 0, 0, 458,
+	459, 460, 461, 0, 462, 463, 464, 466, 465, 0,
+	467, 468, 469, 0, 470, 471, 868, 472, 473, 474,
+	476, 478, 475, 477, 479, 480, 481, 482, 483, 869,
+	870, 484, 485, 0, 362, 0, 0, 0, 0, 0,
+	486, 487, 488, 871, 0, 0, 0, 489, 0, 491,
+	495, 496, 492, 493, 494, 497, 0, 490, 498, 499,
+	0, 929, 500, 501, 502, 872, 873, 503, 504, 505,
+	506, 507, 508, 509, 510, 511, 0, 512, 513, 874,
+	0, 875, 514, 0, 515, 516, 517, 518, 519, 520,
+	521, 876, 877, 878, 630, 931, 522, 523, 524, 525,
+	0, 526, 527, 528, 529, 530, 531, 532, 0, 0,
+	0, 533, 534, 535, 536, 0, 0, 0, 0, 930,
+	879, 537, 631, 538, 539, 880, 881, 0, 882, 0,
+	540, 541, 544, 932, 883, 933, 543, 545, 546, 934,
+	547, 0, 0, 0, 548, 549, 550, 551, 552, 553,
+	554, 0, 555, 557, 556, 0, 559, 884, 558, 935,
+	560, 561, 936, 0, 562, 563, 564, 565, 566, 567,
+	572, 0, 0, 568, 569, 570, 571, 573, 574, 0,
+	575, 576, 578, 581, 577, 579, 580, 582, 583, 596,
+	597, 598, 584, 585, 586, 587, 588, 589, 590, 591,
+	592, 593, 594, 595, 600, 0, 599, 937, 0, 601,
+	602, 603, 604, 605, 606, 612, 615, 617, 618, 613,
+	614, 616, 619, 620, 621, 623, 624, 609, 610, 611,
+	938, 622, 607, 0, 608, 0, 939, 625, 626, 627,
+	628, 0, 885, 629, 886, 632, 633, 0, 0, 634,
+	0, 635, 636, 0, 0, 638, 639, 640, 0, 0,
+	641, 642, 887, 940, 643, 941, 888, 644, 645, 637,
+	646, 647, 648, 649, 650, 651, 652, 653, 654, 655,
+	656, 657, 0, 658, 659, 889, 660, 661, 662, 663,
+	664, 890, 665, 666, 667, 891, 668, 892, 669, 670,
+	671, 0, 672, 673, 674, 0, 675, 676, 677, 678,
+	679, 680, 681, 682, 683, 684, 893, 685, 686, 688,
+	687, 689, 690, 0, 691, 692, 0, 693, 694, 695,
+	0, 0, 0, 0, 0, 696, 697, 699, 0, 700,
+	701, 702, 703, 704, 705, 698, 706, 707, 708, 709,
+	710, 711, 712, 713, 0, 715, 716, 714, 717, 718,
+	942, 719, 720, 721, 722, 723, 894, 724, 0, 725,
+	726, 734, 735, 736, 727, 728, 730, 737, 729, 738,
+	739, 740, 741, 743, 742, 0, 745, 746, 744, 747,
+	748, 749, 750, 0, 751, 895, 752, 731, 732, 753,
+	754, 755, 943, 756, 757, 758, 759, 760, 761, 762,
+	763, 764, 896, 0, 766, 0, 765, 767, 768, 769,
+	770, 771, 772, 773, 775, 733, 776, 777, 778, 783,
+	784, 785, 897, 779, 780, 781, 782, 787, 898, 788,
+	789, 790, 791, 0, 792, 793, 0, 786, 774, 0,
+	794, 795, 796, 797, 798, 799, 800, 801, 802, 803,
+	0, 804, 899, 900, 901, 902, 0, 817, 0, 805,
+	807, 808, 809, 810, 903, 811, 812, 904, 0, 813,
+	814, 815, 816, 806, 819, 820, 818, 0, 0, 821,
+	822, 823, 824, 826, 828, 829, 830, 825, 827, 831,
+	0, 832, 0, 0, 833, 834, 835, 905, 906, 907,
+	0, 908, 838, 839, 836, 837, 840, 841, 844, 842,
+	843, 909, 847, 542, 848, 849, 850, 845, 846, 0,
+	0, 0, 0, 851, 852, 910, 853, 854, 855, 3120,
+	0, 1654, 1653, 0, 0, 0, 0, 1838, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 367, 368,
+	370, 369, 371, 372, 373, 374, 0, 375, 376, 0,
+	0, 0, 0, 0, 856, 0, 0, 0, 378, 0,
+	377, 0, 379, 380, 381, 926, 382, 383, 384, 385,
+	386, 387, 388, 389, 390, 857, 391, 858, 0, 392,
+	859, 393, 860, 0, 861, 394, 395, 396, 397, 398,
+	399, 400, 401, 402, 403, 404, 0, 0, 0, 405,
+	862, 863, 864, 0, 406, 407, 408, 409, 865, 0,
+	927, 0, 410, 411, 412, 413, 414, 415, 416, 417,
+	0, 0, 419, 420, 421, 418, 422, 423, 0, 424,
+	0, 425, 426, 427, 428, 429, 0, 430, 431, 0,
+	432, 433, 434, 928, 435, 436, 437, 0, 0, 0,
+	0, 0, 0, 0, 438, 439, 440, 441, 442, 0,
+	443, 445, 866, 867, 0, 448, 450, 444, 446, 0,
+	449, 447, 451, 452, 0, 453, 454, 455, 456, 457,
+	0, 0, 0, 458, 459, 460, 461, 0, 462, 463,
+	464, 466, 465, 0, 467, 468, 469, 0, 470, 471,
+	868, 472, 473, 474, 476, 478, 475, 477, 479, 480,
+	481, 482, 483, 869, 870, 484, 485, 0, 362, 0,
+	0, 0, 0, 0, 486, 487, 488, 871, 0, 0,
+	0, 489, 0, 491, 495, 496, 492, 493, 494, 497,
+	0, 490, 498, 499, 0, 929, 500, 501, 502, 872,
+	873, 503, 504, 505, 506, 507, 508, 509, 510, 511,
+	0, 512, 513, 874, 0, 875, 514, 0, 515, 516,
+	517, 518, 519, 520, 521, 876, 877, 878, 630, 931,
+	522, 523, 524, 525, 0, 526, 527, 528, 529, 530,
+	531, 532, 0, 0, 0, 533, 534, 535, 536, 0,
+	0, 0, 0, 930, 879, 537, 631, 538, 539, 880,
+	881, 0, 882, 0, 540, 541, 544, 932, 883, 933,
+	543, 545, 546, 934, 547, 0, 0, 0, 548, 549,
+	550, 551, 552, 553, 554, 0, 555, 557, 556, 0,
+	559, 884, 558, 935, 560, 561, 936, 0, 562, 563,
+	564, 565, 566, 567, 572, 0, 0, 568, 569, 570,
+	571, 573, 574, 0, 575, 576, 578, 581, 577, 579,
+	580, 582, 583, 596, 597, 598, 584, 585, 586, 587,
+	588, 589, 590, 591, 592, 593, 594, 595, 600, 0,
+	599, 937, 0, 601, 602, 603, 604, 605, 606, 612,
+	615, 617, 618, 613, 614, 616, 619, 620, 621, 623,
+	624, 609, 610, 611, 938, 622, 607, 0, 608, 0,
+	939, 625, 626, 627, 628, 0, 885, 629, 886, 632,
+	633, 0, 0, 634, 0, 635, 636, 0, 0, 638,
+	639, 640, 0, 0, 641, 642, 887, 940, 643, 941,
+	888, 644, 645, 637, 646, 647, 648, 649, 650, 651,
+	652, 653, 654, 655, 656, 657, 0, 658, 659, 889,
+	660, 661, 662, 663, 664, 890, 665, 666, 667, 891,
+	668, 892, 669, 670, 671, 0, 672, 673, 674, 0,
+	675, 676, 677, 678, 679, 680, 681, 682, 683, 684,
+	893, 685, 686, 688, 687, 689, 690, 0, 691, 692,
+	0, 693, 694, 695, 0, 0, 0, 0, 0, 696,
+	697, 699, 0, 700, 701, 702, 703, 704, 705, 698,
+	706, 707, 708, 709, 710, 711, 712, 713, 0, 715,
+	716, 714, 717, 718, 942, 719, 720, 721, 722, 723,
+	894, 724, 0, 725, 726, 734, 735, 736, 727, 728,
+	730, 737, 729, 738, 739, 740, 741, 743, 742, 0,
+	745, 746, 744, 747, 748, 749, 750, 0, 751, 895,
+	752, 731, 732, 753, 754, 755, 943, 756, 757, 758,
+	759, 760, 761, 762, 763, 764, 896, 0, 766, 0,
+	765, 767, 768, 769, 770, 771, 772, 773, 775, 733,
+	776, 777, 778, 783, 784, 785, 897, 779, 780, 781,
+	782, 787, 898, 788, 789, 790, 791, 0, 792, 793,
+	0, 786, 774, 0, 794, 795, 796, 797, 798, 799,
+	800, 801, 802, 803, 0, 804, 899, 900, 901, 902,
+	0, 817, 0, 805, 807, 808, 809, 810, 903, 811,
+	812, 904, 0, 813, 814, 815, 816, 806, 819, 820,
+	818, 0, 0, 821, 822, 823, 824, 826, 828, 829,
+	830, 825, 827, 831, 0, 832, 0, 0, 833, 834,
+	835, 905, 906, 907, 0, 908, 838, 839, 836, 837,
+	840, 841, 844, 842, 843, 909, 847, 542, 848, 849,
+	850, 845, 846, 0, 0, 0, 0, 851, 852, 910,
+	853, 854, 855, 3059, 0, 1654, 1653, 0, 0, 0,
+	0, 1838, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 367, 368, 370, 369, 371, 372, 373, 374,
+	0, 375, 376, 0, 0, 0, 0, 0, 856, 0,
+	0, 0, 378, 0, 377, 0, 379, 380, 381, 926,
+	382, 383, 384, 385, 386, 387, 388, 389, 390, 857,
+	391, 858, 0, 392, 859, 393, 860, 0, 861, 394,
+	395, 396, 397, 398, 399, 400, 401, 402, 403, 404,
+	0, 0, 0, 405, 862, 863, 864, 0, 406, 407,
+	408, 409, 865, 0, 927, 0, 410, 411, 412, 413,
+	414, 415, 416, 417, 0, 0, 419, 420, 421, 418,
+	422, 423, 0, 424, 0, 425, 426, 427, 428, 429,
+	0, 430, 431, 0, 432, 433, 434, 928, 435, 436,
+	437, 0, 0, 0, 0, 0, 0, 0, 438, 439,
+	440, 441, 442, 0, 443, 445, 866, 867, 0, 448,
+	450, 444, 446, 0, 449, 447, 451, 452, 0, 453,
+	454, 455, 456, 457, 0, 0, 0, 458, 459, 460,
+	461, 0, 462, 463, 464, 466, 465, 0, 467, 468,
+	469, 0, 470, 471, 868, 472, 473, 474, 476, 478,
+	475, 477, 479, 480, 481, 482, 483, 869, 870, 484,
+	485, 0, 362, 0, 0, 0, 0, 0, 486, 487,
+	488, 871, 0, 0, 0, 489, 0, 491, 495, 496,
+	492, 493, 494, 497, 0, 490, 498, 499, 0, 929,
+	500, 501, 502, 872, 873, 503, 504, 505, 506, 507,
+	508, 509, 510, 511, 0, 512, 513, 874, 0, 875,
+	514, 0, 515, 516, 517, 518, 519, 520, 521, 2152,
+	877, 878, 630, 931, 522, 523, 524, 525, 0, 526,
+	527, 528, 529, 530, 531, 532, 0, 0, 0, 533,
+	534, 535, 536, 0, 0, 0, 0, 930, 879, 537,
+	631, 538, 539, 880, 881, 0, 882, 0, 540, 541,
+	544, 932, 883, 933, 543, 545, 546, 934, 547, 0,
+	0, 0, 548, 549, 550, 551, 552, 553, 554, 0,
+	555, 557, 556, 0, 559, 884, 558, 935, 560, 561,
+	936, 0, 562, 563, 564, 565, 566, 567, 572, 0,
+	0, 568, 569, 570, 571, 573, 574, 0, 575, 576,
+	578, 581, 577, 579, 580, 582, 583, 596, 597, 598,
+	584, 585, 586, 587, 588, 589, 590, 591, 592, 593,
+	594, 595, 600, 0, 599, 937, 0, 601, 602, 603,
+	604, 605, 606, 612, 615, 617, 618, 613, 614, 616,
+	619, 620, 621, 623, 624, 609, 610, 611, 938, 622,
+	607, 0, 608, 0, 939, 625, 626, 627, 628, 0,
+	885, 629, 886, 632, 633, 0, 0, 634, 0, 635,
+	636, 0, 0, 638, 639, 640, 0, 0, 641, 642,
+	887, 940, 643, 941, 888, 644, 645, 637, 646, 647,
+	648, 649, 650, 651, 652, 653, 654, 655, 656, 657,
+	0, 658, 659, 889, 660, 661, 662, 663, 664, 890,
+	665, 666, 667, 891, 668, 892, 669, 670, 671, 0,
+	672, 673, 674, 0, 675, 676, 677, 678, 679, 680,
+	681, 682, 683, 684, 893, 685, 686, 688, 687, 689,
+	690, 0, 691, 692, 0, 693, 694, 695, 0, 0,
+	0, 0, 0, 696, 697, 699, 0, 700, 701, 702,
+	703, 704, 705, 698, 706, 707, 708, 709, 710, 711,
+	712, 713, 0, 715, 716, 714, 717, 718, 942, 719,
+	720, 721, 722, 723, 894, 724, 0, 725, 726, 734,
+	735, 736, 727, 728, 730, 737, 729, 738, 739, 740,
+	741, 743, 742, 0, 745, 746, 744, 747, 748, 749,
+	750, 0, 751, 895, 752, 731, 732, 753, 754, 755,
+	943, 756, 757, 758, 759, 760, 761, 762, 763, 764,
+	896, 0, 766, 0, 765, 767, 768, 769, 770, 771,
+	772, 773, 775, 733, 776, 777, 778, 783, 784, 785,
+	897, 779, 780, 781, 782, 787, 898, 788, 789, 790,
+	791, 0, 792, 793, 0, 786, 774, 0, 794, 795,
+	796, 797, 798, 799, 800, 801, 802, 803, 0, 804,
+	899, 900, 901, 902, 0, 817, 0, 805, 807, 808,
+	809, 810, 903, 811, 812, 904, 0, 813, 814, 815,
+	816, 806, 819, 820, 818, 0, 0, 821, 822, 823,
+	824, 826, 828, 829, 830, 825, 827, 831, 0, 832,
+	0, 0, 833, 834, 835, 905, 906, 907, 0, 908,
+	838, 839, 836, 837, 840, 841, 844, 842, 843, 909,
+	847, 542, 848, 849, 850, 845, 846, 0, 0, 0,
+	0, 851, 852, 910, 853, 854, 855, 2758, 0, 1654,
+	1653, 0, 0, 0, 0, 1838, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 367, 368, 370, 369,
+	371, 372, 373, 374, 0, 375, 376, 0, 0, 0,
+	0, 0, 856, 0, 0, 0, 378, 0, 377, 0,
+	379, 380, 381, 926, 382, 383, 384, 385, 386, 387,
+	388, 389, 390, 857, 391, 858, 0, 392, 859, 393,
+	860, 0, 861, 394, 395, 396, 397, 398, 399, 400,
+	401, 402, 403, 404, 0, 0, 0, 405, 862, 863,
+	864, 0, 406, 407, 408, 409, 865, 0, 927, 0,
+	410, 411, 412, 413, 414, 415, 416, 417, 0, 0,
+	419, 420, 421, 418, 422, 423, 0, 424, 0, 425,
+	426, 427, 428, 429, 0, 430, 431, 0, 432, 433,
+	434, 928, 435, 436, 437, 0, 0, 0, 0, 0,
+	0, 0, 438, 439, 440, 441, 442, 0, 443, 445,
+	866, 867, 0, 448, 450, 444, 446, 0, 449, 447,
+	451, 452, 0, 453, 454, 455, 456, 457, 0, 0,
+	0, 458, 459, 460, 461, 0, 462, 463, 464, 466,
+	465, 0, 467, 468, 469, 0, 470, 471, 868, 472,
+	473, 474, 476, 478, 475, 477, 479, 480, 481, 482,
+	483, 869, 870, 484, 485, 0, 362, 0, 0, 0,
+	0, 0, 486, 487, 488, 871, 0, 0, 0, 489,
+	0, 491, 495, 496, 492, 493, 494, 497, 0, 490,
+	498, 499, 0, 929, 500, 501, 502, 872, 873, 503,
+	504, 505, 506, 507, 508, 509, 510, 511, 0, 512,
+	513, 874, 0, 875, 514, 0, 515, 516, 517, 518,
+	519, 520, 521, 876, 877, 878, 630, 931, 522, 523,
+	524, 525, 0, 526, 527, 528, 529, 530, 531, 532,
+	0, 0, 0, 533, 534, 535, 536, 0, 0, 0,
+	0, 930, 879, 537, 631, 538, 539, 880, 881, 0,
+	882, 0, 540, 541, 544, 932, 883, 933, 543, 545,
+	546, 934, 547, 0, 0, 0, 548, 549, 550, 551,
+	552, 553, 554, 0, 555, 557, 556, 0, 559, 884,
+	558, 935, 560, 561, 936, 0, 562, 563, 564, 565,
+	566, 567, 572, 0, 0, 568, 569, 570, 571, 573,
+	574, 0, 575, 576, 578, 581, 577, 579, 580, 582,
+	583, 596, 597, 598, 584, 585, 586, 587, 588, 589,
+	590, 591, 592, 593, 594, 595, 600, 0, 599, 937,
+	0, 601, 602, 603, 604, 605, 606, 612, 615, 617,
+	618, 613, 614, 616, 619, 620, 621, 623, 624, 609,
+	610, 611, 938, 622, 607, 0, 608, 0, 939, 625,
+	626, 627, 628, 0, 885, 629, 886, 632, 633, 0,
+	0, 634, 0, 635, 636, 0, 0, 638, 639, 640,
+	0, 0, 641, 642, 887, 940, 643, 941, 888, 644,
+	645, 637, 646, 647, 648, 649, 650, 651, 652, 653,
+	654, 655, 656, 657, 0, 658, 659, 889, 660, 661,
+	662, 663, 664, 890, 665, 666, 667, 891, 668, 892,
+	669, 670, 671, 0, 672, 673, 674, 0, 675, 676,
+	677, 678, 679, 680, 681, 682, 683, 684, 893, 685,
+	686, 688, 687, 689, 690, 0, 691, 692, 0, 693,
+	694, 695, 0, 0, 0, 0, 0, 696, 697, 699,
+	0, 700, 701, 702, 703, 704, 705, 698, 706, 707,
+	708, 709, 710, 711, 712, 713, 0, 715, 716, 714,
+	717, 718, 942, 719, 720, 721, 722, 723, 894, 724,
+	0, 725, 726, 734, 735, 736, 727, 728, 730, 737,
+	729, 738, 739, 740, 741, 743, 742, 0, 745, 746,
+	744, 747, 748, 749, 750, 0, 751, 895, 752, 731,
+	732, 753, 754, 755, 943, 756, 757, 758, 759, 760,
+	761, 762, 763, 764, 896, 0, 766, 0, 765, 767,
+	768, 769, 770, 771, 772, 773, 775, 733, 776, 777,
+	778, 783, 784, 785, 897, 779, 780, 781, 782, 787,
+	898, 788, 789, 790, 791, 0, 792, 793, 0, 786,
+	774, 0, 794, 795, 796, 797, 798, 799, 800, 801,
+	802, 803, 0, 804, 899, 900, 901, 902, 0, 817,
+	0, 805, 807, 808, 809, 810, 903, 811, 812, 904,
+	0, 813, 814, 815, 816, 806, 819, 820, 818, 0,
+	0, 821, 822, 823, 824, 826, 828, 829, 830, 825,
+	827, 831, 0, 832, 0, 0, 833, 834, 835, 905,
+	906, 907, 0, 908, 838, 839, 836, 837, 840, 841,
+	844, 842, 843, 909, 847, 542, 848, 849, 850, 845,
+	846, 0, 0, 0, 0, 851, 852, 910, 853, 854,
+	855, 2613, 0, 1654, 1653, 0, 0, 0, 0, 1838,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	367, 368, 370, 369, 371, 372, 373, 374, 0, 375,
+	376, 0, 0, 0, 0, 0, 856, 0, 0, 0,
+	378, 0, 377, 0, 379, 380, 381, 926, 382, 383,
+	384, 385, 386, 387, 388, 389, 390, 857, 391, 858,
+	0, 392, 859, 393, 860, 0, 861, 394, 395, 396,
+	397, 398, 399, 400, 401, 402, 403, 404, 0, 0,
+	0, 405, 862, 863, 864, 0, 406, 407, 408, 409,
+	865, 0, 927, 0, 410, 411, 412, 413, 414, 415,
+	416, 417, 0, 0, 419, 420, 421, 418, 422, 423,
+	0, 424, 0, 425, 426, 427, 428, 429, 0, 430,
+	431, 0, 432, 433, 434, 928, 435, 436, 437, 0,
+	0, 0, 0, 0, 0, 0, 438, 439, 440, 441,
+	442, 0, 443, 445, 866, 867, 0, 448, 450, 444,
+	446, 0, 449, 447, 451, 452, 0, 453, 454, 455,
+	456, 457, 0, 0, 0, 458, 459, 460, 461, 0,
+	462, 463, 464, 466, 465, 0, 467, 468, 469, 0,
+	470, 471, 868, 472, 473, 474, 476, 478, 475, 477,
+	479, 480, 481, 482, 483, 869, 870, 484, 485, 0,
+	362, 0, 0, 0, 0, 0, 486, 487, 488, 871,
+	0, 0, 0, 489, 0, 491, 495, 496, 492, 493,
+	494, 497, 0, 490, 498, 499, 0, 929, 500, 501,
+	502, 872, 873, 503, 504, 505, 506, 507, 508, 509,
+	510, 511, 0, 512, 513, 874, 0, 875, 514, 0,
+	515, 516, 517, 518, 519, 520, 521, 876, 877, 878,
+	630, 931, 522, 523, 524, 525, 0, 526, 527, 528,
+	529, 530, 531, 532, 0, 0, 0, 533, 534, 535,
+	536, 0, 0, 0, 0, 930, 879, 537, 631, 538,
+	539, 880, 881, 0, 882, 0, 540, 541, 544, 932,
+	883, 933, 543, 545, 546, 934, 547, 0, 0, 0,
+	548, 549, 550, 551, 552, 553, 554, 0, 555, 557,
+	556, 0, 559, 884, 558, 935, 560, 561, 936, 0,
+	562, 563, 564, 565, 566, 567, 572, 0, 0, 568,
+	569, 570, 571, 573, 574, 0, 575, 576, 578, 581,
+	577, 579, 580, 582, 583, 596, 597, 598, 584, 585,
+	586, 587, 588, 589, 590, 591, 592, 593, 594, 595,
+	600, 0, 599, 937, 0, 601, 602, 603, 604, 605,
+	606, 612, 615, 617, 618, 613, 614, 616, 619, 620,
+	621, 623, 624, 609, 610, 611, 938, 622, 607, 0,
+	608, 0, 939, 625, 626, 627, 628, 0, 885, 629,
+	886, 632, 633, 0, 0, 634, 0, 635, 636, 0,
+	0, 638, 639, 640, 0, 0, 641, 642, 887, 940,
+	643, 941, 888, 644, 645, 637, 646, 647, 648, 649,
+	650, 651, 652, 653, 654, 655, 656, 657, 0, 658,
+	659, 889, 660, 661, 662, 663, 664, 890, 665, 666,
+	667, 891, 668, 892, 669, 670, 671, 0, 672, 673,
+	674, 0, 675, 676, 677, 678, 679, 680, 681, 682,
+	683, 684, 893, 685, 686, 688, 687, 689, 690, 0,
+	691, 692, 0, 693, 694, 695, 0, 0, 0, 0,
+	0, 696, 697, 699, 0, 700, 701, 702, 703, 704,
+	705, 698, 706, 707, 708, 709, 710, 711, 712, 713,
+	0, 715, 716, 714, 717, 718, 942, 719, 720, 721,
+	722, 723, 894, 724, 0, 725, 726, 734, 735, 736,
+	727, 728, 730, 737, 729, 738, 739, 740, 741, 743,
+	742, 0, 745, 746, 744, 747, 748, 749, 750, 0,
+	751, 895, 752, 731, 732, 753, 754, 755, 943, 756,
+	757, 758, 759, 760, 761, 762, 763, 764, 896, 0,
+	766, 0, 765, 767, 768, 769, 770, 771, 772, 773,
+	775, 733, 776, 777, 778, 783, 784, 785, 897, 779,
+	780, 781, 782, 787, 898, 788, 789, 790, 791, 0,
+	792, 793, 0, 786, 774, 0, 794, 795, 796, 797,
+	798, 799, 800, 801, 802, 803, 0, 804, 899, 900,
+	901, 902, 0, 817, 0, 805, 807, 808, 809, 810,
+	903, 811, 812, 904, 0, 813, 814, 815, 816, 806,
+	819, 820, 818, 0, 0, 821, 822, 823, 824, 826,
+	828, 829, 830, 825, 827, 831, 0, 832, 0, 0,
+	833, 834, 835, 905, 906, 907, 0, 908, 838, 839,
+	836, 837, 840, 841, 844, 842, 843, 909, 847, 542,
+	848, 849, 850, 845, 846, 0, 0, 0, 0, 851,
+	852, 910, 853, 854, 855, 2258, 0, 1654, 1653, 0,
+	0, 0, 0, 1838, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 367, 368, 370, 369, 371, 372,
+	373, 374, 0, 375, 376, 0, 0, 0, 0, 0,
+	856, 0, 0, 0, 378, 0, 377, 0, 379, 380,
+	381, 926, 382, 383, 384, 385, 386, 387, 388, 389,
+	390, 857, 391, 858, 0, 392, 859, 393, 860, 0,
+	861, 394, 395, 396, 397, 398, 399, 400, 401, 402,
+	403, 404, 0, 0, 0, 405, 862, 863, 864, 0,
+	406, 407, 408, 409, 865, 0, 927, 0, 410, 411,
+	412, 413, 414, 415, 416, 417, 0, 0, 419, 420,
+	421, 418, 422, 423, 0, 424, 0, 425, 426, 427,
+	428, 429, 0, 430, 431, 0, 432, 433, 434, 928,
+	435, 436, 437, 0, 0, 0, 0, 0, 0, 0,
+	438, 439, 440, 441, 442, 0, 443, 445, 866, 867,
+	0, 448, 450, 444, 446, 0, 449, 447, 451, 452,
+	0, 453, 454, 455, 456, 457, 0, 0, 0, 458,
+	459, 460, 461, 0, 462, 463, 464, 466, 465, 0,
+	467, 468, 469, 0, 470, 471, 868, 472, 473, 474,
+	476, 478, 475, 477, 479, 480, 481, 482, 483, 869,
+	870, 484, 485, 0, 362, 0, 0, 0, 0, 0,
+	486, 487, 488, 871, 0, 0, 0, 489, 0, 491,
+	495, 496, 492, 493, 494, 497, 0, 490, 498, 499,
+	0, 929, 500, 501, 502, 872, 873, 503, 504, 505,
+	506, 507, 508, 509, 510, 511, 0, 512, 513, 874,
+	0, 875, 514, 0, 515, 516, 517, 518, 519, 520,
+	521, 876, 877, 878, 630, 931, 522, 523, 524, 525,
+	0, 526, 527, 528, 529, 530, 531, 532, 0, 0,
+	0, 533, 534, 535, 536, 0, 0, 0, 0, 930,
+	879, 537, 631, 538, 539, 880, 881, 0, 882, 0,
+	540, 541, 544, 932, 883, 933, 543, 545, 546, 934,
+	547, 0, 0, 0, 548, 549, 550, 551, 552, 553,
+	554, 0, 555, 557, 556, 0, 559, 884, 558, 935,
+	560, 561, 936, 0, 562, 563, 564, 565, 566, 567,
+	572, 0, 0, 568, 569, 570, 571, 573, 574, 0,
+	575, 576, 578, 581, 577, 579, 580, 582, 583, 596,
+	597, 598, 584, 585, 586, 587, 588, 589, 590, 591,
+	592, 593, 594, 595, 600, 0, 599, 937, 0, 601,
+	602, 603, 604, 605, 606, 612, 615, 617, 618, 613,
+	614, 616, 619, 620, 621, 623, 624, 609, 610, 611,
+	938, 622, 607, 0, 608, 0, 939, 625, 626, 627,
+	628, 0, 885, 629, 886, 632, 633, 0, 0, 634,
+	0, 635, 636, 0, 0, 638, 639, 640, 0, 0,
+	641, 642, 887, 940, 643, 941, 888, 644, 645, 637,
+	646, 647, 648, 649, 650, 651, 652, 653, 654, 655,
+	656, 657, 0, 658, 659, 889, 660, 661, 662, 663,
+	664, 890, 665, 666, 667, 891, 668, 892, 669, 670,
+	671, 0, 672, 673, 674, 0, 675, 676, 677, 678,
+	679, 680, 681, 682, 683, 684, 893, 685, 686, 688,
+	687, 689, 690, 0, 691, 692, 0, 693, 694, 695,
+	0, 0, 0, 0, 0, 696, 697, 699, 0, 700,
+	701, 702, 703, 704, 705, 698, 706, 707, 708, 709,
+	710, 711, 712, 713, 0, 715, 716, 714, 717, 718,
+	942, 719, 720, 721, 722, 723, 894, 724, 0, 725,
+	726, 734, 735, 736, 727, 728, 730, 737, 729, 738,
+	739, 740, 741, 743, 742, 0, 745, 746, 744, 747,
+	748, 749, 750, 0, 751, 895, 752, 731, 732, 753,
+	754, 755, 943, 756, 757, 758, 759, 760, 761, 762,
+	763, 764, 896, 0, 766, 0, 765, 767, 768, 769,
+	770, 771, 772, 773, 775, 733, 776, 777, 778, 783,
+	784, 785, 897, 779, 780, 781, 782, 787, 898, 788,
+	789, 790, 791, 0, 792, 793, 0, 786, 774, 0,
+	794, 795, 796, 797, 798, 799, 800, 801, 802, 803,
+	0, 804, 899, 900, 901, 902, 0, 817, 0, 805,
+	807, 808, 809, 810, 903, 811, 812, 904, 0, 813,
+	814, 815, 816, 806, 819, 820, 818, 0, 0, 821,
+	822, 823, 824, 826, 828, 829, 830, 825, 827, 831,
+	0, 832, 0, 0, 833, 834, 835, 905, 906, 907,
+	0, 908, 838, 839, 836, 837, 840, 841, 844, 842,
+	843, 909, 847, 542, 848, 849, 850, 845, 846, 0,
+	0, 0, 0, 851, 852, 910, 853, 854, 855, 2149,
+	0, 1654, 1653, 0, 0, 0, 0, 1838, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 367, 368,
+	370, 369, 371, 372, 373, 374, 0, 375, 376, 0,
+	0, 0, 0, 0, 856, 0, 0, 0, 378, 0,
+	377, 0, 379, 380, 381, 926, 382, 383, 384, 385,
+	386, 387, 388, 389, 390, 857, 391, 858, 0, 392,
+	859, 393, 860, 0, 861, 394, 395, 396, 397, 398,
+	399, 400, 401, 402, 403, 404, 0, 0, 0, 405,
+	862, 863, 864, 0, 406, 407, 408, 409, 865, 0,
+	927, 0, 410, 411, 412, 413, 414, 415, 416, 417,
+	0, 0, 419, 420, 421, 418, 422, 423, 0, 424,
+	0, 425, 426, 427, 428, 429, 0, 430, 431, 0,
+	432, 433, 434, 928, 435, 436, 437, 0, 0, 0,
+	0, 0, 0, 0, 438, 439, 440, 441, 442, 0,
+	443, 445, 866, 867, 0, 448, 450, 444, 446, 0,
+	449, 447, 451, 452, 0, 453, 454, 455, 456, 457,
+	0, 0, 0, 458, 459, 460, 461, 0, 462, 463,
+	464, 466, 465, 0, 467, 468, 469, 0, 470, 471,
+	868, 472, 473, 474, 476, 478, 475, 477, 479, 480,
+	481, 482, 483, 869, 870, 484, 485, 0, 362, 0,
+	0, 0, 0, 0, 486, 487, 488, 871, 0, 0,
+	0, 489, 0, 491, 495, 496, 492, 493, 494, 497,
+	0, 490, 498, 499, 0, 929, 500, 501, 502, 872,
+	873, 503, 504, 505, 506, 507, 508, 509, 510, 511,
+	0, 512, 513, 874, 0, 875, 514, 0, 515, 516,
+	517, 518, 519, 520, 521, 2152, 877, 878, 630, 931,
+	522, 523, 524, 525, 0, 526, 527, 528, 529, 530,
+	531, 532, 0, 0, 0, 533, 534, 535, 536, 0,
+	0, 0, 0, 930, 879, 537, 631, 538, 539, 880,
+	881, 0, 882, 0, 540, 541, 544, 932, 883, 933,
+	543, 545, 546, 934, 547, 0, 0, 0, 548, 549,
+	550, 551, 552, 553, 554, 0, 555, 557, 556, 0,
+	559, 884, 558, 935, 560, 561, 936, 0, 562, 563,
+	564, 565, 566, 567, 572, 0, 0, 568, 569, 570,
+	571, 573, 574, 0, 575, 576, 578, 581, 577, 579,
+	580, 582, 583, 596, 597, 598, 584, 585, 586, 587,
+	588, 589, 590, 591, 592, 593, 594, 595, 600, 0,
+	599, 937, 0, 601, 602, 603, 604, 605, 606, 612,
+	615, 617, 618, 613, 614, 616, 619, 620, 621, 623,
+	624, 609, 610, 611, 938, 622, 607, 0, 608, 0,
+	939, 625, 626, 627, 628, 0, 885, 629, 886, 632,
+	633, 0, 0, 634, 0, 635, 636, 0, 0, 638,
+	639, 640, 0, 0, 641, 642, 887, 940, 643, 941,
+	888, 644, 645, 637, 646, 647, 648, 649, 650, 651,
+	652, 653, 654, 655, 656, 657, 0, 658, 659, 889,
+	660, 661, 662, 663, 664, 890, 665, 666, 667, 891,
+	668, 892, 669, 670, 671, 0, 672, 673, 674, 0,
+	675, 676, 677, 678, 679, 680, 681, 682, 683, 684,
+	893, 685, 686, 688, 687, 689, 690, 0, 691, 692,
+	0, 693, 694, 695, 0, 0, 0, 0, 0, 696,
+	697, 699, 0, 700, 701, 702, 703, 704, 705, 698,
+	706, 707, 708, 709, 710, 711, 712, 713, 0, 715,
+	716, 714, 717, 718, 942, 719, 720, 721, 722, 723,
+	894, 724, 0, 725, 726, 734, 735, 736, 727, 728,
+	730, 737, 729, 738, 739, 740, 741, 743, 742, 0,
+	745, 746, 744, 747, 748, 749, 750, 0, 751, 895,
+	752, 731, 732, 753, 754, 755, 943, 756, 757, 758,
+	759, 760, 761, 762, 763, 764, 896, 0, 766, 0,
+	765, 767, 768, 769, 770, 771, 772, 773, 775, 733,
+	776, 777, 778, 783, 784, 785, 897, 779, 780, 781,
+	782, 787, 898, 788, 789, 790, 791, 0, 792, 793,
+	0, 786, 774, 0, 794, 795, 796, 797, 798, 799,
+	800, 801, 802, 803, 0, 804, 899, 900, 901, 902,
+	0, 817, 0, 805, 807, 808, 809, 810, 903, 811,
+	812, 904, 0, 813, 814, 815, 816, 806, 819, 820,
+	818, 0, 0, 821, 822, 823, 824, 826, 828, 829,
+	830, 825, 827, 831, 0, 832, 0, 0, 833, 834,
+	835, 905, 906, 907, 0, 908, 838, 839, 836, 837,
+	840, 841, 844, 842, 843, 909, 847, 542, 848, 849,
+	850, 845, 846, 0, 0, 0, 0, 851, 852, 910,
+	853, 854, 855, 2095, 0, 1654, 1653, 0, 0, 0,
+	0, 1838, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 367, 368, 370, 369, 371, 372, 373, 374,
+	0, 375, 376, 0, 0, 0, 0, 0, 856, 0,
+	0, 0, 378, 0, 377, 0, 379, 380, 381, 926,
+	382, 383, 384, 385, 386, 387, 388, 389, 390, 857,
+	391, 858, 0, 392, 859, 393, 860, 0, 861, 394,
+	395, 396, 397, 398, 399, 400, 401, 402, 403, 404,
+	0, 0, 0, 405, 862, 863, 864, 0, 406, 407,
+	408, 409, 865, 0, 927, 0, 410, 411, 412, 413,
+	414, 415, 416, 417, 0, 0, 419, 420, 421, 418,
+	422, 423, 0, 424, 0, 425, 426, 427, 428, 429,
+	0, 430, 431, 0, 432, 433, 434, 928, 435, 436,
+	437, 0, 0, 0, 0, 0, 0, 0, 438, 439,
+	440, 441, 442, 0, 443, 445, 866, 867, 0, 448,
+	450, 444, 446, 0, 449, 447, 451, 452, 0, 453,
+	454, 455, 456, 457, 0, 0, 0, 458, 459, 460,
+	461, 0, 462, 463, 464, 466, 465, 0, 467, 468,
+	469, 0, 470, 471, 868, 472, 473, 474, 476, 478,
+	475, 477, 479, 480, 481, 482, 483, 869, 870, 484,
+	485, 0, 362, 0, 0, 0, 0, 0, 486, 487,
+	488, 871, 0, 0, 0, 489, 0, 491, 495, 496,
+	492, 493, 494, 497, 0, 490, 498, 499, 0, 929,
+	500, 501, 502, 872, 873, 503, 504, 505, 506, 507,
+	508, 509, 510, 511, 0, 512, 513, 874, 0, 875,
+	514, 0, 515, 516, 517, 518, 519, 520, 521, 876,
+	877, 878, 630, 931, 522, 523, 524, 525, 0, 526,
+	527, 528, 529, 530, 531, 532, 0, 0, 0, 533,
+	534, 535, 536, 0, 0, 0, 0, 930, 879, 537,
+	631, 538, 539, 880, 881, 0, 882, 0, 540, 541,
+	544, 932, 883, 933, 543, 545, 546, 934, 547, 0,
+	0, 0, 548, 549, 550, 551, 552, 553, 554, 0,
+	555, 557, 556, 0, 559, 884, 558, 935, 560, 561,
+	936, 0, 562, 563, 564, 565, 566, 567, 572, 0,
+	0, 568, 569, 570, 571, 573, 574, 0, 575, 576,
+	578, 581, 577, 579, 580, 582, 583, 596, 597, 598,
+	584, 585, 586, 587, 588, 589, 590, 591, 592, 593,
+	594, 595, 600, 0, 599, 937, 0, 601, 602, 603,
+	604, 605, 606, 612, 615, 617, 618, 613, 614, 616,
+	619, 620, 621, 623, 624, 609, 610, 611, 938, 622,
+	607, 0, 608, 0, 939, 625, 626, 627, 628, 0,
+	885, 629, 886, 632, 633, 0, 0, 634, 0, 635,
+	636, 0, 0, 638, 639, 640, 0, 0, 641, 642,
+	887, 940, 643, 941, 888, 644, 645, 637, 646, 647,
+	648, 649, 650, 651, 652, 653, 654, 655, 656, 657,
+	0, 658, 659, 889, 660, 661, 662, 663, 664, 890,
+	665, 666, 667, 891, 668, 892, 669, 670, 671, 0,
+	672, 673, 674, 0, 675, 676, 677, 678, 679, 680,
+	681, 682, 683, 684, 893, 685, 686, 688, 687, 689,
+	690, 0, 691, 692, 0, 693, 694, 695, 0, 0,
+	0, 0, 0, 696, 697, 699, 0, 700, 701, 702,
+	703, 704, 705, 698, 706, 707, 708, 709, 710, 711,
+	712, 713, 0, 715, 716, 714, 717, 718, 942, 719,
+	720, 721, 722, 723, 894, 724, 0, 725, 726, 734,
+	735, 736, 2093, 728, 730, 737, 729, 738, 739, 740,
+	741, 743, 742, 0, 745, 746, 744, 747, 748, 749,
+	750, 0, 751, 895, 752, 731, 732, 753, 754, 755,
+	943, 756, 757, 758, 759, 760, 761, 762, 763, 764,
+	896, 0, 766, 0, 765, 767, 768, 769, 770, 771,
+	772, 773, 775, 733, 776, 777, 778, 783, 784, 785,
+	897, 779, 780, 781, 782, 787, 898, 788, 789, 790,
+	791, 0, 792, 793, 0, 786, 774, 0, 794, 795,
+	796, 797, 798, 799, 800, 801, 802, 803, 0, 804,
+	899, 900, 901, 902, 0, 817, 0, 805, 807, 808,
+	809, 810, 903, 811, 812, 904, 0, 813, 814, 815,
+	816, 806, 819, 820, 818, 0, 0, 821, 822, 823,
+	824, 826, 828, 829, 830, 825, 827, 831, 0, 832,
+	0, 0, 833, 834, 835, 905, 906, 907, 0, 908,
+	838, 839, 836, 837, 840, 841, 844, 842, 843, 909,
+	847, 542, 848, 849, 850, 845, 846, 0, 0, 0,
+	0, 851, 852, 910, 853, 854, 855, 1836, 0, 1654,
+	1653, 0, 0, 0, 0, 1838, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 367, 368, 370, 369,
+	371, 372, 373, 374, 0, 375, 376, 0, 0, 0,
+	0, 0, 856, 0, 0, 0, 378, 0, 377, 0,
+	379, 380, 381, 926, 382, 383, 384, 385, 386, 387,
+	388, 389, 390, 857, 391, 858, 0, 392, 859, 393,
+	860, 0, 861, 394, 395, 396, 397, 398, 399, 400,
+	401, 402, 403, 404, 0, 0, 0, 405, 862, 863,
+	864, 0, 406, 407, 408, 409, 865, 0, 927, 0,
+	410, 411, 412, 413, 414, 415, 416, 417, 0, 0,
+	419, 420, 421, 418, 1835, 423, 0, 424, 0, 425,
+	426, 427, 428, 429, 0, 430, 431, 0, 432, 433,
+	434, 928, 435, 436, 437, 0, 0, 0, 0, 0,
+	0, 0, 438, 439, 440, 441, 442, 0, 443, 445,
+	866, 867, 0, 448, 450, 444, 446, 0, 449, 447,
+	451, 452, 0, 453, 454, 455, 456, 457, 0, 0,
+	0, 458, 459, 460, 461, 0, 462, 463, 464, 466,
+	465, 0, 467, 468, 469, 0, 470, 471, 868, 472,
+	473, 474, 476, 478, 475, 477, 479, 480, 481, 482,
+	483, 869, 870, 484, 485, 0, 362, 0, 0, 0,
+	0, 0, 1832, 487, 488, 871, 0, 0, 0, 489,
+	0, 491, 495, 496, 492, 493, 494, 497, 0, 490,
+	498, 499, 0, 929, 500, 501, 502, 872, 873, 503,
+	504, 505, 506, 507, 508, 509, 510, 511, 0, 512,
+	513, 874, 0, 875, 514, 0, 515, 516, 517, 518,
+	519, 520, 521, 876, 877, 878, 630, 931, 522, 523,
+	524, 525, 0, 526, 527, 528, 529, 530, 531, 532,
+	0, 0, 0, 533, 534, 535, 536, 0, 0, 0,
+	0, 930, 879, 537, 631, 538, 539, 880, 881, 0,
+	882, 0, 540, 541, 544, 932, 883, 933, 543, 545,
+	546, 934, 547, 0, 0, 0, 548, 549, 550, 551,
+	552, 553, 554, 0, 555, 557, 556, 0, 559, 884,
+	558, 935, 560, 561, 936, 0, 562, 563, 564, 565,
+	566, 567, 572, 0, 0, 568, 569, 570, 571, 573,
+	574, 0, 575, 576, 578, 581, 577, 579, 580, 582,
+	583, 596, 597, 598, 584, 585, 586, 587, 588, 589,
+	590, 591, 592, 593, 594, 595, 600, 0, 599, 937,
+	0, 601, 602, 603, 604, 605, 606, 612, 615, 617,
+	618, 613, 614, 616, 619, 620, 621, 623, 624, 609,
+	610, 611, 938, 622, 607, 0, 608, 0, 939, 625,
+	626, 627, 628, 0, 885, 629, 886, 632, 633, 0,
+	0, 634, 0, 635, 636, 0, 0, 638, 639, 640,
+	0, 0, 641, 642, 887, 940, 643, 941, 888, 644,
+	645, 637, 646, 647, 648, 649, 650, 651, 652, 653,
+	654, 655, 656, 657, 0, 658, 659, 889, 660, 661,
+	662, 663, 664, 890, 665, 666, 667, 891, 668, 892,
+	669, 670, 671, 0, 672, 673, 674, 0, 675, 676,
+	677, 678, 679, 680, 681, 682, 1833, 684, 893, 685,
+	686, 688, 687, 689, 690, 0, 691, 692, 0, 693,
+	694, 695, 0, 0, 0, 0, 0, 696, 697, 699,
+	0, 700, 701, 702, 703, 704, 705, 698, 706, 707,
+	708, 709, 710, 711, 712, 713, 0, 715, 716, 714,
+	717, 718, 942, 719, 720, 721, 722, 723, 894, 724,
+	0, 725, 726, 734, 735, 736, 727, 728, 730, 737,
+	729, 1831, 739, 740, 741, 743, 742, 0, 745, 746,
+	744, 747, 748, 749, 750, 0, 751, 895, 752, 731,
+	732, 753, 754, 755, 943, 756, 757, 758, 759, 760,
+	761, 762, 763, 764, 896, 0, 766, 0, 765, 767,
+	768, 769, 770, 771, 772, 773, 775, 733, 776, 777,
+	778, 783, 784, 785, 897, 779, 780, 781, 782, 787,
+	898, 788, 789, 790, 791, 0, 792, 793, 0, 786,
+	774, 0, 794, 795, 796, 797, 798, 799, 800, 801,
+	802, 803, 0, 804, 899, 900, 901, 902, 0, 817,
+	0, 805, 807, 808, 809, 810, 903, 811, 812, 904,
+	0, 813, 814, 815, 816, 806, 819, 820, 818, 0,
+	0, 821, 822, 823, 824, 826, 828, 829, 830, 825,
+	827, 831, 0, 832, 0, 0, 833, 1834, 835, 905,
+	906, 907, 0, 908, 838, 839, 836, 837, 840, 841,
+	844, 842, 843, 909, 847, 542, 848, 849, 850, 845,
+	846, 0, 0, 0, 0, 851, 852, 910, 853, 854,
+	855, 1654, 1653, 0, 0, 0, 0, 1838, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 367, 368,
+	370, 369, 371, 372, 373, 374, 0, 375, 376, 0,
+	0, 0, 0, 0, 856, 0, 0, 0, 378, 0,
+	377, 0, 379, 380, 381, 926, 382, 383, 384, 385,
+	386, 387, 388, 389, 390, 857, 391, 858, 0, 392,
+	859, 393, 860, 0, 861, 394, 395, 396, 397, 398,
+	399, 400, 401, 402, 403, 404, 0, 0, 0, 405,
+	862, 863, 864, 0, 406, 407, 408, 409, 865, 0,
+	927, 0, 410, 411, 412, 413, 414, 415, 416, 417,
+	0, 0, 419, 420, 421, 418, 422, 423, 0, 424,
+	0, 425, 426, 427, 428, 429, 0, 430, 431, 0,
+	432, 433, 434, 928, 435, 436, 437, 0, 0, 0,
+	0, 0, 0, 0, 438, 439, 440, 441, 442, 0,
+	443, 445, 866, 867, 0, 448, 450, 444, 446, 0,
+	449, 447, 451, 452, 0, 453, 454, 455, 456, 457,
+	0, 0, 0, 458, 459, 460, 461, 0, 462, 463,
+	464, 466, 465, 0, 467, 468, 469, 0, 470, 471,
+	868, 472, 473, 474, 476, 478, 475, 477, 479, 480,
+	481, 482, 483, 869, 870, 484, 485, 0, 362, 0,
+	0, 0, 0, 0, 486, 487, 488, 871, 0, 0,
+	0, 489, 0, 491, 495, 496, 492, 493, 494, 497,
+	0, 490, 498, 499, 0, 929, 500, 501, 502, 872,
+	873, 503, 504, 505, 506, 507, 508, 509, 510, 511,
+	0, 512, 513, 874, 0, 875, 514, 0, 515, 516,
+	517, 518, 519, 520, 521, 876, 877, 878, 630, 931,
+	522, 523, 524, 525, 0, 526, 527, 528, 529, 530,
+	531, 532, 0, 0, 0, 533, 534, 535, 536, 0,
+	0, 0, 0, 930, 879, 537, 631, 538, 539, 880,
+	881, 0, 882, 0, 540, 541, 544, 932, 883, 933,
+	543, 545, 546, 934, 547, 0, 0, 0, 548, 549,
+	550, 551, 552, 553, 554, 0, 555, 557, 556, 0,
+	559, 884, 558, 935, 560, 561, 936, 0, 562, 563,
+	564, 565, 566, 567, 572, 0, 0, 568, 569, 570,
+	571, 573, 574, 0, 575, 576, 578, 581, 577, 579,
+	580, 582, 583, 596, 597, 598, 584, 585, 586, 587,
+	588, 589, 590, 591, 592, 593, 594, 595, 600, 0,
+	599, 937, 0, 601, 602, 603, 604, 605, 606, 612,
+	615, 617, 618, 613, 614, 616, 619, 620, 621, 623,
+	624, 609, 610, 611, 938, 622, 607, 0, 608, 0,
+	939, 625, 626, 627, 628, 0, 885, 629, 886, 632,
+	633, 0, 0, 634, 0, 635, 636, 0, 0, 638,
+	639, 640, 0, 0, 641, 642, 887, 940, 643, 941,
+	888, 644, 645, 637, 646, 647, 648, 649, 650, 651,
+	652, 653, 654, 655, 656, 657, 0, 658, 659, 889,
+	660, 661, 662, 663, 664, 890, 665, 666, 667, 891,
+	668, 892, 669, 670, 671, 0, 672, 673, 674, 0,
+	675, 676, 677, 678, 679, 680, 681, 682, 683, 684,
+	893, 685, 686, 688, 687, 689, 690, 0, 691, 692,
+	0, 693, 694, 695, 0, 0, 0, 0, 0, 696,
+	697, 699, 0, 700, 701, 702, 703, 704, 705, 698,
+	706, 707, 708, 709, 710, 711, 712, 713, 0, 715,
+	716, 714, 717, 718, 942, 719, 720, 721, 722, 723,
+	894, 724, 0, 725, 726, 734, 735, 736, 727, 728,
+	730, 737, 729, 738, 739, 740, 741, 743, 742, 0,
+	745, 746, 744, 747, 748, 749, 750, 0, 751, 895,
+	752, 731, 732, 753, 754, 755, 943, 756, 757, 758,
+	759, 760, 761, 762, 763, 764, 896, 0, 766, 0,
+	765, 767, 768, 769, 770, 771, 772, 773, 775, 733,
+	776, 777, 778, 783, 784, 785, 897, 779, 780, 781,
+	782, 787, 898, 788, 789, 790, 791, 0, 792, 793,
+	0, 786, 774, 0, 794, 795, 796, 797, 798, 799,
+	800, 801, 802, 803, 0, 804, 899, 900, 901, 902,
+	0, 817, 0, 805, 807, 808, 809, 810, 903, 811,
+	812, 904, 0, 813, 814, 815, 816, 806, 819, 820,
+	818, 0, 0, 821, 822, 823, 824, 826, 828, 829,
+	830, 825, 827, 831, 0, 832, 0, 0, 833, 834,
+	835, 905, 906, 907, 0, 908, 838, 839, 836, 837,
+	840, 841, 844, 842, 843, 909, 847, 542, 848, 849,
+	850, 845, 846, 1654, 1653, 0, 0, 851, 852, 910,
+	853, 854, 855, 0, 0, 0, 0, 0, 0, 0,
+	367, 368, 370, 369, 371, 372, 373, 374, 0, 375,
+	376, 0, 0, 0, 0, 0, 856, 0, 0, 0,
+	378, 0, 377, 0, 379, 380, 381, 926, 382, 383,
+	384, 385, 386, 387, 388, 389, 390, 857, 391, 858,
+	0, 392, 859, 393, 860, 0, 861, 394, 395, 396,
+	397, 398, 399, 400, 401, 402, 403, 404, 0, 0,
+	0, 405, 862, 863, 864, 0, 406, 407, 408, 409,
+	865, 0, 927, 0, 410, 411, 412, 413, 414, 415,
+	416, 417, 0, 0, 419, 420, 421, 418, 422, 423,
+	0, 424, 0, 425, 426, 427, 428, 429, 0, 430,
+	431, 0, 432, 433, 434, 928, 435, 436, 437, 0,
+	0, 0, 0, 0, 0, 0, 438, 439, 440, 441,
+	442, 0, 443, 445, 866, 867, 0, 448, 450, 444,
+	446, 0, 449, 447, 451, 452, 0, 453, 454, 455,
+	456, 457, 0, 0, 0, 458, 459, 460, 461, 0,
+	462, 463, 464, 466, 465, 0, 467, 468, 469, 0,
+	470, 471, 868, 472, 473, 474, 476, 478, 475, 477,
+	479, 480, 481, 482, 483, 869, 870, 484, 485, 0,
+	362, 0, 0, 0, 0, 0, 486, 487, 488, 871,
+	0, 0, 0, 489, 0, 491, 495, 496, 492, 493,
+	494, 497, 0, 490, 498, 499, 0, 929, 500, 501,
+	502, 872, 873, 503, 504, 505, 506, 507, 508, 509,
+	510, 511, 0, 512, 513, 874, 0, 875, 514, 0,
+	515, 516, 517, 518, 519, 520, 521, 876, 877, 878,
+	630, 931, 522, 523, 524, 525, 0, 526, 527, 528,
+	529, 530, 531, 532, 0, 0, 0, 533, 534, 535,
+	536, 0, 0, 0, 0, 930, 879, 537, 631, 538,
+	539, 880, 881, 0, 882, 0, 540, 541, 544, 932,
+	883, 933, 543, 545, 546, 934, 547, 0, 0, 0,
+	548, 549, 550, 551, 552, 553, 554, 0, 555, 557,
+	556, 0, 559, 884, 558, 935, 560, 561, 936, 0,
+	562, 563, 564, 565, 566, 567, 572, 0, 0, 568,
+	569, 570, 571, 573, 574, 0, 575, 576, 578, 581,
+	577, 579, 580, 582, 583, 596, 597, 598, 584, 585,
+	586, 587, 588, 589, 590, 591, 592, 593, 594, 595,
+	600, 0, 599, 937, 0, 601, 602, 603, 604, 605,
+	606, 612, 615, 617, 618, 613, 614, 616, 619, 620,
+	621, 623, 624, 609, 610, 611, 938, 622, 607, 0,
+	608, 0, 939, 625, 626, 627, 628, 0, 885, 629,
+	886, 632, 633, 0, 0, 634, 0, 635, 636, 0,
+	0, 638, 639, 640, 0, 0, 641, 642, 887, 940,
+	643, 941, 888, 644, 645, 637, 646, 647, 648, 649,
+	650, 651, 652, 653, 654, 655, 656, 657, 0, 658,
+	659, 889, 660, 661, 662, 663, 664, 890, 665, 666,
+	667, 891, 668, 892, 669, 670, 671, 0, 672, 673,
+	674, 0, 675, 676, 677, 678, 679, 680, 681, 682,
+	683, 684, 893, 685, 686, 688, 687, 689, 690, 0,
+	691, 692, 0, 693, 694, 695, 0, 0, 0, 0,
+	0, 696, 697, 699, 0, 700, 701, 702, 703, 704,
+	705, 698, 706, 707, 708, 709, 710, 711, 712, 713,
+	0, 715, 716, 714, 717, 718, 942, 719, 720, 721,
+	722, 723, 894, 724, 0, 725, 726, 734, 735, 736,
+	727, 728, 730, 737, 729, 738, 739, 740, 741, 743,
+	742, 0, 745, 746, 744, 747, 748, 749, 750, 0,
+	751, 895, 752, 731, 732, 753, 754, 755, 943, 756,
+	757, 758, 759, 760, 761, 762, 763, 764, 896, 0,
+	766, 0, 765, 767, 768, 769, 770, 771, 772, 773,
+	775, 733, 776, 777, 778, 783, 784, 785, 897, 779,
+	780, 781, 782, 787, 898, 788, 789, 790, 791, 0,
+	792, 793, 0, 786, 774, 0, 794, 795, 796, 797,
+	798, 799, 800, 801, 802, 803, 0, 804, 899, 900,
+	901, 902, 0, 817, 0, 805, 807, 808, 809, 810,
+	903, 811, 812, 904, 0, 813, 814, 815, 816, 806,
+	819, 820, 818, 0, 0, 821, 822, 823, 824, 826,
+	828, 829, 830, 825, 827, 831, 0, 832, 0, 0,
+	833, 834, 835, 905, 906, 907, 0, 908, 838, 839,
+	836, 837, 840, 841, 844, 842, 843, 909, 847, 542,
+	848, 849, 850, 845, 846, 1654, 0, 0, 0, 851,
+	852, 910, 853, 854, 855, 0, 0, 0, 0, 0,
+	0, 0, 367, 368, 370, 369, 371, 372, 373, 374,
+	0, 375, 376, 0, 0, 0, 0, 0, 856, 0,
+	0, 0, 378, 0, 377, 0, 379, 380, 381, 926,
+	382, 383, 384, 385, 386, 387, 388, 389, 390, 857,
+	391, 858, 0, 392, 859, 393, 860, 0, 861, 394,
+	395, 396, 397, 398, 399, 400, 401, 402, 403, 404,
+	0, 0, 0, 405, 862, 863, 864, 0, 406, 407,
+	408, 409, 865, 0, 927, 0, 410, 411, 412, 413,
+	414, 415, 416, 417, 0, 0, 419, 420, 421, 418,
+	422, 423, 0, 424, 0, 425, 426, 427, 428, 429,
+	0, 430, 431, 0, 432, 433, 434, 928, 435, 436,
+	437, 0, 0, 0, 0, 0, 0, 0, 438, 439,
+	440, 441, 442, 0, 443, 445, 866, 867, 0, 448,
+	450, 444, 446, 0, 449, 447, 451, 452, 0, 453,
+	454, 455, 456, 457, 0, 0, 0, 458, 459, 460,
+	461, 0, 462, 463, 464, 466, 465, 0, 467, 468,
+	469, 0, 470, 471, 868, 472, 473, 474, 476, 478,
+	475, 477, 479, 480, 481, 482, 483, 869, 870, 484,
+	485, 0, 362, 0, 0, 0, 0, 0, 486, 487,
+	488, 871, 0, 0, 0, 489, 0, 491, 495, 496,
+	492, 493, 494, 497, 0, 490, 498, 499, 0, 929,
+	500, 501, 502, 872, 873, 503, 504, 505, 506, 507,
+	508, 509, 510, 511, 0, 512, 513, 874, 0, 875,
+	514, 0, 515, 516, 517, 518, 519, 520, 521, 876,
+	877, 878, 630, 931, 522, 523, 524, 525, 0, 526,
+	527, 528, 529, 530, 531, 532, 0, 0, 0, 533,
+	534, 535, 536, 0, 0, 0, 0, 930, 879, 537,
+	631, 538, 539, 880, 881, 0, 882, 0, 540, 541,
+	544, 932, 883, 933, 543, 545, 546, 934, 547, 0,
+	0, 0, 548, 549, 550, 551, 552, 553, 554, 0,
+	555, 557, 556, 0, 559, 884, 558, 935, 560, 561,
+	936, 0, 562, 563, 564, 565, 566, 567, 572, 0,
+	0, 568, 569, 570, 571, 573, 574, 0, 575, 576,
+	578, 581, 577, 579, 580, 582, 583, 596, 597, 598,
+	584, 585, 586, 587, 588, 589, 590, 591, 592, 593,
+	594, 595, 600, 0, 599, 937, 0, 601, 602, 603,
+	604, 605, 606, 612, 615, 617, 618, 613, 614, 616,
+	619, 620, 621, 623, 624, 609, 610, 611, 938, 622,
+	607, 0, 608, 0, 939, 625, 626, 627, 628, 0,
+	885, 629, 886, 632, 633, 0, 0, 634, 0, 635,
+	636, 0, 0, 638, 639, 640, 0, 0, 641, 642,
+	887, 940, 643, 941, 888, 644, 645, 637, 646, 647,
+	648, 649, 650, 651, 652, 653, 654, 655, 656, 657,
+	0, 658, 659, 889, 660, 661, 662, 663, 664, 890,
+	665, 666, 667, 891, 668, 892, 669, 670, 671, 0,
+	672, 673, 674, 0, 675, 676, 677, 678, 679, 680,
+	681, 682, 683, 684, 893, 685, 686, 688, 687, 689,
+	690, 0, 691, 692, 0, 693, 694, 695, 0, 0,
+	0, 0, 0, 696, 697, 699, 0, 700, 701, 702,
+	703, 704, 705, 698, 706, 707, 708, 709, 710, 711,
+	712, 713, 0, 715, 716, 714, 717, 718, 942, 719,
+	720, 721, 722, 723, 894, 724, 0, 725, 726, 734,
+	735, 736, 727, 728, 730, 737, 729, 738, 739, 740,
+	741, 743, 742, 0, 745, 746, 744, 747, 748, 749,
+	750, 0, 751, 895, 752, 731, 732, 753, 754, 755,
+	943, 756, 757, 758, 759, 760, 761, 762, 763, 764,
+	896, 0, 766, 0, 765, 767, 768, 769, 770, 771,
+	772, 773, 775, 733, 776, 777, 778, 783, 784, 785,
+	897, 779, 780, 781, 782, 787, 898, 788, 789, 790,
+	791, 0, 792, 793, 0, 786, 774, 0, 794, 795,
+	796, 797, 798, 799, 800, 801, 802, 803, 0, 804,
+	899, 900, 901, 902, 0, 817, 0, 805, 807, 808,
+	809, 810, 903, 811, 812, 904, 0, 813, 814, 815,
+	816, 806, 819, 820, 818, 0, 0, 821, 822, 823,
+	824, 826, 828, 829, 830, 825, 827, 831, 0, 832,
+	0, 0, 833, 834, 835, 905, 906, 907, 0, 908,
+	838, 839, 836, 837, 840, 841, 844, 842, 843, 909,
+	847, 542, 848, 849, 850, 845, 846, 359, 0, 0,
+	0, 851, 852, 910, 853, 854, 855, 0, 0, 0,
+	0, 0, 0, 0, 367, 368, 370, 369, 371, 372,
+	373, 374, 0, 375, 376, 0, 0, 0, 0, 0,
+	856, 0, 0, 0, 378, 0, 377, 0, 379, 380,
+	381, 0, 382, 383, 384, 385, 386, 387, 388, 389,
+	390, 857, 391, 858, 0, 392, 859, 393, 860, 0,
+	861, 394, 395, 396, 397, 398, 399, 400, 401, 402,
+	403, 404, 0, 0, 0, 405, 862, 863, 864, 4403,
+	406, 407, 408, 409, 865, 0, 0, 0, 410, 411,
+	412, 413, 414, 415, 416, 417, 0, 0, 419, 420,
+	421, 418, 422, 423, 5361, 424, 0, 425, 426, 427,
+	428, 429, 0, 430, 431, 0, 432, 433, 434, 0,
+	435, 436, 437, 0, 0, 0, 0, 0, 0, 0,
+	438, 439, 440, 441, 442, 0, 443, 445, 866, 867,
+	0, 448, 450, 444, 446, 0, 449, 447, 451, 452,
+	0, 453, 454, 455, 456, 457, 0, 0, 0, 458,
+	459, 460, 461, 0, 462, 463, 464, 466, 465, 0,
+	467, 468, 469, 0, 4407, 471, 868, 472, 473, 474,
+	476, 478, 475, 477, 479, 480, 481, 482, 483, 869,
+	870, 484, 485, 0, 5360, 0, 0, 0, 0, 0,
+	486, 487, 488, 871, 0, 0, 0, 489, 0, 491,
+	495, 496, 492, 493, 494, 497, 4406, 490, 498, 499,
+	0, 0, 500, 501, 502, 872, 873, 503, 504, 505,
+	506, 507, 508, 509, 510, 511, 0, 512, 513, 874,
+	0, 875, 514, 0, 515, 516, 517, 518, 519, 520,
+	521, 876, 877, 878, 630, 0, 522, 523, 524, 525,
+	0, 526, 527, 528, 529, 530, 531, 532, 0, 0,
+	0, 533, 534, 535, 536, 0, 5355, 5356, 0, 0,
+	879, 537, 631, 538, 539, 880, 881, 0, 882, 0,
+	540, 5358, 544, 0, 883, 0, 543, 545, 546, 0,
+	547, 0, 0, 0, 548, 549, 550, 551, 552, 553,
+	554, 0, 555, 557, 556, 0, 559, 884, 558, 0,
+	560, 561, 5354, 0, 562, 563, 564, 565, 566, 567,
+	572, 0, 0, 568, 569, 570, 571, 573, 574, 0,
+	575, 576, 578, 581, 577, 579, 580, 582, 583, 596,
+	597, 598, 584, 585, 586, 587, 588, 589, 590, 591,
+	592, 593, 594, 595, 600, 0, 599, 0, 0, 601,
+	602, 603, 604, 605, 606, 612, 615, 617, 618, 613,
+	614, 616, 619, 620, 621, 623, 624, 609, 610, 611,
+	0, 622, 607, 0, 608, 0, 0, 625, 626, 627,
+	628, 0, 885, 629, 886, 632, 633, 0, 0, 634,
+	0, 635, 636, 0, 0, 638, 639, 640, 0, 0,
+	641, 642, 887, 0, 643, 0, 888, 644, 645, 637,
+	646, 647, 648, 649, 650, 651, 652, 653, 654, 655,
+	656, 657, 0, 658, 659, 889, 660, 661, 662, 663,
+	664, 890, 665, 666, 667, 891, 668, 892, 669, 670,
+	671, 4405, 672, 673, 674, 0, 675, 676, 677, 678,
+	679, 680, 681, 682, 683, 684, 893, 685, 686, 688,
+	687, 689, 690, 0, 691, 692, 0, 693, 694, 695,
+	0, 0, 0, 0, 0, 696, 697, 699, 0, 700,
+	701, 702, 703, 704, 705, 698, 706, 707, 708, 709,
+	710, 711, 712, 713, 0, 715, 716, 714, 717, 718,
+	0, 719, 720, 721, 722, 723, 894, 724, 0, 725,
+	726, 734, 735, 736, 727, 728, 730, 737, 729, 738,
+	739, 740, 741, 743, 742, 0, 745, 746, 744, 747,
+	748, 749, 750, 0, 751, 895, 752, 731, 732, 753,
+	754, 755, 0, 756, 757, 758, 759, 760, 761, 762,
+	763, 764, 896, 0, 766, 0, 765, 767, 768, 769,
+	770, 771, 772, 773, 775, 733, 776, 777, 778, 783,
+	784, 785, 897, 779, 780, 781, 782, 787, 898, 788,
+	789, 790, 791, 0, 792, 793, 0, 786, 774, 0,
+	794, 795, 796, 797, 798, 799, 800, 801, 802, 803,
+	0, 804, 899, 900, 901, 902, 0, 817, 0, 805,
+	807, 808, 809, 810, 903, 811, 812, 904, 0, 813,
+	814, 815, 816, 806, 819, 820, 818, 0, 5357, 821,
+	822, 823, 824, 826, 828, 829, 830, 825, 827, 831,
+	0, 832, 0, 0, 833, 834, 835, 905, 906, 907,
+	0, 5359, 838, 839, 836, 837, 840, 841, 844, 842,
+	843, 909, 847, 542, 848, 849, 850, 845, 846, 1942,
+	0, 359, 0, 851, 852, 910, 853, 854, 855, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 367, 368,
+	370, 369, 371, 372, 373, 374, 1941, 375, 376, 0,
+	0, 0, 0, 0, 856, 0, 0, 0, 378, 0,
+	377, 0, 379, 380, 381, 0, 382, 383, 384, 385,
+	386, 387, 388, 389, 390, 857, 391, 858, 0, 392,
+	859, 393, 860, 0, 861, 394, 395, 396, 397, 398,
+	399, 400, 401, 402, 403, 404, 0, 0, 0, 405,
+	862, 863, 864, 0, 406, 407, 408, 409, 865, 0,
+	0, 0, 410, 411, 412, 413, 414, 415, 416, 417,
+	0, 0, 419, 420, 421, 418, 422, 423, 0, 424,
+	0, 425, 426, 427, 428, 429, 0, 430, 431, 0,
+	432, 433, 434, 0, 435, 436, 437, 0, 0, 0,
+	0, 0, 0, 0, 438, 439, 440, 1935, 442, 0,
+	443, 445, 866, 867, 0, 448, 450, 444, 446, 0,
+	449, 447, 451, 452, 0, 453, 454, 455, 456, 457,
+	0, 0, 0, 458, 459, 460, 461, 0, 462, 463,
+	464, 466, 465, 0, 467, 468, 469, 0, 470, 471,
+	868, 472, 473, 474, 476, 478, 475, 477, 479, 480,
+	481, 482, 1944, 869, 870, 484, 485, 0, 362, 0,
+	0, 0, 0, 0, 486, 487, 488, 871, 0, 0,
+	0, 489, 0, 491, 495, 496, 492, 493, 494, 497,
+	0, 490, 498, 499, 0, 0, 1938, 501, 502, 872,
+	873, 503, 504, 505, 506, 507, 508, 509, 510, 511,
+	0, 512, 513, 874, 0, 875, 514, 0, 515, 516,
+	517, 518, 519, 520, 521, 876, 877, 878, 630, 0,
+	522, 523, 524, 525, 0, 526, 527, 528, 529, 530,
+	531, 532, 0, 0, 0, 533, 1936, 535, 536, 0,
+	364, 363, 365, 0, 879, 537, 631, 538, 539, 880,
+	881, 0, 882, 0, 540, 541, 544, 0, 883, 0,
+	543, 545, 546, 0, 547, 0, 0, 0, 548, 549,
+	550, 551, 552, 553, 554, 0, 555, 557, 556, 0,
+	559, 884, 558, 0, 560, 561, 0, 0, 562, 563,
+	564, 565, 566, 567, 572, 0, 0, 568, 569, 570,
+	571, 573, 574, 0, 575, 576, 578, 581, 577, 579,
+	580, 582, 583, 596, 597, 598, 584, 585, 586, 587,
+	588, 589, 590, 591, 592, 593, 594, 595, 600, 0,
+	599, 0, 0, 601, 602, 603, 604, 605, 606, 612,
+	615, 617, 618, 613, 614, 616, 619, 620, 621, 623,
+	624, 609, 610, 611, 0, 622, 607, 0, 608, 366,
+	0, 625, 626, 627, 628, 0, 885, 629, 886, 632,
+	633, 0, 0, 634, 0, 635, 636, 0, 0, 638,
+	639, 640, 0, 0, 641, 642, 887, 0, 643, 0,
+	888, 644, 645, 637, 646, 647, 648, 649, 650, 651,
+	652, 653, 654, 655, 656, 657, 0, 658, 659, 889,
+	660, 661, 662, 663, 664, 890, 665, 666, 667, 891,
+	668, 892, 669, 670, 671, 0, 672, 673, 674, 0,
+	1939, 676, 677, 678, 679, 680, 681, 682, 683, 684,
+	893, 685, 686, 688, 687, 689, 690, 0, 691, 692,
+	0, 693, 694, 695, 0, 0, 0, 0, 0, 696,
+	697, 699, 0, 700, 701, 702, 703, 704, 705, 698,
+	706, 707, 708, 709, 710, 711, 712, 713, 0, 715,
+	716, 714, 717, 718, 0, 719, 720, 721, 722, 723,
+	894, 724, 0, 725, 726, 734, 735, 736, 1943, 728,
+	730, 737, 729, 738, 739, 740, 741, 1937, 742, 0,
+	1934, 746, 744, 747, 748, 749, 750, 0, 751, 895,
+	752, 731, 732, 753, 754, 755, 0, 756, 757, 758,
+	759, 760, 761, 762, 763, 764, 896, 0, 766, 0,
+	765, 767, 768, 769, 770, 771, 772, 773, 775, 733,
+	776, 777, 778, 783, 784, 785, 897, 779, 780, 781,
+	782, 787, 898, 788, 789, 790, 791, 0, 792, 793,
+	0, 786, 774, 1932, 794, 795, 796, 797, 798, 799,
+	800, 801, 802, 803, 0, 804, 899, 900, 901, 902,
+	0, 817, 0, 805, 807, 808, 809, 810, 903, 1940,
+	812, 904, 0, 813, 814, 815, 816, 806, 819, 820,
+	818, 0, 0, 821, 822, 823, 824, 826, 828, 829,
+	830, 825, 827, 831, 0, 832, 0, 0, 833, 834,
+	835, 905, 906, 907, 0, 908, 838, 1933, 836, 837,
+	840, 841, 844, 842, 843, 909, 847, 542, 848, 849,
+	850, 845, 846, 2068, 0, 359, 0, 851, 852, 910,
+	853, 854, 855, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 367, 368, 370, 369, 371, 372, 373, 374,
+	0, 375, 376, 0, 0, 0, 0, 0, 856, 0,
+	0, 0, 378, 0, 377, 0, 379, 380, 381, 0,
+	382, 383, 384, 385, 386, 387, 388, 389, 390, 857,
+	391, 858, 0, 392, 859, 393, 860, 0, 861, 394,
+	395, 396, 397, 398, 399, 400, 401, 402, 403, 404,
+	0, 0, 0, 405, 862, 863, 864, 0, 406, 407,
+	408, 409, 865, 0, 0, 0, 410, 411, 412, 413,
+	414, 415, 416, 417, 0, 0, 419, 420, 421, 418,
+	422, 423, 0, 424, 0, 425, 426, 427, 428, 429,
+	0, 430, 431, 0, 432, 433, 434, 0, 435, 436,
+	437, 0, 0, 0, 0, 0, 0, 0, 438, 439,
+	440, 441, 442, 0, 443, 445, 866, 867, 0, 448,
+	450, 444, 446, 0, 449, 447, 451, 452, 0, 453,
+	454, 455, 456, 457, 0, 0, 0, 458, 459, 460,
+	461, 0, 462, 463, 464, 466, 465, 0, 467, 468,
+	469, 0, 470, 471, 868, 472, 473, 474, 476, 478,
+	475, 477, 479, 480, 481, 482, 483, 869, 870, 484,
+	485, 0, 362, 0, 0, 0, 0, 0, 486, 487,
+	488, 871, 0, 0, 0, 489, 0, 491, 495, 496,
+	492, 493, 494, 497, 0, 490, 498, 499, 0, 0,
+	500, 501, 502, 872, 873, 503, 504, 505, 506, 507,
+	508, 509, 510, 511, 0, 512, 513, 874, 0, 875,
+	514, 0, 515, 516, 517, 518, 519, 520, 521, 2070,
+	877, 878, 630, 0, 522, 523, 524, 525, 0, 526,
+	527, 528, 529, 530, 531, 532, 0, 0, 0, 533,
+	534, 535, 536, 0, 364, 363, 365, 0, 879, 537,
+	631, 538, 539, 880, 881, 0, 882, 0, 540, 541,
+	544, 0, 883, 0, 543, 545, 546, 0, 547, 0,
+	0, 0, 548, 549, 550, 551, 552, 553, 554, 0,
+	555, 557, 556, 0, 559, 884, 558, 0, 560, 561,
+	0, 0, 562, 563, 564, 565, 566, 567, 572, 0,
+	0, 568, 569, 570, 571, 573, 574, 0, 575, 576,
+	578, 581, 577, 579, 580, 582, 583, 596, 597, 598,
+	584, 585, 586, 587, 588, 589, 590, 591, 592, 593,
+	594, 595, 600, 0, 599, 0, 0, 601, 602, 603,
+	604, 605, 606, 612, 615, 617, 618, 613, 614, 616,
+	619, 620, 621, 623, 624, 609, 610, 611, 0, 622,
+	607, 0, 608, 366, 0, 625, 626, 627, 628, 0,
+	885, 629, 886, 632, 633, 0, 0, 634, 0, 635,
+	636, 0, 1619, 638, 639, 640, 0, 0, 641, 642,
+	887, 0, 643, 0, 888, 644, 645, 637, 646, 647,
+	648, 649, 650, 651, 652, 653, 654, 655, 656, 657,
+	0, 658, 659, 889, 660, 661, 662, 663, 664, 890,
+	665, 666, 667, 891, 668, 892, 669, 670, 671, 0,
+	672, 673, 674, 0, 675, 676, 677, 678, 679, 680,
+	681, 682, 683, 684, 893, 685, 686, 688, 687, 689,
+	690, 0, 691, 692, 0, 693, 694, 695, 0, 0,
+	0, 0, 0, 696, 697, 699, 0, 700, 701, 702,
+	703, 704, 705, 698, 706, 707, 708, 709, 710, 711,
+	712, 713, 0, 715, 716, 714, 717, 718, 0, 719,
+	720, 721, 722, 723, 894, 724, 0, 725, 726, 734,
+	735, 736, 727, 728, 730, 737, 729, 738, 739, 740,
+	741, 743, 742, 0, 745, 746, 744, 747, 748, 749,
+	750, 0, 751, 895, 752, 731, 732, 753, 754, 755,
+	0, 756, 757, 758, 759, 760, 761, 762, 763, 764,
+	896, 0, 766, 0, 765, 767, 768, 769, 770, 771,
+	772, 773, 775, 733, 776, 777, 778, 783, 784, 785,
+	897, 779, 780, 781, 782, 787, 898, 788, 789, 790,
+	791, 0, 792, 793, 0, 786, 774, 0, 794, 795,
+	796, 797, 798, 799, 800, 801, 802, 803, 0, 804,
+	899, 900, 901, 902, 0, 817, 0, 805, 807, 808,
+	809, 810, 903, 811, 812, 904, 0, 813, 814, 815,
+	816, 806, 819, 820, 818, 0, 0, 821, 822, 823,
+	824, 826, 828, 829, 830, 825, 827, 831, 0, 832,
+	0, 0, 833, 834, 835, 905, 906, 907, 0, 908,
+	838, 839, 836, 837, 840, 841, 844, 842, 843, 909,
+	847, 542, 848, 849, 850, 845, 846, 2065, 0, 359,
+	0, 851, 852, 910, 853, 854, 855, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 367, 368, 370, 369,
+	371, 372, 373, 374, 0, 375, 376, 0, 0, 0,
+	0, 0, 856, 0, 0, 0, 378, 0, 377, 0,
+	379, 380, 381, 0, 382, 383, 384, 385, 386, 387,
+	388, 389, 390, 857, 391, 858, 0, 392, 859, 393,
+	860, 0, 861, 394, 395, 396, 397, 398, 399, 400,
+	401, 402, 403, 404, 0, 0, 0, 405, 862, 863,
+	864, 0, 406, 407, 408, 409, 865, 0, 0, 0,
+	410, 411, 412, 413, 414, 415, 416, 417, 0, 0,
+	419, 420, 421, 418, 422, 423, 0, 424, 0, 425,
+	426, 427, 428, 429, 0, 430, 431, 0, 432, 433,
+	434, 0, 435, 436, 437, 0, 0, 0, 0, 0,
+	0, 0, 438, 439, 440, 441, 442, 0, 443, 445,
+	866, 867, 0, 448, 450, 444, 446, 0, 449, 447,
+	451, 452, 0, 453, 454, 455, 456, 457, 0, 0,
+	0, 458, 459, 460, 461, 0, 462, 463, 464, 466,
+	465, 0, 467, 468, 469, 0, 470, 471, 868, 472,
+	473, 474, 476, 478, 475, 477, 479, 480, 481, 482,
+	483, 869, 870, 484, 485, 0, 362, 0, 0, 0,
+	0, 0, 486, 487, 488, 871, 0, 0, 0, 489,
+	0, 491, 495, 496, 492, 493, 494, 497, 0, 490,
+	498, 499, 0, 0, 500, 501, 502, 872, 873, 503,
+	504, 505, 506, 507, 508, 509, 510, 511, 0, 512,
+	513, 874, 0, 875, 514, 0, 515, 516, 517, 518,
+	519, 520, 521, 2067, 877, 878, 630, 0, 522, 523,
+	524, 525, 0, 526, 527, 528, 529, 530, 531, 532,
+	0, 0, 0, 533, 534, 535, 536, 0, 364, 363,
+	365, 0, 879, 537, 631, 538, 539, 880, 881, 0,
+	882, 0, 540, 541, 544, 0, 883, 0, 543, 545,
+	546, 0, 547, 0, 0, 0, 548, 549, 550, 551,
+	552, 553, 554, 0, 555, 557, 556, 0, 559, 884,
+	558, 0, 560, 561, 0, 0, 562, 563, 564, 565,
+	566, 567, 572, 0, 0, 568, 569, 570, 571, 573,
+	574, 0, 575, 576, 578, 581, 577, 579, 580, 582,
+	583, 596, 597, 598, 584, 585, 586, 587, 588, 589,
+	590, 591, 592, 593, 594, 595, 600, 0, 599, 0,
+	0, 601, 602, 603, 604, 605, 606, 612, 615, 617,
+	618, 613, 614, 616, 619, 620, 621, 623, 624, 609,
+	610, 611, 0, 622, 607, 0, 608, 366, 0, 625,
+	626, 627, 628, 0, 885, 629, 886, 632, 633, 0,
+	0, 634, 0, 635, 636, 0, 1619, 638, 639, 640,
+	0, 0, 641, 642, 887, 0, 643, 0, 888, 644,
+	645, 637, 646, 647, 648, 649, 650, 651, 652, 653,
+	654, 655, 656, 657, 0, 658, 659, 889, 660, 661,
+	662, 663, 664, 890, 665, 666, 667, 891, 668, 892,
+	669, 670, 671, 0, 672, 673, 674, 0, 675, 676,
+	677, 678, 679, 680, 681, 682, 683, 684, 893, 685,
+	686, 688, 687, 689, 690, 0, 691, 692, 0, 693,
+	694, 695, 0, 0, 0, 0, 0, 696, 697, 699,
+	0, 700, 701, 702, 703, 704, 705, 698, 706, 707,
+	708, 709, 710, 711, 712, 713, 0, 715, 716, 714,
+	717, 718, 0, 719, 720, 721, 722, 723, 894, 724,
+	0, 725, 726, 734, 735, 736, 727, 728, 730, 737,
+	729, 738, 739, 740, 741, 743, 742, 0, 745, 746,
+	744, 747, 748, 749, 750, 0, 751, 895, 752, 731,
+	732, 753, 754, 755, 0, 756, 757, 758, 759, 760,
+	761, 762, 763, 764, 896, 0, 766, 0, 765, 767,
+	768, 769, 770, 771, 772, 773, 775, 733, 776, 777,
+	778, 783, 784, 785, 897, 779, 780, 781, 782, 787,
+	898, 788, 789, 790, 791, 0, 792, 793, 0, 786,
+	774, 0, 794, 795, 796, 797, 798, 799, 800, 801,
+	802, 803, 0, 804, 899, 900, 901, 902, 0, 817,
+	0, 805, 807, 808, 809, 810, 903, 811, 812, 904,
+	0, 813, 814, 815, 816, 806, 819, 820, 818, 0,
+	0, 821, 822, 823, 824, 826, 828, 829, 830, 825,
+	827, 831, 0, 832, 0, 0, 833, 834, 835, 905,
+	906, 907, 0, 908, 838, 839, 836, 837, 840, 841,
+	844, 842, 843, 909, 847, 542, 848, 849, 850, 845,
+	846, 1973, 0, 359, 0, 851, 852, 910, 853, 854,
+	855, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	367, 368, 370, 369, 371, 372, 373, 374, 0, 375,
+	376, 0, 0, 0, 0, 0, 856, 0, 0, 0,
+	378, 0, 377, 0, 379, 380, 381, 0, 382, 383,
+	384, 385, 386, 387, 388, 389, 390, 857, 391, 858,
+	0, 392, 859, 393, 860, 0, 861, 394, 395, 396,
+	397, 398, 399, 400, 401, 402, 403, 404, 0, 0,
+	0, 405, 862, 863, 864, 0, 406, 407, 408, 409,
+	865, 0, 0, 0, 410, 411, 412, 413, 414, 415,
+	416, 417, 0, 0, 419, 420, 421, 418, 422, 423,
+	0, 424, 0, 425, 426, 427, 428, 429, 0, 430,
+	431, 0, 432, 433, 434, 0, 435, 436, 437, 0,
+	0, 0, 0, 0, 0, 0, 438, 439, 440, 441,
+	442, 0, 443, 445, 866, 867, 0, 448, 450, 444,
+	446, 0, 449, 447, 451, 452, 0, 453, 454, 455,
+	456, 457, 0, 0, 0, 458, 459, 460, 461, 0,
+	462, 463, 464, 466, 465, 0, 467, 468, 469, 0,
+	470, 471, 868, 472, 473, 474, 476, 478, 475, 477,
+	479, 480, 481, 482, 483, 869, 870, 484, 485, 0,
+	362, 0, 0, 0, 0, 0, 486, 487, 488, 871,
+	0, 0, 0, 489, 0, 491, 495, 496, 492, 493,
+	494, 497, 0, 490, 498, 499, 0, 0, 500, 501,
+	502, 872, 873, 503, 504, 505, 506, 507, 508, 509,
+	510, 511, 0, 512, 513, 874, 0, 875, 514, 0,
+	515, 516, 517, 518, 519, 520, 521, 1975, 877, 878,
+	630, 0, 522, 523, 524, 525, 0, 526, 527, 528,
+	529, 530, 531, 532, 0, 0, 0, 533, 534, 535,
+	536, 0, 364, 363, 365, 0, 879, 537, 631, 538,
+	539, 880, 881, 0, 882, 0, 540, 541, 544, 0,
+	883, 0, 543, 545, 546, 0, 547, 0, 0, 0,
+	548, 549, 550, 551, 552, 553, 554, 0, 555, 557,
+	556, 0, 559, 884, 558, 0, 560, 561, 0, 0,
+	562, 563, 564, 565, 566, 567, 572, 0, 0, 568,
+	569, 570, 571, 573, 574, 0, 575, 576, 578, 581,
+	577, 579, 580, 582, 583, 596, 597, 598, 584, 585,
+	586, 587, 588, 589, 590, 591, 592, 593, 594, 595,
+	600, 0, 599, 0, 0, 601, 602, 603, 604, 605,
+	606, 612, 615, 617, 618, 613, 614, 616, 619, 620,
+	621, 623, 624, 609, 610, 611, 0, 622, 607, 0,
+	608, 366, 0, 625, 626, 627, 628, 0, 885, 629,
+	886, 632, 633, 0, 0, 634, 0, 635, 636, 0,
+	1619, 638, 639, 640, 0, 0, 641, 642, 887, 0,
+	643, 0, 888, 644, 645, 637, 646, 647, 648, 649,
+	650, 651, 652, 653, 654, 655, 656, 657, 0, 658,
+	659, 889, 660, 661, 662, 663, 664, 890, 665, 666,
+	667, 891, 668, 892, 669, 670, 671, 0, 672, 673,
+	674, 0, 675, 676, 677, 678, 679, 680, 681, 682,
+	683, 684, 893, 685, 686, 688, 687, 689, 690, 0,
+	691, 692, 0, 693, 694, 695, 0, 0, 0, 0,
+	0, 696, 697, 699, 0, 700, 701, 702, 703, 704,
+	705, 698, 706, 707, 708, 709, 710, 711, 712, 713,
+	0, 715, 716, 714, 717, 718, 0, 719, 720, 721,
+	722, 723, 894, 724, 0, 725, 726, 734, 735, 736,
+	727, 728, 730, 737, 729, 738, 739, 740, 741, 743,
+	742, 0, 745, 746, 744, 747, 748, 749, 750, 0,
+	751, 895, 752, 731, 732, 753, 754, 755, 0, 756,
+	757, 758, 759, 760, 761, 762, 763, 764, 896, 0,
+	766, 0, 765, 767, 768, 769, 770, 771, 772, 773,
+	775, 733, 776, 777, 778, 783, 784, 785, 897, 779,
+	780, 781, 782, 787, 898, 788, 789, 790, 791, 0,
+	792, 793, 0, 786, 774, 0, 794, 795, 796, 797,
+	798, 799, 800, 801, 802, 803, 0, 804, 899, 900,
+	901, 902, 0, 817, 0, 805, 807, 808, 809, 810,
+	903, 811, 812, 904, 0, 813, 814, 815, 816, 806,
+	819, 820, 818, 0, 0, 821, 822, 823, 824, 826,
+	828, 829, 830, 825, 827, 831, 0, 832, 0, 0,
+	833, 834, 835, 905, 906, 907, 0, 908, 838, 839,
+	836, 837, 840, 841, 844, 842, 843, 909, 847, 542,
+	848, 849, 850, 845, 846, 359, 0, 0, 0, 851,
+	852, 910, 853, 854, 855, 0, 0, 0, 0, 0,
+	0, 0, 367, 368, 370, 369, 371, 372, 373, 374,
+	0, 375, 376, 0, 0, 0, 0, 0, 856, 0,
+	0, 0, 378, 0, 377, 0, 379, 380, 381, 0,
+	382, 383, 384, 385, 386, 387, 388, 389, 390, 857,
+	391, 858, 0, 392, 859, 393, 860, 0, 861, 394,
+	395, 396, 397, 398, 399, 400, 401, 402, 403, 404,
+	0, 0, 0, 405, 862, 863, 864, 0, 406, 407,
+	408, 409, 865, 0, 0, 0, 410, 411, 412, 413,
+	414, 415, 416, 417, 0, 0, 419, 420, 421, 418,
+	422, 423, 0, 424, 0, 425, 426, 427, 428, 429,
+	0, 430, 431, 0, 432, 433, 434, 0, 435, 436,
+	437, 0, 0, 0, 0, 0, 0, 0, 438, 439,
+	440, 441, 442, 0, 443, 445, 866, 867, 0, 448,
+	450, 444, 446, 0, 449, 447, 451, 452, 0, 453,
+	454, 455, 456, 457, 0, 0, 0, 458, 459, 460,
+	461, 0, 462, 463, 464, 466, 465, 0, 467, 468,
+	469, 0, 470, 471, 868, 472, 473, 474, 476, 478,
+	475, 477, 479, 480, 481, 482, 483, 869, 870, 484,
+	485, 0, 362, 0, 0, 0, 0, 0, 486, 487,
+	488, 871, 0, 0, 0, 489, 0, 491, 495, 496,
+	492, 493, 494, 497, 0, 490, 498, 499, 0, 0,
+	500, 501, 502, 872, 873, 503, 504, 505, 506, 507,
+	508, 509, 510, 511, 0, 512, 513, 874, 0, 875,
+	514, 0, 515, 516, 517, 518, 519, 520, 521, 876,
+	877, 878, 630, 0, 522, 523, 524, 525, 0, 526,
+	527, 528, 529, 530, 531, 532, 0, 0, 0, 533,
+	534, 535, 536, 0, 364, 363, 365, 0, 879, 537,
+	631, 538, 539, 880, 881, 0, 882, 0, 540, 541,
+	544, 0, 883, 0, 543, 545, 546, 0, 547, 0,
+	0, 0, 548, 549, 550, 551, 552, 553, 554, 0,
+	555, 557, 556, 0, 559, 884, 558, 0, 560, 561,
+	0, 0, 562, 563, 564, 565, 566, 567, 572, 0,
+	0, 568, 569, 570, 571, 573, 574, 0, 575, 576,
+	578, 581, 577, 579, 580, 582, 583, 596, 597, 598,
+	584, 585, 586, 587, 588, 589, 590, 591, 592, 593,
+	594, 595, 600, 0, 599, 0, 0, 601, 602, 603,
+	604, 605, 606, 612, 615, 617, 618, 613, 614, 616,
+	619, 620, 621, 623, 624, 609, 610, 611, 0, 622,
+	607, 0, 608, 366, 0, 625, 626, 627, 628, 0,
+	885, 629, 886, 632, 633, 0, 0, 634, 0, 635,
+	636, 0, 1619, 638, 639, 640, 0, 0, 641, 642,
+	887, 0, 643, 0, 888, 644, 645, 637, 646, 647,
+	648, 649, 650, 651, 652, 653, 654, 655, 656, 657,
+	0, 658, 659, 889, 660, 661, 662, 663, 664, 890,
+	665, 666, 667, 891, 668, 892, 669, 670, 671, 0,
+	672, 673, 674, 0, 675, 676, 677, 678, 679, 680,
+	681, 682, 683, 684, 893, 685, 686, 688, 687, 689,
+	690, 0, 691, 692, 0, 693, 694, 695, 0, 0,
+	0, 0, 0, 696, 697, 699, 0, 700, 701, 702,
+	703, 704, 705, 698, 706, 707, 708, 709, 710, 711,
+	712, 713, 0, 715, 716, 714, 717, 718, 0, 719,
+	720, 721, 722, 723, 894, 724, 0, 725, 726, 734,
+	735, 736, 727, 728, 730, 737, 729, 738, 739, 740,
+	741, 743, 742, 0, 745, 746, 744, 747, 748, 749,
+	750, 0, 751, 895, 752, 731, 732, 753, 754, 755,
+	0, 756, 757, 758, 759, 760, 761, 762, 763, 764,
+	896, 0, 766, 0, 765, 767, 768, 769, 770, 771,
+	772, 773, 775, 733, 776, 777, 778, 783, 784, 785,
+	897, 779, 780, 781, 782, 787, 898, 788, 789, 790,
+	791, 0, 792, 793, 0, 786, 774, 0, 794, 795,
+	796, 797, 798, 799, 800, 801, 802, 803, 0, 804,
+	899, 900, 901, 902, 0, 817, 0, 805, 807, 808,
+	809, 810, 903, 811, 812, 904, 0, 813, 814, 815,
+	816, 806, 819, 820, 818, 0, 0, 821, 822, 823,
+	824, 826, 828, 829, 830, 825, 827, 831, 0, 832,
+	0, 0, 833, 834, 835, 905, 906, 907, 0, 908,
+	838, 839, 836, 837, 840, 841, 844, 842, 843, 909,
+	847, 542, 848, 849, 850, 845, 846, 359, 0, 0,
+	0, 851, 852, 910, 853, 854, 855, 0, 0, 0,
+	0, 0, 0, 0, 367, 368, 370, 369, 371, 372,
+	373, 374, 0, 375, 376, 0, 0, 0, 0, 0,
+	856, 0, 0, 0, 378, 0, 377, 0, 379, 380,
+	381, 0, 382, 383, 384, 385, 386, 387, 388, 389,
+	390, 857, 391, 858, 0, 392, 859, 393, 860, 0,
+	861, 394, 395, 396, 397, 398, 399, 400, 401, 402,
+	403, 404, 0, 0, 0, 405, 862, 863, 864, 0,
+	406, 407, 408, 409, 865, 0, 0, 0, 410, 411,
+	412, 413, 414, 415, 416, 417, 0, 0, 419, 420,
+	421, 418, 422, 423, 0, 424, 0, 425, 426, 427,
+	428, 429, 0, 430, 431, 0, 432, 433, 434, 0,
+	435, 436, 437, 0, 0, 0, 0, 0, 0, 0,
+	438, 439, 440, 441, 442, 0, 443, 445, 866, 867,
+	0, 448, 450, 444, 446, 0, 449, 447, 451, 452,
+	0, 453, 454, 455, 456, 457, 0, 0, 0, 458,
+	459, 460, 461, 0, 462, 463, 464, 466, 465, 0,
+	467, 468, 469, 0, 470, 471, 868, 472, 473, 474,
+	476, 478, 475, 477, 479, 480, 481, 482, 483, 869,
+	870, 484, 485, 0, 362, 0, 0, 0, 0, 0,
+	486, 487, 488, 871, 0, 0, 0, 489, 0, 491,
+	495, 496, 492, 493, 494, 497, 0, 490, 498, 499,
+	0, 0, 500, 501, 502, 872, 873, 503, 504, 505,
+	506, 507, 508, 509, 510, 511, 0, 512, 513, 874,
+	0, 875, 514, 0, 515, 516, 517, 518, 519, 520,
+	521, 876, 877, 878, 630, 0, 522, 523, 524, 525,
+	0, 526, 527, 528, 529, 530, 531, 532, 0, 0,
+	0, 533, 534, 535, 536, 0, 364, 363, 365, 0,
+	879, 537, 631, 538, 539, 880, 881, 0, 882, 0,
+	540, 541, 544, 0, 883, 0, 543, 545, 546, 0,
+	547, 0, 0, 0, 548, 549, 550, 551, 552, 553,
+	554, 0, 555, 557, 556, 0, 559, 884, 558, 0,
+	560, 561, 0, 0, 562, 563, 564, 565, 566, 567,
+	572, 0, 0, 568, 569, 570, 571, 573, 574, 0,
+	575, 576, 578, 581, 577, 579, 580, 582, 583, 596,
+	597, 598, 584, 585, 586, 587, 588, 589, 590, 591,
+	592, 593, 594, 595, 600, 0, 599, 0, 0, 601,
+	602, 603, 604, 605, 606, 612, 615, 617, 618, 613,
+	614, 616, 619, 620, 621, 623, 624, 609, 610, 611,
+	5176, 622, 607, 0, 608, 366, 0, 625, 626, 627,
+	628, 0, 885, 629, 886, 632, 633, 0, 0, 634,
+	0, 635, 636, 0, 0, 638, 639, 640, 0, 0,
+	641, 642, 887, 0, 643, 0, 888, 644, 645, 637,
+	646, 647, 648, 649, 650, 651, 652, 653, 654, 655,
+	656, 657, 0, 658, 659, 889, 660, 661, 662, 663,
+	664, 890, 665, 666, 667, 891, 668, 892, 669, 670,
+	671, 0, 672, 673, 674, 0, 675, 676, 677, 678,
+	679, 680, 681, 682, 683, 684, 893, 685, 686, 688,
+	687, 689, 690, 0, 691, 692, 0, 693, 694, 695,
+	0, 0, 0, 0, 0, 696, 697, 699, 0, 700,
+	701, 702, 703, 704, 705, 698, 706, 707, 708, 709,
+	710, 711, 712, 713, 0, 715, 716, 714, 717, 718,
+	0, 719, 720, 721, 722, 723, 894, 724, 0, 725,
+	726, 734, 735, 736, 727, 728, 730, 737, 729, 738,
+	739, 740, 741, 743, 742, 0, 745, 746, 744, 747,
+	748, 749, 750, 0, 751, 895, 752, 731, 732, 753,
+	754, 755, 0, 756, 757, 758, 759, 760, 761, 762,
+	763, 764, 896, 0, 766, 0, 765, 767, 768, 769,
+	770, 771, 772, 773, 775, 733, 776, 777, 778, 783,
+	784, 785, 897, 779, 780, 781, 782, 787, 898, 788,
+	789, 790, 791, 0, 792, 793, 0, 786, 774, 0,
+	794, 795, 796, 797, 798, 799, 800, 801, 802, 803,
+	0, 804, 899, 900, 901, 902, 0, 817, 0, 805,
+	807, 808, 809, 810, 903, 811, 812, 904, 0, 813,
+	814, 815, 816, 806, 819, 820, 818, 0, 0, 821,
+	822, 823, 824, 826, 828, 829, 830, 825, 827, 831,
+	0, 832, 0, 0, 833, 834, 835, 905, 906, 907,
+	0, 908, 838, 839, 836, 837, 840, 841, 844, 842,
+	843, 909, 847, 542, 848, 849, 850, 845, 846, 4669,
+	0, 359, 0, 851, 852, 910, 853, 854, 855, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 367, 368,
+	370, 369, 371, 372, 373, 374, 0, 375, 376, 0,
+	0, 0, 0, 0, 856, 0, 0, 0, 378, 0,
+	377, 0, 379, 380, 381, 0, 382, 383, 384, 385,
+	386, 387, 388, 389, 390, 857, 391, 858, 0, 392,
+	859, 393, 860, 0, 861, 394, 395, 396, 397, 398,
+	399, 400, 401, 402, 403, 404, 0, 0, 0, 405,
+	862, 863, 864, 0, 406, 407, 408, 409, 865, 0,
+	0, 0, 410, 411, 412, 413, 414, 415, 416, 417,
+	0, 0, 419, 420, 421, 418, 422, 423, 0, 424,
+	0, 425, 426, 427, 428, 429, 0, 430, 431, 0,
+	432, 433, 434, 0, 435, 436, 437, 0, 0, 0,
+	0, 0, 0, 0, 438, 439, 440, 441, 442, 0,
+	443, 445, 866, 867, 0, 448, 450, 444, 446, 0,
+	449, 447, 451, 452, 0, 453, 454, 455, 456, 457,
+	0, 0, 0, 458, 459, 460, 461, 0, 462, 463,
+	464, 466, 465, 0, 467, 468, 469, 0, 470, 471,
+	868, 472, 473, 474, 476, 478, 475, 477, 479, 480,
+	481, 482, 483, 869, 870, 484, 485, 0, 362, 0,
+	0, 0, 0, 0, 486, 487, 488, 871, 0, 0,
+	0, 489, 0, 491, 495, 496, 492, 493, 494, 497,
+	0, 490, 498, 499, 0, 0, 500, 501, 502, 872,
+	873, 503, 504, 505, 506, 507, 508, 509, 510, 511,
+	0, 512, 513, 874, 0, 875, 514, 0, 515, 516,
+	517, 518, 519, 520, 521, 4668, 877, 878, 630, 0,
+	522, 523, 524, 525, 0, 526, 527, 528, 529, 530,
+	531, 532, 0, 0, 0, 533, 534, 535, 536, 0,
+	364, 363, 365, 0, 879, 537, 631, 538, 539, 880,
+	881, 0, 882, 0, 540, 541, 544, 0, 883, 0,
+	543, 545, 546, 0, 547, 0, 0, 0, 548, 549,
+	550, 551, 552, 553, 554, 0, 555, 557, 556, 0,
+	559, 884, 558, 0, 560, 561, 0, 0, 562, 563,
+	564, 565, 566, 567, 572, 0, 0, 568, 569, 570,
+	571, 573, 574, 0, 575, 576, 578, 581, 577, 579,
+	580, 582, 583, 596, 597, 598, 584, 585, 586, 587,
+	588, 589, 590, 591, 592, 593, 594, 595, 600, 0,
+	599, 0, 0, 601, 602, 603, 604, 605, 606, 612,
+	615, 617, 618, 613, 614, 616, 619, 620, 621, 623,
+	624, 609, 610, 611, 0, 622, 607, 0, 608, 366,
+	0, 625, 626, 627, 628, 0, 885, 629, 886, 632,
+	633, 0, 0, 634, 0, 635, 636, 0, 0, 638,
+	639, 640, 0, 0, 641, 642, 887, 0, 643, 0,
+	888, 644, 645, 637, 646, 647, 648, 649, 650, 651,
+	652, 653, 654, 655, 656, 657, 0, 658, 659, 889,
+	660, 661, 662, 663, 664, 890, 665, 666, 667, 891,
+	668, 892, 669, 670, 671, 0, 672, 673, 674, 0,
+	675, 676, 677, 678, 679, 680, 681, 682, 683, 684,
+	893, 685, 686, 688, 687, 689, 690, 0, 691, 692,
+	0, 693, 694, 695, 0, 0, 0, 0, 0, 696,
+	697, 699, 0, 700, 701, 702, 703, 704, 705, 698,
+	706, 707, 708, 709, 710, 711, 712, 713, 0, 715,
+	716, 714, 717, 718, 0, 719, 720, 721, 722, 723,
+	894, 724, 0, 725, 726, 734, 735, 736, 727, 728,
+	730, 737, 729, 738, 739, 740, 741, 743, 742, 0,
+	745, 746, 744, 747, 748, 749, 750, 0, 751, 895,
+	752, 731, 732, 753, 754, 755, 0, 756, 757, 758,
+	759, 760, 761, 762, 763, 764, 896, 0, 766, 0,
+	765, 767, 768, 769, 770, 771, 772, 773, 775, 733,
+	776, 777, 778, 783, 784, 785, 897, 779, 780, 781,
+	782, 787, 898, 788, 789, 790, 791, 0, 792, 793,
+	0, 786, 774, 0, 794, 795, 796, 797, 798, 799,
+	800, 801, 802, 803, 0, 804, 899, 900, 901, 902,
+	0, 817, 0, 805, 807, 808, 809, 810, 903, 811,
+	812, 904, 0, 813, 814, 815, 816, 806, 819, 820,
+	818, 0, 0, 821, 822, 823, 824, 826, 828, 829,
+	830, 825, 827, 831, 0, 832, 0, 0, 833, 834,
+	835, 905, 906, 907, 0, 908, 838, 839, 836, 837,
+	840, 841, 844, 842, 843, 909, 847, 542, 848, 849,
+	850, 845, 846, 359, 0, 0, 0, 851, 852, 910,
+	853, 854, 855, 0, 0, 0, 0, 0, 0, 0,
+	367, 368, 370, 369, 371, 372, 373, 374, 0, 375,
+	376, 0, 0, 0, 0, 0, 856, 0, 0, 0,
+	378, 0, 377, 0, 379, 380, 381, 0, 382, 383,
+	384, 385, 386, 387, 388, 389, 390, 857, 391, 858,
+	0, 392, 859, 393, 860, 0, 861, 394, 395, 396,
+	397, 398, 399, 400, 401, 402, 403, 404, 0, 0,
+	0, 405, 862, 863, 864, 4403, 406, 407, 408, 409,
+	865, 0, 0, 4397, 410, 411, 412, 413, 414, 415,
+	416, 417, 0, 0, 419, 420, 421, 418, 422, 423,
+	4399, 424, 0, 425, 426, 427, 428, 429, 0, 430,
+	431, 0, 432, 433, 434, 0, 435, 436, 437, 0,
+	0, 0, 0, 0, 0, 0, 438, 439, 440, 441,
+	442, 0, 443, 445, 866, 867, 0, 448, 450, 444,
+	446, 0, 449, 447, 451, 452, 0, 453, 454, 455,
+	456, 457, 0, 0, 0, 458, 459, 460, 461, 0,
+	462, 463, 464, 466, 465, 0, 467, 468, 469, 0,
+	4407, 471, 868, 472, 473, 474, 476, 478, 475, 477,
+	479, 480, 481, 482, 483, 869, 870, 484, 485, 0,
+	0, 0, 0, 0, 0, 0, 486, 487, 488, 871,
+	0, 0, 0, 489, 0, 491, 495, 496, 492, 493,
+	494, 497, 4406, 490, 498, 499, 0, 0, 500, 501,
+	502, 872, 873, 503, 504, 505, 506, 507, 508, 509,
+	510, 511, 0, 512, 513, 874, 0, 875, 514, 0,
+	515, 516, 517, 518, 519, 520, 521, 4396, 877, 878,
+	630, 0, 522, 523, 524, 525, 0, 526, 527, 528,
+	529, 530, 531, 532, 0, 0, 0, 533, 534, 535,
+	536, 0, 0, 0, 0, 0, 879, 537, 631, 538,
+	539, 880, 881, 0, 882, 0, 540, 541, 544, 0,
+	883, 0, 543, 545, 546, 0, 547, 0, 0, 0,
+	548, 549, 550, 551, 552, 553, 554, 0, 555, 557,
+	556, 0, 559, 884, 558, 0, 560, 561, 0, 0,
+	562, 563, 564, 565, 566, 567, 572, 0, 0, 568,
+	569, 570, 571, 573, 574, 0, 575, 576, 578, 581,
+	577, 579, 580, 582, 583, 596, 597, 598, 584, 585,
+	586, 587, 588, 589, 590, 591, 592, 593, 594, 595,
+	600, 0, 599, 0, 0, 601, 602, 603, 604, 605,
+	606, 612, 615, 617, 618, 613, 614, 616, 619, 620,
+	621, 623, 624, 609, 610, 611, 0, 622, 607, 0,
+	608, 0, 0, 625, 626, 627, 628, 0, 885, 629,
+	886, 632, 633, 0, 0, 634, 0, 635, 636, 0,
+	0, 638, 639, 640, 0, 0, 641, 642, 887, 0,
+	643, 0, 888, 644, 645, 637, 646, 647, 648, 649,
+	650, 651, 652, 653, 654, 655, 656, 657, 0, 658,
+	659, 889, 660, 661, 662, 663, 664, 890, 665, 666,
+	667, 891, 668, 892, 669, 670, 671, 4405, 672, 673,
+	674, 0, 675, 676, 677, 678, 679, 680, 681, 682,
+	683, 684, 893, 685, 686, 688, 687, 689, 690, 0,
+	691, 692, 0, 693, 694, 695, 0, 0, 0, 0,
+	0, 696, 697, 699, 0, 700, 701, 702, 703, 704,
+	705, 698, 706, 707, 708, 709, 710, 711, 712, 713,
+	0, 715, 716, 714, 717, 718, 0, 719, 720, 721,
+	722, 723, 894, 724, 0, 725, 726, 734, 735, 736,
+	727, 728, 730, 737, 729, 738, 739, 740, 741, 743,
+	742, 0, 745, 746, 744, 747, 748, 749, 750, 0,
+	751, 895, 752, 731, 732, 753, 754, 755, 0, 756,
+	757, 758, 759, 760, 761, 762, 763, 764, 896, 0,
+	766, 0, 765, 767, 768, 769, 770, 771, 772, 773,
+	775, 733, 776, 777, 778, 783, 784, 785, 897, 779,
+	780, 781, 782, 787, 898, 788, 789, 790, 791, 0,
+	792, 793, 0, 786, 774, 0, 794, 795, 796, 797,
+	798, 799, 800, 801, 802, 803, 0, 804, 899, 900,
+	901, 902, 0, 817, 0, 805, 807, 808, 809, 810,
+	903, 811, 812, 904, 0, 813, 814, 815, 816, 806,
+	819, 820, 818, 0, 4404, 821, 822, 823, 824, 826,
+	828, 829, 830, 825, 827, 831, 0, 832, 0, 0,
+	833, 834, 835, 905, 906, 907, 0, 908, 838, 839,
+	836, 837, 840, 841, 844, 842, 843, 909, 847, 542,
+	848, 849, 850, 845, 846, 3154, 0, 359, 0, 851,
+	852, 910, 853, 854, 855, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 367, 368, 370, 369, 371, 372,
+	373, 374, 0, 375, 376, 0, 0, 0, 0, 0,
+	856, 0, 0, 0, 378, 0, 377, 0, 379, 380,
+	381, 0, 382, 383, 384, 385, 386, 387, 388, 389,
+	390, 857, 391, 858, 0, 392, 859, 393, 860, 0,
+	861, 394, 395, 396, 397, 398, 399, 400, 401, 402,
+	403, 404, 0, 0, 0, 405, 862, 863, 864, 0,
+	406, 407, 408, 409, 865, 0, 0, 0, 410, 411,
+	412, 413, 414, 415, 416, 417, 0, 0, 419, 420,
+	421, 418, 422, 423, 0, 424, 0, 425, 426, 427,
+	428, 429, 0, 430, 431, 0, 432, 433, 434, 0,
+	435, 436, 437, 0, 0, 0, 0, 0, 0, 0,
+	438, 439, 440, 441, 442, 0, 443, 445, 866, 867,
+	0, 448, 450, 444, 446, 0, 449, 447, 451, 452,
+	0, 453, 454, 455, 456, 457, 0, 0, 0, 458,
+	459, 460, 461, 0, 462, 463, 464, 466, 465, 0,
+	467, 468, 469, 0, 470, 471, 868, 472, 473, 474,
+	476, 478, 475, 477, 479, 480, 481, 482, 483, 869,
+	870, 484, 485, 0, 362, 0, 0, 0, 0, 0,
+	486, 487, 488, 871, 0, 0, 0, 489, 0, 491,
+	495, 496, 492, 493, 494, 497, 0, 490, 498, 499,
+	0, 0, 500, 501, 502, 872, 873, 503, 504, 505,
+	506, 507, 508, 509, 510, 511, 0, 512, 513, 874,
+	0, 875, 514, 0, 515, 516, 517, 518, 519, 520,
+	521, 876, 877, 878, 630, 0, 522, 523, 524, 525,
+	0, 526, 527, 528, 529, 530, 531, 532, 0, 0,
+	0, 533, 534, 535, 536, 0, 364, 363, 365, 0,
+	879, 537, 631, 538, 539, 880, 881, 0, 882, 0,
+	540, 541, 544, 0, 883, 0, 543, 545, 546, 0,
+	547, 0, 0, 0, 548, 549, 550, 551, 552, 553,
+	554, 0, 555, 557, 556, 0, 559, 884, 558, 0,
+	560, 561, 0, 0, 562, 563, 564, 565, 566, 567,
+	572, 0, 0, 568, 569, 570, 571, 573, 574, 0,
+	575, 576, 578, 581, 577, 579, 580, 582, 583, 596,
+	597, 598, 584, 585, 586, 587, 588, 589, 590, 591,
+	592, 593, 594, 595, 600, 0, 599, 0, 0, 601,
+	602, 603, 604, 605, 606, 612, 615, 617, 618, 613,
+	614, 616, 619, 620, 621, 623, 624, 609, 610, 611,
+	0, 622, 607, 0, 608, 366, 0, 625, 626, 627,
+	628, 0, 885, 629, 886, 632, 633, 0, 0, 634,
+	0, 635, 636, 0, 0, 638, 639, 640, 0, 0,
+	641, 642, 887, 0, 643, 0, 888, 644, 645, 637,
+	646, 647, 648, 649, 650, 651, 652, 653, 654, 655,
+	656, 657, 0, 658, 659, 889, 660, 661, 662, 663,
+	664, 890, 665, 666, 667, 891, 668, 892, 669, 670,
+	671, 0, 672, 673, 674, 0, 675, 676, 677, 678,
+	679, 680, 681, 682, 683, 684, 893, 685, 686, 688,
+	687, 689, 690, 0, 691, 692, 0, 693, 694, 695,
+	0, 0, 0, 0, 0, 696, 697, 699, 0, 700,
+	701, 702, 703, 704, 705, 698, 706, 707, 708, 709,
+	710, 711, 712, 713, 0, 715, 716, 714, 717, 718,
+	0, 719, 720, 721, 722, 723, 894, 724, 0, 725,
+	726, 734, 735, 736, 727, 728, 730, 737, 729, 738,
+	739, 740, 741, 743, 742, 0, 745, 746, 744, 747,
+	748, 749, 750, 0, 751, 895, 752, 731, 732, 753,
+	754, 755, 0, 756, 757, 758, 759, 760, 761, 762,
+	763, 764, 896, 0, 766, 0, 765, 767, 768, 769,
+	770, 771, 772, 773, 775, 733, 776, 777, 778, 783,
+	784, 785, 897, 779, 780, 781, 782, 787, 898, 788,
+	789, 790, 791, 0, 792, 793, 0, 786, 774, 0,
+	794, 795, 796, 797, 798, 799, 800, 801, 802, 803,
+	0, 804, 899, 900, 901, 902, 0, 817, 0, 805,
+	807, 808, 809, 810, 903, 811, 812, 904, 0, 813,
+	814, 815, 816, 806, 819, 820, 818, 0, 0, 821,
+	822, 823, 824, 826, 828, 829, 830, 825, 827, 831,
+	0, 832, 0, 0, 833, 834, 835, 905, 906, 907,
+	0, 908, 838, 839, 836, 837, 840, 841, 844, 842,
+	843, 909, 847, 542, 848, 849, 850, 845, 846, 3101,
+	0, 359, 0, 851, 852, 910, 853, 854, 855, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 367, 368,
+	370, 369, 371, 372, 373, 374, 0, 375, 376, 0,
+	0, 0, 0, 0, 856, 0, 0, 0, 378, 0,
+	377, 0, 379, 380, 381, 0, 382, 383, 384, 385,
+	386, 387, 388, 389, 390, 857, 391, 858, 0, 392,
+	859, 393, 860, 0, 861, 394, 395, 396, 397, 398,
+	399, 400, 401, 402, 403, 404, 0, 0, 0, 405,
+	862, 863, 864, 0, 406, 407, 408, 409, 865, 0,
+	0, 0, 410, 411, 412, 413, 414, 415, 416, 417,
+	0, 0, 419, 420, 421, 418, 422, 423, 0, 424,
+	0, 425, 426, 427, 428, 429, 0, 430, 431, 0,
+	432, 433, 434, 0, 435, 436, 437, 0, 0, 0,
+	0, 0, 0, 0, 438, 439, 440, 441, 442, 0,
+	443, 445, 866, 867, 0, 448, 450, 444, 446, 0,
+	449, 447, 451, 452, 0, 453, 454, 455, 456, 457,
+	0, 0, 0, 458, 459, 460, 461, 0, 462, 463,
+	464, 466, 465, 0, 467, 468, 469, 0, 470, 471,
+	868, 472, 473, 474, 476, 478, 475, 477, 479, 480,
+	481, 482, 483, 869, 870, 484, 485, 0, 362, 0,
+	0, 0, 0, 0, 486, 487, 488, 871, 0, 0,
+	0, 489, 0, 491, 495, 496, 492, 493, 494, 497,
+	0, 490, 498, 499, 0, 0, 500, 501, 502, 872,
+	873, 503, 504, 505, 506, 507, 508, 509, 510, 511,
+	0, 512, 513, 874, 0, 875, 514, 0, 515, 516,
+	517, 518, 519, 520, 521, 3100, 877, 878, 630, 0,
+	522, 523, 524, 525, 0, 526, 527, 528, 529, 530,
+	531, 532, 0, 0, 0, 533, 534, 535, 536, 0,
+	364, 363, 365, 0, 879, 537, 631, 538, 539, 880,
+	881, 0, 882, 0, 540, 541, 544, 0, 883, 0,
+	543, 545, 546, 0, 547, 0, 0, 0, 548, 549,
+	550, 551, 552, 553, 554, 0, 555, 557, 556, 0,
+	559, 884, 558, 0, 560, 561, 0, 0, 562, 563,
+	564, 565, 566, 567, 572, 0, 0, 568, 569, 570,
+	571, 573, 574, 0, 575, 576, 578, 581, 577, 579,
+	580, 582, 583, 596, 597, 598, 584, 585, 586, 587,
+	588, 589, 590, 591, 592, 593, 594, 595, 600, 0,
+	599, 0, 0, 601, 602, 603, 604, 605, 606, 612,
+	615, 617, 618, 613, 614, 616, 619, 620, 621, 623,
+	624, 609, 610, 611, 0, 622, 607, 0, 608, 366,
+	0, 625, 626, 627, 628, 0, 885, 629, 886, 632,
+	633, 0, 0, 634, 0, 635, 636, 0, 0, 638,
+	639, 640, 0, 0, 641, 642, 887, 0, 643, 0,
+	888, 644, 645, 637, 646, 647, 648, 649, 650, 651,
+	652, 653, 654, 655, 656, 657, 0, 658, 659, 889,
+	660, 661, 662, 663, 664, 890, 665, 666, 667, 891,
+	668, 892, 669, 670, 671, 0, 672, 673, 674, 0,
+	675, 676, 677, 678, 679, 680, 681, 682, 683, 684,
+	893, 685, 686, 688, 687, 689, 690, 0, 691, 692,
+	0, 693, 694, 695, 0, 0, 0, 0, 0, 696,
+	697, 699, 0, 700, 701, 702, 703, 704, 705, 698,
+	706, 707, 708, 709, 710, 711, 712, 713, 0, 715,
+	716, 714, 717, 718, 0, 719, 720, 721, 722, 723,
+	894, 724, 0, 725, 726, 734, 735, 736, 727, 728,
+	730, 737, 729, 738, 739, 740, 741, 743, 742, 0,
+	745, 746, 744, 747, 748, 749, 750, 0, 751, 895,
+	752, 731, 732, 753, 754, 755, 0, 756, 757, 758,
+	759, 760, 761, 762, 763, 764, 896, 0, 766, 0,
+	765, 767, 768, 769, 770, 771, 772, 773, 775, 733,
+	776, 777, 778, 783, 784, 785, 897, 779, 780, 781,
+	782, 787, 898, 788, 789, 790, 791, 0, 792, 793,
+	0, 786, 774, 0, 794, 795, 796, 797, 798, 799,
+	800, 801, 802, 803, 0, 804, 899, 900, 901, 902,
+	0, 817, 0, 805, 807, 808, 809, 810, 903, 811,
+	812, 904, 0, 813, 814, 815, 816, 806, 819, 820,
+	818, 0, 0, 821, 822, 823, 824, 826, 828, 829,
+	830, 825, 827, 831, 0, 832, 0, 0, 833, 834,
+	835, 905, 906, 907, 0, 908, 838, 839, 836, 837,
+	840, 841, 844, 842, 843, 909, 847, 542, 848, 849,
+	850, 845, 846, 3085, 0, 359, 0, 851, 852, 910,
+	853, 854, 855, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 367, 368, 370, 369, 371, 372, 373, 374,
+	0, 375, 376, 0, 0, 0, 0, 0, 856, 0,
+	0, 0, 378, 0, 377, 0, 379, 380, 381, 0,
+	382, 383, 384, 385, 386, 387, 388, 389, 390, 857,
+	391, 858, 0, 392, 859, 393, 860, 0, 861, 394,
+	395, 396, 397, 398, 399, 400, 401, 402, 403, 404,
+	0, 0, 0, 405, 862, 863, 864, 0, 406, 407,
+	408, 409, 865, 0, 0, 0, 410, 411, 412, 413,
+	414, 415, 416, 417, 0, 0, 419, 420, 421, 418,
+	422, 423, 0, 424, 0, 425, 426, 427, 428, 429,
+	0, 430, 431, 0, 432, 433, 434, 0, 435, 436,
+	437, 0, 0, 0, 0, 0, 0, 0, 438, 439,
+	440, 441, 442, 0, 443, 445, 866, 867, 0, 448,
+	450, 444, 446, 0, 449, 447, 451, 452, 0, 453,
+	454, 455, 456, 457, 0, 0, 0, 458, 459, 460,
+	461, 0, 462, 463, 464, 466, 465, 0, 467, 468,
+	469, 0, 470, 471, 868, 472, 473, 474, 476, 478,
+	475, 477, 479, 480, 481, 482, 483, 869, 870, 484,
+	485, 0, 362, 0, 0, 0, 0, 0, 486, 487,
+	488, 871, 0, 0, 0, 489, 0, 491, 495, 496,
+	492, 493, 494, 497, 0, 490, 498, 499, 0, 0,
+	500, 501, 502, 872, 873, 503, 504, 505, 506, 507,
+	508, 509, 510, 511, 0, 512, 513, 874, 0, 875,
+	514, 0, 515, 516, 517, 518, 519, 520, 521, 3087,
+	877, 878, 630, 0, 522, 523, 524, 525, 0, 526,
+	527, 528, 529, 530, 531, 532, 0, 0, 0, 533,
+	534, 535, 536, 0, 364, 363, 365, 0, 879, 537,
+	631, 538, 539, 880, 881, 0, 882, 0, 540, 541,
+	544, 0, 883, 0, 543, 545, 546, 0, 547, 0,
+	0, 0, 548, 549, 550, 551, 552, 553, 554, 0,
+	555, 557, 556, 0, 559, 884, 558, 0, 560, 561,
+	0, 0, 562, 563, 564, 565, 566, 567, 572, 0,
+	0, 568, 569, 570, 571, 573, 574, 0, 575, 576,
+	578, 581, 577, 579, 580, 582, 583, 596, 597, 598,
+	584, 585, 586, 587, 588, 589, 590, 591, 592, 593,
+	594, 595, 600, 0, 599, 0, 0, 601, 602, 603,
+	604, 605, 606, 612, 615, 617, 618, 613, 614, 616,
+	619, 620, 621, 623, 624, 609, 610, 611, 0, 622,
+	607, 0, 608, 366, 0, 625, 626, 627, 628, 0,
+	885, 629, 886, 632, 633, 0, 0, 634, 0, 635,
+	636, 0, 0, 638, 639, 640, 0, 0, 641, 642,
+	887, 0, 643, 0, 888, 644, 645, 637, 646, 647,
+	648, 649, 650, 651, 652, 653, 654, 655, 656, 657,
+	0, 658, 659, 889, 660, 661, 662, 663, 664, 890,
+	665, 666, 667, 891, 668, 892, 669, 670, 671, 0,
+	672, 673, 674, 0, 675, 676, 677, 678, 679, 680,
+	681, 682, 683, 684, 893, 685, 686, 688, 687, 689,
+	690, 0, 691, 692, 0, 693, 694, 695, 0, 0,
+	0, 0, 0, 696, 697, 699, 0, 700, 701, 702,
+	703, 704, 705, 698, 706, 707, 708, 709, 710, 711,
+	712, 713, 0, 715, 716, 714, 717, 718, 0, 719,
+	720, 721, 722, 723, 894, 724, 0, 725, 726, 734,
+	735, 736, 727, 728, 730, 737, 729, 738, 739, 740,
+	741, 743, 742, 0, 745, 746, 744, 747, 748, 749,
+	750, 0, 751, 895, 752, 731, 732, 753, 754, 755,
+	0, 756, 757, 758, 759, 760, 761, 762, 763, 764,
+	896, 0, 766, 0, 765, 767, 768, 769, 770, 771,
+	772, 773, 775, 733, 776, 777, 778, 783, 784, 785,
+	897, 779, 780, 781, 782, 787, 898, 788, 789, 790,
+	791, 0, 792, 793, 0, 786, 774, 0, 794, 795,
+	796, 797, 798, 799, 800, 801, 802, 803, 0, 804,
+	899, 900, 901, 902, 0, 817, 0, 805, 807, 808,
+	809, 810, 903, 811, 812, 904, 0, 813, 814, 815,
+	816, 806, 819, 820, 818, 0, 0, 821, 822, 823,
+	824, 826, 828, 829, 830, 825, 827, 831, 0, 832,
+	0, 0, 833, 834, 835, 905, 906, 907, 0, 908,
+	838, 839, 836, 837, 840, 841, 844, 842, 843, 909,
+	847, 542, 848, 849, 850, 845, 846, 3075, 0, 359,
+	0, 851, 852, 910, 853, 854, 855, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 367, 368, 370, 369,
+	371, 372, 373, 374, 0, 375, 376, 0, 0, 0,
+	0, 0, 856, 0, 0, 0, 378, 0, 377, 0,
+	379, 380, 381, 0, 382, 383, 384, 385, 386, 387,
+	388, 389, 390, 857, 391, 858, 0, 392, 859, 393,
+	860, 0, 861, 394, 395, 396, 397, 398, 399, 400,
+	401, 402, 403, 404, 0, 0, 0, 405, 862, 863,
+	864, 0, 406, 407, 408, 409, 865, 0, 0, 0,
+	410, 411, 412, 413, 414, 415, 416, 417, 0, 0,
+	419, 420, 421, 418, 422, 423, 0, 424, 0, 425,
+	426, 427, 428, 429, 0, 430, 431, 0, 432, 433,
+	434, 0, 435, 436, 437, 0, 0, 0, 0, 0,
+	0, 0, 438, 439, 440, 441, 442, 0, 443, 445,
+	866, 867, 0, 448, 450, 444, 446, 0, 449, 447,
+	451, 452, 0, 453, 454, 455, 456, 457, 0, 0,
+	0, 458, 459, 460, 461, 0, 462, 463, 464, 466,
+	465, 0, 467, 468, 469, 0, 470, 471, 868, 472,
+	473, 474, 476, 478, 475, 477, 479, 480, 481, 482,
+	483, 869, 870, 484, 485, 0, 362, 0, 0, 0,
+	0, 0, 486, 487, 488, 871, 0, 0, 0, 489,
+	0, 491, 495, 496, 492, 493, 494, 497, 0, 490,
+	498, 499, 0, 0, 500, 501, 502, 872, 873, 503,
+	504, 505, 506, 507, 508, 509, 510, 511, 0, 512,
+	513, 874, 0, 875, 514, 0, 515, 516, 517, 518,
+	519, 520, 521, 876, 877, 878, 630, 0, 522, 523,
+	524, 525, 0, 526, 527, 528, 529, 530, 531, 532,
+	0, 0, 0, 533, 534, 535, 536, 0, 364, 363,
+	365, 0, 879, 537, 631, 538, 539, 880, 881, 0,
+	882, 0, 540, 541, 544, 0, 883, 0, 543, 545,
+	546, 0, 547, 0, 0, 0, 548, 549, 550, 551,
+	552, 553, 554, 0, 555, 557, 556, 0, 559, 884,
+	558, 0, 560, 561, 0, 0, 562, 563, 564, 565,
+	566, 567, 572, 0, 0, 568, 569, 570, 571, 573,
+	574, 0, 575, 576, 578, 581, 577, 579, 580, 582,
+	583, 596, 597, 598, 584, 585, 586, 587, 588, 589,
+	590, 591, 592, 593, 594, 595, 600, 0, 599, 0,
+	0, 601, 602, 603, 604, 605, 606, 612, 615, 617,
+	618, 613, 614, 616, 619, 620, 621, 623, 624, 609,
+	610, 611, 0, 622, 607, 0, 608, 366, 0, 625,
+	626, 627, 628, 0, 885, 629, 886, 632, 633, 0,
+	0, 634, 0, 635, 636, 0, 0, 638, 639, 640,
+	0, 0, 641, 642, 887, 0, 643, 0, 888, 644,
+	645, 637, 646, 647, 648, 649, 650, 651, 652, 653,
+	654, 655, 656, 657, 0, 658, 659, 889, 660, 661,
+	662, 663, 664, 890, 665, 666, 667, 891, 668, 892,
+	669, 670, 671, 0, 672, 673, 674, 0, 675, 676,
+	677, 678, 679, 680, 681, 682, 683, 684, 893, 685,
+	686, 688, 687, 689, 690, 0, 691, 692, 0, 693,
+	694, 695, 0, 0, 0, 0, 0, 696, 697, 699,
+	0, 700, 701, 702, 703, 704, 705, 698, 706, 707,
+	708, 709, 710, 711, 712, 713, 0, 715, 716, 714,
+	717, 718, 0, 719, 720, 721, 722, 723, 894, 724,
+	0, 725, 726, 734, 735, 736, 727, 728, 730, 737,
+	729, 738, 739, 740, 741, 743, 742, 0, 745, 746,
+	744, 747, 748, 749, 750, 0, 751, 895, 752, 731,
+	732, 753, 754, 755, 0, 756, 757, 758, 759, 760,
+	761, 762, 763, 764, 896, 0, 766, 0, 765, 767,
+	768, 769, 770, 771, 772, 773, 775, 733, 776, 777,
+	778, 783, 784, 785, 897, 779, 780, 781, 782, 787,
+	898, 788, 789, 790, 791, 0, 792, 793, 0, 786,
+	774, 0, 794, 795, 796, 797, 798, 799, 800, 801,
+	802, 803, 0, 804, 899, 900, 901, 902, 0, 817,
+	0, 805, 807, 808, 809, 810, 903, 811, 812, 904,
+	0, 813, 814, 815, 816, 806, 819, 820, 818, 0,
+	0, 821, 822, 823, 824, 826, 828, 829, 830, 825,
+	827, 831, 0, 832, 0, 0, 833, 834, 835, 905,
+	906, 907, 0, 908, 838, 839, 836, 837, 840, 841,
+	844, 842, 843, 909, 847, 542, 848, 849, 850, 845,
+	846, 3072, 0, 359, 0, 851, 852, 910, 853, 854,
+	855, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	367, 368, 370, 369, 371, 372, 373, 374, 0, 375,
+	376, 0, 0, 0, 0, 0, 856, 0, 0, 0,
+	378, 0, 377, 0, 379, 380, 381, 0, 382, 383,
+	384, 385, 386, 387, 388, 389, 390, 857, 391, 858,
+	0, 392, 859, 393, 860, 0, 861, 394, 395, 396,
+	397, 398, 399, 400, 401, 402, 403, 404, 0, 0,
+	0, 405, 862, 863, 864, 0, 406, 407, 408, 409,
+	865, 0, 0, 0, 410, 411, 412, 413, 414, 415,
+	416, 417, 0, 0, 419, 420, 421, 418, 422, 423,
+	0, 424, 0, 425, 426, 427, 428, 429, 0, 430,
+	431, 0, 432, 433, 434, 0, 435, 436, 437, 0,
+	0, 0, 0, 0, 0, 0, 438, 439, 440, 441,
+	442, 0, 443, 445, 866, 867, 0, 448, 450, 444,
+	446, 0, 449, 447, 451, 452, 0, 453, 454, 455,
+	456, 457, 0, 0, 0, 458, 459, 460, 461, 0,
+	462, 463, 464, 466, 465, 0, 467, 468, 469, 0,
+	470, 471, 868, 472, 473, 474, 476, 478, 475, 477,
+	479, 480, 481, 482, 483, 869, 870, 484, 485, 0,
+	362, 0, 0, 0, 0, 0, 486, 487, 488, 871,
+	0, 0, 0, 489, 0, 491, 495, 496, 492, 493,
+	494, 497, 0, 490, 498, 499, 0, 0, 500, 501,
+	502, 872, 873, 503, 504, 505, 506, 507, 508, 509,
+	510, 511, 0, 512, 513, 874, 0, 875, 514, 0,
+	515, 516, 517, 518, 519, 520, 521, 876, 877, 878,
+	630, 0, 522, 523, 524, 525, 0, 526, 527, 528,
+	529, 530, 531, 532, 0, 0, 0, 533, 534, 535,
+	536, 0, 364, 363, 365, 0, 879, 537, 631, 538,
+	539, 880, 881, 0, 882, 0, 540, 541, 544, 0,
+	883, 0, 543, 545, 546, 0, 547, 0, 0, 0,
+	548, 549, 550, 551, 552, 553, 554, 0, 555, 557,
+	556, 0, 559, 884, 558, 0, 560, 561, 0, 0,
+	562, 563, 564, 565, 566, 567, 572, 0, 0, 568,
+	569, 570, 571, 573, 574, 0, 575, 576, 578, 581,
+	577, 579, 580, 582, 583, 596, 597, 598, 584, 585,
+	586, 587, 588, 589, 590, 591, 592, 593, 594, 595,
+	600, 0, 599, 0, 0, 601, 602, 603, 604, 605,
+	606, 612, 615, 617, 618, 613, 614, 616, 619, 620,
+	621, 623, 624, 609, 610, 611, 0, 622, 607, 0,
+	608, 366, 0, 625, 626, 627, 628, 0, 885, 629,
+	886, 632, 633, 0, 0, 634, 0, 635, 636, 0,
+	0, 638, 639, 640, 0, 0, 641, 642, 887, 0,
+	643, 0, 888, 644, 645, 637, 646, 647, 648, 649,
+	650, 651, 652, 653, 654, 655, 656, 657, 0, 658,
+	659, 889, 660, 661, 662, 663, 664, 890, 665, 666,
+	667, 891, 668, 892, 669, 670, 671, 0, 672, 673,
+	674, 0, 675, 676, 677, 678, 679, 680, 681, 682,
+	683, 684, 893, 685, 686, 688, 687, 689, 690, 0,
+	691, 692, 0, 693, 694, 695, 0, 0, 0, 0,
+	0, 696, 697, 699, 0, 700, 701, 702, 703, 704,
+	705, 698, 706, 707, 708, 709, 710, 711, 712, 713,
+	0, 715, 716, 714, 717, 718, 0, 719, 720, 721,
+	722, 723, 894, 724, 0, 725, 726, 734, 735, 736,
+	727, 728, 730, 737, 729, 738, 739, 740, 741, 743,
+	742, 0, 745, 746, 744, 747, 748, 749, 750, 0,
+	751, 895, 752, 731, 732, 753, 754, 755, 0, 756,
+	757, 758, 759, 760, 761, 762, 763, 764, 896, 0,
+	766, 0, 765, 767, 768, 769, 770, 771, 772, 773,
+	775, 733, 776, 777, 778, 783, 784, 785, 897, 779,
+	780, 781, 782, 787, 898, 788, 789, 790, 791, 0,
+	792, 793, 0, 786, 774, 0, 794, 795, 796, 797,
+	798, 799, 800, 801, 802, 803, 0, 804, 899, 900,
+	901, 902, 0, 817, 0, 805, 807, 808, 809, 810,
+	903, 811, 812, 904, 0, 813, 814, 815, 816, 806,
+	819, 820, 818, 0, 0, 821, 822, 823, 824, 826,
+	828, 829, 830, 825, 827, 831, 0, 832, 0, 0,
+	833, 834, 835, 905, 906, 907, 0, 908, 838, 839,
+	836, 837, 840, 841, 844, 842, 843, 909, 847, 542,
+	848, 849, 850, 845, 846, 359, 0, 0, 0, 851,
+	852, 910, 853, 854, 855, 0, 0, 0, 0, 0,
+	0, 0, 367, 368, 370, 369, 371, 372, 373, 374,
+	0, 375, 376, 0, 0, 0, 0, 0, 856, 0,
+	0, 0, 378, 0, 377, 0, 379, 380, 381, 0,
+	382, 383, 384, 385, 386, 387, 388, 389, 390, 857,
+	391, 858, 0, 392, 859, 393, 860, 0, 861, 394,
+	395, 396, 397, 398, 399, 400, 401, 402, 403, 404,
+	0, 0, 0, 405, 862, 863, 864, 0, 406, 407,
+	408, 409, 865, 0, 0, 0, 410, 411, 412, 413,
+	414, 415, 416, 417, 0, 0, 419, 420, 421, 418,
+	422, 423, 0, 424, 0, 425, 426, 427, 428, 429,
+	0, 430, 431, 0, 432, 433, 434, 0, 435, 436,
+	437, 0, 0, 0, 0, 0, 0, 0, 438, 439,
+	440, 441, 442, 0, 443, 445, 866, 867, 0, 448,
+	450, 444, 446, 0, 449, 447, 451, 452, 0, 453,
+	454, 455, 456, 457, 0, 0, 0, 458, 459, 460,
+	461, 0, 462, 463, 464, 466, 465, 0, 467, 468,
+	469, 0, 470, 471, 868, 472, 473, 474, 476, 478,
+	475, 477, 479, 480, 481, 482, 483, 869, 870, 484,
+	485, 0, 362, 0, 0, 0, 0, 0, 486, 487,
+	488, 871, 0, 0, 0, 489, 0, 491, 495, 496,
+	492, 493, 494, 497, 0, 490, 498, 499, 0, 0,
+	500, 501, 502, 872, 873, 503, 504, 505, 506, 507,
+	508, 509, 510, 511, 0, 512, 513, 874, 0, 875,
+	514, 0, 515, 516, 517, 518, 519, 520, 521, 3036,
+	877, 878, 630, 0, 522, 523, 524, 525, 0, 526,
+	527, 528, 529, 530, 531, 532, 0, 0, 0, 533,
+	534, 535, 536, 0, 364, 363, 365, 0, 879, 537,
+	631, 538, 539, 880, 881, 0, 882, 0, 540, 541,
+	544, 0, 883, 0, 543, 545, 546, 0, 547, 0,
+	0, 0, 548, 549, 550, 551, 552, 553, 554, 0,
+	555, 557, 556, 0, 559, 884, 558, 0, 560, 561,
+	0, 0, 562, 563, 564, 565, 566, 567, 572, 0,
+	0, 568, 569, 570, 571, 573, 574, 0, 575, 576,
+	578, 581, 577, 579, 580, 582, 583, 596, 597, 598,
+	584, 585, 586, 587, 588, 589, 590, 591, 592, 593,
+	594, 595, 600, 0, 599, 0, 0, 601, 602, 603,
+	604, 605, 606, 612, 615, 617, 618, 613, 614, 616,
+	619, 620, 621, 623, 624, 609, 610, 611, 0, 622,
+	607, 0, 608, 366, 0, 625, 626, 627, 628, 0,
+	885, 629, 886, 632, 633, 0, 0, 634, 0, 635,
+	636, 0, 1619, 638, 639, 640, 0, 0, 641, 642,
+	887, 0, 643, 0, 888, 644, 645, 637, 646, 647,
+	648, 649, 650, 651, 652, 653, 654, 655, 656, 657,
+	0, 658, 659, 889, 660, 661, 662, 663, 664, 890,
+	665, 666, 667, 891, 668, 892, 669, 670, 671, 0,
+	672, 673, 674, 0, 675, 676, 677, 678, 679, 680,
+	681, 682, 683, 684, 893, 685, 686, 688, 687, 689,
+	690, 0, 691, 692, 0, 693, 694, 695, 0, 0,
+	0, 0, 0, 696, 697, 699, 0, 700, 701, 702,
+	703, 704, 705, 698, 706, 707, 708, 709, 710, 711,
+	712, 713, 0, 715, 716, 714, 717, 718, 0, 719,
+	720, 721, 722, 723, 894, 724, 0, 725, 726, 734,
+	735, 736, 727, 728, 730, 737, 729, 738, 739, 740,
+	741, 743, 742, 0, 745, 746, 744, 747, 748, 749,
+	750, 0, 751, 895, 752, 731, 732, 753, 754, 755,
+	0, 756, 757, 758, 759, 760, 761, 762, 763, 764,
+	896, 0, 766, 0, 765, 767, 768, 769, 770, 771,
+	772, 773, 775, 733, 776, 777, 778, 783, 784, 785,
+	897, 779, 780, 781, 782, 787, 898, 788, 789, 790,
+	791, 0, 792, 793, 0, 786, 774, 0, 794, 795,
+	796, 797, 798, 799, 800, 801, 802, 803, 0, 804,
+	899, 900, 901, 902, 0, 817, 0, 805, 807, 808,
+	809, 810, 903, 811, 812, 904, 0, 813, 814, 815,
+	816, 806, 819, 820, 818, 0, 0, 821, 822, 823,
+	824, 826, 828, 829, 830, 825, 827, 831, 0, 832,
+	0, 0, 833, 834, 835, 905, 906, 907, 0, 908,
+	838, 839, 836, 837, 840, 841, 844, 842, 843, 909,
+	847, 542, 848, 849, 850, 845, 846, 2206, 0, 359,
+	0, 851, 852, 910, 853, 854, 855, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 367, 368, 370, 369,
+	371, 372, 373, 374, 0, 375, 376, 0, 0, 0,
+	0, 0, 856, 0, 0, 0, 378, 0, 377, 0,
+	379, 380, 381, 0, 382, 383, 384, 385, 386, 387,
+	388, 389, 390, 857, 391, 858, 0, 392, 859, 393,
+	860, 0, 861, 394, 395, 396, 397, 398, 399, 400,
+	401, 402, 403, 404, 0, 0, 0, 405, 862, 863,
+	864, 0, 406, 407, 408, 409, 865, 0, 0, 0,
+	410, 411, 412, 413, 414, 415, 416, 417, 0, 0,
+	419, 420, 421, 418, 422, 423, 0, 424, 0, 425,
+	426, 427, 428, 429, 0, 430, 431, 0, 432, 433,
+	434, 0, 435, 436, 437, 0, 0, 0, 0, 0,
+	0, 0, 438, 439, 440, 441, 442, 0, 443, 445,
+	866, 867, 0, 448, 450, 444, 446, 0, 449, 447,
+	451, 452, 0, 453, 454, 455, 456, 457, 0, 0,
+	0, 458, 459, 460, 461, 0, 462, 463, 464, 466,
+	465, 0, 467, 468, 469, 0, 470, 471, 868, 472,
+	473, 474, 476, 478, 475, 477, 479, 480, 481, 482,
+	483, 869, 870, 484, 485, 0, 362, 0, 0, 0,
+	0, 0, 486, 487, 488, 871, 0, 0, 0, 489,
+	0, 491, 495, 496, 492, 493, 494, 497, 0, 490,
+	498, 499, 0, 0, 500, 501, 502, 872, 873, 503,
+	504, 505, 506, 507, 508, 509, 510, 511, 0, 512,
+	513, 874, 0, 875, 514, 0, 515, 516, 517, 518,
+	519, 520, 521, 2205, 877, 878, 630, 0, 522, 523,
+	524, 525, 0, 526, 527, 528, 529, 530, 531, 532,
+	0, 0, 0, 533, 534, 535, 536, 0, 364, 363,
+	365, 0, 879, 537, 631, 538, 539, 880, 881, 0,
+	882, 0, 540, 541, 544, 0, 883, 0, 543, 545,
+	546, 0, 547, 0, 0, 0, 548, 549, 550, 551,
+	552, 553, 554, 0, 555, 557, 556, 0, 559, 884,
+	558, 0, 560, 561, 0, 0, 562, 563, 564, 565,
+	566, 567, 572, 0, 0, 568, 569, 570, 571, 573,
+	574, 0, 575, 576, 578, 581, 577, 579, 580, 582,
+	583, 596, 597, 598, 584, 585, 586, 587, 588, 589,
+	590, 591, 592, 593, 594, 595, 600, 0, 599, 0,
+	0, 601, 602, 603, 604, 605, 606, 612, 615, 617,
+	618, 613, 614, 616, 619, 620, 621, 623, 624, 609,
+	610, 611, 0, 622, 607, 0, 608, 366, 0, 625,
+	626, 627, 628, 0, 885, 629, 886, 632, 633, 0,
+	0, 634, 0, 635, 636, 0, 0, 638, 639, 640,
+	0, 0, 641, 642, 887, 0, 643, 0, 888, 644,
+	645, 637, 646, 647, 648, 649, 650, 651, 652, 653,
+	654, 655, 656, 657, 0, 658, 659, 889, 660, 661,
+	662, 663, 664, 890, 665, 666, 667, 891, 668, 892,
+	669, 670, 671, 0, 672, 673, 674, 0, 675, 676,
+	677, 678, 679, 680, 681, 682, 683, 684, 893, 685,
+	686, 688, 687, 689, 690, 0, 691, 692, 0, 693,
+	694, 695, 0, 0, 0, 0, 0, 696, 697, 699,
+	0, 700, 701, 702, 703, 704, 705, 698, 706, 707,
+	708, 709, 710, 711, 712, 713, 0, 715, 716, 714,
+	717, 718, 0, 719, 720, 721, 722, 723, 894, 724,
+	0, 725, 726, 734, 735, 736, 727, 728, 730, 737,
+	729, 738, 739, 740, 741, 743, 742, 0, 745, 746,
+	744, 747, 748, 749, 750, 0, 751, 895, 752, 731,
+	732, 753, 754, 755, 0, 756, 757, 758, 759, 760,
+	761, 762, 763, 764, 896, 0, 766, 0, 765, 767,
+	768, 769, 770, 771, 772, 773, 775, 733, 776, 777,
+	778, 783, 784, 785, 897, 779, 780, 781, 782, 787,
+	898, 788, 789, 790, 791, 0, 792, 793, 0, 786,
+	774, 0, 794, 795, 796, 797, 798, 799, 800, 801,
+	802, 803, 0, 804, 899, 900, 901, 902, 0, 817,
+	0, 805, 807, 808, 809, 810, 903, 811, 812, 904,
+	0, 813, 814, 815, 816, 806, 819, 820, 818, 0,
+	0, 821, 822, 823, 824, 826, 828, 829, 830, 825,
+	827, 831, 0, 832, 0, 0, 833, 834, 835, 905,
+	906, 907, 0, 908, 838, 839, 836, 837, 840, 841,
+	844, 842, 843, 909, 847, 542, 848, 849, 850, 845,
+	846, 2092, 0, 359, 0, 851, 852, 910, 853, 854,
+	855, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	367, 368, 370, 369, 371, 372, 373, 374, 0, 375,
+	376, 0, 0, 0, 0, 0, 856, 0, 0, 0,
+	378, 0, 377, 0, 379, 380, 381, 0, 382, 383,
+	384, 385, 386, 387, 388, 389, 390, 857, 391, 858,
+	0, 392, 859, 393, 860, 0, 861, 394, 395, 396,
+	397, 398, 399, 400, 401, 402, 403, 404, 0, 0,
+	0, 405, 862, 863, 864, 0, 406, 407, 408, 409,
+	865, 0, 0, 0, 410, 411, 412, 413, 414, 415,
+	416, 417, 0, 0, 419, 420, 421, 418, 422, 423,
+	0, 424, 0, 425, 426, 427, 428, 429, 0, 430,
+	431, 0, 432, 433, 434, 0, 435, 436, 437, 0,
+	0, 0, 0, 0, 0, 0, 438, 439, 440, 441,
+	442, 0, 443, 445, 866, 867, 0, 448, 450, 444,
+	446, 0, 449, 447, 451, 452, 0, 453, 454, 455,
+	456, 457, 0, 0, 0, 458, 459, 460, 461, 0,
+	462, 463, 464, 466, 465, 0, 467, 468, 469, 0,
+	470, 471, 868, 472, 473, 474, 476, 478, 475, 477,
+	479, 480, 481, 482, 483, 869, 870, 484, 485, 0,
+	362, 0, 0, 0, 0, 0, 486, 487, 488, 871,
+	0, 0, 0, 489, 0, 491, 495, 496, 492, 493,
+	494, 497, 0, 490, 498, 499, 0, 0, 500, 501,
+	502, 872, 873, 503, 504, 505, 506, 507, 508, 509,
+	510, 511, 0, 512, 513, 874, 0, 875, 514, 0,
+	515, 516, 517, 518, 519, 520, 521, 876, 877, 878,
+	630, 0, 522, 523, 524, 525, 0, 526, 527, 528,
+	529, 530, 531, 532, 0, 0, 0, 533, 534, 535,
+	536, 0, 364, 363, 365, 0, 879, 537, 631, 538,
+	539, 880, 881, 0, 882, 0, 540, 541, 544, 0,
+	883, 0, 543, 545, 546, 0, 547, 0, 0, 0,
+	548, 549, 550, 551, 552, 553, 554, 0, 555, 557,
+	556, 0, 559, 884, 558, 0, 560, 561, 0, 0,
+	562, 563, 564, 565, 566, 567, 572, 0, 0, 568,
+	569, 570, 571, 573, 574, 0, 575, 576, 578, 581,
+	577, 579, 580, 582, 583, 596, 597, 598, 584, 585,
+	586, 587, 588, 589, 590, 591, 592, 593, 594, 595,
+	600, 0, 599, 0, 0, 601, 602, 603, 604, 605,
+	606, 612, 615, 617, 618, 613, 614, 616, 619, 620,
+	621, 623, 624, 609, 610, 611, 0, 622, 607, 0,
+	608, 366, 0, 625, 626, 627, 628, 0, 885, 629,
+	886, 632, 633, 0, 0, 634, 0, 635, 636, 0,
+	0, 638, 639, 640, 0, 0, 641, 642, 887, 0,
+	643, 0, 888, 644, 645, 637, 646, 647, 648, 649,
+	650, 651, 652, 653, 654, 655, 656, 657, 0, 658,
+	659, 889, 660, 661, 662, 663, 664, 890, 665, 666,
+	667, 891, 668, 892, 669, 670, 671, 0, 672, 673,
+	674, 0, 675, 676, 677, 678, 679, 680, 681, 682,
+	683, 684, 893, 685, 686, 688, 687, 689, 690, 0,
+	691, 692, 0, 693, 694, 695, 0, 0, 0, 0,
+	0, 696, 697, 699, 0, 700, 701, 702, 703, 704,
+	705, 698, 706, 707, 708, 709, 710, 711, 712, 713,
+	0, 715, 716, 714, 717, 718, 0, 719, 720, 721,
+	722, 723, 894, 724, 0, 725, 726, 734, 735, 736,
+	727, 728, 730, 737, 729, 738, 739, 740, 741, 743,
+	742, 0, 745, 746, 744, 747, 748, 749, 750, 0,
+	751, 895, 752, 731, 732, 753, 754, 755, 0, 756,
+	757, 758, 759, 760, 761, 762, 763, 764, 896, 0,
+	766, 0, 765, 767, 768, 769, 770, 771, 772, 773,
+	775, 733, 776, 777, 778, 783, 784, 785, 897, 779,
+	780, 781, 782, 787, 898, 788, 789, 790, 791, 0,
+	792, 793, 0, 786, 774, 0, 794, 795, 796, 797,
+	798, 799, 800, 801, 802, 803, 0, 804, 899, 900,
+	901, 902, 0, 817, 0, 805, 807, 808, 809, 810,
+	903, 811, 812, 904, 0, 813, 814, 815, 816, 806,
+	819, 820, 818, 0, 0, 821, 822, 823, 824, 826,
+	828, 829, 830, 825, 827, 831, 0, 832, 0, 0,
+	833, 834, 835, 905, 906, 907, 0, 908, 838, 839,
+	836, 837, 840, 841, 844, 842, 843, 909, 847, 542,
+	848, 849, 850, 845, 846, 2085, 0, 359, 0, 851,
+	852, 910, 853, 854, 855, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 367, 368, 370, 369, 371, 372,
+	373, 374, 0, 375, 376, 0, 0, 0, 0, 0,
+	856, 0, 0, 0, 378, 0, 377, 0, 379, 380,
+	381, 0, 382, 383, 384, 385, 386, 387, 388, 389,
+	390, 857, 391, 858, 0, 392, 859, 393, 860, 0,
+	861, 394, 395, 396, 397, 398, 399, 400, 401, 402,
+	403, 404, 0, 0, 0, 405, 862, 863, 864, 0,
+	406, 407, 408, 409, 865, 0, 0, 0, 410, 411,
+	412, 413, 414, 415, 416, 417, 0, 0, 419, 420,
+	421, 418, 422, 423, 0, 424, 0, 425, 426, 427,
+	428, 429, 0, 430, 431, 0, 432, 433, 434, 0,
+	435, 436, 437, 0, 0, 0, 0, 0, 0, 0,
+	438, 439, 440, 441, 442, 0, 443, 445, 866, 867,
+	0, 448, 450, 444, 446, 0, 449, 447, 451, 452,
+	0, 453, 454, 455, 456, 457, 0, 0, 0, 458,
+	459, 460, 461, 0, 462, 463, 464, 466, 465, 0,
+	467, 468, 469, 0, 470, 471, 868, 472, 473, 474,
+	476, 478, 475, 477, 479, 480, 481, 482, 483, 869,
+	870, 484, 485, 0, 362, 0, 0, 0, 0, 0,
+	486, 487, 488, 871, 0, 0, 0, 489, 0, 491,
+	495, 496, 492, 493, 494, 497, 0, 490, 498, 499,
+	0, 0, 500, 501, 502, 872, 873, 503, 504, 505,
+	506, 507, 508, 509, 510, 511, 0, 512, 513, 874,
+	0, 875, 514, 0, 515, 516, 517, 518, 519, 520,
+	521, 2087, 877, 878, 630, 0, 522, 523, 524, 525,
+	0, 526, 527, 528, 529, 530, 531, 532, 0, 0,
+	0, 533, 534, 535, 536, 0, 364, 363, 365, 0,
+	879, 537, 631, 538, 539, 880, 881, 0, 882, 0,
+	540, 541, 544, 0, 883, 0, 543, 545, 546, 0,
+	547, 0, 0, 0, 548, 549, 550, 551, 552, 553,
+	554, 0, 555, 557, 556, 0, 559, 884, 558, 0,
+	560, 561, 0, 0, 562, 563, 564, 565, 566, 567,
+	572, 0, 0, 568, 569, 570, 571, 573, 574, 0,
+	575, 576, 578, 581, 577, 579, 580, 582, 583, 596,
+	597, 598, 584, 585, 586, 587, 588, 589, 590, 591,
+	592, 593, 594, 595, 600, 0, 599, 0, 0, 601,
+	602, 603, 604, 605, 606, 612, 615, 617, 618, 613,
+	614, 616, 619, 620, 621, 623, 624, 609, 610, 611,
+	0, 622, 607, 0, 608, 366, 0, 625, 626, 627,
+	628, 0, 885, 629, 886, 632, 633, 0, 0, 634,
+	0, 635, 636, 0, 0, 638, 639, 640, 0, 0,
+	641, 642, 887, 0, 643, 0, 888, 644, 645, 637,
+	646, 647, 648, 649, 650, 651, 652, 653, 654, 655,
+	656, 657, 0, 658, 659, 889, 660, 661, 662, 663,
+	664, 890, 665, 666, 667, 891, 668, 892, 669, 670,
+	671, 0, 672, 673, 674, 0, 675, 676, 677, 678,
+	679, 680, 681, 682, 683, 684, 893, 685, 686, 688,
+	687, 689, 690, 0, 691, 692, 0, 693, 694, 695,
+	0, 0, 0, 0, 0, 696, 697, 699, 0, 700,
+	701, 702, 703, 704, 705, 698, 706, 707, 708, 709,
+	710, 711, 712, 713, 0, 715, 716, 714, 717, 718,
+	0, 719, 720, 721, 722, 723, 894, 724, 0, 725,
+	726, 734, 735, 736, 727, 728, 730, 737, 729, 738,
+	739, 740, 741, 743, 742, 0, 745, 746, 744, 747,
+	748, 749, 750, 0, 751, 895, 752, 731, 732, 753,
+	754, 755, 0, 756, 757, 758, 759, 760, 761, 762,
+	763, 764, 896, 0, 766, 0, 765, 767, 768, 769,
+	770, 771, 772, 773, 775, 733, 776, 777, 778, 783,
+	784, 785, 897, 779, 780, 781, 782, 787, 898, 788,
+	789, 790, 791, 0, 792, 793, 0, 786, 774, 0,
+	794, 795, 796, 797, 798, 799, 800, 801, 802, 803,
+	0, 804, 899, 900, 901, 902, 0, 817, 0, 805,
+	807, 808, 809, 810, 903, 811, 812, 904, 0, 813,
+	814, 815, 816, 806, 819, 820, 818, 0, 0, 821,
+	822, 823, 824, 826, 828, 829, 830, 825, 827, 831,
+	0, 832, 0, 0, 833, 834, 835, 905, 906, 907,
+	0, 908, 838, 839, 836, 837, 840, 841, 844, 842,
+	843, 909, 847, 542, 848, 849, 850, 845, 846, 2075,
+	0, 359, 0, 851, 852, 910, 853, 854, 855, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 367, 368,
+	370, 369, 371, 372, 373, 374, 0, 375, 376, 0,
+	0, 0, 0, 0, 856, 0, 0, 0, 378, 0,
+	377, 0, 379, 380, 381, 0, 382, 383, 384, 385,
+	386, 387, 388, 389, 390, 857, 391, 858, 0, 392,
+	859, 393, 860, 0, 861, 394, 395, 396, 397, 398,
+	399, 400, 401, 402, 403, 404, 0, 0, 0, 405,
+	862, 863, 864, 0, 406, 407, 408, 409, 865, 0,
+	0, 0, 410, 411, 412, 413, 414, 415, 416, 417,
+	0, 0, 419, 420, 421, 418, 422, 423, 0, 424,
+	0, 425, 426, 427, 428, 429, 0, 430, 431, 0,
+	432, 433, 434, 0, 435, 436, 437, 0, 0, 0,
+	0, 0, 0, 0, 438, 439, 440, 441, 442, 0,
+	443, 445, 866, 867, 0, 448, 450, 444, 446, 0,
+	449, 447, 451, 452, 0, 453, 454, 455, 456, 457,
+	0, 0, 0, 458, 459, 460, 461, 0, 462, 463,
+	464, 466, 465, 0, 467, 468, 469, 0, 470, 471,
+	868, 472, 473, 474, 476, 478, 475, 477, 479, 480,
+	481, 482, 483, 869, 870, 484, 485, 0, 362, 0,
+	0, 0, 0, 0, 486, 487, 488, 871, 0, 0,
+	0, 489, 0, 491, 495, 496, 492, 493, 494, 497,
+	0, 490, 498, 499, 0, 0, 500, 501, 502, 872,
+	873, 503, 504, 505, 506, 507, 508, 509, 510, 511,
+	0, 512, 513, 874, 0, 875, 514, 0, 515, 516,
+	517, 518, 519, 520, 521, 876, 877, 878, 630, 0,
+	522, 523, 524, 525, 0, 526, 527, 528, 529, 530,
+	531, 532, 0, 0, 0, 533, 534, 535, 536, 0,
+	364, 363, 365, 0, 879, 537, 631, 538, 539, 880,
+	881, 0, 882, 0, 540, 541, 544, 0, 883, 0,
+	543, 545, 546, 0, 547, 0, 0, 0, 548, 549,
+	550, 551, 552, 553, 554, 0, 555, 557, 556, 0,
+	559, 884, 558, 0, 560, 561, 0, 0, 562, 563,
+	564, 565, 566, 567, 572, 0, 0, 568, 569, 570,
+	571, 573, 574, 0, 575, 576, 578, 581, 577, 579,
+	580, 582, 583, 596, 597, 598, 584, 585, 586, 587,
+	588, 589, 590, 591, 592, 593, 594, 595, 600, 0,
+	599, 0, 0, 601, 602, 603, 604, 605, 606, 612,
+	615, 617, 618, 613, 614, 616, 619, 620, 621, 623,
+	624, 609, 610, 611, 0, 622, 607, 0, 608, 366,
+	0, 625, 626, 627, 628, 0, 885, 629, 886, 632,
+	633, 0, 0, 634, 0, 635, 636, 0, 0, 638,
+	639, 640, 0, 0, 641, 642, 887, 0, 643, 0,
+	888, 644, 645, 637, 646, 647, 648, 649, 650, 651,
+	652, 653, 654, 655, 656, 657, 0, 658, 659, 889,
+	660, 661, 662, 663, 664, 890, 665, 666, 667, 891,
+	668, 892, 669, 670, 671, 0, 672, 673, 674, 0,
+	675, 676, 677, 678, 679, 680, 681, 682, 683, 684,
+	893, 685, 686, 688, 687, 689, 690, 0, 691, 692,
+	0, 693, 694, 695, 0, 0, 0, 0, 0, 696,
+	697, 699, 0, 700, 701, 702, 703, 704, 705, 698,
+	706, 707, 708, 709, 710, 711, 712, 713, 0, 715,
+	716, 714, 717, 718, 0, 719, 720, 721, 722, 723,
+	894, 724, 0, 725, 726, 734, 735, 736, 727, 728,
+	730, 737, 729, 738, 739, 740, 741, 743, 742, 0,
+	745, 746, 744, 747, 748, 749, 750, 0, 751, 895,
+	752, 731, 732, 753, 754, 755, 0, 756, 757, 758,
+	759, 760, 761, 762, 763, 764, 896, 0, 766, 0,
+	765, 767, 768, 769, 770, 771, 772, 773, 775, 733,
+	776, 777, 778, 783, 784, 785, 897, 779, 780, 781,
+	782, 787, 898, 788, 789, 790, 791, 0, 792, 793,
+	0, 786, 774, 0, 794, 795, 796, 797, 798, 799,
+	800, 801, 802, 803, 0, 804, 899, 900, 901, 902,
+	0, 817, 0, 805, 807, 808, 809, 810, 903, 811,
+	812, 904, 0, 813, 814, 815, 816, 806, 819, 820,
+	818, 0, 0, 821, 822, 823, 824, 826, 828, 829,
+	830, 825, 827, 831, 0, 832, 0, 0, 833, 834,
+	835, 905, 906, 907, 0, 908, 838, 839, 836, 837,
+	840, 841, 844, 842, 843, 909, 847, 542, 848, 849,
+	850, 845, 846, 2073, 0, 359, 0, 851, 852, 910,
+	853, 854, 855, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 367, 368, 370, 369, 371, 372, 373, 374,
+	0, 375, 376, 0, 0, 0, 0, 0, 856, 0,
+	0, 0, 378, 0, 377, 0, 379, 380, 381, 0,
+	382, 383, 384, 385, 386, 387, 388, 389, 390, 857,
+	391, 858, 0, 392, 859, 393, 860, 0, 861, 394,
+	395, 396, 397, 398, 399, 400, 401, 402, 403, 404,
+	0, 0, 0, 405, 862, 863, 864, 0, 406, 407,
+	408, 409, 865, 0, 0, 0, 410, 411, 412, 413,
+	414, 415, 416, 417, 0, 0, 419, 420, 421, 418,
+	422, 423, 0, 424, 0, 425, 426, 427, 428, 429,
+	0, 430, 431, 0, 432, 433, 434, 0, 435, 436,
+	437, 0, 0, 0, 0, 0, 0, 0, 438, 439,
+	440, 441, 442, 0, 443, 445, 866, 867, 0, 448,
+	450, 444, 446, 0, 449, 447, 451, 452, 0, 453,
+	454, 455, 456, 457, 0, 0, 0, 458, 459, 460,
+	461, 0, 462, 463, 464, 466, 465, 0, 467, 468,
+	469, 0, 470, 471, 868, 472, 473, 474, 476, 478,
+	475, 477, 479, 480, 481, 482, 483, 869, 870, 484,
+	485, 0, 362, 0, 0, 0, 0, 0, 486, 487,
+	488, 871, 0, 0, 0, 489, 0, 491, 495, 496,
+	492, 493, 494, 497, 0, 490, 498, 499, 0, 0,
+	500, 501, 502, 872, 873, 503, 504, 505, 506, 507,
+	508, 509, 510, 511, 0, 512, 513, 874, 0, 875,
+	514, 0, 515, 516, 517, 518, 519, 520, 521, 876,
+	877, 878, 630, 0, 522, 523, 524, 525, 0, 526,
+	527, 528, 529, 530, 531, 532, 0, 0, 0, 533,
+	534, 535, 536, 0, 364, 363, 365, 0, 879, 537,
+	631, 538, 539, 880, 881, 0, 882, 0, 540, 541,
+	544, 0, 883, 0, 543, 545, 546, 0, 547, 0,
+	0, 0, 548, 549, 550, 551, 552, 553, 554, 0,
+	555, 557, 556, 0, 559, 884, 558, 0, 560, 561,
+	0, 0, 562, 563, 564, 565, 566, 567, 572, 0,
+	0, 568, 569, 570, 571, 573, 574, 0, 575, 576,
+	578, 581, 577, 579, 580, 582, 583, 596, 597, 598,
+	584, 585, 586, 587, 588, 589, 590, 591, 592, 593,
+	594, 595, 600, 0, 599, 0, 0, 601, 602, 603,
+	604, 605, 606, 612, 615, 617, 618, 613, 614, 616,
+	619, 620, 621, 623, 624, 609, 610, 611, 0, 622,
+	607, 0, 608, 366, 0, 625, 626, 627, 628, 0,
+	885, 629, 886, 632, 633, 0, 0, 634, 0, 635,
+	636, 0, 0, 638, 639, 640, 0, 0, 641, 642,
+	887, 0, 643, 0, 888, 644, 645, 637, 646, 647,
+	648, 649, 650, 651, 652, 653, 654, 655, 656, 657,
+	0, 658, 659, 889, 660, 661, 662, 663, 664, 890,
+	665, 666, 667, 891, 668, 892, 669, 670, 671, 0,
+	672, 673, 674, 0, 675, 676, 677, 678, 679, 680,
+	681, 682, 683, 684, 893, 685, 686, 688, 687, 689,
+	690, 0, 691, 692, 0, 693, 694, 695, 0, 0,
+	0, 0, 0, 696, 697, 699, 0, 700, 701, 702,
+	703, 704, 705, 698, 706, 707, 708, 709, 710, 711,
+	712, 713, 0, 715, 716, 714, 717, 718, 0, 719,
+	720, 721, 722, 723, 894, 724, 0, 725, 726, 734,
+	735, 736, 727, 728, 730, 737, 729, 738, 739, 740,
+	741, 743, 742, 0, 745, 746, 744, 747, 748, 749,
+	750, 0, 751, 895, 752, 731, 732, 753, 754, 755,
+	0, 756, 757, 758, 759, 760, 761, 762, 763, 764,
+	896, 0, 766, 0, 765, 767, 768, 769, 770, 771,
+	772, 773, 775, 733, 776, 777, 778, 783, 784, 785,
+	897, 779, 780, 781, 782, 787, 898, 788, 789, 790,
+	791, 0, 792, 793, 0, 786, 774, 0, 794, 795,
+	796, 797, 798, 799, 800, 801, 802, 803, 0, 804,
+	899, 900, 901, 902, 0, 817, 0, 805, 807, 808,
+	809, 810, 903, 811, 812, 904, 0, 813, 814, 815,
+	816, 806, 819, 820, 818, 0, 0, 821, 822, 823,
+	824, 826, 828, 829, 830, 825, 827, 831, 0, 832,
+	0, 0, 833, 834, 835, 905, 906, 907, 0, 908,
+	838, 839, 836, 837, 840, 841, 844, 842, 843, 909,
+	847, 542, 848, 849, 850, 845, 846, 1730, 0, 359,
+	0, 851, 852, 910, 853, 854, 855, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 367, 368, 370, 369,
+	371, 372, 373, 374, 0, 375, 376, 0, 0, 0,
+	0, 0, 856, 0, 0, 0, 378, 0, 377, 0,
+	379, 380, 381, 0, 382, 383, 384, 385, 386, 387,
+	388, 389, 390, 857, 391, 858, 0, 392, 859, 393,
+	860, 0, 861, 394, 395, 396, 397, 398, 399, 400,
+	401, 402, 403, 404, 0, 0, 0, 405, 862, 863,
+	864, 0, 406, 407, 408, 409, 865, 0, 0, 0,
+	410, 411, 412, 413, 414, 415, 416, 417, 0, 0,
+	419, 420, 421, 418, 422, 423, 0, 424, 0, 425,
+	426, 427, 428, 429, 0, 430, 431, 0, 432, 433,
+	434, 0, 435, 436, 437, 0, 0, 0, 0, 0,
+	0, 0, 438, 439, 440, 441, 442, 0, 443, 445,
+	866, 867, 0, 448, 450, 444, 446, 0, 449, 447,
+	451, 452, 0, 453, 454, 455, 456, 457, 0, 0,
+	0, 458, 459, 460, 461, 0, 462, 463, 464, 466,
+	465, 0, 467, 468, 469, 0, 470, 471, 868, 472,
+	473, 474, 476, 478, 475, 477, 479, 480, 481, 482,
+	483, 869, 870, 484, 485, 0, 362, 0, 0, 0,
+	0, 0, 486, 487, 488, 871, 0, 0, 0, 489,
+	0, 491, 495, 496, 492, 493, 494, 497, 0, 490,
+	498, 499, 0, 0, 500, 501, 502, 872, 873, 503,
+	504, 505, 506, 507, 508, 509, 510, 511, 0, 512,
+	513, 874, 0, 875, 514, 0, 515, 516, 517, 518,
+	519, 520, 521, 1729, 877, 878, 630, 0, 522, 523,
+	524, 525, 0, 526, 527, 528, 529, 530, 531, 532,
+	0, 0, 0, 533, 534, 535, 536, 0, 364, 363,
+	365, 0, 879, 537, 631, 538, 539, 880, 881, 0,
+	882, 0, 540, 541, 544, 0, 883, 0, 543, 545,
+	546, 0, 547, 0, 0, 0, 548, 549, 550, 551,
+	552, 553, 554, 0, 555, 557, 556, 0, 559, 884,
+	558, 0, 560, 561, 0, 0, 562, 563, 564, 565,
+	566, 567, 572, 0, 0, 568, 569, 570, 571, 573,
+	574, 0, 575, 576, 578, 581, 577, 579, 580, 582,
+	583, 596, 597, 598, 584, 585, 586, 587, 588, 589,
+	590, 591, 592, 593, 594, 595, 600, 0, 599, 0,
+	0, 601, 602, 603, 604, 605, 606, 612, 615, 617,
+	618, 613, 614, 616, 619, 620, 621, 623, 624, 609,
+	610, 611, 0, 622, 607, 0, 608, 366, 0, 625,
+	626, 627, 628, 0, 885, 629, 886, 632, 633, 0,
+	0, 634, 0, 635, 636, 0, 0, 638, 639, 640,
+	0, 0, 641, 642, 887, 0, 643, 0, 888, 644,
+	645, 637, 646, 647, 648, 649, 650, 651, 652, 653,
+	654, 655, 656, 657, 0, 658, 659, 889, 660, 661,
+	662, 663, 664, 890, 665, 666, 667, 891, 668, 892,
+	669, 670, 671, 0, 672, 673, 674, 0, 675, 676,
+	677, 678, 679, 680, 681, 682, 683, 684, 893, 685,
+	686, 688, 687, 689, 690, 0, 691, 692, 0, 693,
+	694, 695, 0, 0, 0, 0, 0, 696, 697, 699,
+	0, 700, 701, 702, 703, 704, 705, 698, 706, 707,
+	708, 709, 710, 711, 712, 713, 0, 715, 716, 714,
+	717, 718, 0, 719, 720, 721, 722, 723, 894, 724,
+	0, 725, 726, 734, 735, 736, 727, 728, 730, 737,
+	729, 738, 739, 740, 741, 743, 742, 0, 745, 746,
+	744, 747, 748, 749, 750, 0, 751, 895, 752, 731,
+	732, 753, 754, 755, 0, 756, 757, 758, 759, 760,
+	761, 762, 763, 764, 896, 0, 766, 0, 765, 767,
+	768, 769, 770, 771, 772, 773, 775, 733, 776, 777,
+	778, 783, 784, 785, 897, 779, 780, 781, 782, 787,
+	898, 788, 789, 790, 791, 0, 792, 793, 0, 786,
+	774, 0, 794, 795, 796, 797, 798, 799, 800, 801,
+	802, 803, 0, 804, 899, 900, 901, 902, 0, 817,
+	0, 805, 807, 808, 809, 810, 903, 811, 812, 904,
+	0, 813, 814, 815, 816, 806, 819, 820, 818, 0,
+	0, 821, 822, 823, 824, 826, 828, 829, 830, 825,
+	827, 831, 0, 832, 0, 0, 833, 834, 835, 905,
+	906, 907, 0, 908, 838, 839, 836, 837, 840, 841,
+	844, 842, 843, 909, 847, 542, 848, 849, 850, 845,
+	846, 1719, 0, 359, 0, 851, 852, 910, 853, 854,
+	855, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	367, 368, 370, 369, 371, 372, 373, 374, 0, 375,
+	376, 0, 0, 0, 0, 0, 856, 0, 0, 0,
+	378, 0, 377, 0, 379, 380, 381, 0, 382, 383,
+	384, 385, 386, 387, 388, 389, 390, 857, 391, 858,
+	0, 392, 859, 393, 860, 0, 861, 394, 395, 396,
+	397, 398, 399, 400, 401, 402, 403, 404, 0, 0,
+	0, 405, 862, 863, 864, 0, 406, 407, 408, 409,
+	865, 0, 0, 0, 410, 411, 412, 413, 414, 415,
+	416, 417, 0, 0, 419, 420, 421, 418, 422, 423,
+	0, 424, 0, 425, 426, 427, 428, 429, 0, 430,
+	431, 0, 432, 433, 434, 0, 435, 436, 437, 0,
+	0, 0, 0, 0, 0, 0, 438, 439, 440, 441,
+	442, 0, 443, 445, 866, 867, 0, 448, 450, 444,
+	446, 0, 449, 447, 451, 452, 0, 453, 454, 455,
+	456, 457, 0, 0, 0, 458, 459, 460, 461, 0,
+	462, 463, 464, 466, 465, 0, 467, 468, 469, 0,
+	470, 471, 868, 472, 473, 474, 476, 478, 475, 477,
+	479, 480, 481, 482, 483, 869, 870, 484, 485, 0,
+	362, 0, 0, 0, 0, 0, 486, 487, 488, 871,
+	0, 0, 0, 489, 0, 491, 495, 496, 492, 493,
+	494, 497, 0, 490, 498, 499, 0, 0, 500, 501,
+	502, 872, 873, 503, 504, 505, 506, 507, 508, 509,
+	510, 511, 0, 512, 513, 874, 0, 875, 514, 0,
+	515, 516, 517, 518, 519, 520, 521, 1718, 877, 878,
+	630, 0, 522, 523, 524, 525, 0, 526, 527, 528,
+	529, 530, 531, 532, 0, 0, 0, 533, 534, 535,
+	536, 0, 364, 363, 365, 0, 879, 537, 631, 538,
+	539, 880, 881, 0, 882, 0, 540, 541, 544, 0,
+	883, 0, 543, 545, 546, 0, 547, 0, 0, 0,
+	548, 549, 550, 551, 552, 553, 554, 0, 555, 557,
+	556, 0, 559, 884, 558, 0, 560, 561, 0, 0,
+	562, 563, 564, 565, 566, 567, 572, 0, 0, 568,
+	569, 570, 571, 573, 574, 0, 575, 576, 578, 581,
+	577, 579, 580, 582, 583, 596, 597, 598, 584, 585,
+	586, 587, 588, 589, 590, 591, 592, 593, 594, 595,
+	600, 0, 599, 0, 0, 601, 602, 603, 604, 605,
+	606, 612, 615, 617, 618, 613, 614, 616, 619, 620,
+	621, 623, 624, 609, 610, 611, 0, 622, 607, 0,
+	608, 366, 0, 625, 626, 627, 628, 0, 885, 629,
+	886, 632, 633, 0, 0, 634, 0, 635, 636, 0,
+	0, 638, 639, 640, 0, 0, 641, 642, 887, 0,
+	643, 0, 888, 644, 645, 637, 646, 647, 648, 649,
+	650, 651, 652, 653, 654, 655, 656, 657, 0, 658,
+	659, 889, 660, 661, 662, 663, 664, 890, 665, 666,
+	667, 891, 668, 892, 669, 670, 671, 0, 672, 673,
+	674, 0, 675, 676, 677, 678, 679, 680, 681, 682,
+	683, 684, 893, 685, 686, 688, 687, 689, 690, 0,
+	691, 692, 0, 693, 694, 695, 0, 0, 0, 0,
+	0, 696, 697, 699, 0, 700, 701, 702, 703, 704,
+	705, 698, 706, 707, 708, 709, 710, 711, 712, 713,
+	0, 715, 716, 714, 717, 718, 0, 719, 720, 721,
+	722, 723, 894, 724, 0, 725, 726, 734, 735, 736,
+	727, 728, 730, 737, 729, 738, 739, 740, 741, 743,
+	742, 0, 745, 746, 744, 747, 748, 749, 750, 0,
+	751, 895, 752, 731, 732, 753, 754, 755, 0, 756,
+	757, 758, 759, 760, 761, 762, 763, 764, 896, 0,
+	766, 0, 765, 767, 768, 769, 770, 771, 772, 773,
+	775, 733, 776, 777, 778, 783, 784, 785, 897, 779,
+	780, 781, 782, 787, 898, 788, 789, 790, 791, 0,
+	792, 793, 0, 786, 774, 0, 794, 795, 796, 797,
+	798, 799, 800, 801, 802, 803, 0, 804, 899, 900,
+	901, 902, 0, 817, 0, 805, 807, 808, 809, 810,
+	903, 811, 812, 904, 0, 813, 814, 815, 816, 806,
+	819, 820, 818, 0, 0, 821, 822, 823, 824, 826,
+	828, 829, 830, 825, 827, 831, 0, 832, 0, 0,
+	833, 834, 835, 905, 906, 907, 0, 908, 838, 839,
+	836, 837, 840, 841, 844, 842, 843, 909, 847, 542,
+	848, 849, 850, 845, 846, 1715, 0, 359, 0, 851,
+	852, 910, 853, 854, 855, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 367, 368, 370, 369, 371, 372,
+	373, 374, 0, 375, 376, 0, 0, 0, 0, 0,
+	856, 0, 0, 0, 378, 0, 377, 0, 379, 380,
+	381, 0, 382, 383, 384, 385, 386, 387, 388, 389,
+	390, 857, 391, 858, 0, 392, 859, 393, 860, 0,
+	861, 394, 395, 396, 397, 398, 399, 400, 401, 402,
+	403, 404, 0, 0, 0, 405, 862, 863, 864, 0,
+	406, 407, 408, 409, 865, 0, 0, 0, 410, 411,
+	412, 413, 414, 415, 416, 417, 0, 0, 419, 420,
+	421, 418, 422, 423, 0, 424, 0, 425, 426, 427,
+	428, 429, 0, 430, 431, 0, 432, 433, 434, 0,
+	435, 436, 437, 0, 0, 0, 0, 0, 0, 0,
+	438, 439, 440, 441, 442, 0, 443, 445, 866, 867,
+	0, 448, 450, 444, 446, 0, 449, 447, 451, 452,
+	0, 453, 454, 455, 456, 457, 0, 0, 0, 458,
+	459, 460, 461, 0, 462, 463, 464, 466, 465, 0,
+	467, 468, 469, 0, 470, 471, 868, 472, 473, 474,
+	476, 478, 475, 477, 479, 480, 481, 482, 483, 869,
+	870, 484, 485, 0, 362, 0, 0, 0, 0, 0,
+	486, 487, 488, 871, 0, 0, 0, 489, 0, 491,
+	495, 496, 492, 493, 494, 497, 0, 490, 498, 499,
+	0, 0, 500, 501, 502, 872, 873, 503, 504, 505,
+	506, 507, 508, 509, 510, 511, 0, 512, 513, 874,
+	0, 875, 514, 0, 515, 516, 517, 518, 519, 520,
+	521, 1714, 877, 878, 630, 0, 522, 523, 524, 525,
+	0, 526, 527, 528, 529, 530, 531, 532, 0, 0,
+	0, 533, 534, 535, 536, 0, 364, 363, 365, 0,
+	879, 537, 631, 538, 539, 880, 881, 0, 882, 0,
+	540, 541, 544, 0, 883, 0, 543, 545, 546, 0,
+	547, 0, 0, 0, 548, 549, 550, 551, 552, 553,
+	554, 0, 555, 557, 556, 0, 559, 884, 558, 0,
+	560, 561, 0, 0, 562, 563, 564, 565, 566, 567,
+	572, 0, 0, 568, 569, 570, 571, 573, 574, 0,
+	575, 576, 578, 581, 577, 579, 580, 582, 583, 596,
+	597, 598, 584, 585, 586, 587, 588, 589, 590, 591,
+	592, 593, 594, 595, 600, 0, 599, 0, 0, 601,
+	602, 603, 604, 605, 606, 612, 615, 617, 618, 613,
+	614, 616, 619, 620, 621, 623, 624, 609, 610, 611,
+	0, 622, 607, 0, 608, 366, 0, 625, 626, 627,
+	628, 0, 885, 629, 886, 632, 633, 0, 0, 634,
+	0, 635, 636, 0, 0, 638, 639, 640, 0, 0,
+	641, 642, 887, 0, 643, 0, 888, 644, 645, 637,
+	646, 647, 648, 649, 650, 651, 652, 653, 654, 655,
+	656, 657, 0, 658, 659, 889, 660, 661, 662, 663,
+	664, 890, 665, 666, 667, 891, 668, 892, 669, 670,
+	671, 0, 672, 673, 674, 0, 675, 676, 677, 678,
+	679, 680, 681, 682, 683, 684, 893, 685, 686, 688,
+	687, 689, 690, 0, 691, 692, 0, 693, 694, 695,
+	0, 0, 0, 0, 0, 696, 697, 699, 0, 700,
+	701, 702, 703, 704, 705, 698, 706, 707, 708, 709,
+	710, 711, 712, 713, 0, 715, 716, 714, 717, 718,
+	0, 719, 720, 721, 722, 723, 894, 724, 0, 725,
+	726, 734, 735, 736, 727, 728, 730, 737, 729, 738,
+	739, 740, 741, 743, 742, 0, 745, 746, 744, 747,
+	748, 749, 750, 0, 751, 895, 752, 731, 732, 753,
+	754, 755, 0, 756, 757, 758, 759, 760, 761, 762,
+	763, 764, 896, 0, 766, 0, 765, 767, 768, 769,
+	770, 771, 772, 773, 775, 733, 776, 777, 778, 783,
+	784, 785, 897, 779, 780, 781, 782, 787, 898, 788,
+	789, 790, 791, 0, 792, 793, 0, 786, 774, 0,
+	794, 795, 796, 797, 798, 799, 800, 801, 802, 803,
+	0, 804, 899, 900, 901, 902, 0, 817, 0, 805,
+	807, 808, 809, 810, 903, 811, 812, 904, 0, 813,
+	814, 815, 816, 806, 819, 820, 818, 0, 0, 821,
+	822, 823, 824, 826, 828, 829, 830, 825, 827, 831,
+	0, 832, 0, 0, 833, 834, 835, 905, 906, 907,
+	0, 908, 838, 839, 836, 837, 840, 841, 844, 842,
+	843, 909, 847, 542, 848, 849, 850, 845, 846, 1709,
+	0, 359, 0, 851, 852, 910, 853, 854, 855, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 367, 368,
+	370, 369, 371, 372, 373, 374, 0, 375, 376, 0,
+	0, 0, 0, 0, 856, 0, 0, 0, 378, 0,
+	377, 0, 379, 380, 381, 0, 382, 383, 384, 385,
+	386, 387, 388, 389, 390, 857, 391, 858, 0, 392,
+	859, 393, 860, 0, 861, 394, 395, 396, 397, 398,
+	399, 400, 401, 402, 403, 404, 0, 0, 0, 405,
+	862, 863, 864, 0, 406, 407, 408, 409, 865, 0,
+	0, 0, 410, 411, 412, 413, 414, 415, 416, 417,
+	0, 0, 419, 420, 421, 418, 422, 423, 0, 424,
+	0, 425, 426, 427, 428, 429, 0, 430, 431, 0,
+	432, 433, 434, 0, 435, 436, 437, 0, 0, 0,
+	0, 0, 0, 0, 438, 439, 440, 441, 442, 0,
+	443, 445, 866, 867, 0, 448, 450, 444, 446, 0,
+	449, 447, 451, 452, 0, 453, 454, 455, 456, 457,
+	0, 0, 0, 458, 459, 460, 461, 0, 462, 463,
+	464, 466, 465, 0, 467, 468, 469, 0, 470, 471,
+	868, 472, 473, 474, 476, 478, 475, 477, 479, 480,
+	481, 482, 483, 869, 870, 484, 485, 0, 362, 0,
+	0, 0, 0, 0, 486, 487, 488, 871, 0, 0,
+	0, 489, 0, 491, 495, 496, 492, 493, 494, 497,
+	0, 490, 498, 499, 0, 0, 500, 501, 502, 872,
+	873, 503, 504, 505, 506, 507, 508, 509, 510, 511,
+	0, 512, 513, 874, 0, 875, 514, 0, 515, 516,
+	517, 518, 519, 520, 521, 1708, 877, 878, 630, 0,
+	522, 523, 524, 525, 0, 526, 527, 528, 529, 530,
+	531, 532, 0, 0, 0, 533, 534, 535, 536, 0,
+	364, 363, 365, 0, 879, 537, 631, 538, 539, 880,
+	881, 0, 882, 0, 540, 541, 544, 0, 883, 0,
+	543, 545, 546, 0, 547, 0, 0, 0, 548, 549,
+	550, 551, 552, 553, 554, 0, 555, 557, 556, 0,
+	559, 884, 558, 0, 560, 561, 0, 0, 562, 563,
+	564, 565, 566, 567, 572, 0, 0, 568, 569, 570,
+	571, 573, 574, 0, 575, 576, 578, 581, 577, 579,
+	580, 582, 583, 596, 597, 598, 584, 585, 586, 587,
+	588, 589, 590, 591, 592, 593, 594, 595, 600, 0,
+	599, 0, 0, 601, 602, 603, 604, 605, 606, 612,
+	615, 617, 618, 613, 614, 616, 619, 620, 621, 623,
+	624, 609, 610, 611, 0, 622, 607, 0, 608, 366,
+	0, 625, 626, 627, 628, 0, 885, 629, 886, 632,
+	633, 0, 0, 634, 0, 635, 636, 0, 0, 638,
+	639, 640, 0, 0, 641, 642, 887, 0, 643, 0,
+	888, 644, 645, 637, 646, 647, 648, 649, 650, 651,
+	652, 653, 654, 655, 656, 657, 0, 658, 659, 889,
+	660, 661, 662, 663, 664, 890, 665, 666, 667, 891,
+	668, 892, 669, 670, 671, 0, 672, 673, 674, 0,
+	675, 676, 677, 678, 679, 680, 681, 682, 683, 684,
+	893, 685, 686, 688, 687, 689, 690, 0, 691, 692,
+	0, 693, 694, 695, 0, 0, 0, 0, 0, 696,
+	697, 699, 0, 700, 701, 702, 703, 704, 705, 698,
+	706, 707, 708, 709, 710, 711, 712, 713, 0, 715,
+	716, 714, 717, 718, 0, 719, 720, 721, 722, 723,
+	894, 724, 0, 725, 726, 734, 735, 736, 727, 728,
+	730, 737, 729, 738, 739, 740, 741, 743, 742, 0,
+	745, 746, 744, 747, 748, 749, 750, 0, 751, 895,
+	752, 731, 732, 753, 754, 755, 0, 756, 757, 758,
+	759, 760, 761, 762, 763, 764, 896, 0, 766, 0,
+	765, 767, 768, 769, 770, 771, 772, 773, 775, 733,
+	776, 777, 778, 783, 784, 785, 897, 779, 780, 781,
+	782, 787, 898, 788, 789, 790, 791, 0, 792, 793,
+	0, 786, 774, 0, 794, 795, 796, 797, 798, 799,
+	800, 801, 802, 803, 0, 804, 899, 900, 901, 902,
+	0, 817, 0, 805, 807, 808, 809, 810, 903, 811,
+	812, 904, 0, 813, 814, 815, 816, 806, 819, 820,
+	818, 0, 0, 821, 822, 823, 824, 826, 828, 829,
+	830, 825, 827, 831, 0, 832, 0, 0, 833, 834,
+	835, 905, 906, 907, 0, 908, 838, 839, 836, 837,
+	840, 841, 844, 842, 843, 909, 847, 542, 848, 849,
+	850, 845, 846, 1686, 0, 359, 0, 851, 852, 910,
+	853, 854, 855, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 367, 368, 370, 369, 371, 372, 373, 374,
+	0, 375, 376, 0, 0, 0, 0, 0, 856, 0,
+	0, 0, 378, 0, 377, 0, 379, 380, 381, 0,
+	382, 383, 384, 385, 386, 387, 388, 389, 390, 857,
+	391, 858, 0, 392, 859, 393, 860, 0, 861, 394,
+	395, 396, 397, 398, 399, 400, 401, 402, 403, 404,
+	0, 0, 0, 405, 862, 863, 864, 0, 406, 407,
+	408, 409, 865, 0, 0, 0, 410, 411, 412, 413,
+	414, 415, 416, 417, 0, 0, 419, 420, 421, 418,
+	422, 423, 0, 424, 0, 425, 426, 427, 428, 429,
+	0, 430, 431, 0, 432, 433, 434, 0, 435, 436,
+	437, 0, 0, 0, 0, 0, 0, 0, 438, 439,
+	440, 441, 442, 0, 443, 445, 866, 867, 0, 448,
+	450, 444, 446, 0, 449, 447, 451, 452, 0, 453,
+	454, 455, 456, 457, 0, 0, 0, 458, 459, 460,
+	461, 0, 462, 463, 464, 466, 465, 0, 467, 468,
+	469, 0, 470, 471, 868, 472, 473, 474, 476, 478,
+	475, 477, 479, 480, 481, 482, 483, 869, 870, 484,
+	485, 0, 362, 0, 0, 0, 0, 0, 486, 487,
+	488, 871, 0, 0, 0, 489, 0, 491, 495, 496,
+	492, 493, 494, 497, 0, 490, 498, 499, 0, 0,
+	500, 501, 502, 872, 873, 503, 504, 505, 506, 507,
+	508, 509, 510, 511, 0, 512, 513, 874, 0, 875,
+	514, 0, 515, 516, 517, 518, 519, 520, 521, 1685,
+	877, 878, 630, 0, 522, 523, 524, 525, 0, 526,
+	527, 528, 529, 530, 531, 532, 0, 0, 0, 533,
+	534, 535, 536, 0, 364, 363, 365, 0, 879, 537,
+	631, 538, 539, 880, 881, 0, 882, 0, 540, 541,
+	544, 0, 883, 0, 543, 545, 546, 0, 547, 0,
+	0, 0, 548, 549, 550, 551, 552, 553, 554, 0,
+	555, 557, 556, 0, 559, 884, 558, 0, 560, 561,
+	0, 0, 562, 563, 564, 565, 566, 567, 572, 0,
+	0, 568, 569, 570, 571, 573, 574, 0, 575, 576,
+	578, 581, 577, 579, 580, 582, 583, 596, 597, 598,
+	584, 585, 586, 587, 588, 589, 590, 591, 592, 593,
+	594, 595, 600, 0, 599, 0, 0, 601, 602, 603,
+	604, 605, 606, 612, 615, 617, 618, 613, 614, 616,
+	619, 620, 621, 623, 624, 609, 610, 611, 0, 622,
+	607, 0, 608, 366, 0, 625, 626, 627, 628, 0,
+	885, 629, 886, 632, 633, 0, 0, 634, 0, 635,
+	636, 0, 0, 638, 639, 640, 0, 0, 641, 642,
+	887, 0, 643, 0, 888, 644, 645, 637, 646, 647,
+	648, 649, 650, 651, 652, 653, 654, 655, 656, 657,
+	0, 658, 659, 889, 660, 661, 662, 663, 664, 890,
+	665, 666, 667, 891, 668, 892, 669, 670, 671, 0,
+	672, 673, 674, 0, 675, 676, 677, 678, 679, 680,
+	681, 682, 683, 684, 893, 685, 686, 688, 687, 689,
+	690, 0, 691, 692, 0, 693, 694, 695, 0, 0,
+	0, 0, 0, 696, 697, 699, 0, 700, 701, 702,
+	703, 704, 705, 698, 706, 707, 708, 709, 710, 711,
+	712, 713, 0, 715, 716, 714, 717, 718, 0, 719,
+	720, 721, 722, 723, 894, 724, 0, 725, 726, 734,
+	735, 736, 727, 728, 730, 737, 729, 738, 739, 740,
+	741, 743, 742, 0, 745, 746, 744, 747, 748, 749,
+	750, 0, 751, 895, 752, 731, 732, 753, 754, 755,
+	0, 756, 757, 758, 759, 760, 761, 762, 763, 764,
+	896, 0, 766, 0, 765, 767, 768, 769, 770, 771,
+	772, 773, 775, 733, 776, 777, 778, 783, 784, 785,
+	897, 779, 780, 781, 782, 787, 898, 788, 789, 790,
+	791, 0, 792, 793, 0, 786, 774, 0, 794, 795,
+	796, 797, 798, 799, 800, 801, 802, 803, 0, 804,
+	899, 900, 901, 902, 0, 817, 0, 805, 807, 808,
+	809, 810, 903, 811, 812, 904, 0, 813, 814, 815,
+	816, 806, 819, 820, 818, 0, 0, 821, 822, 823,
+	824, 826, 828, 829, 830, 825, 827, 831, 0, 832,
+	0, 0, 833, 834, 835, 905, 906, 907, 0, 908,
+	838, 839, 836, 837, 840, 841, 844, 842, 843, 909,
+	847, 542, 848, 849, 850, 845, 846, 1681, 0, 359,
+	0, 851, 852, 910, 853, 854, 855, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 367, 368, 370, 369,
+	371, 372, 373, 374, 0, 375, 376, 0, 0, 0,
+	0, 0, 856, 0, 0, 0, 378, 0, 377, 0,
+	379, 380, 381, 0, 382, 383, 384, 385, 386, 387,
+	388, 389, 390, 857, 391, 858, 0, 392, 859, 393,
+	860, 0, 861, 394, 395, 396, 397, 398, 399, 400,
+	401, 402, 403, 404, 0, 0, 0, 405, 862, 863,
+	864, 0, 406, 407, 408, 409, 865, 0, 0, 0,
+	410, 411, 412, 413, 414, 415, 416, 417, 0, 0,
+	419, 420, 421, 418, 422, 423, 0, 424, 0, 425,
+	426, 427, 428, 429, 0, 430, 431, 0, 432, 433,
+	434, 0, 435, 436, 437, 0, 0, 0, 0, 0,
+	0, 0, 438, 439, 440, 441, 442, 0, 443, 445,
+	866, 867, 0, 448, 450, 444, 446, 0, 449, 447,
+	451, 452, 0, 453, 454, 455, 456, 457, 0, 0,
+	0, 458, 459, 460, 461, 0, 462, 463, 464, 466,
+	465, 0, 467, 468, 469, 0, 470, 471, 868, 472,
+	473, 474, 476, 478, 475, 477, 479, 480, 481, 482,
+	483, 869, 870, 484, 485, 0, 362, 0, 0, 0,
+	0, 0, 486, 487, 488, 871, 0, 0, 0, 489,
+	0, 491, 495, 496, 492, 493, 494, 497, 0, 490,
+	498, 499, 0, 0, 500, 501, 502, 872, 873, 503,
+	504, 505, 506, 507, 508, 509, 510, 511, 0, 512,
+	513, 874, 0, 875, 514, 0, 515, 516, 517, 518,
+	519, 520, 521, 1680, 877, 878, 630, 0, 522, 523,
+	524, 525, 0, 526, 527, 528, 529, 530, 531, 532,
+	0, 0, 0, 533, 534, 535, 536, 0, 364, 363,
+	365, 0, 879, 537, 631, 538, 539, 880, 881, 0,
+	882, 0, 540, 541, 544, 0, 883, 0, 543, 545,
+	546, 0, 547, 0, 0, 0, 548, 549, 550, 551,
+	552, 553, 554, 0, 555, 557, 556, 0, 559, 884,
+	558, 0, 560, 561, 0, 0, 562, 563, 564, 565,
+	566, 567, 572, 0, 0, 568, 569, 570, 571, 573,
+	574, 0, 575, 576, 578, 581, 577, 579, 580, 582,
+	583, 596, 597, 598, 584, 585, 586, 587, 588, 589,
+	590, 591, 592, 593, 594, 595, 600, 0, 599, 0,
+	0, 601, 602, 603, 604, 605, 606, 612, 615, 617,
+	618, 613, 614, 616, 619, 620, 621, 623, 624, 609,
+	610, 611, 0, 622, 607, 0, 608, 366, 0, 625,
+	626, 627, 628, 0, 885, 629, 886, 632, 633, 0,
+	0, 634, 0, 635, 636, 0, 0, 638, 639, 640,
+	0, 0, 641, 642, 887, 0, 643, 0, 888, 644,
+	645, 637, 646, 647, 648, 649, 650, 651, 652, 653,
+	654, 655, 656, 657, 0, 658, 659, 889, 660, 661,
+	662, 663, 664, 890, 665, 666, 667, 891, 668, 892,
+	669, 670, 671, 0, 672, 673, 674, 0, 675, 676,
+	677, 678, 679, 680, 681, 682, 683, 684, 893, 685,
+	686, 688, 687, 689, 690, 0, 691, 692, 0, 693,
+	694, 695, 0, 0, 0, 0, 0, 696, 697, 699,
+	0, 700, 701, 702, 703, 704, 705, 698, 706, 707,
+	708, 709, 710, 711, 712, 713, 0, 715, 716, 714,
+	717, 718, 0, 719, 720, 721, 722, 723, 894, 724,
+	0, 725, 726, 734, 735, 736, 727, 728, 730, 737,
+	729, 738, 739, 740, 741, 743, 742, 0, 745, 746,
+	744, 747, 748, 749, 750, 0, 751, 895, 752, 731,
+	732, 753, 754, 755, 0, 756, 757, 758, 759, 760,
+	761, 762, 763, 764, 896, 0, 766, 0, 765, 767,
+	768, 769, 770, 771, 772, 773, 775, 733, 776, 777,
+	778, 783, 784, 785, 897, 779, 780, 781, 782, 787,
+	898, 788, 789, 790, 791, 0, 792, 793, 0, 786,
+	774, 0, 794, 795, 796, 797, 798, 799, 800, 801,
+	802, 803, 0, 804, 899, 900, 901, 902, 0, 817,
+	0, 805, 807, 808, 809, 810, 903, 811, 812, 904,
+	0, 813, 814, 815, 816, 806, 819, 820, 818, 0,
+	0, 821, 822, 823, 824, 826, 828, 829, 830, 825,
+	827, 831, 0, 832, 0, 0, 833, 834, 835, 905,
+	906, 907, 0, 908, 838, 839, 836, 837, 840, 841,
+	844, 842, 843, 909, 847, 542, 848, 849, 850, 845,
+	846, 912, 0, 359, 0, 851, 852, 910, 853, 854,
+	855, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	367, 368, 370, 369, 371, 372, 373, 374, 0, 375,
+	376, 0, 0, 0, 0, 0, 856, 0, 0, 0,
+	378, 0, 377, 0, 379, 380, 381, 0, 382, 383,
+	384, 385, 386, 387, 388, 389, 390, 857, 391, 858,
+	0, 392, 859, 393, 860, 0, 861, 394, 395, 396,
+	397, 398, 399, 400, 401, 402, 403, 404, 0, 0,
+	0, 405, 862, 863, 864, 0, 406, 407, 408, 409,
+	865, 0, 0, 0, 410, 411, 412, 413, 414, 415,
+	416, 417, 0, 0, 419, 420, 421, 418, 422, 423,
+	0, 424, 0, 425, 426, 427, 428, 429, 0, 430,
+	431, 0, 432, 433, 434, 0, 435, 436, 437, 0,
+	0, 0, 0, 0, 0, 0, 438, 439, 440, 441,
+	442, 0, 443, 445, 866, 867, 0, 448, 450, 444,
+	446, 0, 449, 447, 451, 452, 0, 453, 454, 455,
+	456, 457, 0, 0, 0, 458, 459, 460, 461, 0,
+	462, 463, 464, 466, 465, 0, 467, 468, 469, 0,
+	470, 471, 868, 472, 473, 474, 476, 478, 475, 477,
+	479, 480, 481, 482, 483, 869, 870, 484, 485, 0,
+	362, 0, 0, 0, 0, 0, 486, 487, 488, 871,
+	0, 0, 0, 489, 0, 491, 495, 496, 492, 493,
+	494, 497, 0, 490, 498, 499, 0, 0, 500, 501,
+	502, 872, 873, 503, 504, 505, 506, 507, 508, 509,
+	510, 511, 0, 512, 513, 874, 0, 875, 514, 0,
+	515, 516, 517, 518, 519, 520, 521, 876, 877, 878,
+	630, 0, 522, 523, 524, 525, 0, 526, 527, 528,
+	529, 530, 531, 532, 0, 0, 0, 533, 534, 535,
+	536, 0, 364, 363, 365, 0, 879, 537, 631, 538,
+	539, 880, 881, 0, 882, 0, 540, 541, 544, 0,
+	883, 0, 543, 545, 546, 0, 547, 0, 0, 0,
+	548, 549, 550, 551, 552, 553, 554, 0, 555, 557,
+	556, 0, 559, 884, 558, 0, 560, 561, 0, 0,
+	562, 563, 564, 565, 566, 567, 572, 0, 0, 568,
+	569, 570, 571, 573, 574, 0, 575, 576, 578, 581,
+	577, 579, 580, 582, 583, 596, 597, 598, 584, 585,
+	586, 587, 588, 589, 590, 591, 592, 593, 594, 595,
+	600, 0, 599, 0, 0, 601, 602, 603, 604, 605,
+	606, 612, 615, 617, 618, 613, 614, 616, 619, 620,
+	621, 623, 624, 609, 610, 611, 0, 622, 607, 0,
+	608, 366, 0, 625, 626, 627, 628, 0, 885, 629,
+	886, 632, 633, 0, 0, 634, 0, 635, 636, 0,
+	0, 638, 639, 640, 0, 0, 641, 642, 887, 0,
+	643, 0, 888, 644, 645, 637, 646, 647, 648, 649,
+	650, 651, 652, 653, 654, 655, 656, 657, 0, 658,
+	659, 889, 660, 661, 662, 663, 664, 890, 665, 666,
+	667, 891, 668, 892, 669, 670, 671, 0, 672, 673,
+	674, 0, 675, 676, 677, 678, 679, 680, 681, 682,
+	683, 684, 893, 685, 686, 688, 687, 689, 690, 0,
+	691, 692, 0, 693, 694, 695, 0, 0, 0, 0,
+	0, 696, 697, 699, 0, 700, 701, 702, 703, 704,
+	705, 698, 706, 707, 708, 709, 710, 711, 712, 713,
+	0, 715, 716, 714, 717, 718, 0, 719, 720, 721,
+	722, 723, 894, 724, 0, 725, 726, 734, 735, 736,
+	727, 728, 730, 737, 729, 738, 739, 740, 741, 743,
+	742, 0, 745, 746, 744, 747, 748, 749, 750, 0,
+	751, 895, 752, 731, 732, 753, 754, 755, 0, 756,
+	757, 758, 759, 760, 761, 762, 763, 764, 896, 0,
+	766, 0, 765, 767, 768, 769, 770, 771, 772, 773,
+	775, 733, 776, 777, 778, 783, 784, 785, 897, 779,
+	780, 781, 782, 787, 898, 788, 789, 790, 791, 0,
+	792, 793, 0, 786, 774, 0, 794, 795, 796, 797,
+	798, 799, 800, 801, 802, 803, 0, 804, 899, 900,
+	901, 902, 0, 817, 0, 805, 807, 808, 809, 810,
+	903, 811, 812, 904, 0, 813, 814, 815, 816, 806,
+	819, 820, 818, 0, 0, 821, 822, 823, 824, 826,
+	828, 829, 830, 825, 827, 831, 0, 832, 0, 0,
+	833, 834, 835, 905, 906, 907, 0, 908, 838, 839,
+	836, 837, 840, 841, 844, 842, 843, 909, 847, 542,
+	848, 849, 850, 845, 846, 350, 0, 359, 0, 851,
+	852, 910, 853, 854, 855, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 367, 368, 370, 369, 371, 372,
+	373, 374, 0, 375, 376, 0, 0, 0, 0, 0,
+	856, 0, 0, 0, 378, 0, 377, 0, 379, 380,
+	381, 0, 382, 383, 384, 385, 386, 387, 388, 389,
+	390, 857, 391, 858, 0, 392, 859, 393, 860, 0,
+	861, 394, 395, 396, 397, 398, 399, 400, 401, 402,
+	403, 404, 0, 0, 0, 405, 862, 863, 864, 0,
+	406, 407, 408, 409, 865, 0, 0, 0, 410, 411,
+	412, 413, 414, 415, 416, 417, 0, 0, 419, 420,
+	421, 418, 422, 423, 0, 424, 0, 425, 426, 427,
+	428, 429, 0, 430, 431, 0, 432, 433, 434, 0,
+	435, 436, 437, 0, 0, 0, 0, 0, 0, 0,
+	438, 439, 440, 441, 442, 0, 443, 445, 866, 867,
+	0, 448, 450, 444, 446, 0, 449, 447, 451, 452,
+	0, 453, 454, 455, 456, 457, 0, 0, 0, 458,
+	459, 460, 461, 0, 462, 463, 464, 466, 465, 0,
+	467, 468, 469, 0, 470, 471, 868, 472, 473, 474,
+	476, 478, 475, 477, 479, 480, 481, 482, 483, 869,
+	870, 484, 485, 0, 362, 0, 0, 0, 0, 0,
+	486, 487, 488, 871, 0, 0, 0, 489, 0, 491,
+	495, 496, 492, 493, 494, 497, 0, 490, 498, 499,
+	0, 0, 500, 501, 502, 872, 873, 503, 504, 505,
+	506, 507, 508, 509, 510, 511, 0, 512, 513, 874,
+	0, 875, 514, 0, 515, 516, 517, 518, 519, 520,
+	521, 876, 877, 878, 630, 0, 522, 523, 524, 525,
+	0, 526, 527, 528, 529, 530, 531, 532, 0, 0,
+	0, 533, 534, 535, 536, 0, 364, 363, 365, 0,
+	879, 537, 631, 538, 539, 880, 881, 0, 882, 0,
+	540, 541, 544, 0, 883, 0, 543, 545, 546, 0,
+	547, 0, 0, 0, 548, 549, 550, 551, 552, 553,
+	554, 0, 555, 557, 556, 0, 559, 884, 558, 0,
+	560, 561, 0, 0, 562, 563, 564, 565, 566, 567,
+	572, 0, 0, 568, 569, 570, 571, 573, 574, 0,
+	575, 576, 578, 581, 577, 579, 580, 582, 583, 596,
+	597, 598, 584, 585, 586, 587, 588, 589, 590, 591,
+	592, 593, 594, 595, 600, 0, 599, 0, 0, 601,
+	602, 603, 604, 605, 606, 612, 615, 617, 618, 613,
+	614, 616, 619, 620, 621, 623, 624, 609, 610, 611,
+	0, 622, 607, 0, 608, 366, 0, 625, 626, 627,
+	628, 0, 885, 629, 886, 632, 633, 0, 0, 634,
+	0, 635, 636, 0, 0, 638, 639, 640, 0, 0,
+	641, 642, 887, 0, 643, 0, 888, 644, 645, 637,
+	646, 647, 648, 649, 650, 651, 652, 653, 654, 655,
+	656, 657, 0, 658, 659, 889, 660, 661, 662, 663,
+	664, 890, 665, 666, 667, 891, 668, 892, 669, 670,
+	671, 0, 672, 673, 674, 0, 675, 676, 677, 678,
+	679, 680, 681, 682, 683, 684, 893, 685, 686, 688,
+	687, 689, 690, 0, 691, 692, 0, 693, 694, 695,
+	0, 0, 0, 0, 0, 696, 697, 699, 0, 700,
+	701, 702, 703, 704, 705, 698, 706, 707, 708, 709,
+	710, 711, 712, 713, 0, 715, 716, 714, 717, 718,
+	0, 719, 720, 721, 722, 723, 894, 724, 0, 725,
+	726, 734, 735, 736, 727, 728, 730, 737, 729, 738,
+	739, 740, 741, 743, 742, 0, 745, 746, 744, 747,
+	748, 749, 750, 0, 751, 895, 752, 731, 732, 753,
+	754, 755, 0, 756, 757, 758, 759, 760, 761, 762,
+	763, 764, 896, 0, 766, 0, 765, 767, 768, 769,
+	770, 771, 772, 773, 775, 733, 776, 777, 778, 783,
+	784, 785, 897, 779, 780, 781, 782, 787, 898, 788,
+	789, 790, 791, 0, 792, 793, 0, 786, 774, 0,
+	794, 795, 796, 797, 798, 799, 800, 801, 802, 803,
+	0, 804, 899, 900, 901, 902, 0, 817, 0, 805,
+	807, 808, 809, 810, 903, 811, 812, 904, 0, 813,
+	814, 815, 816, 806, 819, 820, 818, 0, 0, 821,
+	822, 823, 824, 826, 828, 829, 830, 825, 827, 831,
+	0, 832, 0, 0, 833, 834, 835, 905, 906, 907,
+	0, 908, 838, 839, 836, 837, 840, 841, 844, 842,
+	843, 909, 847, 542, 848, 849, 850, 845, 846, 359,
+	0, 0, 0, 851, 852, 910, 853, 854, 855, 0,
+	0, 0, 0, 0, 0, 0, 367, 368, 370, 369,
+	371, 372, 373, 374, 0, 375, 376, 0, 0, 0,
+	0, 0, 856, 0, 0, 0, 378, 0, 377, 0,
+	379, 380, 381, 0, 382, 383, 384, 385, 386, 387,
+	388, 389, 390, 857, 391, 858, 0, 392, 859, 393,
+	860, 0, 861, 394, 395, 396, 397, 398, 399, 400,
+	401, 402, 403, 404, 0, 0, 0, 405, 862, 863,
+	864, 0, 406, 407, 408, 409, 865, 0, 0, 0,
+	410, 411, 412, 413, 414, 415, 416, 417, 0, 0,
+	419, 420, 421, 418, 422, 423, 0, 424, 0, 425,
+	426, 427, 428, 429, 0, 430, 431, 0, 432, 433,
+	434, 0, 435, 436, 437, 0, 0, 0, 0, 0,
+	0, 0, 438, 439, 440, 441, 442, 0, 443, 445,
+	866, 867, 0, 448, 450, 444, 446, 0, 449, 447,
+	451, 452, 0, 453, 454, 455, 456, 457, 0, 0,
+	0, 458, 459, 460, 461, 0, 462, 463, 464, 466,
+	465, 0, 467, 468, 469, 0, 470, 471, 868, 472,
+	473, 474, 476, 478, 475, 477, 479, 480, 481, 482,
+	483, 869, 870, 484, 485, 0, 362, 0, 0, 0,
+	0, 0, 486, 487, 488, 871, 0, 0, 0, 489,
+	0, 491, 495, 496, 492, 493, 494, 497, 0, 490,
+	498, 499, 0, 0, 500, 501, 502, 872, 873, 503,
+	504, 505, 506, 507, 508, 509, 510, 511, 0, 512,
+	513, 874, 0, 875, 514, 0, 515, 516, 517, 518,
+	519, 520, 521, 876, 877, 878, 630, 0, 522, 523,
+	524, 525, 0, 526, 527, 528, 529, 530, 531, 532,
+	0, 0, 0, 533, 534, 535, 536, 0, 364, 363,
+	365, 0, 879, 537, 631, 538, 539, 880, 881, 0,
+	882, 0, 540, 541, 544, 0, 883, 0, 543, 545,
+	546, 0, 547, 0, 0, 0, 548, 549, 550, 551,
+	552, 553, 554, 0, 555, 557, 556, 0, 559, 884,
+	558, 0, 560, 561, 0, 0, 562, 563, 564, 565,
+	566, 567, 572, 0, 0, 568, 569, 570, 571, 573,
+	574, 0, 575, 576, 578, 581, 577, 579, 580, 582,
+	583, 596, 597, 598, 584, 585, 586, 587, 588, 589,
+	590, 591, 592, 593, 594, 595, 600, 0, 599, 0,
+	0, 601, 602, 603, 604, 605, 606, 612, 615, 617,
+	618, 613, 614, 616, 619, 620, 621, 623, 624, 609,
+	610, 611, 0, 622, 607, 0, 608, 366, 0, 625,
+	626, 627, 628, 0, 885, 629, 886, 632, 633, 0,
+	0, 634, 0, 635, 636, 0, 0, 638, 639, 640,
+	0, 0, 641, 642, 887, 0, 643, 0, 888, 644,
+	645, 637, 646, 647, 648, 649, 650, 651, 652, 653,
+	654, 655, 656, 657, 0, 658, 659, 889, 660, 661,
+	662, 663, 664, 890, 665, 666, 667, 891, 668, 892,
+	669, 670, 671, 0, 672, 673, 674, 0, 675, 676,
+	677, 678, 679, 680, 681, 682, 683, 684, 893, 685,
+	686, 688, 687, 689, 690, 0, 691, 692, 0, 693,
+	694, 695, 0, 0, 0, 0, 0, 696, 697, 699,
+	0, 700, 701, 702, 703, 704, 705, 698, 706, 707,
+	708, 709, 710, 711, 712, 713, 0, 715, 716, 714,
+	717, 718, 0, 719, 720, 721, 722, 723, 894, 724,
+	0, 725, 726, 734, 735, 736, 727, 728, 730, 737,
+	729, 738, 739, 740, 741, 743, 742, 0, 745, 746,
+	744, 747, 748, 749, 750, 0, 751, 895, 752, 731,
+	732, 753, 754, 755, 0, 756, 757, 758, 759, 760,
+	761, 762, 763, 764, 896, 0, 766, 0, 765, 767,
+	768, 769, 770, 771, 772, 773, 775, 733, 776, 777,
+	778, 783, 784, 785, 897, 779, 780, 781, 782, 787,
+	898, 788, 789, 790, 791, 0, 792, 793, 0, 786,
+	774, 0, 794, 795, 796, 797, 798, 799, 800, 801,
+	802, 803, 0, 804, 899, 900, 901, 902, 0, 817,
+	0, 805, 807, 808, 809, 810, 903, 811, 812, 904,
+	0, 813, 814, 815, 816, 806, 819, 820, 818, 0,
+	0, 821, 822, 823, 824, 826, 828, 829, 830, 825,
+	827, 831, 0, 832, 0, 0, 833, 834, 835, 905,
+	906, 907, 0, 908, 838, 839, 836, 837, 840, 841,
+	844, 842, 843, 909, 847, 542, 848, 849, 850, 845,
+	846, 359, 0, 0, 0, 851, 852, 910, 853, 854,
+	855, 0, 0, 0, 0, 0, 0, 0, 367, 368,
+	370, 369, 371, 372, 373, 374, 0, 375, 376, 0,
+	0, 0, 0, 0, 856, 0, 0, 0, 378, 0,
+	377, 0, 379, 380, 381, 0, 382, 383, 384, 385,
+	386, 387, 388, 389, 390, 857, 391, 858, 0, 392,
+	859, 393, 860, 0, 861, 394, 395, 396, 397, 398,
+	399, 400, 401, 402, 403, 404, 0, 0, 0, 405,
+	862, 863, 864, 0, 406, 407, 408, 409, 865, 0,
+	0, 0, 410, 411, 412, 413, 414, 415, 416, 417,
+	0, 0, 419, 420, 421, 418, 422, 423, 0, 424,
+	0, 425, 426, 427, 428, 429, 0, 430, 431, 0,
+	432, 433, 434, 0, 435, 436, 437, 0, 0, 0,
+	0, 0, 0, 0, 438, 439, 440, 441, 442, 0,
+	443, 445, 866, 867, 0, 448, 450, 444, 446, 0,
+	449, 447, 451, 452, 0, 453, 454, 455, 456, 457,
+	0, 0, 0, 458, 459, 460, 461, 0, 462, 463,
+	464, 466, 465, 0, 467, 468, 469, 0, 470, 471,
+	868, 472, 473, 474, 476, 478, 475, 477, 479, 480,
+	481, 482, 483, 869, 870, 484, 485, 0, 362, 0,
+	0, 0, 0, 0, 486, 487, 488, 871, 0, 0,
+	0, 489, 0, 491, 495, 496, 492, 493, 494, 497,
+	0, 490, 498, 499, 0, 0, 500, 501, 502, 872,
+	873, 503, 504, 505, 506, 507, 508, 509, 510, 511,
+	0, 512, 513, 874, 0, 875, 514, 0, 515, 516,
+	517, 518, 519, 520, 521, 3107, 877, 878, 630, 0,
+	522, 523, 524, 525, 0, 526, 527, 528, 529, 530,
+	531, 532, 0, 0, 0, 533, 534, 535, 536, 0,
+	364, 363, 365, 0, 879, 537, 631, 538, 539, 880,
+	881, 0, 882, 0, 540, 541, 544, 0, 883, 0,
+	543, 545, 546, 0, 547, 0, 0, 0, 548, 549,
+	550, 551, 552, 553, 554, 0, 555, 557, 556, 0,
+	559, 884, 558, 0, 560, 561, 0, 0, 562, 563,
+	564, 565, 566, 567, 572, 0, 0, 568, 569, 570,
+	571, 573, 574, 0, 575, 576, 578, 581, 577, 579,
+	580, 582, 583, 596, 597, 598, 584, 585, 586, 587,
+	588, 589, 590, 591, 592, 593, 594, 595, 600, 0,
+	599, 0, 0, 601, 602, 603, 604, 605, 606, 612,
+	615, 617, 618, 613, 614, 616, 619, 620, 621, 623,
+	624, 609, 610, 611, 0, 622, 607, 0, 608, 366,
+	0, 625, 626, 627, 628, 0, 885, 629, 886, 632,
+	633, 0, 0, 634, 0, 635, 636, 0, 0, 638,
+	639, 640, 0, 0, 641, 642, 887, 0, 643, 0,
+	888, 644, 645, 637, 646, 647, 648, 649, 650, 651,
+	652, 653, 654, 655, 656, 657, 0, 658, 659, 889,
+	660, 661, 662, 663, 664, 890, 665, 666, 667, 891,
+	668, 892, 669, 670, 671, 0, 672, 673, 674, 0,
+	675, 676, 677, 678, 679, 680, 681, 682, 683, 684,
+	893, 685, 686, 688, 687, 689, 690, 0, 691, 692,
+	0, 693, 694, 695, 0, 0, 0, 0, 0, 696,
+	697, 699, 0, 700, 701, 702, 703, 704, 705, 698,
+	706, 707, 708, 709, 710, 711, 712, 713, 0, 715,
+	716, 714, 717, 718, 0, 719, 720, 721, 722, 723,
+	894, 724, 0, 725, 726, 734, 735, 736, 727, 728,
+	730, 737, 729, 738, 739, 740, 741, 743, 742, 0,
+	745, 746, 744, 747, 748, 749, 750, 0, 751, 895,
+	752, 731, 732, 753, 754, 755, 0, 756, 757, 758,
+	759, 760, 761, 762, 763, 764, 896, 0, 766, 0,
+	765, 767, 768, 769, 770, 771, 772, 773, 775, 733,
+	776, 777, 778, 783, 784, 785, 897, 779, 780, 781,
+	782, 787, 898, 788, 789, 790, 791, 0, 792, 793,
+	0, 786, 774, 0, 794, 795, 796, 797, 798, 799,
+	800, 801, 802, 803, 0, 804, 899, 900, 901, 902,
+	0, 817, 0, 805, 807, 808, 809, 810, 903, 811,
+	812, 904, 0, 813, 814, 815, 816, 806, 819, 820,
+	818, 0, 0, 821, 822, 823, 824, 826, 828, 829,
+	830, 825, 827, 831, 0, 832, 0, 0, 833, 834,
+	835, 905, 906, 907, 0, 908, 838, 839, 836, 837,
+	840, 841, 844, 842, 843, 909, 847, 542, 848, 849,
+	850, 845, 846, 359, 0, 0, 0, 851, 852, 910,
+	853, 854, 855, 0, 0, 0, 0, 0, 0, 0,
+	367, 368, 370, 369, 371, 372, 373, 374, 0, 375,
+	376, 0, 0, 0, 0, 0, 856, 0, 0, 0,
+	378, 0, 377, 0, 379, 380, 381, 0, 382, 383,
+	384, 385, 386, 387, 388, 389, 390, 857, 391, 858,
+	0, 392, 859, 393, 860, 0, 861, 394, 395, 396,
+	397, 398, 399, 400, 401, 402, 403, 404, 0, 0,
+	0, 405, 862, 863, 864, 0, 406, 407, 408, 409,
+	865, 0, 0, 0, 410, 411, 412, 413, 414, 415,
+	416, 417, 0, 0, 419, 420, 421, 418, 422, 423,
+	0, 424, 0, 425, 426, 427, 428, 429, 0, 430,
+	431, 0, 432, 433, 434, 0, 435, 436, 437, 0,
+	0, 0, 0, 0, 0, 0, 438, 439, 440, 2772,
+	442, 0, 443, 445, 866, 867, 0, 448, 450, 444,
+	446, 0, 449, 447, 451, 452, 0, 453, 454, 455,
+	456, 457, 0, 0, 0, 458, 459, 460, 461, 0,
+	462, 463, 464, 466, 465, 0, 467, 468, 469, 0,
+	470, 471, 868, 472, 473, 474, 476, 478, 475, 477,
+	479, 480, 481, 482, 483, 869, 870, 484, 485, 0,
+	362, 0, 0, 0, 0, 0, 486, 487, 488, 871,
+	0, 0, 0, 489, 0, 491, 495, 496, 492, 493,
+	494, 497, 0, 490, 498, 499, 0, 0, 500, 501,
+	502, 872, 873, 503, 504, 505, 506, 507, 508, 509,
+	510, 511, 0, 512, 513, 874, 0, 875, 514, 0,
+	515, 516, 517, 518, 519, 520, 521, 876, 877, 878,
+	630, 0, 522, 523, 524, 525, 0, 526, 527, 528,
+	529, 530, 531, 532, 0, 0, 0, 533, 534, 535,
+	536, 0, 364, 363, 365, 0, 879, 537, 631, 538,
+	539, 880, 881, 0, 882, 0, 540, 541, 544, 0,
+	883, 0, 543, 545, 546, 0, 547, 0, 0, 0,
+	548, 549, 550, 551, 552, 553, 554, 0, 555, 557,
+	556, 0, 559, 884, 558, 0, 560, 561, 0, 0,
+	562, 563, 564, 565, 566, 567, 572, 0, 0, 568,
+	569, 570, 571, 573, 574, 0, 575, 576, 578, 581,
+	577, 579, 580, 582, 583, 596, 597, 598, 584, 585,
+	586, 587, 588, 589, 590, 591, 592, 593, 594, 595,
+	600, 0, 599, 0, 0, 601, 602, 603, 604, 605,
+	606, 612, 615, 617, 618, 613, 614, 616, 619, 620,
+	621, 623, 624, 609, 610, 611, 0, 622, 607, 0,
+	608, 366, 0, 625, 626, 627, 628, 0, 885, 629,
+	886, 632, 633, 0, 0, 634, 0, 635, 636, 0,
+	0, 638, 639, 640, 0, 0, 641, 642, 887, 0,
+	643, 0, 888, 644, 645, 637, 646, 647, 648, 649,
+	650, 651, 652, 653, 654, 655, 656, 657, 0, 658,
+	659, 889, 660, 661, 662, 663, 664, 890, 665, 666,
+	667, 891, 668, 892, 669, 670, 671, 0, 672, 673,
+	674, 0, 675, 676, 677, 678, 679, 680, 681, 682,
+	683, 684, 893, 685, 686, 688, 687, 689, 690, 0,
+	691, 692, 0, 693, 694, 695, 0, 0, 0, 0,
+	0, 696, 697, 699, 0, 700, 701, 702, 703, 704,
+	705, 698, 706, 707, 708, 709, 710, 711, 712, 713,
+	0, 715, 716, 714, 717, 718, 0, 719, 720, 721,
+	722, 723, 894, 724, 0, 725, 726, 734, 735, 736,
+	727, 728, 730, 737, 729, 738, 739, 740, 741, 743,
+	742, 0, 745, 746, 744, 747, 748, 749, 750, 0,
+	751, 895, 752, 731, 732, 753, 754, 755, 0, 756,
+	757, 758, 759, 760, 761, 762, 763, 764, 896, 0,
+	766, 0, 765, 767, 768, 769, 770, 771, 772, 773,
+	775, 733, 776, 777, 778, 783, 784, 785, 897, 779,
+	780, 781, 782, 787, 898, 788, 789, 790, 791, 0,
+	792, 793, 0, 786, 774, 0, 794, 795, 796, 797,
+	798, 799, 800, 801, 802, 803, 0, 804, 899, 900,
+	901, 902, 0, 817, 0, 805, 807, 808, 809, 810,
+	903, 811, 812, 904, 0, 813, 814, 815, 816, 806,
+	819, 820, 818, 0, 0, 821, 822, 823, 824, 826,
+	828, 829, 830, 825, 827, 831, 0, 832, 0, 0,
+	833, 834, 835, 905, 906, 907, 0, 908, 838, 839,
+	836, 837, 840, 841, 844, 842, 843, 909, 847, 542,
+	848, 849, 850, 845, 846, 359, 0, 0, 0, 851,
+	852, 910, 853, 854, 855, 0, 0, 0, 0, 0,
+	0, 0, 367, 368, 370, 369, 371, 372, 373, 374,
+	0, 375, 376, 0, 0, 0, 0, 0, 856, 0,
+	0, 0, 378, 0, 377, 0, 379, 380, 381, 0,
+	382, 383, 384, 385, 386, 387, 388, 389, 390, 857,
+	391, 858, 0, 392, 859, 393, 860, 0, 861, 394,
+	395, 396, 397, 398, 399, 400, 401, 402, 403, 404,
+	0, 0, 0, 405, 862, 863, 864, 0, 406, 407,
+	408, 409, 865, 0, 0, 0, 410, 411, 412, 413,
+	414, 415, 416, 417, 0, 0, 419, 420, 421, 418,
+	422, 423, 0, 424, 0, 425, 426, 427, 428, 429,
+	0, 430, 431, 0, 432, 433, 434, 0, 435, 436,
+	437, 0, 0, 0, 0, 0, 0, 0, 438, 439,
+	440, 2770, 442, 0, 443, 445, 866, 867, 0, 448,
+	450, 444, 446, 0, 449, 447, 451, 452, 0, 453,
+	454, 455, 456, 457, 0, 0, 0, 458, 459, 460,
+	461, 0, 462, 463, 464, 466, 465, 0, 467, 468,
+	469, 0, 470, 471, 868, 472, 473, 474, 476, 478,
+	475, 477, 479, 480, 481, 482, 483, 869, 870, 484,
+	485, 0, 362, 0, 0, 0, 0, 0, 486, 487,
+	488, 871, 0, 0, 0, 489, 0, 491, 495, 496,
+	492, 493, 494, 497, 0, 490, 498, 499, 0, 0,
+	500, 501, 502, 872, 873, 503, 504, 505, 506, 507,
+	508, 509, 510, 511, 0, 512, 513, 874, 0, 875,
+	514, 0, 515, 516, 517, 518, 519, 520, 521, 876,
+	877, 878, 630, 0, 522, 523, 524, 525, 0, 526,
+	527, 528, 529, 530, 531, 532, 0, 0, 0, 533,
+	534, 535, 536, 0, 364, 363, 365, 0, 879, 537,
+	631, 538, 539, 880, 881, 0, 882, 0, 540, 541,
+	544, 0, 883, 0, 543, 545, 546, 0, 547, 0,
+	0, 0, 548, 549, 550, 551, 552, 553, 554, 0,
+	555, 557, 556, 0, 559, 884, 558, 0, 560, 561,
+	0, 0, 562, 563, 564, 565, 566, 567, 572, 0,
+	0, 568, 569, 570, 571, 573, 574, 0, 575, 576,
+	578, 581, 577, 579, 580, 582, 583, 596, 597, 598,
+	584, 585, 586, 587, 588, 589, 590, 591, 592, 593,
+	594, 595, 600, 0, 599, 0, 0, 601, 602, 603,
+	604, 605, 606, 612, 615, 617, 618, 613, 614, 616,
+	619, 620, 621, 623, 624, 609, 610, 611, 0, 622,
+	607, 0, 608, 366, 0, 625, 626, 627, 628, 0,
+	885, 629, 886, 632, 633, 0, 0, 634, 0, 635,
+	636, 0, 0, 638, 639, 640, 0, 0, 641, 642,
+	887, 0, 643, 0, 888, 644, 645, 637, 646, 647,
+	648, 649, 650, 651, 652, 653, 654, 655, 656, 657,
+	0, 658, 659, 889, 660, 661, 662, 663, 664, 890,
+	665, 666, 667, 891, 668, 892, 669, 670, 671, 0,
+	672, 673, 674, 0, 675, 676, 677, 678, 679, 680,
+	681, 682, 683, 684, 893, 685, 686, 688, 687, 689,
+	690, 0, 691, 692, 0, 693, 694, 695, 0, 0,
+	0, 0, 0, 696, 697, 699, 0, 700, 701, 702,
+	703, 704, 705, 698, 706, 707, 708, 709, 710, 711,
+	712, 713, 0, 715, 716, 714, 717, 718, 0, 719,
+	720, 721, 722, 723, 894, 724, 0, 725, 726, 734,
+	735, 736, 727, 728, 730, 737, 729, 738, 739, 740,
+	741, 743, 742, 0, 745, 746, 744, 747, 748, 749,
+	750, 0, 751, 895, 752, 731, 732, 753, 754, 755,
+	0, 756, 757, 758, 759, 760, 761, 762, 763, 764,
+	896, 0, 766, 0, 765, 767, 768, 769, 770, 771,
+	772, 773, 775, 733, 776, 777, 778, 783, 784, 785,
+	897, 779, 780, 781, 782, 787, 898, 788, 789, 790,
+	791, 0, 792, 793, 0, 786, 774, 0, 794, 795,
+	796, 797, 798, 799, 800, 801, 802, 803, 0, 804,
+	899, 900, 901, 902, 0, 817, 0, 805, 807, 808,
+	809, 810, 903, 811, 812, 904, 0, 813, 814, 815,
+	816, 806, 819, 820, 818, 0, 0, 821, 822, 823,
+	824, 826, 828, 829, 830, 825, 827, 831, 0, 832,
+	0, 0, 833, 834, 835, 905, 906, 907, 0, 908,
+	838, 839, 836, 837, 840, 841, 844, 842, 843, 909,
+	847, 542, 848, 849, 850, 845, 846, 359, 0, 0,
+	0, 851, 852, 910, 853, 854, 855, 0, 0, 0,
+	0, 0, 0, 0, 367, 368, 370, 369, 371, 372,
+	373, 374, 0, 375, 376, 0, 0, 0, 0, 0,
+	856, 0, 0, 0, 378, 0, 377, 0, 379, 380,
+	381, 0, 382, 383, 384, 385, 386, 387, 388, 389,
+	390, 857, 391, 858, 0, 392, 859, 393, 860, 0,
+	861, 394, 395, 396, 397, 398, 399, 400, 401, 402,
+	403, 404, 0, 0, 0, 405, 862, 863, 864, 0,
+	406, 407, 408, 409, 865, 0, 0, 0, 410, 411,
+	412, 413, 414, 415, 416, 417, 0, 0, 419, 420,
+	421, 418, 422, 423, 0, 424, 0, 425, 426, 427,
+	428, 429, 0, 430, 431, 0, 432, 433, 434, 0,
+	435, 436, 437, 0, 0, 0, 0, 0, 0, 0,
+	438, 439, 440, 2768, 442, 0, 443, 445, 866, 867,
+	0, 448, 450, 444, 446, 0, 449, 447, 451, 452,
+	0, 453, 454, 455, 456, 457, 0, 0, 0, 458,
+	459, 460, 461, 0, 462, 463, 464, 466, 465, 0,
+	467, 468, 469, 0, 470, 471, 868, 472, 473, 474,
+	476, 478, 475, 477, 479, 480, 481, 482, 483, 869,
+	870, 484, 485, 0, 362, 0, 0, 0, 0, 0,
+	486, 487, 488, 871, 0, 0, 0, 489, 0, 491,
+	495, 496, 492, 493, 494, 497, 0, 490, 498, 499,
+	0, 0, 500, 501, 502, 872, 873, 503, 504, 505,
+	506, 507, 508, 509, 510, 511, 0, 512, 513, 874,
+	0, 875, 514, 0, 515, 516, 517, 518, 519, 520,
+	521, 876, 877, 878, 630, 0, 522, 523, 524, 525,
+	0, 526, 527, 528, 529, 530, 531, 532, 0, 0,
+	0, 533, 534, 535, 536, 0, 364, 363, 365, 0,
+	879, 537, 631, 538, 539, 880, 881, 0, 882, 0,
+	540, 541, 544, 0, 883, 0, 543, 545, 546, 0,
+	547, 0, 0, 0, 548, 549, 550, 551, 552, 553,
+	554, 0, 555, 557, 556, 0, 559, 884, 558, 0,
+	560, 561, 0, 0, 562, 563, 564, 565, 566, 567,
+	572, 0, 0, 568, 569, 570, 571, 573, 574, 0,
+	575, 576, 578, 581, 577, 579, 580, 582, 583, 596,
+	597, 598, 584, 585, 586, 587, 588, 589, 590, 591,
+	592, 593, 594, 595, 600, 0, 599, 0, 0, 601,
+	602, 603, 604, 605, 606, 612, 615, 617, 618, 613,
+	614, 616, 619, 620, 621, 623, 624, 609, 610, 611,
+	0, 622, 607, 0, 608, 366, 0, 625, 626, 627,
+	628, 0, 885, 629, 886, 632, 633, 0, 0, 634,
+	0, 635, 636, 0, 0, 638, 639, 640, 0, 0,
+	641, 642, 887, 0, 643, 0, 888, 644, 645, 637,
+	646, 647, 648, 649, 650, 651, 652, 653, 654, 655,
+	656, 657, 0, 658, 659, 889, 660, 661, 662, 663,
+	664, 890, 665, 666, 667, 891, 668, 892, 669, 670,
+	671, 0, 672, 673, 674, 0, 675, 676, 677, 678,
+	679, 680, 681, 682, 683, 684, 893, 685, 686, 688,
+	687, 689, 690, 0, 691, 692, 0, 693, 694, 695,
+	0, 0, 0, 0, 0, 696, 697, 699, 0, 700,
+	701, 702, 703, 704, 705, 698, 706, 707, 708, 709,
+	710, 711, 712, 713, 0, 715, 716, 714, 717, 718,
+	0, 719, 720, 721, 722, 723, 894, 724, 0, 725,
+	726, 734, 735, 736, 727, 728, 730, 737, 729, 738,
+	739, 740, 741, 743, 742, 0, 745, 746, 744, 747,
+	748, 749, 750, 0, 751, 895, 752, 731, 732, 753,
+	754, 755, 0, 756, 757, 758, 759, 760, 761, 762,
+	763, 764, 896, 0, 766, 0, 765, 767, 768, 769,
+	770, 771, 772, 773, 775, 733, 776, 777, 778, 783,
+	784, 785, 897, 779, 780, 781, 782, 787, 898, 788,
+	789, 790, 791, 0, 792, 793, 0, 786, 774, 0,
+	794, 795, 796, 797, 798, 799, 800, 801, 802, 803,
+	0, 804, 899, 900, 901, 902, 0, 817, 0, 805,
+	807, 808, 809, 810, 903, 811, 812, 904, 0, 813,
+	814, 815, 816, 806, 819, 820, 818, 0, 0, 821,
+	822, 823, 824, 826, 828, 829, 830, 825, 827, 831,
+	0, 832, 0, 0, 833, 834, 835, 905, 906, 907,
+	0, 908, 838, 839, 836, 837, 840, 841, 844, 842,
+	843, 909, 847, 542, 848, 849, 850, 845, 846, 359,
+	0, 0, 0, 851, 852, 910, 853, 854, 855, 0,
+	0, 0, 0, 0, 0, 0, 367, 368, 370, 369,
+	371, 372, 373, 374, 0, 375, 376, 0, 0, 0,
+	0, 0, 856, 0, 0, 0, 378, 0, 377, 0,
+	379, 380, 381, 0, 382, 383, 384, 385, 386, 387,
+	388, 389, 390, 857, 391, 858, 0, 392, 859, 393,
+	860, 0, 861, 394, 395, 396, 397, 398, 399, 400,
+	401, 402, 403, 404, 0, 0, 0, 405, 862, 863,
+	864, 0, 406, 407, 408, 409, 865, 0, 0, 0,
+	410, 411, 412, 413, 414, 415, 416, 417, 0, 0,
+	419, 420, 421, 418, 422, 423, 0, 424, 0, 425,
+	426, 427, 428, 429, 0, 430, 431, 0, 432, 433,
+	434, 0, 435, 436, 437, 0, 0, 0, 0, 0,
+	0, 0, 438, 439, 440, 441, 442, 0, 443, 445,
+	866, 867, 0, 448, 450, 444, 446, 0, 449, 447,
+	451, 452, 0, 453, 454, 455, 456, 457, 0, 0,
+	0, 458, 459, 460, 461, 0, 462, 463, 464, 466,
+	465, 0, 467, 468, 469, 0, 470, 471, 868, 472,
+	473, 474, 476, 478, 475, 477, 479, 480, 481, 482,
+	483, 869, 870, 484, 485, 0, 362, 0, 0, 0,
+	0, 0, 486, 487, 488, 871, 0, 0, 0, 489,
+	0, 491, 495, 496, 492, 493, 494, 497, 0, 490,
+	498, 499, 0, 0, 500, 501, 502, 872, 873, 503,
+	504, 505, 506, 507, 508, 509, 510, 511, 0, 512,
+	513, 874, 0, 875, 514, 0, 515, 516, 517, 518,
+	519, 520, 521, 2643, 877, 878, 630, 0, 522, 523,
+	524, 525, 0, 526, 527, 528, 529, 530, 531, 532,
+	0, 0, 0, 533, 534, 535, 536, 0, 364, 363,
+	365, 0, 879, 537, 631, 538, 539, 880, 881, 0,
+	882, 0, 540, 541, 544, 0, 883, 0, 543, 545,
+	546, 0, 547, 0, 0, 0, 548, 549, 550, 551,
+	552, 553, 554, 0, 555, 557, 556, 0, 559, 884,
+	558, 0, 560, 561, 0, 0, 562, 563, 564, 565,
+	566, 567, 572, 0, 0, 568, 569, 570, 571, 573,
+	574, 0, 575, 576, 578, 581, 577, 579, 580, 582,
+	583, 596, 597, 598, 584, 585, 586, 587, 588, 589,
+	590, 591, 592, 593, 594, 595, 600, 0, 599, 0,
+	0, 601, 602, 603, 604, 605, 606, 612, 615, 617,
+	618, 613, 614, 616, 619, 620, 621, 623, 624, 609,
+	610, 611, 0, 622, 607, 0, 608, 366, 0, 625,
+	626, 627, 628, 0, 885, 629, 886, 632, 633, 0,
+	0, 634, 0, 635, 636, 0, 0, 638, 639, 640,
+	0, 0, 641, 642, 887, 0, 643, 0, 888, 644,
+	645, 637, 646, 647, 648, 649, 650, 651, 652, 653,
+	654, 655, 656, 657, 0, 658, 659, 889, 660, 661,
+	662, 663, 664, 890, 665, 666, 667, 891, 668, 892,
+	669, 670, 671, 0, 672, 673, 674, 0, 675, 676,
+	677, 678, 679, 680, 681, 682, 683, 684, 893, 685,
+	686, 688, 687, 689, 690, 0, 691, 692, 0, 693,
+	694, 695, 0, 0, 0, 0, 0, 696, 697, 699,
+	0, 700, 701, 702, 703, 704, 705, 698, 706, 707,
+	708, 709, 710, 711, 712, 713, 0, 715, 716, 714,
+	717, 718, 0, 719, 720, 721, 722, 723, 894, 724,
+	0, 725, 726, 734, 735, 736, 727, 728, 730, 737,
+	729, 738, 739, 740, 741, 743, 742, 0, 745, 746,
+	744, 747, 748, 749, 750, 0, 751, 895, 752, 731,
+	732, 753, 754, 755, 0, 756, 757, 758, 759, 760,
+	761, 762, 763, 764, 896, 0, 766, 0, 765, 767,
+	768, 769, 770, 771, 772, 773, 775, 733, 776, 777,
+	778, 783, 784, 785, 897, 779, 780, 781, 782, 787,
+	898, 788, 789, 790, 791, 0, 792, 793, 0, 786,
+	774, 0, 794, 795, 796, 797, 798, 799, 800, 801,
+	802, 803, 0, 804, 899, 900, 901, 902, 0, 817,
+	0, 805, 807, 808, 809, 810, 903, 811, 812, 904,
+	0, 813, 814, 815, 816, 806, 819, 820, 818, 0,
+	0, 821, 822, 823, 824, 826, 828, 829, 830, 825,
+	827, 831, 0, 832, 0, 0, 833, 834, 835, 905,
+	906, 907, 0, 908, 838, 839, 836, 837, 840, 841,
+	844, 842, 843, 909, 847, 542, 848, 849, 850, 845,
+	846, 359, 0, 0, 0, 851, 852, 910, 853, 854,
+	855, 0, 0, 0, 0, 0, 0, 0, 367, 368,
+	370, 369, 371, 372, 373, 374, 0, 375, 376, 0,
+	0, 0, 0, 0, 856, 0, 0, 0, 378, 0,
+	377, 0, 379, 380, 381, 0, 382, 383, 384, 385,
+	386, 387, 388, 389, 390, 857, 391, 858, 0, 392,
+	859, 393, 860, 0, 861, 394, 395, 396, 397, 398,
+	399, 400, 401, 402, 403, 404, 0, 0, 0, 405,
+	862, 863, 864, 0, 406, 407, 408, 409, 865, 0,
+	0, 0, 410, 411, 412, 413, 414, 415, 416, 417,
+	0, 0, 419, 420, 421, 418, 422, 423, 0, 424,
+	0, 425, 426, 427, 428, 429, 0, 430, 431, 0,
+	432, 433, 434, 0, 435, 436, 437, 0, 0, 0,
+	0, 0, 0, 0, 438, 439, 440, 441, 442, 0,
+	443, 445, 866, 867, 0, 448, 450, 444, 446, 0,
+	449, 447, 451, 452, 0, 453, 454, 455, 456, 457,
+	0, 0, 0, 458, 459, 460, 461, 0, 462, 463,
+	464, 466, 465, 0, 467, 468, 469, 0, 470, 471,
+	868, 472, 473, 474, 476, 478, 475, 477, 479, 480,
+	481, 482, 483, 869, 870, 484, 485, 0, 362, 0,
+	0, 0, 0, 0, 486, 487, 488, 871, 0, 0,
+	0, 489, 0, 491, 495, 496, 492, 493, 494, 497,
+	0, 490, 498, 499, 0, 0, 500, 501, 502, 872,
+	873, 503, 504, 505, 506, 507, 508, 509, 510, 511,
+	0, 512, 513, 874, 0, 875, 514, 0, 515, 516,
+	517, 518, 519, 520, 521, 2637, 877, 878, 630, 0,
+	522, 523, 524, 525, 0, 526, 527, 528, 529, 530,
+	531, 532, 0, 0, 0, 533, 534, 535, 536, 0,
+	364, 363, 365, 0, 879, 537, 631, 538, 539, 880,
+	881, 0, 882, 0, 540, 541, 544, 0, 883, 0,
+	543, 545, 546, 0, 547, 0, 0, 0, 548, 549,
+	550, 551, 552, 553, 554, 0, 555, 557, 556, 0,
+	559, 884, 558, 0, 560, 561, 0, 0, 562, 563,
+	564, 565, 566, 567, 572, 0, 0, 568, 569, 570,
+	571, 573, 574, 0, 575, 576, 578, 581, 577, 579,
+	580, 582, 583, 596, 597, 598, 584, 585, 586, 587,
+	588, 589, 590, 591, 592, 593, 594, 595, 600, 0,
+	599, 0, 0, 601, 602, 603, 604, 605, 606, 612,
+	615, 617, 618, 613, 614, 616, 619, 620, 621, 623,
+	624, 609, 610, 611, 0, 622, 607, 0, 608, 366,
+	0, 625, 626, 627, 628, 0, 885, 629, 886, 632,
+	633, 0, 0, 634, 0, 635, 636, 0, 0, 638,
+	639, 640, 0, 0, 641, 642, 887, 0, 643, 0,
+	888, 644, 645, 637, 646, 647, 648, 649, 650, 651,
+	652, 653, 654, 655, 656, 657, 0, 658, 659, 889,
+	660, 661, 662, 663, 664, 890, 665, 666, 667, 891,
+	668, 892, 669, 670, 671, 0, 672, 673, 674, 0,
+	675, 676, 677, 678, 679, 680, 681, 682, 683, 684,
+	893, 685, 686, 688, 687, 689, 690, 0, 691, 692,
+	0, 693, 694, 695, 0, 0, 0, 0, 0, 696,
+	697, 699, 0, 700, 701, 702, 703, 704, 705, 698,
+	706, 707, 708, 709, 710, 711, 712, 713, 0, 715,
+	716, 714, 717, 718, 0, 719, 720, 721, 722, 723,
+	894, 724, 0, 725, 726, 734, 735, 736, 727, 728,
+	730, 737, 729, 738, 739, 740, 741, 743, 742, 0,
+	745, 746, 744, 747, 748, 749, 750, 0, 751, 895,
+	752, 731, 732, 753, 754, 755, 0, 756, 757, 758,
+	759, 760, 761, 762, 763, 764, 896, 0, 766, 0,
+	765, 767, 768, 769, 770, 771, 772, 773, 775, 733,
+	776, 777, 778, 783, 784, 785, 897, 779, 780, 781,
+	782, 787, 898, 788, 789, 790, 791, 0, 792, 793,
+	0, 786, 774, 0, 794, 795, 796, 797, 798, 799,
+	800, 801, 802, 803, 0, 804, 899, 900, 901, 902,
+	0, 817, 0, 805, 807, 808, 809, 810, 903, 811,
+	812, 904, 0, 813, 814, 815, 816, 806, 819, 820,
+	818, 0, 0, 821, 822, 823, 824, 826, 828, 829,
+	830, 825, 827, 831, 0, 832, 0, 0, 833, 834,
+	835, 905, 906, 907, 0, 908, 838, 839, 836, 837,
+	840, 841, 844, 842, 843, 909, 847, 542, 848, 849,
+	850, 845, 846, 983, 0, 359, 0, 851, 852, 910,
+	853, 854, 855, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 367, 368, 370, 369, 371, 981, 373, 374,
+	969, 375, 376, 0, 0, 0, 0, 0, 856, 0,
+	0, 0, 378, 0, 377, 0, 379, 380, 381, 0,
+	382, 383, 384, 385, 386, 387, 388, 389, 390, 857,
+	391, 858, 0, 392, 859, 393, 860, 0, 861, 394,
+	395, 396, 397, 398, 399, 400, 401, 402, 403, 404,
+	0, 0, 0, 405, 862, 863, 864, 0, 406, 407,
+	408, 409, 865, 0, 0, 0, 410, 411, 412, 413,
+	414, 415, 416, 417, 0, 0, 419, 420, 421, 418,
+	422, 423, 0, 424, 0, 425, 426, 427, 428, 429,
+	0, 430, 431, 972, 432, 433, 434, 0, 435, 436,
+	437, 0, 0, 0, 0, 0, 0, 0, 438, 439,
+	440, 441, 442, 0, 443, 445, 866, 867, 0, 448,
+	450, 444, 446, 0, 449, 447, 451, 452, 0, 453,
+	454, 455, 456, 457, 0, 0, 0, 458, 459, 460,
+	461, 0, 462, 463, 464, 466, 465, 0, 467, 468,
+	469, 0, 470, 471, 868, 472, 473, 474, 476, 478,
+	475, 477, 479, 480, 481, 482, 483, 869, 870, 484,
+	485, 0, 0, 0, 0, 0, 0, 0, 486, 487,
+	488, 871, 0, 0, 0, 489, 0, 491, 495, 496,
+	492, 493, 494, 497, 0, 490, 498, 499, 0, 0,
+	500, 501, 502, 872, 873, 503, 504, 505, 506, 507,
+	508, 509, 510, 511, 979, 512, 513, 874, 0, 875,
+	514, 0, 515, 516, 517, 518, 519, 520, 521, 876,
+	877, 878, 630, 0, 522, 523, 524, 525, 0, 526,
+	527, 528, 529, 530, 531, 532, 0, 0, 0, 533,
+	534, 535, 536, 0, 0, 0, 0, 0, 879, 537,
+	631, 538, 539, 880, 881, 0, 882, 0, 540, 541,
+	544, 0, 883, 0, 543, 545, 546, 0, 547, 0,
+	0, 0, 548, 549, 550, 551, 552, 553, 554, 0,
+	555, 557, 556, 0, 559, 884, 558, 0, 560, 561,
+	0, 0, 562, 563, 564, 565, 566, 567, 572, 0,
+	0, 568, 569, 570, 571, 573, 574, 0, 575, 576,
+	578, 581, 577, 579, 580, 582, 583, 596, 597, 598,
+	584, 585, 586, 587, 588, 589, 590, 591, 592, 593,
+	594, 595, 600, 0, 599, 0, 0, 601, 602, 603,
+	604, 605, 606, 612, 615, 617, 618, 613, 614, 616,
+	619, 620, 621, 623, 624, 609, 610, 611, 0, 622,
+	607, 0, 608, 0, 0, 625, 626, 627, 628, 0,
+	885, 629, 886, 632, 633, 0, 0, 634, 0, 635,
+	636, 0, 0, 638, 639, 640, 0, 0, 641, 642,
+	887, 0, 643, 0, 888, 644, 645, 637, 646, 647,
+	648, 649, 650, 651, 652, 653, 654, 655, 656, 657,
+	0, 658, 659, 889, 660, 661, 662, 663, 664, 890,
+	665, 666, 667, 891, 668, 892, 669, 670, 671, 0,
+	672, 673, 674, 0, 675, 676, 677, 678, 679, 680,
+	681, 682, 683, 684, 893, 685, 686, 688, 687, 689,
+	690, 0, 691, 692, 0, 693, 694, 695, 0, 0,
+	0, 0, 0, 696, 697, 699, 0, 700, 701, 702,
+	703, 704, 705, 698, 706, 707, 708, 709, 710, 711,
+	712, 713, 0, 715, 716, 714, 717, 718, 0, 719,
+	720, 721, 722, 723, 894, 724, 0, 725, 726, 734,
+	735, 736, 727, 728, 730, 737, 729, 738, 739, 740,
+	741, 743, 742, 974, 745, 746, 744, 747, 748, 749,
+	750, 0, 751, 895, 752, 731, 732, 753, 754, 755,
+	0, 756, 757, 758, 759, 760, 761, 762, 763, 764,
+	896, 0, 766, 0, 765, 767, 768, 769, 770, 771,
+	772, 773, 775, 733, 776, 777, 778, 783, 784, 785,
+	897, 779, 780, 781, 782, 787, 898, 788, 789, 790,
+	791, 0, 792, 982, 0, 786, 774, 0, 794, 795,
+	796, 797, 798, 799, 800, 801, 802, 803, 0, 804,
+	899, 900, 901, 902, 0, 817, 0, 805, 807, 808,
+	809, 810, 903, 811, 812, 904, 0, 813, 814, 815,
+	816, 806, 819, 820, 818, 0, 0, 821, 822, 823,
+	824, 826, 828, 829, 830, 825, 827, 831, 0, 832,
+	0, 0, 833, 834, 835, 905, 906, 907, 0, 908,
+	838, 839, 836, 837, 840, 841, 844, 842, 843, 909,
+	847, 542, 848, 849, 850, 845, 846, 968, 0, 359,
+	0, 851, 852, 910, 853, 854, 855, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 367, 368, 370, 369,
+	371, 372, 373, 374, 969, 375, 376, 0, 0, 0,
+	0, 0, 856, 0, 0, 0, 378, 0, 377, 0,
+	379, 380, 381, 0, 382, 383, 384, 385, 386, 387,
+	388, 389, 390, 857, 391, 858, 0, 392, 859, 393,
+	860, 0, 861, 394, 395, 396, 397, 398, 399, 400,
+	401, 402, 403, 404, 0, 0, 0, 405, 862, 863,
+	864, 0, 406, 407, 408, 409, 865, 0, 0, 0,
+	410, 411, 412, 413, 414, 415, 416, 417, 0, 0,
+	419, 420, 421, 418, 422, 423, 0, 424, 0, 425,
+	426, 427, 428, 429, 0, 430, 431, 972, 432, 433,
+	434, 0, 435, 436, 437, 0, 0, 0, 0, 0,
+	0, 0, 438, 439, 440, 441, 442, 0, 443, 445,
+	866, 867, 0, 448, 450, 444, 446, 0, 449, 447,
+	451, 452, 0, 453, 454, 455, 456, 457, 0, 0,
+	0, 458, 459, 460, 461, 0, 462, 463, 464, 466,
+	465, 0, 467, 468, 469, 0, 470, 471, 868, 472,
+	473, 474, 476, 478, 475, 477, 479, 480, 481, 482,
+	483, 869, 870, 484, 485, 0, 0, 0, 0, 0,
+	0, 0, 486, 487, 488, 871, 0, 0, 0, 489,
+	0, 491, 495, 496, 492, 493, 494, 497, 0, 490,
+	498, 499, 0, 0, 500, 501, 502, 872, 873, 503,
+	504, 505, 506, 507, 508, 509, 510, 511, 973, 512,
+	513, 874, 0, 875, 514, 0, 515, 516, 517, 518,
+	519, 520, 521, 876, 877, 878, 630, 0, 522, 523,
+	524, 525, 0, 526, 527, 528, 529, 530, 531, 532,
+	0, 0, 0, 533, 534, 535, 536, 0, 0, 0,
+	0, 0, 879, 537, 631, 538, 539, 880, 881, 0,
+	882, 0, 540, 541, 544, 0, 883, 0, 543, 545,
+	546, 0, 547, 0, 0, 0, 548, 549, 550, 551,
+	552, 553, 554, 0, 555, 557, 556, 0, 559, 884,
+	558, 0, 560, 561, 0, 0, 562, 563, 564, 565,
+	566, 567, 572, 0, 0, 568, 569, 570, 571, 573,
+	574, 0, 575, 576, 578, 581, 577, 579, 580, 582,
+	583, 596, 597, 598, 584, 585, 586, 587, 588, 589,
+	590, 591, 592, 593, 594, 595, 600, 0, 599, 0,
+	0, 601, 602, 603, 604, 605, 606, 612, 615, 617,
+	618, 613, 614, 616, 619, 620, 621, 623, 624, 609,
+	610, 611, 0, 622, 607, 0, 608, 0, 0, 625,
+	626, 627, 628, 0, 885, 629, 886, 632, 633, 0,
+	0, 634, 0, 635, 636, 0, 0, 638, 639, 640,
+	0, 0, 641, 642, 887, 0, 643, 0, 888, 644,
+	645, 637, 646, 647, 648, 649, 650, 651, 652, 653,
+	654, 655, 656, 657, 0, 658, 659, 889, 660, 661,
+	662, 663, 664, 890, 665, 666, 667, 891, 668, 892,
+	669, 670, 671, 0, 672, 673, 674, 0, 675, 676,
+	677, 678, 679, 680, 681, 682, 683, 684, 893, 685,
+	686, 688, 687, 689, 690, 0, 691, 692, 0, 693,
+	694, 695, 0, 0, 0, 0, 0, 696, 697, 699,
+	0, 700, 701, 702, 703, 704, 705, 698, 706, 707,
+	708, 709, 710, 711, 712, 713, 0, 715, 716, 714,
+	717, 718, 0, 719, 720, 721, 722, 723, 894, 724,
+	0, 725, 726, 734, 735, 736, 727, 728, 730, 737,
+	729, 738, 739, 740, 741, 743, 742, 974, 745, 746,
+	744, 747, 748, 749, 750, 0, 751, 895, 752, 731,
+	732, 753, 754, 755, 0, 756, 757, 758, 759, 760,
+	761, 762, 763, 764, 896, 0, 766, 0, 765, 767,
+	768, 769, 770, 771, 772, 773, 775, 733, 776, 777,
+	778, 783, 784, 785, 897, 779, 780, 781, 782, 787,
+	898, 788, 789, 790, 791, 0, 792, 967, 0, 786,
+	774, 0, 794, 795, 796, 797, 798, 799, 800, 801,
+	802, 803, 0, 804, 899, 900, 901, 902, 0, 817,
+	0, 805, 807, 808, 809, 810, 903, 811, 812, 904,
+	0, 813, 814, 815, 816, 806, 819, 820, 818, 0,
+	0, 821, 822, 823, 824, 826, 828, 829, 830, 825,
+	827, 831, 0, 832, 0, 0, 833, 834, 835, 905,
+	906, 907, 0, 908, 838, 839, 836, 837, 840, 841,
+	844, 842, 843, 909, 847, 542, 848, 849, 850, 845,
+	846, 359, 0, 0, 0, 851, 852, 910, 853, 854,
+	855, 0, 0, 0, 0, 0, 0, 0, 367, 368,
+	370, 369, 371, 372, 373, 374, 969, 375, 376, 0,
+	0, 0, 0, 0, 856, 0, 0, 0, 378, 0,
+	377, 0, 379, 380, 381, 0, 382, 383, 384, 385,
+	386, 387, 388, 389, 390, 857, 391, 858, 0, 392,
+	859, 393, 860, 0, 861, 394, 395, 396, 397, 398,
+	399, 400, 401, 402, 403, 404, 0, 0, 0, 405,
+	862, 863, 864, 0, 406, 407, 408, 409, 865, 0,
+	0, 0, 410, 411, 412, 413, 414, 415, 416, 417,
+	0, 0, 419, 420, 421, 418, 422, 423, 0, 424,
+	0, 425, 426, 427, 428, 429, 0, 430, 431, 972,
+	432, 433, 434, 0, 435, 436, 437, 0, 0, 0,
+	0, 0, 0, 0, 438, 439, 440, 441, 442, 0,
+	443, 445, 866, 867, 0, 448, 450, 444, 446, 0,
+	449, 447, 451, 452, 0, 453, 454, 455, 456, 457,
+	0, 0, 0, 458, 459, 460, 461, 0, 462, 463,
+	464, 466, 465, 0, 467, 468, 469, 0, 470, 471,
+	868, 472, 473, 474, 476, 478, 475, 477, 479, 480,
+	481, 482, 483, 869, 870, 484, 485, 0, 0, 0,
+	0, 0, 0, 0, 486, 487, 488, 871, 0, 0,
+	0, 489, 0, 491, 495, 496, 492, 493, 494, 497,
+	0, 490, 498, 499, 0, 0, 500, 501, 502, 872,
+	873, 503, 504, 505, 506, 507, 508, 509, 510, 511,
+	973, 512, 513, 874, 0, 875, 514, 0, 515, 516,
+	517, 518, 519, 520, 521, 876, 877, 878, 630, 0,
+	522, 523, 524, 525, 0, 526, 527, 528, 529, 530,
+	531, 532, 0, 0, 0, 533, 534, 535, 536, 0,
+	0, 0, 0, 0, 879, 537, 631, 538, 539, 880,
+	881, 0, 882, 0, 540, 541, 544, 0, 883, 0,
+	543, 545, 546, 0, 547, 0, 0, 0, 548, 549,
+	550, 551, 552, 553, 554, 0, 555, 557, 556, 0,
+	559, 884, 558, 0, 560, 561, 0, 0, 562, 563,
+	564, 565, 566, 567, 572, 0, 0, 568, 569, 570,
+	571, 573, 574, 0, 575, 576, 578, 581, 577, 579,
+	580, 582, 583, 596, 597, 598, 584, 585, 586, 587,
+	588, 589, 590, 591, 592, 593, 594, 595, 600, 0,
+	599, 0, 0, 601, 602, 603, 604, 605, 606, 612,
+	615, 617, 618, 613, 614, 616, 619, 620, 621, 623,
+	624, 609, 610, 611, 0, 622, 607, 0, 608, 0,
+	0, 625, 626, 627, 628, 0, 885, 629, 886, 632,
+	633, 0, 0, 634, 0, 635, 636, 0, 0, 638,
+	639, 640, 0, 0, 641, 642, 887, 0, 643, 0,
+	888, 644, 645, 637, 646, 647, 648, 649, 650, 651,
+	652, 653, 654, 655, 656, 657, 0, 658, 659, 889,
+	660, 661, 662, 663, 664, 890, 665, 666, 667, 891,
+	668, 892, 669, 670, 671, 0, 672, 673, 674, 0,
+	675, 676, 677, 678, 679, 680, 681, 682, 683, 684,
+	893, 685, 686, 688, 687, 689, 690, 0, 691, 692,
+	0, 693, 694, 695, 0, 0, 0, 0, 0, 696,
+	697, 699, 0, 700, 701, 702, 703, 704, 705, 698,
+	706, 707, 708, 709, 710, 711, 712, 713, 0, 715,
+	716, 714, 717, 718, 0, 719, 720, 721, 722, 723,
+	894, 724, 0, 725, 726, 734, 735, 736, 727, 728,
+	730, 737, 729, 738, 739, 740, 741, 743, 742, 974,
+	745, 746, 744, 747, 748, 749, 750, 0, 751, 895,
+	752, 731, 732, 753, 754, 755, 0, 756, 757, 758,
+	759, 760, 761, 762, 763, 764, 896, 0, 766, 0,
+	765, 767, 768, 769, 770, 771, 772, 773, 775, 733,
+	776, 777, 778, 783, 784, 785, 897, 779, 780, 781,
+	782, 787, 898, 788, 789, 790, 791, 0, 792, 793,
+	0, 786, 774, 0, 794, 795, 796, 797, 798, 799,
+	800, 801, 802, 803, 0, 804, 899, 900, 901, 902,
+	0, 817, 0, 805, 807, 808, 809, 810, 903, 811,
+	812, 904, 0, 813, 814, 815, 816, 806, 819, 820,
+	818, 0, 0, 821, 822, 823, 824, 826, 828, 829,
+	830, 825, 827, 831, 0, 832, 0, 0, 833, 834,
+	835, 905, 906, 907, 0, 908, 838, 839, 836, 837,
+	840, 841, 844, 842, 843, 909, 847, 542, 848, 849,
+	850, 845, 846, 359, 0, 0, 0, 851, 852, 910,
+	853, 854, 855, 0, 0, 0, 0, 0, 0, 0,
+	367, 368, 370, 369, 371, 372, 373, 374, 969, 375,
+	376, 0, 0, 0, 0, 0, 856, 0, 0, 0,
+	378, 0, 377, 0, 379, 380, 381, 0, 382, 383,
+	384, 385, 386, 387, 388, 389, 390, 857, 391, 858,
+	0, 392, 859, 393, 860, 0, 861, 394, 395, 396,
+	397, 398, 399, 400, 401, 402, 403, 404, 0, 0,
+	0, 405, 862, 863, 864, 0, 406, 407, 408, 409,
+	865, 0, 0, 0, 410, 411, 412, 413, 414, 415,
+	416, 417, 0, 0, 419, 420, 421, 418, 422, 423,
+	0, 424, 0, 425, 426, 427, 428, 429, 0, 430,
+	431, 972, 432, 433, 434, 0, 435, 436, 437, 0,
+	0, 0, 0, 0, 0, 0, 438, 439, 440, 441,
+	442, 0, 443, 445, 866, 867, 0, 448, 450, 444,
+	446, 0, 449, 447, 451, 452, 0, 453, 454, 455,
+	456, 457, 0, 0, 0, 458, 459, 460, 461, 0,
+	462, 463, 464, 466, 465, 0, 467, 468, 469, 0,
+	470, 471, 868, 472, 473, 474, 476, 478, 475, 477,
+	479, 480, 481, 482, 483, 869, 870, 484, 485, 0,
+	0, 0, 0, 0, 0, 0, 486, 487, 488, 871,
+	0, 0, 0, 489, 0, 491, 495, 496, 492, 493,
+	494, 497, 0, 490, 498, 499, 0, 0, 500, 501,
+	502, 872, 873, 503, 504, 505, 506, 507, 508, 509,
+	510, 511, 5841, 512, 513, 874, 0, 875, 514, 0,
+	515, 516, 517, 518, 519, 520, 521, 876, 877, 878,
+	630, 0, 522, 523, 524, 525, 0, 526, 527, 528,
+	529, 530, 531, 532, 0, 0, 0, 533, 534, 535,
+	536, 0, 0, 0, 0, 0, 879, 537, 631, 538,
+	539, 880, 881, 0, 882, 0, 540, 541, 544, 0,
+	883, 0, 543, 545, 546, 0, 547, 0, 0, 0,
+	548, 549, 550, 551, 552, 553, 554, 0, 555, 557,
+	556, 0, 559, 884, 558, 0, 560, 561, 0, 0,
+	562, 563, 564, 565, 566, 567, 572, 0, 0, 568,
+	569, 570, 571, 573, 574, 0, 575, 576, 578, 581,
+	577, 579, 580, 582, 583, 596, 597, 598, 584, 585,
+	586, 587, 588, 589, 590, 591, 592, 593, 594, 595,
+	600, 0, 599, 0, 0, 601, 602, 603, 604, 605,
+	606, 612, 615, 617, 618, 613, 614, 616, 619, 620,
+	621, 623, 624, 609, 610, 611, 0, 622, 607, 0,
+	608, 0, 0, 625, 626, 627, 628, 0, 885, 629,
+	886, 632, 633, 0, 0, 634, 0, 635, 636, 0,
+	0, 638, 639, 640, 0, 0, 641, 642, 887, 0,
+	643, 0, 888, 644, 645, 637, 646, 647, 648, 649,
+	650, 651, 652, 653, 654, 655, 656, 657, 0, 658,
+	659, 889, 660, 661, 662, 663, 664, 890, 665, 666,
+	667, 891, 668, 892, 669, 670, 671, 0, 672, 673,
+	674, 0, 675, 676, 677, 678, 679, 680, 681, 682,
+	683, 684, 893, 685, 686, 688, 687, 689, 690, 0,
+	691, 692, 0, 693, 694, 695, 0, 0, 0, 0,
+	0, 696, 697, 699, 0, 700, 701, 702, 703, 704,
+	705, 698, 706, 707, 708, 709, 710, 711, 712, 713,
+	0, 715, 716, 714, 717, 718, 0, 719, 720, 721,
+	722, 723, 894, 724, 0, 725, 726, 734, 735, 736,
+	727, 728, 730, 737, 729, 738, 739, 740, 741, 743,
+	742, 974, 745, 746, 744, 747, 748, 749, 750, 0,
+	751, 895, 752, 731, 732, 753, 754, 755, 0, 756,
+	757, 758, 759, 760, 761, 762, 763, 764, 896, 0,
+	766, 0, 765, 767, 768, 769, 770, 771, 772, 773,
+	775, 733, 776, 777, 778, 783, 784, 785, 897, 779,
+	780, 781, 782, 787, 898, 788, 789, 790, 791, 0,
+	792, 793, 0, 786, 774, 0, 794, 795, 796, 797,
+	798, 799, 800, 801, 802, 803, 0, 804, 899, 900,
+	901, 902, 0, 817, 0, 805, 807, 808, 809, 810,
+	903, 811, 812, 904, 0, 813, 814, 815, 816, 806,
+	819, 820, 818, 0, 0, 821, 822, 823, 824, 826,
+	828, 829, 830, 825, 827, 831, 0, 832, 0, 0,
+	833, 834, 835, 905, 906, 907, 0, 908, 838, 839,
+	836, 837, 840, 841, 844, 842, 843, 909, 847, 542,
+	848, 849, 850, 845, 846, 359, 0, 0, 0, 851,
+	852, 910, 853, 854, 855, 0, 0, 0, 0, 0,
+	0, 0, 367, 368, 370, 369, 371, 372, 373, 374,
+	969, 375, 376, 0, 0, 0, 0, 0, 856, 0,
+	0, 0, 378, 0, 377, 0, 379, 380, 381, 0,
+	382, 383, 384, 385, 386, 387, 388, 389, 390, 857,
+	391, 858, 0, 392, 859, 393, 860, 0, 861, 394,
+	395, 396, 397, 398, 399, 400, 401, 402, 403, 404,
+	0, 0, 0, 405, 862, 863, 864, 0, 406, 407,
+	408, 409, 865, 0, 0, 0, 410, 411, 412, 413,
+	414, 415, 416, 417, 0, 0, 419, 420, 421, 418,
+	422, 423, 0, 424, 0, 425, 426, 427, 428, 429,
+	0, 430, 431, 972, 432, 433, 434, 0, 435, 436,
+	437, 0, 0, 0, 0, 0, 0, 0, 438, 439,
+	440, 441, 442, 0, 443, 445, 866, 867, 0, 448,
+	450, 444, 446, 0, 449, 447, 451, 452, 0, 453,
+	454, 455, 456, 457, 0, 0, 0, 458, 459, 460,
+	461, 0, 462, 463, 464, 466, 465, 0, 467, 468,
+	469, 0, 470, 471, 868, 472, 473, 474, 476, 478,
+	475, 477, 479, 480, 481, 482, 483, 869, 870, 484,
+	485, 0, 0, 0, 0, 0, 0, 0, 486, 487,
+	488, 871, 0, 0, 0, 489, 0, 491, 495, 496,
+	492, 493, 494, 497, 0, 490, 498, 499, 0, 0,
+	500, 501, 502, 872, 873, 503, 504, 505, 506, 507,
+	508, 509, 510, 511, 973, 512, 513, 874, 0, 875,
+	514, 0, 515, 516, 517, 518, 519, 520, 521, 876,
+	877, 878, 630, 0, 522, 523, 524, 525, 0, 526,
+	527, 528, 529, 530, 531, 532, 0, 0, 0, 533,
+	534, 535, 536, 0, 0, 0, 0, 0, 879, 537,
+	631, 538, 539, 880, 881, 0, 882, 0, 540, 541,
+	544, 0, 883, 0, 543, 545, 546, 0, 547, 0,
+	0, 0, 548, 549, 550, 551, 552, 553, 554, 0,
+	555, 557, 556, 0, 559, 884, 558, 0, 560, 561,
+	0, 0, 562, 563, 564, 565, 566, 567, 572, 0,
+	0, 568, 569, 570, 571, 573, 574, 0, 575, 576,
+	578, 581, 577, 579, 580, 582, 583, 596, 597, 598,
+	584, 585, 586, 587, 588, 589, 590, 591, 592, 593,
+	594, 595, 600, 0, 599, 0, 0, 601, 602, 603,
+	604, 605, 606, 612, 615, 617, 618, 613, 614, 616,
+	619, 620, 621, 623, 624, 609, 610, 611, 0, 622,
+	607, 0, 608, 0, 0, 625, 626, 627, 628, 0,
+	885, 629, 886, 632, 633, 0, 0, 634, 0, 635,
+	636, 0, 0, 638, 639, 640, 0, 0, 641, 642,
+	887, 0, 643, 0, 888, 644, 645, 637, 646, 647,
+	648, 649, 650, 651, 652, 653, 654, 655, 656, 657,
+	0, 658, 659, 889, 660, 661, 662, 663, 664, 890,
+	665, 666, 667, 891, 668, 892, 669, 670, 671, 0,
+	672, 673, 674, 0, 675, 676, 677, 678, 679, 680,
+	681, 682, 683, 684, 893, 685, 686, 688, 687, 689,
+	690, 0, 691, 692, 0, 693, 694, 695, 0, 0,
+	0, 0, 0, 696, 697, 699, 0, 700, 701, 702,
+	703, 704, 705, 698, 706, 707, 708, 709, 710, 711,
+	712, 713, 0, 715, 716, 714, 717, 718, 0, 719,
+	720, 721, 722, 723, 894, 724, 0, 725, 726, 734,
+	735, 736, 727, 728, 730, 737, 729, 738, 739, 740,
+	741, 743, 742, 974, 745, 746, 744, 747, 748, 749,
+	750, 0, 751, 895, 752, 731, 732, 753, 754, 755,
+	0, 756, 757, 758, 759, 760, 761, 762, 763, 764,
+	896, 0, 766, 0, 765, 767, 768, 769, 770, 771,
+	772, 773, 775, 733, 776, 777, 778, 783, 784, 785,
+	897, 779, 780, 781, 782, 787, 898, 788, 789, 790,
+	791, 0, 792, 4201, 0, 786, 774, 0, 794, 795,
+	796, 797, 798, 799, 800, 801, 802, 803, 0, 804,
+	899, 900, 901, 902, 0, 817, 0, 805, 807, 808,
+	809, 810, 903, 811, 812, 904, 0, 813, 814, 815,
+	816, 806, 819, 820, 818, 0, 0, 821, 822, 823,
+	824, 826, 828, 829, 830, 825, 827, 831, 0, 832,
+	0, 0, 833, 834, 835, 905, 906, 907, 0, 908,
+	838, 839, 836, 837, 840, 841, 844, 842, 843, 909,
+	847, 542, 848, 849, 850, 845, 846, 359, 0, 0,
+	0, 851, 852, 910, 853, 854, 855, 0, 0, 0,
+	0, 0, 0, 0, 367, 368, 370, 369, 371, 372,
+	373, 374, 0, 375, 376, 0, 0, 0, 0, 0,
+	856, 0, 0, 0, 378, 0, 377, 0, 379, 380,
+	381, 0, 382, 383, 384, 385, 386, 387, 388, 389,
+	390, 857, 391, 858, 0, 392, 859, 393, 860, 0,
+	861, 394, 395, 396, 397, 398, 399, 400, 401, 402,
+	403, 404, 0, 0, 0, 405, 862, 863, 864, 0,
+	406, 407, 408, 409, 865, 0, 0, 0, 410, 411,
+	412, 413, 414, 415, 416, 417, 0, 0, 419, 420,
+	421, 418, 422, 423, 0, 424, 0, 425, 426, 427,
+	428, 429, 0, 430, 431, 972, 432, 433, 434, 0,
+	435, 436, 437, 0, 0, 0, 0, 0, 0, 0,
+	438, 439, 440, 441, 442, 0, 443, 445, 866, 867,
+	0, 448, 450, 444, 446, 0, 449, 447, 451, 452,
+	0, 453, 454, 455, 456, 457, 0, 0, 0, 458,
+	459, 460, 461, 0, 462, 463, 464, 466, 465, 0,
+	467, 468, 469, 0, 470, 471, 868, 472, 473, 474,
+	476, 478, 475, 477, 479, 480, 481, 482, 483, 869,
+	870, 484, 485, 0, 0, 0, 0, 0, 0, 0,
+	486, 487, 488, 871, 0, 0, 0, 489, 0, 491,
+	495, 496, 492, 493, 494, 497, 0, 490, 498, 499,
+	0, 0, 500, 501, 502, 872, 873, 503, 504, 505,
+	506, 507, 508, 509, 510, 511, 973, 512, 513, 874,
+	0, 875, 514, 0, 515, 516, 517, 518, 519, 520,
+	521, 876, 877, 878, 630, 0, 522, 523, 524, 525,
+	0, 526, 527, 528, 529, 530, 531, 532, 0, 0,
+	0, 533, 534, 535, 536, 0, 0, 0, 0, 0,
+	879, 537, 631, 538, 539, 880, 881, 0, 882, 0,
+	540, 541, 544, 0, 883, 0, 543, 545, 546, 0,
+	547, 0, 0, 0, 548, 549, 550, 551, 552, 553,
+	554, 0, 555, 557, 556, 0, 559, 884, 558, 0,
+	560, 561, 0, 0, 562, 563, 564, 565, 566, 567,
+	572, 0, 0, 568, 569, 570, 571, 573, 574, 0,
+	575, 576, 578, 581, 577, 579, 580, 582, 583, 596,
+	597, 598, 584, 585, 586, 587, 588, 589, 590, 591,
+	592, 593, 594, 595, 600, 0, 599, 0, 0, 601,
+	602, 603, 604, 605, 606, 612, 615, 617, 618, 613,
+	614, 616, 619, 620, 621, 623, 624, 609, 610, 611,
+	0, 622, 607, 0, 608, 0, 0, 625, 626, 627,
+	628, 0, 885, 629, 886, 632, 633, 0, 0, 634,
+	0, 635, 636, 0, 0, 638, 639, 640, 0, 0,
+	641, 642, 887, 0, 643, 0, 888, 644, 645, 637,
+	646, 647, 648, 649, 650, 651, 652, 653, 654, 655,
+	656, 657, 0, 658, 659, 889, 660, 661, 662, 663,
+	664, 890, 665, 666, 667, 891, 668, 892, 669, 670,
+	671, 0, 672, 673, 674, 0, 675, 676, 677, 678,
+	679, 680, 681, 682, 683, 684, 893, 685, 686, 688,
+	687, 689, 690, 0, 691, 692, 0, 693, 694, 695,
+	0, 0, 0, 0, 0, 696, 697, 699, 0, 700,
+	701, 702, 703, 704, 705, 698, 706, 707, 708, 709,
+	710, 711, 712, 713, 0, 715, 716, 714, 717, 718,
+	0, 719, 720, 721, 722, 723, 894, 724, 0, 725,
+	726, 734, 735, 736, 727, 728, 730, 737, 729, 738,
+	739, 740, 741, 743, 742, 974, 745, 746, 744, 747,
+	748, 749, 750, 0, 751, 895, 752, 731, 732, 753,
+	754, 755, 0, 756, 757, 758, 759, 760, 761, 762,
+	763, 764, 896, 0, 766, 0, 765, 767, 768, 769,
+	770, 771, 772, 773, 775, 733, 776, 777, 778, 783,
+	784, 785, 897, 779, 780, 781, 782, 787, 898, 788,
+	789, 790, 791, 0, 792, 793, 0, 786, 774, 0,
+	794, 795, 796, 797, 798, 799, 800, 801, 802, 803,
+	0, 804, 899, 900, 901, 902, 0, 817, 0, 805,
+	807, 808, 809, 810, 903, 811, 812, 904, 0, 813,
+	814, 815, 816, 806, 819, 820, 818, 0, 0, 821,
+	822, 823, 824, 826, 828, 829, 830, 825, 827, 831,
+	0, 832, 0, 0, 833, 834, 835, 905, 906, 907,
+	0, 908, 838, 839, 836, 837, 840, 841, 844, 842,
+	843, 909, 847, 542, 848, 849, 850, 845, 846, 1306,
+	0, 359, 0, 851, 852, 910, 853, 854, 855, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 367, 368,
+	370, 369, 371, 372, 373, 374, 0, 375, 376, 0,
+	0, 0, 0, 0, 856, 0, 0, 0, 378, 0,
+	377, 0, 379, 380, 381, 0, 382, 383, 384, 385,
+	386, 387, 388, 389, 390, 857, 391, 858, 0, 392,
+	859, 393, 860, 0, 861, 394, 395, 396, 397, 398,
+	399, 400, 401, 402, 403, 404, 0, 0, 0, 405,
+	862, 863, 864, 0, 406, 407, 408, 409, 865, 0,
+	0, 0, 410, 411, 412, 413, 414, 415, 416, 417,
+	0, 0, 419, 420, 421, 418, 422, 423, 0, 424,
+	0, 425, 426, 427, 428, 429, 0, 430, 431, 0,
+	432, 433, 434, 0, 435, 436, 437, 0, 0, 0,
+	0, 0, 0, 0, 438, 439, 440, 441, 442, 0,
+	443, 445, 866, 867, 0, 448, 450, 444, 446, 0,
+	449, 447, 451, 452, 0, 453, 454, 455, 456, 457,
+	0, 0, 0, 458, 459, 460, 461, 0, 462, 463,
+	464, 466, 465, 0, 467, 468, 469, 0, 470, 471,
+	868, 472, 473, 474, 476, 478, 475, 477, 479, 480,
+	481, 482, 483, 869, 870, 484, 485, 0, 0, 0,
+	0, 0, 0, 0, 486, 487, 488, 871, 0, 0,
+	0, 489, 0, 491, 495, 496, 492, 493, 494, 497,
+	0, 490, 498, 499, 0, 0, 500, 501, 502, 872,
+	873, 503, 504, 505, 506, 507, 508, 509, 510, 511,
+	0, 512, 513, 874, 0, 875, 514, 0, 515, 516,
+	517, 518, 519, 520, 521, 876, 877, 878, 630, 0,
+	522, 523, 524, 525, 0, 526, 527, 528, 529, 530,
+	531, 532, 0, 0, 0, 533, 534, 535, 536, 0,
+	0, 0, 0, 0, 879, 537, 631, 538, 539, 880,
+	881, 0, 882, 1305, 540, 541, 544, 0, 883, 0,
+	543, 545, 546, 0, 547, 0, 0, 0, 548, 549,
+	550, 551, 552, 553, 554, 0, 555, 557, 556, 0,
+	559, 884, 558, 0, 560, 561, 0, 0, 562, 563,
+	564, 565, 566, 567, 572, 0, 0, 568, 569, 570,
+	571, 573, 574, 0, 575, 576, 578, 581, 577, 579,
+	580, 582, 583, 596, 597, 598, 584, 585, 586, 587,
+	588, 589, 590, 591, 592, 593, 594, 595, 600, 0,
+	599, 0, 0, 601, 602, 603, 604, 605, 606, 612,
+	615, 617, 618, 613, 614, 616, 619, 620, 621, 623,
+	624, 609, 610, 611, 0, 622, 607, 0, 608, 0,
+	0, 625, 626, 627, 628, 0, 885, 629, 886, 632,
+	633, 0, 0, 634, 0, 635, 636, 0, 0, 638,
+	639, 640, 0, 0, 641, 642, 887, 0, 643, 0,
+	888, 644, 645, 637, 646, 647, 648, 649, 650, 651,
+	652, 653, 654, 655, 656, 657, 0, 658, 659, 889,
+	660, 661, 662, 663, 664, 890, 665, 666, 667, 891,
+	668, 892, 669, 670, 671, 0, 672, 673, 674, 0,
+	675, 676, 677, 678, 679, 680, 681, 682, 683, 684,
+	893, 685, 686, 688, 687, 689, 690, 0, 691, 692,
+	0, 693, 694, 695, 0, 0, 0, 0, 0, 696,
+	697, 699, 0, 700, 701, 702, 703, 704, 705, 698,
+	706, 707, 708, 709, 710, 711, 712, 713, 0, 715,
+	716, 714, 717, 718, 0, 719, 720, 721, 722, 723,
+	894, 724, 0, 725, 726, 734, 735, 736, 727, 728,
+	730, 737, 729, 738, 739, 740, 741, 743, 742, 0,
+	745, 746, 744, 747, 748, 749, 750, 0, 751, 895,
+	752, 731, 732, 753, 754, 755, 0, 756, 757, 758,
+	759, 760, 761, 762, 763, 764, 896, 0, 766, 0,
+	765, 767, 768, 769, 770, 771, 772, 773, 775, 733,
+	776, 777, 778, 783, 784, 785, 897, 779, 780, 781,
+	782, 787, 898, 788, 789, 790, 791, 0, 792, 793,
+	0, 786, 774, 1304, 794, 795, 796, 797, 798, 799,
+	800, 801, 802, 803, 0, 804, 899, 900, 901, 902,
+	0, 817, 0, 805, 807, 808, 809, 810, 903, 811,
+	812, 904, 0, 813, 814, 815, 816, 806, 819, 820,
+	818, 0, 0, 821, 822, 823, 824, 826, 828, 829,
+	830, 825, 827, 831, 0, 832, 0, 0, 833, 834,
+	835, 905, 906, 907, 0, 908, 838, 839, 836, 837,
+	840, 841, 844, 842, 843, 909, 847, 542, 848, 849,
+	850, 845, 846, 1081, 0, 359, 0, 851, 852, 910,
+	853, 854, 855, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 367, 1070, 370, 369, 371, 372, 373, 374,
+	0, 375, 376, 0, 0, 0, 0, 0, 856, 0,
+	0, 0, 378, 0, 377, 0, 379, 380, 381, 0,
+	382, 383, 384, 385, 386, 1079, 388, 389, 390, 857,
+	391, 858, 0, 392, 859, 393, 860, 0, 861, 394,
+	395, 396, 397, 398, 399, 400, 401, 402, 403, 404,
+	0, 0, 0, 405, 862, 863, 864, 0, 406, 407,
+	408, 409, 865, 0, 0, 0, 410, 411, 412, 413,
+	414, 415, 416, 417, 0, 0, 419, 420, 421, 418,
+	422, 423, 0, 424, 0, 425, 426, 427, 428, 429,
+	0, 430, 431, 0, 432, 433, 434, 0, 435, 436,
+	437, 0, 0, 0, 0, 0, 0, 0, 438, 439,
+	440, 441, 442, 0, 443, 445, 866, 867, 0, 448,
+	450, 444, 446, 0, 449, 447, 451, 452, 0, 453,
+	454, 455, 456, 457, 0, 0, 0, 458, 459, 460,
+	461, 0, 462, 463, 464, 466, 465, 0, 467, 468,
+	469, 0, 470, 471, 868, 472, 473, 474, 476, 478,
+	475, 477, 479, 480, 481, 482, 483, 869, 870, 484,
+	485, 0, 0, 0, 0, 0, 0, 0, 486, 487,
+	1072, 871, 0, 0, 0, 489, 0, 491, 495, 496,
+	492, 493, 494, 497, 0, 490, 1078, 499, 1074, 0,
+	500, 501, 502, 872, 873, 503, 504, 505, 506, 507,
+	508, 509, 510, 511, 0, 512, 513, 874, 0, 875,
+	514, 0, 515, 516, 517, 518, 519, 520, 521, 876,
+	877, 878, 630, 0, 522, 523, 524, 525, 1075, 526,
+	527, 528, 529, 530, 531, 532, 0, 0, 0, 533,
+	534, 535, 536, 0, 0, 0, 0, 0, 879, 537,
+	631, 538, 539, 880, 881, 0, 882, 0, 540, 541,
+	544, 0, 883, 0, 543, 545, 546, 0, 547, 0,
+	0, 0, 548, 549, 550, 551, 552, 553, 1073, 0,
+	555, 557, 556, 0, 559, 884, 558, 0, 560, 561,
+	0, 0, 562, 563, 564, 565, 566, 567, 572, 0,
+	0, 568, 569, 570, 571, 573, 574, 0, 575, 576,
+	578, 581, 577, 579, 580, 582, 583, 596, 597, 598,
+	584, 585, 586, 587, 588, 589, 590, 591, 592, 593,
+	594, 595, 600, 0, 599, 0, 0, 601, 602, 603,
+	604, 1076, 606, 612, 615, 617, 618, 613, 614, 616,
+	619, 620, 621, 623, 624, 609, 610, 611, 0, 622,
+	607, 0, 608, 0, 0, 625, 626, 627, 628, 0,
+	885, 629, 886, 632, 633, 0, 0, 634, 0, 635,
+	636, 0, 0, 638, 639, 640, 0, 0, 641, 642,
+	887, 0, 643, 0, 888, 644, 645, 637, 646, 647,
+	648, 649, 650, 651, 652, 653, 654, 655, 656, 657,
+	0, 658, 659, 889, 660, 661, 662, 663, 664, 890,
+	665, 666, 667, 891, 668, 892, 669, 670, 671, 0,
+	1077, 673, 674, 0, 675, 676, 677, 678, 679, 680,
+	681, 682, 683, 684, 893, 685, 686, 688, 687, 689,
+	690, 0, 691, 692, 0, 693, 694, 695, 0, 0,
+	0, 0, 0, 696, 1071, 699, 0, 700, 701, 702,
+	703, 704, 705, 698, 706, 707, 708, 709, 710, 711,
+	712, 713, 0, 715, 716, 714, 717, 718, 0, 719,
+	720, 721, 722, 723, 894, 724, 0, 725, 726, 734,
+	735, 736, 727, 728, 730, 737, 729, 738, 739, 740,
+	741, 743, 742, 0, 745, 746, 744, 747, 748, 749,
+	750, 0, 751, 895, 752, 731, 732, 753, 754, 755,
+	0, 756, 757, 758, 759, 760, 761, 762, 763, 764,
+	896, 0, 766, 0, 765, 767, 768, 769, 770, 771,
+	772, 773, 775, 733, 776, 777, 778, 783, 784, 785,
+	897, 779, 780, 781, 782, 787, 898, 788, 789, 790,
+	791, 0, 792, 793, 0, 786, 774, 0, 794, 795,
+	796, 797, 798, 799, 800, 801, 802, 803, 0, 804,
+	899, 900, 901, 902, 0, 817, 0, 805, 807, 808,
+	809, 810, 903, 811, 812, 904, 0, 813, 814, 815,
+	816, 806, 819, 820, 818, 0, 0, 821, 822, 823,
+	824, 826, 828, 829, 830, 825, 827, 831, 0, 832,
+	0, 0, 833, 834, 835, 905, 906, 907, 0, 908,
+	838, 839, 836, 837, 840, 841, 844, 842, 843, 909,
+	847, 542, 848, 849, 850, 845, 846, 1064, 0, 359,
+	0, 851, 852, 910, 853, 854, 855, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 367, 1070, 370, 369,
+	371, 372, 373, 374, 0, 375, 376, 0, 0, 0,
+	0, 0, 856, 0, 0, 0, 378, 0, 377, 0,
+	379, 380, 381, 0, 382, 383, 384, 385, 386, 1079,
+	388, 389, 390, 857, 391, 858, 0, 392, 859, 393,
+	860, 0, 861, 394, 395, 396, 397, 398, 399, 400,
+	401, 402, 403, 404, 0, 0, 0, 405, 862, 863,
+	864, 0, 406, 407, 408, 409, 865, 0, 0, 0,
+	410, 411, 412, 413, 414, 415, 416, 417, 0, 0,
+	419, 420, 421, 418, 422, 423, 0, 424, 0, 425,
+	426, 427, 428, 429, 0, 430, 431, 0, 432, 433,
+	434, 0, 435, 436, 437, 0, 0, 0, 0, 0,
+	0, 0, 438, 439, 440, 441, 442, 0, 443, 445,
+	866, 867, 0, 448, 450, 444, 446, 0, 449, 447,
+	451, 452, 0, 453, 454, 455, 456, 457, 0, 0,
+	0, 458, 459, 460, 461, 0, 462, 463, 464, 466,
+	465, 0, 467, 468, 469, 0, 470, 471, 868, 472,
+	473, 474, 476, 478, 475, 477, 479, 480, 481, 482,
+	483, 869, 870, 484, 485, 0, 0, 0, 0, 0,
+	0, 0, 486, 487, 1072, 871, 0, 0, 0, 489,
+	0, 491, 495, 496, 492, 493, 494, 497, 0, 490,
+	1078, 499, 1074, 0, 500, 501, 502, 872, 873, 503,
+	504, 505, 506, 507, 508, 509, 510, 511, 0, 512,
+	513, 874, 0, 875, 514, 0, 515, 516, 517, 518,
+	519, 520, 521, 876, 877, 878, 630, 0, 522, 523,
+	524, 525, 1075, 526, 527, 528, 529, 530, 531, 532,
+	0, 0, 0, 533, 534, 535, 536, 0, 0, 0,
+	0, 0, 879, 537, 631, 538, 539, 880, 881, 0,
+	882, 0, 540, 541, 544, 0, 883, 0, 543, 545,
+	546, 0, 547, 0, 0, 0, 548, 549, 550, 551,
+	552, 553, 1073, 0, 555, 557, 556, 0, 559, 884,
+	558, 0, 560, 561, 0, 0, 562, 563, 564, 565,
+	566, 567, 572, 0, 0, 568, 569, 570, 571, 573,
+	574, 0, 575, 576, 578, 581, 577, 579, 580, 582,
+	583, 596, 597, 598, 584, 585, 586, 587, 588, 589,
+	590, 591, 592, 593, 594, 595, 600, 0, 599, 0,
+	0, 601, 602, 603, 604, 1076, 606, 612, 615, 617,
+	618, 613, 614, 616, 619, 620, 621, 623, 624, 609,
+	610, 611, 0, 622, 607, 0, 608, 0, 0, 625,
+	626, 627, 628, 0, 885, 629, 886, 632, 633, 0,
+	0, 634, 0, 635, 636, 0, 0, 638, 639, 640,
+	0, 0, 641, 642, 887, 0, 643, 0, 888, 644,
+	645, 637, 646, 647, 648, 649, 650, 651, 652, 653,
+	654, 655, 656, 657, 0, 658, 659, 889, 660, 661,
+	662, 663, 664, 890, 665, 666, 667, 891, 668, 892,
+	669, 670, 671, 0, 1077, 673, 674, 0, 675, 676,
+	677, 678, 679, 680, 681, 682, 683, 684, 893, 685,
+	686, 688, 687, 689, 690, 0, 691, 692, 0, 693,
+	694, 695, 0, 0, 0, 0, 0, 696, 1071, 699,
+	0, 700, 701, 702, 703, 704, 705, 698, 706, 707,
+	708, 709, 710, 711, 712, 713, 0, 715, 716, 714,
+	717, 718, 0, 719, 720, 721, 722, 723, 894, 724,
+	0, 725, 726, 734, 735, 736, 727, 728, 730, 737,
+	729, 738, 739, 740, 741, 743, 742, 0, 745, 746,
+	744, 747, 748, 749, 750, 0, 751, 895, 752, 731,
+	732, 753, 754, 755, 0, 756, 757, 758, 759, 760,
+	761, 762, 763, 764, 896, 0, 766, 0, 765, 767,
+	768, 769, 770, 771, 772, 773, 775, 733, 776, 777,
+	778, 783, 784, 785, 897, 779, 780, 781, 782, 787,
+	898, 788, 789, 790, 791, 0, 792, 793, 0, 786,
+	774, 0, 794, 795, 796, 797, 798, 799, 800, 801,
+	802, 803, 0, 804, 899, 900, 901, 902, 0, 817,
+	0, 805, 807, 808, 809, 810, 903, 811, 812, 904,
+	0, 813, 814, 815, 816, 806, 819, 820, 818, 0,
+	0, 821, 822, 823, 824, 826, 828, 829, 830, 825,
+	827, 831, 0, 832, 0, 0, 833, 834, 835, 905,
+	906, 907, 0, 908, 838, 839, 836, 837, 840, 841,
+	844, 842, 843, 909, 847, 542, 848, 849, 850, 845,
+	846, 359, 5204, 0, 0, 851, 852, 910, 853, 854,
+	855, 0, 0, 0, 0, 0, 0, 0, 367, 368,
+	370, 369, 371, 372, 373, 374, 0, 375, 376, 0,
+	0, 0, 0, 0, 856, 0, 0, 0, 378, 0,
+	377, 0, 379, 380, 381, 0, 382, 383, 384, 385,
+	386, 387, 388, 389, 390, 857, 391, 858, 0, 392,
+	859, 393, 860, 0, 861, 394, 395, 396, 397, 398,
+	399, 400, 401, 402, 403, 404, 0, 0, 0, 405,
+	862, 863, 864, 0, 406, 407, 408, 409, 865, 0,
+	0, 0, 410, 411, 412, 413, 414, 415, 416, 417,
+	0, 0, 419, 420, 421, 418, 422, 423, 0, 424,
+	0, 425, 426, 427, 428, 429, 0, 430, 431, 0,
+	432, 433, 434, 0, 435, 436, 437, 0, 0, 0,
+	0, 0, 0, 0, 438, 439, 440, 441, 442, 0,
+	443, 445, 866, 867, 0, 448, 450, 444, 446, 0,
+	449, 447, 451, 452, 0, 453, 454, 455, 456, 457,
+	0, 0, 0, 458, 459, 460, 461, 0, 462, 463,
+	464, 466, 465, 0, 467, 468, 469, 0, 470, 471,
+	868, 472, 473, 474, 476, 478, 475, 477, 479, 480,
+	481, 482, 483, 869, 870, 484, 485, 0, 0, 0,
+	0, 0, 0, 0, 486, 487, 488, 871, 0, 0,
+	0, 489, 0, 491, 495, 496, 492, 493, 494, 497,
+	0, 490, 498, 499, 0, 0, 500, 501, 502, 872,
+	873, 503, 504, 505, 506, 507, 508, 509, 510, 511,
+	0, 512, 513, 874, 0, 875, 514, 0, 515, 516,
+	517, 518, 519, 520, 521, 876, 877, 878, 630, 0,
+	522, 523, 524, 525, 0, 526, 527, 528, 529, 530,
+	531, 532, 0, 0, 0, 533, 534, 535, 536, 0,
+	0, 0, 0, 0, 879, 537, 631, 538, 539, 880,
+	881, 0, 882, 0, 540, 541, 544, 0, 883, 0,
+	543, 545, 546, 0, 547, 0, 0, 0, 548, 549,
+	550, 551, 552, 553, 554, 0, 555, 557, 556, 0,
+	559, 884, 558, 0, 560, 561, 0, 0, 562, 563,
+	564, 565, 566, 567, 572, 0, 0, 568, 569, 570,
+	571, 573, 574, 0, 575, 576, 578, 581, 577, 579,
+	580, 582, 583, 596, 597, 598, 584, 585, 586, 587,
+	588, 589, 590, 591, 592, 593, 594, 595, 600, 0,
+	599, 0, 0, 601, 602, 603, 604, 605, 606, 612,
+	615, 617, 618, 613, 614, 616, 619, 620, 621, 623,
+	624, 609, 610, 611, 0, 622, 607, 0, 608, 0,
+	0, 625, 626, 627, 628, 0, 885, 629, 886, 632,
+	633, 0, 0, 634, 0, 635, 636, 0, 0, 638,
+	639, 640, 0, 0, 641, 642, 887, 0, 643, 0,
+	888, 644, 645, 637, 646, 647, 648, 649, 650, 651,
+	652, 653, 654, 655, 656, 657, 0, 658, 659, 889,
+	660, 661, 662, 663, 664, 890, 665, 666, 667, 891,
+	668, 892, 669, 670, 671, 6748, 672, 673, 674, 0,
+	675, 676, 677, 678, 679, 680, 681, 682, 683, 684,
+	893, 685, 686, 688, 687, 689, 690, 0, 691, 692,
+	0, 693, 694, 695, 0, 0, 0, 0, 0, 696,
+	697, 699, 0, 700, 701, 702, 703, 704, 705, 698,
+	706, 707, 708, 709, 710, 711, 712, 713, 0, 715,
+	716, 714, 717, 718, 0, 719, 720, 721, 722, 723,
+	894, 724, 0, 725, 726, 734, 735, 736, 727, 728,
+	730, 737, 729, 738, 739, 740, 741, 743, 742, 0,
+	745, 746, 744, 747, 748, 749, 750, 0, 751, 895,
+	752, 731, 732, 753, 754, 755, 0, 756, 757, 758,
+	759, 760, 761, 762, 763, 764, 896, 0, 766, 0,
+	765, 767, 768, 769, 770, 771, 772, 773, 775, 733,
+	776, 777, 778, 783, 784, 785, 897, 779, 780, 781,
+	782, 787, 898, 788, 789, 790, 791, 0, 792, 793,
+	0, 786, 774, 0, 794, 795, 796, 797, 798, 799,
+	800, 801, 802, 803, 0, 804, 899, 900, 901, 902,
+	0, 817, 0, 805, 807, 808, 809, 810, 903, 811,
+	812, 904, 0, 813, 814, 815, 816, 806, 819, 820,
+	818, 0, 0, 821, 822, 823, 824, 826, 828, 829,
+	830, 825, 827, 831, 0, 832, 0, 0, 833, 834,
+	835, 905, 906, 907, 0, 908, 838, 839, 836, 837,
+	840, 841, 844, 842, 843, 909, 847, 542, 848, 849,
+	850, 845, 846, 359, 0, 0, 0, 851, 852, 910,
+	853, 854, 855, 0, 0, 0, 0, 0, 0, 0,
+	367, 368, 370, 369, 371, 372, 373, 374, 0, 375,
+	376, 0, 0, 0, 0, 0, 856, 0, 0, 0,
+	378, 0, 377, 0, 379, 380, 381, 0, 382, 383,
+	384, 385, 386, 387, 388, 389, 390, 857, 391, 858,
+	0, 392, 859, 393, 860, 0, 861, 394, 395, 396,
+	397, 398, 399, 400, 401, 402, 403, 404, 0, 0,
+	0, 405, 862, 863, 864, 0, 406, 407, 408, 409,
+	865, 0, 0, 0, 410, 411, 412, 413, 414, 415,
+	416, 417, 0, 0, 419, 420, 421, 418, 422, 423,
+	0, 424, 0, 425, 426, 427, 428, 429, 0, 430,
+	431, 0, 432, 433, 434, 0, 435, 436, 437, 0,
+	0, 0, 0, 0, 0, 0, 438, 439, 440, 441,
+	442, 0, 443, 445, 866, 867, 0, 448, 450, 444,
+	446, 0, 449, 447, 451, 452, 0, 453, 454, 455,
+	456, 457, 0, 0, 0, 458, 459, 460, 461, 0,
+	462, 463, 464, 466, 465, 0, 467, 468, 469, 0,
+	470, 471, 868, 472, 473, 474, 476, 478, 475, 477,
+	479, 480, 481, 482, 483, 869, 870, 484, 485, 0,
+	5360, 0, 0, 0, 0, 0, 486, 487, 488, 871,
+	0, 0, 0, 489, 0, 491, 495, 496, 492, 493,
+	494, 497, 0, 490, 498, 499, 0, 0, 500, 501,
+	502, 872, 873, 503, 504, 505, 506, 507, 508, 509,
+	510, 511, 0, 512, 513, 874, 0, 875, 514, 0,
+	515, 516, 517, 518, 519, 520, 521, 876, 877, 878,
+	630, 0, 522, 523, 524, 525, 0, 526, 527, 528,
+	529, 530, 531, 532, 0, 0, 0, 533, 534, 535,
+	536, 0, 0, 0, 0, 0, 879, 537, 631, 538,
+	539, 880, 881, 0, 882, 0, 540, 541, 544, 0,
+	883, 0, 543, 545, 546, 0, 547, 0, 0, 0,
+	548, 549, 550, 551, 552, 553, 554, 0, 555, 557,
+	556, 0, 559, 884, 558, 0, 560, 561, 0, 0,
+	562, 563, 564, 565, 566, 567, 572, 0, 0, 568,
+	569, 570, 571, 573, 574, 0, 575, 576, 578, 581,
+	577, 579, 580, 582, 583, 596, 597, 598, 584, 585,
+	586, 587, 588, 589, 590, 591, 592, 593, 594, 595,
+	600, 0, 599, 0, 0, 601, 602, 603, 604, 605,
+	606, 612, 615, 617, 618, 613, 614, 616, 619, 620,
+	621, 623, 624, 609, 610, 611, 0, 622, 607, 0,
+	608, 0, 0, 625, 626, 627, 628, 0, 885, 629,
+	886, 632, 633, 0, 0, 634, 0, 635, 636, 0,
+	0, 638, 639, 640, 0, 0, 641, 642, 887, 0,
+	643, 0, 888, 644, 645, 637, 646, 647, 648, 649,
+	650, 651, 652, 653, 654, 655, 656, 657, 0, 658,
+	659, 889, 660, 661, 662, 663, 664, 890, 665, 666,
+	667, 891, 668, 892, 669, 670, 671, 6298, 672, 673,
+	674, 0, 675, 676, 677, 678, 679, 680, 681, 682,
+	683, 684, 893, 685, 686, 688, 687, 689, 690, 0,
+	691, 692, 0, 693, 694, 695, 0, 0, 0, 0,
+	0, 696, 697, 699, 0, 700, 701, 702, 703, 704,
+	705, 698, 706, 707, 708, 709, 710, 711, 712, 713,
+	0, 715, 716, 714, 717, 718, 0, 719, 720, 721,
+	722, 723, 894, 724, 0, 725, 726, 734, 735, 736,
+	727, 728, 730, 737, 729, 738, 739, 740, 741, 743,
+	742, 0, 745, 746, 744, 747, 748, 749, 750, 0,
+	751, 895, 752, 731, 732, 753, 754, 755, 0, 756,
+	757, 758, 759, 760, 761, 762, 763, 764, 896, 0,
+	766, 0, 765, 767, 768, 769, 770, 771, 772, 773,
+	775, 733, 776, 777, 778, 783, 784, 785, 897, 779,
+	780, 781, 782, 787, 898, 788, 789, 790, 791, 0,
+	792, 793, 0, 786, 774, 0, 794, 795, 796, 797,
+	798, 799, 800, 801, 802, 803, 0, 804, 899, 900,
+	901, 902, 0, 817, 0, 805, 807, 808, 809, 810,
+	903, 811, 812, 904, 0, 813, 814, 815, 816, 806,
+	819, 820, 818, 0, 0, 821, 822, 823, 824, 826,
+	828, 829, 830, 825, 827, 831, 0, 832, 0, 0,
+	833, 834, 835, 905, 906, 907, 0, 908, 838, 839,
+	836, 837, 840, 841, 844, 842, 843, 909, 847, 542,
+	848, 849, 850, 845, 846, 359, 5204, 0, 0, 851,
+	852, 910, 853, 854, 855, 0, 0, 0, 0, 0,
+	0, 0, 367, 368, 370, 369, 371, 372, 373, 374,
+	0, 375, 376, 0, 0, 0, 0, 0, 856, 0,
+	0, 0, 378, 0, 377, 0, 379, 380, 381, 0,
+	382, 383, 384, 385, 386, 387, 388, 389, 390, 857,
+	391, 858, 0, 392, 859, 393, 860, 0, 861, 394,
+	395, 396, 397, 398, 399, 400, 401, 402, 403, 404,
+	0, 0, 0, 405, 862, 863, 864, 0, 406, 407,
+	408, 409, 865, 0, 0, 0, 410, 411, 412, 413,
+	414, 415, 416, 417, 0, 0, 419, 420, 421, 418,
+	422, 423, 0, 424, 0, 425, 426, 427, 428, 429,
+	0, 430, 431, 0, 432, 433, 434, 0, 435, 436,
+	437, 0, 0, 0, 0, 0, 0, 0, 438, 439,
+	440, 441, 442, 0, 443, 445, 866, 867, 0, 448,
+	450, 444, 446, 0, 449, 447, 451, 452, 0, 453,
+	454, 455, 456, 457, 0, 0, 0, 458, 459, 460,
+	461, 0, 462, 463, 464, 466, 465, 0, 467, 468,
+	469, 0, 470, 471, 868, 472, 473, 474, 476, 478,
+	475, 477, 479, 480, 481, 482, 483, 869, 870, 484,
+	485, 0, 0, 0, 0, 0, 0, 0, 486, 487,
+	488, 871, 0, 0, 0, 489, 0, 491, 495, 496,
+	492, 493, 494, 497, 0, 490, 498, 499, 0, 0,
+	500, 501, 502, 872, 873, 503, 504, 505, 506, 507,
+	508, 509, 510, 511, 0, 512, 513, 874, 0, 875,
+	514, 0, 515, 516, 517, 518, 519, 520, 521, 876,
+	877, 878, 630, 0, 522, 523, 524, 525, 0, 526,
+	527, 528, 529, 530, 531, 532, 0, 0, 0, 533,
+	534, 535, 536, 0, 0, 0, 0, 0, 879, 537,
+	631, 538, 539, 880, 881, 0, 882, 0, 540, 541,
+	544, 0, 883, 0, 543, 545, 546, 0, 547, 0,
+	0, 0, 548, 549, 550, 551, 552, 553, 554, 0,
+	555, 557, 556, 0, 559, 884, 558, 0, 560, 561,
+	0, 0, 562, 563, 564, 565, 566, 567, 572, 0,
+	0, 568, 569, 570, 571, 573, 574, 0, 575, 576,
+	578, 581, 577, 579, 580, 582, 583, 596, 597, 598,
+	584, 585, 586, 587, 588, 589, 590, 591, 592, 593,
+	594, 595, 600, 0, 599, 0, 0, 601, 602, 603,
+	604, 605, 606, 612, 615, 617, 618, 613, 614, 616,
+	619, 620, 621, 623, 624, 609, 610, 611, 0, 622,
+	607, 0, 608, 0, 0, 625, 626, 627, 628, 0,
+	885, 629, 886, 632, 633, 0, 0, 634, 0, 635,
+	636, 0, 0, 638, 639, 640, 0, 0, 641, 642,
+	887, 0, 643, 0, 888, 644, 645, 637, 646, 647,
+	648, 649, 650, 651, 652, 653, 654, 655, 656, 657,
+	0, 658, 659, 889, 660, 661, 662, 663, 664, 890,
+	665, 666, 667, 891, 668, 892, 669, 670, 671, 6114,
+	672, 673, 674, 0, 675, 676, 677, 678, 679, 680,
+	681, 682, 683, 684, 893, 685, 686, 688, 687, 689,
+	690, 0, 691, 692, 0, 693, 694, 695, 0, 0,
+	0, 0, 0, 696, 697, 699, 0, 700, 701, 702,
+	703, 704, 705, 698, 706, 707, 708, 709, 710, 711,
+	712, 713, 0, 715, 716, 714, 717, 718, 0, 719,
+	720, 721, 722, 723, 894, 724, 0, 725, 726, 734,
+	735, 736, 727, 728, 730, 737, 729, 738, 739, 740,
+	741, 743, 742, 0, 745, 746, 744, 747, 748, 749,
+	750, 0, 751, 895, 752, 731, 732, 753, 754, 755,
+	0, 756, 757, 758, 759, 760, 761, 762, 763, 764,
+	896, 0, 766, 0, 765, 767, 768, 769, 770, 771,
+	772, 773, 775, 733, 776, 777, 778, 783, 784, 785,
+	897, 779, 780, 781, 782, 787, 898, 788, 789, 790,
+	791, 0, 792, 793, 0, 786, 774, 0, 794, 795,
+	796, 797, 798, 799, 800, 801, 802, 803, 0, 804,
+	899, 900, 901, 902, 0, 817, 0, 805, 807, 808,
+	809, 810, 903, 811, 812, 904, 0, 813, 814, 815,
+	816, 806, 819, 820, 818, 0, 0, 821, 822, 823,
+	824, 826, 828, 829, 830, 825, 827, 831, 0, 832,
+	0, 0, 833, 834, 835, 905, 906, 907, 0, 908,
+	838, 839, 836, 837, 840, 841, 844, 842, 843, 909,
+	847, 542, 848, 849, 850, 845, 846, 1764, 0, 359,
+	0, 851, 852, 910, 853, 854, 855, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 367, 368, 370, 369,
+	371, 372, 373, 374, 0, 375, 376, 0, 0, 0,
+	0, 0, 856, 0, 0, 0, 378, 0, 377, 0,
+	379, 380, 381, 1767, 382, 383, 384, 385, 386, 387,
+	388, 389, 390, 857, 391, 858, 0, 392, 859, 393,
+	860, 0, 861, 394, 395, 396, 397, 398, 399, 400,
+	401, 402, 403, 404, 0, 0, 0, 405, 862, 863,
+	1765, 0, 406, 407, 408, 409, 865, 0, 0, 0,
+	410, 411, 412, 413, 414, 415, 416, 417, 0, 0,
+	419, 420, 421, 418, 422, 423, 0, 424, 0, 425,
+	426, 427, 428, 429, 0, 430, 431, 0, 432, 433,
+	434, 0, 435, 436, 437, 0, 0, 0, 0, 0,
+	0, 0, 438, 439, 440, 441, 442, 0, 443, 445,
+	866, 867, 0, 448, 450, 444, 446, 0, 449, 447,
+	451, 452, 0, 453, 454, 455, 456, 457, 0, 0,
+	0, 458, 459, 460, 461, 0, 462, 463, 464, 466,
+	465, 0, 467, 468, 469, 0, 470, 471, 868, 472,
+	473, 474, 476, 478, 475, 477, 479, 480, 481, 482,
+	483, 869, 870, 484, 485, 0, 0, 0, 0, 0,
+	0, 0, 486, 487, 488, 871, 0, 0, 0, 489,
+	0, 491, 495, 496, 492, 493, 494, 497, 0, 490,
+	498, 499, 0, 0, 500, 501, 502, 872, 873, 503,
+	504, 505, 506, 507, 508, 509, 510, 511, 0, 512,
+	513, 874, 0, 875, 514, 0, 515, 516, 517, 518,
+	519, 520, 521, 876, 877, 878, 630, 0, 522, 523,
+	524, 525, 0, 526, 527, 528, 529, 530, 531, 532,
+	0, 0, 0, 533, 534, 535, 536, 0, 0, 0,
+	0, 0, 879, 537, 631, 538, 539, 880, 881, 0,
+	882, 0, 540, 541, 544, 0, 883, 0, 543, 545,
+	546, 0, 547, 0, 0, 0, 548, 549, 550, 551,
+	552, 553, 554, 0, 555, 557, 556, 0, 559, 884,
+	558, 0, 560, 561, 0, 0, 562, 563, 564, 565,
+	566, 567, 572, 0, 0, 568, 569, 570, 571, 573,
+	574, 0, 575, 576, 578, 581, 577, 579, 580, 582,
+	583, 596, 597, 598, 584, 585, 586, 587, 588, 589,
+	590, 591, 592, 593, 594, 595, 600, 0, 1049, 0,
+	0, 601, 602, 603, 604, 605, 606, 612, 615, 617,
+	618, 613, 614, 616, 619, 620, 621, 623, 624, 609,
+	610, 611, 0, 622, 607, 0, 608, 0, 0, 625,
+	626, 627, 628, 0, 885, 629, 886, 632, 633, 0,
+	0, 634, 0, 635, 636, 0, 0, 638, 639, 640,
+	0, 0, 641, 642, 887, 0, 643, 0, 888, 644,
+	645, 637, 646, 647, 648, 649, 650, 651, 652, 653,
+	654, 655, 656, 657, 0, 658, 659, 889, 660, 661,
+	662, 663, 664, 890, 665, 666, 667, 891, 668, 892,
+	669, 670, 671, 0, 672, 673, 674, 0, 675, 676,
+	677, 678, 679, 680, 681, 682, 683, 684, 893, 685,
+	686, 688, 687, 689, 690, 0, 691, 692, 0, 693,
+	694, 695, 0, 0, 0, 0, 0, 696, 697, 699,
+	0, 700, 701, 702, 703, 704, 705, 698, 706, 707,
+	708, 709, 710, 711, 712, 713, 0, 715, 716, 714,
+	717, 718, 0, 1048, 720, 721, 722, 723, 894, 724,
+	0, 725, 726, 734, 735, 736, 727, 728, 730, 1047,
+	729, 738, 739, 740, 741, 743, 742, 0, 745, 746,
+	744, 747, 748, 1768, 750, 0, 751, 895, 752, 731,
+	732, 753, 754, 755, 0, 756, 757, 758, 759, 760,
+	761, 762, 763, 764, 896, 0, 766, 0, 765, 767,
+	768, 769, 770, 771, 772, 773, 775, 733, 776, 777,
+	778, 783, 784, 785, 897, 779, 780, 781, 782, 787,
+	898, 788, 789, 790, 791, 0, 792, 793, 0, 786,
+	774, 0, 794, 795, 796, 797, 798, 799, 800, 801,
+	802, 803, 0, 804, 1045, 900, 901, 902, 0, 817,
+	0, 805, 807, 808, 809, 810, 903, 811, 812, 904,
+	0, 813, 814, 815, 816, 806, 819, 820, 818, 0,
+	0, 821, 822, 823, 824, 826, 828, 829, 830, 825,
+	827, 831, 0, 832, 0, 0, 833, 834, 835, 905,
+	906, 907, 0, 908, 838, 839, 836, 837, 840, 841,
+	844, 842, 843, 909, 847, 542, 848, 849, 850, 845,
+	846, 1764, 0, 359, 0, 851, 852, 910, 853, 854,
+	855, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	367, 368, 370, 369, 371, 372, 373, 374, 0, 375,
+	376, 0, 0, 0, 0, 0, 856, 0, 0, 0,
+	378, 0, 377, 0, 379, 380, 381, 1767, 382, 383,
+	384, 385, 386, 387, 388, 389, 390, 857, 391, 858,
+	0, 392, 859, 393, 860, 0, 861, 394, 395, 396,
+	397, 398, 399, 400, 401, 402, 403, 404, 0, 0,
+	0, 405, 862, 863, 1765, 0, 406, 407, 408, 409,
+	865, 0, 0, 0, 410, 411, 412, 413, 414, 415,
+	416, 417, 0, 0, 419, 420, 421, 418, 422, 423,
+	0, 424, 0, 425, 426, 427, 428, 429, 0, 430,
+	431, 0, 432, 433, 434, 0, 435, 436, 437, 0,
+	0, 0, 0, 0, 0, 0, 438, 439, 440, 441,
+	442, 0, 443, 445, 866, 867, 0, 448, 450, 444,
+	446, 0, 449, 447, 451, 452, 0, 453, 454, 455,
+	456, 457, 0, 0, 0, 458, 459, 460, 461, 0,
+	462, 463, 464, 466, 465, 0, 467, 468, 469, 0,
+	470, 471, 868, 472, 473, 474, 476, 478, 475, 477,
+	479, 480, 481, 482, 483, 869, 870, 484, 485, 0,
+	0, 0, 0, 0, 0, 0, 486, 487, 488, 871,
+	0, 0, 0, 489, 0, 491, 495, 496, 492, 493,
+	494, 497, 0, 490, 498, 499, 0, 0, 500, 501,
+	502, 872, 873, 503, 504, 505, 506, 507, 508, 509,
+	510, 511, 0, 512, 513, 874, 0, 875, 514, 0,
+	515, 516, 517, 518, 519, 520, 521, 876, 877, 878,
+	630, 0, 522, 523, 524, 525, 0, 526, 527, 528,
+	529, 530, 531, 532, 0, 0, 0, 533, 534, 535,
+	536, 0, 0, 0, 0, 0, 879, 537, 631, 538,
+	539, 880, 881, 0, 882, 0, 540, 541, 544, 0,
+	883, 0, 543, 545, 546, 0, 547, 0, 0, 0,
+	548, 549, 550, 551, 552, 553, 554, 0, 555, 557,
+	556, 0, 559, 884, 558, 0, 560, 561, 0, 0,
+	562, 563, 564, 565, 566, 567, 572, 0, 0, 568,
+	569, 570, 571, 573, 574, 0, 575, 576, 578, 581,
+	577, 579, 580, 582, 583, 596, 597, 598, 584, 585,
+	586, 587, 588, 589, 590, 591, 592, 593, 594, 595,
+	600, 0, 1049, 0, 0, 601, 602, 603, 604, 605,
+	606, 612, 615, 617, 618, 613, 614, 616, 619, 620,
+	621, 623, 624, 609, 610, 611, 0, 622, 607, 0,
+	608, 0, 0, 625, 626, 627, 628, 0, 885, 629,
+	886, 632, 633, 0, 0, 634, 0, 635, 636, 0,
+	0, 638, 639, 640, 0, 0, 641, 642, 887, 0,
+	643, 0, 888, 644, 645, 637, 646, 647, 648, 649,
+	650, 651, 652, 653, 654, 655, 656, 657, 0, 658,
+	659, 889, 660, 661, 662, 663, 664, 890, 665, 666,
+	667, 891, 668, 892, 669, 670, 671, 0, 672, 673,
+	674, 0, 675, 676, 677, 678, 679, 680, 681, 682,
+	683, 684, 893, 685, 686, 688, 687, 689, 690, 0,
+	691, 692, 0, 693, 694, 695, 0, 0, 0, 0,
+	0, 696, 697, 699, 0, 700, 701, 702, 703, 704,
+	705, 698, 706, 707, 708, 709, 710, 711, 712, 713,
+	0, 715, 716, 714, 717, 718, 0, 1048, 720, 721,
+	722, 723, 894, 724, 0, 725, 726, 734, 735, 736,
+	727, 728, 730, 1047, 729, 738, 739, 740, 741, 743,
+	742, 0, 745, 746, 744, 747, 748, 1768, 750, 0,
+	751, 895, 752, 731, 732, 753, 754, 755, 0, 756,
+	757, 758, 759, 760, 761, 762, 763, 764, 896, 0,
+	766, 0, 765, 767, 768, 769, 770, 771, 772, 773,
+	775, 733, 776, 777, 778, 783, 784, 785, 897, 779,
+	780, 781, 782, 787, 898, 788, 789, 790, 791, 0,
+	792, 793, 0, 786, 774, 0, 794, 795, 796, 797,
+	798, 799, 800, 801, 802, 803, 0, 804, 1045, 900,
+	901, 902, 0, 817, 0, 805, 1766, 808, 809, 810,
+	903, 811, 812, 904, 0, 813, 814, 815, 816, 806,
+	819, 820, 818, 0, 0, 821, 822, 823, 824, 826,
+	828, 829, 830, 825, 827, 831, 0, 832, 0, 0,
+	833, 834, 835, 905, 906, 907, 0, 908, 838, 839,
+	836, 837, 840, 841, 844, 842, 843, 909, 847, 542,
+	848, 849, 850, 845, 846, 1059, 0, 359, 0, 851,
+	852, 910, 853, 854, 855, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 367, 368, 370, 369, 371, 372,
+	373, 374, 1057, 375, 376, 0, 0, 0, 0, 0,
+	856, 0, 0, 0, 378, 0, 377, 0, 379, 380,
+	381, 0, 382, 383, 384, 385, 386, 387, 388, 389,
+	390, 857, 391, 858, 0, 392, 859, 393, 860, 0,
+	861, 394, 395, 396, 397, 398, 399, 400, 401, 402,
+	403, 404, 0, 0, 0, 405, 862, 863, 864, 0,
+	406, 407, 408, 409, 865, 0, 0, 0, 410, 411,
+	412, 413, 414, 415, 416, 417, 0, 0, 419, 420,
+	421, 418, 422, 423, 0, 424, 0, 425, 426, 427,
+	428, 429, 0, 430, 431, 0, 432, 433, 434, 0,
+	435, 436, 437, 0, 0, 0, 0, 0, 0, 0,
+	438, 439, 440, 441, 442, 0, 443, 445, 866, 867,
+	0, 448, 450, 444, 446, 0, 449, 447, 451, 452,
+	0, 453, 454, 455, 456, 457, 0, 0, 0, 458,
+	459, 460, 461, 0, 462, 463, 464, 466, 465, 0,
+	467, 468, 469, 0, 470, 471, 868, 472, 473, 474,
+	476, 478, 475, 477, 479, 480, 481, 482, 483, 869,
+	870, 484, 485, 0, 0, 0, 0, 0, 0, 0,
+	486, 487, 488, 871, 0, 0, 0, 489, 0, 491,
+	495, 496, 492, 493, 494, 497, 0, 490, 498, 499,
+	0, 0, 500, 501, 502, 872, 873, 503, 504, 505,
+	506, 507, 508, 509, 510, 511, 0, 512, 513, 874,
+	0, 875, 514, 0, 515, 516, 517, 518, 519, 520,
+	521, 876, 877, 878, 630, 0, 522, 523, 524, 525,
+	0, 526, 527, 528, 529, 530, 531, 532, 0, 0,
+	0, 533, 534, 535, 536, 0, 0, 0, 0, 0,
+	879, 537, 631, 538, 539, 880, 881, 0, 882, 0,
+	540, 541, 544, 0, 883, 0, 543, 545, 546, 0,
+	547, 0, 0, 0, 548, 549, 550, 551, 552, 553,
+	554, 0, 555, 557, 556, 0, 559, 884, 558, 0,
+	560, 561, 0, 0, 562, 563, 564, 565, 566, 567,
+	572, 0, 0, 568, 569, 570, 571, 573, 574, 0,
+	575, 576, 578, 581, 577, 579, 580, 582, 583, 596,
+	597, 598, 584, 585, 586, 587, 588, 589, 590, 591,
+	592, 593, 594, 595, 600, 0, 599, 0, 0, 601,
+	602, 603, 604, 605, 606, 612, 615, 617, 618, 613,
+	614, 616, 619, 620, 621, 623, 624, 609, 610, 611,
+	0, 622, 607, 0, 608, 0, 0, 625, 626, 627,
+	628, 0, 885, 629, 886, 632, 633, 0, 0, 634,
+	0, 635, 636, 0, 0, 638, 639, 640, 0, 0,
+	641, 642, 887, 0, 643, 0, 888, 644, 645, 637,
+	646, 647, 648, 649, 650, 651, 652, 653, 654, 655,
+	656, 657, 0, 658, 659, 889, 660, 661, 662, 663,
+	664, 890, 665, 666, 667, 891, 668, 892, 669, 670,
+	671, 0, 672, 673, 674, 0, 675, 676, 677, 678,
+	679, 680, 681, 682, 683, 684, 893, 685, 686, 688,
+	687, 689, 690, 0, 691, 692, 0, 693, 694, 695,
+	0, 0, 0, 0, 0, 696, 697, 699, 0, 700,
+	701, 702, 703, 704, 705, 698, 706, 707, 708, 709,
+	710, 711, 712, 713, 0, 715, 716, 714, 717, 718,
+	0, 719, 720, 721, 722, 723, 894, 724, 0, 725,
+	726, 734, 735, 736, 727, 728, 730, 737, 729, 738,
+	739, 740, 741, 743, 742, 0, 745, 746, 744, 747,
+	748, 749, 750, 0, 751, 895, 752, 731, 732, 753,
+	754, 755, 0, 756, 757, 758, 759, 760, 761, 762,
+	763, 764, 896, 0, 766, 0, 765, 767, 768, 769,
+	770, 771, 772, 773, 775, 733, 776, 777, 778, 783,
+	784, 785, 897, 779, 780, 781, 782, 787, 898, 788,
+	789, 790, 791, 0, 792, 793, 0, 786, 774, 0,
+	794, 795, 796, 797, 798, 799, 800, 801, 802, 803,
+	0, 804, 899, 900, 901, 902, 0, 817, 0, 805,
+	807, 808, 809, 810, 903, 811, 812, 904, 0, 813,
+	814, 815, 816, 806, 819, 820, 818, 0, 0, 821,
+	822, 823, 824, 826, 828, 829, 830, 825, 827, 831,
+	0, 832, 0, 0, 833, 834, 835, 905, 906, 907,
+	0, 908, 838, 839, 836, 837, 840, 841, 844, 842,
+	843, 909, 847, 542, 848, 849, 850, 845, 846, 953,
+	0, 359, 0, 851, 852, 910, 853, 854, 855, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 367, 368,
+	370, 369, 371, 372, 373, 374, 952, 375, 376, 0,
+	0, 0, 0, 0, 856, 0, 0, 0, 378, 0,
+	377, 0, 379, 380, 381, 0, 382, 383, 384, 385,
+	386, 387, 388, 389, 390, 857, 391, 858, 0, 392,
+	859, 393, 860, 0, 861, 394, 395, 396, 397, 398,
+	399, 400, 401, 402, 403, 404, 0, 0, 0, 405,
+	862, 863, 864, 0, 406, 407, 408, 409, 865, 0,
+	0, 0, 410, 411, 412, 413, 414, 415, 416, 417,
+	0, 0, 419, 420, 421, 418, 422, 423, 0, 424,
+	0, 425, 426, 427, 428, 429, 0, 430, 431, 0,
+	432, 433, 434, 0, 435, 436, 437, 0, 0, 0,
+	0, 0, 0, 0, 438, 439, 440, 441, 442, 0,
+	443, 445, 866, 867, 0, 448, 450, 444, 446, 0,
+	449, 447, 451, 452, 0, 453, 454, 455, 456, 457,
+	0, 0, 0, 458, 459, 460, 461, 0, 462, 463,
+	464, 466, 465, 0, 467, 468, 469, 0, 470, 471,
+	868, 472, 473, 474, 476, 478, 475, 477, 479, 480,
+	481, 482, 483, 869, 870, 484, 485, 0, 0, 0,
+	0, 0, 0, 0, 486, 487, 488, 871, 0, 0,
+	0, 489, 0, 491, 495, 496, 492, 493, 494, 497,
+	0, 490, 498, 499, 0, 0, 500, 501, 502, 872,
+	873, 503, 504, 505, 506, 507, 508, 509, 510, 511,
+	0, 512, 513, 874, 0, 875, 514, 0, 515, 516,
+	517, 518, 519, 520, 521, 876, 877, 878, 630, 0,
+	522, 523, 524, 525, 0, 526, 527, 528, 529, 530,
+	531, 532, 0, 0, 0, 533, 534, 535, 536, 0,
+	0, 0, 0, 0, 879, 537, 631, 538, 539, 880,
+	881, 0, 882, 0, 540, 541, 544, 0, 883, 0,
+	543, 545, 546, 0, 547, 0, 0, 0, 548, 549,
+	550, 551, 552, 553, 554, 0, 555, 557, 556, 0,
+	559, 884, 558, 0, 560, 561, 0, 0, 562, 563,
+	564, 565, 566, 567, 572, 0, 0, 568, 569, 570,
+	571, 573, 574, 0, 575, 576, 578, 581, 577, 579,
+	580, 582, 583, 596, 597, 598, 584, 585, 586, 587,
+	588, 589, 590, 591, 592, 593, 594, 595, 600, 0,
+	599, 0, 0, 601, 602, 603, 604, 605, 606, 612,
+	615, 617, 618, 613, 614, 616, 619, 620, 621, 623,
+	624, 609, 610, 611, 0, 622, 607, 0, 608, 0,
+	0, 625, 626, 627, 628, 0, 885, 629, 886, 632,
+	633, 0, 0, 634, 0, 635, 636, 0, 0, 638,
+	639, 640, 0, 0, 641, 642, 887, 0, 643, 0,
+	888, 644, 645, 637, 646, 647, 648, 649, 650, 651,
+	652, 653, 654, 655, 656, 657, 0, 658, 659, 889,
+	660, 661, 662, 663, 664, 890, 665, 666, 667, 891,
+	668, 892, 951, 670, 671, 0, 672, 673, 674, 0,
+	675, 676, 677, 678, 679, 680, 681, 682, 683, 684,
+	893, 685, 686, 688, 687, 689, 690, 0, 691, 692,
+	0, 693, 694, 695, 0, 0, 0, 0, 0, 696,
+	697, 699, 0, 700, 701, 702, 703, 704, 705, 698,
+	706, 707, 708, 709, 710, 711, 712, 713, 0, 715,
+	716, 714, 717, 718, 0, 719, 720, 721, 722, 723,
+	894, 724, 0, 725, 726, 734, 735, 736, 727, 728,
+	730, 737, 729, 738, 739, 740, 741, 743, 742, 0,
+	745, 746, 744, 747, 748, 749, 750, 0, 751, 895,
+	752, 731, 732, 753, 754, 755, 0, 756, 757, 758,
+	759, 760, 761, 762, 763, 764, 896, 0, 766, 0,
+	765, 767, 768, 769, 770, 771, 772, 773, 775, 733,
+	776, 777, 778, 783, 784, 785, 897, 779, 780, 781,
+	782, 787, 898, 788, 789, 790, 791, 0, 792, 793,
+	0, 786, 774, 0, 794, 795, 796, 797, 798, 799,
+	800, 801, 802, 803, 0, 804, 899, 900, 901, 902,
+	0, 817, 0, 805, 807, 808, 809, 810, 903, 811,
+	812, 904, 0, 813, 814, 815, 816, 806, 819, 820,
+	818, 0, 0, 821, 822, 823, 824, 826, 828, 829,
+	830, 825, 827, 831, 0, 832, 0, 0, 833, 834,
+	835, 905, 906, 907, 0, 908, 838, 839, 836, 837,
+	840, 841, 844, 842, 843, 909, 847, 542, 848, 849,
+	850, 845, 846, 359, 5204, 0, 0, 851, 852, 910,
+	853, 854, 855, 0, 0, 0, 0, 0, 0, 0,
+	367, 368, 370, 369, 371, 372, 373, 374, 0, 375,
+	376, 0, 0, 0, 0, 0, 856, 0, 0, 0,
+	378, 0, 377, 0, 379, 380, 381, 0, 382, 383,
+	384, 385, 386, 387, 388, 389, 390, 857, 391, 858,
+	0, 392, 859, 393, 860, 0, 861, 394, 395, 396,
+	397, 398, 399, 400, 401, 402, 403, 404, 0, 0,
+	0, 405, 862, 863, 864, 0, 406, 407, 408, 409,
+	865, 0, 0, 0, 410, 411, 412, 413, 414, 415,
+	416, 417, 0, 0, 419, 420, 421, 418, 422, 423,
+	0, 424, 0, 425, 426, 427, 428, 429, 0, 430,
+	431, 0, 432, 433, 434, 0, 435, 436, 437, 0,
+	0, 0, 0, 0, 0, 0, 438, 439, 440, 441,
+	442, 0, 443, 445, 866, 867, 0, 448, 450, 444,
+	446, 0, 449, 447, 451, 452, 0, 453, 454, 455,
+	456, 457, 0, 0, 0, 458, 459, 460, 461, 0,
+	462, 463, 464, 466, 465, 0, 467, 468, 469, 0,
+	470, 471, 868, 472, 473, 474, 476, 478, 475, 477,
+	479, 480, 481, 482, 483, 869, 870, 484, 485, 0,
+	0, 0, 0, 0, 0, 0, 486, 487, 488, 871,
+	0, 0, 0, 489, 0, 491, 495, 496, 492, 493,
+	494, 497, 0, 490, 498, 499, 0, 0, 500, 501,
+	502, 872, 873, 503, 504, 505, 506, 507, 508, 509,
+	510, 511, 0, 512, 513, 874, 0, 875, 514, 0,
+	515, 516, 517, 518, 519, 520, 521, 876, 877, 878,
+	630, 0, 522, 523, 524, 525, 0, 526, 527, 528,
+	529, 530, 531, 532, 0, 0, 0, 533, 534, 535,
+	536, 0, 0, 0, 0, 0, 879, 537, 631, 538,
+	539, 880, 881, 0, 882, 0, 540, 541, 544, 0,
+	883, 0, 543, 545, 546, 0, 547, 0, 0, 0,
+	548, 549, 550, 551, 552, 553, 554, 0, 555, 557,
+	556, 0, 559, 884, 558, 0, 560, 561, 0, 0,
+	562, 563, 564, 565, 566, 567, 572, 0, 0, 568,
+	569, 570, 571, 573, 574, 0, 575, 576, 578, 581,
+	577, 579, 580, 582, 583, 596, 597, 598, 584, 585,
+	586, 587, 588, 589, 590, 591, 592, 593, 594, 595,
+	600, 0, 599, 0, 0, 601, 602, 603, 604, 605,
+	606, 612, 615, 617, 618, 613, 614, 616, 619, 620,
+	621, 623, 624, 609, 610, 611, 0, 622, 607, 0,
+	608, 0, 0, 625, 626, 627, 628, 0, 885, 629,
+	886, 632, 633, 0, 0, 634, 0, 635, 636, 0,
+	0, 638, 639, 640, 0, 0, 641, 642, 887, 0,
+	643, 0, 888, 644, 645, 637, 646, 647, 648, 649,
+	650, 651, 652, 653, 654, 655, 656, 657, 0, 658,
+	659, 889, 660, 661, 662, 663, 664, 890, 665, 666,
+	667, 891, 668, 892, 669, 670, 671, 0, 672, 673,
+	674, 0, 675, 676, 677, 678, 679, 680, 681, 682,
+	683, 684, 893, 685, 686, 688, 687, 689, 690, 0,
+	691, 692, 0, 693, 694, 695, 0, 0, 0, 0,
+	0, 696, 697, 699, 0, 700, 701, 702, 703, 704,
+	705, 698, 706, 707, 708, 709, 710, 711, 712, 713,
+	0, 715, 716, 714, 717, 718, 0, 719, 720, 721,
+	722, 723, 894, 724, 0, 725, 726, 734, 735, 736,
+	727, 728, 730, 737, 729, 738, 739, 740, 741, 743,
+	742, 0, 745, 746, 744, 747, 748, 749, 750, 0,
+	751, 895, 752, 731, 732, 753, 754, 755, 0, 756,
+	757, 758, 759, 760, 761, 762, 763, 764, 896, 0,
+	766, 0, 765, 767, 768, 769, 770, 771, 772, 773,
+	775, 733, 776, 777, 778, 783, 784, 785, 897, 779,
+	780, 781, 782, 787, 898, 788, 789, 790, 791, 0,
+	792, 793, 0, 786, 774, 0, 794, 795, 796, 797,
+	798, 799, 800, 801, 802, 803, 0, 804, 899, 900,
+	901, 902, 0, 817, 0, 805, 807, 808, 809, 810,
+	903, 811, 812, 904, 0, 813, 814, 815, 816, 806,
+	819, 820, 818, 0, 0, 821, 822, 823, 824, 826,
+	828, 829, 830, 825, 827, 831, 0, 832, 0, 0,
+	833, 834, 835, 905, 906, 907, 0, 908, 838, 839,
+	836, 837, 840, 841, 844, 842, 843, 909, 847, 542,
+	848, 849, 850, 845, 846, 359, 4543, 0, 0, 851,
+	852, 910, 853, 854, 855, 0, 0, 0, 0, 0,
+	0, 0, 367, 368, 370, 369, 371, 372, 373, 374,
+	0, 375, 376, 0, 0, 0, 0, 0, 856, 0,
+	0, 0, 378, 0, 377, 0, 379, 380, 381, 0,
+	382, 383, 384, 385, 386, 387, 388, 389, 390, 857,
+	391, 858, 0, 392, 859, 393, 860, 0, 861, 394,
+	395, 396, 397, 398, 399, 400, 401, 402, 403, 404,
+	0, 0, 0, 405, 862, 863, 864, 0, 406, 407,
+	408, 409, 865, 0, 0, 0, 410, 411, 412, 413,
+	414, 415, 416, 417, 0, 0, 419, 420, 421, 418,
+	422, 423, 0, 424, 0, 425, 426, 427, 428, 429,
+	0, 430, 431, 0, 432, 433, 434, 0, 435, 436,
+	437, 0, 0, 0, 0, 0, 0, 0, 438, 439,
+	440, 441, 442, 0, 443, 445, 866, 867, 0, 448,
+	450, 444, 446, 0, 449, 447, 451, 452, 0, 453,
+	454, 455, 456, 457, 0, 0, 0, 458, 459, 460,
+	461, 0, 462, 463, 464, 466, 465, 0, 467, 468,
+	469, 0, 470, 471, 868, 472, 473, 474, 476, 478,
+	475, 477, 479, 480, 481, 482, 483, 869, 870, 484,
+	485, 0, 0, 0, 0, 0, 0, 0, 486, 487,
+	488, 871, 0, 0, 0, 489, 0, 491, 495, 496,
+	492, 493, 494, 497, 0, 490, 498, 499, 0, 0,
+	500, 501, 502, 872, 873, 503, 504, 505, 506, 507,
+	508, 509, 510, 511, 0, 512, 513, 874, 0, 875,
+	514, 0, 515, 516, 517, 518, 519, 520, 521, 876,
+	877, 878, 630, 0, 522, 523, 524, 525, 0, 526,
+	527, 528, 529, 530, 531, 532, 0, 0, 0, 533,
+	534, 535, 536, 0, 0, 0, 0, 0, 879, 537,
+	631, 538, 539, 880, 881, 0, 882, 0, 540, 541,
+	544, 0, 883, 0, 543, 545, 546, 0, 547, 0,
+	0, 0, 548, 549, 550, 551, 552, 553, 554, 0,
+	555, 557, 556, 0, 559, 884, 558, 0, 560, 561,
+	0, 0, 562, 563, 564, 565, 566, 567, 572, 0,
+	0, 568, 569, 570, 571, 573, 574, 0, 575, 576,
+	578, 581, 577, 579, 580, 582, 583, 596, 597, 598,
+	584, 585, 586, 587, 588, 589, 590, 591, 592, 593,
+	594, 595, 600, 0, 599, 0, 0, 601, 602, 603,
+	604, 605, 606, 612, 615, 617, 618, 613, 614, 616,
+	619, 620, 621, 623, 624, 609, 610, 611, 0, 622,
+	607, 0, 608, 0, 0, 625, 626, 627, 628, 0,
+	885, 629, 886, 632, 633, 0, 0, 634, 0, 635,
+	636, 0, 0, 638, 639, 640, 0, 0, 641, 642,
+	887, 0, 643, 0, 888, 644, 645, 637, 646, 647,
+	648, 649, 650, 651, 652, 653, 654, 655, 656, 657,
+	0, 658, 659, 889, 660, 661, 662, 663, 664, 890,
+	665, 666, 667, 891, 668, 892, 669, 670, 671, 0,
+	672, 673, 674, 0, 675, 676, 677, 678, 679, 680,
+	681, 682, 683, 684, 893, 685, 686, 688, 687, 689,
+	690, 0, 691, 692, 0, 693, 694, 695, 0, 0,
+	0, 0, 0, 696, 697, 699, 0, 700, 701, 702,
+	703, 704, 705, 698, 706, 707, 708, 709, 710, 711,
+	712, 713, 0, 715, 716, 714, 717, 718, 0, 719,
+	720, 721, 722, 723, 894, 724, 0, 725, 726, 734,
+	735, 736, 727, 728, 730, 737, 729, 738, 739, 740,
+	741, 743, 742, 0, 745, 746, 744, 747, 748, 749,
+	750, 0, 751, 895, 752, 731, 732, 753, 754, 755,
+	0, 756, 757, 758, 759, 760, 761, 762, 763, 764,
+	896, 0, 766, 0, 765, 767, 768, 769, 770, 771,
+	772, 773, 775, 733, 776, 777, 778, 783, 784, 785,
+	897, 779, 780, 781, 782, 787, 898, 788, 789, 790,
+	791, 0, 792, 793, 0, 786, 774, 0, 794, 795,
+	796, 797, 798, 799, 800, 801, 802, 803, 0, 804,
+	899, 900, 901, 902, 0, 817, 0, 805, 807, 808,
+	809, 810, 903, 811, 812, 904, 0, 813, 814, 815,
+	816, 806, 819, 820, 818, 0, 0, 821, 822, 823,
+	824, 826, 828, 829, 830, 825, 827, 831, 0, 832,
+	0, 0, 833, 834, 835, 905, 906, 907, 0, 908,
+	838, 839, 836, 837, 840, 841, 844, 842, 843, 909,
+	847, 542, 848, 849, 850, 845, 846, 359, 5115, 0,
+	0, 851, 852, 910, 853, 854, 855, 0, 0, 0,
+	0, 0, 0, 0, 367, 368, 370, 369, 371, 372,
+	373, 374, 0, 375, 376, 0, 0, 0, 0, 0,
+	856, 0, 0, 0, 378, 0, 377, 0, 379, 380,
+	381, 0, 382, 383, 384, 385, 386, 387, 388, 389,
+	390, 857, 391, 858, 0, 392, 859, 393, 860, 0,
+	861, 394, 395, 396, 397, 398, 399, 400, 401, 402,
+	403, 404, 0, 0, 0, 405, 862, 863, 864, 0,
+	406, 407, 408, 409, 865, 0, 0, 0, 410, 411,
+	412, 413, 414, 415, 416, 417, 0, 0, 419, 420,
+	421, 418, 422, 423, 0, 424, 0, 425, 426, 427,
+	428, 429, 0, 430, 431, 0, 432, 433, 434, 0,
+	435, 436, 437, 0, 0, 0, 0, 0, 0, 0,
+	438, 439, 440, 441, 442, 0, 443, 445, 866, 867,
+	0, 448, 450, 444, 446, 0, 449, 447, 451, 452,
+	0, 453, 454, 455, 456, 457, 0, 0, 0, 458,
+	459, 460, 461, 0, 462, 463, 464, 466, 465, 0,
+	467, 468, 469, 0, 470, 471, 868, 472, 473, 474,
+	476, 478, 475, 477, 479, 480, 481, 482, 483, 869,
+	870, 484, 485, 0, 0, 0, 0, 0, 0, 0,
+	486, 487, 488, 871, 0, 0, 0, 489, 0, 491,
+	495, 496, 492, 493, 494, 497, 0, 490, 498, 499,
+	0, 0, 500, 501, 502, 872, 873, 503, 504, 505,
+	506, 507, 508, 509, 510, 511, 0, 512, 513, 874,
+	0, 875, 514, 0, 515, 516, 517, 518, 519, 520,
+	521, 876, 877, 878, 630, 0, 522, 523, 524, 525,
+	0, 526, 527, 528, 529, 530, 531, 532, 0, 0,
+	0, 533, 534, 535, 536, 0, 0, 0, 0, 0,
+	879, 537, 631, 538, 539, 880, 881, 0, 882, 0,
+	540, 541, 544, 0, 883, 0, 543, 545, 546, 0,
+	547, 0, 0, 0, 548, 549, 550, 551, 552, 553,
+	554, 0, 555, 557, 556, 0, 559, 884, 558, 0,
+	560, 561, 0, 0, 562, 563, 564, 565, 566, 567,
+	572, 0, 0, 568, 569, 570, 571, 573, 574, 0,
+	575, 576, 578, 581, 577, 579, 580, 582, 583, 596,
+	597, 598, 584, 585, 586, 587, 588, 589, 590, 591,
+	592, 593, 594, 595, 600, 0, 599, 0, 0, 601,
+	602, 603, 604, 605, 606, 612, 615, 617, 618, 613,
+	614, 616, 619, 620, 621, 623, 624, 609, 610, 611,
+	0, 622, 607, 0, 608, 0, 0, 625, 626, 627,
+	628, 0, 885, 629, 886, 632, 633, 0, 0, 634,
+	0, 635, 636, 0, 0, 638, 639, 640, 0, 0,
+	641, 642, 887, 0, 643, 0, 888, 644, 645, 637,
+	646, 647, 648, 649, 650, 651, 652, 653, 654, 655,
+	656, 657, 0, 658, 659, 889, 660, 661, 662, 663,
+	664, 890, 665, 666, 667, 891, 668, 892, 669, 670,
+	671, 0, 672, 673, 674, 0, 675, 676, 677, 678,
+	679, 680, 681, 682, 683, 684, 893, 685, 686, 688,
+	687, 689, 690, 0, 691, 692, 0, 693, 694, 695,
+	0, 0, 0, 0, 0, 696, 697, 699, 0, 700,
+	701, 702, 703, 704, 705, 698, 706, 707, 708, 709,
+	710, 711, 712, 713, 0, 715, 716, 714, 717, 718,
+	0, 719, 720, 721, 722, 723, 894, 724, 0, 725,
+	726, 734, 735, 736, 727, 728, 730, 737, 729, 738,
+	739, 740, 741, 743, 742, 0, 745, 746, 744, 747,
+	748, 749, 750, 0, 751, 895, 752, 731, 732, 753,
+	754, 755, 0, 756, 757, 758, 759, 760, 761, 762,
+	763, 764, 896, 0, 766, 0, 765, 767, 768, 769,
+	770, 771, 772, 773, 775, 733, 776, 777, 778, 783,
+	784, 785, 897, 779, 780, 781, 782, 787, 898, 788,
+	789, 790, 791, 0, 792, 793, 0, 786, 774, 0,
+	794, 795, 796, 797, 798, 799, 800, 801, 802, 803,
+	0, 804, 899, 900, 901, 902, 0, 817, 0, 805,
+	807, 808, 809, 810, 903, 811, 812, 904, 0, 813,
+	814, 815, 816, 806, 819, 820, 818, 0, 0, 821,
+	822, 823, 824, 826, 828, 829, 830, 825, 827, 831,
+	0, 832, 0, 0, 833, 834, 835, 905, 906, 907,
+	0, 908, 838, 839, 836, 837, 840, 841, 844, 842,
+	843, 909, 847, 542, 848, 849, 850, 845, 846, 359,
+	0, 0, 0, 851, 852, 910, 853, 854, 855, 0,
+	0, 0, 0, 0, 0, 0, 367, 368, 370, 369,
+	371, 372, 373, 374, 0, 375, 376, 0, 0, 0,
+	0, 0, 856, 0, 0, 0, 378, 0, 377, 0,
+	379, 380, 381, 0, 382, 383, 384, 385, 386, 387,
+	388, 389, 390, 857, 391, 858, 0, 392, 859, 393,
+	860, 0, 861, 394, 395, 396, 397, 398, 399, 400,
+	401, 402, 403, 404, 0, 0, 0, 405, 862, 863,
+	864, 0, 406, 407, 408, 409, 865, 0, 0, 0,
+	410, 411, 412, 413, 414, 415, 416, 417, 0, 0,
+	419, 420, 421, 418, 422, 423, 0, 424, 0, 425,
+	426, 427, 428, 429, 0, 430, 431, 0, 432, 433,
+	434, 0, 435, 436, 437, 0, 0, 0, 0, 0,
+	0, 0, 438, 439, 440, 441, 442, 0, 443, 445,
+	866, 867, 5741, 448, 450, 444, 446, 0, 449, 447,
+	451, 452, 0, 453, 454, 455, 456, 457, 0, 0,
+	0, 458, 459, 460, 461, 0, 462, 463, 464, 466,
+	465, 0, 467, 468, 469, 0, 470, 471, 868, 472,
+	473, 474, 476, 478, 475, 477, 479, 480, 481, 482,
+	483, 869, 870, 484, 485, 0, 0, 0, 0, 0,
+	0, 0, 486, 487, 488, 871, 0, 0, 0, 489,
+	0, 491, 495, 496, 492, 493, 494, 497, 0, 490,
+	498, 499, 0, 0, 500, 501, 502, 872, 873, 503,
+	504, 505, 506, 507, 508, 509, 510, 511, 0, 512,
+	513, 874, 0, 875, 514, 0, 515, 516, 517, 518,
+	519, 520, 521, 876, 877, 878, 630, 0, 522, 523,
+	524, 525, 0, 526, 527, 528, 529, 530, 531, 532,
+	0, 0, 0, 533, 534, 535, 536, 0, 0, 0,
+	0, 0, 879, 537, 631, 538, 539, 880, 881, 0,
+	882, 0, 540, 541, 544, 0, 883, 0, 543, 545,
+	546, 0, 547, 0, 0, 0, 548, 549, 550, 551,
+	552, 553, 554, 0, 555, 557, 556, 0, 559, 884,
+	558, 0, 560, 561, 0, 0, 562, 563, 564, 565,
+	566, 567, 572, 0, 0, 568, 569, 570, 571, 573,
+	574, 0, 575, 576, 578, 581, 577, 579, 580, 582,
+	583, 596, 597, 598, 584, 585, 586, 587, 588, 589,
+	590, 591, 592, 593, 594, 595, 600, 0, 599, 0,
+	0, 601, 602, 603, 604, 605, 606, 612, 615, 617,
+	618, 613, 614, 616, 619, 620, 621, 623, 624, 609,
+	610, 611, 0, 622, 607, 0, 608, 0, 0, 625,
+	626, 627, 628, 0, 885, 629, 886, 632, 633, 0,
+	0, 634, 0, 635, 636, 0, 0, 638, 639, 640,
+	0, 0, 641, 642, 887, 0, 643, 0, 888, 644,
+	645, 637, 646, 647, 648, 649, 650, 651, 652, 653,
+	654, 655, 656, 657, 0, 658, 659, 889, 660, 661,
+	662, 663, 664, 890, 665, 666, 667, 891, 668, 892,
+	669, 670, 671, 0, 672, 673, 674, 0, 675, 676,
+	677, 678, 679, 680, 681, 682, 683, 684, 893, 685,
+	686, 688, 687, 689, 690, 0, 691, 692, 0, 693,
+	694, 695, 0, 0, 0, 0, 0, 696, 697, 699,
+	0, 700, 701, 702, 703, 704, 705, 698, 706, 707,
+	708, 709, 710, 711, 712, 713, 0, 715, 716, 714,
+	717, 718, 0, 719, 720, 721, 722, 723, 894, 724,
+	0, 725, 726, 734, 735, 736, 727, 728, 730, 737,
+	729, 738, 739, 740, 741, 743, 742, 0, 745, 746,
+	744, 747, 748, 749, 750, 0, 751, 895, 752, 731,
+	732, 753, 754, 755, 0, 756, 757, 758, 759, 760,
+	761, 762, 763, 764, 896, 0, 766, 0, 765, 767,
+	768, 769, 770, 771, 772, 773, 775, 733, 776, 777,
+	778, 783, 784, 785, 897, 779, 780, 781, 782, 787,
+	898, 788, 789, 790, 791, 0, 792, 793, 0, 786,
+	774, 0, 794, 795, 796, 797, 798, 799, 800, 801,
+	802, 803, 0, 804, 899, 900, 901, 902, 0, 817,
+	0, 805, 807, 808, 809, 810, 903, 811, 812, 904,
+	0, 813, 814, 815, 816, 806, 819, 820, 818, 0,
+	0, 821, 822, 823, 824, 826, 828, 829, 830, 825,
+	827, 831, 0, 832, 0, 0, 833, 834, 835, 905,
+	906, 907, 0, 908, 838, 839, 836, 837, 840, 841,
+	844, 842, 843, 909, 847, 542, 848, 849, 850, 845,
+	846, 359, 0, 0, 0, 851, 852, 910, 853, 854,
+	855, 0, 0, 0, 0, 0, 0, 0, 367, 368,
+	370, 369, 371, 372, 373, 374, 0, 375, 376, 0,
+	0, 0, 0, 0, 856, 0, 4123, 0, 378, 0,
+	377, 0, 379, 380, 381, 0, 382, 383, 384, 385,
+	386, 387, 388, 389, 390, 857, 391, 858, 0, 392,
+	859, 393, 860, 0, 861, 394, 395, 396, 397, 398,
+	399, 400, 401, 402, 403, 404, 0, 0, 0, 405,
+	862, 863, 864, 0, 406, 407, 408, 409, 865, 0,
+	0, 0, 410, 411, 412, 413, 414, 415, 416, 417,
+	0, 0, 419, 420, 421, 418, 422, 423, 0, 424,
+	0, 425, 426, 427, 428, 429, 0, 430, 431, 0,
+	432, 433, 434, 0, 435, 436, 437, 0, 0, 0,
+	0, 0, 0, 0, 438, 439, 440, 441, 442, 0,
+	443, 445, 866, 867, 0, 448, 450, 444, 446, 0,
+	449, 447, 451, 452, 0, 453, 454, 455, 456, 457,
+	0, 0, 0, 458, 459, 460, 461, 0, 462, 463,
+	464, 466, 465, 0, 467, 468, 469, 0, 470, 471,
+	868, 472, 473, 474, 476, 478, 475, 477, 479, 480,
+	481, 482, 483, 869, 870, 484, 485, 0, 0, 0,
+	0, 0, 0, 0, 486, 487, 488, 871, 0, 0,
+	0, 489, 0, 491, 495, 496, 492, 493, 494, 497,
+	0, 490, 498, 499, 0, 0, 500, 501, 502, 872,
+	873, 503, 504, 505, 506, 507, 508, 509, 510, 511,
+	0, 512, 513, 874, 0, 875, 514, 0, 515, 516,
+	517, 518, 519, 520, 521, 876, 877, 878, 630, 0,
+	522, 523, 524, 525, 0, 526, 527, 528, 529, 530,
+	531, 532, 0, 0, 0, 533, 534, 535, 536, 0,
+	0, 0, 0, 0, 879, 537, 631, 538, 539, 880,
+	881, 0, 882, 0, 540, 541, 544, 0, 883, 0,
+	543, 545, 546, 0, 547, 0, 0, 0, 548, 549,
+	550, 551, 552, 553, 554, 0, 555, 557, 556, 0,
+	559, 884, 558, 0, 560, 561, 0, 0, 562, 563,
+	564, 565, 566, 567, 572, 0, 0, 568, 569, 570,
+	571, 573, 574, 0, 575, 576, 578, 581, 577, 579,
+	580, 582, 583, 596, 597, 598, 584, 585, 586, 587,
+	588, 589, 590, 591, 592, 593, 594, 595, 600, 0,
+	599, 0, 0, 601, 602, 603, 604, 605, 606, 612,
+	615, 617, 618, 613, 614, 616, 619, 620, 621, 623,
+	624, 609, 610, 611, 0, 622, 607, 0, 608, 0,
+	0, 625, 626, 627, 628, 0, 885, 629, 886, 632,
+	633, 0, 0, 634, 0, 635, 636, 0, 0, 638,
+	639, 640, 0, 0, 641, 642, 887, 0, 643, 0,
+	888, 644, 645, 637, 646, 647, 648, 649, 650, 651,
+	652, 653, 654, 655, 656, 657, 0, 658, 659, 889,
+	660, 661, 662, 663, 664, 890, 665, 666, 667, 891,
+	668, 892, 669, 670, 671, 0, 672, 673, 674, 0,
+	675, 676, 677, 678, 679, 680, 681, 682, 683, 684,
+	893, 685, 686, 688, 687, 689, 690, 0, 691, 692,
+	0, 693, 694, 695, 0, 0, 0, 0, 0, 696,
+	697, 699, 0, 700, 701, 702, 703, 704, 705, 698,
+	706, 707, 708, 709, 710, 711, 712, 713, 0, 715,
+	716, 714, 717, 718, 0, 719, 720, 721, 722, 723,
+	894, 724, 0, 725, 726, 734, 735, 736, 727, 728,
+	730, 737, 729, 738, 739, 740, 741, 743, 742, 0,
+	745, 746, 744, 747, 748, 749, 750, 0, 751, 895,
+	752, 731, 732, 753, 754, 755, 0, 756, 757, 758,
+	759, 760, 761, 762, 763, 764, 896, 0, 766, 0,
+	765, 767, 768, 769, 770, 771, 772, 773, 775, 733,
+	776, 777, 778, 783, 784, 785, 897, 779, 780, 781,
+	782, 787, 898, 788, 789, 790, 791, 0, 792, 793,
+	0, 786, 774, 0, 794, 795, 796, 797, 798, 799,
+	800, 801, 802, 803, 0, 804, 899, 900, 901, 902,
+	0, 817, 0, 805, 807, 808, 809, 810, 903, 811,
+	812, 904, 0, 813, 814, 815, 816, 806, 819, 820,
+	818, 0, 0, 821, 822, 823, 824, 826, 828, 829,
+	830, 825, 827, 831, 0, 832, 0, 0, 833, 834,
+	835, 905, 906, 907, 0, 908, 838, 839, 836, 837,
+	840, 841, 844, 842, 843, 909, 847, 542, 848, 849,
+	850, 845, 846, 359, 0, 0, 0, 851, 852, 910,
+	853, 854, 855, 0, 0, 0, 0, 0, 0, 0,
+	367, 368, 370, 369, 371, 372, 373, 374, 0, 375,
+	376, 0, 0, 0, 0, 0, 856, 0, 4115, 0,
+	378, 0, 377, 0, 379, 380, 381, 0, 382, 383,
+	384, 385, 386, 387, 388, 389, 390, 857, 391, 858,
+	0, 392, 859, 393, 860, 0, 861, 394, 395, 396,
+	397, 398, 399, 400, 401, 402, 403, 404, 0, 0,
+	0, 405, 862, 863, 864, 0, 406, 407, 408, 409,
+	865, 0, 0, 0, 410, 411, 412, 413, 414, 415,
+	416, 417, 0, 0, 419, 420, 421, 418, 422, 423,
+	0, 424, 0, 425, 426, 427, 428, 429, 0, 430,
+	431, 0, 432, 433, 434, 0, 435, 436, 437, 0,
+	0, 0, 0, 0, 0, 0, 438, 439, 440, 441,
+	442, 0, 443, 445, 866, 867, 0, 448, 450, 444,
+	446, 0, 449, 447, 451, 452, 0, 453, 454, 455,
+	456, 457, 0, 0, 0, 458, 459, 460, 461, 0,
+	462, 463, 464, 466, 465, 0, 467, 468, 469, 0,
+	470, 471, 868, 472, 473, 474, 476, 478, 475, 477,
+	479, 480, 481, 482, 483, 869, 870, 484, 485, 0,
+	0, 0, 0, 0, 0, 0, 486, 487, 488, 871,
+	0, 0, 0, 489, 0, 491, 495, 496, 492, 493,
+	494, 497, 0, 490, 498, 499, 0, 0, 500, 501,
+	502, 872, 873, 503, 504, 505, 506, 507, 508, 509,
+	510, 511, 0, 512, 513, 874, 0, 875, 514, 0,
+	515, 516, 517, 518, 519, 520, 521, 876, 877, 878,
+	630, 0, 522, 523, 524, 525, 0, 526, 527, 528,
+	529, 530, 531, 532, 0, 0, 0, 533, 534, 535,
+	536, 0, 0, 0, 0, 0, 879, 537, 631, 538,
+	539, 880, 881, 0, 882, 0, 540, 541, 544, 0,
+	883, 0, 543, 545, 546, 0, 547, 0, 0, 0,
+	548, 549, 550, 551, 552, 553, 554, 0, 555, 557,
+	556, 0, 559, 884, 558, 0, 560, 561, 0, 0,
+	562, 563, 564, 565, 566, 567, 572, 0, 0, 568,
+	569, 570, 571, 573, 574, 0, 575, 576, 578, 581,
+	577, 579, 580, 582, 583, 596, 597, 598, 584, 585,
+	586, 587, 588, 589, 590, 591, 592, 593, 594, 595,
+	600, 0, 599, 0, 0, 601, 602, 603, 604, 605,
+	606, 612, 615, 617, 618, 613, 614, 616, 619, 620,
+	621, 623, 624, 609, 610, 611, 0, 622, 607, 0,
+	608, 0, 0, 625, 626, 627, 628, 0, 885, 629,
+	886, 632, 633, 0, 0, 634, 0, 635, 636, 0,
+	0, 638, 639, 640, 0, 0, 641, 642, 887, 0,
+	643, 0, 888, 644, 645, 637, 646, 647, 648, 649,
+	650, 651, 652, 653, 654, 655, 656, 657, 0, 658,
+	659, 889, 660, 661, 662, 663, 664, 890, 665, 666,
+	667, 891, 668, 892, 669, 670, 671, 0, 672, 673,
+	674, 0, 675, 676, 677, 678, 679, 680, 681, 682,
+	683, 684, 893, 685, 686, 688, 687, 689, 690, 0,
+	691, 692, 0, 693, 694, 695, 0, 0, 0, 0,
+	0, 696, 697, 699, 0, 700, 701, 702, 703, 704,
+	705, 698, 706, 707, 708, 709, 710, 711, 712, 713,
+	0, 715, 716, 714, 717, 718, 0, 719, 720, 721,
+	722, 723, 894, 724, 0, 725, 726, 734, 735, 736,
+	727, 728, 730, 737, 729, 738, 739, 740, 741, 743,
+	742, 0, 745, 746, 744, 747, 748, 749, 750, 0,
+	751, 895, 752, 731, 732, 753, 754, 755, 0, 756,
+	757, 758, 759, 760, 761, 762, 763, 764, 896, 0,
+	766, 0, 765, 767, 768, 769, 770, 771, 772, 773,
+	775, 733, 776, 777, 778, 783, 784, 785, 897, 779,
+	780, 781, 782, 787, 898, 788, 789, 790, 791, 0,
+	792, 793, 0, 786, 774, 0, 794, 795, 796, 797,
+	798, 799, 800, 801, 802, 803, 0, 804, 899, 900,
+	901, 902, 0, 817, 0, 805, 807, 808, 809, 810,
+	903, 811, 812, 904, 0, 813, 814, 815, 816, 806,
+	819, 820, 818, 0, 0, 821, 822, 823, 824, 826,
+	828, 829, 830, 825, 827, 831, 0, 832, 0, 0,
+	833, 834, 835, 905, 906, 907, 0, 908, 838, 839,
+	836, 837, 840, 841, 844, 842, 843, 909, 847, 542,
+	848, 849, 850, 845, 846, 359, 5204, 0, 0, 851,
+	852, 910, 853, 854, 855, 0, 0, 0, 0, 0,
+	0, 0, 367, 368, 370, 369, 371, 372, 373, 374,
+	0, 375, 376, 0, 0, 0, 0, 0, 856, 0,
+	0, 0, 378, 0, 377, 0, 379, 380, 381, 0,
+	382, 383, 384, 385, 386, 387, 388, 389, 390, 857,
+	391, 858, 0, 392, 859, 393, 860, 0, 861, 394,
+	395, 396, 397, 398, 399, 400, 401, 402, 403, 404,
+	0, 0, 0, 405, 862, 863, 864, 0, 406, 407,
+	408, 409, 865, 0, 0, 0, 410, 411, 412, 413,
+	414, 415, 416, 417, 0, 0, 419, 420, 421, 418,
+	422, 423, 0, 424, 0, 425, 426, 427, 428, 429,
+	0, 430, 431, 0, 432, 433, 434, 0, 435, 436,
+	437, 0, 0, 0, 0, 0, 0, 0, 438, 439,
+	440, 441, 442, 0, 443, 445, 866, 867, 0, 448,
+	450, 444, 446, 0, 449, 447, 451, 452, 0, 453,
+	454, 455, 456, 457, 0, 0, 0, 458, 459, 460,
+	461, 0, 462, 463, 464, 466, 465, 0, 467, 468,
+	469, 0, 470, 471, 868, 472, 473, 474, 476, 478,
+	475, 477, 479, 480, 481, 482, 483, 869, 870, 484,
+	485, 0, 0, 0, 0, 0, 0, 0, 486, 487,
+	488, 871, 0, 0, 0, 489, 0, 491, 495, 496,
+	492, 493, 494, 497, 0, 490, 498, 499, 0, 0,
+	500, 501, 502, 872, 873, 503, 504, 505, 506, 507,
+	508, 509, 510, 511, 0, 512, 513, 874, 0, 875,
+	514, 0, 515, 516, 517, 518, 519, 520, 521, 5207,
+	877, 878, 630, 0, 522, 523, 524, 525, 0, 526,
+	527, 528, 529, 530, 531, 532, 0, 0, 0, 533,
+	534, 535, 536, 0, 0, 0, 0, 0, 879, 537,
+	631, 538, 539, 880, 881, 0, 882, 0, 540, 541,
+	544, 0, 883, 0, 543, 545, 546, 0, 547, 0,
+	0, 0, 548, 549, 550, 551, 552, 553, 554, 0,
+	555, 557, 556, 0, 559, 884, 558, 0, 560, 561,
+	0, 0, 562, 563, 564, 565, 566, 567, 572, 0,
+	0, 568, 569, 570, 571, 573, 574, 0, 575, 576,
+	578, 581, 577, 579, 580, 582, 583, 596, 597, 598,
+	584, 585, 586, 587, 588, 589, 590, 591, 592, 593,
+	594, 595, 600, 0, 599, 0, 0, 601, 602, 603,
+	604, 605, 606, 612, 615, 617, 618, 613, 614, 616,
+	619, 620, 621, 623, 624, 609, 610, 611, 0, 622,
+	607, 0, 608, 0, 0, 625, 626, 627, 628, 0,
+	885, 629, 886, 632, 633, 0, 0, 634, 0, 635,
+	636, 0, 0, 638, 639, 640, 0, 0, 641, 642,
+	887, 0, 643, 0, 888, 644, 645, 637, 646, 647,
+	648, 649, 650, 651, 652, 653, 654, 655, 656, 657,
+	0, 658, 659, 889, 660, 661, 662, 663, 664, 890,
+	665, 666, 667, 891, 668, 892, 669, 670, 671, 0,
+	672, 673, 674, 0, 675, 676, 677, 678, 679, 680,
+	681, 682, 683, 684, 893, 685, 686, 688, 687, 689,
+	690, 0, 691, 692, 0, 693, 694, 695, 0, 0,
+	0, 0, 0, 696, 697, 699, 0, 700, 701, 702,
+	703, 704, 705, 698, 706, 707, 708, 709, 710, 711,
+	712, 713, 0, 715, 716, 714, 717, 718, 0, 719,
+	720, 721, 722, 723, 894, 724, 0, 725, 726, 734,
+	735, 736, 727, 728, 730, 737, 729, 738, 739, 740,
+	741, 743, 742, 0, 745, 746, 744, 747, 748, 749,
+	750, 0, 751, 895, 752, 731, 732, 753, 754, 755,
+	0, 756, 757, 758, 759, 760, 761, 762, 763, 764,
+	896, 0, 766, 0, 765, 767, 768, 769, 770, 771,
+	772, 773, 775, 733, 776, 777, 778, 783, 784, 785,
+	897, 779, 780, 781, 782, 787, 898, 788, 789, 790,
+	791, 0, 792, 793, 0, 786, 774, 0, 794, 795,
+	796, 797, 798, 799, 800, 801, 802, 803, 0, 804,
+	899, 900, 901, 902, 0, 817, 0, 805, 807, 808,
+	809, 810, 903, 811, 812, 904, 0, 813, 814, 815,
+	816, 806, 819, 820, 818, 0, 0, 821, 822, 823,
+	824, 826, 828, 829, 830, 825, 827, 831, 0, 832,
+	0, 0, 833, 834, 835, 905, 906, 907, 0, 908,
+	838, 839, 836, 837, 840, 841, 844, 842, 843, 909,
+	847, 542, 848, 849, 850, 845, 846, 359, 5204, 0,
+	0, 851, 852, 910, 853, 854, 855, 0, 0, 0,
+	0, 0, 0, 0, 367, 368, 370, 369, 371, 372,
+	373, 374, 0, 375, 376, 0, 0, 0, 0, 0,
+	856, 0, 0, 0, 378, 0, 377, 0, 379, 380,
+	381, 0, 382, 383, 384, 385, 386, 387, 388, 389,
+	390, 857, 391, 858, 0, 392, 859, 393, 860, 0,
+	861, 394, 395, 396, 397, 398, 399, 400, 401, 402,
+	403, 404, 0, 0, 0, 405, 862, 863, 864, 0,
+	406, 407, 408, 409, 865, 0, 0, 0, 410, 411,
+	412, 413, 414, 415, 416, 417, 0, 0, 419, 420,
+	421, 418, 422, 423, 0, 424, 0, 425, 426, 427,
+	428, 429, 0, 430, 431, 0, 432, 433, 434, 0,
+	435, 436, 437, 0, 0, 0, 0, 0, 0, 0,
+	438, 439, 440, 441, 442, 0, 443, 445, 866, 867,
+	0, 448, 450, 444, 446, 0, 449, 447, 451, 452,
+	0, 453, 454, 455, 456, 457, 0, 0, 0, 458,
+	459, 460, 461, 0, 462, 463, 464, 466, 465, 0,
+	467, 468, 469, 0, 470, 471, 868, 472, 473, 474,
+	476, 478, 475, 477, 479, 480, 481, 482, 483, 869,
+	870, 484, 485, 0, 0, 0, 0, 0, 0, 0,
+	486, 487, 488, 871, 0, 0, 0, 489, 0, 491,
+	495, 496, 492, 493, 494, 497, 0, 490, 498, 499,
+	0, 0, 500, 501, 502, 872, 873, 503, 504, 505,
+	506, 507, 508, 509, 510, 511, 0, 512, 513, 874,
+	0, 875, 514, 0, 515, 516, 517, 518, 519, 520,
+	521, 5202, 877, 878, 630, 0, 522, 523, 524, 525,
+	0, 526, 527, 528, 529, 530, 531, 532, 0, 0,
+	0, 533, 534, 535, 536, 0, 0, 0, 0, 0,
+	879, 537, 631, 538, 539, 880, 881, 0, 882, 0,
+	540, 541, 544, 0, 883, 0, 543, 545, 546, 0,
+	547, 0, 0, 0, 548, 549, 550, 551, 552, 553,
+	554, 0, 555, 557, 556, 0, 559, 884, 558, 0,
+	560, 561, 0, 0, 562, 563, 564, 565, 566, 567,
+	572, 0, 0, 568, 569, 570, 571, 573, 574, 0,
+	575, 576, 578, 581, 577, 579, 580, 582, 583, 596,
+	597, 598, 584, 585, 586, 587, 588, 589, 590, 591,
+	592, 593, 594, 595, 600, 0, 599, 0, 0, 601,
+	602, 603, 604, 605, 606, 612, 615, 617, 618, 613,
+	614, 616, 619, 620, 621, 623, 624, 609, 610, 611,
+	0, 622, 607, 0, 608, 0, 0, 625, 626, 627,
+	628, 0, 885, 629, 886, 632, 633, 0, 0, 634,
+	0, 635, 636, 0, 0, 638, 639, 640, 0, 0,
+	641, 642, 887, 0, 643, 0, 888, 644, 645, 637,
+	646, 647, 648, 649, 650, 651, 652, 653, 654, 655,
+	656, 657, 0, 658, 659, 889, 660, 661, 662, 663,
+	664, 890, 665, 666, 667, 891, 668, 892, 669, 670,
+	671, 0, 672, 673, 674, 0, 675, 676, 677, 678,
+	679, 680, 681, 682, 683, 684, 893, 685, 686, 688,
+	687, 689, 690, 0, 691, 692, 0, 693, 694, 695,
+	0, 0, 0, 0, 0, 696, 697, 699, 0, 700,
+	701, 702, 703, 704, 705, 698, 706, 707, 708, 709,
+	710, 711, 712, 713, 0, 715, 716, 714, 717, 718,
+	0, 719, 720, 721, 722, 723, 894, 724, 0, 725,
+	726, 734, 735, 736, 727, 728, 730, 737, 729, 738,
+	739, 740, 741, 743, 742, 0, 745, 746, 744, 747,
+	748, 749, 750, 0, 751, 895, 752, 731, 732, 753,
+	754, 755, 0, 756, 757, 758, 759, 760, 761, 762,
+	763, 764, 896, 0, 766, 0, 765, 767, 768, 769,
+	770, 771, 772, 773, 775, 733, 776, 777, 778, 783,
+	784, 785, 897, 779, 780, 781, 782, 787, 898, 788,
+	789, 790, 791, 0, 792, 793, 0, 786, 774, 0,
+	794, 795, 796, 797, 798, 799, 800, 801, 802, 803,
+	0, 804, 899, 900, 901, 902, 0, 817, 0, 805,
+	807, 808, 809, 810, 903, 811, 812, 904, 0, 813,
+	814, 815, 816, 806, 819, 820, 818, 0, 0, 821,
+	822, 823, 824, 826, 828, 829, 830, 825, 827, 831,
+	0, 832, 0, 0, 833, 834, 835, 905, 906, 907,
+	0, 908, 838, 839, 836, 837, 840, 841, 844, 842,
+	843, 909, 847, 542, 848, 849, 850, 845, 846, 359,
+	4543, 0, 0, 851, 852, 910, 853, 854, 855, 0,
+	0, 0, 0, 0, 0, 0, 367, 368, 370, 369,
+	371, 372, 373, 374, 0, 375, 376, 0, 0, 0,
+	0, 0, 856, 0, 0, 0, 378, 0, 377, 0,
+	379, 380, 381, 0, 382, 383, 384, 385, 386, 387,
+	388, 389, 390, 857, 391, 858, 0, 392, 859, 393,
+	860, 0, 861, 394, 395, 396, 397, 398, 399, 400,
+	401, 402, 403, 404, 0, 0, 0, 405, 862, 863,
+	864, 0, 406, 407, 408, 409, 865, 0, 0, 0,
+	410, 411, 412, 413, 414, 415, 416, 417, 0, 0,
+	419, 420, 421, 418, 422, 423, 0, 424, 0, 425,
+	426, 427, 428, 429, 0, 430, 431, 0, 432, 433,
+	434, 0, 435, 436, 437, 0, 0, 0, 0, 0,
+	0, 0, 438, 439, 440, 441, 442, 0, 443, 445,
+	866, 867, 0, 448, 450, 444, 446, 0, 449, 447,
+	451, 452, 0, 453, 454, 455, 456, 457, 0, 0,
+	0, 458, 459, 460, 461, 0, 462, 463, 464, 466,
+	465, 0, 467, 468, 469, 0, 470, 471, 868, 472,
+	473, 474, 476, 478, 475, 477, 479, 480, 481, 482,
+	483, 869, 870, 484, 485, 0, 0, 0, 0, 0,
+	0, 0, 486, 487, 488, 871, 0, 0, 0, 489,
+	0, 491, 495, 496, 492, 493, 494, 497, 0, 490,
+	498, 499, 0, 0, 500, 501, 502, 872, 873, 503,
+	504, 505, 506, 507, 508, 509, 510, 511, 0, 512,
+	513, 874, 0, 875, 514, 0, 515, 516, 517, 518,
+	519, 520, 521, 876, 877, 878, 630, 0, 522, 523,
+	524, 525, 0, 526, 527, 528, 529, 530, 531, 532,
+	0, 0, 0, 533, 534, 535, 536, 0, 0, 0,
+	0, 0, 879, 537, 631, 538, 539, 880, 881, 0,
+	882, 0, 540, 541, 544, 0, 883, 0, 543, 545,
+	546, 0, 547, 0, 0, 0, 548, 549, 550, 551,
+	552, 553, 554, 0, 555, 557, 556, 0, 559, 884,
+	558, 0, 560, 561, 0, 0, 562, 563, 564, 565,
+	566, 567, 572, 0, 0, 568, 569, 570, 571, 573,
+	574, 0, 575, 576, 578, 581, 577, 579, 580, 582,
+	583, 596, 597, 598, 584, 585, 586, 587, 588, 589,
+	590, 591, 592, 593, 594, 595, 600, 0, 599, 0,
+	0, 601, 602, 603, 604, 605, 606, 612, 615, 617,
+	618, 613, 614, 616, 619, 620, 621, 623, 624, 609,
+	610, 611, 0, 622, 607, 0, 608, 0, 0, 625,
+	626, 627, 628, 0, 885, 629, 886, 632, 633, 0,
+	0, 634, 0, 635, 636, 0, 0, 638, 639, 4661,
+	0, 0, 641, 642, 887, 0, 643, 0, 888, 644,
+	645, 637, 646, 647, 648, 649, 650, 651, 652, 653,
+	654, 655, 656, 657, 0, 658, 659, 889, 660, 661,
+	662, 663, 664, 890, 665, 666, 667, 891, 668, 892,
+	669, 670, 671, 0, 672, 673, 674, 0, 675, 676,
+	677, 678, 679, 680, 681, 682, 683, 684, 893, 685,
+	686, 688, 687, 689, 690, 0, 691, 692, 0, 693,
+	694, 695, 0, 0, 0, 0, 0, 696, 697, 699,
+	0, 700, 701, 702, 703, 704, 705, 698, 706, 707,
+	708, 709, 710, 711, 712, 713, 0, 715, 716, 714,
+	717, 718, 0, 719, 720, 721, 722, 723, 894, 724,
+	0, 725, 726, 734, 735, 736, 727, 728, 730, 737,
+	729, 738, 739, 740, 741, 743, 742, 0, 745, 746,
+	744, 747, 748, 749, 750, 0, 751, 895, 752, 731,
+	732, 753, 754, 755, 0, 756, 757, 758, 759, 760,
+	761, 762, 763, 764, 896, 0, 766, 0, 765, 767,
+	768, 769, 770, 771, 772, 773, 775, 733, 776, 777,
+	778, 783, 784, 785, 897, 779, 780, 781, 782, 787,
+	898, 788, 789, 790, 791, 0, 792, 793, 0, 786,
+	774, 0, 794, 795, 796, 797, 798, 799, 800, 801,
+	802, 803, 0, 804, 899, 900, 901, 902, 0, 817,
+	0, 805, 807, 808, 809, 810, 903, 811, 812, 904,
+	0, 813, 814, 815, 816, 806, 819, 820, 818, 0,
+	0, 821, 822, 823, 824, 826, 828, 829, 830, 825,
+	827, 831, 0, 832, 0, 0, 833, 834, 835, 905,
+	906, 907, 0, 908, 838, 839, 836, 837, 840, 841,
+	844, 842, 843, 909, 847, 542, 848, 849, 850, 845,
+	846, 359, 0, 0, 0, 851, 852, 910, 853, 854,
+	855, 0, 0, 0, 0, 0, 0, 0, 367, 368,
+	370, 369, 371, 372, 373, 374, 0, 375, 376, 0,
+	0, 0, 0, 0, 856, 0, 0, 0, 378, 0,
+	377, 0, 379, 380, 381, 0, 382, 383, 384, 385,
+	386, 387, 388, 389, 390, 857, 391, 858, 0, 392,
+	859, 393, 860, 0, 861, 394, 395, 396, 397, 398,
+	399, 400, 401, 402, 403, 404, 0, 0, 0, 405,
+	862, 863, 864, 0, 406, 407, 408, 409, 865, 0,
+	0, 0, 410, 411, 412, 413, 414, 415, 416, 417,
+	0, 0, 419, 420, 421, 418, 422, 423, 0, 424,
+	0, 425, 426, 427, 428, 429, 0, 430, 431, 0,
+	432, 433, 434, 0, 435, 436, 437, 0, 0, 0,
+	0, 0, 0, 0, 438, 439, 440, 441, 442, 0,
+	443, 445, 866, 867, 0, 448, 450, 444, 446, 0,
+	449, 447, 451, 452, 0, 453, 454, 455, 456, 457,
+	0, 0, 0, 458, 459, 460, 461, 0, 462, 463,
+	464, 466, 465, 0, 467, 468, 469, 0, 470, 471,
+	868, 472, 473, 474, 476, 478, 475, 477, 479, 480,
+	481, 482, 483, 869, 870, 484, 485, 0, 0, 0,
+	0, 0, 0, 0, 486, 487, 488, 871, 0, 0,
+	0, 489, 0, 491, 495, 496, 492, 493, 494, 497,
+	0, 490, 498, 499, 0, 0, 500, 501, 502, 872,
+	873, 503, 504, 505, 506, 507, 508, 509, 510, 511,
+	0, 512, 513, 874, 0, 875, 514, 0, 515, 516,
+	517, 518, 519, 520, 521, 876, 877, 878, 630, 0,
+	522, 523, 524, 525, 0, 526, 527, 528, 529, 530,
+	531, 532, 0, 0, 0, 533, 534, 535, 536, 0,
+	0, 0, 0, 0, 879, 537, 631, 538, 539, 880,
+	881, 0, 882, 0, 540, 541, 544, 0, 883, 0,
+	543, 545, 546, 0, 547, 0, 0, 0, 548, 549,
+	550, 551, 552, 553, 554, 0, 555, 557, 556, 0,
+	559, 884, 558, 0, 560, 561, 0, 0, 562, 563,
+	564, 565, 566, 567, 572, 0, 0, 568, 569, 570,
+	571, 573, 574, 0, 575, 576, 578, 581, 577, 579,
+	580, 582, 583, 596, 597, 598, 584, 585, 586, 587,
+	588, 589, 590, 591, 592, 593, 594, 595, 600, 0,
+	599, 0, 0, 601, 602, 603, 604, 605, 606, 612,
+	615, 617, 618, 613, 614, 616, 619, 620, 621, 623,
+	624, 609, 610, 611, 0, 622, 607, 0, 608, 0,
+	0, 625, 626, 627, 628, 0, 885, 629, 886, 632,
+	633, 0, 0, 634, 0, 635, 636, 0, 0, 638,
+	639, 640, 0, 0, 641, 642, 887, 0, 643, 0,
+	888, 644, 645, 637, 646, 647, 648, 649, 650, 651,
+	652, 653, 654, 655, 656, 657, 0, 658, 659, 889,
+	660, 661, 662, 663, 664, 890, 665, 666, 667, 891,
+	668, 892, 669, 670, 671, 2960, 672, 673, 674, 0,
+	675, 676, 677, 678, 679, 680, 681, 682, 683, 684,
+	893, 685, 686, 688, 687, 689, 690, 0, 691, 692,
+	0, 693, 694, 695, 0, 0, 0, 0, 0, 696,
+	697, 699, 0, 700, 701, 702, 703, 704, 705, 698,
+	706, 707, 708, 709, 710, 711, 712, 713, 0, 715,
+	716, 714, 717, 718, 0, 1048, 720, 721, 722, 723,
+	894, 724, 0, 725, 726, 734, 735, 736, 727, 728,
+	730, 1047, 729, 738, 739, 740, 741, 4488, 742, 0,
+	745, 746, 744, 747, 748, 749, 750, 0, 751, 895,
+	752, 731, 732, 753, 754, 755, 0, 756, 757, 758,
+	759, 760, 761, 762, 763, 764, 896, 0, 766, 0,
+	765, 767, 768, 769, 770, 771, 772, 773, 775, 733,
+	776, 777, 778, 783, 784, 785, 897, 779, 780, 781,
+	782, 787, 898, 788, 789, 790, 791, 0, 792, 793,
+	0, 786, 774, 0, 794, 795, 796, 797, 798, 799,
+	800, 801, 802, 803, 0, 804, 1045, 900, 901, 902,
+	0, 817, 0, 805, 807, 808, 809, 810, 903, 811,
+	812, 904, 0, 813, 814, 815, 816, 806, 819, 820,
+	818, 0, 0, 821, 822, 823, 824, 826, 828, 829,
+	830, 825, 827, 831, 0, 832, 0, 0, 833, 834,
+	835, 905, 906, 907, 0, 908, 838, 839, 836, 837,
+	840, 841, 844, 842, 843, 909, 847, 542, 848, 849,
+	850, 845, 846, 3152, 0, 359, 0, 851, 852, 910,
+	853, 854, 855, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 367, 368, 370, 369, 371, 372, 373, 374,
+	0, 375, 376, 0, 0, 0, 0, 0, 856, 0,
+	0, 0, 378, 0, 377, 0, 379, 380, 381, 0,
+	382, 383, 384, 385, 386, 387, 388, 389, 390, 857,
+	391, 858, 0, 392, 859, 393, 860, 0, 861, 394,
+	395, 396, 397, 398, 399, 400, 401, 402, 403, 404,
+	0, 0, 0, 405, 862, 863, 864, 0, 406, 407,
+	408, 409, 865, 0, 0, 0, 410, 411, 412, 413,
+	414, 415, 416, 417, 0, 0, 419, 420, 421, 418,
+	422, 423, 0, 424, 0, 425, 426, 427, 428, 429,
+	0, 430, 431, 0, 432, 433, 434, 0, 435, 436,
+	437, 0, 0, 0, 0, 0, 0, 0, 438, 439,
+	440, 441, 442, 0, 443, 445, 866, 867, 0, 448,
+	450, 444, 446, 0, 449, 447, 451, 452, 0, 453,
+	454, 455, 456, 457, 0, 0, 0, 458, 459, 460,
+	461, 0, 462, 463, 464, 466, 465, 0, 467, 468,
+	469, 0, 470, 471, 868, 472, 473, 474, 476, 478,
+	475, 477, 479, 480, 481, 482, 483, 869, 870, 484,
+	485, 0, 0, 0, 0, 0, 0, 0, 486, 487,
+	488, 871, 0, 0, 0, 489, 0, 491, 495, 496,
+	492, 493, 494, 497, 0, 490, 498, 499, 0, 0,
+	500, 501, 502, 872, 873, 503, 504, 505, 506, 507,
+	508, 509, 510, 511, 0, 512, 513, 874, 0, 875,
+	514, 0, 515, 516, 517, 518, 519, 520, 521, 876,
+	877, 878, 630, 0, 522, 523, 524, 525, 0, 526,
+	527, 528, 529, 530, 531, 532, 0, 0, 0, 533,
+	534, 535, 536, 0, 0, 0, 0, 0, 879, 537,
+	631, 538, 539, 880, 881, 0, 882, 0, 540, 541,
+	544, 0, 883, 0, 543, 545, 546, 0, 547, 0,
+	0, 0, 548, 549, 550, 551, 552, 553, 554, 0,
+	555, 557, 556, 0, 559, 884, 558, 0, 560, 561,
+	0, 0, 562, 563, 564, 565, 566, 567, 572, 0,
+	0, 568, 569, 570, 571, 573, 574, 0, 575, 576,
+	578, 581, 577, 579, 580, 582, 583, 596, 597, 598,
+	584, 585, 586, 587, 588, 589, 590, 591, 592, 593,
+	594, 595, 600, 0, 599, 0, 0, 601, 602, 603,
+	604, 605, 606, 612, 615, 617, 618, 613, 614, 616,
+	619, 620, 621, 623, 624, 609, 610, 611, 0, 622,
+	607, 0, 608, 0, 0, 625, 626, 627, 628, 0,
+	885, 629, 886, 632, 633, 0, 0, 634, 0, 635,
+	636, 0, 0, 638, 639, 640, 0, 0, 641, 642,
+	887, 0, 643, 0, 888, 644, 645, 637, 646, 647,
+	648, 649, 650, 651, 652, 653, 654, 655, 656, 657,
+	0, 658, 659, 889, 660, 661, 662, 663, 664, 890,
+	665, 666, 667, 891, 668, 892, 669, 670, 671, 0,
+	672, 673, 674, 0, 675, 676, 677, 678, 679, 680,
+	681, 682, 683, 684, 893, 685, 686, 688, 687, 689,
+	690, 0, 691, 692, 0, 693, 694, 695, 0, 0,
+	0, 0, 0, 696, 697, 699, 0, 700, 701, 702,
+	703, 704, 705, 698, 706, 707, 708, 709, 710, 711,
+	712, 713, 0, 715, 716, 714, 717, 718, 0, 719,
+	720, 721, 722, 723, 894, 724, 0, 725, 726, 734,
+	735, 736, 727, 728, 730, 737, 729, 738, 739, 740,
+	741, 743, 742, 0, 745, 746, 744, 747, 748, 749,
+	750, 0, 751, 895, 752, 731, 732, 753, 754, 755,
+	0, 756, 757, 758, 759, 760, 761, 762, 763, 764,
+	896, 0, 766, 0, 765, 767, 768, 769, 770, 771,
+	772, 773, 775, 733, 776, 777, 778, 783, 784, 785,
+	897, 779, 780, 781, 782, 787, 898, 788, 789, 790,
+	791, 0, 792, 793, 0, 786, 774, 0, 794, 795,
+	796, 797, 798, 799, 800, 801, 802, 803, 0, 804,
+	899, 900, 901, 902, 0, 817, 0, 805, 807, 808,
+	809, 810, 903, 811, 812, 904, 0, 813, 814, 815,
+	816, 806, 819, 820, 818, 0, 0, 821, 822, 823,
+	824, 826, 828, 829, 830, 825, 827, 831, 0, 832,
+	0, 0, 833, 834, 835, 905, 906, 907, 0, 908,
+	838, 839, 836, 837, 840, 841, 844, 842, 843, 909,
+	847, 542, 848, 849, 850, 845, 846, 3077, 0, 359,
+	0, 851, 852, 910, 853, 854, 855, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 367, 368, 370, 369,
+	371, 372, 373, 374, 0, 375, 376, 0, 0, 0,
+	0, 0, 856, 0, 0, 0, 378, 0, 377, 0,
+	379, 380, 381, 0, 382, 383, 384, 385, 386, 387,
+	388, 389, 390, 857, 391, 858, 0, 392, 859, 393,
+	860, 0, 861, 394, 395, 396, 397, 398, 399, 400,
+	401, 402, 403, 404, 0, 0, 0, 405, 862, 863,
+	864, 0, 406, 407, 408, 409, 865, 0, 0, 0,
+	410, 411, 412, 413, 414, 415, 416, 417, 0, 0,
+	419, 420, 421, 418, 422, 423, 0, 424, 0, 425,
+	426, 427, 428, 429, 0, 430, 431, 0, 432, 433,
+	434, 0, 435, 436, 437, 0, 0, 0, 0, 0,
+	0, 0, 438, 439, 440, 441, 442, 0, 443, 445,
+	866, 867, 0, 448, 450, 444, 446, 0, 449, 447,
+	451, 452, 0, 453, 454, 455, 456, 457, 0, 0,
+	0, 458, 459, 460, 461, 0, 462, 463, 464, 466,
+	465, 0, 467, 468, 469, 0, 470, 471, 868, 472,
+	473, 474, 476, 478, 475, 477, 479, 480, 481, 482,
+	483, 869, 870, 484, 485, 0, 0, 0, 0, 0,
+	0, 0, 486, 487, 488, 871, 0, 0, 0, 489,
+	0, 491, 495, 496, 492, 493, 494, 497, 0, 490,
+	498, 499, 0, 0, 500, 501, 502, 872, 873, 503,
+	504, 505, 506, 507, 508, 509, 510, 511, 0, 512,
+	513, 874, 0, 875, 514, 0, 515, 516, 517, 518,
+	519, 520, 521, 876, 877, 878, 630, 0, 522, 523,
+	524, 525, 0, 526, 527, 528, 529, 530, 531, 532,
+	0, 0, 0, 533, 534, 535, 536, 0, 0, 0,
+	0, 0, 879, 537, 631, 538, 539, 880, 881, 0,
+	882, 0, 540, 541, 544, 0, 883, 0, 543, 545,
+	546, 0, 547, 0, 0, 0, 548, 549, 550, 551,
+	552, 553, 554, 0, 555, 557, 556, 0, 559, 884,
+	558, 0, 560, 561, 0, 0, 562, 563, 564, 565,
+	566, 567, 572, 0, 0, 568, 569, 570, 571, 573,
+	574, 0, 575, 576, 578, 581, 577, 579, 580, 582,
+	583, 596, 597, 598, 584, 585, 586, 587, 588, 589,
+	590, 591, 592, 593, 594, 595, 600, 0, 599, 0,
+	0, 601, 602, 603, 604, 605, 606, 612, 615, 617,
+	618, 613, 614, 616, 619, 620, 621, 623, 624, 609,
+	610, 611, 0, 622, 607, 0, 608, 0, 0, 625,
+	626, 627, 628, 0, 885, 629, 886, 632, 633, 0,
+	0, 634, 0, 635, 636, 0, 0, 638, 639, 640,
+	0, 0, 641, 642, 887, 0, 643, 0, 888, 644,
+	645, 637, 646, 647, 648, 649, 650, 651, 652, 653,
+	654, 655, 656, 657, 0, 658, 659, 889, 660, 661,
+	662, 663, 664, 890, 665, 666, 667, 891, 668, 892,
+	669, 670, 671, 0, 672, 673, 674, 0, 675, 676,
+	677, 678, 679, 680, 681, 682, 683, 684, 893, 685,
+	686, 688, 687, 689, 690, 0, 691, 692, 0, 693,
+	694, 695, 0, 0, 0, 0, 0, 696, 697, 699,
+	0, 700, 701, 702, 703, 704, 705, 698, 706, 707,
+	708, 709, 710, 711, 712, 713, 0, 715, 716, 714,
+	717, 718, 0, 719, 720, 721, 722, 723, 894, 724,
+	0, 725, 726, 734, 735, 736, 727, 728, 730, 737,
+	729, 738, 739, 740, 741, 743, 742, 0, 745, 746,
+	744, 747, 748, 749, 750, 0, 751, 895, 752, 731,
+	732, 753, 754, 755, 0, 756, 757, 758, 759, 760,
+	761, 762, 763, 764, 896, 0, 766, 0, 765, 767,
+	768, 769, 770, 771, 772, 773, 775, 733, 776, 777,
+	778, 783, 784, 785, 897, 779, 780, 781, 782, 787,
+	898, 788, 789, 790, 791, 0, 792, 793, 0, 786,
+	774, 0, 794, 795, 796, 797, 798, 799, 800, 801,
+	802, 803, 0, 804, 899, 900, 901, 902, 0, 817,
+	0, 805, 807, 808, 809, 810, 903, 811, 812, 904,
+	0, 813, 814, 815, 816, 806, 819, 820, 818, 0,
+	0, 821, 822, 823, 824, 826, 828, 829, 830, 825,
+	827, 831, 0, 832, 0, 0, 833, 834, 835, 905,
+	906, 907, 0, 908, 838, 839, 836, 837, 840, 841,
+	844, 842, 843, 909, 847, 542, 848, 849, 850, 845,
+	846, 359, 0, 0, 0, 851, 852, 910, 853, 854,
+	855, 0, 0, 0, 0, 0, 0, 0, 367, 368,
+	370, 369, 371, 372, 373, 374, 2735, 375, 376, 0,
+	0, 0, 0, 0, 856, 0, 0, 0, 378, 0,
+	377, 0, 379, 380, 381, 0, 382, 383, 384, 385,
+	386, 387, 388, 389, 390, 857, 391, 858, 0, 392,
+	859, 393, 860, 0, 861, 394, 395, 396, 397, 398,
+	399, 400, 401, 402, 403, 404, 0, 0, 0, 405,
+	862, 863, 864, 0, 406, 407, 408, 409, 865, 0,
+	0, 0, 410, 411, 412, 413, 414, 415, 416, 417,
+	0, 0, 419, 420, 421, 418, 422, 423, 0, 424,
+	0, 425, 426, 427, 428, 429, 0, 430, 431, 0,
+	432, 433, 434, 0, 435, 436, 437, 0, 0, 0,
+	0, 0, 0, 0, 438, 439, 440, 441, 442, 0,
+	443, 445, 866, 867, 0, 448, 450, 444, 446, 0,
+	449, 447, 451, 452, 0, 453, 454, 455, 456, 457,
+	0, 0, 0, 458, 459, 460, 461, 0, 462, 463,
+	464, 466, 465, 0, 467, 468, 469, 0, 470, 471,
+	868, 472, 473, 474, 476, 478, 475, 477, 479, 480,
+	481, 482, 483, 869, 870, 484, 485, 0, 0, 0,
+	0, 0, 0, 0, 486, 487, 488, 871, 0, 0,
+	0, 489, 0, 491, 495, 496, 492, 493, 494, 497,
+	0, 490, 498, 499, 0, 0, 500, 501, 502, 872,
+	873, 503, 504, 505, 506, 507, 508, 509, 510, 511,
+	0, 512, 513, 874, 0, 875, 514, 0, 515, 516,
+	517, 518, 519, 520, 521, 876, 877, 878, 630, 0,
+	522, 523, 524, 525, 0, 526, 527, 528, 529, 530,
+	531, 532, 0, 0, 0, 533, 534, 535, 536, 0,
+	0, 0, 0, 0, 879, 537, 631, 538, 539, 880,
+	881, 0, 882, 0, 540, 541, 544, 0, 883, 0,
+	543, 545, 546, 0, 547, 0, 0, 0, 548, 549,
+	550, 551, 552, 553, 554, 0, 555, 557, 556, 0,
+	559, 884, 558, 0, 560, 561, 0, 0, 562, 563,
+	564, 565, 566, 567, 572, 0, 0, 568, 569, 570,
+	571, 573, 574, 0, 575, 576, 578, 581, 577, 579,
+	580, 582, 583, 596, 597, 598, 584, 585, 586, 587,
+	588, 589, 590, 591, 592, 593, 594, 595, 600, 0,
+	599, 0, 0, 601, 602, 603, 604, 605, 606, 612,
+	615, 617, 618, 613, 614, 616, 619, 620, 621, 623,
+	624, 609, 610, 611, 0, 622, 607, 0, 608, 0,
+	0, 625, 626, 627, 628, 0, 885, 629, 886, 632,
+	633, 0, 0, 634, 0, 635, 636, 0, 0, 638,
+	639, 640, 0, 0, 641, 642, 887, 0, 643, 0,
+	888, 644, 645, 637, 646, 647, 648, 649, 650, 651,
+	652, 653, 654, 655, 656, 657, 0, 658, 659, 889,
+	660, 661, 662, 663, 664, 890, 665, 666, 667, 891,
+	668, 892, 669, 670, 671, 0, 672, 673, 674, 0,
+	675, 676, 677, 678, 679, 680, 681, 682, 683, 684,
+	893, 685, 686, 688, 687, 689, 690, 0, 691, 692,
+	0, 693, 694, 695, 0, 0, 0, 0, 0, 696,
+	697, 699, 0, 700, 701, 702, 703, 704, 705, 698,
+	706, 707, 708, 709, 710, 711, 712, 713, 0, 715,
+	716, 714, 717, 718, 0, 719, 720, 721, 722, 723,
+	894, 724, 0, 725, 726, 734, 735, 736, 727, 728,
+	730, 737, 729, 738, 739, 740, 741, 743, 742, 0,
+	745, 746, 744, 747, 748, 749, 750, 0, 751, 895,
+	752, 731, 732, 753, 754, 755, 0, 756, 757, 758,
+	759, 760, 761, 762, 763, 764, 896, 0, 766, 0,
+	765, 767, 768, 769, 770, 771, 772, 773, 775, 733,
+	776, 777, 778, 783, 784, 785, 897, 779, 780, 781,
+	782, 787, 898, 788, 789, 790, 791, 0, 792, 793,
+	0, 786, 774, 0, 794, 795, 796, 797, 798, 799,
+	800, 801, 802, 803, 0, 804, 899, 900, 901, 902,
+	0, 817, 0, 805, 807, 808, 809, 810, 903, 811,
+	812, 904, 0, 813, 814, 815, 816, 806, 819, 820,
+	818, 0, 0, 821, 822, 823, 824, 826, 828, 829,
+	830, 825, 827, 831, 0, 832, 0, 0, 833, 834,
+	835, 905, 906, 907, 0, 908, 838, 839, 836, 837,
+	840, 841, 844, 842, 843, 909, 847, 542, 848, 849,
+	850, 845, 846, 2263, 0, 359, 0, 851, 852, 910,
+	853, 854, 855, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 367, 368, 370, 369, 371, 372, 373, 374,
+	0, 375, 376, 0, 0, 0, 0, 0, 856, 0,
+	0, 0, 378, 0, 377, 0, 379, 380, 381, 0,
+	382, 383, 384, 385, 386, 387, 388, 389, 390, 857,
+	391, 858, 0, 392, 859, 393, 860, 0, 861, 394,
+	395, 396, 397, 398, 399, 400, 401, 402, 403, 404,
+	0, 0, 0, 405, 862, 863, 864, 0, 406, 407,
+	408, 409, 865, 0, 0, 0, 410, 411, 412, 413,
+	414, 415, 416, 417, 0, 0, 419, 420, 421, 418,
+	422, 423, 0, 424, 0, 425, 426, 427, 428, 429,
+	0, 430, 431, 0, 432, 433, 434, 0, 435, 436,
+	437, 0, 0, 0, 0, 0, 0, 0, 438, 439,
+	440, 441, 442, 0, 443, 445, 866, 867, 0, 448,
+	450, 444, 446, 0, 449, 447, 451, 452, 0, 453,
+	454, 455, 456, 457, 0, 0, 0, 458, 459, 460,
+	461, 0, 462, 463, 464, 466, 465, 0, 467, 468,
+	469, 0, 470, 471, 868, 472, 473, 474, 476, 478,
+	475, 477, 479, 480, 481, 482, 483, 869, 870, 484,
+	485, 0, 0, 0, 0, 0, 0, 0, 486, 487,
+	488, 871, 0, 0, 0, 489, 0, 491, 495, 496,
+	492, 493, 494, 497, 0, 490, 498, 499, 0, 0,
+	500, 501, 502, 872, 873, 503, 504, 505, 506, 507,
+	508, 509, 510, 511, 0, 512, 513, 874, 0, 875,
+	514, 0, 515, 516, 517, 518, 519, 520, 521, 876,
+	877, 878, 630, 0, 522, 523, 524, 525, 0, 526,
+	527, 528, 529, 530, 531, 532, 0, 0, 0, 533,
+	534, 535, 536, 0, 0, 0, 0, 0, 879, 537,
+	631, 538, 539, 880, 881, 0, 882, 0, 540, 541,
+	544, 0, 883, 0, 543, 545, 546, 0, 547, 0,
+	0, 0, 548, 549, 550, 551, 552, 553, 554, 0,
+	555, 557, 556, 0, 559, 884, 558, 0, 560, 561,
+	0, 0, 562, 563, 564, 565, 566, 567, 572, 0,
+	0, 568, 569, 570, 571, 573, 574, 0, 575, 576,
+	578, 581, 577, 579, 580, 582, 583, 596, 597, 598,
+	584, 585, 586, 587, 588, 589, 590, 591, 592, 593,
+	594, 595, 600, 0, 599, 0, 0, 601, 602, 603,
+	604, 605, 606, 612, 615, 617, 618, 613, 614, 616,
+	619, 620, 621, 623, 624, 609, 610, 611, 0, 622,
+	607, 0, 608, 0, 0, 625, 626, 627, 628, 0,
+	885, 629, 886, 632, 633, 0, 0, 634, 0, 635,
+	636, 0, 0, 638, 639, 640, 0, 0, 641, 642,
+	887, 0, 643, 0, 888, 644, 645, 637, 646, 647,
+	648, 649, 650, 651, 652, 653, 654, 655, 656, 657,
+	0, 658, 659, 889, 660, 661, 662, 663, 664, 890,
+	665, 666, 667, 891, 668, 892, 669, 670, 671, 0,
+	672, 673, 674, 0, 675, 676, 677, 678, 679, 680,
+	681, 682, 683, 684, 893, 685, 686, 688, 687, 689,
+	690, 0, 691, 692, 0, 693, 694, 695, 0, 0,
+	0, 0, 0, 696, 697, 699, 0, 700, 701, 702,
+	703, 704, 705, 698, 706, 707, 708, 709, 710, 711,
+	712, 713, 0, 715, 716, 714, 717, 718, 0, 719,
+	720, 721, 722, 723, 894, 724, 0, 725, 726, 734,
+	735, 736, 727, 728, 730, 737, 729, 738, 739, 740,
+	741, 743, 742, 0, 745, 746, 744, 747, 748, 749,
+	750, 0, 751, 895, 752, 731, 732, 753, 754, 755,
+	0, 756, 757, 758, 759, 760, 761, 762, 763, 764,
+	896, 0, 766, 0, 765, 767, 768, 769, 770, 771,
+	772, 773, 775, 733, 776, 777, 778, 783, 784, 785,
+	897, 779, 780, 781, 782, 787, 898, 788, 789, 790,
+	791, 0, 792, 793, 0, 786, 774, 0, 794, 795,
+	796, 797, 798, 799, 800, 801, 802, 803, 0, 804,
+	899, 900, 901, 902, 0, 817, 0, 805, 807, 808,
+	809, 810, 903, 811, 812, 904, 0, 813, 814, 815,
+	816, 806, 819, 820, 818, 0, 0, 821, 822, 823,
+	824, 826, 828, 829, 830, 825, 827, 831, 0, 832,
+	0, 0, 833, 834, 835, 905, 906, 907, 0, 908,
+	838, 839, 836, 837, 840, 841, 844, 842, 843, 909,
+	847, 542, 848, 849, 850, 845, 846, 2257, 0, 359,
+	0, 851, 852, 910, 853, 854, 855, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 367, 368, 370, 369,
+	371, 372, 373, 374, 0, 375, 376, 0, 0, 0,
+	0, 0, 856, 0, 0, 0, 378, 0, 377, 0,
+	379, 380, 381, 0, 382, 383, 384, 385, 386, 387,
+	388, 389, 390, 857, 391, 858, 0, 392, 859, 393,
+	860, 0, 861, 394, 395, 396, 397, 398, 399, 400,
+	401, 402, 403, 404, 0, 0, 0, 405, 862, 863,
+	864, 0, 406, 407, 408, 409, 865, 0, 0, 0,
+	410, 411, 412, 413, 414, 415, 416, 417, 0, 0,
+	419, 420, 421, 418, 422, 423, 0, 424, 0, 425,
+	426, 427, 428, 429, 0, 430, 431, 0, 432, 433,
+	434, 0, 435, 436, 437, 0, 0, 0, 0, 0,
+	0, 0, 438, 439, 440, 441, 442, 0, 443, 445,
+	866, 867, 0, 448, 450, 444, 446, 0, 449, 447,
+	451, 452, 0, 453, 454, 455, 456, 457, 0, 0,
+	0, 458, 459, 460, 461, 0, 462, 463, 464, 466,
+	465, 0, 467, 468, 469, 0, 470, 471, 868, 472,
+	473, 474, 476, 478, 475, 477, 479, 480, 481, 482,
+	483, 869, 870, 484, 485, 0, 0, 0, 0, 0,
+	0, 0, 486, 487, 488, 871, 0, 0, 0, 489,
+	0, 491, 495, 496, 492, 493, 494, 497, 0, 490,
+	498, 499, 0, 0, 500, 501, 502, 872, 873, 503,
+	504, 505, 506, 507, 508, 509, 510, 511, 0, 512,
+	513, 874, 0, 875, 514, 0, 515, 516, 517, 518,
+	519, 520, 521, 876, 877, 878, 630, 0, 522, 523,
+	524, 525, 0, 526, 527, 528, 529, 530, 531, 532,
+	0, 0, 0, 533, 534, 535, 536, 0, 0, 0,
+	0, 0, 879, 537, 631, 538, 539, 880, 881, 0,
+	882, 0, 540, 541, 544, 0, 883, 0, 543, 545,
+	546, 0, 547, 0, 0, 0, 548, 549, 550, 551,
+	552, 553, 554, 0, 555, 557, 556, 0, 559, 884,
+	558, 0, 560, 561, 0, 0, 562, 563, 564, 565,
+	566, 567, 572, 0, 0, 568, 569, 570, 571, 573,
+	574, 0, 575, 576, 578, 581, 577, 579, 580, 582,
+	583, 596, 597, 598, 584, 585, 586, 587, 588, 589,
+	590, 591, 592, 593, 594, 595, 600, 0, 599, 0,
+	0, 601, 602, 603, 604, 605, 606, 612, 615, 617,
+	618, 613, 614, 616, 619, 620, 621, 623, 624, 609,
+	610, 611, 0, 622, 607, 0, 608, 0, 0, 625,
+	626, 627, 628, 0, 885, 629, 886, 632, 633, 0,
+	0, 634, 0, 635, 636, 0, 0, 638, 639, 640,
+	0, 0, 641, 642, 887, 0, 643, 0, 888, 644,
+	645, 637, 646, 647, 648, 649, 650, 651, 652, 653,
+	654, 655, 656, 657, 0, 658, 659, 889, 660, 661,
+	662, 663, 664, 890, 665, 666, 667, 891, 668, 892,
+	669, 670, 671, 0, 672, 673, 674, 0, 675, 676,
+	677, 678, 679, 680, 681, 682, 683, 684, 893, 685,
+	686, 688, 687, 689, 690, 0, 691, 692, 0, 693,
+	694, 695, 0, 0, 0, 0, 0, 696, 697, 699,
+	0, 700, 701, 702, 703, 704, 705, 698, 706, 707,
+	708, 709, 710, 711, 712, 713, 0, 715, 716, 714,
+	717, 718, 0, 719, 720, 721, 722, 723, 894, 724,
+	0, 725, 726, 734, 735, 736, 727, 728, 730, 737,
+	729, 738, 739, 740, 741, 743, 742, 0, 745, 746,
+	744, 747, 748, 749, 750, 0, 751, 895, 752, 731,
+	732, 753, 754, 755, 0, 756, 757, 758, 759, 760,
+	761, 762, 763, 764, 896, 0, 766, 0, 765, 767,
+	768, 769, 770, 771, 772, 773, 775, 733, 776, 777,
+	778, 783, 784, 785, 897, 779, 780, 781, 782, 787,
+	898, 788, 789, 790, 791, 0, 792, 793, 0, 786,
+	774, 0, 794, 795, 796, 797, 798, 799, 800, 801,
+	802, 803, 0, 804, 899, 900, 901, 902, 0, 817,
+	0, 805, 807, 808, 809, 810, 903, 811, 812, 904,
+	0, 813, 814, 815, 816, 806, 819, 820, 818, 0,
+	0, 821, 822, 823, 824, 826, 828, 829, 830, 825,
+	827, 831, 0, 832, 0, 0, 833, 834, 835, 905,
+	906, 907, 0, 908, 838, 839, 836, 837, 840, 841,
+	844, 842, 843, 909, 847, 542, 848, 849, 850, 845,
+	846, 1039, 0, 359, 0, 851, 852, 910, 853, 854,
+	855, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	367, 368, 370, 369, 371, 372, 373, 374, 0, 375,
+	376, 0, 0, 0, 0, 0, 856, 0, 0, 0,
+	378, 0, 377, 0, 379, 380, 381, 0, 382, 383,
+	384, 385, 386, 387, 388, 389, 390, 857, 391, 858,
+	0, 392, 859, 393, 860, 0, 861, 394, 395, 396,
+	397, 398, 399, 400, 401, 402, 403, 404, 0, 0,
+	0, 405, 862, 863, 864, 0, 406, 407, 1035, 409,
+	865, 0, 0, 0, 410, 411, 412, 413, 414, 415,
+	416, 417, 0, 0, 419, 420, 421, 418, 422, 423,
+	0, 424, 0, 425, 426, 427, 428, 429, 0, 430,
+	431, 0, 432, 433, 434, 0, 435, 436, 437, 0,
+	0, 0, 0, 0, 0, 0, 438, 439, 440, 441,
+	442, 0, 443, 445, 866, 867, 0, 448, 450, 444,
+	446, 0, 449, 447, 451, 452, 0, 453, 454, 455,
+	456, 457, 0, 0, 0, 458, 459, 460, 461, 0,
+	462, 463, 464, 466, 465, 0, 467, 468, 469, 0,
+	470, 471, 868, 472, 473, 474, 476, 478, 475, 477,
+	479, 480, 481, 482, 483, 869, 870, 484, 485, 0,
+	0, 0, 0, 0, 0, 0, 486, 487, 488, 871,
+	0, 0, 0, 489, 0, 491, 495, 496, 492, 493,
+	494, 497, 0, 490, 498, 499, 0, 0, 500, 501,
+	502, 872, 873, 503, 504, 505, 506, 507, 508, 509,
+	510, 511, 0, 512, 513, 874, 0, 875, 514, 0,
+	515, 516, 517, 518, 519, 520, 521, 876, 877, 878,
+	630, 0, 522, 523, 524, 525, 0, 526, 527, 528,
+	529, 530, 531, 532, 0, 0, 0, 533, 534, 535,
+	536, 0, 0, 0, 0, 0, 879, 537, 631, 538,
+	539, 880, 881, 0, 882, 0, 540, 541, 544, 0,
+	883, 0, 543, 545, 546, 0, 547, 0, 0, 0,
+	548, 549, 550, 551, 552, 553, 554, 0, 555, 557,
+	556, 0, 559, 884, 558, 0, 560, 561, 0, 0,
+	562, 563, 564, 565, 566, 1040, 572, 0, 0, 568,
+	569, 570, 571, 573, 574, 0, 575, 576, 578, 581,
+	577, 579, 580, 582, 583, 596, 597, 598, 584, 585,
+	586, 587, 588, 589, 590, 591, 592, 593, 594, 595,
+	600, 0, 1049, 0, 0, 601, 602, 603, 604, 605,
+	606, 612, 615, 617, 618, 613, 614, 616, 619, 620,
+	621, 623, 624, 609, 610, 611, 0, 622, 607, 0,
+	608, 0, 0, 625, 626, 627, 628, 0, 885, 629,
+	886, 632, 633, 0, 0, 634, 0, 635, 636, 0,
+	0, 638, 639, 640, 0, 0, 641, 642, 887, 0,
+	643, 0, 888, 644, 645, 637, 646, 647, 648, 649,
+	650, 651, 652, 653, 654, 655, 656, 657, 0, 658,
+	659, 889, 660, 661, 662, 663, 664, 890, 665, 666,
+	667, 891, 668, 892, 669, 670, 671, 0, 672, 673,
+	674, 0, 675, 676, 677, 678, 679, 680, 681, 682,
+	683, 684, 893, 685, 686, 688, 687, 689, 690, 0,
+	691, 692, 0, 693, 694, 695, 0, 0, 0, 0,
+	0, 696, 697, 699, 0, 700, 701, 702, 703, 704,
+	705, 698, 706, 707, 708, 709, 710, 711, 712, 713,
+	0, 715, 716, 714, 717, 718, 0, 1048, 720, 721,
+	722, 723, 894, 724, 0, 725, 726, 734, 735, 736,
+	727, 728, 730, 1047, 729, 738, 739, 740, 741, 743,
+	742, 0, 745, 746, 744, 747, 748, 2242, 750, 0,
+	751, 895, 752, 731, 732, 753, 754, 755, 0, 756,
+	757, 758, 759, 760, 761, 762, 763, 764, 896, 0,
+	766, 0, 765, 767, 768, 769, 770, 771, 772, 773,
+	775, 733, 776, 777, 778, 783, 784, 785, 897, 779,
+	780, 781, 782, 787, 898, 788, 789, 790, 791, 0,
+	792, 793, 0, 786, 774, 0, 794, 795, 796, 797,
+	798, 799, 800, 801, 802, 803, 0, 804, 1045, 900,
+	901, 902, 0, 817, 0, 805, 807, 808, 809, 810,
+	903, 811, 812, 904, 0, 813, 814, 815, 816, 806,
+	819, 820, 818, 0, 0, 821, 822, 823, 824, 826,
+	828, 829, 830, 825, 827, 831, 0, 832, 0, 0,
+	833, 834, 835, 905, 906, 907, 0, 908, 838, 839,
+	836, 837, 840, 841, 844, 842, 843, 909, 847, 542,
+	848, 849, 850, 845, 846, 2213, 0, 359, 0, 851,
+	852, 910, 853, 854, 855, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 367, 368, 370, 369, 371, 372,
+	373, 374, 0, 375, 376, 0, 0, 0, 0, 0,
+	856, 0, 0, 0, 378, 0, 377, 0, 379, 380,
+	381, 0, 382, 383, 384, 385, 386, 387, 388, 389,
+	390, 857, 391, 858, 0, 392, 859, 393, 860, 0,
+	861, 394, 395, 396, 397, 398, 399, 400, 401, 402,
+	403, 404, 0, 0, 0, 405, 862, 863, 864, 0,
+	406, 407, 408, 409, 865, 0, 0, 0, 410, 411,
+	412, 413, 414, 415, 416, 417, 0, 0, 419, 420,
+	421, 418, 422, 423, 0, 424, 0, 425, 426, 427,
+	428, 429, 0, 430, 431, 0, 432, 433, 434, 0,
+	435, 436, 437, 0, 0, 0, 0, 0, 0, 0,
+	438, 439, 440, 441, 442, 0, 443, 445, 866, 867,
+	0, 448, 450, 444, 446, 0, 449, 447, 451, 452,
+	0, 453, 454, 455, 456, 457, 0, 0, 0, 458,
+	459, 460, 461, 0, 462, 463, 464, 466, 465, 0,
+	467, 468, 469, 0, 470, 471, 868, 472, 473, 474,
+	476, 478, 475, 477, 479, 480, 481, 482, 483, 869,
+	870, 484, 485, 0, 0, 0, 0, 0, 0, 0,
+	486, 487, 488, 871, 0, 0, 0, 489, 0, 491,
+	495, 496, 492, 493, 494, 497, 0, 490, 498, 499,
+	0, 0, 500, 501, 502, 872, 873, 503, 504, 505,
+	506, 507, 508, 509, 510, 511, 0, 512, 513, 874,
+	0, 875, 514, 0, 515, 516, 517, 518, 519, 520,
+	521, 2212, 877, 878, 630, 0, 522, 523, 524, 525,
+	0, 526, 527, 528, 529, 530, 531, 532, 0, 0,
+	0, 533, 534, 535, 536, 0, 0, 0, 0, 0,
+	879, 537, 631, 538, 539, 880, 881, 0, 882, 0,
+	540, 541, 544, 0, 883, 0, 543, 545, 546, 0,
+	547, 0, 0, 0, 548, 549, 550, 551, 552, 553,
+	554, 0, 555, 557, 556, 0, 559, 884, 558, 0,
+	560, 561, 0, 0, 562, 563, 564, 565, 566, 567,
+	572, 0, 0, 568, 569, 570, 571, 573, 574, 0,
+	575, 576, 578, 581, 577, 579, 580, 582, 583, 596,
+	597, 598, 584, 585, 586, 587, 588, 589, 590, 591,
+	592, 593, 594, 595, 600, 0, 599, 0, 0, 601,
+	602, 603, 604, 605, 606, 612, 615, 617, 618, 613,
+	614, 616, 619, 620, 621, 623, 624, 609, 610, 611,
+	0, 622, 607, 0, 608, 0, 0, 625, 626, 627,
+	628, 0, 885, 629, 886, 632, 633, 0, 0, 634,
+	0, 635, 636, 0, 0, 638, 639, 640, 0, 0,
+	641, 642, 887, 0, 643, 0, 888, 644, 645, 637,
+	646, 647, 648, 649, 650, 651, 652, 653, 654, 655,
+	656, 657, 0, 658, 659, 889, 660, 661, 662, 663,
+	664, 890, 665, 666, 667, 891, 668, 892, 669, 670,
+	671, 0, 672, 673, 674, 0, 675, 676, 677, 678,
+	679, 680, 681, 682, 683, 684, 893, 685, 686, 688,
+	687, 689, 690, 0, 691, 692, 0, 693, 694, 695,
+	0, 0, 0, 0, 0, 696, 697, 699, 0, 700,
+	701, 702, 703, 704, 705, 698, 706, 707, 708, 709,
+	710, 711, 712, 713, 0, 715, 716, 714, 717, 718,
+	0, 719, 720, 721, 722, 723, 894, 724, 0, 725,
+	726, 734, 735, 736, 727, 728, 730, 737, 729, 738,
+	739, 740, 741, 743, 742, 0, 745, 746, 744, 747,
+	748, 749, 750, 0, 751, 895, 752, 731, 732, 753,
+	754, 755, 0, 756, 757, 758, 759, 760, 761, 762,
+	763, 764, 896, 0, 766, 0, 765, 767, 768, 769,
+	770, 771, 772, 773, 775, 733, 776, 777, 778, 783,
+	784, 785, 897, 779, 780, 781, 782, 787, 898, 788,
+	789, 790, 791, 0, 792, 793, 0, 786, 774, 0,
+	794, 795, 796, 797, 798, 799, 800, 801, 802, 803,
+	0, 804, 899, 900, 901, 902, 0, 817, 0, 805,
+	807, 808, 809, 810, 903, 811, 812, 904, 0, 813,
+	814, 815, 816, 806, 819, 820, 818, 0, 0, 821,
+	822, 823, 824, 826, 828, 829, 830, 825, 827, 831,
+	0, 832, 0, 0, 833, 834, 835, 905, 906, 907,
+	0, 908, 838, 839, 836, 837, 840, 841, 844, 842,
+	843, 909, 847, 542, 848, 849, 850, 845, 846, 2195,
+	0, 359, 0, 851, 852, 910, 853, 854, 855, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 367, 368,
+	370, 369, 371, 372, 373, 374, 0, 375, 376, 0,
+	0, 0, 0, 0, 856, 0, 0, 0, 378, 0,
+	377, 0, 379, 380, 381, 0, 382, 383, 384, 385,
+	386, 387, 388, 389, 390, 857, 391, 858, 0, 392,
+	859, 393, 860, 0, 861, 394, 395, 396, 397, 398,
+	399, 400, 401, 402, 403, 404, 0, 0, 0, 405,
+	862, 863, 864, 0, 406, 407, 408, 409, 865, 0,
+	0, 0, 410, 411, 412, 413, 414, 415, 416, 417,
+	0, 0, 419, 420, 421, 418, 422, 423, 0, 424,
+	0, 425, 426, 427, 428, 429, 0, 430, 431, 0,
+	432, 433, 434, 0, 435, 436, 437, 0, 0, 0,
+	0, 0, 0, 0, 438, 439, 440, 441, 442, 0,
+	443, 445, 866, 867, 0, 448, 450, 444, 446, 0,
+	449, 447, 451, 452, 0, 453, 454, 455, 456, 457,
+	0, 0, 0, 458, 459, 460, 461, 0, 462, 463,
+	464, 466, 465, 0, 467, 468, 469, 0, 470, 471,
+	868, 472, 473, 474, 476, 478, 475, 477, 479, 480,
+	481, 482, 483, 869, 870, 484, 485, 0, 0, 0,
+	0, 0, 0, 0, 486, 487, 488, 871, 0, 0,
+	0, 489, 0, 491, 495, 496, 492, 493, 494, 497,
+	0, 490, 498, 499, 0, 0, 500, 501, 502, 872,
+	873, 503, 504, 505, 506, 507, 508, 509, 510, 511,
+	0, 512, 513, 874, 0, 875, 514, 0, 515, 516,
+	517, 518, 519, 520, 521, 2193, 877, 878, 630, 0,
+	522, 523, 524, 525, 0, 526, 527, 528, 529, 530,
+	531, 532, 0, 0, 0, 533, 534, 535, 536, 0,
+	0, 0, 0, 0, 879, 537, 631, 538, 539, 880,
+	881, 0, 882, 0, 540, 541, 544, 0, 883, 0,
+	543, 545, 546, 0, 547, 0, 0, 0, 548, 549,
+	550, 551, 552, 553, 554, 0, 555, 557, 556, 0,
+	559, 884, 558, 0, 560, 561, 0, 0, 562, 563,
+	564, 565, 566, 567, 572, 0, 0, 568, 569, 570,
+	571, 573, 574, 0, 575, 576, 578, 581, 577, 579,
+	580, 582, 583, 596, 597, 598, 584, 585, 586, 587,
+	588, 589, 590, 591, 592, 593, 594, 595, 600, 0,
+	599, 0, 0, 601, 602, 603, 604, 605, 606, 612,
+	615, 617, 618, 613, 614, 616, 619, 620, 621, 623,
+	624, 609, 610, 611, 0, 622, 607, 0, 608, 0,
+	0, 625, 626, 627, 628, 0, 885, 629, 886, 632,
+	633, 0, 0, 634, 0, 635, 636, 0, 0, 638,
+	639, 640, 0, 0, 641, 642, 887, 0, 643, 0,
+	888, 644, 645, 637, 646, 647, 648, 649, 650, 651,
+	652, 653, 654, 655, 656, 657, 0, 658, 659, 889,
+	660, 661, 662, 663, 664, 890, 665, 666, 667, 891,
+	668, 892, 669, 670, 671, 0, 672, 673, 674, 0,
+	675, 676, 677, 678, 679, 680, 681, 682, 683, 684,
+	893, 685, 686, 688, 687, 689, 690, 0, 691, 692,
+	0, 693, 694, 695, 0, 0, 0, 0, 0, 696,
+	697, 699, 0, 700, 701, 702, 703, 704, 705, 698,
+	706, 707, 708, 709, 710, 711, 712, 713, 0, 715,
+	716, 714, 717, 718, 0, 719, 720, 721, 722, 723,
+	894, 724, 0, 725, 726, 734, 735, 736, 727, 728,
+	730, 737, 729, 738, 739, 740, 741, 743, 742, 0,
+	745, 746, 744, 747, 748, 749, 750, 0, 751, 895,
+	752, 731, 732, 753, 754, 755, 0, 756, 757, 758,
+	759, 760, 761, 762, 763, 764, 896, 0, 766, 0,
+	765, 767, 768, 769, 770, 771, 772, 773, 775, 733,
+	776, 777, 778, 783, 784, 785, 897, 779, 780, 781,
+	782, 787, 898, 788, 789, 790, 791, 0, 792, 793,
+	0, 786, 774, 0, 794, 795, 796, 797, 798, 799,
+	800, 801, 802, 803, 0, 804, 899, 900, 901, 902,
+	0, 817, 0, 805, 807, 808, 809, 810, 903, 811,
+	812, 904, 0, 813, 814, 815, 816, 806, 819, 820,
+	818, 0, 0, 821, 822, 823, 824, 826, 828, 829,
+	830, 825, 827, 831, 0, 832, 0, 0, 833, 834,
+	835, 905, 906, 907, 0, 908, 838, 839, 836, 837,
+	840, 841, 844, 842, 843, 909, 847, 542, 848, 849,
+	850, 845, 846, 2187, 0, 359, 0, 851, 852, 910,
+	853, 854, 855, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 367, 368, 370, 369, 371, 372, 373, 374,
+	0, 375, 376, 0, 0, 0, 0, 0, 856, 0,
+	0, 0, 378, 0, 377, 0, 379, 380, 381, 0,
+	382, 383, 384, 385, 386, 387, 388, 389, 390, 857,
+	391, 858, 0, 392, 859, 393, 860, 0, 861, 394,
+	395, 396, 397, 398, 399, 400, 401, 402, 403, 404,
+	0, 0, 0, 405, 862, 863, 864, 0, 406, 407,
+	408, 409, 865, 0, 0, 0, 410, 411, 412, 413,
+	414, 415, 416, 417, 0, 0, 419, 420, 421, 418,
+	422, 423, 0, 424, 0, 425, 426, 427, 428, 429,
+	0, 430, 431, 0, 432, 433, 434, 0, 435, 436,
+	437, 0, 0, 0, 0, 0, 0, 0, 438, 439,
+	440, 441, 442, 0, 443, 445, 866, 867, 0, 448,
+	450, 444, 446, 0, 449, 447, 451, 452, 0, 453,
+	454, 455, 456, 457, 0, 0, 0, 458, 459, 460,
+	461, 0, 462, 463, 464, 466, 465, 0, 467, 468,
+	469, 0, 470, 471, 868, 472, 473, 474, 476, 478,
+	475, 477, 479, 480, 481, 482, 483, 869, 870, 484,
+	485, 0, 0, 0, 0, 0, 0, 0, 486, 487,
+	488, 871, 0, 0, 0, 489, 0, 491, 495, 496,
+	492, 493, 494, 497, 0, 490, 498, 499, 0, 0,
+	500, 501, 502, 872, 873, 503, 504, 505, 506, 507,
+	508, 509, 510, 511, 0, 512, 513, 874, 0, 875,
+	514, 0, 515, 516, 517, 518, 519, 520, 521, 876,
+	877, 878, 630, 0, 522, 523, 524, 525, 0, 526,
+	527, 528, 529, 530, 531, 532, 0, 0, 0, 533,
+	534, 535, 536, 0, 0, 0, 0, 0, 879, 537,
+	631, 538, 539, 880, 881, 0, 882, 0, 540, 541,
+	544, 0, 883, 0, 543, 545, 546, 0, 547, 0,
+	0, 0, 548, 549, 550, 551, 552, 553, 554, 0,
+	555, 557, 556, 0, 559, 884, 558, 0, 560, 561,
+	0, 0, 562, 563, 564, 565, 566, 567, 572, 0,
+	0, 568, 569, 570, 571, 573, 574, 0, 575, 576,
+	578, 581, 577, 579, 580, 582, 583, 596, 597, 598,
+	584, 585, 586, 587, 588, 589, 590, 591, 592, 593,
+	594, 595, 600, 0, 599, 0, 0, 601, 602, 603,
+	604, 605, 606, 612, 615, 617, 618, 613, 614, 616,
+	619, 620, 621, 623, 624, 609, 610, 611, 0, 622,
+	607, 0, 608, 0, 0, 625, 626, 627, 628, 0,
+	885, 629, 886, 632, 633, 0, 0, 634, 0, 635,
+	636, 0, 0, 638, 639, 640, 0, 0, 641, 642,
+	887, 0, 643, 0, 888, 644, 645, 637, 646, 647,
+	648, 649, 650, 651, 652, 653, 654, 655, 656, 657,
+	0, 658, 659, 889, 660, 661, 662, 663, 664, 890,
+	665, 666, 667, 891, 668, 892, 669, 670, 671, 0,
+	672, 673, 674, 0, 675, 676, 677, 678, 679, 680,
+	681, 682, 683, 684, 893, 685, 686, 688, 687, 689,
+	690, 0, 691, 692, 0, 693, 694, 695, 0, 0,
+	0, 0, 0, 696, 697, 699, 0, 700, 701, 702,
+	703, 704, 705, 698, 706, 707, 708, 709, 710, 711,
+	712, 713, 0, 715, 716, 714, 717, 718, 0, 719,
+	720, 721, 722, 723, 894, 724, 0, 725, 726, 734,
+	735, 736, 727, 728, 730, 737, 729, 738, 739, 740,
+	741, 743, 742, 0, 745, 746, 744, 747, 748, 749,
+	750, 0, 751, 895, 752, 731, 732, 753, 754, 755,
+	0, 756, 757, 758, 759, 760, 761, 762, 763, 764,
+	896, 0, 766, 0, 765, 767, 768, 769, 770, 771,
+	772, 773, 775, 733, 776, 777, 778, 783, 784, 785,
+	897, 779, 780, 781, 782, 787, 898, 788, 789, 790,
+	791, 0, 792, 793, 0, 786, 774, 0, 794, 795,
+	796, 797, 798, 799, 800, 801, 802, 803, 0, 804,
+	899, 900, 901, 902, 0, 817, 0, 805, 807, 808,
+	809, 810, 903, 811, 812, 904, 0, 813, 814, 815,
+	816, 806, 819, 820, 818, 0, 0, 821, 822, 823,
+	824, 826, 828, 829, 830, 825, 827, 831, 0, 832,
+	0, 0, 833, 834, 835, 905, 906, 907, 0, 908,
+	838, 839, 836, 837, 840, 841, 844, 842, 843, 909,
+	847, 542, 848, 849, 850, 845, 846, 2164, 0, 359,
+	0, 851, 852, 910, 853, 854, 855, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 367, 368, 370, 369,
+	371, 372, 373, 374, 0, 375, 376, 0, 0, 0,
+	0, 0, 856, 0, 0, 0, 378, 0, 377, 0,
+	379, 380, 381, 0, 382, 383, 384, 385, 386, 387,
+	388, 389, 390, 857, 391, 858, 0, 392, 859, 393,
+	860, 0, 861, 394, 395, 396, 397, 398, 399, 400,
+	401, 402, 403, 404, 0, 0, 0, 405, 862, 863,
+	864, 0, 406, 407, 408, 409, 865, 0, 0, 0,
+	410, 411, 412, 413, 414, 415, 416, 417, 0, 0,
+	419, 420, 421, 418, 422, 423, 0, 424, 0, 425,
+	426, 427, 428, 429, 0, 430, 431, 0, 432, 433,
+	434, 0, 435, 436, 437, 0, 0, 0, 0, 0,
+	0, 0, 438, 439, 440, 441, 442, 0, 443, 445,
+	866, 867, 0, 448, 450, 444, 446, 0, 449, 447,
+	451, 452, 0, 453, 454, 455, 456, 457, 0, 0,
+	0, 458, 459, 460, 461, 0, 462, 463, 464, 466,
+	465, 0, 467, 468, 469, 0, 470, 471, 868, 472,
+	473, 474, 476, 478, 475, 477, 479, 480, 481, 482,
+	483, 869, 870, 484, 485, 0, 0, 0, 0, 0,
+	0, 0, 486, 487, 488, 871, 0, 0, 0, 489,
+	0, 491, 495, 496, 492, 493, 494, 497, 0, 490,
+	498, 499, 0, 0, 500, 501, 502, 872, 873, 503,
+	504, 505, 506, 507, 508, 509, 510, 511, 0, 512,
+	513, 874, 0, 875, 514, 0, 515, 516, 517, 518,
+	519, 520, 521, 2163, 877, 878, 630, 0, 522, 523,
+	524, 525, 0, 526, 527, 528, 529, 530, 531, 532,
+	0, 0, 0, 533, 534, 535, 536, 0, 0, 0,
+	0, 0, 879, 537, 631, 538, 539, 880, 881, 0,
+	882, 0, 540, 541, 544, 0, 883, 0, 543, 545,
+	546, 0, 547, 0, 0, 0, 548, 549, 550, 551,
+	552, 553, 554, 0, 555, 557, 556, 0, 559, 884,
+	558, 0, 560, 561, 0, 0, 562, 563, 564, 565,
+	566, 567, 572, 0, 0, 568, 569, 570, 571, 573,
+	574, 0, 575, 576, 578, 581, 577, 579, 580, 582,
+	583, 596, 597, 598, 584, 585, 586, 587, 588, 589,
+	590, 591, 592, 593, 594, 595, 600, 0, 599, 0,
+	0, 601, 602, 603, 604, 605, 606, 612, 615, 617,
+	618, 613, 614, 616, 619, 620, 621, 623, 624, 609,
+	610, 611, 0, 622, 607, 0, 608, 0, 0, 625,
+	626, 627, 628, 0, 885, 629, 886, 632, 633, 0,
+	0, 634, 0, 635, 636, 0, 0, 638, 639, 640,
+	0, 0, 641, 642, 887, 0, 643, 0, 888, 644,
+	645, 637, 646, 647, 648, 649, 650, 651, 652, 653,
+	654, 655, 656, 657, 0, 658, 659, 889, 660, 661,
+	662, 663, 664, 890, 665, 666, 667, 891, 668, 892,
+	669, 670, 671, 0, 672, 673, 674, 0, 675, 676,
+	677, 678, 679, 680, 681, 682, 683, 684, 893, 685,
+	686, 688, 687, 689, 690, 0, 691, 692, 0, 693,
+	694, 695, 0, 0, 0, 0, 0, 696, 697, 699,
+	0, 700, 701, 702, 703, 704, 705, 698, 706, 707,
+	708, 709, 710, 711, 712, 713, 0, 715, 716, 714,
+	717, 718, 0, 719, 720, 721, 722, 723, 894, 724,
+	0, 725, 726, 734, 735, 736, 727, 728, 730, 737,
+	729, 738, 739, 740, 741, 743, 742, 0, 745, 746,
+	744, 747, 748, 749, 750, 0, 751, 895, 752, 731,
+	732, 753, 754, 755, 0, 756, 757, 758, 759, 760,
+	761, 762, 763, 764, 896, 0, 766, 0, 765, 767,
+	768, 769, 770, 771, 772, 773, 775, 733, 776, 777,
+	778, 783, 784, 785, 897, 779, 780, 781, 782, 787,
+	898, 788, 789, 790, 791, 0, 792, 793, 0, 786,
+	774, 0, 794, 795, 796, 797, 798, 799, 800, 801,
+	802, 803, 0, 804, 899, 900, 901, 902, 0, 817,
+	0, 805, 807, 808, 809, 810, 903, 811, 812, 904,
+	0, 813, 814, 815, 816, 806, 819, 820, 818, 0,
+	0, 821, 822, 823, 824, 826, 828, 829, 830, 825,
+	827, 831, 0, 832, 0, 0, 833, 834, 835, 905,
+	906, 907, 0, 908, 838, 839, 836, 837, 840, 841,
+	844, 842, 843, 909, 847, 542, 848, 849, 850, 845,
+	846, 2161, 0, 359, 0, 851, 852, 910, 853, 854,
+	855, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	367, 368, 370, 369, 371, 372, 373, 374, 0, 375,
+	376, 0, 0, 0, 0, 0, 856, 0, 0, 0,
+	378, 0, 377, 0, 379, 380, 381, 0, 382, 383,
+	384, 385, 386, 387, 388, 389, 390, 857, 391, 858,
+	0, 392, 859, 393, 860, 0, 861, 394, 395, 396,
+	397, 398, 399, 400, 401, 402, 403, 404, 0, 0,
+	0, 405, 862, 863, 864, 0, 406, 407, 408, 409,
+	865, 0, 0, 0, 410, 411, 412, 413, 414, 415,
+	416, 417, 0, 0, 419, 420, 421, 418, 422, 423,
+	0, 424, 0, 425, 426, 427, 428, 429, 0, 430,
+	431, 0, 432, 433, 434, 0, 435, 436, 437, 0,
+	0, 0, 0, 0, 0, 0, 438, 439, 440, 441,
+	442, 0, 443, 445, 866, 867, 0, 448, 450, 444,
+	446, 0, 449, 447, 451, 452, 0, 453, 454, 455,
+	456, 457, 0, 0, 0, 458, 459, 460, 461, 0,
+	462, 463, 464, 466, 465, 0, 467, 468, 469, 0,
+	470, 471, 868, 472, 473, 474, 476, 478, 475, 477,
+	479, 480, 481, 482, 483, 869, 870, 484, 485, 0,
+	0, 0, 0, 0, 0, 0, 486, 487, 488, 871,
+	0, 0, 0, 489, 0, 491, 495, 496, 492, 493,
+	494, 497, 0, 490, 498, 499, 0, 0, 500, 501,
+	502, 872, 873, 503, 504, 505, 506, 507, 508, 509,
+	510, 511, 0, 512, 513, 874, 0, 875, 514, 0,
+	515, 516, 517, 518, 519, 520, 521, 2159, 877, 878,
+	630, 0, 522, 523, 524, 525, 0, 526, 527, 528,
+	529, 530, 531, 532, 0, 0, 0, 533, 534, 535,
+	536, 0, 0, 0, 0, 0, 879, 537, 631, 538,
+	539, 880, 881, 0, 882, 0, 540, 541, 544, 0,
+	883, 0, 543, 545, 546, 0, 547, 0, 0, 0,
+	548, 549, 550, 551, 552, 553, 554, 0, 555, 557,
+	556, 0, 559, 884, 558, 0, 560, 561, 0, 0,
+	562, 563, 564, 565, 566, 567, 572, 0, 0, 568,
+	569, 570, 571, 573, 574, 0, 575, 576, 578, 581,
+	577, 579, 580, 582, 583, 596, 597, 598, 584, 585,
+	586, 587, 588, 589, 590, 591, 592, 593, 594, 595,
+	600, 0, 599, 0, 0, 601, 602, 603, 604, 605,
+	606, 612, 615, 617, 618, 613, 614, 616, 619, 620,
+	621, 623, 624, 609, 610, 611, 0, 622, 607, 0,
+	608, 0, 0, 625, 626, 627, 628, 0, 885, 629,
+	886, 632, 633, 0, 0, 634, 0, 635, 636, 0,
+	0, 638, 639, 640, 0, 0, 641, 642, 887, 0,
+	643, 0, 888, 644, 645, 637, 646, 647, 648, 649,
+	650, 651, 652, 653, 654, 655, 656, 657, 0, 658,
+	659, 889, 660, 661, 662, 663, 664, 890, 665, 666,
+	667, 891, 668, 892, 669, 670, 671, 0, 672, 673,
+	674, 0, 675, 676, 677, 678, 679, 680, 681, 682,
+	683, 684, 893, 685, 686, 688, 687, 689, 690, 0,
+	691, 692, 0, 693, 694, 695, 0, 0, 0, 0,
+	0, 696, 697, 699, 0, 700, 701, 702, 703, 704,
+	705, 698, 706, 707, 708, 709, 710, 711, 712, 713,
+	0, 715, 716, 714, 717, 718, 0, 719, 720, 721,
+	722, 723, 894, 724, 0, 725, 726, 734, 735, 736,
+	727, 728, 730, 737, 729, 738, 739, 740, 741, 743,
+	742, 0, 745, 746, 744, 747, 748, 749, 750, 0,
+	751, 895, 752, 731, 732, 753, 754, 755, 0, 756,
+	757, 758, 759, 760, 761, 762, 763, 764, 896, 0,
+	766, 0, 765, 767, 768, 769, 770, 771, 772, 773,
+	775, 733, 776, 777, 778, 783, 784, 785, 897, 779,
+	780, 781, 782, 787, 898, 788, 789, 790, 791, 0,
+	792, 793, 0, 786, 774, 0, 794, 795, 796, 797,
+	798, 799, 800, 801, 802, 803, 0, 804, 899, 900,
+	901, 902, 0, 817, 0, 805, 807, 808, 809, 810,
+	903, 811, 812, 904, 0, 813, 814, 815, 816, 806,
+	819, 820, 818, 0, 0, 821, 822, 823, 824, 826,
+	828, 829, 830, 825, 827, 831, 0, 832, 0, 0,
+	833, 834, 835, 905, 906, 907, 0, 908, 838, 839,
+	836, 837, 840, 841, 844, 842, 843, 909, 847, 542,
+	848, 849, 850, 845, 846, 2147, 0, 359, 0, 851,
+	852, 910, 853, 854, 855, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 367, 368, 370, 369, 371, 372,
+	373, 374, 0, 375, 376, 0, 0, 0, 0, 0,
+	856, 0, 0, 0, 378, 0, 377, 0, 379, 380,
+	381, 0, 382, 383, 384, 385, 386, 387, 388, 389,
+	390, 857, 391, 858, 0, 392, 859, 393, 860, 0,
+	861, 394, 395, 396, 397, 398, 399, 400, 401, 402,
+	403, 404, 0, 0, 0, 405, 862, 863, 864, 0,
+	406, 407, 408, 409, 865, 0, 0, 0, 410, 411,
+	412, 413, 414, 415, 416, 417, 0, 0, 419, 420,
+	421, 418, 422, 423, 0, 424, 0, 425, 426, 427,
+	428, 429, 0, 430, 431, 0, 432, 433, 434, 0,
+	435, 436, 437, 0, 0, 0, 0, 0, 0, 0,
+	438, 439, 440, 441, 442, 0, 443, 445, 866, 867,
+	0, 448, 450, 444, 446, 0, 449, 447, 451, 452,
+	0, 453, 454, 455, 456, 457, 0, 0, 0, 458,
+	459, 460, 461, 0, 462, 463, 464, 466, 465, 0,
+	467, 468, 469, 0, 470, 471, 868, 472, 473, 474,
+	476, 478, 475, 477, 479, 480, 481, 482, 483, 869,
+	870, 484, 485, 0, 0, 0, 0, 0, 0, 0,
+	486, 487, 488, 871, 0, 0, 0, 489, 0, 491,
+	495, 496, 492, 493, 494, 497, 0, 490, 498, 499,
+	0, 0, 500, 501, 502, 872, 873, 503, 504, 505,
+	506, 507, 508, 509, 510, 511, 0, 512, 513, 874,
+	0, 875, 514, 0, 515, 516, 517, 518, 519, 520,
+	521, 876, 877, 878, 630, 0, 522, 523, 524, 525,
+	0, 526, 527, 528, 529, 530, 531, 532, 0, 0,
+	0, 533, 534, 535, 536, 0, 0, 0, 0, 0,
+	879, 537, 631, 538, 539, 880, 881, 0, 882, 0,
+	540, 541, 544, 0, 883, 0, 543, 545, 546, 0,
+	547, 0, 0, 0, 548, 549, 550, 551, 552, 553,
+	554, 0, 555, 557, 556, 0, 559, 884, 558, 0,
+	560, 561, 0, 0, 562, 563, 564, 565, 566, 567,
+	572, 0, 0, 568, 569, 570, 571, 573, 574, 0,
+	575, 576, 578, 581, 577, 579, 580, 582, 583, 596,
+	597, 598, 584, 585, 586, 587, 588, 589, 590, 591,
+	592, 593, 594, 595, 600, 0, 599, 0, 0, 601,
+	602, 603, 604, 605, 606, 612, 615, 617, 618, 613,
+	614, 616, 619, 620, 621, 623, 624, 609, 610, 611,
+	0, 622, 607, 0, 608, 0, 0, 625, 626, 627,
+	628, 0, 885, 629, 886, 632, 633, 0, 0, 634,
+	0, 635, 636, 0, 0, 638, 639, 640, 0, 0,
+	641, 642, 887, 0, 643, 0, 888, 644, 645, 637,
+	646, 647, 648, 649, 650, 651, 652, 653, 654, 655,
+	656, 657, 0, 658, 659, 889, 660, 661, 662, 663,
+	664, 890, 665, 666, 667, 891, 668, 892, 669, 670,
+	671, 0, 672, 673, 674, 0, 675, 676, 677, 678,
+	679, 680, 681, 682, 683, 684, 893, 685, 686, 688,
+	687, 689, 690, 0, 691, 692, 0, 693, 694, 695,
+	0, 0, 0, 0, 0, 696, 697, 699, 0, 700,
+	701, 702, 703, 704, 705, 698, 706, 707, 708, 709,
+	710, 711, 712, 713, 0, 715, 716, 714, 717, 718,
+	0, 719, 720, 721, 722, 723, 894, 724, 0, 725,
+	726, 734, 735, 736, 727, 728, 730, 737, 729, 738,
+	739, 740, 741, 743, 742, 0, 745, 746, 744, 747,
+	748, 749, 750, 0, 751, 895, 752, 731, 732, 753,
+	754, 755, 0, 756, 757, 758, 759, 760, 761, 762,
+	763, 764, 896, 0, 766, 0, 765, 767, 768, 769,
+	770, 771, 772, 773, 775, 733, 776, 777, 778, 783,
+	784, 785, 897, 779, 780, 781, 782, 787, 898, 788,
+	789, 790, 791, 0, 792, 793, 0, 786, 774, 0,
+	794, 795, 796, 797, 798, 799, 800, 801, 802, 803,
+	0, 804, 899, 900, 901, 902, 0, 817, 0, 805,
+	807, 808, 809, 810, 903, 811, 812, 904, 0, 813,
+	814, 815, 816, 806, 819, 820, 818, 0, 0, 821,
+	822, 823, 824, 826, 828, 829, 830, 825, 827, 831,
+	0, 832, 0, 0, 833, 834, 835, 905, 906, 907,
+	0, 908, 838, 839, 836, 837, 840, 841, 844, 842,
+	843, 909, 847, 542, 848, 849, 850, 845, 846, 2109,
+	0, 359, 0, 851, 852, 910, 853, 854, 855, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 367, 368,
+	370, 369, 371, 372, 373, 374, 0, 375, 376, 0,
+	0, 0, 0, 0, 856, 0, 0, 0, 378, 0,
+	377, 0, 379, 380, 381, 0, 382, 383, 384, 385,
+	386, 387, 388, 389, 390, 857, 391, 858, 0, 392,
+	859, 393, 860, 0, 861, 394, 395, 396, 397, 398,
+	399, 400, 401, 402, 403, 404, 0, 0, 0, 405,
+	862, 863, 864, 0, 406, 407, 408, 409, 865, 0,
+	0, 0, 410, 411, 412, 413, 414, 415, 416, 417,
+	0, 0, 419, 420, 421, 418, 422, 423, 0, 424,
+	0, 425, 426, 427, 428, 429, 0, 430, 431, 0,
+	432, 433, 434, 0, 435, 436, 437, 0, 0, 0,
+	0, 0, 0, 0, 438, 439, 440, 441, 442, 0,
+	443, 445, 866, 867, 0, 448, 450, 444, 446, 0,
+	449, 447, 451, 452, 0, 453, 454, 455, 456, 457,
+	0, 0, 0, 458, 459, 460, 461, 0, 462, 463,
+	464, 466, 465, 0, 467, 468, 469, 0, 470, 471,
+	868, 472, 473, 474, 476, 478, 475, 477, 479, 480,
+	481, 482, 483, 869, 870, 484, 485, 0, 0, 0,
+	0, 0, 0, 0, 486, 487, 488, 871, 0, 0,
+	0, 489, 0, 491, 495, 496, 492, 493, 494, 497,
+	0, 490, 498, 499, 0, 0, 500, 501, 502, 872,
+	873, 503, 504, 505, 506, 507, 508, 509, 510, 511,
+	0, 512, 513, 874, 0, 875, 514, 0, 515, 516,
+	517, 518, 519, 520, 521, 876, 877, 878, 630, 0,
+	522, 523, 524, 525, 0, 526, 527, 528, 529, 530,
+	531, 532, 0, 0, 0, 533, 534, 535, 536, 0,
+	0, 0, 0, 0, 879, 537, 631, 538, 539, 880,
+	881, 0, 882, 0, 540, 541, 544, 0, 883, 0,
+	543, 545, 546, 0, 547, 0, 0, 0, 548, 549,
+	550, 551, 552, 553, 554, 0, 555, 557, 556, 0,
+	559, 884, 558, 0, 560, 561, 0, 0, 562, 563,
+	564, 565, 566, 567, 572, 0, 0, 568, 569, 570,
+	571, 573, 574, 0, 575, 576, 578, 581, 577, 579,
+	580, 582, 583, 596, 597, 598, 584, 585, 586, 587,
+	588, 589, 590, 591, 592, 593, 594, 595, 600, 0,
+	599, 0, 0, 601, 602, 603, 604, 605, 606, 612,
+	615, 617, 618, 613, 614, 616, 619, 620, 621, 623,
+	624, 609, 610, 611, 0, 622, 607, 0, 608, 0,
+	0, 625, 626, 627, 628, 0, 885, 629, 886, 632,
+	633, 0, 0, 634, 0, 635, 636, 0, 0, 638,
+	639, 640, 0, 0, 641, 642, 887, 0, 643, 0,
+	888, 644, 645, 637, 646, 647, 648, 649, 650, 651,
+	652, 653, 654, 655, 656, 657, 0, 658, 659, 889,
+	660, 661, 662, 663, 664, 890, 665, 666, 667, 891,
+	668, 892, 669, 670, 671, 0, 672, 673, 674, 0,
+	675, 676, 677, 678, 679, 680, 681, 682, 683, 684,
+	893, 685, 686, 688, 687, 689, 690, 0, 691, 692,
+	0, 693, 694, 695, 0, 0, 0, 0, 0, 696,
+	697, 699, 0, 700, 701, 702, 703, 704, 705, 698,
+	706, 707, 708, 709, 710, 711, 712, 713, 0, 715,
+	716, 714, 717, 718, 0, 719, 720, 721, 722, 723,
+	894, 724, 0, 725, 726, 734, 735, 736, 727, 728,
+	730, 737, 729, 738, 739, 740, 741, 743, 742, 0,
+	745, 746, 744, 747, 748, 749, 750, 0, 751, 895,
+	752, 731, 732, 753, 754, 755, 0, 756, 757, 758,
+	759, 760, 761, 762, 763, 764, 896, 0, 766, 0,
+	765, 767, 768, 769, 770, 771, 772, 773, 775, 733,
+	776, 777, 778, 783, 784, 785, 897, 779, 780, 781,
+	782, 787, 898, 788, 789, 790, 791, 0, 792, 793,
+	0, 786, 774, 0, 794, 795, 796, 797, 798, 799,
+	800, 801, 802, 803, 0, 804, 899, 900, 901, 902,
+	0, 817, 0, 805, 807, 808, 809, 810, 903, 811,
+	812, 904, 0, 813, 814, 815, 816, 806, 819, 820,
+	818, 0, 0, 821, 822, 823, 824, 826, 828, 829,
+	830, 825, 827, 831, 0, 832, 0, 0, 833, 834,
+	835, 905, 906, 907, 0, 908, 838, 839, 836, 837,
+	840, 841, 844, 842, 843, 909, 847, 542, 848, 849,
+	850, 845, 846, 2099, 0, 359, 0, 851, 852, 910,
+	853, 854, 855, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 367, 368, 370, 369, 371, 372, 373, 374,
+	0, 375, 376, 0, 0, 0, 0, 0, 856, 0,
+	0, 0, 378, 0, 377, 0, 379, 380, 381, 0,
+	382, 383, 384, 385, 386, 387, 388, 389, 390, 857,
+	391, 858, 0, 392, 859, 393, 860, 0, 861, 394,
+	395, 396, 397, 398, 399, 400, 401, 402, 403, 404,
+	0, 0, 0, 405, 862, 863, 864, 0, 406, 407,
+	408, 409, 865, 0, 0, 0, 410, 411, 412, 413,
+	414, 415, 416, 417, 0, 0, 419, 420, 421, 418,
+	422, 423, 0, 424, 0, 425, 426, 427, 428, 429,
+	0, 430, 431, 0, 432, 433, 434, 0, 435, 436,
+	437, 0, 0, 0, 0, 0, 0, 0, 438, 439,
+	440, 441, 442, 0, 443, 445, 866, 867, 0, 448,
+	450, 444, 446, 0, 449, 447, 451, 452, 0, 453,
+	454, 455, 456, 457, 0, 0, 0, 458, 459, 460,
+	461, 0, 462, 463, 464, 466, 465, 0, 467, 468,
+	469, 0, 470, 471, 868, 472, 473, 474, 476, 478,
+	475, 477, 479, 480, 481, 482, 483, 869, 870, 484,
+	485, 0, 0, 0, 0, 0, 0, 0, 486, 487,
+	488, 871, 0, 0, 0, 489, 0, 491, 495, 496,
+	492, 493, 494, 497, 0, 490, 498, 499, 0, 0,
+	500, 501, 502, 872, 873, 503, 504, 505, 506, 507,
+	508, 509, 510, 511, 0, 512, 513, 874, 0, 875,
+	514, 0, 515, 516, 517, 518, 519, 520, 521, 876,
+	877, 878, 630, 0, 522, 523, 524, 525, 0, 526,
+	527, 528, 529, 530, 531, 532, 0, 0, 0, 533,
+	534, 535, 536, 0, 0, 0, 0, 0, 879, 537,
+	631, 538, 539, 880, 881, 0, 882, 0, 540, 541,
+	544, 0, 883, 0, 543, 545, 546, 0, 547, 0,
+	0, 0, 548, 549, 550, 551, 552, 553, 554, 0,
+	555, 557, 556, 0, 559, 884, 558, 0, 560, 561,
+	0, 0, 562, 563, 564, 565, 566, 567, 572, 0,
+	0, 568, 569, 570, 571, 573, 574, 0, 575, 576,
+	578, 581, 577, 579, 580, 582, 583, 596, 597, 598,
+	584, 585, 586, 587, 588, 589, 590, 591, 592, 593,
+	594, 595, 600, 0, 599, 0, 0, 601, 602, 603,
+	604, 605, 606, 612, 615, 617, 618, 613, 614, 616,
+	619, 620, 621, 623, 624, 609, 610, 611, 0, 622,
+	607, 0, 608, 0, 0, 625, 626, 627, 628, 0,
+	885, 629, 886, 632, 633, 0, 0, 634, 0, 635,
+	636, 0, 0, 638, 639, 640, 0, 0, 641, 642,
+	887, 0, 643, 0, 888, 644, 645, 637, 646, 647,
+	648, 649, 650, 651, 652, 653, 654, 655, 656, 657,
+	0, 658, 659, 889, 660, 661, 662, 663, 664, 890,
+	665, 666, 667, 891, 668, 892, 669, 670, 671, 0,
+	672, 673, 674, 0, 675, 676, 677, 678, 679, 680,
+	681, 682, 683, 684, 893, 685, 686, 688, 687, 689,
+	690, 0, 691, 692, 0, 693, 694, 695, 0, 0,
+	0, 0, 0, 696, 697, 699, 0, 700, 701, 702,
+	703, 704, 705, 698, 706, 707, 708, 709, 710, 711,
+	712, 713, 0, 715, 716, 714, 717, 718, 0, 719,
+	720, 721, 722, 723, 894, 724, 0, 725, 726, 734,
+	735, 736, 727, 728, 730, 737, 729, 738, 739, 740,
+	741, 743, 742, 0, 745, 746, 744, 747, 748, 749,
+	750, 0, 751, 895, 752, 731, 732, 753, 754, 755,
+	0, 756, 757, 758, 759, 760, 761, 762, 763, 764,
+	896, 0, 766, 0, 765, 767, 768, 769, 770, 771,
+	772, 773, 775, 733, 776, 777, 778, 783, 784, 785,
+	897, 779, 780, 781, 782, 787, 898, 788, 789, 790,
+	791, 0, 792, 793, 0, 786, 774, 0, 794, 795,
+	796, 797, 798, 799, 800, 801, 802, 803, 0, 804,
+	899, 900, 901, 902, 0, 817, 0, 805, 807, 808,
+	809, 810, 903, 811, 812, 904, 0, 813, 814, 815,
+	816, 806, 819, 820, 818, 0, 0, 821, 822, 823,
+	824, 826, 828, 829, 830, 825, 827, 831, 0, 832,
+	0, 0, 833, 834, 835, 905, 906, 907, 0, 908,
+	838, 839, 836, 837, 840, 841, 844, 842, 843, 909,
+	847, 542, 848, 849, 850, 845, 846, 2077, 0, 359,
+	0, 851, 852, 910, 853, 854, 855, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 367, 368, 370, 369,
+	371, 372, 373, 374, 0, 375, 376, 0, 0, 0,
+	0, 0, 856, 0, 0, 0, 378, 0, 377, 0,
+	379, 380, 381, 0, 382, 383, 384, 385, 386, 387,
+	388, 389, 390, 857, 391, 858, 0, 392, 859, 393,
+	860, 0, 861, 394, 395, 396, 397, 398, 399, 400,
+	401, 402, 403, 404, 0, 0, 0, 405, 862, 863,
+	864, 0, 406, 407, 408, 409, 865, 0, 0, 0,
+	410, 411, 412, 413, 414, 415, 416, 417, 0, 0,
+	419, 420, 421, 418, 422, 423, 0, 424, 0, 425,
+	426, 427, 428, 429, 0, 430, 431, 0, 432, 433,
+	434, 0, 435, 436, 437, 0, 0, 0, 0, 0,
+	0, 0, 438, 439, 440, 441, 442, 0, 443, 445,
+	866, 867, 0, 448, 450, 444, 446, 0, 449, 447,
+	451, 452, 0, 453, 454, 455, 456, 457, 0, 0,
+	0, 458, 459, 460, 461, 0, 462, 463, 464, 466,
+	465, 0, 467, 468, 469, 0, 470, 471, 868, 472,
+	473, 474, 476, 478, 475, 477, 479, 480, 481, 482,
+	483, 869, 870, 484, 485, 0, 0, 0, 0, 0,
+	0, 0, 486, 487, 488, 871, 0, 0, 0, 489,
+	0, 491, 495, 496, 492, 493, 494, 497, 0, 490,
+	498, 499, 0, 0, 500, 501, 502, 872, 873, 503,
+	504, 505, 506, 507, 508, 509, 510, 511, 0, 512,
+	513, 874, 0, 875, 514, 0, 515, 516, 517, 518,
+	519, 520, 521, 876, 877, 878, 630, 0, 522, 523,
+	524, 525, 0, 526, 527, 528, 529, 530, 531, 532,
+	0, 0, 0, 533, 534, 535, 536, 0, 0, 0,
+	0, 0, 879, 537, 631, 538, 539, 880, 881, 0,
+	882, 0, 540, 541, 544, 0, 883, 0, 543, 545,
+	546, 0, 547, 0, 0, 0, 548, 549, 550, 551,
+	552, 553, 554, 0, 555, 557, 556, 0, 559, 884,
+	558, 0, 560, 561, 0, 0, 562, 563, 564, 565,
+	566, 567, 572, 0, 0, 568, 569, 570, 571, 573,
+	574, 0, 575, 576, 578, 581, 577, 579, 580, 582,
+	583, 596, 597, 598, 584, 585, 586, 587, 588, 589,
+	590, 591, 592, 593, 594, 595, 600, 0, 599, 0,
+	0, 601, 602, 603, 604, 605, 606, 612, 615, 617,
+	618, 613, 614, 616, 619, 620, 621, 623, 624, 609,
+	610, 611, 0, 622, 607, 0, 608, 0, 0, 625,
+	626, 627, 628, 0, 885, 629, 886, 632, 633, 0,
+	0, 634, 0, 635, 636, 0, 0, 638, 639, 640,
+	0, 0, 641, 642, 887, 0, 643, 0, 888, 644,
+	645, 637, 646, 647, 648, 649, 650, 651, 652, 653,
+	654, 655, 656, 657, 0, 658, 659, 889, 660, 661,
+	662, 663, 664, 890, 665, 666, 667, 891, 668, 892,
+	669, 670, 671, 0, 672, 673, 674, 0, 675, 676,
+	677, 678, 679, 680, 681, 682, 683, 684, 893, 685,
+	686, 688, 687, 689, 690, 0, 691, 692, 0, 693,
+	694, 695, 0, 0, 0, 0, 0, 696, 697, 699,
+	0, 700, 701, 702, 703, 704, 705, 698, 706, 707,
+	708, 709, 710, 711, 712, 713, 0, 715, 716, 714,
+	717, 718, 0, 719, 720, 721, 722, 723, 894, 724,
+	0, 725, 726, 734, 735, 736, 727, 728, 730, 737,
+	729, 738, 739, 740, 741, 743, 742, 0, 745, 746,
+	744, 747, 748, 749, 750, 0, 751, 895, 752, 731,
+	732, 753, 754, 755, 0, 756, 757, 758, 759, 760,
+	761, 762, 763, 764, 896, 0, 766, 0, 765, 767,
+	768, 769, 770, 771, 772, 773, 775, 733, 776, 777,
+	778, 783, 784, 785, 897, 779, 780, 781, 782, 787,
+	898, 788, 789, 790, 791, 0, 792, 793, 0, 786,
+	774, 0, 794, 795, 796, 797, 798, 799, 800, 801,
+	802, 803, 0, 804, 899, 900, 901, 902, 0, 817,
+	0, 805, 807, 808, 809, 810, 903, 811, 812, 904,
+	0, 813, 814, 815, 816, 806, 819, 820, 818, 0,
+	0, 821, 822, 823, 824, 826, 828, 829, 830, 825,
+	827, 831, 0, 832, 0, 0, 833, 834, 835, 905,
+	906, 907, 0, 908, 838, 839, 836, 837, 840, 841,
+	844, 842, 843, 909, 847, 542, 848, 849, 850, 845,
+	846, 1770, 0, 359, 0, 851, 852, 910, 853, 854,
+	855, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	367, 368, 370, 369, 371, 372, 373, 374, 0, 375,
+	376, 0, 0, 0, 0, 0, 856, 0, 0, 0,
+	378, 0, 377, 0, 379, 380, 381, 0, 382, 383,
+	384, 385, 386, 387, 388, 389, 390, 857, 391, 858,
+	0, 392, 859, 393, 860, 0, 861, 394, 395, 396,
+	397, 398, 399, 400, 401, 402, 403, 404, 0, 0,
+	0, 405, 862, 863, 864, 0, 406, 407, 408, 409,
+	865, 0, 0, 0, 410, 411, 412, 413, 414, 415,
+	416, 417, 0, 0, 419, 420, 421, 418, 422, 423,
+	0, 424, 0, 425, 426, 427, 428, 429, 0, 430,
+	431, 0, 432, 433, 434, 0, 435, 436, 437, 0,
+	0, 0, 0, 0, 0, 0, 438, 439, 440, 441,
+	442, 0, 443, 445, 866, 867, 0, 448, 450, 444,
+	446, 0, 449, 447, 451, 452, 0, 453, 454, 455,
+	456, 457, 0, 0, 0, 458, 459, 460, 461, 0,
+	462, 463, 464, 466, 465, 0, 467, 468, 469, 0,
+	470, 471, 868, 472, 473, 474, 476, 478, 475, 477,
+	479, 480, 481, 482, 483, 869, 870, 484, 485, 0,
+	0, 0, 0, 0, 0, 0, 486, 487, 488, 871,
+	0, 0, 0, 489, 0, 491, 495, 496, 492, 493,
+	494, 497, 0, 490, 498, 499, 0, 0, 500, 501,
+	502, 872, 873, 503, 504, 505, 506, 507, 508, 509,
+	510, 511, 0, 512, 513, 874, 0, 875, 514, 0,
+	515, 516, 517, 518, 519, 520, 521, 876, 877, 878,
+	630, 0, 522, 523, 524, 525, 0, 526, 527, 528,
+	529, 530, 531, 532, 0, 0, 0, 533, 534, 535,
+	536, 0, 0, 0, 0, 0, 879, 537, 631, 538,
+	539, 880, 881, 0, 882, 0, 540, 541, 544, 0,
+	883, 0, 543, 545, 546, 0, 547, 0, 0, 0,
+	548, 549, 550, 551, 552, 553, 554, 0, 555, 557,
+	556, 0, 559, 884, 558, 0, 560, 561, 0, 0,
+	562, 563, 564, 565, 566, 567, 572, 0, 0, 568,
+	569, 570, 571, 573, 574, 0, 575, 576, 578, 581,
+	577, 579, 580, 582, 583, 596, 597, 598, 584, 585,
+	586, 587, 588, 589, 590, 591, 592, 593, 594, 595,
+	600, 0, 599, 0, 0, 601, 602, 603, 604, 605,
+	606, 612, 615, 617, 618, 613, 614, 616, 619, 620,
+	621, 623, 624, 609, 610, 611, 0, 622, 607, 0,
+	608, 0, 0, 625, 626, 627, 628, 0, 885, 629,
+	886, 632, 633, 0, 0, 634, 0, 635, 636, 0,
+	0, 638, 639, 640, 0, 0, 641, 642, 887, 0,
+	643, 0, 888, 644, 645, 637, 646, 647, 648, 649,
+	650, 651, 652, 653, 654, 655, 656, 657, 0, 658,
+	659, 889, 660, 661, 662, 663, 664, 890, 665, 666,
+	667, 891, 668, 892, 669, 670, 671, 0, 672, 673,
+	674, 0, 675, 676, 677, 678, 679, 680, 681, 682,
+	683, 684, 893, 685, 686, 688, 687, 689, 690, 0,
+	691, 692, 0, 693, 694, 695, 0, 0, 0, 0,
+	0, 696, 697, 699, 0, 700, 701, 702, 703, 704,
+	705, 698, 706, 707, 708, 709, 710, 711, 712, 713,
+	0, 715, 716, 714, 717, 718, 0, 1048, 720, 721,
+	722, 723, 894, 724, 0, 725, 726, 734, 735, 736,
+	727, 728, 730, 1047, 729, 738, 739, 740, 741, 743,
+	742, 0, 745, 746, 744, 747, 748, 749, 750, 0,
+	751, 895, 752, 731, 732, 753, 754, 755, 0, 756,
+	757, 758, 759, 760, 761, 762, 763, 764, 896, 0,
+	766, 0, 765, 767, 768, 769, 770, 771, 772, 773,
+	775, 733, 776, 777, 778, 783, 784, 785, 897, 779,
+	780, 781, 782, 787, 898, 788, 789, 790, 791, 0,
+	792, 793, 0, 786, 774, 0, 794, 795, 796, 797,
+	798, 799, 800, 801, 802, 803, 0, 804, 1045, 900,
+	901, 902, 0, 817, 0, 805, 807, 808, 809, 810,
+	903, 811, 812, 904, 0, 813, 814, 815, 816, 806,
+	819, 820, 818, 0, 0, 821, 822, 823, 824, 826,
+	828, 829, 830, 825, 827, 831, 0, 832, 0, 0,
+	833, 834, 835, 905, 906, 907, 0, 908, 838, 839,
+	836, 837, 840, 841, 844, 842, 843, 909, 847, 542,
+	848, 849, 850, 845, 846, 1740, 0, 359, 0, 851,
+	852, 910, 853, 854, 855, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 367, 368, 370, 369, 371, 372,
+	373, 374, 0, 375, 376, 0, 0, 0, 0, 0,
+	856, 0, 0, 0, 378, 0, 377, 0, 379, 380,
+	381, 0, 382, 383, 384, 385, 386, 387, 388, 389,
+	390, 857, 391, 858, 0, 392, 859, 393, 860, 0,
+	861, 394, 395, 396, 397, 398, 399, 400, 401, 402,
+	403, 404, 0, 0, 0, 405, 862, 863, 864, 0,
+	406, 407, 408, 409, 865, 0, 0, 0, 410, 411,
+	412, 413, 414, 415, 416, 417, 0, 0, 419, 420,
+	421, 418, 422, 423, 0, 424, 0, 425, 426, 427,
+	428, 429, 0, 430, 431, 0, 432, 433, 434, 0,
+	435, 436, 437, 0, 0, 0, 0, 0, 0, 0,
+	438, 439, 440, 441, 442, 0, 443, 445, 866, 867,
+	0, 448, 450, 444, 446, 0, 449, 447, 451, 452,
+	0, 453, 454, 455, 456, 457, 0, 0, 0, 458,
+	459, 460, 461, 0, 462, 463, 464, 466, 465, 0,
+	467, 468, 469, 0, 470, 471, 868, 472, 473, 474,
+	476, 478, 475, 477, 479, 480, 481, 482, 483, 869,
+	870, 484, 485, 0, 0, 0, 0, 0, 0, 0,
+	486, 487, 488, 871, 0, 0, 0, 489, 0, 491,
+	495, 496, 492, 493, 494, 497, 0, 490, 498, 499,
+	0, 0, 500, 501, 502, 872, 873, 503, 504, 505,
+	506, 507, 508, 509, 510, 511, 0, 512, 513, 874,
+	0, 875, 514, 0, 515, 516, 517, 518, 519, 520,
+	521, 1739, 877, 878, 630, 0, 522, 523, 524, 525,
+	0, 526, 527, 528, 529, 530, 531, 532, 0, 0,
+	0, 533, 534, 535, 536, 0, 0, 0, 0, 0,
+	879, 537, 631, 538, 539, 880, 881, 0, 882, 0,
+	540, 541, 544, 0, 883, 0, 543, 545, 546, 0,
+	547, 0, 0, 0, 548, 549, 550, 551, 552, 553,
+	554, 0, 555, 557, 556, 0, 559, 884, 558, 0,
+	560, 561, 0, 0, 562, 563, 564, 565, 566, 567,
+	572, 0, 0, 568, 569, 570, 571, 573, 574, 0,
+	575, 576, 578, 581, 577, 579, 580, 582, 583, 596,
+	597, 598, 584, 585, 586, 587, 588, 589, 590, 591,
+	592, 593, 594, 595, 600, 0, 599, 0, 0, 601,
+	602, 603, 604, 605, 606, 612, 615, 617, 618, 613,
+	614, 616, 619, 620, 621, 623, 624, 609, 610, 611,
+	0, 622, 607, 0, 608, 0, 0, 625, 626, 627,
+	628, 0, 885, 629, 886, 632, 633, 0, 0, 634,
+	0, 635, 636, 0, 0, 638, 639, 640, 0, 0,
+	641, 642, 887, 0, 643, 0, 888, 644, 645, 637,
+	646, 647, 648, 649, 650, 651, 652, 653, 654, 655,
+	656, 657, 0, 658, 659, 889, 660, 661, 662, 663,
+	664, 890, 665, 666, 667, 891, 668, 892, 669, 670,
+	671, 0, 672, 673, 674, 0, 675, 676, 677, 678,
+	679, 680, 681, 682, 683, 684, 893, 685, 686, 688,
+	687, 689, 690, 0, 691, 692, 0, 693, 694, 695,
+	0, 0, 0, 0, 0, 696, 697, 699, 0, 700,
+	701, 702, 703, 704, 705, 698, 706, 707, 708, 709,
+	710, 711, 712, 713, 0, 715, 716, 714, 717, 718,
+	0, 719, 720, 721, 722, 723, 894, 724, 0, 725,
+	726, 734, 735, 736, 727, 728, 730, 737, 729, 738,
+	739, 740, 741, 743, 742, 0, 745, 746, 744, 747,
+	748, 749, 750, 0, 751, 895, 752, 731, 732, 753,
+	754, 755, 0, 756, 757, 758, 759, 760, 761, 762,
+	763, 764, 896, 0, 766, 0, 765, 767, 768, 769,
+	770, 771, 772, 773, 775, 733, 776, 777, 778, 783,
+	784, 785, 897, 779, 780, 781, 782, 787, 898, 788,
+	789, 790, 791, 0, 792, 793, 0, 786, 774, 0,
+	794, 795, 796, 797, 798, 799, 800, 801, 802, 803,
+	0, 804, 899, 900, 901, 902, 0, 817, 0, 805,
+	807, 808, 809, 810, 903, 811, 812, 904, 0, 813,
+	814, 815, 816, 806, 819, 820, 818, 0, 0, 821,
+	822, 823, 824, 826, 828, 829, 830, 825, 827, 831,
+	0, 832, 0, 0, 833, 834, 835, 905, 906, 907,
+	0, 908, 838, 839, 836, 837, 840, 841, 844, 842,
+	843, 909, 847, 542, 848, 849, 850, 845, 846, 1726,
+	0, 359, 0, 851, 852, 910, 853, 854, 855, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 367, 368,
+	370, 369, 371, 372, 373, 374, 0, 375, 376, 0,
+	0, 0, 0, 0, 856, 0, 0, 0, 378, 0,
+	377, 0, 379, 380, 381, 0, 382, 383, 384, 385,
+	386, 387, 388, 389, 390, 857, 391, 858, 0, 392,
+	859, 393, 860, 0, 861, 394, 395, 396, 397, 398,
+	399, 400, 401, 402, 403, 404, 0, 0, 0, 405,
+	862, 863, 864, 0, 406, 407, 408, 409, 865, 0,
+	0, 0, 410, 411, 412, 413, 414, 415, 416, 417,
+	0, 0, 419, 420, 421, 418, 422, 423, 0, 424,
+	0, 425, 426, 427, 428, 429, 0, 430, 431, 0,
+	432, 433, 434, 0, 435, 436, 437, 0, 0, 0,
+	0, 0, 0, 0, 438, 439, 440, 441, 442, 0,
+	443, 445, 866, 867, 0, 448, 450, 444, 446, 0,
+	449, 447, 451, 452, 0, 453, 454, 455, 456, 457,
+	0, 0, 0, 458, 459, 460, 461, 0, 462, 463,
+	464, 466, 465, 0, 467, 468, 469, 0, 470, 471,
+	868, 472, 473, 474, 476, 478, 475, 477, 479, 480,
+	481, 482, 483, 869, 870, 484, 485, 0, 0, 0,
+	0, 0, 0, 0, 486, 487, 488, 871, 0, 0,
+	0, 489, 0, 491, 495, 496, 492, 493, 494, 497,
+	0, 490, 498, 499, 0, 0, 500, 501, 502, 872,
+	873, 503, 504, 505, 506, 507, 508, 509, 510, 511,
+	0, 512, 513, 874, 0, 875, 514, 0, 515, 516,
+	517, 518, 519, 520, 521, 1725, 877, 878, 630, 0,
+	522, 523, 524, 525, 0, 526, 527, 528, 529, 530,
+	531, 532, 0, 0, 0, 533, 534, 535, 536, 0,
+	0, 0, 0, 0, 879, 537, 631, 538, 539, 880,
+	881, 0, 882, 0, 540, 541, 544, 0, 883, 0,
+	543, 545, 546, 0, 547, 0, 0, 0, 548, 549,
+	550, 551, 552, 553, 554, 0, 555, 557, 556, 0,
+	559, 884, 558, 0, 560, 561, 0, 0, 562, 563,
+	564, 565, 566, 567, 572, 0, 0, 568, 569, 570,
+	571, 573, 574, 0, 575, 576, 578, 581, 577, 579,
+	580, 582, 583, 596, 597, 598, 584, 585, 586, 587,
+	588, 589, 590, 591, 592, 593, 594, 595, 600, 0,
+	599, 0, 0, 601, 602, 603, 604, 605, 606, 612,
+	615, 617, 618, 613, 614, 616, 619, 620, 621, 623,
+	624, 609, 610, 611, 0, 622, 607, 0, 608, 0,
+	0, 625, 626, 627, 628, 0, 885, 629, 886, 632,
+	633, 0, 0, 634, 0, 635, 636, 0, 0, 638,
+	639, 640, 0, 0, 641, 642, 887, 0, 643, 0,
+	888, 644, 645, 637, 646, 647, 648, 649, 650, 651,
+	652, 653, 654, 655, 656, 657, 0, 658, 659, 889,
+	660, 661, 662, 663, 664, 890, 665, 666, 667, 891,
+	668, 892, 669, 670, 671, 0, 672, 673, 674, 0,
+	675, 676, 677, 678, 679, 680, 681, 682, 683, 684,
+	893, 685, 686, 688, 687, 689, 690, 0, 691, 692,
+	0, 693, 694, 695, 0, 0, 0, 0, 0, 696,
+	697, 699, 0, 700, 701, 702, 703, 704, 705, 698,
+	706, 707, 708, 709, 710, 711, 712, 713, 0, 715,
+	716, 714, 717, 718, 0, 719, 720, 721, 722, 723,
+	894, 724, 0, 725, 726, 734, 735, 736, 727, 728,
+	730, 737, 729, 738, 739, 740, 741, 743, 742, 0,
+	745, 746, 744, 747, 748, 749, 750, 0, 751, 895,
+	752, 731, 732, 753, 754, 755, 0, 756, 757, 758,
+	759, 760, 761, 762, 763, 764, 896, 0, 766, 0,
+	765, 767, 768, 769, 770, 771, 772, 773, 775, 733,
+	776, 777, 778, 783, 784, 785, 897, 779, 780, 781,
+	782, 787, 898, 788, 789, 790, 791, 0, 792, 793,
+	0, 786, 774, 0, 794, 795, 796, 797, 798, 799,
+	800, 801, 802, 803, 0, 804, 899, 900, 901, 902,
+	0, 817, 0, 805, 807, 808, 809, 810, 903, 811,
+	812, 904, 0, 813, 814, 815, 816, 806, 819, 820,
+	818, 0, 0, 821, 822, 823, 824, 826, 828, 829,
+	830, 825, 827, 831, 0, 832, 0, 0, 833, 834,
+	835, 905, 906, 907, 0, 908, 838, 839, 836, 837,
+	840, 841, 844, 842, 843, 909, 847, 542, 848, 849,
+	850, 845, 846, 1689, 0, 359, 0, 851, 852, 910,
+	853, 854, 855, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 367, 368, 370, 369, 371, 372, 373, 374,
+	0, 375, 376, 0, 0, 0, 0, 0, 856, 0,
+	0, 0, 378, 0, 377, 0, 379, 380, 381, 0,
+	382, 383, 384, 385, 386, 387, 388, 389, 390, 857,
+	391, 858, 0, 392, 859, 393, 860, 0, 861, 394,
+	395, 396, 397, 398, 399, 400, 401, 402, 403, 404,
+	0, 0, 0, 405, 862, 863, 864, 0, 406, 407,
+	408, 409, 865, 0, 0, 0, 410, 411, 412, 413,
+	414, 415, 416, 417, 0, 0, 419, 420, 421, 418,
+	422, 423, 0, 424, 0, 425, 426, 427, 428, 429,
+	0, 430, 431, 0, 432, 433, 434, 0, 435, 436,
+	437, 0, 0, 0, 0, 0, 0, 0, 438, 439,
+	440, 441, 442, 0, 443, 445, 866, 867, 0, 448,
+	450, 444, 446, 0, 449, 447, 451, 452, 0, 453,
+	454, 455, 456, 457, 0, 0, 0, 458, 459, 460,
+	461, 0, 462, 463, 464, 466, 465, 0, 467, 468,
+	469, 0, 470, 471, 868, 472, 473, 474, 476, 478,
+	475, 477, 479, 480, 481, 482, 483, 869, 870, 484,
+	485, 0, 0, 0, 0, 0, 0, 0, 486, 487,
+	488, 871, 0, 0, 0, 489, 0, 491, 495, 496,
+	492, 493, 494, 497, 0, 490, 498, 499, 0, 0,
+	500, 501, 502, 872, 873, 503, 504, 505, 506, 507,
+	508, 509, 510, 511, 0, 512, 513, 874, 0, 875,
+	514, 0, 515, 516, 517, 518, 519, 520, 521, 1688,
+	877, 878, 630, 0, 522, 523, 524, 525, 0, 526,
+	527, 528, 529, 530, 531, 532, 0, 0, 0, 533,
+	534, 535, 536, 0, 0, 0, 0, 0, 879, 537,
+	631, 538, 539, 880, 881, 0, 882, 0, 540, 541,
+	544, 0, 883, 0, 543, 545, 546, 0, 547, 0,
+	0, 0, 548, 549, 550, 551, 552, 553, 554, 0,
+	555, 557, 556, 0, 559, 884, 558, 0, 560, 561,
+	0, 0, 562, 563, 564, 565, 566, 567, 572, 0,
+	0, 568, 569, 570, 571, 573, 574, 0, 575, 576,
+	578, 581, 577, 579, 580, 582, 583, 596, 597, 598,
+	584, 585, 586, 587, 588, 589, 590, 591, 592, 593,
+	594, 595, 600, 0, 599, 0, 0, 601, 602, 603,
+	604, 605, 606, 612, 615, 617, 618, 613, 614, 616,
+	619, 620, 621, 623, 624, 609, 610, 611, 0, 622,
+	607, 0, 608, 0, 0, 625, 626, 627, 628, 0,
+	885, 629, 886, 632, 633, 0, 0, 634, 0, 635,
+	636, 0, 0, 638, 639, 640, 0, 0, 641, 642,
+	887, 0, 643, 0, 888, 644, 645, 637, 646, 647,
+	648, 649, 650, 651, 652, 653, 654, 655, 656, 657,
+	0, 658, 659, 889, 660, 661, 662, 663, 664, 890,
+	665, 666, 667, 891, 668, 892, 669, 670, 671, 0,
+	672, 673, 674, 0, 675, 676, 677, 678, 679, 680,
+	681, 682, 683, 684, 893, 685, 686, 688, 687, 689,
+	690, 0, 691, 692, 0, 693, 694, 695, 0, 0,
+	0, 0, 0, 696, 697, 699, 0, 700, 701, 702,
+	703, 704, 705, 698, 706, 707, 708, 709, 710, 711,
+	712, 713, 0, 715, 716, 714, 717, 718, 0, 719,
+	720, 721, 722, 723, 894, 724, 0, 725, 726, 734,
+	735, 736, 727, 728, 730, 737, 729, 738, 739, 740,
+	741, 743, 742, 0, 745, 746, 744, 747, 748, 749,
+	750, 0, 751, 895, 752, 731, 732, 753, 754, 755,
+	0, 756, 757, 758, 759, 760, 761, 762, 763, 764,
+	896, 0, 766, 0, 765, 767, 768, 769, 770, 771,
+	772, 773, 775, 733, 776, 777, 778, 783, 784, 785,
+	897, 779, 780, 781, 782, 787, 898, 788, 789, 790,
+	791, 0, 792, 793, 0, 786, 774, 0, 794, 795,
+	796, 797, 798, 799, 800, 801, 802, 803, 0, 804,
+	899, 900, 901, 902, 0, 817, 0, 805, 807, 808,
+	809, 810, 903, 811, 812, 904, 0, 813, 814, 815,
+	816, 806, 819, 820, 818, 0, 0, 821, 822, 823,
+	824, 826, 828, 829, 830, 825, 827, 831, 0, 832,
+	0, 0, 833, 834, 835, 905, 906, 907, 0, 908,
+	838, 839, 836, 837, 840, 841, 844, 842, 843, 909,
+	847, 542, 848, 849, 850, 845, 846, 1678, 0, 359,
+	0, 851, 852, 910, 853, 854, 855, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 367, 368, 370, 369,
+	371, 372, 373, 374, 0, 375, 376, 0, 0, 0,
+	0, 0, 856, 0, 0, 0, 378, 0, 377, 0,
+	379, 380, 381, 0, 382, 383, 384, 385, 386, 387,
+	388, 389, 390, 857, 391, 858, 0, 392, 859, 393,
+	860, 0, 861, 394, 395, 396, 397, 398, 399, 400,
+	401, 402, 403, 404, 0, 0, 0, 405, 862, 863,
+	864, 0, 406, 407, 408, 409, 865, 0, 0, 0,
+	410, 411, 412, 413, 414, 415, 416, 417, 0, 0,
+	419, 420, 421, 418, 422, 423, 0, 424, 0, 425,
+	426, 427, 428, 429, 0, 430, 431, 0, 432, 433,
+	434, 0, 435, 436, 437, 0, 0, 0, 0, 0,
+	0, 0, 438, 439, 440, 441, 442, 0, 443, 445,
+	866, 867, 0, 448, 450, 444, 446, 0, 449, 447,
+	451, 452, 0, 453, 454, 455, 456, 457, 0, 0,
+	0, 458, 459, 460, 461, 0, 462, 463, 464, 466,
+	465, 0, 467, 468, 469, 0, 470, 471, 868, 472,
+	473, 474, 476, 478, 475, 477, 479, 480, 481, 482,
+	483, 869, 870, 484, 485, 0, 0, 0, 0, 0,
+	0, 0, 486, 487, 488, 871, 0, 0, 0, 489,
+	0, 491, 495, 496, 492, 493, 494, 497, 0, 490,
+	498, 499, 0, 0, 500, 501, 502, 872, 873, 503,
+	504, 505, 506, 507, 508, 509, 510, 511, 0, 512,
+	513, 874, 0, 875, 514, 0, 515, 516, 517, 518,
+	519, 520, 521, 1677, 877, 878, 630, 0, 522, 523,
+	524, 525, 0, 526, 527, 528, 529, 530, 531, 532,
+	0, 0, 0, 533, 534, 535, 536, 0, 0, 0,
+	0, 0, 879, 537, 631, 538, 539, 880, 881, 0,
+	882, 0, 540, 541, 544, 0, 883, 0, 543, 545,
+	546, 0, 547, 0, 0, 0, 548, 549, 550, 551,
+	552, 553, 554, 0, 555, 557, 556, 0, 559, 884,
+	558, 0, 560, 561, 0, 0, 562, 563, 564, 565,
+	566, 567, 572, 0, 0, 568, 569, 570, 571, 573,
+	574, 0, 575, 576, 578, 581, 577, 579, 580, 582,
+	583, 596, 597, 598, 584, 585, 586, 587, 588, 589,
+	590, 591, 592, 593, 594, 595, 600, 0, 599, 0,
+	0, 601, 602, 603, 604, 605, 606, 612, 615, 617,
+	618, 613, 614, 616, 619, 620, 621, 623, 624, 609,
+	610, 611, 0, 622, 607, 0, 608, 0, 0, 625,
+	626, 627, 628, 0, 885, 629, 886, 632, 633, 0,
+	0, 634, 0, 635, 636, 0, 0, 638, 639, 640,
+	0, 0, 641, 642, 887, 0, 643, 0, 888, 644,
+	645, 637, 646, 647, 648, 649, 650, 651, 652, 653,
+	654, 655, 656, 657, 0, 658, 659, 889, 660, 661,
+	662, 663, 664, 890, 665, 666, 667, 891, 668, 892,
+	669, 670, 671, 0, 672, 673, 674, 0, 675, 676,
+	677, 678, 679, 680, 681, 682, 683, 684, 893, 685,
+	686, 688, 687, 689, 690, 0, 691, 692, 0, 693,
+	694, 695, 0, 0, 0, 0, 0, 696, 697, 699,
+	0, 700, 701, 702, 703, 704, 705, 698, 706, 707,
+	708, 709, 710, 711, 712, 713, 0, 715, 716, 714,
+	717, 718, 0, 719, 720, 721, 722, 723, 894, 724,
+	0, 725, 726, 734, 735, 736, 727, 728, 730, 737,
+	729, 738, 739, 740, 741, 743, 742, 0, 745, 746,
+	744, 747, 748, 749, 750, 0, 751, 895, 752, 731,
+	732, 753, 754, 755, 0, 756, 757, 758, 759, 760,
+	761, 762, 763, 764, 896, 0, 766, 0, 765, 767,
+	768, 769, 770, 771, 772, 773, 775, 733, 776, 777,
+	778, 783, 784, 785, 897, 779, 780, 781, 782, 787,
+	898, 788, 789, 790, 791, 0, 792, 793, 0, 786,
+	774, 0, 794, 795, 796, 797, 798, 799, 800, 801,
+	802, 803, 0, 804, 899, 900, 901, 902, 0, 817,
+	0, 805, 807, 808, 809, 810, 903, 811, 812, 904,
+	0, 813, 814, 815, 816, 806, 819, 820, 818, 0,
+	0, 821, 822, 823, 824, 826, 828, 829, 830, 825,
+	827, 831, 0, 832, 0, 0, 833, 834, 835, 905,
+	906, 907, 0, 908, 838, 839, 836, 837, 840, 841,
+	844, 842, 843, 909, 847, 542, 848, 849, 850, 845,
+	846, 359, 0, 0, 0, 851, 852, 910, 853, 854,
+	855, 0, 0, 0, 0, 0, 0, 0, 367, 368,
+	370, 369, 371, 372, 373, 374, 1649, 375, 376, 0,
+	0, 0, 0, 0, 856, 0, 0, 0, 378, 0,
+	377, 0, 379, 380, 381, 0, 382, 383, 384, 385,
+	386, 387, 388, 389, 390, 857, 391, 858, 0, 392,
+	859, 393, 860, 0, 861, 394, 395, 396, 397, 398,
+	399, 400, 401, 402, 403, 404, 0, 0, 0, 405,
+	862, 863, 864, 0, 406, 407, 408, 409, 865, 0,
+	0, 0, 410, 411, 412, 413, 414, 415, 416, 417,
+	0, 0, 419, 420, 421, 418, 422, 423, 0, 424,
+	0, 425, 426, 427, 428, 429, 0, 430, 431, 0,
+	432, 433, 434, 0, 435, 436, 437, 0, 0, 0,
+	0, 0, 0, 0, 438, 439, 440, 441, 442, 0,
+	443, 445, 866, 867, 0, 448, 450, 444, 446, 0,
+	449, 447, 451, 452, 0, 453, 454, 455, 456, 457,
+	0, 0, 0, 458, 459, 460, 461, 0, 462, 463,
+	464, 466, 465, 0, 467, 468, 469, 0, 470, 471,
+	868, 472, 473, 474, 476, 478, 475, 477, 479, 480,
+	481, 482, 483, 869, 870, 484, 485, 0, 0, 0,
+	0, 0, 0, 0, 486, 487, 488, 871, 0, 0,
+	0, 489, 0, 491, 495, 496, 492, 493, 494, 497,
+	0, 490, 498, 499, 0, 0, 500, 501, 502, 872,
+	873, 503, 504, 505, 506, 507, 508, 509, 510, 511,
+	0, 512, 513, 874, 0, 875, 514, 0, 515, 516,
+	517, 518, 519, 520, 521, 876, 877, 878, 630, 0,
+	522, 523, 524, 525, 0, 526, 527, 528, 529, 530,
+	531, 532, 0, 0, 0, 533, 534, 535, 536, 0,
+	0, 0, 0, 0, 879, 537, 631, 538, 539, 880,
+	881, 0, 882, 0, 540, 541, 544, 0, 883, 0,
+	543, 545, 546, 0, 547, 0, 0, 0, 548, 549,
+	550, 551, 552, 553, 554, 0, 555, 557, 556, 0,
+	559, 884, 558, 0, 560, 561, 0, 0, 562, 563,
+	564, 565, 566, 567, 572, 0, 0, 568, 569, 570,
+	571, 573, 574, 0, 575, 576, 578, 581, 577, 579,
+	580, 582, 583, 596, 597, 598, 584, 585, 586, 587,
+	588, 589, 590, 591, 592, 593, 594, 595, 600, 0,
+	599, 0, 0, 601, 602, 603, 604, 605, 606, 612,
+	615, 617, 618, 613, 614, 616, 619, 620, 621, 623,
+	624, 609, 610, 611, 0, 622, 607, 0, 608, 0,
+	0, 625, 626, 627, 628, 0, 885, 629, 886, 632,
+	633, 0, 0, 634, 0, 635, 636, 0, 0, 638,
+	639, 640, 0, 0, 641, 642, 887, 0, 643, 0,
+	888, 644, 645, 637, 646, 647, 648, 649, 650, 651,
+	652, 653, 654, 655, 656, 657, 0, 658, 659, 889,
+	660, 661, 662, 663, 664, 890, 665, 666, 667, 891,
+	668, 892, 669, 670, 671, 0, 672, 673, 674, 0,
+	675, 676, 677, 678, 679, 680, 681, 682, 683, 684,
+	893, 685, 686, 688, 687, 689, 690, 0, 691, 692,
+	0, 693, 694, 695, 0, 0, 0, 0, 0, 696,
+	697, 699, 0, 700, 701, 702, 703, 704, 705, 698,
+	706, 707, 708, 709, 710, 711, 712, 713, 0, 715,
+	716, 714, 717, 718, 0, 719, 720, 721, 722, 723,
+	894, 724, 0, 725, 726, 734, 735, 736, 727, 728,
+	730, 737, 729, 738, 739, 740, 741, 743, 742, 0,
+	745, 746, 744, 747, 748, 749, 750, 0, 751, 895,
+	752, 731, 732, 753, 754, 755, 0, 756, 757, 758,
+	759, 760, 761, 762, 763, 764, 896, 0, 766, 0,
+	765, 767, 768, 769, 770, 771, 772, 773, 775, 733,
+	776, 777, 778, 783, 784, 785, 897, 779, 780, 781,
+	782, 787, 898, 788, 789, 790, 791, 0, 792, 793,
+	0, 786, 774, 0, 794, 795, 796, 797, 798, 799,
+	800, 801, 802, 803, 0, 804, 899, 900, 901, 902,
+	0, 817, 0, 805, 807, 808, 809, 810, 903, 811,
+	812, 904, 0, 813, 814, 815, 816, 806, 819, 820,
+	818, 0, 0, 821, 822, 823, 824, 826, 828, 829,
+	830, 825, 827, 831, 0, 832, 0, 0, 833, 834,
+	835, 905, 906, 907, 0, 908, 838, 839, 836, 837,
+	840, 841, 844, 842, 843, 909, 847, 542, 848, 849,
+	850, 845, 846, 1062, 0, 359, 0, 851, 852, 910,
+	853, 854, 855, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 367, 368, 370, 369, 371, 372, 373, 374,
+	0, 375, 376, 0, 0, 0, 0, 0, 856, 0,
+	0, 0, 378, 0, 377, 0, 379, 380, 381, 0,
+	382, 383, 384, 385, 386, 387, 388, 389, 390, 857,
+	391, 858, 0, 392, 859, 393, 860, 0, 861, 394,
+	395, 396, 397, 398, 399, 400, 401, 402, 403, 404,
+	0, 0, 0, 405, 862, 863, 864, 0, 406, 407,
+	408, 409, 865, 0, 0, 0, 410, 411, 412, 413,
+	414, 415, 416, 417, 0, 0, 419, 420, 421, 418,
+	422, 423, 0, 424, 0, 425, 426, 427, 428, 429,
+	0, 430, 431, 0, 432, 433, 434, 0, 435, 436,
+	437, 0, 0, 0, 0, 0, 0, 0, 438, 439,
+	440, 441, 442, 0, 443, 445, 866, 867, 0, 448,
+	450, 444, 446, 0, 449, 447, 451, 452, 0, 453,
+	454, 455, 456, 457, 0, 0, 0, 458, 459, 460,
+	461, 0, 462, 463, 464, 466, 465, 0, 467, 468,
+	469, 0, 470, 471, 868, 472, 473, 474, 476, 478,
+	475, 477, 479, 480, 481, 482, 483, 869, 870, 484,
+	485, 0, 0, 0, 0, 0, 0, 0, 486, 487,
+	488, 871, 0, 0, 0, 489, 0, 491, 495, 496,
+	492, 493, 494, 497, 0, 490, 498, 499, 0, 0,
+	500, 501, 502, 872, 873, 503, 504, 505, 506, 507,
+	508, 509, 510, 511, 0, 512, 513, 874, 0, 875,
+	514, 0, 515, 516, 517, 518, 519, 520, 521, 876,
+	877, 878, 630, 0, 522, 523, 524, 525, 0, 526,
+	527, 528, 529, 530, 531, 532, 0, 0, 0, 533,
+	534, 535, 536, 0, 0, 0, 0, 0, 879, 537,
+	631, 538, 539, 880, 881, 0, 882, 0, 540, 541,
+	544, 0, 883, 0, 543, 545, 546, 0, 547, 0,
+	0, 0, 548, 549, 550, 551, 552, 553, 554, 0,
+	555, 557, 556, 0, 559, 884, 558, 0, 560, 561,
+	0, 0, 562, 563, 564, 565, 566, 567, 572, 0,
+	0, 568, 569, 570, 571, 573, 574, 0, 575, 576,
+	578, 581, 577, 579, 580, 582, 583, 596, 597, 598,
+	584, 585, 586, 587, 588, 589, 590, 591, 592, 593,
+	594, 595, 600, 0, 599, 0, 0, 601, 602, 603,
+	604, 605, 606, 612, 615, 617, 618, 613, 614, 616,
+	619, 620, 621, 623, 624, 609, 610, 611, 0, 622,
+	607, 0, 608, 0, 0, 625, 626, 627, 628, 0,
+	885, 629, 886, 632, 633, 0, 0, 634, 0, 635,
+	636, 0, 0, 638, 639, 640, 0, 0, 641, 642,
+	887, 0, 643, 0, 888, 644, 645, 637, 646, 647,
+	648, 649, 650, 651, 652, 653, 654, 655, 656, 657,
+	0, 658, 659, 889, 660, 661, 662, 663, 664, 890,
+	665, 666, 667, 891, 668, 892, 669, 670, 671, 0,
+	672, 673, 674, 0, 675, 676, 677, 678, 679, 680,
+	681, 682, 683, 684, 893, 685, 686, 688, 687, 689,
+	690, 0, 691, 692, 0, 693, 694, 695, 0, 0,
+	0, 0, 0, 696, 697, 699, 0, 700, 701, 702,
+	703, 704, 705, 698, 706, 707, 708, 709, 710, 711,
+	712, 713, 0, 715, 716, 714, 717, 718, 0, 719,
+	720, 721, 722, 723, 894, 724, 0, 725, 726, 734,
+	735, 736, 727, 728, 730, 737, 729, 738, 739, 740,
+	741, 743, 742, 0, 745, 746, 744, 747, 748, 749,
+	750, 0, 751, 895, 752, 731, 732, 753, 754, 755,
+	0, 756, 757, 758, 759, 760, 761, 762, 763, 764,
+	896, 0, 766, 0, 765, 767, 768, 769, 770, 771,
+	772, 773, 775, 733, 776, 777, 778, 783, 784, 785,
+	897, 779, 780, 781, 782, 787, 898, 788, 789, 790,
+	791, 0, 792, 793, 0, 786, 774, 0, 794, 795,
+	796, 797, 798, 799, 800, 801, 802, 803, 0, 804,
+	899, 900, 901, 902, 0, 817, 0, 805, 807, 808,
+	809, 810, 903, 811, 812, 904, 0, 813, 814, 815,
+	816, 806, 819, 820, 818, 0, 0, 821, 822, 823,
+	824, 826, 828, 829, 830, 825, 827, 831, 0, 832,
+	0, 0, 833, 834, 835, 905, 906, 907, 0, 908,
+	838, 839, 836, 837, 840, 841, 844, 842, 843, 909,
+	847, 542, 848, 849, 850, 845, 846, 1039, 0, 359,
+	0, 851, 852, 910, 853, 854, 855, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 367, 368, 370, 369,
+	371, 372, 373, 374, 0, 375, 376, 0, 0, 0,
+	0, 0, 856, 0, 0, 0, 378, 0, 377, 0,
+	379, 380, 381, 0, 382, 383, 384, 385, 386, 387,
+	388, 389, 390, 857, 391, 858, 0, 392, 859, 393,
+	860, 0, 861, 394, 395, 396, 397, 398, 399, 400,
+	401, 402, 403, 404, 0, 0, 0, 405, 862, 863,
+	864, 0, 406, 407, 1035, 409, 865, 0, 0, 0,
+	410, 411, 412, 413, 414, 415, 416, 417, 0, 0,
+	419, 420, 421, 418, 422, 423, 0, 1034, 0, 425,
+	426, 427, 428, 429, 0, 430, 431, 0, 432, 433,
+	434, 0, 435, 436, 437, 0, 0, 0, 0, 0,
+	0, 0, 438, 439, 440, 441, 442, 0, 443, 445,
+	866, 867, 0, 448, 450, 444, 446, 0, 449, 447,
+	451, 452, 0, 453, 454, 455, 456, 457, 0, 0,
+	0, 458, 459, 460, 461, 0, 462, 463, 464, 466,
+	465, 0, 467, 468, 469, 0, 470, 471, 868, 472,
+	473, 474, 476, 478, 475, 477, 479, 480, 481, 482,
+	483, 869, 870, 484, 485, 0, 0, 0, 0, 0,
+	0, 0, 486, 487, 488, 871, 0, 0, 0, 489,
+	0, 491, 495, 496, 492, 493, 494, 497, 0, 490,
+	498, 499, 0, 0, 500, 501, 502, 872, 873, 503,
+	504, 505, 506, 507, 508, 509, 510, 511, 0, 512,
+	513, 874, 0, 875, 514, 0, 515, 516, 517, 518,
+	519, 520, 521, 876, 877, 878, 630, 0, 522, 523,
+	524, 525, 0, 526, 527, 528, 529, 530, 531, 532,
+	0, 0, 0, 533, 534, 535, 536, 0, 0, 0,
+	0, 0, 879, 537, 631, 538, 539, 880, 881, 0,
+	882, 0, 540, 541, 544, 0, 883, 0, 543, 545,
+	546, 0, 547, 0, 0, 0, 548, 549, 550, 551,
+	552, 553, 554, 0, 555, 557, 556, 0, 559, 884,
+	558, 0, 560, 561, 0, 0, 562, 563, 564, 565,
+	566, 1040, 572, 0, 0, 568, 569, 570, 571, 573,
+	574, 0, 575, 576, 578, 581, 577, 579, 580, 582,
+	583, 596, 597, 598, 584, 585, 586, 587, 588, 589,
+	590, 591, 592, 593, 594, 595, 600, 0, 1049, 0,
+	0, 601, 602, 603, 604, 605, 606, 612, 615, 617,
+	618, 613, 614, 616, 619, 620, 621, 623, 624, 609,
+	610, 611, 0, 622, 607, 0, 608, 0, 0, 625,
+	626, 627, 628, 0, 885, 629, 886, 632, 633, 0,
+	0, 634, 0, 635, 636, 0, 0, 638, 639, 640,
+	0, 0, 641, 642, 887, 0, 643, 0, 888, 644,
+	645, 637, 646, 647, 648, 649, 650, 651, 652, 653,
+	654, 655, 656, 657, 0, 658, 659, 889, 660, 661,
+	662, 663, 664, 890, 665, 666, 667, 891, 668, 892,
+	669, 670, 671, 0, 672, 673, 674, 0, 675, 676,
+	677, 678, 679, 680, 681, 682, 683, 684, 893, 685,
+	686, 688, 687, 689, 690, 0, 691, 692, 0, 693,
+	694, 695, 0, 0, 0, 0, 0, 696, 697, 699,
+	0, 700, 701, 702, 703, 704, 705, 698, 706, 707,
+	708, 709, 710, 711, 712, 713, 0, 715, 716, 714,
+	717, 718, 0, 1048, 720, 721, 722, 723, 1036, 724,
+	0, 725, 726, 734, 735, 736, 727, 728, 730, 1047,
+	729, 738, 739, 740, 741, 743, 742, 0, 745, 746,
+	744, 747, 748, 1037, 750, 0, 751, 895, 752, 731,
+	732, 753, 754, 755, 0, 756, 757, 758, 759, 760,
+	761, 762, 763, 764, 896, 0, 766, 0, 765, 767,
+	768, 769, 770, 771, 772, 773, 775, 733, 776, 777,
+	778, 783, 784, 785, 897, 779, 780, 781, 782, 787,
+	898, 788, 789, 790, 791, 0, 792, 793, 0, 786,
+	774, 0, 794, 795, 796, 797, 798, 799, 800, 801,
+	802, 803, 0, 804, 1045, 900, 901, 902, 0, 817,
+	0, 805, 1041, 808, 809, 810, 903, 811, 812, 904,
+	0, 813, 814, 815, 816, 806, 819, 820, 818, 0,
+	0, 821, 822, 823, 824, 826, 828, 829, 830, 825,
+	827, 831, 0, 832, 0, 0, 833, 834, 835, 905,
+	906, 907, 0, 908, 838, 839, 836, 837, 840, 841,
+	844, 842, 843, 909, 847, 542, 848, 849, 850, 845,
+	846, 1028, 0, 359, 0, 851, 852, 910, 853, 854,
+	855, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	367, 368, 370, 369, 371, 372, 373, 374, 0, 375,
+	376, 0, 0, 0, 0, 0, 856, 0, 0, 0,
+	378, 0, 377, 0, 379, 380, 381, 0, 382, 383,
+	384, 385, 386, 387, 388, 389, 390, 857, 391, 858,
+	0, 392, 859, 393, 860, 0, 861, 394, 395, 396,
+	397, 398, 399, 400, 401, 402, 403, 404, 0, 0,
+	0, 405, 862, 863, 864, 0, 406, 407, 408, 409,
+	865, 0, 0, 0, 410, 411, 412, 413, 414, 415,
+	416, 417, 0, 0, 419, 420, 421, 418, 422, 423,
+	0, 424, 0, 425, 426, 427, 428, 429, 0, 430,
+	431, 0, 432, 433, 434, 0, 435, 436, 437, 0,
+	0, 0, 0, 0, 0, 0, 438, 439, 440, 441,
+	442, 0, 443, 445, 866, 867, 0, 448, 450, 444,
+	446, 0, 449, 447, 451, 452, 0, 453, 454, 455,
+	456, 457, 0, 0, 0, 458, 459, 460, 461, 0,
+	462, 463, 464, 466, 465, 0, 467, 468, 469, 0,
+	470, 471, 868, 472, 473, 474, 476, 478, 475, 477,
+	479, 480, 481, 482, 483, 869, 870, 484, 485, 0,
+	0, 0, 0, 0, 0, 0, 486, 487, 488, 871,
+	0, 0, 0, 489, 0, 491, 495, 496, 492, 493,
+	494, 497, 0, 490, 498, 499, 0, 0, 500, 501,
+	502, 872, 873, 503, 504, 505, 506, 507, 508, 509,
+	510, 511, 0, 512, 513, 874, 0, 875, 514, 0,
+	515, 516, 517, 518, 519, 520, 521, 876, 877, 878,
+	630, 0, 522, 523, 524, 525, 0, 526, 527, 528,
+	529, 530, 531, 532, 0, 0, 0, 533, 534, 535,
+	536, 0, 0, 0, 0, 0, 879, 537, 631, 538,
+	539, 880, 881, 0, 882, 0, 540, 541, 544, 0,
+	883, 0, 543, 545, 546, 0, 547, 0, 0, 0,
+	548, 549, 550, 551, 552, 553, 554, 0, 555, 557,
+	556, 0, 559, 884, 558, 0, 560, 561, 0, 0,
+	562, 563, 564, 565, 566, 567, 572, 0, 0, 568,
+	569, 570, 571, 573, 574, 0, 575, 576, 578, 581,
+	577, 579, 580, 582, 583, 596, 597, 598, 584, 585,
+	586, 587, 588, 589, 590, 591, 592, 593, 594, 595,
+	600, 0, 599, 0, 0, 601, 602, 603, 604, 605,
+	606, 612, 615, 617, 618, 613, 614, 616, 619, 620,
+	621, 623, 624, 609, 610, 611, 0, 622, 607, 0,
+	608, 0, 0, 625, 626, 627, 628, 0, 885, 629,
+	886, 632, 633, 0, 0, 634, 0, 635, 636, 0,
+	0, 638, 639, 640, 0, 0, 641, 642, 887, 0,
+	643, 0, 888, 644, 645, 637, 646, 647, 648, 649,
+	650, 651, 652, 653, 654, 655, 656, 657, 0, 658,
+	659, 889, 660, 661, 662, 663, 664, 890, 665, 666,
+	667, 891, 668, 892, 669, 670, 671, 0, 672, 673,
+	674, 0, 675, 676, 677, 678, 679, 680, 681, 682,
+	683, 684, 893, 685, 686, 688, 687, 689, 690, 0,
+	691, 692, 0, 693, 694, 695, 0, 0, 0, 0,
+	0, 696, 697, 699, 0, 700, 701, 702, 703, 704,
+	705, 698, 706, 707, 708, 709, 710, 711, 712, 713,
+	0, 715, 716, 714, 717, 718, 0, 719, 720, 721,
+	722, 723, 894, 724, 0, 725, 726, 1029, 735, 736,
+	727, 728, 730, 737, 729, 738, 739, 740, 741, 743,
+	742, 0, 745, 746, 744, 747, 748, 749, 750, 0,
+	751, 895, 752, 731, 732, 753, 754, 755, 0, 756,
+	757, 758, 759, 760, 761, 762, 763, 764, 896, 0,
+	766, 0, 765, 767, 768, 769, 770, 771, 772, 773,
+	775, 733, 776, 777, 778, 783, 784, 785, 897, 779,
+	780, 781, 782, 787, 898, 788, 789, 790, 791, 0,
+	792, 793, 0, 786, 774, 0, 794, 795, 796, 797,
+	798, 799, 800, 801, 802, 803, 0, 804, 899, 900,
+	901, 902, 0, 817, 0, 805, 807, 808, 809, 810,
+	903, 811, 812, 904, 0, 813, 814, 815, 816, 806,
+	819, 820, 818, 0, 0, 821, 822, 823, 824, 826,
+	828, 829, 830, 825, 827, 831, 0, 832, 0, 0,
+	833, 834, 835, 905, 906, 907, 0, 908, 838, 839,
+	836, 837, 840, 841, 844, 842, 843, 909, 847, 542,
+	848, 849, 850, 845, 846, 985, 0, 359, 0, 851,
+	852, 910, 853, 854, 855, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 367, 368, 370, 369, 371, 372,
+	373, 374, 0, 375, 376, 0, 0, 0, 0, 0,
+	856, 0, 0, 0, 378, 0, 377, 0, 379, 380,
+	381, 0, 382, 383, 384, 385, 386, 387, 388, 389,
+	390, 857, 391, 858, 0, 392, 859, 393, 860, 0,
+	861, 394, 395, 396, 397, 398, 399, 400, 401, 402,
+	403, 404, 0, 0, 0, 405, 862, 863, 864, 0,
+	406, 407, 408, 409, 865, 0, 0, 0, 410, 411,
+	412, 413, 414, 415, 416, 417, 0, 0, 419, 420,
+	421, 418, 422, 423, 0, 424, 0, 425, 426, 427,
+	428, 429, 0, 430, 431, 0, 432, 433, 434, 0,
+	435, 436, 437, 0, 0, 0, 0, 0, 0, 0,
+	438, 439, 440, 441, 442, 0, 443, 445, 866, 867,
+	0, 448, 450, 444, 446, 0, 449, 447, 451, 452,
+	0, 453, 454, 455, 456, 457, 0, 0, 0, 458,
+	459, 460, 461, 0, 462, 463, 464, 466, 465, 0,
+	467, 468, 469, 0, 470, 471, 868, 472, 473, 474,
+	476, 478, 475, 477, 479, 480, 481, 482, 483, 869,
+	870, 484, 485, 0, 0, 0, 0, 0, 0, 0,
+	486, 487, 488, 871, 0, 0, 0, 489, 0, 491,
+	495, 496, 492, 493, 494, 497, 0, 490, 498, 499,
+	0, 0, 500, 501, 502, 872, 873, 503, 504, 505,
+	506, 507, 508, 509, 510, 511, 0, 512, 513, 874,
+	0, 875, 514, 0, 515, 516, 517, 518, 519, 520,
+	521, 876, 877, 878, 630, 0, 522, 523, 524, 525,
+	0, 526, 527, 528, 529, 530, 531, 532, 0, 0,
+	0, 533, 534, 535, 536, 0, 0, 0, 0, 0,
+	879, 537, 631, 538, 539, 880, 881, 0, 882, 0,
+	540, 541, 544, 0, 883, 0, 543, 545, 546, 0,
+	547, 0, 0, 0, 548, 549, 550, 551, 552, 553,
+	554, 0, 555, 557, 556, 0, 559, 884, 558, 0,
+	560, 561, 0, 0, 562, 563, 564, 565, 566, 567,
+	572, 0, 0, 568, 569, 570, 571, 573, 574, 0,
+	575, 576, 578, 581, 577, 579, 580, 582, 583, 596,
+	597, 598, 584, 585, 586, 587, 588, 589, 590, 591,
+	592, 593, 594, 595, 600, 0, 599, 0, 0, 601,
+	602, 603, 604, 605, 606, 612, 615, 617, 618, 613,
+	614, 616, 619, 620, 621, 623, 624, 609, 610, 611,
+	0, 622, 607, 0, 608, 0, 0, 625, 626, 627,
+	628, 0, 885, 629, 886, 632, 633, 0, 0, 634,
+	0, 635, 636, 0, 0, 638, 639, 640, 0, 0,
+	641, 642, 887, 0, 643, 0, 888, 644, 645, 637,
+	646, 647, 648, 649, 650, 651, 652, 653, 654, 655,
+	656, 657, 0, 658, 659, 889, 660, 661, 662, 663,
+	664, 890, 665, 666, 667, 891, 668, 892, 669, 670,
+	671, 0, 672, 673, 674, 0, 675, 676, 677, 678,
+	679, 680, 681, 682, 683, 684, 893, 685, 686, 688,
+	687, 689, 690, 0, 691, 692, 0, 693, 694, 695,
+	0, 0, 0, 0, 0, 696, 697, 699, 0, 700,
+	701, 702, 703, 704, 705, 698, 706, 707, 708, 709,
+	710, 711, 712, 713, 0, 715, 716, 714, 717, 718,
+	0, 719, 720, 721, 722, 723, 894, 724, 0, 725,
+	726, 734, 735, 736, 727, 728, 730, 737, 729, 738,
+	739, 740, 741, 743, 742, 0, 745, 746, 744, 747,
+	748, 749, 750, 0, 751, 895, 752, 731, 732, 753,
+	754, 755, 0, 756, 757, 758, 759, 760, 761, 762,
+	763, 764, 896, 0, 766, 0, 765, 767, 768, 769,
+	770, 771, 772, 773, 775, 733, 776, 777, 778, 783,
+	784, 785, 897, 779, 780, 781, 782, 787, 898, 788,
+	789, 790, 791, 0, 792, 793, 0, 786, 774, 0,
+	794, 795, 796, 797, 798, 799, 800, 801, 802, 803,
+	0, 804, 899, 900, 901, 902, 0, 817, 0, 805,
+	807, 808, 809, 810, 903, 811, 812, 904, 0, 813,
+	814, 815, 816, 806, 819, 820, 818, 0, 0, 821,
+	822, 823, 824, 826, 828, 829, 830, 825, 827, 831,
+	0, 832, 0, 0, 833, 834, 835, 905, 906, 907,
+	0, 908, 838, 839, 836, 837, 840, 841, 844, 842,
+	843, 909, 847, 542, 848, 849, 850, 845, 846, 976,
+	0, 359, 0, 851, 852, 910, 853, 854, 855, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 367, 368,
+	370, 369, 371, 372, 373, 374, 0, 375, 376, 0,
+	0, 0, 0, 0, 856, 0, 0, 0, 378, 0,
+	377, 0, 379, 380, 381, 0, 382, 383, 384, 385,
+	386, 387, 388, 389, 390, 857, 391, 858, 0, 392,
+	859, 393, 860, 0, 861, 394, 395, 396, 397, 398,
+	399, 400, 401, 402, 403, 404, 0, 0, 0, 405,
+	862, 863, 864, 0, 406, 407, 408, 409, 865, 0,
+	0, 0, 410, 411, 412, 413, 414, 415, 416, 417,
+	0, 0, 419, 420, 421, 418, 422, 423, 0, 424,
+	0, 425, 426, 427, 428, 429, 0, 430, 431, 0,
+	432, 433, 434, 0, 435, 436, 437, 0, 0, 0,
+	0, 0, 0, 0, 438, 439, 440, 441, 442, 0,
+	443, 445, 866, 867, 0, 448, 450, 444, 446, 0,
+	449, 447, 451, 452, 0, 453, 454, 455, 456, 457,
+	0, 0, 0, 458, 459, 460, 461, 0, 462, 463,
+	464, 466, 465, 0, 467, 468, 469, 0, 470, 471,
+	868, 472, 473, 474, 476, 478, 475, 477, 479, 480,
+	481, 482, 483, 869, 870, 484, 485, 0, 0, 0,
+	0, 0, 0, 0, 486, 487, 488, 871, 0, 0,
+	0, 489, 0, 491, 495, 496, 492, 493, 494, 497,
+	0, 490, 498, 499, 0, 0, 500, 501, 502, 872,
+	873, 503, 504, 505, 506, 507, 508, 509, 510, 511,
+	0, 512, 513, 874, 0, 875, 514, 0, 515, 516,
+	517, 518, 519, 520, 521, 876, 877, 878, 630, 0,
+	522, 523, 524, 525, 0, 526, 527, 528, 529, 530,
+	531, 532, 0, 0, 0, 533, 534, 535, 536, 0,
+	0, 0, 0, 0, 879, 537, 631, 538, 539, 880,
+	881, 0, 882, 0, 540, 541, 544, 0, 883, 0,
+	543, 545, 546, 0, 547, 0, 0, 0, 548, 549,
+	550, 551, 552, 553, 554, 0, 555, 557, 556, 0,
+	559, 884, 558, 0, 560, 561, 0, 0, 562, 563,
+	564, 565, 566, 567, 572, 0, 0, 568, 569, 570,
+	571, 573, 574, 0, 575, 576, 578, 581, 577, 579,
+	580, 582, 583, 596, 597, 598, 584, 585, 586, 587,
+	588, 589, 590, 591, 592, 593, 594, 595, 600, 0,
+	599, 0, 0, 601, 602, 603, 604, 605, 606, 612,
+	615, 617, 618, 613, 614, 616, 619, 620, 621, 623,
+	624, 609, 610, 611, 0, 622, 607, 0, 608, 0,
+	0, 625, 626, 627, 628, 0, 885, 629, 886, 632,
+	633, 0, 0, 634, 0, 635, 636, 0, 0, 638,
+	639, 640, 0, 0, 641, 642, 887, 0, 643, 0,
+	888, 644, 645, 637, 646, 647, 648, 649, 650, 651,
+	652, 653, 654, 655, 656, 657, 0, 658, 659, 889,
+	660, 661, 662, 663, 664, 890, 665, 666, 667, 891,
+	668, 892, 669, 670, 671, 0, 672, 673, 674, 0,
+	675, 676, 677, 678, 679, 680, 681, 682, 683, 684,
+	893, 685, 686, 688, 687, 689, 690, 0, 691, 692,
+	0, 693, 694, 695, 0, 0, 0, 0, 0, 696,
+	697, 699, 0, 700, 701, 702, 703, 704, 705, 698,
+	706, 707, 708, 709, 710, 711, 712, 713, 0, 715,
+	716, 714, 717, 718, 0, 719, 720, 721, 722, 723,
+	894, 724, 0, 725, 726, 734, 735, 736, 727, 728,
+	730, 737, 729, 738, 739, 740, 741, 743, 742, 0,
+	745, 746, 744, 747, 748, 749, 750, 0, 751, 895,
+	752, 731, 732, 753, 754, 755, 0, 756, 757, 758,
+	759, 760, 761, 762, 763, 764, 896, 0, 766, 0,
+	765, 767, 768, 769, 770, 771, 772, 773, 775, 733,
+	776, 777, 778, 783, 784, 785, 897, 779, 780, 781,
+	782, 787, 898, 788, 789, 790, 791, 0, 792, 793,
+	0, 786, 774, 0, 794, 795, 796, 797, 798, 799,
+	800, 801, 802, 803, 0, 804, 899, 900, 901, 902,
+	0, 817, 0, 805, 977, 808, 809, 810, 903, 811,
+	812, 904, 0, 813, 814, 815, 816, 806, 819, 820,
+	818, 0, 0, 821, 822, 823, 824, 826, 828, 829,
+	830, 825, 827, 831, 0, 832, 0, 0, 833, 834,
+	835, 905, 906, 907, 0, 908, 838, 839, 836, 837,
+	840, 841, 844, 842, 843, 909, 847, 542, 848, 849,
+	850, 845, 846, 948, 0, 359, 0, 851, 852, 910,
+	853, 854, 855, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 367, 368, 370, 369, 371, 372, 373, 374,
+	0, 375, 376, 0, 0, 0, 0, 0, 856, 0,
+	0, 0, 378, 0, 377, 0, 379, 380, 381, 0,
+	382, 383, 384, 385, 386, 387, 388, 389, 390, 857,
+	391, 858, 0, 392, 859, 393, 860, 0, 861, 394,
+	395, 396, 397, 398, 399, 400, 401, 402, 403, 404,
+	0, 0, 0, 405, 862, 863, 864, 0, 406, 407,
+	408, 409, 865, 0, 0, 0, 410, 411, 412, 413,
+	414, 415, 416, 417, 0, 0, 419, 420, 421, 418,
+	422, 423, 0, 424, 0, 425, 426, 427, 428, 429,
+	0, 430, 431, 0, 432, 433, 434, 0, 435, 436,
+	437, 0, 0, 0, 0, 0, 0, 0, 438, 439,
+	440, 441, 442, 0, 443, 445, 866, 867, 0, 448,
+	450, 444, 446, 0, 449, 447, 451, 452, 0, 453,
+	454, 455, 456, 457, 0, 0, 0, 458, 459, 460,
+	461, 0, 462, 463, 464, 466, 465, 0, 467, 468,
+	469, 0, 470, 471, 868, 472, 473, 474, 476, 478,
+	475, 477, 479, 480, 481, 482, 483, 869, 870, 484,
+	485, 0, 0, 0, 0, 0, 0, 0, 486, 487,
+	488, 871, 0, 0, 0, 489, 0, 491, 495, 496,
+	492, 493, 494, 497, 0, 490, 498, 499, 0, 0,
+	500, 501, 502, 872, 873, 503, 504, 505, 506, 507,
+	508, 509, 510, 511, 0, 512, 513, 874, 0, 875,
+	514, 0, 515, 516, 517, 518, 519, 520, 521, 876,
+	877, 878, 630, 0, 522, 523, 524, 525, 0, 526,
+	527, 528, 529, 530, 531, 532, 0, 0, 0, 533,
+	534, 535, 536, 0, 0, 0, 0, 0, 879, 537,
+	631, 538, 539, 880, 881, 0, 882, 0, 540, 541,
+	544, 0, 883, 0, 543, 545, 546, 0, 547, 0,
+	0, 0, 548, 549, 550, 551, 552, 553, 554, 0,
+	555, 557, 556, 0, 559, 884, 558, 0, 560, 561,
+	0, 0, 562, 563, 564, 565, 566, 567, 572, 0,
+	0, 568, 569, 570, 571, 573, 574, 0, 575, 576,
+	578, 581, 577, 579, 580, 582, 583, 596, 597, 598,
+	584, 585, 586, 587, 588, 589, 590, 591, 592, 593,
+	594, 595, 600, 0, 599, 0, 0, 601, 602, 603,
+	604, 605, 606, 612, 615, 617, 618, 613, 614, 616,
+	619, 620, 621, 623, 624, 609, 610, 611, 0, 622,
+	607, 0, 608, 0, 0, 625, 626, 627, 628, 0,
+	885, 629, 886, 632, 633, 0, 0, 634, 0, 635,
+	636, 0, 0, 638, 639, 640, 0, 0, 641, 642,
+	887, 0, 643, 0, 888, 644, 645, 637, 646, 647,
+	648, 649, 650, 651, 652, 653, 654, 655, 656, 657,
+	0, 658, 659, 889, 660, 661, 662, 663, 664, 890,
+	665, 666, 667, 891, 668, 892, 669, 670, 671, 0,
+	672, 673, 674, 0, 675, 676, 677, 678, 679, 680,
+	681, 682, 683, 684, 893, 685, 686, 688, 687, 689,
+	690, 0, 691, 692, 0, 693, 694, 695, 0, 0,
+	0, 0, 0, 696, 697, 699, 0, 700, 701, 702,
+	703, 704, 705, 698, 706, 707, 708, 709, 710, 711,
+	712, 713, 0, 715, 716, 714, 717, 718, 0, 719,
+	720, 721, 722, 723, 894, 724, 0, 725, 726, 734,
+	735, 736, 727, 728, 730, 737, 729, 738, 739, 740,
+	741, 743, 742, 0, 745, 746, 744, 747, 748, 749,
+	750, 0, 751, 895, 752, 731, 732, 753, 754, 755,
+	0, 756, 757, 758, 759, 760, 761, 762, 763, 764,
+	896, 0, 766, 0, 765, 767, 768, 769, 770, 771,
+	772, 773, 775, 733, 776, 777, 778, 783, 784, 785,
+	897, 779, 780, 781, 782, 787, 898, 788, 789, 790,
+	791, 0, 792, 793, 0, 786, 774, 0, 794, 795,
+	796, 797, 798, 799, 800, 801, 802, 803, 0, 804,
+	899, 900, 901, 902, 0, 817, 0, 805, 807, 808,
+	809, 810, 903, 811, 812, 904, 0, 813, 814, 815,
+	816, 806, 819, 820, 818, 0, 0, 821, 822, 823,
+	824, 826, 828, 829, 830, 825, 827, 831, 0, 832,
+	0, 0, 833, 834, 835, 905, 906, 907, 0, 908,
+	838, 839, 836, 837, 840, 841, 844, 842, 843, 909,
+	847, 542, 848, 849, 850, 845, 846, 359, 0, 0,
+	0, 851, 852, 910, 853, 854, 855, 0, 0, 0,
+	0, 0, 0, 0, 367, 368, 370, 369, 371, 372,
+	373, 374, 0, 375, 376, 0, 0, 0, 0, 0,
+	856, 0, 0, 0, 378, 0, 377, 0, 379, 380,
+	381, 0, 382, 383, 384, 385, 386, 387, 388, 389,
+	390, 857, 391, 858, 0, 392, 859, 393, 860, 0,
+	861, 394, 395, 396, 397, 398, 399, 400, 401, 402,
+	403, 404, 0, 0, 0, 405, 862, 863, 864, 0,
+	406, 407, 408, 409, 865, 0, 0, 0, 410, 411,
+	412, 413, 414, 415, 416, 417, 0, 0, 419, 420,
+	421, 418, 422, 423, 0, 424, 0, 425, 426, 427,
+	428, 429, 0, 430, 431, 0, 432, 433, 434, 0,
+	435, 436, 437, 0, 0, 0, 0, 0, 0, 0,
+	438, 439, 440, 441, 442, 0, 443, 445, 866, 867,
+	0, 448, 450, 444, 446, 0, 449, 447, 451, 452,
+	0, 453, 454, 455, 456, 457, 0, 0, 0, 458,
+	459, 460, 461, 0, 462, 463, 464, 466, 465, 0,
+	467, 468, 469, 0, 470, 471, 868, 472, 473, 474,
+	476, 478, 475, 477, 479, 480, 481, 482, 483, 869,
+	870, 484, 485, 0, 0, 0, 0, 0, 0, 0,
+	486, 487, 488, 871, 0, 0, 0, 489, 0, 491,
+	495, 496, 492, 493, 494, 497, 0, 490, 498, 499,
+	0, 0, 500, 501, 502, 872, 873, 503, 504, 505,
+	506, 507, 508, 509, 510, 511, 0, 512, 513, 874,
+	0, 875, 514, 0, 515, 516, 517, 518, 519, 520,
+	521, 876, 877, 878, 630, 0, 522, 523, 524, 525,
+	0, 526, 527, 528, 529, 530, 531, 532, 0, 0,
+	0, 533, 534, 535, 536, 0, 0, 0, 0, 0,
+	879, 537, 631, 538, 539, 880, 881, 0, 882, 0,
+	540, 541, 544, 0, 883, 0, 543, 545, 546, 0,
+	547, 0, 0, 0, 548, 549, 550, 551, 552, 553,
+	554, 0, 555, 557, 556, 0, 559, 884, 558, 0,
+	560, 561, 0, 0, 562, 563, 564, 565, 566, 567,
+	572, 0, 0, 568, 569, 570, 571, 573, 574, 0,
+	575, 576, 578, 581, 577, 579, 580, 582, 583, 596,
+	597, 598, 584, 585, 586, 587, 588, 589, 590, 591,
+	592, 593, 594, 595, 600, 0, 599, 0, 0, 601,
+	602, 603, 604, 605, 606, 612, 615, 617, 618, 613,
+	614, 616, 619, 620, 621, 623, 624, 609, 610, 611,
+	0, 622, 607, 0, 608, 0, 0, 625, 626, 627,
+	628, 0, 885, 629, 886, 632, 633, 0, 0, 634,
+	0, 635, 636, 0, 0, 638, 639, 640, 0, 0,
+	641, 642, 887, 0, 643, 0, 888, 644, 645, 637,
+	646, 647, 648, 649, 650, 651, 652, 653, 654, 655,
+	656, 657, 0, 658, 659, 889, 660, 661, 662, 663,
+	664, 890, 665, 666, 667, 891, 668, 892, 669, 670,
+	671, 0, 672, 673, 674, 0, 675, 676, 677, 678,
+	679, 680, 681, 682, 683, 684, 893, 685, 686, 688,
+	687, 689, 690, 0, 691, 692, 0, 693, 694, 695,
+	0, 0, 0, 0, 0, 696, 697, 699, 0, 700,
+	701, 702, 703, 704, 705, 698, 706, 707, 708, 709,
+	710, 711, 712, 713, 0, 715, 716, 714, 717, 718,
+	0, 719, 720, 721, 722, 723, 894, 724, 0, 725,
+	726, 734, 735, 736, 727, 728, 730, 737, 729, 738,
+	739, 740, 741, 743, 742, 0, 745, 746, 744, 747,
+	748, 749, 750, 0, 751, 895, 752, 731, 732, 753,
+	754, 755, 0, 756, 757, 758, 759, 760, 761, 762,
+	763, 764, 896, 0, 766, 0, 765, 767, 768, 769,
+	770, 771, 772, 773, 775, 733, 776, 777, 778, 783,
+	784, 785, 897, 779, 780, 781, 782, 787, 898, 788,
+	789, 790, 791, 0, 792, 793, 0, 786, 774, 0,
+	794, 795, 796, 797, 798, 799, 800, 801, 802, 803,
+	0, 804, 899, 900, 901, 902, 0, 817, 0, 805,
+	807, 808, 809, 810, 903, 811, 812, 904, 0, 813,
+	814, 815, 816, 806, 819, 820, 818, 0, 0, 821,
+	822, 823, 824, 826, 828, 829, 830, 825, 827, 831,
+	0, 832, 0, 0, 833, 834, 835, 905, 906, 907,
+	0, 908, 838, 839, 836, 837, 840, 841, 844, 842,
+	843, 909, 847, 542, 848, 849, 850, 845, 846, 359,
+	0, 0, 0, 851, 852, 910, 853, 854, 855, 0,
+	0, 0, 0, 0, 0, 0, 367, 368, 370, 369,
+	371, 372, 373, 374, 0, 375, 376, 0, 0, 0,
+	0, 0, 856, 0, 0, 0, 378, 0, 377, 0,
+	379, 380, 381, 0, 382, 383, 384, 385, 386, 387,
+	388, 389, 390, 857, 391, 858, 0, 392, 859, 393,
+	860, 0, 861, 394, 395, 396, 397, 398, 399, 400,
+	401, 402, 403, 404, 0, 0, 0, 405, 862, 863,
+	864, 0, 406, 407, 408, 409, 865, 0, 0, 0,
+	410, 411, 412, 413, 414, 415, 416, 417, 0, 0,
+	419, 420, 421, 418, 422, 423, 0, 424, 0, 425,
+	426, 427, 428, 429, 0, 430, 431, 0, 432, 433,
+	434, 0, 435, 436, 437, 0, 0, 0, 0, 0,
+	0, 0, 438, 439, 440, 441, 442, 0, 443, 445,
+	866, 867, 0, 448, 450, 444, 446, 0, 449, 447,
+	451, 452, 0, 453, 454, 455, 456, 457, 0, 0,
+	0, 458, 459, 460, 461, 0, 462, 463, 464, 466,
+	465, 0, 467, 468, 469, 0, 470, 471, 868, 472,
+	473, 474, 476, 478, 475, 477, 479, 480, 481, 482,
+	483, 869, 870, 484, 485, 0, 0, 0, 0, 0,
+	0, 0, 486, 487, 488, 871, 0, 0, 0, 489,
+	0, 491, 495, 496, 492, 493, 494, 497, 0, 490,
+	498, 499, 0, 0, 500, 501, 502, 872, 873, 503,
+	504, 505, 506, 507, 508, 509, 510, 511, 0, 512,
+	513, 874, 0, 875, 514, 0, 515, 516, 517, 518,
+	519, 520, 521, 5396, 877, 878, 630, 0, 522, 523,
+	524, 525, 0, 526, 527, 528, 529, 530, 531, 532,
+	0, 0, 0, 533, 534, 535, 536, 0, 0, 0,
+	0, 0, 879, 537, 631, 538, 539, 880, 881, 0,
+	882, 0, 540, 541, 544, 0, 883, 0, 543, 545,
+	546, 0, 547, 0, 0, 0, 548, 549, 550, 551,
+	552, 553, 554, 0, 555, 557, 556, 0, 559, 884,
+	558, 0, 560, 561, 0, 0, 562, 563, 564, 565,
+	566, 567, 572, 0, 0, 568, 569, 570, 571, 573,
+	574, 0, 575, 576, 578, 581, 577, 579, 580, 582,
+	583, 596, 597, 598, 584, 585, 586, 587, 588, 589,
+	590, 591, 592, 593, 594, 595, 600, 0, 599, 0,
+	0, 601, 602, 603, 604, 605, 606, 612, 615, 617,
+	618, 613, 614, 616, 619, 620, 621, 623, 624, 609,
+	610, 611, 0, 622, 607, 0, 608, 0, 0, 625,
+	626, 627, 628, 0, 885, 629, 886, 632, 633, 0,
+	0, 634, 0, 635, 636, 0, 0, 638, 639, 640,
+	0, 0, 641, 642, 887, 0, 643, 0, 888, 644,
+	645, 637, 646, 647, 648, 649, 650, 651, 652, 653,
+	654, 655, 656, 657, 0, 658, 659, 889, 660, 661,
+	662, 663, 664, 890, 665, 666, 667, 891, 668, 892,
+	669, 670, 671, 0, 672, 673, 674, 0, 675, 676,
+	677, 678, 679, 680, 681, 682, 683, 684, 893, 685,
+	686, 688, 687, 689, 690, 0, 691, 692, 0, 693,
+	694, 695, 0, 0, 0, 0, 0, 696, 697, 699,
+	0, 700, 701, 702, 703, 704, 705, 698, 706, 707,
+	708, 709, 710, 711, 712, 713, 0, 715, 716, 714,
+	717, 718, 0, 719, 720, 721, 722, 723, 894, 724,
+	0, 725, 726, 734, 735, 736, 727, 728, 730, 737,
+	729, 738, 739, 740, 741, 743, 742, 0, 745, 746,
+	744, 747, 748, 749, 750, 0, 751, 895, 752, 731,
+	732, 753, 754, 755, 0, 756, 757, 758, 759, 760,
+	761, 762, 763, 764, 896, 0, 766, 0, 765, 767,
+	768, 769, 770, 771, 772, 773, 775, 733, 776, 777,
+	778, 783, 784, 785, 897, 779, 780, 781, 782, 787,
+	898, 788, 789, 790, 791, 0, 792, 793, 0, 786,
+	774, 0, 794, 795, 796, 797, 798, 799, 800, 801,
+	802, 803, 0, 804, 899, 900, 901, 902, 0, 817,
+	0, 805, 807, 808, 809, 810, 903, 811, 812, 904,
+	0, 813, 814, 815, 816, 806, 819, 820, 818, 0,
+	0, 821, 822, 823, 824, 826, 828, 829, 830, 825,
+	827, 831, 0, 832, 0, 0, 833, 834, 835, 905,
+	906, 907, 0, 908, 838, 839, 836, 837, 840, 841,
+	844, 842, 843, 909, 847, 542, 848, 849, 850, 845,
+	846, 359, 0, 0, 0, 851, 852, 910, 853, 854,
+	855, 0, 0, 0, 0, 0, 0, 0, 367, 368,
+	370, 369, 371, 372, 373, 374, 0, 375, 376, 0,
+	0, 0, 0, 0, 856, 0, 0, 0, 378, 0,
+	377, 0, 379, 380, 381, 0, 382, 383, 384, 385,
+	386, 387, 388, 389, 390, 857, 391, 858, 0, 392,
+	859, 393, 860, 0, 861, 394, 395, 396, 397, 398,
+	399, 400, 401, 402, 403, 404, 0, 0, 0, 405,
+	862, 863, 864, 0, 406, 407, 408, 409, 865, 0,
+	0, 0, 410, 411, 412, 413, 414, 415, 416, 417,
+	0, 0, 419, 420, 421, 418, 422, 423, 0, 424,
+	0, 425, 426, 427, 428, 429, 0, 430, 431, 0,
+	432, 433, 434, 0, 435, 436, 437, 0, 0, 0,
+	0, 0, 0, 0, 438, 439, 440, 441, 442, 0,
+	443, 445, 866, 867, 0, 448, 450, 444, 446, 0,
+	449, 447, 451, 452, 0, 453, 454, 455, 456, 457,
+	0, 0, 0, 458, 459, 460, 461, 0, 462, 463,
+	464, 466, 465, 0, 467, 468, 469, 0, 470, 471,
+	868, 472, 473, 474, 476, 478, 475, 477, 479, 480,
+	481, 482, 483, 869, 870, 484, 485, 0, 0, 0,
+	0, 0, 0, 0, 486, 487, 488, 871, 0, 0,
+	0, 489, 0, 491, 495, 496, 492, 493, 494, 497,
+	0, 490, 498, 499, 0, 0, 500, 501, 502, 872,
+	873, 503, 504, 505, 506, 507, 508, 509, 510, 511,
+	0, 512, 513, 874, 0, 875, 514, 0, 515, 516,
+	517, 518, 519, 520, 521, 5394, 877, 878, 630, 0,
+	522, 523, 524, 525, 0, 526, 527, 528, 529, 530,
+	531, 532, 0, 0, 0, 533, 534, 535, 536, 0,
+	0, 0, 0, 0, 879, 537, 631, 538, 539, 880,
+	881, 0, 882, 0, 540, 541, 544, 0, 883, 0,
+	543, 545, 546, 0, 547, 0, 0, 0, 548, 549,
+	550, 551, 552, 553, 554, 0, 555, 557, 556, 0,
+	559, 884, 558, 0, 560, 561, 0, 0, 562, 563,
+	564, 565, 566, 567, 572, 0, 0, 568, 569, 570,
+	571, 573, 574, 0, 575, 576, 578, 581, 577, 579,
+	580, 582, 583, 596, 597, 598, 584, 585, 586, 587,
+	588, 589, 590, 591, 592, 593, 594, 595, 600, 0,
+	599, 0, 0, 601, 602, 603, 604, 605, 606, 612,
+	615, 617, 618, 613, 614, 616, 619, 620, 621, 623,
+	624, 609, 610, 611, 0, 622, 607, 0, 608, 0,
+	0, 625, 626, 627, 628, 0, 885, 629, 886, 632,
+	633, 0, 0, 634, 0, 635, 636, 0, 0, 638,
+	639, 640, 0, 0, 641, 642, 887, 0, 643, 0,
+	888, 644, 645, 637, 646, 647, 648, 649, 650, 651,
+	652, 653, 654, 655, 656, 657, 0, 658, 659, 889,
+	660, 661, 662, 663, 664, 890, 665, 666, 667, 891,
+	668, 892, 669, 670, 671, 0, 672, 673, 674, 0,
+	675, 676, 677, 678, 679, 680, 681, 682, 683, 684,
+	893, 685, 686, 688, 687, 689, 690, 0, 691, 692,
+	0, 693, 694, 695, 0, 0, 0, 0, 0, 696,
+	697, 699, 0, 700, 701, 702, 703, 704, 705, 698,
+	706, 707, 708, 709, 710, 711, 712, 713, 0, 715,
+	716, 714, 717, 718, 0, 719, 720, 721, 722, 723,
+	894, 724, 0, 725, 726, 734, 735, 736, 727, 728,
+	730, 737, 729, 738, 739, 740, 741, 743, 742, 0,
+	745, 746, 744, 747, 748, 749, 750, 0, 751, 895,
+	752, 731, 732, 753, 754, 755, 0, 756, 757, 758,
+	759, 760, 761, 762, 763, 764, 896, 0, 766, 0,
+	765, 767, 768, 769, 770, 771, 772, 773, 775, 733,
+	776, 777, 778, 783, 784, 785, 897, 779, 780, 781,
+	782, 787, 898, 788, 789, 790, 791, 0, 792, 793,
+	0, 786, 774, 0, 794, 795, 796, 797, 798, 799,
+	800, 801, 802, 803, 0, 804, 899, 900, 901, 902,
+	0, 817, 0, 805, 807, 808, 809, 810, 903, 811,
+	812, 904, 0, 813, 814, 815, 816, 806, 819, 820,
+	818, 0, 0, 821, 822, 823, 824, 826, 828, 829,
+	830, 825, 827, 831, 0, 832, 0, 0, 833, 834,
+	835, 905, 906, 907, 0, 908, 838, 839, 836, 837,
+	840, 841, 844, 842, 843, 909, 847, 542, 848, 849,
+	850, 845, 846, 359, 0, 0, 0, 851, 852, 910,
+	853, 854, 855, 0, 0, 0, 0, 0, 0, 0,
+	367, 368, 370, 369, 371, 372, 373, 374, 0, 375,
+	376, 0, 0, 0, 0, 0, 856, 0, 0, 0,
+	378, 0, 377, 0, 379, 380, 381, 0, 382, 383,
+	384, 385, 386, 387, 388, 389, 390, 857, 391, 858,
+	0, 392, 859, 393, 860, 0, 861, 394, 395, 396,
+	397, 398, 399, 400, 401, 402, 403, 404, 0, 0,
+	0, 405, 862, 863, 864, 0, 406, 407, 408, 409,
+	865, 0, 0, 0, 410, 411, 412, 413, 414, 415,
+	416, 417, 0, 0, 419, 420, 421, 418, 422, 423,
+	0, 424, 0, 425, 426, 427, 428, 429, 0, 430,
+	431, 0, 432, 433, 434, 0, 435, 436, 437, 0,
+	0, 0, 0, 0, 0, 0, 438, 439, 440, 441,
+	442, 0, 443, 445, 866, 867, 0, 448, 450, 444,
+	446, 0, 449, 447, 451, 452, 0, 453, 454, 455,
+	456, 457, 0, 0, 0, 458, 459, 460, 461, 0,
+	462, 463, 464, 466, 465, 0, 467, 468, 469, 0,
+	470, 471, 868, 472, 473, 474, 476, 478, 475, 477,
+	479, 480, 481, 482, 483, 869, 870, 484, 485, 0,
+	0, 0, 0, 0, 0, 0, 486, 487, 488, 871,
+	0, 0, 0, 489, 0, 491, 495, 496, 492, 493,
+	494, 497, 0, 490, 498, 499, 0, 0, 500, 501,
+	502, 872, 873, 503, 504, 505, 506, 507, 508, 509,
+	510, 511, 0, 512, 513, 874, 0, 875, 514, 0,
+	515, 516, 517, 518, 519, 520, 521, 876, 877, 878,
+	630, 0, 522, 523, 524, 525, 0, 526, 527, 528,
+	529, 530, 531, 532, 0, 0, 0, 533, 534, 535,
+	536, 0, 0, 0, 0, 0, 879, 537, 631, 538,
+	539, 880, 881, 0, 882, 0, 540, 541, 544, 0,
+	883, 0, 543, 545, 546, 0, 547, 0, 0, 0,
+	548, 549, 550, 551, 552, 553, 554, 0, 555, 557,
+	556, 0, 559, 884, 558, 0, 560, 561, 0, 0,
+	562, 563, 564, 565, 566, 567, 572, 0, 0, 568,
+	569, 570, 571, 573, 574, 0, 575, 576, 578, 581,
+	577, 579, 580, 582, 583, 596, 597, 598, 584, 585,
+	586, 587, 588, 589, 590, 591, 592, 593, 594, 595,
+	600, 0, 599, 0, 0, 601, 602, 603, 604, 605,
+	606, 612, 615, 617, 618, 613, 614, 616, 619, 620,
+	621, 623, 624, 609, 610, 611, 0, 622, 607, 0,
+	608, 0, 0, 625, 626, 627, 628, 0, 885, 629,
+	886, 632, 633, 0, 0, 634, 0, 635, 636, 0,
+	0, 638, 639, 640, 0, 0, 641, 642, 887, 0,
+	643, 0, 888, 644, 645, 637, 646, 647, 648, 649,
+	650, 651, 652, 653, 654, 655, 656, 657, 0, 658,
+	659, 889, 660, 661, 662, 663, 664, 890, 665, 666,
+	667, 891, 668, 892, 669, 670, 671, 0, 672, 673,
+	674, 0, 675, 676, 677, 678, 679, 680, 681, 682,
+	683, 684, 893, 685, 686, 688, 687, 689, 690, 0,
+	691, 692, 0, 693, 694, 695, 0, 0, 0, 0,
+	0, 696, 697, 699, 0, 700, 701, 702, 703, 704,
+	705, 698, 706, 707, 708, 709, 710, 711, 712, 713,
+	0, 715, 716, 714, 717, 718, 0, 1048, 720, 721,
+	722, 723, 894, 724, 0, 725, 726, 734, 735, 736,
+	727, 728, 730, 1047, 729, 738, 739, 740, 741, 743,
+	742, 0, 745, 746, 744, 747, 748, 749, 750, 0,
+	751, 895, 752, 731, 732, 753, 754, 755, 0, 756,
+	757, 758, 759, 760, 761, 762, 763, 764, 896, 0,
+	766, 0, 765, 767, 768, 769, 770, 771, 772, 773,
+	775, 733, 776, 777, 778, 783, 784, 785, 897, 779,
+	780, 781, 782, 787, 898, 788, 789, 790, 791, 0,
+	792, 793, 0, 786, 774, 0, 794, 795, 796, 797,
+	798, 799, 800, 801, 802, 803, 0, 804, 1045, 900,
+	901, 902, 0, 817, 0, 805, 807, 808, 809, 810,
+	903, 811, 812, 904, 0, 813, 814, 815, 816, 806,
+	819, 820, 818, 0, 0, 821, 822, 823, 824, 826,
+	828, 829, 830, 825, 827, 831, 0, 832, 0, 0,
+	833, 834, 835, 905, 906, 907, 0, 908, 838, 839,
+	836, 837, 840, 841, 844, 842, 843, 909, 847, 542,
+	848, 849, 850, 845, 846, 359, 0, 0, 0, 851,
+	852, 910, 853, 854, 855, 0, 0, 0, 0, 0,
+	0, 0, 367, 368, 370, 369, 371, 372, 373, 374,
+	0, 375, 376, 0, 0, 0, 0, 0, 856, 0,
+	0, 0, 378, 0, 377, 0, 379, 380, 381, 0,
+	382, 383, 384, 385, 386, 387, 388, 389, 390, 857,
+	391, 858, 0, 392, 859, 393, 860, 0, 861, 394,
+	395, 396, 397, 398, 399, 400, 401, 402, 403, 404,
+	0, 0, 0, 405, 862, 863, 864, 0, 406, 407,
+	408, 409, 865, 0, 0, 0, 410, 411, 412, 413,
+	414, 415, 416, 417, 0, 0, 419, 420, 421, 418,
+	422, 423, 0, 424, 0, 425, 426, 427, 428, 429,
+	0, 430, 431, 0, 432, 433, 434, 0, 435, 436,
+	437, 0, 0, 0, 0, 0, 0, 0, 438, 439,
+	440, 441, 442, 0, 443, 445, 866, 867, 0, 448,
+	450, 444, 446, 0, 449, 447, 451, 452, 0, 453,
+	454, 455, 456, 457, 0, 0, 0, 458, 459, 460,
+	461, 0, 462, 463, 464, 466, 465, 0, 467, 468,
+	469, 0, 470, 471, 868, 472, 473, 474, 476, 478,
+	475, 477, 479, 480, 481, 482, 483, 869, 870, 484,
+	485, 0, 0, 0, 0, 0, 0, 0, 486, 487,
+	488, 871, 0, 0, 0, 489, 0, 491, 495, 496,
+	492, 493, 494, 497, 0, 490, 498, 499, 0, 0,
+	500, 501, 502, 872, 873, 503, 504, 505, 506, 507,
+	508, 509, 510, 511, 0, 512, 513, 874, 0, 875,
+	514, 0, 515, 516, 517, 518, 519, 520, 521, 5238,
+	877, 878, 630, 0, 522, 523, 524, 525, 0, 526,
+	527, 528, 529, 530, 531, 532, 0, 0, 0, 533,
+	534, 535, 536, 0, 0, 0, 0, 0, 879, 537,
+	631, 538, 539, 880, 881, 0, 882, 0, 540, 541,
+	544, 0, 883, 0, 543, 545, 546, 0, 547, 0,
+	0, 0, 548, 549, 550, 551, 552, 553, 554, 0,
+	555, 557, 556, 0, 559, 884, 558, 0, 560, 561,
+	0, 0, 562, 563, 564, 565, 566, 567, 572, 0,
+	0, 568, 569, 570, 571, 573, 574, 0, 575, 576,
+	578, 581, 577, 579, 580, 582, 583, 596, 597, 598,
+	584, 585, 586, 587, 588, 589, 590, 591, 592, 593,
+	594, 595, 600, 0, 599, 0, 0, 601, 602, 603,
+	604, 605, 606, 612, 615, 617, 618, 613, 614, 616,
+	619, 620, 621, 623, 624, 609, 610, 611, 0, 622,
+	607, 0, 608, 0, 0, 625, 626, 627, 628, 0,
+	885, 629, 886, 632, 633, 0, 0, 634, 0, 635,
+	636, 0, 0, 638, 639, 640, 0, 0, 641, 642,
+	887, 0, 643, 0, 888, 644, 645, 637, 646, 647,
+	648, 649, 650, 651, 652, 653, 654, 655, 656, 657,
+	0, 658, 659, 889, 660, 661, 662, 663, 664, 890,
+	665, 666, 667, 891, 668, 892, 669, 670, 671, 0,
+	672, 673, 674, 0, 675, 676, 677, 678, 679, 680,
+	681, 682, 683, 684, 893, 685, 686, 688, 687, 689,
+	690, 0, 691, 692, 0, 693, 694, 695, 0, 0,
+	0, 0, 0, 696, 697, 699, 0, 700, 701, 702,
+	703, 704, 705, 698, 706, 707, 708, 709, 710, 711,
+	712, 713, 0, 715, 716, 714, 717, 718, 0, 719,
+	720, 721, 722, 723, 894, 724, 0, 725, 726, 734,
+	735, 736, 727, 728, 730, 737, 729, 738, 739, 740,
+	741, 743, 742, 0, 745, 746, 744, 747, 748, 749,
+	750, 0, 751, 895, 752, 731, 732, 753, 754, 755,
+	0, 756, 757, 758, 759, 760, 761, 762, 763, 764,
+	896, 0, 766, 0, 765, 767, 768, 769, 770, 771,
+	772, 773, 775, 733, 776, 777, 778, 783, 784, 785,
+	897, 779, 780, 781, 782, 787, 898, 788, 789, 790,
+	791, 0, 792, 793, 0, 786, 774, 0, 794, 795,
+	796, 797, 798, 799, 800, 801, 802, 803, 0, 804,
+	899, 900, 901, 902, 0, 817, 0, 805, 807, 808,
+	809, 810, 903, 811, 812, 904, 0, 813, 814, 815,
+	816, 806, 819, 820, 818, 0, 0, 821, 822, 823,
+	824, 826, 828, 829, 830, 825, 827, 831, 0, 832,
+	0, 0, 833, 834, 835, 905, 906, 907, 0, 908,
+	838, 839, 836, 837, 840, 841, 844, 842, 843, 909,
+	847, 542, 848, 849, 850, 845, 846, 359, 0, 0,
+	0, 851, 852, 910, 853, 854, 855, 0, 0, 0,
+	0, 0, 0, 0, 367, 368, 370, 369, 371, 372,
+	373, 374, 0, 375, 376, 0, 0, 0, 0, 0,
+	856, 0, 0, 0, 378, 0, 377, 0, 379, 380,
+	381, 0, 382, 383, 384, 385, 386, 387, 388, 389,
+	390, 857, 391, 858, 0, 392, 859, 393, 860, 0,
+	861, 394, 395, 396, 397, 398, 399, 400, 401, 402,
+	403, 404, 0, 0, 0, 405, 862, 863, 864, 0,
+	406, 407, 408, 409, 865, 0, 0, 0, 410, 411,
+	412, 413, 414, 415, 416, 417, 0, 0, 419, 420,
+	421, 418, 422, 423, 0, 424, 0, 425, 426, 427,
+	428, 429, 0, 430, 431, 0, 432, 433, 434, 0,
+	435, 436, 437, 0, 0, 0, 0, 0, 0, 0,
+	438, 439, 440, 441, 442, 0, 443, 445, 866, 867,
+	0, 448, 450, 444, 446, 0, 449, 447, 451, 452,
+	0, 453, 454, 455, 456, 457, 0, 0, 0, 458,
+	459, 460, 461, 0, 462, 463, 464, 466, 465, 0,
+	467, 468, 469, 0, 470, 471, 868, 472, 473, 474,
+	476, 478, 475, 477, 479, 480, 481, 482, 483, 869,
+	870, 484, 485, 0, 0, 0, 0, 0, 0, 0,
+	486, 487, 488, 871, 0, 0, 0, 489, 0, 491,
+	495, 496, 492, 493, 494, 497, 0, 490, 498, 499,
+	0, 0, 500, 501, 502, 872, 873, 503, 504, 505,
+	506, 507, 508, 509, 510, 511, 0, 512, 513, 874,
+	0, 875, 514, 0, 515, 516, 517, 518, 519, 520,
+	521, 5140, 877, 878, 630, 0, 522, 523, 524, 525,
+	0, 526, 527, 528, 529, 530, 531, 532, 0, 0,
+	0, 533, 534, 535, 536, 0, 0, 0, 0, 0,
+	879, 537, 631, 538, 539, 880, 881, 0, 882, 0,
+	540, 541, 544, 0, 883, 0, 543, 545, 546, 0,
+	547, 0, 0, 0, 548, 549, 550, 551, 552, 553,
+	554, 0, 555, 557, 556, 0, 559, 884, 558, 0,
+	560, 561, 0, 0, 562, 563, 564, 565, 566, 567,
+	572, 0, 0, 568, 569, 570, 571, 573, 574, 0,
+	575, 576, 578, 581, 577, 579, 580, 582, 583, 596,
+	597, 598, 584, 585, 586, 587, 588, 589, 590, 591,
+	592, 593, 594, 595, 600, 0, 599, 0, 0, 601,
+	602, 603, 604, 605, 606, 612, 615, 617, 618, 613,
+	614, 616, 619, 620, 621, 623, 624, 609, 610, 611,
+	0, 622, 607, 0, 608, 0, 0, 625, 626, 627,
+	628, 0, 885, 629, 886, 632, 633, 0, 0, 634,
+	0, 635, 636, 0, 0, 638, 639, 640, 0, 0,
+	641, 642, 887, 0, 643, 0, 888, 644, 645, 637,
+	646, 647, 648, 649, 650, 651, 652, 653, 654, 655,
+	656, 657, 0, 658, 659, 889, 660, 661, 662, 663,
+	664, 890, 665, 666, 667, 891, 668, 892, 669, 670,
+	671, 0, 672, 673, 674, 0, 675, 676, 677, 678,
+	679, 680, 681, 682, 683, 684, 893, 685, 686, 688,
+	687, 689, 690, 0, 691, 692, 0, 693, 694, 695,
+	0, 0, 0, 0, 0, 696, 697, 699, 0, 700,
+	701, 702, 703, 704, 705, 698, 706, 707, 708, 709,
+	710, 711, 712, 713, 0, 715, 716, 714, 717, 718,
+	0, 719, 720, 721, 722, 723, 894, 724, 0, 725,
+	726, 734, 735, 736, 727, 728, 730, 737, 729, 738,
+	739, 740, 741, 743, 742, 0, 745, 746, 744, 747,
+	748, 749, 750, 0, 751, 895, 752, 731, 732, 753,
+	754, 755, 0, 756, 757, 758, 759, 760, 761, 762,
+	763, 764, 896, 0, 766, 0, 765, 767, 768, 769,
+	770, 771, 772, 773, 775, 733, 776, 777, 778, 783,
+	784, 785, 897, 779, 780, 781, 782, 787, 898, 788,
+	789, 790, 791, 0, 792, 793, 0, 786, 774, 0,
+	794, 795, 796, 797, 798, 799, 800, 801, 802, 803,
+	0, 804, 899, 900, 901, 902, 0, 817, 0, 805,
+	807, 808, 809, 810, 903, 811, 812, 904, 0, 813,
+	814, 815, 816, 806, 819, 820, 818, 0, 0, 821,
+	822, 823, 824, 826, 828, 829, 830, 825, 827, 831,
+	0, 832, 0, 0, 833, 834, 835, 905, 906, 907,
+	0, 908, 838, 839, 836, 837, 840, 841, 844, 842,
+	843, 909, 847, 542, 848, 849, 850, 845, 846, 359,
+	0, 0, 0, 851, 852, 910, 853, 854, 855, 0,
+	0, 0, 0, 0, 0, 0, 367, 368, 370, 369,
+	371, 372, 373, 374, 0, 375, 376, 0, 0, 0,
+	0, 0, 856, 0, 0, 0, 378, 0, 377, 0,
+	379, 380, 381, 0, 382, 383, 384, 385, 386, 387,
+	388, 389, 390, 857, 391, 858, 0, 392, 859, 393,
+	860, 0, 861, 394, 395, 396, 397, 398, 399, 400,
+	401, 402, 403, 404, 0, 0, 0, 405, 862, 863,
+	864, 0, 406, 407, 408, 409, 865, 0, 0, 0,
+	410, 411, 412, 413, 414, 415, 416, 417, 0, 0,
+	419, 420, 421, 418, 422, 423, 0, 424, 0, 425,
+	426, 427, 428, 429, 0, 430, 431, 0, 432, 433,
+	434, 0, 435, 436, 437, 0, 0, 0, 0, 0,
+	0, 0, 438, 439, 440, 441, 442, 0, 443, 445,
+	866, 867, 0, 448, 450, 444, 446, 0, 449, 447,
+	451, 452, 0, 453, 454, 455, 456, 457, 0, 0,
+	0, 458, 459, 460, 461, 0, 462, 463, 464, 466,
+	465, 0, 467, 468, 469, 0, 470, 471, 868, 472,
+	473, 474, 476, 478, 475, 477, 479, 480, 481, 482,
+	483, 869, 870, 484, 485, 0, 0, 0, 0, 0,
+	0, 0, 486, 487, 488, 871, 0, 0, 0, 489,
+	0, 491, 495, 496, 492, 493, 494, 497, 0, 490,
+	498, 499, 0, 0, 500, 501, 502, 872, 873, 503,
+	504, 505, 506, 507, 508, 509, 510, 511, 0, 512,
+	513, 874, 0, 875, 514, 0, 515, 516, 517, 518,
+	519, 520, 521, 5138, 877, 878, 630, 0, 522, 523,
+	524, 525, 0, 526, 527, 528, 529, 530, 531, 532,
+	0, 0, 0, 533, 534, 535, 536, 0, 0, 0,
+	0, 0, 879, 537, 631, 538, 539, 880, 881, 0,
+	882, 0, 540, 541, 544, 0, 883, 0, 543, 545,
+	546, 0, 547, 0, 0, 0, 548, 549, 550, 551,
+	552, 553, 554, 0, 555, 557, 556, 0, 559, 884,
+	558, 0, 560, 561, 0, 0, 562, 563, 564, 565,
+	566, 567, 572, 0, 0, 568, 569, 570, 571, 573,
+	574, 0, 575, 576, 578, 581, 577, 579, 580, 582,
+	583, 596, 597, 598, 584, 585, 586, 587, 588, 589,
+	590, 591, 592, 593, 594, 595, 600, 0, 599, 0,
+	0, 601, 602, 603, 604, 605, 606, 612, 615, 617,
+	618, 613, 614, 616, 619, 620, 621, 623, 624, 609,
+	610, 611, 0, 622, 607, 0, 608, 0, 0, 625,
+	626, 627, 628, 0, 885, 629, 886, 632, 633, 0,
+	0, 634, 0, 635, 636, 0, 0, 638, 639, 640,
+	0, 0, 641, 642, 887, 0, 643, 0, 888, 644,
+	645, 637, 646, 647, 648, 649, 650, 651, 652, 653,
+	654, 655, 656, 657, 0, 658, 659, 889, 660, 661,
+	662, 663, 664, 890, 665, 666, 667, 891, 668, 892,
+	669, 670, 671, 0, 672, 673, 674, 0, 675, 676,
+	677, 678, 679, 680, 681, 682, 683, 684, 893, 685,
+	686, 688, 687, 689, 690, 0, 691, 692, 0, 693,
+	694, 695, 0, 0, 0, 0, 0, 696, 697, 699,
+	0, 700, 701, 702, 703, 704, 705, 698, 706, 707,
+	708, 709, 710, 711, 712, 713, 0, 715, 716, 714,
+	717, 718, 0, 719, 720, 721, 722, 723, 894, 724,
+	0, 725, 726, 734, 735, 736, 727, 728, 730, 737,
+	729, 738, 739, 740, 741, 743, 742, 0, 745, 746,
+	744, 747, 748, 749, 750, 0, 751, 895, 752, 731,
+	732, 753, 754, 755, 0, 756, 757, 758, 759, 760,
+	761, 762, 763, 764, 896, 0, 766, 0, 765, 767,
+	768, 769, 770, 771, 772, 773, 775, 733, 776, 777,
+	778, 783, 784, 785, 897, 779, 780, 781, 782, 787,
+	898, 788, 789, 790, 791, 0, 792, 793, 0, 786,
+	774, 0, 794, 795, 796, 797, 798, 799, 800, 801,
+	802, 803, 0, 804, 899, 900, 901, 902, 0, 817,
+	0, 805, 807, 808, 809, 810, 903, 811, 812, 904,
+	0, 813, 814, 815, 816, 806, 819, 820, 818, 0,
+	0, 821, 822, 823, 824, 826, 828, 829, 830, 825,
+	827, 831, 0, 832, 0, 0, 833, 834, 835, 905,
+	906, 907, 0, 908, 838, 839, 836, 837, 840, 841,
+	844, 842, 843, 909, 847, 542, 848, 849, 850, 845,
+	846, 359, 0, 0, 0, 851, 852, 910, 853, 854,
+	855, 0, 0, 0, 0, 0, 0, 0, 367, 368,
+	370, 369, 371, 372, 373, 374, 0, 375, 376, 0,
+	0, 0, 0, 0, 856, 0, 0, 0, 378, 0,
+	377, 0, 379, 380, 381, 0, 382, 383, 384, 385,
+	386, 387, 388, 389, 390, 857, 391, 858, 0, 392,
+	859, 393, 860, 0, 861, 394, 395, 396, 397, 398,
+	399, 400, 401, 402, 403, 404, 0, 0, 0, 405,
+	862, 863, 864, 0, 406, 407, 408, 409, 865, 0,
+	0, 0, 410, 411, 412, 413, 414, 415, 416, 417,
+	0, 0, 419, 420, 421, 418, 422, 423, 0, 424,
+	0, 425, 426, 427, 428, 429, 0, 430, 431, 0,
+	432, 433, 434, 0, 435, 436, 437, 0, 0, 0,
+	0, 0, 0, 0, 438, 439, 440, 441, 442, 0,
+	443, 445, 866, 867, 0, 448, 450, 444, 446, 0,
+	449, 447, 451, 452, 0, 453, 454, 455, 456, 457,
+	0, 0, 0, 458, 459, 460, 461, 0, 462, 463,
+	464, 466, 465, 0, 467, 468, 469, 0, 470, 471,
+	868, 472, 473, 474, 476, 478, 475, 477, 479, 480,
+	481, 482, 483, 869, 870, 484, 485, 0, 0, 0,
+	0, 0, 0, 0, 486, 487, 488, 871, 0, 0,
+	0, 489, 0, 491, 495, 496, 492, 493, 494, 497,
+	0, 490, 498, 499, 0, 0, 500, 501, 502, 872,
+	873, 503, 504, 505, 506, 507, 508, 509, 510, 511,
+	0, 512, 513, 874, 0, 875, 514, 0, 515, 516,
+	517, 518, 519, 520, 521, 5126, 877, 878, 630, 0,
+	522, 523, 524, 525, 0, 526, 527, 528, 529, 530,
+	531, 532, 0, 0, 0, 533, 534, 535, 536, 0,
+	0, 0, 0, 0, 879, 537, 631, 538, 539, 880,
+	881, 0, 882, 0, 540, 541, 544, 0, 883, 0,
+	543, 545, 546, 0, 547, 0, 0, 0, 548, 549,
+	550, 551, 552, 553, 554, 0, 555, 557, 556, 0,
+	559, 884, 558, 0, 560, 561, 0, 0, 562, 563,
+	564, 565, 566, 567, 572, 0, 0, 568, 569, 570,
+	571, 573, 574, 0, 575, 576, 578, 581, 577, 579,
+	580, 582, 583, 596, 597, 598, 584, 585, 586, 587,
+	588, 589, 590, 591, 592, 593, 594, 595, 600, 0,
+	599, 0, 0, 601, 602, 603, 604, 605, 606, 612,
+	615, 617, 618, 613, 614, 616, 619, 620, 621, 623,
+	624, 609, 610, 611, 0, 622, 607, 0, 608, 0,
+	0, 625, 626, 627, 628, 0, 885, 629, 886, 632,
+	633, 0, 0, 634, 0, 635, 636, 0, 0, 638,
+	639, 640, 0, 0, 641, 642, 887, 0, 643, 0,
+	888, 644, 645, 637, 646, 647, 648, 649, 650, 651,
+	652, 653, 654, 655, 656, 657, 0, 658, 659, 889,
+	660, 661, 662, 663, 664, 890, 665, 666, 667, 891,
+	668, 892, 669, 670, 671, 0, 672, 673, 674, 0,
+	675, 676, 677, 678, 679, 680, 681, 682, 683, 684,
+	893, 685, 686, 688, 687, 689, 690, 0, 691, 692,
+	0, 693, 694, 695, 0, 0, 0, 0, 0, 696,
+	697, 699, 0, 700, 701, 702, 703, 704, 705, 698,
+	706, 707, 708, 709, 710, 711, 712, 713, 0, 715,
+	716, 714, 717, 718, 0, 719, 720, 721, 722, 723,
+	894, 724, 0, 725, 726, 734, 735, 736, 727, 728,
+	730, 737, 729, 738, 739, 740, 741, 743, 742, 0,
+	745, 746, 744, 747, 748, 749, 750, 0, 751, 895,
+	752, 731, 732, 753, 754, 755, 0, 756, 757, 758,
+	759, 760, 761, 762, 763, 764, 896, 0, 766, 0,
+	765, 767, 768, 769, 770, 771, 772, 773, 775, 733,
+	776, 777, 778, 783, 784, 785, 897, 779, 780, 781,
+	782, 787, 898, 788, 789, 790, 791, 0, 792, 793,
+	0, 786, 774, 0, 794, 795, 796, 797, 798, 799,
+	800, 801, 802, 803, 0, 804, 899, 900, 901, 902,
+	0, 817, 0, 805, 807, 808, 809, 810, 903, 811,
+	812, 904, 0, 813, 814, 815, 816, 806, 819, 820,
+	818, 0, 0, 821, 822, 823, 824, 826, 828, 829,
+	830, 825, 827, 831, 0, 832, 0, 0, 833, 834,
+	835, 905, 906, 907, 0, 908, 838, 839, 836, 837,
+	840, 841, 844, 842, 843, 909, 847, 542, 848, 849,
+	850, 845, 846, 359, 0, 0, 0, 851, 852, 910,
+	853, 854, 855, 0, 0, 0, 0, 0, 0, 0,
+	367, 368, 370, 369, 371, 372, 373, 374, 0, 375,
+	376, 0, 0, 0, 0, 0, 856, 0, 0, 0,
+	378, 0, 377, 0, 379, 380, 381, 0, 382, 383,
+	384, 385, 386, 387, 388, 389, 390, 857, 391, 858,
+	0, 392, 859, 393, 860, 0, 861, 394, 395, 396,
+	397, 398, 399, 400, 401, 402, 403, 404, 0, 0,
+	0, 405, 862, 863, 864, 0, 406, 407, 408, 409,
+	865, 0, 0, 0, 410, 411, 412, 413, 414, 415,
+	416, 417, 0, 0, 419, 420, 421, 418, 422, 423,
+	0, 424, 0, 425, 426, 427, 428, 429, 0, 430,
+	431, 0, 432, 433, 434, 0, 435, 436, 437, 0,
+	0, 0, 0, 0, 0, 0, 438, 439, 440, 441,
+	442, 0, 443, 445, 866, 867, 0, 448, 450, 444,
+	446, 0, 449, 447, 451, 452, 0, 453, 454, 455,
+	456, 457, 0, 0, 0, 458, 459, 460, 461, 0,
+	462, 463, 464, 466, 465, 0, 467, 468, 469, 0,
+	470, 471, 868, 472, 473, 474, 476, 478, 475, 477,
+	479, 480, 481, 482, 483, 869, 870, 484, 485, 0,
+	0, 0, 0, 0, 0, 0, 486, 487, 488, 871,
+	0, 0, 0, 489, 0, 491, 495, 496, 492, 493,
+	494, 497, 0, 490, 498, 499, 0, 0, 500, 501,
+	502, 872, 873, 503, 504, 505, 506, 507, 508, 509,
+	510, 511, 0, 512, 513, 874, 0, 875, 514, 0,
+	515, 516, 517, 518, 519, 520, 521, 5123, 877, 878,
+	630, 0, 522, 523, 524, 525, 0, 526, 527, 528,
+	529, 530, 531, 532, 0, 0, 0, 533, 534, 535,
+	536, 0, 0, 0, 0, 0, 879, 537, 631, 538,
+	539, 880, 881, 0, 882, 0, 540, 541, 544, 0,
+	883, 0, 543, 545, 546, 0, 547, 0, 0, 0,
+	548, 549, 550, 551, 552, 553, 554, 0, 555, 557,
+	556, 0, 559, 884, 558, 0, 560, 561, 0, 0,
+	562, 563, 564, 565, 566, 567, 572, 0, 0, 568,
+	569, 570, 571, 573, 574, 0, 575, 576, 578, 581,
+	577, 579, 580, 582, 583, 596, 597, 598, 584, 585,
+	586, 587, 588, 589, 590, 591, 592, 593, 594, 595,
+	600, 0, 599, 0, 0, 601, 602, 603, 604, 605,
+	606, 612, 615, 617, 618, 613, 614, 616, 619, 620,
+	621, 623, 624, 609, 610, 611, 0, 622, 607, 0,
+	608, 0, 0, 625, 626, 627, 628, 0, 885, 629,
+	886, 632, 633, 0, 0, 634, 0, 635, 636, 0,
+	0, 638, 639, 640, 0, 0, 641, 642, 887, 0,
+	643, 0, 888, 644, 645, 637, 646, 647, 648, 649,
+	650, 651, 652, 653, 654, 655, 656, 657, 0, 658,
+	659, 889, 660, 661, 662, 663, 664, 890, 665, 666,
+	667, 891, 668, 892, 669, 670, 671, 0, 672, 673,
+	674, 0, 675, 676, 677, 678, 679, 680, 681, 682,
+	683, 684, 893, 685, 686, 688, 687, 689, 690, 0,
+	691, 692, 0, 693, 694, 695, 0, 0, 0, 0,
+	0, 696, 697, 699, 0, 700, 701, 702, 703, 704,
+	705, 698, 706, 707, 708, 709, 710, 711, 712, 713,
+	0, 715, 716, 714, 717, 718, 0, 719, 720, 721,
+	722, 723, 894, 724, 0, 725, 726, 734, 735, 736,
+	727, 728, 730, 737, 729, 738, 739, 740, 741, 743,
+	742, 0, 745, 746, 744, 747, 748, 749, 750, 0,
+	751, 895, 752, 731, 732, 753, 754, 755, 0, 756,
+	757, 758, 759, 760, 761, 762, 763, 764, 896, 0,
+	766, 0, 765, 767, 768, 769, 770, 771, 772, 773,
+	775, 733, 776, 777, 778, 783, 784, 785, 897, 779,
+	780, 781, 782, 787, 898, 788, 789, 790, 791, 0,
+	792, 793, 0, 786, 774, 0, 794, 795, 796, 797,
+	798, 799, 800, 801, 802, 803, 0, 804, 899, 900,
+	901, 902, 0, 817, 0, 805, 807, 808, 809, 810,
+	903, 811, 812, 904, 0, 813, 814, 815, 816, 806,
+	819, 820, 818, 0, 0, 821, 822, 823, 824, 826,
+	828, 829, 830, 825, 827, 831, 0, 832, 0, 0,
+	833, 834, 835, 905, 906, 907, 0, 908, 838, 839,
+	836, 837, 840, 841, 844, 842, 843, 909, 847, 542,
+	848, 849, 850, 845, 846, 359, 0, 0, 0, 851,
+	852, 910, 853, 854, 855, 0, 0, 0, 0, 0,
+	0, 0, 367, 368, 370, 369, 371, 372, 373, 374,
+	0, 375, 376, 0, 0, 0, 0, 0, 856, 0,
+	0, 0, 378, 0, 377, 0, 379, 380, 381, 0,
+	382, 383, 384, 385, 386, 387, 388, 389, 390, 857,
+	391, 858, 0, 392, 859, 393, 860, 0, 861, 394,
+	395, 396, 397, 398, 399, 400, 401, 402, 403, 404,
+	0, 0, 0, 405, 862, 863, 864, 0, 406, 407,
+	408, 409, 865, 0, 0, 0, 410, 411, 412, 413,
+	414, 415, 416, 417, 0, 0, 419, 420, 421, 418,
+	422, 423, 0, 424, 0, 425, 426, 427, 428, 429,
+	0, 430, 431, 0, 432, 433, 434, 0, 435, 436,
+	437, 0, 0, 0, 0, 0, 0, 0, 438, 439,
+	440, 441, 442, 0, 443, 445, 866, 867, 0, 448,
+	450, 444, 446, 0, 449, 447, 451, 452, 0, 453,
+	454, 455, 456, 457, 0, 0, 0, 458, 459, 460,
+	461, 0, 462, 463, 464, 466, 465, 0, 467, 468,
+	469, 0, 470, 471, 868, 472, 473, 474, 476, 478,
+	475, 477, 479, 480, 481, 482, 483, 869, 870, 484,
+	485, 0, 0, 0, 0, 0, 0, 0, 486, 487,
+	488, 871, 0, 0, 0, 489, 0, 491, 495, 496,
+	492, 493, 494, 497, 0, 490, 498, 499, 0, 0,
+	500, 501, 502, 872, 873, 503, 504, 505, 506, 507,
+	508, 509, 510, 511, 0, 512, 513, 874, 0, 875,
+	514, 0, 515, 516, 517, 518, 519, 520, 521, 4680,
+	877, 878, 630, 0, 522, 523, 524, 525, 0, 526,
+	527, 528, 529, 530, 531, 532, 0, 0, 0, 533,
+	534, 535, 536, 0, 0, 0, 0, 0, 879, 537,
+	631, 538, 539, 880, 881, 0, 882, 0, 540, 541,
+	544, 0, 883, 0, 543, 545, 546, 0, 547, 0,
+	0, 0, 548, 549, 550, 551, 552, 553, 554, 0,
+	555, 557, 556, 0, 559, 884, 558, 0, 560, 561,
+	0, 0, 562, 563, 564, 565, 566, 567, 572, 0,
+	0, 568, 569, 570, 571, 573, 574, 0, 575, 576,
+	578, 581, 577, 579, 580, 582, 583, 596, 597, 598,
+	584, 585, 586, 587, 588, 589, 590, 591, 592, 593,
+	594, 595, 600, 0, 599, 0, 0, 601, 602, 603,
+	604, 605, 606, 612, 615, 617, 618, 613, 614, 616,
+	619, 620, 621, 623, 624, 609, 610, 611, 0, 622,
+	607, 0, 608, 0, 0, 625, 626, 627, 628, 0,
+	885, 629, 886, 632, 633, 0, 0, 634, 0, 635,
+	636, 0, 0, 638, 639, 640, 0, 0, 641, 642,
+	887, 0, 643, 0, 888, 644, 645, 637, 646, 647,
+	648, 649, 650, 651, 652, 653, 654, 655, 656, 657,
+	0, 658, 659, 889, 660, 661, 662, 663, 664, 890,
+	665, 666, 667, 891, 668, 892, 669, 670, 671, 0,
+	672, 673, 674, 0, 675, 676, 677, 678, 679, 680,
+	681, 682, 683, 684, 893, 685, 686, 688, 687, 689,
+	690, 0, 691, 692, 0, 693, 694, 695, 0, 0,
+	0, 0, 0, 696, 697, 699, 0, 700, 701, 702,
+	703, 704, 705, 698, 706, 707, 708, 709, 710, 711,
+	712, 713, 0, 715, 716, 714, 717, 718, 0, 719,
+	720, 721, 722, 723, 894, 724, 0, 725, 726, 734,
+	735, 736, 727, 728, 730, 737, 729, 738, 739, 740,
+	741, 743, 742, 0, 745, 746, 744, 747, 748, 749,
+	750, 0, 751, 895, 752, 731, 732, 753, 754, 755,
+	0, 756, 757, 758, 759, 760, 761, 762, 763, 764,
+	896, 0, 766, 0, 765, 767, 768, 769, 770, 771,
+	772, 773, 775, 733, 776, 777, 778, 783, 784, 785,
+	897, 779, 780, 781, 782, 787, 898, 788, 789, 790,
+	791, 0, 792, 793, 0, 786, 774, 0, 794, 795,
+	796, 797, 798, 799, 800, 801, 802, 803, 0, 804,
+	899, 900, 901, 902, 0, 817, 0, 805, 807, 808,
+	809, 810, 903, 811, 812, 904, 0, 813, 814, 815,
+	816, 806, 819, 820, 818, 0, 0, 821, 822, 823,
+	824, 826, 828, 829, 830, 825, 827, 831, 0, 832,
+	0, 0, 833, 834, 835, 905, 906, 907, 0, 908,
+	838, 839, 836, 837, 840, 841, 844, 842, 843, 909,
+	847, 542, 848, 849, 850, 845, 846, 359, 0, 0,
+	0, 851, 852, 910, 853, 854, 855, 0, 0, 0,
+	0, 0, 0, 0, 367, 368, 370, 369, 371, 372,
+	373, 374, 0, 375, 376, 0, 0, 0, 0, 0,
+	856, 0, 0, 0, 378, 0, 377, 0, 379, 380,
+	381, 0, 382, 383, 384, 385, 386, 387, 388, 389,
+	390, 857, 391, 858, 0, 392, 859, 393, 860, 0,
+	861, 394, 395, 396, 397, 398, 399, 400, 401, 402,
+	403, 404, 0, 0, 0, 405, 862, 863, 864, 0,
+	406, 407, 408, 409, 865, 0, 0, 0, 410, 411,
+	412, 413, 414, 415, 416, 417, 0, 0, 419, 420,
+	421, 418, 422, 423, 0, 424, 0, 425, 426, 427,
+	428, 429, 0, 430, 431, 0, 432, 433, 434, 0,
+	435, 436, 437, 0, 0, 0, 0, 0, 0, 0,
+	438, 439, 440, 441, 442, 0, 443, 445, 866, 867,
+	0, 448, 450, 444, 446, 0, 449, 447, 451, 452,
+	0, 453, 454, 455, 456, 457, 0, 0, 0, 458,
+	459, 460, 461, 0, 462, 463, 464, 466, 465, 0,
+	467, 468, 469, 0, 470, 471, 868, 472, 473, 474,
+	476, 478, 475, 477, 479, 480, 481, 482, 483, 869,
+	870, 484, 485, 0, 0, 0, 0, 0, 0, 0,
+	486, 487, 488, 871, 0, 0, 0, 489, 0, 491,
+	495, 496, 492, 493, 494, 497, 0, 490, 498, 499,
+	0, 0, 500, 501, 502, 872, 873, 503, 504, 505,
+	506, 507, 508, 509, 510, 511, 0, 512, 513, 874,
+	0, 875, 514, 0, 515, 516, 517, 518, 519, 520,
+	521, 876, 877, 878, 630, 0, 522, 523, 524, 525,
+	0, 526, 527, 528, 529, 530, 531, 532, 0, 0,
+	0, 533, 534, 535, 536, 0, 0, 0, 0, 0,
+	879, 537, 631, 538, 539, 880, 881, 0, 882, 0,
+	540, 541, 544, 0, 883, 0, 543, 545, 546, 0,
+	547, 0, 0, 0, 548, 549, 550, 551, 552, 553,
+	554, 0, 555, 557, 556, 0, 559, 884, 558, 0,
+	560, 561, 0, 0, 562, 563, 564, 565, 566, 567,
+	572, 0, 0, 568, 569, 570, 571, 573, 574, 0,
+	575, 576, 578, 581, 577, 579, 580, 582, 583, 596,
+	597, 598, 584, 585, 586, 587, 588, 589, 590, 591,
+	592, 593, 594, 595, 600, 0, 599, 0, 0, 601,
+	602, 603, 604, 605, 606, 612, 615, 617, 618, 613,
+	614, 616, 619, 620, 621, 623, 624, 609, 610, 611,
+	0, 622, 607, 0, 608, 0, 0, 625, 626, 627,
+	628, 0, 885, 629, 886, 632, 633, 0, 0, 634,
+	0, 635, 636, 0, 0, 638, 639, 640, 0, 0,
+	641, 642, 887, 0, 643, 0, 888, 644, 645, 637,
+	646, 647, 648, 649, 650, 651, 652, 653, 654, 655,
+	656, 657, 0, 658, 659, 889, 660, 661, 662, 663,
+	664, 890, 665, 666, 667, 891, 668, 892, 669, 670,
+	671, 0, 672, 673, 674, 0, 675, 676, 677, 678,
+	679, 680, 681, 682, 683, 684, 893, 685, 686, 688,
+	687, 689, 690, 0, 691, 692, 0, 693, 694, 695,
+	0, 0, 0, 0, 0, 696, 697, 699, 0, 700,
+	701, 702, 703, 704, 705, 698, 706, 707, 708, 709,
+	710, 711, 712, 713, 0, 715, 716, 714, 717, 718,
+	0, 719, 720, 721, 722, 723, 894, 724, 0, 725,
+	726, 1029, 735, 736, 727, 728, 730, 737, 729, 738,
+	739, 740, 741, 743, 742, 0, 745, 746, 744, 747,
+	748, 749, 750, 0, 751, 895, 752, 731, 732, 753,
+	754, 755, 0, 756, 757, 758, 759, 760, 761, 762,
+	763, 764, 896, 0, 766, 0, 765, 767, 768, 769,
+	770, 771, 772, 773, 775, 733, 776, 777, 778, 783,
+	784, 785, 897, 779, 780, 781, 782, 787, 898, 788,
+	789, 790, 791, 0, 792, 793, 0, 786, 774, 0,
+	794, 795, 796, 797, 798, 799, 800, 801, 802, 803,
+	0, 804, 899, 900, 901, 902, 0, 817, 0, 805,
+	807, 808, 809, 810, 903, 811, 812, 904, 0, 813,
+	814, 815, 816, 806, 819, 820, 818, 0, 0, 821,
+	822, 823, 824, 826, 828, 829, 830, 825, 827, 831,
+	0, 832, 0, 0, 833, 834, 835, 905, 906, 907,
+	0, 908, 838, 839, 836, 837, 840, 841, 844, 842,
+	843, 909, 847, 542, 848, 849, 850, 845, 846, 359,
+	0, 0, 0, 851, 852, 910, 853, 854, 855, 0,
+	0, 0, 0, 0, 0, 0, 367, 368, 370, 369,
+	371, 372, 373, 374, 0, 375, 376, 0, 0, 0,
+	0, 0, 856, 0, 3129, 0, 378, 0, 377, 0,
+	379, 380, 381, 0, 382, 383, 384, 385, 386, 387,
+	388, 389, 390, 857, 391, 858, 0, 392, 859, 393,
+	860, 0, 861, 394, 395, 396, 397, 398, 399, 400,
+	401, 402, 403, 404, 0, 0, 0, 405, 862, 863,
+	864, 0, 406, 407, 408, 409, 865, 0, 0, 0,
+	410, 411, 412, 413, 414, 415, 416, 417, 0, 0,
+	419, 420, 421, 418, 422, 423, 0, 424, 0, 425,
+	426, 427, 428, 429, 0, 430, 431, 0, 432, 433,
+	434, 0, 435, 436, 437, 0, 0, 0, 0, 0,
+	0, 0, 438, 439, 440, 441, 442, 0, 443, 445,
+	866, 867, 0, 448, 450, 444, 446, 0, 449, 447,
+	451, 452, 0, 453, 454, 455, 456, 457, 0, 0,
+	0, 458, 459, 460, 461, 0, 462, 463, 464, 466,
+	465, 0, 467, 468, 469, 0, 470, 471, 868, 472,
+	473, 474, 476, 478, 475, 477, 479, 480, 481, 482,
+	483, 869, 870, 484, 485, 0, 0, 0, 0, 0,
+	0, 0, 486, 487, 488, 871, 0, 0, 0, 489,
+	0, 491, 495, 496, 492, 493, 494, 497, 0, 490,
+	498, 499, 0, 0, 500, 501, 502, 872, 873, 503,
+	504, 505, 506, 507, 508, 509, 510, 511, 0, 512,
+	513, 874, 0, 875, 514, 0, 515, 516, 517, 518,
+	519, 520, 521, 876, 877, 878, 630, 0, 522, 523,
+	524, 525, 0, 526, 527, 528, 529, 530, 531, 532,
+	0, 0, 0, 533, 534, 535, 536, 0, 0, 0,
+	0, 0, 879, 537, 631, 538, 539, 880, 881, 0,
+	882, 0, 540, 541, 544, 0, 883, 0, 543, 545,
+	546, 0, 547, 0, 0, 0, 548, 549, 550, 551,
+	552, 553, 554, 0, 555, 557, 556, 0, 559, 884,
+	558, 0, 560, 561, 0, 0, 562, 563, 564, 565,
+	566, 567, 572, 0, 0, 568, 569, 570, 571, 573,
+	574, 0, 575, 576, 578, 581, 577, 579, 580, 582,
+	583, 596, 597, 598, 584, 585, 586, 587, 588, 589,
+	590, 591, 592, 593, 594, 595, 600, 0, 599, 0,
+	0, 601, 602, 603, 604, 605, 606, 612, 615, 617,
+	618, 613, 614, 616, 619, 620, 621, 623, 624, 609,
+	610, 611, 0, 622, 607, 0, 608, 0, 0, 625,
+	626, 627, 628, 0, 885, 629, 886, 632, 633, 0,
+	0, 634, 0, 635, 636, 0, 0, 638, 639, 640,
+	0, 0, 641, 642, 887, 0, 643, 0, 888, 644,
+	645, 637, 646, 647, 648, 649, 650, 651, 652, 653,
+	654, 655, 656, 657, 0, 658, 659, 889, 660, 661,
+	662, 663, 664, 890, 665, 666, 667, 891, 668, 892,
+	669, 670, 671, 0, 672, 673, 674, 0, 675, 676,
+	677, 678, 679, 680, 681, 682, 683, 684, 893, 685,
+	686, 688, 687, 689, 690, 0, 691, 692, 0, 693,
+	694, 695, 0, 0, 0, 0, 0, 696, 697, 699,
+	0, 700, 701, 702, 703, 704, 705, 698, 706, 707,
+	708, 709, 710, 711, 712, 713, 0, 715, 716, 714,
+	717, 718, 0, 719, 720, 721, 722, 723, 894, 724,
+	0, 725, 726, 734, 735, 736, 727, 728, 730, 737,
+	729, 738, 739, 740, 741, 743, 742, 0, 745, 746,
+	744, 747, 748, 749, 750, 0, 0, 895, 752, 731,
+	732, 753, 754, 755, 0, 756, 757, 758, 759, 760,
+	761, 762, 763, 764, 896, 0, 766, 0, 765, 767,
+	768, 769, 770, 771, 772, 773, 775, 733, 776, 777,
+	778, 783, 784, 785, 897, 779, 780, 781, 782, 787,
+	898, 788, 789, 790, 791, 0, 792, 793, 0, 786,
+	774, 0, 794, 795, 796, 797, 798, 799, 800, 801,
+	802, 803, 0, 804, 899, 900, 901, 902, 0, 817,
+	0, 805, 807, 808, 809, 810, 903, 811, 812, 904,
+	0, 813, 814, 815, 816, 806, 819, 820, 818, 0,
+	0, 821, 822, 823, 824, 826, 828, 829, 830, 825,
+	827, 831, 0, 832, 0, 0, 833, 834, 835, 905,
+	906, 907, 0, 908, 838, 839, 836, 837, 840, 841,
+	844, 842, 843, 909, 847, 542, 848, 849, 850, 845,
+	846, 359, 0, 0, 0, 851, 852, 910, 853, 854,
+	855, 0, 0, 0, 0, 0, 0, 0, 367, 368,
+	370, 369, 371, 372, 373, 374, 0, 375, 376, 0,
+	0, 0, 0, 0, 856, 0, 0, 0, 378, 0,
+	377, 0, 379, 380, 381, 0, 382, 383, 384, 385,
+	386, 387, 388, 389, 390, 857, 391, 858, 0, 392,
+	859, 393, 860, 0, 861, 394, 395, 396, 397, 398,
+	399, 400, 401, 402, 403, 404, 0, 0, 0, 405,
+	862, 863, 864, 0, 406, 407, 408, 409, 865, 0,
+	0, 0, 410, 411, 412, 413, 414, 415, 416, 417,
+	0, 0, 419, 420, 421, 418, 422, 423, 0, 424,
+	0, 425, 426, 427, 428, 429, 0, 430, 431, 0,
+	432, 433, 434, 0, 435, 436, 437, 0, 0, 0,
+	0, 0, 0, 0, 438, 439, 440, 441, 442, 0,
+	443, 445, 866, 867, 0, 448, 450, 444, 446, 0,
+	449, 447, 451, 452, 0, 453, 454, 455, 456, 457,
+	0, 0, 0, 458, 459, 460, 461, 0, 462, 463,
+	464, 466, 465, 0, 467, 468, 469, 0, 470, 471,
+	868, 472, 2782, 474, 476, 478, 475, 477, 479, 480,
+	481, 482, 483, 869, 870, 484, 485, 0, 0, 0,
+	0, 0, 0, 0, 486, 487, 488, 871, 0, 0,
+	0, 489, 0, 491, 495, 496, 492, 493, 494, 497,
+	0, 490, 498, 499, 0, 0, 500, 501, 502, 872,
+	873, 503, 504, 505, 506, 507, 508, 509, 510, 511,
+	0, 512, 513, 874, 0, 875, 514, 0, 515, 516,
+	517, 518, 519, 520, 521, 876, 877, 878, 630, 0,
+	522, 523, 524, 525, 0, 526, 527, 528, 529, 530,
+	531, 532, 0, 0, 0, 533, 534, 535, 536, 0,
+	0, 0, 0, 0, 879, 537, 631, 538, 539, 880,
+	881, 0, 882, 0, 540, 541, 544, 0, 883, 0,
+	543, 545, 546, 0, 547, 0, 0, 0, 548, 549,
+	550, 551, 552, 553, 554, 0, 555, 557, 556, 0,
+	559, 884, 558, 0, 560, 561, 0, 0, 562, 563,
+	564, 565, 566, 567, 572, 0, 0, 568, 569, 570,
+	571, 573, 574, 0, 575, 576, 578, 581, 577, 579,
+	580, 582, 583, 596, 597, 598, 584, 585, 586, 587,
+	588, 589, 590, 591, 592, 593, 594, 595, 600, 0,
+	599, 0, 0, 601, 602, 603, 604, 605, 606, 612,
+	615, 617, 618, 613, 614, 616, 619, 620, 621, 623,
+	624, 609, 610, 611, 0, 622, 607, 0, 608, 0,
+	0, 625, 626, 627, 628, 0, 885, 629, 886, 632,
+	633, 0, 0, 634, 0, 635, 636, 0, 0, 638,
+	639, 640, 0, 0, 641, 642, 887, 0, 643, 0,
+	888, 644, 645, 637, 646, 647, 648, 649, 650, 651,
+	652, 653, 654, 655, 656, 657, 0, 658, 659, 889,
+	660, 661, 662, 663, 664, 890, 665, 666, 667, 891,
+	668, 892, 669, 670, 671, 0, 672, 673, 674, 0,
+	675, 676, 677, 678, 679, 680, 681, 682, 683, 684,
+	893, 685, 686, 1593, 687, 689, 690, 0, 691, 692,
+	0, 693, 694, 695, 0, 0, 0, 0, 0, 696,
+	697, 699, 0, 700, 701, 702, 703, 704, 705, 698,
+	706, 707, 708, 709, 710, 711, 712, 713, 0, 715,
+	716, 714, 717, 718, 0, 719, 720, 721, 722, 723,
+	894, 724, 0, 725, 726, 734, 735, 736, 727, 728,
+	730, 737, 729, 738, 739, 740, 741, 743, 742, 0,
+	745, 746, 744, 747, 748, 749, 750, 0, 751, 895,
+	752, 731, 732, 753, 754, 755, 0, 756, 757, 758,
+	759, 760, 761, 762, 763, 764, 896, 0, 766, 0,
+	765, 767, 768, 769, 770, 771, 772, 773, 775, 733,
+	776, 777, 778, 783, 784, 785, 897, 779, 780, 781,
+	782, 787, 898, 788, 789, 790, 791, 0, 792, 793,
+	0, 786, 774, 0, 794, 795, 796, 797, 798, 799,
+	800, 801, 802, 803, 0, 804, 899, 900, 901, 902,
+	0, 817, 0, 805, 807, 808, 809, 810, 903, 811,
+	812, 904, 0, 813, 814, 815, 816, 806, 819, 820,
+	818, 0, 0, 821, 822, 823, 824, 826, 828, 829,
+	830, 825, 827, 831, 0, 832, 0, 0, 833, 834,
+	835, 905, 906, 907, 0, 908, 838, 839, 836, 837,
+	840, 841, 844, 842, 843, 909, 847, 542, 848, 849,
+	850, 845, 846, 359, 0, 0, 0, 851, 852, 910,
+	853, 854, 855, 0, 0, 0, 0, 0, 0, 0,
+	367, 368, 370, 369, 371, 372, 373, 374, 0, 375,
+	376, 0, 0, 0, 0, 0, 856, 0, 0, 0,
+	378, 0, 377, 0, 379, 380, 381, 0, 382, 383,
+	384, 385, 386, 387, 388, 389, 390, 857, 391, 858,
+	0, 392, 859, 393, 860, 0, 861, 394, 395, 396,
+	397, 398, 399, 400, 401, 402, 403, 404, 0, 0,
+	0, 405, 862, 863, 864, 0, 406, 407, 408, 409,
+	865, 0, 0, 0, 410, 411, 412, 413, 414, 415,
+	416, 417, 0, 0, 419, 420, 421, 418, 422, 423,
+	0, 424, 0, 425, 426, 427, 428, 429, 0, 430,
+	431, 0, 432, 433, 434, 0, 435, 436, 437, 0,
+	0, 0, 0, 0, 0, 0, 438, 439, 440, 441,
+	442, 0, 443, 445, 866, 867, 0, 448, 450, 444,
+	446, 0, 449, 447, 451, 452, 0, 453, 454, 455,
+	456, 457, 0, 0, 0, 458, 459, 460, 461, 0,
+	462, 463, 464, 466, 465, 0, 467, 468, 469, 0,
+	470, 471, 868, 472, 473, 474, 476, 478, 475, 477,
+	479, 480, 481, 482, 483, 869, 870, 484, 485, 0,
+	0, 0, 0, 0, 0, 0, 486, 487, 488, 871,
+	0, 0, 0, 489, 0, 491, 495, 496, 492, 493,
+	494, 497, 0, 490, 498, 499, 0, 0, 500, 501,
+	502, 872, 873, 503, 504, 505, 506, 507, 508, 509,
+	510, 511, 0, 512, 513, 874, 0, 875, 514, 0,
+	515, 516, 517, 518, 519, 520, 521, 1696, 877, 878,
+	630, 0, 522, 523, 524, 525, 0, 526, 527, 528,
+	529, 530, 531, 532, 0, 0, 0, 533, 534, 535,
+	536, 0, 0, 0, 0, 0, 879, 537, 631, 538,
+	539, 880, 881, 0, 882, 0, 540, 541, 544, 0,
+	883, 0, 543, 545, 546, 0, 547, 0, 0, 0,
+	548, 549, 550, 551, 552, 553, 554, 0, 555, 557,
+	556, 0, 559, 884, 558, 0, 560, 561, 0, 0,
+	562, 563, 564, 565, 566, 567, 572, 0, 0, 568,
+	569, 570, 571, 573, 574, 0, 575, 576, 578, 581,
+	577, 579, 580, 582, 583, 596, 597, 598, 584, 585,
+	586, 587, 588, 589, 590, 591, 592, 593, 594, 595,
+	600, 0, 599, 0, 0, 601, 602, 603, 604, 605,
+	606, 612, 615, 617, 618, 613, 614, 616, 619, 620,
+	621, 623, 624, 609, 610, 611, 0, 622, 607, 0,
+	608, 0, 0, 625, 626, 627, 628, 0, 885, 629,
+	886, 632, 633, 0, 0, 634, 0, 635, 636, 0,
+	0, 638, 639, 640, 0, 0, 641, 642, 887, 0,
+	643, 0, 888, 644, 645, 637, 646, 647, 648, 649,
+	650, 651, 652, 653, 654, 655, 656, 657, 0, 658,
+	659, 889, 660, 661, 662, 663, 664, 890, 665, 666,
+	667, 891, 668, 892, 669, 670, 671, 0, 672, 673,
+	674, 0, 675, 676, 677, 678, 679, 680, 681, 682,
+	683, 684, 893, 685, 686, 688, 687, 689, 690, 0,
+	691, 692, 0, 693, 694, 695, 0, 0, 0, 0,
+	0, 696, 697, 699, 0, 700, 701, 702, 703, 704,
+	705, 698, 706, 707, 708, 709, 710, 711, 712, 713,
+	0, 715, 716, 714, 717, 718, 0, 719, 720, 721,
+	722, 723, 894, 724, 0, 725, 726, 734, 735, 736,
+	727, 728, 730, 737, 729, 738, 739, 740, 741, 743,
+	742, 0, 745, 746, 744, 747, 748, 749, 750, 0,
+	751, 895, 752, 731, 732, 753, 754, 755, 0, 756,
+	757, 758, 759, 760, 761, 762, 763, 764, 896, 0,
+	766, 0, 765, 767, 768, 769, 770, 771, 772, 773,
+	775, 733, 776, 777, 778, 783, 784, 785, 897, 779,
+	780, 781, 782, 787, 898, 788, 789, 790, 791, 0,
+	792, 793, 0, 786, 774, 0, 794, 795, 796, 797,
+	798, 799, 800, 801, 802, 803, 0, 804, 899, 900,
+	901, 902, 0, 817, 0, 805, 807, 808, 809, 810,
+	903, 811, 812, 904, 0, 813, 814, 815, 816, 806,
+	819, 820, 818, 0, 0, 821, 822, 823, 824, 826,
+	828, 829, 830, 825, 827, 831, 0, 832, 0, 0,
+	833, 834, 835, 905, 906, 907, 0, 908, 838, 839,
+	836, 837, 840, 841, 844, 842, 843, 909, 847, 542,
+	848, 849, 850, 845, 846, 359, 0, 0, 0, 851,
+	852, 910, 853, 854, 855, 0, 0, 0, 0, 0,
+	0, 0, 367, 368, 370, 369, 371, 372, 373, 374,
+	0, 375, 376, 0, 0, 0, 0, 0, 856, 0,
+	0, 0, 378, 0, 377, 0, 379, 380, 381, 0,
+	382, 383, 384, 385, 386, 387, 388, 389, 390, 857,
+	391, 858, 0, 392, 859, 393, 860, 0, 861, 394,
+	395, 396, 397, 398, 399, 400, 401, 402, 403, 404,
+	0, 0, 0, 405, 862, 863, 864, 0, 406, 407,
+	408, 409, 865, 0, 0, 0, 410, 411, 412, 413,
+	414, 415, 416, 417, 0, 0, 419, 420, 421, 418,
+	422, 423, 0, 424, 0, 425, 426, 427, 428, 429,
+	0, 430, 431, 0, 432, 433, 434, 0, 435, 436,
+	437, 0, 0, 0, 0, 0, 0, 0, 438, 439,
+	440, 441, 442, 0, 443, 445, 866, 867, 0, 448,
+	450, 444, 446, 0, 449, 447, 451, 452, 0, 453,
+	454, 455, 456, 457, 0, 0, 0, 458, 459, 460,
+	461, 0, 462, 463, 464, 466, 465, 0, 467, 468,
+	469, 0, 470, 471, 868, 472, 473, 474, 476, 478,
+	475, 477, 479, 480, 481, 482, 483, 869, 870, 484,
+	485, 0, 0, 0, 0, 0, 0, 0, 486, 487,
+	488, 871, 0, 0, 0, 489, 0, 491, 495, 496,
+	492, 493, 494, 497, 0, 490, 498, 499, 0, 0,
+	500, 501, 502, 872, 873, 503, 504, 505, 506, 507,
+	508, 509, 510, 511, 0, 512, 513, 874, 0, 875,
+	514, 0, 515, 516, 517, 518, 519, 520, 521, 876,
+	877, 878, 630, 0, 522, 523, 524, 525, 0, 526,
+	527, 528, 529, 530, 531, 532, 0, 0, 0, 533,
+	534, 535, 536, 0, 0, 0, 0, 0, 879, 537,
+	631, 538, 539, 880, 881, 0, 882, 0, 540, 541,
+	544, 0, 883, 0, 543, 545, 546, 0, 547, 0,
+	0, 0, 548, 549, 550, 551, 552, 553, 554, 0,
+	555, 557, 556, 0, 559, 884, 558, 0, 560, 561,
+	0, 0, 562, 563, 564, 565, 566, 567, 572, 0,
+	0, 568, 569, 570, 571, 573, 574, 0, 575, 576,
+	578, 581, 577, 579, 580, 582, 583, 596, 597, 598,
+	584, 585, 586, 587, 588, 589, 590, 591, 592, 593,
+	594, 595, 600, 0, 599, 0, 0, 601, 602, 603,
+	604, 605, 606, 612, 615, 617, 618, 613, 614, 616,
+	619, 620, 621, 623, 624, 609, 610, 611, 0, 622,
+	607, 0, 608, 0, 0, 625, 626, 627, 628, 0,
+	885, 629, 886, 632, 633, 0, 0, 634, 0, 635,
+	636, 0, 0, 638, 639, 640, 0, 0, 641, 642,
+	887, 0, 643, 0, 888, 644, 645, 637, 646, 647,
+	648, 649, 650, 651, 652, 653, 654, 655, 656, 657,
+	0, 658, 659, 889, 660, 661, 662, 663, 664, 890,
+	665, 666, 667, 891, 668, 892, 669, 670, 671, 0,
+	672, 673, 674, 0, 675, 676, 677, 678, 679, 680,
+	681, 682, 683, 684, 893, 685, 686, 1593, 687, 689,
+	690, 0, 691, 692, 0, 693, 694, 695, 0, 0,
+	0, 0, 0, 696, 697, 699, 0, 700, 701, 702,
+	703, 704, 705, 698, 706, 707, 708, 709, 710, 711,
+	712, 713, 0, 715, 716, 714, 717, 718, 0, 719,
+	720, 721, 722, 723, 894, 724, 0, 725, 726, 734,
+	735, 736, 727, 728, 730, 737, 729, 738, 739, 740,
+	741, 743, 742, 0, 745, 746, 744, 747, 748, 749,
+	750, 0, 751, 895, 752, 731, 732, 753, 754, 755,
+	0, 756, 757, 758, 759, 760, 761, 762, 763, 764,
+	896, 0, 766, 0, 765, 767, 768, 769, 770, 771,
+	772, 773, 775, 733, 776, 777, 778, 783, 784, 785,
+	897, 779, 780, 781, 782, 787, 898, 788, 789, 790,
+	791, 0, 792, 793, 0, 786, 774, 0, 794, 795,
+	796, 797, 798, 799, 800, 801, 802, 803, 0, 804,
+	899, 900, 901, 902, 0, 817, 0, 805, 807, 808,
+	809, 810, 903, 811, 812, 904, 0, 813, 814, 815,
+	816, 806, 819, 820, 818, 0, 0, 821, 822, 823,
+	824, 826, 828, 829, 830, 825, 827, 831, 0, 832,
+	0, 0, 833, 834, 835, 905, 906, 907, 0, 908,
+	838, 839, 836, 837, 840, 841, 844, 842, 843, 909,
+	847, 542, 848, 849, 850, 845, 846, 359, 0, 0,
+	0, 851, 852, 910, 853, 854, 855, 0, 0, 0,
+	0, 0, 0, 0, 367, 368, 370, 369, 371, 372,
+	373, 374, 0, 375, 376, 0, 0, 0, 0, 0,
+	856, 0, 0, 0, 378, 0, 377, 0, 379, 380,
+	381, 0, 382, 383, 384, 385, 386, 387, 388, 389,
+	390, 857, 391, 858, 0, 392, 859, 393, 860, 0,
+	861, 394, 395, 396, 397, 398, 399, 400, 401, 402,
+	403, 404, 0, 0, 0, 405, 862, 863, 864, 0,
+	406, 407, 408, 409, 865, 0, 0, 0, 410, 411,
+	412, 413, 414, 415, 416, 417, 0, 0, 419, 420,
+	421, 418, 422, 423, 0, 424, 0, 425, 426, 427,
+	428, 429, 0, 430, 431, 0, 432, 433, 434, 0,
+	435, 436, 437, 0, 0, 0, 0, 0, 0, 0,
+	438, 439, 440, 441, 442, 0, 443, 445, 866, 867,
+	0, 448, 450, 444, 446, 0, 449, 447, 451, 452,
+	0, 453, 454, 455, 456, 457, 0, 0, 0, 458,
+	459, 460, 461, 0, 462, 463, 464, 466, 465, 0,
+	467, 468, 469, 0, 470, 471, 868, 472, 473, 474,
+	476, 478, 475, 477, 479, 480, 481, 482, 483, 869,
+	870, 484, 485, 0, 0, 0, 0, 0, 0, 0,
+	486, 487, 488, 871, 0, 0, 0, 489, 0, 491,
+	495, 496, 492, 493, 494, 497, 0, 490, 498, 499,
+	0, 0, 500, 501, 502, 872, 873, 503, 504, 505,
+	506, 507, 508, 509, 510, 511, 0, 512, 513, 874,
+	0, 875, 0, 0, 515, 516, 517, 518, 519, 520,
+	521, 876, 877, 878, 630, 0, 522, 523, 524, 525,
+	0, 526, 527, 528, 529, 530, 531, 532, 0, 0,
+	0, 533, 534, 535, 536, 0, 0, 0, 0, 0,
+	879, 537, 631, 538, 539, 880, 881, 0, 882, 0,
+	540, 541, 544, 0, 883, 0, 543, 545, 546, 0,
+	547, 0, 0, 0, 548, 549, 550, 551, 552, 553,
+	554, 0, 555, 557, 556, 0, 559, 884, 558, 0,
+	560, 561, 0, 0, 562, 563, 564, 565, 566, 567,
+	572, 0, 0, 568, 569, 570, 571, 573, 574, 0,
+	575, 576, 578, 581, 577, 579, 580, 582, 583, 596,
+	597, 598, 584, 585, 586, 587, 588, 589, 590, 591,
+	592, 593, 594, 595, 600, 0, 599, 0, 0, 601,
+	602, 603, 604, 605, 606, 612, 615, 617, 618, 613,
+	614, 616, 619, 620, 621, 623, 624, 609, 610, 611,
+	0, 622, 607, 0, 608, 0, 0, 625, 626, 627,
+	628, 0, 885, 629, 886, 632, 633, 0, 0, 634,
+	0, 635, 636, 0, 0, 638, 639, 640, 0, 0,
+	641, 642, 887, 0, 643, 0, 888, 644, 645, 637,
+	646, 647, 648, 0, 650, 651, 652, 653, 654, 655,
+	656, 657, 0, 658, 659, 889, 660, 661, 662, 663,
+	664, 890, 665, 666, 667, 891, 668, 892, 669, 670,
+	671, 0, 672, 673, 674, 0, 675, 676, 677, 678,
+	679, 680, 681, 0, 683, 684, 893, 685, 686, 688,
+	687, 689, 690, 0, 691, 692, 0, 693, 694, 695,
+	0, 0, 0, 0, 0, 696, 697, 699, 0, 700,
+	701, 702, 703, 704, 705, 698, 706, 707, 708, 709,
+	710, 711, 712, 713, 0, 715, 716, 714, 717, 718,
+	0, 719, 720, 721, 722, 723, 894, 0, 0, 725,
+	726, 734, 735, 736, 727, 728, 730, 737, 729, 738,
+	739, 740, 741, 743, 742, 0, 745, 746, 744, 747,
+	748, 749, 750, 0, 751, 895, 752, 731, 732, 753,
+	754, 755, 0, 756, 757, 758, 759, 760, 761, 762,
+	763, 764, 896, 0, 766, 0, 765, 767, 768, 769,
+	770, 771, 772, 773, 775, 733, 776, 777, 778, 783,
+	784, 785, 897, 779, 780, 781, 782, 787, 898, 788,
+	789, 790, 791, 0, 792, 793, 0, 786, 774, 0,
+	794, 795, 796, 797, 798, 799, 800, 801, 802, 803,
+	0, 804, 899, 900, 901, 902, 0, 817, 0, 805,
+	807, 808, 809, 810, 903, 811, 812, 904, 0, 813,
+	814, 815, 816, 806, 819, 820, 818, 0, 0, 821,
+	822, 823, 824, 826, 828, 829, 830, 825, 827, 831,
+	0, 832, 0, 0, 833, 834, 835, 905, 906, 907,
+	0, 908, 838, 839, 836, 837, 840, 841, 844, 842,
+	843, 909, 847, 542, 848, 849, 850, 845, 846, 6994,
+	0, 0, 0, 851, 852, 910, 853, 854, 855, 0,
+	0, 0, 0, 0, 0, 0, 367, 368, 370, 369,
+	371, 372, 373, 374, 0, 375, 376, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 378, 0, 377, 0,
+	379, 380, 381, 926, 382, 383, 384, 385, 386, 387,
+	388, 389, 390, 0, 391, 0, 0, 392, 0, 393,
+	0, 0, 0, 394, 395, 396, 397, 398, 399, 400,
+	401, 402, 403, 404, 0, 0, 0, 405, 0, 0,
+	0, 0, 406, 407, 408, 409, 0, 0, 927, 0,
+	410, 411, 412, 413, 414, 415, 416, 417, 0, 0,
+	419, 420, 421, 418, 422, 423, 0, 424, 0, 425,
+	426, 427, 428, 429, 0, 430, 431, 0, 432, 433,
+	434, 928, 435, 436, 437, 0, 0, 0, 0, 0,
+	0, 0, 438, 439, 440, 441, 442, 0, 443, 445,
+	0, 0, 0, 448, 450, 444, 446, 0, 449, 447,
+	451, 452, 0, 453, 454, 455, 456, 457, 0, 0,
+	0, 458, 459, 460, 461, 0, 462, 463, 464, 466,
+	465, 0, 467, 468, 469, 0, 470, 471, 0, 472,
+	473, 474, 476, 478, 475, 477, 479, 480, 481, 482,
+	483, 0, 0, 484, 485, 0, 362, 0, 0, 0,
+	0, 0, 486, 487, 488, 0, 0, 0, 0, 489,
+	0, 491, 495, 496, 492, 493, 494, 497, 0, 490,
+	498, 499, 0, 929, 500, 501, 502, 0, 0, 503,
+	504, 505, 506, 507, 508, 509, 510, 511, 0, 512,
+	513, 0, 0, 0, 514, 0, 515, 516, 517, 518,
+	519, 520, 521, 0, 0, 0, 630, 931, 522, 523,
+	524, 525, 0, 526, 527, 528, 529, 530, 531, 532,
+	0, 0, 0, 533, 534, 535, 536, 0, 0, 0,
+	0, 930, 0, 537, 631, 538, 539, 0, 0, 0,
+	0, 0, 540, 541, 544, 932, 0, 933, 543, 545,
+	546, 934, 547, 0, 0, 0, 548, 549, 550, 551,
+	552, 553, 554, 0, 555, 557, 556, 0, 559, 0,
+	558, 935, 560, 561, 936, 0, 562, 563, 564, 565,
+	566, 567, 572, 0, 0, 568, 569, 570, 571, 573,
+	574, 0, 575, 576, 578, 581, 577, 579, 580, 582,
+	583, 596, 597, 598, 584, 585, 586, 587, 588, 589,
+	590, 591, 592, 593, 594, 595, 600, 0, 599, 937,
+	0, 601, 602, 603, 604, 605, 606, 612, 615, 617,
+	618, 613, 614, 616, 619, 620, 621, 623, 624, 609,
+	610, 611, 938, 622, 607, 0, 608, 0, 939, 625,
+	626, 627, 628, 0, 0, 629, 0, 632, 633, 0,
+	0, 634, 0, 635, 636, 0, 0, 638, 639, 640,
+	0, 0, 641, 642, 0, 940, 643, 941, 0, 644,
+	645, 637, 646, 647, 648, 649, 650, 651, 652, 653,
+	654, 655, 656, 657, 0, 658, 659, 0, 660, 661,
+	662, 663, 664, 0, 665, 666, 667, 0, 668, 0,
+	669, 670, 671, 0, 672, 673, 674, 0, 675, 676,
+	677, 678, 679, 680, 681, 682, 683, 684, 0, 685,
+	686, 688, 687, 689, 690, 0, 691, 692, 0, 693,
+	694, 695, 0, 0, 0, 0, 0, 696, 697, 699,
+	0, 700, 701, 702, 703, 704, 705, 698, 706, 707,
+	708, 709, 710, 711, 712, 713, 0, 715, 716, 714,
+	717, 718, 942, 719, 720, 721, 722, 723, 0, 724,
+	0, 725, 726, 734, 735, 736, 727, 728, 730, 737,
+	729, 738, 739, 740, 741, 743, 742, 0, 745, 746,
+	744, 747, 748, 749, 750, 0, 751, 0, 752, 731,
+	732, 753, 754, 755, 943, 756, 757, 758, 759, 760,
+	761, 762, 763, 764, 0, 0, 766, 0, 765, 767,
+	768, 769, 770, 771, 772, 773, 775, 733, 776, 777,
+	778, 783, 784, 785, 0, 779, 780, 781, 782, 787,
+	0, 788, 789, 790, 791, 0, 792, 793, 0, 786,
+	774, 0, 794, 795, 796, 797, 798, 799, 800, 801,
+	802, 803, 0, 804, 0, 0, 0, 0, 0, 817,
+	0, 805, 807, 808, 809, 810, 0, 811, 812, 0,
+	0, 813, 814, 815, 816, 806, 819, 820, 818, 0,
+	0, 821, 822, 823, 824, 826, 828, 829, 830, 825,
+	827, 831, 0, 832, 0, 0, 833, 834, 835, 0,
+	0, 0, 0, 0, 838, 839, 836, 837, 840, 841,
+	844, 842, 843, 0, 847, 542, 848, 849, 850, 845,
+	846, 2201, 0, 1747, 0, 851, 852, 0, 853, 854,
+	855, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	367, 368, 370, 369, 371, 372, 373, 374, 0, 375,
+	376, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	378, 0, 377, 0, 379, 380, 381, 0, 382, 383,
+	384, 385, 386, 387, 388, 389, 390, 0, 391, 0,
+	0, 392, 0, 393, 0, 0, 0, 394, 395, 396,
+	397, 398, 399, 400, 401, 402, 403, 404, 0, 0,
+	0, 405, 0, 0, 0, 0, 406, 407, 408, 409,
+	0, 0, 0, 0, 410, 411, 412, 413, 414, 415,
+	416, 417, 0, 0, 419, 420, 421, 418, 422, 423,
+	0, 424, 0, 425, 426, 427, 428, 429, 0, 430,
+	431, 0, 432, 433, 434, 0, 435, 436, 437, 0,
+	0, 0, 0, 0, 0, 1749, 438, 439, 440, 441,
+	442, 0, 443, 445, 0, 0, 0, 448, 450, 444,
+	446, 0, 449, 447, 451, 452, 0, 453, 454, 455,
+	456, 457, 0, 0, 0, 458, 459, 460, 461, 0,
+	462, 463, 464, 466, 465, 0, 467, 468, 469, 0,
+	470, 471, 0, 472, 473, 474, 476, 478, 475, 477,
+	479, 480, 481, 482, 483, 0, 0, 484, 485, 0,
+	0, 0, 0, 0, 0, 0, 486, 487, 488, 0,
+	0, 0, 0, 489, 0, 491, 495, 496, 492, 493,
+	494, 497, 0, 490, 498, 499, 0, 0, 500, 501,
+	502, 0, 0, 503, 504, 505, 506, 507, 508, 509,
+	510, 511, 0, 512, 513, 0, 0, 0, 514, 0,
+	515, 516, 517, 518, 519, 520, 521, 2200, 0, 0,
+	630, 0, 522, 523, 524, 525, 0, 526, 527, 528,
+	529, 530, 531, 532, 0, 0, 0, 533, 534, 535,
+	536, 0, 0, 0, 0, 0, 0, 537, 631, 538,
+	539, 0, 0, 0, 0, 0, 540, 541, 544, 0,
+	0, 0, 543, 545, 546, 0, 547, 0, 0, 0,
+	548, 549, 550, 551, 552, 553, 554, 0, 555, 557,
+	556, 0, 559, 0, 558, 0, 560, 561, 0, 0,
+	562, 563, 564, 565, 566, 567, 572, 0, 0, 568,
+	569, 570, 571, 573, 574, 0, 575, 576, 578, 581,
+	577, 579, 580, 582, 583, 596, 597, 598, 584, 585,
+	586, 587, 588, 589, 590, 591, 592, 593, 594, 595,
+	600, 0, 599, 0, 0, 601, 602, 603, 604, 605,
+	606, 612, 615, 617, 618, 613, 614, 616, 619, 620,
+	621, 623, 624, 609, 610, 611, 0, 622, 607, 0,
+	608, 0, 0, 625, 626, 627, 628, 0, 0, 629,
+	0, 632, 633, 0, 0, 634, 0, 635, 636, 0,
+	0, 638, 639, 640, 0, 0, 641, 642, 0, 0,
+	643, 0, 0, 644, 645, 637, 646, 647, 648, 649,
+	650, 651, 652, 653, 654, 655, 656, 657, 0, 658,
+	659, 0, 660, 661, 662, 663, 664, 0, 665, 666,
+	667, 0, 668, 0, 669, 670, 671, 0, 672, 673,
+	674, 0, 675, 676, 677, 678, 679, 680, 681, 682,
+	683, 684, 0, 685, 686, 688, 687, 689, 690, 0,
+	691, 692, 0, 693, 694, 695, 0, 0, 0, 0,
+	0, 696, 697, 699, 0, 700, 701, 702, 703, 704,
+	705, 698, 706, 707, 708, 709, 710, 711, 712, 713,
+	0, 715, 716, 714, 717, 718, 0, 719, 720, 721,
+	722, 723, 0, 724, 0, 725, 726, 734, 735, 736,
+	727, 728, 730, 737, 729, 738, 739, 740, 741, 743,
+	742, 0, 745, 746, 744, 747, 748, 749, 750, 1750,
+	751, 0, 752, 731, 732, 753, 754, 755, 0, 756,
+	757, 758, 759, 760, 761, 762, 763, 764, 0, 0,
+	766, 0, 765, 767, 768, 769, 770, 771, 772, 773,
+	775, 733, 776, 777, 778, 783, 784, 785, 0, 779,
+	780, 781, 782, 787, 0, 788, 789, 790, 791, 0,
+	792, 793, 0, 786, 774, 0, 794, 795, 796, 797,
+	798, 799, 800, 801, 802, 803, 0, 804, 0, 0,
+	0, 0, 0, 817, 0, 805, 807, 808, 809, 810,
+	0, 811, 812, 0, 0, 813, 814, 815, 816, 806,
+	819, 820, 818, 0, 0, 821, 822, 823, 824, 826,
+	828, 829, 830, 825, 827, 831, 0, 832, 0, 0,
+	833, 834, 835, 0, 0, 0, 0, 0, 838, 839,
+	836, 837, 840, 841, 844, 842, 843, 0, 847, 542,
+	848, 849, 850, 845, 846, 2112, 0, 1747, 0, 851,
+	852, 0, 853, 854, 855, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 367, 368, 370, 369, 371, 372,
+	373, 374, 0, 375, 376, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 378, 0, 377, 0, 379, 380,
+	381, 0, 382, 383, 384, 385, 386, 387, 388, 389,
+	390, 0, 391, 0, 0, 392, 0, 393, 0, 0,
+	0, 394, 395, 396, 397, 398, 399, 400, 401, 402,
+	403, 404, 0, 0, 0, 405, 0, 0, 0, 0,
+	406, 407, 408, 409, 0, 0, 0, 0, 410, 411,
+	412, 413, 414, 415, 416, 417, 0, 0, 419, 420,
+	421, 418, 422, 423, 0, 424, 0, 425, 426, 427,
+	428, 429, 0, 430, 431, 0, 432, 433, 434, 0,
+	435, 436, 437, 0, 0, 0, 0, 0, 0, 1749,
+	438, 439, 440, 441, 442, 0, 443, 445, 0, 0,
+	0, 448, 450, 444, 446, 0, 449, 447, 451, 452,
+	0, 453, 454, 455, 456, 457, 0, 0, 0, 458,
+	459, 460, 461, 0, 462, 463, 464, 466, 465, 0,
+	467, 468, 469, 0, 470, 471, 0, 472, 473, 474,
+	476, 478, 475, 477, 479, 480, 481, 482, 483, 0,
+	0, 484, 485, 0, 0, 0, 0, 0, 0, 0,
+	486, 487, 488, 0, 0, 0, 0, 489, 0, 491,
+	495, 496, 492, 493, 494, 497, 0, 490, 498, 499,
+	0, 0, 500, 501, 502, 0, 0, 503, 504, 505,
+	506, 507, 508, 509, 510, 511, 0, 512, 513, 0,
+	0, 0, 514, 0, 515, 516, 517, 518, 519, 520,
+	521, 2111, 0, 0, 630, 0, 522, 523, 524, 525,
+	0, 526, 527, 528, 529, 530, 531, 532, 0, 0,
+	0, 533, 534, 535, 536, 0, 0, 0, 0, 0,
+	0, 537, 631, 538, 539, 0, 0, 0, 0, 0,
+	540, 541, 544, 0, 0, 0, 543, 545, 546, 0,
+	547, 0, 0, 0, 548, 549, 550, 551, 552, 553,
+	554, 0, 555, 557, 556, 0, 559, 0, 558, 0,
+	560, 561, 0, 0, 562, 563, 564, 565, 566, 567,
+	572, 0, 0, 568, 569, 570, 571, 573, 574, 0,
+	575, 576, 578, 581, 577, 579, 580, 582, 583, 596,
+	597, 598, 584, 585, 586, 587, 588, 589, 590, 591,
+	592, 593, 594, 595, 600, 0, 599, 0, 0, 601,
+	602, 603, 604, 605, 606, 612, 615, 617, 618, 613,
+	614, 616, 619, 620, 621, 623, 624, 609, 610, 611,
+	0, 622, 607, 0, 608, 0, 0, 625, 626, 627,
+	628, 0, 0, 629, 0, 632, 633, 0, 0, 634,
+	0, 635, 636, 0, 0, 638, 639, 640, 0, 0,
+	641, 642, 0, 0, 643, 0, 0, 644, 645, 637,
+	646, 647, 648, 649, 650, 651, 652, 653, 654, 655,
+	656, 657, 0, 658, 659, 0, 660, 661, 662, 663,
+	664, 0, 665, 666, 667, 0, 668, 0, 669, 670,
+	671, 0, 672, 673, 674, 0, 675, 676, 677, 678,
+	679, 680, 681, 682, 683, 684, 0, 685, 686, 688,
+	687, 689, 690, 0, 691, 692, 0, 693, 694, 695,
+	0, 0, 0, 0, 0, 696, 697, 699, 0, 700,
+	701, 702, 703, 704, 705, 698, 706, 707, 708, 709,
+	710, 711, 712, 713, 0, 715, 716, 714, 717, 718,
+	0, 719, 720, 721, 722, 723, 0, 724, 0, 725,
+	726, 734, 735, 736, 727, 728, 730, 737, 729, 738,
+	739, 740, 741, 743, 742, 0, 745, 746, 744, 747,
+	748, 749, 750, 1750, 751, 0, 752, 731, 732, 753,
+	754, 755, 0, 756, 757, 758, 759, 760, 761, 762,
+	763, 764, 0, 0, 766, 0, 765, 767, 768, 769,
+	770, 771, 772, 773, 775, 733, 776, 777, 778, 783,
+	784, 785, 0, 779, 780, 781, 782, 787, 0, 788,
+	789, 790, 791, 0, 792, 793, 0, 786, 774, 0,
+	794, 795, 796, 797, 798, 799, 800, 801, 802, 803,
+	0, 804, 0, 0, 0, 0, 0, 817, 0, 805,
+	807, 808, 809, 810, 0, 811, 812, 0, 0, 813,
+	814, 815, 816, 806, 819, 820, 818, 0, 0, 821,
+	822, 823, 824, 826, 828, 829, 830, 825, 827, 831,
+	0, 832, 0, 0, 833, 834, 835, 0, 0, 0,
+	0, 0, 838, 839, 836, 837, 840, 841, 844, 842,
+	843, 0, 847, 542, 848, 849, 850, 845, 846, 1745,
+	0, 1747, 0, 851, 852, 0, 853, 854, 855, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 367, 368,
+	370, 369, 371, 372, 373, 374, 0, 375, 376, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 378, 0,
+	377, 0, 379, 380, 381, 0, 382, 383, 384, 385,
+	386, 387, 388, 389, 390, 0, 391, 0, 0, 392,
+	0, 393, 0, 0, 0, 394, 395, 396, 397, 398,
+	399, 400, 401, 402, 403, 404, 0, 0, 0, 405,
+	0, 0, 0, 0, 406, 407, 408, 409, 0, 0,
+	0, 0, 410, 411, 412, 413, 414, 415, 416, 417,
+	0, 0, 419, 420, 421, 418, 422, 423, 0, 424,
+	0, 425, 426, 427, 428, 429, 0, 430, 431, 0,
+	432, 433, 434, 0, 435, 436, 437, 0, 0, 0,
+	0, 0, 0, 1749, 438, 439, 440, 441, 442, 0,
+	443, 445, 0, 0, 0, 448, 450, 444, 446, 0,
+	449, 447, 451, 452, 0, 453, 454, 455, 456, 457,
+	0, 0, 0, 458, 459, 460, 461, 0, 462, 463,
+	464, 466, 465, 0, 467, 468, 469, 0, 470, 471,
+	0, 472, 473, 474, 476, 478, 475, 477, 479, 480,
+	481, 482, 483, 0, 0, 484, 485, 0, 0, 0,
+	0, 0, 0, 0, 486, 487, 488, 0, 0, 0,
+	0, 489, 0, 491, 495, 496, 492, 493, 494, 497,
+	0, 490, 498, 499, 0, 0, 500, 501, 502, 0,
+	0, 503, 504, 505, 506, 507, 508, 509, 510, 511,
+	0, 512, 513, 0, 0, 0, 514, 0, 515, 516,
+	517, 518, 519, 520, 521, 1744, 0, 0, 630, 0,
+	522, 523, 524, 525, 0, 526, 527, 528, 529, 530,
+	531, 532, 0, 0, 0, 533, 534, 535, 536, 0,
+	0, 0, 0, 0, 0, 537, 631, 538, 539, 0,
+	0, 0, 0, 0, 540, 541, 544, 0, 0, 0,
+	543, 545, 546, 0, 547, 0, 0, 0, 548, 549,
+	550, 551, 552, 553, 554, 0, 555, 557, 556, 0,
+	559, 0, 558, 0, 560, 561, 0, 0, 562, 563,
+	564, 565, 566, 567, 572, 0, 0, 568, 569, 570,
+	571, 573, 574, 0, 575, 576, 578, 581, 577, 579,
+	580, 582, 583, 596, 597, 598, 584, 585, 586, 587,
+	588, 589, 590, 591, 592, 593, 594, 595, 600, 0,
+	599, 0, 0, 601, 602, 603, 604, 605, 606, 612,
+	615, 617, 618, 613, 614, 616, 619, 620, 621, 623,
+	624, 609, 610, 611, 0, 622, 607, 0, 608, 0,
+	0, 625, 626, 627, 628, 0, 0, 629, 0, 632,
+	633, 0, 0, 634, 0, 635, 636, 0, 0, 638,
+	639, 640, 0, 0, 641, 642, 0, 0, 643, 0,
+	0, 644, 645, 637, 646, 647, 648, 649, 650, 651,
+	652, 653, 654, 655, 656, 657, 0, 658, 659, 0,
+	660, 661, 662, 663, 664, 0, 665, 666, 667, 0,
+	668, 0, 669, 670, 671, 0, 672, 673, 674, 0,
+	675, 676, 677, 678, 679, 680, 681, 682, 683, 684,
+	0, 685, 686, 688, 687, 689, 690, 0, 691, 692,
+	0, 693, 694, 695, 0, 0, 0, 0, 0, 696,
+	697, 699, 0, 700, 701, 702, 703, 704, 705, 698,
+	706, 707, 708, 709, 710, 711, 712, 713, 0, 715,
+	716, 714, 717, 718, 0, 719, 720, 721, 722, 723,
+	0, 724, 0, 725, 726, 734, 735, 736, 727, 728,
+	730, 737, 729, 738, 739, 740, 741, 743, 742, 0,
+	745, 746, 744, 747, 748, 749, 750, 1750, 751, 0,
+	752, 731, 732, 753, 754, 755, 0, 756, 757, 758,
+	759, 760, 761, 762, 763, 764, 0, 0, 766, 0,
+	765, 767, 768, 769, 770, 771, 772, 773, 775, 733,
+	776, 777, 778, 783, 784, 785, 0, 779, 780, 781,
+	782, 787, 0, 788, 789, 790, 791, 0, 792, 793,
+	0, 786, 774, 0, 794, 795, 796, 797, 798, 799,
+	800, 801, 802, 803, 0, 804, 0, 0, 0, 0,
+	0, 817, 0, 805, 807, 808, 809, 810, 0, 811,
+	812, 0, 0, 813, 814, 815, 816, 806, 819, 820,
+	818, 0, 0, 821, 822, 823, 824, 826, 828, 829,
+	830, 825, 827, 831, 0, 832, 0, 0, 833, 834,
+	835, 0, 0, 0, 0, 0, 838, 839, 836, 837,
+	840, 841, 844, 842, 843, 0, 847, 542, 848, 849,
+	850, 845, 846, 5670, 0, 1747, 0, 851, 852, 0,
+	853, 854, 855, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 367, 368, 370, 369, 371, 372, 373, 374,
+	0, 375, 376, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 378, 0, 377, 0, 379, 380, 381, 0,
+	382, 383, 384, 385, 386, 387, 388, 389, 390, 0,
+	391, 0, 0, 392, 0, 393, 0, 0, 0, 394,
+	395, 396, 397, 398, 399, 400, 401, 402, 403, 404,
+	0, 0, 0, 405, 0, 0, 0, 0, 406, 407,
+	408, 409, 0, 0, 0, 0, 410, 411, 412, 413,
+	414, 415, 416, 417, 0, 0, 419, 420, 421, 418,
+	422, 423, 0, 424, 0, 425, 426, 427, 428, 429,
+	0, 430, 431, 0, 432, 433, 434, 0, 435, 436,
+	437, 0, 0, 0, 0, 0, 0, 1749, 438, 439,
+	440, 441, 442, 0, 443, 445, 0, 0, 0, 448,
+	450, 444, 446, 0, 449, 447, 451, 452, 0, 453,
+	454, 455, 456, 457, 0, 0, 0, 458, 459, 460,
+	461, 0, 462, 463, 464, 466, 465, 0, 467, 468,
+	469, 0, 470, 471, 0, 472, 473, 474, 476, 478,
+	475, 477, 479, 480, 481, 482, 483, 0, 0, 484,
+	485, 0, 0, 0, 0, 0, 0, 0, 486, 487,
+	488, 0, 0, 0, 0, 489, 0, 491, 495, 496,
+	492, 493, 494, 497, 0, 490, 498, 499, 0, 0,
+	500, 501, 502, 0, 0, 503, 504, 505, 506, 507,
+	508, 509, 510, 511, 0, 512, 513, 0, 0, 0,
+	514, 0, 515, 516, 517, 518, 519, 520, 521, 0,
+	0, 0, 630, 0, 522, 523, 524, 525, 0, 526,
+	527, 528, 529, 530, 531, 532, 0, 0, 0, 533,
+	534, 535, 536, 0, 0, 0, 0, 0, 0, 537,
+	631, 538, 539, 0, 0, 0, 0, 0, 540, 541,
+	544, 0, 0, 0, 543, 545, 546, 0, 547, 0,
+	0, 0, 548, 549, 550, 551, 552, 553, 554, 0,
+	555, 557, 556, 0, 559, 0, 558, 0, 560, 561,
+	0, 0, 562, 563, 564, 565, 566, 567, 572, 0,
+	0, 568, 569, 570, 571, 573, 574, 0, 575, 576,
+	578, 581, 577, 579, 580, 582, 583, 596, 597, 598,
+	584, 585, 586, 587, 588, 589, 590, 591, 592, 593,
+	594, 595, 600, 0, 599, 0, 0, 601, 602, 603,
+	604, 605, 606, 612, 615, 617, 618, 613, 614, 616,
+	619, 620, 621, 623, 624, 609, 610, 611, 0, 622,
+	607, 0, 608, 0, 0, 625, 626, 627, 628, 0,
+	0, 629, 0, 632, 633, 0, 0, 634, 0, 635,
+	636, 0, 0, 638, 639, 640, 0, 0, 641, 642,
+	0, 0, 643, 0, 0, 644, 645, 637, 646, 647,
+	648, 649, 650, 651, 652, 653, 654, 655, 656, 657,
+	0, 658, 659, 0, 660, 661, 662, 663, 664, 0,
+	665, 666, 667, 0, 668, 0, 669, 670, 671, 0,
+	672, 673, 674, 0, 675, 676, 677, 678, 679, 680,
+	681, 682, 683, 684, 0, 685, 686, 688, 687, 689,
+	690, 0, 691, 692, 0, 693, 694, 695, 0, 0,
+	0, 0, 0, 696, 697, 699, 0, 700, 701, 702,
+	703, 704, 705, 698, 706, 707, 708, 709, 710, 711,
+	712, 713, 0, 715, 716, 714, 717, 718, 0, 719,
+	720, 721, 722, 723, 0, 724, 0, 725, 726, 734,
+	735, 736, 727, 728, 730, 737, 729, 738, 739, 740,
+	741, 743, 742, 0, 745, 746, 744, 747, 748, 749,
+	750, 1750, 751, 0, 752, 731, 732, 753, 754, 755,
+	0, 756, 757, 758, 759, 760, 761, 762, 763, 764,
+	0, 0, 766, 0, 765, 767, 768, 769, 770, 771,
+	772, 773, 775, 733, 776, 777, 778, 783, 784, 785,
+	0, 779, 780, 781, 782, 787, 0, 788, 789, 790,
+	791, 0, 792, 793, 0, 786, 774, 0, 794, 795,
+	796, 797, 798, 799, 800, 801, 802, 803, 0, 804,
+	0, 0, 0, 0, 0, 817, 0, 805, 807, 808,
+	809, 810, 0, 811, 812, 0, 0, 813, 814, 815,
+	816, 806, 819, 820, 818, 0, 0, 821, 822, 823,
+	824, 826, 828, 829, 830, 825, 827, 831, 0, 832,
+	0, 0, 833, 834, 835, 0, 0, 0, 0, 0,
+	838, 839, 836, 837, 840, 841, 844, 842, 843, 0,
+	847, 542, 848, 849, 850, 845, 846, 2662, 0, 1747,
+	0, 851, 852, 0, 853, 854, 855, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 367, 368, 370, 369,
+	371, 372, 373, 374, 0, 375, 376, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 378, 0, 377, 0,
+	379, 380, 381, 0, 382, 383, 384, 385, 386, 387,
+	388, 389, 390, 0, 391, 0, 0, 392, 0, 393,
+	0, 0, 0, 394, 395, 396, 397, 398, 399, 400,
+	401, 402, 403, 404, 0, 0, 0, 405, 0, 0,
+	0, 0, 406, 407, 408, 409, 0, 0, 0, 0,
+	410, 411, 412, 413, 414, 415, 416, 417, 0, 0,
+	419, 420, 421, 418, 422, 423, 0, 424, 0, 425,
+	426, 427, 428, 429, 0, 430, 431, 0, 432, 433,
+	434, 0, 435, 436, 437, 0, 0, 0, 0, 0,
+	0, 1749, 438, 439, 440, 441, 442, 0, 443, 445,
+	0, 0, 0, 448, 450, 444, 446, 0, 449, 447,
+	451, 452, 0, 453, 454, 455, 456, 457, 0, 0,
+	0, 458, 459, 460, 461, 0, 462, 463, 464, 466,
+	465, 0, 467, 468, 469, 0, 470, 471, 0, 472,
+	473, 474, 476, 478, 475, 477, 479, 480, 481, 482,
+	483, 0, 0, 484, 485, 0, 0, 0, 0, 0,
+	0, 0, 486, 487, 488, 0, 0, 0, 0, 489,
+	0, 491, 495, 496, 492, 493, 494, 497, 0, 490,
+	498, 499, 0, 0, 500, 501, 502, 0, 0, 503,
+	504, 505, 506, 507, 508, 509, 510, 511, 0, 512,
+	513, 0, 0, 0, 514, 0, 515, 516, 517, 518,
+	519, 520, 521, 0, 0, 0, 630, 0, 522, 523,
+	524, 525, 0, 526, 527, 528, 529, 530, 531, 532,
+	0, 0, 0, 533, 534, 535, 536, 0, 0, 0,
+	0, 0, 0, 537, 631, 538, 539, 0, 0, 0,
+	0, 0, 540, 541, 544, 0, 0, 0, 543, 545,
+	546, 0, 547, 0, 0, 0, 548, 549, 550, 551,
+	552, 553, 554, 0, 555, 557, 556, 0, 559, 0,
+	558, 0, 560, 561, 0, 0, 562, 563, 564, 565,
+	566, 567, 572, 0, 0, 568, 569, 570, 571, 573,
+	574, 0, 575, 576, 578, 581, 577, 579, 580, 582,
+	583, 596, 597, 598, 584, 585, 586, 587, 588, 589,
+	590, 591, 592, 593, 594, 595, 600, 0, 599, 0,
+	0, 601, 602, 603, 604, 605, 606, 612, 615, 617,
+	618, 613, 614, 616, 619, 620, 621, 623, 624, 609,
+	610, 611, 0, 622, 607, 0, 608, 0, 0, 625,
+	626, 627, 628, 0, 0, 629, 0, 632, 633, 0,
+	0, 634, 0, 635, 636, 0, 0, 638, 639, 640,
+	0, 0, 641, 642, 0, 0, 643, 0, 0, 644,
+	645, 637, 646, 647, 648, 649, 650, 651, 652, 653,
+	654, 655, 656, 657, 0, 658, 659, 0, 660, 661,
+	662, 663, 664, 0, 665, 666, 667, 0, 668, 0,
+	669, 670, 671, 0, 672, 673, 674, 0, 675, 676,
+	677, 678, 679, 680, 681, 682, 683, 684, 0, 685,
+	686, 688, 687, 689, 690, 0, 691, 692, 0, 693,
+	694, 695, 0, 0, 0, 0, 0, 696, 697, 699,
+	0, 700, 701, 702, 703, 704, 705, 698, 706, 707,
+	708, 709, 710, 711, 712, 713, 0, 715, 716, 714,
+	717, 718, 0, 719, 720, 721, 722, 723, 0, 724,
+	0, 725, 726, 734, 735, 736, 727, 728, 730, 737,
+	729, 738, 739, 740, 741, 743, 742, 0, 745, 746,
+	744, 747, 748, 749, 750, 1750, 751, 0, 752, 731,
+	732, 753, 754, 755, 0, 756, 757, 758, 759, 760,
+	761, 762, 763, 764, 0, 0, 766, 0, 765, 767,
+	768, 769, 770, 771, 772, 773, 775, 733, 776, 777,
+	778, 783, 784, 785, 0, 779, 780, 781, 782, 787,
+	0, 788, 789, 790, 791, 0, 792, 793, 0, 786,
+	774, 0, 794, 795, 796, 797, 798, 799, 800, 801,
+	802, 803, 0, 804, 0, 0, 0, 0, 0, 817,
+	0, 805, 807, 808, 809, 810, 0, 811, 812, 0,
+	0, 813, 814, 815, 816, 806, 819, 820, 818, 0,
+	0, 821, 822, 823, 824, 826, 828, 829, 830, 825,
+	827, 831, 0, 832, 0, 0, 833, 834, 835, 0,
+	0, 0, 0, 0, 838, 839, 836, 837, 840, 841,
+	844, 842, 843, 0, 847, 542, 848, 849, 850, 845,
+	846, 2611, 0, 1747, 0, 851, 852, 0, 853, 854,
+	855, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	367, 368, 370, 369, 371, 372, 373, 374, 0, 375,
+	376, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	378, 0, 377, 0, 379, 380, 381, 0, 382, 383,
+	384, 385, 386, 387, 388, 389, 390, 0, 391, 0,
+	0, 392, 0, 393, 0, 0, 0, 394, 395, 396,
+	397, 398, 399, 400, 401, 402, 403, 404, 0, 0,
+	0, 405, 0, 0, 0, 0, 406, 407, 408, 409,
+	0, 0, 0, 0, 410, 411, 412, 413, 414, 415,
+	416, 417, 0, 0, 419, 420, 421, 418, 422, 423,
+	0, 424, 0, 425, 426, 427, 428, 429, 0, 430,
+	431, 0, 432, 433, 434, 0, 435, 436, 437, 0,
+	0, 0, 0, 0, 0, 1749, 438, 439, 440, 441,
+	442, 0, 443, 445, 0, 0, 0, 448, 450, 444,
+	446, 0, 449, 447, 451, 452, 0, 453, 454, 455,
+	456, 457, 0, 0, 0, 458, 459, 460, 461, 0,
+	462, 463, 464, 466, 465, 0, 467, 468, 469, 0,
+	470, 471, 0, 472, 473, 474, 476, 478, 475, 477,
+	479, 480, 481, 482, 483, 0, 0, 484, 485, 0,
+	0, 0, 0, 0, 0, 0, 486, 487, 488, 0,
+	0, 0, 0, 489, 0, 491, 495, 496, 492, 493,
+	494, 497, 0, 490, 498, 499, 0, 0, 500, 501,
+	502, 0, 0, 503, 504, 505, 506, 507, 508, 509,
+	510, 511, 0, 512, 513, 0, 0, 0, 514, 0,
+	515, 516, 517, 518, 519, 520, 521, 0, 0, 0,
+	630, 0, 522, 523, 524, 525, 0, 526, 527, 528,
+	529, 530, 531, 532, 0, 0, 0, 533, 534, 535,
+	536, 0, 0, 0, 0, 0, 0, 537, 631, 538,
+	539, 0, 0, 0, 0, 0, 540, 541, 544, 0,
+	0, 0, 543, 545, 546, 0, 547, 0, 0, 0,
+	548, 549, 550, 551, 552, 553, 554, 0, 555, 557,
+	556, 0, 559, 0, 558, 0, 560, 561, 0, 0,
+	562, 563, 564, 565, 566, 567, 572, 0, 0, 568,
+	569, 570, 571, 573, 574, 0, 575, 576, 578, 581,
+	577, 579, 580, 582, 583, 596, 597, 598, 584, 585,
+	586, 587, 588, 589, 590, 591, 592, 593, 594, 595,
+	600, 0, 599, 0, 0, 601, 602, 603, 604, 605,
+	606, 612, 615, 617, 618, 613, 614, 616, 619, 620,
+	621, 623, 624, 609, 610, 611, 0, 622, 607, 0,
+	608, 0, 0, 625, 626, 627, 628, 0, 0, 629,
+	0, 632, 633, 0, 0, 634, 0, 635, 636, 0,
+	0, 638, 639, 640, 0, 0, 641, 642, 0, 0,
+	643, 0, 0, 644, 645, 637, 646, 647, 648, 649,
+	650, 651, 652, 653, 654, 655, 656, 657, 0, 658,
+	659, 0, 660, 661, 662, 663, 664, 0, 665, 666,
+	667, 0, 668, 0, 669, 670, 671, 0, 672, 673,
+	674, 0, 675, 676, 677, 678, 679, 680, 681, 682,
+	683, 684, 0, 685, 686, 688, 687, 689, 690, 0,
+	691, 692, 0, 693, 694, 695, 0, 0, 0, 0,
+	0, 696, 697, 699, 0, 700, 701, 702, 703, 704,
+	705, 698, 706, 707, 708, 709, 710, 711, 712, 713,
+	0, 715, 716, 714, 717, 718, 0, 719, 720, 721,
+	722, 723, 0, 724, 0, 725, 726, 734, 735, 736,
+	727, 728, 730, 737, 729, 738, 739, 740, 741, 743,
+	742, 0, 745, 746, 744, 747, 748, 749, 750, 1750,
+	751, 0, 752, 731, 732, 753, 754, 755, 0, 756,
+	757, 758, 759, 760, 761, 762, 763, 764, 0, 0,
+	766, 0, 765, 767, 768, 769, 770, 771, 772, 773,
+	775, 733, 776, 777, 778, 783, 784, 785, 0, 779,
+	780, 781, 782, 787, 0, 788, 789, 790, 791, 0,
+	792, 793, 0, 786, 774, 0, 794, 795, 796, 797,
+	798, 799, 800, 801, 802, 803, 0, 804, 0, 0,
+	0, 0, 0, 817, 0, 805, 807, 808, 809, 810,
+	0, 811, 812, 0, 0, 813, 814, 815, 816, 806,
+	819, 820, 818, 0, 0, 821, 822, 823, 824, 826,
+	828, 829, 830, 825, 827, 831, 0, 832, 0, 0,
+	833, 834, 835, 0, 0, 0, 0, 0, 838, 839,
+	836, 837, 840, 841, 844, 842, 843, 0, 847, 542,
+	848, 849, 850, 845, 846, 1747, 0, 0, 0, 851,
+	852, 0, 853, 854, 855, 0, 0, 0, 0, 0,
+	0, 0, 367, 368, 370, 369, 371, 372, 373, 374,
+	0, 375, 376, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 378, 0, 377, 0, 379, 380, 381, 0,
+	382, 383, 384, 385, 386, 387, 388, 389, 390, 0,
+	391, 0, 0, 392, 0, 393, 0, 0, 0, 394,
+	395, 396, 397, 398, 399, 400, 401, 402, 403, 404,
+	0, 0, 0, 405, 0, 0, 0, 0, 406, 407,
+	408, 409, 0, 0, 0, 0, 410, 411, 412, 413,
+	414, 415, 416, 417, 0, 0, 419, 420, 421, 418,
+	422, 423, 0, 424, 0, 425, 426, 427, 428, 429,
+	0, 430, 431, 0, 432, 433, 434, 0, 435, 436,
+	437, 0, 0, 0, 0, 0, 0, 1749, 438, 439,
+	440, 441, 442, 0, 443, 445, 0, 0, 0, 448,
+	450, 444, 446, 0, 449, 447, 451, 452, 0, 453,
+	454, 455, 456, 457, 0, 0, 0, 458, 459, 460,
+	461, 0, 462, 463, 464, 466, 465, 0, 467, 468,
+	469, 0, 470, 471, 0, 472, 473, 474, 476, 478,
+	475, 477, 479, 480, 481, 482, 483, 0, 0, 484,
+	485, 0, 0, 0, 0, 0, 0, 0, 486, 487,
+	488, 0, 0, 0, 0, 489, 0, 491, 495, 496,
+	492, 493, 494, 497, 0, 490, 498, 499, 0, 0,
+	500, 501, 502, 0, 0, 503, 504, 505, 506, 507,
+	508, 509, 510, 511, 0, 512, 513, 0, 0, 0,
+	514, 0, 515, 516, 517, 518, 519, 520, 521, 0,
+	0, 0, 630, 0, 522, 523, 524, 525, 0, 526,
+	527, 528, 529, 530, 531, 532, 0, 0, 0, 533,
+	534, 535, 536, 0, 0, 0, 0, 0, 0, 537,
+	631, 538, 539, 0, 0, 0, 0, 0, 540, 541,
+	544, 0, 0, 0, 543, 545, 546, 0, 547, 0,
+	0, 0, 548, 549, 550, 551, 552, 553, 554, 0,
+	555, 557, 556, 0, 559, 0, 558, 0, 560, 561,
+	0, 0, 562, 563, 564, 565, 566, 567, 572, 0,
+	0, 568, 569, 570, 571, 573, 574, 0, 575, 576,
+	578, 581, 577, 579, 580, 582, 583, 596, 597, 598,
+	584, 585, 586, 587, 588, 589, 590, 591, 592, 593,
+	594, 595, 600, 0, 599, 0, 0, 601, 602, 603,
+	604, 605, 606, 612, 615, 617, 618, 613, 614, 616,
+	619, 620, 621, 623, 624, 609, 610, 611, 0, 622,
+	607, 0, 608, 0, 0, 625, 626, 627, 628, 0,
+	0, 629, 0, 632, 633, 0, 0, 634, 0, 635,
+	636, 0, 0, 638, 639, 640, 0, 0, 641, 642,
+	0, 0, 643, 0, 0, 644, 645, 637, 646, 647,
+	648, 649, 650, 651, 652, 653, 654, 655, 656, 657,
+	0, 658, 659, 0, 660, 661, 662, 663, 664, 0,
+	665, 666, 667, 0, 668, 0, 669, 670, 671, 0,
+	672, 673, 674, 0, 675, 676, 677, 678, 679, 680,
+	681, 682, 683, 684, 0, 685, 686, 688, 687, 689,
+	690, 0, 691, 692, 0, 693, 694, 695, 0, 0,
+	0, 0, 0, 696, 697, 699, 0, 700, 701, 702,
+	703, 704, 705, 698, 706, 707, 708, 709, 710, 711,
+	712, 713, 0, 715, 716, 714, 717, 718, 0, 719,
+	720, 721, 722, 723, 0, 724, 0, 725, 726, 734,
+	735, 736, 727, 728, 730, 737, 729, 738, 739, 740,
+	741, 743, 742, 0, 745, 746, 744, 747, 748, 749,
+	750, 1750, 751, 0, 752, 731, 732, 753, 754, 755,
+	0, 756, 757, 758, 759, 760, 761, 762, 763, 764,
+	0, 0, 766, 0, 765, 767, 768, 769, 770, 771,
+	772, 773, 775, 733, 776, 777, 778, 783, 784, 785,
+	0, 779, 780, 781, 782, 787, 0, 788, 789, 790,
+	791, 0, 792, 793, 0, 786, 774, 0, 794, 795,
+	796, 797, 798, 799, 800, 801, 802, 803, 0, 804,
+	0, 0, 0, 0, 0, 817, 0, 805, 807, 808,
+	809, 810, 0, 811, 812, 0, 0, 813, 814, 815,
+	816, 806, 819, 820, 818, 0, 0, 821, 822, 823,
+	824, 826, 828, 829, 830, 825, 827, 831, 0, 832,
+	0, 0, 833, 834, 835, 0, 0, 0, 0, 0,
+	838, 839, 836, 837, 840, 841, 844, 842, 843, 0,
+	847, 542, 848, 849, 850, 845, 846, 0, 0, 0,
+	0, 851, 852, 0, 853, 854, 855, 2310, 2311, 0,
+	2347, 2348, 2349, 2358, 2359, 2360, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	2351, 2341, 0, 0, 0, 0, 0, 0, 2342, 0,
+	0, 2313, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 2364, 0, 0, 0, 2310, 2311,
+	0, 2347, 2348, 2349, 2358, 2359, 2360, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 2370, 0, 0,
+	0, 2351, 2341, 0, 0, 0, 0, 0, 2312, 2342,
+	0, 0, 2313, 0, 0, 0, 0, 0, 0, 2332,
+	0, 0, 0, 0, 0, 2364, 0, 0, 0, 2329,
+	0, 0, 0, 0, 0, 2344, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 2370, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 2312,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	2332, 0, 0, 0, 0, 0, 0, 0, 0, 2343,
+	2329, 0, 0, 0, 0, 0, 2344, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 2310,
+	2311, 0, 2347, 2348, 2349, 2358, 2359, 2360, 0, 2335,
+	2336, 2337, 2338, 0, 0, 0, 0, 0, 0, 2318,
+	2343, 0, 2351, 2341, 0, 0, 0, 0, 0, 0,
+	2342, 0, 0, 2313, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 2364, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	2335, 2336, 2337, 2338, 0, 0, 0, 0, 2355, 2370,
+	2318, 0, 0, 2365, 0, 0, 0, 0, 0, 0,
+	2312, 0, 2340, 2346, 0, 0, 0, 0, 0, 0,
+	0, 2332, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 2329, 0, 0, 0, 0, 2361, 2344, 2362, 0,
+	0, 0, 0, 0, 0, 2327, 2328, 0, 0, 2355,
+	0, 0, 0, 0, 2365, 0, 0, 0, 0, 0,
+	0, 0, 0, 2340, 2346, 2353, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 2343, 2333, 0, 0, 0, 0, 2361, 0, 2362,
+	0, 0, 0, 0, 0, 0, 2327, 2328, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 2345, 0, 0, 0, 0, 2353, 0, 0, 0,
+	0, 2335, 2336, 2337, 2338, 0, 0, 0, 0, 0,
+	0, 2318, 0, 2333, 0, 0, 0, 0, 0, 2363,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 2352, 2345, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 2367, 0, 0, 0, 0, 0, 0, 0,
+	2355, 0, 0, 0, 0, 2365, 0, 0, 0, 0,
+	2363, 0, 0, 0, 2340, 2346, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 2352, 0, 0, 0, 0, 0, 2361, 0,
+	2362, 0, 0, 2367, 0, 0, 0, 2327, 2328, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 2339, 0, 0, 0, 0, 0, 2353, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 2333, 0, 0, 0, 0, 0,
+	0, 2334, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 2339, 2345, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 2356, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 2363, 2334, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 2352, 0, 0, 0, 0, 0, 2369,
+	0, 0, 0, 0, 2367, 0, 2356, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	2369, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 2339, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 2354, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 2334, 0, 2324, 2325, 2331, 2357, 2330,
+	2326, 0, 2323, 2321, 2322, 2314, 2315, 2316, 2317, 2319,
+	2320, 0, 0, 0, 0, 0, 4815, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 2356, 0, 0,
+	0, 0, 0, 2354, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 2324, 2325, 2331, 2357,
+	2330, 2326, 0, 2323, 2321, 2322, 2314, 2315, 2316, 2317,
+	2319, 2320, 0, 0, 0, 0, 0, 4814, 0, 0,
+	0, 2369, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 2310, 2311, 0, 2347, 2348, 2349, 2358, 2359, 2360,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 2351, 2341, 0, 0, 0, 0,
+	0, 0, 2342, 0, 0, 2313, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 2364, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 2370, 0, 0, 2354, 0, 0, 0, 0, 0,
+	0, 0, 2312, 0, 0, 0, 0, 2324, 2325, 2331,
+	2357, 2330, 2326, 2332, 2323, 2321, 2322, 2314, 2315, 2316,
+	2317, 2319, 2320, 2329, 0, 0, 0, 0, 4813, 2344,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 2310, 2311, 0, 2347, 2348, 2349, 2358, 2359,
+	2360, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 2343, 0, 2351, 2341, 0, 0, 0,
+	0, 0, 0, 2342, 0, 0, 2313, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 2364,
+	0, 0, 0, 2310, 2311, 0, 2347, 2348, 2349, 2358,
+	2359, 2360, 0, 2335, 2336, 2337, 2338, 0, 0, 0,
+	0, 0, 2370, 2318, 0, 0, 2351, 2341, 0, 0,
+	0, 0, 0, 2312, 2342, 0, 0, 2313, 0, 0,
+	0, 0, 0, 0, 2332, 0, 0, 0, 0, 0,
+	2364, 0, 0, 0, 2329, 0, 0, 0, 0, 0,
+	2344, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 2355, 2370, 0, 0, 0, 2365, 0, 0,
+	0, 0, 0, 0, 2312, 0, 2340, 2346, 0, 0,
+	0, 0, 0, 0, 0, 2332, 0, 0, 0, 0,
+	0, 0, 0, 0, 2343, 2329, 0, 0, 0, 0,
+	2361, 2344, 2362, 0, 0, 0, 0, 0, 0, 2327,
+	2328, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 2353,
+	0, 0, 0, 0, 2335, 2336, 2337, 2338, 0, 0,
+	0, 0, 0, 0, 2318, 2343, 2333, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 2345, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 2335, 2336, 2337, 2338, 0,
+	0, 0, 0, 2355, 0, 2318, 0, 0, 2365, 0,
+	0, 0, 0, 2363, 0, 0, 0, 2340, 2346, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 2352, 0, 0, 0, 0,
+	0, 2361, 0, 2362, 0, 0, 2367, 0, 0, 0,
+	2327, 2328, 0, 0, 2355, 0, 0, 0, 0, 2365,
+	0, 0, 0, 0, 0, 0, 0, 0, 2340, 2346,
+	2353, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 2333, 0, 0,
+	0, 0, 2361, 0, 2362, 0, 0, 0, 0, 0,
+	0, 2327, 2328, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 2339, 2345, 0, 0, 0,
+	0, 2353, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 2333, 0,
+	0, 0, 0, 0, 2363, 2334, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 2352, 2345, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 2367, 0, 2356,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 2363, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 2352, 0, 0,
+	0, 0, 0, 2369, 0, 0, 0, 0, 2367, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 2339, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 2334, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 2310, 2311,
+	0, 2347, 2348, 2349, 2358, 2359, 2360, 2339, 0, 0,
+	0, 0, 3003, 0, 0, 0, 0, 0, 0, 0,
+	2356, 2351, 2341, 0, 0, 0, 2354, 0, 0, 2342,
+	0, 0, 2313, 0, 0, 0, 0, 2334, 0, 2324,
+	2325, 2331, 2357, 2330, 2326, 2364, 2323, 2321, 2322, 2314,
+	2315, 2316, 2317, 2319, 2320, 0, 0, 0, 0, 0,
+	4812, 0, 0, 0, 2369, 0, 0, 0, 2370, 0,
+	0, 2356, 0, 0, 0, 0, 0, 0, 0, 2312,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	2332, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	2329, 0, 0, 0, 0, 0, 2344, 0, 0, 0,
+	0, 0, 0, 0, 0, 2369, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	2343, 0, 0, 0, 0, 3004, 0, 2354, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	2324, 2325, 2331, 2357, 2330, 2326, 0, 2323, 2321, 2322,
+	2314, 2315, 2316, 2317, 2319, 2320, 0, 0, 0, 4783,
+	2335, 2336, 2337, 2338, 0, 0, 0, 0, 0, 0,
+	2318, 0, 0, 0, 0, 0, 0, 0, 2354, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 2324, 2325, 2331, 2357, 2330, 2326, 0, 2323, 2321,
+	2322, 2314, 2315, 2316, 2317, 2319, 2320, 0, 0, 0,
+	4241, 0, 0, 0, 0, 0, 0, 0, 0, 2355,
+	0, 0, 0, 0, 2365, 0, 0, 0, 0, 0,
+	0, 0, 0, 2340, 2346, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 2310, 2311, 0, 2347, 2348,
+	2349, 2358, 2359, 2360, 0, 0, 0, 2361, 0, 2362,
+	0, 0, 0, 0, 0, 0, 2327, 2328, 2351, 2341,
+	0, 0, 0, 0, 0, 0, 2342, 0, 0, 2313,
+	0, 0, 0, 0, 0, 0, 2353, 0, 0, 0,
+	0, 0, 2364, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 2333, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 2370, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 2312, 0, 0, 0,
+	0, 0, 2345, 0, 0, 0, 0, 2332, 0, 0,
+	0, 2895, 0, 0, 0, 0, 0, 2329, 0, 0,
+	0, 0, 0, 2344, 0, 0, 0, 0, 0, 0,
+	2363, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 2352, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 2367, 0, 0, 0, 2343, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 2893, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 2335, 2336, 2337,
+	2338, 0, 0, 0, 0, 0, 0, 2318, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 2339, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 2334, 0, 0, 0, 2355, 0, 0, 0,
+	0, 2365, 0, 0, 0, 0, 0, 0, 0, 0,
+	2340, 2346, 0, 0, 0, 0, 0, 0, 3005, 0,
+	0, 0, 0, 0, 0, 0, 2356, 0, 0, 0,
+	0, 0, 0, 0, 2361, 0, 2362, 0, 0, 0,
+	0, 0, 0, 2327, 2328, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 2353, 0, 0, 0, 0, 0, 0,
+	2369, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	2333, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 2345,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 3006, 0, 0, 2310, 2311, 0, 2347, 2348, 2349,
+	2358, 2359, 2360, 0, 0, 0, 0, 2363, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 2351, 2341, 0,
+	0, 0, 0, 0, 0, 2342, 0, 0, 2313, 2352,
+	0, 0, 0, 2354, 0, 0, 0, 0, 0, 0,
+	2367, 2364, 0, 0, 0, 0, 2324, 2325, 2331, 2357,
+	2330, 2326, 0, 2323, 2321, 2322, 2314, 2315, 2316, 2317,
+	2319, 2320, 0, 0, 2370, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 2312, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 2332, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 2329, 0, 0, 0,
+	0, 0, 2344, 0, 0, 0, 0, 0, 2894, 2339,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 2334,
+	0, 0, 0, 0, 0, 0, 2343, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 2310, 2311, 0, 2347, 2348, 2349, 2358, 2359, 2360,
+	0, 0, 0, 2356, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 2351, 2341, 2335, 2336, 2337, 2338,
+	0, 0, 2342, 0, 0, 2313, 2318, 7173, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 2364, 0,
+	0, 0, 0, 0, 0, 0, 0, 2369, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 2892,
+	0, 2370, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 2312, 0, 0, 2355, 0, 0, 0, 0,
+	2365, 0, 0, 2332, 0, 0, 0, 0, 0, 2340,
+	2346, 0, 0, 2329, 0, 0, 0, 0, 0, 2344,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 2361, 0, 2362, 0, 0, 0, 0,
+	0, 0, 2327, 2328, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	2354, 0, 2353, 2343, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 2324, 2325, 2331, 2357, 2330, 2326, 2333,
+	2323, 2321, 2322, 2314, 2315, 2316, 2317, 2319, 2320, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 2335, 2336, 2337, 2338, 0, 2345, 0,
+	0, 0, 0, 2318, 0, 4881, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 4880, 0, 0,
+	0, 0, 0, 0, 0, 0, 2363, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 2352, 0,
+	0, 0, 2355, 0, 0, 0, 0, 2365, 0, 2367,
+	0, 0, 0, 0, 0, 0, 2340, 2346, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 7172, 0, 0, 0,
+	2361, 0, 2362, 0, 0, 0, 0, 0, 0, 2327,
+	2328, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 2353,
+	0, 0, 0, 0, 0, 0, 0, 0, 2339, 0,
+	0, 0, 0, 0, 0, 0, 2333, 0, 0, 2310,
+	2311, 0, 2347, 2348, 2349, 2358, 2359, 2360, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 2334, 0,
+	0, 0, 2351, 2341, 0, 2345, 0, 0, 4753, 0,
+	2342, 0, 0, 2313, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 2364, 0, 0, 0,
+	0, 0, 2356, 2363, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 2370,
+	0, 0, 0, 0, 0, 2352, 0, 0, 0, 0,
+	2312, 0, 0, 0, 0, 0, 2367, 0, 0, 0,
+	0, 2332, 0, 0, 0, 0, 2369, 0, 0, 0,
+	0, 2329, 0, 0, 0, 0, 0, 2344, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 4754, 0, 0, 0, 0,
+	0, 2343, 0, 0, 0, 2339, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 2334, 0, 0, 0, 2354,
+	0, 2335, 2336, 2337, 2338, 0, 0, 0, 0, 0,
+	0, 2318, 2324, 2325, 2331, 2357, 2330, 2326, 0, 2323,
+	2321, 2322, 2314, 2315, 2316, 2317, 2319, 2320, 0, 2356,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 2310, 2311, 0, 2347, 2348,
+	2349, 2358, 2359, 2360, 0, 0, 0, 0, 0, 0,
+	2355, 0, 0, 0, 0, 2365, 0, 0, 2351, 2341,
+	0, 0, 0, 2369, 2340, 2346, 2342, 0, 0, 2313,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 2364, 0, 0, 0, 0, 0, 2361, 0,
+	2362, 0, 0, 0, 0, 0, 0, 2327, 2328, 0,
+	0, 0, 0, 0, 0, 2370, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 2312, 2353, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 2332, 0, 0,
+	0, 0, 0, 0, 2333, 0, 0, 2329, 0, 0,
+	0, 0, 0, 2344, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 2354, 0, 0, 0,
+	0, 0, 0, 2345, 0, 0, 0, 0, 0, 2324,
+	2325, 2331, 2357, 2330, 2326, 0, 2323, 2321, 2322, 2314,
+	2315, 2316, 2317, 2319, 2320, 0, 0, 2343, 0, 0,
+	0, 2363, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 2352, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 2367, 0, 0, 2335, 2336, 2337,
+	2338, 0, 0, 0, 0, 0, 0, 2318, 0, 6567,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 2310, 2311, 0, 2347, 2348, 2349,
+	2358, 2359, 2360, 0, 0, 0, 2355, 0, 0, 0,
+	0, 2365, 0, 2339, 0, 0, 0, 2351, 2341, 0,
+	2340, 2346, 0, 0, 0, 2342, 0, 0, 2313, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 2364, 0, 2334, 2361, 0, 2362, 0, 0, 0,
+	0, 0, 0, 2327, 2328, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 2370, 0, 0, 0, 0, 0,
+	0, 0, 0, 2353, 0, 2312, 0, 2356, 0, 0,
+	0, 0, 0, 0, 0, 0, 2332, 0, 0, 0,
+	2333, 0, 0, 0, 0, 0, 2329, 0, 0, 0,
+	0, 0, 2344, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 2345,
+	0, 2369, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 2343, 2363, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 2352,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	2367, 0, 0, 0, 0, 0, 2335, 2336, 2337, 2338,
+	0, 0, 0, 0, 0, 0, 2318, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 2354, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 2324, 2325, 2331,
+	2357, 2330, 2326, 0, 2323, 2321, 2322, 2314, 2315, 2316,
+	2317, 2319, 2320, 0, 0, 2355, 0, 0, 0, 2339,
+	2365, 0, 0, 0, 0, 0, 0, 0, 0, 2340,
+	2346, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 2334,
+	0, 0, 0, 2361, 0, 2362, 0, 0, 0, 0,
+	0, 0, 2327, 2328, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 2353, 2356, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 2333,
+	0, 0, 2310, 2311, 0, 2347, 2348, 2349, 2358, 2359,
+	2360, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 2351, 2341, 2369, 2345, 0,
+	0, 0, 0, 2342, 0, 0, 2313, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 2364,
+	0, 0, 0, 0, 0, 0, 2363, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 2370, 0, 0, 0, 0, 0, 2352, 0,
+	0, 0, 0, 2312, 0, 0, 0, 0, 0, 2367,
+	0, 0, 0, 0, 2332, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 2329, 0, 0, 0, 0, 0,
+	2344, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	2354, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 2324, 2325, 2331, 2357, 2330, 2326, 0,
+	2323, 2321, 2322, 2314, 2315, 2316, 2317, 2319, 2320, 0,
+	0, 0, 0, 0, 2343, 0, 0, 0, 2339, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 2310,
+	2311, 0, 2347, 2348, 2349, 2358, 2359, 2360, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 2334, 0,
+	0, 0, 2351, 2341, 2335, 2336, 2337, 2338, 0, 0,
+	2342, 0, 0, 2313, 2318, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 2364, 0, 0, 0,
+	0, 0, 2356, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 2370,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	2312, 0, 0, 2355, 0, 0, 0, 0, 2365, 0,
+	0, 2332, 0, 0, 0, 0, 2369, 2340, 2346, 0,
+	0, 2329, 0, 0, 0, 0, 0, 2344, 0, 0,
+	0, 0, 0, 0, 0, 0, 6207, 0, 0, 0,
+	0, 2361, 0, 2362, 0, 0, 0, 0, 0, 0,
+	2327, 2328, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	2353, 2343, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 2333, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 2354,
+	0, 2335, 2336, 2337, 2338, 0, 2345, 0, 0, 0,
+	0, 2318, 2324, 2325, 2331, 2357, 2330, 2326, 0, 2323,
+	2321, 2322, 2314, 2315, 2316, 2317, 2319, 2320, 0, 0,
+	0, 0, 0, 0, 2363, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 2352, 4140, 0, 0,
+	2355, 0, 0, 0, 0, 2365, 0, 2367, 0, 0,
+	0, 0, 0, 0, 2340, 2346, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 2361, 0,
+	2362, 0, 0, 0, 0, 0, 0, 2327, 2328, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 2353, 0, 0,
+	0, 0, 0, 0, 0, 0, 2339, 0, 0, 0,
+	0, 0, 0, 0, 2333, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 2334, 0, 0, 0,
+	0, 0, 0, 2345, 0, 0, 0, 0, 0, 2310,
+	2311, 0, 2347, 2348, 2349, 2358, 2359, 2360, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	2356, 2363, 2351, 2341, 0, 0, 0, 0, 0, 0,
+	2342, 0, 0, 2313, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 2352, 0, 0, 2364, 0, 0, 0,
+	0, 0, 0, 0, 2367, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 2369, 0, 0, 0, 0, 2370,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	2312, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 2332, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 2329, 0, 0, 0, 0, 0, 2344, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 2339, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 2343, 0, 2334, 0, 0, 0, 2354, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	2324, 2325, 2331, 2357, 2330, 2326, 0, 2323, 2321, 2322,
+	2314, 2315, 2316, 2317, 2319, 2320, 0, 2356, 0, 0,
+	0, 2335, 2336, 2337, 2338, 0, 0, 0, 0, 0,
+	0, 2318, 0, 5774, 0, 0, 0, 0, 0, 0,
+	2310, 2311, 0, 2347, 2348, 2349, 2358, 2359, 2360, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 2369, 0, 2351, 2341, 0, 0, 0, 0, 0,
+	0, 2342, 0, 0, 2313, 0, 0, 0, 0, 0,
+	2355, 5775, 0, 0, 0, 2365, 0, 2364, 0, 0,
+	0, 0, 0, 0, 2340, 2346, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	2370, 0, 0, 0, 0, 0, 0, 0, 2361, 0,
+	2362, 2312, 0, 0, 0, 0, 0, 2327, 2328, 0,
+	0, 0, 2332, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 2329, 0, 0, 0, 0, 2353, 2344, 0,
+	0, 0, 0, 0, 2354, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 2333, 0, 0, 2324, 2325, 2331,
+	2357, 2330, 2326, 0, 2323, 2321, 2322, 2314, 2315, 2316,
+	2317, 2319, 2320, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 2343, 2345, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 2363, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 2335, 2336, 2337, 2338, 0, 0, 0, 0,
+	0, 0, 2318, 2352, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 2367, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 2355, 0, 0, 0, 0, 2365, 0, 0, 0,
+	0, 0, 0, 0, 0, 2340, 2346, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 2339, 0, 0, 0, 0, 0, 2361,
+	0, 2362, 0, 0, 0, 0, 0, 0, 2327, 2328,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 2334, 0, 0, 0, 0, 2353, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 2333, 0, 0, 2310, 2311,
+	0, 2347, 2348, 2349, 2358, 2359, 2360, 2356, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 2351, 2341, 0, 2345, 0, 0, 0, 0, 2342,
+	0, 0, 2313, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 2364, 0, 0, 0, 0,
+	0, 2369, 2363, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 2370, 0,
+	0, 0, 0, 0, 2352, 0, 0, 0, 0, 2312,
+	0, 0, 0, 0, 0, 2367, 0, 0, 0, 0,
+	2332, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	2329, 0, 0, 0, 0, 0, 2344, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 2354, 0, 0, 0, 0, 0,
+	2343, 0, 0, 0, 2339, 0, 0, 2324, 2325, 2331,
+	2357, 2330, 2326, 0, 2323, 2321, 2322, 2314, 2315, 2316,
+	2317, 2319, 2320, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 2334, 0, 0, 0, 0, 0,
+	2335, 2336, 2337, 2338, 0, 0, 0, 0, 0, 0,
+	2318, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 4887, 0, 0, 0, 2356, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 2310, 2311, 0,
+	2347, 2348, 2349, 2358, 2359, 2360, 0, 0, 0, 2355,
+	0, 0, 0, 0, 2365, 0, 0, 0, 0, 0,
+	2351, 2341, 2369, 2340, 2346, 4882, 0, 0, 2342, 0,
+	0, 2313, 0, 0, 0, 0, 5483, 0, 0, 0,
+	0, 0, 0, 0, 2364, 0, 0, 2361, 0, 2362,
+	0, 0, 0, 0, 0, 0, 2327, 2328, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 2370, 0, 0,
+	0, 0, 0, 0, 0, 0, 2353, 0, 2312, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 2332,
+	0, 0, 0, 2333, 0, 0, 0, 0, 0, 2329,
+	0, 0, 0, 0, 0, 2344, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 2354, 0, 0, 0, 0,
+	0, 0, 2345, 0, 0, 0, 0, 0, 2324, 2325,
+	2331, 2357, 2330, 2326, 0, 2323, 2321, 2322, 2314, 2315,
+	2316, 2317, 2319, 2320, 0, 0, 0, 0, 0, 2343,
+	2363, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 2352, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 2367, 0, 0, 0, 0, 0, 2335,
+	2336, 2337, 2338, 0, 0, 0, 0, 0, 0, 2318,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 2310, 2311, 0, 2347, 2348, 2349, 2358,
+	2359, 2360, 0, 0, 0, 0, 0, 0, 2355, 0,
+	0, 0, 2339, 2365, 0, 0, 2351, 2341, 0, 0,
+	0, 0, 2340, 2346, 2342, 0, 0, 2313, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	2364, 0, 2334, 0, 0, 0, 2361, 0, 2362, 0,
+	0, 0, 0, 0, 0, 2327, 2328, 0, 0, 0,
+	0, 0, 0, 2370, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 2312, 2353, 2356, 0, 0, 0,
+	0, 0, 0, 0, 0, 2332, 0, 0, 0, 0,
+	0, 0, 2333, 0, 0, 2329, 0, 0, 0, 0,
+	0, 2344, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	2369, 2345, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 2343, 0, 0, 0, 2363,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 2352, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 2367, 0, 0, 2335, 2336, 2337, 2338, 0,
+	0, 0, 0, 0, 0, 2318, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 2354, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 2324, 2325, 2331, 2357,
+	2330, 2326, 0, 2323, 2321, 2322, 2314, 2315, 2316, 2317,
+	2319, 2320, 0, 0, 2355, 0, 0, 0, 0, 2365,
+	0, 2339, 0, 0, 0, 0, 0, 0, 2340, 2346,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 2334, 2361, 0, 2362, 0, 0, 0, 0, 0,
+	0, 2327, 2328, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 2353, 0, 0, 0, 2356, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 2333, 0,
+	0, 0, 2310, 2311, 0, 2347, 2348, 2349, 2358, 2359,
+	2360, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 2351, 2341, 2345, 0, 2369,
+	4816, 0, 0, 2342, 0, 0, 2313, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 2364,
+	0, 0, 0, 0, 0, 2363, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 2370, 0, 0, 0, 0, 2352, 0, 0,
+	0, 0, 0, 2312, 0, 0, 0, 0, 2367, 0,
+	0, 0, 0, 0, 2332, 0, 0, 0, 0, 0,
+	0, 4847, 0, 0, 2329, 0, 0, 0, 0, 0,
+	2344, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 2354, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 2324, 2325, 2331, 2357, 2330,
+	2326, 0, 2323, 2321, 2322, 2314, 2315, 2316, 2317, 2319,
+	2320, 0, 0, 0, 2343, 0, 0, 2339, 2310, 2311,
+	0, 2347, 2348, 2349, 2358, 2359, 2360, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 2351, 2341, 0, 0, 0, 0, 2334, 0, 2342,
+	0, 0, 2313, 0, 2335, 2336, 2337, 2338, 0, 0,
+	0, 0, 0, 0, 2318, 2364, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 2356, 0, 0, 0, 0, 0, 0, 2370, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 2312,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	2332, 0, 0, 2355, 0, 0, 0, 0, 2365, 0,
+	2329, 0, 0, 0, 0, 2369, 2344, 2340, 2346, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 2361, 0, 2362, 0, 0, 0, 0, 0, 0,
+	2327, 2328, 0, 0, 0, 0, 0, 0, 0, 0,
+	2343, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	2353, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 2333, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	2335, 2336, 2337, 2338, 0, 0, 0, 0, 2354, 0,
+	2318, 0, 0, 0, 0, 0, 2345, 0, 0, 0,
+	0, 2324, 2325, 2331, 2357, 2330, 2326, 0, 2323, 2321,
+	2322, 2314, 2315, 2316, 2317, 2319, 2320, 0, 0, 0,
+	0, 0, 0, 0, 2363, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 2355,
+	0, 0, 0, 0, 2365, 0, 2352, 0, 0, 0,
+	0, 0, 0, 2340, 2346, 0, 0, 2367, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 2310, 2311, 0,
+	2347, 2348, 2349, 2358, 2359, 2360, 0, 2361, 0, 2362,
+	0, 0, 0, 0, 0, 0, 2327, 2328, 0, 0,
+	2351, 2341, 0, 0, 0, 0, 0, 0, 2342, 0,
+	0, 2313, 0, 0, 0, 0, 2353, 0, 0, 0,
+	0, 0, 0, 0, 2364, 0, 0, 0, 0, 0,
+	0, 0, 0, 2333, 0, 0, 2339, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 2370, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 2312, 0,
+	0, 0, 2345, 0, 0, 0, 2334, 0, 0, 2332,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 2329,
+	0, 0, 0, 0, 0, 2344, 0, 0, 0, 0,
+	2363, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	2356, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 2352, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 2367, 0, 0, 0, 0, 0, 2343,
+	0, 0, 0, 2310, 2311, 0, 2347, 2348, 2349, 2358,
+	2359, 2360, 0, 0, 2369, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 2351, 2341, 0, 0,
+	0, 0, 0, 0, 2342, 0, 0, 2313, 0, 2335,
+	2336, 2337, 2338, 0, 0, 0, 0, 0, 0, 2318,
+	2364, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 2339, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 2370, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 2312, 0, 0, 0, 0, 0,
+	0, 0, 2334, 0, 0, 2332, 0, 0, 2355, 0,
+	0, 0, 0, 2365, 0, 2329, 0, 2354, 0, 0,
+	0, 2344, 2340, 2346, 0, 0, 0, 0, 0, 0,
+	2324, 2325, 2331, 2357, 2330, 2326, 2356, 2323, 2321, 2322,
+	2314, 2315, 2316, 2317, 2319, 2320, 2361, 0, 2362, 0,
+	0, 0, 0, 0, 0, 2327, 2328, 0, 0, 0,
+	0, 0, 0, 0, 0, 2343, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 2353, 0, 0, 0, 0,
+	2369, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 2333, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 2335, 2336, 2337, 2338, 0,
+	0, 0, 0, 0, 0, 2318, 0, 0, 0, 0,
+	0, 2345, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 2363,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 2355, 0, 3141, 0, 0, 2365,
+	0, 2352, 0, 2354, 0, 0, 0, 0, 2340, 2346,
+	0, 3000, 2367, 0, 0, 0, 2324, 2325, 2331, 2357,
+	2330, 2326, 0, 2323, 2321, 2322, 2314, 2315, 2316, 2317,
+	2319, 2320, 2361, 0, 2362, 0, 0, 0, 0, 0,
+	0, 2327, 2328, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 2353, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 2333, 0,
+	0, 2339, 2310, 2311, 0, 2347, 2348, 2349, 2358, 2359,
+	2360, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 2351, 2341, 2345, 0, 0,
+	0, 2334, 0, 2342, 0, 0, 2313, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 2364,
+	0, 0, 0, 0, 0, 2363, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 2356, 0, 0, 0, 0,
+	0, 0, 2370, 0, 0, 0, 0, 2352, 0, 0,
+	0, 0, 0, 2312, 0, 0, 0, 0, 2367, 0,
+	0, 0, 0, 0, 2332, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 2329, 0, 0, 0, 0, 2369,
+	2344, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 2343, 0, 0, 2339, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 2334, 0, 0,
+	0, 0, 0, 0, 2335, 2336, 2337, 2338, 0, 0,
+	0, 0, 2354, 0, 2318, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 2324, 2325, 2331, 2357, 2330,
+	2326, 2356, 2323, 2321, 2322, 2314, 2315, 2316, 2317, 2319,
+	2320, 0, 0, 0, 0, 0, 0, 0, 2310, 2311,
+	0, 2347, 2348, 2349, 2358, 2359, 2360, 0, 0, 0,
+	0, 0, 0, 2355, 0, 0, 0, 0, 2365, 0,
+	0, 2351, 2341, 0, 0, 2369, 0, 2340, 2346, 2342,
+	0, 0, 2313, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 2364, 0, 0, 0, 0,
+	0, 2361, 0, 2362, 0, 0, 0, 0, 0, 0,
+	2327, 2328, 0, 0, 0, 0, 0, 0, 2370, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 2312,
+	2353, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	2332, 0, 0, 0, 0, 0, 0, 2333, 0, 0,
+	2329, 0, 0, 0, 0, 0, 2344, 0, 0, 0,
+	0, 2792, 0, 0, 0, 0, 0, 0, 2354, 0,
+	0, 0, 0, 0, 0, 0, 2345, 0, 0, 0,
+	0, 2324, 2325, 2331, 2357, 2330, 2326, 0, 2323, 2321,
+	2322, 2314, 2315, 2316, 2317, 2319, 2320, 0, 0, 0,
+	2343, 0, 0, 0, 2363, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 2352, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 2367, 0, 0,
+	2335, 2336, 2337, 2338, 0, 0, 0, 0, 0, 0,
+	2318, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 2355,
+	0, 0, 0, 0, 2365, 0, 2339, 0, 0, 0,
+	0, 0, 0, 2340, 2346, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 2334, 2361, 0, 2362,
+	0, 0, 0, 0, 0, 0, 2327, 2328, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 2353, 0, 0, 0,
+	2356, 1093, 0, 1157, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 2333, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 1101, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 2345, 0, 2369, 0, 0, 0, 1121, 0,
+	0, 1099, 1098, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	2363, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 1123, 0, 0, 0, 0, 0, 0, 1100, 0,
+	0, 0, 0, 0, 1103, 0, 0, 1115, 0, 1170,
+	0, 1135, 0, 2367, 0, 0, 0, 0, 0, 0,
+	1116, 1117, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 1141, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 2354, 0, 1158,
+	1105, 0, 0, 0, 0, 0, 1106, 0, 0, 0,
+	2324, 2325, 2331, 2357, 2330, 2326, 0, 2323, 2321, 2322,
+	2314, 2315, 2316, 2317, 2319, 2320, 0, 0, 0, 0,
+	0, 0, 2339, 0, 0, 0, 0, 1107, 0, 0,
+	0, 0, 0, 0, 0, 0, 1151, 0, 0, 0,
+	0, 0, 0, 0, 1108, 0, 0, 0, 0, 0,
+	0, 0, 2334, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 1152, 0, 1130,
+	0, 0, 0, 0, 0, 0, 2356, 0, 0, 0,
+	0, 0, 0, 0, 1110, 0, 0, 0, 0, 0,
+	0, 0, 0, 1097, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 1112, 1113, 0,
+	2369, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 1124, 1122, 0, 0, 0, 0, 0,
+	0, 1114, 0, 0, 0, 0, 1137, 0, 0, 1163,
+	1162, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 1167, 1150, 0, 0, 0,
+	1092, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 1159, 2354, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 2324, 2325, 2331, 2357,
+	2330, 2326, 0, 2323, 2321, 2322, 2314, 2315, 2316, 2317,
+	2319, 2320, 0, 0, 0, 0, 0, 0, 0, 1093,
+	0, 1157, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 1101, 0, 0, 0,
+	1104, 0, 0, 1169, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 1136, 1121, 0, 0, 1099,
+	1098, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 1131, 1102, 0, 0, 0, 0, 1145,
+	1146, 0, 0, 0, 0, 0, 0, 0, 0, 1123,
+	0, 0, 0, 0, 0, 1148, 1100, 0, 0, 0,
+	0, 0, 1103, 0, 0, 0, 0, 1170, 0, 1135,
+	0, 0, 0, 0, 0, 0, 0, 0, 1116, 1117,
+	0, 0, 0, 0, 0, 0, 0, 1160, 1143, 1141,
+	0, 0, 0, 0, 0, 0, 1168, 1138, 0, 0,
+	1127, 1125, 0, 0, 0, 1132, 0, 1158, 1105, 0,
+	0, 0, 0, 1133, 1106, 0, 0, 1095, 0, 1161,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 1107, 0, 0, 0, 0,
+	1096, 0, 0, 0, 1151, 0, 0, 0, 0, 0,
+	0, 0, 1108, 0, 0, 1149, 0, 0, 1147, 0,
+	1134, 1111, 0, 0, 0, 0, 1129, 0, 0, 0,
+	0, 1155, 0, 1154, 0, 0, 0, 0, 1165, 0,
+	0, 0, 0, 0, 0, 1152, 1139, 1130, 1140, 0,
+	0, 1119, 1118, 0, 0, 0, 0, 0, 1109, 1164,
+	0, 0, 1110, 0, 0, 0, 0, 0, 0, 0,
+	0, 1097, 0, 0, 0, 0, 0, 1142, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 1112, 1113, 1156, 0, 0,
+	0, 0, 0, 1166, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 1144, 0, 0, 0, 0, 0,
+	0, 1124, 1122, 0, 0, 1153, 0, 0, 0, 1114,
+	0, 0, 0, 0, 1137, 0, 0, 1163, 1162, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 1167, 1150, 0, 0, 0, 1092, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	1159, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 1065, 1039, 0, 0, 0, 0,
-	1078, 1079, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 1081, 0, 0, 0, 0,
 	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 1093, 1076, 0, 0, 0,
-	0, 0, 0, 0, 1101, 1071, 0, 0, 1061, 1059,
-	0, 0, 0, 1066, 0, 0, 0, 0, 0, 0,
-	0, 1067, 0, 0, 0, 1032, 0, 1094, 0, 0,
 	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 1104, 0,
+	0, 1169, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 1136, 0, 0, 0, 0, 0, 0,
 	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 1033, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 1082,
-	0, 0, 1080, 0, 1068, 1047, 0, 0, 0, 0,
-	1063, 0, 0, 0, 0, 1088, 0, 1087, 0, 0,
-	0, 0, 1098, 0, 0, 0, 0, 0, 0, 0,
-	1072, 0, 1073, 0, 0, 0, 0, 0, 0, 0,
-	0, 1045, 1097, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 1075,
+	0, 1131, 1102, 0, 0, 0, 0, 1145, 1146, 0,
 	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 1089, 0, 0,
-	0, 0, 0, 1099, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 1077, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 1086,
+	0, 0, 0, 1148, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 1160, 1143, 0, 0, 0,
+	0, 0, 0, 0, 1168, 1138, 0, 0, 1127, 1125,
+	0, 0, 0, 1132, 0, 0, 0, 0, 0, 0,
+	0, 1133, 0, 0, 0, 1095, 0, 1161, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 1096, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 1149, 0, 0, 1147, 0, 1134, 1111,
+	0, 0, 0, 0, 1129, 0, 0, 0, 0, 1155,
+	0, 1154, 0, 0, 0, 0, 1165, 0, 0, 0,
+	0, 0, 0, 0, 1139, 0, 1140, 0, 0, 1119,
+	1118, 0, 0, 0, 0, 0, 1109, 1164, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 1142, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 1156, 0, 0, 0, 0,
+	0, 1166, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 1144, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 1153,
 }
 
 var sqlPact = [...]int32{
-	8241, -1000, -1000, -1000, -1000, -1000, -1000, 385, -1000, -1000,
-	-1000, 384, 373, 368, 365, 363, 362, 356, 355, 354,
-	351, 349, -1000, -1000, 348, 346, 345, 344, -1000, -1000,
-	341, 339, 337, -1000, 334, -1000, -1000, 332, -1000, 330,
-	329, 324, -1000, -1000, 321, -1000, 320, -1000, -1000, -1000,
-	-1000, 319, 312, 309, 126715, 126054, 84985, 86979, 3060, 163018,
-	141890, 2976, 132650, 162357, 131989, 161696, 2920, 15932, 161035, 3625,
-	307, -1000, 160374, 306, 304, 303, -1000, 141229, 159713, 137269,
-	136608, 2619, 99544, 183726, 2109, 2105, -1000, 302, -1000, -1000,
-	9736, 96905, 299, 296, 294, 292, 3809, 289, -1000, 287,
-	285, 279, 275, 272, -1000, -1000, 13704, 1971, -1000, 271,
-	270, 269, 267, -1000, 508, 135947, 266, 265, 263, 3190,
-	260, 259, 92942, 256, 254, 247, 3097, 3746, -1000, -1000,
-	2695, -1000, -1000, 244, 241, 238, 237, 236, 235, 232,
-	230, 228, 227, 222, 220, 218, 217, -1000, 216, 215,
-	214, 210, 209, 207, 206, -1000, 205, 204, 203, -1000,
-	197, -1000, 196, 194, 190, 189, 182, 181, 180, 179,
-	178, 177, 176, 175, 174, 173, 172, 171, -1000, -1000,
-	169, -1000, 2443, 2090, 2089, 2088, 1270, 166, 164, 163,
-	162, 161, 160, 159, 158, 153, 151, 150, 147, 145,
-	143, 142, 141, 138, 137, 135, 134, 129, 128, 127,
-	124, 123, 122, 120, 118, 117, 115, 114, 109, 261,
-	108, 107, 106, 103, 102, 101, 100, 95, 93, 3502,
-	4475, -1000, 1996, 1076, 1543, 40551, 3858, -1000, -1000, -1000,
+	3518, -1000, -1000, -1000, -1000, -1000, -1000, 504, -1000, -1000,
+	-1000, 502, 500, 499, 495, 494, 490, 487, 485, 474,
+	472, 458, 454, -1000, -1000, 449, 446, 441, 440, -1000,
+	-1000, 439, 437, 436, -1000, 435, -1000, -1000, -1000, 434,
+	-1000, 433, 432, 392, -1000, -1000, 388, -1000, 387, -1000,
+	-1000, -1000, -1000, 371, 370, 365, 142363, 141669, 94333, 96426,
+	3461, 183951, 158297, 2925, 4066, 148595, 183257, 147901, 182563, 3258,
+	17243, 181869, 4038, 364, -1000, 181175, 363, 359, 357, -1000,
+	353, 352, 350, 157603, 180481, 153445, 152751, 2537, 108925, 208109,
+	2291, 2289, -1000, 349, -1000, -1000, 12409, 106154, 347, 345,
+	344, 343, 3255, 342, -1000, 341, 340, 339, 333, 331,
+	323, -1000, -1000, 12629, 322, 4543, 2118, -1000, 321, 320,
+	319, 317, -1000, 1413, 152057, 316, 315, 314, 3711, 312,
+	311, 101993, 305, 292, 289, 3560, 4148, -1000, -1000, 3009,
+	-1000, -1000, 288, 287, 286, 283, 282, 281, 280, 269,
+	267, 265, 263, 260, 258, 256, 254, 253, 251, -1000,
+	249, 248, 246, 244, 243, 242, 241, -1000, 240, 239,
+	237, -1000, 236, -1000, 235, 232, 231, 228, 227, 226,
+	222, 221, 219, 217, 216, 212, 211, 209, 208, 207,
+	206, 204, -1000, -1000, 203, -1000, 2704, 2262, 2377, 2312,
+	1414, 202, 200, 197, 196, 195, 194, 187, 186, 184,
+	182, 181, 180, 179, 178, 176, 175, 173, 172, 171,
+	168, 166, 165, 160, 159, 157, 155, 153, 151, 150,
+	149, 148, 147, 146, 145, 144, 143, 142, 278, 140,
+	136, 135, 134, 132, 130, 129, 123, 122, 115, 113,
+	2844, 5086, -1000, 2490, 1231, 1720, 47047, 4315, -1000, -1000,
+	-1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000,
 	-1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000,
 	-1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000,
 	-1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000,
 	-1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000,
-	-1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, 172244,
-	163677, 92, -56, 90, -1000, 4223, 1311, 76980, -1000, -1000,
+	194331, 184643, 111, 6, 99, -1000, 4634, 1395, 85932, -1000,
 	-1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000,
 	-1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000,
 	-1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000,
-	-1000, -1000, -1000, 471, -1000, -1000, -1000, -1000, -1000, -1000,
+	-1000, -1000, -1000, -1000, -1000, 565, -1000, -1000, -1000, -1000,
 	-1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000,
 	-1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000,
 	-1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000,
@@ -25882,257 +28107,267 @@ var sqlPact = [...]int32{
 	-1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000,
 	-1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000,
 	-1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000,
-	-1000, -1000, 930, -1000, 3671, -1000, -1000, -1000, -1000, -1000,
-	-1000, 467, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000,
 	-1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000,
-	-1000, -1000, 653, 191, 2759, 925, -1000, -1000, -1000, 159052,
-	-1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, 3059, 10,
-	133309, -1000, 2794, -1000, -1000, -1000, -1000, -1000, 923, -1000,
-	3058, 2991, 377, 2984, 133309, -1000, -1000, -1000, 4333, 4190,
-	125393, 124732, 3283, 4853, 4852, 4851, 4850, 4849, 171585, 2324,
-	3364, 4848, 4844, 4843, 4842, 4840, 4839, 4837, -1000, 124071,
-	1362, 123410, 122749, 4317, 158393, 122088, 72965, 157732, 174886, 61054,
-	1073, 4332, -1000, -1000, 4270, -1000, -1000, -1000, -1000, -1000,
-	163677, -1000, 1358, -1000, -1000, 4836, 2641, 922, 140568, -1000,
-	-1000, 157071, 2173, -1000, -1000, -1000, 1189, 1463, 44086, 44086,
-	44086, 464, -1000, -1000, -1000, -1000, -1000, -1000, -1000, 4329,
-	-1000, -1000, -1000, -1000, 163677, 3565, 3565, 1796, 1710, 1710,
-	3565, 3565, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000,
-	4835, 4834, 4832, 4831, 4828, -1000, -1000, -1000, 1295, 4826,
-	-1000, -1000, 2940, 2039, 4542, 3593, 106230, 2638, 1768, 4272,
-	3974, 3972, 1911, 2793, 3969, 4825, 3413, 3648, 3968, 3966,
-	3963, 1552, 3962, 3956, 1999, 3424, 505, 3415, 39844, 3848,
-	2326, 60347, 1949, 1904, 3950, 3942, 3938, 3931, 4593, 4407,
-	2773, 2584, 2768, 2604, 109537, 4824, 4823, 4219, 3922, 1893,
-	3657, 3908, 2656, -1000, 3814, 1952, 4474, -1000, 74305, 1751,
-	461, -1000, -1000, -1000, -1000, -1000, -1000, 461, 1839, -1000,
-	-1000, -1000, -1000, -1000, 1690, -1000, -1000, -1000, -1000, -1000,
-	-1000, 111520, 33557, 110859, 110198, 121427, 120766, 156410, 59640, 120105,
-	119444, 105559, 4821, 4820, 58933, 72294, 4473, 1673, 155749, 174225,
-	4472, 4471, 1357, 2787, 1800, -1000, -1000, -1000, -1000, -1000,
-	-1000, 57, 98885, 4557, 163677, 4270, -1000, -1000, 458, -1000,
-	-1000, -1000, -1000, -1000, -1000, -1000, 58226, 843, 57519, 818,
-	56812, 785, 155088, -1000, -1000, -1000, -1000, -1000, -1000, 104888,
-	4188, -1000, 71623, 154427, 1859, 3274, 4816, 4813, 1469, 4812,
-	4150, 2306, 4805, 4804, 4801, 4800, 4799, 4798, 4795, 1938,
-	153766, 3541, 153105, 2262, 173564, 2636, 1356, 118783, 127374, 3456,
-	152444, 1950, 1892, -1000, -1000, -1000, -1000, 4420, 3745, 3744,
-	1361, -1000, -1000, -1000, -1000, -1000, -1000, 81641, 3338, 3156,
-	-1000, -1000, -1000, -1000, 16889, 184202, 151783, 84323, 127374, 127374,
-	-1000, -1000, -1000, -1000, -1000, -1000, 56105, 563, 55398, 1071,
-	151122, -1000, -1000, 82313, 3810, 1407, -1000, -1000, -1000, -1000,
-	-1000, 150461, 54691, 534, 53984, 1007, 163677, -1000, 3857, 2532,
 	-1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000,
 	-1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000,
+	-1000, -1000, -1000, -1000, 1059, -1000, 4104, -1000, -1000, -1000,
+	-1000, -1000, -1000, 564, -1000, -1000, -1000, -1000, -1000, -1000,
 	-1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000,
+	-1000, -1000, -1000, -1000, 785, 201, 3533, 1058, -1000, -1000,
+	-1000, 179787, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000,
+	4067, -1000, -1000, -1000, 122249, 3460, 110, 149287, -1000, 3122,
+	-1000, -1000, -1000, -1000, -1000, 1055, -1000, 5190, 3459, 3326,
+	443, 3321, 149287, -1000, -1000, -1000, 4901, 4723, 179095, 140975,
+	140281, 178401, 3675, 5362, 5361, 5360, 5359, 5357, 193639, 2608,
+	3748, 5354, 5353, 5352, 5351, 5349, 5348, -1000, 139587, 1513,
+	138893, 138199, 4836, 177707, 137505, 81719, 177013, 197797, 69247, 1122,
+	4900, -1000, -1000, 4829, -1000, -1000, -1000, -1000, -1000, 184643,
+	-1000, 1511, -1000, -1000, 5346, 2960, 1054, 156909, -1000, -1000,
+	176319, 2084, -1000, -1000, -1000, 1344, 1644, 50747, 50747, 50747,
+	562, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000,
+	-1000, 4909, -1000, -1000, -1000, -1000, 184643, 3974, 3974, 1938,
+	1896, 1896, 3974, 3974, -1000, -1000, -1000, -1000, -1000, -1000,
+	-1000, -1000, 5345, 5343, 5342, 5341, 5340, -1000, -1000, -1000,
+	1454, 5338, 2912, -1000, -1000, 2227, 2199, 5140, 4001, 120855,
+	3044, 1964, 4830, 4430, 4416, 2100, 2542, 4415, 4691, 2098,
+	3762, 4080, 4414, 4410, 4409, 1980, 4403, 4396, 4392, 5335,
+	2285, 3802, 423, 3817, 46307, 4296, 2690, 68507, 2087, 2076,
+	4389, 4360, 2068, 4356, 5152, 4958, 4480, 3088, 2882, 3045,
+	2906, 124327, 5331, 5330, 4728, 4355, 2067, 4086, 4344, 2900,
+	-1000, 4233, 2144, 5084, -1000, 83125, 1930, 561, -1000, -1000,
+	-1000, -1000, -1000, -1000, 561, 2043, -1000, -1000, -1000, -1000,
+	-1000, 1999, -1000, -1000, -1000, -1000, -1000, -1000, 126409, 39723,
+	125715, 125021, 136811, 136117, 175625, 67767, 135423, 134729, 120151, 5328,
+	5326, 174931, 67027, 66287, 81015, 5077, 1891, 174237, 197103, 5075,
+	5073, 1510, 3111, 2012, -1000, -1000, -1000, -1000, -1000, -1000,
+	64, 108233, 5137, 184643, 4829, -1000, -1000, 560, -1000, -1000,
+	-1000, -1000, -1000, -1000, -1000, 65547, 902, 64807, 901, 64067,
+	569, 173543, -1000, -1000, -1000, -1000, -1000, -1000, -1000, 119447,
+	4722, -1000, 2897, 2855, 80311, 172849, 172155, 2646, 3659, 5324,
+	5323, 1618, 5320, 4680, 2555, 5319, 5317, 5315, 5314, 5313,
+	5312, 2106, 171461, 3937, 170767, 2578, 196409, 2871, 1509, 134035,
+	143055, 1910, 170073, 2137, 2079, -1000, -1000, -1000, -1000, -1000,
+	4706, -1000, 4972, 4144, 4141, 1561, -1000, -1000, -1000, -1000,
+	-1000, -1000, 90824, 11625, 10320, -1000, -1000, -1000, -1000, -1000,
+	20516, 208517, 169379, 93638, 143055, 143055, -1000, -1000, -1000, -1000,
+	-1000, -1000, 63327, 557, 62587, 1102, 168685, -1000, -1000, 118743,
+	4232, 1547, -1000, -1000, -1000, -1000, -1000, 167991, 61847, 424,
+	61107, 970, 184643, -1000, 4313, 2742, -1000, -1000, -1000, -1000,
 	-1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000,
-	-1000, -1000, 112179, -1000, -1000, 1690, -1000, -1000, -1000, 1833,
 	-1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000,
 	-1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000,
 	-1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000,
-	-1000, -1000, -1000, -1000, -1000, -1000, 1996, -1000, -1000, -1000,
-	-1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, 2661,
-	-1000, 2681, -1000, -1000, -1000, 3299, 4191, 4191, 4191, 4330,
-	614, 598, -1000, 261, 1080, 1443, -1000, -1000, 183020, -1000,
-	-1000, 61761, 61761, 61761, 61761, 61761, 61761, 61761, 61761, 2924,
-	-1000, 921, -1000, -1000, -1000, 972, -1000, 920, 798, 789,
-	-1000, -1000, -1000, -1000, -1000, -1000, 916, -1000, -1000, -1000,
-	-1000, -1000, -1000, 4522, -1000, 35602, -1000, -1000, -1000, 689,
-	915, 61761, 4673, 4672, 1236, -1000, 454, 1243, -1000, -1000,
-	-1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, 3856,
-	911, 910, -1000, 908, 904, 903, 902, 900, -1000, 899,
-	-1000, 898, 896, 893, 891, 890, 887, 882, 881, -1000,
-	-1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, 837, 2810,
-	836, 836, 836, -1000, 1341, 835, 880, -1000, 490, 831,
-	478, 827, 826, 824, -1000, 870, 866, 859, 857, 856,
-	855, 852, 849, 848, 1343, -1000, -1000, -1000, -1000, 1392,
-	53, 163677, -1000, 782, 53, -1000, -1000, 847, -1000, 42672,
-	42672, 42672, -1000, -1000, 3052, 61761, -1000, 3401, -1000, 63,
-	63, 1158, 78966, -1000, 75646, 1158, 374, 979, 86317, -1000,
-	3808, -1000, -1000, 452, 34226, 32867, 4555, 34226, 1890, 163677,
-	608, 83, 80, -1000, 77, 76, 163677, 163677, 127374, 127374,
-	127374, 163677, 4793, 4789, 3990, 61761, -1000, -1000, 96243, 176867,
-	135286, 1829, 56, -1000, -1000, 4446, 100873, 95584, 3854, 176867,
-	3853, 3806, 176208, 104217, 315, 4042, -1000, -1000, 846, 315,
-	4041, -1000, 4787, -1000, -1000, -1000, -1000, -1000, 4040, 4786,
-	4785, 4784, 163677, -1000, -1000, -1000, -1000, -1000, -1000, -1000,
-	3004, 4039, -1000, 54, -1000, 131328, 3004, 4038, -1000, 54,
-	3004, 4036, -1000, 54, 130669, -1000, -1000, 3004, 4035, -1000,
-	-1000, 314, 4033, -1000, -1000, 3600, 1145, -1000, -1000, 68124,
-	-1000, 313, 4032, -1000, -1000, 448, -47, 4030, -1000, -1000,
-	-1000, -1000, -1000, -1000, 183020, -1000, -1000, -1000, 175547, -1000,
-	-1000, 4222, -1000, 163677, -1000, 61761, -1000, -1000, 4445, 2027,
-	4233, 4388, -1000, -1000, 34, -1000, -1000, -1000, -1000, -1000,
-	-1000, -1000, 3342, 3340, 1456, 3121, -1000, 4082, 1789, 44086,
-	4133, -1000, -1000, -1000, -1000, -1000, 447, 34226, 3711, -1000,
-	-1000, 163677, -1000, 163677, 3565, 3565, -1000, -1000, -1000, 4572,
-	4571, 3565, 3565, 163677, 163677, -1000, -1000, -1000, -1000, -1000,
-	-1000, 2993, -1000, -1000, -1000, 1887, 3390, -1000, -1000, -1000,
-	82313, 3802, 1650, 106899, 106899, 106899, 106899, 106899, -1000, -1000,
-	-1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, 149800, -1000,
-	-1000, 1906, 2665, 1989, 4204, 2664, 127374, -1000, 2429, -1000,
-	-1000, -1000, 4252, 4037, 163677, -1000, -1000, 3851, -1000, 98226,
-	3851, 130010, -1000, 129351, -1000, 128692, -1000, -1000, 127374, -1000,
-	127374, -1000, 4781, 4779, 4778, -1000, -1000, 4777, 170926, -1000,
-	1905, 4234, -1000, 2408, 926, 53277, 182896, 4227, -1000, 4774,
-	2609, 3848, 183020, -1000, 4034, 2120, 2084, 163677, -1000, -1000,
-	163677, -1000, 163677, -1000, 163677, -1000, 163677, -1000, -1000, -1000,
-	3095, 2041, -1000, -1000, 3339, -1000, -1000, -1000, 1294, -1000,
-	1288, 127374, 127374, 127374, 127374, 3801, 3489, 127374, 127374, 2204,
-	-1000, 52570, 4187, -1000, -1000, 3903, 4773, 2284, -1000, 2364,
-	-1000, -1000, 2771, 3798, 4228, -1000, 3796, 1396, 2435, -1000,
-	-1000, 74305, 4470, -1000, 441, 4678, 441, -1000, -1000, -1000,
-	34, -1000, 6878, 4029, 1551, -1000, 3119, -1000, -1000, -1000,
+	-1000, -1000, -1000, 127101, -1000, -1000, 1999, -1000, -1000, -1000,
+	5187, 1974, -1000, 5186, -1000, -1000, -1000, -1000, -1000, -1000,
 	-1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000,
 	-1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000,
 	-1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000,
+	-1000, -1000, -1000, -1000, 2490, -1000, -1000, -1000, -1000, -1000,
+	-1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, 2847,
+	-1000, 2972, -1000, -1000, -1000, 3717, 4564, 4564, 4564, 4899,
+	742, 719, -1000, 278, 1234, 1578, -1000, -1000, 207541, -1000,
+	-1000, 69987, 69987, 69987, 69987, 69987, 69987, 69987, 69987, 3263,
+	-1000, 1053, -1000, -1000, -1000, 1116, -1000, 1052, 961, 950,
+	-1000, -1000, -1000, -1000, -1000, -1000, 1051, -1000, -1000, -1000,
+	-1000, -1000, -1000, 5123, -1000, 41867, -1000, -1000, -1000, 766,
+	1050, 69987, 5185, 5182, 1369, -1000, 556, 1358, -1000, -1000,
 	-1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000,
+	4308, 1049, 1047, -1000, 1046, 1045, 1043, 1042, 1041, -1000,
+	1039, -1000, 1038, 1036, 1035, 1034, 1033, 1031, 1030, 1029,
+	-1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, 1003,
+	3184, 1001, 1001, 1001, -1000, 1496, 1000, 1028, -1000, 587,
+	989, 579, 988, 987, 986, -1000, 984, 1027, 1026, 1025,
+	1022, 1021, 1018, 1016, 1015, 1014, 1498, -1000, -1000, -1000,
+	-1000, 1553, 61, 184643, -1000, 938, 61, -1000, -1000, 1013,
+	-1000, 49267, 49267, 49267, -1000, 3455, 69987, -1000, 3571, -1000,
+	71, 71, 1324, 88017, -1000, 84532, 1324, 419, 1128, 95731,
+	-1000, 4230, -1000, -1000, 553, 40425, 39000, 5141, 40425, 2039,
+	184643, 740, 98, 91, -1000, 90, 89, 184643, 184643, 143055,
+	143055, 143055, 143055, 184643, 5311, 5310, 4545, 69987, -1000, -1000,
+	-1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, 105459,
+	200571, 151363, 1965, 63, -1000, -1000, 5033, 110320, -1000, 104767,
+	4307, 200571, 4302, 4228, 199879, 118039, 3454, 4522, -1000, 335,
+	4521, -1000, -1000, 1012, 335, 4519, -1000, 3452, 4518, -1000,
+	5309, -1000, -1000, -1000, -1000, -1000, 4517, 5308, 5307, 5306,
+	184643, -1000, -1000, -1000, -1000, -1000, -1000, 3291, 4516, -1000,
+	62, -1000, 147207, 3291, 4510, -1000, 62, 3291, 4509, -1000,
+	62, 146515, -1000, -1000, 3291, 4508, -1000, -1000, 332, 4506,
+	-1000, -1000, 4007, 1286, -1000, -1000, 76647, -1000, 330, 4504,
+	-1000, -1000, 551, -19, 4503, -1000, -1000, -1000, -1000, -1000,
+	-1000, 207541, -1000, -1000, -1000, 199185, -1000, -1000, 4735, -1000,
+	184643, -1000, 69987, -1000, -1000, 5031, 2083, 4779, 4934, -1000,
+	-1000, 42, -1000, -1000, -1000, -1000, -1000, -1000, -1000, 3722,
+	3710, 1668, 3535, -1000, 4570, 1887, 50747, 4663, -1000, -1000,
+	-1000, -1000, -1000, 545, 40425, 4113, -1000, -1000, 184643, -1000,
+	184643, 3974, 3974, -1000, -1000, -1000, 5145, 5144, 3974, 3974,
+	184643, 184643, -1000, -1000, -1000, -1000, -1000, -1000, 3414, -1000,
+	3800, -1000, -1000, 2102, 3766, -1000, -1000, -1000, 91529, 4226,
+	1809, 121557, 121557, 121557, 121557, 121557, -1000, -1000, -1000, 167297,
+	-1000, -1000, 2097, 3002, 2138, 4729, 2996, 143055, -1000, 2730,
+	-1000, -1000, -1000, 4751, 4465, 1500, 184643, -1000, 5304, 117335,
+	-1000, -1000, 4300, -1000, 107541, 4300, 145823, -1000, 145131, -1000,
+	144439, -1000, -1000, 143055, -1000, 143055, -1000, 143055, -1000, -1000,
+	5302, 5300, 5298, -1000, -1000, 5297, 192947, -1000, 2073, 4742,
+	-1000, 2728, 958, 60367, 207202, 4740, -1000, 5296, 3011, 4296,
+	207541, -1000, 4460, 2281, 2278, 184643, -1000, -1000, 184643, -1000,
+	184643, -1000, 184643, -1000, -1000, 184643, -1000, -1000, -1000, 3473,
+	143055, -1000, 2295, -1000, -1000, 3721, -1000, -1000, -1000, 1451,
+	-1000, 1445, 143055, 143055, 143055, 143055, 4223, 3891, 143055, 143055,
+	184643, 2524, -1000, 59627, 4704, -1000, -1000, 4337, 5295, 2415,
+	-1000, 2700, -1000, -1000, 2928, 4222, 4702, -1000, 4221, 1549,
+	2698, -1000, -1000, 83125, 5070, -1000, 543, 5193, 543, -1000,
+	-1000, -1000, 42, -1000, 3819, 4500, 1984, -1000, 3534, -1000,
 	-1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000,
 	-1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000,
 	-1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000,
 	-1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000,
-	-1000, -1000, -1000, -1000, 2639, 4028, -1000, 3142, 4026, 2528,
-	-1000, -1000, 3310, -1000, 2517, -1000, 2448, -1000, 179337, 1686,
-	-1000, -1000, -1000, -1000, 2854, 4024, 65, -1000, -1000, 3133,
-	-1000, 4533, 3761, -1000, -1000, -1000, 179213, -1000, -1000, 3159,
-	2769, 4468, 2710, -1000, 1641, 4022, -1000, 3586, 3586, 118122,
-	4027, 83653, 82313, 98885, 36, -1000, -1000, -1000, -1000, -1000,
-	30, -1000, 31482, 183020, -1000, -1000, -1000, -1000, 183020, 1142,
-	-1000, -1000, 4021, -1000, 183020, 1141, -1000, -1000, 4020, -1000,
-	3419, -1000, 3847, -1000, -1000, -1000, 3218, 103546, 3329, 801,
-	-1000, 3215, 1292, -1000, 117463, 116802, 2780, 4771, -1000, 4768,
-	-1000, -1000, 4767, -1000, 4766, 4764, 4762, -1000, -1000, -1000,
-	-1000, -1000, -1000, -1000, 116141, 3050, -1000, -1000, 1864, 1253,
-	106899, -1000, 3214, 4378, -1000, 115480, 1353, -1000, 1261, 3213,
-	-1000, 1873, 128033, 1231, 3211, -1000, 4761, 4307, 3505, 1261,
-	3209, -1000, -1000, -1000, -1000, -1000, 3792, -1000, 845, 87641,
-	-1000, 87641, -1000, 2168, -1000, 170267, 63, 127374, 4522, -1000,
-	8, -1000, -1000, -1000, 1311, -1000, 80969, -1000, 80969, 139907,
-	106899, 1253, 3789, 92280, 182859, -1000, 1291, -1000, -1000, 183020,
-	-1000, -1000, -1000, 3418, -1000, -144, 3575, -1000, 106899, 82313,
-	3787, 3416, -1000, 183020, -1000, -1000, -1000, -1000, 183020, -1000,
-	-1000, -1000, 106899, 1864, -1000, 149141, 114819, 316, -1000, -1000,
-	169608, -1000, 3299, -1000, 163677, -1000, 3298, 3838, 3845, 2101,
-	3094, 3445, -1000, 51863, 3404, 67417, 3118, 261, -1000, -1000,
-	261, 261, 41965, -1000, -1000, 44086, 1080, 100873, 100873, 34226,
-	1683, 61761, 61761, 61761, 61761, 61761, 61761, 61761, 61761, 61761,
-	61761, 61761, 61761, 61761, 61761, 61761, 61761, 61761, 61761, 61761,
-	61761, 61761, 61761, 61761, 61761, 61761, 61761, 61761, 61761, 61761,
-	61761, 61761, 61761, 61761, 61761, 61761, 61761, 61761, 2822, 61761,
-	1563, 61761, 61761, 61761, 61761, 2839, -1000, -1000, 2502, 704,
-	2712, 798, -1000, -1000, -1000, 4503, 4503, 4503, 1675, 1675,
-	1675, 183433, 183433, 809, 4760, 972, -1000, 61761, -1000, 191,
-	80288, 61761, 32867, -1000, 598, 13985, 3285, -1000, 597, 32160,
-	-1000, -1000, -1000, 35602, 789, 66710, 61761, 1304, 183020, -1000,
-	-1000, 1790, 4555, 30804, 3721, 3645, 844, 1143, 928, 39137,
-	38430, 37723, 37016, 906, 905, 61761, 61761, 61761, 61761, 61761,
-	61761, 61761, 61761, -1000, 4569, -1000, -1000, 4555, -1000, -1000,
-	842, -1000, 4555, 4555, -1000, 4555, 1750, 1694, 4555, -1000,
-	4555, 4555, 10792, 10792, 51156, 50449, 49742, 68831, 49035, 61761,
-	36309, 48328, 47621, -1000, 70952, 163677, 53, 4444, 163677, 61761,
-	370, -1000, 25395, -1000, 370, 370, 841, 2, 183020, 3386,
-	3386, 77642, 3070, 2928, 2928, 2928, -1000, 1158, 24012, 1158,
-	145844, 2950, 1158, 1158, 469, 595, 74976, 3401, 145185, 949,
-	839, 75, 74, 72, -1000, -1000, 71, 68, -1000, -1000,
-	127374, 838, 34226, 434, -1000, 154, 61761, 61761, 61761, 594,
-	-1000, 943, -1000, 433, 2591, 2578, -6, 1827, -1000, -1000,
-	-1000, -1000, 3453, 3451, 3450, 3447, -1000, 3438, 3046, -1000,
-	-1000, -1000, 2450, -8, 1817, 127374, 163677, 2377, -1000, -1000,
-	-1000, -1000, 98885, 51, 98885, 163677, 4176, 127374, 127374, -14,
-	-1000, 176867, 6993, -18, -1000, 1609, 423, 4555, -1000, -1000,
-	-1000, 4759, 4756, -1000, 483, -1000, -1000, -1000, -1000, -1000,
-	-1000, -1000, -1000, 837, 836, 836, 836, -1000, 1341, 835,
-	490, 831, 478, 827, 826, 824, -1000, -1000, -1000, -1000,
-	-1000, 3786, 127374, 163677, 2325, 97567, 134627, -47, 135286, 176867,
-	-15, -1000, -1000, -1000, -1000, 127374, -1000, -1000, 127374, -1000,
-	89623, -1000, 127374, -1000, 163677, -1000, -1000, -1000, 4755, -1000,
-	127374, 127374, 3004, 4019, -1000, 127374, -1000, 127374, 311, 4016,
-	-1000, -1000, 163677, -1000, 127374, 127374, -1000, -1000, 74305, 179010,
-	4555, -1000, 163677, 163677, 163677, 176867, 176867, 308, -1000, 127374,
-	1080, -24, 1476, 34, -1000, -1000, -1000, -1000, 1690, -1000,
-	2252, -1000, -1000, -1000, -1000, -1000, -1000, 1961, -1000, -1000,
-	-1000, -1000, -1000, -1000, -1000, -1000, 1236, -1000, -1000, -1000,
-	-1000, 4549, 4529, 37, -1000, -1000, 34226, -1000, 2596, -1000,
-	-1000, -1000, -1000, 163677, 163677, -1000, -1000, 163677, 163677, -1000,
-	-1000, 50, 2022, -1000, 127374, 3844, -1000, -1000, 106899, 82313,
-	-1000, 3435, 1260, 1260, 1260, 1260, 1290, -1000, -1000, -1000,
-	-1000, -1000, -1000, 4754, 4753, 4752, 4749, -1000, -1000, 1281,
-	127374, 163677, 127374, -1000, 3536, 2108, -1000, 420, -1000, 176867,
-	-1000, 176867, 163677, 127374, -1000, -1000, 1281, 163677, 1281, 163677,
-	1281, 163677, 1281, 1281, -1000, -1000, -1000, -1000, 40, -1000,
-	4064, 3924, -1000, 191, 191, 61761, -1000, -1000, 183020, -1000,
-	3924, 61761, -1000, -1000, 2035, -1000, 4748, 2181, -1000, 3843,
-	-1000, 3839, -1000, 113, 419, 415, -1000, -1000, 4567, 2556,
-	-1000, 4670, -1000, 2737, 1288, 1288, -1000, -1000, -1000, -1000,
-	127374, 3783, -1000, -1000, -1000, -1000, -1000, 4746, 4169, 183020,
-	-1000, 102875, 2473, -1000, -1000, -1000, -1000, 127374, 127374, 127374,
-	127374, 163677, 1286, 49, -1000, -1000, -1000, -1000, -1000, 4108,
-	-1000, 163677, 4097, 4106, 127374, 74305, -1000, -1000, -1000, 4677,
-	-1000, 28, 2058, 717, 1815, -1000, 114158, 3239, 4182, 4742,
-	3497, 4167, 2166, -1000, 2024, 823, -1000, 4352, 112179, 4405,
-	4419, 1664, -1000, 3779, -1000, -1000, -1000, 1187, 2258, 2402,
-	1810, 1809, 112179, 3142, -1000, 100873, -1000, 3510, 4328, 1710,
-	1775, 1710, 1710, 1773, 1746, -1000, 112179, 2400, 1806, 1805,
-	3368, 1798, 2399, 1760, 4073, -1000, -1000, 3045, 3146, -1000,
-	-1000, -1000, -1000, 2238, 3588, -1000, 3341, 1685, 1685, 163677,
-	-1000, 1754, 2397, 1747, 1739, -1000, -1000, 2078, 2092, -1000,
-	-1000, 148480, 2219, -1000, 1676, 1669, 164995, 4466, 2661, 2868,
-	997, 2716, -1000, 1677, 1668, 3778, -1000, -1000, 27, 4401,
-	4418, 1664, -1000, -1000, 3777, 1665, -1000, 1325, -1000, -1000,
-	4518, -1000, -1000, 4327, 127374, 34226, 1993, 1990, 1965, 2396,
-	1655, 48, -1000, 4393, 2164, -1000, 4481, 106899, -1000, 3240,
-	2005, -1000, 1864, 1864, 143208, 163677, 1653, 2817, 2751, 2628,
-	2625, 2616, 2970, -1000, 4383, 4375, -1000, -1000, 4269, -1000,
-	-1000, 4268, 2752, 1581, 1580, -1000, 1303, 9386, 4104, -1000,
-	176867, 1303, 1303, 2456, 4010, 3534, 2071, -1000, 3571, 1085,
-	3566, -1000, -1000, 1085, 36, 98885, 163677, 408, -1000, 61761,
-	191, 61761, 191, -1000, 4322, 4007, 4443, -1000, 3775, 74305,
-	4000, 3998, 4741, 822, -1000, -1000, 820, -1000, 3363, -1000,
-	-1000, -1000, -1000, -1000, -1000, -1000, 816, 3208, 3774, 163677,
-	295, -1000, 127374, -1000, 4442, 147821, -1000, 3995, 176867, 3142,
-	3207, -1000, 113499, -1000, 3994, 2745, 653, 3206, -1000, 946,
-	4740, 3992, -1000, 168949, -1000, 4222, 1788, 3991, 1242, 2045,
-	865, 4441, -1000, 865, 90294, -1000, 163677, -1000, 63, 784,
-	108217, -26, -33, 593, -1000, 163677, 163677, 4120, 2762, 2756,
-	-1000, 1256, 82313, -1000, 82313, -40, -1000, -144, 3562, 82313,
-	-1000, 1253, -163, 1085, -1000, 1085, -1000, -1000, 112179, -1000,
-	3298, 3838, -1000, -1000, -1000, -1000, -1000, -1000, 1778, 2996,
-	-1000, 3400, -1000, 2095, -1000, -1000, -1000, 183020, 69538, -1000,
-	-1000, 183020, 2458, -1000, 66003, 65296, -1000, -1000, 2254, 127374,
-	3468, -1000, 3468, -29, -1000, -1000, 180459, 3391, 127374, 37,
-	44086, -1000, -1000, -1000, -1000, -1000, 1186, 1075, 1075, 1745,
-	1745, 1745, 1745, 4341, 8785, 3399, 8140, 7983, 7983, 7082,
-	7082, 7082, 7082, 7082, 7983, 439, 1675, 1675, 439, 439,
-	439, 439, 439, 1675, 1675, 439, 1675, 7983, 7983, 7983,
-	1675, 183433, 12555, 14886, 61761, 61761, 1578, 2511, 704, 13267,
-	61761, 15677, 15677, 15677, 15677, -1000, 2455, -1000, -1000, -1000,
-	-1000, 3773, 813, 68831, 68831, -1000, -1000, -1000, -1000, 34895,
-	61761, -1000, -1000, -1000, -1000, 46914, -1000, -1000, 178599, -339,
-	592, -1000, 407, -1000, -1000, -1000, -1000, -1000, -1000, -1000,
 	-1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000,
 	-1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000,
-	-1000, -1000, -1000, -1000, -1000, -1000, -1000, 591, -21, 154,
-	388, 61761, 163677, -1000, 18284, 940, -98, -1000, 64589, -57,
-	1797, -1000, 61761, -1000, -1000, 1577, -1000, 1568, 1567, 1564,
-	-1000, 811, 590, 375, -1000, 2931, 808, 800, 61761, -1000,
-	-1000, -1000, -1000, -1000, 178475, -1000, -1000, 178396, -1000, -1000,
-	178272, -1000, -1000, 177861, -1000, -1000, -1000, -1000, -1000, 182725,
-	17825, 16588, 15533, 13936, 15010, 14683, -62, 589, -63, 4555,
-	588, 587, 584, 1185, 1183, 583, 581, 578, -64, -1000,
 	-1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000,
 	-1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000,
+	-1000, -1000, -1000, -1000, -1000, -1000, 3144, 4499, -1000, 3450,
+	4498, 3128, -1000, -1000, 3617, -1000, 3100, -1000, 3405, -1000,
+	203014, 1853, -1000, -1000, -1000, -1000, 3231, 4496, 72, -1000,
+	-1000, 3423, -1000, 5138, 4174, -1000, -1000, -1000, 3451, -1000,
+	207046, -1000, 202737, -1000, -1000, 3398, 3081, 5069, 3186, -1000,
+	1801, 4490, -1000, 4000, 4000, 133341, 4459, 92935, 5293, 108233,
+	45, -1000, -1000, -1000, -1000, -1000, 19, -1000, 36845, 207541,
+	-1000, -1000, -1000, -1000, 207541, 1284, -1000, -1000, 4487, -1000,
+	207541, 1283, -1000, -1000, 4486, -1000, 3792, -1000, 4291, -1000,
+	-1000, -1000, 3604, 116631, 2236, 2538, 4220, 1063, -1000, 3602,
+	1450, -1000, 3443, 3600, -1000, 132649, 131955, 166605, 3097, 5291,
+	-1000, 5290, -1000, -1000, 5289, -1000, 5288, 5287, 5286, -1000,
+	-1000, -1000, -1000, -1000, -1000, 131261, 3442, -1000, -1000, 2096,
+	1398, 121557, -1000, 3599, 4933, -1000, 130567, 1507, -1000, 1429,
+	3597, -1000, 2071, 143747, 1423, 3596, -1000, 5285, 4835, 3913,
+	3911, 1429, 3595, -1000, -1000, -1000, -1000, -1000, 115927, 4219,
+	-1000, 1011, 1320, -1000, 1320, -1000, 2449, -1000, 192255, 71,
+	143055, 5123, -1000, 2, -1000, -1000, -1000, 1395, -1000, 90119,
+	-1000, 90119, 156215, 121557, 1398, 4218, 101298, 206767, -1000, 1447,
+	-1000, -1000, 207541, -1000, -1000, -1000, 3789, -1000, -1000, 3999,
+	115223, 4216, 3782, -1000, 207541, -1000, -1000, -1000, -1000, 207541,
+	-1000, -1000, -1000, 121557, 2096, -1000, 165911, 129873, 336, -1000,
+	-1000, -1000, 191563, -1000, -1000, 3717, -1000, 184643, -1000, 3699,
+	4282, 4288, 2251, 3456, 3841, -1000, 58887, 3815, 75907, 3532,
+	278, -1000, -1000, 278, 278, 48527, -1000, -1000, 50747, 1234,
+	110320, 110320, 40425, 2011, 69987, 69987, 69987, 69987, 69987, 69987,
+	69987, 69987, 69987, 69987, 69987, 69987, 69987, 69987, 69987, 69987,
+	69987, 69987, 69987, 69987, 69987, 69987, 69987, 69987, 69987, 69987,
+	69987, 69987, 69987, 69987, 69987, 69987, 69987, 69987, 69987, 69987,
+	69987, 69987, 69987, 69987, 3065, 69987, 1802, 69987, 69987, 69987,
+	69987, 2974, -1000, -1000, 2801, 872, 2967, 961, -1000, -1000,
+	-1000, 5113, 5113, 5113, 824, 824, 824, 14347, 14347, 948,
+	5284, 1116, -1000, 69987, -1000, 201, 89405, 69987, 39000, -1000,
+	719, 10522, 3660, -1000, 718, 38260, -1000, -1000, -1000, 41867,
+	950, 75167, 69987, 1467, 207541, -1000, -1000, 1929, 5141, 36134,
+	4324, 4076, 1010, 1259, 1075, 45567, 44827, 44087, 43347, 1064,
+	837, 69987, 69987, 69987, 69987, 69987, 69987, 69987, 69987, -1000,
+	5143, -1000, -1000, 5141, -1000, -1000, 1007, -1000, 5141, 5141,
+	-1000, 5141, 2037, 2014, 5141, -1000, 5141, 5141, 9119, 9119,
+	5141, 58147, 57407, 56667, 77387, 55927, 69987, 42607, 55187, 54447,
+	-1000, 79607, 184643, 61, 5030, 184643, 69987, 4215, 21, -1000,
+	30461, -1000, 376, 376, 1006, 0, 207541, 2718, 2718, 86627,
+	3491, 3270, 3270, 3270, -1000, 1324, 29012, 1324, 162449, 3282,
+	1324, 1324, 583, 715, 83829, 3571, 161757, 1090, 1005, 87,
+	86, 82, -1000, -1000, 80, 77, -1000, -1000, 143055, 1004,
+	40425, 541, -1000, 137, 69987, 69987, 69987, 710, -1000, 1089,
+	-1000, 532, 2869, 2892, -5, 1949, -1000, -1000, -1000, -1000,
+	3836, 3833, 3832, 3829, 3828, -1000, 3827, 3441, -1000, -1000,
+	-1000, 2727, -8, 1937, 143055, 184643, 2771, -1000, -1000, -1000,
+	-1000, 108233, 60, 108233, 184643, 4697, 143055, 143055, 1, -1000,
+	200571, 8138, -13, -1000, 1788, 531, 5141, -1000, -1000, -1000,
+	5282, 5281, -1000, 804, -1000, -1000, -1000, -1000, -1000, -1000,
+	-1000, -1000, 1003, 1001, 1001, 1001, -1000, 1496, 1000, 587,
+	989, 579, 988, 987, 986, -1000, 984, -1000, -1000, -1000,
+	-1000, 4211, 143055, 184643, 2553, 106849, 150671, -19, 151363, 200571,
+	34, -1000, -1000, -1000, 143055, 184643, -1000, 143055, -1000, -1000,
+	143055, -1000, 98509, -1000, 143055, 143055, 184643, -1000, 184643, -1000,
+	-1000, -1000, 5280, -1000, 143055, 143055, 3291, 4485, -1000, 143055,
+	-1000, 143055, 328, 4484, -1000, -1000, 184643, -1000, 143055, 143055,
+	-1000, -1000, 83125, 202252, 5141, -1000, 184643, 184643, 184643, 200571,
+	200571, 327, -1000, 143055, 1234, -16, 1628, 42, -1000, -1000,
+	-1000, -1000, 1999, -1000, 2440, -1000, -1000, -1000, -1000, -1000,
+	-1000, 2152, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000,
+	1369, -1000, -1000, -1000, -1000, 5125, 5120, 46, -1000, -1000,
+	40425, -1000, 2852, -1000, -1000, -1000, -1000, 184643, 184643, -1000,
+	-1000, 184643, 184643, -1000, -1000, 59, 2275, -1000, 2881, 2072,
+	143055, 4287, -1000, -1000, 121557, 121557, 91529, 5279, 3936, 1428,
+	1428, 1428, 1428, 5273, -1000, -1000, -1000, -1000, -1000, -1000,
+	5268, 5264, 5263, 5262, -1000, -1000, 1439, 143055, 184643, 143055,
+	-1000, 3955, 2224, -1000, 4286, 530, -1000, -1000, -1000, -1000,
+	200571, -1000, 200571, 184643, 143055, -1000, -1000, 1439, 184643, 1439,
+	184643, 1439, 184643, 1439, 1439, -1000, -1000, -1000, -1000, -1000,
+	50, -1000, 4556, 4373, -1000, 201, 201, 69987, -1000, -1000,
+	207541, -1000, 4373, 69987, -1000, -1000, 2294, -1000, 5260, 2477,
+	-1000, 4285, -1000, 4284, -1000, 117, 528, 525, 1439, -1000,
+	5142, -1000, 2826, -1000, 5181, -1000, 3281, 1445, 1445, -1000,
+	-1000, -1000, -1000, 143055, 4208, -1000, -1000, 3435, -1000, -1000,
+	-1000, 5257, 4692, 207541, -1000, 114519, 2854, -1000, -1000, -1000,
+	-1000, 143055, 143055, 143055, 143055, 184643, 1443, 58, -1000, -1000,
+	-1000, -1000, -1000, 4613, -1000, 184643, 4589, 4611, 143055, 83125,
+	-1000, -1000, -1000, 5192, -1000, 40, 2463, 946, 1936, -1000,
+	129179, 3553, 4714, 5256, 3963, 4686, 2422, -1000, 2288, 978,
+	2762, -1000, 4914, -1000, -1000, -1000, 127101, 4948, 4961, 1847,
+	-1000, 4207, -1000, -1000, -1000, 1343, 2404, 2685, 1927, 1918,
+	127101, 3450, -1000, 110320, -1000, 3888, 4895, 1896, 3582, 1944,
+	1896, 1896, 1935, 1928, -1000, 127101, 2669, 1911, 1897, 3625,
+	1890, 2662, 1889, 4565, -1000, -1000, 3431, 3545, -1000, -1000,
+	-1000, -1000, 2526, 3976, -1000, 3726, 1892, 1892, 184643, -1000,
+	1888, 2660, 1881, 1880, -1000, -1000, 2338, 2473, -1000, -1000,
+	165217, 2472, -1000, 1877, 1876, 186719, 5066, 2847, 3208, 1143,
+	3024, -1000, 1849, 1874, 4206, -1000, -1000, 39, 4946, 4960,
+	1847, -1000, -1000, 4203, 1873, -1000, 1479, -1000, -1000, 5130,
+	-1000, -1000, 4894, 143055, 40425, 2155, 2153, 2162, 2657, 1869,
+	57, -1000, 4940, 2745, -1000, 5091, 121557, -1000, 3628, 143055,
+	1866, 2276, -1000, 2096, 2096, 159681, 184643, 4648, 1856, 3066,
+	3030, 2880, 2878, 2874, 3274, -1000, 4936, 4927, -1000, -1000,
+	-1000, -1000, 4824, 4809, 3041, 1837, 1828, -1000, 1465, 9795,
+	4595, -1000, 200571, 1465, 1465, 3067, 4483, 3953, 2229, -1000,
+	3996, 1318, 3991, -1000, -1000, -1000, 45, 108233, 184643, 522,
+	-1000, 69987, 201, 69987, 201, -1000, 4878, 4482, 5029, -1000,
+	4333, 4202, 143055, 977, 184643, 2873, 4481, 4479, 5255, 143055,
+	4478, 976, -1000, -1000, 973, -1000, 4140, -1000, 3747, -1000,
+	-1000, -1000, -1000, -1000, -1000, -1000, 972, 3594, 4201, 184643,
+	372, -1000, 143055, -1000, 5025, 164525, -1000, 4477, 200571, 3450,
+	3592, -1000, 128487, -1000, 4475, 3034, 785, 3591, -1000, 1099,
+	5254, 4473, -1000, 190871, -1000, 4735, 4735, 1900, 4450, 1444,
+	-1000, 1320, 2316, 943, 5023, 71, 943, 99213, -1000, 184643,
+	-1000, 71, 8419, 122941, -21, -26, 709, -1000, 184643, 184643,
+	4642, 3071, 3047, -1000, 91529, -1000, 3989, 113815, -1000, 1398,
+	-35, 1318, -1000, 1318, -1000, -1000, 127101, -1000, 3699, 4282,
+	-1000, -1000, -1000, -1000, -1000, -1000, 2303, 3330, -1000, 3772,
+	-1000, 2329, -1000, -1000, -1000, 207541, 78127, -1000, -1000, 207541,
+	2817, -1000, 74427, 73687, -1000, -1000, 2544, 143055, 3860, -1000,
+	3860, -3, -1000, -1000, 203898, 3771, 143055, 46, 50747, -1000,
+	-1000, -1000, -1000, -1000, 1342, 814, 814, 1833, 1833, 1833,
+	1833, 4922, 3094, 7446, 520, 19341, 19341, 838, 838, 838,
+	838, 838, 19341, 475, 824, 824, 475, 475, 475, 475,
+	475, 824, 824, 475, 475, 475, 475, 824, 19341, 19341,
+	19341, 824, 14347, 207777, 15977, 69987, 69987, 1818, 2808, 872,
+	15657, 69987, 19096, 19096, 19096, 19096, -1000, 2993, -1000, -1000,
+	-1000, -1000, 4200, 968, 77387, 77387, -1000, -1000, -1000, -1000,
+	41127, 69987, -1000, -1000, -1000, -1000, 53707, -1000, -1000, 202201,
+	-346, 708, -1000, 521, -1000, -1000, -1000, -1000, -1000, -1000,
 	-1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000,
-	-1000, -69, 574, -1000, 3771, -21, -1000, -1000, -1000, -1000,
-	-1000, -1000, -1000, -1000, 573, -1000, 572, -1000, 182034, -21,
-	570, 3387, -1000, 68831, 68831, 68831, 68831, 567, -1000, 180048,
-	-1000, 182168, 46207, 46207, 46207, 561, 181997, 61761, -21, -70,
-	-1000, -71, -1000, -1000, -1000, -1000, 3234, -72, -1000, -77,
-	1301, 42672, 76318, 1683, 61761, 61761, 61761, 61761, 1563, 2839,
-	2502, 704, 34226, -1000, 798, -1000, -1000, -1000, -1000, -1000,
 	-1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000,
 	-1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000,
+	-1000, 704, 3, 137, 517, 69987, 184643, -1000, 19021, 1085,
+	-23, -1000, 72947, -27, 1987, -1000, 69987, -1000, -1000, 1817,
+	-1000, 1816, 1808, 1803, -1000, 967, 702, 514, -1000, 3265,
+	964, 963, 69987, -1000, -1000, -1000, -1000, -1000, 202070, -1000,
+	-1000, 201448, -1000, -1000, 201317, -1000, -1000, 201266, -1000, -1000,
+	-1000, -1000, -1000, 206611, 17709, 16892, 15175, 9022, 14218, 13574,
+	-32, 701, -37, 5141, 697, 696, 695, 1338, 1337, 685,
+	684, 679, -38, -1000, -1000, -1000, -1000, -1000, -1000, -1000,
 	-1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000,
 	-1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000,
+	-1000, -1000, -1000, -1000, -1000, -39, 677, 674, -1000, 4196,
+	3, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, 672,
+	-1000, 671, -1000, 206272, 3, 670, 3569, -1000, 77387, 77387,
+	77387, 77387, 669, -1000, 203560, -1000, 206036, 52967, 52967, 52967,
+	667, 205797, 69987, 3, -46, -1000, -54, -1000, -1000, -1000,
+	-1000, 3614, -55, -1000, -60, 1397, 85237, 49267, 2011, 69987,
+	69987, 69987, 69987, 1802, 2974, 2801, 872, 40425, -1000, 961,
 	-1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000,
 	-1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000,
 	-1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000,
@@ -26185,385 +28420,437 @@ var sqlPact = [...]int32{
 	-1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000,
 	-1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000,
 	-1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000,
-	-1000, -1000, -1000, 1301, 1301, 61761, -1000, 61761, 3412, -1000,
-	-1000, -1000, -1000, 3411, 2494, 3386, 77642, -1000, -1000, -1000,
-	-1000, 145844, -1000, 4522, 3622, -1000, 145844, -1000, -1000, 163677,
-	782, -1000, 145844, 145844, 1158, -1000, -1000, 163677, 781, 1158,
-	145844, 814, -1000, -1000, -1000, -1000, -1000, 559, 79628, 326,
-	34226, 558, 45500, -1000, 4326, 181166, 152, -78, -1000, -1000,
-	34226, 1261, -1000, 1261, -1000, -1000, 2576, 3550, 3550, 3550,
-	3550, 3550, 127374, -1000, -1000, 176867, 1561, 42, -38, 3561,
-	3556, 3553, 3551, 36, 98885, 36, 30, 163677, 47, 47,
-	4479, -271, -1000, 2823, -1000, 100873, -1000, 961, 1340, 34226,
-	-1000, -1000, -1000, -1000, 4555, 176867, 3769, 336, 3548, 3545,
-	3544, 3543, -1000, 3043, 133309, 282, -47, 176867, -1000, 315,
-	-79, -1000, -1000, 100203, 94922, -1000, 2938, -1000, -1000, -1000,
-	-1000, -1000, -1000, -1000, 315, 4737, -1000, 3004, -1000, -1000,
-	127374, 3004, 3004, -1000, 127374, 127374, 3004, -1000, 314, 3600,
-	-1000, -1000, 313, -1000, -1000, -47, -1000, 1287, 44086, -1000,
-	1690, -1000, -1000, 1974, -1000, 2753, -1000, 1591, -1000, -1000,
-	44086, -1000, 4123, -1000, 2405, -1000, -1000, -1000, -1000, 2992,
-	-1000, 1253, 1879, 3539, 1260, 43, 797, -1000, -1000, -1000,
-	2064, -1000, -1000, 1133, 1132, 1131, -1000, 1130, -1000, -1000,
-	-1000, -1000, -1000, -1000, 2072, -1000, -1000, -1000, -1000, -1000,
-	-1000, -1000, -1000, 61, -1000, 2393, 176867, 2506, 176867, 163677,
-	-47, -47, 17, -1000, -1000, 225, 42, -1000, 1281, -1000,
-	1281, -1000, 1281, -1000, -1000, 3924, -1000, 40, 4064, -1000,
-	-1000, 183020, 40, 183020, -1000, -1000, -1000, 2177, 2172, 163677,
-	-1000, 163677, 163677, 3836, -1000, 163677, -1000, -1000, -1000, -1000,
-	-1000, 127374, -1000, 4736, -1000, -1000, 34226, 163677, 127374, 34226,
-	127374, 3833, 3832, 1286, 1286, 1286, -1000, 2684, 163677, -1000,
-	-1000, 163677, -1000, -1000, -1000, 3417, 163677, 163677, 127374, -1000,
-	143867, 163677, -1000, 2906, 176867, -1000, 3205, 168290, 3178, 167631,
-	100873, -1000, -1000, 796, 1215, 3385, 3384, 1398, 163677, 163677,
-	3379, 166972, 166313, -1000, 4735, 163677, 2829, 61761, 143867, 4325,
-	2919, 5319, 191, 191, -1000, 191, -1000, -1000, 795, 1651,
-	127374, 127374, 163677, 176867, 127374, 2407, -1000, -1000, -1000, -1000,
-	-1000, 112838, -1000, -1000, 1710, -1000, -1000, -1000, 1710, -1000,
-	1710, 3142, 2391, 163677, 176867, 127374, -1000, -1000, -1000, -1000,
-	163677, 163677, 176867, 3042, 3141, 3037, 3585, -1000, -1000, -1000,
-	-1000, -1000, -1000, 163677, 163677, 176867, 176867, 147162, 2713, 146503,
-	2708, 2700, -1000, -1000, -1000, 2659, 2690, 2903, 2390, 163677,
-	-1000, -1000, -1000, -1000, -1000, 1785, -1000, 997, 1560, 3768,
-	61761, 61761, 2880, 191, 191, -1000, 191, 794, 34226, -1000,
-	-1000, 1588, -1000, 3804, 163677, 4669, 165654, 4665, 163677, 163677,
-	163677, 176867, 4196, 163677, 39, -1000, 1643, -1000, 4481, -1000,
-	1129, -1000, -163, 38, -49, -1000, 1126, 1124, 30, 73635,
-	2438, -1000, -1000, -1000, -1000, -1000, 1558, 2641, 2526, 163677,
-	4306, -1000, 163677, 4302, -1000, -1000, -1000, 163677, 176867, -1000,
-	164995, 9386, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000,
 	-1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000,
 	-1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000,
-	-1000, 2846, 3564, 1418, 163677, 1641, -1000, -1000, 2380, 1557,
-	1553, 112179, 2761, 2373, 2499, 82313, 1257, 82313, 3513, -1000,
-	-1000, 30126, 183020, -1000, 183020, -1000, 94263, 2266, 106899, 106899,
-	2608, -1000, 73635, 163677, -1000, 90956, 90956, 163677, 108876, 1207,
-	3989, 88301, 30, 1253, 1864, 3874, 2209, -49, 793, 163677,
-	-1000, -1000, 3142, 3988, 653, 3203, -1000, 176867, 1345, 4440,
-	3987, 792, 163677, 4734, -1000, 127374, 3036, 3200, -1000, -1000,
-	164336, 3961, 997, 163677, 1412, -80, -1000, 61761, 2658, -1000,
-	85647, 1382, 163677, 2553, 276, -1000, -1000, -1000, 88, 163677,
-	-1000, 977, -1000, -1000, 784, 784, 1253, 82983, -86, -1000,
-	212, 790, 1118, 1117, -1000, 9058, -1000, -144, -1000, 106899,
-	1256, 82313, -144, 3537, 3767, -1000, -1000, 1284, -1000, -1000,
-	-1000, -1000, 1432, -1000, 2458, 2978, -1000, 789, -1000, -1000,
-	-1000, -1000, -1000, -1000, -1000, -1000, -1000, 3302, -1000, -1000,
-	41965, 1149, -1000, -1000, 127374, 60, 37, 61761, 61761, 11613,
-	10133, 61761, 68831, 68831, -1000, 61761, 9432, -1000, -1000, -1000,
-	-1000, -1000, 3765, 788, 61761, 100873, 2848, 2772, -1000, 557,
-	11453, 439, -1000, 61761, -1000, 642, -1000, 556, 24705, -21,
-	-87, -1000, -1000, 960, -1000, 3945, -1000, 61761, 181873, 3263,
-	2493, 2515, 2249, 4555, 4660, 29448, -1000, 91618, 1302, 2956,
-	177690, -1000, -1000, -1000, -1000, 100873, 100873, 61761, 61761, -1000,
-	61761, 61761, 61761, -1000, -1000, -1000, 4555, 550, -1000, -1000,
-	1178, -1000, -1000, -1000, 1178, -1000, -1000, 1710, -1000, 1710,
-	-1000, 61761, -1000, -1000, 3760, 61761, -1000, 100873, 100873, 68831,
-	68831, 68831, 68831, 68831, 68831, 68831, 68831, 68831, 68831, 68831,
-	68831, 68831, 68831, 68831, 68831, 68831, 68831, 68831, 68831, 3353,
-	68831, 4497, 4497, 4497, 1170, -1000, 3831, 3760, 61761, 61761,
-	100873, 544, 543, 542, -1000, 61761, -21, -1000, -1000, 786,
-	-1000, 3291, -1000, 163677, -1000, 3639, -1000, 61761, -1000, -88,
-	-1000, 3401, -1000, -1000, 3639, 3639, -92, 183020, 77642, 77642,
-	-1000, 783, 61761, 3408, -1000, -1000, 939, -330, -1000, 1115,
-	-1000, -1000, -1000, -1000, -1000, -1000, 1114, 1113, -1000, 782,
-	-1000, -1000, -1000, 145844, 781, -1000, 163677, 145844, 938, -1000,
-	-95, -1000, -1000, -105, -1000, 145185, 34226, -1000, -1000, 61761,
-	61761, 541, 540, -1000, 89, 1301, 325, -1000, 1261, -1000,
-	-1000, -1000, -1000, -1000, -1000, -1000, -1000, 3422, -271, 176867,
-	176867, 2369, 2365, 2361, 2359, 36, 30, 2980, -1000, 3655,
-	4659, -1000, 4552, 957, 937, 192, 539, -47, 176867, 176867,
-	2357, 2354, 2350, 2336, 93601, 3759, 176867, -1000, -1000, -1000,
-	90956, 100873, -1000, 100873, -1000, -1000, -1000, -1000, -1000, 3004,
-	-1000, -1000, -1000, 311, -1000, -1000, -1000, -1000, -1000, 3488,
-	-1000, 34, -1000, -1000, -1000, 61761, -1000, 1213, -1000, 2016,
-	-1000, -1000, 127374, 82313, -1000, 3496, 3496, -1000, 82313, 82313,
-	106899, 106899, 33, 777, -1000, 1112, 1111, 1108, 28770, 163677,
-	255, 3536, -47, -1000, 101535, -1000, -1000, -1000, -1000, -1000,
-	-1000, 1281, -1000, -1000, 4641, 30, -1000, -1000, -1000, -1000,
-	-1000, 2883, 3105, 2883, 2485, 2480, -1000, -1000, -1000, -1000,
-	-1000, -1000, -1000, -1000, -1000, -1000, -1000, 4181, 765, 1548,
-	1538, -1000, -107, -1000, 1107, -1000, -1000, -1000, -1000, -1000,
-	3713, -1000, 3984, -1000, 3199, -1000, 1386, 3195, 2104, -1000,
-	61761, 764, 3504, 756, 752, 4733, 2796, 4732, 1404, 3977,
-	3004, 3970, 3004, -1000, -1000, -1000, 1193, -1000, 183020, -108,
-	-1000, 2919, -1000, 751, 750, -1000, 28, 1998, 610, 1537,
-	1279, -1000, -1000, 61761, 61761, 144526, -1000, 636, 4194, 59,
-	-1000, -1000, -1000, 2318, 1532, 1530, -1000, -1000, -1000, -1000,
-	-1000, 3142, 2315, 1529, 1526, -1000, -1000, -1000, -1000, -1000,
-	-1000, 3889, 3476, 3140, -1000, -1000, -1000, -1000, -1000, -1000,
-	-1000, 3193, -1000, -1000, 142549, -1000, 3960, 142549, 3607, 997,
-	142549, 4194, 3677, 1274, -1000, 3879, 3878, 1177, 142549, 61761,
-	61761, 181460, 181299, -1000, 1269, -1000, -1000, 61761, -1000, 27,
-	-1000, 1525, 4387, 3192, 127374, -1000, 3004, 3959, 1524, -1000,
-	1523, -1000, -1000, -1000, 4392, 4390, 1542, 2164, 106899, 82313,
-	2554, -1000, 4376, 2979, 4521, 4481, 82313, -1000, 143208, 106899,
-	106899, -1000, -1000, -1000, 2167, -36, -1000, 1092, 1544, 26,
-	-1000, 1080, -1000, 26, -1000, -1000, -1000, -1000, 4521, -1000,
-	-1000, -1000, -1000, 102204, -1000, -1000, 1303, 163677, 176867, 127374,
-	2384, -1000, -1000, 133309, 133968, 163677, 3534, 1085, -1000, 2624,
-	1085, 1257, 3758, -1000, 3464, -1000, 165, 1253, -1000, 106899,
-	-1000, -1000, 3104, 3329, 1266, 538, 25, -1000, 1550, 535,
-	4731, 528, -116, 24, 100873, -1000, -1000, -1000, -1000, 3178,
-	127374, 749, 163677, 1607, 3482, 163677, 163677, 4438, -1000, 3091,
-	833, 127374, 1238, -1000, 4522, -1000, -1000, -1000, 163677, 42672,
-	143208, -1000, 4355, 127374, 4437, 3955, 1261, 127374, 191, 127374,
-	4585, 525, 23, 100873, -1000, 4436, 127374, 3954, 3034, 3181,
-	3347, 997, 107558, 1261, 1301, 77642, -1000, 2045, 183020, -1000,
-	2553, 44793, 4192, -124, -1000, -1000, -1000, 1301, 90294, 77642,
-	61761, 4730, -126, -1000, -1000, -1000, -1000, -1000, 106899, 1253,
-	163677, 163677, 4728, 106899, 106899, 106899, 22, 748, -1000, 1082,
-	1079, 1078, -1000, -1000, -1000, -1000, -1000, -1000, -1000, 1070,
-	1065, 1062, 1061, 1059, 1050, -1000, -1000, -1000, 3309, 4079,
-	-1000, -1000, -1000, -1000, -1000, -1000, -1000, 1256, -1000, -1000,
-	-144, 1256, 82313, 191, -1000, 2967, -1000, 2972, -1000, -1000,
-	-1000, -1000, -1000, 3463, 4189, 34226, 4356, 15677, 61761, 61761,
-	3221, 1729, 779, 15677, 61761, 61761, 100873, 8894, -127, 61761,
-	61761, -1000, 61761, 936, 183020, -1000, 4637, -1000, -1000, 4539,
-	-1000, -1000, -1000, 183020, 61761, -1000, -1000, -1000, -1000, -1000,
-	-1000, -1000, 524, -1000, 184, -1000, -1000, -1000, 172903, -1000,
-	61761, 520, 4324, -1000, 517, 514, 9602, 7934, 177566, 177529,
-	23216, 510, -1000, -1000, -1000, 509, 506, 183020, 3831, 183020,
-	-1000, -1000, 1275, 1275, 1667, 1667, 1667, 1667, 4497, 971,
-	1298, 744, 657, 657, 657, 884, 1170, 1170, 657, 657,
-	657, 1170, 3757, 3337, 743, 3640, -1000, -1000, 183020, 183020,
-	501, -1000, -1000, -1000, -21, 7494, -1000, -1000, 3630, 4323,
-	183020, -1000, 77642, 3630, 3630, -1000, -1000, 2494, 163677, 183020,
-	77642, -1000, 3622, -1000, 26745, 26076, 955, -1000, -1000, -1000,
-	-133, -1000, 100873, -1000, -1000, -1000, 4522, -1000, 79628, -1000,
-	89, 181166, 19, -1000, -1000, -1000, 34226, -1000, 3716, 5757,
-	-1000, 1048, -1000, -1000, 106899, 106899, 4726, 4724, -1000, 4610,
-	4609, 2927, 4604, -1000, 3550, -1000, -271, -196, 163677, 163677,
-	163677, 163677, -1000, 2977, -1000, 934, 4723, 947, 34226, -1000,
-	-47, -47, 163677, 163677, 163677, 163677, 3747, 127374, 163677, 2295,
-	176867, -47, -1000, -1000, -1000, -1000, -1000, -1000, 4119, 183020,
-	3829, 3620, 3616, -1000, 1253, 1260, -1000, -135, -1000, -1000,
-	-1000, -1000, 1984, 1984, 106899, 106899, 61761, -1000, -1000, -1000,
-	-1000, -1000, -1000, -1000, -1000, -1000, 34226, 2180, -1000, 742,
-	730, 163677, 163677, -1000, 143867, 44086, 2060, 139246, 163677, 3948,
-	-1000, 3940, -1000, 1398, 3333, 22760, 78304, -1000, 78304, 163677,
-	-1000, -1000, -1000, -1000, 2415, 1958, 4722, 1459, -1000, 4256,
-	163677, -1000, 163677, -1000, -1000, -1000, 143867, -1000, 163677, 163677,
-	127374, 163677, -1000, 176867, 3907, -136, 183020, 18, -1000, 1046,
-	-1000, 1679, -1000, 28092, 163677, 176867, 127374, 163677, 176867, 127374,
-	163677, -1000, 3475, 3937, 1381, 142549, -1000, 3936, 142549, 1379,
-	-1000, -1000, 142549, 2908, -1000, -1000, 3877, -1000, 183020, 180755,
-	191, 61761, 3893, -138, 34226, -1000, 4602, 4601, 3934, 4261,
-	-1000, 163677, 4599, 163677, 127374, 4116, -1000, -1000, -1000, -1000,
-	1041, 1034, 1023, 1020, 1017, 3307, 1016, 1015, 4488, 143208,
-	-1000, 1259, -1000, -1000, -1000, 1555, -1000, 2526, 73635, 1014,
-	163677, 44086, -1000, -1000, -1000, -1000, -1000, -1000, -1000, 2308,
-	1521, 1516, 3032, 3024, 2975, 17, 2761, 1257, 16, 729,
-	-1000, 1257, -1000, 106899, 82313, 1253, 4434, -1000, 73635, 3743,
-	4721, 2520, 90956, 61761, 61761, 7236, -1000, 3493, -1000, 138587,
-	108876, 3084, -1000, -1000, 78304, 728, 163677, 727, 163677, 725,
-	-1000, 191, -1000, 4720, 143867, 723, -1000, 1267, 2963, -1000,
-	4514, -1000, 3884, -1000, 932, -1000, -1000, 274, -143, 176867,
-	3142, 191, 127374, -1000, 653, 1255, 653, 498, 15, -1000,
-	-1000, 163677, -1000, 1049, 1390, 34226, 127374, 3933, 3352, 997,
-	107558, -1000, 1788, 2954, 12, -1000, -1000, 13, -1000, 700,
-	191, 2954, -1000, 12, 183020, -1000, 1012, 497, -1000, 4115,
-	-1000, -1000, -149, -1000, -1000, 10695, 10695, 106899, 82313, 106899,
-	106899, 106899, 61761, 82313, 106899, 106899, 1011, 4145, -1000, 1256,
-	-1000, -144, -1000, 3288, -1000, -1000, -1000, -1000, 4189, 15677,
-	15677, 61761, 61761, 61761, 15677, 8894, -154, -1000, 15677, 15677,
-	-21, -1000, -1000, -1000, 183020, -1000, 27414, 2891, -1000, 22589,
-	-1000, 41965, -1000, -1000, 61761, 61761, -1000, -1000, -1000, -1000,
-	-1000, -1000, -1000, -1000, 68831, 3740, 718, 100873, -1000, 496,
-	1276, 61761, 63882, 3401, 1276, 1276, -1000, -156, -1000, -1000,
-	-1000, 4522, -1000, 4522, 4522, -1000, 163677, -1000, -1000, -1000,
-	495, 41965, -1000, -1000, -157, -1000, 106899, 2516, 106899, 106899,
-	4714, 4712, 1907, 4598, 4597, 4711, 4709, 4708, 4596, 106899,
-	-1000, -1000, -1000, -1000, -1000, -1000, 4707, 3135, 4706, 4704,
-	-1000, -1000, -1000, 3888, -117, -118, -119, -125, -1000, 907,
-	-1000, 4703, -1000, 243, 229, 224, 221, 176867, 3717, 211,
-	3533, 3531, 3530, -47, -1000, 191, -1000, -1000, -1000, -1000,
-	-1000, -1000, -162, -1000, -1000, 183020, -1000, 127374, 127374, 61761,
-	61761, -1000, -1000, -1000, -1000, 3528, 4433, -1000, 2682, -1000,
-	163677, 163677, -1000, 163677, -1000, 34226, 163677, 3662, 1595, -1000,
-	1215, 3374, 715, 68831, 1430, 127374, 1188, 3611, 3594, -1000,
-	4456, 4320, 3609, -165, -1000, 163677, 61761, 163677, -168, -174,
-	3128, -1000, -1000, 1428, 1587, 61761, 1427, -1000, -1000, -1000,
-	100873, 714, 3004, 3004, -1000, -177, -180, -1000, -1000, -1000,
-	61761, 1514, 163677, 43379, -1000, 4702, 4194, -1000, -1000, -1000,
-	-1000, -1000, -1000, -1000, -1000, 142549, 142549, -1000, -1000, -1000,
-	142549, 4194, 163677, -1000, 61761, -1000, 180607, 61761, 1511, -1000,
-	-1000, -1000, 4595, 3004, 34226, 3004, -1000, 3004, 4261, 1451,
-	106899, 61761, 1902, 82313, 82313, 1010, 61761, 61761, -1000, -1000,
-	-1000, 3072, 61761, -1000, -1000, 73635, -1000, -1000, 163677, 176867,
-	127374, 2130, 2130, 3815, -1000, -1000, -1000, 2554, 2554, -1000,
-	11, 1257, 2743, 2202, 3021, 2537, -1000, 1814, -1000, 183020,
-	183020, 2955, 7236, -1000, 4594, 107558, -1000, -1000, -1000, 2886,
-	4697, -1000, -1000, -1000, -1000, 3371, -1000, -1000, -1000, 163677,
-	3370, 3606, -182, 78304, 712, 78304, 709, 163677, 1254, -1000,
-	-185, 108876, 1207, -1000, 1267, -1000, -1000, -1000, 87641, -1000,
-	-1000, -1000, -1000, 653, 4432, -1000, 3486, 4430, -1000, 4591,
-	100873, 708, 163677, 706, 163677, 3020, 705, 34226, 4171, 997,
-	107558, -1000, 3961, 3445, -1000, 3154, 163677, 4163, -1000, 3445,
-	704, 1253, 703, 1253, -1000, -187, -1000, -1000, -1000, -1000,
-	-1000, 183020, -1000, -1000, -1000, 106899, -1000, -1000, 1256, 5,
-	-1000, 4465, 701, 991, -1000, -1000, 15677, 15677, 15677, -1000,
-	-1000, 2953, 4315, -1000, -1, -11, 22133, 21252, 7842, 68831,
-	100873, -195, -1000, -1000, 163677, 183020, -13, -1000, 183020, 696,
-	695, 663, -1000, -1000, -1000, 929, 885, 815, -1000, -1000,
-	-1000, -1000, -1000, 5757, -1000, -1000, -1000, -1000, -1000, -1000,
 	-1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000,
-	4696, -1000, -1000, 4695, -1000, -1000, -1000, 176867, 176867, 176867,
-	176867, 4694, -1000, 176867, 176867, 176867, 176867, -47, 176867, 176867,
-	2293, 2279, 2256, -1000, -1000, -1000, -1000, -198, -203, 137928,
-	163677, -1000, -1000, 2104, 2317, -1000, -1000, 163677, 3180, -1000,
-	-1000, -1000, 1258, 61761, 3640, 68831, 692, 61761, -1000, 691,
-	690, 4429, 4088, -1000, 3487, 3703, 2475, 78304, -1000, 4189,
-	-1000, 20086, -1000, 1389, 2667, -1000, -1000, -1000, -1000, 183020,
-	68831, 4261, 78304, -1000, -1000, 675, 673, 183020, 672, 1004,
-	3714, -1000, -1000, -1000, -1000, -106, -1000, -106, -1000, -1000,
-	183020, 191, 183020, 668, 4387, -1000, -1000, -1000, -1000, 3004,
-	127374, -1000, 183020, -1000, -1000, -1000, -1000, 106899, 183020, 183020,
-	1003, 183020, -1000, -1000, -1000, -1000, 1498, -1000, -1000, -1000,
-	-1000, -1000, 4692, 3712, 133309, -1000, -206, 2743, 1249, 42672,
-	73635, 3102, 2124, -1000, -1000, -1000, 4395, 61761, -1000, -19,
-	-1000, -1000, 1207, -1000, -1000, 3084, 661, -1000, 1232, 3279,
-	3279, 1389, -212, 78304, -214, 78304, -219, 3001, 3481, -1000,
-	492, 4428, 1267, 1301, -1000, 4427, 191, 4114, -1000, 191,
-	-1000, -1000, 4585, 487, 78304, -1000, 127374, 78304, 3014, 2802,
-	3321, 107558, -1000, 3347, 2553, -1000, -1000, -234, 163677, 2553,
-	-1000, -1000, 106899, -1000, -1000, -1000, -1000, 3288, -1000, 163677,
-	-1000, 163677, 2735, 61761, 41965, 41965, -1000, -1000, 7842, -235,
-	-1000, -20, -1000, 4422, 63882, 4690, 4687, 4686, -1000, -1000,
-	-1000, -1000, -1000, -1000, -271, -271, -271, -271, -1000, -47,
-	-47, -47, -47, -47, -47, 163677, 163677, 163677, -1000, -1000,
-	-1000, 2677, -1000, 3178, -1000, -1000, 3929, -1000, 3626, 660,
-	19504, 3640, 3295, 163677, 411, 3142, 3142, -1000, 4421, 3672,
-	-1000, -1000, 2880, 656, -1000, -1000, -1000, -1000, 1149, 163677,
-	1232, 3615, 127374, 3640, 1393, -236, 2883, 2883, 61761, 41258,
-	2907, 142549, -1000, 61761, -1000, -1000, 4261, -1000, 82313, 176867,
-	-1000, 176867, 3010, -1000, 3674, -1000, 2410, 200, 1252, 73635,
-	100873, -1000, -1000, 183020, -1000, 4576, 3001, 163677, -1000, -1000,
 	-1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000,
-	2475, 1389, -242, 2880, -245, -1000, -1000, 4236, -1000, 4113,
-	3493, 191, -1000, 191, -1000, 4685, 1255, 485, -1000, -247,
-	1390, -250, 127374, 2741, -1000, 997, -1000, 3352, -1000, 1301,
-	4043, -1000, -252, -1000, -253, -264, 484, 63175, 63175, 63175,
-	-21, -29, -29, -1000, 163677, 655, -1000, -1000, -1000, -1000,
-	-1000, -1000, -1000, -1000, 199, 198, 183, -1000, -1000, 3873,
-	1156, -1000, 1144, 2463, 479, 1406, 245, 167, -1000, -1000,
-	-1000, 3609, -1000, 163677, -1000, -1000, -1000, 1156, 653, -1000,
-	61761, 1389, -269, -1000, 1376, -274, -1000, 1375, -275, -1000,
-	3710, -1000, -1000, -290, 3004, -1000, -271, 308, 2130, 1249,
-	4373, 2957, 87641, -1000, 2652, 3002, 7236, -1000, 180018, -1000,
-	3306, -295, -1000, -1000, 2880, 2475, 1389, 1232, 2880, 3116,
-	-1000, 2886, 1254, -1000, -1000, -1000, -1000, 1389, 643, 2475,
-	641, 1966, 997, -1000, -1000, 1710, 4171, 3978, 1719, 1253,
-	-1000, -1000, -1000, 3926, -1000, 70245, 3065, 2474, 179720, 3926,
-	3926, -1000, -1000, 176867, 176867, 176867, 163677, 1232, 4343, -1000,
-	1148, 1146, 1901, -1000, -1000, -1000, -1000, -1000, -1000, -1000,
-	-1000, 1301, -296, -1000, 3295, 183020, 1232, -1000, 2883, 3524,
-	-1000, 2883, 3688, -1000, 2905, -1000, -1000, -1000, -1000, 3682,
-	-1000, 4486, 88961, 1301, -36, 638, 73635, 2955, -320, -1000,
-	-1000, -1000, -1000, -1000, 1232, 163677, 1232, 2880, 2475, 1301,
-	1232, 2444, 2441, 4683, 1207, 3001, 2475, 78304, 2880, 78304,
-	2836, -1000, 142549, -1000, 2802, 1688, -1000, 2153, -1000, -1000,
-	2339, 4452, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -47,
-	-47, -47, -1000, -1000, 1001, -1000, 4076, -1000, 1424, 2595,
-	2595, -1000, -1000, 1144, -1000, -1000, 619, -1000, 618, -1000,
-	176867, -1000, -1000, -49, 143208, 2743, 2526, 1252, -1000, -1000,
-	-1000, -1000, 1301, 1232, 2880, 1584, 1301, -1000, 4682, -1000,
-	3001, -1000, 2880, -297, 1232, -298, 2909, -1000, -106, 2741,
-	-1000, 2150, 90294, 2460, -1000, -1000, 2944, 62468, 61761, -1000,
-	4483, -1000, -1000, 3381, -1000, 3609, 61761, 61761, 308, -305,
-	1249, -306, -1000, 1584, 1301, 1232, -1000, 1315, -1000, -1000,
-	4501, 1584, -1000, 3306, 1232, 1389, 1301, 2475, 1981, 997,
-	1966, 90294, -277, -1000, -1000, -1000, 183020, -1000, -1000, -1000,
-	-1000, -307, -313, -1000, -1000, -1000, -1000, -1000, 1584, 1301,
-	-1000, -1000, -1000, -1000, 1301, 2475, 1584, 2880, 2240, -1000,
-	2663, 176867, 2836, -277, -1000, 2880, 1484, -1000, 1584, 1584,
-	2880, -1000, 1232, -1000, -1000, 2659, 142549, -1000, 2909, -1000,
-	-1000, -1000, 617, -1000, -1000, 1232, 1301, 1372, 1981, 61761,
-	1301, 1584, 142549, 2240, -314, 1584, -1000, -106, -1000, 2880,
-	-1000, -1000,
+	-1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000,
+	-1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000,
+	-1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000,
+	-1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, 1397, 1397,
+	69987, -1000, 69987, 3779, -1000, -1000, -1000, -1000, -1000, 3778,
+	3016, 2718, 86627, -1000, -1000, -1000, -1000, 162449, -1000, 5123,
+	4528, -1000, 162449, -1000, -1000, 184643, 938, -1000, 162449, 162449,
+	1324, -1000, -1000, 184643, 932, 1324, 162449, 888, -1000, -1000,
+	-1000, -1000, -1000, 666, 88712, 425, 40425, 664, 52227, -1000,
+	4892, 204711, 44, -61, -1000, -1000, 40425, 1429, -1000, 1429,
+	-1000, -1000, 2872, 3898, 3898, 3898, 3898, 3898, 3898, 143055,
+	-1000, -1000, 200571, 1782, 54, -53, 3988, 3981, 3980, 3979,
+	45, 108233, 45, 19, 184643, 56, 56, 5082, -269, -1000,
+	3165, -1000, 110320, -1000, 1115, 1530, 40425, -1000, -1000, -1000,
+	-1000, 5141, 200571, 4195, 366, 3978, 3977, 3975, 3973, -1000,
+	3430, 149287, 358, -19, 200571, 3291, 3426, -1000, 335, -63,
+	-1000, -1000, 109617, 104072, -1000, 3272, -1000, -1000, -1000, -1000,
+	-1000, -1000, -1000, 335, 3291, 3422, 5252, -1000, 3291, -1000,
+	-1000, 143055, 3291, 3291, -1000, 143055, 143055, 3291, -1000, 332,
+	4007, -1000, -1000, 330, -1000, -1000, -19, -1000, 1318, 50747,
+	-1000, 1999, -1000, -1000, 2164, -1000, 3075, -1000, 2002, -1000,
+	-1000, 50747, -1000, 4636, -1000, 2688, -1000, -1000, -1000, -1000,
+	3327, -1000, 4558, -1000, -1000, 4557, 1398, 2101, -75, -1000,
+	3962, 1428, -1000, 55, 960, -1000, -1000, -1000, 2327, -1000,
+	-1000, 1296, 1295, 1294, -1000, 1293, 5251, 5250, 5245, 5244,
+	-1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, 70,
+	-1000, 2656, 200571, 2775, 200571, 1845, 184643, -19, -19, 25,
+	-1000, -1000, 367, 54, -1000, 1439, -1000, 1439, -1000, 1439,
+	-1000, -1000, 4373, -1000, 50, 4556, -1000, -1000, 207541, 50,
+	207541, -1000, -1000, -1000, 2471, 2457, 184643, -1000, 184643, 184643,
+	-1000, 4281, -1000, 184643, -1000, -1000, -1000, -1000, -1000, -1000,
+	143055, 143055, -1000, 5243, -1000, -1000, 40425, 184643, 143055, 40425,
+	143055, 4279, 4278, 1443, 1443, 1443, -1000, 2674, 184643, -1000,
+	-1000, 184643, 1442, 1442, -1000, 5163, 184643, 184643, 143055, -1000,
+	160373, 184643, -1000, 3259, 200571, -1000, 3589, 190179, 3554, 189487,
+	110320, -1000, -1000, 959, 1354, 3770, 3767, 1542, 184643, 184643,
+	3765, 188795, 188103, -1000, 5242, -1000, 184643, 3151, 69987, 160373,
+	3718, 4881, 3287, 3397, 201, 201, -1000, 201, -1000, -1000,
+	957, 1744, 143055, 143055, 184643, 200571, 143055, 3040, -1000, -1000,
+	-1000, -1000, -1000, 127793, -1000, 4870, -1000, 1896, -1000, -1000,
+	-1000, 1896, -1000, 1896, 3450, 2886, 184643, 200571, 143055, -1000,
+	-1000, -1000, -1000, 184643, 184643, 200571, 3419, 3543, 3413, 3970,
+	-1000, -1000, -1000, -1000, -1000, -1000, 184643, 184643, 200571, 200571,
+	163833, 3023, 163141, 3020, 3019, -1000, -1000, -1000, 2923, 3017,
+	3246, 2653, 184643, -1000, -1000, -1000, -1000, -1000, 1991, -1000,
+	1143, 1779, 4188, 69987, 69987, 3220, 201, 201, -1000, 201,
+	956, 40425, -1000, -1000, 2172, -1000, 4280, 184643, 5179, 187411,
+	5178, 184643, 184643, 184643, 200571, 4718, 184643, 49, -1000, 1977,
+	4052, -1000, 5091, -1000, 1275, 1760, 200571, -1000, -35, 48,
+	-28, -1000, 1272, 1269, 19, 1778, 82422, 2768, -1000, 3519,
+	-1000, -1000, -1000, -1000, 1774, 2960, 2560, 184643, 4856, -1000,
+	184643, 4845, -1000, -1000, -1000, 184643, 200571, -1000, 186719, 9795,
+	-1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000,
+	-1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000,
+	-1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000,
+	-1000, -1000, 3215, 3965, 1556, 113111, 184643, 1801, -1000, -1000,
+	2643, 1773, 1749, 127101, 3113, 2641, 2735, 91529, 1416, -1000,
+	91529, -1000, -1000, 35423, 207541, -1000, 207541, -1000, 103380, 2697,
+	121557, 121557, 2538, -1000, 2538, -1000, 143055, -1000, 3501, 83125,
+	184643, -1000, 4998, 184643, 99908, 99908, 2108, -1000, -1000, 3497,
+	184643, 123633, 1353, 4445, 97121, 19, 1398, 2096, 4334, 2504,
+	-28, 955, 184643, -1000, -1000, 3450, 4444, 785, 3588, -1000,
+	200571, 1506, 5020, 4437, 954, 184643, 5241, -1000, 143055, 3410,
+	3585, -1000, -1000, 186027, 185335, 4420, 1143, 184643, -1000, 2501,
+	1545, -78, -1000, 69987, 2898, -1000, 95028, 1525, 184643, -1000,
+	2822, 325, -1000, -1000, -1000, 97, 184643, -1000, 1108, -1000,
+	-1000, 8419, 8419, 1398, 92232, -81, -1000, 337, 951, 1268,
+	1267, 1318, 91529, -1000, 3958, 4187, -1000, -1000, 1441, -1000,
+	-1000, -1000, -1000, 1577, -1000, 2817, 3329, -1000, 950, -1000,
+	-1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, 3694, -1000,
+	-1000, 48527, 1321, -1000, -1000, 143055, 69, 46, 69987, 69987,
+	15122, 10801, 69987, 77387, 77387, -1000, 69987, 9602, -1000, -1000,
+	-1000, -1000, -1000, 4186, 949, 69987, 110320, 3207, 3060, -1000,
+	660, 13096, 475, -1000, 69987, -1000, 657, -1000, 659, 29738,
+	3, -83, -1000, -1000, 1114, -1000, 4399, -1000, 69987, 205459,
+	3652, 2895, 2749, 2548, 5141, 5177, 34712, -1000, 100603, 1459,
+	3289, 28126, -1000, -1000, -1000, -1000, 110320, 110320, 69987, 69987,
+	-1000, 69987, 69987, 69987, -1000, -1000, -1000, 5141, 658, -1000,
+	-1000, 1336, -1000, -1000, -1000, 1336, -1000, -1000, 1896, -1000,
+	1896, -1000, -1000, 69987, -1000, -1000, 4183, 69987, -1000, 110320,
+	110320, 77387, 77387, 77387, 77387, 77387, 77387, 77387, 77387, 77387,
+	77387, 77387, 77387, 77387, 77387, 77387, 77387, 77387, 77387, 77387,
+	77387, 3730, 77387, 5111, 5111, 5111, 1227, -1000, 4277, 4183,
+	69987, 69987, 110320, 656, 652, 642, -1000, 69987, 3, -1000,
+	-1000, 945, -1000, 3680, -1000, 184643, -1000, 4071, -1000, 69987,
+	-51, -1000, 3571, -1000, -1000, -1000, 4071, 4071, -84, 207541,
+	86627, 86627, -1000, 944, 69987, 3769, -1000, -1000, 1082, -347,
+	-1000, 1266, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000,
+	1265, 1263, -1000, 938, -1000, -1000, -1000, 162449, 932, -1000,
+	184643, 162449, 1081, -1000, -89, -1000, -1000, -90, -1000, 161757,
+	40425, -1000, -1000, 69987, 69987, 635, 632, -1000, 138, 1397,
+	426, -1000, 1429, -1000, -1000, -1000, -1000, -1000, -1000, -1000,
+	-1000, -1000, 3812, -269, 200571, 200571, 2637, 2634, 2625, 2617,
+	45, 19, 3320, -1000, 4084, 5176, -1000, 5139, 1109, 1080,
+	326, 631, -19, 200571, 200571, 2614, 2612, 2606, 2589, 102685,
+	4182, 200571, -1000, -1000, 143055, -1000, -1000, 99908, 110320, -1000,
+	110320, -1000, -1000, -1000, -1000, 143055, -1000, -1000, 3291, -1000,
+	-1000, -1000, 328, -1000, -1000, -1000, -1000, 1440, -1000, 42,
+	-1000, -1000, -1000, 69987, -1000, 1365, -1000, 2258, -1000, 2867,
+	-1000, -1000, -1000, -1000, 143055, -1000, 121557, 91529, -1000, 3914,
+	3914, -1000, 91529, 91529, 121557, 121557, -1000, -1000, -1000, -1000,
+	34001, 184643, 191, 3955, -19, 198491, 5065, 5058, -1000, 111015,
+	-1000, -1000, -1000, -1000, -1000, -1000, 1439, -1000, -1000, 5175,
+	19, -1000, -1000, -1000, -1000, -1000, -1000, 3222, 3494, 3222,
+	2757, 2753, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000,
+	-1000, -1000, -1000, 2785, -1000, -1000, 4710, 928, 1748, 1747,
+	-1000, -91, -1000, 1262, -1000, -1000, -1000, -1000, -1000, 4125,
+	-1000, 4431, -1000, 3579, -1000, 1532, 3578, 2630, -1000, 69987,
+	926, 3907, 925, 923, 5240, 3085, 5239, 1543, 4429, 3291,
+	4427, 3291, -1000, -1000, -1000, 1347, -1000, 207541, -97, -1000,
+	2518, 3287, -1000, 919, 917, -1000, 40, 2462, 920, 1742,
+	1437, -1000, -1000, 69987, 69987, 161065, -1000, 680, 4720, 66,
+	-1000, -1000, -1000, 2584, 1741, 1739, -1000, -1000, 1896, -1000,
+	-1000, -1000, 3450, 2583, 1731, 1677, -1000, -1000, -1000, -1000,
+	-1000, -1000, 4357, 3869, 3541, -1000, -1000, -1000, -1000, -1000,
+	-1000, -1000, 3576, -1000, -1000, 158989, -1000, 4424, 158989, 4029,
+	1143, 158989, 4720, 4099, 1434, -1000, 4345, 4343, 1335, 158989,
+	69987, 69987, 205248, 204878, -1000, 1433, -1000, -1000, 69987, -1000,
+	39, -1000, 1674, 4945, 3574, 143055, -1000, 3291, 4422, 1672,
+	-1000, 1663, -1000, -1000, -1000, 4939, 4938, 1718, 2745, 121557,
+	91529, 2705, -1000, 4925, 3308, 5122, -1000, 3939, 5091, 91529,
+	1657, 1402, 200571, -1000, -1000, 159681, 121557, 121557, 2093, -1000,
+	-1000, -1000, 82422, 2368, -10, 4359, -1000, 1258, 1485, 38,
+	-1000, 1234, -1000, 38, -1000, -1000, -1000, -1000, 5122, -1000,
+	-1000, -1000, -1000, 112409, -1000, -1000, -1000, -1000, 1465, 184643,
+	200571, 143055, 2731, -1000, -1000, 149287, 149979, 184643, 3953, 1318,
+	-1000, 2536, 1318, -1000, 3857, -1000, 154, 1398, -1000, 121557,
+	-1000, -1000, 3409, 3401, -103, -1000, 82422, 4179, 1431, 4270,
+	3106, 3396, 630, 37, -1000, 1716, 614, 3298, -1000, -1000,
+	-1000, 3486, -1000, -1000, 5238, 612, -104, 36, 110320, -1000,
+	-1000, -1000, -1000, 3554, 143055, 916, 184643, 1789, 3889, 3877,
+	184643, 184643, 5019, -1000, 3429, 911, 143055, 1396, -1000, 5123,
+	-1000, -1000, -1000, 184643, 49267, 159681, -1000, 4932, 143055, 5013,
+	4413, 1429, 143055, 201, 143055, 5151, 611, 35, 110320, -1000,
+	5011, 143055, 4411, 3390, 3573, 3389, 3572, 3736, 1143, 122249,
+	1429, 33, 913, -1000, 1254, 1252, 1251, 1397, 86627, -1000,
+	2316, 207541, -1000, 2822, 51487, 4703, -109, -1000, -1000, -1000,
+	1397, 99213, 86627, 69987, 5237, -110, -1000, -1000, -1000, -1000,
+	-1000, 121557, 1398, 184643, 184643, 5235, 121557, 121557, 121557, 1411,
+	1318, 91529, 201, -1000, 3302, -1000, 3318, -1000, -1000, -1000,
+	-1000, -1000, 3852, 4679, 40425, 4924, 19096, 69987, 69987, 8807,
+	1156, 491, 19096, 69987, 69987, 110320, 17986, -112, 69987, 69987,
+	-1000, 69987, 1079, 207541, -1000, 5173, -1000, -1000, 5135, -1000,
+	-1000, -1000, 207541, 69987, -1000, -1000, -1000, -1000, -1000, -1000,
+	-1000, 610, -1000, 295, -1000, -1000, -1000, 195023, -1000, 69987,
+	609, 4880, -1000, 607, 605, 11723, 420, 27849, 27352, 27116,
+	604, -1000, -1000, -1000, 602, 599, 207541, 4277, 207541, -1000,
+	-1000, 1329, 1329, 1843, 1843, 1843, 1843, 5111, 699, 1278,
+	1002, 634, 634, 634, 799, 1227, 1227, 634, 634, 634,
+	1227, 4173, 3732, 910, 7214, -1000, -1000, 207541, 207541, 598,
+	-1000, -1000, -1000, 3, 8877, -1000, -1000, 4070, 4879, 207541,
+	-1000, 86627, 4070, 4070, -1000, -1000, 3016, 184643, 207541, 86627,
+	-1000, 4528, -1000, 31877, 31175, 1106, -1000, -1000, -1000, -123,
+	-1000, 110320, -1000, -1000, -1000, 5123, -1000, 88712, -1000, 138,
+	204711, 31, -1000, -1000, -1000, 40425, -1000, 7593, 5443, -1000,
+	1250, -1000, -1000, 121557, 121557, 5234, 5233, -1000, 5172, 5171,
+	3316, 5170, -1000, 3898, -1000, -269, -122, 184643, 184643, 184643,
+	184643, -1000, 3306, -1000, 1074, 5232, 1105, 40425, -1000, -19,
+	-19, 184643, 184643, 184643, 184643, 4172, 143055, 184643, 2383, 200571,
+	-19, 3291, -1000, -1000, -1000, 3291, -1000, -1000, -1000, 3880,
+	207541, 4274, 4059, 4057, -1000, 4549, 1398, -1000, 1428, -1000,
+	-124, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000,
+	-1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, 40425, 2342,
+	-1000, 908, 907, 30, 906, -1000, 1966, 4794, 184643, 184643,
+	-1000, 160373, 50747, 2325, 155521, 184643, 4408, -1000, 4407, -1000,
+	1542, 3197, 26618, 87322, -1000, 87322, 184643, -1000, -1000, -1000,
+	-1000, 2903, 2031, -1000, -1000, 2445, 3064, 1602, -1000, 1919,
+	-1000, 4777, 184643, -1000, 184643, -1000, -1000, -1000, 160373, -1000,
+	-1000, 184643, 184643, 143055, 184643, -1000, 200571, 4364, -125, 207541,
+	29, -1000, 1248, -1000, 1855, -1000, 33290, 184643, 200571, 143055,
+	-1000, 184643, 200571, 143055, 184643, -1000, 3867, 4406, 1524, 158989,
+	-1000, 4401, 158989, 1523, -1000, -1000, 158989, 3241, -1000, -1000,
+	4342, -1000, 207541, 204373, 201, 69987, 4362, -126, 40425, -1000,
+	5169, 5167, 4394, 4802, -1000, 184643, 5166, 184643, 143055, 4627,
+	-1000, -1000, -1000, -1000, 1247, 1245, 1242, 1241, 1232, 3705,
+	1230, 1228, -1000, -1000, 5083, 159681, -1000, -1000, 1425, 184643,
+	-1000, 904, 4842, -19, -1000, -1000, -1000, 2001, 3388, 1990,
+	-1000, 2846, 27, -1000, 1457, 82422, 4807, 184643, 50747, -1000,
+	-1000, -1000, -1000, -1000, -1000, -1000, 2581, 1656, 1655, 3386,
+	3385, 3305, 25, 3113, 1416, 24, 900, -1000, 1416, 91529,
+	1398, 5007, -1000, 121557, 121557, -1000, 143055, 3384, 2866, 5230,
+	1648, 2535, -1000, -1000, 143055, 8143, 99908, 69987, 69987, 7916,
+	143055, 2108, 184643, -1000, 3882, -1000, 154829, 123633, 3425, -1000,
+	-1000, 87322, 899, 184643, 898, 184643, 896, 184643, 895, -1000,
+	201, -1000, 5229, 160373, 894, -1000, 1387, 3293, -1000, 5127,
+	-1000, 4338, -1000, 1071, -1000, -1000, 324, -131, 200571, 3450,
+	201, 143055, -1000, 785, 1407, 785, 597, 23, -1000, -1000,
+	184643, -1000, 754, 1538, 40425, 143055, 4393, 143055, 4390, 3733,
+	1143, 122249, -1000, 1900, 2200, 2200, 121557, 121557, 69987, 3288,
+	20, -1000, -1000, 21, -1000, 855, 201, 3288, -1000, 20,
+	207541, -1000, 1226, 592, -1000, 4622, -1000, -1000, -138, -1000,
+	-1000, -1000, 7292, 1411, 1318, -1000, 3565, -1000, -1000, -1000,
+	-1000, 4679, 19096, 19096, 69987, 69987, 69987, 19096, 17986, -144,
+	-1000, 19096, 19096, 3, -1000, -1000, -1000, 207541, -1000, 32579,
+	3227, -1000, 26567, -1000, 48527, -1000, -1000, 69987, 69987, -1000,
+	-1000, -1000, -1000, -1000, -1000, -1000, -1000, 77387, 4170, 892,
+	110320, -1000, 584, 1424, 69987, 72207, 3571, 1424, 1424, -1000,
+	-145, -1000, -1000, -1000, 5123, -1000, 5123, 5123, -1000, 184643,
+	-1000, -1000, -1000, 581, 48527, -1000, -1000, -152, -1000, 121557,
+	2715, 121557, 121557, 5225, 5222, 2059, 5164, 5161, 5221, 5218,
+	5217, 5156, 121557, -1000, -1000, -1000, -1000, -1000, -1000, 5216,
+	3540, 5215, -1000, -1000, -1000, -1000, 4327, -117, -134, -136,
+	-137, -1000, 1094, -1000, 5214, -1000, 308, 302, 294, 271,
+	200571, 4169, 262, 3952, 3951, 3949, -19, -1000, -1000, -1000,
+	4619, 201, -1000, -1000, -1000, -1000, -1000, -1000, -1000, 143055,
+	143055, 69987, 69987, 2712, 2712, 1221, 1220, -1000, -1000, -1000,
+	-1000, 3944, 5000, -1000, 2973, -1000, 184643, 184643, -1000, 184643,
+	-1000, 40425, 184643, 4036, 1756, -1000, 1354, 3763, 891, 77387,
+	1573, 143055, 1307, 4051, 4050, -1000, 5049, 4877, 4022, -153,
+	-1000, 184643, 69987, 184643, -154, -162, 3515, 4028, -1000, -1000,
+	1571, 4048, 4034, -1000, -1000, 3764, 1753, 69987, 1569, -1000,
+	-1000, 3884, 1896, 1854, 1896, 1896, 1850, 5213, 5044, 4876,
+	-1000, 110320, -1000, 1896, 886, 3291, 3291, -1000, -165, -168,
+	-1000, -1000, -1000, 69987, 1654, 184643, 50007, -1000, 5212, 4720,
+	-1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, 158989, 158989,
+	-1000, -1000, -1000, 158989, 4720, 184643, -1000, 69987, -1000, 204134,
+	69987, 1652, -1000, -1000, -1000, 5155, 3291, 40425, 3291, -1000,
+	3291, 4802, 1601, 121557, 69987, 2057, 91529, 91529, 1217, 69987,
+	69987, -1000, -1000, -1000, 3415, -1000, 69987, 884, 69987, 82422,
+	69987, -1000, 4359, 1216, -1000, -1000, -1000, -1000, 184643, 200571,
+	143055, 2411, 2411, 4273, -1000, -1000, -1000, 2705, 2705, -1000,
+	1416, 3039, 2489, 3830, 1412, -1000, 82422, 3480, -1000, 1402,
+	-1000, -1000, -1000, -1000, -1000, 4998, 2410, 3248, 7916, -1000,
+	5154, 122249, -1000, -1000, -1000, -1000, 207541, 207541, 3248, 3028,
+	-1000, 19, 3223, 5211, -1000, -1000, -1000, -1000, 3755, -1000,
+	-1000, -1000, 184643, 3754, 4015, -170, 87322, 883, 87322, 881,
+	87322, 880, 184643, 1405, -1000, -171, 123633, 1353, -1000, 1387,
+	-1000, -1000, -1000, 1320, -1000, -1000, -1000, -1000, 785, 4994,
+	-1000, 3826, 4989, -1000, 5153, 110320, 879, 184643, 876, 184643,
+	3382, 874, 40425, 873, 40425, 4696, 1143, 122249, -1000, 4420,
+	-1000, -176, -1000, -1000, 207541, 3841, -1000, 3551, 184643, 4684,
+	-1000, 3841, 872, 1398, 869, 1398, 18, 859, -1000, 1214,
+	1213, 1212, -1000, -1000, -1000, -1000, -1000, -1000, -1000, 1203,
+	1201, 1199, 1196, -1000, -1000, -1000, 3704, 4609, -1000, -1000,
+	-1000, -1000, -1000, -1000, 1411, 17, -1000, 5057, 856, 914,
+	-1000, -1000, 19096, 19096, 19096, -1000, -1000, 3286, 4875, -1000,
+	15, 14, 26070, 25732, 3744, 77387, 110320, -178, -1000, -1000,
+	184643, 207541, 13, -1000, 207541, 852, 850, 772, -1000, -1000,
+	-1000, 1068, 1065, 1062, -1000, -1000, -1000, -1000, -1000, 5443,
+	-1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000,
+	-1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, 5210,
+	-1000, -1000, 200571, 200571, 200571, 200571, 5209, -1000, 200571, 200571,
+	200571, 200571, -19, 200571, 200571, 2573, 2567, 2557, -1000, -1000,
+	-1000, -1000, -183, -186, -1000, -194, 82422, 91529, 154137, 184643,
+	-1000, -1000, 2630, 3108, -1000, -1000, 184643, 3556, -1000, -1000,
+	-1000, 1404, 69987, 7214, 77387, 849, 69987, -1000, 848, 846,
+	4986, 4578, -1000, 3895, 4130, 2751, 87322, -1000, 4679, -1000,
+	25253, -1000, 1535, 3033, -1000, 4383, -1000, 845, 844, -1000,
+	-1000, 207541, 69987, -1000, -1000, -1000, -1000, -1000, 1896, -1000,
+	-1000, -1000, 1896, -1000, -1000, 4577, 4802, -1000, 87322, -1000,
+	-1000, 843, 841, 207541, 834, 1195, 4163, -1000, -1000, -1000,
+	-1000, -140, -1000, -140, -1000, -1000, 207541, 201, 207541, 823,
+	4945, -1000, -1000, -1000, -1000, 3291, 143055, -1000, 207541, -1000,
+	-1000, -1000, -1000, 121557, 207541, 207541, 1194, 24973, 69987, 207541,
+	1391, 207541, -1000, 82422, -1000, -1000, -1000, 1651, -1000, -1000,
+	-1000, -1000, -1000, 5208, 4126, 149287, -1000, -195, 3039, 1384,
+	49267, 2538, -1000, 2335, 1391, 82422, -1000, 4270, 110320, 822,
+	-1000, -1000, -1000, 4942, 69987, -1000, 12, -1000, -1000, -1000,
+	4268, 3511, 1353, -1000, -1000, 3425, 812, -1000, 1378, 3130,
+	3130, 1535, -196, 87322, -197, 87322, -202, 87322, -203, 3337,
+	3821, -1000, 574, 4984, 1387, 1397, -1000, 4983, 201, 4616,
+	-1000, 201, -1000, -1000, 5151, 572, 87322, -1000, 143055, 87322,
+	3378, 87322, 3363, 3143, 3715, 122249, -1000, 3736, -1000, 2822,
+	-1000, -1000, -204, 184643, 2822, -1000, -1000, 121557, -1000, 7951,
+	7951, 121557, 91529, 121557, 121557, 91529, 121557, 121557, 1193, 4676,
+	-1000, -1000, 3565, -1000, 184643, -1000, 184643, 3132, 69987, 48527,
+	48527, -1000, -1000, 3744, -210, -1000, 11, -1000, 4982, 72207,
+	5207, 5206, 5205, -1000, -1000, -1000, -1000, -1000, -269, -269,
+	-269, -269, -1000, -19, -19, -19, -19, -19, -19, 184643,
+	184643, 184643, -1000, -1000, -1000, -1000, -1000, -1000, 2949, -1000,
+	3554, -1000, -1000, 4382, -1000, 4068, 811, 24469, 7214, 3685,
+	184643, 24192, 3450, 3450, -1000, 4981, 4121, -1000, -1000, 3220,
+	805, -1000, -1000, -1000, -1000, 1321, 184643, 1378, 4042, 143055,
+	-1000, 3450, 3450, 207541, -1000, -1000, -1000, 1541, -216, 3222,
+	3222, 69987, 47787, 3237, 158989, -1000, 69987, -1000, -1000, 4802,
+	-1000, 91529, 1410, 23104, -1000, 2986, -1000, 200571, -1000, 200571,
+	3356, -1000, 4106, -1000, 2693, 255, 1408, 10, 800, -1000,
+	1191, 1186, 1181, -1000, 3348, -1000, 3346, 1648, 7916, -1000,
+	195715, -1000, 207541, -1000, 5150, 1462, 4428, 3511, -1000, 2265,
+	-1000, -1000, 3337, 184643, -1000, -1000, -1000, -1000, -1000, -1000,
+	-1000, -1000, -1000, -1000, -1000, -1000, 2751, 1535, -218, 3220,
+	-225, 3220, -226, -1000, -1000, 4748, -1000, 4610, 3882, 201,
+	-1000, 201, -1000, 5204, 1407, 570, -1000, -231, 1538, -236,
+	143055, -249, 143055, 3007, -1000, 1143, -1000, 3733, -1000, 1397,
+	4434, -1000, -250, -1000, -259, -1000, -1000, -1000, -1000, -1000,
+	-1000, -1000, 121557, -1000, -1000, -260, -261, 567, 71467, 71467,
+	71467, 3, -3, -3, -1000, 184643, 797, -1000, -1000, -1000,
+	-1000, -1000, -1000, -1000, -1000, 250, 190, 189, -1000, -1000,
+	4332, 1323, -1000, 1233, 2885, 558, 1567, 264, 257, -1000,
+	-1000, -1000, 4022, -1000, 184643, -1000, -1000, -1000, 1323, 785,
+	252, 192, -1000, 69987, 1535, -268, -1000, 1522, -271, -1000,
+	1521, -273, -1000, 4122, -1000, -1000, -276, 3291, -1000, 4841,
+	1537, -10, 784, -269, 327, 2411, 1384, 4921, 3284, 1320,
+	-1000, 3544, 2324, 2324, 121557, 121557, 121557, 121557, 82422, 1402,
+	3248, -281, -1000, 110320, -1000, -1000, 21141, -1000, 4377, 69987,
+	2469, -1000, -1000, 4968, -1000, -1000, 3702, -283, -1000, -1000,
+	3220, 2751, 1535, 1378, 3220, 1378, 3220, 3502, -1000, 3223,
+	1405, -1000, -1000, -1000, -1000, 1535, 782, 2751, 781, 2751,
+	775, 2105, 1143, -1000, -1000, 1896, 4696, 4433, 1832, 1398,
+	-1000, -1000, -1000, -1000, -1000, 4405, -1000, 78867, 3404, 2741,
+	203393, 4405, 4405, -1000, -1000, 200571, 200571, 200571, 184643, 1378,
+	4883, -1000, 1303, 1289, 2089, -1000, -1000, -1000, -1000, -1000,
+	-1000, -1000, -1000, 1397, -284, -1000, 3685, -1000, -1000, 207541,
+	1378, -1000, 3222, 3941, -1000, 3222, 4118, -1000, 3236, -1000,
+	-1000, 774, 765, 2846, -1000, -1000, 4115, -1000, 5079, 97814,
+	1397, -18, 762, -1000, 1160, 1153, 4102, 143055, 1152, 2541,
+	1149, 1148, -1000, -291, -1000, -1000, -1000, -1000, 1391, -1000,
+	-1000, 7916, 195715, -1000, -336, -1000, -1000, -1000, 3381, 207541,
+	-1000, -1000, -1000, 184643, -1000, -1000, -1000, 1378, 184643, 1378,
+	3220, 2751, 1397, 1378, 1397, 1378, 2722, 2709, 5203, 1353,
+	3337, 2751, 87322, 3220, 87322, 3220, 87322, 3205, -1000, 158989,
+	-1000, 3143, 1821, -1000, 2421, -1000, -1000, 2600, 5040, -1000,
+	-1000, -1000, -1000, -1000, -1000, -1000, -19, -19, -19, -1000,
+	-1000, 1147, -1000, 4566, -1000, 1566, 3084, 3084, -1000, -1000,
+	1233, -1000, -1000, 755, -1000, 753, -1000, 69987, 69987, -292,
+	200571, -1000, -1000, -28, 159681, 3039, 3752, 3752, 121557, 121557,
+	1145, 4266, 121557, 4839, 121557, 121557, -1000, -1000, 3248, -1000,
+	-1000, 111707, -1000, -1000, -1000, -1000, -1000, 1397, 1378, 3220,
+	1784, 1397, 1784, 1397, -1000, 5196, -1000, 3337, -1000, 3220,
+	-297, 1378, -298, 1378, -299, 3249, -1000, -140, 3007, -1000,
+	2409, 99213, 2706, -1000, -1000, 3275, 70727, 69987, -1000, 5097,
+	-1000, -1000, 3820, -1000, 4022, 69987, 69987, 22225, 21385, -1000,
+	327, -300, 1384, -1000, -311, -1000, -1000, 121557, 2055, -1000,
+	-1000, -1000, -1000, -1000, 747, 1784, 1397, 1378, -1000, 1477,
+	-1000, -1000, 5126, 1784, -1000, 1784, -1000, 3702, 1378, 1535,
+	1397, 2751, 1397, 2751, 2225, 1143, 2105, 99213, -293, -1000,
+	-1000, -1000, 207541, -1000, -1000, -1000, -1000, -316, -321, -1000,
+	-1000, -1000, -1000, -1000, -1000, -1000, 143055, 37556, -1000, 1784,
+	1397, -1000, -1000, -1000, -1000, -1000, 1397, 2751, 1784, 3220,
+	1784, 3220, 2540, -1000, 2939, 200571, 3205, -293, -1000, 3220,
+	1636, -1000, -322, -1000, -1000, -1000, -1000, -1000, -1000, 1784,
+	1784, 3220, -1000, 1378, -1000, 1378, -1000, -1000, 2923, 158989,
+	-1000, 3249, -1000, -1000, -1000, 744, -1000, 37556, -1000, -1000,
+	1378, 1397, 1397, 1520, 2225, 69987, -1000, 1397, 1784, 1784,
+	158989, 2540, -333, 1784, -1000, -1000, -140, -1000, 3220, -1000,
+	-1000,
 }
 
 var sqlPgo = [...]int16{
-	0, 5645, 5643, 69, 5642, 5639, 5638, 5635, 5633, 5632,
-	5631, 5630, 5628, 5627, 5626, 5625, 211, 5624, 5623, 5622,
-	5621, 5619, 5618, 5616, 5615, 5614, 5613, 5612, 5611, 5610,
-	5609, 5608, 5607, 5606, 5605, 145, 230, 5604, 5603, 5602,
-	5601, 5600, 5599, 5598, 5597, 5596, 5593, 5590, 5589, 5587,
-	5581, 5580, 5578, 5577, 5573, 5572, 5571, 5569, 5567, 5566,
-	5563, 5561, 5560, 5559, 5558, 5556, 5555, 5554, 5553, 5551,
-	5550, 5548, 5547, 5544, 5543, 5537, 5535, 5534, 5531, 5530,
-	5523, 5522, 5521, 5520, 5519, 61, 5511, 5509, 5508, 5500,
-	5498, 5496, 5490, 5485, 5482, 5481, 84, 53, 5480, 5479,
-	5478, 5477, 5476, 5475, 5473, 5472, 5470, 5468, 5467, 5466,
-	5465, 5464, 5463, 5462, 5459, 5458, 5457, 5456, 5453, 5452,
-	183, 5451, 5450, 116, 94, 5448, 366, 5445, 5444, 5442,
-	5441, 5440, 5438, 5435, 5434, 5433, 5432, 5431, 5430, 5429,
-	5428, 5426, 247, 5425, 361, 5424, 48, 227, 5423, 5422,
-	5421, 51, 5420, 5419, 364, 5418, 5414, 5413, 5412, 5411,
-	369, 5410, 5408, 5406, 5405, 5404, 315, 5403, 5402, 5398,
-	5397, 5395, 5394, 176, 175, 5393, 5392, 1844, 5390, 5389,
-	5388, 5387, 5382, 5381, 5380, 297, 317, 5378, 5377, 5376,
-	335, 233, 5375, 359, 5374, 5373, 5372, 5371, 5367, 300,
-	5366, 5365, 5364, 5362, 5361, 5360, 5358, 5357, 5353, 5352,
-	5351, 5350, 5348, 5346, 5343, 5342, 5340, 5338, 5337, 5336,
-	5334, 5332, 5330, 5329, 5327, 5320, 5319, 5317, 5316, 5315,
-	5312, 5309, 5308, 5307, 5281, 5279, 5277, 5276, 5275, 5274,
-	5272, 5270, 5269, 5267, 354, 293, 159, 5266, 5265, 5264,
-	5262, 5261, 5260, 362, 358, 5259, 5258, 5257, 5256, 5255,
-	4372, 5254, 5253, 5252, 5250, 5249, 5245, 5244, 5240, 5238,
-	168, 28, 128, 5237, 14, 194, 121, 124, 171, 135,
-	133, 21, 149, 20, 5233, 245, 303, 164, 200, 198,
-	152, 5231, 148, 201, 161, 5222, 96, 5219, 180, 150,
-	5214, 151, 142, 31, 106, 246, 332, 7992, 327, 5212,
-	5211, 5204, 344, 268, 5200, 334, 5199, 5198, 5194, 5184,
-	5181, 5179, 98, 78, 285, 5171, 187, 5162, 5161, 185,
-	234, 249, 242, 232, 241, 337, 83, 134, 114, 86,
-	70, 15, 33, 299, 25, 294, 3, 5160, 4, 9,
-	350, 11, 345, 10, 190, 12, 39, 5159, 5158, 5157,
-	5153, 5109, 177, 5152, 355, 328, 226, 5151, 5150, 5148,
-	5147, 5146, 706, 5145, 79, 329, 439, 129, 143, 257,
-	170, 5144, 220, 287, 50, 5142, 228, 105, 5138, 5137,
-	155, 127, 15133, 9116, 5136, 5135, 219, 109, 163, 6274,
-	256, 248, 306, 617, 195, 239, 229, 5131, 156, 5128,
-	254, 210, 238, 378, 5127, 336, 5125, 4406, 139, 252,
-	222, 7703, 5124, 5120, 5119, 117, 5118, 140, 5115, 5113,
-	91, 19, 1, 2, 193, 46, 43, 29, 5112, 27,
-	196, 74, 32, 5111, 34, 5110, 5108, 5107, 5106, 73,
-	5105, 131, 225, 5104, 5103, 365, 5102, 5101, 138, 104,
-	82, 5098, 108, 5097, 7, 240, 269, 310, 5096, 5091,
-	318, 188, 5090, 5088, 260, 270, 272, 250, 307, 5087,
-	59, 321, 5086, 5085, 5084, 5083, 5082, 370, 107, 8,
-	172, 5080, 5079, 208, 5078, 81, 341, 274, 5077, 87,
-	5072, 5071, 182, 5070, 278, 80, 207, 363, 197, 319,
-	169, 323, 253, 330, 5069, 5068, 5067, 259, 5065, 5064,
-	316, 221, 5063, 291, 5062, 5061, 281, 374, 126, 72,
-	110, 331, 113, 271, 224, 5059, 276, 206, 5053, 209,
-	5052, 122, 5051, 368, 251, 305, 55, 13, 42, 125,
-	144, 112, 5, 326, 223, 290, 165, 5050, 10206, 2708,
-	325, 99, 5045, 214, 174, 111, 202, 218, 356, 101,
-	5044, 5043, 663, 5041, 5038, 5036, 5035, 262, 5033, 5032,
-	301, 212, 217, 5031, 205, 265, 5030, 136, 137, 97,
-	76, 26, 184, 56, 357, 162, 320, 261, 280, 5028,
-	5027, 5026, 258, 5025, 102, 178, 284, 186, 5024, 275,
-	339, 95, 5023, 5022, 115, 2360, 120, 213, 2512, 90,
-	215, 5020, 312, 5015, 5014, 5012, 5009, 5008, 5004, 5001,
-	4998, 324, 4997, 4996, 4995, 44, 277, 4992, 273, 216,
-	283, 132, 77, 266, 173, 3211, 153, 166, 279, 85,
-	17, 6, 314, 4990, 7126, 88, 4989, 0, 15519, 11494,
-	16651, 4987, 4984, 17723, 4983, 3155, 4981, 4979, 4977, 296,
-	103, 4976, 4972, 4968, 141, 4967, 118, 4943, 4942, 100,
-	4941, 30, 23, 24, 35, 36, 367, 973, 4939, 4936,
-	45, 181, 64, 4935, 360, 322, 4934, 4933, 4932, 4931,
-	147, 4929, 68, 4927, 63, 4926, 4923, 71, 18, 38,
-	4922, 4920, 264, 235, 4261, 237, 204, 4919, 158, 47,
-	4918, 351, 89, 199, 4917, 4913, 372, 286, 295, 130,
-	4908, 338, 4907, 289, 4906, 22, 37, 4905, 4904, 352,
-	167, 160, 93, 343, 189, 67, 4903, 4902, 4901, 4900,
-	255, 4898, 231, 4897, 4896, 4895, 146, 203, 4894, 75,
-	60, 4892, 4891, 119, 304, 244, 349, 66, 4890, 4889,
-	41, 309, 311, 4888, 342, 267, 4887, 191, 308, 4886,
-	4885, 243, 157, 4879, 4878, 4877, 399, 4876, 4875, 347,
-	4874, 4873, 4363, 353, 4872, 40, 4871, 4870, 4868, 16,
-	4867, 4866, 282, 4093, 4865, 4860, 58, 4856, 263,
+	0, 6219, 6216, 81, 6214, 6213, 6205, 6203, 6202, 6200,
+	6198, 6195, 6194, 6193, 6192, 6190, 225, 6185, 6183, 6180,
+	6179, 6175, 6174, 6173, 6171, 6170, 6168, 6167, 6166, 6165,
+	6164, 6163, 6162, 6161, 6160, 6156, 178, 255, 6155, 6154,
+	6152, 6150, 6148, 6147, 6146, 6145, 6144, 6141, 6139, 6138,
+	6137, 6136, 6135, 6134, 6133, 6132, 6131, 6129, 6128, 6127,
+	6126, 6125, 6123, 6121, 6120, 6118, 6117, 6116, 6115, 6114,
+	6113, 6112, 6111, 6110, 6109, 6108, 6104, 6101, 6099, 6097,
+	6092, 6091, 6087, 6086, 6085, 6084, 6083, 79, 6082, 6080,
+	6079, 6078, 6077, 6076, 6073, 6072, 6071, 6069, 96, 77,
+	6067, 6066, 6064, 6062, 6059, 6057, 6050, 6048, 6047, 6041,
+	6038, 6037, 6033, 6029, 6026, 6025, 6024, 6023, 6022, 6021,
+	6018, 6013, 6005, 5997, 5994, 5993, 5988, 121, 5987, 5982,
+	30, 27, 5979, 58, 76, 5974, 5973, 139, 120, 5967,
+	160, 165, 5966, 387, 5965, 5964, 5960, 5959, 5958, 5957,
+	5954, 5953, 5949, 5948, 5945, 5944, 5943, 5941, 5940, 5936,
+	5935, 273, 5934, 388, 5933, 66, 246, 5930, 5929, 72,
+	5928, 70, 5926, 5924, 384, 5923, 5921, 5918, 5916, 5911,
+	5910, 394, 5907, 5906, 5905, 5901, 5895, 327, 5894, 5893,
+	5892, 5888, 5887, 5885, 1279, 5883, 5878, 1985, 5872, 5871,
+	5870, 5866, 5863, 5862, 5861, 5860, 5857, 5856, 314, 324,
+	5853, 5852, 5849, 356, 259, 5848, 376, 5844, 5843, 5842,
+	5841, 5840, 5838, 318, 5837, 5836, 5834, 5830, 5823, 5821,
+	5816, 5815, 5814, 271, 155, 157, 5813, 5812, 5811, 5810,
+	5808, 5807, 5806, 5804, 5803, 5797, 5794, 5789, 5788, 5787,
+	5786, 5785, 5784, 5783, 5780, 5777, 5775, 5772, 5771, 5767,
+	5766, 5761, 5757, 5756, 5755, 5754, 5752, 5750, 5748, 5746,
+	5745, 5744, 5743, 5742, 5741, 5740, 5738, 375, 309, 219,
+	5736, 5735, 5734, 5732, 5731, 5730, 382, 379, 5728, 5727,
+	5726, 5725, 5723, 4937, 5720, 5717, 5716, 5715, 5714, 5713,
+	5711, 5710, 185, 18, 112, 5709, 14, 147, 146, 144,
+	125, 105, 99, 39, 179, 36, 149, 5708, 5707, 270,
+	325, 205, 226, 221, 222, 200, 5705, 122, 5703, 201,
+	184, 5702, 192, 169, 28, 4, 256, 358, 8007, 350,
+	5701, 5700, 5699, 360, 296, 5698, 344, 5697, 5696, 5694,
+	5690, 5689, 5688, 123, 92, 310, 5687, 213, 5684, 5683,
+	212, 260, 267, 266, 264, 265, 867, 95, 173, 134,
+	102, 69, 16, 65, 330, 32, 317, 5, 5682, 7,
+	10, 368, 8, 367, 11, 214, 13, 50, 5681, 5678,
+	5677, 5675, 5733, 210, 5674, 377, 355, 244, 5673, 5672,
+	5671, 5668, 23, 5666, 2504, 5665, 90, 336, 161, 199,
+	191, 492, 198, 5661, 236, 277, 46, 5660, 42, 114,
+	5658, 5657, 202, 150, 18063, 10875, 5656, 5655, 188, 131,
+	148, 1719, 249, 248, 321, 279, 215, 254, 247, 5653,
+	351, 5652, 261, 280, 268, 962, 5651, 364, 5650, 4978,
+	168, 276, 242, 15568, 5649, 5648, 5647, 140, 5644, 166,
+	5643, 5641, 110, 21, 2, 1, 216, 53, 57, 64,
+	5639, 49, 217, 87, 43, 5638, 41, 5637, 5636, 5634,
+	5631, 86, 5627, 118, 245, 5624, 5623, 390, 5619, 5613,
+	158, 130, 101, 5611, 33, 5610, 20, 263, 83, 323,
+	333, 5609, 5608, 340, 207, 5607, 5606, 284, 305, 297,
+	278, 328, 5602, 74, 348, 5600, 5599, 5594, 5593, 5592,
+	395, 5591, 117, 12, 203, 5590, 5586, 230, 5585, 93,
+	349, 302, 5584, 111, 5583, 5581, 209, 5580, 285, 94,
+	163, 5578, 183, 391, 283, 337, 197, 341, 286, 338,
+	5576, 5573, 5572, 288, 5569, 5568, 335, 239, 5566, 252,
+	5565, 5564, 322, 396, 154, 135, 343, 136, 292, 243,
+	5563, 301, 224, 5561, 234, 5559, 156, 5558, 392, 269,
+	326, 60, 29, 17, 151, 171, 115, 6, 357, 241,
+	299, 193, 5557, 21774, 3287, 4518, 262, 5556, 238, 204,
+	133, 195, 237, 374, 129, 5555, 5554, 6535, 5553, 5551,
+	5550, 5549, 290, 5548, 5547, 312, 229, 228, 5543, 223,
+	282, 5542, 162, 164, 116, 103, 35, 208, 153, 389,
+	194, 329, 289, 307, 304, 5541, 5540, 287, 5539, 113,
+	177, 308, 206, 5536, 300, 361, 107, 5534, 5530, 141,
+	180, 137, 240, 1748, 119, 235, 5528, 334, 5527, 5521,
+	5519, 5518, 5517, 5516, 5515, 5512, 339, 5511, 5510, 5508,
+	5507, 54, 295, 5506, 294, 298, 126, 182, 88, 293,
+	152, 84, 52, 868, 303, 138, 159, 3, 363, 5505,
+	3368, 100, 5504, 0, 18409, 11938, 10369, 5503, 5502, 14538,
+	5501, 372, 5499, 5498, 5497, 320, 127, 5496, 5495, 5494,
+	181, 5493, 142, 5491, 5489, 124, 5488, 44, 26, 31,
+	47, 45, 2120, 2252, 5486, 5485, 466, 231, 62, 5482,
+	383, 342, 5480, 5479, 5478, 5477, 170, 5476, 85, 5475,
+	82, 5474, 5473, 97, 22, 48, 5468, 5467, 275, 250,
+	4788, 258, 233, 5463, 187, 55, 5461, 373, 128, 232,
+	5457, 5456, 385, 311, 313, 167, 5454, 352, 5453, 272,
+	5452, 25, 40, 5448, 5447, 370, 176, 175, 75, 362,
+	91, 61, 145, 108, 5446, 211, 106, 5445, 5441, 5440,
+	38, 5436, 251, 5431, 5429, 5428, 5426, 172, 218, 37,
+	5425, 68, 34, 5422, 5421, 143, 315, 281, 371, 5420,
+	398, 56, 5419, 5417, 24, 332, 331, 5416, 5413, 174,
+	5412, 89, 5411, 5410, 5408, 5407, 5405, 5404, 5403, 9,
+	5402, 5401, 5399, 365, 274, 5397, 227, 316, 190, 189,
+	5396, 5395, 5393, 5392, 253, 5391, 5390, 5388, 5387, 403,
+	5386, 5385, 5384, 366, 5383, 5382, 4931, 415, 5376, 51,
+	5374, 15, 5372, 5371, 306, 4534, 5370, 5369, 19, 5366,
+	291,
 }
 
 var sqlR1 = [...]int16{
@@ -26571,492 +28858,538 @@ var sqlR1 = [...]int16{
 	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, 4, 4,
-	4, 4, 4, 4, 7, 7, 7, 7, 7, 7,
+	3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+	4, 4, 4, 4, 4, 4, 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, 8, 8, 8, 8, 8, 8,
-	8, 8, 8, 8, 8, 14, 14, 10, 10, 10,
-	10, 11, 11, 11, 11, 11, 71, 71, 12, 12,
+	7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+	8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
+	8, 14, 14, 10, 10, 10, 10, 11, 11, 11,
+	11, 11, 73, 73, 12, 12, 12, 12, 12, 12,
 	12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
-	12, 12, 12, 12, 20, 20, 20, 20, 20, 20,
-	21, 21, 21, 21, 21, 50, 52, 51, 45, 45,
-	46, 46, 47, 48, 48, 53, 55, 54, 56, 57,
-	57, 58, 58, 58, 13, 13, 13, 9, 9, 9,
-	9, 9, 9, 9, 9, 9, 24, 24, 59, 59,
-	25, 25, 61, 61, 26, 26, 62, 62, 726, 726,
-	726, 727, 727, 728, 728, 728, 29, 64, 66, 66,
-	465, 465, 465, 465, 22, 23, 23, 23, 23, 729,
-	729, 729, 729, 49, 30, 65, 42, 42, 42, 42,
-	42, 273, 273, 273, 273, 28, 28, 60, 60, 332,
-	332, 331, 331, 331, 331, 331, 331, 331, 331, 331,
-	331, 331, 331, 331, 331, 331, 331, 331, 331, 331,
-	331, 331, 331, 331, 331, 331, 331, 331, 331, 331,
-	331, 725, 725, 334, 334, 333, 319, 319, 320, 320,
-	321, 321, 730, 730, 335, 335, 335, 336, 336, 17,
-	17, 17, 17, 17, 17, 17, 17, 17, 17, 619,
-	619, 619, 650, 650, 650, 650, 652, 652, 780, 780,
-	781, 781, 781, 781, 781, 176, 176, 501, 501, 501,
-	83, 83, 83, 83, 83, 715, 715, 275, 275, 275,
-	277, 277, 276, 276, 276, 276, 276, 276, 276, 276,
-	276, 276, 276, 276, 276, 782, 782, 110, 110, 111,
-	111, 327, 327, 326, 326, 326, 326, 326, 326, 326,
-	736, 736, 735, 774, 774, 734, 734, 737, 737, 737,
-	274, 274, 274, 107, 107, 131, 131, 172, 172, 172,
-	172, 172, 172, 172, 173, 173, 174, 174, 278, 278,
-	278, 280, 280, 279, 279, 279, 279, 279, 279, 279,
-	279, 279, 279, 279, 279, 279, 279, 279, 279, 279,
-	279, 279, 279, 279, 279, 279, 784, 784, 783, 783,
-	298, 19, 19, 155, 155, 155, 155, 155, 155, 155,
-	150, 150, 654, 654, 655, 655, 269, 269, 270, 270,
-	270, 270, 271, 271, 272, 272, 272, 85, 99, 99,
-	99, 99, 99, 99, 293, 293, 293, 295, 295, 297,
-	297, 294, 294, 294, 294, 294, 294, 294, 294, 294,
-	294, 294, 294, 294, 294, 296, 296, 296, 296, 296,
-	296, 296, 296, 296, 296, 296, 296, 296, 296, 296,
-	296, 296, 296, 86, 86, 86, 86, 86, 86, 86,
-	86, 86, 87, 87, 87, 87, 87, 88, 88, 88,
-	88, 88, 88, 89, 89, 89, 89, 89, 89, 90,
-	90, 97, 97, 97, 97, 97, 97, 97, 97, 246,
-	246, 100, 100, 100, 100, 100, 100, 100, 100, 100,
-	100, 100, 100, 100, 100, 100, 100, 115, 115, 115,
-	115, 115, 786, 786, 120, 120, 281, 281, 281, 283,
-	283, 282, 282, 101, 101, 101, 101, 101, 106, 106,
-	106, 106, 106, 118, 118, 119, 119, 746, 746, 747,
-	747, 748, 748, 766, 752, 752, 753, 753, 756, 756,
-	756, 757, 757, 757, 757, 757, 765, 765, 765, 765,
-	765, 759, 758, 760, 760, 761, 761, 763, 763, 763,
-	763, 763, 764, 764, 764, 764, 764, 764, 764, 764,
-	764, 764, 764, 764, 764, 764, 764, 764, 764, 751,
-	767, 768, 768, 769, 769, 770, 770, 770, 773, 773,
-	139, 139, 139, 140, 140, 140, 772, 772, 771, 771,
-	754, 754, 755, 755, 75, 762, 762, 787, 787, 76,
-	77, 78, 79, 80, 81, 82, 749, 749, 785, 785,
-	785, 785, 785, 785, 785, 785, 785, 785, 785, 785,
-	785, 785, 785, 785, 785, 788, 788, 789, 789, 790,
-	790, 790, 790, 790, 790, 790, 790, 790, 790, 790,
-	790, 790, 790, 790, 790, 790, 790, 104, 104, 104,
-	104, 104, 104, 104, 104, 104, 104, 104, 104, 104,
-	104, 104, 104, 104, 104, 104, 104, 104, 121, 121,
-	453, 453, 416, 416, 122, 122, 122, 123, 123, 124,
-	124, 124, 124, 102, 102, 102, 103, 103, 103, 712,
-	712, 713, 719, 791, 791, 608, 608, 606, 606, 607,
-	126, 126, 469, 469, 469, 503, 503, 502, 500, 500,
-	127, 127, 127, 127, 127, 127, 128, 128, 128, 128,
-	128, 128, 128, 128, 128, 128, 128, 129, 129, 129,
-	129, 129, 129, 129, 129, 129, 129, 129, 129, 129,
-	129, 129, 129, 129, 129, 137, 137, 137, 137, 137,
-	138, 138, 138, 135, 135, 135, 132, 132, 132, 130,
-	130, 130, 136, 136, 136, 141, 141, 141, 142, 142,
-	718, 402, 402, 134, 134, 134, 133, 133, 133, 475,
-	475, 476, 478, 477, 143, 143, 143, 143, 417, 144,
-	144, 144, 144, 144, 144, 144, 144, 147, 147, 147,
-	147, 146, 146, 146, 146, 146, 146, 146, 146, 146,
-	146, 146, 146, 146, 146, 146, 146, 146, 146, 146,
+	20, 20, 20, 20, 20, 20, 21, 21, 21, 21,
+	21, 52, 54, 53, 47, 47, 48, 48, 49, 50,
+	50, 55, 57, 56, 58, 59, 59, 60, 60, 60,
+	13, 13, 13, 9, 9, 9, 9, 9, 9, 9,
+	9, 9, 25, 25, 61, 61, 26, 26, 63, 63,
+	27, 27, 64, 64, 762, 762, 762, 763, 763, 764,
+	764, 764, 30, 66, 68, 68, 497, 497, 497, 497,
+	23, 24, 24, 24, 24, 765, 765, 765, 765, 51,
+	31, 67, 44, 44, 44, 44, 44, 305, 305, 305,
+	305, 29, 29, 62, 62, 363, 363, 362, 362, 362,
+	362, 362, 362, 362, 362, 362, 362, 362, 362, 362,
+	362, 362, 362, 362, 362, 362, 362, 362, 362, 362,
+	362, 362, 362, 362, 362, 362, 362, 362, 362, 362,
+	362, 362, 362, 362, 362, 362, 362, 761, 761, 365,
+	365, 364, 350, 350, 351, 351, 352, 352, 766, 766,
+	366, 366, 366, 367, 367, 542, 542, 542, 542, 542,
+	542, 542, 542, 542, 542, 542, 542, 542, 542, 542,
+	541, 541, 17, 17, 17, 17, 17, 17, 17, 17,
+	17, 17, 654, 654, 654, 686, 686, 686, 686, 688,
+	688, 843, 843, 844, 844, 844, 844, 844, 196, 196,
+	535, 535, 535, 85, 85, 85, 85, 85, 751, 751,
+	307, 307, 307, 309, 309, 308, 308, 308, 308, 308,
+	308, 308, 308, 308, 308, 308, 308, 308, 845, 845,
+	112, 112, 113, 113, 358, 358, 357, 357, 357, 357,
+	357, 357, 357, 357, 357, 772, 772, 771, 833, 833,
+	770, 770, 773, 773, 773, 306, 306, 306, 109, 109,
+	126, 126, 139, 139, 139, 140, 140, 141, 141, 141,
+	148, 148, 193, 193, 193, 193, 193, 193, 193, 194,
+	194, 310, 310, 310, 312, 312, 311, 311, 311, 311,
+	311, 311, 311, 311, 311, 311, 311, 311, 311, 311,
+	311, 311, 311, 311, 311, 311, 311, 847, 847, 846,
+	846, 329, 19, 19, 175, 175, 175, 175, 175, 175,
+	175, 170, 170, 690, 690, 691, 691, 302, 302, 302,
+	302, 303, 303, 304, 304, 304, 87, 101, 101, 101,
+	101, 101, 101, 324, 324, 324, 326, 326, 328, 328,
+	325, 325, 325, 325, 325, 325, 325, 325, 325, 325,
+	325, 325, 325, 325, 327, 327, 327, 327, 327, 327,
+	327, 327, 327, 327, 327, 327, 327, 327, 327, 327,
+	327, 327, 88, 88, 88, 88, 88, 88, 88, 88,
+	88, 89, 89, 89, 89, 89, 90, 90, 90, 90,
+	90, 90, 91, 91, 91, 91, 91, 91, 92, 92,
+	99, 99, 99, 99, 99, 99, 99, 99, 99, 279,
+	279, 102, 102, 102, 102, 102, 102, 102, 102, 102,
+	102, 102, 102, 102, 102, 102, 102, 102, 102, 125,
+	125, 125, 118, 118, 118, 127, 127, 127, 128, 128,
+	129, 129, 129, 132, 132, 132, 131, 131, 134, 134,
+	130, 130, 130, 130, 130, 130, 130, 130, 133, 133,
+	133, 133, 133, 117, 117, 117, 117, 117, 849, 849,
+	313, 313, 313, 315, 315, 314, 314, 317, 317, 316,
+	103, 103, 103, 103, 103, 108, 108, 108, 108, 108,
+	22, 22, 22, 124, 124, 124, 157, 157, 157, 782,
+	782, 782, 783, 783, 783, 783, 783, 783, 780, 780,
+	781, 781, 781, 781, 781, 784, 784, 784, 784, 121,
+	121, 121, 121, 122, 122, 787, 787, 788, 788, 808,
+	792, 792, 793, 793, 797, 797, 797, 798, 798, 798,
+	798, 798, 807, 807, 807, 807, 807, 801, 800, 799,
+	796, 796, 802, 802, 803, 803, 805, 805, 805, 805,
+	805, 806, 806, 806, 806, 806, 806, 806, 806, 806,
+	806, 806, 806, 806, 806, 806, 806, 806, 791, 811,
+	812, 812, 813, 813, 814, 814, 814, 817, 817, 169,
+	169, 809, 809, 810, 810, 156, 156, 156, 158, 158,
+	158, 816, 816, 815, 815, 794, 794, 795, 795, 77,
+	804, 804, 850, 850, 78, 79, 80, 81, 82, 83,
+	84, 789, 789, 123, 123, 818, 818, 818, 820, 820,
+	819, 819, 819, 819, 819, 823, 823, 822, 822, 821,
+	830, 830, 824, 824, 825, 825, 826, 826, 851, 851,
+	827, 827, 828, 828, 831, 831, 832, 832, 832, 829,
+	829, 829, 829, 159, 159, 159, 848, 848, 848, 848,
+	848, 848, 848, 848, 848, 848, 848, 848, 848, 848,
+	848, 848, 852, 852, 853, 853, 854, 854, 854, 854,
+	854, 854, 854, 854, 854, 854, 854, 854, 854, 854,
+	854, 854, 854, 106, 106, 106, 106, 106, 106, 106,
+	106, 106, 106, 106, 106, 106, 106, 106, 106, 106,
+	106, 106, 106, 106, 106, 106, 106, 106, 135, 135,
+	485, 485, 448, 448, 136, 136, 136, 137, 137, 138,
+	138, 138, 138, 104, 104, 104, 105, 105, 105, 748,
+	748, 749, 755, 855, 855, 643, 643, 641, 641, 642,
+	143, 143, 502, 502, 502, 537, 537, 536, 534, 534,
+	144, 144, 144, 144, 144, 144, 145, 145, 145, 145,
+	145, 145, 145, 145, 145, 145, 145, 146, 146, 146,
 	146, 146, 146, 146, 146, 146, 146, 146, 146, 146,
-	146, 146, 148, 148, 148, 148, 148, 148, 148, 148,
-	148, 148, 148, 148, 149, 149, 149, 149, 149, 149,
-	149, 149, 149, 610, 610, 5, 5, 325, 325, 324,
-	324, 324, 324, 6, 6, 6, 330, 330, 329, 328,
-	231, 231, 524, 524, 524, 524, 524, 524, 232, 232,
-	233, 233, 233, 233, 145, 145, 145, 570, 570, 151,
-	151, 151, 518, 518, 152, 152, 152, 152, 152, 153,
-	153, 153, 153, 153, 153, 153, 153, 153, 153, 153,
-	153, 175, 175, 175, 175, 175, 175, 175, 175, 175,
-	175, 175, 175, 175, 175, 175, 175, 175, 175, 175,
-	722, 722, 467, 467, 364, 364, 364, 364, 164, 164,
-	164, 164, 165, 165, 165, 165, 166, 166, 255, 255,
-	182, 182, 182, 182, 181, 181, 181, 181, 181, 181,
-	181, 181, 91, 91, 91, 92, 92, 93, 93, 94,
-	94, 95, 95, 96, 96, 96, 96, 96, 185, 185,
-	34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
-	34, 523, 523, 40, 41, 41, 41, 41, 41, 39,
-	39, 39, 39, 39, 37, 37, 37, 37, 37, 186,
-	186, 777, 777, 38, 38, 38, 38, 38, 38, 35,
-	35, 36, 36, 188, 184, 184, 184, 184, 184, 184,
-	184, 183, 183, 187, 187, 187, 187, 189, 191, 191,
-	191, 191, 191, 190, 190, 190, 190, 190, 192, 192,
-	644, 644, 486, 486, 642, 642, 666, 666, 666, 643,
-	643, 423, 423, 423, 423, 423, 424, 424, 424, 653,
-	653, 653, 653, 653, 653, 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, 193, 193,
-	193, 193, 193, 193, 193, 193, 193, 193, 193, 193,
-	193, 193, 193, 193, 193, 193, 193, 193, 193, 256,
-	256, 256, 257, 257, 262, 262, 263, 263, 263, 264,
-	264, 264, 261, 261, 261, 258, 258, 259, 259, 260,
-	260, 260, 260, 260, 260, 260, 260, 260, 260, 267,
-	267, 265, 265, 266, 266, 793, 793, 792, 792, 268,
-	268, 268, 268, 268, 224, 224, 224, 245, 245, 245,
-	245, 245, 245, 245, 245, 245, 245, 245, 245, 245,
-	245, 487, 487, 227, 227, 227, 211, 211, 194, 194,
-	194, 194, 194, 194, 194, 194, 194, 194, 284, 284,
-	284, 284, 284, 287, 287, 287, 289, 289, 288, 288,
-	288, 288, 288, 288, 288, 288, 288, 288, 288, 291,
-	291, 291, 292, 292, 290, 290, 290, 202, 202, 202,
-	202, 202, 202, 202, 202, 203, 203, 203, 195, 195,
-	213, 213, 213, 213, 213, 204, 204, 205, 205, 205,
-	205, 206, 206, 206, 206, 238, 238, 210, 210, 210,
-	212, 212, 212, 212, 212, 212, 212, 212, 212, 196,
-	197, 197, 197, 197, 215, 215, 215, 215, 527, 527,
-	527, 244, 244, 214, 214, 214, 214, 214, 214, 214,
-	214, 214, 214, 214, 214, 214, 214, 214, 214, 214,
-	214, 214, 286, 286, 285, 241, 241, 241, 241, 241,
-	241, 738, 738, 739, 739, 739, 739, 234, 234, 234,
-	234, 234, 234, 586, 586, 225, 225, 225, 225, 230,
-	230, 230, 230, 208, 208, 208, 208, 209, 209, 209,
-	209, 236, 236, 236, 236, 508, 508, 222, 222, 222,
-	223, 223, 223, 228, 228, 243, 229, 454, 454, 226,
-	226, 235, 235, 235, 235, 237, 237, 237, 198, 198,
-	198, 198, 198, 198, 198, 198, 198, 198, 198, 198,
-	198, 199, 199, 200, 200, 200, 200, 201, 201, 201,
-	201, 239, 239, 221, 221, 240, 240, 240, 240, 240,
-	240, 240, 240, 240, 240, 240, 794, 794, 217, 217,
-	217, 216, 216, 216, 216, 216, 216, 216, 216, 775,
-	775, 776, 776, 776, 776, 776, 776, 776, 776, 776,
-	776, 219, 219, 220, 220, 220, 220, 220, 220, 220,
-	218, 207, 207, 242, 720, 720, 716, 716, 716, 716,
-	716, 716, 716, 716, 716, 716, 716, 714, 714, 714,
-	714, 714, 714, 714, 714, 714, 717, 717, 717, 717,
-	717, 721, 721, 156, 156, 156, 156, 156, 156, 156,
-	167, 167, 167, 167, 167, 167, 167, 170, 170, 157,
-	157, 157, 157, 157, 157, 157, 160, 160, 158, 158,
-	158, 158, 159, 159, 112, 112, 112, 112, 112, 18,
-	18, 18, 113, 113, 355, 355, 303, 303, 303, 441,
-	441, 304, 304, 431, 431, 431, 431, 299, 299, 300,
-	300, 301, 302, 302, 114, 114, 795, 795, 795, 731,
-	731, 731, 732, 732, 732, 732, 732, 732, 425, 425,
-	426, 426, 550, 550, 550, 550, 550, 429, 429, 429,
-	430, 430, 430, 430, 430, 430, 430, 430, 430, 439,
-	440, 440, 432, 432, 438, 437, 437, 436, 436, 435,
-	435, 433, 434, 434, 434, 443, 443, 442, 445, 445,
-	444, 549, 675, 675, 677, 677, 677, 677, 677, 677,
-	677, 679, 679, 679, 679, 679, 679, 679, 679, 679,
-	679, 679, 679, 679, 679, 679, 679, 679, 528, 528,
-	796, 796, 797, 798, 673, 673, 673, 673, 673, 674,
-	669, 669, 670, 670, 670, 670, 670, 427, 427, 428,
-	428, 428, 428, 671, 672, 463, 463, 591, 676, 676,
-	678, 678, 680, 799, 799, 799, 799, 799, 799, 800,
-	800, 800, 548, 548, 547, 547, 546, 546, 451, 451,
-	681, 681, 681, 681, 682, 682, 682, 682, 682, 685,
-	684, 683, 683, 683, 683, 683, 117, 117, 117, 505,
-	505, 504, 504, 506, 506, 506, 506, 506, 506, 506,
-	506, 506, 506, 506, 506, 506, 506, 506, 506, 506,
-	506, 251, 251, 367, 367, 367, 109, 109, 109, 15,
-	15, 15, 15, 15, 15, 15, 383, 383, 16, 16,
-	16, 16, 733, 733, 733, 116, 116, 116, 116, 116,
-	116, 449, 449, 449, 366, 366, 366, 366, 366, 366,
-	366, 366, 366, 366, 366, 366, 366, 366, 366, 366,
-	366, 366, 366, 366, 366, 366, 366, 366, 366, 366,
-	366, 366, 724, 724, 723, 723, 368, 368, 802, 802,
-	125, 125, 125, 125, 125, 125, 125, 125, 125, 611,
-	611, 612, 612, 614, 614, 613, 613, 108, 108, 108,
-	108, 108, 529, 529, 526, 526, 525, 525, 462, 462,
-	589, 589, 589, 590, 373, 373, 374, 374, 322, 322,
-	322, 464, 464, 464, 464, 464, 44, 43, 27, 27,
-	31, 31, 32, 32, 354, 354, 354, 354, 354, 354,
-	354, 354, 354, 33, 33, 68, 68, 68, 68, 69,
-	69, 69, 69, 72, 72, 73, 73, 67, 67, 67,
-	67, 70, 70, 63, 63, 74, 74, 74, 74, 74,
-	740, 742, 742, 741, 741, 745, 745, 745, 745, 745,
-	745, 743, 743, 404, 404, 744, 744, 778, 778, 779,
-	779, 163, 163, 168, 168, 168, 168, 168, 169, 169,
-	169, 169, 171, 171, 171, 171, 180, 180, 247, 247,
-	247, 247, 247, 247, 247, 84, 84, 98, 98, 178,
-	804, 804, 804, 179, 179, 179, 248, 248, 248, 248,
-	249, 249, 250, 250, 803, 803, 365, 365, 543, 543,
-	544, 544, 805, 805, 545, 545, 545, 545, 545, 358,
-	357, 359, 359, 360, 360, 105, 105, 105, 344, 344,
-	343, 346, 346, 345, 348, 348, 347, 349, 349, 350,
-	350, 341, 341, 656, 656, 352, 352, 352, 353, 353,
-	337, 337, 338, 338, 339, 339, 340, 340, 356, 356,
-	651, 651, 806, 806, 154, 154, 154, 254, 254, 415,
-	415, 415, 536, 536, 536, 452, 452, 380, 380, 542,
-	542, 542, 542, 542, 499, 499, 499, 253, 253, 473,
-	473, 489, 489, 490, 490, 603, 603, 491, 161, 161,
-	162, 162, 177, 177, 307, 307, 305, 305, 305, 305,
-	305, 305, 305, 305, 312, 312, 313, 313, 314, 314,
-	315, 316, 316, 316, 316, 479, 479, 317, 317, 317,
-	306, 306, 306, 308, 308, 308, 308, 308, 308, 308,
-	311, 311, 311, 311, 318, 318, 318, 310, 310, 692,
-	692, 692, 694, 694, 696, 696, 696, 695, 691, 691,
-	693, 693, 801, 801, 507, 507, 507, 448, 450, 446,
-	446, 447, 447, 458, 458, 459, 459, 455, 456, 457,
-	457, 457, 457, 460, 460, 460, 460, 461, 461, 461,
-	588, 588, 587, 323, 323, 323, 496, 496, 496, 496,
-	497, 497, 532, 532, 530, 530, 530, 530, 531, 531,
-	533, 533, 533, 534, 534, 535, 535, 493, 493, 494,
-	494, 495, 495, 495, 495, 566, 566, 309, 309, 309,
-	470, 470, 470, 471, 471, 556, 556, 556, 556, 556,
-	556, 556, 556, 556, 556, 556, 556, 557, 557, 555,
-	555, 555, 555, 592, 592, 592, 592, 592, 592, 592,
-	592, 592, 593, 594, 594, 472, 472, 595, 539, 539,
-	540, 540, 537, 537, 538, 538, 541, 541, 710, 710,
-	710, 711, 711, 585, 585, 596, 596, 596, 596, 596,
-	596, 581, 581, 582, 582, 583, 583, 584, 584, 604,
-	605, 605, 511, 511, 511, 511, 509, 509, 512, 512,
-	512, 512, 512, 510, 510, 597, 597, 597, 597, 498,
-	498, 252, 252, 598, 598, 598, 598, 599, 600, 600,
-	601, 601, 551, 552, 552, 615, 615, 615, 615, 617,
-	468, 468, 468, 468, 468, 668, 667, 667, 616, 616,
-	616, 616, 616, 616, 616, 631, 631, 631, 631, 631,
-	631, 631, 631, 631, 631, 631, 631, 631, 631, 631,
-	631, 631, 631, 631, 631, 631, 631, 631, 631, 631,
-	631, 631, 631, 631, 631, 631, 631, 632, 632, 632,
-	632, 632, 632, 632, 618, 618, 618, 618, 618, 618,
-	618, 622, 622, 622, 621, 621, 621, 621, 621, 621,
-	621, 621, 621, 621, 621, 623, 623, 628, 628, 629,
-	629, 629, 624, 625, 630, 630, 630, 630, 807, 807,
-	634, 634, 626, 626, 626, 626, 626, 626, 626, 626,
-	626, 620, 620, 620, 627, 627, 627, 520, 520, 520,
-	520, 520, 520, 520, 520, 520, 520, 520, 520, 520,
-	519, 519, 521, 521, 558, 558, 558, 558, 558, 558,
-	558, 558, 558, 558, 558, 558, 558, 558, 558, 558,
-	558, 558, 558, 558, 558, 558, 558, 558, 558, 558,
-	558, 558, 558, 558, 558, 558, 558, 558, 558, 558,
-	558, 558, 558, 558, 558, 558, 558, 558, 558, 558,
-	558, 558, 558, 558, 558, 558, 558, 558, 558, 558,
-	558, 558, 558, 558, 558, 558, 558, 558, 558, 558,
-	558, 558, 558, 558, 558, 558, 558, 558, 558, 558,
-	558, 558, 558, 558, 558, 558, 558, 558, 558, 558,
-	558, 558, 558, 558, 558, 559, 559, 559, 559, 559,
-	559, 559, 559, 559, 559, 559, 559, 559, 559, 559,
-	559, 559, 559, 559, 559, 559, 559, 559, 559, 559,
-	559, 559, 559, 559, 559, 559, 560, 560, 560, 560,
-	561, 561, 561, 561, 561, 561, 561, 561, 561, 561,
-	561, 561, 561, 561, 561, 561, 561, 561, 561, 561,
-	561, 561, 561, 561, 561, 686, 686, 686, 686, 686,
-	686, 686, 686, 372, 372, 562, 562, 689, 689, 690,
-	690, 687, 687, 687, 687, 687, 687, 687, 687, 687,
-	687, 687, 687, 687, 687, 687, 687, 687, 687, 687,
-	687, 687, 687, 687, 688, 688, 688, 688, 688, 688,
-	688, 688, 688, 688, 688, 688, 688, 688, 688, 688,
-	688, 688, 688, 688, 688, 688, 688, 688, 688, 688,
-	688, 688, 688, 688, 688, 688, 688, 688, 688, 688,
-	688, 688, 697, 697, 698, 698, 700, 700, 701, 701,
-	702, 703, 703, 703, 704, 705, 705, 699, 699, 706,
-	706, 706, 706, 707, 707, 708, 708, 708, 708, 708,
-	709, 709, 709, 709, 709, 572, 572, 573, 573, 579,
-	579, 579, 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, 422, 422,
-	421, 369, 369, 369, 369, 369, 369, 484, 484, 482,
-	482, 482, 485, 485, 483, 483, 481, 481, 480, 480,
-	569, 569, 567, 567, 571, 571, 513, 513, 633, 633,
-	633, 633, 633, 633, 633, 633, 514, 514, 514, 522,
-	515, 515, 516, 516, 516, 516, 516, 563, 564, 517,
-	517, 517, 565, 565, 574, 578, 578, 577, 576, 576,
-	575, 575, 553, 553, 554, 554, 492, 492, 808, 808,
-	488, 488, 602, 602, 602, 602, 662, 662, 419, 419,
-	474, 474, 418, 418, 410, 410, 411, 411, 411, 411,
-	466, 466, 580, 580, 635, 635, 636, 636, 637, 637,
-	638, 638, 639, 640, 641, 568, 568, 391, 390, 377,
-	378, 389, 388, 387, 376, 379, 384, 385, 386, 381,
-	382, 398, 397, 396, 342, 342, 351, 351, 403, 405,
-	405, 408, 408, 409, 407, 406, 406, 393, 394, 395,
-	609, 375, 412, 412, 413, 413, 413, 414, 414, 414,
-	414, 370, 370, 370, 371, 371, 399, 399, 400, 401,
-	401, 392, 392, 392, 361, 361, 361, 362, 362, 363,
-	363, 649, 649, 646, 646, 646, 647, 647, 647, 750,
-	648, 648, 648, 648, 645, 645, 645, 645, 645, 657,
-	657, 657, 657, 657, 657, 657, 657, 657, 657, 657,
-	657, 657, 657, 657, 657, 657, 657, 657, 657, 657,
-	657, 657, 657, 657, 657, 657, 657, 657, 657, 657,
-	657, 657, 657, 657, 657, 657, 657, 657, 657, 657,
-	657, 657, 657, 657, 657, 657, 657, 657, 657, 657,
-	657, 657, 657, 657, 657, 657, 657, 657, 657, 657,
-	657, 657, 657, 657, 657, 657, 657, 657, 657, 657,
-	657, 657, 657, 657, 657, 657, 657, 657, 657, 657,
-	657, 657, 657, 657, 657, 657, 657, 657, 657, 657,
-	657, 657, 657, 657, 657, 657, 657, 657, 657, 657,
-	657, 657, 657, 657, 657, 657, 657, 657, 657, 657,
-	657, 657, 657, 657, 657, 657, 657, 657, 657, 657,
-	657, 657, 657, 657, 657, 657, 657, 657, 657, 657,
-	657, 657, 657, 657, 657, 657, 657, 657, 657, 657,
-	657, 657, 657, 657, 657, 657, 657, 657, 657, 657,
-	657, 657, 657, 657, 657, 657, 657, 657, 657, 657,
-	657, 657, 657, 657, 657, 657, 657, 657, 657, 657,
-	657, 657, 657, 657, 657, 657, 657, 657, 657, 657,
-	657, 657, 657, 657, 657, 657, 657, 657, 657, 657,
-	657, 657, 657, 657, 657, 657, 657, 657, 657, 657,
-	657, 657, 657, 657, 657, 657, 657, 657, 657, 657,
-	657, 657, 657, 657, 657, 657, 657, 657, 657, 657,
-	657, 657, 657, 657, 657, 657, 657, 657, 657, 657,
-	657, 657, 657, 657, 657, 657, 657, 657, 657, 657,
-	657, 657, 657, 657, 657, 657, 657, 657, 657, 657,
-	657, 657, 657, 657, 657, 657, 657, 657, 657, 657,
-	657, 657, 657, 657, 657, 657, 657, 657, 657, 657,
-	657, 657, 657, 657, 657, 657, 657, 657, 657, 657,
-	657, 657, 657, 657, 657, 657, 657, 657, 657, 657,
-	657, 657, 657, 657, 657, 657, 657, 657, 657, 657,
-	657, 657, 657, 657, 657, 657, 657, 657, 657, 657,
-	657, 657, 657, 657, 657, 657, 657, 657, 657, 657,
-	657, 657, 657, 657, 657, 657, 657, 657, 657, 657,
-	657, 657, 657, 657, 657, 657, 657, 657, 657, 657,
-	657, 657, 657, 657, 657, 657, 657, 657, 657, 657,
-	657, 657, 657, 657, 657, 657, 657, 657, 657, 657,
-	657, 657, 657, 657, 657, 657, 657, 657, 657, 657,
-	657, 657, 657, 657, 657, 657, 657, 657, 657, 657,
-	657, 657, 657, 657, 657, 657, 657, 657, 657, 657,
-	657, 657, 657, 657, 657, 657, 657, 657, 657, 657,
-	657, 657, 657, 657, 657, 657, 657, 657, 657, 657,
-	657, 657, 657, 657, 657, 657, 657, 657, 657, 657,
-	657, 657, 657, 657, 657, 657, 657, 657, 657, 657,
-	657, 657, 657, 657, 657, 657, 657, 657, 657, 657,
-	657, 657, 657, 657, 657, 657, 657, 657, 657, 657,
-	657, 657, 657, 657, 657, 657, 657, 657, 657, 661,
-	661, 661, 661, 661, 661, 661, 661, 661, 661, 661,
-	661, 661, 661, 661, 661, 661, 661, 661, 661, 661,
-	661, 661, 661, 661, 661, 661, 661, 661, 661, 661,
-	661, 661, 661, 661, 661, 661, 661, 661, 661, 661,
-	661, 661, 661, 661, 661, 661, 661, 661, 661, 661,
-	661, 661, 661, 661, 661, 661, 661, 661, 661, 661,
-	661, 661, 661, 661, 661, 661, 661, 661, 661, 661,
-	661, 661, 661, 661, 661, 661, 661, 661, 661, 661,
-	661, 661, 661, 661, 661, 661, 661, 661, 661, 661,
-	661, 661, 661, 661, 661, 661, 661, 661, 661, 661,
-	661, 661, 661, 661, 661, 661, 661, 661, 661, 661,
-	661, 661, 661, 661, 661, 661, 661, 661, 661, 661,
-	661, 661, 661, 661, 661, 661, 661, 661, 661, 661,
-	661, 661, 661, 661, 661, 661, 661, 661, 661, 661,
-	661, 661, 661, 661, 661, 661, 661, 661, 661, 661,
-	661, 661, 661, 661, 661, 661, 661, 661, 661, 661,
-	661, 661, 661, 661, 661, 661, 661, 661, 661, 661,
-	661, 661, 661, 661, 661, 661, 661, 661, 661, 661,
-	661, 661, 661, 661, 661, 661, 661, 661, 661, 661,
-	661, 661, 661, 661, 661, 661, 661, 661, 661, 661,
-	661, 661, 661, 661, 661, 661, 661, 661, 661, 661,
-	661, 661, 661, 661, 661, 661, 661, 661, 661, 661,
-	661, 661, 661, 661, 661, 661, 661, 661, 661, 661,
-	661, 661, 661, 661, 661, 661, 661, 661, 661, 661,
-	661, 661, 661, 661, 661, 661, 661, 661, 661, 661,
-	661, 661, 661, 661, 661, 661, 661, 661, 661, 661,
-	661, 661, 661, 661, 661, 661, 661, 661, 661, 661,
-	661, 661, 661, 661, 661, 661, 661, 661, 661, 661,
-	661, 661, 661, 661, 661, 661, 661, 661, 661, 661,
-	661, 661, 661, 661, 661, 661, 661, 661, 661, 661,
-	661, 661, 661, 661, 661, 661, 661, 661, 661, 661,
-	661, 661, 661, 661, 661, 661, 661, 661, 661, 661,
-	661, 661, 661, 661, 661, 661, 661, 661, 661, 661,
-	661, 661, 661, 661, 661, 661, 661, 661, 661, 661,
-	661, 661, 661, 661, 661, 661, 661, 661, 661, 661,
-	661, 661, 661, 661, 661, 661, 661, 661, 661, 661,
-	661, 661, 661, 661, 661, 661, 661, 661, 661, 661,
-	661, 661, 661, 661, 661, 661, 661, 661, 661, 661,
-	661, 661, 661, 661, 661, 661, 661, 661, 661, 661,
-	661, 661, 661, 661, 661, 661, 661, 661, 661, 661,
-	661, 661, 661, 661, 661, 661, 661, 661, 661, 661,
-	661, 661, 661, 661, 661, 661, 661, 661, 661, 661,
-	661, 661, 661, 661, 661, 661, 661, 661, 661, 661,
-	661, 661, 661, 661, 661, 661, 661, 661, 661, 661,
-	661, 661, 661, 661, 661, 661, 661, 661, 661, 661,
-	661, 661, 661, 661, 661, 661, 661, 661, 661, 661,
-	661, 661, 661, 661, 661, 661, 661, 661, 661, 661,
-	661, 661, 661, 661, 661, 661, 661, 661, 661, 661,
-	661, 661, 661, 661, 661, 661, 661, 661, 661, 661,
-	661, 661, 661, 661, 661, 661, 661, 661, 661, 661,
-	661, 661, 661, 661, 661, 661, 661, 661, 661, 661,
-	661, 661, 661, 661, 661, 661, 661, 661, 661, 661,
-	661, 661, 661, 661, 661, 661, 661, 661, 661, 661,
-	661, 661, 661, 661, 661, 661, 661, 661, 661, 661,
-	661, 661, 661, 661, 661, 661, 661, 661, 661, 661,
-	661, 661, 661, 661, 661, 661, 661, 661, 661, 661,
-	661, 661, 661, 661, 661, 661, 661, 661, 661, 661,
-	661, 661, 661, 661, 661, 663, 663, 663, 663, 663,
-	663, 663, 663, 663, 663, 663, 663, 663, 663, 663,
-	663, 663, 663, 663, 663, 663, 663, 663, 663, 663,
-	663, 663, 663, 663, 663, 663, 663, 663, 663, 663,
-	663, 663, 663, 663, 663, 663, 663, 663, 663, 663,
-	663, 663, 663, 663, 663, 663, 663, 663, 663, 658,
-	658, 659, 659, 659, 659, 659, 659, 659, 659, 659,
-	659, 659, 659, 659, 659, 659, 659, 659, 659, 660,
-	664, 664, 664, 664, 664, 664, 664, 664, 664, 664,
-	664, 664, 664, 664, 664, 664, 664, 664, 664, 664,
-	664, 664, 664, 664, 664, 664, 664, 664, 664, 664,
-	664, 664, 664, 664, 664, 664, 664, 664, 664, 664,
-	664, 664, 664, 664, 664, 664, 664, 664, 664, 664,
-	664, 664, 664, 664, 664, 664, 664, 664, 664, 664,
-	664, 664, 664, 664, 664, 664, 664, 664, 664, 664,
-	664, 664, 664, 664, 664, 664, 664, 664, 664, 664,
-	665, 665, 665, 665,
+	146, 146, 146, 146, 146, 146, 146, 146, 146, 154,
+	154, 154, 154, 154, 155, 155, 155, 152, 152, 152,
+	149, 149, 149, 147, 147, 147, 153, 153, 153, 160,
+	160, 160, 161, 161, 754, 434, 434, 151, 151, 151,
+	150, 150, 150, 508, 508, 509, 511, 510, 162, 162,
+	162, 162, 449, 163, 163, 163, 163, 163, 163, 163,
+	163, 166, 166, 166, 166, 166, 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, 167, 167,
+	167, 167, 167, 167, 167, 167, 167, 167, 167, 167,
+	168, 168, 168, 168, 168, 168, 168, 168, 168, 645,
+	645, 180, 180, 5, 5, 356, 356, 355, 355, 355,
+	355, 6, 6, 6, 361, 361, 360, 359, 259, 259,
+	560, 560, 560, 560, 560, 560, 260, 260, 261, 261,
+	261, 261, 261, 261, 273, 273, 274, 274, 275, 164,
+	164, 164, 605, 605, 171, 171, 171, 554, 554, 172,
+	172, 172, 172, 172, 173, 173, 173, 173, 173, 173,
+	173, 173, 173, 173, 173, 173, 195, 195, 195, 195,
+	195, 195, 195, 195, 195, 195, 195, 195, 195, 195,
+	195, 195, 195, 195, 195, 758, 758, 500, 500, 395,
+	395, 395, 395, 185, 185, 185, 185, 186, 186, 186,
+	186, 187, 187, 288, 288, 205, 205, 205, 205, 204,
+	204, 204, 204, 204, 204, 204, 204, 93, 93, 93,
+	94, 94, 95, 95, 96, 96, 97, 97, 98, 98,
+	98, 98, 98, 208, 208, 35, 35, 35, 35, 35,
+	35, 35, 35, 35, 35, 35, 35, 35, 559, 559,
+	42, 41, 43, 43, 43, 43, 43, 40, 40, 40,
+	40, 40, 40, 40, 38, 38, 38, 38, 38, 209,
+	209, 836, 836, 39, 39, 39, 39, 39, 39, 36,
+	36, 37, 37, 211, 207, 207, 207, 207, 207, 207,
+	207, 206, 206, 210, 210, 210, 210, 212, 214, 214,
+	214, 214, 214, 213, 213, 213, 213, 213, 215, 215,
+	680, 680, 519, 519, 678, 678, 702, 702, 702, 679,
+	679, 455, 455, 455, 455, 455, 456, 456, 456, 689,
+	689, 689, 689, 689, 689, 216, 216, 216, 216, 216,
+	216, 216, 216, 216, 216, 216, 216, 216, 216, 216,
+	216, 216, 216, 216, 216, 216, 216, 216, 216, 216,
+	216, 216, 216, 216, 216, 216, 216, 216, 216, 216,
+	216, 216, 216, 216, 216, 216, 216, 216, 216, 216,
+	216, 216, 216, 216, 216, 216, 216, 216, 216, 216,
+	216, 216, 216, 216, 216, 216, 216, 216, 216, 216,
+	216, 216, 216, 216, 216, 216, 216, 216, 216, 216,
+	216, 216, 216, 216, 216, 216, 216, 216, 216, 216,
+	216, 216, 216, 216, 216, 216, 216, 216, 216, 289,
+	289, 289, 290, 290, 295, 295, 296, 296, 296, 297,
+	297, 297, 294, 294, 294, 291, 291, 292, 292, 293,
+	293, 293, 293, 293, 293, 293, 293, 293, 293, 300,
+	300, 298, 298, 299, 299, 857, 857, 856, 856, 301,
+	301, 301, 301, 301, 252, 252, 252, 278, 278, 278,
+	278, 278, 278, 278, 278, 278, 278, 278, 278, 278,
+	278, 520, 520, 255, 255, 255, 239, 239, 217, 217,
+	217, 217, 217, 217, 217, 217, 217, 217, 318, 318,
+	318, 318, 318, 321, 321, 321, 323, 323, 322, 322,
+	322, 322, 322, 322, 322, 322, 322, 322, 226, 226,
+	226, 226, 226, 226, 226, 226, 227, 227, 227, 218,
+	218, 241, 241, 241, 241, 241, 228, 228, 229, 229,
+	229, 229, 230, 230, 230, 230, 231, 231, 231, 231,
+	266, 266, 238, 238, 238, 240, 240, 240, 240, 240,
+	240, 240, 240, 240, 219, 220, 220, 220, 220, 221,
+	221, 221, 243, 243, 243, 243, 563, 563, 563, 277,
+	277, 242, 242, 242, 242, 242, 242, 242, 242, 242,
+	242, 242, 242, 242, 242, 242, 242, 242, 242, 242,
+	320, 320, 319, 270, 270, 270, 270, 270, 270, 774,
+	774, 775, 775, 775, 775, 262, 262, 262, 262, 262,
+	262, 621, 621, 253, 253, 253, 253, 258, 258, 258,
+	258, 236, 236, 236, 236, 237, 237, 237, 237, 264,
+	264, 264, 264, 544, 544, 250, 250, 250, 251, 251,
+	251, 256, 256, 272, 276, 276, 257, 486, 486, 254,
+	254, 263, 263, 263, 263, 265, 265, 265, 222, 222,
+	222, 222, 222, 222, 222, 222, 222, 222, 222, 222,
+	222, 222, 223, 223, 223, 224, 224, 224, 224, 225,
+	225, 225, 225, 267, 267, 268, 268, 268, 268, 249,
+	249, 269, 269, 269, 269, 269, 269, 269, 269, 269,
+	269, 269, 858, 858, 245, 245, 245, 244, 244, 244,
+	244, 244, 244, 244, 244, 834, 834, 835, 835, 835,
+	835, 835, 835, 835, 835, 835, 835, 247, 247, 248,
+	248, 248, 248, 248, 248, 248, 246, 232, 232, 233,
+	233, 233, 234, 234, 235, 235, 271, 756, 756, 752,
+	752, 752, 752, 752, 752, 752, 752, 752, 752, 752,
+	750, 750, 750, 750, 750, 750, 750, 750, 750, 753,
+	753, 753, 753, 753, 757, 757, 176, 176, 176, 176,
+	176, 176, 176, 188, 188, 188, 188, 188, 188, 188,
+	191, 191, 177, 177, 177, 177, 177, 177, 177, 181,
+	181, 178, 178, 178, 178, 179, 179, 114, 114, 114,
+	114, 114, 18, 18, 18, 115, 115, 386, 386, 334,
+	334, 334, 473, 473, 335, 335, 463, 463, 463, 463,
+	330, 330, 331, 331, 332, 333, 333, 116, 116, 859,
+	859, 859, 767, 767, 767, 768, 768, 768, 768, 768,
+	768, 457, 457, 458, 458, 585, 585, 585, 585, 585,
+	461, 461, 461, 462, 462, 462, 462, 462, 462, 462,
+	462, 462, 471, 472, 472, 464, 464, 470, 469, 469,
+	468, 468, 467, 467, 465, 466, 466, 466, 475, 475,
+	474, 477, 477, 476, 584, 711, 711, 713, 713, 713,
+	713, 713, 713, 713, 715, 715, 715, 715, 715, 715,
+	715, 715, 715, 715, 715, 715, 715, 715, 715, 715,
+	715, 564, 564, 860, 860, 840, 841, 838, 839, 709,
+	709, 709, 709, 709, 709, 709, 710, 705, 705, 706,
+	706, 706, 706, 706, 459, 459, 460, 460, 460, 460,
+	707, 708, 495, 495, 626, 712, 712, 714, 714, 716,
+	861, 861, 861, 861, 861, 861, 862, 862, 862, 583,
+	583, 582, 582, 581, 581, 483, 483, 717, 717, 717,
+	717, 718, 718, 718, 718, 718, 721, 720, 719, 719,
+	719, 719, 719, 120, 120, 120, 539, 539, 538, 538,
+	540, 540, 540, 540, 540, 540, 540, 540, 540, 540,
+	540, 540, 540, 540, 540, 540, 540, 540, 540, 284,
+	284, 398, 398, 398, 111, 111, 111, 15, 15, 15,
+	15, 15, 15, 15, 415, 415, 16, 16, 16, 16,
+	769, 769, 769, 119, 119, 119, 119, 119, 119, 481,
+	481, 481, 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, 760, 760, 759, 759, 399, 399, 400,
+	400, 864, 864, 142, 142, 142, 142, 142, 142, 142,
+	142, 142, 646, 646, 647, 647, 649, 649, 648, 648,
+	110, 110, 110, 110, 110, 110, 110, 498, 498, 562,
+	562, 561, 561, 494, 494, 624, 624, 624, 625, 405,
+	405, 406, 406, 353, 353, 353, 496, 496, 496, 496,
+	496, 46, 45, 28, 28, 32, 32, 33, 33, 385,
+	385, 385, 385, 385, 385, 385, 385, 385, 34, 34,
+	70, 70, 70, 70, 71, 71, 71, 71, 74, 74,
+	75, 75, 69, 69, 69, 69, 72, 72, 65, 65,
+	76, 76, 76, 76, 76, 776, 778, 778, 777, 777,
+	786, 786, 786, 786, 786, 786, 779, 779, 436, 436,
+	785, 785, 837, 837, 842, 842, 184, 184, 189, 189,
+	189, 189, 189, 190, 190, 190, 190, 192, 192, 192,
+	192, 200, 200, 280, 280, 280, 280, 280, 280, 280,
+	280, 280, 280, 280, 280, 280, 86, 86, 100, 100,
+	198, 866, 866, 866, 199, 199, 199, 281, 281, 281,
+	281, 282, 282, 283, 283, 865, 865, 396, 396, 578,
+	578, 579, 579, 867, 867, 580, 580, 580, 580, 580,
+	389, 388, 390, 390, 391, 391, 201, 202, 203, 107,
+	107, 107, 375, 375, 374, 377, 377, 376, 379, 379,
+	378, 380, 380, 381, 381, 372, 372, 692, 692, 383,
+	383, 383, 384, 384, 368, 368, 369, 369, 370, 370,
+	371, 371, 387, 387, 687, 687, 868, 868, 174, 174,
+	174, 287, 287, 447, 447, 447, 571, 571, 571, 484,
+	484, 412, 412, 577, 577, 577, 577, 577, 533, 533,
+	533, 286, 286, 506, 506, 523, 523, 524, 524, 638,
+	638, 525, 182, 182, 183, 183, 197, 197, 338, 338,
+	336, 336, 336, 336, 336, 336, 336, 336, 343, 343,
+	344, 344, 345, 345, 346, 347, 347, 347, 347, 512,
+	512, 348, 348, 348, 337, 337, 337, 339, 339, 339,
+	339, 339, 339, 339, 342, 342, 342, 349, 349, 349,
+	341, 341, 728, 728, 728, 730, 730, 732, 732, 732,
+	731, 727, 727, 729, 729, 863, 863, 543, 543, 543,
+	480, 482, 478, 478, 479, 479, 490, 490, 491, 491,
+	487, 488, 489, 489, 489, 489, 492, 492, 492, 492,
+	493, 493, 493, 623, 623, 622, 354, 354, 354, 530,
+	530, 530, 530, 531, 531, 567, 567, 565, 565, 565,
+	565, 566, 566, 568, 568, 568, 569, 569, 570, 570,
+	527, 527, 528, 528, 529, 529, 529, 529, 601, 601,
+	340, 340, 340, 503, 503, 503, 504, 504, 591, 591,
+	591, 591, 591, 591, 591, 591, 591, 591, 591, 591,
+	591, 591, 592, 592, 590, 590, 590, 590, 627, 627,
+	627, 627, 627, 627, 627, 627, 627, 628, 629, 629,
+	505, 505, 630, 574, 574, 575, 575, 572, 572, 573,
+	573, 576, 576, 746, 746, 746, 747, 747, 620, 620,
+	631, 631, 631, 631, 631, 631, 616, 616, 617, 617,
+	618, 618, 619, 619, 639, 640, 640, 547, 547, 547,
+	547, 545, 545, 548, 548, 548, 548, 548, 548, 546,
+	546, 632, 632, 632, 632, 532, 532, 285, 285, 633,
+	633, 633, 633, 634, 635, 635, 636, 636, 586, 587,
+	587, 650, 650, 650, 650, 652, 501, 501, 501, 501,
+	501, 704, 703, 703, 651, 651, 651, 651, 651, 651,
+	651, 666, 666, 666, 666, 666, 666, 666, 666, 666,
+	666, 666, 666, 666, 666, 666, 666, 666, 666, 666,
+	666, 666, 666, 666, 666, 666, 666, 666, 666, 666,
+	666, 666, 666, 667, 667, 667, 667, 667, 667, 667,
+	668, 668, 653, 653, 653, 653, 653, 653, 653, 653,
+	657, 657, 657, 656, 656, 656, 656, 656, 656, 656,
+	656, 656, 656, 656, 658, 658, 663, 663, 664, 664,
+	664, 659, 660, 665, 665, 665, 665, 869, 869, 670,
+	670, 661, 661, 661, 661, 661, 661, 661, 661, 661,
+	655, 655, 655, 662, 662, 662, 556, 556, 556, 556,
+	556, 556, 556, 556, 556, 556, 556, 556, 556, 555,
+	555, 557, 557, 593, 593, 593, 593, 593, 593, 593,
+	593, 593, 593, 593, 593, 593, 593, 593, 593, 593,
+	593, 593, 593, 593, 593, 593, 593, 593, 593, 593,
+	593, 593, 593, 593, 593, 593, 593, 593, 593, 593,
+	593, 593, 593, 593, 593, 593, 593, 593, 593, 593,
+	593, 593, 593, 593, 593, 593, 593, 593, 593, 593,
+	593, 593, 593, 593, 593, 593, 593, 593, 593, 593,
+	593, 593, 593, 593, 593, 593, 593, 593, 593, 593,
+	593, 593, 593, 593, 593, 593, 593, 593, 593, 593,
+	593, 593, 593, 593, 593, 593, 593, 594, 594, 594,
+	594, 594, 594, 594, 594, 594, 594, 594, 594, 594,
+	594, 594, 594, 594, 594, 594, 594, 594, 594, 594,
+	594, 594, 594, 594, 594, 594, 594, 594, 595, 595,
+	595, 595, 596, 596, 596, 596, 596, 596, 596, 596,
+	596, 596, 596, 596, 596, 596, 596, 596, 596, 596,
+	596, 596, 596, 596, 596, 596, 596, 722, 722, 722,
+	722, 722, 722, 722, 722, 404, 404, 597, 597, 725,
+	725, 726, 726, 723, 723, 723, 723, 723, 723, 723,
+	723, 723, 723, 723, 723, 723, 723, 723, 723, 723,
+	723, 723, 723, 723, 723, 723, 724, 724, 724, 724,
+	724, 724, 724, 724, 724, 724, 724, 724, 724, 724,
+	724, 724, 724, 724, 724, 724, 724, 724, 724, 724,
+	724, 724, 724, 724, 724, 724, 724, 724, 724, 724,
+	724, 724, 724, 724, 733, 733, 734, 734, 736, 736,
+	737, 737, 738, 739, 739, 739, 740, 741, 741, 735,
+	735, 742, 742, 742, 742, 743, 743, 744, 744, 744,
+	744, 744, 745, 745, 745, 745, 745, 607, 607, 608,
+	608, 614, 614, 614, 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,
+	452, 452, 452, 454, 454, 453, 401, 401, 401, 401,
+	401, 401, 517, 517, 515, 515, 515, 518, 518, 516,
+	516, 514, 514, 513, 513, 604, 604, 602, 602, 606,
+	606, 549, 549, 669, 669, 669, 669, 669, 669, 669,
+	669, 550, 550, 550, 558, 551, 551, 552, 552, 552,
+	552, 552, 598, 599, 553, 553, 553, 600, 600, 609,
+	613, 613, 612, 611, 611, 610, 610, 588, 588, 589,
+	589, 526, 526, 870, 870, 522, 522, 521, 521, 637,
+	637, 637, 637, 698, 698, 451, 451, 507, 507, 450,
+	450, 442, 442, 443, 443, 443, 443, 499, 499, 615,
+	615, 671, 671, 672, 672, 673, 673, 674, 674, 675,
+	676, 677, 603, 603, 423, 422, 409, 410, 421, 420,
+	419, 408, 411, 416, 417, 418, 413, 414, 430, 429,
+	428, 373, 373, 382, 382, 435, 437, 437, 440, 440,
+	441, 439, 438, 438, 425, 426, 427, 644, 407, 444,
+	444, 445, 445, 445, 446, 446, 446, 446, 402, 402,
+	402, 403, 403, 431, 431, 432, 433, 433, 424, 424,
+	424, 392, 392, 392, 393, 393, 394, 394, 685, 685,
+	682, 682, 682, 683, 683, 683, 790, 684, 684, 684,
+	684, 681, 681, 681, 681, 681, 693, 693, 693, 693,
+	693, 693, 693, 693, 693, 693, 693, 693, 693, 693,
+	693, 693, 693, 693, 693, 693, 693, 693, 693, 693,
+	693, 693, 693, 693, 693, 693, 693, 693, 693, 693,
+	693, 693, 693, 693, 693, 693, 693, 693, 693, 693,
+	693, 693, 693, 693, 693, 693, 693, 693, 693, 693,
+	693, 693, 693, 693, 693, 693, 693, 693, 693, 693,
+	693, 693, 693, 693, 693, 693, 693, 693, 693, 693,
+	693, 693, 693, 693, 693, 693, 693, 693, 693, 693,
+	693, 693, 693, 693, 693, 693, 693, 693, 693, 693,
+	693, 693, 693, 693, 693, 693, 693, 693, 693, 693,
+	693, 693, 693, 693, 693, 693, 693, 693, 693, 693,
+	693, 693, 693, 693, 693, 693, 693, 693, 693, 693,
+	693, 693, 693, 693, 693, 693, 693, 693, 693, 693,
+	693, 693, 693, 693, 693, 693, 693, 693, 693, 693,
+	693, 693, 693, 693, 693, 693, 693, 693, 693, 693,
+	693, 693, 693, 693, 693, 693, 693, 693, 693, 693,
+	693, 693, 693, 693, 693, 693, 693, 693, 693, 693,
+	693, 693, 693, 693, 693, 693, 693, 693, 693, 693,
+	693, 693, 693, 693, 693, 693, 693, 693, 693, 693,
+	693, 693, 693, 693, 693, 693, 693, 693, 693, 693,
+	693, 693, 693, 693, 693, 693, 693, 693, 693, 693,
+	693, 693, 693, 693, 693, 693, 693, 693, 693, 693,
+	693, 693, 693, 693, 693, 693, 693, 693, 693, 693,
+	693, 693, 693, 693, 693, 693, 693, 693, 693, 693,
+	693, 693, 693, 693, 693, 693, 693, 693, 693, 693,
+	693, 693, 693, 693, 693, 693, 693, 693, 693, 693,
+	693, 693, 693, 693, 693, 693, 693, 693, 693, 693,
+	693, 693, 693, 693, 693, 693, 693, 693, 693, 693,
+	693, 693, 693, 693, 693, 693, 693, 693, 693, 693,
+	693, 693, 693, 693, 693, 693, 693, 693, 693, 693,
+	693, 693, 693, 693, 693, 693, 693, 693, 693, 693,
+	693, 693, 693, 693, 693, 693, 693, 693, 693, 693,
+	693, 693, 693, 693, 693, 693, 693, 693, 693, 693,
+	693, 693, 693, 693, 693, 693, 693, 693, 693, 693,
+	693, 693, 693, 693, 693, 693, 693, 693, 693, 693,
+	693, 693, 693, 693, 693, 693, 693, 693, 693, 693,
+	693, 693, 693, 693, 693, 693, 693, 693, 693, 693,
+	693, 693, 693, 693, 693, 693, 693, 693, 693, 693,
+	693, 693, 693, 693, 693, 693, 693, 693, 693, 693,
+	693, 693, 693, 693, 693, 693, 693, 693, 693, 693,
+	693, 693, 693, 693, 693, 693, 693, 693, 693, 693,
+	693, 693, 693, 693, 693, 693, 693, 693, 693, 693,
+	693, 693, 693, 693, 693, 693, 693, 693, 693, 693,
+	693, 693, 693, 693, 693, 693, 693, 693, 693, 693,
+	693, 693, 693, 693, 693, 693, 693, 693, 693, 693,
+	693, 693, 693, 693, 693, 693, 693, 693, 693, 693,
+	693, 693, 693, 693, 693, 693, 693, 693, 693, 693,
+	693, 693, 693, 693, 693, 693, 693, 693, 693, 693,
+	693, 693, 693, 693, 693, 697, 697, 697, 697, 697,
+	697, 697, 697, 697, 697, 697, 697, 697, 697, 697,
+	697, 697, 697, 697, 697, 697, 697, 697, 697, 697,
+	697, 697, 697, 697, 697, 697, 697, 697, 697, 697,
+	697, 697, 697, 697, 697, 697, 697, 697, 697, 697,
+	697, 697, 697, 697, 697, 697, 697, 697, 697, 697,
+	697, 697, 697, 697, 697, 697, 697, 697, 697, 697,
+	697, 697, 697, 697, 697, 697, 697, 697, 697, 697,
+	697, 697, 697, 697, 697, 697, 697, 697, 697, 697,
+	697, 697, 697, 697, 697, 697, 697, 697, 697, 697,
+	697, 697, 697, 697, 697, 697, 697, 697, 697, 697,
+	697, 697, 697, 697, 697, 697, 697, 697, 697, 697,
+	697, 697, 697, 697, 697, 697, 697, 697, 697, 697,
+	697, 697, 697, 697, 697, 697, 697, 697, 697, 697,
+	697, 697, 697, 697, 697, 697, 697, 697, 697, 697,
+	697, 697, 697, 697, 697, 697, 697, 697, 697, 697,
+	697, 697, 697, 697, 697, 697, 697, 697, 697, 697,
+	697, 697, 697, 697, 697, 697, 697, 697, 697, 697,
+	697, 697, 697, 697, 697, 697, 697, 697, 697, 697,
+	697, 697, 697, 697, 697, 697, 697, 697, 697, 697,
+	697, 697, 697, 697, 697, 697, 697, 697, 697, 697,
+	697, 697, 697, 697, 697, 697, 697, 697, 697, 697,
+	697, 697, 697, 697, 697, 697, 697, 697, 697, 697,
+	697, 697, 697, 697, 697, 697, 697, 697, 697, 697,
+	697, 697, 697, 697, 697, 697, 697, 697, 697, 697,
+	697, 697, 697, 697, 697, 697, 697, 697, 697, 697,
+	697, 697, 697, 697, 697, 697, 697, 697, 697, 697,
+	697, 697, 697, 697, 697, 697, 697, 697, 697, 697,
+	697, 697, 697, 697, 697, 697, 697, 697, 697, 697,
+	697, 697, 697, 697, 697, 697, 697, 697, 697, 697,
+	697, 697, 697, 697, 697, 697, 697, 697, 697, 697,
+	697, 697, 697, 697, 697, 697, 697, 697, 697, 697,
+	697, 697, 697, 697, 697, 697, 697, 697, 697, 697,
+	697, 697, 697, 697, 697, 697, 697, 697, 697, 697,
+	697, 697, 697, 697, 697, 697, 697, 697, 697, 697,
+	697, 697, 697, 697, 697, 697, 697, 697, 697, 697,
+	697, 697, 697, 697, 697, 697, 697, 697, 697, 697,
+	697, 697, 697, 697, 697, 697, 697, 697, 697, 697,
+	697, 697, 697, 697, 697, 697, 697, 697, 697, 697,
+	697, 697, 697, 697, 697, 697, 697, 697, 697, 697,
+	697, 697, 697, 697, 697, 697, 697, 697, 697, 697,
+	697, 697, 697, 697, 697, 697, 697, 697, 697, 697,
+	697, 697, 697, 697, 697, 697, 697, 697, 697, 697,
+	697, 697, 697, 697, 697, 697, 697, 697, 697, 697,
+	697, 697, 697, 697, 697, 697, 697, 697, 697, 697,
+	697, 697, 697, 697, 697, 697, 697, 697, 697, 697,
+	697, 697, 697, 697, 697, 697, 697, 697, 697, 697,
+	697, 697, 697, 697, 697, 697, 697, 697, 697, 697,
+	697, 697, 697, 697, 697, 697, 697, 697, 697, 697,
+	697, 697, 697, 697, 697, 697, 697, 697, 697, 697,
+	697, 697, 697, 697, 697, 697, 697, 697, 697, 697,
+	697, 697, 697, 697, 697, 697, 697, 697, 697, 697,
+	697, 697, 697, 697, 697, 697, 697, 697, 697, 697,
+	697, 697, 697, 697, 697, 697, 697, 697, 697, 697,
+	697, 697, 697, 697, 697, 697, 697, 697, 697, 697,
+	697, 697, 697, 697, 697, 697, 697, 697, 697, 697,
+	697, 697, 697, 697, 697, 697, 697, 697, 697, 697,
+	697, 697, 697, 697, 697, 697, 697, 697, 697, 697,
+	697, 697, 697, 697, 697, 697, 697, 697, 697, 697,
+	697, 697, 697, 697, 697, 697, 697, 697, 697, 697,
+	697, 697, 697, 697, 697, 697, 697, 697, 697, 697,
+	697, 699, 699, 699, 699, 699, 699, 699, 699, 699,
+	699, 699, 699, 699, 699, 699, 699, 699, 699, 699,
+	699, 699, 699, 699, 699, 699, 699, 699, 699, 699,
+	699, 699, 699, 699, 699, 699, 699, 699, 699, 699,
+	699, 699, 699, 699, 699, 699, 699, 699, 699, 699,
+	699, 699, 699, 699, 699, 699, 694, 694, 695, 695,
+	695, 695, 695, 695, 695, 695, 695, 695, 695, 695,
+	695, 695, 695, 695, 695, 695, 696, 700, 700, 700,
+	700, 700, 700, 700, 700, 700, 700, 700, 700, 700,
+	700, 700, 700, 700, 700, 700, 700, 700, 700, 700,
+	700, 700, 700, 700, 700, 700, 700, 700, 700, 700,
+	700, 700, 700, 700, 700, 700, 700, 700, 700, 700,
+	700, 700, 700, 700, 700, 700, 700, 700, 700, 700,
+	700, 700, 700, 700, 700, 700, 700, 700, 700, 700,
+	700, 700, 700, 700, 700, 700, 700, 700, 700, 700,
+	700, 700, 700, 700, 700, 700, 700, 701, 701, 701,
+	701,
 }
 
 var sqlR2 = [...]int8{
 	0, 1, 1, 1, 1, 0, 1, 1, 2, 1,
 	1, 1, 1, 2, 1, 2, 1, 2, 1, 2,
 	1, 2, 1, 2, 1, 2, 1, 2, 1, 2,
-	1, 2, 1, 2, 1, 1, 1, 2, 1, 2,
-	1, 2, 1, 2, 1, 1, 1, 2, 1, 1,
-	2, 1, 1, 2, 1, 2, 1, 2, 1, 2,
+	1, 2, 1, 2, 1, 2, 1, 1, 1, 2,
+	1, 2, 1, 2, 1, 2, 1, 1, 1, 2,
+	1, 1, 2, 1, 1, 2, 1, 2, 1, 2,
+	1, 2, 1, 2, 1, 2, 1, 2, 1, 2,
 	1, 2, 1, 2, 1, 2, 1, 2, 1, 2,
 	1, 2, 1, 2, 1, 2, 1, 2, 1, 2,
-	1, 2, 1, 2, 1, 1, 1, 1, 1, 1,
-	1, 1, 1, 1, 3, 1, 3, 1, 1, 1,
-	3, 1, 1, 1, 1, 3, 4, 6, 1, 1,
 	1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
-	1, 1, 1, 1, 1, 1, 1, 1, 1, 3,
-	1, 1, 1, 3, 3, 6, 4, 4, 6, 9,
-	6, 8, 4, 4, 5, 9, 7, 9, 5, 6,
-	8, 7, 7, 9, 1, 1, 3, 1, 1, 1,
-	1, 1, 1, 1, 1, 3, 4, 6, 4, 6,
-	6, 9, 6, 9, 6, 5, 6, 5, 1, 1,
-	1, 1, 1, 1, 0, 1, 6, 6, 4, 6,
-	2, 1, 1, 2, 4, 8, 7, 10, 9, 4,
-	4, 4, 3, 4, 4, 4, 7, 7, 9, 8,
-	9, 5, 3, 5, 7, 4, 12, 4, 12, 1,
-	3, 5, 5, 2, 5, 3, 6, 4, 4, 4,
-	6, 5, 6, 5, 6, 4, 8, 3, 8, 4,
-	2, 3, 10, 3, 6, 4, 3, 1, 3, 4,
-	4, 2, 1, 1, 3, 1, 3, 2, 4, 3,
-	2, 3, 2, 0, 1, 1, 0, 2, 0, 7,
-	10, 6, 8, 6, 6, 6, 9, 4, 3, 2,
-	2, 0, 1, 1, 1, 1, 1, 3, 1, 3,
-	6, 4, 6, 7, 9, 6, 2, 2, 3, 0,
-	8, 6, 8, 7, 2, 0, 1, 2, 5, 0,
-	1, 3, 3, 1, 3, 1, 3, 3, 3, 3,
-	4, 1, 3, 1, 3, 1, 1, 12, 6, 5,
-	4, 1, 3, 3, 3, 3, 2, 4, 4, 4,
-	1, 1, 2, 1, 4, 1, 0, 3, 3, 0,
-	4, 6, 0, 6, 4, 4, 4, 5, 7, 6,
-	8, 7, 9, 2, 1, 3, 1, 3, 2, 5,
-	0, 1, 3, 3, 3, 3, 1, 1, 1, 1,
-	1, 1, 1, 3, 3, 1, 3, 3, 3, 3,
-	1, 1, 1, 4, 3, 1, 1, 1, 1, 1,
-	1, 3, 3, 6, 4, 9, 7, 12, 9, 2,
-	7, 2, 1, 1, 1, 3, 3, 0, 3, 1,
-	3, 1, 1, 3, 2, 5, 0, 2, 7, 5,
-	6, 5, 7, 6, 2, 4, 0, 1, 2, 1,
-	3, 3, 1, 1, 2, 2, 2, 2, 1, 2,
-	2, 3, 4, 3, 3, 2, 2, 2, 2, 2,
-	2, 2, 2, 2, 1, 2, 2, 2, 2, 2,
-	2, 2, 3, 1, 2, 1, 2, 1, 2, 1,
-	2, 2, 3, 3, 3, 3, 3, 3, 5, 3,
-	3, 5, 3, 3, 5, 3, 3, 5, 3, 4,
-	3, 6, 6, 6, 6, 6, 8, 4, 4, 1,
+	3, 1, 3, 1, 1, 1, 3, 1, 1, 1,
+	1, 3, 4, 6, 1, 1, 1, 1, 1, 1,
+	1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+	1, 1, 1, 1, 1, 3, 1, 1, 1, 3,
+	3, 6, 4, 4, 6, 9, 6, 8, 4, 4,
+	5, 9, 7, 9, 5, 6, 8, 7, 7, 9,
+	1, 1, 3, 1, 1, 1, 1, 1, 1, 1,
+	1, 3, 4, 6, 4, 6, 6, 9, 6, 9,
+	6, 5, 6, 5, 1, 1, 1, 1, 1, 1,
+	0, 1, 6, 6, 4, 6, 2, 1, 1, 2,
+	4, 8, 7, 10, 9, 4, 4, 4, 3, 4,
+	4, 4, 7, 7, 9, 8, 9, 5, 3, 5,
+	7, 4, 12, 4, 12, 1, 3, 5, 5, 2,
+	5, 3, 6, 4, 4, 4, 6, 6, 6, 9,
+	9, 4, 4, 4, 5, 7, 5, 6, 5, 6,
+	4, 8, 3, 8, 4, 2, 3, 10, 3, 6,
+	4, 3, 1, 3, 4, 4, 4, 2, 1, 1,
+	3, 1, 3, 2, 4, 3, 2, 3, 2, 0,
+	1, 1, 0, 2, 0, 2, 3, 3, 3, 4,
+	3, 3, 3, 3, 3, 4, 1, 2, 3, 3,
+	1, 2, 7, 10, 6, 8, 6, 6, 6, 9,
+	4, 3, 2, 2, 0, 1, 1, 1, 1, 1,
+	3, 1, 3, 6, 4, 6, 7, 9, 7, 2,
+	2, 3, 0, 8, 6, 8, 4, 2, 0, 1,
+	2, 5, 0, 1, 3, 3, 1, 3, 1, 3,
+	3, 3, 3, 4, 1, 3, 1, 3, 1, 1,
+	12, 6, 5, 4, 1, 3, 3, 3, 3, 2,
+	4, 4, 4, 2, 3, 1, 1, 2, 1, 4,
+	1, 0, 3, 3, 0, 4, 6, 0, 6, 4,
+	5, 4, 2, 5, 0, 1, 3, 3, 3, 3,
+	4, 4, 3, 7, 4, 8, 5, 9, 2, 1,
+	3, 2, 5, 0, 1, 3, 3, 3, 3, 1,
+	1, 1, 1, 1, 1, 1, 3, 3, 3, 3,
+	1, 1, 1, 4, 3, 2, 1, 1, 1, 1,
+	1, 1, 3, 3, 6, 4, 9, 7, 12, 9,
+	2, 7, 2, 1, 1, 1, 3, 3, 1, 3,
+	1, 1, 3, 2, 5, 0, 2, 7, 5, 6,
+	5, 7, 6, 2, 4, 0, 1, 2, 1, 3,
+	3, 1, 1, 2, 2, 2, 2, 1, 2, 2,
+	3, 4, 3, 2, 2, 2, 2, 2, 2, 2,
+	2, 2, 2, 1, 2, 2, 2, 2, 2, 2,
+	2, 2, 1, 2, 1, 2, 1, 2, 1, 2,
+	2, 3, 3, 3, 3, 3, 3, 5, 3, 3,
+	5, 3, 3, 5, 3, 3, 5, 3, 4, 3,
+	6, 6, 6, 6, 6, 6, 8, 4, 4, 1,
 	1, 1, 2, 1, 1, 2, 1, 2, 1, 2,
-	1, 2, 1, 2, 1, 1, 2, 4, 7, 11,
-	14, 3, 1, 2, 0, 2, 2, 5, 0, 1,
-	3, 3, 4, 1, 2, 1, 2, 3, 6, 3,
-	8, 5, 3, 13, 4, 9, 4, 2, 0, 1,
-	0, 1, 0, 1, 1, 0, 1, 3, 1, 3,
-	3, 3, 3, 2, 2, 1, 1, 1, 1, 2,
-	1, 1, 1, 1, 0, 1, 2, 3, 2, 1,
-	1, 1, 4, 5, 1, 1, 1, 1, 3, 3,
-	2, 2, 1, 2, 2, 2, 2, 1, 1, 1,
-	2, 1, 1, 3, 0, 1, 4, 0, 2, 0,
-	4, 6, 3, 4, 6, 3, 1, 3, 2, 1,
-	3, 2, 1, 3, 5, 1, 2, 1, 0, 6,
-	6, 6, 8, 6, 6, 6, 1, 0, 4, 3,
-	3, 4, 3, 4, 4, 4, 7, 3, 3, 4,
-	3, 3, 3, 3, 3, 1, 0, 1, 0, 4,
-	3, 3, 3, 3, 3, 6, 4, 4, 4, 5,
-	3, 3, 3, 3, 3, 3, 3, 1, 2, 1,
-	2, 1, 2, 1, 2, 1, 2, 4, 1, 2,
+	1, 2, 1, 2, 1, 2, 1, 1, 2, 1,
+	2, 2, 11, 9, 5, 2, 4, 2, 1, 3,
+	2, 5, 0, 2, 5, 0, 1, 3, 1, 3,
+	3, 3, 4, 5, 3, 3, 3, 3, 3, 3,
+	3, 1, 3, 3, 6, 10, 13, 3, 1, 2,
+	2, 5, 0, 1, 3, 3, 3, 1, 3, 4,
+	1, 2, 1, 2, 3, 6, 3, 8, 5, 3,
+	8, 7, 3, 9, 12, 3, 6, 8, 3, 2,
+	2, 0, 2, 2, 2, 2, 2, 0, 2, 0,
+	9, 9, 5, 4, 0, 1, 1, 1, 2, 12,
+	14, 9, 4, 9, 4, 2, 0, 1, 0, 1,
+	1, 0, 1, 3, 1, 3, 3, 3, 3, 2,
+	2, 1, 1, 1, 1, 2, 1, 1, 1, 2,
+	1, 3, 1, 0, 1, 2, 3, 2, 1, 1,
+	1, 4, 5, 1, 1, 1, 1, 3, 3, 2,
+	2, 1, 2, 2, 2, 2, 1, 1, 1, 2,
+	1, 1, 3, 0, 1, 4, 0, 2, 0, 2,
+	2, 1, 2, 1, 2, 4, 6, 3, 4, 6,
+	3, 1, 3, 2, 1, 3, 2, 1, 3, 5,
+	1, 2, 1, 0, 6, 6, 6, 8, 6, 6,
+	6, 1, 0, 17, 4, 1, 1, 2, 1, 3,
+	1, 1, 1, 3, 1, 2, 0, 1, 2, 4,
+	1, 0, 1, 1, 1, 1, 3, 0, 1, 0,
+	1, 1, 2, 0, 1, 1, 1, 3, 0, 1,
+	1, 1, 1, 6, 8, 3, 4, 3, 3, 4,
+	3, 4, 4, 4, 7, 3, 3, 4, 3, 3,
+	3, 3, 1, 0, 1, 0, 4, 3, 3, 3,
+	3, 3, 6, 4, 4, 4, 5, 3, 3, 3,
+	3, 3, 3, 1, 2, 1, 2, 1, 2, 1,
+	2, 1, 2, 4, 1, 2, 1, 2, 1, 2,
 	1, 2, 1, 2, 1, 2, 1, 2, 7, 3,
 	2, 0, 1, 3, 1, 3, 0, 1, 2, 2,
 	1, 2, 1, 6, 10, 5, 10, 15, 6, 1,
@@ -27065,33 +29398,35 @@ var sqlR2 = [...]int8{
 	2, 2, 2, 2, 2, 2, 1, 1, 2, 1,
 	2, 1, 2, 1, 2, 1, 2, 1, 2, 1,
 	2, 1, 2, 1, 2, 1, 2, 1, 2, 1,
-	2, 1, 2, 1, 2, 4, 6, 5, 7, 3,
-	4, 6, 3, 4, 6, 3, 5, 7, 3, 4,
-	6, 3, 4, 6, 3, 4, 6, 3, 0, 1,
-	1, 1, 3, 4, 6, 3, 3, 5, 3, 1,
-	3, 1, 1, 1, 2, 2, 2, 2, 1, 2,
-	2, 5, 3, 3, 6, 6, 3, 1, 1, 1,
-	1, 1, 1, 2, 1, 1, 1, 2, 1, 1,
-	2, 1, 2, 1, 2, 1, 1, 1, 2, 1,
-	1, 2, 1, 1, 1, 1, 1, 2, 1, 2,
-	1, 2, 1, 2, 1, 2, 1, 2, 1, 1,
-	1, 2, 1, 2, 1, 2, 1, 2, 1, 1,
-	2, 1, 2, 1, 3, 4, 3, 1, 2, 3,
-	2, 2, 2, 4, 6, 3, 1, 2, 2, 7,
-	3, 3, 2, 1, 2, 3, 2, 3, 0, 2,
-	2, 1, 4, 3, 5, 7, 2, 3, 0, 3,
-	5, 2, 3, 0, 2, 3, 2, 3, 2, 7,
-	4, 7, 8, 8, 9, 11, 11, 11, 11, 6,
-	2, 6, 9, 4, 7, 7, 10, 7, 10, 10,
-	10, 13, 10, 13, 10, 13, 5, 8, 5, 2,
-	2, 1, 1, 3, 1, 1, 1, 1, 1, 2,
-	1, 2, 2, 3, 2, 2, 4, 3, 2, 2,
-	1, 2, 1, 3, 1, 2, 1, 2, 1, 2,
-	1, 2, 1, 1, 3, 5, 4, 6, 4, 3,
-	0, 1, 3, 2, 4, 2, 4, 1, 6, 3,
-	1, 2, 1, 2, 1, 2, 1, 2, 1, 2,
-	3, 1, 3, 6, 6, 6, 5, 5, 5, 5,
-	5, 9, 7, 6, 4, 4, 5, 5, 4, 1,
+	2, 1, 2, 1, 2, 1, 2, 1, 2, 4,
+	6, 5, 7, 3, 4, 6, 3, 4, 6, 3,
+	5, 7, 3, 4, 6, 3, 4, 6, 3, 4,
+	6, 3, 0, 1, 1, 1, 3, 4, 6, 3,
+	3, 5, 3, 1, 3, 1, 1, 1, 2, 2,
+	2, 2, 1, 2, 2, 5, 3, 3, 6, 6,
+	3, 1, 1, 1, 1, 1, 1, 1, 2, 1,
+	1, 1, 1, 2, 1, 1, 2, 1, 2, 1,
+	2, 1, 1, 1, 2, 1, 1, 2, 1, 1,
+	1, 1, 1, 2, 1, 2, 1, 2, 1, 2,
+	1, 2, 1, 2, 1, 1, 1, 2, 1, 2,
+	1, 2, 1, 2, 1, 1, 2, 1, 2, 1,
+	3, 6, 3, 4, 3, 1, 2, 3, 2, 2,
+	2, 4, 6, 3, 1, 2, 2, 7, 3, 3,
+	2, 1, 2, 3, 2, 3, 0, 2, 2, 1,
+	3, 4, 3, 5, 5, 5, 0, 2, 1, 5,
+	7, 2, 3, 0, 3, 5, 2, 3, 0, 2,
+	3, 2, 3, 2, 7, 4, 7, 8, 8, 9,
+	11, 11, 11, 11, 6, 2, 6, 9, 4, 7,
+	7, 10, 7, 10, 10, 10, 13, 10, 13, 10,
+	13, 5, 8, 5, 2, 2, 1, 1, 3, 1,
+	1, 1, 1, 1, 2, 1, 2, 2, 3, 2,
+	2, 4, 3, 2, 2, 1, 2, 1, 3, 1,
+	2, 1, 2, 1, 2, 1, 2, 1, 1, 3,
+	5, 4, 6, 4, 3, 0, 1, 3, 2, 4,
+	2, 4, 1, 6, 3, 1, 2, 1, 2, 1,
+	2, 1, 2, 1, 2, 1, 2, 3, 1, 3,
+	9, 6, 6, 6, 5, 5, 5, 5, 5, 9,
+	7, 6, 7, 10, 4, 4, 5, 5, 4, 1,
 	1, 1, 1, 6, 6, 6, 6, 5, 5, 1,
 	3, 1, 3, 5, 4, 5, 3, 3, 2, 2,
 	6, 3, 3, 3, 3, 4, 4, 3, 1, 3,
@@ -27100,10 +29435,11 @@ var sqlR2 = [...]int8{
 	3, 2, 2, 1, 2, 1, 1, 1, 1, 1,
 	1, 1, 1, 1, 1, 1, 2, 1, 2, 1,
 	2, 1, 2, 1, 2, 1, 2, 1, 2, 1,
-	2, 1, 2, 1, 2, 1, 1, 2, 1, 2,
-	1, 2, 1, 2, 1, 2, 1, 2, 1, 2,
-	1, 1, 2, 1, 2, 1, 2, 1, 1, 2,
-	1, 1, 2, 1, 2, 1, 2, 1, 2, 1,
+	2, 1, 2, 1, 2, 1, 2, 1, 2, 1,
+	2, 1, 1, 2, 1, 2, 1, 2, 1, 2,
+	1, 2, 1, 2, 1, 2, 1, 1, 2, 1,
+	2, 1, 2, 1, 1, 2, 1, 1, 2, 1,
+	2, 1, 2, 1, 2, 1, 2, 1, 2, 1,
 	2, 1, 2, 1, 2, 1, 2, 1, 2, 1,
 	2, 1, 2, 1, 2, 1, 2, 1, 2, 1,
 	2, 1, 2, 2, 1, 1, 1, 2, 1, 2,
@@ -27114,175 +29450,184 @@ var sqlR2 = [...]int8{
 	3, 3, 3, 3, 2, 3, 3, 1, 2, 1,
 	1, 1, 1, 1, 1, 1, 1, 2, 2, 2,
 	1, 2, 3, 6, 8, 3, 3, 3, 4, 8,
-	6, 4, 5, 5, 5, 5, 5, 3, 0, 1,
+	6, 5, 6, 6, 6, 6, 5, 3, 0, 1,
 	1, 1, 1, 2, 5, 0, 1, 3, 1, 1,
-	2, 1, 1, 3, 3, 3, 1, 3, 1, 2,
-	5, 0, 1, 3, 3, 3, 3, 4, 4, 3,
-	4, 4, 3, 4, 4, 1, 4, 4, 5, 3,
-	5, 5, 5, 7, 3, 3, 3, 5, 7, 7,
-	4, 2, 6, 4, 3, 2, 3, 4, 4, 3,
-	5, 3, 6, 5, 6, 3, 5, 6, 3, 3,
-	5, 3, 5, 3, 3, 4, 4, 5, 0, 1,
-	1, 1, 1, 3, 2, 4, 3, 4, 3, 4,
-	3, 5, 5, 3, 4, 4, 3, 5, 4, 5,
-	3, 4, 1, 3, 2, 3, 4, 4, 5, 3,
-	3, 1, 1, 0, 2, 3, 2, 5, 4, 6,
-	4, 6, 4, 1, 0, 3, 4, 4, 5, 7,
-	5, 3, 3, 6, 4, 2, 3, 6, 4, 2,
-	3, 3, 4, 4, 5, 2, 0, 4, 2, 3,
-	4, 2, 3, 3, 3, 7, 5, 2, 0, 3,
+	2, 1, 1, 3, 3, 3, 1, 3, 4, 4,
+	3, 4, 4, 3, 4, 4, 1, 4, 4, 5,
+	3, 5, 5, 5, 7, 3, 3, 3, 5, 7,
+	7, 4, 2, 6, 4, 3, 3, 4, 4, 4,
+	3, 3, 4, 4, 3, 5, 3, 6, 5, 6,
+	3, 5, 6, 3, 3, 5, 3, 5, 3, 4,
+	3, 3, 3, 4, 4, 5, 0, 1, 1, 1,
+	1, 3, 2, 4, 3, 4, 3, 4, 3, 5,
+	5, 3, 4, 4, 3, 5, 4, 5, 3, 4,
+	1, 3, 2, 3, 4, 4, 5, 3, 3, 1,
+	1, 0, 2, 3, 2, 5, 4, 6, 4, 6,
+	4, 1, 0, 3, 4, 4, 5, 7, 5, 3,
+	3, 6, 4, 2, 3, 6, 4, 2, 3, 3,
+	4, 4, 5, 2, 0, 5, 3, 3, 4, 2,
+	3, 3, 3, 7, 4, 3, 5, 2, 0, 3,
 	3, 4, 3, 3, 3, 5, 3, 3, 4, 5,
-	5, 4, 4, 5, 6, 4, 4, 4, 4, 4,
-	3, 0, 2, 4, 5, 4, 4, 5, 6, 5,
-	5, 2, 3, 2, 3, 6, 6, 7, 9, 7,
-	9, 4, 3, 4, 4, 5, 1, 1, 10, 10,
-	3, 6, 6, 6, 5, 3, 3, 4, 4, 0,
-	2, 1, 1, 1, 1, 1, 3, 3, 3, 3,
-	3, 5, 6, 4, 4, 5, 5, 2, 6, 3,
-	2, 5, 5, 4, 2, 0, 1, 1, 1, 1,
-	2, 3, 2, 2, 3, 2, 2, 1, 1, 1,
-	1, 3, 2, 2, 2, 2, 2, 2, 2, 2,
-	1, 2, 0, 1, 2, 1, 2, 1, 2, 2,
-	1, 2, 1, 2, 1, 2, 2, 4, 3, 3,
-	7, 3, 3, 7, 3, 3, 3, 3, 3, 3,
-	3, 3, 4, 3, 3, 6, 5, 8, 3, 6,
-	6, 3, 12, 15, 1, 0, 1, 2, 3, 0,
-	2, 0, 4, 0, 4, 5, 4, 1, 1, 1,
-	3, 3, 1, 3, 10, 13, 0, 2, 3, 1,
-	1, 0, 1, 2, 2, 2, 2, 1, 1, 0,
-	1, 3, 1, 1, 1, 2, 3, 3, 3, 0,
-	1, 1, 1, 1, 1, 1, 1, 1, 1, 2,
-	1, 0, 1, 0, 1, 1, 0, 1, 4, 1,
-	0, 3, 7, 7, 1, 1, 3, 7, 1, 3,
-	11, 3, 2, 0, 3, 1, 2, 2, 3, 2,
-	6, 2, 1, 2, 2, 3, 6, 4, 2, 3,
-	5, 5, 5, 2, 5, 5, 2, 2, 2, 0,
-	1, 1, 3, 4, 10, 11, 12, 9, 10, 5,
-	3, 1, 5, 9, 7, 11, 3, 3, 0, 2,
-	4, 3, 3, 1, 6, 1, 3, 1, 2, 0,
-	1, 2, 3, 0, 1, 3, 3, 2, 2, 1,
-	1, 1, 4, 0, 3, 0, 4, 0, 3, 0,
-	2, 2, 2, 0, 1, 1, 2, 2, 0, 3,
-	3, 2, 1, 1, 2, 2, 5, 8, 4, 1,
-	0, 1, 2, 2, 1, 2, 3, 3, 2, 2,
-	3, 2, 2, 2, 2, 2, 3, 1, 2, 3,
-	1, 4, 2, 3, 2, 2, 4, 7, 3, 4,
-	6, 5, 7, 5, 5, 3, 3, 0, 2, 2,
-	2, 2, 1, 1, 1, 8, 10, 11, 8, 11,
-	5, 4, 2, 0, 1, 1, 1, 1, 1, 1,
-	1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+	5, 4, 4, 5, 6, 4, 4, 6, 4, 4,
+	4, 3, 0, 2, 2, 4, 5, 4, 4, 5,
+	6, 5, 5, 2, 3, 7, 7, 7, 7, 2,
+	3, 6, 6, 7, 9, 7, 9, 4, 3, 4,
+	4, 5, 1, 1, 10, 10, 3, 6, 6, 6,
+	5, 3, 3, 4, 4, 0, 2, 1, 1, 1,
+	1, 1, 3, 3, 3, 3, 3, 5, 6, 4,
+	4, 5, 5, 2, 6, 3, 2, 6, 6, 2,
+	5, 0, 1, 3, 4, 4, 4, 2, 0, 1,
+	1, 1, 1, 2, 3, 2, 2, 3, 2, 2,
+	1, 1, 1, 1, 3, 2, 2, 2, 2, 2,
+	2, 2, 2, 1, 2, 0, 1, 2, 1, 2,
+	1, 2, 2, 1, 2, 1, 2, 1, 2, 2,
+	4, 3, 3, 7, 3, 3, 7, 3, 3, 3,
+	3, 3, 3, 3, 3, 4, 3, 3, 6, 5,
+	8, 3, 6, 6, 3, 12, 15, 1, 0, 1,
+	2, 3, 0, 2, 0, 4, 0, 4, 5, 4,
+	1, 1, 1, 3, 3, 1, 3, 10, 13, 0,
+	2, 3, 1, 1, 0, 1, 2, 2, 2, 2,
+	1, 1, 0, 1, 3, 1, 1, 1, 2, 3,
+	3, 3, 0, 1, 1, 1, 1, 1, 1, 1,
+	1, 1, 2, 1, 0, 1, 0, 1, 1, 0,
+	1, 4, 1, 0, 3, 7, 7, 1, 1, 3,
+	7, 1, 3, 11, 3, 2, 0, 3, 1, 2,
+	2, 3, 2, 6, 2, 1, 2, 2, 3, 6,
+	4, 2, 3, 5, 5, 5, 2, 5, 5, 2,
+	2, 2, 0, 1, 1, 3, 4, 3, 4, 10,
+	11, 12, 9, 10, 9, 10, 5, 3, 1, 5,
+	9, 7, 11, 3, 3, 0, 2, 4, 3, 3,
+	1, 6, 1, 3, 1, 2, 0, 1, 2, 3,
+	0, 1, 3, 3, 2, 2, 1, 1, 1, 4,
+	0, 3, 0, 4, 0, 3, 0, 2, 2, 2,
+	0, 1, 1, 2, 2, 0, 3, 3, 2, 1,
+	1, 2, 2, 5, 8, 4, 1, 0, 1, 2,
+	2, 1, 2, 3, 3, 2, 4, 2, 3, 2,
+	2, 2, 2, 2, 3, 1, 2, 3, 1, 4,
+	2, 3, 2, 2, 4, 7, 3, 4, 6, 5,
+	7, 5, 5, 3, 3, 0, 2, 2, 2, 2,
+	1, 1, 1, 8, 10, 11, 8, 11, 5, 4,
+	2, 0, 1, 1, 1, 1, 1, 1, 1, 1,
 	1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
-	1, 1, 1, 2, 2, 0, 3, 3, 0, 1,
-	8, 11, 3, 7, 10, 6, 5, 3, 4, 1,
-	0, 1, 3, 1, 0, 2, 4, 17, 20, 16,
-	19, 4, 2, 0, 1, 0, 1, 0, 1, 3,
-	2, 4, 2, 3, 1, 0, 2, 0, 1, 1,
-	0, 2, 1, 1, 2, 0, 9, 6, 6, 8,
-	6, 8, 5, 7, 2, 6, 7, 4, 4, 5,
-	2, 4, 6, 6, 8, 6, 7, 8, 9, 6,
-	7, 8, 9, 6, 8, 6, 8, 6, 7, 8,
-	9, 6, 8, 6, 8, 6, 6, 8, 8, 4,
-	7, 3, 0, 7, 10, 1, 1, 1, 1, 1,
-	2, 3, 0, 3, 0, 3, 0, 1, 0, 2,
-	0, 2, 2, 3, 3, 3, 3, 3, 3, 3,
-	3, 3, 3, 3, 3, 3, 2, 2, 1, 2,
-	1, 2, 1, 2, 1, 3, 2, 2, 2, 2,
-	1, 1, 0, 2, 4, 2, 1, 2, 1, 2,
-	3, 2, 2, 2, 1, 0, 2, 1, 1, 0,
-	1, 3, 1, 0, 1, 1, 1, 1, 1, 2,
-	3, 2, 2, 1, 2, 16, 19, 3, 1, 0,
-	4, 1, 0, 4, 1, 0, 5, 1, 0, 2,
-	2, 3, 0, 1, 1, 4, 4, 5, 1, 0,
-	3, 0, 3, 0, 3, 0, 3, 0, 4, 0,
-	3, 0, 1, 0, 6, 7, 3, 6, 3, 1,
-	3, 1, 1, 4, 2, 1, 3, 1, 3, 4,
-	8, 11, 7, 10, 2, 2, 0, 10, 3, 2,
-	0, 1, 3, 1, 1, 3, 3, 5, 6, 4,
-	5, 4, 1, 1, 3, 3, 1, 2, 4, 4,
-	2, 3, 5, 5, 1, 3, 1, 0, 1, 2,
-	3, 2, 4, 2, 3, 0, 2, 0, 2, 1,
-	2, 1, 1, 1, 2, 1, 2, 1, 2, 1,
-	8, 8, 8, 2, 4, 4, 4, 2, 2, 2,
-	2, 3, 1, 3, 1, 2, 0, 7, 1, 0,
-	1, 0, 1, 0, 1, 1, 0, 1, 5, 1,
-	0, 1, 0, 1, 0, 1, 0, 3, 3, 3,
-	3, 5, 5, 1, 1, 3, 3, 1, 3, 3,
-	4, 5, 3, 2, 2, 0, 2, 2, 1, 1,
-	1, 0, 1, 0, 2, 2, 5, 4, 2, 3,
-	1, 1, 1, 1, 1, 1, 1, 3, 0, 1,
-	3, 1, 3, 3, 3, 2, 0, 4, 2, 5,
-	3, 2, 0, 1, 3, 3, 5, 1, 1, 1,
-	1, 1, 1, 1, 3, 5, 5, 1, 3, 2,
-	4, 4, 0, 4, 4, 3, 4, 1, 5, 3,
-	4, 5, 5, 1, 5, 1, 3, 2, 3, 0,
-	1, 3, 0, 3, 1, 3, 1, 2, 0, 2,
-	3, 1, 3, 2, 0, 3, 5, 6, 4, 6,
-	4, 3, 2, 1, 0, 3, 2, 1, 0, 5,
-	1, 0, 2, 2, 2, 1, 1, 0, 1, 1,
-	1, 1, 0, 4, 2, 1, 2, 2, 4, 1,
-	3, 2, 2, 1, 2, 3, 2, 4, 1, 0,
-	1, 0, 2, 1, 0, 2, 5, 7, 2, 1,
-	2, 4, 3, 5, 0, 1, 3, 5, 1, 2,
-	1, 1, 1, 2, 2, 1, 1, 1, 1, 1,
 	1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+	1, 1, 1, 1, 2, 2, 0, 3, 3, 2,
+	2, 0, 1, 8, 11, 3, 7, 10, 6, 5,
+	3, 4, 1, 0, 1, 3, 1, 0, 2, 4,
+	17, 20, 16, 19, 16, 19, 4, 2, 0, 1,
+	0, 1, 0, 1, 3, 2, 4, 2, 3, 1,
+	0, 2, 0, 1, 1, 0, 2, 1, 1, 2,
+	0, 9, 6, 6, 8, 6, 8, 5, 7, 2,
+	6, 7, 4, 4, 5, 2, 4, 6, 6, 8,
+	6, 7, 8, 9, 6, 7, 8, 9, 6, 8,
+	6, 8, 6, 7, 8, 9, 6, 8, 6, 8,
+	6, 6, 8, 8, 4, 7, 3, 0, 7, 10,
+	1, 1, 1, 1, 1, 2, 3, 0, 3, 0,
+	3, 0, 1, 0, 2, 0, 2, 2, 3, 3,
+	3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+	3, 2, 2, 1, 2, 1, 2, 1, 2, 1,
+	1, 2, 1, 2, 1, 2, 3, 2, 2, 2,
+	2, 1, 1, 0, 2, 4, 2, 1, 2, 1,
+	2, 3, 2, 2, 2, 1, 0, 2, 1, 1,
+	0, 1, 3, 1, 0, 1, 1, 1, 1, 1,
+	2, 3, 2, 2, 1, 2, 3, 3, 3, 16,
+	19, 3, 1, 0, 4, 1, 0, 4, 1, 0,
+	5, 1, 0, 2, 2, 3, 0, 1, 1, 4,
+	4, 5, 1, 0, 3, 0, 3, 0, 3, 0,
+	3, 0, 4, 0, 3, 0, 1, 0, 6, 7,
+	3, 6, 3, 1, 3, 2, 1, 4, 2, 1,
+	3, 1, 3, 4, 8, 11, 7, 10, 2, 2,
+	0, 10, 3, 2, 0, 1, 3, 1, 1, 3,
+	3, 5, 6, 4, 5, 4, 1, 1, 3, 3,
+	1, 2, 4, 4, 2, 3, 5, 5, 1, 3,
+	1, 0, 1, 2, 3, 2, 4, 2, 3, 0,
+	2, 0, 2, 1, 2, 1, 1, 1, 2, 1,
+	2, 1, 2, 1, 8, 8, 8, 4, 4, 4,
+	2, 2, 2, 2, 3, 1, 3, 1, 2, 0,
+	7, 1, 0, 1, 0, 1, 0, 1, 1, 0,
+	1, 5, 1, 0, 1, 0, 1, 0, 1, 0,
+	3, 3, 3, 3, 5, 5, 1, 1, 3, 3,
+	1, 3, 3, 4, 5, 3, 2, 2, 0, 2,
+	2, 1, 1, 1, 0, 1, 0, 2, 2, 5,
+	4, 2, 3, 1, 1, 1, 1, 1, 1, 1,
+	3, 0, 1, 3, 1, 3, 3, 3, 2, 0,
+	4, 2, 5, 3, 2, 0, 1, 3, 3, 5,
+	1, 1, 1, 1, 1, 1, 1, 1, 1, 3,
+	5, 5, 1, 3, 2, 4, 4, 0, 4, 4,
+	3, 4, 1, 5, 3, 4, 5, 5, 1, 5,
+	1, 3, 2, 3, 0, 1, 3, 0, 3, 1,
+	3, 1, 2, 0, 2, 3, 1, 3, 2, 0,
+	3, 5, 6, 4, 6, 4, 3, 2, 1, 0,
+	3, 2, 1, 0, 5, 1, 0, 2, 2, 2,
+	1, 1, 0, 1, 1, 1, 1, 1, 0, 4,
+	2, 1, 2, 2, 4, 1, 3, 2, 2, 1,
+	2, 3, 2, 4, 1, 0, 1, 0, 2, 1,
+	0, 2, 5, 7, 2, 1, 2, 4, 3, 5,
+	0, 1, 3, 5, 1, 2, 1, 1, 1, 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,
-	4, 4, 6, 6, 1, 1, 1, 1, 1, 1,
-	1, 3, 5, 0, 1, 1, 1, 1, 1, 2,
-	2, 2, 2, 2, 1, 3, 0, 5, 4, 1,
-	2, 1, 4, 1, 1, 2, 1, 1, 1, 1,
-	1, 0, 1, 2, 5, 1, 4, 2, 5, 1,
-	4, 3, 3, 0, 1, 2, 4, 1, 1, 1,
-	1, 1, 1, 3, 3, 3, 3, 3, 3, 3,
-	1, 0, 1, 4, 1, 3, 3, 3, 5, 2,
-	2, 2, 2, 2, 3, 3, 3, 3, 3, 3,
+	1, 1, 1, 1, 1, 1, 4, 4, 6, 6,
+	1, 4, 1, 1, 1, 1, 1, 1, 1, 1,
+	3, 5, 0, 1, 1, 1, 1, 1, 2, 2,
+	2, 2, 2, 1, 3, 0, 5, 4, 1, 2,
+	1, 4, 1, 1, 2, 1, 1, 1, 1, 1,
+	0, 1, 2, 5, 1, 4, 2, 5, 1, 4,
+	3, 3, 0, 1, 2, 4, 1, 1, 1, 1,
+	1, 1, 3, 3, 3, 3, 3, 3, 3, 1,
+	0, 1, 4, 1, 3, 3, 3, 5, 2, 2,
+	2, 2, 2, 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, 3, 3,
-	3, 2, 2, 3, 5, 4, 6, 3, 5, 4,
-	6, 4, 6, 5, 7, 3, 3, 3, 3, 3,
-	4, 3, 2, 4, 2, 3, 3, 4, 3, 4,
-	3, 4, 5, 6, 6, 7, 6, 7, 6, 7,
-	3, 4, 4, 1, 3, 1, 3, 3, 2, 2,
-	2, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+	3, 3, 3, 3, 3, 3, 3, 3, 3, 2,
+	3, 3, 3, 2, 2, 3, 5, 4, 6, 3,
+	5, 4, 6, 4, 6, 5, 7, 3, 3, 3,
+	3, 3, 4, 3, 2, 4, 2, 3, 3, 4,
+	3, 4, 3, 4, 5, 6, 6, 7, 6, 7,
+	6, 7, 3, 4, 4, 1, 3, 1, 3, 3,
+	2, 2, 2, 3, 3, 3, 3, 3, 3, 3,
 	3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
-	2, 3, 5, 6, 6, 7, 1, 2, 1, 2,
-	1, 1, 1, 1, 1, 6, 1, 1, 1, 1,
-	1, 1, 2, 1, 5, 5, 6, 3, 1, 1,
-	1, 2, 2, 2, 4, 3, 5, 6, 8, 6,
-	5, 4, 3, 1, 4, 2, 2, 4, 1, 1,
-	1, 5, 1, 1, 1, 1, 1, 1, 1, 1,
-	1, 1, 1, 6, 6, 8, 8, 6, 4, 6,
-	6, 6, 4, 1, 3, 3, 3, 3, 3, 4,
-	3, 3, 4, 3, 3, 4, 3, 3, 4, 3,
-	3, 3, 3, 3, 4, 3, 4, 3, 4, 3,
-	4, 4, 3, 6, 5, 5, 5, 4, 4, 3,
-	4, 3, 5, 0, 5, 0, 2, 0, 1, 3,
-	3, 2, 2, 0, 6, 1, 0, 3, 0, 3,
-	3, 3, 0, 1, 4, 2, 2, 2, 2, 2,
-	3, 2, 2, 3, 0, 4, 1, 1, 5, 1,
+	3, 3, 2, 3, 5, 6, 6, 7, 1, 2,
+	1, 2, 1, 1, 1, 1, 1, 6, 1, 1,
+	1, 1, 1, 1, 2, 1, 5, 5, 6, 3,
+	1, 1, 1, 2, 2, 2, 4, 3, 5, 6,
+	8, 6, 5, 4, 3, 1, 4, 2, 2, 4,
+	1, 1, 1, 5, 1, 1, 1, 1, 1, 1,
+	1, 1, 1, 1, 1, 6, 6, 8, 8, 6,
+	4, 6, 6, 6, 4, 1, 3, 3, 3, 3,
+	3, 4, 3, 3, 4, 3, 3, 4, 3, 3,
+	4, 3, 3, 3, 3, 3, 4, 3, 4, 3,
+	4, 3, 4, 4, 3, 6, 5, 5, 5, 4,
+	4, 3, 4, 3, 5, 0, 5, 0, 2, 0,
+	1, 3, 3, 2, 2, 0, 6, 1, 0, 3,
+	0, 3, 3, 3, 0, 1, 4, 2, 2, 2,
+	2, 2, 3, 2, 2, 3, 0, 4, 1, 1,
+	5, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+	1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+	1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+	1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+	1, 1, 1, 1, 3, 4, 1, 1, 1, 2,
+	1, 2, 2, 3, 1, 2, 3, 2, 3, 2,
+	3, 1, 0, 1, 3, 1, 3, 3, 3, 1,
+	3, 3, 1, 1, 1, 1, 1, 1, 1, 1,
+	1, 4, 3, 1, 2, 3, 0, 3, 3, 2,
+	2, 1, 2, 2, 3, 2, 1, 1, 1, 5,
+	1, 2, 4, 2, 0, 1, 0, 3, 5, 1,
+	0, 1, 2, 1, 0, 1, 3, 1, 0, 3,
+	2, 1, 1, 1, 1, 1, 3, 1, 3, 3,
+	1, 1, 1, 1, 5, 3, 1, 1, 3, 1,
+	1, 1, 1, 2, 2, 1, 1, 2, 2, 1,
+	1, 1, 3, 5, 1, 1, 1, 1, 1, 1,
+	1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+	1, 1, 1, 1, 3, 1, 1, 3, 1, 3,
+	1, 3, 1, 0, 1, 1, 1, 1, 1, 1,
+	1, 3, 5, 7, 1, 7, 5, 3, 1, 1,
+	1, 1, 1, 1, 1, 1, 3, 5, 1, 1,
+	1, 1, 1, 1, 1, 0, 3, 0, 1, 1,
+	1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
 	1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
 	1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
 	1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
-	1, 1, 1, 1, 1, 1, 1, 1, 1, 3,
-	4, 1, 1, 1, 2, 1, 2, 2, 3, 1,
-	2, 3, 2, 3, 2, 3, 1, 0, 1, 3,
-	1, 3, 3, 3, 1, 3, 3, 1, 1, 1,
-	1, 1, 1, 1, 1, 1, 4, 3, 1, 2,
-	3, 0, 3, 3, 2, 2, 1, 2, 2, 3,
-	2, 1, 1, 1, 5, 1, 2, 4, 2, 0,
-	1, 0, 3, 5, 1, 0, 1, 2, 1, 0,
-	1, 3, 3, 2, 1, 1, 1, 1, 1, 3,
-	1, 3, 3, 1, 1, 1, 1, 5, 3, 1,
-	1, 3, 1, 1, 1, 1, 2, 2, 1, 1,
-	2, 2, 1, 1, 1, 3, 5, 1, 1, 1,
 	1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
-	1, 1, 1, 1, 1, 1, 1, 3, 1, 1,
-	3, 1, 3, 1, 3, 1, 0, 1, 1, 1,
-	1, 1, 1, 1, 3, 5, 7, 1, 7, 5,
-	3, 1, 1, 1, 1, 1, 1, 1, 1, 3,
-	5, 1, 1, 1, 1, 1, 1, 1, 0, 3,
-	0, 1, 1, 1, 1, 1, 1, 1, 1, 1,
 	1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
 	1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
 	1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
@@ -27403,1397 +29748,1513 @@ var sqlR2 = [...]int8{
 	1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
 	1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
 	1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
-	1, 1, 1, 1,
+	1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+	1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+	1,
 }
 
 var sqlChk = [...]int16{
-	-1000, -1, -2, 709, -3, -248, -146, -143, -85, -99,
-	-97, -151, -152, -127, -153, -145, -175, -180, -161, -162,
-	-163, -176, -182, -247, -256, -257, -258, -259, -268, -252,
-	-196, -249, -250, -4, -83, -86, -100, -126, -128, -144,
-	-155, -154, -156, -164, -172, -167, -150, -91, -177, -181,
-	-193, -251, -253, -254, 33, 32, 69, 115, 93, 178,
-	148, 159, 236, 444, 501, 513, 463, 164, 488, 469,
-	-187, -188, 536, -84, -98, -179, -178, 85, 149, 196,
-	346, 479, 626, 543, 56, 170, -7, -15, -34, -19,
-	30, 51, -87, -88, -89, -90, 71, -109, -104, -121,
-	-102, -106, -107, -115, -101, -785, 118, -693, -129, -133,
-	-171, -131, -141, -790, 186, 258, -157, -158, -159, 426,
-	-165, -166, 491, -168, -169, -170, 494, 187, -93, -92,
-	180, -305, -307, -184, -183, -185, -255, -194, -195, -197,
-	-198, -200, -201, -203, -204, -206, -238, -207, -208, -209,
-	-210, -211, -212, -213, -214, -218, -241, -215, -216, -217,
-	-220, -219, -221, -226, -222, -223, -224, -225, -227, -228,
-	-230, -231, -234, -235, -236, -237, -239, -240, -229, -242,
-	-205, -243, 616, 562, 95, 505, 21, -8, -9, -10,
-	-11, -12, -13, -14, -18, -17, -74, -5, -6, -20,
-	-21, -111, -39, -37, -38, -40, -41, -105, -108, -112,
-	-113, -114, -125, -116, -117, -118, -119, -103, -110, -692,
-	-130, -132, -135, -137, -138, -134, -136, -139, -140, 489,
-	679, -308, -306, 706, 685, 635, -202, -24, -29, -25,
-	-26, -28, -30, -27, -31, -32, -33, -59, -64, -61,
-	-62, -60, -63, -65, -66, -67, -68, -69, -70, -71,
-	-72, -73, -43, -49, -50, -44, -45, -46, -47, -48,
-	-51, -52, -53, -54, -55, -56, -57, -58, -22, -23,
-	-42, -75, -76, -78, -77, -79, -80, -82, -81, 666,
-	675, -311, -309, -310, -318, 527, 643, 587, 709, 709,
-	709, 709, 709, 709, 709, 709, 709, 709, 709, 709,
-	709, 709, 709, 709, 709, 709, 709, 709, 709, 709,
-	709, 709, 709, 709, 709, 709, 709, -417, 2, -393,
-	-399, -400, -401, -392, -361, -660, -665, 4, -657, -663,
-	195, 276, 275, 277, 386, 21, 22, 24, 23, 25,
-	26, 27, 28, 30, 31, 43, 41, 45, 46, 47,
-	49, 50, 51, 52, 53, 54, 55, 56, 60, 62,
-	66, 67, 68, 69, 70, 71, 72, 73, 74, 75,
-	79, 84, 85, 86, 87, 92, 93, 94, 95, 96,
-	97, 98, 99, 105, 102, 103, 104, 106, 107, 109,
-	111, 112, 113, 114, 115, 116, 117, 119, 120, 121,
-	123, 124, 125, 133, 134, 135, 136, 137, 139, 148,
-	140, 141, 143, 149, 152, 146, 151, 147, 153, 154,
-	156, 157, 158, 159, 162, 163, 164, 166, 167, 169,
-	168, 171, 172, 173, 175, 176, 178, 179, 180, 183,
-	181, 184, 182, 185, 186, 187, 188, 189, 192, 193,
-	201, 202, 203, 208, 217, 210, 212, 213, 214, 211,
-	215, 218, 219, 222, 223, 224, 227, 228, 229, 230,
-	231, 232, 233, 234, 235, 237, 238, 242, 244, 245,
-	246, 247, 248, 249, 250, 256, 257, 258, 260, 261,
-	262, 263, 264, 265, 266, 270, 271, 272, 273, 280,
-	282, 288, 289, 657, 294, 290, 295, 296, 298, 302,
-	303, 304, 305, 306, 307, 308, 310, 312, 311, 316,
-	314, 318, 319, 322, 323, 324, 325, 326, 327, 331,
-	332, 328, 333, 334, 336, 337, 340, 338, 341, 342,
-	339, 343, 344, 347, 348, 349, 350, 351, 352, 353,
-	354, 355, 356, 357, 358, 345, 346, 361, 359, 363,
-	364, 365, 366, 367, 383, 385, 378, 379, 380, 371,
-	372, 368, 373, 369, 370, 374, 375, 382, 376, 377,
-	388, 389, 390, 391, 394, 254, 281, 396, 397, 400,
-	402, 419, 405, 406, 407, 410, 411, 414, 417, 418,
-	420, 421, 422, 423, 424, 425, 426, 427, 428, 429,
-	431, 432, 434, 435, 436, 438, 439, 440, 442, 444,
-	445, 447, 448, 449, 451, 452, 453, 454, 455, 456,
-	457, 458, 459, 460, 462, 463, 465, 464, 466, 467,
-	469, 471, 472, 473, 479, 480, 488, 481, 483, 484,
-	485, 486, 487, 489, 490, 491, 492, 493, 494, 495,
-	499, 497, 498, 500, 501, 503, 504, 505, 506, 507,
-	509, 511, 512, 516, 517, 520, 518, 539, 540, 565,
-	513, 514, 515, 519, 521, 522, 523, 524, 526, 525,
-	530, 528, 529, 531, 532, 533, 534, 536, 538, 541,
-	542, 543, 545, 546, 547, 548, 549, 550, 551, 552,
-	553, 556, 558, 559, 560, 561, 562, 563, 586, 564,
-	566, 567, 568, 572, 573, 574, 575, 569, 570, 585,
-	577, 578, 579, 580, 582, 583, 588, 589, 590, 591,
-	592, 593, 594, 595, 596, 597, 599, 607, 620, 608,
-	609, 610, 611, 613, 616, 617, 618, 619, 605, 621,
-	622, 625, 626, 627, 628, 633, 629, 634, 630, 631,
-	632, 635, 637, 640, 641, 642, 649, 647, 648, 650,
-	651, 653, 654, 652, 661, 662, 656, 658, 659, 660,
-	667, 668, 670, 671, 672, 37, 57, 58, 61, 63,
-	65, 80, 81, 82, 88, 142, 144, 177, 190, 191,
-	204, 225, 226, 239, 241, 251, 252, 253, 279, 283,
-	284, 286, 292, 315, 393, 395, 412, 416, 433, 437,
-	441, 443, 461, 508, 537, 554, 571, 576, 600, 601,
-	602, 603, 612, 614, 643, 644, 645, 655, 669, -417,
-	2, -686, -372, -370, 704, -646, -413, 275, 4, -657,
-	-658, -392, -659, -660, 48, 90, 122, 221, 278, 255,
-	291, 293, 297, 317, 320, 362, 381, 387, 413, 415,
-	502, 544, -393, 706, 403, -386, 2, -361, -361, 444,
-	29, 2, 29, 432, 529, 590, 592, 2, -722, -467,
-	583, 2, 29, -364, -361, 118, 236, 527, -386, 2,
-	-722, 236, -467, 26, 583, 2, -361, 2, 417, 189,
-	222, 451, 23, 28, 77, 90, 113, 162, 188, 216,
-	-789, 419, 454, 511, 531, 585, 597, 613, 2, 648,
-	337, 528, 587, 270, 136, 618, -786, 519, -733, 516,
-	517, 417, 450, 593, 655, 503, 240, 636, -365, 2,
-	513, -361, 337, 2, 709, 109, 86, 508, 533, -190,
-	2, 327, 608, -191, -192, -189, 600, -644, 519, 503,
-	361, -361, 709, 709, 709, 29, -375, 2, -361, -375,
-	2, -260, 2, -375, -792, -267, -266, -265, 22, 480,
-	203, 308, 220, 259, 366, 447, 218, 53, -260, 2,
-	587, 270, 519, 136, 583, -397, 698, -399, -524, -786,
-	2, -245, 533, 564, 247, 52, 51, 86, 29, 453,
-	92, 424, 137, 145, 172, 619, 238, 583, 270, 271,
-	303, 95, 108, 109, -527, 49, 296, 79, 295, 517,
-	-738, 516, -586, 588, 223, 452, 521, 529, 582, 99,
-	308, 513, 608, 610, 118, 637, 504, 672, 458, 459,
-	580, 473, 577, 328, 181, 221, 683, 595, 593, 655,
-	4, 136, 361, 503, 535, 312, 311, 620, 600, 661,
-	327, 512, 427, 97, -803, 2, 608, -803, 2, 709,
-	2, 587, 423, 648, 528, 222, 451, 136, 458, 270,
-	618, 51, 162, 28, 79, -786, 683, 655, 519, -733,
-	680, 681, 337, 145, -715, 2, -714, 4, -663, -657,
-	-411, -410, 587, -786, 136, 655, 593, -401, -392, 698,
-	-400, 709, 709, 709, 709, 2, 295, 296, 456, 455,
-	533, 534, 29, 709, 709, 709, 709, 709, 709, 516,
-	189, 2, -786, 188, -746, 23, 28, 77, 108, 113,
-	145, 216, 419, 454, 531, 585, 589, 597, 613, -732,
-	564, 79, 519, -731, -733, 408, 337, 618, 162, -525,
-	136, 327, 234, 627, 592, 590, 624, 152, 282, 632,
-	630, 709, 709, 709, 709, -147, 2, 706, 33, 32,
-	-146, -97, -151, -85, 164, 543, 536, -298, 587, 287,
-	2, -361, 709, 709, 709, 2, 295, 296, 516, 517,
-	29, 709, 709, 220, -714, 583, 2, 709, 709, 709,
-	2, 29, 295, 296, 516, 517, 287, 2, 79, 522,
-	709, 709, 709, 709, 709, 709, 709, 709, 709, 709,
-	709, 709, 709, 709, 709, 709, 709, 709, 709, 709,
-	709, 709, 709, 709, 709, 709, 709, 709, 709, 709,
-	709, 709, 709, 709, 709, 709, 709, 709, 709, 709,
-	709, 709, -801, 2, 587, 608, 2, -803, 2, -803,
-	2, -804, 608, 669, 709, 709, 709, 709, 709, 709,
-	709, 709, 709, 709, 709, 709, 709, 709, 709, 709,
-	709, 709, 709, 709, 709, 709, 709, 709, 709, 709,
-	709, 709, 709, 709, 709, 709, -306, -308, -307, 709,
-	709, 709, 709, 709, 709, 709, 709, 709, -245, 533,
-	2, 86, 29, 29, -455, -458, 623, 285, 174, 409,
-	-305, -307, 2, -692, 620, 533, -642, 2, -558, -666,
-	-560, 696, 697, 689, 584, 78, -421, 384, 673, -572,
-	145, 624, 403, 381, -665, -561, -574, 177, 419, 508,
-	-485, 8, 9, 5, 6, 7, -372, -562, -568, 615,
-	194, 392, -414, 710, 10, 706, -689, -307, -573, 38,
-	241, 76, -371, -618, 286, -412, -392, -686, -687, -413,
-	-647, -621, -629, -628, -625, -624, -626, -632, -361, 90,
-	127, 128, 126, 131, 130, 330, 329, 132, 129, 535,
-	636, 77, 37, 251, 252, 292, 393, 253, 88, -688,
-	4, -657, -659, 283, 284, 554, 58, 461, 204, 163,
-	144, 142, 395, 63, 61, 644, -630, 138, 600, 601,
-	602, 603, 225, 226, 65, 190, 191, 416, 441, 576,
-	612, 614, 239, 315, -807, 645, 571, 80, 81, 209,
-	-694, 464, -695, -386, -694, 709, 709, 711, 709, -446,
-	-448, -450, 2, 29, 160, 706, 2, -592, 2, -593,
-	-597, -307, 309, -596, 706, -594, 704, -393, 404, -690,
-	509, -686, -687, -392, 708, 706, 222, 708, -451, 706,
-	-149, -126, -154, -177, -253, -254, 136, 519, 587, 91,
-	270, 108, 188, 222, -518, 706, -361, 29, 403, 604,
-	711, -722, -467, -447, 449, -570, 706, 403, 406, 220,
-	406, -722, 67, 106, -772, 251, 2, -771, -399, -772,
-	251, 2, 341, 2, 2, 2, 2, 2, 251, -361,
-	587, 135, 307, 2, 2, 2, 2, 2, 2, 2,
-	-477, 251, 2, -475, -399, 648, -478, 251, 2, -475,
-	-476, 251, 2, -475, -526, 2, 101, -376, 251, 2,
-	-361, -402, 251, 2, -397, -523, 251, 2, -561, 704,
-	-572, -408, 251, 2, -405, -361, -652, 251, 2, -650,
-	4, -657, 132, 535, -558, 2, -177, 2, 67, 86,
-	-361, 648, 2, 539, 2, 706, -190, 2, 82, 608,
-	48, 533, -191, 2, -544, 2, -545, -357, -358, -359,
-	-604, -360, 294, 448, 460, 676, 150, 384, 672, -777,
-	220, 688, 604, -642, -642, -642, -486, 708, -262, 60,
-	-375, -793, -792, -793, -640, 29, -635, 8, -636, 696,
-	697, -640, -640, -793, -793, 2, 2, 2, 2, 2,
-	-232, 666, 2, -245, 2, 209, 638, 2, 8, 2,
-	259, -284, -654, 521, 201, 459, 641, 106, 2, -649,
-	10, -648, 5, 4, -657, -663, -658, -660, 539, 2,
-	540, 459, 86, -527, 672, 86, 220, 2, 220, 2,
-	-508, 2, 666, 449, 220, 2, 2, -720, 2, 403,
-	238, 220, 2, 220, 2, 220, 2, 602, 220, 2,
-	220, 2, -244, 534, 609, 586, 455, 296, 666, 2,
-	-177, 663, -160, 209, 296, 295, -558, 663, 2, -739,
-	209, 517, -558, 2, 607, 305, 182, 220, -508, 2,
-	220, 2, 220, 2, 220, 2, 220, 2, 5, 2,
-	45, 456, 565, 2, 294, 448, 565, 2, 563, 2,
-	-393, 587, 648, 528, 136, 271, 525, 222, 451, 29,
-	2, 516, 189, 2, 2, 102, 103, 220, 2, 220,
-	-775, 2, 666, 235, 220, 2, 473, 220, 587, 29,
-	-523, 86, 684, 87, -487, 708, -487, 672, 2, -543,
-	-544, 2, -597, 251, -393, 2, -390, -645, 4, -657,
-	-663, -658, -664, 29, 32, 33, 34, 36, 38, 39,
-	40, 44, 64, 76, 77, 83, 89, 91, 101, 108,
-	118, 126, 127, 129, 128, 130, 131, 132, 145, 150,
-	155, 160, 161, 165, 170, 174, 194, 196, 209, 216,
-	220, 236, 240, 243, 259, 274, 285, 287, 309, 313,
-	321, 329, 330, 384, 392, 398, 403, 404, 408, 409,
-	430, 446, 468, 496, 527, 535, 557, 581, 587, 598,
-	604, 606, 615, 623, 624, 636, 638, 646, 663, 664,
-	665, 666, -665, 2, -597, 251, 2, -396, 251, -597,
-	-399, 2, -771, 2, -771, 2, -376, 2, -558, -726,
-	596, 184, 481, 2, -418, 251, -393, -395, -399, -397,
-	2, 516, -654, 2, 2, 2, -558, 2, 2, -523,
-	29, 684, -405, 2, -650, 251, 2, 29, 29, 648,
-	449, 287, 604, 711, -474, -410, -411, -641, 4, 8,
-	-466, -361, 708, -558, 2, -177, -160, 2, -558, 251,
-	2, -177, 251, 2, -558, 251, 2, -177, 251, 2,
-	-361, 2, -734, 2, -774, -654, 251, 106, -561, 251,
-	2, 251, -361, 2, 222, 451, -788, 511, 617, 341,
-	2, 2, 613, 2, 113, 587, 135, 2, 2, 2,
-	2, 2, 2, 2, 587, -381, 2, -361, 209, -606,
-	287, -405, 251, -406, 2, 528, -802, 464, -650, 251,
-	2, 486, 648, -397, 251, 2, -397, 270, 289, -376,
-	251, 2, 592, 590, 592, 590, -469, 2, 54, 287,
-	2, 287, 2, -598, 2, -599, -593, -600, 704, 404,
-	-610, 2, -609, -648, 643, -147, 706, -147, 706, 533,
-	706, -654, -393, -393, -558, 2, -177, -160, 2, -558,
-	2, -177, 2, -361, 2, -174, -654, -173, 706, 220,
-	637, -361, 2, -558, 2, -177, -160, 2, -558, 2,
-	-177, 2, -298, 209, 2, 136, 587, -498, -597, -543,
-	604, -455, -458, -245, 539, 2, -312, -496, -314, 209,
-	-530, -531, -315, 321, 196, 398, -316, -507, 29, 160,
-	-507, -507, 67, 707, 707, -777, 620, 11, 12, 89,
-	45, 696, 697, 698, 699, 207, 700, 701, 694, 695,
-	693, 686, 687, 691, 300, 301, 110, 690, 688, 100,
-	335, 510, 197, 198, 199, 200, 482, 268, 35, 42,
-	269, 14, 15, 16, -421, 34, 408, 320, 673, 255,
-	544, 689, 17, 18, 19, 291, 293, 387, 57, 259,
-	-369, 419, -420, 584, 78, -558, -558, -558, -558, -558,
-	-558, -558, -558, 415, 706, -492, -553, 704, -307, 706,
-	706, 706, 706, -641, -307, -558, -572, 707, -483, 706,
-	-307, -572, -567, 706, 508, 704, 706, -575, -558, 5,
-	5, 5, 706, 708, -697, 667, 209, 706, 706, 706,
-	706, 706, 706, 706, 706, 706, 706, 706, 706, 706,
-	706, 706, 706, -623, 706, 443, -622, 706, -622, -622,
-	-634, 649, 706, 706, -620, 706, 675, 668, 706, -620,
-	706, 706, 706, 706, 706, 706, 706, 706, 706, 706,
-	706, 706, 706, 649, -786, 711, -694, -539, 706, 706,
-	-488, -602, -558, 698, -488, -488, 403, -480, -558, 122,
-	-511, 297, 362, 221, 317, 502, 278, -555, 710, -555,
-	-585, 675, -307, -594, -307, -596, 706, -592, -585, -148,
-	-641, -126, -144, -154, -177, -193, -253, -254, 698, -393,
-	706, 220, 708, -645, 707, -480, 646, 29, 160, 698,
-	2, -639, 8, -645, 220, 604, -466, 707, 709, 709,
-	709, 709, -376, -405, -393, -412, -413, -418, -387, -361,
-	2, 2, 159, -480, -716, 618, 519, 29, 4, -663,
-	-657, -411, 528, -410, 587, 136, 189, 222, 451, -652,
-	-364, 604, 39, -569, -615, -616, -668, 710, -667, -618,
-	-627, 433, 437, -647, 286, 4, -657, -659, 283, 284,
-	554, 58, 461, 204, 144, 142, 395, 63, 61, 644,
-	600, 601, 602, 603, 225, 226, 65, 645, 571, 80,
-	81, -716, 618, 519, 29, 528, 209, -652, 209, 220,
-	-652, 2, -654, 2, -335, 711, 75, 492, 177, -754,
-	706, -335, 177, 2, 177, 2, 2, 2, -361, -335,
-	177, 711, -477, 251, -335, 177, -335, 177, -419, 251,
-	-418, -335, 177, -335, 711, 177, -142, 256, 177, -558,
-	222, -335, 711, 177, 708, 711, 177, -652, 2, -526,
-	-644, -480, 39, -544, 2, 145, 4, 5, -805, 711,
-	319, -424, 334, 383, 246, 404, 670, 396, 150, -653,
-	5, 4, -568, -580, 145, 327, 286, -635, -637, 9,
-	-638, 696, 697, -643, -642, 125, 708, -645, -263, 281,
-	43, -375, -375, -793, -793, 8, 8, -793, -793, -375,
-	-375, -233, 487, 73, 587, 298, -173, -654, 220, 259,
-	-287, 666, -654, -654, -654, -654, -654, -644, 29, -775,
-	2, 540, 2, -244, 534, 609, 103, 540, 2, -393,
-	587, 136, 270, 93, -743, 209, 2, -361, -721, 209,
-	-717, 503, 519, 618, -716, -721, -393, 136, -393, 136,
-	-393, 136, -393, -393, 2, 2, 2, 2, -286, -285,
-	179, 666, 2, 98, 517, 516, 2, -177, -558, 2,
-	666, 98, 2, 51, 559, 79, -739, 209, 2, 607,
-	2, 607, 2, -361, -361, -361, -361, -361, 398, 564,
-	319, 666, -199, 666, -393, -393, -396, -399, -394, -399,
-	220, 271, -399, -399, 521, 588, 619, 517, 189, -558,
-	2, 106, -794, 2, 220, 209, 2, 587, 270, 270,
-	587, 136, 126, -776, 588, 271, 158, 303, 186, 220,
-	86, 136, 29, 220, 587, -786, 514, -523, 29, 708,
-	4, -332, 484, 536, 418, -331, 25, 30, 164, 272,
-	367, 641, 183, -436, 273, 489, -433, 423, 177, 558,
-	629, -726, -729, 515, 596, 184, 481, 104, 396, 536,
-	418, 484, 177, -504, -506, 39, 134, 367, 417, 68,
-	264, 339, 340, 562, 490, 655, 177, 536, 418, 484,
-	-762, 484, 536, 418, -749, -764, 367, 70, 498, 570,
-	257, 561, 659, 189, 526, 316, 384, 116, 509, 578,
-	420, 484, 536, 418, 418, -16, -350, 25, 164, -352,
-	-343, 536, 30, -729, 114, 484, 685, 679, 489, 429,
-	579, 446, -729, -726, 314, -728, 660, 382, -334, 558,
-	629, -726, -465, -729, 515, 484, -333, 384, 657, 656,
-	658, -438, -433, 423, 177, 710, 25, 164, 484, 536,
-	418, -780, -781, 30, -641, 2, -330, 259, -329, 25,
-	-325, -324, 25, 164, 536, 633, 484, 562, 568, 426,
-	494, 98, 536, -186, 236, 501, -166, -185, 489, -186,
-	2, 536, 29, 484, 418, -723, -383, -691, 259, 666,
-	177, -383, -383, -597, 251, -743, 209, 2, -736, -173,
-	310, 5, 10, -173, -474, 711, 711, -645, 698, 177,
-	177, 177, 177, 296, 209, 384, -774, 2, -120, 320,
-	384, 384, 666, -766, 2, -399, -766, 2, -789, 2,
-	2, 2, 2, 2, 2, 2, -393, 251, -453, 403,
-	-712, -713, -791, 587, -272, 666, -654, 384, 48, -396,
-	251, 2, 648, -723, 384, -731, -398, 251, -393, 39,
-	706, 384, 2, -526, 2, 270, -691, 384, 220, 706,
-	-415, -393, -593, -415, 536, -386, 39, -555, -393, 707,
-	711, -610, -610, -654, -272, 220, 706, -298, 666, 666,
-	296, -605, 711, -604, 259, -655, -654, -174, -654, 220,
-	296, -654, -712, -376, 2, -393, 2, -335, 711, -365,
-	-312, -496, -644, -497, -496, -313, -312, -315, 209, 460,
-	630, 367, 541, 302, -531, -530, 29, -558, -535, 203,
-	366, -558, -533, -560, 696, 697, -636, -638, -479, 396,
-	-306, -306, -306, -460, -587, -588, -558, 446, 277, -643,
-	-777, -617, -615, -615, -391, -645, 600, -558, -558, -558,
-	-558, -558, -558, -558, -558, -558, -558, -558, -558, -558,
-	-558, -558, -558, -558, -558, -558, -558, -558, -558, -558,
-	-558, -558, -558, -558, -558, -558, -558, -558, -558, -558,
-	-558, -558, -558, -558, 320, 255, 544, 57, 259, -558,
-	604, -558, -558, -558, -558, 359, 384, 392, 615, 194,
-	625, 160, 396, -808, 581, 44, -565, -307, -484, 706,
-	-579, 36, 557, 29, -572, 706, 2, -553, -558, -554,
-	-422, -420, -361, 696, 697, 698, 699, 700, 701, 686,
-	687, 688, 14, 15, 16, 691, 695, 693, 694, 207,
-	110, 690, 335, 510, 100, 197, 198, 199, 200, 300,
-	301, 17, 18, 19, 35, 42, 689, -481, -480, -480,
-	707, 711, 39, 707, -558, -481, -571, -567, 704, -480,
-	-578, -577, 663, -519, -520, 671, 345, 139, 249, 342,
-	-521, 524, -639, -645, 698, -698, 202, 240, 706, 707,
-	2, 707, 2, 707, -558, 2, 707, -558, 2, 707,
-	-558, 2, 707, -558, 2, 707, 2, 707, 2, -558,
-	-558, -558, -558, -558, -558, -558, -480, 8, -639, 706,
-	-639, -639, -639, 600, 600, -639, -639, -639, -631, 433,
-	434, 435, 436, 322, 323, 324, 325, 437, 438, 439,
-	440, 351, 352, 353, 354, 347, 348, 349, 350, 355,
-	356, 357, 358, 230, 231, 232, 233, 226, 227, 228,
-	229, -631, -513, 2, -633, -480, 4, 671, 345, 139,
-	249, 342, 524, 5, -513, 2, -514, 2, -558, -480,
-	-515, -559, -560, 696, 697, 689, -421, -516, 2, -558,
-	-481, -558, 64, 313, 606, -517, -558, 220, -480, -480,
-	2, -480, 2, -523, 2, -695, 39, -540, -361, -480,
-	-470, 711, 220, 45, 34, 408, 320, 255, 544, 291,
-	57, 259, 39, -662, 419, 4, -661, 21, 22, 23,
-	24, 25, 26, 27, 28, 29, 30, 31, 32, 33,
-	37, 36, 40, 43, 44, 41, 46, 47, 48, 49,
-	50, 51, 52, 53, 54, 55, 56, 58, 60, 61,
-	63, 64, 65, 62, 66, 67, 68, 69, 70, 71,
-	72, 73, 74, 75, 76, 77, 79, 82, 83, 84,
-	85, 86, 87, 88, 90, 91, 92, 93, 94, 95,
-	96, 97, 98, 99, 101, 102, 103, 104, 105, 106,
-	107, 108, 109, 111, 112, 113, 114, 115, 116, 117,
-	119, 120, 121, 122, 123, 124, 125, 126, 127, 129,
-	128, 130, 131, 132, 133, 134, 135, 136, 137, 148,
-	143, 140, 141, 142, 144, 149, 145, 146, 150, 151,
-	147, 152, 153, 154, 155, 156, 157, 158, 159, 160,
-	161, 162, 163, 164, 165, 166, 167, 168, 169, 170,
-	171, 172, 173, 175, 176, 178, 179, 177, 180, 183,
-	181, 184, 182, 185, 186, 187, 188, 189, 190, 191,
-	192, 193, 194, 195, 201, 203, 204, 208, 210, 212,
-	213, 214, 211, 215, 216, 217, 218, 219, 221, 222,
-	223, 224, 225, 226, 230, 231, 232, 233, 227, 228,
-	229, 234, 235, 237, 238, 239, 241, 242, 244, 245,
-	246, 247, 248, 250, 251, 252, 253, 254, 256, 257,
-	258, 260, 262, 263, 261, 264, 265, 266, 270, 271,
-	277, 276, 275, 272, 274, 273, 278, 279, 280, 281,
-	282, 283, 284, 286, 288, 289, 657, 290, 292, 294,
-	295, 296, 297, 298, 302, 303, 304, 305, 306, 307,
-	308, 309, 310, 312, 311, 313, 316, 314, 315, 317,
-	318, 319, 322, 323, 324, 325, 326, 327, 328, 329,
-	330, 331, 332, 333, 334, 336, 337, 340, 338, 341,
-	339, 343, 344, 346, 347, 348, 349, 350, 351, 352,
-	353, 354, 355, 356, 357, 358, 361, 359, 362, 363,
-	364, 365, 366, 367, 368, 369, 370, 371, 372, 373,
-	374, 375, 381, 382, 383, 376, 377, 384, 385, 386,
-	388, 389, 390, 391, 380, 378, 379, 392, 393, 394,
-	395, 396, 397, 400, 402, 404, 405, 406, 407, 410,
-	411, 412, 413, 416, 417, 418, 420, 421, 422, 423,
-	424, 425, 426, 427, 428, 429, 430, 431, 432, 433,
-	434, 435, 436, 437, 438, 439, 440, 441, 442, 444,
-	445, 446, 447, 448, 449, 451, 452, 453, 454, 455,
-	456, 457, 458, 459, 460, 461, 462, 463, 465, 464,
-	466, 467, 468, 469, 471, 472, 473, 479, 480, 488,
-	481, 483, 484, 485, 486, 487, 489, 490, 491, 492,
-	493, 494, 495, 499, 497, 498, 500, 501, 502, 503,
-	504, 505, 506, 507, 508, 509, 511, 512, 513, 514,
-	515, 516, 517, 519, 521, 520, 518, 522, 523, 525,
-	526, 527, 528, 529, 530, 531, 532, 533, 534, 535,
-	536, 537, 538, 539, 540, 541, 542, 543, 545, 546,
-	547, 548, 549, 550, 551, 553, 552, 554, 556, 557,
-	558, 559, 560, 561, 562, 563, 586, 564, 565, 566,
-	567, 568, 572, 573, 574, 575, 569, 570, 571, 585,
-	576, 577, 578, 580, 579, 581, 582, 583, 587, 588,
-	589, 590, 591, 592, 593, 595, 594, 596, 597, 598,
-	605, 599, 600, 602, 603, 601, 607, 620, 606, 608,
-	609, 610, 611, 612, 613, 614, 615, 616, 617, 618,
-	619, 621, 622, 624, 625, 626, 627, 628, 633, 629,
-	634, 630, 631, 632, 635, 636, 637, 638, 640, 641,
-	642, 643, 644, 645, 646, 647, 648, 650, 651, 653,
-	654, 652, 655, 661, 662, 656, 658, 659, 660, 663,
-	669, 670, 672, -470, -470, 706, 707, 711, -512, 244,
-	338, 333, 289, -512, -592, -511, 297, -509, 413, -509,
-	-509, -585, -377, 704, 713, -645, -585, -582, -581, 39,
-	-386, 410, -585, -585, 707, -584, -583, 39, -386, 705,
-	-710, 706, 709, 709, 709, 709, 709, -393, 706, -645,
-	708, -459, 711, -456, 409, -558, -480, -480, 707, 705,
-	708, 566, 2, 567, 2, 707, 604, 291, 291, 291,
-	291, 291, 403, 509, 707, 604, -718, -402, -408, 529,
-	588, 223, 452, -474, 711, -474, -466, 106, -772, -772,
-	666, -652, -146, 405, 707, 711, -468, 38, 704, 708,
-	-639, 2, 2, -520, 706, 220, -718, -408, 588, 529,
-	223, 452, 2, -722, 583, -467, -652, 604, -771, -772,
-	-755, 707, -757, -765, -750, -759, 259, 412, 279, 646,
-	-646, -615, 4, -657, -772, -361, 2, -477, -399, -335,
-	177, -478, -476, -335, 711, 177, -376, -397, -402, -523,
-	705, -405, -408, -361, -650, -652, -335, -398, -777, 707,
-	608, -545, -423, 460, 556, 485, 530, 583, 9, 9,
-	711, -645, -264, 518, 367, -375, -375, -375, -375, 711,
-	565, -393, 209, -654, -173, -289, 407, -288, 41, 84,
-	547, 391, 140, 266, 304, 169, 449, 168, 143, -287,
-	-287, -287, -287, -291, 666, 2, 2, 2, 2, -508,
-	-393, -376, -418, -393, -404, 259, 237, 29, -733, 708,
-	-652, -652, -408, -409, -407, -361, -402, -508, -376, -508,
-	-376, -508, -376, -508, -508, 711, 158, -286, 179, -177,
-	-177, -558, -286, -558, 564, 2, 533, 209, 209, 708,
-	-508, 708, 708, 8, -454, 496, 5, 466, -199, -199,
-	-393, 220, 2, 107, -654, 2, 458, 136, 587, 423,
-	270, -393, -418, -418, -393, -376, -775, 711, 136, -376,
-	137, 136, -393, -523, 4, 711, -778, 108, 604, 91,
-	706, 519, -354, 328, 604, -549, 251, 91, -669, 108,
-	-379, -670, -361, 83, 624, 446, 216, 175, -778, 108,
-	446, -778, 108, 2, 272, 108, 536, 564, 706, 29,
-	67, -597, 45, 45, 29, -727, -728, 314, 220, 672,
-	587, 270, 519, 604, 604, -597, -506, -615, 134, 339,
-	340, 67, -640, -640, 67, -640, -640, -640, 666, -640,
-	666, -396, -597, 519, 604, 604, -787, -764, 492, 536,
-	604, 519, 604, 154, 403, 392, 526, 147, 290, 316,
-	-580, -580, -361, 604, 519, 604, 604, 471, 577, 471,
-	577, 525, -343, -345, -191, 525, 577, 328, 604, 604,
-	-191, 29, -245, 493, 145, -806, 688, 471, 314, -728,
-	604, 220, 711, 45, 45, 29, -727, 220, 604, 656,
-	9, -418, -377, 642, 47, 642, 47, 642, 604, 47,
-	519, 604, 711, 47, -327, -326, 536, -329, -654, -328,
-	365, -324, -712, -712, -271, -270, -361, 5, -466, 604,
-	532, 2, 532, 2, 487, 487, 487, 86, 487, 74,
-	29, 2, 74, 29, 2, -186, 2, 604, 604, -16,
-	536, -724, -366, 121, 373, 332, 374, 112, 370, 111,
-	369, 119, 371, 120, 372, 650, 388, 651, 389, 72,
-	368, 343, 375, 560, 377, 654, 390, -367, -368, 487,
-	376, 167, 425, 640, 136, -650, -16, -16, 536, 418,
-	484, 177, -744, 259, 29, 259, -605, 259, -605, -410,
-	-361, 708, -558, -177, -558, -177, 51, 79, 177, 39,
-	220, -523, 177, 177, 2, 706, 706, 307, 706, -427,
-	384, 220, -466, -606, 711, -393, 39, -271, 407, 177,
-	-650, -505, -504, 384, -398, 251, 2, 177, -802, -451,
-	384, 171, 706, 458, 2, 177, -378, 251, -362, -361,
-	-526, -337, 591, 177, -598, -503, -502, 546, -536, -177,
-	706, 145, 39, -536, -489, -490, -603, -491, -379, 706,
-	-386, -555, -147, -609, 707, 707, 707, -298, -452, -380,
-	-379, 135, 462, 462, -278, 666, -173, -174, 707, 711,
-	-605, 259, -174, -654, -272, -272, -605, -605, -597, -497,
-	-313, 404, 302, 541, -533, -534, -560, 508, 509, -534,
-	508, 509, 8, 9, 8, 9, -317, 547, 391, -476,
-	711, -322, 40, 155, 302, -393, -643, 672, 173, -558,
-	-558, 604, -808, 581, -565, 173, -558, 359, 392, 615,
-	194, 625, 160, 396, 220, 706, -559, -559, 707, -482,
-	-558, -558, 705, 715, 707, 708, 707, -459, 708, -480,
-	-466, 705, 705, 711, 707, -576, -577, 165, -558, 604,
-	604, 604, 604, 706, 707, 708, -703, 414, 706, 706,
-	-558, 707, 707, 707, 707, 39, 711, 711, 711, 707,
-	711, 711, 711, 707, 707, 707, 711, -639, 707, 707,
-	707, 672, 672, 707, 707, 707, 707, 711, 707, 711,
-	707, 220, 707, 707, -522, 430, 707, 11, 12, 696,
-	697, 698, 699, 207, 700, 701, 694, 695, 693, 686,
-	687, 688, 100, 335, 510, 14, 15, 16, -421, 291,
-	259, -559, -559, -559, -559, 707, -563, -564, 220, 209,
-	39, -517, -517, -517, 707, 220, -480, 707, 707, -696,
-	337, 384, 707, 711, 707, -552, -551, 664, -602, -471,
-	2, -592, -388, -645, -552, -552, -480, -558, 297, 297,
-	-510, 638, 403, -512, -592, -582, -641, -557, -556, 211,
-	40, 155, 378, 379, 380, 254, 215, 195, -582, -386,
-	-539, -582, -582, -585, -386, -537, 706, -585, -581, 707,
-	-711, -641, 707, -472, -595, -690, 708, -645, 707, 646,
-	67, -459, -459, 707, -645, -293, -691, -293, 567, 2,
-	-246, 5, 392, -246, -246, -246, -246, -393, -652, 604,
-	604, 259, 259, 259, 259, -474, -466, 26, -742, 666,
-	431, -615, 704, 705, 8, -645, -639, -652, 220, 220,
-	259, 259, 259, 259, 403, -722, 220, -650, -335, 707,
-	711, -750, -759, -765, -759, 412, -335, 2, -335, -477,
-	-335, -335, -418, -419, -335, -335, -142, -335, -501, 666,
-	-642, -544, 622, 96, 460, 600, -642, 133, 518, 487,
-	73, -272, 587, 259, -287, 711, 706, 546, 688, 688,
-	688, 688, -292, 407, -290, 610, 600, 101, 710, 519,
-	-652, 504, -652, -361, 708, -508, -508, -508, -285, 533,
-	533, -361, -361, -361, 209, -466, -393, 2, -389, -645,
-	-376, -393, -390, -418, 209, 209, -775, -775, -775, 588,
-	271, 158, 186, 303, -376, -376, -331, 484, 536, -379,
-	-379, -393, -302, -301, -299, -361, 5, -403, -361, 234,
-	472, -650, 384, -549, 251, -336, 384, 251, -387, -615,
-	706, -528, 668, 302, 302, 638, -379, -387, 302, 251,
-	-379, 251, -387, 2, -387, -725, 460, 397, -558, -300,
-	-299, 67, -434, 326, 458, 385, -332, 484, 536, 418,
-	-177, -177, -177, 706, -777, 638, 159, -393, -418, -393,
-	-403, -650, -398, 536, 418, 484, 381, -412, -640, -640,
-	-640, -504, 536, 418, 484, -403, -650, -396, -361, -403,
-	-650, 403, 392, 403, 147, 290, -361, -403, -650, -650,
-	-342, 251, -361, 5, 471, -342, 251, 471, 471, 471,
-	471, 234, 472, 519, -376, 471, 672, 50, -806, 604,
-	220, -558, -558, -333, -177, -177, -177, 706, -377, -334,
-	-465, 484, 5, 251, -379, 5, -379, 251, 5, -361,
-	-379, -403, -650, -781, 25, 164, -379, 711, 306, 287,
-	666, -735, 221, 516, 465, -330, 688, -272, 711, 688,
-	688, -561, 189, 542, 604, -283, -282, 495, 494, -36,
-	-35, -644, 73, -36, 73, -403, -650, -366, 425, -736,
-	392, 5, 10, 634, -376, -723, -383, 519, 604, 604,
-	-597, -740, -741, 236, 501, 519, 504, -173, -275, 666,
-	-173, -269, 265, 698, -715, 2, -712, -607, 2, 287,
-	-654, -654, 487, -561, -361, -752, -753, -756, -757, -752,
-	-361, -425, -428, -426, -379, -550, -549, -673, -674, -669,
-	320, 275, 276, 624, 289, 195, 108, -303, -304, 668,
-	666, 177, -416, -393, 704, -272, -713, -608, 195, 527,
-	706, -405, -406, 177, -451, 384, -650, 648, 39, 177,
-	706, -614, -613, -361, 2, -397, 403, 384, -378, 251,
-	-338, 166, -806, -376, -500, 638, 707, 711, -558, -499,
-	-542, 496, 403, -452, 643, -386, -499, -473, 711, 220,
-	688, 708, -452, -601, 698, -147, -147, -272, 706, -654,
-	707, 711, 708, 706, 688, 688, -280, 407, -279, 169,
-	304, 288, 549, 550, 551, 552, 553, 157, 548, 141,
-	364, -782, 266, -783, -784, 520, 647, 628, 179, 180,
-	483, 262, 263, 594, 661, 593, 662, -605, -654, -278,
-	-174, -605, 259, 220, -94, 666, 630, -534, 404, 331,
-	-587, -588, -323, 674, -393, 710, -558, -558, 173, 173,
-	-558, -559, -559, -558, 173, 220, 706, -558, -569, 34,
-	34, 707, 711, -554, -558, -420, 707, 698, -645, 710,
-	707, -567, 170, -558, 598, 345, 249, 342, -521, 342,
-	-521, -521, -639, 5, -645, 698, -704, -382, 706, -361,
-	664, -457, 409, 707, -617, -615, -558, -558, -558, -558,
-	-558, -639, 707, -620, -620, -635, -635, -558, -563, -558,
-	-617, -615, -559, -559, -559, -559, -559, -559, -559, -559,
-	-559, -559, -559, -559, -559, -559, -559, -559, -559, -559,
-	-559, -559, 160, 384, 396, -559, -564, -563, -558, -558,
-	-615, 707, 707, 707, -480, 706, 337, -361, -493, 240,
-	-558, -605, 711, -493, -493, 707, -592, -592, 706, -558,
-	297, 705, 711, 714, 688, 688, 688, -539, -581, -537,
-	-538, -541, -361, -582, 705, 707, 711, 707, 711, -584,
-	-645, -558, -461, -587, 707, 707, 708, -552, -295, 706,
-	-294, 156, 60, 123, 153, 392, 400, 219, 245, 457,
-	173, 210, 166, -293, 291, -742, -652, -652, 519, 519,
-	519, 519, 406, 236, 5, 8, 704, 705, 708, 707,
-	-652, -652, 519, 519, 519, 519, -716, 618, 519, 29,
-	220, -652, -757, -759, -759, -335, -335, 135, 367, -558,
-	-261, 666, 668, 565, -393, -173, -288, -289, -173, -173,
-	-654, -654, 711, 706, 688, 688, 688, 698, -403, -404,
-	-404, 698, -508, 5, -440, -439, 423, 396, -440, 508,
-	508, 604, 604, 707, 711, 688, 67, 259, 177, 384,
-	640, 384, -670, 175, -675, -558, 706, 270, 706, 706,
-	2, -319, -320, -321, 164, 536, 25, -779, 2, 638,
-	177, -335, 177, -335, 670, 707, 711, -434, 706, 706,
-	604, 519, -354, 604, 666, -480, -558, -273, 145, -644,
-	-729, 710, -729, 710, 519, 604, 604, 519, 604, 604,
-	188, 280, 392, 384, -342, 177, -342, 251, -806, -342,
-	-729, -729, 259, 666, 193, 193, 672, -342, -558, -558,
-	209, 604, 666, -480, 604, -619, 55, 27, 384, -397,
-	-335, 177, 604, 604, 618, 536, -326, -654, -173, -276,
-	169, 500, 157, 304, 266, 179, -782, 631, 51, 406,
-	-736, -173, -270, -654, -654, 583, 310, 711, 688, 602,
-	711, -777, -736, -654, 392, -16, -403, -650, -398, 536,
-	418, 484, -722, -722, 236, -408, -744, -605, -277, 407,
-	-276, -605, -275, 220, 287, -607, -272, -654, 396, -120,
-	666, 707, 711, 145, 688, 707, 2, 707, 707, 711,
-	711, -676, -336, -393, 706, -361, 270, 275, 276, -385,
-	-362, 39, 400, 400, 706, -393, -122, -123, 666, -124,
-	605, -604, 638, -551, -641, -384, -361, -488, -271, 48,
-	-396, 39, 177, -723, -398, -177, -398, -611, -612, 5,
-	707, 711, -616, 39, -393, 177, 403, 384, -339, 312,
-	-806, -649, -691, -552, -471, -502, -499, -488, 386, 105,
-	707, -552, -490, -471, -558, 2, 707, -654, -272, -298,
-	-380, 2, -655, -654, -654, 711, 706, 688, 688, 688,
-	688, 688, 688, 688, 688, 688, 328, 151, -278, -605,
-	-278, -174, -177, 407, 404, 203, 308, -322, -377, -558,
-	-558, 173, 34, 34, -558, -558, -569, 707, -558, -558,
-	-480, 705, 5, 8, -558, 707, 708, -705, -361, -558,
-	707, 67, 707, 707, 711, 711, 707, 707, 707, 707,
-	707, 707, 707, -564, 220, 160, 396, 706, 707, -146,
-	-566, 243, 67, -592, -566, -566, -510, -466, -592, -556,
-	-377, 704, -377, 704, 704, 707, 711, -615, -641, -595,
-	-459, 711, -645, -294, -297, -296, 156, 217, 153, 392,
-	400, 219, 245, 457, 173, 214, 212, 213, 166, 688,
-	-654, -654, 2, 2, 5, 5, 457, 384, 392, 5,
-	-246, -742, -742, 666, -408, -408, -408, -408, 406, 705,
-	2, 704, -645, -408, -408, -408, -408, 220, -718, -408,
-	588, 223, 452, -652, 135, 209, 248, 248, -272, -287,
-	707, -290, -292, -654, -654, -558, -390, 587, 270, 706,
-	706, -379, -379, -301, -642, 587, 508, -342, 446, -549,
-	177, 177, -677, 108, -679, 89, 195, 118, 384, 392,
-	624, 446, 83, 145, 403, 468, -796, -797, -798, 39,
-	677, 678, 707, -462, -589, -690, 706, -361, -462, -466,
-	384, 574, 145, 403, 384, 145, 403, 656, 135, 2,
-	618, 92, -379, -387, -299, -466, -466, -393, -403, -650,
-	185, 707, 711, 688, 2, 698, 698, -403, -650, -398,
-	-403, -650, -396, -361, 280, 177, 643, -342, 177, -342,
-	643, -342, 421, 193, 604, -177, -558, 185, 707, -377,
-	5, 5, 177, -374, 89, -379, 5, -379, -397, 135,
-	688, 688, 688, 688, 688, 328, 688, 688, 31, -736,
-	-270, 666, 600, -282, -561, 688, -35, -642, 519, 604,
-	604, 403, 403, 406, -740, -741, -275, 711, 706, -275,
-	-655, -173, -272, 39, -561, 220, 2, 498, -756, -558,
-	-558, -760, -761, -763, 39, 307, 611, 665, -764, -441,
-	272, -379, -674, -671, -672, 446, -550, -678, -680, 195,
-	446, -429, -462, 706, -378, 706, -361, 706, -177, 2,
-	-302, 706, -427, -124, 407, 9, 192, 705, 220, 707,
-	-650, -505, -177, -398, -451, -449, 666, -451, 707, 711,
-	-361, 171, 706, -529, 638, -377, -393, 177, -340, 311,
-	-806, -649, -337, -458, -455, 161, 706, 403, -177, -458,
-	688, 707, 135, 707, -279, -280, -654, -173, -654, -654,
-	-654, -558, -173, -654, -654, 688, 115, -278, -605, -95,
-	-96, 270, 275, 108, 428, -322, -558, -558, -558, 707,
-	698, -699, 423, 707, -587, -588, -558, -558, -559, 220,
-	706, -569, 707, -700, 665, -558, -494, -495, -558, 506,
-	124, 241, -700, -700, 707, -641, -641, -641, -541, 707,
-	-587, -588, 707, 711, -654, 60, 123, 597, 5, -654,
-	-654, 2, 2, 615, 194, 5, 5, 2, 2, 2,
-	5, -654, 2, 392, 2, 2, 2, 604, 604, 604,
-	604, 704, 2, 220, 220, 220, 220, -652, 220, 220,
-	259, 259, 259, -177, 707, -393, -418, -480, -480, 259,
-	39, 471, -549, -387, -387, -391, -384, 195, 251, 392,
-	656, -528, 302, 706, -559, 630, -393, 706, 2, 250,
-	250, 31, 67, -799, 150, 274, 707, 711, -590, -373,
-	-361, -558, -590, 707, 707, 392, 630, 392, 656, -558,
-	630, -615, 706, -335, -335, 707, 707, -558, 604, -644,
-	115, -642, 2, -729, -342, -351, -342, -351, -729, -376,
-	-558, 209, -558, 604, 5, -335, -391, -335, -335, -374,
-	618, -654, -558, 615, 194, -173, -173, 688, -558, -558,
-	402, -558, -561, -403, -650, -398, -745, 588, 529, 619,
-	521, 223, 507, -745, 209, -276, -277, -275, -735, 527,
-	403, 487, -747, 587, -770, -767, 56, 497, -763, -751,
-	5, -649, -435, -436, 2, -676, 302, -384, 302, 261,
-	176, 707, -462, 706, -462, 706, -466, -795, 666, 707,
-	-425, -303, -123, -719, -415, -451, 39, 367, 135, 39,
-	5, -616, 706, -614, 706, -361, 403, 706, -377, -356,
-	106, -806, -649, -338, -532, -530, 385, -466, 108, -532,
-	-565, -272, 706, -272, 707, -654, -278, 711, 29, 706,
-	29, 706, -459, 67, 711, 711, 707, 707, -559, -569,
-	707, -701, -702, -382, 711, 706, 706, 538, 705, 705,
-	705, -296, 2, 2, -652, -652, -652, -652, 2, -652,
-	-652, -652, -652, -652, -652, 519, 519, 519, 707, 707,
-	-342, 446, -361, -670, -679, -384, 384, -304, 638, 666,
-	-558, -559, -363, 706, -558, 706, 706, 39, 145, 274,
-	151, 256, -548, -800, 117, 575, 260, -589, -322, 707,
-	-547, 638, 468, -559, -374, -462, 706, 706, 706, 688,
-	220, 711, -177, 706, -619, -335, -397, -654, 688, 604,
-	2, 220, -722, 707, -735, -274, 666, -488, -561, 396,
-	-748, 537, 46, -558, -773, 711, -303, 706, -304, -430,
-	94, 109, 146, 250, 224, 271, 564, 572, 29, -430,
-	-547, 707, -462, 707, -462, 707, -431, 403, 135, 367,
-	707, 39, -552, 39, -177, 135, -177, -611, 707, -462,
-	-393, -462, 403, -344, -343, 321, -649, -339, -499, 707,
-	-387, -499, -655, -96, -466, -466, -706, 458, 509, 242,
-	-480, -460, -460, 707, 711, 39, -495, 2, 2, 2,
-	-742, -742, -742, -742, -408, -408, -408, 471, -336, 177,
-	244, 707, -681, 336, -361, 707, -505, -505, 39, 151,
-	256, -437, -433, 706, -323, -590, -304, 244, -393, -730,
-	638, 707, -443, -442, -439, -445, -444, -439, -480, -642,
-	115, 421, -342, -480, -374, -173, -652, -652, 403, -737,
-	221, 516, 220, -281, 666, -561, -758, -759, -769, 5,
-	-431, -463, -591, -379, -548, -547, 707, -437, 707, 95,
-	135, -441, -177, -177, 2, -449, 707, 707, -529, 707,
-	-393, -341, -656, 471, 473, -806, -340, -552, 161, 707,
-	707, 707, 707, -707, -708, 57, 621, 125, -558, -707,
-	-707, -702, -704, 220, 220, 220, 195, -546, 675, -682,
-	-685, -684, 682, 545, 221, 422, 707, 574, 655, 707,
-	707, -799, -466, -546, -451, -558, -547, 707, 711, 643,
-	707, 711, 643, 707, 220, 707, -335, -742, -335, -745,
-	-274, 51, 407, -719, -283, 407, 403, -760, -768, 170,
-	-3, -767, -355, -354, 707, 711, -437, -548, -547, -304,
-	-437, 445, 152, 164, -435, -795, -547, 706, -548, 706,
-	-353, -352, -806, -635, -356, 161, 385, 630, -272, -709,
-	175, -708, 442, 208, 508, 442, 208, -709, -709, -652,
-	-652, -652, -384, -304, 62, -684, 682, -685, 682, 630,
-	152, -552, 707, -681, -304, -442, 259, -444, 220, 421,
-	220, -736, 31, -271, 706, -552, 706, -561, -770, 712,
-	-304, -591, -304, -437, -548, -552, -304, 509, 509, 2,
-	-303, -431, -548, -462, -437, -462, -349, -350, -351, -344,
-	385, 630, 536, 125, 240, 599, 367, 34, 688, -683,
-	367, 492, 75, 536, -683, -682, 706, 706, -652, -271,
-	-735, -283, -281, -552, -304, -437, -464, 384, 657, 656,
-	658, -552, 2, -431, -437, 707, -304, 707, -651, 418,
-	-341, 536, -489, 508, 411, -708, -558, 24, 392, 145,
-	-799, -480, -480, -335, 707, -274, 707, -464, -552, -304,
-	656, 9, -464, -355, -304, -547, -552, -548, -348, -347,
-	577, -806, -353, -489, -552, 707, 707, -464, -552, -552,
-	-548, -464, -437, -346, -345, 525, 471, -650, -349, -552,
-	-432, -433, 604, -464, -464, -437, -304, -342, -651, 706,
-	-304, -552, 643, -348, -480, -552, -464, -351, -346, 707,
-	-464, -432,
+	-1000, -1, -2, 742, -3, -281, -165, -162, -87, -101,
+	-99, -171, -172, -144, -169, -173, -164, -195, -200, -182,
+	-183, -184, -196, -205, -280, -289, -290, -291, -292, -301,
+	-285, -219, -282, -283, -4, -85, -88, -102, -125, -143,
+	-145, -163, -175, -174, -176, -185, -193, -188, -170, -93,
+	-197, -204, -216, -284, -286, -287, 33, 32, 72, 118,
+	96, 184, 150, 162, 165, 243, 465, 526, 538, 485,
+	168, 512, 492, -210, -211, 561, -86, -100, -199, -198,
+	-201, -202, -203, 88, 151, 202, 358, 502, 657, 568,
+	57, 176, -7, -15, -35, -19, 30, 52, -89, -90,
+	-91, -92, 74, -111, -106, -135, -104, -108, -109, -117,
+	-118, -103, -848, 122, -126, 86, -729, -146, -150, -192,
+	-148, -160, -854, 192, 266, -177, -178, -179, 443, -186,
+	-187, 515, -189, -190, -191, 519, 193, -95, -94, 186,
+	-336, -338, -207, -206, -208, -288, -217, -218, -220, -221,
+	-222, -224, -225, -227, -273, -228, -230, -231, -266, -232,
+	-236, -237, -238, -239, -240, -241, -242, -246, -270, -243,
+	-244, -245, -248, -247, -249, -254, -250, -251, -252, -253,
+	-255, -256, -258, -259, -262, -263, -264, -265, -267, -268,
+	-269, -276, -257, -271, -229, -272, 646, 588, 98, 530,
+	21, -8, -9, -10, -11, -12, -13, -14, -18, -17,
+	-76, -5, -6, -20, -21, -113, -22, -180, -40, -38,
+	-39, -41, -42, -43, -107, -110, -114, -115, -116, -142,
+	-119, -120, -121, -122, -123, -124, -105, -112, -728, -147,
+	-149, -152, -154, -155, -151, -153, -156, -158, -159, -157,
+	513, 712, -339, -337, 739, 718, 666, -226, -25, -30,
+	-26, -27, -29, -31, -28, -32, -33, -34, -61, -66,
+	-63, -64, -62, -65, -67, -68, -69, -70, -71, -72,
+	-73, -74, -75, -45, -51, -52, -46, -47, -48, -49,
+	-50, -53, -54, -55, -56, -57, -58, -59, -60, -23,
+	-24, -44, -77, -78, -80, -79, -81, -82, -84, -83,
+	699, 708, -342, -340, -341, -349, 552, 674, 616, 742,
+	742, 742, 742, 742, 742, 742, 742, 742, 742, 742,
+	742, 742, 742, 742, 742, 742, 742, 742, 742, 742,
+	742, 742, 742, 742, 742, 742, 742, 742, 742, -449,
+	2, -425, -431, -432, -433, -424, -392, -696, -701, 4,
+	-693, -699, 201, 284, 283, 285, 402, 21, 22, 24,
+	23, 25, 26, 27, 28, 30, 31, 43, 41, 45,
+	46, 47, 49, 50, 51, 52, 53, 54, 55, 56,
+	57, 59, 62, 64, 68, 69, 70, 71, 72, 73,
+	74, 75, 76, 77, 78, 82, 87, 88, 89, 90,
+	95, 96, 97, 98, 99, 100, 101, 102, 108, 105,
+	106, 107, 109, 110, 112, 114, 115, 116, 117, 118,
+	120, 121, 123, 124, 125, 127, 128, 129, 137, 138,
+	139, 140, 141, 143, 150, 144, 151, 154, 148, 153,
+	149, 155, 156, 158, 159, 160, 161, 162, 166, 167,
+	168, 169, 171, 172, 173, 175, 174, 177, 178, 179,
+	181, 182, 184, 185, 186, 189, 187, 190, 188, 191,
+	192, 193, 194, 195, 198, 199, 207, 208, 209, 214,
+	224, 216, 219, 220, 221, 217, 218, 222, 225, 226,
+	229, 230, 231, 234, 235, 236, 237, 238, 239, 240,
+	241, 242, 244, 245, 249, 251, 252, 253, 254, 255,
+	256, 257, 263, 264, 265, 266, 268, 269, 270, 271,
+	272, 273, 274, 278, 279, 280, 281, 288, 290, 291,
+	297, 298, 690, 303, 299, 304, 305, 307, 311, 312,
+	313, 314, 315, 316, 317, 319, 321, 320, 325, 323,
+	327, 328, 331, 332, 333, 334, 335, 336, 340, 341,
+	342, 343, 337, 344, 345, 347, 348, 351, 349, 352,
+	353, 350, 354, 355, 359, 360, 361, 362, 363, 364,
+	365, 366, 367, 368, 369, 370, 356, 357, 358, 373,
+	371, 376, 377, 378, 379, 380, 381, 399, 401, 394,
+	395, 396, 382, 386, 387, 383, 388, 384, 385, 389,
+	390, 391, 398, 392, 393, 404, 405, 406, 407, 410,
+	261, 289, 412, 413, 416, 418, 419, 436, 422, 423,
+	424, 427, 428, 431, 434, 435, 437, 438, 439, 440,
+	441, 442, 443, 444, 445, 446, 447, 448, 450, 451,
+	453, 454, 455, 456, 457, 459, 460, 461, 463, 465,
+	466, 467, 469, 470, 471, 473, 474, 475, 476, 477,
+	478, 479, 480, 481, 482, 484, 485, 487, 486, 488,
+	489, 491, 492, 494, 495, 496, 502, 503, 512, 504,
+	506, 507, 508, 509, 510, 511, 513, 514, 515, 516,
+	517, 518, 519, 520, 524, 522, 523, 525, 526, 528,
+	529, 530, 531, 532, 534, 536, 537, 541, 542, 545,
+	543, 564, 565, 592, 538, 539, 540, 544, 546, 547,
+	548, 549, 551, 550, 555, 553, 554, 556, 557, 558,
+	559, 561, 563, 566, 567, 568, 570, 571, 572, 573,
+	574, 575, 576, 577, 578, 583, 581, 584, 585, 586,
+	587, 588, 589, 590, 615, 591, 593, 594, 595, 600,
+	601, 602, 603, 596, 597, 598, 614, 604, 606, 607,
+	608, 609, 611, 612, 617, 618, 619, 620, 621, 622,
+	623, 624, 625, 626, 628, 636, 650, 637, 638, 639,
+	640, 642, 643, 646, 647, 648, 649, 634, 653, 651,
+	652, 656, 657, 658, 659, 664, 660, 665, 661, 662,
+	663, 666, 668, 671, 672, 673, 681, 682, 679, 680,
+	683, 684, 686, 687, 685, 694, 695, 689, 691, 692,
+	693, 700, 701, 703, 704, 705, 37, 58, 60, 63,
+	65, 67, 83, 84, 85, 91, 145, 146, 183, 196,
+	197, 210, 232, 233, 246, 248, 258, 259, 260, 287,
+	292, 293, 295, 301, 324, 409, 411, 429, 433, 452,
+	458, 462, 464, 483, 533, 562, 579, 599, 605, 629,
+	630, 631, 632, 641, 644, 674, 675, 676, 678, 688,
+	702, -449, 2, -722, -404, -402, 737, -682, -445, 283,
+	4, -693, -694, -424, -695, -696, 48, 93, 126, 228,
+	286, 262, 300, 302, 306, 326, 329, 374, 397, 403,
+	430, 432, 527, 569, -425, 739, 420, -418, 2, -392,
+	-392, 465, 29, 2, 29, 451, 554, 619, 621, 2,
+	-809, 2, -810, 5, 316, -758, -500, 612, 2, 29,
+	-395, -392, 122, 243, 552, -418, 2, 637, -758, 243,
+	-500, 26, 612, 2, -392, 2, 434, 195, 457, 229,
+	473, 642, 23, 28, 80, 93, 116, 166, 194, 223,
+	-853, 436, 476, 536, 556, 614, 626, 2, 680, 348,
+	553, 616, 278, 140, 648, -849, 544, -769, 541, 542,
+	434, 472, 622, 688, 528, 247, 667, -396, 2, 538,
+	-392, 348, 2, 742, 112, 89, 533, 558, -213, 2,
+	336, 637, -214, -215, -212, 629, -680, 544, 528, 373,
+	-392, 742, 742, 742, 742, 742, 742, 29, -407, 2,
+	-392, -407, 2, -293, 2, -407, -856, -300, -299, -298,
+	22, 503, 209, 317, 227, 267, 380, 469, 225, 54,
+	-293, 2, 616, 278, 544, 140, 612, -429, 731, -431,
+	-560, -849, 341, 2, -278, 558, 591, 254, 53, 52,
+	89, 29, 475, 95, 441, 141, 147, 178, 195, 649,
+	245, 612, 278, 279, 312, 98, 111, 112, 643, 642,
+	-563, 49, 305, 82, 304, 542, -774, 541, -621, 617,
+	230, 474, 546, 554, 611, 102, 456, 317, 538, 637,
+	639, 122, 668, 529, 705, 480, 481, 609, 496, 606,
+	337, 187, 228, 716, 624, 622, 688, 4, 140, 373,
+	528, 560, 321, 320, 650, 629, 694, 336, 537, 444,
+	100, -865, 2, 637, -865, 2, 742, 2, 616, 440,
+	680, 553, 229, 473, 140, 480, 278, 648, 52, 166,
+	28, 457, 304, 82, -849, 716, 688, 544, -769, 713,
+	714, 348, 147, -751, 2, -750, 4, -699, -693, -443,
+	-442, 616, -849, 140, 688, 622, -433, -424, 731, -432,
+	742, 742, 742, 742, 2, 304, 305, 478, 477, 558,
+	559, 29, 742, 742, 742, 742, 742, 742, 742, 541,
+	195, 2, 341, 342, -849, 194, 457, -787, 23, 28,
+	80, 111, 116, 147, 223, 436, 476, 556, 614, 618,
+	626, -768, 591, 82, 544, -767, -769, 425, 348, 648,
+	166, -561, 140, 336, 241, 658, 621, 619, 655, 742,
+	195, 2, 154, 290, 663, 661, 742, 742, 742, 742,
+	-166, 2, 739, 33, 32, -165, -99, -171, -87, -169,
+	168, 568, 561, -329, 616, 296, 2, -392, 742, 742,
+	742, 2, 304, 305, 541, 542, 29, 742, 742, 227,
+	-750, 612, 2, 742, 742, 742, 2, 29, 304, 305,
+	541, 542, 296, 2, 82, 547, 742, 742, 742, 742,
+	742, 742, 742, 742, 742, 742, 742, 742, 742, 742,
+	742, 742, 742, 742, 742, 742, 742, 742, 742, 742,
+	742, 742, 742, 742, 742, 742, 742, 742, 742, 742,
+	742, 742, 742, 742, 742, 742, 742, 742, 742, 742,
+	742, 742, 742, -863, 2, 616, 637, 2, -865, 2,
+	466, -865, 2, 466, -866, 637, 702, 742, 742, 742,
+	742, 742, 742, 742, 742, 742, 742, 742, 742, 742,
+	742, 742, 742, 742, 742, 742, 742, 742, 742, 742,
+	742, 742, 742, 742, 742, 742, 742, 742, 742, 742,
+	742, 742, 742, 742, -337, -339, -338, 742, 742, 742,
+	742, 742, 742, 742, 742, 742, 742, 742, -278, 558,
+	2, 89, 29, 29, -487, -490, 654, 294, 180, 426,
+	-336, -338, 2, -728, 650, 558, -678, 2, -593, -702,
+	-595, 729, 730, 722, 613, 81, -453, 400, 706, -607,
+	147, 655, 420, 397, -701, -596, -609, 183, 436, 533,
+	-518, 8, 9, 5, 6, 7, -404, -597, -603, 645,
+	200, 408, -446, 743, 10, 739, -725, -338, -608, 38,
+	248, 79, -403, -653, 295, -444, -424, -722, -723, -445,
+	-683, -656, -664, -663, -660, -659, -661, -667, -668, -392,
+	93, 131, 132, 130, 135, 134, 339, 338, 136, 133,
+	560, 667, 80, 37, 258, 259, 301, 409, 260, 91,
+	-724, 4, -693, -695, 292, 293, 579, 60, 483, 210,
+	167, 146, 145, 411, 65, 63, 675, -665, 142, 629,
+	630, 631, 632, 232, 233, 67, 678, 196, 197, 433,
+	462, 605, 641, 644, 246, 324, -869, 676, 599, 83,
+	84, 215, -730, 486, -731, -418, -730, 742, 742, 744,
+	742, -478, -480, -482, 29, 164, 739, 2, -627, 2,
+	-628, -632, -338, 318, -631, 739, -629, 737, -425, 421,
+	-726, 534, -722, -723, -424, 741, 739, 229, 741, -483,
+	739, -168, -143, -174, -197, -286, -287, 140, 544, 648,
+	616, 94, 278, 111, 194, 229, -554, 739, -392, 29,
+	-810, -685, -684, 5, 4, -693, -699, -694, -696, 420,
+	633, 744, -758, -500, -479, 471, -605, 739, 5, 420,
+	423, 227, 423, -758, 69, 109, -392, 258, 2, -816,
+	258, 2, -815, -431, -816, 258, 2, -392, 258, 2,
+	352, 2, 2, 2, 2, 2, 258, -392, 616, 139,
+	316, 2, 2, 2, 2, 2, 2, -510, 258, 2,
+	-508, -431, 680, -511, 258, 2, -508, -509, 258, 2,
+	-508, -562, 2, 104, -408, 258, 2, -392, -434, 258,
+	2, -429, -559, 258, 2, -596, 737, -607, -440, 258,
+	2, -437, -392, -688, 258, 2, -686, 4, -693, 136,
+	560, -593, 2, -197, 2, 69, 89, -392, 680, 2,
+	564, 2, 739, -213, 2, 85, 637, 48, 558, -214,
+	2, -579, 2, -580, -388, -389, -390, -639, -391, 303,
+	470, 482, 709, 152, 400, 705, -836, 227, 721, 633,
+	-678, -678, -678, -519, 741, -295, 62, -407, -857, -856,
+	-857, -676, 29, -671, 8, -672, 729, 730, -676, -676,
+	-857, -857, 2, 2, 2, 2, 2, -260, 699, 2,
+	511, -278, 2, 215, 669, 2, 8, 2, 267, -318,
+	-690, 546, 207, 481, 672, 109, 2, -685, 10, 564,
+	2, 565, 481, 89, -563, 705, 89, 227, 2, 227,
+	2, -544, 2, 699, 471, 558, 227, 2, 110, 109,
+	-544, 2, -756, 2, 420, 245, 227, 2, 227, 2,
+	227, 2, 631, 227, 2, 227, 2, 227, 2, 2,
+	-277, 559, 638, 615, 477, 305, 699, 2, -197, 696,
+	-181, 215, 305, 304, -593, 696, 2, -775, 215, 542,
+	-593, 2, 636, 314, 188, 227, -544, 2, 227, 2,
+	227, 2, 227, -544, 2, 227, 2, 5, 2, 45,
+	215, 2, 478, 592, 2, 303, 470, 592, 2, 589,
+	2, -425, 616, 680, 553, 140, 279, 550, 229, 473,
+	642, 29, 2, 541, 195, 2, 2, 105, 106, 227,
+	2, 227, -834, 2, 699, 242, 227, 2, 496, 227,
+	616, 29, -559, 89, 717, 90, -520, 741, -520, 705,
+	2, -578, -579, 2, -632, 258, -425, 2, -422, -681,
+	4, -693, -699, -694, -700, 29, 32, 33, 34, 36,
+	38, 39, 40, 44, 66, 79, 80, 86, 92, 94,
+	104, 111, 122, 130, 131, 133, 132, 134, 135, 136,
+	147, 152, 157, 164, 165, 170, 176, 180, 200, 202,
+	215, 223, 227, 243, 247, 250, 267, 282, 294, 296,
+	318, 322, 330, 338, 339, 400, 408, 414, 420, 421,
+	425, 426, 449, 468, 490, 521, 552, 560, 582, 610,
+	616, 627, 633, 635, 645, 654, 655, 667, 669, 677,
+	696, 697, 698, 699, -701, 2, -632, 258, 2, -428,
+	258, -632, -431, 2, -815, 2, -815, 2, -408, 2,
+	-593, -762, 625, 190, 504, 2, -450, 258, -425, -427,
+	-431, -429, 2, 541, -690, 2, 2, 2, -392, 2,
+	-593, 2, -593, 2, 2, -559, 29, 717, -437, 2,
+	-686, 258, 2, 29, 29, 680, 471, 296, 633, 744,
+	-507, -442, -443, -677, 4, 8, -499, -392, 741, -593,
+	2, -197, -181, 2, -593, 258, 2, -197, 258, 2,
+	-593, 258, 2, -197, 258, 2, -392, 2, -770, 2,
+	-833, -690, 258, 109, 511, 510, -559, 258, 2, 258,
+	-392, 2, -392, 258, 2, 229, 473, 642, -852, 536,
+	647, 352, 2, 2, 642, 2, 116, 616, 139, 2,
+	2, 2, 2, 2, 2, 616, -413, 2, -392, 215,
+	-641, 296, -437, 258, -438, 2, 553, -864, 486, -686,
+	258, 2, 509, 680, -429, 258, 2, -429, 278, 298,
+	678, -408, 258, 2, 621, 619, 621, 619, 109, -502,
+	2, 55, 296, 2, 296, 2, -633, 2, -634, -628,
+	-635, 737, 421, -645, 2, -644, -684, 674, -166, 739,
+	-166, 739, 558, 739, -690, -425, -425, -593, 2, -197,
+	-181, 2, -593, 2, -197, 2, -392, 2, 2, -690,
+	227, 668, -392, 2, -593, 2, -197, -181, 2, -593,
+	2, -197, 2, -329, 215, 2, 140, 616, -532, -632,
+	-578, 5, 633, 5, -487, -490, -278, 564, 2, -343,
+	-530, -345, 215, -565, -566, -346, 330, 202, 414, -347,
+	-543, 29, 164, -543, -543, 69, 740, 740, -836, 650,
+	11, 12, 92, 45, 729, 730, 731, 732, 213, 733,
+	734, 727, 728, 726, 719, 720, 724, 309, 310, 113,
+	723, 721, 103, 346, 535, 203, 204, 205, 206, 505,
+	276, 35, 42, 163, 119, 375, 277, 14, 15, 16,
+	-453, 34, 425, 329, 706, 262, 569, 722, 17, 18,
+	19, 300, 302, 403, 58, 267, -401, 436, -452, 613,
+	81, -593, -593, -593, -593, -593, -593, -593, -593, 432,
+	739, -526, -588, 737, -338, 739, 739, 739, 739, -677,
+	-338, -593, -607, 740, -516, 739, -338, -607, -602, 739,
+	533, 737, 739, -610, -593, 5, 5, 5, 739, 741,
+	-733, 700, 215, 739, 739, 739, 739, 739, 739, 739,
+	739, 739, 739, 739, 739, 739, 739, 739, 739, -658,
+	739, 464, -657, 739, -657, -657, -670, 682, 739, 739,
+	-655, 739, 708, 701, 739, -655, 739, 739, 739, 739,
+	739, 739, 739, 739, 739, 739, 739, 739, 739, 739,
+	682, -849, 744, -730, -574, 739, 739, -521, -522, -637,
+	-593, 731, -522, -522, 420, -513, -593, 126, -547, 306,
+	374, 228, 326, 527, 286, -590, 743, -590, -620, 708,
+	-338, -629, -338, -631, 739, -627, -620, -167, -677, -143,
+	-163, -174, -197, -216, -286, -287, 731, -425, 739, 227,
+	741, -681, 740, -513, 677, 29, 164, 731, 2, -675,
+	8, -681, 227, 633, -499, 740, 742, 742, 742, 742,
+	-408, -437, -429, -425, -444, -445, -450, -419, -392, 2,
+	2, 162, -513, -752, 648, 544, 29, 4, -699, -693,
+	-443, 553, -442, 616, 140, 195, 229, 473, -688, -395,
+	633, 39, -604, -650, -651, -704, 743, -703, -653, -662,
+	452, 458, -683, 295, 4, -693, -695, 292, 293, 579,
+	60, 483, 210, 146, 145, 411, 65, 63, 675, 629,
+	630, 631, 632, 232, 233, 67, 678, 676, 599, 83,
+	84, -752, 648, 544, 29, 553, 215, -688, 215, 227,
+	-688, 2, -690, 2, 420, 183, -366, 744, 78, 516,
+	183, -794, 739, -366, 183, 420, 183, 2, 183, 2,
+	2, 2, -392, -366, 183, 744, -510, 258, -366, 183,
+	-366, 183, -451, 258, -450, -366, 183, -366, 744, 183,
+	-161, 263, 183, -593, 229, -366, 744, 183, 741, 744,
+	183, -688, 2, -562, -680, -513, 39, -579, 2, 147,
+	4, 5, -867, 744, 328, -456, 345, 399, 253, 421,
+	703, 412, 152, -689, 5, 4, -603, -615, 147, 336,
+	295, -671, -673, 9, -674, 729, 730, -679, -678, 129,
+	741, -681, -296, 289, 43, -407, -407, -857, -857, 8,
+	8, -857, -857, -407, -407, -261, 511, 76, 469, 305,
+	616, 307, -194, -690, 739, 227, 267, -321, 699, -690,
+	-690, -690, -690, -690, -680, 29, -834, 2, 565, 2,
+	-277, 559, 638, 106, 565, 2, -425, 616, 140, 278,
+	96, -779, 215, 2, 681, -392, 2, -690, 2, -757,
+	215, -753, 528, 544, 648, -752, -757, -425, 140, -425,
+	140, -425, 140, -425, -425, -425, 2, 2, 2, 2,
+	-320, -319, 185, 699, 2, 101, 542, 541, 2, -197,
+	-593, 2, 699, 101, 2, 52, 585, 82, -775, 215,
+	2, 636, 2, 636, 2, -392, -392, -392, -392, -392,
+	414, -425, 591, 328, 699, -223, 699, -425, -425, -428,
+	-431, -426, -431, 227, 279, -431, -431, -392, 546, 617,
+	649, 542, 195, -593, 2, 109, -858, 2, 227, 215,
+	2, 616, 278, 278, 616, 140, 130, -835, 617, 279,
+	160, 312, 192, 227, 89, 140, 29, 227, 616, -849,
+	539, -559, 29, 741, 4, -363, 507, 561, 435, -362,
+	25, 30, 168, 280, 381, 672, 189, -468, 281, 513,
+	-784, -465, 440, 171, 161, 216, 183, 584, 660, -762,
+	-765, 540, 625, 190, 504, 107, 412, 561, 435, 507,
+	183, -538, -540, 39, 138, 381, 434, 71, 445, 272,
+	350, 351, 588, 514, 688, 183, 561, 435, 507, -804,
+	507, 561, 435, -789, -806, 381, 73, 523, 598, 265,
+	587, 692, 195, 551, 325, 400, 120, 534, 607, 437,
+	507, 561, 435, 435, -16, -381, 25, 168, -383, -374,
+	561, 30, -765, 117, 507, 718, 712, 513, 448, 608,
+	468, -765, -762, 323, -764, 693, 398, -365, 584, 660,
+	-762, -497, -765, 540, 507, -364, 400, 690, 689, 691,
+	-470, -465, 440, 183, 743, 25, 168, 507, 561, 435,
+	-843, -844, 30, -677, 2, -361, 267, -360, 25, 420,
+	435, -356, -355, 25, 168, 561, 664, 513, 507, 588,
+	595, 443, 519, 101, 561, -209, 243, 526, -187, -208,
+	-209, 2, 513, 561, 29, 507, 435, -759, -415, -727,
+	267, 699, 183, -415, -415, -632, 258, -779, 215, 2,
+	-772, -194, 319, 5, 10, 2, -507, 744, 744, -681,
+	731, 183, 183, 183, 183, 305, 215, 400, -833, 2,
+	597, -127, 616, 617, 140, 227, 400, 400, 699, 420,
+	400, -808, 2, -431, -808, 2, -392, 2, -853, 2,
+	2, 2, 2, 2, 2, 2, -425, 258, -485, 420,
+	-748, -749, -855, 616, -304, 699, -690, 400, 48, -428,
+	258, 2, 680, -759, 400, -767, -430, 258, -425, 39,
+	739, 400, 2, -562, 2, 278, 278, -727, 400, -690,
+	2, 227, 739, -447, -634, -628, -447, 561, -418, 39,
+	-590, -425, 740, 744, -645, -645, -690, -304, 227, 739,
+	-329, 699, 699, 305, 267, 2, -690, 227, 305, -690,
+	-748, -408, 2, -425, 2, -366, 744, -396, -343, -530,
+	-680, -531, -530, -344, -343, -346, 215, 482, 661, 381,
+	566, 311, -566, -565, 29, -593, -570, 209, 380, -593,
+	-568, -595, 729, 730, -672, -674, -512, 412, -337, -337,
+	-337, -492, -622, -623, -593, 468, 285, -679, -836, -652,
+	-650, -650, -423, -681, 629, -593, -593, -593, -593, -593,
+	-593, -593, -593, -593, -593, -593, -593, -593, -593, -593,
+	-593, -593, -593, -593, -593, -593, -593, -593, -593, -593,
+	-593, -593, -593, -593, -593, -593, -593, -593, -593, -593,
+	-593, -593, -593, -593, -593, 329, 262, 569, 58, 267,
+	-593, 633, -593, -593, -593, -593, 371, 400, 408, 645,
+	200, 656, 164, 412, -870, 610, 44, -600, -338, -517,
+	739, -614, 36, 582, 29, -607, 739, 2, -588, -593,
+	-589, -454, -452, -392, 729, 730, 731, 732, 733, 734,
+	719, 720, 721, 14, 15, 16, 724, 728, 726, 727,
+	213, 113, 723, 346, 535, 103, 203, 204, 205, 206,
+	309, 310, 17, 18, 19, 35, 42, 163, 119, 375,
+	722, -514, -513, -513, 740, 744, 39, 740, -593, -514,
+	-606, -602, 737, -513, -613, -612, 696, -555, -556, 704,
+	357, 143, 256, 353, -557, 549, -675, -681, 731, -734,
+	208, 247, 739, 740, 2, 740, 2, 740, -593, 2,
+	740, -593, 2, 740, -593, 2, 740, -593, 2, 740,
+	2, 740, 2, -593, -593, -593, -593, -593, -593, -593,
+	-513, 8, -675, 739, -675, -675, -675, 629, 629, -675,
+	-675, -675, -666, 452, 453, 454, 455, 331, 332, 333,
+	334, 458, 459, 460, 461, 363, 364, 365, 366, 359,
+	360, 361, 362, 367, 368, 369, 370, 237, 238, 239,
+	240, 233, 234, 235, 236, -666, -675, -549, 2, -669,
+	-513, 4, 704, 357, 143, 256, 353, 549, 5, -549,
+	2, -550, 2, -593, -513, -551, -594, -595, 729, 730,
+	722, -453, -552, 2, -593, -514, -593, 66, 322, 635,
+	-553, -593, 227, -513, -513, 2, -513, 2, -559, 2,
+	-731, 39, -575, -392, -513, -503, 227, 744, 45, 34,
+	425, 329, 262, 569, 300, 58, 267, 39, -698, 436,
+	4, -697, 21, 22, 23, 24, 25, 26, 27, 28,
+	29, 30, 31, 32, 33, 37, 36, 40, 43, 44,
+	41, 46, 47, 48, 49, 50, 51, 52, 53, 54,
+	55, 56, 57, 59, 60, 62, 63, 65, 66, 67,
+	64, 68, 69, 70, 71, 72, 73, 74, 75, 76,
+	77, 78, 79, 80, 82, 85, 86, 87, 88, 89,
+	90, 91, 93, 94, 95, 96, 97, 98, 99, 100,
+	101, 102, 104, 105, 106, 107, 108, 109, 110, 111,
+	112, 114, 115, 116, 117, 118, 120, 121, 123, 124,
+	125, 126, 127, 128, 129, 130, 131, 133, 132, 134,
+	135, 136, 137, 138, 139, 140, 141, 150, 144, 145,
+	146, 151, 147, 148, 152, 153, 149, 154, 155, 156,
+	157, 158, 159, 160, 161, 162, 164, 165, 166, 167,
+	168, 169, 170, 171, 172, 173, 174, 175, 176, 177,
+	178, 179, 181, 182, 184, 185, 183, 186, 189, 187,
+	190, 188, 191, 192, 193, 194, 195, 196, 197, 198,
+	199, 200, 201, 207, 209, 210, 214, 216, 219, 220,
+	221, 217, 218, 222, 223, 224, 225, 226, 228, 229,
+	230, 231, 232, 233, 237, 238, 239, 240, 234, 235,
+	236, 241, 242, 244, 245, 246, 248, 249, 251, 252,
+	253, 254, 255, 257, 258, 259, 260, 261, 263, 264,
+	265, 266, 268, 270, 271, 269, 272, 273, 274, 278,
+	279, 285, 284, 283, 280, 282, 281, 286, 287, 288,
+	289, 290, 291, 292, 293, 295, 297, 298, 690, 299,
+	301, 303, 304, 305, 306, 307, 311, 312, 313, 314,
+	315, 316, 317, 318, 319, 321, 320, 322, 325, 323,
+	324, 326, 327, 328, 331, 332, 333, 334, 335, 336,
+	337, 338, 339, 340, 341, 342, 343, 344, 345, 347,
+	348, 351, 349, 352, 350, 356, 354, 355, 358, 359,
+	360, 361, 362, 363, 364, 365, 366, 367, 368, 369,
+	370, 373, 371, 374, 376, 377, 378, 379, 380, 381,
+	382, 383, 384, 385, 386, 387, 388, 389, 390, 391,
+	397, 398, 399, 392, 393, 400, 401, 402, 404, 405,
+	406, 407, 396, 394, 395, 408, 409, 410, 411, 412,
+	413, 416, 418, 419, 421, 422, 423, 424, 427, 428,
+	429, 430, 433, 434, 435, 437, 438, 439, 440, 441,
+	442, 443, 444, 445, 446, 447, 448, 449, 450, 451,
+	452, 453, 454, 455, 456, 457, 458, 459, 460, 461,
+	462, 463, 465, 466, 467, 468, 469, 470, 471, 473,
+	474, 475, 476, 477, 478, 479, 480, 481, 482, 483,
+	484, 485, 487, 486, 488, 489, 490, 491, 492, 494,
+	495, 496, 502, 503, 512, 504, 506, 507, 508, 509,
+	510, 511, 513, 514, 515, 516, 517, 518, 519, 520,
+	524, 522, 523, 525, 526, 527, 528, 529, 530, 531,
+	532, 533, 534, 536, 537, 538, 539, 540, 541, 542,
+	544, 546, 545, 543, 547, 548, 550, 551, 552, 553,
+	554, 555, 556, 557, 558, 559, 560, 561, 562, 563,
+	564, 565, 566, 567, 568, 570, 571, 572, 573, 574,
+	575, 576, 578, 577, 579, 581, 582, 583, 584, 585,
+	586, 587, 588, 589, 590, 615, 591, 592, 593, 594,
+	595, 600, 601, 602, 603, 596, 597, 598, 599, 614,
+	605, 604, 606, 607, 609, 608, 610, 611, 612, 616,
+	617, 618, 619, 620, 621, 622, 624, 623, 625, 626,
+	627, 634, 628, 629, 631, 632, 630, 636, 650, 635,
+	637, 638, 639, 640, 641, 642, 643, 644, 645, 646,
+	647, 648, 649, 651, 652, 653, 655, 656, 657, 658,
+	659, 664, 660, 665, 661, 662, 663, 666, 667, 668,
+	669, 671, 672, 673, 674, 675, 676, 681, 677, 678,
+	679, 680, 683, 684, 686, 687, 685, 688, 694, 695,
+	689, 691, 692, 693, 696, 702, 703, 705, -503, -503,
+	739, 740, 744, -548, 251, 349, 344, 298, 596, -548,
+	-627, -547, 306, -545, 430, -545, -545, -620, -409, 737,
+	746, -681, -620, -617, -616, 39, -418, 427, -620, -620,
+	740, -619, -618, 39, -418, 738, -746, 739, 742, 742,
+	742, 742, 742, -425, 739, -681, 741, -491, 744, -488,
+	426, -593, -513, -513, 740, 738, 741, 593, 2, 594,
+	2, 740, 633, 300, 300, 300, 300, 300, 300, 420,
+	534, 740, 633, -754, -434, -440, 554, 617, 230, 474,
+	-507, 744, -507, -499, 109, -816, -816, 699, -688, -165,
+	422, 740, 744, -501, 38, 737, 741, -675, 2, 2,
+	-556, 739, 227, -754, -440, 617, 554, 230, 474, 2,
+	-758, 612, -500, -688, 633, -425, -392, -815, -816, -795,
+	740, -798, -807, -790, -801, 267, 429, 287, 677, -682,
+	-650, 4, -693, -816, -425, -392, -392, 2, -510, -431,
+	-366, 183, -511, -509, -366, 744, 183, -408, -429, -434,
+	-559, 738, -437, -440, -392, -686, -688, -366, -430, -836,
+	740, 637, -580, -455, 482, 581, 508, 555, 612, 9,
+	9, 744, -681, -297, 543, 381, -407, -407, -407, -407,
+	744, 592, 511, -274, 2, 699, -425, 215, -691, -690,
+	-690, -194, 2, -323, 424, -322, 41, 87, 572, 407,
+	144, 274, 313, 175, 471, 174, -321, -321, -321, -321,
+	2, 2, 2, 2, 2, -544, -425, -408, -450, -425,
+	-436, 267, 244, 29, -769, 215, 741, -688, -688, -440,
+	-441, -439, -392, -434, -544, -408, -544, -408, -544, -408,
+	-544, -544, 744, 160, -320, 185, -197, -197, -593, -320,
+	-593, 591, 2, 558, 215, 215, 741, -544, 741, 741,
+	-544, 8, -486, 521, 5, 488, 261, -223, -223, -425,
+	227, 420, 2, 110, -690, 2, 480, 140, 616, 440,
+	278, -425, -450, -450, -425, -408, -834, 744, 140, -408,
+	141, 140, -425, -559, 4, 744, -837, 111, 633, 94,
+	739, 544, -385, 337, 633, -584, 258, 94, -705, 111,
+	-411, -706, -392, 86, 655, 468, 223, 181, -837, 111,
+	468, -837, 111, 2, 280, 216, 111, 561, 591, 739,
+	533, 29, 69, -632, 45, 45, 29, -763, -764, 323,
+	227, 705, 616, 278, 544, 633, 633, -632, -540, -650,
+	138, 350, 351, 69, -676, 389, -676, 69, -676, -676,
+	-676, 699, -676, 699, -428, -632, 544, 633, 633, -850,
+	-806, 516, 561, 633, 544, 633, 156, 420, 408, 551,
+	149, 299, 325, -615, -615, -392, 633, 544, 633, 633,
+	494, 606, 494, 606, 550, -374, -376, -214, 550, 606,
+	337, 633, 633, -214, 29, -278, 517, 147, -868, 721,
+	494, 323, -764, 633, 227, 744, 45, 45, 29, -763,
+	227, 633, 689, 9, -450, -409, 673, 47, 673, 47,
+	673, 633, 47, 544, 633, 744, 47, -358, -357, 561,
+	184, -360, -690, -359, 379, -425, 633, -355, -748, -748,
+	-303, -302, -392, 5, -499, 139, 633, 557, 2, 511,
+	557, 2, 511, 511, 511, 89, 511, 77, 29, 2,
+	77, 29, 2, -209, 2, 633, 633, -16, 561, -760,
+	-397, 125, 388, 343, 390, 115, 385, 114, 384, 123,
+	386, 124, 387, 683, 404, 684, 405, 75, 383, 354,
+	391, 586, 393, 687, 406, -398, -399, -400, 511, 392,
+	70, 382, 173, 442, 671, 604, 140, -686, -16, -16,
+	561, 435, 507, 183, -785, 267, 29, 267, -640, -639,
+	267, -442, -392, 741, -593, -197, -593, -197, 52, 82,
+	183, 39, 227, 2, 227, -431, 739, -408, 511, 183,
+	183, 2, -425, 183, 739, 739, -818, 56, 27, 291,
+	316, 739, -459, 400, 227, -499, -641, 744, -425, 39,
+	-303, 424, 183, -686, -539, -538, 400, -430, 258, 2,
+	183, -864, -483, 400, 177, 739, 480, 2, 183, -410,
+	258, -393, -392, -562, -562, -368, 620, 183, -139, 699,
+	-633, -537, -536, 571, -571, -197, 739, 147, 39, -590,
+	-571, -523, -524, -638, -525, -411, 739, -418, -590, -166,
+	-644, 740, 740, 740, -329, -484, -412, -411, 139, 484,
+	484, -194, 267, 2, -690, -304, -304, -640, -640, -632,
+	-531, -344, 421, 311, 566, -568, -569, -595, 533, 534,
+	-569, 533, 534, 8, 9, 8, 9, -348, 572, 407,
+	-509, 744, -353, 40, 157, 311, -425, -679, 705, 179,
+	-593, -593, 633, -870, 610, -600, 179, -593, 371, 408,
+	645, 200, 656, 164, 412, 227, 739, -594, -594, 740,
+	-515, -593, -593, 738, 748, 740, 741, 740, -491, 741,
+	-513, -499, 738, 738, 744, 740, -611, -612, 170, -593,
+	633, 633, 633, 633, 739, 740, 741, -739, 431, 739,
+	739, -593, 740, 740, 740, 740, 39, 744, 744, 744,
+	740, 744, 744, 744, 740, 740, 740, 744, -675, 740,
+	740, 740, 705, 705, 740, 740, 740, 740, 744, 740,
+	744, 740, 740, 227, 740, 740, -558, 449, 740, 11,
+	12, 729, 730, 731, 732, 213, 733, 734, 727, 728,
+	726, 719, 720, 721, 103, 346, 535, 14, 15, 16,
+	-453, 300, 267, -594, -594, -594, -594, 740, -598, -599,
+	227, 215, 39, -553, -553, -553, 740, 227, -513, 740,
+	740, -732, 348, 400, 740, 744, 740, -587, -586, 697,
+	-504, 2, -627, -637, -420, -681, -587, -587, -513, -593,
+	306, 306, -546, 669, 420, -548, -627, -617, -677, -592,
+	-591, 217, 40, 157, 394, 395, 396, 51, 261, 218,
+	222, 201, -617, -418, -574, -617, -617, -620, -418, -572,
+	739, -620, -616, 740, -747, -677, 740, -505, -630, -726,
+	741, -681, 740, 677, 69, -491, -491, 740, -681, -324,
+	-727, -324, 594, 2, -279, 5, 408, -279, -279, -279,
+	-279, -279, -425, -688, 633, 633, 267, 267, 267, 267,
+	-507, -499, 26, -778, 699, 450, -650, 737, 738, 8,
+	-681, -675, -688, 227, 227, 267, 267, 267, 267, 420,
+	-758, 227, -686, -366, 420, -366, 740, 744, -790, -801,
+	-807, -801, 429, -366, -366, 420, 2, -366, -510, -366,
+	-366, -450, -451, -366, -366, -161, -366, -640, -678, -579,
+	652, 99, 482, 629, -678, 137, 543, 511, 76, 469,
+	160, -275, 160, -304, 616, 740, 744, 267, -321, 744,
+	739, 571, 721, 721, 721, 721, 2, 2, 2, 2,
+	743, 544, -688, 529, -688, -769, 713, 714, -392, 741,
+	-544, -544, -544, -319, 558, 558, -392, -392, -392, 215,
+	-499, -425, -425, 2, -421, -681, -408, -425, -422, -450,
+	215, 215, -834, -834, -834, 617, 279, 160, 192, 312,
+	-408, -408, -233, 699, -233, -362, 507, 561, -411, -411,
+	-425, -333, -332, -330, -392, 5, -435, -392, 241, 495,
+	-686, 400, -584, 258, -367, 400, 258, -419, -650, 739,
+	-564, 701, 311, 311, 669, -411, -419, 311, 258, -411,
+	258, -419, 2, -419, -761, 482, 413, -593, -331, -330,
+	328, 69, -466, 335, 480, 401, -363, 507, 561, 435,
+	-197, -197, -197, 739, -836, 669, 162, -425, -450, -425,
+	-435, -686, -430, 561, 435, 507, 397, -444, 71, -676,
+	-676, -676, -538, 561, 435, 507, -435, -686, -428, -392,
+	-435, -686, 420, 408, 420, 149, 299, -392, -435, -686,
+	-686, -373, 258, -392, 5, 494, -373, 258, 494, 494,
+	494, 494, 241, 495, 544, -408, 494, 705, 50, -868,
+	633, 227, -593, -593, -364, -197, -197, -197, 739, -409,
+	-365, -497, 507, 5, 258, -411, 5, -411, 258, 5,
+	-392, -411, -435, -686, -844, 25, 168, -411, 744, 315,
+	296, 699, -771, 228, 541, 487, 264, 228, -361, 721,
+	507, -780, 633, -686, -304, 744, 721, 721, 633, -596,
+	195, 567, 412, 633, -315, 583, -314, 520, 482, -37,
+	-36, -680, 76, -37, 76, -435, -686, -397, 442, -772,
+	408, 5, 10, 665, -690, 408, -408, -759, -415, 544,
+	633, 633, -632, -776, -777, 243, 526, 544, 529, -194,
+	-307, 699, -194, 731, -751, 2, -748, -642, 2, 296,
+	-690, -690, -127, -127, -128, -431, 412, -559, -392, -782,
+	39, -392, -792, -793, -797, -798, -792, -820, -819, 290,
+	154, 661, 646, 412, -392, -457, -460, -458, -411, -585,
+	-584, -709, -710, -705, 329, 283, 284, 655, 298, 678,
+	201, 111, -334, -335, 701, 699, 183, -448, -425, 737,
+	-304, -749, -643, 201, 552, 739, -437, -438, 183, -483,
+	400, -686, 680, 39, 183, 739, -649, -648, -392, 2,
+	-429, 420, 400, -410, 258, -410, 258, -369, 172, -868,
+	-408, -140, 424, -141, 639, 629, 104, -534, 669, 740,
+	744, -593, -533, -577, 521, 420, -484, 674, -418, -533,
+	-506, 744, 227, 721, 741, -484, -636, 731, -166, -166,
+	-304, 739, -690, 740, 744, 741, 739, 721, 721, -640,
+	-194, 267, 227, -96, 699, 661, -569, 421, 340, -622,
+	-623, -354, 707, -425, 743, -593, -593, 179, 179, -593,
+	-594, -594, -593, 179, 227, 739, -593, -604, 34, 34,
+	740, 744, -589, -593, -452, 740, 731, -681, 743, 740,
+	-602, 176, -593, 627, 357, 256, 353, -557, 353, -557,
+	-557, -675, 5, -681, 731, -740, -414, 739, -392, 697,
+	-489, 426, 740, -652, -650, -593, -593, -593, -593, -593,
+	-675, 740, -655, -655, -671, -671, -593, -598, -593, -652,
+	-650, -594, -594, -594, -594, -594, -594, -594, -594, -594,
+	-594, -594, -594, -594, -594, -594, -594, -594, -594, -594,
+	-594, 164, 400, 412, -594, -599, -598, -593, -593, -650,
+	740, 740, 740, -513, 739, 348, -392, -527, 247, -593,
+	-640, 744, -527, -527, 740, -627, -627, 739, -593, 306,
+	738, 744, 747, 721, 721, 721, -574, -616, -572, -573,
+	-576, -392, -617, 738, 740, 744, 740, 744, -619, -681,
+	-593, -493, -622, 740, 740, 741, -587, -326, 739, -325,
+	158, 62, 127, 155, 408, 416, 226, 252, 479, 179,
+	216, 172, -324, 300, -778, -688, -688, 544, 544, 544,
+	544, 423, 243, 5, 8, 737, 738, 741, 740, -688,
+	-688, 544, 544, 544, 544, -752, 648, 544, 29, 227,
+	-688, -425, -798, -801, -801, -425, -366, -366, -535, 699,
+	-593, -294, 699, 701, 592, 511, -425, -690, -194, -322,
+	-323, -194, -194, -690, -690, 731, -435, -436, -436, -686,
+	2, 29, 29, 731, -544, 5, -472, -471, 440, 412,
+	-472, 533, 533, -234, 424, -235, 588, 181, 633, 633,
+	740, 744, 721, 69, 267, 183, 400, 671, 400, -706,
+	181, -711, -593, 739, 278, 739, 739, 2, -350, -351,
+	-352, 168, 25, -840, -841, -541, 561, -842, -542, 514,
+	2, 669, 183, -366, 183, -366, 703, 740, 744, 551,
+	-466, 739, 739, 633, 544, -385, 633, 699, -513, -593,
+	-305, 147, -680, -765, 743, -765, 743, 544, 633, 633,
+	-676, 544, 633, 633, 194, 288, 408, 400, -373, 183,
+	-373, 258, -868, -373, -765, -765, 267, 699, 199, 199,
+	705, -373, -593, -593, 215, 633, 699, -513, 633, -654,
+	56, 27, 400, -429, -366, 183, 633, 633, 648, 561,
+	-357, -690, -194, -308, 175, 525, 159, 313, 274, 185,
+	-845, 662, 270, 271, 52, 423, -772, 264, -194, 633,
+	-781, 669, 699, -688, -302, -690, -690, 612, -596, 612,
+	319, 744, -317, -316, 191, 721, 688, 744, -836, -772,
+	-690, 408, -16, -435, -686, -430, 561, 435, 507, -758,
+	-758, 243, -440, -785, -640, -309, 424, -308, -640, 296,
+	-642, -304, -690, 420, 420, 740, 744, -596, 227, 699,
+	-783, 215, 446, 518, 420, 740, 744, 147, 721, 740,
+	420, 425, 412, 2, 740, 740, 744, 744, -712, -367,
+	-425, 739, -392, 278, 283, 284, 283, 284, -417, -393,
+	39, 416, 416, 739, -425, -136, -137, 699, -138, 634,
+	-639, 669, -586, -677, -416, -392, -522, -303, 48, -428,
+	39, 183, -759, -430, -197, -430, -646, -647, 5, 740,
+	744, -651, 39, -425, 183, 420, 400, 420, 400, -370,
+	321, -868, -685, -727, 744, 739, 721, 721, 721, -587,
+	-504, -536, -533, -522, 402, 108, 740, -587, -524, -504,
+	-593, 2, 740, -690, -304, -329, -412, 2, -691, -690,
+	-690, -310, 699, -640, -194, -197, 424, 421, 209, 317,
+	-353, -409, -593, -593, 179, 34, 34, -593, -593, -604,
+	740, -593, -593, -513, 738, 5, 8, -593, 740, 741,
+	-741, -392, -593, 740, 69, 740, 740, 744, 744, 740,
+	740, 740, 740, 740, 740, 740, -599, 227, 164, 412,
+	739, 740, -165, -601, 250, 69, -627, -601, -601, -546,
+	-499, -627, -591, -409, 737, -409, 737, 737, 740, 744,
+	-650, -677, -630, -491, 744, -681, -325, -328, -327, 158,
+	224, 155, 408, 416, 226, 252, 479, 179, 221, 219,
+	220, 172, 721, -690, -690, 2, 2, 5, 5, 479,
+	400, 408, 5, -279, -778, -778, 699, -440, -440, -440,
+	-440, 423, 738, 2, 737, -681, -440, -440, -440, -440,
+	227, -754, -440, 617, 230, 474, -688, -366, -366, 139,
+	381, 215, 255, 255, 160, -304, -321, 740, -422, 616,
+	278, 739, 739, 744, 739, 631, 95, -411, -411, -332,
+	-678, 616, 533, -373, 468, -584, 183, 183, -713, 111,
+	-715, 92, 201, 122, 400, 408, 655, 468, 86, 147,
+	420, 490, -860, -838, -839, 39, 710, 711, 740, -494,
+	-624, -726, 739, -392, -494, -499, 400, 257, 602, 147,
+	420, -838, -839, 2, -542, 561, 400, 147, 420, 689,
+	138, 381, 71, 272, 350, 351, 588, -540, 710, 711,
+	139, 648, -676, 699, 95, -411, -419, -330, -499, -499,
+	-425, -435, -686, 191, 740, 744, 721, 2, 731, 731,
+	-435, -686, -430, -435, -686, -428, -392, 288, 183, 674,
+	-373, 183, -373, 674, -373, 438, 199, 633, -197, -593,
+	191, 740, -409, 5, 5, 183, -406, 92, -411, 5,
+	-411, -429, 139, 721, 721, 721, 721, 721, 337, 721,
+	721, 31, -772, -302, 699, -392, 739, 86, 629, 420,
+	629, -314, 744, 698, -596, 89, -36, -678, 544, 633,
+	633, 420, 420, 423, -776, -777, -307, 744, 739, -307,
+	-194, -304, 39, -690, -690, -431, 420, 511, 2, -780,
+	29, 552, 290, 661, 154, -425, 523, -802, -803, -805,
+	39, 316, 640, 698, -806, -797, -593, -593, -802, -425,
+	-819, -499, -473, 280, -411, -710, -707, -708, 468, -585,
+	-714, -716, 201, 468, -461, -494, 739, -410, 739, -392,
+	739, -392, 739, -197, 2, -333, 739, -459, -138, 424,
+	9, 198, 738, 227, 740, -686, -539, -197, -430, -483,
+	-481, 699, -483, 740, 744, -392, 177, 739, -498, 669,
+	-409, -425, 183, -425, 183, -371, 320, -868, -685, -368,
+	-141, -140, -690, -690, -593, -490, -487, 165, 739, 420,
+	-197, -490, 721, 740, 139, 740, -312, 424, -311, 175,
+	313, 297, 574, 575, 576, 577, 578, 159, 573, 378,
+	274, -846, -847, 545, 679, 659, 185, 186, 506, 623,
+	694, 622, 695, -310, -640, -97, -98, 278, 283, 111,
+	447, -353, -593, -593, -593, 740, 731, -735, 440, 740,
+	-622, -623, -593, -593, -594, 227, 739, -604, 740, -736,
+	698, -593, -528, -529, -593, 531, 128, 248, -736, -736,
+	740, -677, -677, -677, -576, 740, -622, -623, 740, 744,
+	-690, 62, 127, 626, 5, -690, -690, 2, 2, 645,
+	200, 5, 5, 2, 2, 2, 5, -690, 2, 408,
+	2, 2, 633, 633, 633, 633, 737, 2, 227, 227,
+	227, 227, -688, 227, 227, 267, 267, 267, 139, -197,
+	-425, -450, -513, -513, -235, -234, 721, 721, 267, 39,
+	494, -584, -419, -419, -423, -416, 201, 258, 408, 689,
+	-564, 311, 739, -594, 661, -425, 739, 2, 257, 257,
+	31, 69, -861, 152, 282, 740, 744, -625, -405, -392,
+	-593, -625, 740, 740, 408, 258, 661, 257, 257, 408,
+	689, -593, 661, 138, 350, 351, -676, -676, 69, -676,
+	-676, -676, 699, 2, 31, 69, -650, -676, 739, -366,
+	-366, 740, 740, -593, 633, -680, 118, -678, 2, -765,
+	-373, -382, -373, -382, -765, -408, -593, 215, -593, 633,
+	5, -366, -423, -366, -366, -406, 648, -690, -593, 645,
+	200, -194, -194, 721, -593, -593, 419, -593, 739, -593,
+	-596, -593, -316, 721, -435, -686, -430, -786, 617, 554,
+	649, 546, 230, 532, -786, 215, -308, -309, -307, -771,
+	552, 296, -132, 699, -596, 412, -781, -782, -788, 616,
+	562, -814, -811, 57, 522, -805, -791, 5, -685, -814,
+	-823, 491, -467, -468, 2, -712, 311, -416, 311, 269,
+	182, 740, -494, 739, -494, 739, -494, 739, -499, -859,
+	699, 740, -457, -334, -137, -755, -447, -483, 39, 381,
+	139, 39, 5, -651, 739, -649, 739, -392, 420, 739,
+	-409, 739, -409, -387, 109, -868, -685, -369, 740, -567,
+	-565, 401, -499, 111, -567, -600, -304, 739, -304, 744,
+	739, 721, 721, 721, 721, 721, 721, 721, 337, 153,
+	118, -310, 744, 29, 739, 29, 739, -491, 69, 744,
+	744, 740, 740, -594, -604, 740, -737, -738, -414, 744,
+	739, 739, 563, 738, 738, 738, -327, 2, -688, -688,
+	-688, -688, 2, -688, -688, -688, -688, -688, -688, 544,
+	544, 544, 740, 740, 740, -596, -194, -373, 468, -392,
+	-706, -715, -416, 400, -335, 669, 699, -593, -594, -394,
+	739, -593, 739, 739, 39, 147, 282, 153, 263, -583,
+	-862, 121, 603, 268, -624, -353, 740, -582, 669, 490,
+	183, 739, 739, -593, -676, -676, 147, -406, -494, 739,
+	739, 739, 721, 227, 744, -197, 739, -654, -366, -429,
+	-690, 721, 740, -593, -313, 699, -596, 633, 2, 227,
+	-758, 740, -771, -306, 699, -522, -127, -134, 424, -133,
+	356, 162, 315, 653, 59, -313, -596, -783, -800, -801,
+	739, 46, -593, -817, 744, -826, 215, -822, -821, -824,
+	377, 418, -334, 739, -335, -462, 97, 112, 148, 257,
+	231, 279, 591, 600, 29, -462, -582, 740, -494, 740,
+	-494, 740, -494, 740, -463, 420, 139, 381, 740, 39,
+	-587, 39, -197, 139, -197, -646, 740, -494, -425, -494,
+	420, -494, 420, -375, -374, 330, -685, -370, -533, 740,
+	-419, -533, -691, -311, -312, -690, -194, -690, -690, -194,
+	-690, -690, 721, 118, -98, -499, -499, -742, 480, 534,
+	249, -513, -492, -492, 740, 744, 39, -529, 2, 2,
+	2, -778, -778, -778, -778, -440, -440, -440, 494, -367,
+	183, 251, 740, -717, 347, -392, 740, -539, -539, 39,
+	153, 263, -469, -465, 739, -354, -625, -335, 251, -425,
+	-539, -539, -766, 669, 740, -475, -474, -471, -477, -476,
+	-471, -513, -678, 118, 438, -373, -513, -406, -194, 699,
+	740, -315, 424, -688, -688, 420, -773, 228, 541, 227,
+	-129, 699, 744, 739, 721, 721, 721, 420, 420, -780,
+	-802, -796, -799, -790, 4, -693, -813, 5, -828, 696,
+	-851, 169, -821, -825, 533, 616, -463, -495, -626, -411,
+	-583, -582, 740, -469, 740, -469, 740, 98, 139, -473,
+	-197, -197, 2, -481, 740, 740, -498, 740, -425, 740,
+	-425, -372, -692, 494, 496, -868, -371, -587, 165, 740,
+	740, -690, 740, 740, 740, -743, -744, 58, 651, 129,
+	-593, -743, -743, -738, -740, 227, 227, 227, 201, -581,
+	708, -718, -721, -720, 715, 570, 228, 439, 740, 602,
+	688, 740, 740, -861, -499, -581, -483, 740, 740, -593,
+	-582, 740, 744, 674, 740, 744, 674, 740, 227, 740,
+	-366, 86, 669, 739, -778, -366, -786, -306, 52, 424,
+	-755, -131, 424, -130, 137, 356, 147, 229, 162, 572,
+	315, 438, -133, -134, -690, -690, -690, -690, -596, -781,
+	-814, 740, 744, -801, -812, 176, -3, -811, 184, -593,
+	-827, 533, 590, -830, 39, -386, -385, 740, 744, -469,
+	-583, -582, -335, -469, -335, -469, 467, 154, 168, -467,
+	-859, -582, 739, -583, 739, -583, 739, -384, -383, -868,
+	-671, -387, 165, 401, 661, -304, -745, 181, -744, 463,
+	214, 533, 463, 214, -745, -745, -688, -688, -688, -416,
+	-335, 64, -720, 715, -721, 715, 661, 154, -587, 740,
+	-717, -335, -474, 267, -476, 227, 438, 739, 739, -315,
+	227, -772, 31, -303, 739, -587, 744, 739, 721, 721,
+	229, -431, 721, 544, 721, 721, 740, -313, -802, -799,
+	745, -831, 229, 473, -418, -335, -626, -335, -469, -583,
+	-587, -335, -587, -335, 534, 534, 2, -334, -463, -583,
+	-494, -469, -494, -469, -494, -380, -381, -382, -375, 401,
+	661, 561, 129, 247, 628, 381, 34, 721, -719, 381,
+	516, 78, 561, -719, -718, 739, 739, -593, -593, 740,
+	-688, -303, -771, -130, -131, -690, -690, 721, 215, -690,
+	86, -690, -690, -814, -402, -587, -335, -469, -496, 400,
+	690, 689, 691, -587, -496, -587, 2, -463, -469, 740,
+	-335, 740, -335, 740, -687, 435, -372, 561, -523, 533,
+	428, -744, -593, 24, 408, 147, -861, -513, -513, 740,
+	740, -366, 740, -306, 740, -690, 616, 739, -496, -587,
+	-335, 689, 9, -496, -496, -386, -335, -582, -587, -583,
+	-587, -583, -379, -378, 606, -868, -384, -523, -587, 740,
+	740, -431, -832, -829, 8, 9, 5, -681, -496, -587,
+	-587, -583, -496, -469, -496, -469, -377, -376, 550, 494,
+	-686, -380, -587, -464, -465, 633, 740, 744, -496, -496,
+	-469, -335, -335, -373, -687, 739, -829, -335, -587, -587,
+	674, -379, -513, -587, -496, -496, -382, -377, 740, -496,
+	-464,
 }
 
 var sqlDef = [...]int16{
 	-2, -2, 1, 2, 3, 4, 6, 7, 9, 10,
 	11, 12, 14, 16, 18, 20, 22, 24, 26, 28,
-	30, 32, 34, 35, 36, 38, 40, 42, 44, 45,
-	46, 2006, 2008, 841, 842, 844, 845, 846, 848, 849,
-	851, 853, 855, 856, 857, 859, 860, 862, 863, 864,
-	865, 866, 868, 870, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, -2, 0, 0,
-	990, 992, 0, 1988, 1990, 1992, 1994, 0, 0, -2,
-	-2, 0, 0, -2, -2, -2, 48, 49, 51, 52,
-	0, -2, 473, 475, 477, 479, 0, 511, 513, 514,
-	516, 518, 520, 522, 524, 525, -2, 0, 756, 757,
-	759, 761, 763, 765, -2, 0, 1553, 1555, 1557, 0,
-	978, 980, 0, 1560, 1562, 1564, 0, 0, 1002, 1003,
-	0, 2112, -2, 994, 996, 998, 1000, 1115, 1117, 1119,
-	1121, 1123, 1125, 1127, 1129, 1131, 1133, 1135, 1136, 1138,
-	1140, 1142, 1144, 1146, 1148, 1150, 1151, 1153, 1155, 1157,
-	1158, 1160, 1161, 1163, 1165, 1167, 1169, 1171, 1173, 1175,
-	1177, 1179, 1181, 1183, 1185, 1187, 1189, 1191, 1194, 1195,
-	1196, 1198, -2, 0, -2, -2, 2002, 54, 56, 58,
-	60, 62, 64, 66, 68, 70, 72, 74, 76, 78,
-	80, 82, 1020, 1022, 1024, 1026, 1028, 687, 689, 691,
-	693, 695, 698, 700, 702, 704, 706, 543, 545, 2170,
-	767, 769, 771, 773, 775, 777, 779, 781, 783, 0,
-	0, -2, 2184, 0, 0, 0, 1315, 84, 85, 86,
-	87, 88, 89, 90, 91, 92, 93, 157, 158, 159,
-	160, 161, 162, 163, 164, 97, 98, 99, 101, 102,
-	103, 104, 108, 109, 110, 111, 112, 113, 114, 115,
-	116, 117, 118, 119, 120, 121, 122, 123, 154, 155,
-	95, 124, 125, 126, 127, 128, 130, 131, 132, 0,
-	0, 2143, 2145, 2147, 2149, -2, 0, 0, 8, 13,
-	15, 17, 19, 21, 23, 25, 27, 29, 31, 33,
-	37, 39, 41, 43, 47, 2007, 2009, 843, 847, 850,
-	852, 854, 858, 861, 867, 869, 871, 824, 825, 828,
-	2917, 2936, 2937, 2938, 2941, 2942, 2943, 2944, 2945, 2946,
-	4079, 4160, 4161, 4162, 4163, 2969, 2970, 2971, 2972, 2973,
-	2974, 2975, 2976, 2977, 2978, 2979, 2980, 2981, 2982, 2983,
-	2984, 2985, 2986, 2987, 2988, 2989, 2990, 2991, 2992, 2993,
-	2994, 2995, 2996, 2997, 2998, 2999, 3000, 3001, 3002, 3003,
-	3004, 3005, 3006, 3007, 3008, 3009, 3010, 3011, 3012, 3013,
-	3014, 3015, 3016, 3017, 3018, 3019, 3020, 3021, 3022, 3023,
-	3024, 3025, 3026, 3027, 3028, 3029, 3030, 3031, 3032, 3033,
-	3034, 3035, 3036, 3037, 3038, 3039, 3040, 3041, 3042, 3043,
-	3044, 3045, 3046, 3047, 3048, 3049, 3050, 3051, 3052, 3053,
-	3054, 3055, 3056, 3057, 3058, 3059, 3060, 3061, 3062, 3063,
-	3064, 3065, 3066, 3067, 3068, 3069, 3070, 3071, 3072, 3073,
-	3074, 3075, 3076, 3077, 3078, 3079, 3080, 3081, 3082, 3083,
-	3084, 3085, 3086, 3087, 3088, 3089, 3090, 3091, 3092, 3093,
-	3094, 3095, 3096, 3097, 3098, 3099, 3100, 3101, 3102, 3103,
-	3104, 3105, 3106, 3107, 3108, 3109, 3110, 3111, 3112, 3113,
-	3114, 3115, 3116, 3117, 3118, 3119, 3120, 3121, 3122, 3123,
-	3124, 3125, 3126, 3127, 3128, 3129, 3130, 3131, 3132, 3133,
-	3134, 3135, 3136, 3137, 3138, 3139, 3140, 3141, 3142, 3143,
-	3144, 3145, 3146, 3147, 3148, 3149, 3150, 3151, 3152, 3153,
-	3154, 3155, 3156, 3157, 3158, 3159, 3160, 3161, 3162, 3163,
-	3164, 3165, 3166, 3167, 3168, 3169, 3170, 3171, 3172, 3173,
-	3174, 3175, 3176, 3177, 3178, 3179, 3180, 3181, 3182, 3183,
-	3184, 3185, 3186, 3187, 3188, 3189, 3190, 3191, 3192, 3193,
-	3194, 3195, 3196, 3197, 3198, 3199, 3200, 3201, 3202, 3203,
-	3204, 3205, 3206, 3207, 3208, 3209, 3210, 3211, 3212, 3213,
-	3214, 3215, 3216, 3217, 3218, 3219, 3220, 3221, 3222, 3223,
-	3224, 3225, 3226, 3227, 3228, 3229, 3230, 3231, 3232, 3233,
-	3234, 3235, 3236, 3237, 3238, 3239, 3240, 3241, 3242, 3243,
-	3244, 3245, 3246, 3247, 3248, 3249, 3250, 3251, 3252, 3253,
-	3254, 3255, 3256, 3257, 3258, 3259, 3260, 3261, 3262, 3263,
-	3264, 3265, 3266, 3267, 3268, 3269, 3270, 3271, 3272, 3273,
-	3274, 3275, 3276, 3277, 3278, 3279, 3280, 3281, 3282, 3283,
-	3284, 3285, 3286, 3287, 3288, 3289, 3290, 3291, 3292, 3293,
-	3294, 3295, 3296, 3297, 3298, 3299, 3300, 3301, 3302, 3303,
-	3304, 3305, 3306, 3307, 3308, 3309, 3310, 3311, 3312, 3313,
-	3314, 3315, 3316, 3317, 3318, 3319, 3320, 3321, 3322, 3323,
-	3324, 3325, 3326, 3327, 3328, 3329, 3330, 3331, 3332, 3333,
-	3334, 3335, 3336, 3337, 3338, 3339, 3340, 3341, 3342, 3343,
-	3344, 3345, 3346, 3347, 3348, 3349, 3350, 3351, 3352, 3353,
-	3354, 3355, 3356, 3357, 3358, 3359, 3360, 3361, 3362, 3363,
-	3364, 3365, 3366, 3367, 3368, 3369, 3370, 3371, 3372, 3373,
-	3374, 3375, 3376, 3377, 3378, 3379, 3380, 3381, 3382, 3383,
-	3384, 3385, 3386, 3387, 3388, 3389, 3390, 3391, 3392, 3393,
-	3394, 3395, 3396, 3397, 3398, 3399, 3400, 3401, 3402, 3403,
-	3404, 3405, 3406, 3407, 3408, 3409, 3410, 3411, 3412, 3413,
-	3414, 3415, 3416, 3417, 3418, 3419, 3420, 3421, 3422, 3423,
-	3424, 3425, 3426, 3427, 3428, 4005, 4006, 4007, 4008, 4009,
+	30, 32, 34, 36, 37, 38, 40, 42, 44, 46,
+	47, 48, 2227, 2229, 1006, 1007, 1009, 1010, 1011, 1012,
+	1014, 1015, 1017, 1019, 1021, 1022, 1023, 1025, 1026, 1028,
+	1029, 1030, 1031, 1032, 1034, 1036, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	-2, 0, 0, 1165, 1167, 0, 2203, 2205, 2207, 2209,
+	2210, 2212, 2214, 0, 0, -2, -2, 0, 0, -2,
+	-2, -2, 50, 51, 53, 54, 0, -2, 512, 514,
+	516, 518, 0, 551, 553, 554, 556, 558, 560, 562,
+	564, 566, 567, -2, 569, 0, 0, 916, 917, 919,
+	921, 923, 925, -2, 0, 1756, 1758, 1760, 0, 1153,
+	1155, 0, 1763, 1765, 1767, 0, 0, 1177, 1178, 0,
+	2336, -2, 1169, 1171, 1173, 1175, 1295, 1297, 1299, 1301,
+	1303, 1305, 1307, 1309, 1311, 1313, 1315, 1317, 1319, 1321,
+	1322, 1324, 1326, 1328, 1330, 1332, 1334, 1336, 1337, 1339,
+	1341, 1343, 1344, 1346, 1347, 1349, 1351, 1353, 1355, 1357,
+	1359, 1361, 1363, 1365, 1367, 1369, 1371, 1373, 1375, 1377,
+	1379, 1381, 1384, 1385, 1386, 1388, -2, 0, -2, -2,
+	2223, 56, 58, 60, 62, 64, 66, 68, 70, 72,
+	74, 76, 78, 80, 82, 84, 86, 88, 1195, 1197,
+	1199, 1201, 1203, 1205, 843, 845, 847, 849, 851, 854,
+	856, 858, 860, 862, 864, 866, 620, 622, 2393, 927,
+	929, 931, 933, 935, 937, 939, 941, 943, 945, 947,
+	0, 0, -2, 2407, 0, 0, 0, 1496, 90, 91,
+	92, 93, 94, 95, 96, 97, 98, 99, 163, 164,
+	165, 166, 167, 168, 169, 170, 103, 104, 105, 107,
+	108, 109, 110, 114, 115, 116, 117, 118, 119, 120,
+	121, 122, 123, 124, 125, 126, 127, 128, 129, 160,
+	161, 101, 130, 131, 132, 133, 134, 136, 137, 138,
+	0, 0, 2367, 2369, 2371, 2373, 2403, 0, 0, 8,
+	13, 15, 17, 19, 21, 23, 25, 27, 29, 31,
+	33, 35, 39, 41, 43, 45, 49, 2228, 2230, 1008,
+	1013, 1016, 1018, 1020, 1024, 1027, 1033, 1035, 1037, 988,
+	989, 992, 3154, 3173, 3174, 3175, 3178, 3179, 3180, 3181,
+	3182, 3183, 4376, 4457, 4458, 4459, 4460, 3206, 3207, 3208,
+	3209, 3210, 3211, 3212, 3213, 3214, 3215, 3216, 3217, 3218,
+	3219, 3220, 3221, 3222, 3223, 3224, 3225, 3226, 3227, 3228,
+	3229, 3230, 3231, 3232, 3233, 3234, 3235, 3236, 3237, 3238,
+	3239, 3240, 3241, 3242, 3243, 3244, 3245, 3246, 3247, 3248,
+	3249, 3250, 3251, 3252, 3253, 3254, 3255, 3256, 3257, 3258,
+	3259, 3260, 3261, 3262, 3263, 3264, 3265, 3266, 3267, 3268,
+	3269, 3270, 3271, 3272, 3273, 3274, 3275, 3276, 3277, 3278,
+	3279, 3280, 3281, 3282, 3283, 3284, 3285, 3286, 3287, 3288,
+	3289, 3290, 3291, 3292, 3293, 3294, 3295, 3296, 3297, 3298,
+	3299, 3300, 3301, 3302, 3303, 3304, 3305, 3306, 3307, 3308,
+	3309, 3310, 3311, 3312, 3313, 3314, 3315, 3316, 3317, 3318,
+	3319, 3320, 3321, 3322, 3323, 3324, 3325, 3326, 3327, 3328,
+	3329, 3330, 3331, 3332, 3333, 3334, 3335, 3336, 3337, 3338,
+	3339, 3340, 3341, 3342, 3343, 3344, 3345, 3346, 3347, 3348,
+	3349, 3350, 3351, 3352, 3353, 3354, 3355, 3356, 3357, 3358,
+	3359, 3360, 3361, 3362, 3363, 3364, 3365, 3366, 3367, 3368,
+	3369, 3370, 3371, 3372, 3373, 3374, 3375, 3376, 3377, 3378,
+	3379, 3380, 3381, 3382, 3383, 3384, 3385, 3386, 3387, 3388,
+	3389, 3390, 3391, 3392, 3393, 3394, 3395, 3396, 3397, 3398,
+	3399, 3400, 3401, 3402, 3403, 3404, 3405, 3406, 3407, 3408,
+	3409, 3410, 3411, 3412, 3413, 3414, 3415, 3416, 3417, 3418,
+	3419, 3420, 3421, 3422, 3423, 3424, 3425, 3426, 3427, 3428,
+	3429, 3430, 3431, 3432, 3433, 3434, 3435, 3436, 3437, 3438,
+	3439, 3440, 3441, 3442, 3443, 3444, 3445, 3446, 3447, 3448,
+	3449, 3450, 3451, 3452, 3453, 3454, 3455, 3456, 3457, 3458,
+	3459, 3460, 3461, 3462, 3463, 3464, 3465, 3466, 3467, 3468,
+	3469, 3470, 3471, 3472, 3473, 3474, 3475, 3476, 3477, 3478,
+	3479, 3480, 3481, 3482, 3483, 3484, 3485, 3486, 3487, 3488,
+	3489, 3490, 3491, 3492, 3493, 3494, 3495, 3496, 3497, 3498,
+	3499, 3500, 3501, 3502, 3503, 3504, 3505, 3506, 3507, 3508,
+	3509, 3510, 3511, 3512, 3513, 3514, 3515, 3516, 3517, 3518,
+	3519, 3520, 3521, 3522, 3523, 3524, 3525, 3526, 3527, 3528,
+	3529, 3530, 3531, 3532, 3533, 3534, 3535, 3536, 3537, 3538,
+	3539, 3540, 3541, 3542, 3543, 3544, 3545, 3546, 3547, 3548,
+	3549, 3550, 3551, 3552, 3553, 3554, 3555, 3556, 3557, 3558,
+	3559, 3560, 3561, 3562, 3563, 3564, 3565, 3566, 3567, 3568,
+	3569, 3570, 3571, 3572, 3573, 3574, 3575, 3576, 3577, 3578,
+	3579, 3580, 3581, 3582, 3583, 3584, 3585, 3586, 3587, 3588,
+	3589, 3590, 3591, 3592, 3593, 3594, 3595, 3596, 3597, 3598,
+	3599, 3600, 3601, 3602, 3603, 3604, 3605, 3606, 3607, 3608,
+	3609, 3610, 3611, 3612, 3613, 3614, 3615, 3616, 3617, 3618,
+	3619, 3620, 3621, 3622, 3623, 3624, 3625, 3626, 3627, 3628,
+	3629, 3630, 3631, 3632, 3633, 3634, 3635, 3636, 3637, 3638,
+	3639, 3640, 3641, 3642, 3643, 3644, 3645, 3646, 3647, 3648,
+	3649, 3650, 3651, 3652, 3653, 3654, 3655, 3656, 3657, 3658,
+	3659, 3660, 3661, 3662, 3663, 3664, 3665, 3666, 3667, 3668,
+	3669, 3670, 3671, 3672, 3673, 3674, 3675, 3676, 3677, 3678,
+	3679, 3680, 3681, 3682, 3683, 3684, 3685, 3686, 3687, 3688,
+	3689, 3690, 3691, 3692, 3693, 3694, 4301, 4302, 4303, 4304,
+	4305, 4306, 4307, 4308, 4309, 4310, 4311, 4312, 4313, 4314,
+	4315, 4316, 4317, 4318, 4319, 4320, 4321, 4322, 4323, 4324,
+	4325, 4326, 4327, 4328, 4329, 4330, 4331, 4332, 4333, 4334,
+	4335, 4336, 4337, 4338, 4339, 4340, 4341, 4342, 4343, 4344,
+	4345, 4346, 4347, 4348, 4349, 4350, 4351, 4352, 4353, 4354,
+	4355, 990, 991, 466, 0, 2865, 0, 3168, 3169, -2,
+	-2, -2, 3192, 0, 4356, -2, 4358, 4359, 4360, 4361,
+	4362, 4363, 4364, 4365, 4366, 4367, 4368, 4369, 4370, 4371,
+	4372, 4373, 4374, 4375, 1956, 2394, 0, 1108, 1106, 3135,
+	1109, 3508, 1111, 1113, 910, 911, 912, 913, 914, 915,
+	729, 730, 731, 733, 0, 0, 1146, 3632, 1125, 2405,
+	1147, 1149, 1150, 1151, 1152, 1103, 1101, 3646, 0, 1151,
+	1146, 3211, 3632, 1144, 2201, 2202, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 926, 0, 0,
+	0, 0, -2, 0, 0, 0, 0, 0, 0, 0,
+	0, 824, 608, 0, 2020, 2021, 2022, 2186, 2187, 3573,
+	2238, 0, 329, 1166, -2, -2, 4339, -2, 1248, 1249,
+	-2, -2, 1263, 1267, 1258, 4344, 0, 3576, 3558, -2,
+	1270, 2204, 2206, 2208, 2211, 2213, 2215, 1389, 1390, 1391,
+	3158, 1395, 1393, 1405, 1406, 1409, 0, 1426, -2, 0,
+	3207, 3536, -2, -2, 1427, 1428, -2, -2, -2, -2,
+	1407, 1408, 0, 0, 0, 0, 0, 2557, 2558, 3139,
+	1086, 0, 0, 1383, 1434, 0, 0, 0, 0, -2,
+	-2, -2, 0, 0, 0, -2, 0, -2, 0, -2,
+	-2, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, -2, 0, 0, 1581, 0, 0, 0, -2,
+	-2, -2, -2, -2, 0, 0, 0, 0, 0, 0,
+	0, 0, -2, -2, 0, 0, -2, 0, -2, 0,
+	1716, 0, 0, 0, 1081, 608, 0, 1437, 1440, 1441,
+	1442, 1443, 1444, 1445, 1446, 0, 1450, 1548, 1579, 1580,
+	1591, 2240, 2232, 2235, 2233, 2234, 52, 55, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 337, 339, -2, -2, -2, -2,
+	0, 0, 0, 3280, 4354, -2, 3103, 3175, 3106, 3101,
+	513, 515, 517, 519, 520, 0, 0, 0, 0, 0,
+	0, 0, 552, 555, 557, 559, 561, 563, 565, -2,
+	0, 568, 0, 0, 0, 0, 0, 823, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 898, -2, -2, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 1830, 1822, 1823, 2101, 570,
+	0, 571, -2, 0, 0, -2, 918, 920, 922, 924,
+	993, 994, 0, 2394, 2394, 1001, 1002, 1003, 1004, 1005,
+	-2, -2, 0, 0, 0, 0, 450, 441, 1757, 1759,
+	1761, 1762, 0, 0, 0, 0, 0, 1154, 1156, 0,
+	0, 3632, 408, 1764, 1766, 1768, 1769, 0, 0, 0,
+	0, 0, 0, 452, 0, 0, 1170, 1172, 1174, 1176,
+	1296, 1298, 1300, 1302, 1304, 1306, 1308, 1310, 1312, 1314,
+	1316, 1318, 1320, 1323, 1325, 1327, 1329, 1331, 1333, 1335,
+	1338, 1340, 1342, 1345, 1348, 1350, 1352, 1354, 1356, 1358,
+	1360, 1362, 1364, 1366, 1368, 1370, 1372, 1374, 1376, 1378,
+	1380, 1382, 1387, 0, 2000, 2395, 2240, 2217, 2218, 2219,
+	0, 2224, 2226, 0, 2220, 2221, 2222, 57, 59, 61,
+	63, 65, 67, 69, 71, 73, 75, 77, 79, 81,
+	83, 85, 87, 89, 1196, 1198, 1200, 1202, 1204, 1206,
+	844, 846, 848, 850, 852, 855, 857, 859, 861, 863,
+	865, 867, 621, 623, -2, 2365, 2366, 928, 930, 932,
+	934, 936, 938, 940, 942, 944, 946, 948, 1157, 0,
+	1160, 0, 1439, 1159, -2, 0, 2399, 2399, 2399, 0,
+	0, 2366, 2364, 0, 0, 0, 1163, 1164, 1274, 1275,
+	2703, 0, 0, 0, 0, 0, 0, 0, 0, 2969,
+	2795, 0, 1276, -2, -2, 2828, 2830, 4313, 3476, 4339,
+	2968, 2832, 2833, 2834, 2835, 2836, 0, 2838, 2839, 2840,
+	2841, 2842, 2843, 0, 2845, 0, 2850, 2851, 2852, 0,
+	4320, 3076, 0, 0, 4327, 3164, 0, 2935, 2870, -2,
+	3171, 2632, 2633, 2634, 2635, 2636, 2637, 2638, 2639, -2,
+	4359, 2874, 2875, 2876, 2877, 2878, 2879, 2880, 2881, 2882,
+	2883, 2884, 0, 4301, 4321, 4322, 4328, 4330, 4323, 4310,
+	2895, -2, -2, -2, -2, -2, -2, -2, -2, -2,
+	3298, -2, -2, -2, -2, -2, -2, 2662, 2671, -2,
+	-2, -2, -2, -2, -2, -2, -2, 4314, 4315, 4333,
+	4336, 4343, 4348, 4349, 4319, 4329, 2663, -2, -2, -2,
+	-2, 0, 2382, 3527, 2385, 2504, 2383, 2368, 2370, 0,
+	2372, 3088, 0, 0, 2402, 2400, 0, 2461, 2380, 2381,
+	2487, 2487, 2519, 0, 2492, 0, 2519, 2394, 2551, 0,
+	2498, 3563, 2871, 2872, 3175, 0, 0, 0, 0, 0,
+	0, 0, 1050, 1052, 1054, 1055, 1057, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 1104, 0, 1110, 1112,
+	732, 734, 3188, 3189, 3197, 3198, 3199, 3200, 4357, 0,
+	0, 0, 0, 1146, 1145, 2404, 0, 0, 2256, 0,
+	0, 0, 0, 0, 0, 0, 0, 4321, 638, 282,
+	4321, 737, 741, 744, 282, 4321, 740, 0, 4321, 805,
+	0, 827, 828, 829, 830, 831, 4321, 0, 0, 0,
+	0, 837, 838, 839, 840, 841, 842, 282, 4321, 953,
+	987, 983, 0, 282, 4321, 956, 986, 282, 4321, 959,
+	985, 0, 962, 2099, 282, 4321, 965, 3131, 282, 4321,
+	968, 975, 972, 4321, 971, 1208, 0, 2969, 282, 4321,
+	979, 3148, 3146, 980, 0, 982, 319, 315, 316, 317,
+	318, 2197, 2198, 2199, 2200, 0, 609, 2237, 2100, 1168,
+	0, 1194, 0, 1246, 1247, 4309, -2, 0, 3588, 1251,
+	1252, -2, 1254, 2241, 2245, 2246, 2247, 2248, 2249, 0,
+	0, 0, 0, 2254, 0, 0, 0, 0, 1231, 1232,
+	1261, 1262, 1268, 1271, 0, 1398, 1394, 1410, 0, 1425,
+	0, 1426, 1426, 3120, 3111, 3112, 0, 0, 1426, 1426,
+	0, 0, 1429, 1430, 1431, 1432, 1433, 1078, 0, 1079,
+	0, 1435, 1436, 0, 0, 1455, 1456, 1457, 0, 0,
+	1475, -2, -2, -2, -2, 3261, 1467, 453, 454, 0,
+	1490, 1493, -2, -2, 0, 0, 0, 0, 1500, 0,
+	1505, 1506, 1507, 0, -2, 0, 0, 1515, -2, 0,
+	1520, 1521, 1755, 1524, 0, 1755, 0, 1526, 0, 1530,
+	0, 1533, 1534, 0, 1536, 0, 1538, 0, 1541, 1540,
+	-2, -2, -2, 1549, 1550, -2, 0, 1556, -2, 0,
+	1561, 0, -2, 0, 1564, 0, 1568, -2, 0, 1581,
+	1577, 1578, 0, 0, 0, 0, 1599, 1600, 0, 1604,
+	0, 1608, 0, 1616, 1617, 0, 1620, 1621, 1622, 0,
+	0, 1625, 0, 1629, 1630, 0, 1632, 1633, 1634, 1636,
+	1637, 1652, 0, 3678, 3584, 3280, 3373, 3582, 3339, 3514,
+	3650, 0, 1651, -2, 3322, 1664, 1670, 0, -2, 0,
+	1686, 0, 1691, 1692, 0, 0, 0, 1715, 0, 0,
+	0, 1080, 1082, 609, 0, 1084, 1438, 0, 1447, 1448,
+	1449, 2231, -2, 100, 0, 4321, 2551, 102, 0, 3125,
+	3201, 3202, 3203, 3204, 3205, 4377, 4378, 4379, 4380, 4381,
+	4382, 4383, 4384, 4385, 4386, 4387, 4388, 4389, 4390, 4391,
+	4392, 4393, 4394, 4395, 4396, 4397, 4398, 4399, 4400, 4401,
+	4402, 4403, 4404, 4405, 4406, 4407, 4408, 4409, 4410, 4411,
+	4412, 4413, 4414, 4415, 4416, 4417, 4418, 4419, 4420, 4421,
+	4422, 4423, 4424, 4425, 4426, 4427, 4428, 4429, 4430, 4431,
+	4432, 4433, 4434, 4435, 4436, 4437, 4438, 4439, 4440, 4441,
+	4442, 4443, 4444, 4445, 4446, 4447, 4448, 4449, 4450, 4451,
+	4452, 4453, 4454, 4455, 4456, 106, 0, 4321, 111, 0,
+	4321, 0, -2, 135, 762, 139, 0, 140, 0, 162,
+	0, 190, -2, -2, -2, 171, 0, 4321, 0, 3100,
+	-2, 0, 311, -2, 0, 1073, 442, 443, 0, 632,
+	0, 1062, 0, 1064, 1207, 0, 0, 0, 0, 1794,
+	-2, 0, 2013, 2015, 2015, 0, -2, 0, 0, 0,
+	1745, 3097, 3102, 1746, 1747, 3121, 1748, 3107, 0, 521,
+	522, 523, 524, 525, 526, 4321, 528, 529, 0, 531,
+	532, 4321, 534, 535, 0, 537, 0, 539, 0, 624,
+	380, 378, 4321, 0, 0, 0, 603, 4321, 607, 4321,
+	626, 629, 0, 4321, 635, 0, 0, 0, 825, 0,
+	822, 0, 807, 808, 0, 810, 0, 0, 0, 815,
+	816, 818, 819, 820, 821, 0, 871, 869, 3136, 894,
+	465, 0, -2, 4321, 0, 1791, 0, 0, 2072, -2,
+	0, 2006, -2, 0, 2080, 4321, 2075, 0, -2, 0,
+	0, 2392, 4321, 2261, 1826, 1827, 1828, 1829, 0, 0,
+	901, 902, 2565, 2300, 2565, 2302, 0, 2322, 2559, 2487,
+	0, 0, 2564, 0, -2, 1059, 3157, -2, 996, 0,
+	997, 0, -2, 0, 465, 0, 0, 1772, 1774, 1775,
+	1777, 1778, 1781, 1782, 1783, 1784, 0, 1786, 402, 0,
+	0, 0, 0, 1771, 2188, 2189, 2190, 2191, 2192, 2193,
+	2194, 2195, 2196, 0, 894, 1179, 0, 0, 282, 2555,
+	2216, 2257, 0, 2258, -2, 0, 1158, 0, 1162, 2434,
+	2351, 2348, 0, 2431, 2432, 2352, 0, 0, 0, 2359,
+	0, 2397, 2398, 0, 0, 0, 2338, 2339, 0, 0,
+	0, 0, 0, 0, 2974, 2975, 2976, 2977, 2990, 2978,
+	2979, 2989, 2987, 2988, 2980, 2981, 2986, 3000, 3001, 2991,
+	2992, 2982, 2995, 2993, 2994, 2996, 2997, 2998, 2999, 0,
+	0, 3005, 3006, 3007, 3008, 3009, 0, 2983, 2984, 2985,
+	3017, 0, 0, 3018, 0, 3020, 0, 3010, 3002, 3003,
+	3004, 0, 2774, 2776, 3084, 0, 0, 0, 3016, 3011,
+	3012, 2708, 2709, 2710, 2711, 2712, 2749, 2753, 2754, 0,
+	0, 2829, 3081, 3080, 2831, 0, 0, 3032, 0, 2844,
+	-2, 0, 2969, 3027, 0, 0, 2853, 2854, 2855, 0,
+	0, 3032, 0, 0, 3075, 2867, 2868, 2700, 0, 0,
+	2937, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 2648,
+	0, 2649, 2650, 0, 2651, 2652, 0, -2, 0, 0,
+	2672, 0, 0, 0, 0, 2676, 0, 0, 0, 0,
+	0, 0, 0, 0, 3056, -2, 0, 0, 0, 0,
+	2664, 0, 0, 2384, 0, 0, 0, 2465, 3087, 3085,
+	3091, 3092, 2465, 2465, 0, 0, 3033, 2548, 2548, 0,
+	0, 2542, 2542, 2542, 2540, 2519, 0, 2519, 2529, 0,
+	2519, 2519, -2, 2492, 0, 0, 2533, 0, 2513, 1038,
+	1040, 1042, 1044, 1045, 1046, 1048, 2552, 2553, 0, 0,
+	0, 3176, 2857, 2409, 0, 0, 0, 0, 2864, 0,
+	3119, 3161, 0, 0, 0, 0, 1051, 1053, 1056, 1058,
+	0, 0, 0, 0, 0, 3160, 0, 0, 3130, 547,
+	548, 0, 0, 0, 3654, 3576, 0, -2, -2, -2,
+	-2, 3584, 0, 0, 3280, 3322, 3339, 3514, 1115, 1148,
+	0, 2394, 0, 3035, 2580, 2584, 0, 2586, 2587, 2588,
+	0, 0, 2581, 2683, 3193, 3194, 3195, 2643, 2644, 2645,
+	2646, 2647, 2655, 2642, 2642, 2642, 2653, -2, 2660, 2682,
+	2674, 2682, 2678, 2623, 2624, 2625, 2630, 2665, 2666, 2667,
+	2668, 0, 3654, 3576, 0, -2, 0, 1128, 0, 0,
+	0, 2333, 400, 401, 0, 0, 735, 0, 280, 281,
+	0, 743, 0, 738, 0, 0, 0, 826, 0, 833,
+	834, 835, 0, 949, 0, 0, 282, 4321, 954, 0,
+	957, 0, 282, 4321, 3095, 963, 0, 966, 0, 0,
+	969, 973, 0, 0, 3339, 977, 0, 0, 0, 0,
+	0, 282, 2335, 0, 0, 0, 0, -2, 1256, 1264,
+	1265, 1266, 0, 2243, 0, 2250, 1286, 1287, 1288, 2252,
+	2253, 0, 2255, 1259, 1289, 1290, 1291, 1292, 1293, 1294,
+	0, 3109, 3110, 3115, 3116, 0, 0, 1257, 1279, 1260,
+	0, 1272, 1401, 1396, 1397, 1411, 1412, 0, 0, 3113,
+	3114, 0, 0, 1417, 1418, 1087, 0, 1089, 0, -2,
+	0, 0, 1458, 409, 0, 0, 0, 0, 0, 1475,
+	1475, 1475, 1475, 0, 1488, 1489, 1693, 1694, 1491, 1492,
+	-2, -2, -2, -2, 1494, 1495, 1614, 0, 0, 0,
+	1613, 2179, 0, 1511, 0, 1514, 1517, 1518, 1519, 1522,
+	0, 1727, 3558, 3576, 3654, 1753, 1523, 1614, 3280, 1614,
+	3280, 1614, 3280, 1614, 1614, 1539, 1543, 1594, 1610, 1555,
+	1553, 1570, 3312, 0, 1563, 0, 0, 0, 1557, 1562,
+	1566, 1569, 0, 0, 1574, 1582, 0, 1584, -2, 0,
+	1586, 0, 1588, 0, 1590, 1614, 1602, 1606, 1614, 1618,
+	0, 1624, 1628, 1631, 0, 1638, 0, 1652, 1652, 1641,
+	3140, 1642, 3155, 0, 0, 1645, 1646, 0, 1648, 1649,
+	1650, -2, 0, 1657, 1658, 0, 0, 1677, 1682, 1683,
+	1679, 0, 0, 0, 0, 0, 1695, 1696, 1697, 1698,
+	1699, 1700, 1701, 0, 1709, 1710, 0, 0, 0, 0,
+	1726, 1085, 1083, 0, 1451, 172, 2183, 0, 0, 225,
+	0, 2183, 2183, 0, 0, 0, 0, 262, 0, 0,
+	0, 1860, 0, 655, 656, 657, 0, 0, 0, 190,
+	210, 221, 184, 185, 186, 0, 0, 0, 0, 0,
+	0, 112, 1978, 0, 1981, 0, 0, 0, 0, 0,
+	0, 0, 0, 1995, 1998, 0, 0, 0, 0, 753,
+	0, 716, 0, 0, 750, 761, 0, 0, 703, 704,
+	705, 706, 0, 0, 711, 0, 0, 0, 0, 717,
+	0, 0, 0, 0, 142, 143, 0, 0, 148, 149,
+	0, 0, 209, 0, 0, 0, 0, 0, 0, 2297,
+	0, 200, 190, 0, 0, 189, 191, 174, 0, 0,
+	190, 194, 211, 223, 0, 269, 0, 197, 198, 0,
+	271, 1857, 0, 0, 0, 0, 0, 0, 0, 0,
+	310, 321, 0, 0, 363, 1071, 0, 1074, 0, 0,
+	0, 1063, 1065, 894, 894, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 1224, 0, 0, 1229, 1230,
+	1225, 1228, 0, 0, 0, 0, 0, 2007, 0, 0,
+	0, 2391, 0, 0, 0, 0, 4321, 2181, 0, 2164,
+	0, 2536, 3394, -2, -2, 336, 1744, 0, 0, 3176,
+	3105, 0, 0, 0, 0, 538, 0, 0, 0, 389,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 662, 669, 0, 664, 0, 764, 0, 817,
+	806, 809, 811, 812, 813, 853, 1925, 4321, 0, 0,
+	898, 889, 0, 893, 0, 0, 897, 0, 0, 1977,
+	4321, 1975, 0, 2004, 0, 2071, 1956, 4321, 3138, 0,
+	0, 0, 2081, 3185, 2096, 2100, 2100, 2285, 0, 394,
+	391, 2565, 0, 0, 2303, 2487, 0, 0, 2560, 0,
+	2562, 2487, 2394, 0, 0, 0, 0, 445, 0, 0,
+	0, 0, 0, 1785, 0, 404, 0, 0, 1770, 465,
+	465, 2536, 1181, 2536, 1183, 1999, 0, 2225, 2434, 2351,
+	1161, 2342, 2433, 2343, 2350, 2353, 0, 0, 2355, 0,
+	2357, 0, 2429, 2430, 2437, 2438, 0, 2448, 2449, 2441,
+	0, -2, 0, 0, 2444, 2445, 2361, 0, 2377, 2378,
+	2379, 2410, 2416, 2417, 2115, 0, 4459, 1244, 0, 2704,
+	2575, 2705, 2706, 3124, 0, 2713, 2714, 2715, 2716, 2717,
+	2718, 2719, 2720, 2721, 2722, -2, -2, -2, -2, -2,
+	-2, -2, -2, 2731, 2732, 2733, 2734, 2735, 2736, 2737,
+	2738, 2739, 2740, 2741, 2742, 2743, 2744, 2745, -2, -2,
+	-2, 2750, 2751, 2752, -2, 3019, 3021, 0, 3084, 0,
+	-2, 0, -2, -2, -2, -2, 2771, 0, 2773, 2778,
+	2780, 2782, 0, 0, 0, 0, 3083, 2792, 3067, 3068,
+	0, 0, 2971, 2972, 2973, 2777, 0, 2796, 3082, 3079,
+	0, 0, 3013, 0, 2974, 2975, 2976, 2977, 2978, 2979,
+	2980, 2981, 2982, 2983, 2984, 2985, 2986, 2987, 2988, 2989,
+	2990, 2991, 2992, 2993, 2994, 2995, 2996, 2997, 2998, 2999,
+	3000, 3001, 3002, 3003, 3004, 3005, 3006, 3007, 3008, 3009,
+	3010, 0, 3031, 2409, 2849, 3029, 0, 3028, 0, 0,
+	0, 3039, 3032, 0, 3074, 3070, 0, 3122, 2699, 2686,
+	2687, 2688, 2689, 2690, 2691, 2701, 0, 3161, 3167, 2945,
+	0, 0, 0, 2896, 2897, 2898, 2899, 2900, 0, 2902,
+	2903, 0, 2905, 2906, 0, 2908, 2909, 0, 2911, 2912,
+	2913, 2914, 2915, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 2591, 2592, 2593, 2594, 2595, 2596, 2597,
+	2598, 2599, 2600, 2601, 2602, 2603, 2604, 2605, 2606, 2607,
+	2608, 2609, 2610, 2611, 2612, 2613, 2614, 2615, 2616, 2617,
+	2618, 2619, 2620, 2621, 2622, 0, 0, 0, 2917, 0,
+	3042, -2, -2, -2, -2, -2, -2, -2, -2, 0,
+	2919, 0, 2921, 3033, 3053, 0, 0, 2797, 0, 0,
+	0, 0, 0, 2924, 3033, 3061, 0, 0, 0, 0,
+	0, 3033, 0, 3066, 0, 2931, 0, 2933, 1497, 1498,
+	2386, 2389, 0, 2505, 0, 2570, 0, 0, 3715, 3708,
+	4049, -2, -2, 4177, 3938, -2, 3909, 0, 3090, 4045,
+	3093, 3094, 3695, 3696, 3697, 3698, 3699, 3700, 3701, 3702,
+	3703, 3704, 3705, 3706, 3707, 3709, 3710, 3711, 3712, 3713,
+	3714, 3716, 3717, 3718, 3719, 3720, 3721, 3722, 3723, 3724,
+	3725, 3726, 3727, 3729, 3730, 3731, 3732, 3733, 3734, 3735,
+	3736, 3737, 3738, 3739, 3740, 3741, 3742, 3743, 3744, 3745,
+	3746, 3747, 3748, 3749, 3750, 3751, 3752, 3753, 3754, 3755,
+	3756, 3757, 3758, 3759, 3760, 3761, 3762, 3763, 3764, 3765,
+	3766, 3767, 3768, 3769, 3770, 3771, 3772, 3773, 3774, 3775,
+	3776, 3777, 3778, 3779, 3780, 3781, 3782, 3783, 3784, 3785,
+	3786, 3787, 3788, 3789, 3790, 3791, 3792, 3793, 3794, 3795,
+	3796, 3797, 3798, 3799, 3800, 3801, 3802, 3803, 3804, 3805,
+	3806, 3807, 3808, 3809, 3810, 3811, 3812, 3813, 3814, 3815,
+	3816, 3817, 3818, 3819, 3820, 3821, 3822, 3823, 3824, 3825,
+	3826, 3827, 3828, 3829, 3830, 3831, 3832, 3833, 3834, 3835,
+	3836, 3837, 3838, 3839, 3840, 3841, 3842, 3843, 3844, 3845,
+	3846, 3847, 3848, 3849, 3850, 3851, 3852, 3853, 3854, 3855,
+	3856, 3857, 3858, 3859, 3860, 3861, 3862, 3863, 3864, 3865,
+	3866, 3867, 3868, 3869, 3870, 3871, 3872, 3873, 3874, 3875,
+	3876, 3877, 3878, 3879, 3880, 3881, 3882, 3883, 3884, 3885,
+	3886, 3887, 3888, 3889, 3890, 3891, 3892, 3893, 3894, 3895,
+	3896, 3897, 3898, 3899, 3900, 3901, 3902, 3903, 3905, 3906,
+	3907, 3908, 3910, 3911, 3912, 3913, 3914, 3915, 3916, 3917,
+	3918, 3919, 3920, 3921, 3922, 3923, 3924, 3925, 3926, 3927,
+	3928, 3929, 3930, 3931, 3932, 3933, 3934, 3935, 3936, 3937,
+	3939, 3940, 3941, 3942, 3943, 3944, 3945, 3946, 3947, 3948,
+	3949, 3950, 3951, 3952, 3953, 3954, 3955, 3956, 3957, 3958,
+	3959, 3960, 3961, 3962, 3964, 3965, 3966, 3967, 3968, 3969,
+	3970, 3971, 3972, 3973, 3974, 3975, 3976, 3977, 3978, 3979,
+	3980, 3981, 3982, 3983, 3984, 3985, 3986, 3987, 3988, 3989,
+	3990, 3991, 3992, 3993, 3994, 3995, 3996, 3997, 3998, 3999,
+	4000, 4001, 4002, 4003, 4004, 4005, 4006, 4007, 4008, 4009,
 	4010, 4011, 4012, 4013, 4014, 4015, 4016, 4017, 4018, 4019,
 	4020, 4021, 4022, 4023, 4024, 4025, 4026, 4027, 4028, 4029,
 	4030, 4031, 4032, 4033, 4034, 4035, 4036, 4037, 4038, 4039,
-	4040, 4041, 4042, 4043, 4044, 4045, 4046, 4047, 4048, 4049,
-	4050, 4051, 4052, 4053, 4054, 4055, 4056, 4057, 4058, 826,
-	827, 427, 0, 2633, 0, 2931, 2932, -2, -2, -2,
-	2955, 0, 4059, -2, 4061, 4062, 4063, 4064, 4065, 4066,
-	4067, 4068, 4069, 4070, 4071, 4072, 4073, 4074, 4075, 4076,
-	4077, 4078, 1749, 2171, 0, 933, 931, 2898, 934, 3253,
-	936, 938, 750, 751, 752, 753, 754, 755, 0, 971,
-	3369, 950, 2182, 972, 974, 975, 976, 977, 928, 926,
-	0, 976, 971, 2974, 3369, 969, 1986, 1987, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 766, 0,
-	0, 0, 0, -2, 0, 0, 0, 0, 0, 0,
-	0, 0, 667, 532, 0, 1812, 1813, 1814, 1971, 1972,
-	3314, 2017, 0, 296, 991, -2, -2, 4043, -2, 1068,
-	1069, -2, -2, 1083, 1087, 1078, 4048, 0, 3317, 3299,
-	-2, 1090, 1989, 1991, 1993, 1199, 1200, 1201, 2921, 1205,
-	1203, 1215, 1216, 1219, 0, 1236, -2, 0, 2970, 3279,
-	-2, -2, 1237, 1238, -2, -2, -2, -2, 1217, 1218,
-	0, 0, 0, 0, 0, 2331, 2332, 2902, 918, 0,
-	1193, 1244, 0, 0, 0, 0, -2, -2, -2, 0,
-	0, 0, -2, 0, -2, -2, -2, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, -2, 0, 0, 1393,
-	0, 0, 0, -2, -2, -2, -2, -2, 0, 0,
-	0, 0, 0, 0, 0, -2, -2, 0, 0, -2,
-	0, -2, 0, 1520, 0, 0, 0, 913, 532, 0,
-	1247, 1250, 1251, 1252, 1253, 1254, 1255, 1256, 0, 1260,
-	1360, 1391, 1392, 1403, 2019, 2011, 2014, 2012, 2013, 50,
-	53, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 304, 306, -2, -2, -2,
-	-2, 0, 0, 0, 3040, 4057, -2, 2866, 2938, 2869,
-	2864, 474, 476, 478, 480, 481, 0, 0, 0, 0,
-	0, 0, 0, 512, 515, 517, 519, 521, 523, -2,
-	0, 526, 0, 0, 666, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 738, -2, -2, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 1627, 1619, 1620, 1886, -2, 0, 0,
-	-2, 758, 760, 762, 764, 829, 830, 0, 2171, 2171,
-	837, 838, 839, 840, -2, -2, 0, 0, 0, 0,
-	409, 400, 1554, 1556, 1558, 1559, 0, 0, 0, 0,
-	0, 979, 981, 0, 0, 3369, 363, 1561, 1563, 1565,
-	1566, 0, 0, 0, 0, 0, 0, 411, 0, 0,
-	995, 997, 999, 1001, 1116, 1118, 1120, 1122, 1124, 1126,
-	1128, 1130, 1132, 1134, 1137, 1139, 1141, 1143, 1145, 1147,
-	1149, 1152, 1154, 1156, 1159, 1162, 1164, 1166, 1168, 1170,
-	1172, 1174, 1176, 1178, 1180, 1182, 1184, 1186, 1188, 1190,
-	1192, 1197, 0, 1792, 2172, 2019, 1996, 1997, 1998, 2003,
-	2005, 1999, 2000, 2001, 55, 57, 59, 61, 63, 65,
-	67, 69, 71, 73, 75, 77, 79, 81, 83, 1021,
-	1023, 1025, 1027, 1029, 688, 690, 692, 694, 696, 699,
-	701, 703, 705, 707, 544, 546, -2, 2141, 2142, 768,
-	770, 772, 774, 776, 778, 780, 782, 784, 982, 0,
-	985, 0, 1249, 984, -2, 0, 2176, 2176, 2176, 0,
-	0, 2142, 2140, 0, 0, 0, 988, 989, 1094, 1095,
-	2474, 0, 0, 0, 0, 0, 0, 0, 0, 2737,
-	2563, 0, 1096, -2, -2, 2596, 2598, 4017, 3225, 4043,
-	2736, 2600, 2601, 2602, 2603, 2604, 0, 2606, 2607, 2608,
-	2609, 2610, 2611, 0, 2613, 0, 2618, 2619, 2620, 0,
-	4024, 2841, 0, 0, 4031, 2927, 0, 2703, 2638, -2,
-	2934, 2404, 2405, 2406, 2407, 2408, 2409, 2410, -2, 4062,
-	2642, 2643, 2644, 2645, 2646, 2647, 2648, 2649, 2650, 2651,
-	2652, 0, 4005, 4025, 4026, 4032, 4034, 4027, 4014, 2663,
-	-2, -2, -2, -2, -2, -2, -2, -2, -2, 3059,
-	-2, -2, -2, -2, -2, -2, 2433, 2442, -2, -2,
-	-2, -2, -2, -2, -2, 4018, 4019, 4037, 4040, 4047,
-	4052, 4053, 4023, 4033, 2434, -2, -2, -2, -2, 0,
-	2159, 3271, 2162, 2279, 2160, 2144, 2146, 0, 2148, 0,
-	0, 0, 2153, 2179, 2177, 0, 2238, 2157, 2158, 2262,
-	2262, 2294, 0, 2267, 0, 2294, 2171, 2325, 0, 2273,
-	3304, 2639, 2640, 2938, 0, 0, 0, 0, 0, 0,
-	0, 884, 886, 888, 889, 891, 0, 0, 0, 0,
-	0, 0, 0, 0, 929, 0, 935, 937, 0, 0,
-	0, 0, 971, 970, 2181, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 266, 4025, 622, 626, 629, 266,
-	4025, 625, 0, 670, 671, 672, 673, 674, 4025, 0,
-	0, 0, 0, 680, 681, 682, 683, 684, 685, 686,
-	266, 4025, 789, 823, 819, 0, 266, 4025, 792, 822,
-	266, 4025, 795, 821, 0, 798, 1884, 266, 4025, 801,
-	2894, 266, 4025, 804, 811, 808, 4025, 807, 1031, 0,
-	2737, 266, 4025, 815, 2911, 2909, 816, 0, 818, 286,
-	282, 283, 284, 285, 1982, 1983, 1984, 1985, 0, 533,
-	2016, 1885, 993, 0, 1019, 0, 1066, 1067, 4013, -2,
-	0, 3329, 1071, 1072, -2, 1074, 2020, 2024, 2025, 2026,
-	2027, 2028, 0, 0, 0, 0, 2033, 0, 0, 0,
-	0, 1051, 1052, 1081, 1082, 1088, 1091, 0, 1208, 1204,
-	1220, 0, 1235, 0, 1236, 1236, 2883, 2874, 2875, 0,
-	0, 1236, 1236, 0, 0, 1239, 1240, 1241, 1242, 1243,
-	910, 0, 911, 1245, 1246, 0, 0, 1265, 1266, 1267,
-	0, 0, 1285, -2, -2, -2, -2, 3021, 1277, 412,
-	413, 2951, 2952, 2960, 2961, 2962, 2963, 4060, 0, 1309,
-	1312, -2, -2, 0, 0, 0, 0, 1319, 0, 1324,
-	1325, 1326, 0, -2, 0, 1334, 1336, 1552, 1339, 0,
-	1552, 0, 1341, 0, 1345, 0, 1348, 1349, 0, 1351,
-	0, 1353, -2, -2, -2, 1361, 1362, -2, 0, 1368,
-	-2, 0, 1373, 0, -2, 0, 1376, 0, 1380, -2,
-	0, 1393, 1389, 1390, 0, 0, 0, 0, 1411, 1412,
-	0, 1416, 0, 1420, 0, 1429, 0, 1432, 1433, 1434,
-	0, 0, 1439, 1440, 0, 1442, 1443, 1444, 1446, 1447,
-	1461, 0, 3412, 3325, 3040, 3130, 3323, 3097, 3258, 0,
-	1460, -2, 3081, 1472, 1474, 0, -2, 0, 1490, 0,
-	1495, 1496, 0, 0, 0, 1519, 0, 0, 0, 912,
-	914, 533, 0, 916, 1248, 0, 1257, 1258, 1259, 2010,
-	-2, 94, 0, 4025, 2325, 96, 0, 2888, 2964, 2965,
-	2966, 2967, 2968, 4080, 4081, 4082, 4083, 4084, 4085, 4086,
-	4087, 4088, 4089, 4090, 4091, 4092, 4093, 4094, 4095, 4096,
-	4097, 4098, 4099, 4100, 4101, 4102, 4103, 4104, 4105, 4106,
-	4107, 4108, 4109, 4110, 4111, 4112, 4113, 4114, 4115, 4116,
-	4117, 4118, 4119, 4120, 4121, 4122, 4123, 4124, 4125, 4126,
-	4127, 4128, 4129, 4130, 4131, 4132, 4133, 4134, 4135, 4136,
-	4137, 4138, 4139, 4140, 4141, 4142, 4143, 4144, 4145, 4146,
-	4147, 4148, 4149, 4150, 4151, 4152, 4153, 4154, 4155, 4156,
-	4157, 4158, 4159, 100, 0, 4025, 105, 0, 4025, 0,
-	-2, 129, 647, 133, 0, 134, 0, 156, 0, 184,
-	-2, -2, -2, 165, 0, 4025, 0, 2863, -2, 0,
-	278, -2, 0, 905, 401, 402, 0, 896, 1030, 0,
-	0, 0, 0, 1591, -2, 0, 1805, 1807, 1807, 0,
-	-2, 0, 0, 0, 1542, 2860, 2865, 1543, 1544, 2884,
-	1545, 2870, 0, 482, 483, 484, 485, 486, 487, 4025,
-	489, 490, 0, 492, 493, 4025, 495, 496, 0, 498,
-	0, 500, 0, 547, 345, 343, 4025, 0, 534, 4025,
-	531, 4025, 549, 552, 0, 0, 668, 0, 665, 0,
-	649, 650, 0, 652, 0, 0, 0, 657, 658, 660,
-	661, 662, 663, 664, 0, 711, 709, 2899, 734, 426,
-	0, -2, 4025, 0, 1588, 0, 0, 1859, -2, 0,
-	1798, -2, 0, 1867, 4025, 1862, 0, -2, 0, 2169,
-	4025, 2037, 1623, 1624, 1625, 1626, 0, 741, 742, 0,
-	2076, 0, 2078, 0, 2098, 2333, 2262, 0, 0, 2338,
-	0, -2, 893, 2920, -2, 832, 0, 833, 0, -2,
-	0, 426, 0, 0, 1569, 1571, 1572, 1574, 1575, 1578,
-	1579, 1580, 1581, 0, 1583, 2311, 364, 366, 0, 0,
-	0, 0, 1568, 1973, 1974, 1975, 1976, 1977, 1978, 1979,
-	1980, 1981, 0, 734, 1004, 0, 0, 266, 2329, 1995,
-	0, -2, 0, 983, 0, 987, 2211, 2127, 2124, 0,
-	2208, 2209, 2128, 0, 0, 0, 2135, 0, 2174, 2175,
-	0, 0, 0, 2114, 2115, 0, 0, 0, 0, 0,
-	0, 2742, 2743, 2744, 2745, 2758, 2746, 2747, 2757, 2755,
-	2756, 2748, 2749, 2754, 2768, 2769, 2759, 2760, 2750, 2763,
-	2761, 2762, 2764, 2765, 2766, 2767, 0, 0, 2773, 2774,
-	0, 2751, 2752, 2753, 2782, 0, 0, 2783, 0, 2785,
-	0, 2775, 2770, 2771, 2772, 0, 2542, 2544, 2849, 0,
-	0, 0, 2781, 2776, 2777, 2479, 2480, 2481, 2482, 2483,
-	2517, 2521, 2522, 0, 0, 2597, 2846, 2845, 2599, 0,
-	0, 2797, 0, 2612, -2, 0, 2737, 2792, 0, 0,
-	2621, 2622, 2623, 0, 0, 2797, 0, 0, 2840, 2635,
-	2636, 2471, 0, 0, 2705, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 2419, 0, 2420, 2421, 0, 2422, 2423,
-	0, -2, 0, 0, 2443, 0, 0, 0, 0, 2447,
-	0, 0, 0, 0, 0, 0, 0, 2821, -2, 0,
-	0, 0, 0, 2435, 0, 0, 2161, 0, 0, 0,
-	2242, 2850, 2854, 2855, 2242, 2242, 0, 0, 2798, 2322,
-	2322, 0, 0, 2317, 2317, 2317, 2315, 2294, 0, 2294,
-	2304, 0, 2294, 2294, -2, 2267, 0, 0, 2308, 0,
-	2288, 872, 874, 876, 878, 879, 880, 882, 2326, 2327,
-	0, 0, 0, 2939, 2625, 2186, 0, 0, 0, 0,
-	2632, 0, 2882, 2924, 0, 0, 0, 0, 885, 887,
-	890, 892, 0, 0, 0, 0, 2923, 0, 0, 2893,
-	507, 508, 0, 0, 0, 3390, 3317, 0, -2, -2,
-	-2, -2, 3325, 0, 0, 3040, 3081, 3097, 3258, 940,
-	973, 0, 2171, 0, 2800, 2354, 2358, 0, 2360, 2361,
-	2362, 0, 0, 2355, 2454, 2956, 2957, 2958, 2414, 2415,
-	2416, 2417, 2418, 2426, 2413, 2413, 2413, 2424, -2, 2431,
-	2453, 2445, 2453, 2449, 2397, 2398, 2399, 2436, 2437, 2438,
-	2439, 0, 3390, 3317, 0, -2, 0, 953, 0, 0,
-	0, 2109, 355, 356, 620, 0, 264, 265, 0, 628,
-	0, 623, 0, 669, 0, 676, 677, 678, 0, 785,
-	0, 0, 266, 4025, 790, 0, 793, 0, 266, 4025,
-	2858, 799, 0, 802, 0, 0, 805, 809, 0, 0,
-	3097, 813, 0, 0, 0, 0, 0, 266, 2111, 0,
-	0, 0, 0, -2, 1076, 1084, 1085, 1086, 0, 2022,
-	0, 2029, 1106, 1107, 1108, 2031, 2032, 0, 2034, 1079,
-	1109, 1110, 1111, 1112, 1113, 1114, 0, 2872, 2873, 2878,
-	2879, 0, 0, 1077, 1099, 1080, 0, 1092, 1211, 1206,
-	1207, 1221, 1222, 0, 0, 2876, 2877, 0, 0, 1227,
-	1228, 919, 0, 921, 0, 0, 1268, 364, 0, 0,
-	1271, 0, 1285, 1285, 1285, 1285, 1301, 1307, 1308, 1497,
-	1498, 1310, 1311, -2, -2, -2, -2, 1313, 1314, 1426,
-	0, 0, 0, 1425, 1964, 0, 1330, 1333, 1337, 0,
-	1524, 3299, 3317, 3390, 1550, 1338, 1426, 3040, 1426, 3040,
-	1426, 3040, 1426, 1426, 1355, 1406, 1422, 1367, 1365, 1382,
-	3071, 0, 1375, 0, 0, 0, 1369, 1374, 1378, 1381,
-	0, 0, 1386, 1394, 0, 1396, -2, 0, 1398, 0,
-	1400, 0, 1402, 1426, 1414, 1418, 1427, 1430, 0, 1438,
-	1441, 0, 1448, 0, 1461, 1461, 1451, 2903, 1452, 2918,
-	0, 0, 1455, 1456, 1457, 1458, 1459, -2, 0, 1465,
-	1466, 0, 0, 1481, 1486, 1487, 1483, 0, 0, 0,
-	0, 0, 1499, 1500, 1501, 1502, 1503, 1504, 1505, 0,
-	1513, 1514, 0, 0, 0, 0, 1523, 917, 915, 0,
-	1261, 166, 1968, 0, 0, 219, 0, 1968, 1968, 0,
-	0, 0, 0, 247, 0, 0, 1657, 0, 0, 0,
-	0, 184, 204, 215, 178, 179, 180, 0, 0, 0,
-	0, 0, 0, 106, 1771, 0, 1774, 0, 0, 0,
-	0, 0, 0, 0, 1787, 1790, 0, 0, 0, 0,
-	638, 0, 607, 0, 0, 635, 646, 0, 0, 594,
-	595, 596, 597, 0, 0, 602, 0, 0, 0, 0,
-	608, 0, 0, 0, 0, 136, 137, 0, 0, 142,
-	143, 0, 0, 203, 0, 0, 0, 0, 0, 0,
-	2073, 0, 194, 184, 0, 0, 183, 185, 168, 0,
-	0, 184, 188, 205, 217, 0, 253, 0, 191, 192,
-	0, 255, 1654, 0, 0, 0, 0, 0, 0, 0,
-	0, 277, 288, 0, 0, 330, 903, 0, 906, 0,
-	895, 897, 734, 734, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 1044, 0, 0, 1049, 1050, 0, 1045,
-	1048, 0, 0, 0, 0, 1799, 0, 0, 0, 2168,
-	0, 0, 0, 0, 4025, 1966, 0, 1949, 0, 2311,
-	3150, -2, -2, 2311, 1541, 0, 0, 2939, 2868, 0,
-	0, 0, 0, 499, 0, 0, 0, 354, 527, 0,
-	0, 0, 0, 0, 554, 563, 0, 556, 0, 659,
-	648, 651, 653, 654, 655, 697, 1718, 4025, 0, 0,
-	738, 729, 0, 733, 0, 0, 737, 0, 0, 1770,
-	4025, 1768, 0, 1796, 0, 1858, 1749, 4025, 2901, 0,
-	0, 0, 1868, 2948, 1881, 1885, 2061, 0, 2339, 0,
-	0, 2079, 2081, 0, 0, 2334, 0, 2336, 2262, 2171,
-	0, 0, 0, 0, 404, 0, 0, 0, 0, 0,
-	1582, 370, 0, 2310, 0, 0, 414, 2311, 364, 0,
-	1567, 426, 426, 2311, 1006, 2311, 1008, 1791, 0, 2004,
-	2211, 2127, 986, 2118, 2210, 2119, 2126, 2129, 0, 0,
-	2131, 0, 2133, 0, 2206, 2207, 2214, 2215, 0, 2225,
-	2226, 2218, 0, -2, 0, 0, 2221, 2222, 2137, 0,
-	2154, 2155, 2156, 2187, 2193, 2194, 1900, 0, 4162, 1064,
-	0, 2475, 2349, 2476, 2477, 2887, 0, 2484, 2485, 2486,
-	2487, 2488, 2489, 2490, 2491, 2492, 2493, -2, -2, -2,
-	-2, -2, -2, -2, -2, 2502, 2503, 2504, 2505, 2506,
-	2507, 2508, 2509, 2510, 2511, 2512, 2513, -2, -2, -2,
-	2518, 2519, 2520, -2, 2784, 2786, 0, 2849, 0, -2,
-	0, -2, -2, -2, -2, 2539, 0, 2541, 2546, 2548,
-	2550, 0, 0, 0, 0, 2848, 2560, 2832, 2833, 0,
-	0, 2739, 2740, 2741, 2545, 0, 2564, 2847, 2844, 0,
-	0, 2778, 0, 2742, 2743, 2744, 2745, 2746, 2747, 2748,
-	2749, 2750, 2751, 2752, 2753, 2754, 2755, 2756, 2757, 2758,
-	2759, 2760, 2761, 2762, 2763, 2764, 2765, 2766, 2767, 2768,
-	2769, 2770, 2771, 2772, 2773, 2774, 2775, 0, 2796, 2186,
-	2617, 2794, 0, 2793, 0, 0, 0, 2804, 2797, 0,
-	2839, 2835, 0, 2885, 2470, 2457, 2458, 2459, 2460, 2461,
-	2462, 2472, 0, 2924, 2930, 2713, 0, 0, 0, 2664,
-	2665, 2666, 2667, 2668, 0, 2670, 2671, 0, 2673, 2674,
-	0, 2676, 2677, 0, 2679, 2680, 2681, 2682, 2683, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 2365,
-	2366, 2367, 2368, 2369, 2370, 2371, 2372, 2373, 2374, 2375,
-	2376, 2377, 2378, 2379, 2380, 2381, 2382, 2383, 2384, 2385,
-	2386, 2387, 2388, 2389, 2390, 2391, 2392, 2393, 2394, 2395,
-	2396, 0, 0, 2685, 0, 2807, -2, -2, -2, -2,
-	-2, -2, -2, -2, 0, 2687, 0, 2689, 2798, 2818,
-	0, 0, 2565, 0, 0, 0, 0, 0, 2692, 2798,
-	2826, 0, 0, 0, 0, 0, 2798, 0, 2831, 0,
-	2699, 0, 2701, 1316, 1317, 2163, 2166, 0, 2280, 0,
-	2344, 0, 0, 3449, 3442, 3769, -2, -2, 3889, 3665,
-	-2, 3637, 0, 2853, 3765, 2856, 2857, 3429, 3430, 3431,
-	3432, 3433, 3434, 3435, 3436, 3437, 3438, 3439, 3440, 3441,
-	3443, 3444, 3445, 3446, 3447, 3448, 3450, 3451, 3452, 3453,
-	3454, 3455, 3456, 3457, 3458, 3459, 3460, 3462, 3463, 3464,
-	3465, 3466, 3467, 3468, 3469, 3470, 3471, 3472, 3473, 3474,
-	3475, 3476, 3477, 3478, 3479, 3480, 3481, 3482, 3483, 3484,
-	3485, 3486, 3487, 3488, 3489, 3490, 3491, 3492, 3493, 3494,
-	3495, 3496, 3497, 3498, 3499, 3500, 3501, 3502, 3503, 3504,
-	3505, 3506, 3507, 3508, 3509, 3510, 3511, 3512, 3513, 3514,
-	3515, 3516, 3517, 3518, 3519, 3520, 3521, 3522, 3523, 3524,
-	3525, 3526, 3527, 3528, 3529, 3530, 3531, 3532, 3533, 3534,
-	3535, 3536, 3537, 3538, 3539, 3540, 3541, 3542, 3543, 3544,
-	3545, 3546, 3547, 3548, 3549, 3550, 3551, 3552, 3553, 3554,
-	3555, 3556, 3557, 3558, 3559, 3560, 3561, 3562, 3563, 3564,
-	3565, 3566, 3567, 3568, 3569, 3570, 3571, 3572, 3573, 3574,
-	3575, 3576, 3577, 3578, 3579, 3580, 3581, 3582, 3583, 3584,
-	3585, 3586, 3587, 3588, 3589, 3590, 3591, 3592, 3593, 3594,
-	3595, 3596, 3597, 3598, 3599, 3600, 3601, 3602, 3603, 3604,
-	3605, 3606, 3607, 3608, 3609, 3610, 3611, 3612, 3613, 3614,
-	3615, 3616, 3617, 3618, 3619, 3620, 3621, 3622, 3623, 3624,
-	3625, 3626, 3627, 3628, 3629, 3630, 3631, 3632, 3634, 3635,
-	3636, 3638, 3639, 3640, 3641, 3642, 3643, 3644, 3645, 3646,
-	3647, 3648, 3649, 3650, 3651, 3652, 3653, 3654, 3655, 3656,
-	3657, 3658, 3659, 3660, 3661, 3662, 3663, 3664, 3666, 3667,
-	3668, 3669, 3670, 3671, 3672, 3673, 3674, 3675, 3676, 3677,
-	3678, 3679, 3680, 3681, 3682, 3683, 3684, 3685, 3686, 3687,
-	3688, 3689, 3691, 3692, 3693, 3694, 3695, 3696, 3697, 3698,
-	3699, 3700, 3701, 3702, 3703, 3704, 3705, 3706, 3707, 3708,
-	3709, 3710, 3711, 3712, 3713, 3714, 3715, 3716, 3717, 3718,
-	3719, 3720, 3721, 3722, 3723, 3724, 3725, 3726, 3727, 3728,
-	3729, 3730, 3731, 3732, 3733, 3734, 3735, 3736, 3737, 3738,
-	3739, 3740, 3741, 3742, 3743, 3744, 3745, 3746, 3747, 3748,
-	3749, 3750, 3751, 3752, 3753, 3754, 3755, 3756, 3757, 3758,
-	3759, 3760, 3761, 3762, 3763, 3764, 3766, 3767, 3768, 3770,
-	3771, 3772, 3773, 3774, 3775, 3776, 3777, 3778, 3779, 3780,
-	3781, 3782, 3783, 3784, 3785, 3786, 3787, 3788, 3789, 3790,
-	3791, 3792, 3793, 3794, 3795, 3796, 3797, 3798, 3799, 3800,
-	3801, 3802, 3803, 3804, 3805, 3806, 3807, 3808, 3809, 3810,
-	3811, 3812, 3813, 3814, 3815, 3816, 3817, 3818, 3819, 3820,
-	3821, 3822, 3823, 3824, 3825, 3826, 3827, 3828, 3829, 3830,
-	3831, 3832, 3833, 3834, 3835, 3836, 3837, 3838, 3839, 3840,
-	3841, 3842, 3843, 3844, 3845, 3846, 3847, 3848, 3849, 3850,
-	3851, 3852, 3853, 3854, 3855, 3856, 3857, 3858, 3859, 3860,
-	3861, 3862, 3863, 3864, 3865, 3866, 3867, 3868, 3869, 3870,
-	3871, 3872, 3873, 3874, 3875, 3876, 3877, 3878, 3879, 3880,
-	3881, 3882, 3883, 3884, 3885, 3886, 3887, 3888, 3890, 3891,
-	3892, 3893, 3894, 3895, 3896, 3897, 3898, 3899, 3900, 3901,
-	3902, 3903, 3904, 3905, 3906, 3907, 3908, 3909, 3910, 3911,
-	3912, 3913, 3914, 3915, 3916, 3917, 3918, 3919, 3920, 3921,
-	3922, 3923, 3924, 3925, 3926, 3927, 3928, 3929, 3930, 3931,
-	3932, 3933, 3934, 3935, 3936, 3937, 3938, 3939, 3940, 3941,
-	3942, 3943, 3944, 3945, 3946, 3947, 3948, 3949, 3950, 3951,
-	3952, 3953, 3954, 3955, 3956, 3957, 3958, 3959, 3960, 3961,
-	3962, 3963, 3964, 3965, 3966, 3967, 3968, 3969, 3970, 3971,
-	3972, 3973, 3974, 3975, 3976, 3977, 3978, 3979, 3980, 3981,
-	3982, 3983, 3984, 3985, 3986, 3987, 3988, 3989, 3990, 3991,
-	3992, 3993, 3994, 3995, 3996, 3997, 3998, 3999, 4000, 4001,
-	4002, 4003, 4004, 2344, 2344, 0, 2237, 0, 0, 2318,
-	2319, 2320, 2321, 0, 0, 2322, 0, 2312, 2316, 2313,
-	2314, 2304, 2259, 0, 0, 2889, 2304, 2265, 2303, 0,
-	2279, 2293, 2304, 2304, -2, 2269, 2307, 0, 2282, 2294,
-	0, 0, 873, 875, 877, 881, 883, 0, 0, -2,
-	0, 0, 0, 2185, 0, 2186, 2186, 0, 2631, 2634,
-	0, -2, 429, -2, 431, 1748, 0, 0, 0, 0,
-	0, 0, 0, 930, 932, 0, 0, 810, 0, 0,
-	0, 0, 0, 1530, 0, 1532, 1533, 0, 1535, 1536,
-	0, 1952, 924, 0, 927, 0, 2345, 2348, 0, 0,
-	2359, 2363, 2364, 2455, 0, 0, 0, 0, 0, 0,
-	0, 0, 968, 0, 3369, 0, 966, 0, 627, 266,
-	0, 631, 632, 0, 0, 575, 576, 577, 578, 580,
-	2959, 581, -2, -2, 266, 0, 679, 266, 820, 787,
-	0, 266, 266, 796, 0, 0, 266, 812, 266, 808,
-	1032, 2912, 266, 2910, 287, 817, 2110, 299, 0, 1063,
-	0, 2021, 2030, 0, 1103, 0, 1105, 0, 2880, 2881,
-	0, 1093, 0, 1209, 0, 1223, 1224, 1225, 1226, 0,
-	920, 426, 0, 0, 1285, 1283, 0, 1286, 1288, 1289,
-	0, 1291, 1292, 0, 0, 0, 1296, 0, 1298, 1272,
-	1273, 1274, 1275, 1276, 0, 1357, 1408, 1424, 1485, 1318,
-	1320, 1321, 1322, 0, 1327, 0, 0, 0, 0, 0,
-	1551, 1546, 1547, 1548, 2913, 2909, 1549, 1340, 1426, 1343,
-	1426, 1346, 1426, 1350, 1352, 0, 1384, 1371, 0, 1372,
-	1576, 1577, 1377, 1379, 1395, 1388, 1397, 0, 0, 0,
-	1410, 0, 0, 0, 1436, 0, 1445, 1462, 1449, 1450,
-	1453, 0, 1464, -2, 1469, 1470, 0, 0, 0, 0,
-	0, 0, 0, 1499, 1499, 1499, 1494, 0, 1511, 1516,
-	1515, 0, 1521, 1522, 1262, 0, 0, 0, 0, 1967,
-	0, 0, 1912, 0, 0, 223, 4025, 0, 268, 0,
-	0, 1711, 2895, 0, 1699, 0, 0, 3068, 0, 0,
-	0, 0, 0, 240, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 175, 0, 181, 182, 0, 0,
-	0, 0, 0, 0, 0, 0, 1772, 1773, 1775, 1782,
-	1784, 0, 1778, 1779, 0, 1781, 1783, 1785, 0, 1788,
-	0, 0, 0, 0, 0, 0, 634, 636, 637, 607,
-	0, 0, 0, 0, 0, 0, 0, 600, 601, 603,
-	604, 605, 606, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 144, 148, 1808, 3323, 0, 0, 0, 0,
-	1809, 1810, 1811, 2049, 2050, 0, 2072, 2073, 0, 0,
-	0, 0, 0, 0, 0, 177, 0, 0, 0, 190,
-	193, 0, 2862, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 329, 331, 0, 907, 0, 908,
-	0, 898, 426, 900, 901, 422, 419, 421, 902, 0,
-	0, 1037, 1036, 1038, 1039, 1040, 0, 0, 0, 0,
-	0, 1057, 0, 0, 1058, 1046, 1047, 0, 0, 1801,
-	0, 1854, 1852, 1824, 1825, 1826, 1827, 1828, 1829, 1830,
-	1831, 1832, 1833, 1834, 1835, 1836, 1837, 1838, 1839, 1840,
-	1841, 1842, 1843, 1844, 1845, 1846, 1847, 1848, 1849, 1850,
-	1851, 0, 0, 0, 0, -2, 1803, 1804, 0, 0,
-	0, 0, 0, 0, 0, 0, 309, 0, 417, 2861,
-	2871, 0, 488, 491, 494, 497, -2, -2, 0, 0,
-	0, 535, 0, 0, 551, 565, 565, 0, 1629, 1601,
-	0, 0, 710, 426, 734, 736, 0, 424, 3228, 2916,
-	1586, 1766, 1769, 0, 1749, 4025, 1820, 0, 0, 0,
-	0, 0, 1874, 0, 1866, 0, 0, 4025, 2890, 2947,
-	2948, 2063, 2073, 0, 749, 0, 745, 0, 2096, 2082,
-	0, 0, 0, 2096, 2100, 2101, 2103, 2104, 0, 0,
-	2335, 2341, 831, 894, 2171, 2171, 426, 0, 0, 2085,
-	2087, 0, 0, 0, 357, 0, 367, 2311, 365, 0,
-	370, 0, 2311, 364, 0, 725, 1005, 1010, 2330, 2122,
-	2123, 2125, 0, 2134, 0, 0, 2220, -2, -2, 2219,
-	2223, 2224, -2, -2, -2, -2, 2130, 0, 2139, 2136,
-	0, 2205, 1898, 1899, 0, 0, 1065, 0, 0, -2,
-	-2, 0, 0, 0, 2561, 0, -2, 2540, 2543, 2547,
-	2549, 2551, 0, 0, 0, 0, 0, 0, 2787, 0,
-	2789, 2562, 2842, 2845, 2780, 0, 2735, 0, 0, 2795,
-	0, 2802, 2803, 0, 2624, 0, 2836, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 2637, 0, 0, 0,
-	0, 2669, 2672, 2675, 2678, 0, 0, 0, 0, 2658,
-	0, 0, 0, 2662, 2425, 2411, 0, 0, 2428, 2432,
-	2453, 2451, 2452, 2446, 2453, 2450, 2401, 0, 2400, 0,
-	2684, 0, 2686, 2688, 0, 0, 2690, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 2568, 2569, 2570, 2590, 2691, 2824, 2825, 0, 0,
-	0, 0, 0, 0, 2697, 0, 2830, 2698, 2700, 0,
-	2164, 0, 2278, 0, 2239, 2228, 2343, 0, 2851, 2311,
-	2241, 2243, 2852, 2892, 2228, 2228, 0, 2799, 0, 0,
-	2298, 0, 0, 0, 2300, 2263, 0, 0, 2257, 0,
-	2247, 2248, 2249, 2250, 2251, 2252, 2253, 0, 2264, 2279,
-	2302, 2266, 2270, 0, 2282, 2306, 0, 2304, 0, 2289,
-	0, 2291, 2328, 0, 2275, 2308, 0, 2940, 2626, 0,
-	0, 0, 0, 2630, 2925, 2344, 0, 430, -2, 433,
-	501, 509, 510, 502, 503, 504, 505, 0, 1952, 0,
-	0, 0, 0, 0, 0, 1531, 1534, 0, 949, 0,
-	0, 2801, 0, 2350, 0, 2356, 0, 951, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 2108, 621, 630,
-	0, 0, 574, 0, 573, 579, 624, 675, 786, 266,
-	791, 794, 2859, 266, 800, 803, 806, 814, 295, 0,
-	1018, -2, 1101, 1102, 1104, 0, 1100, 1214, 1210, 0,
-	923, 1263, 0, 0, 1270, 0, 0, 1290, 0, 0,
-	0, 0, 1299, 0, 1302, 0, 0, 0, 0, 0,
-	1964, 1964, 1961, 1332, 0, 1342, 1344, 1347, 1383, 1399,
-	1401, 1426, 1413, 1417, 0, 1437, 1454, 1468, 1475, 2891,
-	1476, 1651, 0, 1651, 0, 0, 1491, 1492, 1493, 1506,
-	1507, 1508, 1509, 1510, 1512, 1518, 220, 1968, 0, 0,
-	0, 1908, 0, 1612, 0, 1607, 1608, 1910, 2908, 1914,
-	1920, 1923, 0, 225, 4025, 237, 0, 4025, 0, 1673,
-	0, 0, 0, 0, 0, 0, 1970, 0, 0, 4025,
-	266, 4025, 266, 241, 243, 246, 0, 252, 248, 0,
-	1609, 0, 1661, 0, 0, 1664, 167, 1968, 0, 0,
-	170, 174, 186, 0, 0, 0, 202, 0, 0, 0,
-	1925, 1929, 1937, 0, 0, 0, 1776, 1777, 1780, 1786,
-	1789, 107, 0, 0, 0, 1933, 1935, 1941, 639, 640,
-	641, 0, 0, 0, 598, 599, 643, 644, 645, 135,
-	138, 4025, 2904, 2905, 0, 140, 4025, 0, 149, 2073,
-	0, 0, 0, 0, 1907, 0, 0, 0, 0, 0,
-	0, 0, 0, 254, 172, 176, 187, 0, 1943, 169,
-	189, 0, 281, 0, 0, 271, 266, 4025, 0, 273,
-	0, 274, 275, 289, 0, 0, 0, 0, 0, 0,
-	0, 336, 0, 0, 0, 904, 0, 899, 0, 0,
-	0, 1033, 1034, 1035, 0, 1043, 539, 0, 0, 1053,
-	1061, 1059, 1054, 1055, 1056, 1589, 1590, 1853, 0, 1794,
-	1795, 340, 341, 0, 1806, 1800, 0, 0, 0, 0,
-	0, 1945, 1946, 0, 0, 0, 1966, 2311, 301, 0,
-	2311, 309, 0, 2867, 0, 328, 0, 426, 728, 0,
-	344, 353, 0, 534, 548, 0, 564, 566, 568, 0,
-	0, 0, 0, 1628, 1729, 1630, 1632, 1633, 1634, 268,
-	0, 0, 0, 1699, 3136, 2948, 0, 0, 1596, 0,
-	0, 0, 716, 712, 0, 723, 730, 731, 0, 0,
-	0, -2, 0, 0, 0, 0, -2, 0, 0, 0,
-	1870, 0, 1873, 0, 1865, 0, 0, 0, 0, 4025,
-	2065, 2073, 0, 2169, 2344, 0, 743, 0, 747, 2074,
-	2096, 0, 0, 0, 2084, 2080, 2077, 2344, 0, 0,
-	0, 0, 0, 2337, 2340, 834, 835, 403, 0, 426,
-	0, 0, 0, 0, 0, 0, 368, 0, 371, 0,
-	0, 0, 376, 377, 378, 379, 380, 381, 382, 0,
-	0, 385, 0, 0, 0, 390, 391, 392, 0, 0,
-	395, 325, 326, 398, 399, 396, 397, 370, 415, 359,
-	2311, 370, 0, 0, 1007, 0, 2132, 0, 2217, 2138,
-	2195, 2196, 2202, 0, 1900, 0, 2478, 2524, 0, 0,
-	-2, 0, 0, 2528, 0, 0, 0, -2, 0, 0,
-	0, 2788, 2790, 0, 2844, 2779, 2626, 2614, 2615, 0,
-	2738, 2805, 2834, 2838, 0, 2463, 2464, 2465, 2466, 2467,
-	2468, 2469, 0, 2886, 2925, 2929, 2711, 2712, 2716, 2900,
-	0, 0, 0, 2641, 0, 0, 0, 0, 0, 0,
-	0, 0, 2427, 2444, 2448, 0, 0, 2806, 2817, 2819,
-	2566, 2567, 2571, 2572, 2573, 2574, 2575, 2576, 2577, 2578,
-	2579, 2580, -2, -2, -2, 2584, 2585, 2586, -2, -2,
-	-2, 2591, 0, 0, 0, 2820, 2822, 2823, 2827, 2828,
-	0, 2694, 2695, 2696, 2829, 2171, 2165, 2281, 2236, 0,
-	2342, 2240, 0, 2236, 2236, 2178, 2296, 0, 0, 2324,
-	0, 2260, 0, 2261, 0, 0, 0, 2301, 2268, 2305,
-	0, 2284, 2286, 2271, 2272, 2290, 0, 2274, 0, 2277,
-	-2, 2186, 2188, 2197, 2627, 2629, 0, 428, 434, 0,
-	437, 0, 442, 443, 0, 0, 0, 0, 448, 0,
-	0, 0, 0, 432, 0, 939, 1952, 1952, 0, 0,
-	0, 0, 941, 0, 925, 0, 0, 2352, 0, 2456,
-	955, 957, 0, 0, 0, 0, 0, 3390, 3317, 0,
-	0, 954, 633, 571, 572, 788, 797, 297, 0, 2309,
-	0, 0, 0, 922, 426, 1285, 1287, 0, 1293, 1294,
-	1295, 1297, 0, 0, 0, 0, 0, 1323, 1963, 1328,
-	1329, 2914, 1409, 1435, 1477, 1650, 0, 0, 1479, 0,
-	0, 0, 0, 249, 0, 0, 0, 0, 0, 0,
-	267, 0, 1710, 0, 1671, 0, 0, 1698, 0, 0,
-	1716, 227, 228, 229, 0, 0, 0, 0, 239, 0,
-	0, 235, 0, 245, 251, 250, 0, 1658, 0, 0,
-	0, 0, 1913, 0, 0, 0, 199, 200, 201, 0,
-	206, 0, 207, 0, 0, 0, 0, 0, 0, 0,
-	0, 592, 0, 0, 0, 0, 146, 0, 0, 0,
-	151, 152, 0, 0, 2055, 2056, 0, 2040, 196, 0,
-	0, 0, 0, 0, 0, 269, 0, 0, 0, 1897,
-	291, 0, 0, 0, 0, 0, 332, 333, 334, 335,
-	0, 313, 315, 0, 0, 0, 321, 323, 0, 0,
-	342, 0, 423, 418, 420, 0, 1042, 0, 0, 0,
-	0, 0, 1793, 1856, 1857, 1802, 1926, 1930, 1938, 0,
-	0, 0, 0, 0, 976, 1965, 0, 309, 307, 0,
-	310, 309, 303, 0, 0, 426, 0, 739, 0, 528,
-	0, 0, 0, 0, 0, 584, 656, 1599, 1717, 0,
-	0, 1719, 1635, 1639, 0, 0, 2948, 0, 0, 0,
-	2897, 0, 1597, 0, 0, 1718, 708, 714, 0, 717,
-	0, 720, 0, 722, 0, 735, 2896, 0, 0, 0,
-	1770, 0, 0, 1797, 1749, 1823, 1749, 0, 1869, 1871,
-	1863, 0, 1875, 0, 1883, 0, 0, 0, 2067, 2073,
-	0, 2060, 2061, 2184, 748, 746, 2075, 2094, -2, 0,
-	0, 2184, 2102, 2099, 2105, 2106, 0, 0, 406, 0,
-	2086, 2088, 0, 1570, 1573, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 358, 370,
-	361, 2311, 410, 0, 2216, 2203, 2204, 2200, 1900, 2526,
-	2530, 0, 0, 0, 2532, -2, 0, 2554, -2, -2,
-	2791, 2843, 2605, 2616, 2837, 2473, 0, 2718, 2715, 0,
-	2702, 0, 2653, 2654, 0, 0, 2657, 2659, 2660, 2661,
-	2412, 2403, 2402, 2816, 0, 0, 0, 0, 2693, 0,
-	2707, 0, 0, 2244, 2707, 2707, 2297, 0, 2299, 2258,
-	2245, 0, 2254, 0, 0, 2283, 0, 2287, 2292, 2276,
-	0, 0, 2926, 438, 0, 439, 0, 0, 0, 0,
-	0, 0, 464, 0, 0, 0, 0, 0, 0, 0,
-	444, 445, 446, 447, 449, 450, 0, 0, 0, 0,
-	506, 942, 943, 0, 0, 0, 0, 0, 1951, 2346,
-	2351, 0, 2357, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 967, 298, 0, 1212, 1213, 1264, 1269,
-	1284, 1303, 0, 1304, 1305, 1306, 1649, 0, 0, 0,
-	0, 221, 222, 1613, 1611, 1917, 1921, 1918, 0, 224,
-	0, 0, 1672, 0, 1675, 0, 0, 0, 0, 1682,
-	1699, 0, 0, 0, 0, 0, 0, 1701, 0, 1700,
-	0, 0, 1733, 0, 1888, 1895, 0, -2, 0, 0,
-	0, 231, 257, 0, 0, 0, 0, 260, 1969, 233,
-	0, 0, 266, 266, 1610, 0, 0, 1909, 1911, 1924,
-	0, 0, 0, 0, 209, 0, 0, 1927, 1931, 1939,
-	1934, 1936, 1942, 642, 593, 0, 0, 141, 150, 2043,
-	0, 0, 0, 2057, 0, 195, 0, 0, 0, 1944,
-	279, 280, 0, 266, 0, 266, 272, 266, 1897, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 337, 338,
-	339, 0, 0, 540, 541, 0, 1062, 1060, 0, 0,
-	0, 0, 0, 0, 1947, 1948, 300, 0, 0, 302,
-	416, 309, 0, 0, 0, 0, 550, 560, 567, 569,
-	570, 617, 583, 585, 0, 0, 589, 590, 591, 1660,
-	0, 1729, 1721, 1722, 1723, 0, 1631, 1728, 1730, 0,
-	0, 1636, 0, 0, 0, 0, 0, 0, 1616, 1598,
-	0, 1629, 1601, 718, 0, 719, 721, 713, 0, 425,
-	1587, 1767, 1815, 1749, 0, 1818, 0, 0, 1860, 0,
-	0, 0, 1874, 0, 0, 0, 0, 0, 2069, 2073,
-	0, 2062, 2063, 2213, 2183, 0, 0, 0, 2083, 2213,
-	0, 426, 0, 426, 372, 0, 373, 374, 375, 383,
-	384, 386, 387, 388, 389, 0, 394, 360, 370, 1009,
-	1011, 0, 0, 0, 1017, 2201, 2534, -2, -2, 2555,
-	2928, 2186, 0, 2704, 2189, 2190, 0, 0, -2, 0,
-	0, 0, 2167, 2150, 0, 2235, 2227, 2229, 2231, 3302,
-	3035, 4024, 2151, 2152, 2323, 0, 0, 0, 2285, 2628,
-	2198, 2199, 435, 0, 455, 456, 457, 458, 459, 460,
-	461, 462, 463, 465, 466, 467, 468, 469, 470, 471,
-	0, 441, 451, 0, 453, 454, 944, 0, 0, 0,
-	0, 0, 2353, 0, 0, 0, 0, 952, 0, 0,
-	0, 0, 0, 1202, 1300, 1478, 1480, 0, 0, 0,
-	0, 1919, 226, 0, 0, 1676, 1677, 1679, 0, 1681,
-	1683, 1684, 1601, 0, 1688, 0, 2950, 0, 1693, 1696,
-	1697, 0, 0, 1712, 1734, 0, 1743, 0, 1890, 1900,
-	1894, 0, 1892, 1745, 0, 230, 259, 232, 261, 256,
-	0, 1897, 0, 234, 244, 0, 0, 171, 0, 0,
-	3028, 212, 210, 208, 139, 145, 2906, 147, 153, 1906,
-	198, 0, 173, 0, 281, 290, 1896, 292, 276, 266,
-	0, 312, 314, 316, 317, 318, 319, 0, 322, 324,
-	0, 1041, 542, 1928, 1932, 1940, 0, 1955, 1956, 1957,
-	1958, 1959, 0, 0, 0, 311, 0, 0, 352, 0,
-	0, 0, 562, 559, 555, 615, 0, 0, 586, 619,
-	609, 588, 1601, 1659, 1600, 1720, 0, 1731, 1601, 0,
-	0, 1745, 0, 0, 0, 0, 0, 1603, 0, 1602,
-	0, 0, 715, 2344, 732, 0, 0, 0, 1822, 0,
-	1872, 1876, 1870, 0, 0, 1882, 0, 0, 0, 2039,
-	0, 0, 2064, 2065, 2096, 2212, 2089, 0, 0, 2096,
-	2107, 405, 0, 408, 369, 393, 362, 0, 1013, 0,
-	1015, 0, 2722, 0, 0, 0, 2655, 2656, -2, 0,
-	2594, 2706, 2708, 0, 0, 0, 0, 0, 2246, 2255,
-	2256, 440, 472, 452, 1952, 1952, 1952, 1952, 2347, 959,
-	960, 962, 964, 956, 958, 0, 0, 0, 1488, 1489,
-	1915, 0, 1922, 268, 1674, 1678, 0, 1685, 0, 0,
-	0, 1689, 1753, 0, 0, 1770, 1770, 1702, 0, 0,
-	1737, 1738, 1656, 0, 1739, 1740, 1741, 1889, 2205, 1895,
-	1601, 0, 0, 258, 263, 0, 0, 0, 0, 0,
-	0, 0, 197, 0, 270, 293, 1897, 320, 0, 0,
-	1960, 0, 0, 308, 349, 726, 0, 0, 538, 0,
-	0, 561, 614, 610, 587, 0, 1603, 0, 1732, 1637,
-	1640, 1641, 1642, 1643, 1644, 1645, 1646, 1647, 1648, 1638,
-	1743, 1745, 0, 1656, 0, 1709, 1614, 0, 1617, 0,
-	1599, 0, 724, 0, 1816, 0, 1823, 0, 1864, 0,
-	1883, 0, 0, 2052, 2038, 2073, 2066, 2067, 740, 2344,
-	0, 2097, 0, 1012, 0, 0, 0, 0, 0, 0,
-	2717, 2191, 2192, 2595, 0, 0, 2230, 2232, 2233, 2234,
-	945, 946, 947, 948, 0, 0, 0, 1916, 238, 0,
-	1747, 1687, 1758, 0, 0, 0, 0, 0, 1703, 1735,
-	1736, 1733, 1655, 0, 1893, 1891, 1714, 1747, 1749, 236,
-	0, 1745, 0, 1665, 0, 0, 1668, 0, 0, 213,
-	3028, 211, 2907, 0, 266, 909, 1952, 266, 0, 352,
-	0, 0, 0, 529, 0, 0, 584, 582, 2171, 618,
-	1595, 0, 1725, 1727, 1656, 1743, 1745, 1601, 1656, 0,
-	1618, 1660, 1616, 1817, 1821, 1819, 1861, 1745, 0, 1743,
-	0, 2059, 2073, 2053, 2054, 0, 2069, 0, 0, 426,
-	1014, 1016, 2714, 2734, 2723, -2, 3393, 3036, 0, 2734,
-	2734, 2709, 2710, 0, 0, 0, 0, 1601, 0, 1690,
-	1754, 1755, 0, 1750, 1751, 1752, 2949, 1691, 1692, 1694,
-	1695, 2344, 0, 1744, 1753, 262, 1601, 1662, 0, 0,
-	1663, 0, 0, 216, 0, 218, 294, 1950, 1953, 0,
-	327, 0, 0, 2344, 536, 0, 0, 617, 0, 616,
-	611, 612, 1592, 1594, 1601, 0, 1601, 1656, 1743, 2344,
-	1601, 0, 0, 0, 1601, 1603, 1743, 0, 1656, 0,
-	2048, 2058, 0, 2068, 2039, 0, 2092, 0, 407, 2719,
-	0, 0, 2725, 2726, 2727, 2728, 2729, 2720, 2721, 961,
-	963, 965, 1680, 1686, 0, 1756, 0, 1757, 0, 0,
-	0, 1713, 1742, 1758, 242, 1666, 0, 1669, 0, 214,
-	0, 347, 348, 350, 0, 0, 0, 538, 553, 613,
-	1724, 1726, 2344, 1601, 1656, 1905, 2344, 1604, 0, 1606,
-	1603, 1615, 1656, 0, 1601, 0, 2071, 2047, 2051, 2052,
-	2090, 0, 0, 0, 2731, 2732, 0, 0, 0, 1759,
-	0, 1762, 1763, 0, 1760, 1733, 0, 0, 266, 0,
-	352, 0, 530, 1905, 2344, 1601, 1707, 0, 1902, 1903,
-	0, 1905, 1605, 1595, 1601, 1745, 2344, 1743, 2045, 2073,
-	2059, 0, 2344, 2730, 2733, 2724, 1746, 1761, 1764, 1765,
-	1715, 0, 0, 1954, 351, 727, 537, 1704, 1905, 2344,
-	1901, 1904, 1708, 1593, 2344, 1743, 1905, 1656, 2042, 2044,
-	0, 0, 2048, 2344, 2093, 1653, 0, 1705, 1905, 1905,
-	1656, 1879, 1601, 2035, 2041, 0, 0, 2070, 2071, 2091,
-	1667, 1652, 0, 1706, 1877, 1601, 2344, 0, 2045, 0,
-	2344, 1905, 0, 2042, 0, 1905, 1880, 2046, 2036, 1653,
-	1878, 1670,
+	4040, 4041, 4042, 4043, 4044, 4046, 4047, 4048, 4050, 4051,
+	4052, 4053, 4054, 4055, 4056, 4057, 4058, 4059, 4060, 4061,
+	4062, 4063, 4064, 4065, 4066, 4067, 4068, 4069, 4070, 4071,
+	4072, 4073, 4074, 4075, 4076, 4077, 4078, 4079, 4080, 4081,
+	4082, 4083, 4084, 4085, 4086, 4087, 4088, 4089, 4090, 4091,
+	4092, 4093, 4094, 4095, 4096, 4097, 4098, 4099, 4100, 4101,
+	4102, 4103, 4104, 4105, 4106, 4107, 4108, 4109, 4110, 4111,
+	4112, 4113, 4114, 4115, 4116, 4117, 4118, 4119, 4120, 4121,
+	4122, 4123, 4124, 4125, 4126, 4127, 4128, 4129, 4130, 4131,
+	4132, 4133, 4134, 4135, 4136, 4137, 4138, 4139, 4140, 4141,
+	4142, 4143, 4144, 4145, 4146, 4147, 4148, 4149, 4150, 4151,
+	4152, 4153, 4154, 4155, 4156, 4157, 4158, 4159, 4160, 4161,
+	4162, 4163, 4164, 4165, 4166, 4167, 4168, 4169, 4170, 4171,
+	4172, 4173, 4174, 4175, 4176, 4178, 4179, 4180, 4181, 4182,
+	4183, 4184, 4185, 4186, 4187, 4188, 4189, 4190, 4191, 4192,
+	4193, 4194, 4195, 4196, 4197, 4198, 4199, 4200, 4201, 4202,
+	4203, 4204, 4205, 4206, 4207, 4208, 4209, 4210, 4211, 4212,
+	4213, 4214, 4215, 4216, 4217, 4218, 4219, 4220, 4221, 4222,
+	4223, 4224, 4225, 4226, 4227, 4228, 4229, 4230, 4231, 4232,
+	4233, 4234, 4235, 4236, 4237, 4238, 4239, 4240, 4241, 4242,
+	4243, 4244, 4245, 4246, 4247, 4248, 4249, 4250, 4251, 4252,
+	4253, 4254, 4255, 4256, 4257, 4258, 4259, 4260, 4261, 4262,
+	4263, 4264, 4265, 4266, 4267, 4268, 4269, 4270, 4271, 4272,
+	4273, 4274, 4275, 4276, 4277, 4278, 4279, 4280, 4281, 4282,
+	4283, 4284, 4285, 4286, 4287, 4288, 4289, 4290, 4291, 4292,
+	4293, 4294, 4295, 4296, 4297, 4298, 4299, 4300, 2570, 2570,
+	0, 2460, 0, 0, 2543, 2544, 2545, 2546, 2547, 0,
+	0, 2548, 0, 2537, 2541, 2538, 2539, 2529, 2484, 0,
+	0, 3126, 2529, 2490, 2528, 0, 2504, 2518, 2529, 2529,
+	-2, 2494, 2532, 0, 2507, 2519, 0, 0, 1039, 1041,
+	1043, 1047, 1049, 0, 0, -2, 0, 0, 0, 2408,
+	0, 2409, 2409, 0, 2863, 2866, 0, -2, 468, -2,
+	470, 1955, 0, 0, 0, 0, 0, 0, 0, 0,
+	1105, 1107, 0, 0, 974, 0, 0, 0, 0, 0,
+	1733, 0, 1735, 1736, 0, 1738, 1739, 0, 2167, 1099,
+	0, 1102, 0, 2571, 2574, 0, 0, 2585, 2589, 2590,
+	2684, 0, 0, 0, 0, 0, 0, 0, 0, 1143,
+	0, 3632, 0, 1141, 0, 282, 0, 742, 282, 0,
+	746, 747, 0, 0, 681, 682, 683, 684, 686, 3196,
+	687, -2, -2, 282, 282, 0, 0, 836, 282, 984,
+	951, 0, 282, 282, 960, 0, 0, 282, 976, 282,
+	972, 1209, 3149, 282, 3147, 320, 981, 2334, 2536, 0,
+	1243, 0, 2242, 2251, 0, 1283, 0, 1285, 0, 3117,
+	3118, 0, 1273, 0, 1399, 0, 1413, 1414, 1415, 1416,
+	0, 1088, 0, 1094, 1095, 0, 465, 0, 0, 455,
+	0, 1475, 1461, 1473, 0, 1476, 1478, 1479, 0, 1481,
+	1482, 0, 0, 0, 1486, 0, 0, 0, 0, 0,
+	1466, 1545, 1596, 1612, 1681, 1499, 1501, 1502, 1503, 0,
+	1508, 0, 0, 0, 0, 0, 0, 1754, 1749, 1750,
+	1751, 3150, 3146, 1752, 1525, 1614, 1528, 1614, 1531, 1614,
+	1535, 1537, 0, 1572, 1559, 0, 1560, 1779, 1780, 1565,
+	1567, 1583, 1576, 1585, 0, 0, 0, 1598, 0, 0,
+	1615, 0, 1626, 0, 1635, 1653, 1654, 1639, 1640, 1643,
+	0, 0, 1656, -2, 1661, 1662, 0, 0, 0, 0,
+	0, 0, 0, 1695, 1695, 1695, 1690, 0, 1707, 1712,
+	1711, 0, 1721, 1721, 1452, 0, 0, 0, 0, 2182,
+	0, 0, 2127, 0, 0, 229, 4321, 0, 284, 0,
+	0, 1918, 3132, 0, 1902, 0, 0, 3309, 0, 0,
+	0, 0, 0, 255, 0, 658, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 181, 0, 187, 188,
+	0, 0, 0, 0, 0, 0, 0, 0, 1979, 1980,
+	1982, 1990, 1992, 0, 1985, 0, 1987, 0, 1989, 1991,
+	1993, 0, 1996, 0, 0, 0, 0, 0, 0, 749,
+	751, 752, 716, 0, 0, 0, 0, 0, 0, 0,
+	709, 710, 712, 713, 714, 715, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 150, 154, 2016, 3582, 0,
+	0, 0, 0, 2017, 2018, 2019, 2273, 2274, 0, 2296,
+	2297, 0, 0, 0, 0, 0, 0, 0, 183, 0,
+	0, 0, 196, 199, 0, 3099, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 362, 364, 0,
+	0, 1075, 0, 1076, 0, 649, 0, 1066, 465, 1068,
+	1069, 461, 458, 460, 1070, 0, 0, 0, 1215, 0,
+	1214, 1216, 1217, 1218, 0, 0, 0, 0, 0, 1237,
+	0, 0, 1238, 1226, 1227, 0, 0, 2009, 0, 2065,
+	2063, 2032, 2033, 2034, 2035, 2036, 2037, 2038, 2039, 2040,
+	2041, 2042, 2043, 2044, 2045, 2046, 2047, 2048, 2049, 2050,
+	2051, 2052, 2053, 2054, 2055, 2056, 2057, 2058, 2059, 2060,
+	2061, 2062, 0, 0, 0, 0, 0, -2, 2011, 2012,
+	0, 0, 0, 0, 0, 0, 0, 0, 342, 2535,
+	0, 3098, 3108, 0, 527, 530, 533, 536, -2, -2,
+	0, 0, 0, 574, 0, 575, 0, 577, 0, 0,
+	0, 628, 641, 0, 671, 671, 0, 765, 766, 0,
+	0, 1832, 1804, 0, 0, 870, 465, 894, 896, 0,
+	463, 3479, 3153, 1789, 1973, 1976, 0, 1956, 4321, 2028,
+	0, 0, 0, 0, 0, 2087, 0, 2079, 0, 0,
+	4321, 3127, 3184, 3185, 3185, 2287, 2297, 0, 390, 0,
+	909, 0, 905, 0, 2320, 2306, 0, 0, 0, 2305,
+	2320, 2324, 2325, 2327, 2328, 0, 0, 2561, 2567, 995,
+	1060, 2394, 2394, 465, 0, 0, 2309, 2311, 0, 0,
+	0, 2536, 0, 406, 0, 0, 885, 1180, 1185, 2556,
+	2346, 2347, 2349, 0, 2358, 0, 0, 2443, -2, -2,
+	2442, 2446, 2447, -2, -2, -2, -2, 2354, 0, 2363,
+	2360, 0, 2428, 2113, 2114, 0, 0, 1245, 0, 0,
+	-2, -2, 0, 0, 0, 2793, 0, -2, 2772, 2775,
+	2779, 2781, 2783, 0, 0, 0, 0, 0, 0, 3022,
+	0, 3024, 2794, 3077, 3080, 3015, 0, 2967, 0, 0,
+	3030, 0, 3037, 3038, 0, 2856, 0, 3071, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 2869, 0, 0,
+	0, 0, 2901, 2904, 2907, 2910, 0, 0, 0, 0,
+	2890, 0, 0, 0, 2894, 2654, 2640, 0, 0, 2657,
+	2661, 2682, 2680, 2681, 2675, 2682, 2679, 2627, 0, 2626,
+	0, 2631, 2916, 0, 2918, 2920, 0, 0, 2922, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 2800, 2801, 2802, 2822, 2923, 3059, 3060,
+	0, 0, 0, 0, 0, 0, 2929, 0, 3065, 2930,
+	2932, 0, 2387, 0, 2503, 0, 2462, 2451, 2569, 0,
+	2536, 2464, 2466, 3086, 3089, 3129, 2451, 2451, 0, 3034,
+	0, 0, 2523, 0, 0, 0, 2525, 2488, 0, 0,
+	2482, 0, 2470, 2471, 2472, 2473, 2474, 2475, 2476, 2477,
+	2478, 0, 2489, 2504, 2527, 2491, 2495, 0, 2507, 2531,
+	0, 2529, 0, 2514, 0, 2516, 2554, 0, 2500, 2533,
+	0, 3177, 2858, 0, 0, 0, 0, 2862, 3162, 2570,
+	0, 469, -2, 472, 540, 549, 550, 541, 542, 543,
+	544, 545, 0, 2167, 0, 0, 0, 0, 0, 0,
+	1734, 1737, 0, 1124, 0, 0, 3036, 0, 2576, 0,
+	2582, 0, 1126, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 2332, 636, 0, 736, 745, 0, 0, 680,
+	0, 679, 685, 739, 803, 0, 832, 950, 282, 955,
+	958, 3096, 282, 964, 967, 970, 978, 332, 1193, -2,
+	1281, 1282, 1284, 0, 1280, 1404, 1400, 0, 1092, 0,
+	1090, 1097, 1098, 1453, 0, 410, 0, 0, 1460, 0,
+	0, 1480, 0, 0, 0, 0, 1462, 1463, 1464, 1465,
+	0, 0, 2179, 2179, 2176, 0, 0, 0, 1513, 0,
+	1527, 1529, 1532, 1571, 1587, 1589, 1614, 1601, 1605, 0,
+	1627, 1644, 1647, 1660, 1671, 3128, 1672, 1854, 0, 1854,
+	0, 0, 1687, 1688, 1689, 1702, 1703, 1704, 1705, 1706,
+	1708, 1714, 1717, 0, 1718, 226, 2183, 0, 0, 0,
+	2123, 0, 1815, 0, 1810, 1811, 2125, 3145, 2129, 2135,
+	2138, 0, 231, 4321, 252, 0, 4321, 0, 1876, 0,
+	0, 0, 0, 0, 0, 2185, 0, 0, 4321, 282,
+	4321, 282, 256, 258, 261, 0, 268, 263, 0, 1812,
+	0, 0, 1864, 0, 0, 1867, 173, 2183, 0, 0,
+	176, 180, 192, 0, 0, 0, 208, 0, 0, 0,
+	2140, 2144, 2152, 0, 0, 0, 1983, 1984, 0, 1988,
+	1994, 1997, 113, 0, 0, 0, 2148, 2150, 2156, 754,
+	755, 756, 0, 0, 0, 707, 708, 758, 759, 760,
+	141, 144, 4321, 3141, 3142, 0, 146, 4321, 0, 155,
+	2297, 0, 0, 0, 0, 2122, 0, 0, 0, 0,
+	0, 0, 0, 0, 270, 178, 182, 193, 0, 2158,
+	175, 195, 0, 314, 0, 0, 304, 282, 4321, 0,
+	306, 0, 307, 308, 322, 0, 0, 0, 0, 0,
+	0, 0, 369, 0, 0, 0, 373, 0, 1072, 0,
+	0, 654, 0, 1061, 1067, 0, 0, 0, 0, 1211,
+	1212, 1213, 0, 0, 1221, 0, 613, 0, 0, 1233,
+	1241, 1239, 1234, 1235, 1236, 1792, 1793, 2064, 0, 2002,
+	2003, 375, 376, 0, 2069, 2070, 2014, 2008, 0, 0,
+	0, 0, 0, 2160, 2161, 0, 0, 0, 2181, 2536,
+	334, 0, 2536, 3104, 0, 361, 0, 465, 888, 0,
+	379, 388, 0, 0, 0, 578, 0, 604, 625, 647,
+	0, 0, 0, 670, 672, 674, 0, 0, 768, 770,
+	771, 772, 774, 767, 0, 0, 0, 1831, 1936, 1833,
+	1835, 1836, 1837, 284, 0, 0, 0, 1902, 3380, 4353,
+	3185, 0, 0, 1799, 0, 0, 0, 876, 872, 0,
+	883, 890, 891, 0, 0, 0, -2, 0, 0, 0,
+	0, -2, 0, 0, 0, 2083, 0, 2086, 0, 2078,
+	0, 0, 0, 0, 4321, 0, 4321, 2289, 2297, 0,
+	2392, 392, 0, 395, 0, 0, 0, 2570, 0, 903,
+	0, 907, 2298, 2320, 0, 0, 0, 2308, 2304, 2301,
+	2570, 0, 0, 0, 0, 0, 2563, 2566, 998, 999,
+	444, 0, 465, 0, 0, 0, 0, 0, 0, 413,
+	2536, 0, 0, 1182, 0, 2356, 0, 2440, 2362, 2418,
+	2419, 2425, 0, 2115, 0, 2707, 2756, 0, 0, -2,
+	0, 0, 2760, 0, 0, 0, -2, 0, 0, 0,
+	3023, 3025, 0, 3079, 3014, 2858, 2846, 2847, 0, 2970,
+	3040, 3069, 3073, 0, 2692, 2693, 2694, 2695, 2696, 2697,
+	2698, 0, 3123, 3162, 3166, 2943, 2944, 2948, 3137, 0,
+	0, 0, 2873, 0, 0, 0, 0, 0, 0, 0,
+	0, 2656, 2673, 2677, 0, 0, 3041, 3052, 3054, 2798,
+	2799, 2803, 2804, 2805, 2806, 2807, 2808, 2809, 2810, 2811,
+	2812, -2, -2, -2, 2816, 2817, 2818, -2, -2, -2,
+	2823, 0, 0, 0, 3055, 3057, 3058, 3062, 3063, 0,
+	2926, 2927, 2928, 3064, 2394, 2388, 2506, 2459, 0, 2568,
+	2463, 0, 2459, 2459, 2401, 2521, 0, 0, 2550, 0,
+	2485, 0, 2486, 0, 0, 0, 2526, 2493, 2530, 0,
+	2509, 2511, 2496, 2497, 2515, 0, 2499, 0, 2502, -2,
+	2409, 2411, 2420, 2859, 2861, 0, 467, 473, 0, 476,
+	0, 481, 482, 0, 0, 0, 0, 487, 0, 0,
+	0, 0, 471, 0, 1114, 2167, 2167, 0, 0, 0,
+	0, 1116, 0, 1100, 0, 0, 2578, 0, 2685, 1130,
+	1132, 0, 0, 0, 0, 0, 3654, 3576, 0, 0,
+	1129, 282, 748, 677, 678, 282, 952, 961, 328, 0,
+	2534, 0, 0, 0, 1091, 0, 465, 456, 1475, 1477,
+	0, 1483, 1484, 1485, 1487, 1504, 2178, 1509, 1510, 1665,
+	1668, 1666, 1667, 3151, 1597, 1623, 1673, 1853, 0, 0,
+	1675, 0, 0, 1719, 0, 1722, 0, 0, 0, 0,
+	264, 0, 0, 0, 0, 0, 0, 283, 0, 1917,
+	0, 1874, 0, 0, 1901, 0, 0, 1923, 233, 234,
+	235, 0, 0, 241, 242, 243, 0, 0, 300, 296,
+	254, 0, 0, 250, 0, 260, 267, 265, 0, 266,
+	1861, 0, 0, 0, 0, 2128, 0, 0, 0, 205,
+	206, 207, 0, 212, 0, 213, 0, 0, 0, 0,
+	1986, 0, 0, 0, 0, 701, 0, 0, 0, 0,
+	152, 0, 0, 0, 157, 158, 0, 0, 2279, 2280,
+	0, 2264, 202, 0, 0, 0, 0, 0, 0, 302,
+	0, 0, 0, 2112, 324, 0, 0, 0, 0, 0,
+	365, 366, 367, 368, 0, 346, 348, 0, 0, 0,
+	354, 356, 358, 359, 0, 0, 377, 374, 0, 0,
+	631, 0, 0, 648, 462, 457, 459, 0, 0, 0,
+	1220, 0, 1222, 617, 0, 0, 0, 0, 0, 2001,
+	2067, 2068, 2010, 2141, 2145, 2153, 0, 0, 0, 0,
+	0, 1151, 2180, 0, 342, 340, 0, 343, 342, 0,
+	465, 0, 899, 0, 0, 576, 0, 0, 0, 0,
+	649, 0, 639, 640, 0, 693, 0, 0, 0, 693,
+	0, 0, 0, 814, 1802, 1924, 0, 0, 1926, 1838,
+	1842, 0, 0, 3185, 0, 0, 0, 0, 0, 3134,
+	0, 1800, 0, 0, 1925, 868, 874, 0, 877, 0,
+	880, 0, 882, 0, 895, 3133, 0, 0, 0, 1977,
+	0, 0, 2005, 1956, 2031, 1956, 0, 2082, 2084, 2076,
+	0, 2088, 0, 2098, 0, 0, 0, 0, 0, 2291,
+	2297, 0, 2284, 2285, 0, 0, 0, 0, 0, 2407,
+	908, 906, 2299, 2318, -2, 0, 0, 2407, 2326, 2323,
+	2329, 2330, 0, 0, 447, 0, 2310, 2312, 0, 1773,
+	1776, 403, 0, 413, 2536, 451, 0, 2439, 2426, 2427,
+	2423, 2115, 2758, 2762, 0, 0, 0, 2764, -2, 0,
+	2786, -2, -2, 3026, 3078, 2837, 2848, 3072, 2702, 0,
+	2950, 2947, 0, 2934, 0, 2885, 2886, 0, 0, 2889,
+	2891, 2892, 2893, 2641, 2629, 2628, 3051, 0, 0, 0,
+	0, 2925, 0, 2939, 0, 0, 2467, 2939, 2939, 2522,
+	0, 2524, 2483, 2468, 0, 2479, 0, 0, 2508, 0,
+	2512, 2517, 2501, 0, 0, 3163, 477, 0, 478, 0,
+	0, 0, 0, 0, 0, 503, 0, 0, 0, 0,
+	0, 0, 0, 483, 484, 485, 486, 488, 489, 0,
+	0, 0, 493, 546, 1117, 1118, 0, 0, 0, 0,
+	0, 2166, 2572, 2577, 0, 2583, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 1142, 637, 804, 330,
+	0, 0, 1402, 1403, 1093, 1454, 1459, 1474, 1852, 0,
+	0, 0, 0, 0, 0, 0, 0, 227, 228, 1816,
+	1814, 2132, 2136, 2133, 0, 230, 0, 0, 1875, 0,
+	1878, 0, 0, 0, 0, 1885, 1902, 0, 0, 0,
+	0, 0, 0, 1904, 0, 1903, 0, 0, 1940, 0,
+	2103, 2110, 0, -2, 0, 0, 0, 244, 246, 273,
+	0, 0, 0, 248, 301, 0, 0, 0, 0, 276,
+	-2, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	2184, 0, 297, 0, 0, 282, 282, 1813, 0, 0,
+	2124, 2126, 2139, 0, 0, 0, 0, 215, 0, 0,
+	2142, 2146, 2154, 2149, 2151, 2157, 757, 702, 0, 0,
+	147, 156, 2267, 0, 0, 0, 2281, 0, 201, 0,
+	0, 0, 2159, 312, 313, 0, 282, 0, 282, 305,
+	282, 2112, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 370, 371, 372, 0, 630, 0, 0, 0, 0,
+	0, 614, 0, 0, 615, 616, 1242, 1240, 0, 0,
+	0, 0, 0, 0, 2162, 2163, 333, 0, 0, 335,
+	342, 0, 0, 0, 585, 579, 0, 0, 627, 654,
+	642, 643, 644, 645, 646, 641, 668, 726, 692, 694,
+	0, 0, 698, 699, 700, 673, 675, 676, 726, 776,
+	769, 773, 1863, 0, 1936, 1928, 1929, 1930, 0, 1834,
+	1935, 1937, 0, 0, 1839, 0, 0, 0, 0, 0,
+	0, 0, 0, 1819, 1801, 0, 1832, 1804, 878, 0,
+	879, 881, 873, 2565, 464, 1790, 1974, 2023, 1956, 0,
+	2026, 0, 0, 2073, 0, 0, 0, 2087, 0, 0,
+	0, 0, 0, 0, 0, 2293, 2297, 0, 2286, 2287,
+	396, 0, 397, 398, 399, 2436, 2406, 0, 0, 0,
+	2307, 2436, 0, 465, 0, 465, 411, 0, 414, 0,
+	0, 0, 419, 420, 421, 422, 423, 424, 425, 0,
+	0, 0, 0, 430, 431, 432, 0, 0, 436, 439,
+	440, 437, 438, 405, 413, 1184, 1186, 0, 0, 0,
+	1192, 2424, 2766, -2, -2, 2787, 3165, 2409, 0, 2936,
+	2412, 2413, 0, 0, -2, 0, 0, 0, 2390, 2374,
+	0, 2458, 2450, 2452, 2454, 3561, 3275, 4320, 2375, 2376,
+	2549, 0, 0, 0, 2510, 2860, 2421, 2422, 474, 0,
+	494, 495, 496, 497, 498, 499, 500, 501, 502, 504,
+	505, 506, 507, 508, 509, 510, 511, 480, 490, 0,
+	492, 1119, 0, 0, 0, 0, 0, 2579, 0, 0,
+	0, 0, 1127, 0, 0, 0, 0, 0, 331, 1392,
+	1674, 1676, 0, 0, 1723, 0, 0, 0, 0, 0,
+	2134, 232, 0, 0, 1879, 1880, 1882, 0, 1884, 1886,
+	1887, 1804, 0, 1891, 0, 3187, 0, 1896, 1899, 1900,
+	0, 0, 1919, 1941, 0, 1950, 0, 2105, 2115, 2109,
+	0, 2107, 1952, 0, 236, 0, 275, 237, 238, 247,
+	277, 272, 0, -2, -2, -2, -2, -2, 0, -2,
+	-2, -2, 0, 299, 1905, 0, 2112, 298, 0, 249,
+	259, 0, 0, 177, 0, 0, 3268, 218, 216, 214,
+	145, 151, 3143, 153, 159, 2121, 204, 0, 179, 0,
+	314, 323, 2111, 325, 309, 282, 0, 345, 347, 349,
+	350, 351, 352, 0, 355, 357, 0, 0, 0, 1210,
+	612, 1219, 618, 0, 2143, 2147, 2155, 0, 2170, 2171,
+	2172, 2173, 2174, 0, 0, 0, 344, 0, 0, 387,
+	0, 0, 573, 0, 612, 0, 633, 647, 0, 0,
+	667, 661, 724, 0, 0, 695, 728, 718, 697, 663,
+	787, 0, 1804, 1862, 1803, 1927, 0, 1938, 1804, 0,
+	0, 1952, 0, 0, 0, 0, 0, 0, 0, 1806,
+	0, 1805, 0, 0, 875, 2570, 892, 0, 0, 0,
+	2030, 0, 2085, 2089, 2083, 0, 0, 2097, 0, 0,
+	0, 0, 0, 2263, 0, 0, 2288, 2289, 393, 2320,
+	2435, 2313, 0, 0, 2320, 2331, 446, 0, 449, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	435, 407, 0, 1188, 0, 1190, 0, 2954, 0, 0,
+	0, 2887, 2888, -2, 0, 2826, 2938, 2940, 0, 0,
+	0, 0, 0, 2469, 2480, 2481, 479, 491, 2167, 2167,
+	2167, 2167, 2573, 1134, 1135, 1137, 1139, 1131, 1133, 0,
+	0, 0, 1684, 1685, 1720, 1724, 1725, 2130, 0, 2137,
+	284, 1877, 1881, 0, 1888, 0, 0, 0, 1892, 1960,
+	0, 0, 1977, 1977, 1907, 0, 0, 1944, 1945, 1859,
+	0, 1946, 1947, 1948, 2104, 2428, 2110, 1804, 0, 0,
+	245, 1977, 1977, 274, -2, -2, 1906, 279, 0, 0,
+	0, 0, 0, 0, 0, 203, 0, 303, 326, 2112,
+	353, 0, 653, 0, 1223, 0, 619, 0, 2175, 0,
+	0, 341, 384, 886, 0, 0, 582, 583, 0, 588,
+	0, 0, 0, 601, 0, 605, 0, 649, 693, 688,
+	0, 723, 719, 696, 0, 793, 789, 775, 777, 0,
+	782, 783, 1806, 0, 1939, 1840, 1843, 1844, 1845, 1846,
+	1847, 1848, 1849, 1850, 1851, 1841, 1950, 1952, 0, 1859,
+	0, 1859, 0, 1916, 1817, 0, 1820, 0, 1802, 0,
+	884, 0, 2024, 0, 2031, 0, 2077, 0, 2098, 0,
+	0, 0, 0, 2276, 2262, 2297, 2290, 2291, 900, 2570,
+	0, 2321, 0, 415, 0, 416, 417, 418, 426, 427,
+	428, 429, 0, 434, 1187, 0, 0, 0, 0, 0,
+	0, 2949, 2414, 2415, 2827, 0, 0, 2453, 2455, 2456,
+	2457, 1120, 1121, 1122, 1123, 0, 0, 0, 2131, 253,
+	0, 1954, 1890, 1965, 0, 0, 0, 0, 0, 1908,
+	1942, 1943, 1940, 1858, 0, 2108, 2106, 1921, 1954, 1956,
+	0, 0, 251, 0, 1952, 0, 1868, 0, 0, 1871,
+	0, 0, 219, 3268, 217, 3144, 0, 282, 1077, 0,
+	652, 610, 0, 2167, 282, 0, 387, 0, 0, 2565,
+	572, 0, 0, 0, 0, 0, 0, 0, 0, 654,
+	726, 0, 690, 0, 3190, 3191, 2394, 727, 0, 0,
+	0, 788, 778, 781, 784, 785, 1798, 0, 1932, 1934,
+	1859, 1950, 1952, 1804, 1859, 1804, 1859, 0, 1821, 1863,
+	1819, 2025, 2029, 2027, 2074, 1952, 0, 1950, 0, 1950,
+	0, 2283, 2297, 2277, 2278, 0, 2293, 0, 0, 465,
+	412, 433, 1189, 1191, 2946, 2966, 2955, -2, 3658, 3276,
+	0, 2966, 2966, 2941, 2942, 0, 0, 0, 0, 1804,
+	0, 1893, 1961, 1962, 0, 1957, 1958, 1959, 3186, 1894,
+	1895, 1897, 1898, 2570, 0, 1951, 1960, 239, 240, 278,
+	1804, 1865, 0, 0, 1866, 0, 0, 222, 0, 224,
+	327, 0, 0, 0, 2165, 2168, 0, 360, 0, 0,
+	2570, 580, 0, 586, 0, 0, 0, 0, 0, 0,
+	0, 0, 589, 0, 598, 599, 600, 602, 612, 634,
+	659, 693, 0, 689, 0, 725, 720, 721, 0, 792,
+	786, 790, 791, 0, 780, 1795, 1797, 1804, 0, 1804,
+	1859, 1950, 2570, 1804, 2570, 1804, 0, 0, 0, 1804,
+	1806, 1950, 0, 1859, 0, 1859, 0, 2272, 2282, 0,
+	2292, 2263, 0, 2316, 0, 448, 2951, 0, 0, 2957,
+	2958, 2959, 2960, 2961, 2952, 2953, 1136, 1138, 1140, 1883,
+	1889, 0, 1963, 0, 1964, 0, 0, 0, 1920, 1949,
+	1965, 257, 1869, 0, 1872, 0, 220, 0, 0, 0,
+	0, 382, 383, 385, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 584, 606, 726, 691,
+	722, 0, 794, 795, 779, 1931, 1933, 2570, 1804, 1859,
+	2120, 2570, 2120, 2570, 1807, 0, 1809, 1806, 1818, 1859,
+	0, 1804, 0, 1804, 0, 2295, 2271, 2275, 2276, 2314,
+	0, 0, 0, 2963, 2964, 0, 0, 0, 1966, 0,
+	1969, 1970, 0, 1967, 1940, 0, 0, 0, 0, 611,
+	282, 0, 387, 587, 0, 590, 591, 0, 0, 594,
+	595, 596, 597, 660, 0, 2120, 2570, 1804, 1912, 0,
+	2117, 2118, 0, 2120, 1914, 2120, 1808, 1798, 1804, 1952,
+	2570, 1950, 2570, 1950, 2269, 2297, 2283, 0, 2570, 2962,
+	2965, 2956, 1953, 1968, 1971, 1972, 1922, 0, 0, 650,
+	651, 2169, 386, 887, 581, 592, 0, 798, 1909, 2120,
+	2570, 2116, 2119, 1913, 1915, 1796, 2570, 1950, 2120, 1859,
+	2120, 1859, 2266, 2268, 0, 0, 2272, 2570, 2317, 1856,
+	0, 593, 0, 796, 799, 800, 801, 802, 1910, 2120,
+	2120, 1859, 2092, 1804, 2094, 1804, 2259, 2265, 0, 0,
+	2294, 2295, 2315, 1870, 1855, 0, 763, 0, 1911, 2090,
+	1804, 2570, 2570, 0, 2269, 0, 797, 2570, 2120, 2120,
+	0, 2266, 0, 2120, 2093, 2095, 2270, 2260, 1856, 2091,
+	1873,
 }
 
 var sqlTok1 = [...]int16{
 	1, 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, 694, 3, 700, 695, 3,
-	706, 707, 698, 696, 711, 697, 708, 699, 3, 3,
-	3, 3, 3, 3, 3, 3, 3, 3, 715, 712,
-	686, 688, 687, 691, 710, 3, 3, 3, 3, 3,
+	3, 3, 3, 3, 3, 727, 3, 733, 728, 3,
+	739, 740, 731, 729, 744, 730, 741, 732, 3, 3,
+	3, 3, 3, 3, 3, 3, 3, 3, 748, 745,
+	719, 721, 720, 724, 743, 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, 704, 3, 705, 701, 3, 3, 3, 3, 3,
+	3, 737, 3, 738, 734, 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, 713, 693, 714, 689,
+	3, 3, 3, 746, 726, 747, 722,
 }
 
 var sqlTok2 = [...]int16{
@@ -28911,8 +31372,15 @@ var sqlTok3 = [...]uint16{
 	58010, 668, 58011, 669, 58012, 670, 58013, 671, 58014, 672,
 	58015, 673, 58016, 674, 58017, 675, 58018, 676, 58019, 677,
 	58020, 678, 58021, 679, 58022, 680, 58023, 681, 58024, 682,
-	58025, 683, 58026, 684, 58027, 685, 58028, 690, 58029, 692,
-	58030, 702, 58031, 703, 58032, 709, 0,
+	58025, 683, 58026, 684, 58027, 685, 58028, 686, 58029, 687,
+	58030, 688, 58031, 689, 58032, 690, 58033, 691, 58034, 692,
+	58035, 693, 58036, 694, 58037, 695, 58038, 696, 58039, 697,
+	58040, 698, 58041, 699, 58042, 700, 58043, 701, 58044, 702,
+	58045, 703, 58046, 704, 58047, 705, 58048, 706, 58049, 707,
+	58050, 708, 58051, 709, 58052, 710, 58053, 711, 58054, 712,
+	58055, 713, 58056, 714, 58057, 715, 58058, 716, 58059, 717,
+	58060, 718, 58061, 723, 58062, 725, 58063, 735, 58064, 736,
+	58065, 742, 0,
 }
 
 var sqlErrorMessages = [...]struct {
@@ -29254,289 +31722,307 @@ sqldefault:
 
 	case 1:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:1777
+//line sql-gen.y:1884
 		{
 			sqllex.(*lexer).SetStmt(sqlDollar[1].union.stmt())
 		}
 	case 2:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:1782
+//line sql-gen.y:1889
 		{
 			return helpWith(sqllex, "")
 		}
 	case 5:
 		sqlDollar = sqlS[sqlpt-0 : sqlpt+1]
-//line sql-gen.y:1786
+//line sql-gen.y:1893
 		{
 			sqlVAL.union.val = tree.Statement(nil)
 		}
 	case 8:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:1792
+//line sql-gen.y:1899
 		{
 			return helpWith(sqllex, "ANALYZE")
 		}
 	case 13:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:1796
+//line sql-gen.y:1903
 		{
 			return helpWith(sqllex, "EXECUTE")
 		}
 	case 15:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:1797
+//line sql-gen.y:1904
 		{
 			return helpWith(sqllex, "DEALLOCATE")
 		}
 	case 17:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:1798
+//line sql-gen.y:1905
 		{
 			return helpWith(sqllex, "DISCARD")
 		}
 	case 19:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:1799
+//line sql-gen.y:1906
 		{
-			return helpWith(sqllex, "GRANT")
+			return helpWith(sqllex, "DO")
 		}
 	case 21:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:1800
+//line sql-gen.y:1907
 		{
-			return helpWith(sqllex, "PREPARE")
+			return helpWith(sqllex, "GRANT")
 		}
 	case 23:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:1801
+//line sql-gen.y:1908
 		{
-			return helpWith(sqllex, "REVOKE")
+			return helpWith(sqllex, "PREPARE")
 		}
 	case 25:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:1802
+//line sql-gen.y:1909
 		{
-			return helpWith(sqllex, "SAVEPOINT")
+			return helpWith(sqllex, "REVOKE")
 		}
 	case 27:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:1803
+//line sql-gen.y:1910
 		{
-			return helpWith(sqllex, "REASSIGN OWNED BY")
+			return helpWith(sqllex, "SAVEPOINT")
 		}
 	case 29:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:1804
+//line sql-gen.y:1911
 		{
-			return helpWith(sqllex, "DROP OWNED BY")
+			return helpWith(sqllex, "REASSIGN OWNED BY")
 		}
 	case 31:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:1805
+//line sql-gen.y:1912
 		{
-			return helpWith(sqllex, "RELEASE")
+			return helpWith(sqllex, "DROP OWNED BY")
 		}
 	case 33:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:1806
+//line sql-gen.y:1913
+		{
+			return helpWith(sqllex, "RELEASE")
+		}
+	case 35:
+		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
+//line sql-gen.y:1914
 		{
 			return helpWith(sqllex, "REFRESH")
 		}
-	case 37:
+	case 39:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:1809
+//line sql-gen.y:1917
 		{
 			return helpWith(sqllex, "CLOSE")
 		}
-	case 39:
+	case 41:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:1810
+//line sql-gen.y:1918
 		{
 			return helpWith(sqllex, "DECLARE")
 		}
-	case 41:
+	case 43:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:1811
+//line sql-gen.y:1919
 		{
 			return helpWith(sqllex, "FETCH")
 		}
-	case 43:
+	case 45:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:1812
+//line sql-gen.y:1920
 		{
 			return helpWith(sqllex, "MOVE")
 		}
-	case 47:
+	case 49:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:1815
+//line sql-gen.y:1923
 		{
 			return helpWith(sqllex, "SHOW COMMIT TIMESTAMP")
 		}
-	case 50:
+	case 52:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:1822
+//line sql-gen.y:1930
 		{
 			return helpWith(sqllex, "ALTER ROLE")
 		}
-	case 53:
+	case 55:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:1825
+//line sql-gen.y:1933
 		{
 			return helpWith(sqllex, "ALTER")
 		}
-	case 55:
+	case 57:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:1828
+//line sql-gen.y:1936
 		{
 			return helpWith(sqllex, "ALTER TABLE")
 		}
-	case 57:
+	case 59:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:1829
+//line sql-gen.y:1937
 		{
 			return helpWith(sqllex, "ALTER INDEX")
 		}
-	case 59:
+	case 61:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:1830
+//line sql-gen.y:1938
 		{
 			return helpWith(sqllex, "ALTER VIEW")
 		}
-	case 61:
+	case 63:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:1831
+//line sql-gen.y:1939
 		{
 			return helpWith(sqllex, "ALTER SEQUENCE")
 		}
-	case 63:
+	case 65:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:1832
+//line sql-gen.y:1940
 		{
 			return helpWith(sqllex, "ALTER DATABASE")
 		}
-	case 65:
+	case 67:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:1833
+//line sql-gen.y:1941
 		{
 			return helpWith(sqllex, "ALTER RANGE")
 		}
-	case 67:
+	case 69:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:1834
+//line sql-gen.y:1942
 		{
 			return helpWith(sqllex, "ALTER PARTITION")
 		}
-	case 69:
+	case 71:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:1835
+//line sql-gen.y:1943
 		{
 			return helpWith(sqllex, "ALTER SCHEMA")
 		}
-	case 71:
+	case 73:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:1836
+//line sql-gen.y:1944
 		{
 			return helpWith(sqllex, "ALTER TYPE")
 		}
-	case 73:
+	case 75:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:1837
+//line sql-gen.y:1945
 		{
 			return helpWith(sqllex, "ALTER DEFAULT PRIVILEGES")
 		}
-	case 75:
+	case 77:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:1838
+//line sql-gen.y:1946
 		{
 			return helpWith(sqllex, "ALTER CHANGEFEED")
 		}
-	case 77:
+	case 79:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:1839
+//line sql-gen.y:1947
 		{
 			return helpWith(sqllex, "ALTER BACKUP")
 		}
-	case 79:
+	case 81:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:1840
+//line sql-gen.y:1948
 		{
 			return helpWith(sqllex, "ALTER FUNCTION")
 		}
-	case 81:
+	case 83:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:1841
+//line sql-gen.y:1949
 		{
 			return helpWith(sqllex, "ALTER PROCEDURE")
 		}
-	case 83:
+	case 85:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:1842
+//line sql-gen.y:1950
 		{
 			return helpWith(sqllex, "ALTER BACKUP SCHEDULE")
 		}
-	case 94:
+	case 87:
+		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
+//line sql-gen.y:1951
+		{
+			return helpWith(sqllex, "ALTER POLICY")
+		}
+	case 89:
+		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
+//line sql-gen.y:1952
+		{
+			return helpWith(sqllex, "ALTER JOB")
+		}
+	case 100:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:1903
+//line sql-gen.y:2018
 		{
 			return helpWith(sqllex, "ALTER TABLE")
 		}
-	case 96:
+	case 102:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:1929
+//line sql-gen.y:2044
 		{
 			return helpWith(sqllex, "ALTER PARTITION")
 		}
-	case 100:
+	case 106:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:1943
+//line sql-gen.y:2058
 		{
 			return helpWith(sqllex, "ALTER VIEW")
 		}
-	case 105:
+	case 111:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:1963
+//line sql-gen.y:2078
 		{
 			return helpWith(sqllex, "ALTER SEQUENCE")
 		}
-	case 106:
+	case 112:
 		sqlDollar = sqlS[sqlpt-4 : sqlpt+1]
-//line sql-gen.y:1967
+//line sql-gen.y:2082
 		{
 			sqlVAL.union.val = &tree.AlterSequence{Name: sqlDollar[3].union.unresolvedObjectName(), Options: sqlDollar[4].union.seqOpts(), IfExists: false}
 		}
-	case 107:
+	case 113:
 		sqlDollar = sqlS[sqlpt-6 : sqlpt+1]
-//line sql-gen.y:1971
+//line sql-gen.y:2086
 		{
 			sqlVAL.union.val = &tree.AlterSequence{Name: sqlDollar[5].union.unresolvedObjectName(), Options: sqlDollar[6].union.seqOpts(), IfExists: true}
 		}
-	case 129:
+	case 135:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:2034
+//line sql-gen.y:2150
 		{
 			return helpWith(sqllex, "ALTER FUNCTION")
 		}
-	case 133:
+	case 139:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:2051
+//line sql-gen.y:2167
 		{
 			return helpWith(sqllex, "ALTER PROCEDURE")
 		}
-	case 134:
+	case 140:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:2055
+//line sql-gen.y:2171
 		{
 			return helpWith(sqllex, "ALTER DATABASE")
 		}
-	case 135:
+	case 141:
 		sqlDollar = sqlS[sqlpt-6 : sqlpt+1]
-//line sql-gen.y:2059
+//line sql-gen.y:2175
 		{
 			sqlVAL.union.val = &tree.AlterDatabaseOwner{Name: tree.Name(sqlDollar[3].str), Owner: sqlDollar[6].union.roleSpec()}
 		}
-	case 136:
+	case 142:
 		sqlDollar = sqlS[sqlpt-4 : sqlpt+1]
-//line sql-gen.y:2066
+//line sql-gen.y:2182
 		{
 			sqlVAL.union.val = &tree.AlterRoleSet{
 				AllRoles:     true,
@@ -29545,27 +32031,27 @@ sqldefault:
 				SetOrReset:   sqlDollar[4].union.setVar(),
 			}
 		}
-	case 137:
+	case 143:
 		sqlDollar = sqlS[sqlpt-4 : sqlpt+1]
-//line sql-gen.y:2077
+//line sql-gen.y:2193
 		{
 			sqlVAL.union.val = &tree.AlterDatabasePlacement{
 				Name:      tree.Name(sqlDollar[3].str),
 				Placement: sqlDollar[4].union.dataPlacement(),
 			}
 		}
-	case 138:
+	case 144:
 		sqlDollar = sqlS[sqlpt-6 : sqlpt+1]
-//line sql-gen.y:2086
+//line sql-gen.y:2202
 		{
 			sqlVAL.union.val = &tree.AlterDatabaseAddRegion{
 				Name:   tree.Name(sqlDollar[3].str),
 				Region: tree.Name(sqlDollar[6].str),
 			}
 		}
-	case 139:
+	case 145:
 		sqlDollar = sqlS[sqlpt-9 : sqlpt+1]
-//line sql-gen.y:2093
+//line sql-gen.y:2209
 		{
 			sqlVAL.union.val = &tree.AlterDatabaseAddRegion{
 				Name:        tree.Name(sqlDollar[3].str),
@@ -29573,18 +32059,18 @@ sqldefault:
 				IfNotExists: true,
 			}
 		}
-	case 140:
+	case 146:
 		sqlDollar = sqlS[sqlpt-6 : sqlpt+1]
-//line sql-gen.y:2103
+//line sql-gen.y:2219
 		{
 			sqlVAL.union.val = &tree.AlterDatabaseDropRegion{
 				Name:   tree.Name(sqlDollar[3].str),
 				Region: tree.Name(sqlDollar[6].str),
 			}
 		}
-	case 141:
+	case 147:
 		sqlDollar = sqlS[sqlpt-8 : sqlpt+1]
-//line sql-gen.y:2110
+//line sql-gen.y:2226
 		{
 			sqlVAL.union.val = &tree.AlterDatabaseDropRegion{
 				Name:     tree.Name(sqlDollar[3].str),
@@ -29592,36 +32078,36 @@ sqldefault:
 				IfExists: true,
 			}
 		}
-	case 142:
+	case 148:
 		sqlDollar = sqlS[sqlpt-4 : sqlpt+1]
-//line sql-gen.y:2120
+//line sql-gen.y:2236
 		{
 			sqlVAL.union.val = &tree.AlterDatabaseSurvivalGoal{
 				Name:         tree.Name(sqlDollar[3].str),
 				SurvivalGoal: sqlDollar[4].union.survivalGoal(),
 			}
 		}
-	case 143:
+	case 149:
 		sqlDollar = sqlS[sqlpt-4 : sqlpt+1]
-//line sql-gen.y:2129
+//line sql-gen.y:2245
 		{
 			sqlVAL.union.val = &tree.AlterDatabasePrimaryRegion{
 				Name:          tree.Name(sqlDollar[3].str),
 				PrimaryRegion: tree.Name(sqlDollar[4].str),
 			}
 		}
-	case 144:
+	case 150:
 		sqlDollar = sqlS[sqlpt-5 : sqlpt+1]
-//line sql-gen.y:2136
+//line sql-gen.y:2252
 		{
 			sqlVAL.union.val = &tree.AlterDatabasePrimaryRegion{
 				Name:          tree.Name(sqlDollar[3].str),
 				PrimaryRegion: tree.Name(sqlDollar[5].str),
 			}
 		}
-	case 145:
+	case 151:
 		sqlDollar = sqlS[sqlpt-9 : sqlpt+1]
-//line sql-gen.y:2145
+//line sql-gen.y:2261
 		{
 			sqlVAL.union.val = &tree.AlterDatabaseAddSuperRegion{
 				DatabaseName:    tree.Name(sqlDollar[3].str),
@@ -29629,18 +32115,18 @@ sqldefault:
 				Regions:         sqlDollar[9].union.nameList(),
 			}
 		}
-	case 146:
+	case 152:
 		sqlDollar = sqlS[sqlpt-7 : sqlpt+1]
-//line sql-gen.y:2155
+//line sql-gen.y:2271
 		{
 			sqlVAL.union.val = &tree.AlterDatabaseDropSuperRegion{
 				DatabaseName:    tree.Name(sqlDollar[3].str),
 				SuperRegionName: tree.Name(sqlDollar[7].str),
 			}
 		}
-	case 147:
+	case 153:
 		sqlDollar = sqlS[sqlpt-9 : sqlpt+1]
-//line sql-gen.y:2164
+//line sql-gen.y:2280
 		{
 			sqlVAL.union.val = &tree.AlterDatabaseAlterSuperRegion{
 				DatabaseName:    tree.Name(sqlDollar[3].str),
@@ -29648,36 +32134,36 @@ sqldefault:
 				Regions:         sqlDollar[9].union.nameList(),
 			}
 		}
-	case 148:
+	case 154:
 		sqlDollar = sqlS[sqlpt-5 : sqlpt+1]
-//line sql-gen.y:2174
+//line sql-gen.y:2290
 		{
 			sqlVAL.union.val = &tree.AlterDatabaseSecondaryRegion{
 				DatabaseName:    tree.Name(sqlDollar[3].str),
 				SecondaryRegion: tree.Name(sqlDollar[5].str),
 			}
 		}
-	case 149:
+	case 155:
 		sqlDollar = sqlS[sqlpt-6 : sqlpt+1]
-//line sql-gen.y:2183
+//line sql-gen.y:2299
 		{
 			sqlVAL.union.val = &tree.AlterDatabaseDropSecondaryRegion{
 				DatabaseName: tree.Name(sqlDollar[3].str),
 				IfExists:     false,
 			}
 		}
-	case 150:
+	case 156:
 		sqlDollar = sqlS[sqlpt-8 : sqlpt+1]
-//line sql-gen.y:2191
+//line sql-gen.y:2307
 		{
 			sqlVAL.union.val = &tree.AlterDatabaseDropSecondaryRegion{
 				DatabaseName: tree.Name(sqlDollar[3].str),
 				IfExists:     true,
 			}
 		}
-	case 151:
+	case 157:
 		sqlDollar = sqlS[sqlpt-7 : sqlpt+1]
-//line sql-gen.y:2200
+//line sql-gen.y:2316
 		{
 			s := sqlDollar[7].union.setZoneConfig()
 			sqlVAL.union.val = &tree.AlterDatabaseSetZoneConfigExtension{
@@ -29690,9 +32176,9 @@ sqldefault:
 				},
 			}
 		}
-	case 152:
+	case 158:
 		sqlDollar = sqlS[sqlpt-7 : sqlpt+1]
-//line sql-gen.y:2213
+//line sql-gen.y:2329
 		{
 			s := sqlDollar[7].union.setZoneConfig()
 			sqlVAL.union.val = &tree.AlterDatabaseSetZoneConfigExtension{
@@ -29705,9 +32191,9 @@ sqldefault:
 				},
 			}
 		}
-	case 153:
+	case 159:
 		sqlDollar = sqlS[sqlpt-9 : sqlpt+1]
-//line sql-gen.y:2226
+//line sql-gen.y:2342
 		{
 			s := sqlDollar[9].union.setZoneConfig()
 			sqlVAL.union.val = &tree.AlterDatabaseSetZoneConfigExtension{
@@ -29721,45 +32207,45 @@ sqldefault:
 				},
 			}
 		}
-	case 156:
+	case 162:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:2262
+//line sql-gen.y:2378
 		{
 			return helpWith(sqllex, "ALTER RANGE")
 		}
-	case 165:
+	case 171:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:2296
+//line sql-gen.y:2412
 		{
 			return helpWith(sqllex, "ALTER INDEX")
 		}
-	case 166:
+	case 172:
 		sqlDollar = sqlS[sqlpt-4 : sqlpt+1]
-//line sql-gen.y:2300
+//line sql-gen.y:2416
 		{
 			sqlVAL.union.val = &tree.AlterTable{Table: sqlDollar[3].union.unresolvedObjectName(), IfExists: false, Cmds: sqlDollar[4].union.alterTableCmds()}
 		}
-	case 167:
+	case 173:
 		sqlDollar = sqlS[sqlpt-6 : sqlpt+1]
-//line sql-gen.y:2304
+//line sql-gen.y:2420
 		{
 			sqlVAL.union.val = &tree.AlterTable{Table: sqlDollar[5].union.unresolvedObjectName(), IfExists: true, Cmds: sqlDollar[6].union.alterTableCmds()}
 		}
-	case 168:
+	case 174:
 		sqlDollar = sqlS[sqlpt-4 : sqlpt+1]
-//line sql-gen.y:2310
+//line sql-gen.y:2426
 		{
 			sqlVAL.union.val = &tree.AlterIndex{Index: sqlDollar[3].union.tableIndexName(), IfExists: false, Cmds: sqlDollar[4].union.alterIndexCmds()}
 		}
-	case 169:
+	case 175:
 		sqlDollar = sqlS[sqlpt-6 : sqlpt+1]
-//line sql-gen.y:2314
+//line sql-gen.y:2430
 		{
 			sqlVAL.union.val = &tree.AlterIndex{Index: sqlDollar[5].union.tableIndexName(), IfExists: true, Cmds: sqlDollar[6].union.alterIndexCmds()}
 		}
-	case 170:
+	case 176:
 		sqlDollar = sqlS[sqlpt-6 : sqlpt+1]
-//line sql-gen.y:2320
+//line sql-gen.y:2436
 		{
 			name := sqlDollar[3].union.unresolvedObjectName().ToTableName()
 			sqlVAL.union.val = &tree.Split{
@@ -29768,9 +32254,9 @@ sqldefault:
 				ExpireExpr:   tree.Expr(nil),
 			}
 		}
-	case 171:
+	case 177:
 		sqlDollar = sqlS[sqlpt-9 : sqlpt+1]
-//line sql-gen.y:2329
+//line sql-gen.y:2445
 		{
 			name := sqlDollar[3].union.unresolvedObjectName().ToTableName()
 			sqlVAL.union.val = &tree.Split{
@@ -29779,21 +32265,21 @@ sqldefault:
 				ExpireExpr:   sqlDollar[9].union.expr(),
 			}
 		}
-	case 172:
+	case 178:
 		sqlDollar = sqlS[sqlpt-6 : sqlpt+1]
-//line sql-gen.y:2340
+//line sql-gen.y:2456
 		{
 			sqlVAL.union.val = &tree.Split{TableOrIndex: sqlDollar[3].union.tableIndexName(), Rows: sqlDollar[6].union.slct(), ExpireExpr: tree.Expr(nil)}
 		}
-	case 173:
+	case 179:
 		sqlDollar = sqlS[sqlpt-9 : sqlpt+1]
-//line sql-gen.y:2344
+//line sql-gen.y:2460
 		{
 			sqlVAL.union.val = &tree.Split{TableOrIndex: sqlDollar[3].union.tableIndexName(), Rows: sqlDollar[6].union.slct(), ExpireExpr: sqlDollar[9].union.expr()}
 		}
-	case 174:
+	case 180:
 		sqlDollar = sqlS[sqlpt-6 : sqlpt+1]
-//line sql-gen.y:2350
+//line sql-gen.y:2466
 		{
 			name := sqlDollar[3].union.unresolvedObjectName().ToTableName()
 			sqlVAL.union.val = &tree.Unsplit{
@@ -29801,9 +32287,9 @@ sqldefault:
 				Rows:         sqlDollar[6].union.slct(),
 			}
 		}
-	case 175:
+	case 181:
 		sqlDollar = sqlS[sqlpt-5 : sqlpt+1]
-//line sql-gen.y:2358
+//line sql-gen.y:2474
 		{
 			name := sqlDollar[3].union.unresolvedObjectName().ToTableName()
 			sqlVAL.union.val = &tree.Unsplit{
@@ -29811,46 +32297,46 @@ sqldefault:
 				All:          true,
 			}
 		}
-	case 176:
+	case 182:
 		sqlDollar = sqlS[sqlpt-6 : sqlpt+1]
-//line sql-gen.y:2368
+//line sql-gen.y:2484
 		{
 			sqlVAL.union.val = &tree.Unsplit{TableOrIndex: sqlDollar[3].union.tableIndexName(), Rows: sqlDollar[6].union.slct()}
 		}
-	case 177:
+	case 183:
 		sqlDollar = sqlS[sqlpt-5 : sqlpt+1]
-//line sql-gen.y:2372
+//line sql-gen.y:2488
 		{
 			sqlVAL.union.val = &tree.Unsplit{TableOrIndex: sqlDollar[3].union.tableIndexName(), All: true}
 		}
-	case 182:
+	case 188:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:2384
+//line sql-gen.y:2500
 		{
 			sqlVAL.union.val = tree.RelocateLease
 		}
-	case 183:
+	case 189:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:2390
+//line sql-gen.y:2506
 		{
 			sqlVAL.union.val = tree.RelocateVoters
 		}
-	case 184:
+	case 190:
 		sqlDollar = sqlS[sqlpt-0 : sqlpt+1]
-//line sql-gen.y:2394
+//line sql-gen.y:2510
 		{
 
 			sqlVAL.union.val = tree.RelocateVoters
 		}
-	case 185:
+	case 191:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:2399
+//line sql-gen.y:2515
 		{
 			sqlVAL.union.val = tree.RelocateNonVoters
 		}
-	case 186:
+	case 192:
 		sqlDollar = sqlS[sqlpt-6 : sqlpt+1]
-//line sql-gen.y:2405
+//line sql-gen.y:2521
 		{
 
 			name := sqlDollar[3].union.unresolvedObjectName().ToTableName()
@@ -29860,9 +32346,9 @@ sqldefault:
 				SubjectReplicas: sqlDollar[5].union.relocateSubject(),
 			}
 		}
-	case 187:
+	case 193:
 		sqlDollar = sqlS[sqlpt-6 : sqlpt+1]
-//line sql-gen.y:2417
+//line sql-gen.y:2533
 		{
 
 			sqlVAL.union.val = &tree.Relocate{
@@ -29871,9 +32357,9 @@ sqldefault:
 				SubjectReplicas: sqlDollar[5].union.relocateSubject(),
 			}
 		}
-	case 188:
+	case 194:
 		sqlDollar = sqlS[sqlpt-4 : sqlpt+1]
-//line sql-gen.y:2428
+//line sql-gen.y:2544
 		{
 			sqlVAL.union.val = &tree.AlterIndexVisible{
 				Index:        sqlDollar[3].union.tableIndexName(),
@@ -29881,9 +32367,9 @@ sqldefault:
 				IfExists:     false,
 			}
 		}
-	case 189:
+	case 195:
 		sqlDollar = sqlS[sqlpt-6 : sqlpt+1]
-//line sql-gen.y:2436
+//line sql-gen.y:2552
 		{
 			sqlVAL.union.val = &tree.AlterIndexVisible{
 				Index:        sqlDollar[5].union.tableIndexName(),
@@ -29891,27 +32377,27 @@ sqldefault:
 				IfExists:     true,
 			}
 		}
-	case 190:
+	case 196:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:2446
+//line sql-gen.y:2562
 		{
 			sqlVAL.union.val = tree.IndexInvisibility{Value: 1.0}
 		}
-	case 191:
+	case 197:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:2450
+//line sql-gen.y:2566
 		{
 			sqlVAL.union.val = tree.IndexInvisibility{Value: 1.0}
 		}
-	case 192:
+	case 198:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:2454
+//line sql-gen.y:2570
 		{
 			sqlVAL.union.val = tree.IndexInvisibility{Value: 0.0}
 		}
-	case 193:
+	case 199:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:2458
+//line sql-gen.y:2574
 		{
 			visibilityConst, _ := constant.Float64Val(sqlDollar[2].union.numVal().AsConstantValue())
 			if visibilityConst < 0.0 || visibilityConst > 1.0 {
@@ -29921,9 +32407,9 @@ sqldefault:
 			invisibilityConst := 1.0 - visibilityConst
 			sqlVAL.union.val = tree.IndexInvisibility{Value: invisibilityConst, FloatProvided: true}
 		}
-	case 194:
+	case 200:
 		sqlDollar = sqlS[sqlpt-4 : sqlpt+1]
-//line sql-gen.y:2480
+//line sql-gen.y:2596
 		{
 			var zoneName string
 			switch e := sqlDollar[3].union.expr().(type) {
@@ -29941,9 +32427,9 @@ sqldefault:
 			s.ZoneSpecifier = tree.ZoneSpecifier{NamedZone: tree.UnrestrictedName(zoneName)}
 			sqlVAL.union.val = s
 		}
-	case 195:
+	case 201:
 		sqlDollar = sqlS[sqlpt-8 : sqlpt+1]
-//line sql-gen.y:2500
+//line sql-gen.y:2616
 		{
 			sqlVAL.union.val = &tree.RelocateRange{
 				Rows:            sqlDollar[8].union.slct(),
@@ -29952,9 +32438,9 @@ sqldefault:
 				SubjectReplicas: tree.RelocateLease,
 			}
 		}
-	case 196:
+	case 202:
 		sqlDollar = sqlS[sqlpt-7 : sqlpt+1]
-//line sql-gen.y:2509
+//line sql-gen.y:2625
 		{
 			sqlVAL.union.val = &tree.RelocateRange{
 				Rows: &tree.Select{
@@ -29965,9 +32451,9 @@ sqldefault:
 				SubjectReplicas: tree.RelocateLease,
 			}
 		}
-	case 197:
+	case 203:
 		sqlDollar = sqlS[sqlpt-10 : sqlpt+1]
-//line sql-gen.y:2520
+//line sql-gen.y:2636
 		{
 			sqlVAL.union.val = &tree.RelocateRange{
 				Rows:            sqlDollar[10].union.slct(),
@@ -29976,9 +32462,9 @@ sqldefault:
 				SubjectReplicas: sqlDollar[4].union.relocateSubject(),
 			}
 		}
-	case 198:
+	case 204:
 		sqlDollar = sqlS[sqlpt-9 : sqlpt+1]
-//line sql-gen.y:2529
+//line sql-gen.y:2645
 		{
 			sqlVAL.union.val = &tree.RelocateRange{
 				Rows: &tree.Select{
@@ -29989,9 +32475,9 @@ sqldefault:
 				SubjectReplicas: sqlDollar[5].union.relocateSubject(),
 			}
 		}
-	case 199:
+	case 205:
 		sqlDollar = sqlS[sqlpt-4 : sqlpt+1]
-//line sql-gen.y:2542
+//line sql-gen.y:2658
 		{
 
 			sqlVAL.union.val = &tree.SetZoneConfig{
@@ -30000,9 +32486,9 @@ sqldefault:
 				},
 			}
 		}
-	case 200:
+	case 206:
 		sqlDollar = sqlS[sqlpt-4 : sqlpt+1]
-//line sql-gen.y:2551
+//line sql-gen.y:2667
 		{
 			sqlVAL.union.val = &tree.SetZoneConfig{
 				ZoneConfigSettings: tree.ZoneConfigSettings{
@@ -30010,9 +32496,9 @@ sqldefault:
 				},
 			}
 		}
-	case 201:
+	case 207:
 		sqlDollar = sqlS[sqlpt-4 : sqlpt+1]
-//line sql-gen.y:2559
+//line sql-gen.y:2675
 		{
 
 			sqlVAL.union.val = &tree.SetZoneConfig{
@@ -30021,27 +32507,28 @@ sqldefault:
 				},
 			}
 		}
-	case 202:
+	case 208:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:2568
+//line sql-gen.y:2684
 		{
 			sqlVAL.union.val = &tree.SetZoneConfig{
 				ZoneConfigSettings: tree.ZoneConfigSettings{
+					Discard:    true,
 					YAMLConfig: tree.DNull,
 				},
 			}
 		}
-	case 203:
+	case 209:
 		sqlDollar = sqlS[sqlpt-4 : sqlpt+1]
-//line sql-gen.y:2578
+//line sql-gen.y:2695
 		{
 			s := sqlDollar[4].union.setZoneConfig()
 			s.ZoneSpecifier = tree.ZoneSpecifier{Database: tree.Name(sqlDollar[3].str)}
 			sqlVAL.union.val = s
 		}
-	case 204:
+	case 210:
 		sqlDollar = sqlS[sqlpt-4 : sqlpt+1]
-//line sql-gen.y:2586
+//line sql-gen.y:2703
 		{
 			name := sqlDollar[3].union.unresolvedObjectName().ToTableName()
 			s := sqlDollar[4].union.setZoneConfig()
@@ -30050,9 +32537,9 @@ sqldefault:
 			}
 			sqlVAL.union.val = s
 		}
-	case 205:
+	case 211:
 		sqlDollar = sqlS[sqlpt-4 : sqlpt+1]
-//line sql-gen.y:2597
+//line sql-gen.y:2714
 		{
 			s := sqlDollar[4].union.setZoneConfig()
 			s.ZoneSpecifier = tree.ZoneSpecifier{
@@ -30060,9 +32547,9 @@ sqldefault:
 			}
 			sqlVAL.union.val = s
 		}
-	case 206:
+	case 212:
 		sqlDollar = sqlS[sqlpt-7 : sqlpt+1]
-//line sql-gen.y:2607
+//line sql-gen.y:2724
 		{
 			name := sqlDollar[6].union.unresolvedObjectName().ToTableName()
 			s := sqlDollar[7].union.setZoneConfig()
@@ -30072,9 +32559,9 @@ sqldefault:
 			}
 			sqlVAL.union.val = s
 		}
-	case 207:
+	case 213:
 		sqlDollar = sqlS[sqlpt-7 : sqlpt+1]
-//line sql-gen.y:2617
+//line sql-gen.y:2734
 		{
 			s := sqlDollar[7].union.setZoneConfig()
 			s.ZoneSpecifier = tree.ZoneSpecifier{
@@ -30083,69 +32570,69 @@ sqldefault:
 			}
 			sqlVAL.union.val = s
 		}
-	case 208:
+	case 214:
 		sqlDollar = sqlS[sqlpt-9 : sqlpt+1]
-//line sql-gen.y:2626
+//line sql-gen.y:2743
 		{
 			name := sqlDollar[6].union.unresolvedObjectName().ToTableName()
 			s := sqlDollar[9].union.setZoneConfig()
 			s.ZoneSpecifier = tree.ZoneSpecifier{
 				TableOrIndex: tree.TableIndexName{Table: name},
 				Partition:    tree.Name(sqlDollar[3].str),
+				StarIndex:    true,
 			}
-			s.AllIndexes = true
 			sqlVAL.union.val = s
 		}
-	case 209:
+	case 215:
 		sqlDollar = sqlS[sqlpt-8 : sqlpt+1]
-//line sql-gen.y:2637
+//line sql-gen.y:2754
 		{
 			err := errors.New("index name should not be specified in ALTER PARTITION ... OF TABLE")
 			err = errors.WithHint(err, "try ALTER PARTITION ... OF INDEX")
 			return setErr(sqllex, err)
 		}
-	case 210:
+	case 216:
 		sqlDollar = sqlS[sqlpt-9 : sqlpt+1]
-//line sql-gen.y:2643
+//line sql-gen.y:2760
 		{
 			err := errors.New("index wildcard unsupported in ALTER PARTITION ... OF TABLE")
 			err = errors.WithHint(err, "try ALTER PARTITION <partition> OF INDEX <tablename>@*")
 			return setErr(sqllex, err)
 		}
-	case 211:
+	case 217:
 		sqlDollar = sqlS[sqlpt-5 : sqlpt+1]
-//line sql-gen.y:2651
+//line sql-gen.y:2768
 		{
 			sqlVAL.union.val = []tree.KVOption{tree.KVOption{Key: tree.Name(strings.Join(sqlDollar[1].union.strs(), "."))}}
 		}
-	case 212:
+	case 218:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:2655
+//line sql-gen.y:2772
 		{
 			sqlVAL.union.val = []tree.KVOption{tree.KVOption{Key: tree.Name(strings.Join(sqlDollar[1].union.strs(), ".")), Value: sqlDollar[3].union.expr()}}
 		}
-	case 213:
+	case 219:
 		sqlDollar = sqlS[sqlpt-5 : sqlpt+1]
-//line sql-gen.y:2659
+//line sql-gen.y:2776
 		{
 			sqlVAL.union.val = append(sqlDollar[1].union.kvOptions(), tree.KVOption{Key: tree.Name(strings.Join(sqlDollar[3].union.strs(), ".")), Value: sqlDollar[5].union.expr()})
 		}
-	case 214:
+	case 220:
 		sqlDollar = sqlS[sqlpt-7 : sqlpt+1]
-//line sql-gen.y:2663
+//line sql-gen.y:2780
 		{
 			sqlVAL.union.val = append(sqlDollar[1].union.kvOptions(), tree.KVOption{Key: tree.Name(strings.Join(sqlDollar[3].union.strs(), "."))})
 		}
-	case 215:
+	case 221:
 		sqlDollar = sqlS[sqlpt-4 : sqlpt+1]
-//line sql-gen.y:2669
+//line sql-gen.y:2786
 		{
 			name := sqlDollar[3].union.unresolvedObjectName().ToTableName()
 			sqlVAL.union.val = &tree.Scatter{TableOrIndex: tree.TableIndexName{Table: name}}
 		}
-	case 216:
+	case 222:
 		sqlDollar = sqlS[sqlpt-12 : sqlpt+1]
-//line sql-gen.y:2674
+//line sql-gen.y:2791
 		{
 			name := sqlDollar[3].union.unresolvedObjectName().ToTableName()
 			sqlVAL.union.val = &tree.Scatter{
@@ -30154,111 +32641,173 @@ sqldefault:
 				To:           sqlDollar[11].union.exprs(),
 			}
 		}
-	case 217:
+	case 223:
 		sqlDollar = sqlS[sqlpt-4 : sqlpt+1]
-//line sql-gen.y:2685
+//line sql-gen.y:2802
 		{
 			sqlVAL.union.val = &tree.Scatter{TableOrIndex: sqlDollar[3].union.tableIndexName()}
 		}
-	case 218:
+	case 224:
 		sqlDollar = sqlS[sqlpt-12 : sqlpt+1]
-//line sql-gen.y:2689
+//line sql-gen.y:2806
 		{
 			sqlVAL.union.val = &tree.Scatter{TableOrIndex: sqlDollar[3].union.tableIndexName(), From: sqlDollar[7].union.exprs(), To: sqlDollar[11].union.exprs()}
 		}
-	case 219:
+	case 225:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:2695
+//line sql-gen.y:2812
 		{
 			sqlVAL.union.val = tree.AlterTableCmds{sqlDollar[1].union.alterTableCmd()}
 		}
-	case 220:
+	case 226:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:2699
+//line sql-gen.y:2816
 		{
 			sqlVAL.union.val = append(sqlDollar[1].union.alterTableCmds(), sqlDollar[3].union.alterTableCmd())
 		}
-	case 221:
+	case 227:
 		sqlDollar = sqlS[sqlpt-5 : sqlpt+1]
-//line sql-gen.y:2706
+//line sql-gen.y:2823
 		{
 			sqlVAL.union.val = &tree.AlterTableRenameColumn{Column: tree.Name(sqlDollar[3].str), NewName: tree.Name(sqlDollar[5].str)}
 		}
-	case 222:
+	case 228:
 		sqlDollar = sqlS[sqlpt-5 : sqlpt+1]
-//line sql-gen.y:2711
+//line sql-gen.y:2828
 		{
 			sqlVAL.union.val = &tree.AlterTableRenameConstraint{Constraint: tree.Name(sqlDollar[3].str), NewName: tree.Name(sqlDollar[5].str)}
 		}
-	case 223:
+	case 229:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:2716
+//line sql-gen.y:2833
 		{
 			sqlVAL.union.val = &tree.AlterTableAddColumn{IfNotExists: false, ColumnDef: sqlDollar[2].union.colTableDef()}
 		}
-	case 224:
+	case 230:
 		sqlDollar = sqlS[sqlpt-5 : sqlpt+1]
-//line sql-gen.y:2721
+//line sql-gen.y:2838
 		{
 			sqlVAL.union.val = &tree.AlterTableAddColumn{IfNotExists: true, ColumnDef: sqlDollar[5].union.colTableDef()}
 		}
-	case 225:
+	case 231:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:2726
+//line sql-gen.y:2843
 		{
 			sqlVAL.union.val = &tree.AlterTableAddColumn{IfNotExists: false, ColumnDef: sqlDollar[3].union.colTableDef()}
 		}
-	case 226:
+	case 232:
 		sqlDollar = sqlS[sqlpt-6 : sqlpt+1]
-//line sql-gen.y:2731
+//line sql-gen.y:2848
 		{
 			sqlVAL.union.val = &tree.AlterTableAddColumn{IfNotExists: true, ColumnDef: sqlDollar[6].union.colTableDef()}
 		}
-	case 227:
+	case 233:
 		sqlDollar = sqlS[sqlpt-4 : sqlpt+1]
-//line sql-gen.y:2736
+//line sql-gen.y:2853
 		{
 			sqlVAL.union.val = &tree.AlterTableSetDefault{Column: tree.Name(sqlDollar[3].str), Default: sqlDollar[4].union.expr()}
 		}
-	case 228:
+	case 234:
 		sqlDollar = sqlS[sqlpt-4 : sqlpt+1]
-//line sql-gen.y:2741
+//line sql-gen.y:2858
 		{
 			sqlVAL.union.val = &tree.AlterTableSetOnUpdate{Column: tree.Name(sqlDollar[3].str), Expr: sqlDollar[4].union.expr()}
 		}
-	case 229:
+	case 235:
 		sqlDollar = sqlS[sqlpt-4 : sqlpt+1]
-//line sql-gen.y:2746
+//line sql-gen.y:2863
 		{
 			sqlVAL.union.val = &tree.AlterTableSetVisible{Column: tree.Name(sqlDollar[3].str), Visible: sqlDollar[4].union.bool()}
 		}
-	case 230:
+	case 236:
 		sqlDollar = sqlS[sqlpt-6 : sqlpt+1]
-//line sql-gen.y:2751
+//line sql-gen.y:2868
 		{
 			sqlVAL.union.val = &tree.AlterTableDropNotNull{Column: tree.Name(sqlDollar[3].str)}
 		}
-	case 231:
+	case 237:
+		sqlDollar = sqlS[sqlpt-6 : sqlpt+1]
+//line sql-gen.y:2872
+		{
+			qualification := tree.GeneratedAlwaysAsIdentity{}
+			sqlVAL.union.val = &tree.AlterTableAddIdentity{Column: tree.Name(sqlDollar[3].str), Qualification: &qualification}
+		}
+	case 238:
+		sqlDollar = sqlS[sqlpt-6 : sqlpt+1]
+//line sql-gen.y:2877
+		{
+			qualification := tree.GeneratedByDefAsIdentity{}
+			sqlVAL.union.val = &tree.AlterTableAddIdentity{Column: tree.Name(sqlDollar[3].str), Qualification: &qualification}
+		}
+	case 239:
+		sqlDollar = sqlS[sqlpt-9 : sqlpt+1]
+//line sql-gen.y:2882
+		{
+			qualification := tree.GeneratedAlwaysAsIdentity{
+				SeqOptions: sqlDollar[8].union.seqOpts(),
+			}
+			sqlVAL.union.val = &tree.AlterTableAddIdentity{Column: tree.Name(sqlDollar[3].str), Qualification: &qualification}
+		}
+	case 240:
+		sqlDollar = sqlS[sqlpt-9 : sqlpt+1]
+//line sql-gen.y:2889
+		{
+			qualification := tree.GeneratedByDefAsIdentity{
+				SeqOptions: sqlDollar[8].union.seqOpts(),
+			}
+			sqlVAL.union.val = &tree.AlterTableAddIdentity{Column: tree.Name(sqlDollar[3].str), Qualification: &qualification}
+		}
+	case 241:
+		sqlDollar = sqlS[sqlpt-4 : sqlpt+1]
+//line sql-gen.y:2896
+		{
+			sqlVAL.union.val = &tree.AlterTableSetIdentity{Column: tree.Name(sqlDollar[3].str), GeneratedAsIdentityType: tree.GeneratedAlways}
+		}
+	case 242:
+		sqlDollar = sqlS[sqlpt-4 : sqlpt+1]
+//line sql-gen.y:2900
+		{
+			sqlVAL.union.val = &tree.AlterTableSetIdentity{Column: tree.Name(sqlDollar[3].str), GeneratedAsIdentityType: tree.GeneratedByDefault}
+		}
+	case 243:
+		sqlDollar = sqlS[sqlpt-4 : sqlpt+1]
+//line sql-gen.y:2905
+		{
+			sqlVAL.union.val = &tree.AlterTableIdentity{Column: tree.Name(sqlDollar[3].str), SeqOptions: sqlDollar[4].union.seqOpts()}
+		}
+	case 244:
+		sqlDollar = sqlS[sqlpt-5 : sqlpt+1]
+//line sql-gen.y:2910
+		{
+			sqlVAL.union.val = &tree.AlterTableDropIdentity{Column: tree.Name(sqlDollar[3].str), IfExists: false}
+		}
+	case 245:
+		sqlDollar = sqlS[sqlpt-7 : sqlpt+1]
+//line sql-gen.y:2915
+		{
+			sqlVAL.union.val = &tree.AlterTableDropIdentity{Column: tree.Name(sqlDollar[3].str), IfExists: true}
+		}
+	case 246:
 		sqlDollar = sqlS[sqlpt-5 : sqlpt+1]
-//line sql-gen.y:2756
+//line sql-gen.y:2920
 		{
 			sqlVAL.union.val = &tree.AlterTableDropStored{Column: tree.Name(sqlDollar[3].str)}
 		}
-	case 232:
+	case 247:
 		sqlDollar = sqlS[sqlpt-6 : sqlpt+1]
-//line sql-gen.y:2761
+//line sql-gen.y:2925
 		{
 			sqlVAL.union.val = &tree.AlterTableSetNotNull{Column: tree.Name(sqlDollar[3].str)}
 		}
-	case 233:
+	case 248:
 		sqlDollar = sqlS[sqlpt-5 : sqlpt+1]
-//line sql-gen.y:2765
+//line sql-gen.y:2929
 		{
 			return unimplemented(sqllex, "alter table alter column add")
 		}
-	case 234:
+	case 249:
 		sqlDollar = sqlS[sqlpt-6 : sqlpt+1]
-//line sql-gen.y:2770
+//line sql-gen.y:2934
 		{
 			sqlVAL.union.val = &tree.AlterTableDropColumn{
 				IfExists:     true,
@@ -30266,9 +32815,9 @@ sqldefault:
 				DropBehavior: sqlDollar[6].union.dropBehavior(),
 			}
 		}
-	case 235:
+	case 250:
 		sqlDollar = sqlS[sqlpt-4 : sqlpt+1]
-//line sql-gen.y:2779
+//line sql-gen.y:2943
 		{
 			sqlVAL.union.val = &tree.AlterTableDropColumn{
 				IfExists:     false,
@@ -30276,9 +32825,9 @@ sqldefault:
 				DropBehavior: sqlDollar[4].union.dropBehavior(),
 			}
 		}
-	case 236:
+	case 251:
 		sqlDollar = sqlS[sqlpt-8 : sqlpt+1]
-//line sql-gen.y:2791
+//line sql-gen.y:2955
 		{
 			sqlVAL.union.val = &tree.AlterTableAlterColumnType{
 				Column:    tree.Name(sqlDollar[3].str),
@@ -30287,18 +32836,18 @@ sqldefault:
 				Using:     sqlDollar[8].union.expr(),
 			}
 		}
-	case 237:
+	case 252:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:2801
+//line sql-gen.y:2965
 		{
 			sqlVAL.union.val = &tree.AlterTableAddConstraint{
 				ConstraintDef:      sqlDollar[2].union.constraintDef(),
 				ValidationBehavior: sqlDollar[3].union.validationBehavior(),
 			}
 		}
-	case 238:
+	case 253:
 		sqlDollar = sqlS[sqlpt-8 : sqlpt+1]
-//line sql-gen.y:2809
+//line sql-gen.y:2973
 		{
 			def := sqlDollar[7].union.constraintDef()
 			def.SetName(tree.Name(sqlDollar[6].str))
@@ -30308,29 +32857,29 @@ sqldefault:
 				ValidationBehavior: sqlDollar[8].union.validationBehavior(),
 			}
 		}
-	case 239:
+	case 254:
 		sqlDollar = sqlS[sqlpt-4 : sqlpt+1]
-//line sql-gen.y:2819
+//line sql-gen.y:2983
 		{
 			return unimplementedWithIssueDetail(sqllex, 31632, "alter constraint")
 		}
-	case 240:
+	case 255:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:2822
+//line sql-gen.y:2986
 		{
 
 			return unimplementedWithIssueDetail(sqllex, 22456, "alter table inherits")
 		}
-	case 241:
+	case 256:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:2828
+//line sql-gen.y:2992
 		{
 
 			return unimplementedWithIssueDetail(sqllex, 22456, "alter table no inherits")
 		}
-	case 242:
+	case 257:
 		sqlDollar = sqlS[sqlpt-10 : sqlpt+1]
-//line sql-gen.y:2834
+//line sql-gen.y:2998
 		{
 			sqlVAL.union.val = &tree.AlterTableAlterPrimaryKey{
 				Columns:       sqlDollar[7].union.idxElems(),
@@ -30338,17 +32887,17 @@ sqldefault:
 				StorageParams: sqlDollar[10].union.storageParams(),
 			}
 		}
-	case 243:
+	case 258:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:2843
+//line sql-gen.y:3007
 		{
 			sqlVAL.union.val = &tree.AlterTableValidateConstraint{
 				Constraint: tree.Name(sqlDollar[3].str),
 			}
 		}
-	case 244:
+	case 259:
 		sqlDollar = sqlS[sqlpt-6 : sqlpt+1]
-//line sql-gen.y:2850
+//line sql-gen.y:3014
 		{
 			sqlVAL.union.val = &tree.AlterTableDropConstraint{
 				IfExists:     true,
@@ -30356,9 +32905,9 @@ sqldefault:
 				DropBehavior: sqlDollar[6].union.dropBehavior(),
 			}
 		}
-	case 245:
+	case 260:
 		sqlDollar = sqlS[sqlpt-4 : sqlpt+1]
-//line sql-gen.y:2859
+//line sql-gen.y:3023
 		{
 			sqlVAL.union.val = &tree.AlterTableDropConstraint{
 				IfExists:     false,
@@ -30366,158 +32915,277 @@ sqldefault:
 				DropBehavior: sqlDollar[4].union.dropBehavior(),
 			}
 		}
-	case 246:
+	case 261:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:2868
+//line sql-gen.y:3032
 		{
 			sqlVAL.union.val = &tree.AlterTableSetAudit{Mode: sqlDollar[3].union.auditMode()}
 		}
-	case 247:
+	case 262:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:2873
+//line sql-gen.y:3037
 		{
 			sqlVAL.union.val = &tree.AlterTablePartitionByTable{
 				PartitionByTable: sqlDollar[1].union.partitionByTable(),
 			}
 		}
-	case 248:
+	case 263:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:2880
+//line sql-gen.y:3044
 		{
 
 			sqlVAL.union.val = &tree.AlterTableInjectStats{
 				Stats: sqlDollar[3].union.expr(),
 			}
 		}
-	case 249:
+	case 264:
 		sqlDollar = sqlS[sqlpt-4 : sqlpt+1]
-//line sql-gen.y:2887
+//line sql-gen.y:3051
 		{
 			sqlVAL.union.val = &tree.AlterTableSetStorageParams{
 				StorageParams: sqlDollar[3].union.storageParams(),
 			}
 		}
-	case 250:
+	case 265:
 		sqlDollar = sqlS[sqlpt-4 : sqlpt+1]
-//line sql-gen.y:2893
+//line sql-gen.y:3057
 		{
 			sqlVAL.union.val = &tree.AlterTableResetStorageParams{
 				Params: sqlDollar[3].union.storageParamKeys(),
 			}
 		}
-	case 251:
+	case 266:
+		sqlDollar = sqlS[sqlpt-4 : sqlpt+1]
+//line sql-gen.y:3063
+		{
+			sqlVAL.union.val = &tree.AlterTableSetRLSMode{
+				Mode: sqlDollar[1].union.rlsTableMode(),
+			}
+		}
+	case 267:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:2900
+//line sql-gen.y:3070
 		{
 			sqlVAL.union.val = tree.AuditModeReadWrite
 		}
-	case 252:
+	case 268:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:2901
+//line sql-gen.y:3071
 		{
 			sqlVAL.union.val = tree.AuditModeDisable
 		}
-	case 253:
+	case 269:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:2905
+//line sql-gen.y:3075
 		{
 			sqlVAL.union.val = tree.AlterIndexCmds{sqlDollar[1].union.alterIndexCmd()}
 		}
-	case 254:
+	case 270:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:2909
+//line sql-gen.y:3079
 		{
 			sqlVAL.union.val = append(sqlDollar[1].union.alterIndexCmds(), sqlDollar[3].union.alterIndexCmd())
 		}
-	case 255:
+	case 271:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:2915
+//line sql-gen.y:3085
 		{
 			sqlVAL.union.val = &tree.AlterIndexPartitionBy{
 				PartitionByIndex: sqlDollar[1].union.partitionByIndex(),
 			}
 		}
-	case 256:
+	case 272:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:2923
+//line sql-gen.y:3093
 		{
 			sqlVAL.union.val = sqlDollar[3].union.expr()
 		}
-	case 257:
+	case 273:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:2927
+//line sql-gen.y:3097
 		{
 			sqlVAL.union.val = nil
 		}
-	case 258:
+	case 274:
 		sqlDollar = sqlS[sqlpt-4 : sqlpt+1]
-//line sql-gen.y:2933
+//line sql-gen.y:3103
 		{
 			sqlVAL.union.val = sqlDollar[4].union.expr()
 		}
-	case 259:
+	case 275:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:2937
+//line sql-gen.y:3107
 		{
 			sqlVAL.union.val = nil
 		}
-	case 260:
+	case 276:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:2943
+//line sql-gen.y:3113
 		{
 			sqlVAL.union.val = true
 		}
-	case 261:
+	case 277:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:2947
+//line sql-gen.y:3117
 		{
 			sqlVAL.union.val = false
 		}
-	case 262:
+	case 278:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:2953
+//line sql-gen.y:3123
 		{
 			sqlVAL.union.val = sqlDollar[2].union.expr()
 		}
-	case 263:
+	case 279:
 		sqlDollar = sqlS[sqlpt-0 : sqlpt+1]
-//line sql-gen.y:2957
+//line sql-gen.y:3127
 		{
 			sqlVAL.union.val = nil
 		}
-	case 264:
+	case 280:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:2964
+//line sql-gen.y:3134
 		{
 			sqlVAL.union.val = tree.DropCascade
 		}
-	case 265:
+	case 281:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:2968
+//line sql-gen.y:3138
 		{
 			sqlVAL.union.val = tree.DropRestrict
 		}
-	case 266:
+	case 282:
 		sqlDollar = sqlS[sqlpt-0 : sqlpt+1]
-//line sql-gen.y:2972
+//line sql-gen.y:3142
 		{
 			sqlVAL.union.val = tree.DropDefault
 		}
-	case 267:
+	case 283:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:2978
+//line sql-gen.y:3148
 		{
 			sqlVAL.union.val = tree.ValidationSkip
 		}
-	case 268:
+	case 284:
 		sqlDollar = sqlS[sqlpt-0 : sqlpt+1]
-//line sql-gen.y:2982
+//line sql-gen.y:3152
 		{
 			sqlVAL.union.val = tree.ValidationDefault
 		}
-	case 269:
+	case 285:
+		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
+//line sql-gen.y:3157
+		{
+			sqlVAL.union.val = tree.SequenceOption{Name: tree.SeqOptCycle}
+		}
+	case 286:
+		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
+//line sql-gen.y:3159
+		{
+			sqlVAL.union.val = tree.SequenceOption{Name: tree.SeqOptNoCycle}
+		}
+	case 287:
+		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
+//line sql-gen.y:3160
+		{
+			x := sqlDollar[3].union.int64()
+			sqlVAL.union.val = tree.SequenceOption{Name: tree.SeqOptCache, IntVal: &x}
+		}
+	case 288:
+		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
+//line sql-gen.y:3162
+		{
+			x := sqlDollar[3].union.int64()
+			sqlVAL.union.val = tree.SequenceOption{Name: tree.SeqOptIncrement, IntVal: &x}
+		}
+	case 289:
+		sqlDollar = sqlS[sqlpt-4 : sqlpt+1]
+//line sql-gen.y:3164
+		{
+			x := sqlDollar[4].union.int64()
+			sqlVAL.union.val = tree.SequenceOption{Name: tree.SeqOptIncrement, IntVal: &x, OptionalWord: true}
+		}
+	case 290:
+		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
+//line sql-gen.y:3166
+		{
+			x := sqlDollar[3].union.int64()
+			sqlVAL.union.val = tree.SequenceOption{Name: tree.SeqOptMinValue, IntVal: &x}
+		}
+	case 291:
+		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
+//line sql-gen.y:3168
+		{
+			sqlVAL.union.val = tree.SequenceOption{Name: tree.SeqOptMinValue}
+		}
+	case 292:
+		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
+//line sql-gen.y:3169
+		{
+			x := sqlDollar[3].union.int64()
+			sqlVAL.union.val = tree.SequenceOption{Name: tree.SeqOptMaxValue, IntVal: &x}
+		}
+	case 293:
+		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
+//line sql-gen.y:3171
+		{
+			sqlVAL.union.val = tree.SequenceOption{Name: tree.SeqOptMaxValue}
+		}
+	case 294:
+		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
+//line sql-gen.y:3172
+		{
+			x := sqlDollar[3].union.int64()
+			sqlVAL.union.val = tree.SequenceOption{Name: tree.SeqOptStart, IntVal: &x}
+		}
+	case 295:
+		sqlDollar = sqlS[sqlpt-4 : sqlpt+1]
+//line sql-gen.y:3174
+		{
+			x := sqlDollar[4].union.int64()
+			sqlVAL.union.val = tree.SequenceOption{Name: tree.SeqOptStart, IntVal: &x, OptionalWord: true}
+		}
+	case 296:
+		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
+//line sql-gen.y:3176
+		{
+			sqlVAL.union.val = tree.SequenceOption{Name: tree.SeqOptRestart}
+		}
+	case 297:
+		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
+//line sql-gen.y:3177
+		{
+			x := sqlDollar[2].union.int64()
+			sqlVAL.union.val = tree.SequenceOption{Name: tree.SeqOptRestart, IntVal: &x}
+		}
+	case 298:
+		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
+//line sql-gen.y:3179
+		{
+			x := sqlDollar[3].union.int64()
+			sqlVAL.union.val = tree.SequenceOption{Name: tree.SeqOptRestart, IntVal: &x, OptionalWord: true}
+		}
+	case 299:
+		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
+//line sql-gen.y:3181
+		{
+			return setErr(sqllex, errors.Newf("sequence option \"%s\" not supported here", sqlDollar[2].union.seqOpt().Name))
+		}
+	case 300:
+		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
+//line sql-gen.y:3184
+		{
+			sqlVAL.union.val = []tree.SequenceOption{sqlDollar[1].union.seqOpt()}
+		}
+	case 301:
+		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
+//line sql-gen.y:3185
+		{
+			sqlVAL.union.val = append(sqlDollar[1].union.seqOpts(), sqlDollar[2].union.seqOpt())
+		}
+	case 302:
 		sqlDollar = sqlS[sqlpt-7 : sqlpt+1]
-//line sql-gen.y:3007
+//line sql-gen.y:3208
 		{
 			sqlVAL.union.val = &tree.AlterType{
 				Type: sqlDollar[3].union.unresolvedObjectName(),
@@ -30528,9 +33196,9 @@ sqldefault:
 				},
 			}
 		}
-	case 270:
+	case 303:
 		sqlDollar = sqlS[sqlpt-10 : sqlpt+1]
-//line sql-gen.y:3018
+//line sql-gen.y:3219
 		{
 			sqlVAL.union.val = &tree.AlterType{
 				Type: sqlDollar[3].union.unresolvedObjectName(),
@@ -30541,9 +33209,9 @@ sqldefault:
 				},
 			}
 		}
-	case 271:
+	case 304:
 		sqlDollar = sqlS[sqlpt-6 : sqlpt+1]
-//line sql-gen.y:3029
+//line sql-gen.y:3230
 		{
 			sqlVAL.union.val = &tree.AlterType{
 				Type: sqlDollar[3].union.unresolvedObjectName(),
@@ -30552,9 +33220,9 @@ sqldefault:
 				},
 			}
 		}
-	case 272:
+	case 305:
 		sqlDollar = sqlS[sqlpt-8 : sqlpt+1]
-//line sql-gen.y:3038
+//line sql-gen.y:3239
 		{
 			sqlVAL.union.val = &tree.AlterType{
 				Type: sqlDollar[3].union.unresolvedObjectName(),
@@ -30564,9 +33232,9 @@ sqldefault:
 				},
 			}
 		}
-	case 273:
+	case 306:
 		sqlDollar = sqlS[sqlpt-6 : sqlpt+1]
-//line sql-gen.y:3048
+//line sql-gen.y:3249
 		{
 			sqlVAL.union.val = &tree.AlterType{
 				Type: sqlDollar[3].union.unresolvedObjectName(),
@@ -30575,9 +33243,9 @@ sqldefault:
 				},
 			}
 		}
-	case 274:
+	case 307:
 		sqlDollar = sqlS[sqlpt-6 : sqlpt+1]
-//line sql-gen.y:3057
+//line sql-gen.y:3258
 		{
 			sqlVAL.union.val = &tree.AlterType{
 				Type: sqlDollar[3].union.unresolvedObjectName(),
@@ -30586,9 +33254,9 @@ sqldefault:
 				},
 			}
 		}
-	case 275:
+	case 308:
 		sqlDollar = sqlS[sqlpt-6 : sqlpt+1]
-//line sql-gen.y:3066
+//line sql-gen.y:3267
 		{
 			sqlVAL.union.val = &tree.AlterType{
 				Type: sqlDollar[3].union.unresolvedObjectName(),
@@ -30597,322 +33265,315 @@ sqldefault:
 				},
 			}
 		}
-	case 276:
+	case 309:
 		sqlDollar = sqlS[sqlpt-9 : sqlpt+1]
-//line sql-gen.y:3075
+//line sql-gen.y:3276
 		{
 			return unimplementedWithIssueDetail(sqllex, 48701, "ALTER TYPE ATTRIBUTE")
 		}
-	case 277:
+	case 310:
 		sqlDollar = sqlS[sqlpt-4 : sqlpt+1]
-//line sql-gen.y:3079
+//line sql-gen.y:3280
 		{
 			return unimplementedWithIssueDetail(sqllex, 48701, "ALTER TYPE ATTRIBUTE")
 		}
-	case 278:
+	case 311:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:3082
+//line sql-gen.y:3283
 		{
 			return helpWith(sqllex, "ALTER TYPE")
 		}
-	case 279:
+	case 312:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:3086
+//line sql-gen.y:3287
 		{
 			sqlVAL.union.val = &tree.AlterTypeAddValuePlacement{
 				Before:      true,
 				ExistingVal: tree.EnumValue(sqlDollar[2].str),
 			}
 		}
-	case 280:
+	case 313:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:3093
+//line sql-gen.y:3294
 		{
 			sqlVAL.union.val = &tree.AlterTypeAddValuePlacement{
 				Before:      false,
 				ExistingVal: tree.EnumValue(sqlDollar[2].str),
 			}
 		}
-	case 281:
+	case 314:
 		sqlDollar = sqlS[sqlpt-0 : sqlpt+1]
-//line sql-gen.y:3100
+//line sql-gen.y:3301
 		{
 			sqlVAL.union.val = (*tree.AlterTypeAddValuePlacement)(nil)
 		}
-	case 282:
+	case 315:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:3106
+//line sql-gen.y:3307
 		{
 			sqlVAL.union.val = tree.RoleSpec{
 				RoleSpecType: tree.RoleName,
 				Name:         sqlDollar[1].str,
 			}
 		}
-	case 283:
+	case 316:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:3113
+//line sql-gen.y:3314
 		{
 			sqlVAL.union.val = tree.RoleSpec{
 				RoleSpecType: tree.RoleName,
 				Name:         sqlDollar[1].str,
 			}
 		}
-	case 284:
+	case 317:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:3120
+//line sql-gen.y:3321
 		{
 			sqlVAL.union.val = tree.RoleSpec{
 				RoleSpecType: tree.CurrentUser,
 			}
 		}
-	case 285:
+	case 318:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:3126
+//line sql-gen.y:3327
 		{
 			sqlVAL.union.val = tree.RoleSpec{
 				RoleSpecType: tree.SessionUser,
 			}
 		}
-	case 286:
+	case 319:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:3134
+//line sql-gen.y:3335
 		{
 			sqlVAL.union.val = tree.RoleSpecList{sqlDollar[1].union.roleSpec()}
 		}
-	case 287:
+	case 320:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:3138
+//line sql-gen.y:3339
 		{
 			sqlVAL.union.val = append(sqlDollar[1].union.roleSpecList(), sqlDollar[3].union.roleSpec())
 		}
-	case 295:
-		sqlDollar = sqlS[sqlpt-6 : sqlpt+1]
-//line sql-gen.y:3159
+	case 328:
+		sqlDollar = sqlS[sqlpt-7 : sqlpt+1]
+//line sql-gen.y:3360
 		{
 			sqlVAL.union.val = &tree.RefreshMaterializedView{
 				Name:              sqlDollar[5].union.unresolvedObjectName(),
 				Concurrently:      sqlDollar[4].union.bool(),
-				RefreshDataOption: sqlDollar[6].union.refreshDataOption(),
+				AsOf:              sqlDollar[6].union.asOfClause(),
+				RefreshDataOption: sqlDollar[7].union.refreshDataOption(),
 			}
 		}
-	case 296:
+	case 329:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:3166
+//line sql-gen.y:3368
 		{
 			return helpWith(sqllex, "REFRESH")
 		}
-	case 297:
+	case 330:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:3170
+//line sql-gen.y:3372
 		{
 			sqlVAL.union.val = tree.RefreshDataWithData
 		}
-	case 298:
+	case 331:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:3174
+//line sql-gen.y:3376
 		{
 			sqlVAL.union.val = tree.RefreshDataClear
 		}
-	case 299:
+	case 332:
 		sqlDollar = sqlS[sqlpt-0 : sqlpt+1]
-//line sql-gen.y:3178
+//line sql-gen.y:3380
 		{
 			sqlVAL.union.val = tree.RefreshDataDefault
 		}
-	case 300:
+	case 333:
 		sqlDollar = sqlS[sqlpt-8 : sqlpt+1]
-//line sql-gen.y:3222
+//line sql-gen.y:3424
 		{
 			sqlVAL.union.val = &tree.Backup{
 				Targets:        sqlDollar[2].union.backupTargetListPtr(),
 				To:             sqlDollar[6].union.stringOrPlaceholderOptList(),
-				Nested:         true,
 				AppendToLatest: false,
 				Subdir:         sqlDollar[4].union.expr(),
 				AsOf:           sqlDollar[7].union.asOfClause(),
 				Options:        *sqlDollar[8].union.backupOptions(),
 			}
 		}
-	case 301:
+	case 334:
 		sqlDollar = sqlS[sqlpt-6 : sqlpt+1]
-//line sql-gen.y:3234
+//line sql-gen.y:3435
 		{
 			sqlVAL.union.val = &tree.Backup{
 				Targets: sqlDollar[2].union.backupTargetListPtr(),
 				To:      sqlDollar[4].union.stringOrPlaceholderOptList(),
-				Nested:  true,
 				AsOf:    sqlDollar[5].union.asOfClause(),
 				Options: *sqlDollar[6].union.backupOptions(),
 			}
 		}
-	case 302:
+	case 335:
 		sqlDollar = sqlS[sqlpt-8 : sqlpt+1]
-//line sql-gen.y:3244
+//line sql-gen.y:3444
 		{
 			sqlVAL.union.val = &tree.Backup{
 				Targets:        sqlDollar[2].union.backupTargetListPtr(),
 				To:             sqlDollar[6].union.stringOrPlaceholderOptList(),
-				Nested:         true,
 				AppendToLatest: true,
 				AsOf:           sqlDollar[7].union.asOfClause(),
 				Options:        *sqlDollar[8].union.backupOptions(),
 			}
 		}
-	case 303:
-		sqlDollar = sqlS[sqlpt-7 : sqlpt+1]
-//line sql-gen.y:3255
+	case 336:
+		sqlDollar = sqlS[sqlpt-4 : sqlpt+1]
+//line sql-gen.y:3454
 		{
-			sqlVAL.union.val = &tree.Backup{
-				Targets:         sqlDollar[2].union.backupTargetListPtr(),
-				To:              sqlDollar[4].union.stringOrPlaceholderOptList(),
-				IncrementalFrom: sqlDollar[6].union.exprs(),
-				AsOf:            sqlDollar[5].union.asOfClause(),
-				Options:         *sqlDollar[7].union.backupOptions(),
-			}
+			setErr(sqllex, errors.New("The `BACKUP TO` syntax is no longer supported. Please use `BACKUP INTO` to create a backup collection."))
+			return helpWith(sqllex, "BACKUP")
 		}
-	case 304:
+	case 337:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:3264
+//line sql-gen.y:3458
 		{
 			return helpWith(sqllex, "BACKUP")
 		}
-	case 305:
+	case 338:
 		sqlDollar = sqlS[sqlpt-0 : sqlpt+1]
-//line sql-gen.y:3268
+//line sql-gen.y:3462
 		{
 			sqlVAL.union.val = (*tree.BackupTargetList)(nil)
 		}
-	case 306:
+	case 339:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:3272
+//line sql-gen.y:3466
 		{
 			t := sqlDollar[1].union.backupTargetList()
 			sqlVAL.union.val = &t
 		}
-	case 307:
+	case 340:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:3280
+//line sql-gen.y:3474
 		{
 			sqlVAL.union.val = sqlDollar[2].union.backupOptions()
 		}
-	case 308:
+	case 341:
 		sqlDollar = sqlS[sqlpt-5 : sqlpt+1]
-//line sql-gen.y:3284
+//line sql-gen.y:3478
 		{
 			sqlVAL.union.val = sqlDollar[4].union.backupOptions()
 		}
-	case 309:
+	case 342:
 		sqlDollar = sqlS[sqlpt-0 : sqlpt+1]
-//line sql-gen.y:3288
+//line sql-gen.y:3482
 		{
 			sqlVAL.union.val = &tree.BackupOptions{}
 		}
-	case 310:
+	case 343:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:3295
+//line sql-gen.y:3489
 		{
 			sqlVAL.union.val = sqlDollar[1].union.backupOptions()
 		}
-	case 311:
+	case 344:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:3299
+//line sql-gen.y:3493
 		{
 			if err := sqlDollar[1].union.backupOptions().CombineWith(sqlDollar[3].union.backupOptions()); err != nil {
 				return setErr(sqllex, err)
 			}
 		}
-	case 312:
+	case 345:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:3308
+//line sql-gen.y:3502
 		{
 			sqlVAL.union.val = &tree.BackupOptions{EncryptionPassphrase: sqlDollar[3].union.expr()}
 		}
-	case 313:
+	case 346:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:3312
+//line sql-gen.y:3506
 		{
 			sqlVAL.union.val = &tree.BackupOptions{CaptureRevisionHistory: tree.MakeDBool(true)}
 		}
-	case 314:
+	case 347:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:3316
+//line sql-gen.y:3510
 		{
 			sqlVAL.union.val = &tree.BackupOptions{CaptureRevisionHistory: sqlDollar[3].union.expr()}
 		}
-	case 315:
+	case 348:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:3320
+//line sql-gen.y:3514
 		{
 			sqlVAL.union.val = &tree.BackupOptions{Detached: tree.MakeDBool(true)}
 		}
-	case 316:
+	case 349:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:3324
+//line sql-gen.y:3518
 		{
 			sqlVAL.union.val = &tree.BackupOptions{Detached: tree.MakeDBool(true)}
 		}
-	case 317:
+	case 350:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:3328
+//line sql-gen.y:3522
 		{
 			sqlVAL.union.val = &tree.BackupOptions{Detached: tree.MakeDBool(false)}
 		}
-	case 318:
+	case 351:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:3332
+//line sql-gen.y:3526
 		{
 			sqlVAL.union.val = &tree.BackupOptions{EncryptionKMSURI: sqlDollar[3].union.stringOrPlaceholderOptList()}
 		}
-	case 319:
+	case 352:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:3336
+//line sql-gen.y:3530
 		{
 			sqlVAL.union.val = &tree.BackupOptions{IncrementalStorage: sqlDollar[3].union.stringOrPlaceholderOptList()}
 		}
-	case 320:
+	case 353:
 		sqlDollar = sqlS[sqlpt-4 : sqlpt+1]
-//line sql-gen.y:3340
+//line sql-gen.y:3534
 		{
 			sqlVAL.union.val = &tree.BackupOptions{ExecutionLocality: sqlDollar[4].union.expr()}
 		}
-	case 321:
+	case 354:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:3344
+//line sql-gen.y:3538
 		{
 
 			sqlVAL.union.val = &tree.BackupOptions{IncludeAllSecondaryTenants: tree.MakeDBool(true)}
 		}
-	case 322:
+	case 355:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:3349
+//line sql-gen.y:3543
 		{
 			sqlVAL.union.val = &tree.BackupOptions{IncludeAllSecondaryTenants: sqlDollar[3].union.expr()}
 		}
-	case 323:
+	case 356:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:3353
+//line sql-gen.y:3547
 		{
 			sqlVAL.union.val = &tree.BackupOptions{UpdatesClusterMonitoringMetrics: tree.MakeDBool(true)}
 		}
-	case 324:
+	case 357:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:3357
+//line sql-gen.y:3551
 		{
 			sqlVAL.union.val = &tree.BackupOptions{UpdatesClusterMonitoringMetrics: sqlDollar[3].union.expr()}
 		}
-	case 325:
+	case 358:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:3362
+//line sql-gen.y:3556
 		{
 		}
-	case 326:
+	case 359:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:3363
+//line sql-gen.y:3557
 		{
 		}
-	case 327:
+	case 360:
 		sqlDollar = sqlS[sqlpt-12 : sqlpt+1]
-//line sql-gen.y:3442
+//line sql-gen.y:3636
 		{
 			sqlVAL.union.val = &tree.ScheduledBackup{
 				ScheduleLabelSpec: *(sqlDollar[3].union.scheduleLabelSpec()),
@@ -30924,674 +33585,703 @@ sqldefault:
 				ScheduleOptions:   sqlDollar[12].union.kvOptions(),
 			}
 		}
-	case 328:
+	case 361:
 		sqlDollar = sqlS[sqlpt-6 : sqlpt+1]
-//line sql-gen.y:3453
+//line sql-gen.y:3647
 		{
 			return helpWith(sqllex, "CREATE SCHEDULE FOR BACKUP")
 		}
-	case 329:
+	case 362:
 		sqlDollar = sqlS[sqlpt-5 : sqlpt+1]
-//line sql-gen.y:3472
+//line sql-gen.y:3666
 		{
 			sqlVAL.union.val = &tree.AlterBackupSchedule{
 				ScheduleID: uint64(sqlDollar[4].union.int64()),
 				Cmds:       sqlDollar[5].union.alterBackupScheduleCmds(),
 			}
 		}
-	case 330:
+	case 363:
 		sqlDollar = sqlS[sqlpt-4 : sqlpt+1]
-//line sql-gen.y:3478
+//line sql-gen.y:3672
 		{
 			return helpWith(sqllex, "ALTER BACKUP SCHEDULE")
 		}
-	case 331:
+	case 364:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:3483
+//line sql-gen.y:3677
 		{
 			sqlVAL.union.val = tree.AlterBackupScheduleCmds{sqlDollar[1].union.alterBackupScheduleCmd()}
 		}
-	case 332:
+	case 365:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:3487
+//line sql-gen.y:3681
 		{
 			sqlVAL.union.val = append(sqlDollar[1].union.alterBackupScheduleCmds(), sqlDollar[3].union.alterBackupScheduleCmd())
 		}
-	case 333:
+	case 366:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:3494
+//line sql-gen.y:3688
 		{
 			sqlVAL.union.val = &tree.AlterBackupScheduleSetLabel{
 				Label: sqlDollar[3].union.expr(),
 			}
 		}
-	case 334:
+	case 367:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:3500
+//line sql-gen.y:3694
 		{
 			sqlVAL.union.val = &tree.AlterBackupScheduleSetInto{
 				Into: sqlDollar[3].union.stringOrPlaceholderOptList(),
 			}
 		}
-	case 335:
+	case 368:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:3506
+//line sql-gen.y:3700
 		{
 			sqlVAL.union.val = &tree.AlterBackupScheduleSetWith{
 				With: sqlDollar[3].union.backupOptions(),
 			}
 		}
-	case 336:
+	case 369:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:3512
+//line sql-gen.y:3706
 		{
 			sqlVAL.union.val = &tree.AlterBackupScheduleSetRecurring{
 				Recurrence: sqlDollar[2].union.expr(),
 			}
 		}
-	case 337:
+	case 370:
 		sqlDollar = sqlS[sqlpt-4 : sqlpt+1]
-//line sql-gen.y:3518
+//line sql-gen.y:3712
 		{
 			sqlVAL.union.val = &tree.AlterBackupScheduleSetFullBackup{
 				FullBackup: tree.FullBackupClause{AlwaysFull: true},
 			}
 		}
-	case 338:
+	case 371:
 		sqlDollar = sqlS[sqlpt-4 : sqlpt+1]
-//line sql-gen.y:3524
+//line sql-gen.y:3718
 		{
 			sqlVAL.union.val = &tree.AlterBackupScheduleSetFullBackup{
 				FullBackup: tree.FullBackupClause{Recurrence: sqlDollar[4].union.expr()},
 			}
 		}
-	case 339:
+	case 372:
 		sqlDollar = sqlS[sqlpt-4 : sqlpt+1]
-//line sql-gen.y:3530
+//line sql-gen.y:3724
 		{
 			sqlVAL.union.val = &tree.AlterBackupScheduleSetScheduleOption{
 				Option: sqlDollar[4].union.kvOption(),
 			}
 		}
-	case 340:
+	case 373:
+		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
+//line sql-gen.y:3730
+		{
+			sqlVAL.union.val = &tree.AlterBackupScheduleNextRun{}
+		}
+	case 374:
+		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
+//line sql-gen.y:3734
+		{
+			sqlVAL.union.val = &tree.AlterBackupScheduleNextRun{Full: true}
+		}
+	case 375:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:3539
+//line sql-gen.y:3741
 		{
 			sqlVAL.union.val = tree.NewStrVal(sqlDollar[1].str)
 		}
-	case 341:
+	case 376:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:3543
+//line sql-gen.y:3745
 		{
 			p := sqlDollar[1].union.placeholder()
 			sqllex.(*lexer).UpdateNumPlaceholders(p)
 			sqlVAL.union.val = p
 		}
-	case 342:
+	case 377:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:3553
+//line sql-gen.y:3755
 		{
 			sqlVAL.union.val = sqlDollar[2].union.expr()
 		}
-	case 343:
+	case 378:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:3559
+//line sql-gen.y:3761
 		{
 			sqlVAL.union.val = &tree.LabelSpec{Label: sqlDollar[1].union.expr(), IfNotExists: false}
 		}
-	case 344:
+	case 379:
 		sqlDollar = sqlS[sqlpt-4 : sqlpt+1]
-//line sql-gen.y:3563
+//line sql-gen.y:3765
 		{
 			sqlVAL.union.val = &tree.LabelSpec{Label: sqlDollar[4].union.expr(), IfNotExists: true}
 		}
-	case 345:
+	case 380:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:3569
+//line sql-gen.y:3771
 		{
 			sqlVAL.union.val = sqlDollar[1].union.labelSpec()
 		}
-	case 346:
+	case 381:
 		sqlDollar = sqlS[sqlpt-0 : sqlpt+1]
-//line sql-gen.y:3573
+//line sql-gen.y:3775
 		{
 			sqlVAL.union.val = &tree.LabelSpec{IfNotExists: false}
 		}
-	case 347:
+	case 382:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:3582
+//line sql-gen.y:3784
 		{
 			sqlVAL.union.val = &tree.FullBackupClause{Recurrence: sqlDollar[3].union.expr()}
 		}
-	case 348:
+	case 383:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:3586
+//line sql-gen.y:3788
 		{
 			sqlVAL.union.val = &tree.FullBackupClause{AlwaysFull: true}
 		}
-	case 349:
+	case 384:
 		sqlDollar = sqlS[sqlpt-0 : sqlpt+1]
-//line sql-gen.y:3590
+//line sql-gen.y:3792
 		{
 			sqlVAL.union.val = (*tree.FullBackupClause)(nil)
 		}
-	case 350:
+	case 385:
 		sqlDollar = sqlS[sqlpt-4 : sqlpt+1]
-//line sql-gen.y:3596
+//line sql-gen.y:3798
 		{
 			sqlVAL.union.val = sqlDollar[4].union.kvOptions()
 		}
-	case 351:
+	case 386:
 		sqlDollar = sqlS[sqlpt-6 : sqlpt+1]
-//line sql-gen.y:3600
+//line sql-gen.y:3802
 		{
 			sqlVAL.union.val = sqlDollar[5].union.kvOptions()
 		}
-	case 352:
+	case 387:
 		sqlDollar = sqlS[sqlpt-0 : sqlpt+1]
-//line sql-gen.y:3604
+//line sql-gen.y:3806
 		{
 			sqlVAL.union.val = nil
 		}
-	case 353:
+	case 388:
 		sqlDollar = sqlS[sqlpt-6 : sqlpt+1]
-//line sql-gen.y:3621
+//line sql-gen.y:3823
 		{
 			sqlVAL.union.val = &tree.CreateExternalConnection{
 				ConnectionLabelSpec: *(sqlDollar[4].union.labelSpec()),
 				As:                  sqlDollar[6].union.expr(),
 			}
 		}
-	case 354:
+	case 389:
 		sqlDollar = sqlS[sqlpt-4 : sqlpt+1]
-//line sql-gen.y:3627
+//line sql-gen.y:3829
 		{
 			return helpWith(sqllex, "CREATE EXTERNAL CONNECTION")
 		}
-	case 355:
+	case 390:
+		sqlDollar = sqlS[sqlpt-5 : sqlpt+1]
+//line sql-gen.y:3840
+		{
+			sqlVAL.union.val = &tree.CheckExternalConnection{
+				URI:     sqlDollar[4].union.expr(),
+				Options: *(sqlDollar[5].union.checkExternalConnectionOptions()),
+			}
+		}
+	case 391:
+		sqlDollar = sqlS[sqlpt-4 : sqlpt+1]
+//line sql-gen.y:3846
+		{
+			return helpWith(sqllex, "CHECK EXTERNAL CONNECTION")
+		}
+	case 392:
+		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
+//line sql-gen.y:3850
+		{
+			sqlVAL.union.val = sqlDollar[2].union.checkExternalConnectionOptions()
+		}
+	case 393:
+		sqlDollar = sqlS[sqlpt-5 : sqlpt+1]
+//line sql-gen.y:3854
+		{
+			sqlVAL.union.val = sqlDollar[4].union.checkExternalConnectionOptions()
+		}
+	case 394:
+		sqlDollar = sqlS[sqlpt-0 : sqlpt+1]
+//line sql-gen.y:3858
+		{
+			sqlVAL.union.val = &tree.CheckExternalConnectionOptions{}
+		}
+	case 395:
+		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
+//line sql-gen.y:3865
+		{
+			sqlVAL.union.val = sqlDollar[1].union.checkExternalConnectionOptions()
+		}
+	case 396:
+		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
+//line sql-gen.y:3869
+		{
+			if err := sqlDollar[1].union.checkExternalConnectionOptions().CombineWith(sqlDollar[3].union.checkExternalConnectionOptions()); err != nil {
+				return setErr(sqllex, err)
+			}
+		}
+	case 397:
+		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
+//line sql-gen.y:3877
+		{
+			sqlVAL.union.val = &tree.CheckExternalConnectionOptions{TransferSize: sqlDollar[3].union.expr()}
+		}
+	case 398:
+		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
+//line sql-gen.y:3881
+		{
+			sqlVAL.union.val = &tree.CheckExternalConnectionOptions{Duration: sqlDollar[3].union.expr()}
+		}
+	case 399:
+		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
+//line sql-gen.y:3885
+		{
+			sqlVAL.union.val = &tree.CheckExternalConnectionOptions{Concurrency: sqlDollar[3].union.expr()}
+		}
+	case 400:
 		sqlDollar = sqlS[sqlpt-4 : sqlpt+1]
-//line sql-gen.y:3638
+//line sql-gen.y:3898
 		{
 			sqlVAL.union.val = &tree.DropExternalConnection{
 				ConnectionLabel: sqlDollar[4].union.expr(),
 			}
 		}
-	case 356:
+	case 401:
 		sqlDollar = sqlS[sqlpt-4 : sqlpt+1]
-//line sql-gen.y:3643
+//line sql-gen.y:3903
 		{
 			return helpWith(sqllex, "DROP EXTERNAL CONNECTION")
 		}
-	case 357:
-		sqlDollar = sqlS[sqlpt-5 : sqlpt+1]
-//line sql-gen.y:3680
+	case 402:
+		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
+//line sql-gen.y:3939
 		{
-			sqlVAL.union.val = &tree.Restore{
-				DescriptorCoverage: tree.AllDescriptors,
-				From:               sqlDollar[3].union.listOfStringOrPlaceholderOptList(),
-				AsOf:               sqlDollar[4].union.asOfClause(),
-				Options:            *(sqlDollar[5].union.restoreOptions()),
-			}
+			setErr(sqllex, errors.New("The `RESTORE FROM <backupURI>` syntax is no longer supported. Please use `RESTORE FROM <subdirectory> IN <collectionURI>`."))
+			return helpWith(sqllex, "RESTORE")
 		}
-	case 358:
+	case 403:
 		sqlDollar = sqlS[sqlpt-7 : sqlpt+1]
-//line sql-gen.y:3689
+//line sql-gen.y:3944
 		{
 			sqlVAL.union.val = &tree.Restore{
 				DescriptorCoverage: tree.AllDescriptors,
 				Subdir:             sqlDollar[3].union.expr(),
-				From:               sqlDollar[5].union.listOfStringOrPlaceholderOptList(),
+				From:               sqlDollar[5].union.stringOrPlaceholderOptList(),
 				AsOf:               sqlDollar[6].union.asOfClause(),
 				Options:            *(sqlDollar[7].union.restoreOptions()),
 			}
 		}
-	case 359:
-		sqlDollar = sqlS[sqlpt-6 : sqlpt+1]
-//line sql-gen.y:3699
+	case 404:
+		sqlDollar = sqlS[sqlpt-4 : sqlpt+1]
+//line sql-gen.y:3954
 		{
-			sqlVAL.union.val = &tree.Restore{
-				Targets: sqlDollar[2].union.backupTargetList(),
-				From:    sqlDollar[4].union.listOfStringOrPlaceholderOptList(),
-				AsOf:    sqlDollar[5].union.asOfClause(),
-				Options: *(sqlDollar[6].union.restoreOptions()),
-			}
+			setErr(sqllex, errors.New("The `RESTORE <targets> FROM <backupURI>` syntax is no longer supported. Please use `RESTORE <targets> FROM <subdirectory> IN <collectionURI>`."))
+			return helpWith(sqllex, "RESTORE")
 		}
-	case 360:
+	case 405:
 		sqlDollar = sqlS[sqlpt-8 : sqlpt+1]
-//line sql-gen.y:3708
+//line sql-gen.y:3959
 		{
 			sqlVAL.union.val = &tree.Restore{
 				Targets: sqlDollar[2].union.backupTargetList(),
 				Subdir:  sqlDollar[4].union.expr(),
-				From:    sqlDollar[6].union.listOfStringOrPlaceholderOptList(),
+				From:    sqlDollar[6].union.stringOrPlaceholderOptList(),
 				AsOf:    sqlDollar[7].union.asOfClause(),
 				Options: *(sqlDollar[8].union.restoreOptions()),
 			}
 		}
-	case 361:
-		sqlDollar = sqlS[sqlpt-7 : sqlpt+1]
-//line sql-gen.y:3718
+	case 406:
+		sqlDollar = sqlS[sqlpt-5 : sqlpt+1]
+//line sql-gen.y:3969
 		{
-			sqlVAL.union.val = &tree.Restore{
-				DescriptorCoverage: tree.SystemUsers,
-				From:               sqlDollar[5].union.listOfStringOrPlaceholderOptList(),
-				AsOf:               sqlDollar[6].union.asOfClause(),
-				Options:            *(sqlDollar[7].union.restoreOptions()),
-			}
+			setErr(sqllex, errors.New("The `RESTORE <targets> FROM <backupURI>` syntax is no longer supported. Please use `RESTORE <targets> FROM <subdirectory> IN <collectionURI>`."))
+			return helpWith(sqllex, "RESTORE")
 		}
-	case 362:
+	case 407:
 		sqlDollar = sqlS[sqlpt-9 : sqlpt+1]
-//line sql-gen.y:3727
+//line sql-gen.y:3974
 		{
 			sqlVAL.union.val = &tree.Restore{
 				DescriptorCoverage: tree.SystemUsers,
 				Subdir:             sqlDollar[5].union.expr(),
-				From:               sqlDollar[7].union.listOfStringOrPlaceholderOptList(),
+				From:               sqlDollar[7].union.stringOrPlaceholderOptList(),
 				AsOf:               sqlDollar[8].union.asOfClause(),
 				Options:            *(sqlDollar[9].union.restoreOptions()),
 			}
 		}
-	case 363:
+	case 408:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:3736
+//line sql-gen.y:3983
 		{
 			return helpWith(sqllex, "RESTORE")
 		}
-	case 364:
+	case 409:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:3740
+//line sql-gen.y:3987
 		{
 			sqlVAL.union.val = tree.StringOrPlaceholderOptList{sqlDollar[1].union.expr()}
 		}
-	case 365:
+	case 410:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:3744
+//line sql-gen.y:3991
 		{
 			sqlVAL.union.val = tree.StringOrPlaceholderOptList(sqlDollar[2].union.exprs())
 		}
-	case 366:
-		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:3750
-		{
-			sqlVAL.union.val = []tree.StringOrPlaceholderOptList{sqlDollar[1].union.stringOrPlaceholderOptList()}
-		}
-	case 367:
-		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:3754
-		{
-			sqlVAL.union.val = append(sqlDollar[1].union.listOfStringOrPlaceholderOptList(), sqlDollar[3].union.stringOrPlaceholderOptList())
-		}
-	case 368:
+	case 411:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:3761
+//line sql-gen.y:3998
 		{
 			sqlVAL.union.val = sqlDollar[2].union.restoreOptions()
 		}
-	case 369:
+	case 412:
 		sqlDollar = sqlS[sqlpt-5 : sqlpt+1]
-//line sql-gen.y:3765
+//line sql-gen.y:4002
 		{
 			sqlVAL.union.val = sqlDollar[4].union.restoreOptions()
 		}
-	case 370:
+	case 413:
 		sqlDollar = sqlS[sqlpt-0 : sqlpt+1]
-//line sql-gen.y:3769
+//line sql-gen.y:4006
 		{
 			sqlVAL.union.val = &tree.RestoreOptions{}
 		}
-	case 371:
+	case 414:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:3776
+//line sql-gen.y:4013
 		{
 			sqlVAL.union.val = sqlDollar[1].union.restoreOptions()
 		}
-	case 372:
+	case 415:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:3780
+//line sql-gen.y:4017
 		{
 			if err := sqlDollar[1].union.restoreOptions().CombineWith(sqlDollar[3].union.restoreOptions()); err != nil {
 				return setErr(sqllex, err)
 			}
 		}
-	case 373:
+	case 416:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:3789
+//line sql-gen.y:4026
 		{
 			sqlVAL.union.val = &tree.RestoreOptions{EncryptionPassphrase: sqlDollar[3].union.expr()}
 		}
-	case 374:
+	case 417:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:3793
+//line sql-gen.y:4030
 		{
 			sqlVAL.union.val = &tree.RestoreOptions{DecryptionKMSURI: sqlDollar[3].union.stringOrPlaceholderOptList()}
 		}
-	case 375:
+	case 418:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:3797
+//line sql-gen.y:4034
 		{
 			sqlVAL.union.val = &tree.RestoreOptions{IntoDB: sqlDollar[3].union.expr()}
 		}
-	case 376:
+	case 419:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:3801
+//line sql-gen.y:4038
 		{
 			sqlVAL.union.val = &tree.RestoreOptions{SkipMissingFKs: true}
 		}
-	case 377:
+	case 420:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:3805
+//line sql-gen.y:4042
 		{
 			sqlVAL.union.val = &tree.RestoreOptions{SkipMissingSequences: true}
 		}
-	case 378:
+	case 421:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:3809
+//line sql-gen.y:4046
 		{
 			sqlVAL.union.val = &tree.RestoreOptions{SkipMissingSequenceOwners: true}
 		}
-	case 379:
+	case 422:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:3813
+//line sql-gen.y:4050
 		{
 			sqlVAL.union.val = &tree.RestoreOptions{SkipMissingViews: true}
 		}
-	case 380:
+	case 423:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:3817
+//line sql-gen.y:4054
 		{
 			sqlVAL.union.val = &tree.RestoreOptions{SkipMissingUDFs: true}
 		}
-	case 381:
+	case 424:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:3821
+//line sql-gen.y:4058
 		{
 			sqlVAL.union.val = &tree.RestoreOptions{Detached: true}
 		}
-	case 382:
+	case 425:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:3825
+//line sql-gen.y:4062
 		{
 			sqlVAL.union.val = &tree.RestoreOptions{SkipLocalitiesCheck: true}
 		}
-	case 383:
-		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:3829
-		{
-			sqlVAL.union.val = &tree.RestoreOptions{DebugPauseOn: sqlDollar[3].union.expr()}
-		}
-	case 384:
+	case 426:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:3833
+//line sql-gen.y:4066
 		{
 			sqlVAL.union.val = &tree.RestoreOptions{NewDBName: sqlDollar[3].union.expr()}
 		}
-	case 385:
-		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:3837
-		{
-			sqlVAL.union.val = &tree.RestoreOptions{IncludeAllSecondaryTenants: tree.MakeDBool(true)}
-		}
-	case 386:
-		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:3841
-		{
-			sqlVAL.union.val = &tree.RestoreOptions{IncludeAllSecondaryTenants: sqlDollar[3].union.expr()}
-		}
-	case 387:
+	case 427:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:3845
+//line sql-gen.y:4070
 		{
 			sqlVAL.union.val = &tree.RestoreOptions{IncrementalStorage: sqlDollar[3].union.stringOrPlaceholderOptList()}
 		}
-	case 388:
+	case 428:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:3849
+//line sql-gen.y:4074
 		{
 			sqlVAL.union.val = &tree.RestoreOptions{AsTenant: sqlDollar[3].union.expr()}
 		}
-	case 389:
+	case 429:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:3853
+//line sql-gen.y:4078
 		{
 			sqlVAL.union.val = &tree.RestoreOptions{ForceTenantID: sqlDollar[3].union.expr()}
 		}
-	case 390:
+	case 430:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:3857
+//line sql-gen.y:4082
 		{
 			sqlVAL.union.val = &tree.RestoreOptions{SchemaOnly: true}
 		}
-	case 391:
+	case 431:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:3861
+//line sql-gen.y:4086
 		{
 			sqlVAL.union.val = &tree.RestoreOptions{VerifyData: true}
 		}
-	case 392:
+	case 432:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:3865
+//line sql-gen.y:4090
 		{
 			sqlVAL.union.val = &tree.RestoreOptions{UnsafeRestoreIncompatibleVersion: true}
 		}
-	case 393:
+	case 433:
 		sqlDollar = sqlS[sqlpt-4 : sqlpt+1]
-//line sql-gen.y:3869
+//line sql-gen.y:4094
 		{
 			sqlVAL.union.val = &tree.RestoreOptions{ExecutionLocality: sqlDollar[4].union.expr()}
 		}
-	case 394:
+	case 434:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:3873
+//line sql-gen.y:4098
 		{
 			sqlVAL.union.val = &tree.RestoreOptions{ExperimentalOnline: true}
 		}
-	case 395:
+	case 435:
+		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
+//line sql-gen.y:4102
+		{
+			sqlVAL.union.val = &tree.RestoreOptions{ExperimentalCopy: true}
+		}
+	case 436:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:3877
+//line sql-gen.y:4106
 		{
 			sqlVAL.union.val = &tree.RestoreOptions{RemoveRegions: true, SkipLocalitiesCheck: true}
 		}
-	case 396:
+	case 437:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:3882
+//line sql-gen.y:4111
 		{
 		}
-	case 397:
+	case 438:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:3883
+//line sql-gen.y:4112
 		{
 		}
-	case 398:
+	case 439:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:3886
+//line sql-gen.y:4115
 		{
 		}
-	case 399:
+	case 440:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:3887
+//line sql-gen.y:4116
 		{
 		}
-	case 400:
+	case 441:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:3891
+//line sql-gen.y:4120
 		{
 			sqlVAL.str = strings.ToUpper(sqlDollar[1].str)
 		}
-	case 401:
+	case 442:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:3897
+//line sql-gen.y:4126
 		{
 			return unimplemented(sqllex, "alter domain")
 		}
-	case 402:
+	case 443:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:3901
+//line sql-gen.y:4130
 		{
 			return unimplementedWithIssueDetail(sqllex, 74775, "alter aggregate")
 		}
-	case 403:
+	case 444:
 		sqlDollar = sqlS[sqlpt-6 : sqlpt+1]
-//line sql-gen.y:3928
+//line sql-gen.y:4157
 		{
 
 			sqlVAL.union.val = &tree.Import{Bundle: true, FileFormat: sqlDollar[2].str, Files: tree.Exprs{sqlDollar[4].union.expr()}, Options: sqlDollar[6].union.kvOptions()}
 		}
-	case 404:
+	case 445:
 		sqlDollar = sqlS[sqlpt-4 : sqlpt+1]
-//line sql-gen.y:3933
+//line sql-gen.y:4162
 		{
 			sqlVAL.union.val = &tree.Import{Bundle: true, FileFormat: sqlDollar[2].str, Files: tree.Exprs{sqlDollar[3].union.expr()}, Options: sqlDollar[4].union.kvOptions()}
 		}
-	case 405:
+	case 446:
 		sqlDollar = sqlS[sqlpt-9 : sqlpt+1]
-//line sql-gen.y:3937
+//line sql-gen.y:4166
 		{
 
 			name := sqlDollar[3].union.unresolvedObjectName().ToTableName()
 			sqlVAL.union.val = &tree.Import{Bundle: true, Table: &name, FileFormat: sqlDollar[5].str, Files: tree.Exprs{sqlDollar[7].union.expr()}, Options: sqlDollar[9].union.kvOptions()}
 		}
-	case 406:
+	case 447:
 		sqlDollar = sqlS[sqlpt-7 : sqlpt+1]
-//line sql-gen.y:3943
+//line sql-gen.y:4172
 		{
 			name := sqlDollar[3].union.unresolvedObjectName().ToTableName()
 			sqlVAL.union.val = &tree.Import{Bundle: true, Table: &name, FileFormat: sqlDollar[5].str, Files: tree.Exprs{sqlDollar[6].union.expr()}, Options: sqlDollar[7].union.kvOptions()}
 		}
-	case 407:
+	case 448:
 		sqlDollar = sqlS[sqlpt-12 : sqlpt+1]
-//line sql-gen.y:3948
+//line sql-gen.y:4177
 		{
 			name := sqlDollar[3].union.unresolvedObjectName().ToTableName()
 			sqlVAL.union.val = &tree.Import{Table: &name, Into: true, IntoCols: sqlDollar[5].union.nameList(), FileFormat: sqlDollar[7].str, Files: sqlDollar[10].union.exprs(), Options: sqlDollar[12].union.kvOptions()}
 		}
-	case 408:
+	case 449:
 		sqlDollar = sqlS[sqlpt-9 : sqlpt+1]
-//line sql-gen.y:3953
+//line sql-gen.y:4182
 		{
 			name := sqlDollar[3].union.unresolvedObjectName().ToTableName()
 			sqlVAL.union.val = &tree.Import{Table: &name, Into: true, IntoCols: nil, FileFormat: sqlDollar[4].str, Files: sqlDollar[7].union.exprs(), Options: sqlDollar[9].union.kvOptions()}
 		}
-	case 409:
+	case 450:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:3957
+//line sql-gen.y:4186
 		{
 			return helpWith(sqllex, "IMPORT")
 		}
-	case 410:
+	case 451:
 		sqlDollar = sqlS[sqlpt-7 : sqlpt+1]
-//line sql-gen.y:3974
+//line sql-gen.y:4203
 		{
 			sqlVAL.union.val = &tree.Export{Query: sqlDollar[7].union.slct(), FileFormat: sqlDollar[3].str, File: sqlDollar[4].union.expr(), Options: sqlDollar[5].union.kvOptions()}
 		}
-	case 411:
+	case 452:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:3977
+//line sql-gen.y:4206
 		{
 			return helpWith(sqllex, "EXPORT")
 		}
-	case 412:
+	case 453:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:3981
+//line sql-gen.y:4210
 		{
 			sqlVAL.union.val = tree.NewStrVal(sqlDollar[1].str)
 		}
-	case 413:
+	case 454:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:3985
+//line sql-gen.y:4214
 		{
 			p := sqlDollar[1].union.placeholder()
 			sqllex.(*lexer).UpdateNumPlaceholders(p)
 			sqlVAL.union.val = p
 		}
-	case 414:
+	case 455:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:3993
+//line sql-gen.y:4222
 		{
 			sqlVAL.union.val = tree.Exprs{sqlDollar[1].union.expr()}
 		}
-	case 415:
+	case 456:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:3997
+//line sql-gen.y:4226
 		{
 			sqlVAL.union.val = append(sqlDollar[1].union.exprs(), sqlDollar[3].union.expr())
 		}
-	case 416:
-		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:4003
-		{
-			sqlVAL.union.val = sqlDollar[3].union.exprs()
-		}
-	case 417:
-		sqlDollar = sqlS[sqlpt-0 : sqlpt+1]
-//line sql-gen.y:4007
-		{
-			sqlVAL.union.val = tree.Exprs(nil)
-		}
-	case 418:
+	case 457:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:4013
+//line sql-gen.y:4232
 		{
 			sqlVAL.union.val = tree.KVOption{Key: tree.Name(sqlDollar[1].str), Value: sqlDollar[3].union.expr()}
 		}
-	case 419:
+	case 458:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:4017
+//line sql-gen.y:4236
 		{
 			sqlVAL.union.val = tree.KVOption{Key: tree.Name(sqlDollar[1].str)}
 		}
-	case 420:
+	case 459:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:4021
+//line sql-gen.y:4240
 		{
 			sqlVAL.union.val = tree.KVOption{Key: tree.Name(sqlDollar[1].str), Value: sqlDollar[3].union.expr()}
 		}
-	case 421:
+	case 460:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:4025
+//line sql-gen.y:4244
 		{
 			sqlVAL.union.val = tree.KVOption{Key: tree.Name(sqlDollar[1].str)}
 		}
-	case 422:
+	case 461:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:4031
+//line sql-gen.y:4250
 		{
 			sqlVAL.union.val = []tree.KVOption{sqlDollar[1].union.kvOption()}
 		}
-	case 423:
+	case 462:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:4035
+//line sql-gen.y:4254
 		{
 			sqlVAL.union.val = append(sqlDollar[1].union.kvOptions(), sqlDollar[3].union.kvOption())
 		}
-	case 424:
+	case 463:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:4041
+//line sql-gen.y:4260
 		{
 			sqlVAL.union.val = sqlDollar[2].union.kvOptions()
 		}
-	case 425:
+	case 464:
 		sqlDollar = sqlS[sqlpt-5 : sqlpt+1]
-//line sql-gen.y:4045
+//line sql-gen.y:4264
 		{
 			sqlVAL.union.val = sqlDollar[4].union.kvOptions()
 		}
-	case 426:
+	case 465:
 		sqlDollar = sqlS[sqlpt-0 : sqlpt+1]
-//line sql-gen.y:4049
+//line sql-gen.y:4268
 		{
 			sqlVAL.union.val = nil
 		}
-	case 427:
+	case 466:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:4059
+//line sql-gen.y:4278
 		{
 			p := sqlDollar[2].union.expr().(*tree.FuncExpr)
 			p.InCall = true
 			sqlVAL.union.val = &tree.Call{Proc: p}
 		}
-	case 428:
+	case 467:
 		sqlDollar = sqlS[sqlpt-7 : sqlpt+1]
-//line sql-gen.y:4073
+//line sql-gen.y:4292
 		{
 
 			name := sqlDollar[2].union.unresolvedObjectName().ToTableName()
@@ -31605,15 +34295,15 @@ sqldefault:
 				Options: *sqlDollar[6].union.copyOptions(),
 			}
 		}
-	case 429:
+	case 468:
 		sqlDollar = sqlS[sqlpt-5 : sqlpt+1]
-//line sql-gen.y:4087
+//line sql-gen.y:4306
 		{
 			return unimplemented(sqllex, "copy from unsupported format")
 		}
-	case 430:
+	case 469:
 		sqlDollar = sqlS[sqlpt-6 : sqlpt+1]
-//line sql-gen.y:4091
+//line sql-gen.y:4310
 		{
 
 			name := sqlDollar[2].union.unresolvedObjectName().ToTableName()
@@ -31623,15 +34313,15 @@ sqldefault:
 				Options: *sqlDollar[6].union.copyOptions(),
 			}
 		}
-	case 431:
+	case 470:
 		sqlDollar = sqlS[sqlpt-5 : sqlpt+1]
-//line sql-gen.y:4101
+//line sql-gen.y:4320
 		{
 			return unimplementedWithIssue(sqllex, 97181)
 		}
-	case 432:
+	case 471:
 		sqlDollar = sqlS[sqlpt-7 : sqlpt+1]
-//line sql-gen.y:4105
+//line sql-gen.y:4324
 		{
 
 			sqlVAL.union.val = &tree.CopyTo{
@@ -31639,169 +34329,169 @@ sqldefault:
 				Options:   *sqlDollar[7].union.copyOptions(),
 			}
 		}
-	case 433:
+	case 472:
 		sqlDollar = sqlS[sqlpt-6 : sqlpt+1]
-//line sql-gen.y:4113
+//line sql-gen.y:4332
 		{
 			return unimplementedWithIssue(sqllex, 96590)
 		}
-	case 434:
+	case 473:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:4119
+//line sql-gen.y:4338
 		{
 			sqlVAL.union.val = sqlDollar[2].union.copyOptions()
 		}
-	case 435:
+	case 474:
 		sqlDollar = sqlS[sqlpt-4 : sqlpt+1]
-//line sql-gen.y:4123
+//line sql-gen.y:4342
 		{
 			sqlVAL.union.val = sqlDollar[3].union.copyOptions()
 		}
-	case 436:
+	case 475:
 		sqlDollar = sqlS[sqlpt-0 : sqlpt+1]
-//line sql-gen.y:4127
+//line sql-gen.y:4346
 		{
 			sqlVAL.union.val = &tree.CopyOptions{}
 		}
-	case 437:
+	case 476:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:4133
+//line sql-gen.y:4352
 		{
 			sqlVAL.union.val = sqlDollar[1].union.copyOptions()
 		}
-	case 438:
+	case 477:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:4137
+//line sql-gen.y:4356
 		{
 			if err := sqlDollar[1].union.copyOptions().CombineWith(sqlDollar[2].union.copyOptions()); err != nil {
 				return setErr(sqllex, err)
 			}
 		}
-	case 439:
+	case 478:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:4145
+//line sql-gen.y:4364
 		{
 			sqlVAL.union.val = sqlDollar[1].union.copyOptions()
 		}
-	case 440:
+	case 479:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:4149
+//line sql-gen.y:4368
 		{
 			if err := sqlDollar[1].union.copyOptions().CombineWith(sqlDollar[3].union.copyOptions()); err != nil {
 				return setErr(sqllex, err)
 			}
 		}
-	case 441:
+	case 480:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:4157
+//line sql-gen.y:4376
 		{
 			sqlVAL.union.val = &tree.CopyOptions{Destination: sqlDollar[3].union.expr()}
 		}
-	case 442:
+	case 481:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:4161
+//line sql-gen.y:4380
 		{
 			sqlVAL.union.val = &tree.CopyOptions{CopyFormat: tree.CopyFormatBinary, HasFormat: true}
 		}
-	case 443:
+	case 482:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:4165
+//line sql-gen.y:4384
 		{
 			sqlVAL.union.val = &tree.CopyOptions{CopyFormat: tree.CopyFormatCSV, HasFormat: true}
 		}
-	case 444:
+	case 483:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:4169
+//line sql-gen.y:4388
 		{
 			sqlVAL.union.val = &tree.CopyOptions{Delimiter: sqlDollar[2].union.expr()}
 		}
-	case 445:
+	case 484:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:4173
+//line sql-gen.y:4392
 		{
 			sqlVAL.union.val = &tree.CopyOptions{Null: sqlDollar[2].union.expr()}
 		}
-	case 446:
+	case 485:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:4177
+//line sql-gen.y:4396
 		{
 			return unimplementedWithIssueDetail(sqllex, 41608, "oids")
 		}
-	case 447:
+	case 486:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:4181
+//line sql-gen.y:4400
 		{
 			return unimplementedWithIssueDetail(sqllex, 41608, "freeze")
 		}
-	case 448:
+	case 487:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:4185
+//line sql-gen.y:4404
 		{
 			sqlVAL.union.val = &tree.CopyOptions{Header: true, HasHeader: true}
 		}
-	case 449:
+	case 488:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:4189
+//line sql-gen.y:4408
 		{
 			sqlVAL.union.val = &tree.CopyOptions{Quote: tree.NewStrVal(sqlDollar[2].str)}
 		}
-	case 450:
+	case 489:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:4193
+//line sql-gen.y:4412
 		{
 			sqlVAL.union.val = &tree.CopyOptions{Escape: tree.NewStrVal(sqlDollar[2].str)}
 		}
-	case 451:
+	case 490:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:4197
+//line sql-gen.y:4416
 		{
 			return unimplementedWithIssueDetail(sqllex, 41608, "force_quote")
 		}
-	case 452:
+	case 491:
 		sqlDollar = sqlS[sqlpt-4 : sqlpt+1]
-//line sql-gen.y:4201
+//line sql-gen.y:4420
 		{
 			return unimplementedWithIssueDetail(sqllex, 41608, "force_not_null")
 		}
-	case 453:
+	case 492:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:4205
+//line sql-gen.y:4424
 		{
 			return unimplementedWithIssueDetail(sqllex, 41608, "force_null")
 		}
-	case 454:
-		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:4209
+	case 493:
+		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
+//line sql-gen.y:4428
 		{
-			return unimplementedWithIssueDetail(sqllex, 41608, "encoding")
+			sqlVAL.union.val = &tree.CopyOptions{Encoding: tree.NewStrVal(sqlDollar[2].str)}
 		}
-	case 455:
+	case 494:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:4215
+//line sql-gen.y:4434
 		{
 			sqlVAL.union.val = &tree.CopyOptions{Destination: sqlDollar[2].union.expr()}
 		}
-	case 456:
+	case 495:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:4219
+//line sql-gen.y:4438
 		{
 			sqlVAL.union.val = &tree.CopyOptions{CopyFormat: tree.CopyFormatBinary, HasFormat: true}
 		}
-	case 457:
+	case 496:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:4223
+//line sql-gen.y:4442
 		{
 			sqlVAL.union.val = &tree.CopyOptions{CopyFormat: tree.CopyFormatCSV, HasFormat: true}
 		}
-	case 458:
+	case 497:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:4227
+//line sql-gen.y:4446
 		{
 			sqlVAL.union.val = &tree.CopyOptions{CopyFormat: tree.CopyFormatText, HasFormat: true}
 		}
-	case 459:
+	case 498:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:4231
+//line sql-gen.y:4450
 		{
 			format := sqlDollar[2].str
 			switch format {
@@ -31816,117 +34506,117 @@ sqldefault:
 				return 1
 			}
 		}
-	case 460:
+	case 499:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:4246
+//line sql-gen.y:4465
 		{
 			sqlVAL.union.val = &tree.CopyOptions{Delimiter: sqlDollar[2].union.expr()}
 		}
-	case 461:
+	case 500:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:4250
+//line sql-gen.y:4469
 		{
 			sqlVAL.union.val = &tree.CopyOptions{Null: sqlDollar[2].union.expr()}
 		}
-	case 462:
+	case 501:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:4254
+//line sql-gen.y:4473
 		{
 			return unimplementedWithIssueDetail(sqllex, 41608, "oids")
 		}
-	case 463:
+	case 502:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:4258
+//line sql-gen.y:4477
 		{
 			return unimplementedWithIssueDetail(sqllex, 41608, "freeze")
 		}
-	case 464:
+	case 503:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:4262
+//line sql-gen.y:4481
 		{
 			sqlVAL.union.val = &tree.CopyOptions{Header: true, HasHeader: true}
 		}
-	case 465:
+	case 504:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:4266
+//line sql-gen.y:4485
 		{
 			sqlVAL.union.val = &tree.CopyOptions{Header: true, HasHeader: true}
 		}
-	case 466:
+	case 505:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:4270
+//line sql-gen.y:4489
 		{
 			sqlVAL.union.val = &tree.CopyOptions{Header: false, HasHeader: true}
 		}
-	case 467:
+	case 506:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:4274
+//line sql-gen.y:4493
 		{
 			sqlVAL.union.val = &tree.CopyOptions{Quote: tree.NewStrVal(sqlDollar[2].str)}
 		}
-	case 468:
+	case 507:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:4278
+//line sql-gen.y:4497
 		{
 			sqlVAL.union.val = &tree.CopyOptions{Escape: tree.NewStrVal(sqlDollar[2].str)}
 		}
-	case 469:
+	case 508:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:4282
+//line sql-gen.y:4501
 		{
 			return unimplementedWithIssueDetail(sqllex, 41608, "force_quote")
 		}
-	case 470:
+	case 509:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:4286
+//line sql-gen.y:4505
 		{
 			return unimplementedWithIssueDetail(sqllex, 41608, "force_not_null")
 		}
-	case 471:
+	case 510:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:4290
+//line sql-gen.y:4509
 		{
 			return unimplementedWithIssueDetail(sqllex, 41608, "force_null")
 		}
-	case 472:
-		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:4294
+	case 511:
+		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
+//line sql-gen.y:4513
 		{
-			return unimplementedWithIssueDetail(sqllex, 41608, "encoding")
+			sqlVAL.union.val = &tree.CopyOptions{Encoding: tree.NewStrVal(sqlDollar[2].str)}
 		}
-	case 474:
+	case 513:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:4302
+//line sql-gen.y:4521
 		{
 			return helpWith(sqllex, "CANCEL JOBS")
 		}
-	case 476:
+	case 515:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:4303
+//line sql-gen.y:4522
 		{
 			return helpWith(sqllex, "CANCEL QUERIES")
 		}
-	case 478:
+	case 517:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:4304
+//line sql-gen.y:4523
 		{
 			return helpWith(sqllex, "CANCEL SESSIONS")
 		}
-	case 480:
+	case 519:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:4305
+//line sql-gen.y:4524
 		{
 			return helpWith(sqllex, "CANCEL ALL JOBS")
 		}
-	case 481:
+	case 520:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:4306
+//line sql-gen.y:4525
 		{
 			return helpWith(sqllex, "CANCEL")
 		}
-	case 482:
+	case 521:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:4316
+//line sql-gen.y:4535
 		{
 			sqlVAL.union.val = &tree.ControlJobs{
 				Jobs: &tree.Select{
@@ -31935,33 +34625,33 @@ sqldefault:
 				Command: tree.CancelJob,
 			}
 		}
-	case 483:
+	case 522:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:4324
+//line sql-gen.y:4543
 		{
 			return helpWith(sqllex, "CANCEL JOBS")
 		}
-	case 484:
+	case 523:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:4326
+//line sql-gen.y:4545
 		{
 			sqlVAL.union.val = &tree.ControlJobs{Jobs: sqlDollar[3].union.slct(), Command: tree.CancelJob}
 		}
-	case 485:
+	case 524:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:4330
+//line sql-gen.y:4549
 		{
 			sqlVAL.union.val = &tree.ControlJobsForSchedules{Schedules: sqlDollar[3].union.slct(), Command: tree.CancelJob}
 		}
-	case 486:
+	case 525:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:4333
+//line sql-gen.y:4552
 		{
 			return helpWith(sqllex, "CANCEL JOBS")
 		}
-	case 487:
+	case 526:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:4343
+//line sql-gen.y:4562
 		{
 			sqlVAL.union.val = &tree.CancelQueries{
 				Queries: &tree.Select{
@@ -31970,9 +34660,9 @@ sqldefault:
 				IfExists: false,
 			}
 		}
-	case 488:
+	case 527:
 		sqlDollar = sqlS[sqlpt-5 : sqlpt+1]
-//line sql-gen.y:4352
+//line sql-gen.y:4571
 		{
 			sqlVAL.union.val = &tree.CancelQueries{
 				Queries: &tree.Select{
@@ -31981,33 +34671,33 @@ sqldefault:
 				IfExists: true,
 			}
 		}
-	case 489:
+	case 528:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:4360
+//line sql-gen.y:4579
 		{
 			return helpWith(sqllex, "CANCEL QUERIES")
 		}
-	case 490:
+	case 529:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:4362
+//line sql-gen.y:4581
 		{
 			sqlVAL.union.val = &tree.CancelQueries{Queries: sqlDollar[3].union.slct(), IfExists: false}
 		}
-	case 491:
+	case 530:
 		sqlDollar = sqlS[sqlpt-5 : sqlpt+1]
-//line sql-gen.y:4366
+//line sql-gen.y:4585
 		{
 			sqlVAL.union.val = &tree.CancelQueries{Queries: sqlDollar[5].union.slct(), IfExists: true}
 		}
-	case 492:
+	case 531:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:4369
+//line sql-gen.y:4588
 		{
 			return helpWith(sqllex, "CANCEL QUERIES")
 		}
-	case 493:
+	case 532:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:4379
+//line sql-gen.y:4598
 		{
 			sqlVAL.union.val = &tree.CancelSessions{
 				Sessions: &tree.Select{
@@ -32016,9 +34706,9 @@ sqldefault:
 				IfExists: false,
 			}
 		}
-	case 494:
+	case 533:
 		sqlDollar = sqlS[sqlpt-5 : sqlpt+1]
-//line sql-gen.y:4388
+//line sql-gen.y:4607
 		{
 			sqlVAL.union.val = &tree.CancelSessions{
 				Sessions: &tree.Select{
@@ -32027,63 +34717,69 @@ sqldefault:
 				IfExists: true,
 			}
 		}
-	case 495:
+	case 534:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:4396
+//line sql-gen.y:4615
 		{
 			return helpWith(sqllex, "CANCEL SESSIONS")
 		}
-	case 496:
+	case 535:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:4398
+//line sql-gen.y:4617
 		{
 			sqlVAL.union.val = &tree.CancelSessions{Sessions: sqlDollar[3].union.slct(), IfExists: false}
 		}
-	case 497:
+	case 536:
 		sqlDollar = sqlS[sqlpt-5 : sqlpt+1]
-//line sql-gen.y:4402
+//line sql-gen.y:4621
 		{
 			sqlVAL.union.val = &tree.CancelSessions{Sessions: sqlDollar[5].union.slct(), IfExists: true}
 		}
-	case 498:
+	case 537:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:4405
+//line sql-gen.y:4624
 		{
 			return helpWith(sqllex, "CANCEL SESSIONS")
 		}
-	case 499:
+	case 538:
 		sqlDollar = sqlS[sqlpt-4 : sqlpt+1]
-//line sql-gen.y:4413
+//line sql-gen.y:4632
 		{
 			sqlVAL.union.val = &tree.ControlJobsOfType{Type: sqlDollar[3].str, Command: tree.CancelJob}
 		}
-	case 500:
+	case 539:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:4416
+//line sql-gen.y:4635
 		{
 			return helpWith(sqllex, "CANCEL ALL JOBS")
 		}
-	case 501:
+	case 540:
 		sqlDollar = sqlS[sqlpt-6 : sqlpt+1]
-//line sql-gen.y:4420
+//line sql-gen.y:4639
 		{
 			sqlVAL.union.val = &tree.CommentOnDatabase{Name: tree.Name(sqlDollar[4].str), Comment: sqlDollar[6].union.strPtr()}
 		}
-	case 502:
+	case 541:
 		sqlDollar = sqlS[sqlpt-6 : sqlpt+1]
-//line sql-gen.y:4424
+//line sql-gen.y:4643
 		{
 			sqlVAL.union.val = &tree.CommentOnSchema{Name: sqlDollar[4].union.objectNamePrefix(), Comment: sqlDollar[6].union.strPtr()}
 		}
-	case 503:
+	case 542:
 		sqlDollar = sqlS[sqlpt-6 : sqlpt+1]
-//line sql-gen.y:4428
+//line sql-gen.y:4647
+		{
+			sqlVAL.union.val = &tree.CommentOnType{Name: sqlDollar[4].union.unresolvedObjectName(), Comment: sqlDollar[6].union.strPtr()}
+		}
+	case 543:
+		sqlDollar = sqlS[sqlpt-6 : sqlpt+1]
+//line sql-gen.y:4651
 		{
 			sqlVAL.union.val = &tree.CommentOnTable{Table: sqlDollar[4].union.unresolvedObjectName(), Comment: sqlDollar[6].union.strPtr()}
 		}
-	case 504:
+	case 544:
 		sqlDollar = sqlS[sqlpt-6 : sqlpt+1]
-//line sql-gen.y:4432
+//line sql-gen.y:4655
 		{
 			varName, err := sqlDollar[4].union.unresolvedName().NormalizeVarName()
 			if err != nil {
@@ -32100,257 +34796,760 @@ sqldefault:
 			}
 			sqlVAL.union.val = &tree.CommentOnColumn{ColumnItem: columnItem, Comment: sqlDollar[6].union.strPtr()}
 		}
-	case 505:
+	case 545:
 		sqlDollar = sqlS[sqlpt-6 : sqlpt+1]
-//line sql-gen.y:4449
+//line sql-gen.y:4672
 		{
 			sqlVAL.union.val = &tree.CommentOnIndex{Index: sqlDollar[4].union.tableIndexName(), Comment: sqlDollar[6].union.strPtr()}
 		}
-	case 506:
+	case 546:
 		sqlDollar = sqlS[sqlpt-8 : sqlpt+1]
-//line sql-gen.y:4454
+//line sql-gen.y:4677
 		{
 			sqlVAL.union.val = &tree.CommentOnConstraint{Constraint: tree.Name(sqlDollar[4].str), Table: sqlDollar[6].union.unresolvedObjectName(), Comment: sqlDollar[8].union.strPtr()}
 		}
-	case 507:
+	case 547:
 		sqlDollar = sqlS[sqlpt-4 : sqlpt+1]
-//line sql-gen.y:4457
+//line sql-gen.y:4680
 		{
 			return unimplementedWithIssueDetail(sqllex, 74777, "comment on extension")
 		}
-	case 508:
+	case 548:
 		sqlDollar = sqlS[sqlpt-4 : sqlpt+1]
-//line sql-gen.y:4458
+//line sql-gen.y:4681
 		{
 			return unimplementedWithIssueDetail(sqllex, 17511, "comment on function")
 		}
-	case 509:
+	case 549:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:4462
+//line sql-gen.y:4685
 		{
 			t := sqlDollar[1].str
 			sqlVAL.union.val = &t
 		}
-	case 510:
+	case 550:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:4467
+//line sql-gen.y:4690
 		{
 			var str *string
 			sqlVAL.union.val = str
 		}
-	case 512:
+	case 552:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:4479
+//line sql-gen.y:4702
 		{
 			return helpWith(sqllex, "CREATE ROLE")
 		}
-	case 515:
+	case 555:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:4481
+//line sql-gen.y:4704
 		{
 			return helpWith(sqllex, "CREATE STATISTICS")
 		}
-	case 517:
+	case 557:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:4482
+//line sql-gen.y:4705
 		{
 			return helpWith(sqllex, "CREATE CHANGEFEED")
 		}
-	case 519:
+	case 559:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:4483
+//line sql-gen.y:4706
 		{
 			return helpWith(sqllex, "CREATE EXTENSION")
 		}
-	case 521:
+	case 561:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:4484
+//line sql-gen.y:4707
 		{
 			return helpWith(sqllex, "CREATE EXTERNAL CONNECTION")
 		}
-	case 523:
+	case 563:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:4485
+//line sql-gen.y:4708
 		{
 			return helpWith(sqllex, "CREATE VIRTUAL CLUSTER")
 		}
-	case 525:
+	case 565:
+		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
+//line sql-gen.y:4709
+		{
+			return helpWith(sqllex, "CREATE LOGICAL REPLICATION STREAM")
+		}
+	case 567:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:4487
+//line sql-gen.y:4711
 		{
 		}
-	case 526:
+	case 568:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:4488
+//line sql-gen.y:4712
 		{
 			return helpWith(sqllex, "CREATE")
 		}
-	case 527:
-		sqlDollar = sqlS[sqlpt-4 : sqlpt+1]
-//line sql-gen.y:4499
+	case 570:
+		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
+//line sql-gen.y:4719
+		{
+			return helpWith(sqllex, "CHECK EXTERNAL CONNECTION")
+		}
+	case 571:
+		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
+//line sql-gen.y:4720
+		{
+			return helpWith(sqllex, "CHECK")
+		}
+	case 572:
+		sqlDollar = sqlS[sqlpt-11 : sqlpt+1]
+//line sql-gen.y:4738
 		{
 
-			sqlVAL.union.val = &tree.CreateTenant{
-				TenantSpec: &tree.TenantSpec{IsName: true, Expr: sqlDollar[3].union.expr()},
-				Like:       sqlDollar[4].union.likeTenantSpec(),
+			sqlVAL.union.val = &tree.CreateLogicalReplicationStream{
+				From:    sqlDollar[6].union.logicalReplicationResources(),
+				PGURL:   sqlDollar[8].union.expr(),
+				Into:    sqlDollar[10].union.logicalReplicationResources(),
+				Options: *sqlDollar[11].union.logicalReplicationOptions(),
 			}
 		}
-	case 528:
-		sqlDollar = sqlS[sqlpt-7 : sqlpt+1]
-//line sql-gen.y:4507
+	case 573:
+		sqlDollar = sqlS[sqlpt-9 : sqlpt+1]
+//line sql-gen.y:4748
+		{
+			sqlVAL.union.val = &tree.CreateLogicalReplicationStream{
+				Into:        sqlDollar[4].union.logicalReplicationResources(),
+				From:        sqlDollar[6].union.logicalReplicationResources(),
+				PGURL:       sqlDollar[8].union.expr(),
+				CreateTable: true,
+				Options:     *sqlDollar[9].union.logicalReplicationOptions(),
+			}
+		}
+	case 574:
+		sqlDollar = sqlS[sqlpt-5 : sqlpt+1]
+//line sql-gen.y:4757
+		{
+			return helpWith(sqllex, "CREATE LOGICAL REPLICATION STREAM")
+		}
+	case 575:
+		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
+//line sql-gen.y:4761
+		{
+			sqlVAL.union.val = tree.LogicalReplicationResources{
+				Tables: []*tree.UnresolvedName{
+					sqlDollar[2].union.unresolvedObjectName().ToUnresolvedName(),
+				},
+			}
+		}
+	case 576:
+		sqlDollar = sqlS[sqlpt-4 : sqlpt+1]
+//line sql-gen.y:4769
+		{
+			sqlVAL.union.val = sqlDollar[3].union.logicalReplicationResources()
+		}
+	case 577:
+		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
+//line sql-gen.y:4773
+		{
+			sqlVAL.union.val = tree.LogicalReplicationResources{
+				Database: tree.Name(sqlDollar[2].str),
+			}
+		}
+	case 578:
+		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
+//line sql-gen.y:4781
+		{
+			sqlVAL.union.val = tree.LogicalReplicationResources{
+				Tables: []*tree.UnresolvedName{
+					sqlDollar[1].union.unresolvedObjectName().ToUnresolvedName(),
+				},
+			}
+		}
+	case 579:
+		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
+//line sql-gen.y:4789
+		{
+			sqlVAL.union.val = tree.LogicalReplicationResources{
+				Tables: append(sqlDollar[1].union.logicalReplicationResources().Tables, sqlDollar[3].union.unresolvedObjectName().ToUnresolvedName()),
+			}
+		}
+	case 580:
+		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
+//line sql-gen.y:4798
+		{
+			sqlVAL.union.val = sqlDollar[2].union.logicalReplicationOptions()
+		}
+	case 581:
+		sqlDollar = sqlS[sqlpt-5 : sqlpt+1]
+//line sql-gen.y:4802
+		{
+			sqlVAL.union.val = sqlDollar[4].union.logicalReplicationOptions()
+		}
+	case 582:
+		sqlDollar = sqlS[sqlpt-0 : sqlpt+1]
+//line sql-gen.y:4806
+		{
+			sqlVAL.union.val = &tree.LogicalReplicationOptions{}
+		}
+	case 583:
+		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
+//line sql-gen.y:4812
+		{
+			sqlVAL.union.val = sqlDollar[2].union.logicalReplicationOptions()
+		}
+	case 584:
+		sqlDollar = sqlS[sqlpt-5 : sqlpt+1]
+//line sql-gen.y:4816
+		{
+			sqlVAL.union.val = sqlDollar[4].union.logicalReplicationOptions()
+		}
+	case 585:
+		sqlDollar = sqlS[sqlpt-0 : sqlpt+1]
+//line sql-gen.y:4820
+		{
+			sqlVAL.union.val = &tree.LogicalReplicationOptions{}
+		}
+	case 586:
+		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
+//line sql-gen.y:4827
+		{
+			sqlVAL.union.val = sqlDollar[1].union.logicalReplicationOptions()
+		}
+	case 587:
+		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
+//line sql-gen.y:4831
+		{
+			if err := sqlDollar[1].union.logicalReplicationOptions().CombineWith(sqlDollar[3].union.logicalReplicationOptions()); err != nil {
+				return setErr(sqllex, err)
+			}
+		}
+	case 588:
+		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
+//line sql-gen.y:4840
+		{
+			sqlVAL.union.val = sqlDollar[1].union.logicalReplicationOptions()
+		}
+	case 589:
+		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
+//line sql-gen.y:4844
+		{
+			if err := sqlDollar[1].union.logicalReplicationOptions().CombineWith(sqlDollar[3].union.logicalReplicationOptions()); err != nil {
+				return setErr(sqllex, err)
+			}
+		}
+	case 590:
+		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
+//line sql-gen.y:4853
+		{
+			sqlVAL.union.val = &tree.LogicalReplicationOptions{Cursor: sqlDollar[3].union.expr()}
+		}
+	case 591:
+		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
+//line sql-gen.y:4858
+		{
+			sqlVAL.union.val = &tree.LogicalReplicationOptions{Mode: sqlDollar[3].union.expr()}
+		}
+	case 592:
+		sqlDollar = sqlS[sqlpt-4 : sqlpt+1]
+//line sql-gen.y:4862
+		{
+			sqlVAL.union.val = &tree.LogicalReplicationOptions{DefaultFunction: sqlDollar[4].union.expr()}
+		}
+	case 593:
+		sqlDollar = sqlS[sqlpt-5 : sqlpt+1]
+//line sql-gen.y:4866
+		{
+			sqlVAL.union.val = &tree.LogicalReplicationOptions{UserFunctions: map[tree.UnresolvedName]tree.RoutineName{*sqlDollar[5].union.unresolvedObjectName().ToUnresolvedName(): sqlDollar[2].union.unresolvedObjectName().ToRoutineName()}}
+		}
+	case 594:
+		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
+//line sql-gen.y:4870
+		{
+			sqlVAL.union.val = &tree.LogicalReplicationOptions{Discard: sqlDollar[3].union.expr()}
+		}
+	case 595:
+		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
+//line sql-gen.y:4874
+		{
+			sqlVAL.union.val = &tree.LogicalReplicationOptions{SkipSchemaCheck: tree.MakeDBool(true)}
+		}
+	case 596:
+		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
+//line sql-gen.y:4878
+		{
+			sqlVAL.union.val = &tree.LogicalReplicationOptions{MetricsLabel: sqlDollar[3].union.expr()}
+		}
+	case 597:
+		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
+//line sql-gen.y:4883
+		{
+			sqlVAL.union.val = &tree.LogicalReplicationOptions{ParentID: sqlDollar[3].union.expr()}
+		}
+	case 598:
+		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
+//line sql-gen.y:4890
+		{
+			sqlVAL.union.val = &tree.LogicalReplicationOptions{Mode: sqlDollar[3].union.expr()}
+		}
+	case 599:
+		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
+//line sql-gen.y:4894
+		{
+			sqlVAL.union.val = &tree.LogicalReplicationOptions{Discard: sqlDollar[3].union.expr()}
+		}
+	case 600:
+		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
+//line sql-gen.y:4898
+		{
+			sqlVAL.union.val = &tree.LogicalReplicationOptions{MetricsLabel: sqlDollar[3].union.expr()}
+		}
+	case 601:
+		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
+//line sql-gen.y:4902
+		{
+			sqlVAL.union.val = &tree.LogicalReplicationOptions{Unidirectional: tree.MakeDBool(true)}
+		}
+	case 602:
+		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
+//line sql-gen.y:4906
+		{
+			sqlVAL.union.val = &tree.LogicalReplicationOptions{BidirectionalURI: sqlDollar[3].union.expr()}
+		}
+	case 603:
+		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
+//line sql-gen.y:4920
+		{
+
+			sqlVAL.union.val = &tree.CreateTenant{
+				TenantSpec: sqlDollar[3].union.tenantSpec(),
+			}
+		}
+	case 604:
+		sqlDollar = sqlS[sqlpt-6 : sqlpt+1]
+//line sql-gen.y:4927
 		{
 
 			sqlVAL.union.val = &tree.CreateTenant{
 				IfNotExists: true,
-				TenantSpec:  &tree.TenantSpec{IsName: true, Expr: sqlDollar[6].union.expr()},
-				Like:        sqlDollar[7].union.likeTenantSpec(),
+				TenantSpec:  sqlDollar[6].union.tenantSpec(),
 			}
 		}
-	case 529:
-		sqlDollar = sqlS[sqlpt-11 : sqlpt+1]
-//line sql-gen.y:4516
+	case 605:
+		sqlDollar = sqlS[sqlpt-10 : sqlpt+1]
+//line sql-gen.y:4935
 		{
 
 			sqlVAL.union.val = &tree.CreateTenantFromReplication{
-				TenantSpec:                  &tree.TenantSpec{IsName: true, Expr: sqlDollar[3].union.expr()},
-				ReplicationSourceTenantName: &tree.TenantSpec{IsName: true, Expr: sqlDollar[8].union.expr()},
-				ReplicationSourceAddress:    sqlDollar[10].union.expr(),
-				Options:                     *sqlDollar[11].union.tenantReplicationOptions(),
-				Like:                        sqlDollar[4].union.likeTenantSpec(),
+				TenantSpec:                  sqlDollar[3].union.tenantSpec(),
+				ReplicationSourceTenantName: &tree.TenantSpec{IsName: true, Expr: sqlDollar[7].union.expr()},
+				ReplicationSourceConnUri:    sqlDollar[9].union.expr(),
+				Options:                     *sqlDollar[10].union.tenantReplicationOptions(),
 			}
 		}
-	case 530:
-		sqlDollar = sqlS[sqlpt-14 : sqlpt+1]
-//line sql-gen.y:4527
+	case 606:
+		sqlDollar = sqlS[sqlpt-13 : sqlpt+1]
+//line sql-gen.y:4945
 		{
 
 			sqlVAL.union.val = &tree.CreateTenantFromReplication{
 				IfNotExists:                 true,
-				TenantSpec:                  &tree.TenantSpec{IsName: true, Expr: sqlDollar[6].union.expr()},
-				ReplicationSourceTenantName: &tree.TenantSpec{IsName: true, Expr: sqlDollar[11].union.expr()},
-				ReplicationSourceAddress:    sqlDollar[13].union.expr(),
-				Options:                     *sqlDollar[14].union.tenantReplicationOptions(),
-				Like:                        sqlDollar[7].union.likeTenantSpec(),
+				TenantSpec:                  sqlDollar[6].union.tenantSpec(),
+				ReplicationSourceTenantName: &tree.TenantSpec{IsName: true, Expr: sqlDollar[10].union.expr()},
+				ReplicationSourceConnUri:    sqlDollar[12].union.expr(),
+				Options:                     *sqlDollar[13].union.tenantReplicationOptions(),
 			}
 		}
-	case 531:
+	case 607:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:4538
+//line sql-gen.y:4955
 		{
 			return helpWith(sqllex, "CREATE VIRTUAL CLUSTER")
 		}
-	case 532:
+	case 608:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:4541
-		{
-		}
-	case 534:
-		sqlDollar = sqlS[sqlpt-0 : sqlpt+1]
-//line sql-gen.y:4549
+//line sql-gen.y:4958
 		{
-			sqlVAL.union.val = &tree.LikeTenantSpec{}
 		}
-	case 535:
-		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:4553
-		{
-			sqlVAL.union.val = &tree.LikeTenantSpec{OtherTenant: sqlDollar[2].union.tenantSpec()}
-		}
-	case 536:
+	case 610:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:4560
+//line sql-gen.y:4964
 		{
 			sqlVAL.union.val = sqlDollar[2].union.tenantReplicationOptions()
 		}
-	case 537:
+	case 611:
 		sqlDollar = sqlS[sqlpt-5 : sqlpt+1]
-//line sql-gen.y:4564
+//line sql-gen.y:4968
 		{
 			sqlVAL.union.val = sqlDollar[4].union.tenantReplicationOptions()
 		}
-	case 538:
+	case 612:
 		sqlDollar = sqlS[sqlpt-0 : sqlpt+1]
-//line sql-gen.y:4568
+//line sql-gen.y:4972
 		{
 			sqlVAL.union.val = &tree.TenantReplicationOptions{}
 		}
-	case 539:
+	case 613:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:4575
+//line sql-gen.y:4979
 		{
 			sqlVAL.union.val = sqlDollar[1].union.tenantReplicationOptions()
 		}
-	case 540:
+	case 614:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:4579
+//line sql-gen.y:4983
+		{
+			if err := sqlDollar[1].union.tenantReplicationOptions().CombineWith(sqlDollar[3].union.tenantReplicationOptions()); err != nil {
+				return setErr(sqllex, err)
+			}
+		}
+	case 615:
+		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
+//line sql-gen.y:4992
+		{
+			sqlVAL.union.val = &tree.TenantReplicationOptions{Retention: sqlDollar[3].union.expr()}
+		}
+	case 616:
+		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
+//line sql-gen.y:4996
+		{
+			sqlVAL.union.val = &tree.TenantReplicationOptions{EnableReaderTenant: tree.MakeDBool(true)}
+		}
+	case 617:
+		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
+//line sql-gen.y:5003
+		{
+			sqlVAL.union.val = sqlDollar[1].union.tenantReplicationOptions()
+		}
+	case 618:
+		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
+//line sql-gen.y:5007
+		{
+			if err := sqlDollar[1].union.tenantReplicationOptions().CombineWith(sqlDollar[3].union.tenantReplicationOptions()); err != nil {
+				return setErr(sqllex, err)
+			}
+		}
+	case 619:
+		sqlDollar = sqlS[sqlpt-4 : sqlpt+1]
+//line sql-gen.y:5016
+		{
+			sqlVAL.union.val = &tree.TenantReplicationOptions{ExpirationWindow: sqlDollar[4].union.expr()}
+		}
+	case 621:
+		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
+//line sql-gen.y:5026
+		{
+			return helpWith(sqllex, "CREATE SCHEDULE FOR CHANGEFEED")
+		}
+	case 623:
+		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
+//line sql-gen.y:5027
+		{
+			return helpWith(sqllex, "CREATE SCHEDULE FOR BACKUP")
+		}
+	case 624:
+		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
+//line sql-gen.y:5028
+		{
+			return helpWith(sqllex, "CREATE SCHEDULE")
+		}
+	case 625:
+		sqlDollar = sqlS[sqlpt-6 : sqlpt+1]
+//line sql-gen.y:5035
+		{
+			sqlVAL.union.val = &tree.CreateExtension{IfNotExists: true, Name: tree.Name(sqlDollar[6].str)}
+		}
+	case 626:
+		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
+//line sql-gen.y:5038
+		{
+			sqlVAL.union.val = &tree.CreateExtension{Name: tree.Name(sqlDollar[3].str)}
+		}
+	case 627:
+		sqlDollar = sqlS[sqlpt-8 : sqlpt+1]
+//line sql-gen.y:5042
+		{
+			return unimplementedWithIssueDetail(sqllex, 74777, "create extension if not exists with")
+		}
+	case 628:
+		sqlDollar = sqlS[sqlpt-5 : sqlpt+1]
+//line sql-gen.y:5045
+		{
+			return unimplementedWithIssueDetail(sqllex, 74777, "create extension with")
+		}
+	case 629:
+		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
+//line sql-gen.y:5048
+		{
+			return helpWith(sqllex, "CREATE EXTENSION")
+		}
+	case 630:
+		sqlDollar = sqlS[sqlpt-8 : sqlpt+1]
+//line sql-gen.y:5063
+		{
+			sqlVAL.union.val = &tree.AlterPolicy{
+				PolicyName:    tree.Name(sqlDollar[3].str),
+				TableName:     sqlDollar[5].union.unresolvedObjectName(),
+				NewPolicyName: tree.Name(sqlDollar[8].str),
+			}
+		}
+	case 631:
+		sqlDollar = sqlS[sqlpt-7 : sqlpt+1]
+//line sql-gen.y:5071
+		{
+			sqlVAL.union.val = &tree.AlterPolicy{
+				PolicyName: tree.Name(sqlDollar[3].str),
+				TableName:  sqlDollar[5].union.unresolvedObjectName(),
+				Roles:      sqlDollar[6].union.roleSpecList(),
+				Exprs:      sqlDollar[7].union.policyExpressions(),
+			}
+		}
+	case 632:
+		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
+//line sql-gen.y:5079
+		{
+			return helpWith(sqllex, "ALTER POLICY")
+		}
+	case 633:
+		sqlDollar = sqlS[sqlpt-9 : sqlpt+1]
+//line sql-gen.y:5094
+		{
+			sqlVAL.union.val = &tree.CreatePolicy{
+				IfNotExists: false,
+				PolicyName:  tree.Name(sqlDollar[3].str),
+				TableName:   sqlDollar[5].union.unresolvedObjectName(),
+				Type:        sqlDollar[6].union.policyType(),
+				Cmd:         sqlDollar[7].union.policyCommand(),
+				Roles:       sqlDollar[8].union.roleSpecList(),
+				Exprs:       sqlDollar[9].union.policyExpressions(),
+			}
+		}
+	case 634:
+		sqlDollar = sqlS[sqlpt-12 : sqlpt+1]
+//line sql-gen.y:5106
+		{
+			sqlVAL.union.val = &tree.CreatePolicy{
+				IfNotExists: true,
+				PolicyName:  tree.Name(sqlDollar[6].str),
+				TableName:   sqlDollar[8].union.unresolvedObjectName(),
+				Type:        sqlDollar[9].union.policyType(),
+				Cmd:         sqlDollar[10].union.policyCommand(),
+				Roles:       sqlDollar[11].union.roleSpecList(),
+				Exprs:       sqlDollar[12].union.policyExpressions(),
+			}
+		}
+	case 635:
+		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
+//line sql-gen.y:5117
+		{
+			return helpWith(sqllex, "CREATE POLICY")
+		}
+	case 636:
+		sqlDollar = sqlS[sqlpt-6 : sqlpt+1]
+//line sql-gen.y:5127
+		{
+			sqlVAL.union.val = &tree.DropPolicy{
+				PolicyName:   tree.Name(sqlDollar[3].str),
+				TableName:    sqlDollar[5].union.unresolvedObjectName(),
+				DropBehavior: sqlDollar[6].union.dropBehavior(),
+				IfExists:     false,
+			}
+		}
+	case 637:
+		sqlDollar = sqlS[sqlpt-8 : sqlpt+1]
+//line sql-gen.y:5136
+		{
+			sqlVAL.union.val = &tree.DropPolicy{
+				PolicyName:   tree.Name(sqlDollar[5].str),
+				TableName:    sqlDollar[7].union.unresolvedObjectName(),
+				DropBehavior: sqlDollar[8].union.dropBehavior(),
+				IfExists:     true,
+			}
+		}
+	case 638:
+		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
+//line sql-gen.y:5144
+		{
+			return helpWith(sqllex, "DROP POLICY")
+		}
+	case 639:
+		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
+//line sql-gen.y:5148
+		{
+			sqlVAL.union.val = tree.PolicyTypePermissive
+		}
+	case 640:
+		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
+//line sql-gen.y:5152
+		{
+			sqlVAL.union.val = tree.PolicyTypeRestrictive
+		}
+	case 641:
+		sqlDollar = sqlS[sqlpt-0 : sqlpt+1]
+//line sql-gen.y:5156
+		{
+			sqlVAL.union.val = tree.PolicyTypeDefault
+		}
+	case 642:
+		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
+//line sql-gen.y:5162
+		{
+			sqlVAL.union.val = tree.PolicyCommandAll
+		}
+	case 643:
+		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
+//line sql-gen.y:5166
+		{
+			sqlVAL.union.val = tree.PolicyCommandSelect
+		}
+	case 644:
+		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
+//line sql-gen.y:5170
+		{
+			sqlVAL.union.val = tree.PolicyCommandInsert
+		}
+	case 645:
+		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
+//line sql-gen.y:5174
+		{
+			sqlVAL.union.val = tree.PolicyCommandUpdate
+		}
+	case 646:
+		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
+//line sql-gen.y:5178
+		{
+			sqlVAL.union.val = tree.PolicyCommandDelete
+		}
+	case 647:
+		sqlDollar = sqlS[sqlpt-0 : sqlpt+1]
+//line sql-gen.y:5182
+		{
+			sqlVAL.union.val = tree.PolicyCommandDefault
+		}
+	case 648:
+		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
+//line sql-gen.y:5188
+		{
+			sqlVAL.union.val = sqlDollar[2].union.roleSpecList()
+		}
+	case 649:
+		sqlDollar = sqlS[sqlpt-0 : sqlpt+1]
+//line sql-gen.y:5191
+		{
+			sqlVAL.union.val = tree.RoleSpecList(nil)
+		}
+	case 650:
+		sqlDollar = sqlS[sqlpt-9 : sqlpt+1]
+//line sql-gen.y:5197
+		{
+			sqlVAL.union.val = tree.PolicyExpressions{
+				Using:     sqlDollar[3].union.expr(),
+				WithCheck: sqlDollar[8].union.expr(),
+			}
+		}
+	case 651:
+		sqlDollar = sqlS[sqlpt-9 : sqlpt+1]
+//line sql-gen.y:5204
 		{
-			if err := sqlDollar[1].union.tenantReplicationOptions().CombineWith(sqlDollar[3].union.tenantReplicationOptions()); err != nil {
-				return setErr(sqllex, err)
+			sqlVAL.union.val = tree.PolicyExpressions{
+				Using:     sqlDollar[8].union.expr(),
+				WithCheck: sqlDollar[4].union.expr(),
 			}
 		}
-	case 541:
-		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:4588
+	case 652:
+		sqlDollar = sqlS[sqlpt-5 : sqlpt+1]
+//line sql-gen.y:5211
 		{
-			sqlVAL.union.val = &tree.TenantReplicationOptions{Retention: sqlDollar[3].union.expr()}
+			sqlVAL.union.val = tree.PolicyExpressions{
+				WithCheck: sqlDollar[4].union.expr(),
+			}
 		}
-	case 542:
+	case 653:
 		sqlDollar = sqlS[sqlpt-4 : sqlpt+1]
-//line sql-gen.y:4593
-		{
-			sqlVAL.union.val = &tree.TenantReplicationOptions{ResumeTimestamp: sqlDollar[4].union.expr()}
-		}
-	case 544:
-		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:4603
+//line sql-gen.y:5217
 		{
-			return helpWith(sqllex, "CREATE SCHEDULE FOR CHANGEFEED")
+			sqlVAL.union.val = tree.PolicyExpressions{
+				Using: sqlDollar[3].union.expr(),
+			}
 		}
-	case 546:
-		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:4604
+	case 654:
+		sqlDollar = sqlS[sqlpt-0 : sqlpt+1]
+//line sql-gen.y:5222
 		{
-			return helpWith(sqllex, "CREATE SCHEDULE FOR BACKUP")
+			sqlVAL.union.val = tree.PolicyExpressions{}
 		}
-	case 547:
-		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:4605
+	case 655:
+		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
+//line sql-gen.y:5228
 		{
-			return helpWith(sqllex, "CREATE SCHEDULE")
+			sqlVAL.union.val = tree.TableRLSEnable
 		}
-	case 548:
-		sqlDollar = sqlS[sqlpt-6 : sqlpt+1]
-//line sql-gen.y:4612
+	case 656:
+		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
+//line sql-gen.y:5232
 		{
-			sqlVAL.union.val = &tree.CreateExtension{IfNotExists: true, Name: tree.Name(sqlDollar[6].str)}
+			sqlVAL.union.val = tree.TableRLSDisable
 		}
-	case 549:
-		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:4615
+	case 657:
+		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
+//line sql-gen.y:5236
 		{
-			sqlVAL.union.val = &tree.CreateExtension{Name: tree.Name(sqlDollar[3].str)}
+			sqlVAL.union.val = tree.TableRLSForce
 		}
-	case 550:
-		sqlDollar = sqlS[sqlpt-8 : sqlpt+1]
-//line sql-gen.y:4619
+	case 658:
+		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
+//line sql-gen.y:5240
 		{
-			return unimplementedWithIssueDetail(sqllex, 74777, "create extension if not exists with")
+			sqlVAL.union.val = tree.TableRLSNoForce
 		}
-	case 551:
-		sqlDollar = sqlS[sqlpt-5 : sqlpt+1]
-//line sql-gen.y:4622
+	case 659:
+		sqlDollar = sqlS[sqlpt-12 : sqlpt+1]
+//line sql-gen.y:5261
 		{
-			return unimplementedWithIssueDetail(sqllex, 74777, "create extension with")
+			name := sqlDollar[4].union.unresolvedObjectName().ToRoutineName()
+			sqlVAL.union.val = &tree.CreateRoutine{
+				IsProcedure: false,
+				Replace:     sqlDollar[2].union.bool(),
+				Name:        name,
+				Params:      sqlDollar[6].union.routineParams(),
+				ReturnType: &tree.RoutineReturnType{
+					Type:  sqlDollar[10].union.typeReference(),
+					SetOf: sqlDollar[9].union.bool(),
+				},
+				Options:     sqlDollar[11].union.routineOptions(),
+				RoutineBody: sqlDollar[12].union.routineBody(),
+			}
 		}
-	case 552:
-		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:4625
+	case 660:
+		sqlDollar = sqlS[sqlpt-14 : sqlpt+1]
+//line sql-gen.y:5278
 		{
-			return helpWith(sqllex, "CREATE EXTENSION")
+
+			tableParams := sqlDollar[11].union.routineParams()
+			returnType := tree.ResolvableTypeReference(types.AnyTuple)
+			if len(tableParams) == 1 {
+				returnType = tableParams[0].Type
+			}
+			routineParams := sqlDollar[6].union.routineParams()
+			for i := range routineParams {
+
+				if tree.IsOutParamClass(routineParams[i].Class) {
+					return setErrNoDetails(sqllex, errors.New("OUT and INOUT arguments aren't allowed in TABLE functions"))
+				}
+			}
+			sqlVAL.union.val = &tree.CreateRoutine{
+				IsProcedure: false,
+				Replace:     sqlDollar[2].union.bool(),
+				Name:        sqlDollar[4].union.unresolvedObjectName().ToRoutineName(),
+				Params:      append(routineParams, tableParams...),
+				ReturnType: &tree.RoutineReturnType{
+					Type:  returnType,
+					SetOf: true,
+				},
+				Options:     sqlDollar[13].union.routineOptions(),
+				RoutineBody: sqlDollar[14].union.routineBody(),
+			}
 		}
-	case 553:
-		sqlDollar = sqlS[sqlpt-13 : sqlpt+1]
-//line sql-gen.y:4644
+	case 661:
+		sqlDollar = sqlS[sqlpt-9 : sqlpt+1]
+//line sql-gen.y:5310
 		{
 			name := sqlDollar[4].union.unresolvedObjectName().ToRoutineName()
 			sqlVAL.union.val = &tree.CreateRoutine{
@@ -32358,23 +35557,20 @@ sqldefault:
 				Replace:     sqlDollar[2].union.bool(),
 				Name:        name,
 				Params:      sqlDollar[6].union.routineParams(),
-				ReturnType: tree.RoutineReturnType{
-					Type:  sqlDollar[11].union.typeReference(),
-					SetOf: sqlDollar[10].union.bool(),
-				},
-				Options:     sqlDollar[12].union.routineOptions(),
-				RoutineBody: sqlDollar[13].union.routineBody(),
+				ReturnType:  (*tree.RoutineReturnType)(nil),
+				Options:     sqlDollar[8].union.routineOptions(),
+				RoutineBody: sqlDollar[9].union.routineBody(),
 			}
 		}
-	case 554:
+	case 662:
 		sqlDollar = sqlS[sqlpt-4 : sqlpt+1]
-//line sql-gen.y:4659
+//line sql-gen.y:5322
 		{
 			return helpWith(sqllex, "CREATE FUNCTION")
 		}
-	case 555:
+	case 663:
 		sqlDollar = sqlS[sqlpt-9 : sqlpt+1]
-//line sql-gen.y:4673
+//line sql-gen.y:5336
 		{
 			name := sqlDollar[4].union.unresolvedObjectName().ToRoutineName()
 			sqlVAL.union.val = &tree.CreateRoutine{
@@ -32384,96 +35580,82 @@ sqldefault:
 				Params:      sqlDollar[6].union.routineParams(),
 				Options:     sqlDollar[8].union.routineOptions(),
 				RoutineBody: sqlDollar[9].union.routineBody(),
-				ReturnType: tree.RoutineReturnType{
-					Type: types.Void,
-				},
+				ReturnType:  (*tree.RoutineReturnType)(nil),
 			}
 		}
-	case 556:
+	case 664:
 		sqlDollar = sqlS[sqlpt-4 : sqlpt+1]
-//line sql-gen.y:4687
+//line sql-gen.y:5348
 		{
 			return helpWith(sqllex, "CREATE PROCEDURE")
 		}
-	case 557:
+	case 665:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:4690
+//line sql-gen.y:5351
 		{
 			sqlVAL.union.val = true
 		}
-	case 558:
-		sqlDollar = sqlS[sqlpt-0 : sqlpt+1]
-//line sql-gen.y:4691
-		{
-			sqlVAL.union.val = false
-		}
-	case 559:
-		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:4694
-		{
-			return unimplementedWithIssueDetail(sqllex, 100226, "UDF returning TABLE")
-		}
-	case 560:
+	case 666:
 		sqlDollar = sqlS[sqlpt-0 : sqlpt+1]
-//line sql-gen.y:4695
+//line sql-gen.y:5352
 		{
 			sqlVAL.union.val = false
 		}
-	case 561:
+	case 667:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:4698
+//line sql-gen.y:5355
 		{
 			sqlVAL.union.val = true
 		}
-	case 562:
+	case 668:
 		sqlDollar = sqlS[sqlpt-0 : sqlpt+1]
-//line sql-gen.y:4699
+//line sql-gen.y:5356
 		{
 			sqlVAL.union.val = false
 		}
-	case 564:
+	case 670:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:4705
+//line sql-gen.y:5362
 		{
 			sqlVAL.union.val = sqlDollar[1].union.routineParams()
 		}
-	case 565:
+	case 671:
 		sqlDollar = sqlS[sqlpt-0 : sqlpt+1]
-//line sql-gen.y:4706
+//line sql-gen.y:5363
 		{
 			sqlVAL.union.val = tree.RoutineParams{}
 		}
-	case 566:
+	case 672:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:4709
+//line sql-gen.y:5366
 		{
 			sqlVAL.union.val = tree.RoutineParams{sqlDollar[1].union.routineParam()}
 		}
-	case 567:
+	case 673:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:4711
+//line sql-gen.y:5368
 		{
 			sqlVAL.union.val = append(sqlDollar[1].union.routineParams(), sqlDollar[3].union.routineParam())
 		}
-	case 569:
+	case 675:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:4718
+//line sql-gen.y:5375
 		{
 			arg := sqlDollar[1].union.routineParam()
 			arg.DefaultVal = sqlDollar[3].union.expr()
 			sqlVAL.union.val = arg
 		}
-	case 570:
+	case 676:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:4724
+//line sql-gen.y:5381
 		{
 			arg := sqlDollar[1].union.routineParam()
 			arg.DefaultVal = sqlDollar[3].union.expr()
 			sqlVAL.union.val = arg
 		}
-	case 571:
+	case 677:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:4732
+//line sql-gen.y:5389
 		{
 			sqlVAL.union.val = tree.RoutineParam{
 				Name:  tree.Name(sqlDollar[2].str),
@@ -32481,9 +35663,9 @@ sqldefault:
 				Class: sqlDollar[1].union.routineParamClass(),
 			}
 		}
-	case 572:
+	case 678:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:4740
+//line sql-gen.y:5397
 		{
 			sqlVAL.union.val = tree.RoutineParam{
 				Name:  tree.Name(sqlDollar[1].str),
@@ -32491,97 +35673,119 @@ sqldefault:
 				Class: sqlDollar[2].union.routineParamClass(),
 			}
 		}
-	case 573:
+	case 679:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:4748
+//line sql-gen.y:5405
 		{
 			sqlVAL.union.val = tree.RoutineParam{
 				Name:  tree.Name(sqlDollar[1].str),
 				Type:  sqlDollar[2].union.typeReference(),
-				Class: tree.RoutineParamIn,
+				Class: tree.RoutineParamDefault,
 			}
 		}
-	case 574:
+	case 680:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:4756
+//line sql-gen.y:5413
 		{
 			sqlVAL.union.val = tree.RoutineParam{
 				Type:  sqlDollar[2].union.typeReference(),
 				Class: sqlDollar[1].union.routineParamClass(),
 			}
 		}
-	case 575:
+	case 681:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:4763
+//line sql-gen.y:5420
 		{
 			sqlVAL.union.val = tree.RoutineParam{
 				Type:  sqlDollar[1].union.typeReference(),
-				Class: tree.RoutineParamIn,
+				Class: tree.RoutineParamDefault,
 			}
 		}
-	case 576:
+	case 682:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:4771
+//line sql-gen.y:5428
 		{
 			sqlVAL.union.val = tree.RoutineParamIn
 		}
-	case 577:
+	case 683:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:4772
+//line sql-gen.y:5429
 		{
-			return unimplementedWithIssueDetail(sqllex, 100405, "create function with 'OUT' argument class")
+			sqlVAL.union.val = tree.RoutineParamOut
 		}
-	case 578:
+	case 684:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:4773
+//line sql-gen.y:5430
 		{
-			return unimplementedWithIssueDetail(sqllex, 100405, "create function with 'INOUT' argument class")
+			sqlVAL.union.val = tree.RoutineParamInOut
 		}
-	case 579:
+	case 685:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:4774
+//line sql-gen.y:5431
 		{
-			return unimplementedWithIssueDetail(sqllex, 100405, "create function with 'IN OUT' argument class")
+			sqlVAL.union.val = tree.RoutineParamInOut
 		}
-	case 580:
+	case 686:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:4775
+//line sql-gen.y:5432
 		{
 			return unimplementedWithIssueDetail(sqllex, 88947, "variadic user-defined functions")
 		}
-	case 583:
+	case 689:
+		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
+//line sql-gen.y:5441
+		{
+			sqlVAL.union.val = tree.RoutineParam{
+				Name:  tree.Name(sqlDollar[1].str),
+				Type:  sqlDollar[2].union.typeReference(),
+				Class: tree.RoutineParamOut,
+			}
+		}
+	case 690:
+		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
+//line sql-gen.y:5451
+		{
+			sqlVAL.union.val = tree.RoutineParams{sqlDollar[1].union.routineParam()}
+		}
+	case 691:
+		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
+//line sql-gen.y:5455
+		{
+			sqlVAL.union.val = append(sqlDollar[1].union.routineParams(), sqlDollar[3].union.routineParam())
+		}
+	case 692:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:4784
+//line sql-gen.y:5460
 		{
 			sqlVAL.union.val = sqlDollar[1].union.routineOptions()
 		}
-	case 584:
+	case 693:
 		sqlDollar = sqlS[sqlpt-0 : sqlpt+1]
-//line sql-gen.y:4785
+//line sql-gen.y:5461
 		{
 			sqlVAL.union.val = tree.RoutineOptions{}
 		}
-	case 585:
+	case 694:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:4788
+//line sql-gen.y:5464
 		{
 			sqlVAL.union.val = tree.RoutineOptions{sqlDollar[1].union.functionOption()}
 		}
-	case 586:
+	case 695:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:4790
+//line sql-gen.y:5466
 		{
 			sqlVAL.union.val = append(sqlDollar[1].union.routineOptions(), sqlDollar[2].union.functionOption())
 		}
-	case 587:
+	case 696:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:4796
+//line sql-gen.y:5472
 		{
 			sqlVAL.union.val = tree.RoutineBodyStr(sqlDollar[2].str)
 		}
-	case 588:
+	case 697:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:4800
+//line sql-gen.y:5476
 		{
 			lang, err := tree.AsRoutineLanguage(sqlDollar[2].str)
 			if err != nil {
@@ -32589,190 +35793,234 @@ sqldefault:
 			}
 			sqlVAL.union.val = lang
 		}
-	case 589:
+	case 698:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:4807
+//line sql-gen.y:5483
 		{
 			return unimplemented(sqllex, "create transform function")
 		}
-	case 590:
+	case 699:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:4808
+//line sql-gen.y:5484
 		{
 			return unimplemented(sqllex, "create window function")
 		}
-	case 591:
+	case 700:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:4810
+//line sql-gen.y:5486
 		{
 			sqlVAL.union.val = sqlDollar[1].union.functionOption()
 		}
-	case 592:
+	case 701:
 		sqlDollar = sqlS[sqlpt-4 : sqlpt+1]
-//line sql-gen.y:4816
+//line sql-gen.y:5492
 		{
 			sqlVAL.union.val = tree.RoutineCalledOnNullInput
 		}
-	case 593:
+	case 702:
 		sqlDollar = sqlS[sqlpt-5 : sqlpt+1]
-//line sql-gen.y:4820
+//line sql-gen.y:5496
 		{
 			sqlVAL.union.val = tree.RoutineReturnsNullOnNullInput
 		}
-	case 594:
+	case 703:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:4824
+//line sql-gen.y:5500
 		{
 			sqlVAL.union.val = tree.RoutineStrict
 		}
-	case 595:
+	case 704:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:4828
+//line sql-gen.y:5504
 		{
 			sqlVAL.union.val = tree.RoutineImmutable
 		}
-	case 596:
+	case 705:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:4832
+//line sql-gen.y:5508
 		{
 			sqlVAL.union.val = tree.RoutineStable
 		}
-	case 597:
+	case 706:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:4836
+//line sql-gen.y:5512
 		{
 			sqlVAL.union.val = tree.RoutineVolatile
 		}
-	case 598:
+	case 707:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:4840
+//line sql-gen.y:5516
 		{
-			return unimplemented(sqllex, "create function...security")
+			sqlVAL.union.val = tree.RoutineDefiner
 		}
-	case 599:
+	case 708:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:4844
+//line sql-gen.y:5520
 		{
-			return unimplemented(sqllex, "create function...security")
+			sqlVAL.union.val = tree.RoutineInvoker
 		}
-	case 600:
+	case 709:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:4848
+//line sql-gen.y:5524
 		{
-			return unimplemented(sqllex, "create function...security")
+			sqlVAL.union.val = tree.RoutineDefiner
 		}
-	case 601:
+	case 710:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:4852
+//line sql-gen.y:5528
 		{
-			return unimplemented(sqllex, "create function...security")
+			sqlVAL.union.val = tree.RoutineInvoker
 		}
-	case 602:
+	case 711:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:4856
+//line sql-gen.y:5532
 		{
 			sqlVAL.union.val = tree.RoutineLeakproof(true)
 		}
-	case 603:
+	case 712:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:4860
+//line sql-gen.y:5536
 		{
 			sqlVAL.union.val = tree.RoutineLeakproof(false)
 		}
-	case 604:
+	case 713:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:4864
+//line sql-gen.y:5540
 		{
 			return unimplemented(sqllex, "create function/procedure ... cost")
 		}
-	case 605:
+	case 714:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:4868
+//line sql-gen.y:5544
 		{
 			return unimplemented(sqllex, "create function/procedure ... rows")
 		}
-	case 606:
+	case 715:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:4872
+//line sql-gen.y:5548
 		{
 			return unimplemented(sqllex, "create function/procedure ... support")
 		}
-	case 607:
+	case 716:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:4879
+//line sql-gen.y:5555
 		{
 			return unimplemented(sqllex, "create function/procedure ... set")
 		}
-	case 608:
+	case 717:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:4880
+//line sql-gen.y:5556
 		{
 			return unimplemented(sqllex, "create function/procedure ... parallel")
 		}
-	case 610:
+	case 719:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:4887
+//line sql-gen.y:5563
 		{
 			sqlVAL.union.val = &tree.RoutineReturn{
 				ReturnVal: sqlDollar[2].union.expr(),
 			}
 		}
-	case 613:
+	case 722:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:4899
+//line sql-gen.y:5575
 		{
 			sqlVAL.union.val = append(sqlDollar[1].union.stmts(), sqlDollar[2].union.stmt())
 		}
-	case 614:
+	case 723:
 		sqlDollar = sqlS[sqlpt-0 : sqlpt+1]
-//line sql-gen.y:4903
+//line sql-gen.y:5579
 		{
 			sqlVAL.union.val = tree.Statements{}
 		}
-	case 615:
+	case 724:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:4909
+//line sql-gen.y:5585
 		{
 			sqlVAL.union.val = &tree.RoutineBody{
 				Stmts: tree.Statements{sqlDollar[1].union.stmt()},
 			}
 		}
-	case 616:
+	case 725:
 		sqlDollar = sqlS[sqlpt-4 : sqlpt+1]
-//line sql-gen.y:4915
+//line sql-gen.y:5591
 		{
 			sqlVAL.union.val = &tree.RoutineBody{
 				Stmts: sqlDollar[3].union.stmts(),
 			}
 		}
-	case 617:
+	case 726:
 		sqlDollar = sqlS[sqlpt-0 : sqlpt+1]
-//line sql-gen.y:4921
+//line sql-gen.y:5597
 		{
 			sqlVAL.union.val = (*tree.RoutineBody)(nil)
 		}
-	case 618:
+	case 727:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:4927
+//line sql-gen.y:5603
 		{
 		}
-	case 619:
+	case 728:
 		sqlDollar = sqlS[sqlpt-0 : sqlpt+1]
-//line sql-gen.y:4930
+//line sql-gen.y:5606
+		{
+		}
+	case 729:
+		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
+//line sql-gen.y:5615
+		{
+			doBlockBody, err := ParseDoBlockFn(sqlDollar[2].union.doBlockOptions())
+			if err != nil {
+				return setErrNoDetails(sqllex, err)
+			}
+			sqlVAL.union.val = &tree.DoBlock{Code: doBlockBody}
+		}
+	case 730:
+		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
+//line sql-gen.y:5622
+		{
+			return helpWith(sqllex, "DO")
+		}
+	case 731:
+		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
+//line sql-gen.y:5626
+		{
+			sqlVAL.union.val = tree.DoBlockOptions{sqlDollar[1].union.doBlockOption()}
+		}
+	case 732:
+		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
+//line sql-gen.y:5630
+		{
+			sqlVAL.union.val = append(sqlDollar[1].union.doBlockOptions(), sqlDollar[2].union.doBlockOption())
+		}
+	case 733:
+		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
+//line sql-gen.y:5636
+		{
+			sqlVAL.union.val = tree.RoutineBodyStr(sqlDollar[1].str)
+		}
+	case 734:
+		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
+//line sql-gen.y:5640
 		{
+			lang, err := tree.AsRoutineLanguage(sqlDollar[2].str)
+			if err != nil {
+				return setErr(sqllex, err)
+			}
+			sqlVAL.union.val = lang
 		}
-	case 620:
+	case 735:
 		sqlDollar = sqlS[sqlpt-4 : sqlpt+1]
-//line sql-gen.y:4941
+//line sql-gen.y:5656
 		{
 			sqlVAL.union.val = &tree.DropRoutine{
 				Routines:     sqlDollar[3].union.routineObjs(),
 				DropBehavior: sqlDollar[4].union.dropBehavior(),
 			}
 		}
-	case 621:
+	case 736:
 		sqlDollar = sqlS[sqlpt-6 : sqlpt+1]
-//line sql-gen.y:4948
+//line sql-gen.y:5663
 		{
 			sqlVAL.union.val = &tree.DropRoutine{
 				IfExists:     true,
@@ -32780,15 +36028,15 @@ sqldefault:
 				DropBehavior: sqlDollar[6].union.dropBehavior(),
 			}
 		}
-	case 622:
+	case 737:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:4955
+//line sql-gen.y:5670
 		{
 			return helpWith(sqllex, "DROP FUNCTION")
 		}
-	case 623:
+	case 738:
 		sqlDollar = sqlS[sqlpt-4 : sqlpt+1]
-//line sql-gen.y:4965
+//line sql-gen.y:5680
 		{
 			sqlVAL.union.val = &tree.DropRoutine{
 				Procedure:    true,
@@ -32796,9 +36044,9 @@ sqldefault:
 				DropBehavior: sqlDollar[4].union.dropBehavior(),
 			}
 		}
-	case 624:
+	case 739:
 		sqlDollar = sqlS[sqlpt-6 : sqlpt+1]
-//line sql-gen.y:4973
+//line sql-gen.y:5688
 		{
 			sqlVAL.union.val = &tree.DropRoutine{
 				IfExists:     true,
@@ -32807,474 +36055,761 @@ sqldefault:
 				DropBehavior: sqlDollar[6].union.dropBehavior(),
 			}
 		}
-	case 625:
+	case 740:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:4981
+//line sql-gen.y:5696
 		{
 			return helpWith(sqllex, "DROP PROCEDURE")
 		}
-	case 626:
+	case 741:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:4985
+//line sql-gen.y:5700
 		{
 			sqlVAL.union.val = tree.RoutineObjs{sqlDollar[1].union.functionObj()}
 		}
-	case 627:
+	case 742:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:4989
+//line sql-gen.y:5704
 		{
 			sqlVAL.union.val = append(sqlDollar[1].union.routineObjs(), sqlDollar[3].union.functionObj())
 		}
-	case 628:
+	case 743:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:4995
+//line sql-gen.y:5710
 		{
 			sqlVAL.union.val = tree.RoutineObj{
 				FuncName: sqlDollar[1].union.unresolvedObjectName().ToRoutineName(),
 				Params:   sqlDollar[2].union.routineParams(),
 			}
 		}
-	case 629:
+	case 744:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:5002
+//line sql-gen.y:5717
 		{
 			sqlVAL.union.val = tree.RoutineObj{
 				FuncName: sqlDollar[1].union.unresolvedObjectName().ToRoutineName(),
 			}
 		}
-	case 630:
+	case 745:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:5010
+//line sql-gen.y:5725
 		{
 			sqlVAL.union.val = sqlDollar[2].union.routineParams()
 		}
-	case 631:
+	case 746:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:5014
+//line sql-gen.y:5729
 		{
 			sqlVAL.union.val = tree.RoutineParams{}
 		}
-	case 632:
+	case 747:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:5020
+//line sql-gen.y:5735
 		{
 			sqlVAL.union.val = tree.RoutineParams{sqlDollar[1].union.routineParam()}
 		}
-	case 633:
+	case 748:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:5024
+//line sql-gen.y:5739
 		{
 			sqlVAL.union.val = append(sqlDollar[1].union.routineParams(), sqlDollar[3].union.routineParam())
 		}
-	case 634:
+	case 749:
 		sqlDollar = sqlS[sqlpt-5 : sqlpt+1]
-//line sql-gen.y:5030
+//line sql-gen.y:5745
 		{
 			sqlVAL.union.val = &tree.AlterFunctionOptions{
 				Function: sqlDollar[3].union.functionObj(),
 				Options:  sqlDollar[4].union.routineOptions(),
 			}
 		}
-	case 635:
+	case 750:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:5039
+//line sql-gen.y:5754
 		{
 			sqlVAL.union.val = tree.RoutineOptions{sqlDollar[1].union.functionOption()}
 		}
-	case 636:
+	case 751:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:5043
+//line sql-gen.y:5758
 		{
 			sqlVAL.union.val = append(sqlDollar[1].union.routineOptions(), sqlDollar[2].union.functionOption())
 		}
-	case 637:
+	case 752:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:5048
+//line sql-gen.y:5763
 		{
 		}
-	case 638:
+	case 753:
 		sqlDollar = sqlS[sqlpt-0 : sqlpt+1]
-//line sql-gen.y:5049
+//line sql-gen.y:5764
 		{
 		}
-	case 639:
+	case 754:
 		sqlDollar = sqlS[sqlpt-6 : sqlpt+1]
-//line sql-gen.y:5053
+//line sql-gen.y:5768
 		{
 			sqlVAL.union.val = &tree.AlterRoutineRename{
 				Function: sqlDollar[3].union.functionObj(),
 				NewName:  tree.Name(sqlDollar[6].str),
 			}
 		}
-	case 640:
+	case 755:
+		sqlDollar = sqlS[sqlpt-6 : sqlpt+1]
+//line sql-gen.y:5777
+		{
+			sqlVAL.union.val = &tree.AlterRoutineSetSchema{
+				Function:      sqlDollar[3].union.functionObj(),
+				NewSchemaName: tree.Name(sqlDollar[6].str),
+			}
+		}
+	case 756:
+		sqlDollar = sqlS[sqlpt-6 : sqlpt+1]
+//line sql-gen.y:5786
+		{
+			sqlVAL.union.val = &tree.AlterRoutineSetOwner{
+				Function: sqlDollar[3].union.functionObj(),
+				NewOwner: sqlDollar[6].union.roleSpec(),
+			}
+		}
+	case 757:
+		sqlDollar = sqlS[sqlpt-8 : sqlpt+1]
+//line sql-gen.y:5795
+		{
+			sqlVAL.union.val = &tree.AlterFunctionDepExtension{
+				Function:  sqlDollar[3].union.functionObj(),
+				Remove:    sqlDollar[4].union.bool(),
+				Extension: tree.Name(sqlDollar[8].str),
+			}
+		}
+	case 758:
+		sqlDollar = sqlS[sqlpt-6 : sqlpt+1]
+//line sql-gen.y:5805
+		{
+			sqlVAL.union.val = &tree.AlterRoutineRename{
+				Function:  sqlDollar[3].union.functionObj(),
+				NewName:   tree.Name(sqlDollar[6].str),
+				Procedure: true,
+			}
+		}
+	case 759:
 		sqlDollar = sqlS[sqlpt-6 : sqlpt+1]
-//line sql-gen.y:5062
+//line sql-gen.y:5815
 		{
 			sqlVAL.union.val = &tree.AlterRoutineSetSchema{
 				Function:      sqlDollar[3].union.functionObj(),
 				NewSchemaName: tree.Name(sqlDollar[6].str),
+				Procedure:     true,
+			}
+		}
+	case 760:
+		sqlDollar = sqlS[sqlpt-6 : sqlpt+1]
+//line sql-gen.y:5825
+		{
+			sqlVAL.union.val = &tree.AlterRoutineSetOwner{
+				Function:  sqlDollar[3].union.functionObj(),
+				NewOwner:  sqlDollar[6].union.roleSpec(),
+				Procedure: true,
+			}
+		}
+	case 761:
+		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
+//line sql-gen.y:5835
+		{
+			sqlVAL.union.val = true
+		}
+	case 762:
+		sqlDollar = sqlS[sqlpt-0 : sqlpt+1]
+//line sql-gen.y:5839
+		{
+			sqlVAL.union.val = false
+		}
+	case 763:
+		sqlDollar = sqlS[sqlpt-17 : sqlpt+1]
+//line sql-gen.y:5856
+		{
+			sqlVAL.union.val = &tree.CreateTrigger{
+				Replace:     sqlDollar[2].union.bool(),
+				Name:        tree.Name(sqlDollar[4].str),
+				ActionTime:  sqlDollar[5].union.triggerActionTime(),
+				Events:      sqlDollar[6].union.triggerEvents(),
+				TableName:   sqlDollar[8].union.unresolvedObjectName(),
+				Transitions: sqlDollar[9].union.triggerTransitions(),
+				ForEach:     sqlDollar[10].union.triggerForEach(),
+				When:        sqlDollar[11].union.expr(),
+				FuncName:    sqlDollar[14].union.unresolvedName(),
+				FuncArgs:    sqlDollar[16].union.strs(),
+			}
+		}
+	case 764:
+		sqlDollar = sqlS[sqlpt-4 : sqlpt+1]
+//line sql-gen.y:5870
+		{
+			return helpWith(sqllex, "CREATE TRIGGER")
+		}
+	case 765:
+		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
+//line sql-gen.y:5873
+		{
+			sqlVAL.union.val = tree.TriggerActionTimeBefore
+		}
+	case 766:
+		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
+//line sql-gen.y:5874
+		{
+			sqlVAL.union.val = tree.TriggerActionTimeAfter
+		}
+	case 767:
+		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
+//line sql-gen.y:5875
+		{
+			sqlVAL.union.val = tree.TriggerActionTimeInsteadOf
+		}
+	case 768:
+		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
+//line sql-gen.y:5879
+		{
+			sqlVAL.union.val = []*tree.TriggerEvent{sqlDollar[1].union.triggerEvent()}
+		}
+	case 769:
+		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
+//line sql-gen.y:5883
+		{
+			events := append(sqlDollar[1].union.triggerEvents(), sqlDollar[3].union.triggerEvent())
+
+			var seenEvents tree.TriggerEventTypeSet
+			for i := range events {
+				if seenEvents.Contains(events[i].EventType) {
+					return setErr(sqllex, errors.New("duplicate trigger events specified"))
+				}
+				seenEvents.Add(events[i].EventType)
+			}
+			sqlVAL.union.val = events
+		}
+	case 770:
+		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
+//line sql-gen.y:5899
+		{
+			sqlVAL.union.val = &tree.TriggerEvent{EventType: tree.TriggerEventInsert}
+		}
+	case 771:
+		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
+//line sql-gen.y:5903
+		{
+			sqlVAL.union.val = &tree.TriggerEvent{EventType: tree.TriggerEventDelete}
+		}
+	case 772:
+		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
+//line sql-gen.y:5907
+		{
+			sqlVAL.union.val = &tree.TriggerEvent{EventType: tree.TriggerEventUpdate}
+		}
+	case 773:
+		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
+//line sql-gen.y:5911
+		{
+			sqlVAL.union.val = &tree.TriggerEvent{EventType: tree.TriggerEventUpdate, Columns: sqlDollar[3].union.nameList()}
+		}
+	case 774:
+		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
+//line sql-gen.y:5915
+		{
+			sqlVAL.union.val = &tree.TriggerEvent{EventType: tree.TriggerEventTruncate}
+		}
+	case 775:
+		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
+//line sql-gen.y:5921
+		{
+			sqlVAL.union.val = sqlDollar[2].union.triggerTransitions()
+		}
+	case 776:
+		sqlDollar = sqlS[sqlpt-0 : sqlpt+1]
+//line sql-gen.y:5925
+		{
+			sqlVAL.union.val = []*tree.TriggerTransition{}
+		}
+	case 777:
+		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
+//line sql-gen.y:5931
+		{
+			sqlVAL.union.val = []*tree.TriggerTransition{sqlDollar[1].union.triggerTransition()}
+		}
+	case 778:
+		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
+//line sql-gen.y:5935
+		{
+			sqlVAL.union.val = append(sqlDollar[1].union.triggerTransitions(), sqlDollar[2].union.triggerTransition())
+		}
+	case 779:
+		sqlDollar = sqlS[sqlpt-4 : sqlpt+1]
+//line sql-gen.y:5941
+		{
+			sqlVAL.union.val = &tree.TriggerTransition{
+				Name:  tree.Name(sqlDollar[4].str),
+				IsNew: sqlDollar[1].union.bool(),
+				IsRow: sqlDollar[2].union.bool(),
 			}
 		}
-	case 641:
-		sqlDollar = sqlS[sqlpt-6 : sqlpt+1]
-//line sql-gen.y:5071
+	case 780:
+		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
+//line sql-gen.y:5950
+		{
+		}
+	case 781:
+		sqlDollar = sqlS[sqlpt-0 : sqlpt+1]
+//line sql-gen.y:5951
+		{
+		}
+	case 782:
+		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
+//line sql-gen.y:5954
+		{
+			sqlVAL.union.val = true
+		}
+	case 783:
+		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
+//line sql-gen.y:5955
+		{
+			sqlVAL.union.val = false
+		}
+	case 784:
+		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
+//line sql-gen.y:5958
+		{
+			sqlVAL.union.val = true
+		}
+	case 785:
+		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
+//line sql-gen.y:5959
+		{
+			sqlVAL.union.val = false
+		}
+	case 786:
+		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
+//line sql-gen.y:5963
+		{
+			sqlVAL.union.val = sqlDollar[3].union.triggerForEach()
+		}
+	case 787:
+		sqlDollar = sqlS[sqlpt-0 : sqlpt+1]
+//line sql-gen.y:5967
+		{
+
+			sqlVAL.union.val = tree.TriggerForEachStatement
+		}
+	case 788:
+		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
+//line sql-gen.y:5973
+		{
+		}
+	case 789:
+		sqlDollar = sqlS[sqlpt-0 : sqlpt+1]
+//line sql-gen.y:5974
+		{
+		}
+	case 790:
+		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
+//line sql-gen.y:5977
+		{
+			sqlVAL.union.val = tree.TriggerForEachRow
+		}
+	case 791:
+		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
+//line sql-gen.y:5978
+		{
+			sqlVAL.union.val = tree.TriggerForEachStatement
+		}
+	case 792:
+		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
+//line sql-gen.y:5982
+		{
+			sqlVAL.union.val = sqlDollar[2].union.expr()
+		}
+	case 793:
+		sqlDollar = sqlS[sqlpt-0 : sqlpt+1]
+//line sql-gen.y:5986
+		{
+			sqlVAL.union.val = nil
+		}
+	case 794:
+		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
+//line sql-gen.y:5991
+		{
+		}
+	case 795:
+		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
+//line sql-gen.y:5992
+		{
+		}
+	case 796:
+		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
+//line sql-gen.y:5996
+		{
+			sqlVAL.union.val = []string{sqlDollar[1].str}
+		}
+	case 797:
+		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
+//line sql-gen.y:6000
+		{
+			sqlVAL.union.val = append(sqlDollar[1].union.strs(), sqlDollar[3].str)
+		}
+	case 798:
+		sqlDollar = sqlS[sqlpt-0 : sqlpt+1]
+//line sql-gen.y:6004
+		{
+			sqlVAL.union.val = []string{}
+		}
+	case 799:
+		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
+//line sql-gen.y:6010
 		{
-			sqlVAL.union.val = &tree.AlterRoutineSetOwner{
-				Function: sqlDollar[3].union.functionObj(),
-				NewOwner: sqlDollar[6].union.roleSpec(),
-			}
+
+			sqlVAL.str = sqlDollar[1].union.numVal().OrigString()
 		}
-	case 642:
-		sqlDollar = sqlS[sqlpt-8 : sqlpt+1]
-//line sql-gen.y:5080
+	case 800:
+		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
+//line sql-gen.y:6018
 		{
-			sqlVAL.union.val = &tree.AlterFunctionDepExtension{
-				Function:  sqlDollar[3].union.functionObj(),
-				Remove:    sqlDollar[4].union.bool(),
-				Extension: tree.Name(sqlDollar[8].str),
-			}
+			sqlVAL.str = sqlDollar[1].union.numVal().OrigString()
 		}
-	case 643:
-		sqlDollar = sqlS[sqlpt-6 : sqlpt+1]
-//line sql-gen.y:5090
+	case 801:
+		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
+//line sql-gen.y:6022
 		{
-			sqlVAL.union.val = &tree.AlterRoutineRename{
-				Function:  sqlDollar[3].union.functionObj(),
-				NewName:   tree.Name(sqlDollar[6].str),
-				Procedure: true,
-			}
+			sqlVAL.str = sqlDollar[1].str
 		}
-	case 644:
-		sqlDollar = sqlS[sqlpt-6 : sqlpt+1]
-//line sql-gen.y:5100
+	case 802:
+		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
+//line sql-gen.y:6026
 		{
-			sqlVAL.union.val = &tree.AlterRoutineSetSchema{
-				Function:      sqlDollar[3].union.functionObj(),
-				NewSchemaName: tree.Name(sqlDollar[6].str),
-				Procedure:     true,
-			}
+			sqlVAL.str = sqlDollar[1].str
 		}
-	case 645:
+	case 803:
 		sqlDollar = sqlS[sqlpt-6 : sqlpt+1]
-//line sql-gen.y:5110
+//line sql-gen.y:6036
 		{
-			sqlVAL.union.val = &tree.AlterRoutineSetOwner{
-				Function:  sqlDollar[3].union.functionObj(),
-				NewOwner:  sqlDollar[6].union.roleSpec(),
-				Procedure: true,
+			sqlVAL.union.val = &tree.DropTrigger{
+				Trigger:      tree.Name(sqlDollar[3].str),
+				Table:        sqlDollar[5].union.unresolvedObjectName(),
+				DropBehavior: sqlDollar[6].union.dropBehavior(),
 			}
 		}
-	case 646:
-		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:5120
+	case 804:
+		sqlDollar = sqlS[sqlpt-8 : sqlpt+1]
+//line sql-gen.y:6044
 		{
-			sqlVAL.union.val = true
+			sqlVAL.union.val = &tree.DropTrigger{
+				IfExists:     true,
+				Trigger:      tree.Name(sqlDollar[5].str),
+				Table:        sqlDollar[7].union.unresolvedObjectName(),
+				DropBehavior: sqlDollar[8].union.dropBehavior(),
+			}
 		}
-	case 647:
-		sqlDollar = sqlS[sqlpt-0 : sqlpt+1]
-//line sql-gen.y:5124
+	case 805:
+		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
+//line sql-gen.y:6052
 		{
-			sqlVAL.union.val = false
+			return helpWith(sqllex, "DROP TRIGGER")
 		}
-	case 648:
+	case 806:
 		sqlDollar = sqlS[sqlpt-4 : sqlpt+1]
-//line sql-gen.y:5129
+//line sql-gen.y:6055
 		{
 			return unimplemented(sqllex, "create access method")
 		}
-	case 649:
+	case 807:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:5130
+//line sql-gen.y:6056
 		{
 			return unimplementedWithIssueDetail(sqllex, 74775, "create aggregate")
 		}
-	case 650:
+	case 808:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:5131
+//line sql-gen.y:6057
 		{
 			return unimplemented(sqllex, "create cast")
 		}
-	case 651:
+	case 809:
 		sqlDollar = sqlS[sqlpt-4 : sqlpt+1]
-//line sql-gen.y:5132
+//line sql-gen.y:6058
 		{
 			return unimplementedWithIssueDetail(sqllex, 28296, "create constraint")
 		}
-	case 652:
+	case 810:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:5133
+//line sql-gen.y:6059
 		{
 			return unimplemented(sqllex, "create conversion")
 		}
-	case 653:
+	case 811:
 		sqlDollar = sqlS[sqlpt-4 : sqlpt+1]
-//line sql-gen.y:5134
+//line sql-gen.y:6060
 		{
 			return unimplemented(sqllex, "create def conv")
 		}
-	case 654:
+	case 812:
 		sqlDollar = sqlS[sqlpt-4 : sqlpt+1]
-//line sql-gen.y:5135
+//line sql-gen.y:6061
 		{
 			return unimplemented(sqllex, "create foreign table")
 		}
-	case 655:
+	case 813:
 		sqlDollar = sqlS[sqlpt-4 : sqlpt+1]
-//line sql-gen.y:5136
+//line sql-gen.y:6062
 		{
 			return unimplemented(sqllex, "create fdw")
 		}
-	case 656:
+	case 814:
 		sqlDollar = sqlS[sqlpt-7 : sqlpt+1]
-//line sql-gen.y:5137
+//line sql-gen.y:6063
 		{
 			return unimplementedWithIssueDetail(sqllex, 17511, "create language "+sqlDollar[6].str)
 		}
-	case 657:
+	case 815:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:5138
+//line sql-gen.y:6064
 		{
 			return unimplementedWithIssue(sqllex, 65017)
 		}
-	case 658:
+	case 816:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:5139
+//line sql-gen.y:6065
 		{
 			return unimplemented(sqllex, "create publication")
 		}
-	case 659:
+	case 817:
 		sqlDollar = sqlS[sqlpt-4 : sqlpt+1]
-//line sql-gen.y:5140
+//line sql-gen.y:6066
 		{
 			return unimplemented(sqllex, "create rule")
 		}
-	case 660:
+	case 818:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:5141
+//line sql-gen.y:6067
 		{
 			return unimplemented(sqllex, "create server")
 		}
-	case 661:
+	case 819:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:5142
+//line sql-gen.y:6068
 		{
 			return unimplemented(sqllex, "create subscription")
 		}
-	case 662:
+	case 820:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:5143
+//line sql-gen.y:6069
 		{
 			return unimplementedWithIssueDetail(sqllex, 54113, "create tablespace")
 		}
-	case 663:
+	case 821:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:5144
+//line sql-gen.y:6070
 		{
 			return unimplementedWithIssueDetail(sqllex, 7821, "create text")
 		}
-	case 664:
-		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:5145
-		{
-			return unimplementedWithIssueDetail(sqllex, 28296, "create trigger")
-		}
-	case 665:
+	case 822:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:5148
+//line sql-gen.y:6073
 		{
 		}
-	case 666:
+	case 823:
 		sqlDollar = sqlS[sqlpt-0 : sqlpt+1]
-//line sql-gen.y:5149
+//line sql-gen.y:6074
 		{
 		}
-	case 667:
+	case 824:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:5152
+//line sql-gen.y:6077
 		{
 		}
-	case 668:
+	case 825:
 		sqlDollar = sqlS[sqlpt-0 : sqlpt+1]
-//line sql-gen.y:5153
+//line sql-gen.y:6078
 		{
 		}
-	case 669:
+	case 826:
 		sqlDollar = sqlS[sqlpt-4 : sqlpt+1]
-//line sql-gen.y:5156
+//line sql-gen.y:6081
 		{
 			return unimplemented(sqllex, "drop access method")
 		}
-	case 670:
+	case 827:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:5157
+//line sql-gen.y:6082
 		{
 			return unimplementedWithIssueDetail(sqllex, 74775, "drop aggregate")
 		}
-	case 671:
+	case 828:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:5158
+//line sql-gen.y:6083
 		{
 			return unimplemented(sqllex, "drop cast")
 		}
-	case 672:
+	case 829:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:5159
+//line sql-gen.y:6084
 		{
 			return unimplemented(sqllex, "drop collation")
 		}
-	case 673:
+	case 830:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:5160
+//line sql-gen.y:6085
 		{
 			return unimplemented(sqllex, "drop conversion")
 		}
-	case 674:
+	case 831:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:5161
+//line sql-gen.y:6086
 		{
 			return unimplementedWithIssueDetail(sqllex, 27796, "drop")
 		}
-	case 675:
+	case 832:
 		sqlDollar = sqlS[sqlpt-6 : sqlpt+1]
-//line sql-gen.y:5162
+//line sql-gen.y:6087
 		{
 			return unimplementedWithIssueDetail(sqllex, 74777, "drop extension if exists")
 		}
-	case 676:
+	case 833:
 		sqlDollar = sqlS[sqlpt-4 : sqlpt+1]
-//line sql-gen.y:5163
+//line sql-gen.y:6088
 		{
 			return unimplementedWithIssueDetail(sqllex, 74777, "drop extension")
 		}
-	case 677:
+	case 834:
 		sqlDollar = sqlS[sqlpt-4 : sqlpt+1]
-//line sql-gen.y:5164
+//line sql-gen.y:6089
 		{
 			return unimplemented(sqllex, "drop foreign table")
 		}
-	case 678:
+	case 835:
 		sqlDollar = sqlS[sqlpt-4 : sqlpt+1]
-//line sql-gen.y:5165
+//line sql-gen.y:6090
 		{
 			return unimplemented(sqllex, "drop fdw")
 		}
-	case 679:
+	case 836:
 		sqlDollar = sqlS[sqlpt-5 : sqlpt+1]
-//line sql-gen.y:5166
+//line sql-gen.y:6091
 		{
 			return unimplementedWithIssueDetail(sqllex, 17511, "drop language "+sqlDollar[4].str)
 		}
-	case 680:
+	case 837:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:5167
+//line sql-gen.y:6092
 		{
 			return unimplemented(sqllex, "drop operator")
 		}
-	case 681:
+	case 838:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:5168
+//line sql-gen.y:6093
 		{
 			return unimplemented(sqllex, "drop publication")
 		}
-	case 682:
+	case 839:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:5169
+//line sql-gen.y:6094
 		{
 			return unimplemented(sqllex, "drop rule")
 		}
-	case 683:
+	case 840:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:5170
+//line sql-gen.y:6095
 		{
 			return unimplemented(sqllex, "drop server")
 		}
-	case 684:
+	case 841:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:5171
+//line sql-gen.y:6096
 		{
 			return unimplemented(sqllex, "drop subscription")
 		}
-	case 685:
+	case 842:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:5172
+//line sql-gen.y:6097
 		{
 			return unimplementedWithIssueDetail(sqllex, 7821, "drop text")
 		}
-	case 686:
-		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:5173
-		{
-			return unimplementedWithIssueDetail(sqllex, 28296, "drop")
-		}
-	case 688:
+	case 844:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:5176
+//line sql-gen.y:6100
 		{
 			return helpWith(sqllex, "CREATE DATABASE")
 		}
-	case 690:
+	case 846:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:5177
+//line sql-gen.y:6101
 		{
 			return helpWith(sqllex, "CREATE INDEX")
 		}
-	case 692:
+	case 848:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:5178
+//line sql-gen.y:6102
 		{
 			return helpWith(sqllex, "CREATE SCHEMA")
 		}
-	case 694:
+	case 850:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:5179
+//line sql-gen.y:6103
 		{
 			return helpWith(sqllex, "CREATE TABLE")
 		}
-	case 696:
+	case 852:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:5180
+//line sql-gen.y:6104
 		{
 			return helpWith(sqllex, "CREATE TABLE")
 		}
-	case 697:
+	case 853:
 		sqlDollar = sqlS[sqlpt-4 : sqlpt+1]
-//line sql-gen.y:5182
+//line sql-gen.y:6106
 		{
 			return helpWith(sqllex, "CREATE TABLE")
 		}
-	case 699:
+	case 855:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:5183
+//line sql-gen.y:6107
 		{
 			return helpWith(sqllex, "CREATE TYPE")
 		}
-	case 701:
+	case 857:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:5184
+//line sql-gen.y:6108
 		{
 			return helpWith(sqllex, "CREATE VIEW")
 		}
-	case 703:
+	case 859:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:5185
+//line sql-gen.y:6109
 		{
 			return helpWith(sqllex, "CREATE SEQUENCE")
 		}
-	case 705:
+	case 861:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:5186
+//line sql-gen.y:6110
 		{
 			return helpWith(sqllex, "CREATE FUNCTION")
 		}
-	case 707:
+	case 863:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:5187
+//line sql-gen.y:6111
 		{
 			return helpWith(sqllex, "CREATE PROCEDURE")
 		}
-	case 708:
+	case 865:
+		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
+//line sql-gen.y:6112
+		{
+			return helpWith(sqllex, "CREATE TRIGGER")
+		}
+	case 867:
+		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
+//line sql-gen.y:6113
+		{
+			return helpWith(sqllex, "CREATE POLICY")
+		}
+	case 868:
 		sqlDollar = sqlS[sqlpt-7 : sqlpt+1]
-//line sql-gen.y:5197
+//line sql-gen.y:6123
 		{
 			sqlVAL.union.val = &tree.CreateStats{
 				Name:        tree.Name(sqlDollar[3].str),
@@ -33283,66 +36818,66 @@ sqldefault:
 				Options:     *sqlDollar[7].union.createStatsOptions(),
 			}
 		}
-	case 709:
+	case 869:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:5205
+//line sql-gen.y:6131
 		{
 			return helpWith(sqllex, "CREATE STATISTICS")
 		}
-	case 710:
+	case 870:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:5209
+//line sql-gen.y:6135
 		{
 			sqlVAL.union.val = sqlDollar[2].union.nameList()
 		}
-	case 711:
+	case 871:
 		sqlDollar = sqlS[sqlpt-0 : sqlpt+1]
-//line sql-gen.y:5213
+//line sql-gen.y:6139
 		{
 			sqlVAL.union.val = tree.NameList(nil)
 		}
-	case 712:
+	case 872:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:5219
+//line sql-gen.y:6145
 		{
 			sqlVAL.union.val = sqlDollar[1].union.unresolvedObjectName()
 		}
-	case 713:
+	case 873:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:5223
+//line sql-gen.y:6149
 		{
 
 			sqlVAL.union.val = &tree.TableRef{
 				TableID: sqlDollar[2].union.int64(),
 			}
 		}
-	case 714:
+	case 874:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:5232
+//line sql-gen.y:6158
 		{
 			sqlVAL.union.val = sqlDollar[1].union.createStatsOptions()
 		}
-	case 715:
+	case 875:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:5236
+//line sql-gen.y:6162
 		{
 			sqlVAL.union.val = sqlDollar[3].union.createStatsOptions()
 		}
-	case 716:
+	case 876:
 		sqlDollar = sqlS[sqlpt-0 : sqlpt+1]
-//line sql-gen.y:5240
+//line sql-gen.y:6166
 		{
 			sqlVAL.union.val = &tree.CreateStatsOptions{}
 		}
-	case 717:
+	case 877:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:5246
+//line sql-gen.y:6172
 		{
 			sqlVAL.union.val = sqlDollar[1].union.createStatsOptions()
 		}
-	case 718:
+	case 878:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:5250
+//line sql-gen.y:6176
 		{
 			a := sqlDollar[1].union.createStatsOptions()
 			b := sqlDollar[2].union.createStatsOptions()
@@ -33351,9 +36886,9 @@ sqldefault:
 			}
 			sqlVAL.union.val = a
 		}
-	case 719:
+	case 879:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:5261
+//line sql-gen.y:6187
 		{
 
 			value, _ := constant.Float64Val(sqlDollar[2].union.numVal().AsConstantValue())
@@ -33365,33 +36900,33 @@ sqldefault:
 				Throttling: value,
 			}
 		}
-	case 720:
+	case 880:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:5273
+//line sql-gen.y:6199
 		{
 			sqlVAL.union.val = &tree.CreateStatsOptions{
 				AsOf: sqlDollar[1].union.asOfClause(),
 			}
 		}
-	case 721:
+	case 881:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:5279
+//line sql-gen.y:6205
 		{
 			sqlVAL.union.val = &tree.CreateStatsOptions{
 				UsingExtremes: true,
 			}
 		}
-	case 722:
+	case 882:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:5285
+//line sql-gen.y:6211
 		{
 			sqlVAL.union.val = &tree.CreateStatsOptions{
 				Where: tree.NewWhere(tree.AstWhere, sqlDollar[1].union.expr()),
 			}
 		}
-	case 723:
+	case 883:
 		sqlDollar = sqlS[sqlpt-6 : sqlpt+1]
-//line sql-gen.y:5300
+//line sql-gen.y:6226
 		{
 			sqlVAL.union.val = &tree.CreateChangefeed{
 				Targets: sqlDollar[4].union.changefeedTargets(),
@@ -33399,9 +36934,9 @@ sqldefault:
 				Options: sqlDollar[6].union.kvOptions(),
 			}
 		}
-	case 724:
+	case 884:
 		sqlDollar = sqlS[sqlpt-10 : sqlpt+1]
-//line sql-gen.y:5309
+//line sql-gen.y:6235
 		{
 			target, err := tree.ChangefeedTargetFromTableExpr(sqlDollar[9].union.tblExpr())
 			if err != nil {
@@ -33419,9 +36954,9 @@ sqldefault:
 				},
 			}
 		}
-	case 725:
+	case 885:
 		sqlDollar = sqlS[sqlpt-5 : sqlpt+1]
-//line sql-gen.y:5327
+//line sql-gen.y:6253
 		{
 
 			sqlVAL.union.val = &tree.CreateChangefeed{
@@ -33429,9 +36964,9 @@ sqldefault:
 				Options: sqlDollar[5].union.kvOptions(),
 			}
 		}
-	case 726:
+	case 886:
 		sqlDollar = sqlS[sqlpt-10 : sqlpt+1]
-//line sql-gen.y:5364
+//line sql-gen.y:6290
 		{
 			sqlVAL.union.val = &tree.ScheduledChangefeed{
 				CreateChangefeed: &tree.CreateChangefeed{
@@ -33444,9 +36979,9 @@ sqldefault:
 				ScheduleOptions:   sqlDollar[10].union.kvOptions(),
 			}
 		}
-	case 727:
+	case 887:
 		sqlDollar = sqlS[sqlpt-15 : sqlpt+1]
-//line sql-gen.y:5379
+//line sql-gen.y:6305
 		{
 			target, err := tree.ChangefeedTargetFromTableExpr(sqlDollar[12].union.tblExpr())
 			if err != nil {
@@ -33471,77 +37006,77 @@ sqldefault:
 				ScheduleOptions:   sqlDollar[15].union.kvOptions(),
 			}
 		}
-	case 728:
+	case 888:
 		sqlDollar = sqlS[sqlpt-6 : sqlpt+1]
-//line sql-gen.y:5403
+//line sql-gen.y:6329
 		{
 			return helpWith(sqllex, "CREATE SCHEDULE FOR CHANGEFEED")
 		}
-	case 729:
+	case 889:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:5407
+//line sql-gen.y:6333
 		{
 			sqlVAL.union.val = tree.ChangefeedTargets{sqlDollar[1].union.changefeedTarget()}
 		}
-	case 730:
+	case 890:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:5411
+//line sql-gen.y:6337
 		{
 			sqlVAL.union.val = append(sqlDollar[1].union.changefeedTargets(), sqlDollar[3].union.changefeedTarget())
 		}
-	case 731:
+	case 891:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:5417
+//line sql-gen.y:6343
 		{
 			sqlVAL.union.val = tree.ChangefeedTarget{
 				TableName:  sqlDollar[2].union.unresolvedObjectName().ToUnresolvedName(),
 				FamilyName: tree.Name(sqlDollar[3].str),
 			}
 		}
-	case 733:
+	case 893:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:5428
+//line sql-gen.y:6354
 		{
 		}
-	case 734:
+	case 894:
 		sqlDollar = sqlS[sqlpt-0 : sqlpt+1]
-//line sql-gen.y:5430
+//line sql-gen.y:6356
 		{
 		}
-	case 735:
+	case 895:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:5434
+//line sql-gen.y:6360
 		{
 			sqlVAL.str = sqlDollar[2].str
 		}
-	case 736:
+	case 896:
 		sqlDollar = sqlS[sqlpt-0 : sqlpt+1]
-//line sql-gen.y:5438
+//line sql-gen.y:6364
 		{
 			sqlVAL.str = ""
 		}
-	case 737:
+	case 897:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:5444
+//line sql-gen.y:6370
 		{
 			sqlVAL.union.val = sqlDollar[2].union.expr()
 		}
-	case 738:
+	case 898:
 		sqlDollar = sqlS[sqlpt-0 : sqlpt+1]
-//line sql-gen.y:5448
+//line sql-gen.y:6374
 		{
 
 			sqlVAL.union.val = nil
 		}
-	case 739:
+	case 899:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:5455
+//line sql-gen.y:6381
 		{
 			sqlVAL.union.val = sqlDollar[2].union.expr()
 		}
-	case 740:
+	case 900:
 		sqlDollar = sqlS[sqlpt-10 : sqlpt+1]
-//line sql-gen.y:5472
+//line sql-gen.y:6398
 		{
 			sqlVAL.union.val = &tree.Delete{
 				With:      sqlDollar[1].union.with(),
@@ -33554,200 +37089,212 @@ sqldefault:
 				Returning: sqlDollar[10].union.retClause(),
 			}
 		}
-	case 741:
+	case 901:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:5484
+//line sql-gen.y:6410
 		{
 			return helpWith(sqllex, "DELETE")
 		}
-	case 742:
+	case 902:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:5488
+//line sql-gen.y:6414
 		{
 			sqlVAL.union.val = &tree.Batch{}
 		}
-	case 743:
+	case 903:
 		sqlDollar = sqlS[sqlpt-4 : sqlpt+1]
-//line sql-gen.y:5492
+//line sql-gen.y:6418
 		{
 			sqlVAL.union.val = &tree.Batch{Params: sqlDollar[3].union.batchParams()}
 		}
-	case 744:
+	case 904:
 		sqlDollar = sqlS[sqlpt-0 : sqlpt+1]
-//line sql-gen.y:5496
+//line sql-gen.y:6422
 		{
 			sqlVAL.union.val = (*tree.Batch)(nil)
 		}
-	case 745:
+	case 905:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:5502
+//line sql-gen.y:6428
 		{
 			sqlVAL.union.val = []tree.BatchParam{sqlDollar[1].union.batchParam()}
 		}
-	case 746:
+	case 906:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:5506
+//line sql-gen.y:6432
 		{
 			sqlVAL.union.val = append(sqlDollar[1].union.batchParams(), sqlDollar[3].union.batchParam())
 		}
-	case 747:
+	case 907:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:5512
+//line sql-gen.y:6438
 		{
 			sqlVAL.union.val = &tree.SizeBatchParam{Size: sqlDollar[2].union.expr()}
 		}
-	case 748:
+	case 908:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:5518
+//line sql-gen.y:6444
 		{
 			sqlVAL.union.val = sqlDollar[2].union.tblExprs()
 		}
-	case 749:
+	case 909:
 		sqlDollar = sqlS[sqlpt-0 : sqlpt+1]
-//line sql-gen.y:5522
+//line sql-gen.y:6448
 		{
 			sqlVAL.union.val = tree.TableExprs{}
 		}
-	case 750:
+	case 910:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:5532
+//line sql-gen.y:6458
 		{
 			sqlVAL.union.val = &tree.Discard{Mode: tree.DiscardModeAll}
 		}
-	case 751:
+	case 911:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:5535
+//line sql-gen.y:6461
 		{
 			return unimplemented(sqllex, "discard plans")
 		}
-	case 752:
+	case 912:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:5537
+//line sql-gen.y:6463
 		{
 			sqlVAL.union.val = &tree.Discard{Mode: tree.DiscardModeSequences}
 		}
-	case 753:
+	case 913:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:5541
+//line sql-gen.y:6467
 		{
 			sqlVAL.union.val = &tree.Discard{Mode: tree.DiscardModeTemp}
 		}
-	case 754:
+	case 914:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:5545
+//line sql-gen.y:6471
 		{
 			sqlVAL.union.val = &tree.Discard{Mode: tree.DiscardModeTemp}
 		}
-	case 755:
+	case 915:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:5548
+//line sql-gen.y:6474
 		{
 			return helpWith(sqllex, "DISCARD")
 		}
-	case 758:
+	case 918:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:5557
+//line sql-gen.y:6483
 		{
 			return helpWith(sqllex, "DROP ROLE")
 		}
-	case 760:
+	case 920:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:5558
+//line sql-gen.y:6484
 		{
 			return helpWith(sqllex, "DROP SCHEDULES")
 		}
-	case 762:
+	case 922:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:5559
+//line sql-gen.y:6485
 		{
 			return helpWith(sqllex, "DROP EXTERNAL CONNECTION")
 		}
-	case 764:
+	case 924:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:5560
+//line sql-gen.y:6486
 		{
 			return helpWith(sqllex, "DROP VIRTUAL CLUSTER")
 		}
-	case 765:
+	case 925:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:5561
+//line sql-gen.y:6487
 		{
 		}
-	case 766:
+	case 926:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:5562
+//line sql-gen.y:6488
 		{
 			return helpWith(sqllex, "DROP")
 		}
-	case 768:
+	case 928:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:5565
+//line sql-gen.y:6491
 		{
 			return helpWith(sqllex, "DROP DATABASE")
 		}
-	case 770:
+	case 930:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:5566
+//line sql-gen.y:6492
 		{
 			return helpWith(sqllex, "DROP INDEX")
 		}
-	case 772:
+	case 932:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:5567
+//line sql-gen.y:6493
 		{
 			return helpWith(sqllex, "DROP TABLE")
 		}
-	case 774:
+	case 934:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:5568
+//line sql-gen.y:6494
 		{
 			return helpWith(sqllex, "DROP VIEW")
 		}
-	case 776:
+	case 936:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:5569
+//line sql-gen.y:6495
 		{
 			return helpWith(sqllex, "DROP SEQUENCE")
 		}
-	case 778:
+	case 938:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:5570
+//line sql-gen.y:6496
 		{
 			return helpWith(sqllex, "DROP SCHEMA")
 		}
-	case 780:
+	case 940:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:5571
+//line sql-gen.y:6497
 		{
 			return helpWith(sqllex, "DROP TYPE")
 		}
-	case 782:
+	case 942:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:5572
+//line sql-gen.y:6498
 		{
 			return helpWith(sqllex, "DROP FUNCTION")
 		}
-	case 784:
+	case 944:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:5573
+//line sql-gen.y:6499
 		{
 			return helpWith(sqllex, "DROP FUNCTION")
 		}
-	case 785:
+	case 946:
+		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
+//line sql-gen.y:6500
+		{
+			return helpWith(sqllex, "DROP TRIGGER")
+		}
+	case 948:
+		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
+//line sql-gen.y:6501
+		{
+			return helpWith(sqllex, "DROP POLICY")
+		}
+	case 949:
 		sqlDollar = sqlS[sqlpt-4 : sqlpt+1]
-//line sql-gen.y:5581
+//line sql-gen.y:6509
 		{
 			sqlVAL.union.val = &tree.DropView{Names: sqlDollar[3].union.tableNames(), IfExists: false, DropBehavior: sqlDollar[4].union.dropBehavior()}
 		}
-	case 786:
+	case 950:
 		sqlDollar = sqlS[sqlpt-6 : sqlpt+1]
-//line sql-gen.y:5585
+//line sql-gen.y:6513
 		{
 			sqlVAL.union.val = &tree.DropView{Names: sqlDollar[5].union.tableNames(), IfExists: true, DropBehavior: sqlDollar[6].union.dropBehavior()}
 		}
-	case 787:
+	case 951:
 		sqlDollar = sqlS[sqlpt-5 : sqlpt+1]
-//line sql-gen.y:5589
+//line sql-gen.y:6517
 		{
 			sqlVAL.union.val = &tree.DropView{
 				Names:          sqlDollar[4].union.tableNames(),
@@ -33756,9 +37303,9 @@ sqldefault:
 				IsMaterialized: true,
 			}
 		}
-	case 788:
+	case 952:
 		sqlDollar = sqlS[sqlpt-7 : sqlpt+1]
-//line sql-gen.y:5598
+//line sql-gen.y:6526
 		{
 			sqlVAL.union.val = &tree.DropView{
 				Names:          sqlDollar[6].union.tableNames(),
@@ -33767,51 +37314,51 @@ sqldefault:
 				IsMaterialized: true,
 			}
 		}
-	case 789:
+	case 953:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:5606
+//line sql-gen.y:6534
 		{
 			return helpWith(sqllex, "DROP VIEW")
 		}
-	case 790:
+	case 954:
 		sqlDollar = sqlS[sqlpt-4 : sqlpt+1]
-//line sql-gen.y:5614
+//line sql-gen.y:6542
 		{
 			sqlVAL.union.val = &tree.DropSequence{Names: sqlDollar[3].union.tableNames(), IfExists: false, DropBehavior: sqlDollar[4].union.dropBehavior()}
 		}
-	case 791:
+	case 955:
 		sqlDollar = sqlS[sqlpt-6 : sqlpt+1]
-//line sql-gen.y:5618
+//line sql-gen.y:6546
 		{
 			sqlVAL.union.val = &tree.DropSequence{Names: sqlDollar[5].union.tableNames(), IfExists: true, DropBehavior: sqlDollar[6].union.dropBehavior()}
 		}
-	case 792:
+	case 956:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:5621
+//line sql-gen.y:6549
 		{
 			return helpWith(sqllex, "DROP VIEW")
 		}
-	case 793:
+	case 957:
 		sqlDollar = sqlS[sqlpt-4 : sqlpt+1]
-//line sql-gen.y:5629
+//line sql-gen.y:6557
 		{
 			sqlVAL.union.val = &tree.DropTable{Names: sqlDollar[3].union.tableNames(), IfExists: false, DropBehavior: sqlDollar[4].union.dropBehavior()}
 		}
-	case 794:
+	case 958:
 		sqlDollar = sqlS[sqlpt-6 : sqlpt+1]
-//line sql-gen.y:5633
+//line sql-gen.y:6561
 		{
 			sqlVAL.union.val = &tree.DropTable{Names: sqlDollar[5].union.tableNames(), IfExists: true, DropBehavior: sqlDollar[6].union.dropBehavior()}
 		}
-	case 795:
+	case 959:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:5636
+//line sql-gen.y:6564
 		{
 			return helpWith(sqllex, "DROP TABLE")
 		}
-	case 796:
+	case 960:
 		sqlDollar = sqlS[sqlpt-5 : sqlpt+1]
-//line sql-gen.y:5644
+//line sql-gen.y:6572
 		{
 			sqlVAL.union.val = &tree.DropIndex{
 				IndexList:    sqlDollar[4].union.newTableIndexNames(),
@@ -33820,9 +37367,9 @@ sqldefault:
 				Concurrently: sqlDollar[3].union.bool(),
 			}
 		}
-	case 797:
+	case 961:
 		sqlDollar = sqlS[sqlpt-7 : sqlpt+1]
-//line sql-gen.y:5653
+//line sql-gen.y:6581
 		{
 			sqlVAL.union.val = &tree.DropIndex{
 				IndexList:    sqlDollar[6].union.newTableIndexNames(),
@@ -33831,15 +37378,15 @@ sqldefault:
 				Concurrently: sqlDollar[3].union.bool(),
 			}
 		}
-	case 798:
+	case 962:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:5661
+//line sql-gen.y:6589
 		{
 			return helpWith(sqllex, "DROP INDEX")
 		}
-	case 799:
+	case 963:
 		sqlDollar = sqlS[sqlpt-4 : sqlpt+1]
-//line sql-gen.y:5669
+//line sql-gen.y:6597
 		{
 			sqlVAL.union.val = &tree.DropDatabase{
 				Name:         tree.Name(sqlDollar[3].str),
@@ -33847,9 +37394,9 @@ sqldefault:
 				DropBehavior: sqlDollar[4].union.dropBehavior(),
 			}
 		}
-	case 800:
+	case 964:
 		sqlDollar = sqlS[sqlpt-6 : sqlpt+1]
-//line sql-gen.y:5677
+//line sql-gen.y:6605
 		{
 			sqlVAL.union.val = &tree.DropDatabase{
 				Name:         tree.Name(sqlDollar[5].str),
@@ -33857,15 +37404,15 @@ sqldefault:
 				DropBehavior: sqlDollar[6].union.dropBehavior(),
 			}
 		}
-	case 801:
+	case 965:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:5684
+//line sql-gen.y:6612
 		{
 			return helpWith(sqllex, "DROP DATABASE")
 		}
-	case 802:
+	case 966:
 		sqlDollar = sqlS[sqlpt-4 : sqlpt+1]
-//line sql-gen.y:5691
+//line sql-gen.y:6619
 		{
 			sqlVAL.union.val = &tree.DropType{
 				Names:        sqlDollar[3].union.unresolvedObjectNames(),
@@ -33873,9 +37420,9 @@ sqldefault:
 				DropBehavior: sqlDollar[4].union.dropBehavior(),
 			}
 		}
-	case 803:
+	case 967:
 		sqlDollar = sqlS[sqlpt-6 : sqlpt+1]
-//line sql-gen.y:5699
+//line sql-gen.y:6627
 		{
 			sqlVAL.union.val = &tree.DropType{
 				Names:        sqlDollar[5].union.unresolvedObjectNames(),
@@ -33883,15 +37430,15 @@ sqldefault:
 				DropBehavior: sqlDollar[6].union.dropBehavior(),
 			}
 		}
-	case 804:
+	case 968:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:5706
+//line sql-gen.y:6634
 		{
 			return helpWith(sqllex, "DROP TYPE")
 		}
-	case 805:
+	case 969:
 		sqlDollar = sqlS[sqlpt-4 : sqlpt+1]
-//line sql-gen.y:5713
+//line sql-gen.y:6641
 		{
 
 			sqlVAL.union.val = &tree.DropTenant{
@@ -33900,9 +37447,9 @@ sqldefault:
 				Immediate:  sqlDollar[4].union.bool(),
 			}
 		}
-	case 806:
+	case 970:
 		sqlDollar = sqlS[sqlpt-6 : sqlpt+1]
-//line sql-gen.y:5722
+//line sql-gen.y:6650
 		{
 
 			sqlVAL.union.val = &tree.DropTenant{
@@ -33911,45 +37458,45 @@ sqldefault:
 				Immediate:  sqlDollar[6].union.bool(),
 			}
 		}
-	case 807:
+	case 971:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:5730
+//line sql-gen.y:6658
 		{
 			return helpWith(sqllex, "DROP VIRTUAL CLUSTER")
 		}
-	case 808:
+	case 972:
 		sqlDollar = sqlS[sqlpt-0 : sqlpt+1]
-//line sql-gen.y:5734
+//line sql-gen.y:6662
 		{
 			sqlVAL.union.val = false
 		}
-	case 809:
+	case 973:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:5736
+//line sql-gen.y:6664
 		{
 			sqlVAL.union.val = true
 		}
-	case 810:
+	case 974:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:5740
+//line sql-gen.y:6668
 		{
 			sqlVAL.union.val = tree.GrantTargetList{Types: sqlDollar[1].union.unresolvedObjectNames()}
 		}
-	case 811:
+	case 975:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:5746
+//line sql-gen.y:6674
 		{
 			sqlVAL.union.val = []*tree.UnresolvedObjectName{sqlDollar[1].union.unresolvedObjectName()}
 		}
-	case 812:
+	case 976:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:5750
+//line sql-gen.y:6678
 		{
 			sqlVAL.union.val = append(sqlDollar[1].union.unresolvedObjectNames(), sqlDollar[3].union.unresolvedObjectName())
 		}
-	case 813:
+	case 977:
 		sqlDollar = sqlS[sqlpt-4 : sqlpt+1]
-//line sql-gen.y:5759
+//line sql-gen.y:6687
 		{
 			sqlVAL.union.val = &tree.DropSchema{
 				Names:        sqlDollar[3].union.objectNamePrefixList(),
@@ -33957,9 +37504,9 @@ sqldefault:
 				DropBehavior: sqlDollar[4].union.dropBehavior(),
 			}
 		}
-	case 814:
+	case 978:
 		sqlDollar = sqlS[sqlpt-6 : sqlpt+1]
-//line sql-gen.y:5767
+//line sql-gen.y:6695
 		{
 			sqlVAL.union.val = &tree.DropSchema{
 				Names:        sqlDollar[5].union.objectNamePrefixList(),
@@ -33967,81 +37514,81 @@ sqldefault:
 				DropBehavior: sqlDollar[6].union.dropBehavior(),
 			}
 		}
-	case 815:
+	case 979:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:5774
+//line sql-gen.y:6702
 		{
 			return helpWith(sqllex, "DROP SCHEMA")
 		}
-	case 816:
+	case 980:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:5782
+//line sql-gen.y:6710
 		{
 			sqlVAL.union.val = &tree.DropRole{Names: sqlDollar[3].union.roleSpecList(), IfExists: false, IsRole: sqlDollar[2].union.bool()}
 		}
-	case 817:
+	case 981:
 		sqlDollar = sqlS[sqlpt-5 : sqlpt+1]
-//line sql-gen.y:5786
+//line sql-gen.y:6714
 		{
 			sqlVAL.union.val = &tree.DropRole{Names: sqlDollar[5].union.roleSpecList(), IfExists: true, IsRole: sqlDollar[2].union.bool()}
 		}
-	case 818:
+	case 982:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:5789
+//line sql-gen.y:6717
 		{
 			return helpWith(sqllex, "DROP ROLE")
 		}
-	case 819:
+	case 983:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:5793
+//line sql-gen.y:6721
 		{
 			name := sqlDollar[1].union.unresolvedObjectName().ToTableName()
 			sqlVAL.union.val = tree.TableNames{name}
 		}
-	case 820:
+	case 984:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:5798
+//line sql-gen.y:6726
 		{
 			name := sqlDollar[3].union.unresolvedObjectName().ToTableName()
 			sqlVAL.union.val = append(sqlDollar[1].union.tableNames(), name)
 		}
-	case 824:
+	case 988:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:5820
+//line sql-gen.y:6748
 		{
 			sqlVAL.union.val = &tree.Analyze{
 				Table: sqlDollar[2].union.tblExpr(),
 			}
 		}
-	case 825:
+	case 989:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:5825
+//line sql-gen.y:6753
 		{
 			return helpWith(sqllex, "ANALYZE")
 		}
-	case 826:
+	case 990:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:5827
+//line sql-gen.y:6755
 		{
 			sqlVAL.union.val = &tree.Analyze{
 				Table: sqlDollar[2].union.tblExpr(),
 			}
 		}
-	case 827:
+	case 991:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:5832
+//line sql-gen.y:6760
 		{
 			return helpWith(sqllex, "ANALYZE")
 		}
-	case 828:
+	case 992:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:5836
+//line sql-gen.y:6764
 		{
 			sqlVAL.union.val = sqlDollar[1].union.unresolvedObjectName()
 		}
-	case 829:
+	case 993:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:5859
+//line sql-gen.y:6787
 		{
 			var err error
 			sqlVAL.union.val, err = tree.MakeExplain(nil, sqlDollar[2].union.stmt())
@@ -34049,15 +37596,15 @@ sqldefault:
 				return setErr(sqllex, err)
 			}
 		}
-	case 830:
+	case 994:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:5866
+//line sql-gen.y:6794
 		{
 			return helpWith(sqllex, "EXPLAIN")
 		}
-	case 831:
+	case 995:
 		sqlDollar = sqlS[sqlpt-5 : sqlpt+1]
-//line sql-gen.y:5868
+//line sql-gen.y:6796
 		{
 			var err error
 			sqlVAL.union.val, err = tree.MakeExplain(sqlDollar[3].union.strs(), sqlDollar[5].union.stmt())
@@ -34065,9 +37612,9 @@ sqldefault:
 				return setErr(sqllex, err)
 			}
 		}
-	case 832:
+	case 996:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:5876
+//line sql-gen.y:6804
 		{
 			var err error
 			sqlVAL.union.val, err = tree.MakeExplain([]string{"ANALYZE"}, sqlDollar[3].union.stmt())
@@ -34075,9 +37622,9 @@ sqldefault:
 				return setErr(sqllex, err)
 			}
 		}
-	case 833:
+	case 997:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:5884
+//line sql-gen.y:6812
 		{
 			var err error
 			sqlVAL.union.val, err = tree.MakeExplain([]string{"ANALYZE"}, sqlDollar[3].union.stmt())
@@ -34085,9 +37632,9 @@ sqldefault:
 				return setErr(sqllex, err)
 			}
 		}
-	case 834:
+	case 998:
 		sqlDollar = sqlS[sqlpt-6 : sqlpt+1]
-//line sql-gen.y:5892
+//line sql-gen.y:6820
 		{
 			var err error
 			sqlVAL.union.val, err = tree.MakeExplain(append(sqlDollar[4].union.strs(), "ANALYZE"), sqlDollar[6].union.stmt())
@@ -34095,9 +37642,9 @@ sqldefault:
 				return setErr(sqllex, err)
 			}
 		}
-	case 835:
+	case 999:
 		sqlDollar = sqlS[sqlpt-6 : sqlpt+1]
-//line sql-gen.y:5900
+//line sql-gen.y:6828
 		{
 			var err error
 			sqlVAL.union.val, err = tree.MakeExplain(append(sqlDollar[4].union.strs(), "ANALYZE"), sqlDollar[6].union.stmt())
@@ -34105,228 +37652,243 @@ sqldefault:
 				return setErr(sqllex, err)
 			}
 		}
-	case 836:
+	case 1000:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:5911
+//line sql-gen.y:6839
 		{
 			return helpWith(sqllex, "EXPLAIN")
 		}
-	case 843:
+	case 1008:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:5921
+//line sql-gen.y:6850
 		{
 			return helpWith(sqllex, "BACKUP")
 		}
-	case 847:
+	case 1013:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:5924
+//line sql-gen.y:6854
 		{
 			return helpWith(sqllex, "DELETE")
 		}
-	case 850:
+	case 1016:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:5926
+//line sql-gen.y:6856
 		{
 			return helpWith(sqllex, "EXPLAIN")
 		}
-	case 852:
+	case 1018:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:5927
+//line sql-gen.y:6857
 		{
 			return helpWith(sqllex, "IMPORT")
 		}
-	case 854:
+	case 1020:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:5928
+//line sql-gen.y:6858
 		{
 			return helpWith(sqllex, "INSERT")
 		}
-	case 858:
+	case 1024:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:5931
+//line sql-gen.y:6861
 		{
 			return helpWith(sqllex, "RESTORE")
 		}
-	case 861:
+	case 1027:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:5933
+//line sql-gen.y:6863
 		{
 			return helpWith(sqllex, "EXPORT")
 		}
-	case 863:
+	case 1029:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:5936
+//line sql-gen.y:6866
 		{
 			sqlVAL.union.val = sqlDollar[1].union.slct()
 		}
-	case 867:
+	case 1033:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:5941
+//line sql-gen.y:6871
 		{
 			return helpWith(sqllex, "TRUNCATE")
 		}
-	case 869:
+	case 1035:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:5942
+//line sql-gen.y:6872
 		{
 			return helpWith(sqllex, "UPDATE")
 		}
-	case 871:
+	case 1037:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:5943
+//line sql-gen.y:6873
 		{
 			return helpWith(sqllex, "UPSERT")
 		}
-	case 873:
+	case 1039:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:5948
+//line sql-gen.y:6878
 		{
 			return helpWith(sqllex, "DELETE")
 		}
-	case 875:
+	case 1041:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:5949
+//line sql-gen.y:6879
 		{
 			return helpWith(sqllex, "EXPLAIN")
 		}
-	case 877:
+	case 1043:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:5950
+//line sql-gen.y:6880
 		{
 			return helpWith(sqllex, "INSERT")
 		}
-	case 878:
+	case 1044:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:5952
+//line sql-gen.y:6882
 		{
 			sqlVAL.union.val = sqlDollar[1].union.slct()
 		}
-	case 881:
+	case 1047:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:5956
+//line sql-gen.y:6886
 		{
 			return helpWith(sqllex, "UPDATE")
 		}
-	case 883:
+	case 1049:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:5957
+//line sql-gen.y:6887
 		{
 			return helpWith(sqllex, "UPSERT")
 		}
-	case 885:
+	case 1051:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:5960
+//line sql-gen.y:6890
 		{
 			return helpWith(sqllex, "DELETE")
 		}
-	case 887:
+	case 1053:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:5961
+//line sql-gen.y:6891
 		{
 			return helpWith(sqllex, "INSERT")
 		}
-	case 888:
+	case 1054:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:5963
+//line sql-gen.y:6893
 		{
 			sqlVAL.union.val = sqlDollar[1].union.slct()
 		}
-	case 890:
+	case 1056:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:5966
+//line sql-gen.y:6896
 		{
 			return helpWith(sqllex, "UPDATE")
 		}
-	case 892:
+	case 1058:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:5967
+//line sql-gen.y:6897
 		{
 			return helpWith(sqllex, "UPSERT")
 		}
-	case 893:
+	case 1059:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:5971
+//line sql-gen.y:6901
 		{
 			sqlVAL.union.val = []string{sqlDollar[1].str}
 		}
-	case 894:
+	case 1060:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:5975
+//line sql-gen.y:6905
 		{
 			sqlVAL.union.val = append(sqlDollar[1].union.strs(), sqlDollar[3].str)
 		}
-	case 895:
+	case 1061:
+		sqlDollar = sqlS[sqlpt-6 : sqlpt+1]
+//line sql-gen.y:6916
+		{
+			sqlVAL.union.val = &tree.AlterJobOwner{
+				Job:   sqlDollar[3].union.expr(),
+				Owner: sqlDollar[6].union.roleSpec(),
+			}
+		}
+	case 1062:
+		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
+//line sql-gen.y:6922
+		{
+			return helpWith(sqllex, "ALTER JOB")
+		}
+	case 1063:
 		sqlDollar = sqlS[sqlpt-4 : sqlpt+1]
-//line sql-gen.y:5985
+//line sql-gen.y:6931
 		{
 			sqlVAL.union.val = &tree.AlterChangefeed{
 				Jobs: sqlDollar[3].union.expr(),
 				Cmds: sqlDollar[4].union.alterChangefeedCmds(),
 			}
 		}
-	case 896:
+	case 1064:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:5991
+//line sql-gen.y:6937
 		{
 			return helpWith(sqllex, "ALTER CHANGEFEED")
 		}
-	case 897:
+	case 1065:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:5995
+//line sql-gen.y:6941
 		{
 			sqlVAL.union.val = tree.AlterChangefeedCmds{sqlDollar[1].union.alterChangefeedCmd()}
 		}
-	case 898:
+	case 1066:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:5999
+//line sql-gen.y:6945
 		{
 			sqlVAL.union.val = append(sqlDollar[1].union.alterChangefeedCmds(), sqlDollar[2].union.alterChangefeedCmd())
 		}
-	case 899:
+	case 1067:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:6006
+//line sql-gen.y:6952
 		{
 			sqlVAL.union.val = &tree.AlterChangefeedAddTarget{
 				Targets: sqlDollar[2].union.changefeedTargets(),
 				Options: sqlDollar[3].union.kvOptions(),
 			}
 		}
-	case 900:
+	case 1068:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:6014
+//line sql-gen.y:6960
 		{
 			sqlVAL.union.val = &tree.AlterChangefeedDropTarget{
 				Targets: sqlDollar[2].union.changefeedTargets(),
 			}
 		}
-	case 901:
+	case 1069:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:6020
+//line sql-gen.y:6966
 		{
 			sqlVAL.union.val = &tree.AlterChangefeedSetOptions{
 				Options: sqlDollar[2].union.kvOptions(),
 			}
 		}
-	case 902:
+	case 1070:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:6026
+//line sql-gen.y:6972
 		{
 			sqlVAL.union.val = &tree.AlterChangefeedUnsetOptions{
 				Options: sqlDollar[2].union.nameList(),
 			}
 		}
-	case 903:
+	case 1071:
 		sqlDollar = sqlS[sqlpt-4 : sqlpt+1]
-//line sql-gen.y:6045
+//line sql-gen.y:6991
 		{
 			sqlVAL.union.val = &tree.AlterBackup{
 				Backup: sqlDollar[3].union.expr(),
 				Cmds:   sqlDollar[4].union.alterBackupCmds(),
 			}
 		}
-	case 904:
+	case 1072:
 		sqlDollar = sqlS[sqlpt-6 : sqlpt+1]
-//line sql-gen.y:6052
+//line sql-gen.y:6998
 		{
 			sqlVAL.union.val = &tree.AlterBackup{
 				Subdir: sqlDollar[3].union.expr(),
@@ -34334,44 +37896,44 @@ sqldefault:
 				Cmds:   sqlDollar[6].union.alterBackupCmds(),
 			}
 		}
-	case 905:
+	case 1073:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:6059
+//line sql-gen.y:7005
 		{
 			return helpWith(sqllex, "ALTER BACKUP")
 		}
-	case 906:
+	case 1074:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:6063
+//line sql-gen.y:7009
 		{
 			sqlVAL.union.val = tree.AlterBackupCmds{sqlDollar[1].union.alterBackupCmd()}
 		}
-	case 907:
+	case 1075:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:6067
+//line sql-gen.y:7013
 		{
 			sqlVAL.union.val = append(sqlDollar[1].union.alterBackupCmds(), sqlDollar[2].union.alterBackupCmd())
 		}
-	case 908:
+	case 1076:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:6073
+//line sql-gen.y:7019
 		{
 			sqlVAL.union.val = &tree.AlterBackupKMS{
 				KMSInfo: sqlDollar[2].union.backupKMS(),
 			}
 		}
-	case 909:
+	case 1077:
 		sqlDollar = sqlS[sqlpt-7 : sqlpt+1]
-//line sql-gen.y:6081
+//line sql-gen.y:7027
 		{
 			sqlVAL.union.val = tree.BackupKMS{
 				NewKMSURI: sqlDollar[3].union.stringOrPlaceholderOptList(),
 				OldKMSURI: sqlDollar[7].union.stringOrPlaceholderOptList(),
 			}
 		}
-	case 910:
+	case 1078:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:6099
+//line sql-gen.y:7045
 		{
 
 			sqlVAL.union.val = &tree.ShowTenant{
@@ -34379,100 +37941,152 @@ sqldefault:
 				ShowTenantOptions: sqlDollar[3].union.showTenantOpts(),
 			}
 		}
-	case 911:
+	case 1079:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:6106
+//line sql-gen.y:7052
 		{
 			return helpWith(sqllex, "SHOW VIRTUAL CLUSTER")
 		}
-	case 912:
+	case 1080:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:6110
+//line sql-gen.y:7056
 		{
 
 			sqlVAL.union.val = &tree.TenantSpec{All: true}
 		}
-	case 913:
+	case 1081:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:6115
+//line sql-gen.y:7061
 		{
 
 			sqlVAL.union.val = &tree.TenantSpec{All: true}
 		}
-	case 914:
+	case 1082:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:6120
+//line sql-gen.y:7066
 		{
 
 			sqlVAL.union.val = sqlDollar[2].union.tenantSpec()
 		}
-	case 915:
+	case 1083:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:6125
+//line sql-gen.y:7071
 		{
 			sqlVAL.union.val = &tree.TenantSpec{All: true}
 		}
-	case 916:
+	case 1084:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:6129
+//line sql-gen.y:7075
 		{
 			sqlVAL.union.val = &tree.TenantSpec{All: true}
 		}
-	case 917:
+	case 1085:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:6133
+//line sql-gen.y:7079
 		{
 			sqlVAL.union.val = sqlDollar[3].union.tenantSpec()
 		}
-	case 918:
+	case 1086:
 		sqlDollar = sqlS[sqlpt-0 : sqlpt+1]
-//line sql-gen.y:6139
+//line sql-gen.y:7085
 		{
 
 			sqlVAL.union.val = tree.ShowTenantOptions{}
 		}
-	case 919:
+	case 1087:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:6144
+//line sql-gen.y:7090
 		{
 
 			sqlVAL.union.val = sqlDollar[2].union.showTenantOpts()
 		}
-	case 920:
+	case 1088:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:6151
+//line sql-gen.y:7097
 		{
 
 			sqlVAL.union.val = tree.ShowTenantOptions{WithReplication: true}
 		}
-	case 921:
+	case 1089:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:6156
+//line sql-gen.y:7102
 		{
 
 			sqlVAL.union.val = tree.ShowTenantOptions{WithCapabilities: true}
 		}
-	case 922:
+	case 1090:
+		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
+//line sql-gen.y:7107
+		{
+
+			sqlVAL.union.val = tree.ShowTenantOptions{WithPriorReplication: true}
+		}
+	case 1091:
 		sqlDollar = sqlS[sqlpt-4 : sqlpt+1]
-//line sql-gen.y:6161
+//line sql-gen.y:7112
 		{
 
 			o := sqlDollar[1].union.showTenantOpts()
 			o.WithReplication = true
 			sqlVAL.union.val = o
 		}
-	case 923:
+	case 1092:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:6168
+//line sql-gen.y:7119
 		{
 
 			o := sqlDollar[1].union.showTenantOpts()
 			o.WithCapabilities = true
 			sqlVAL.union.val = o
 		}
-	case 924:
+	case 1093:
+		sqlDollar = sqlS[sqlpt-5 : sqlpt+1]
+//line sql-gen.y:7126
+		{
+
+			o := sqlDollar[1].union.showTenantOpts()
+			o.WithPriorReplication = true
+			sqlVAL.union.val = o
+		}
+	case 1094:
+		sqlDollar = sqlS[sqlpt-5 : sqlpt+1]
+//line sql-gen.y:7141
+		{
+
+			sqlVAL.union.val = &tree.ShowLogicalReplicationJobs{
+				ShowLogicalReplicationJobsOptions: sqlDollar[5].union.showLogicalReplicationJobsOpts(),
+			}
+		}
+	case 1095:
+		sqlDollar = sqlS[sqlpt-5 : sqlpt+1]
+//line sql-gen.y:7147
+		{
+			return helpWith(sqllex, "SHOW LOGICAL REPLICATION JOBS")
+		}
+	case 1096:
+		sqlDollar = sqlS[sqlpt-0 : sqlpt+1]
+//line sql-gen.y:7151
+		{
+
+			sqlVAL.union.val = tree.ShowLogicalReplicationJobsOptions{}
+		}
+	case 1097:
+		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
+//line sql-gen.y:7156
+		{
+
+			sqlVAL.union.val = sqlDollar[2].union.showLogicalReplicationJobsOpts()
+		}
+	case 1098:
+		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
+//line sql-gen.y:7163
+		{
+
+			sqlVAL.union.val = tree.ShowLogicalReplicationJobsOptions{WithDetails: true}
+		}
+	case 1099:
 		sqlDollar = sqlS[sqlpt-5 : sqlpt+1]
-//line sql-gen.y:6181
+//line sql-gen.y:7174
 		{
 			sqlVAL.union.val = &tree.Prepare{
 				Name:      tree.Name(sqlDollar[2].str),
@@ -34480,9 +38094,9 @@ sqldefault:
 				Statement: sqlDollar[5].union.stmt(),
 			}
 		}
-	case 925:
+	case 1100:
 		sqlDollar = sqlS[sqlpt-7 : sqlpt+1]
-//line sql-gen.y:6189
+//line sql-gen.y:7182
 		{
 
 			sqlVAL.union.val = &tree.Prepare{
@@ -34491,36 +38105,36 @@ sqldefault:
 				Statement: &tree.CannedOptPlan{Plan: sqlDollar[7].str},
 			}
 		}
-	case 926:
+	case 1101:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:6197
+//line sql-gen.y:7190
 		{
 			return helpWith(sqllex, "PREPARE")
 		}
-	case 927:
+	case 1102:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:6201
+//line sql-gen.y:7194
 		{
 			sqlVAL.union.val = sqlDollar[2].union.typeReferences()
 		}
-	case 928:
+	case 1103:
 		sqlDollar = sqlS[sqlpt-0 : sqlpt+1]
-//line sql-gen.y:6205
+//line sql-gen.y:7198
 		{
 			sqlVAL.union.val = []tree.ResolvableTypeReference(nil)
 		}
-	case 929:
+	case 1104:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:6215
+//line sql-gen.y:7208
 		{
 			sqlVAL.union.val = &tree.Execute{
 				Name:   tree.Name(sqlDollar[2].str),
 				Params: sqlDollar[3].union.exprs(),
 			}
 		}
-	case 930:
+	case 1105:
 		sqlDollar = sqlS[sqlpt-5 : sqlpt+1]
-//line sql-gen.y:6222
+//line sql-gen.y:7215
 		{
 
 			sqlVAL.union.val = &tree.Execute{
@@ -34529,81 +38143,81 @@ sqldefault:
 				DiscardRows: true,
 			}
 		}
-	case 931:
+	case 1106:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:6230
+//line sql-gen.y:7223
 		{
 			return helpWith(sqllex, "EXECUTE")
 		}
-	case 932:
+	case 1107:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:6234
+//line sql-gen.y:7227
 		{
 			sqlVAL.union.val = sqlDollar[2].union.exprs()
 		}
-	case 933:
+	case 1108:
 		sqlDollar = sqlS[sqlpt-0 : sqlpt+1]
-//line sql-gen.y:6238
+//line sql-gen.y:7231
 		{
 			sqlVAL.union.val = tree.Exprs(nil)
 		}
-	case 934:
+	case 1109:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:6248
+//line sql-gen.y:7241
 		{
 			sqlVAL.union.val = &tree.Deallocate{Name: tree.Name(sqlDollar[2].str)}
 		}
-	case 935:
+	case 1110:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:6252
+//line sql-gen.y:7245
 		{
 			sqlVAL.union.val = &tree.Deallocate{Name: tree.Name(sqlDollar[3].str)}
 		}
-	case 936:
+	case 1111:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:6256
+//line sql-gen.y:7249
 		{
 			sqlVAL.union.val = &tree.Deallocate{}
 		}
-	case 937:
+	case 1112:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:6260
+//line sql-gen.y:7253
 		{
 			sqlVAL.union.val = &tree.Deallocate{}
 		}
-	case 938:
+	case 1113:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:6263
+//line sql-gen.y:7256
 		{
 			return helpWith(sqllex, "DEALLOCATE")
 		}
-	case 939:
+	case 1114:
 		sqlDollar = sqlS[sqlpt-7 : sqlpt+1]
-//line sql-gen.y:6287
+//line sql-gen.y:7280
 		{
 			sqlVAL.union.val = &tree.Grant{Privileges: sqlDollar[2].union.privilegeList(), Grantees: sqlDollar[6].union.roleSpecList(), Targets: sqlDollar[4].union.grantTargetList(), WithGrantOption: sqlDollar[7].union.bool()}
 		}
-	case 940:
+	case 1115:
 		sqlDollar = sqlS[sqlpt-4 : sqlpt+1]
-//line sql-gen.y:6291
+//line sql-gen.y:7284
 		{
 			sqlVAL.union.val = &tree.GrantRole{Roles: sqlDollar[2].union.nameList(), Members: sqlDollar[4].union.roleSpecList(), AdminOption: false}
 		}
-	case 941:
+	case 1116:
 		sqlDollar = sqlS[sqlpt-7 : sqlpt+1]
-//line sql-gen.y:6295
+//line sql-gen.y:7288
 		{
 			sqlVAL.union.val = &tree.GrantRole{Roles: sqlDollar[2].union.nameList(), Members: sqlDollar[4].union.roleSpecList(), AdminOption: true}
 		}
-	case 942:
+	case 1117:
 		sqlDollar = sqlS[sqlpt-8 : sqlpt+1]
-//line sql-gen.y:6299
+//line sql-gen.y:7292
 		{
 			sqlVAL.union.val = &tree.Grant{Privileges: sqlDollar[2].union.privilegeList(), Targets: sqlDollar[5].union.grantTargetList(), Grantees: sqlDollar[7].union.roleSpecList(), WithGrantOption: sqlDollar[8].union.bool()}
 		}
-	case 943:
+	case 1118:
 		sqlDollar = sqlS[sqlpt-8 : sqlpt+1]
-//line sql-gen.y:6303
+//line sql-gen.y:7296
 		{
 			sqlVAL.union.val = &tree.Grant{
 				Privileges: sqlDollar[2].union.privilegeList(),
@@ -34614,15 +38228,15 @@ sqldefault:
 				WithGrantOption: sqlDollar[8].union.bool(),
 			}
 		}
-	case 944:
+	case 1119:
 		sqlDollar = sqlS[sqlpt-9 : sqlpt+1]
-//line sql-gen.y:6314
+//line sql-gen.y:7307
 		{
 			return unimplemented(sqllex, "grant privileges on schema with")
 		}
-	case 945:
+	case 1120:
 		sqlDollar = sqlS[sqlpt-11 : sqlpt+1]
-//line sql-gen.y:6318
+//line sql-gen.y:7311
 		{
 			sqlVAL.union.val = &tree.Grant{
 				Privileges: sqlDollar[2].union.privilegeList(),
@@ -34634,9 +38248,9 @@ sqldefault:
 				WithGrantOption: sqlDollar[11].union.bool(),
 			}
 		}
-	case 946:
+	case 1121:
 		sqlDollar = sqlS[sqlpt-11 : sqlpt+1]
-//line sql-gen.y:6330
+//line sql-gen.y:7323
 		{
 			sqlVAL.union.val = &tree.Grant{
 				Privileges: sqlDollar[2].union.privilegeList(),
@@ -34648,9 +38262,9 @@ sqldefault:
 				WithGrantOption: sqlDollar[11].union.bool(),
 			}
 		}
-	case 947:
+	case 1122:
 		sqlDollar = sqlS[sqlpt-11 : sqlpt+1]
-//line sql-gen.y:6342
+//line sql-gen.y:7335
 		{
 			sqlVAL.union.val = &tree.Grant{
 				Privileges: sqlDollar[2].union.privilegeList(),
@@ -34662,9 +38276,9 @@ sqldefault:
 				WithGrantOption: sqlDollar[11].union.bool(),
 			}
 		}
-	case 948:
+	case 1123:
 		sqlDollar = sqlS[sqlpt-11 : sqlpt+1]
-//line sql-gen.y:6354
+//line sql-gen.y:7347
 		{
 			sqlVAL.union.val = &tree.Grant{
 				Privileges: sqlDollar[2].union.privilegeList(),
@@ -34676,9 +38290,9 @@ sqldefault:
 				WithGrantOption: sqlDollar[11].union.bool(),
 			}
 		}
-	case 949:
+	case 1124:
 		sqlDollar = sqlS[sqlpt-6 : sqlpt+1]
-//line sql-gen.y:6366
+//line sql-gen.y:7359
 		{
 			sqlVAL.union.val = &tree.Grant{
 				Privileges: sqlDollar[3].union.privilegeList(),
@@ -34689,51 +38303,51 @@ sqldefault:
 				WithGrantOption: sqlDollar[6].union.bool(),
 			}
 		}
-	case 950:
+	case 1125:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:6376
+//line sql-gen.y:7369
 		{
 			return helpWith(sqllex, "GRANT")
 		}
-	case 951:
+	case 1126:
 		sqlDollar = sqlS[sqlpt-6 : sqlpt+1]
-//line sql-gen.y:6400
+//line sql-gen.y:7393
 		{
 			sqlVAL.union.val = &tree.Revoke{Privileges: sqlDollar[2].union.privilegeList(), Grantees: sqlDollar[6].union.roleSpecList(), Targets: sqlDollar[4].union.grantTargetList(), GrantOptionFor: false}
 		}
-	case 952:
+	case 1127:
 		sqlDollar = sqlS[sqlpt-9 : sqlpt+1]
-//line sql-gen.y:6404
+//line sql-gen.y:7397
 		{
 			sqlVAL.union.val = &tree.Revoke{Privileges: sqlDollar[5].union.privilegeList(), Grantees: sqlDollar[9].union.roleSpecList(), Targets: sqlDollar[7].union.grantTargetList(), GrantOptionFor: true}
 		}
-	case 953:
+	case 1128:
 		sqlDollar = sqlS[sqlpt-4 : sqlpt+1]
-//line sql-gen.y:6408
+//line sql-gen.y:7401
 		{
 			sqlVAL.union.val = &tree.RevokeRole{Roles: sqlDollar[2].union.nameList(), Members: sqlDollar[4].union.roleSpecList(), AdminOption: false}
 		}
-	case 954:
+	case 1129:
 		sqlDollar = sqlS[sqlpt-7 : sqlpt+1]
-//line sql-gen.y:6412
+//line sql-gen.y:7405
 		{
 			sqlVAL.union.val = &tree.RevokeRole{Roles: sqlDollar[5].union.nameList(), Members: sqlDollar[7].union.roleSpecList(), AdminOption: true}
 		}
-	case 955:
+	case 1130:
 		sqlDollar = sqlS[sqlpt-7 : sqlpt+1]
-//line sql-gen.y:6416
+//line sql-gen.y:7409
 		{
 			sqlVAL.union.val = &tree.Revoke{Privileges: sqlDollar[2].union.privilegeList(), Targets: sqlDollar[5].union.grantTargetList(), Grantees: sqlDollar[7].union.roleSpecList(), GrantOptionFor: false}
 		}
-	case 956:
+	case 1131:
 		sqlDollar = sqlS[sqlpt-10 : sqlpt+1]
-//line sql-gen.y:6420
+//line sql-gen.y:7413
 		{
 			sqlVAL.union.val = &tree.Revoke{Privileges: sqlDollar[5].union.privilegeList(), Targets: sqlDollar[8].union.grantTargetList(), Grantees: sqlDollar[10].union.roleSpecList(), GrantOptionFor: true}
 		}
-	case 957:
+	case 1132:
 		sqlDollar = sqlS[sqlpt-7 : sqlpt+1]
-//line sql-gen.y:6424
+//line sql-gen.y:7417
 		{
 			sqlVAL.union.val = &tree.Revoke{
 				Privileges: sqlDollar[2].union.privilegeList(),
@@ -34744,9 +38358,9 @@ sqldefault:
 				GrantOptionFor: false,
 			}
 		}
-	case 958:
+	case 1133:
 		sqlDollar = sqlS[sqlpt-10 : sqlpt+1]
-//line sql-gen.y:6435
+//line sql-gen.y:7428
 		{
 			sqlVAL.union.val = &tree.Revoke{
 				Privileges: sqlDollar[5].union.privilegeList(),
@@ -34757,9 +38371,9 @@ sqldefault:
 				GrantOptionFor: true,
 			}
 		}
-	case 959:
+	case 1134:
 		sqlDollar = sqlS[sqlpt-10 : sqlpt+1]
-//line sql-gen.y:6446
+//line sql-gen.y:7439
 		{
 			sqlVAL.union.val = &tree.Revoke{
 				Privileges: sqlDollar[2].union.privilegeList(),
@@ -34771,9 +38385,9 @@ sqldefault:
 				GrantOptionFor: false,
 			}
 		}
-	case 960:
+	case 1135:
 		sqlDollar = sqlS[sqlpt-10 : sqlpt+1]
-//line sql-gen.y:6458
+//line sql-gen.y:7451
 		{
 			sqlVAL.union.val = &tree.Revoke{
 				Privileges: sqlDollar[2].union.privilegeList(),
@@ -34785,9 +38399,9 @@ sqldefault:
 				GrantOptionFor: false,
 			}
 		}
-	case 961:
+	case 1136:
 		sqlDollar = sqlS[sqlpt-13 : sqlpt+1]
-//line sql-gen.y:6470
+//line sql-gen.y:7463
 		{
 			sqlVAL.union.val = &tree.Revoke{
 				Privileges: sqlDollar[5].union.privilegeList(),
@@ -34799,9 +38413,9 @@ sqldefault:
 				GrantOptionFor: true,
 			}
 		}
-	case 962:
+	case 1137:
 		sqlDollar = sqlS[sqlpt-10 : sqlpt+1]
-//line sql-gen.y:6482
+//line sql-gen.y:7475
 		{
 			sqlVAL.union.val = &tree.Revoke{
 				Privileges: sqlDollar[2].union.privilegeList(),
@@ -34813,9 +38427,9 @@ sqldefault:
 				GrantOptionFor: false,
 			}
 		}
-	case 963:
+	case 1138:
 		sqlDollar = sqlS[sqlpt-13 : sqlpt+1]
-//line sql-gen.y:6494
+//line sql-gen.y:7487
 		{
 			sqlVAL.union.val = &tree.Revoke{
 				Privileges: sqlDollar[5].union.privilegeList(),
@@ -34827,9 +38441,9 @@ sqldefault:
 				GrantOptionFor: true,
 			}
 		}
-	case 964:
+	case 1139:
 		sqlDollar = sqlS[sqlpt-10 : sqlpt+1]
-//line sql-gen.y:6506
+//line sql-gen.y:7499
 		{
 			sqlVAL.union.val = &tree.Revoke{
 				Privileges: sqlDollar[2].union.privilegeList(),
@@ -34841,9 +38455,9 @@ sqldefault:
 				GrantOptionFor: false,
 			}
 		}
-	case 965:
+	case 1140:
 		sqlDollar = sqlS[sqlpt-13 : sqlpt+1]
-//line sql-gen.y:6518
+//line sql-gen.y:7511
 		{
 			sqlVAL.union.val = &tree.Revoke{
 				Privileges: sqlDollar[5].union.privilegeList(),
@@ -34855,9 +38469,9 @@ sqldefault:
 				GrantOptionFor: true,
 			}
 		}
-	case 966:
+	case 1141:
 		sqlDollar = sqlS[sqlpt-5 : sqlpt+1]
-//line sql-gen.y:6530
+//line sql-gen.y:7523
 		{
 			sqlVAL.union.val = &tree.Revoke{
 				Privileges: sqlDollar[3].union.privilegeList(),
@@ -34867,9 +38481,9 @@ sqldefault:
 				Grantees: sqlDollar[5].union.roleSpecList(),
 			}
 		}
-	case 967:
+	case 1142:
 		sqlDollar = sqlS[sqlpt-8 : sqlpt+1]
-//line sql-gen.y:6540
+//line sql-gen.y:7533
 		{
 			sqlVAL.union.val = &tree.Revoke{
 				Privileges: sqlDollar[6].union.privilegeList(),
@@ -34880,27 +38494,27 @@ sqldefault:
 				GrantOptionFor: true,
 			}
 		}
-	case 968:
+	case 1143:
 		sqlDollar = sqlS[sqlpt-5 : sqlpt+1]
-//line sql-gen.y:6551
+//line sql-gen.y:7544
 		{
 			return unimplemented(sqllex, "revoke privileges on sequence")
 		}
-	case 969:
+	case 1144:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:6554
+//line sql-gen.y:7547
 		{
 			return helpWith(sqllex, "REVOKE")
 		}
-	case 970:
+	case 1145:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:6560
+//line sql-gen.y:7553
 		{
 			sqlVAL.union.val = privilege.List{privilege.ALL}
 		}
-	case 971:
+	case 1146:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:6564
+//line sql-gen.y:7557
 		{
 			privList, err := privilege.ListFromStrings(sqlDollar[1].union.nameList().ToStrings(), privilege.OriginFromUserInput)
 			if err != nil {
@@ -34908,140 +38522,140 @@ sqldefault:
 			}
 			sqlVAL.union.val = privList
 		}
-	case 972:
+	case 1147:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:6574
+//line sql-gen.y:7567
 		{
 			sqlVAL.union.val = tree.NameList{tree.Name(sqlDollar[1].str)}
 		}
-	case 973:
+	case 1148:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:6578
+//line sql-gen.y:7571
 		{
 			sqlVAL.union.val = append(sqlDollar[1].union.nameList(), tree.Name(sqlDollar[3].str))
 		}
-	case 979:
+	case 1154:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:6592
+//line sql-gen.y:7585
 		{
 			return helpWith(sqllex, "RESET")
 		}
-	case 981:
+	case 1156:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:6593
+//line sql-gen.y:7586
 		{
 			return helpWith(sqllex, "RESET CLUSTER SETTING")
 		}
-	case 982:
+	case 1157:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:6601
+//line sql-gen.y:7594
 		{
 			sqlVAL.union.val = &tree.SetVar{Name: sqlDollar[2].str, Values: tree.Exprs{tree.DefaultVal{}}, Reset: true}
 		}
-	case 983:
+	case 1158:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:6605
+//line sql-gen.y:7598
 		{
 			sqlVAL.union.val = &tree.SetVar{Name: sqlDollar[3].str, Values: tree.Exprs{tree.DefaultVal{}}, Reset: true}
 		}
-	case 984:
+	case 1159:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:6609
+//line sql-gen.y:7602
 		{
 			sqlVAL.union.val = &tree.SetVar{ResetAll: true, Reset: true}
 		}
-	case 985:
+	case 1160:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:6612
+//line sql-gen.y:7605
 		{
 			return helpWith(sqllex, "RESET")
 		}
-	case 986:
+	case 1161:
 		sqlDollar = sqlS[sqlpt-4 : sqlpt+1]
-//line sql-gen.y:6620
+//line sql-gen.y:7613
 		{
 			sqlVAL.union.val = &tree.SetClusterSetting{Name: strings.Join(sqlDollar[4].union.strs(), "."), Value: tree.DefaultVal{}}
 		}
-	case 987:
+	case 1162:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:6623
+//line sql-gen.y:7616
 		{
 			return helpWith(sqllex, "RESET CLUSTER SETTING")
 		}
-	case 988:
+	case 1163:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:6634
+//line sql-gen.y:7627
 		{
 			sqlVAL.union.val = &tree.SetVar{Name: "database", Values: tree.Exprs{sqlDollar[2].union.expr()}}
 		}
-	case 989:
+	case 1164:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:6637
+//line sql-gen.y:7630
 		{
 			return helpWith(sqllex, "USE")
 		}
-	case 991:
+	case 1166:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:6641
+//line sql-gen.y:7634
 		{
 			return helpWith(sqllex, "SET TRANSACTION")
 		}
-	case 992:
+	case 1167:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:6642
+//line sql-gen.y:7635
 		{
 		}
-	case 993:
+	case 1168:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:6643
+//line sql-gen.y:7636
 		{
 			return unimplemented(sqllex, "set constraints")
 		}
-	case 995:
+	case 1170:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:6647
+//line sql-gen.y:7640
 		{
 			return helpWith(sqllex, "SET SESSION")
 		}
-	case 997:
+	case 1172:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:6648
+//line sql-gen.y:7641
 		{
 			return helpWith(sqllex, "SET LOCAL")
 		}
-	case 999:
+	case 1174:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:6649
+//line sql-gen.y:7642
 		{
 			return helpWith(sqllex, "SET CLUSTER SETTING")
 		}
-	case 1001:
+	case 1176:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:6650
+//line sql-gen.y:7643
 		{
 			return helpWith(sqllex, "USE")
 		}
-	case 1004:
+	case 1179:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:6666
+//line sql-gen.y:7659
 		{
 			return helpWith(sqllex, "SCRUB")
 		}
-	case 1005:
+	case 1180:
 		sqlDollar = sqlS[sqlpt-5 : sqlpt+1]
-//line sql-gen.y:6681
+//line sql-gen.y:7674
 		{
 			sqlVAL.union.val = &tree.Scrub{Typ: tree.ScrubDatabase, Database: tree.Name(sqlDollar[4].str), AsOf: sqlDollar[5].union.asOfClause()}
 		}
-	case 1006:
+	case 1181:
 		sqlDollar = sqlS[sqlpt-4 : sqlpt+1]
-//line sql-gen.y:6684
+//line sql-gen.y:7677
 		{
 			return helpWith(sqllex, "SCRUB DATABASE")
 		}
-	case 1007:
+	case 1182:
 		sqlDollar = sqlS[sqlpt-6 : sqlpt+1]
-//line sql-gen.y:6702
+//line sql-gen.y:7695
 		{
 			sqlVAL.union.val = &tree.Scrub{
 				Typ:     tree.ScrubTable,
@@ -35050,139 +38664,154 @@ sqldefault:
 				Options: sqlDollar[6].union.scrubOptions(),
 			}
 		}
-	case 1008:
+	case 1183:
 		sqlDollar = sqlS[sqlpt-4 : sqlpt+1]
-//line sql-gen.y:6710
+//line sql-gen.y:7703
 		{
 			return helpWith(sqllex, "SCRUB TABLE")
 		}
-	case 1009:
+	case 1184:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:6714
+//line sql-gen.y:7707
 		{
 			sqlVAL.union.val = sqlDollar[3].union.scrubOptions()
 		}
-	case 1010:
+	case 1185:
 		sqlDollar = sqlS[sqlpt-0 : sqlpt+1]
-//line sql-gen.y:6718
+//line sql-gen.y:7711
 		{
 			sqlVAL.union.val = tree.ScrubOptions{}
 		}
-	case 1011:
+	case 1186:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:6724
+//line sql-gen.y:7717
 		{
 			sqlVAL.union.val = tree.ScrubOptions{sqlDollar[1].union.scrubOption()}
 		}
-	case 1012:
+	case 1187:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:6728
+//line sql-gen.y:7721
 		{
 			sqlVAL.union.val = append(sqlDollar[1].union.scrubOptions(), sqlDollar[3].union.scrubOption())
 		}
-	case 1013:
+	case 1188:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:6734
+//line sql-gen.y:7727
 		{
 			sqlVAL.union.val = &tree.ScrubOptionIndex{}
 		}
-	case 1014:
+	case 1189:
 		sqlDollar = sqlS[sqlpt-4 : sqlpt+1]
-//line sql-gen.y:6738
+//line sql-gen.y:7731
 		{
 			sqlVAL.union.val = &tree.ScrubOptionIndex{IndexNames: sqlDollar[3].union.nameList()}
 		}
-	case 1015:
+	case 1190:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:6742
+//line sql-gen.y:7735
 		{
 			sqlVAL.union.val = &tree.ScrubOptionConstraint{}
 		}
-	case 1016:
+	case 1191:
 		sqlDollar = sqlS[sqlpt-4 : sqlpt+1]
-//line sql-gen.y:6746
+//line sql-gen.y:7739
 		{
 			sqlVAL.union.val = &tree.ScrubOptionConstraint{ConstraintNames: sqlDollar[3].union.nameList()}
 		}
-	case 1017:
+	case 1192:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:6750
+//line sql-gen.y:7743
 		{
 			sqlVAL.union.val = &tree.ScrubOptionPhysical{}
 		}
-	case 1018:
+	case 1193:
 		sqlDollar = sqlS[sqlpt-6 : sqlpt+1]
-//line sql-gen.y:6761
+//line sql-gen.y:7754
 		{
 			sqlVAL.union.val = &tree.SetClusterSetting{Name: strings.Join(sqlDollar[4].union.strs(), "."), Value: sqlDollar[6].union.expr()}
 		}
-	case 1019:
+	case 1194:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:6764
+//line sql-gen.y:7757
 		{
 			return helpWith(sqllex, "SET CLUSTER SETTING")
 		}
-	case 1021:
+	case 1196:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:6774
+//line sql-gen.y:7767
 		{
 			return helpWith(sqllex, "ALTER VIRTUAL CLUSTER REPLICATION")
 		}
-	case 1023:
+	case 1198:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:6775
+//line sql-gen.y:7768
 		{
 			return helpWith(sqllex, "ALTER VIRTUAL CLUSTER SETTING")
 		}
-	case 1025:
+	case 1200:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:6776
+//line sql-gen.y:7769
 		{
 			return helpWith(sqllex, "ALTER VIRTUAL CLUSTER CAPABILITY")
 		}
-	case 1027:
+	case 1202:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:6777
+//line sql-gen.y:7770
 		{
 			return helpWith(sqllex, "ALTER VIRTUAL CLUSTER RENAME")
 		}
-	case 1029:
+	case 1204:
+		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
+//line sql-gen.y:7771
+		{
+			return helpWith(sqllex, "ALTER VIRTUAL CLUSTER RESET")
+		}
+	case 1206:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:6778
+//line sql-gen.y:7772
 		{
 			return helpWith(sqllex, "ALTER VIRTUAL CLUSTER SERVICE")
 		}
-	case 1030:
+	case 1207:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:6779
+//line sql-gen.y:7773
 		{
 			return helpWith(sqllex, "ALTER VIRTUAL CLUSTER")
 		}
-	case 1031:
+	case 1208:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:6783
+//line sql-gen.y:7777
 		{
 			sqlVAL.union.val = &tree.TenantSpec{IsName: true, Expr: sqlDollar[1].union.expr()}
 		}
-	case 1032:
+	case 1209:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:6785
+//line sql-gen.y:7779
 		{
 			sqlVAL.union.val = &tree.TenantSpec{IsName: false, Expr: sqlDollar[2].union.expr()}
 		}
-	case 1033:
-		sqlDollar = sqlS[sqlpt-6 : sqlpt+1]
-//line sql-gen.y:6793
+	case 1210:
+		sqlDollar = sqlS[sqlpt-9 : sqlpt+1]
+//line sql-gen.y:7788
 		{
 
+			sqlVAL.union.val = &tree.AlterTenantReset{
+				TenantSpec: sqlDollar[3].union.tenantSpec(),
+				Timestamp:  sqlDollar[9].union.expr(),
+			}
+		}
+	case 1211:
+		sqlDollar = sqlS[sqlpt-6 : sqlpt+1]
+//line sql-gen.y:7802
+		{
 			sqlVAL.union.val = &tree.AlterTenantRename{
 				TenantSpec: sqlDollar[3].union.tenantSpec(),
 				NewName:    &tree.TenantSpec{IsName: true, Expr: sqlDollar[6].union.expr()},
 			}
 		}
-	case 1034:
+	case 1212:
 		sqlDollar = sqlS[sqlpt-6 : sqlpt+1]
-//line sql-gen.y:6809
+//line sql-gen.y:7817
 		{
 
 			sqlVAL.union.val = &tree.AlterTenantService{
@@ -35190,63 +38819,58 @@ sqldefault:
 				Command:    tree.TenantStartServiceExternal,
 			}
 		}
-	case 1035:
+	case 1213:
 		sqlDollar = sqlS[sqlpt-6 : sqlpt+1]
-//line sql-gen.y:6817
+//line sql-gen.y:7825
 		{
-
 			sqlVAL.union.val = &tree.AlterTenantService{
 				TenantSpec: sqlDollar[3].union.tenantSpec(),
 				Command:    tree.TenantStartServiceShared,
 			}
 		}
-	case 1036:
+	case 1214:
 		sqlDollar = sqlS[sqlpt-5 : sqlpt+1]
-//line sql-gen.y:6825
+//line sql-gen.y:7832
 		{
-
 			sqlVAL.union.val = &tree.AlterTenantService{
 				TenantSpec: sqlDollar[3].union.tenantSpec(),
 				Command:    tree.TenantStopService,
 			}
 		}
-	case 1037:
+	case 1215:
 		sqlDollar = sqlS[sqlpt-5 : sqlpt+1]
-//line sql-gen.y:6832
+//line sql-gen.y:7838
 		{
 			return helpWith(sqllex, "ALTER VIRTUAL CLUSTER SERVICE")
 		}
-	case 1038:
+	case 1216:
 		sqlDollar = sqlS[sqlpt-5 : sqlpt+1]
-//line sql-gen.y:6833
+//line sql-gen.y:7839
 		{
 			return helpWith(sqllex, "ALTER VIRTUAL CLUSTER SERVICE")
 		}
-	case 1039:
+	case 1217:
 		sqlDollar = sqlS[sqlpt-5 : sqlpt+1]
-//line sql-gen.y:6846
+//line sql-gen.y:7853
 		{
-
 			sqlVAL.union.val = &tree.AlterTenantReplication{
 				TenantSpec: sqlDollar[3].union.tenantSpec(),
 				Command:    tree.PauseJob,
 			}
 		}
-	case 1040:
+	case 1218:
 		sqlDollar = sqlS[sqlpt-5 : sqlpt+1]
-//line sql-gen.y:6854
+//line sql-gen.y:7860
 		{
-
 			sqlVAL.union.val = &tree.AlterTenantReplication{
 				TenantSpec: sqlDollar[3].union.tenantSpec(),
 				Command:    tree.ResumeJob,
 			}
 		}
-	case 1041:
+	case 1219:
 		sqlDollar = sqlS[sqlpt-9 : sqlpt+1]
-//line sql-gen.y:6862
+//line sql-gen.y:7867
 		{
-
 			sqlVAL.union.val = &tree.AlterTenantReplication{
 				TenantSpec: sqlDollar[3].union.tenantSpec(),
 				Cutover: &tree.ReplicationCutoverTime{
@@ -35254,11 +38878,10 @@ sqldefault:
 				},
 			}
 		}
-	case 1042:
+	case 1220:
 		sqlDollar = sqlS[sqlpt-7 : sqlpt+1]
-//line sql-gen.y:6872
+//line sql-gen.y:7876
 		{
-
 			sqlVAL.union.val = &tree.AlterTenantReplication{
 				TenantSpec: sqlDollar[3].union.tenantSpec(),
 				Cutover: &tree.ReplicationCutoverTime{
@@ -35266,19 +38889,39 @@ sqldefault:
 				},
 			}
 		}
-	case 1043:
+	case 1221:
 		sqlDollar = sqlS[sqlpt-6 : sqlpt+1]
-//line sql-gen.y:6882
+//line sql-gen.y:7885
 		{
-
 			sqlVAL.union.val = &tree.AlterTenantReplication{
 				TenantSpec: sqlDollar[3].union.tenantSpec(),
 				Options:    *sqlDollar[6].union.tenantReplicationOptions(),
 			}
 		}
-	case 1044:
+	case 1222:
+		sqlDollar = sqlS[sqlpt-7 : sqlpt+1]
+//line sql-gen.y:7892
+		{
+			sqlVAL.union.val = &tree.AlterTenantReplication{
+				TenantSpec: sqlDollar[3].union.tenantSpec(),
+				Producer:   true,
+				Options:    *sqlDollar[7].union.tenantReplicationOptions(),
+			}
+		}
+	case 1223:
+		sqlDollar = sqlS[sqlpt-10 : sqlpt+1]
+//line sql-gen.y:7900
+		{
+			sqlVAL.union.val = &tree.AlterTenantReplication{
+				TenantSpec:                  sqlDollar[3].union.tenantSpec(),
+				ReplicationSourceTenantName: &tree.TenantSpec{IsName: true, Expr: sqlDollar[7].union.expr()},
+				ReplicationSourceConnUri:    sqlDollar[9].union.expr(),
+				Options:                     *sqlDollar[10].union.tenantReplicationOptions(),
+			}
+		}
+	case 1224:
 		sqlDollar = sqlS[sqlpt-4 : sqlpt+1]
-//line sql-gen.y:6899
+//line sql-gen.y:7918
 		{
 
 			csettingStmt := sqlDollar[4].union.stmt().(*tree.SetClusterSetting)
@@ -35287,9 +38930,9 @@ sqldefault:
 				TenantSpec:        sqlDollar[3].union.tenantSpec(),
 			}
 		}
-	case 1045:
+	case 1225:
 		sqlDollar = sqlS[sqlpt-4 : sqlpt+1]
-//line sql-gen.y:6908
+//line sql-gen.y:7927
 		{
 
 			csettingStmt := sqlDollar[4].union.stmt().(*tree.SetClusterSetting)
@@ -35298,9 +38941,9 @@ sqldefault:
 				TenantSpec:        &tree.TenantSpec{All: true},
 			}
 		}
-	case 1046:
+	case 1226:
 		sqlDollar = sqlS[sqlpt-5 : sqlpt+1]
-//line sql-gen.y:6917
+//line sql-gen.y:7936
 		{
 
 			csettingStmt := sqlDollar[5].union.stmt().(*tree.SetClusterSetting)
@@ -35309,84 +38952,80 @@ sqldefault:
 				TenantSpec:        &tree.TenantSpec{All: true},
 			}
 		}
-	case 1047:
+	case 1227:
 		sqlDollar = sqlS[sqlpt-5 : sqlpt+1]
-//line sql-gen.y:6925
+//line sql-gen.y:7944
 		{
 			return helpWith(sqllex, "ALTER VIRTUAL CLUSTER SETTING")
 		}
-	case 1048:
+	case 1228:
 		sqlDollar = sqlS[sqlpt-4 : sqlpt+1]
-//line sql-gen.y:6926
+//line sql-gen.y:7945
 		{
 			return helpWith(sqllex, "ALTER VIRTUAL CLUSTER SETTING")
 		}
-	case 1053:
+	case 1233:
 		sqlDollar = sqlS[sqlpt-6 : sqlpt+1]
-//line sql-gen.y:6943
+//line sql-gen.y:7962
 		{
-
 			sqlVAL.union.val = &tree.AlterTenantCapability{
 				TenantSpec:   sqlDollar[3].union.tenantSpec(),
 				Capabilities: sqlDollar[6].union.tenantCapabilities(),
 			}
 		}
-	case 1054:
+	case 1234:
 		sqlDollar = sqlS[sqlpt-6 : sqlpt+1]
-//line sql-gen.y:6951
+//line sql-gen.y:7969
 		{
-
 			sqlVAL.union.val = &tree.AlterTenantCapability{
 				TenantSpec:      sqlDollar[3].union.tenantSpec(),
 				AllCapabilities: true,
 			}
 		}
-	case 1055:
+	case 1235:
 		sqlDollar = sqlS[sqlpt-6 : sqlpt+1]
-//line sql-gen.y:6959
+//line sql-gen.y:7976
 		{
-
 			sqlVAL.union.val = &tree.AlterTenantCapability{
 				TenantSpec:   sqlDollar[3].union.tenantSpec(),
 				Capabilities: sqlDollar[6].union.tenantCapabilities(),
 				IsRevoke:     true,
 			}
 		}
-	case 1056:
+	case 1236:
 		sqlDollar = sqlS[sqlpt-6 : sqlpt+1]
-//line sql-gen.y:6968
+//line sql-gen.y:7984
 		{
-
 			sqlVAL.union.val = &tree.AlterTenantCapability{
 				TenantSpec:      sqlDollar[3].union.tenantSpec(),
 				AllCapabilities: true,
 				IsRevoke:        true,
 			}
 		}
-	case 1057:
+	case 1237:
 		sqlDollar = sqlS[sqlpt-5 : sqlpt+1]
-//line sql-gen.y:6976
+//line sql-gen.y:7991
 		{
 			return helpWith(sqllex, "ALTER VIRTUAL CLUSTER CAPABILITY")
 		}
-	case 1058:
+	case 1238:
 		sqlDollar = sqlS[sqlpt-5 : sqlpt+1]
-//line sql-gen.y:6977
+//line sql-gen.y:7992
 		{
 			return helpWith(sqllex, "ALTER VIRTUAL CLUSTER CAPABILITY")
 		}
-	case 1059:
+	case 1239:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:6981
+//line sql-gen.y:7996
 		{
 
 			sqlVAL.union.val = tree.TenantCapability{
 				Name: strings.Join(sqlDollar[1].union.strs(), "."),
 			}
 		}
-	case 1060:
+	case 1240:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:6988
+//line sql-gen.y:8003
 		{
 
 			sqlVAL.union.val = tree.TenantCapability{
@@ -35394,553 +39033,583 @@ sqldefault:
 				Value: sqlDollar[3].union.expr(),
 			}
 		}
-	case 1061:
+	case 1241:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:6998
+//line sql-gen.y:8013
 		{
 
 			sqlVAL.union.val = []tree.TenantCapability{sqlDollar[1].union.tenantCapability()}
 		}
-	case 1062:
+	case 1242:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:7003
+//line sql-gen.y:8018
 		{
 
 			sqlVAL.union.val = append(sqlDollar[1].union.tenantCapabilities(), sqlDollar[3].union.tenantCapability())
 		}
-	case 1063:
+	case 1243:
 		sqlDollar = sqlS[sqlpt-5 : sqlpt+1]
-//line sql-gen.y:7012
+//line sql-gen.y:8027
 		{
 			sqlVAL.union.val = &tree.SetVar{Values: sqlDollar[4].union.exprs(), SetRow: true}
 		}
-	case 1064:
+	case 1244:
 		sqlDollar = sqlS[sqlpt-4 : sqlpt+1]
-//line sql-gen.y:7028
+//line sql-gen.y:8043
 		{
 
 			sqlVAL.union.val = &tree.SetTracing{Values: sqlDollar[4].union.exprs()}
 		}
-	case 1065:
+	case 1245:
 		sqlDollar = sqlS[sqlpt-5 : sqlpt+1]
-//line sql-gen.y:7034
+//line sql-gen.y:8049
 		{
 
 			sqlVAL.union.val = &tree.SetTracing{Values: sqlDollar[5].union.exprs()}
 		}
-	case 1066:
+	case 1246:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:7040
+//line sql-gen.y:8055
 		{
 			sqlVAL.union.val = sqlDollar[3].union.stmt()
 		}
-	case 1067:
+	case 1247:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:7043
+//line sql-gen.y:8058
 		{
 			return helpWith(sqllex, "SET SESSION")
 		}
-	case 1068:
+	case 1248:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:7045
+//line sql-gen.y:8060
 		{
 			sqlVAL.union.val = sqlDollar[2].union.stmt()
 		}
-	case 1069:
+	case 1249:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:7048
+//line sql-gen.y:8063
 		{
 			return helpWith(sqllex, "SET SESSION")
 		}
-	case 1070:
+	case 1250:
 		sqlDollar = sqlS[sqlpt-6 : sqlpt+1]
-//line sql-gen.y:7051
+//line sql-gen.y:8066
 		{
 			sqlVAL.union.val = &tree.SetSessionCharacteristics{Modes: sqlDollar[6].union.transactionModes()}
 		}
-	case 1071:
+	case 1251:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:7065
+//line sql-gen.y:8080
 		{
 			ret := sqlDollar[3].union.setVar()
 			ret.Local = true
 			sqlVAL.union.val = ret
 		}
-	case 1072:
+	case 1252:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:7070
+//line sql-gen.y:8085
 		{
 			return helpWith(sqllex, "SET LOCAL")
 		}
-	case 1073:
+	case 1253:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:7087
+//line sql-gen.y:8102
 		{
 			sqlVAL.union.val = &tree.SetTransaction{Modes: sqlDollar[3].union.transactionModes()}
 		}
-	case 1074:
+	case 1254:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:7090
+//line sql-gen.y:8105
 		{
 			return helpWith(sqllex, "SET TRANSACTION")
 		}
-	case 1075:
+	case 1255:
 		sqlDollar = sqlS[sqlpt-4 : sqlpt+1]
-//line sql-gen.y:7092
+//line sql-gen.y:8107
 		{
 			sqlVAL.union.val = &tree.SetTransaction{Modes: sqlDollar[4].union.transactionModes()}
 		}
-	case 1076:
+	case 1256:
 		sqlDollar = sqlS[sqlpt-4 : sqlpt+1]
-//line sql-gen.y:7095
+//line sql-gen.y:8110
 		{
 			return helpWith(sqllex, "SET TRANSACTION")
 		}
-	case 1077:
+	case 1257:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:7099
+//line sql-gen.y:8114
 		{
 			sqlVAL.union.val = &tree.SetVar{Name: strings.Join(sqlDollar[1].union.strs(), "."), Values: sqlDollar[3].union.exprs()}
 		}
-	case 1079:
+	case 1259:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:7111
+//line sql-gen.y:8126
 		{
 
 			sqlVAL.union.val = &tree.SetVar{Name: "timezone", Values: tree.Exprs{sqlDollar[3].union.expr()}}
 		}
-	case 1080:
+	case 1260:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:7115
+//line sql-gen.y:8130
 		{
 			return unimplemented(sqllex, "set from current")
 		}
-	case 1081:
+	case 1261:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:7119
+//line sql-gen.y:8134
 		{
 
 			sqlVAL.union.val = &tree.SetVar{Name: "search_path", Values: tree.Exprs{sqlDollar[2].union.expr()}}
 		}
-	case 1082:
+	case 1262:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:7124
+//line sql-gen.y:8139
 		{
 
 			sqlVAL.union.val = &tree.SetVar{Name: "role", Values: tree.Exprs{sqlDollar[2].union.expr()}}
 		}
-	case 1084:
+	case 1264:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:7133
+//line sql-gen.y:8148
 		{
 
 			sqlVAL.union.val = &tree.SetSessionAuthorizationDefault{}
 		}
-	case 1085:
+	case 1265:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:7138
+//line sql-gen.y:8153
 		{
 			return unimplementedWithIssue(sqllex, 40283)
 		}
-	case 1086:
+	case 1266:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:7142
+//line sql-gen.y:8157
 		{
 			return unimplementedWithIssue(sqllex, 40283)
 		}
-	case 1088:
+	case 1268:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:7154
+//line sql-gen.y:8169
 		{
 
 			sqlVAL.union.val = &tree.SetVar{Name: "client_encoding", Values: tree.Exprs{sqlDollar[2].union.expr()}}
 		}
-	case 1089:
+	case 1269:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:7159
+//line sql-gen.y:8174
 		{
 
 			sqlVAL.union.val = &tree.SetVar{Name: "client_encoding", Values: tree.Exprs{tree.DefaultVal{}}}
 		}
-	case 1090:
+	case 1270:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:7166
+//line sql-gen.y:8181
 		{
 			sqlVAL.union.val = []string{sqlDollar[1].str}
 		}
-	case 1091:
+	case 1271:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:7170
+//line sql-gen.y:8185
 		{
 			sqlVAL.union.val = append([]string{sqlDollar[1].str}, sqlDollar[2].union.strs()...)
 		}
-	case 1092:
+	case 1272:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:7176
+//line sql-gen.y:8191
 		{
 			sqlVAL.union.val = []string{sqlDollar[2].str}
 		}
-	case 1093:
+	case 1273:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:7180
+//line sql-gen.y:8195
 		{
 			sqlVAL.union.val = append(sqlDollar[1].union.strs(), sqlDollar[3].str)
 		}
-	case 1095:
+	case 1275:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:7187
+//line sql-gen.y:8202
 		{
 			sqlVAL.union.val = tree.Expr(&tree.UnresolvedName{NumParts: 1, Parts: tree.NameParts{sqlDollar[1].str}})
 		}
-	case 1099:
+	case 1279:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:7210
+//line sql-gen.y:8225
 		{
 			sqlVAL.union.val = tree.Exprs{sqlDollar[1].union.expr()}
 		}
-	case 1100:
+	case 1280:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:7214
+//line sql-gen.y:8229
 		{
 			sqlVAL.union.val = append(sqlDollar[1].union.exprs(), sqlDollar[3].union.expr())
 		}
-	case 1101:
+	case 1281:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:7220
+//line sql-gen.y:8235
 		{
 			sqlVAL.union.val = tree.ReadUncommittedIsolation
 		}
-	case 1102:
+	case 1282:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:7224
+//line sql-gen.y:8239
 		{
 			sqlVAL.union.val = tree.ReadCommittedIsolation
 		}
-	case 1103:
+	case 1283:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:7228
+//line sql-gen.y:8243
 		{
 			sqlVAL.union.val = tree.SnapshotIsolation
 		}
-	case 1104:
+	case 1284:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:7232
+//line sql-gen.y:8247
 		{
 			sqlVAL.union.val = tree.RepeatableReadIsolation
 		}
-	case 1105:
+	case 1285:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:7236
+//line sql-gen.y:8251
 		{
 			sqlVAL.union.val = tree.SerializableIsolation
 		}
-	case 1106:
+	case 1286:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:7242
+//line sql-gen.y:8257
 		{
 			sqlVAL.union.val = tree.Low
 		}
-	case 1107:
+	case 1287:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:7246
+//line sql-gen.y:8261
 		{
 			sqlVAL.union.val = tree.Normal
 		}
-	case 1108:
+	case 1288:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:7250
+//line sql-gen.y:8265
 		{
 			sqlVAL.union.val = tree.High
 		}
-	case 1109:
+	case 1289:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:7261
+//line sql-gen.y:8276
 		{
 			sqlVAL.union.val = tree.NewStrVal(sqlDollar[1].str)
 		}
-	case 1110:
+	case 1290:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:7265
+//line sql-gen.y:8280
 		{
 			sqlVAL.union.val = tree.NewStrVal(sqlDollar[1].str)
 		}
-	case 1111:
+	case 1291:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:7269
+//line sql-gen.y:8284
 		{
 			sqlVAL.union.val = sqlDollar[1].union.expr()
 		}
-	case 1113:
+	case 1293:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:7274
+//line sql-gen.y:8289
 		{
 			sqlVAL.union.val = tree.DefaultVal{}
 		}
-	case 1114:
+	case 1294:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:7278
+//line sql-gen.y:8293
 		{
 			sqlVAL.union.val = tree.NewStrVal(sqlDollar[1].str)
 		}
-	case 1116:
+	case 1296:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:7295
+//line sql-gen.y:8310
 		{
 			return helpWith(sqllex, "SHOW BACKUP")
 		}
-	case 1118:
+	case 1298:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:7296
+//line sql-gen.y:8311
 		{
 			return helpWith(sqllex, "SHOW COLUMNS")
 		}
-	case 1120:
+	case 1300:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:7297
+//line sql-gen.y:8312
 		{
 			return helpWith(sqllex, "SHOW CONSTRAINTS")
 		}
-	case 1122:
+	case 1302:
+		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
+//line sql-gen.y:8313
+		{
+			return helpWith(sqllex, "SHOW TRIGGERS")
+		}
+	case 1304:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:7298
+//line sql-gen.y:8314
 		{
 			return helpWith(sqllex, "SHOW CREATE")
 		}
-	case 1124:
+	case 1306:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:7299
+//line sql-gen.y:8315
 		{
 			return helpWith(sqllex, "SHOW CREATE SCHEDULES")
 		}
-	case 1126:
+	case 1308:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:7300
+//line sql-gen.y:8316
 		{
 			return helpWith(sqllex, "SHOW CREATE EXTERNAL CONNECTIONS")
 		}
-	case 1128:
+	case 1310:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:7301
+//line sql-gen.y:8317
 		{
 			return helpWith(sqllex, "SHOW CLUSTER SETTING")
 		}
-	case 1130:
+	case 1312:
+		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
+//line sql-gen.y:8318
+		{
+			return helpWith(sqllex, "SHOW LOGICAL REPLICATION JOBS")
+		}
+	case 1314:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:7302
+//line sql-gen.y:8319
 		{
 			return helpWith(sqllex, "SHOW DATABASES")
 		}
-	case 1132:
+	case 1316:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:7303
+//line sql-gen.y:8320
 		{
 			return helpWith(sqllex, "SHOW ENUMS")
 		}
-	case 1134:
+	case 1318:
+		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
+//line sql-gen.y:8321
+		{
+			return helpWith(sqllex, "SHOW EXTERNAL CONNECTIONS")
+		}
+	case 1320:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:7304
+//line sql-gen.y:8322
 		{
 			return helpWith(sqllex, "SHOW TYPES")
 		}
-	case 1137:
+	case 1323:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:7306
+//line sql-gen.y:8324
 		{
 			return helpWith(sqllex, "SHOW FUNCTIONS")
 		}
-	case 1139:
+	case 1325:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:7307
+//line sql-gen.y:8325
 		{
 			return helpWith(sqllex, "SHOW PROCEDURES")
 		}
-	case 1141:
+	case 1327:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:7308
+//line sql-gen.y:8326
 		{
 			return helpWith(sqllex, "SHOW GRANTS")
 		}
-	case 1143:
+	case 1329:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:7309
+//line sql-gen.y:8327
 		{
 			return helpWith(sqllex, "SHOW HISTOGRAM")
 		}
-	case 1145:
+	case 1331:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:7310
+//line sql-gen.y:8328
 		{
 			return helpWith(sqllex, "SHOW INDEXES")
 		}
-	case 1147:
+	case 1333:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:7311
+//line sql-gen.y:8329
 		{
 			return helpWith(sqllex, "SHOW PARTITIONS")
 		}
-	case 1149:
+	case 1335:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:7312
+//line sql-gen.y:8330
 		{
 			return helpWith(sqllex, "SHOW JOBS")
 		}
-	case 1152:
+	case 1338:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:7314
+//line sql-gen.y:8332
 		{
 			return helpWith(sqllex, "SHOW SCHEDULES")
 		}
-	case 1154:
+	case 1340:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:7315
+//line sql-gen.y:8333
 		{
 			return helpWith(sqllex, "SHOW STATEMENTS")
 		}
-	case 1156:
+	case 1342:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:7316
+//line sql-gen.y:8334
 		{
 			return helpWith(sqllex, "SHOW RANGES")
 		}
-	case 1159:
+	case 1345:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:7318
+//line sql-gen.y:8336
 		{
 			return helpWith(sqllex, "SHOW REGIONS")
 		}
-	case 1162:
+	case 1348:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:7320
+//line sql-gen.y:8338
 		{
 			return helpWith(sqllex, "SHOW ROLES")
 		}
-	case 1164:
+	case 1350:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:7321
+//line sql-gen.y:8339
 		{
 			return helpWith(sqllex, "SHOW SAVEPOINT")
 		}
-	case 1166:
+	case 1352:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:7322
+//line sql-gen.y:8340
 		{
 			return helpWith(sqllex, "SHOW SCHEMAS")
 		}
-	case 1168:
+	case 1354:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:7323
+//line sql-gen.y:8341
 		{
 			return helpWith(sqllex, "SHOW SEQUENCES")
 		}
-	case 1170:
+	case 1356:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:7324
+//line sql-gen.y:8342
 		{
 			return helpWith(sqllex, "SHOW SESSION")
 		}
-	case 1172:
+	case 1358:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:7325
+//line sql-gen.y:8343
 		{
 			return helpWith(sqllex, "SHOW SESSIONS")
 		}
-	case 1174:
+	case 1360:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:7326
+//line sql-gen.y:8344
 		{
 			return helpWith(sqllex, "SHOW STATISTICS")
 		}
-	case 1176:
+	case 1362:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:7327
+//line sql-gen.y:8345
 		{
 			return helpWith(sqllex, "SHOW SYNTAX")
 		}
-	case 1178:
+	case 1364:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:7328
+//line sql-gen.y:8346
 		{
 			return helpWith(sqllex, "SHOW TABLES")
 		}
-	case 1180:
+	case 1366:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:7329
+//line sql-gen.y:8347
 		{
 			return helpWith(sqllex, "SHOW VIRTUAL CLUSTER")
 		}
-	case 1182:
+	case 1368:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:7330
+//line sql-gen.y:8348
 		{
 			return helpWith(sqllex, "SHOW TRACE")
 		}
-	case 1184:
+	case 1370:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:7331
+//line sql-gen.y:8349
 		{
 			return helpWith(sqllex, "SHOW TRANSACTION")
 		}
-	case 1186:
+	case 1372:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:7332
+//line sql-gen.y:8350
 		{
 			return helpWith(sqllex, "SHOW TRANSACTIONS")
 		}
-	case 1188:
+	case 1374:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:7333
+//line sql-gen.y:8351
 		{
 			return helpWith(sqllex, "SHOW TRANSFER")
 		}
-	case 1190:
+	case 1376:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:7334
+//line sql-gen.y:8352
 		{
 			return helpWith(sqllex, "SHOW USERS")
 		}
-	case 1192:
+	case 1378:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:7335
+//line sql-gen.y:8353
+		{
+			return helpWith(sqllex, "SHOW DEFAULT SESSION VARIABLES FOR ROLE")
+		}
+	case 1380:
+		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
+//line sql-gen.y:8354
 		{
 			return helpWith(sqllex, "SHOW ZONE CONFIGURATION")
 		}
-	case 1193:
+	case 1382:
+		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
+//line sql-gen.y:8355
+		{
+			return helpWith(sqllex, "SHOW POLICIES")
+		}
+	case 1383:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:7336
+//line sql-gen.y:8356
 		{
 			return helpWith(sqllex, "SHOW")
 		}
-	case 1197:
+	case 1387:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:7339
+//line sql-gen.y:8359
 		{
 			return helpWith(sqllex, "SHOW DEFAULT PRIVILEGES")
 		}
-	case 1199:
+	case 1389:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:7348
+//line sql-gen.y:8368
 		{
 			sqlVAL.union.val = &tree.CloseCursor{
 				All: true,
 			}
 		}
-	case 1200:
+	case 1390:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:7354
+//line sql-gen.y:8374
 		{
 			sqlVAL.union.val = &tree.CloseCursor{
 				Name: tree.Name(sqlDollar[2].str),
 			}
 		}
-	case 1201:
+	case 1391:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:7359
+//line sql-gen.y:8379
 		{
 			return helpWith(sqllex, "CLOSE")
 		}
-	case 1202:
+	case 1392:
 		sqlDollar = sqlS[sqlpt-9 : sqlpt+1]
-//line sql-gen.y:7369
+//line sql-gen.y:8389
 		{
 			sqlVAL.union.val = &tree.DeclareCursor{
 				Binary:      sqlDollar[3].union.bool(),
@@ -35951,154 +39620,154 @@ sqldefault:
 				Select:      sqlDollar[9].union.slct(),
 			}
 		}
-	case 1203:
+	case 1393:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:7379
+//line sql-gen.y:8399
 		{
 			return helpWith(sqllex, "DECLARE")
 		}
-	case 1204:
+	case 1394:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:7383
+//line sql-gen.y:8403
 		{
 			sqlVAL.union.val = true
 		}
-	case 1205:
+	case 1395:
 		sqlDollar = sqlS[sqlpt-0 : sqlpt+1]
-//line sql-gen.y:7387
+//line sql-gen.y:8407
 		{
 			sqlVAL.union.val = false
 		}
-	case 1206:
+	case 1396:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:7393
+//line sql-gen.y:8413
 		{
 			sqlVAL.union.val = tree.Insensitive
 		}
-	case 1207:
+	case 1397:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:7397
+//line sql-gen.y:8417
 		{
 			sqlVAL.union.val = tree.Asensitive
 		}
-	case 1208:
+	case 1398:
 		sqlDollar = sqlS[sqlpt-0 : sqlpt+1]
-//line sql-gen.y:7401
+//line sql-gen.y:8421
 		{
 			sqlVAL.union.val = tree.UnspecifiedSensitivity
 		}
-	case 1209:
+	case 1399:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:7407
+//line sql-gen.y:8427
 		{
 			sqlVAL.union.val = tree.Scroll
 		}
-	case 1210:
+	case 1400:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:7411
+//line sql-gen.y:8431
 		{
 			sqlVAL.union.val = tree.NoScroll
 		}
-	case 1211:
+	case 1401:
 		sqlDollar = sqlS[sqlpt-0 : sqlpt+1]
-//line sql-gen.y:7415
+//line sql-gen.y:8435
 		{
 			sqlVAL.union.val = tree.UnspecifiedScroll
 		}
-	case 1212:
+	case 1402:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:7421
+//line sql-gen.y:8441
 		{
 			sqlVAL.union.val = true
 		}
-	case 1213:
+	case 1403:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:7425
+//line sql-gen.y:8445
 		{
 			sqlVAL.union.val = false
 		}
-	case 1214:
+	case 1404:
 		sqlDollar = sqlS[sqlpt-0 : sqlpt+1]
-//line sql-gen.y:7429
+//line sql-gen.y:8449
 		{
 			sqlVAL.union.val = false
 		}
-	case 1215:
+	case 1405:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:7439
+//line sql-gen.y:8459
 		{
 			sqlVAL.union.val = &tree.FetchCursor{
 				CursorStmt: sqlDollar[2].union.cursorStmt(),
 			}
 		}
-	case 1216:
+	case 1406:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:7444
+//line sql-gen.y:8464
 		{
 			return helpWith(sqllex, "FETCH")
 		}
-	case 1217:
+	case 1407:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:7452
+//line sql-gen.y:8472
 		{
 			sqlVAL.union.val = &tree.MoveCursor{
 				CursorStmt: sqlDollar[2].union.cursorStmt(),
 			}
 		}
-	case 1218:
+	case 1408:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:7457
+//line sql-gen.y:8477
 		{
 			return helpWith(sqllex, "MOVE")
 		}
-	case 1219:
+	case 1409:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:7461
+//line sql-gen.y:8481
 		{
 			sqlVAL.union.val = tree.CursorStmt{
 				Name:  tree.Name(sqlDollar[1].str),
 				Count: 1,
 			}
 		}
-	case 1220:
+	case 1410:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:7468
+//line sql-gen.y:8488
 		{
 			sqlVAL.union.val = tree.CursorStmt{
 				Name:  tree.Name(sqlDollar[2].str),
 				Count: 1,
 			}
 		}
-	case 1221:
+	case 1411:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:7475
+//line sql-gen.y:8495
 		{
 			sqlVAL.union.val = tree.CursorStmt{
 				Name:  tree.Name(sqlDollar[3].str),
 				Count: sqlDollar[1].union.int64(),
 			}
 		}
-	case 1222:
+	case 1412:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:7482
+//line sql-gen.y:8502
 		{
 			sqlVAL.union.val = tree.CursorStmt{
 				Name:  tree.Name(sqlDollar[3].str),
 				Count: sqlDollar[1].union.int64(),
 			}
 		}
-	case 1223:
+	case 1413:
 		sqlDollar = sqlS[sqlpt-4 : sqlpt+1]
-//line sql-gen.y:7489
+//line sql-gen.y:8509
 		{
 			sqlVAL.union.val = tree.CursorStmt{
 				Name:  tree.Name(sqlDollar[4].str),
 				Count: sqlDollar[2].union.int64() * sqlDollar[1].union.int64(),
 			}
 		}
-	case 1224:
+	case 1414:
 		sqlDollar = sqlS[sqlpt-4 : sqlpt+1]
-//line sql-gen.y:7496
+//line sql-gen.y:8516
 		{
 			fetchType := tree.FetchAll
 			count := sqlDollar[1].union.int64()
@@ -36110,9 +39779,9 @@ sqldefault:
 				FetchType: fetchType,
 			}
 		}
-	case 1225:
+	case 1415:
 		sqlDollar = sqlS[sqlpt-4 : sqlpt+1]
-//line sql-gen.y:7508
+//line sql-gen.y:8528
 		{
 			sqlVAL.union.val = tree.CursorStmt{
 				Name:      tree.Name(sqlDollar[4].str),
@@ -36120,9 +39789,9 @@ sqldefault:
 				Count:     sqlDollar[2].union.int64(),
 			}
 		}
-	case 1226:
+	case 1416:
 		sqlDollar = sqlS[sqlpt-4 : sqlpt+1]
-//line sql-gen.y:7516
+//line sql-gen.y:8536
 		{
 			sqlVAL.union.val = tree.CursorStmt{
 				Name:      tree.Name(sqlDollar[4].str),
@@ -36130,193 +39799,193 @@ sqldefault:
 				Count:     sqlDollar[2].union.int64(),
 			}
 		}
-	case 1227:
+	case 1417:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:7524
+//line sql-gen.y:8544
 		{
 			sqlVAL.union.val = tree.CursorStmt{
 				Name:      tree.Name(sqlDollar[3].str),
 				FetchType: tree.FetchFirst,
 			}
 		}
-	case 1228:
+	case 1418:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:7531
+//line sql-gen.y:8551
 		{
 			sqlVAL.union.val = tree.CursorStmt{
 				Name:      tree.Name(sqlDollar[3].str),
 				FetchType: tree.FetchLast,
 			}
 		}
-	case 1229:
+	case 1419:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:7539
+//line sql-gen.y:8559
 		{
 			sqlVAL.union.val = int64(1)
 		}
-	case 1230:
+	case 1420:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:7540
+//line sql-gen.y:8560
 		{
 			sqlVAL.union.val = int64(-1)
 		}
-	case 1231:
+	case 1421:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:7543
+//line sql-gen.y:8563
 		{
 			sqlVAL.union.val = sqlDollar[1].union.int64()
 		}
-	case 1232:
+	case 1422:
 		sqlDollar = sqlS[sqlpt-0 : sqlpt+1]
-//line sql-gen.y:7544
+//line sql-gen.y:8564
 		{
 			sqlVAL.union.val = int64(1)
 		}
-	case 1233:
+	case 1423:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:7547
+//line sql-gen.y:8567
 		{
 			sqlVAL.union.val = int64(1)
 		}
-	case 1234:
+	case 1424:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:7548
+//line sql-gen.y:8568
 		{
 			sqlVAL.union.val = int64(-1)
 		}
-	case 1235:
+	case 1425:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:7551
+//line sql-gen.y:8571
 		{
 		}
-	case 1236:
+	case 1426:
 		sqlDollar = sqlS[sqlpt-0 : sqlpt+1]
-//line sql-gen.y:7552
+//line sql-gen.y:8572
 		{
 		}
-	case 1237:
+	case 1427:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:7555
+//line sql-gen.y:8575
 		{
 		}
-	case 1238:
+	case 1428:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:7556
+//line sql-gen.y:8576
 		{
 		}
-	case 1239:
+	case 1429:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:7560
+//line sql-gen.y:8580
 		{
 
 			return purposelyUnimplemented(sqllex, "reindex table", "CockroachDB does not require reindexing.")
 		}
-	case 1240:
+	case 1430:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:7565
+//line sql-gen.y:8585
 		{
 
 			return purposelyUnimplemented(sqllex, "reindex index", "CockroachDB does not require reindexing.")
 		}
-	case 1241:
+	case 1431:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:7570
+//line sql-gen.y:8590
 		{
 
 			return purposelyUnimplemented(sqllex, "reindex schema", "CockroachDB does not require reindexing.")
 		}
-	case 1242:
+	case 1432:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:7575
+//line sql-gen.y:8595
 		{
 
 			return purposelyUnimplemented(sqllex, "reindex database", "CockroachDB does not require reindexing.")
 		}
-	case 1243:
+	case 1433:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:7580
+//line sql-gen.y:8600
 		{
 
 			return purposelyUnimplemented(sqllex, "reindex system", "CockroachDB does not require reindexing.")
 		}
-	case 1244:
+	case 1434:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:7590
+//line sql-gen.y:8610
 		{
 			sqlVAL.union.val = &tree.ShowVar{Name: sqlDollar[2].str}
 		}
-	case 1245:
+	case 1435:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:7591
+//line sql-gen.y:8611
 		{
 			sqlVAL.union.val = &tree.ShowVar{Name: sqlDollar[3].str}
 		}
-	case 1246:
+	case 1436:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:7592
+//line sql-gen.y:8612
 		{
 			return helpWith(sqllex, "SHOW SESSION")
 		}
-	case 1248:
+	case 1438:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:7597
+//line sql-gen.y:8617
 		{
 			sqlVAL.str = sqlDollar[1].str + "." + strings.Join(sqlDollar[2].union.strs(), ".")
 		}
-	case 1251:
+	case 1441:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:7607
+//line sql-gen.y:8627
 		{
 			sqlVAL.str = "client_encoding"
 		}
-	case 1256:
+	case 1446:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:7612
+//line sql-gen.y:8632
 		{
 		}
-	case 1257:
+	case 1447:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:7614
+//line sql-gen.y:8634
 		{
 
 			sqlVAL.str = sqlDollar[1].str + "." + strings.Join(sqlDollar[2].union.strs(), ".")
 		}
-	case 1258:
+	case 1448:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:7619
+//line sql-gen.y:8639
 		{
 			sqlVAL.str = "timezone"
 		}
-	case 1259:
+	case 1449:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:7620
+//line sql-gen.y:8640
 		{
 			return helpWith(sqllex, "SHOW SESSION")
 		}
-	case 1261:
+	case 1451:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:7625
+//line sql-gen.y:8645
 		{
 			sqlVAL.union.val = []string{sqlDollar[2].str}
 		}
-	case 1262:
+	case 1452:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:7629
+//line sql-gen.y:8649
 		{
 			sqlVAL.union.val = append(sqlDollar[1].union.strs(), sqlDollar[3].str)
 		}
-	case 1263:
+	case 1453:
 		sqlDollar = sqlS[sqlpt-6 : sqlpt+1]
-//line sql-gen.y:7649
+//line sql-gen.y:8669
 		{
 			sqlVAL.union.val = &tree.ShowTableStats{
 				Table:   sqlDollar[5].union.unresolvedObjectName(),
 				Options: sqlDollar[6].union.kvOptions(),
 			}
 		}
-	case 1264:
+	case 1454:
 		sqlDollar = sqlS[sqlpt-8 : sqlpt+1]
-//line sql-gen.y:7656
+//line sql-gen.y:8676
 		{
 
 			sqlVAL.union.val = &tree.ShowTableStats{
@@ -36325,15 +39994,15 @@ sqldefault:
 				Options:   sqlDollar[8].union.kvOptions(),
 			}
 		}
-	case 1265:
+	case 1455:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:7664
+//line sql-gen.y:8684
 		{
 			return helpWith(sqllex, "SHOW STATISTICS")
 		}
-	case 1266:
+	case 1456:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:7677
+//line sql-gen.y:8697
 		{
 
 			id, err := sqlDollar[3].union.numVal().AsInt64()
@@ -36342,23 +40011,23 @@ sqldefault:
 			}
 			sqlVAL.union.val = &tree.ShowHistogram{HistogramID: id}
 		}
-	case 1267:
+	case 1457:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:7685
+//line sql-gen.y:8705
 		{
 			return helpWith(sqllex, "SHOW HISTOGRAM")
 		}
-	case 1268:
+	case 1458:
 		sqlDollar = sqlS[sqlpt-4 : sqlpt+1]
-//line sql-gen.y:7693
+//line sql-gen.y:8713
 		{
 			sqlVAL.union.val = &tree.ShowBackup{
 				InCollection: sqlDollar[4].union.stringOrPlaceholderOptList(),
 			}
 		}
-	case 1269:
+	case 1459:
 		sqlDollar = sqlS[sqlpt-8 : sqlpt+1]
-//line sql-gen.y:7699
+//line sql-gen.y:8719
 		{
 			sqlVAL.union.val = &tree.ShowBackup{
 				From:         true,
@@ -36368,9 +40037,9 @@ sqldefault:
 				Options:      *sqlDollar[8].union.showBackupOptions(),
 			}
 		}
-	case 1270:
+	case 1460:
 		sqlDollar = sqlS[sqlpt-6 : sqlpt+1]
-//line sql-gen.y:7709
+//line sql-gen.y:8729
 		{
 			sqlVAL.union.val = &tree.ShowBackup{
 				Details:      tree.BackupDefaultDetails,
@@ -36379,309 +40048,242 @@ sqldefault:
 				Options:      *sqlDollar[6].union.showBackupOptions(),
 			}
 		}
-	case 1271:
-		sqlDollar = sqlS[sqlpt-4 : sqlpt+1]
-//line sql-gen.y:7718
+	case 1461:
+		sqlDollar = sqlS[sqlpt-5 : sqlpt+1]
+//line sql-gen.y:8738
 		{
-			sqlVAL.union.val = &tree.ShowBackup{
-				Details: tree.BackupDefaultDetails,
-				Path:    sqlDollar[3].union.expr(),
-				Options: *sqlDollar[4].union.showBackupOptions(),
-			}
+			setErr(sqllex, errors.New("The `SHOW BACKUP` syntax without the `IN` keyword is no longer supported. Please use `SHOW BACKUP FROM <subdirectory> IN <collectionURI>`."))
+			return helpWith(sqllex, "SHOW BACKUP")
 		}
-	case 1272:
-		sqlDollar = sqlS[sqlpt-5 : sqlpt+1]
-//line sql-gen.y:7726
+	case 1462:
+		sqlDollar = sqlS[sqlpt-6 : sqlpt+1]
+//line sql-gen.y:8743
 		{
-			sqlVAL.union.val = &tree.ShowBackup{
-				Details: tree.BackupSchemaDetails,
-				Path:    sqlDollar[4].union.expr(),
-				Options: *sqlDollar[5].union.showBackupOptions(),
-			}
+			setErr(sqllex, errors.New("The `SHOW BACKUP SCHEMAS` syntax without the `IN` keyword is no longer supported. Please use `SHOW BACKUP SCHEMAS FROM <subdirectory> IN <collectionURI>`."))
+			return helpWith(sqllex, "SHOW BACKUP")
 		}
-	case 1273:
-		sqlDollar = sqlS[sqlpt-5 : sqlpt+1]
-//line sql-gen.y:7734
+	case 1463:
+		sqlDollar = sqlS[sqlpt-6 : sqlpt+1]
+//line sql-gen.y:8748
 		{
-			sqlVAL.union.val = &tree.ShowBackup{
-				Details: tree.BackupFileDetails,
-				Path:    sqlDollar[4].union.expr(),
-				Options: *sqlDollar[5].union.showBackupOptions(),
-			}
+
+			setErr(sqllex, errors.New("The `SHOW BACKUP FILES` syntax without the `IN` keyword is no longer supported. Please use `SHOW BACKUP FILES FROM <subdirectory> IN <collectionURI>`."))
+			return helpWith(sqllex, "SHOW BACKUP")
 		}
-	case 1274:
-		sqlDollar = sqlS[sqlpt-5 : sqlpt+1]
-//line sql-gen.y:7742
+	case 1464:
+		sqlDollar = sqlS[sqlpt-6 : sqlpt+1]
+//line sql-gen.y:8754
 		{
-			sqlVAL.union.val = &tree.ShowBackup{
-				Details: tree.BackupRangeDetails,
-				Path:    sqlDollar[4].union.expr(),
-				Options: *sqlDollar[5].union.showBackupOptions(),
-			}
+
+			setErr(sqllex, errors.New("The `SHOW BACKUP RANGES` syntax without the `IN` keyword is no longer supported. Please use `SHOW BACKUP RANGES FROM <subdirectory> IN <collectionURI>`."))
+			return helpWith(sqllex, "SHOW BACKUP")
 		}
-	case 1275:
-		sqlDollar = sqlS[sqlpt-5 : sqlpt+1]
-//line sql-gen.y:7750
+	case 1465:
+		sqlDollar = sqlS[sqlpt-6 : sqlpt+1]
+//line sql-gen.y:8760
 		{
-			sqlVAL.union.val = &tree.ShowBackup{
-				Details: tree.BackupValidateDetails,
-				Path:    sqlDollar[4].union.expr(),
-				Options: *sqlDollar[5].union.showBackupOptions(),
-			}
+
+			setErr(sqllex, errors.New("The `SHOW BACKUP VALIDATE` syntax without the `IN` keyword is no longer supported. Please use `SHOW BACKUP VALIDATE FROM <subdirectory> IN <collectionURI>`."))
+			return helpWith(sqllex, "SHOW BACKUP")
 		}
-	case 1276:
+	case 1466:
 		sqlDollar = sqlS[sqlpt-5 : sqlpt+1]
-//line sql-gen.y:7758
+//line sql-gen.y:8766
 		{
-			sqlVAL.union.val = &tree.ShowBackup{
-				Details: tree.BackupConnectionTest,
-				Path:    sqlDollar[4].union.expr(),
-				Options: *sqlDollar[5].union.showBackupOptions(),
-			}
+
+			setErr(sqllex, errors.New("The `SHOW BACKUP CONNECTION` syntax is no longer supported. Please use `CHECK EXTERNAL CONNECTION`."))
+			return helpWith(sqllex, "CHECK EXTERNAL CONNECTION")
 		}
-	case 1277:
+	case 1467:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:7765
+//line sql-gen.y:8771
 		{
 			return helpWith(sqllex, "SHOW BACKUP")
 		}
-	case 1278:
+	case 1468:
 		sqlDollar = sqlS[sqlpt-0 : sqlpt+1]
-//line sql-gen.y:7769
+//line sql-gen.y:8775
 		{
 			sqlVAL.union.val = tree.BackupDefaultDetails
 		}
-	case 1279:
+	case 1469:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:7773
+//line sql-gen.y:8779
 		{
 			sqlVAL.union.val = tree.BackupSchemaDetails
 		}
-	case 1280:
+	case 1470:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:7777
+//line sql-gen.y:8783
 		{
+
 			sqlVAL.union.val = tree.BackupFileDetails
 		}
-	case 1281:
+	case 1471:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:7781
+//line sql-gen.y:8788
 		{
+
 			sqlVAL.union.val = tree.BackupRangeDetails
 		}
-	case 1282:
+	case 1472:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:7785
+//line sql-gen.y:8793
 		{
+
 			sqlVAL.union.val = tree.BackupValidateDetails
 		}
-	case 1283:
+	case 1473:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:7791
+//line sql-gen.y:8800
 		{
 			sqlVAL.union.val = sqlDollar[2].union.showBackupOptions()
 		}
-	case 1284:
+	case 1474:
 		sqlDollar = sqlS[sqlpt-5 : sqlpt+1]
-//line sql-gen.y:7795
+//line sql-gen.y:8804
 		{
 			sqlVAL.union.val = sqlDollar[4].union.showBackupOptions()
 		}
-	case 1285:
+	case 1475:
 		sqlDollar = sqlS[sqlpt-0 : sqlpt+1]
-//line sql-gen.y:7799
+//line sql-gen.y:8808
 		{
 			sqlVAL.union.val = &tree.ShowBackupOptions{}
 		}
-	case 1286:
+	case 1476:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:7806
+//line sql-gen.y:8815
 		{
 			sqlVAL.union.val = sqlDollar[1].union.showBackupOptions()
 		}
-	case 1287:
+	case 1477:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:7810
+//line sql-gen.y:8819
 		{
 			if err := sqlDollar[1].union.showBackupOptions().CombineWith(sqlDollar[3].union.showBackupOptions()); err != nil {
 				return setErr(sqllex, err)
 			}
 		}
-	case 1288:
+	case 1478:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:7818
+//line sql-gen.y:8827
 		{
 			sqlVAL.union.val = &tree.ShowBackupOptions{AsJson: true}
 		}
-	case 1289:
+	case 1479:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:7822
+//line sql-gen.y:8831
 		{
 			sqlVAL.union.val = &tree.ShowBackupOptions{CheckFiles: true}
 		}
-	case 1290:
+	case 1480:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:7826
+//line sql-gen.y:8835
 		{
 			sqlVAL.union.val = &tree.ShowBackupOptions{SkipSize: true}
 		}
-	case 1291:
+	case 1481:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:7830
+//line sql-gen.y:8839
 		{
 
 			sqlVAL.union.val = &tree.ShowBackupOptions{SkipSize: true}
 		}
-	case 1292:
+	case 1482:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:7835
+//line sql-gen.y:8844
 		{
 			sqlVAL.union.val = &tree.ShowBackupOptions{DebugIDs: true}
 		}
-	case 1293:
+	case 1483:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:7839
+//line sql-gen.y:8848
 		{
 			sqlVAL.union.val = &tree.ShowBackupOptions{IncrementalStorage: sqlDollar[3].union.stringOrPlaceholderOptList()}
 		}
-	case 1294:
+	case 1484:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:7843
+//line sql-gen.y:8852
 		{
 			sqlVAL.union.val = &tree.ShowBackupOptions{DecryptionKMSURI: sqlDollar[3].union.stringOrPlaceholderOptList()}
 		}
-	case 1295:
+	case 1485:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:7847
+//line sql-gen.y:8856
 		{
 			sqlVAL.union.val = &tree.ShowBackupOptions{EncryptionPassphrase: sqlDollar[3].union.expr()}
 		}
-	case 1296:
+	case 1486:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:7851
+//line sql-gen.y:8860
 		{
 			sqlVAL.union.val = &tree.ShowBackupOptions{Privileges: true}
 		}
-	case 1297:
+	case 1487:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:7855
+//line sql-gen.y:8864
 		{
 			sqlVAL.union.val = &tree.ShowBackupOptions{EncryptionInfoDir: sqlDollar[3].union.expr()}
 		}
-	case 1298:
-		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:7859
-		{
-			sqlVAL.union.val = &tree.ShowBackupOptions{DebugMetadataSST: true}
-		}
-	case 1299:
-		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:7865
-		{
-			sqlVAL.union.val = sqlDollar[2].union.showBackupOptions()
-		}
-	case 1300:
-		sqlDollar = sqlS[sqlpt-5 : sqlpt+1]
-//line sql-gen.y:7869
-		{
-			sqlVAL.union.val = sqlDollar[4].union.showBackupOptions()
-		}
-	case 1301:
-		sqlDollar = sqlS[sqlpt-0 : sqlpt+1]
-//line sql-gen.y:7873
-		{
-			sqlVAL.union.val = &tree.ShowBackupOptions{}
-		}
-	case 1302:
-		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:7880
-		{
-			sqlVAL.union.val = sqlDollar[1].union.showBackupOptions()
-		}
-	case 1303:
-		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:7884
-		{
-			if err := sqlDollar[1].union.showBackupOptions().CombineWith(sqlDollar[3].union.showBackupOptions()); err != nil {
-				return setErr(sqllex, err)
-			}
-		}
-	case 1304:
-		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:7892
-		{
-			sqlVAL.union.val = &tree.ShowBackupOptions{CheckConnectionTransferSize: sqlDollar[3].union.expr()}
-		}
-	case 1305:
-		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:7896
-		{
-			sqlVAL.union.val = &tree.ShowBackupOptions{CheckConnectionDuration: sqlDollar[3].union.expr()}
-		}
-	case 1306:
-		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:7900
-		{
-			sqlVAL.union.val = &tree.ShowBackupOptions{CheckConnectionConcurrency: sqlDollar[3].union.expr()}
-		}
-	case 1307:
+	case 1488:
 		sqlDollar = sqlS[sqlpt-4 : sqlpt+1]
-//line sql-gen.y:7912
+//line sql-gen.y:8876
 		{
 			sqlVAL.union.val = &tree.ShowClusterSetting{Name: strings.Join(sqlDollar[4].union.strs(), ".")}
 		}
-	case 1308:
+	case 1489:
 		sqlDollar = sqlS[sqlpt-4 : sqlpt+1]
-//line sql-gen.y:7916
+//line sql-gen.y:8880
 		{
 			sqlVAL.union.val = &tree.ShowClusterSettingList{All: true}
 		}
-	case 1309:
+	case 1490:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:7919
+//line sql-gen.y:8883
 		{
 			return helpWith(sqllex, "SHOW CLUSTER SETTING")
 		}
-	case 1310:
+	case 1491:
 		sqlDollar = sqlS[sqlpt-4 : sqlpt+1]
-//line sql-gen.y:7921
+//line sql-gen.y:8885
 		{
 			sqlVAL.union.val = &tree.ShowClusterSettingList{All: true}
 		}
-	case 1311:
+	case 1492:
 		sqlDollar = sqlS[sqlpt-4 : sqlpt+1]
-//line sql-gen.y:7924
+//line sql-gen.y:8888
 		{
 			return helpWith(sqllex, "SHOW CLUSTER SETTING")
 		}
-	case 1312:
+	case 1493:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:7926
+//line sql-gen.y:8890
 		{
 			sqlVAL.union.val = &tree.ShowClusterSettingList{}
 		}
-	case 1313:
+	case 1494:
 		sqlDollar = sqlS[sqlpt-4 : sqlpt+1]
-//line sql-gen.y:7930
+//line sql-gen.y:8894
 		{
 			sqlVAL.union.val = &tree.ShowClusterSettingList{}
 		}
-	case 1314:
+	case 1495:
 		sqlDollar = sqlS[sqlpt-4 : sqlpt+1]
-//line sql-gen.y:7933
+//line sql-gen.y:8897
 		{
 			return helpWith(sqllex, "SHOW CLUSTER SETTING")
 		}
-	case 1315:
+	case 1496:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:7937
+//line sql-gen.y:8901
 		{
 
 			sqlVAL.union.val = sqlDollar[1].union.stmt()
 		}
-	case 1316:
+	case 1497:
 		sqlDollar = sqlS[sqlpt-4 : sqlpt+1]
-//line sql-gen.y:7942
+//line sql-gen.y:8906
 		{
 
 			switch t := sqlDollar[1].union.stmt().(type) {
@@ -36697,78 +40299,78 @@ sqldefault:
 				}
 			}
 		}
-	case 1317:
+	case 1498:
 		sqlDollar = sqlS[sqlpt-4 : sqlpt+1]
-//line sql-gen.y:7957
+//line sql-gen.y:8921
 		{
 			return helpWith(sqllex, "SHOW CLUSTER SETTING")
 		}
-	case 1318:
+	case 1499:
 		sqlDollar = sqlS[sqlpt-5 : sqlpt+1]
-//line sql-gen.y:7965
+//line sql-gen.y:8929
 		{
 			sqlVAL.union.val = &tree.ShowColumns{Table: sqlDollar[4].union.unresolvedObjectName(), WithComment: sqlDollar[5].union.bool()}
 		}
-	case 1319:
+	case 1500:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:7968
+//line sql-gen.y:8932
 		{
 			return helpWith(sqllex, "SHOW COLUMNS")
 		}
-	case 1320:
+	case 1501:
 		sqlDollar = sqlS[sqlpt-5 : sqlpt+1]
-//line sql-gen.y:7976
+//line sql-gen.y:8940
 		{
 			sqlVAL.union.val = &tree.ShowPartitions{IsTable: true, Table: sqlDollar[5].union.unresolvedObjectName()}
 		}
-	case 1321:
+	case 1502:
 		sqlDollar = sqlS[sqlpt-5 : sqlpt+1]
-//line sql-gen.y:7980
+//line sql-gen.y:8944
 		{
 			sqlVAL.union.val = &tree.ShowPartitions{IsDB: true, Database: tree.Name(sqlDollar[5].str)}
 		}
-	case 1322:
+	case 1503:
 		sqlDollar = sqlS[sqlpt-5 : sqlpt+1]
-//line sql-gen.y:7984
+//line sql-gen.y:8948
 		{
 			sqlVAL.union.val = &tree.ShowPartitions{IsIndex: true, Index: sqlDollar[5].union.tableIndexName()}
 		}
-	case 1323:
+	case 1504:
 		sqlDollar = sqlS[sqlpt-7 : sqlpt+1]
-//line sql-gen.y:7988
+//line sql-gen.y:8952
 		{
 			sqlVAL.union.val = &tree.ShowPartitions{IsTable: true, Table: sqlDollar[5].union.unresolvedObjectName()}
 		}
-	case 1324:
+	case 1505:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:7991
+//line sql-gen.y:8955
 		{
 			return helpWith(sqllex, "SHOW PARTITIONS")
 		}
-	case 1325:
+	case 1506:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:7999
+//line sql-gen.y:8963
 		{
 			sqlVAL.union.val = &tree.ShowDatabases{WithComment: sqlDollar[3].union.bool()}
 		}
-	case 1326:
+	case 1507:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:8002
+//line sql-gen.y:8966
 		{
 			return helpWith(sqllex, "SHOW DATABASES")
 		}
-	case 1327:
+	case 1508:
 		sqlDollar = sqlS[sqlpt-5 : sqlpt+1]
-//line sql-gen.y:8009
+//line sql-gen.y:8973
 		{
 			sqlVAL.union.val = &tree.ShowDefaultPrivileges{
 				Roles:  sqlDollar[4].union.roleSpecList(),
 				Schema: tree.Name(sqlDollar[5].str),
 			}
 		}
-	case 1328:
+	case 1509:
 		sqlDollar = sqlS[sqlpt-7 : sqlpt+1]
-//line sql-gen.y:8015
+//line sql-gen.y:8979
 		{
 			sqlVAL.union.val = &tree.ShowDefaultPrivileges{
 				Roles:      sqlDollar[6].union.roleSpecList(),
@@ -36776,30 +40378,30 @@ sqldefault:
 				Schema:     tree.Name(sqlDollar[7].str),
 			}
 		}
-	case 1329:
+	case 1510:
 		sqlDollar = sqlS[sqlpt-7 : sqlpt+1]
-//line sql-gen.y:8022
+//line sql-gen.y:8986
 		{
 			sqlVAL.union.val = &tree.ShowDefaultPrivileges{
 				ForAllRoles: true,
 				Schema:      tree.Name(sqlDollar[7].str),
 			}
 		}
-	case 1330:
+	case 1511:
 		sqlDollar = sqlS[sqlpt-4 : sqlpt+1]
-//line sql-gen.y:8028
+//line sql-gen.y:8992
 		{
 			return helpWith(sqllex, "SHOW DEFAULT PRIVILEGES")
 		}
-	case 1331:
+	case 1512:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:8035
+//line sql-gen.y:8999
 		{
 			sqlVAL.union.val = &tree.ShowEnums{}
 		}
-	case 1332:
+	case 1513:
 		sqlDollar = sqlS[sqlpt-6 : sqlpt+1]
-//line sql-gen.y:8039
+//line sql-gen.y:9003
 		{
 			sqlVAL.union.val = &tree.ShowEnums{ObjectNamePrefix: tree.ObjectNamePrefix{
 				CatalogName:     tree.Name(sqlDollar[4].str),
@@ -36809,9 +40411,9 @@ sqldefault:
 			},
 			}
 		}
-	case 1333:
+	case 1514:
 		sqlDollar = sqlS[sqlpt-4 : sqlpt+1]
-//line sql-gen.y:8049
+//line sql-gen.y:9013
 		{
 			sqlVAL.union.val = &tree.ShowEnums{ObjectNamePrefix: tree.ObjectNamePrefix{
 
@@ -36820,27 +40422,51 @@ sqldefault:
 			},
 			}
 		}
-	case 1334:
+	case 1515:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:8058
+//line sql-gen.y:9022
 		{
 			return helpWith(sqllex, "SHOW ENUMS")
 		}
-	case 1335:
-		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:8065
+	case 1516:
+		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
+//line sql-gen.y:9031
+		{
+			sqlVAL.union.val = &tree.ShowExternalConnections{}
+		}
+	case 1517:
+		sqlDollar = sqlS[sqlpt-4 : sqlpt+1]
+//line sql-gen.y:9034
+		{
+			return helpWith(sqllex, "SHOW EXTERNAL CONNECTIONS")
+		}
+	case 1518:
+		sqlDollar = sqlS[sqlpt-4 : sqlpt+1]
+//line sql-gen.y:9036
+		{
+			sqlVAL.union.val = &tree.ShowExternalConnections{ConnectionLabel: sqlDollar[4].union.expr()}
+		}
+	case 1519:
+		sqlDollar = sqlS[sqlpt-4 : sqlpt+1]
+//line sql-gen.y:9039
+		{
+			return helpWith(sqllex, "SHOW EXTERNAL CONNECTIONS")
+		}
+	case 1520:
+		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
+//line sql-gen.y:9046
 		{
-			sqlVAL.union.val = &tree.ShowTypes{}
+			sqlVAL.union.val = &tree.ShowTypes{WithComment: sqlDollar[3].union.bool()}
 		}
-	case 1336:
+	case 1521:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:8068
+//line sql-gen.y:9049
 		{
 			return helpWith(sqllex, "SHOW TYPES")
 		}
-	case 1337:
+	case 1522:
 		sqlDollar = sqlS[sqlpt-4 : sqlpt+1]
-//line sql-gen.y:8081
+//line sql-gen.y:9062
 		{
 			lst := sqlDollar[3].union.grantTargetListPtr()
 			if lst != nil && lst.ForRoles {
@@ -36849,236 +40475,254 @@ sqldefault:
 				sqlVAL.union.val = &tree.ShowGrants{Targets: lst, Grantees: sqlDollar[4].union.roleSpecList()}
 			}
 		}
-	case 1338:
+	case 1523:
 		sqlDollar = sqlS[sqlpt-4 : sqlpt+1]
-//line sql-gen.y:8090
+//line sql-gen.y:9071
 		{
 			sqlVAL.union.val = &tree.ShowGrants{
 				Targets:  &tree.GrantTargetList{System: true},
 				Grantees: sqlDollar[4].union.roleSpecList(),
 			}
 		}
-	case 1339:
+	case 1524:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:8096
+//line sql-gen.y:9077
 		{
 			return helpWith(sqllex, "SHOW GRANTS")
 		}
-	case 1340:
+	case 1525:
 		sqlDollar = sqlS[sqlpt-5 : sqlpt+1]
-//line sql-gen.y:8104
+//line sql-gen.y:9085
 		{
 			sqlVAL.union.val = &tree.ShowIndexes{Table: sqlDollar[4].union.unresolvedObjectName(), WithComment: sqlDollar[5].union.bool()}
 		}
-	case 1341:
+	case 1526:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:8107
+//line sql-gen.y:9088
 		{
 			return helpWith(sqllex, "SHOW INDEXES")
 		}
-	case 1342:
+	case 1527:
 		sqlDollar = sqlS[sqlpt-6 : sqlpt+1]
-//line sql-gen.y:8109
+//line sql-gen.y:9090
 		{
 			sqlVAL.union.val = &tree.ShowDatabaseIndexes{Database: tree.Name(sqlDollar[5].str), WithComment: sqlDollar[6].union.bool()}
 		}
-	case 1343:
+	case 1528:
 		sqlDollar = sqlS[sqlpt-5 : sqlpt+1]
-//line sql-gen.y:8113
+//line sql-gen.y:9094
 		{
 			sqlVAL.union.val = &tree.ShowIndexes{Table: sqlDollar[4].union.unresolvedObjectName(), WithComment: sqlDollar[5].union.bool()}
 		}
-	case 1344:
+	case 1529:
 		sqlDollar = sqlS[sqlpt-6 : sqlpt+1]
-//line sql-gen.y:8117
+//line sql-gen.y:9098
 		{
 			sqlVAL.union.val = &tree.ShowDatabaseIndexes{Database: tree.Name(sqlDollar[5].str), WithComment: sqlDollar[6].union.bool()}
 		}
-	case 1345:
+	case 1530:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:8120
+//line sql-gen.y:9101
 		{
 			return helpWith(sqllex, "SHOW INDEXES")
 		}
-	case 1346:
+	case 1531:
 		sqlDollar = sqlS[sqlpt-5 : sqlpt+1]
-//line sql-gen.y:8122
+//line sql-gen.y:9103
 		{
 			sqlVAL.union.val = &tree.ShowIndexes{Table: sqlDollar[4].union.unresolvedObjectName(), WithComment: sqlDollar[5].union.bool()}
 		}
-	case 1347:
+	case 1532:
 		sqlDollar = sqlS[sqlpt-6 : sqlpt+1]
-//line sql-gen.y:8126
+//line sql-gen.y:9107
 		{
 			sqlVAL.union.val = &tree.ShowDatabaseIndexes{Database: tree.Name(sqlDollar[5].str), WithComment: sqlDollar[6].union.bool()}
 		}
-	case 1348:
+	case 1533:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:8129
+//line sql-gen.y:9110
 		{
 			return helpWith(sqllex, "SHOW INDEXES")
 		}
-	case 1349:
+	case 1534:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:8143
+//line sql-gen.y:9124
 		{
 			sqlVAL.union.val = &tree.ShowCommitTimestamp{}
 		}
-	case 1350:
+	case 1535:
 		sqlDollar = sqlS[sqlpt-5 : sqlpt+1]
-//line sql-gen.y:8153
+//line sql-gen.y:9134
 		{
 			sqlVAL.union.val = &tree.ShowConstraints{Table: sqlDollar[4].union.unresolvedObjectName(), WithComment: sqlDollar[5].union.bool()}
 		}
-	case 1351:
+	case 1536:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:8156
+//line sql-gen.y:9137
 		{
 			return helpWith(sqllex, "SHOW CONSTRAINTS")
 		}
-	case 1352:
+	case 1537:
 		sqlDollar = sqlS[sqlpt-5 : sqlpt+1]
-//line sql-gen.y:8158
+//line sql-gen.y:9139
 		{
 			sqlVAL.union.val = &tree.ShowConstraints{Table: sqlDollar[4].union.unresolvedObjectName(), WithComment: sqlDollar[5].union.bool()}
 		}
-	case 1353:
+	case 1538:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:8161
+//line sql-gen.y:9142
 		{
 			return helpWith(sqllex, "SHOW CONSTRAINTS")
 		}
-	case 1354:
+	case 1539:
+		sqlDollar = sqlS[sqlpt-4 : sqlpt+1]
+//line sql-gen.y:9150
+		{
+			sqlVAL.union.val = &tree.ShowTriggers{Table: sqlDollar[4].union.unresolvedObjectName()}
+		}
+	case 1540:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:8169
+//line sql-gen.y:9153
+		{
+			return helpWith(sqllex, "SHOW TRIGGERS")
+		}
+	case 1541:
+		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
+//line sql-gen.y:9154
+		{
+			return helpWith(sqllex, "SHOW TRIGGERS")
+		}
+	case 1542:
+		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
+//line sql-gen.y:9162
 		{
 			sqlVAL.union.val = &tree.ShowQueries{All: false, Cluster: sqlDollar[2].union.bool()}
 		}
-	case 1355:
+	case 1543:
 		sqlDollar = sqlS[sqlpt-4 : sqlpt+1]
-//line sql-gen.y:8172
+//line sql-gen.y:9165
 		{
 			return helpWith(sqllex, "SHOW STATEMENTS")
 		}
-	case 1356:
+	case 1544:
 		sqlDollar = sqlS[sqlpt-4 : sqlpt+1]
-//line sql-gen.y:8174
+//line sql-gen.y:9167
 		{
 			sqlVAL.union.val = &tree.ShowQueries{All: true, Cluster: sqlDollar[3].union.bool()}
 		}
-	case 1357:
+	case 1545:
 		sqlDollar = sqlS[sqlpt-5 : sqlpt+1]
-//line sql-gen.y:8177
+//line sql-gen.y:9170
 		{
 			return helpWith(sqllex, "SHOW STATEMENTS")
 		}
-	case 1358:
+	case 1546:
 		sqlDollar = sqlS[sqlpt-0 : sqlpt+1]
-//line sql-gen.y:8181
+//line sql-gen.y:9174
 		{
 			sqlVAL.union.val = true
 		}
-	case 1359:
+	case 1547:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:8183
+//line sql-gen.y:9176
 		{
 			sqlVAL.union.val = true
 		}
-	case 1360:
+	case 1548:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:8185
+//line sql-gen.y:9178
 		{
 			sqlVAL.union.val = false
 		}
-	case 1363:
+	case 1551:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:8202
+//line sql-gen.y:9195
 		{
 			sqlVAL.union.val = &tree.ShowJobs{Automatic: true}
 		}
-	case 1364:
+	case 1552:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:8206
+//line sql-gen.y:9199
 		{
 			sqlVAL.union.val = &tree.ShowJobs{
 				Automatic: false,
 			}
 		}
-	case 1365:
+	case 1553:
 		sqlDollar = sqlS[sqlpt-4 : sqlpt+1]
-//line sql-gen.y:8212
+//line sql-gen.y:9205
 		{
 			sqlVAL.union.val = &tree.ShowJobs{
 				Automatic: false,
 				Options:   sqlDollar[4].union.showJobOptions(),
 			}
 		}
-	case 1366:
+	case 1554:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:8219
+//line sql-gen.y:9212
 		{
 			sqlVAL.union.val = &tree.ShowChangefeedJobs{}
 		}
-	case 1367:
+	case 1555:
 		sqlDollar = sqlS[sqlpt-4 : sqlpt+1]
-//line sql-gen.y:8222
+//line sql-gen.y:9215
 		{
 			return helpWith(sqllex, "SHOW JOBS")
 		}
-	case 1368:
+	case 1556:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:8223
+//line sql-gen.y:9216
 		{
 			return helpWith(sqllex, "SHOW JOBS")
 		}
-	case 1369:
+	case 1557:
 		sqlDollar = sqlS[sqlpt-4 : sqlpt+1]
-//line sql-gen.y:8224
+//line sql-gen.y:9217
 		{
 			return helpWith(sqllex, "SHOW JOBS")
 		}
-	case 1370:
+	case 1558:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:8226
+//line sql-gen.y:9219
 		{
 			sqlVAL.union.val = &tree.ShowJobs{Jobs: sqlDollar[3].union.slct()}
 		}
-	case 1371:
+	case 1559:
 		sqlDollar = sqlS[sqlpt-5 : sqlpt+1]
-//line sql-gen.y:8230
+//line sql-gen.y:9223
 		{
 			sqlVAL.union.val = &tree.ShowJobs{
 				Jobs:    sqlDollar[3].union.slct(),
 				Options: sqlDollar[5].union.showJobOptions(),
 			}
 		}
-	case 1372:
+	case 1560:
 		sqlDollar = sqlS[sqlpt-5 : sqlpt+1]
-//line sql-gen.y:8237
+//line sql-gen.y:9230
 		{
 			sqlVAL.union.val = &tree.ShowJobs{Jobs: sqlDollar[5].union.slct(), Block: true}
 		}
-	case 1373:
+	case 1561:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:8241
+//line sql-gen.y:9234
 		{
 			sqlVAL.union.val = &tree.ShowJobs{Schedules: sqlDollar[3].union.slct()}
 		}
-	case 1374:
+	case 1562:
 		sqlDollar = sqlS[sqlpt-4 : sqlpt+1]
-//line sql-gen.y:8245
+//line sql-gen.y:9238
 		{
 			sqlVAL.union.val = &tree.ShowChangefeedJobs{Jobs: sqlDollar[4].union.slct()}
 		}
-	case 1375:
+	case 1563:
 		sqlDollar = sqlS[sqlpt-4 : sqlpt+1]
-//line sql-gen.y:8248
+//line sql-gen.y:9241
 		{
 			return helpWith(sqllex, "SHOW JOBS")
 		}
-	case 1376:
+	case 1564:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:8250
+//line sql-gen.y:9243
 		{
 			sqlVAL.union.val = &tree.ShowJobs{
 				Jobs: &tree.Select{
@@ -37086,9 +40730,9 @@ sqldefault:
 				},
 			}
 		}
-	case 1377:
+	case 1565:
 		sqlDollar = sqlS[sqlpt-5 : sqlpt+1]
-//line sql-gen.y:8258
+//line sql-gen.y:9251
 		{
 			sqlVAL.union.val = &tree.ShowJobs{
 				Jobs: &tree.Select{
@@ -37097,9 +40741,9 @@ sqldefault:
 				Options: sqlDollar[5].union.showJobOptions(),
 			}
 		}
-	case 1378:
+	case 1566:
 		sqlDollar = sqlS[sqlpt-4 : sqlpt+1]
-//line sql-gen.y:8267
+//line sql-gen.y:9260
 		{
 			sqlVAL.union.val = &tree.ShowChangefeedJobs{
 				Jobs: &tree.Select{
@@ -37107,9 +40751,9 @@ sqldefault:
 				},
 			}
 		}
-	case 1379:
+	case 1567:
 		sqlDollar = sqlS[sqlpt-5 : sqlpt+1]
-//line sql-gen.y:8275
+//line sql-gen.y:9268
 		{
 			sqlVAL.union.val = &tree.ShowJobs{
 				Jobs: &tree.Select{
@@ -37118,197 +40762,197 @@ sqldefault:
 				Block: true,
 			}
 		}
-	case 1380:
+	case 1568:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:8283
+//line sql-gen.y:9276
 		{
 			return helpWith(sqllex, "SHOW JOBS")
 		}
-	case 1381:
+	case 1569:
 		sqlDollar = sqlS[sqlpt-4 : sqlpt+1]
-//line sql-gen.y:8284
+//line sql-gen.y:9277
 		{
 			return helpWith(sqllex, "SHOW JOBS")
 		}
-	case 1382:
+	case 1570:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:8290
+//line sql-gen.y:9283
 		{
 			sqlVAL.union.val = sqlDollar[1].union.showJobOptions()
 		}
-	case 1383:
+	case 1571:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:8294
+//line sql-gen.y:9287
 		{
 			if err := sqlDollar[1].union.showJobOptions().CombineWith(sqlDollar[3].union.showJobOptions()); err != nil {
 				return setErr(sqllex, err)
 			}
 		}
-	case 1384:
+	case 1572:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:8303
+//line sql-gen.y:9296
 		{
 			sqlVAL.union.val = &tree.ShowJobOptions{
 				ExecutionDetails: true,
 			}
 		}
-	case 1385:
+	case 1573:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:8317
+//line sql-gen.y:9310
 		{
 			sqlVAL.union.val = &tree.ShowSchedules{
 				WhichSchedules: tree.SpecifiedSchedules,
 				ExecutorType:   sqlDollar[3].union.executorType(),
 			}
 		}
-	case 1386:
+	case 1574:
 		sqlDollar = sqlS[sqlpt-4 : sqlpt+1]
-//line sql-gen.y:8323
+//line sql-gen.y:9316
 		{
 			return helpWith(sqllex, "SHOW SCHEDULES")
 		}
-	case 1387:
+	case 1575:
 		sqlDollar = sqlS[sqlpt-4 : sqlpt+1]
-//line sql-gen.y:8325
+//line sql-gen.y:9318
 		{
 			sqlVAL.union.val = &tree.ShowSchedules{
 				WhichSchedules: sqlDollar[2].union.scheduleState(),
 				ExecutorType:   sqlDollar[4].union.executorType(),
 			}
 		}
-	case 1388:
+	case 1576:
 		sqlDollar = sqlS[sqlpt-5 : sqlpt+1]
-//line sql-gen.y:8331
+//line sql-gen.y:9324
 		{
 			return helpWith(sqllex, "SHOW SCHEDULES")
 		}
-	case 1389:
+	case 1577:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:8333
+//line sql-gen.y:9326
 		{
 			sqlVAL.union.val = &tree.ShowSchedules{
 				WhichSchedules: tree.SpecifiedSchedules,
 				ScheduleID:     sqlDollar[3].union.expr(),
 			}
 		}
-	case 1390:
+	case 1578:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:8339
+//line sql-gen.y:9332
 		{
 			return helpWith(sqllex, "SHOW SCHEDULES")
 		}
-	case 1391:
+	case 1579:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:8343
+//line sql-gen.y:9336
 		{
 			sqlVAL.union.val = tree.ActiveSchedules
 		}
-	case 1392:
+	case 1580:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:8347
+//line sql-gen.y:9340
 		{
 			sqlVAL.union.val = tree.PausedSchedules
 		}
-	case 1393:
+	case 1581:
 		sqlDollar = sqlS[sqlpt-0 : sqlpt+1]
-//line sql-gen.y:8353
+//line sql-gen.y:9346
 		{
 			sqlVAL.union.val = tree.InvalidExecutor
 		}
-	case 1394:
+	case 1582:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:8357
+//line sql-gen.y:9350
 		{
 			sqlVAL.union.val = tree.ScheduledBackupExecutor
 		}
-	case 1395:
+	case 1583:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:8361
+//line sql-gen.y:9354
 		{
 			sqlVAL.union.val = tree.ScheduledSQLStatsCompactionExecutor
 		}
-	case 1396:
+	case 1584:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:8365
+//line sql-gen.y:9358
 		{
 			sqlVAL.union.val = tree.ScheduledChangefeedExecutor
 		}
-	case 1397:
+	case 1585:
 		sqlDollar = sqlS[sqlpt-5 : sqlpt+1]
-//line sql-gen.y:8376
+//line sql-gen.y:9369
 		{
 			sqlVAL.union.val = &tree.ShowTraceForSession{TraceType: tree.ShowTraceRaw, Compact: sqlDollar[2].union.bool()}
 		}
-	case 1398:
+	case 1586:
 		sqlDollar = sqlS[sqlpt-4 : sqlpt+1]
-//line sql-gen.y:8379
+//line sql-gen.y:9372
 		{
 			return helpWith(sqllex, "SHOW TRACE")
 		}
-	case 1399:
+	case 1587:
 		sqlDollar = sqlS[sqlpt-6 : sqlpt+1]
-//line sql-gen.y:8381
+//line sql-gen.y:9374
 		{
 			sqlVAL.union.val = &tree.ShowTraceForSession{TraceType: tree.ShowTraceKV, Compact: sqlDollar[2].union.bool()}
 		}
-	case 1400:
+	case 1588:
 		sqlDollar = sqlS[sqlpt-4 : sqlpt+1]
-//line sql-gen.y:8384
+//line sql-gen.y:9377
 		{
 			return helpWith(sqllex, "SHOW TRACE")
 		}
-	case 1401:
+	case 1589:
 		sqlDollar = sqlS[sqlpt-6 : sqlpt+1]
-//line sql-gen.y:8386
+//line sql-gen.y:9379
 		{
 
 			sqlVAL.union.val = &tree.ShowTraceForSession{TraceType: tree.ShowTraceReplica, Compact: sqlDollar[2].union.bool()}
 		}
-	case 1402:
+	case 1590:
 		sqlDollar = sqlS[sqlpt-4 : sqlpt+1]
-//line sql-gen.y:8390
+//line sql-gen.y:9383
 		{
 			return helpWith(sqllex, "SHOW TRACE")
 		}
-	case 1403:
+	case 1591:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:8393
+//line sql-gen.y:9386
 		{
 			sqlVAL.union.val = true
 		}
-	case 1404:
+	case 1592:
 		sqlDollar = sqlS[sqlpt-0 : sqlpt+1]
-//line sql-gen.y:8394
+//line sql-gen.y:9387
 		{
 			sqlVAL.union.val = false
 		}
-	case 1405:
+	case 1593:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:8402
+//line sql-gen.y:9395
 		{
 			sqlVAL.union.val = &tree.ShowSessions{Cluster: sqlDollar[2].union.bool()}
 		}
-	case 1406:
+	case 1594:
 		sqlDollar = sqlS[sqlpt-4 : sqlpt+1]
-//line sql-gen.y:8405
+//line sql-gen.y:9398
 		{
 			return helpWith(sqllex, "SHOW SESSIONS")
 		}
-	case 1407:
+	case 1595:
 		sqlDollar = sqlS[sqlpt-4 : sqlpt+1]
-//line sql-gen.y:8407
+//line sql-gen.y:9400
 		{
 			sqlVAL.union.val = &tree.ShowSessions{All: true, Cluster: sqlDollar[3].union.bool()}
 		}
-	case 1408:
+	case 1596:
 		sqlDollar = sqlS[sqlpt-5 : sqlpt+1]
-//line sql-gen.y:8410
+//line sql-gen.y:9403
 		{
 			return helpWith(sqllex, "SHOW SESSIONS")
 		}
-	case 1409:
+	case 1597:
 		sqlDollar = sqlS[sqlpt-7 : sqlpt+1]
-//line sql-gen.y:8418
+//line sql-gen.y:9411
 		{
 			sqlVAL.union.val = &tree.ShowTables{ObjectNamePrefix: tree.ObjectNamePrefix{
 				CatalogName:     tree.Name(sqlDollar[4].str),
@@ -37318,9 +40962,9 @@ sqldefault:
 			},
 				WithComment: sqlDollar[7].union.bool()}
 		}
-	case 1410:
+	case 1598:
 		sqlDollar = sqlS[sqlpt-5 : sqlpt+1]
-//line sql-gen.y:8428
+//line sql-gen.y:9421
 		{
 			sqlVAL.union.val = &tree.ShowTables{ObjectNamePrefix: tree.ObjectNamePrefix{
 
@@ -37329,21 +40973,21 @@ sqldefault:
 			},
 				WithComment: sqlDollar[5].union.bool()}
 		}
-	case 1411:
+	case 1599:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:8438
+//line sql-gen.y:9431
 		{
 			sqlVAL.union.val = &tree.ShowTables{WithComment: sqlDollar[3].union.bool()}
 		}
-	case 1412:
+	case 1600:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:8441
+//line sql-gen.y:9434
 		{
 			return helpWith(sqllex, "SHOW TABLES")
 		}
-	case 1413:
+	case 1601:
 		sqlDollar = sqlS[sqlpt-6 : sqlpt+1]
-//line sql-gen.y:8448
+//line sql-gen.y:9441
 		{
 			sqlVAL.union.val = &tree.ShowRoutines{ObjectNamePrefix: tree.ObjectNamePrefix{
 				CatalogName:     tree.Name(sqlDollar[4].str),
@@ -37352,9 +40996,9 @@ sqldefault:
 				ExplicitSchema:  true,
 			}}
 		}
-	case 1414:
+	case 1602:
 		sqlDollar = sqlS[sqlpt-4 : sqlpt+1]
-//line sql-gen.y:8457
+//line sql-gen.y:9450
 		{
 			sqlVAL.union.val = &tree.ShowRoutines{ObjectNamePrefix: tree.ObjectNamePrefix{
 
@@ -37362,21 +41006,21 @@ sqldefault:
 				ExplicitSchema: true,
 			}}
 		}
-	case 1415:
+	case 1603:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:8466
+//line sql-gen.y:9459
 		{
 			sqlVAL.union.val = &tree.ShowRoutines{}
 		}
-	case 1416:
+	case 1604:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:8469
+//line sql-gen.y:9462
 		{
 			return helpWith(sqllex, "SHOW FUNCTIONS")
 		}
-	case 1417:
+	case 1605:
 		sqlDollar = sqlS[sqlpt-6 : sqlpt+1]
-//line sql-gen.y:8476
+//line sql-gen.y:9469
 		{
 			sqlVAL.union.val = &tree.ShowRoutines{ObjectNamePrefix: tree.ObjectNamePrefix{
 				CatalogName:     tree.Name(sqlDollar[4].str),
@@ -37385,9 +41029,9 @@ sqldefault:
 				ExplicitSchema:  true,
 			}, Procedure: true}
 		}
-	case 1418:
+	case 1606:
 		sqlDollar = sqlS[sqlpt-4 : sqlpt+1]
-//line sql-gen.y:8485
+//line sql-gen.y:9478
 		{
 			sqlVAL.union.val = &tree.ShowRoutines{ObjectNamePrefix: tree.ObjectNamePrefix{
 
@@ -37395,106 +41039,106 @@ sqldefault:
 				ExplicitSchema: true,
 			}, Procedure: true}
 		}
-	case 1419:
+	case 1607:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:8494
+//line sql-gen.y:9487
 		{
 			sqlVAL.union.val = &tree.ShowRoutines{Procedure: true}
 		}
-	case 1420:
+	case 1608:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:8497
+//line sql-gen.y:9490
 		{
 			return helpWith(sqllex, "SHOW PROCEDURES")
 		}
-	case 1421:
+	case 1609:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:8504
+//line sql-gen.y:9497
 		{
 			sqlVAL.union.val = &tree.ShowTransactions{Cluster: sqlDollar[2].union.bool()}
 		}
-	case 1422:
+	case 1610:
 		sqlDollar = sqlS[sqlpt-4 : sqlpt+1]
-//line sql-gen.y:8507
+//line sql-gen.y:9500
 		{
 			return helpWith(sqllex, "SHOW TRANSACTIONS")
 		}
-	case 1423:
+	case 1611:
 		sqlDollar = sqlS[sqlpt-4 : sqlpt+1]
-//line sql-gen.y:8509
+//line sql-gen.y:9502
 		{
 			sqlVAL.union.val = &tree.ShowTransactions{All: true, Cluster: sqlDollar[3].union.bool()}
 		}
-	case 1424:
+	case 1612:
 		sqlDollar = sqlS[sqlpt-5 : sqlpt+1]
-//line sql-gen.y:8512
+//line sql-gen.y:9505
 		{
 			return helpWith(sqllex, "SHOW TRANSACTIONS")
 		}
-	case 1425:
+	case 1613:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:8515
+//line sql-gen.y:9508
 		{
 			sqlVAL.union.val = true
 		}
-	case 1426:
+	case 1614:
 		sqlDollar = sqlS[sqlpt-0 : sqlpt+1]
-//line sql-gen.y:8516
+//line sql-gen.y:9509
 		{
 			sqlVAL.union.val = false
 		}
-	case 1427:
-		sqlDollar = sqlS[sqlpt-4 : sqlpt+1]
-//line sql-gen.y:8523
+	case 1615:
+		sqlDollar = sqlS[sqlpt-5 : sqlpt+1]
+//line sql-gen.y:9516
 		{
-			sqlVAL.union.val = &tree.ShowSchemas{Database: tree.Name(sqlDollar[4].str)}
+			sqlVAL.union.val = &tree.ShowSchemas{Database: tree.Name(sqlDollar[4].str), WithComment: sqlDollar[5].union.bool()}
 		}
-	case 1428:
-		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:8527
+	case 1616:
+		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
+//line sql-gen.y:9520
 		{
-			sqlVAL.union.val = &tree.ShowSchemas{}
+			sqlVAL.union.val = &tree.ShowSchemas{WithComment: sqlDollar[3].union.bool()}
 		}
-	case 1429:
+	case 1617:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:8530
+//line sql-gen.y:9523
 		{
 			return helpWith(sqllex, "SHOW SCHEMAS")
 		}
-	case 1430:
+	case 1618:
 		sqlDollar = sqlS[sqlpt-4 : sqlpt+1]
-//line sql-gen.y:8537
+//line sql-gen.y:9530
 		{
 			sqlVAL.union.val = &tree.ShowSequences{Database: tree.Name(sqlDollar[4].str)}
 		}
-	case 1431:
+	case 1619:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:8541
+//line sql-gen.y:9534
 		{
 			sqlVAL.union.val = &tree.ShowSequences{}
 		}
-	case 1432:
+	case 1620:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:8544
+//line sql-gen.y:9537
 		{
 			return helpWith(sqllex, "SHOW SEQUENCES")
 		}
-	case 1433:
+	case 1621:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:8551
+//line sql-gen.y:9544
 		{
 
 			sqlVAL.union.val = &tree.ShowSyntax{Statement: sqlDollar[3].str}
 		}
-	case 1434:
+	case 1622:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:8555
+//line sql-gen.y:9548
 		{
 			return helpWith(sqllex, "SHOW SYNTAX")
 		}
-	case 1435:
+	case 1623:
 		sqlDollar = sqlS[sqlpt-7 : sqlpt+1]
-//line sql-gen.y:8559
+//line sql-gen.y:9552
 		{
 
 			sqlVAL.union.val = &tree.ShowCompletions{
@@ -37502,94 +41146,109 @@ sqldefault:
 				Offset:    sqlDollar[5].union.numVal(),
 			}
 		}
-	case 1436:
+	case 1624:
+		sqlDollar = sqlS[sqlpt-4 : sqlpt+1]
+//line sql-gen.y:9565
+		{
+
+			sqlVAL.union.val = &tree.ShowPolicies{
+				Table: sqlDollar[4].union.unresolvedObjectName(),
+			}
+		}
+	case 1625:
+		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
+//line sql-gen.y:9571
+		{
+			return helpWith(sqllex, "SHOW POLICIES")
+		}
+	case 1626:
 		sqlDollar = sqlS[sqlpt-5 : sqlpt+1]
-//line sql-gen.y:8569
+//line sql-gen.y:9575
 		{
 
 			sqlVAL.union.val = &tree.ShowLastQueryStatistics{Columns: sqlDollar[5].union.nameList()}
 		}
-	case 1437:
+	case 1627:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:8576
+//line sql-gen.y:9582
 		{
 			sqlVAL.union.val = sqlDollar[2].union.nameList()
 		}
-	case 1438:
+	case 1628:
 		sqlDollar = sqlS[sqlpt-0 : sqlpt+1]
-//line sql-gen.y:8580
+//line sql-gen.y:9586
 		{
 
 			sqlVAL.union.val = tree.ShowLastQueryStatisticsDefaultColumns
 		}
-	case 1439:
+	case 1629:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:8591
+//line sql-gen.y:9597
 		{
 			sqlVAL.union.val = &tree.ShowSavepointStatus{}
 		}
-	case 1440:
+	case 1630:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:8594
+//line sql-gen.y:9600
 		{
 			return helpWith(sqllex, "SHOW SAVEPOINT")
 		}
-	case 1441:
+	case 1631:
 		sqlDollar = sqlS[sqlpt-4 : sqlpt+1]
-//line sql-gen.y:8602
+//line sql-gen.y:9608
 		{
 
 			sqlVAL.union.val = &tree.ShowVar{Name: "transaction_isolation"}
 		}
-	case 1442:
+	case 1632:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:8607
+//line sql-gen.y:9613
 		{
 
 			sqlVAL.union.val = &tree.ShowVar{Name: "transaction_priority"}
 		}
-	case 1443:
+	case 1633:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:8612
+//line sql-gen.y:9618
 		{
 
 			sqlVAL.union.val = &tree.ShowTransactionStatus{}
 		}
-	case 1444:
+	case 1634:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:8616
+//line sql-gen.y:9622
 		{
 			return helpWith(sqllex, "SHOW TRANSACTION")
 		}
-	case 1445:
+	case 1635:
 		sqlDollar = sqlS[sqlpt-5 : sqlpt+1]
-//line sql-gen.y:8623
+//line sql-gen.y:9629
 		{
 			sqlVAL.union.val = &tree.ShowTransferState{TransferKey: tree.NewStrVal(sqlDollar[5].str)}
 		}
-	case 1446:
+	case 1636:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:8627
+//line sql-gen.y:9633
 		{
 			sqlVAL.union.val = &tree.ShowTransferState{}
 		}
-	case 1447:
+	case 1637:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:8630
+//line sql-gen.y:9636
 		{
 			return helpWith(sqllex, "SHOW TRANSFER")
 		}
-	case 1448:
+	case 1638:
 		sqlDollar = sqlS[sqlpt-4 : sqlpt+1]
-//line sql-gen.y:8643
+//line sql-gen.y:9649
 		{
 			sqlVAL.union.val = &tree.ShowCreate{
 				Name: sqlDollar[3].union.unresolvedObjectName(), FmtOpt: sqlDollar[4].union.showCreateFormatOption(),
 			}
 		}
-	case 1449:
+	case 1639:
 		sqlDollar = sqlS[sqlpt-5 : sqlpt+1]
-//line sql-gen.y:8649
+//line sql-gen.y:9655
 		{
 
 			sqlVAL.union.val = &tree.ShowCreate{
@@ -37598,9 +41257,9 @@ sqldefault:
 				FmtOpt: sqlDollar[5].union.showCreateFormatOption(),
 			}
 		}
-	case 1450:
+	case 1640:
 		sqlDollar = sqlS[sqlpt-5 : sqlpt+1]
-//line sql-gen.y:8658
+//line sql-gen.y:9664
 		{
 
 			sqlVAL.union.val = &tree.ShowCreate{
@@ -37609,37 +41268,37 @@ sqldefault:
 				FmtOpt: sqlDollar[5].union.showCreateFormatOption(),
 			}
 		}
-	case 1451:
+	case 1641:
 		sqlDollar = sqlS[sqlpt-4 : sqlpt+1]
-//line sql-gen.y:8667
+//line sql-gen.y:9673
 		{
 
 			sqlVAL.union.val = &tree.ShowCreate{Mode: tree.ShowCreateModeSequence, Name: sqlDollar[4].union.unresolvedObjectName()}
 		}
-	case 1452:
+	case 1642:
 		sqlDollar = sqlS[sqlpt-4 : sqlpt+1]
-//line sql-gen.y:8672
+//line sql-gen.y:9678
 		{
 
 			sqlVAL.union.val = &tree.ShowCreate{Mode: tree.ShowCreateModeDatabase, Name: sqlDollar[4].union.unresolvedObjectName()}
 		}
-	case 1453:
+	case 1643:
 		sqlDollar = sqlS[sqlpt-5 : sqlpt+1]
-//line sql-gen.y:8677
+//line sql-gen.y:9683
 		{
 
 			sqlVAL.union.val = &tree.ShowCreate{Mode: tree.ShowCreateModeIndexes, Name: sqlDollar[5].union.unresolvedObjectName()}
 		}
-	case 1454:
+	case 1644:
 		sqlDollar = sqlS[sqlpt-6 : sqlpt+1]
-//line sql-gen.y:8682
+//line sql-gen.y:9688
 		{
 
 			sqlVAL.union.val = &tree.ShowCreate{Mode: tree.ShowCreateModeSecondaryIndexes, Name: sqlDollar[6].union.unresolvedObjectName()}
 		}
-	case 1455:
+	case 1645:
 		sqlDollar = sqlS[sqlpt-4 : sqlpt+1]
-//line sql-gen.y:8687
+//line sql-gen.y:9693
 		{
 
 			sqlVAL.union.val = &tree.ShowCreateRoutine{
@@ -37648,9 +41307,9 @@ sqldefault:
 				},
 			}
 		}
-	case 1456:
+	case 1646:
 		sqlDollar = sqlS[sqlpt-4 : sqlpt+1]
-//line sql-gen.y:8696
+//line sql-gen.y:9702
 		{
 
 			sqlVAL.union.val = &tree.ShowCreateRoutine{
@@ -37660,129 +41319,169 @@ sqldefault:
 				Procedure: true,
 			}
 		}
-	case 1457:
+	case 1647:
+		sqlDollar = sqlS[sqlpt-6 : sqlpt+1]
+//line sql-gen.y:9712
+		{
+
+			sqlVAL.union.val = &tree.ShowCreateTrigger{
+				Name:      tree.Name(sqlDollar[4].str),
+				TableName: sqlDollar[6].union.unresolvedObjectName(),
+			}
+		}
+	case 1648:
 		sqlDollar = sqlS[sqlpt-4 : sqlpt+1]
-//line sql-gen.y:8706
+//line sql-gen.y:9720
 		{
 			sqlVAL.union.val = &tree.ShowCreateAllSchemas{}
 		}
-	case 1458:
+	case 1649:
 		sqlDollar = sqlS[sqlpt-4 : sqlpt+1]
-//line sql-gen.y:8710
+//line sql-gen.y:9724
 		{
 			sqlVAL.union.val = &tree.ShowCreateAllTables{}
 		}
-	case 1459:
+	case 1650:
 		sqlDollar = sqlS[sqlpt-4 : sqlpt+1]
-//line sql-gen.y:8714
+//line sql-gen.y:9728
 		{
 			sqlVAL.union.val = &tree.ShowCreateAllTypes{}
 		}
-	case 1460:
+	case 1651:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:8717
+//line sql-gen.y:9731
 		{
 			return helpWith(sqllex, "SHOW CREATE")
 		}
-	case 1461:
+	case 1652:
 		sqlDollar = sqlS[sqlpt-0 : sqlpt+1]
-//line sql-gen.y:8721
+//line sql-gen.y:9735
 		{
 			sqlVAL.union.val = tree.ShowCreateFormatOptionNone
 		}
-	case 1462:
+	case 1653:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:8725
+//line sql-gen.y:9739
 		{
 			sqlVAL.union.val = tree.ShowCreateFormatOptionRedactedValues
 		}
-	case 1463:
+	case 1654:
+		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
+//line sql-gen.y:9743
+		{
+			sqlVAL.union.val = tree.ShowCreateFormatOptionIgnoreFKs
+		}
+	case 1655:
 		sqlDollar = sqlS[sqlpt-4 : sqlpt+1]
-//line sql-gen.y:8737
+//line sql-gen.y:9755
 		{
 			sqlVAL.union.val = &tree.ShowCreateSchedules{}
 		}
-	case 1464:
+	case 1656:
 		sqlDollar = sqlS[sqlpt-5 : sqlpt+1]
-//line sql-gen.y:8740
+//line sql-gen.y:9758
 		{
 			return helpWith(sqllex, "SHOW CREATE SCHEDULES")
 		}
-	case 1465:
+	case 1657:
 		sqlDollar = sqlS[sqlpt-4 : sqlpt+1]
-//line sql-gen.y:8742
+//line sql-gen.y:9760
 		{
 			sqlVAL.union.val = &tree.ShowCreateSchedules{ScheduleID: sqlDollar[4].union.expr()}
 		}
-	case 1466:
+	case 1658:
 		sqlDollar = sqlS[sqlpt-4 : sqlpt+1]
-//line sql-gen.y:8745
+//line sql-gen.y:9763
 		{
 			return helpWith(sqllex, "SHOW CREATE SCHEDULES")
 		}
-	case 1467:
+	case 1659:
 		sqlDollar = sqlS[sqlpt-5 : sqlpt+1]
-//line sql-gen.y:8754
+//line sql-gen.y:9772
 		{
 			sqlVAL.union.val = &tree.ShowCreateExternalConnections{}
 		}
-	case 1468:
+	case 1660:
 		sqlDollar = sqlS[sqlpt-6 : sqlpt+1]
-//line sql-gen.y:8757
+//line sql-gen.y:9775
 		{
 			return helpWith(sqllex, "SHOW CREATE EXTERNAL CONNECTIONS")
 		}
-	case 1469:
+	case 1661:
 		sqlDollar = sqlS[sqlpt-5 : sqlpt+1]
-//line sql-gen.y:8759
+//line sql-gen.y:9777
 		{
 			sqlVAL.union.val = &tree.ShowCreateExternalConnections{ConnectionLabel: sqlDollar[5].union.expr()}
 		}
-	case 1470:
+	case 1662:
 		sqlDollar = sqlS[sqlpt-5 : sqlpt+1]
-//line sql-gen.y:8762
+//line sql-gen.y:9780
 		{
 			return helpWith(sqllex, "SHOW CREATE EXTERNAL CONNECTIONS")
 		}
-	case 1471:
+	case 1663:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:8770
+//line sql-gen.y:9788
 		{
 			sqlVAL.union.val = &tree.ShowUsers{}
 		}
-	case 1472:
+	case 1664:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:8773
+//line sql-gen.y:9791
 		{
 			return helpWith(sqllex, "SHOW USERS")
 		}
-	case 1473:
+	case 1665:
+		sqlDollar = sqlS[sqlpt-7 : sqlpt+1]
+//line sql-gen.y:9798
+		{
+			sqlVAL.union.val = &tree.ShowDefaultSessionVariablesForRole{Name: sqlDollar[7].union.roleSpec(), IsRole: sqlDollar[6].union.bool()}
+		}
+	case 1666:
+		sqlDollar = sqlS[sqlpt-7 : sqlpt+1]
+//line sql-gen.y:9802
+		{
+			sqlVAL.union.val = &tree.ShowDefaultSessionVariablesForRole{All: true, IsRole: true}
+		}
+	case 1667:
+		sqlDollar = sqlS[sqlpt-7 : sqlpt+1]
+//line sql-gen.y:9806
+		{
+			sqlVAL.union.val = &tree.ShowDefaultSessionVariablesForRole{All: true, IsRole: false}
+		}
+	case 1668:
+		sqlDollar = sqlS[sqlpt-7 : sqlpt+1]
+//line sql-gen.y:9809
+		{
+			return helpWith(sqllex, "SHOW DEFAULT SESSION VARIABLES FOR ROLE")
+		}
+	case 1669:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:8781
+//line sql-gen.y:9817
 		{
 			sqlVAL.union.val = &tree.ShowRoles{}
 		}
-	case 1474:
+	case 1670:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:8784
+//line sql-gen.y:9820
 		{
 			return helpWith(sqllex, "SHOW ROLES")
 		}
-	case 1475:
+	case 1671:
 		sqlDollar = sqlS[sqlpt-6 : sqlpt+1]
-//line sql-gen.y:8794
+//line sql-gen.y:9830
 		{
 			sqlVAL.union.val = &tree.ShowZoneConfig{ZoneSpecifier: tree.ZoneSpecifier{NamedZone: tree.UnrestrictedName(sqlDollar[6].str)}}
 		}
-	case 1476:
+	case 1672:
 		sqlDollar = sqlS[sqlpt-6 : sqlpt+1]
-//line sql-gen.y:8798
+//line sql-gen.y:9834
 		{
 			sqlVAL.union.val = &tree.ShowZoneConfig{ZoneSpecifier: tree.ZoneSpecifier{Database: tree.Name(sqlDollar[6].str)}}
 		}
-	case 1477:
+	case 1673:
 		sqlDollar = sqlS[sqlpt-7 : sqlpt+1]
-//line sql-gen.y:8802
+//line sql-gen.y:9838
 		{
 			name := sqlDollar[6].union.unresolvedObjectName().ToTableName()
 			sqlVAL.union.val = &tree.ShowZoneConfig{ZoneSpecifier: tree.ZoneSpecifier{
@@ -37790,9 +41489,9 @@ sqldefault:
 				Partition:    tree.Name(sqlDollar[7].str),
 			}}
 		}
-	case 1478:
+	case 1674:
 		sqlDollar = sqlS[sqlpt-9 : sqlpt+1]
-//line sql-gen.y:8810
+//line sql-gen.y:9846
 		{
 			name := sqlDollar[9].union.unresolvedObjectName().ToTableName()
 			sqlVAL.union.val = &tree.ShowZoneConfig{ZoneSpecifier: tree.ZoneSpecifier{
@@ -37800,62 +41499,62 @@ sqldefault:
 				Partition:    tree.Name(sqlDollar[6].str),
 			}}
 		}
-	case 1479:
+	case 1675:
 		sqlDollar = sqlS[sqlpt-7 : sqlpt+1]
-//line sql-gen.y:8818
+//line sql-gen.y:9854
 		{
 			sqlVAL.union.val = &tree.ShowZoneConfig{ZoneSpecifier: tree.ZoneSpecifier{
 				TableOrIndex: sqlDollar[6].union.tableIndexName(),
 				Partition:    tree.Name(sqlDollar[7].str),
 			}}
 		}
-	case 1480:
+	case 1676:
 		sqlDollar = sqlS[sqlpt-9 : sqlpt+1]
-//line sql-gen.y:8825
+//line sql-gen.y:9861
 		{
 			sqlVAL.union.val = &tree.ShowZoneConfig{ZoneSpecifier: tree.ZoneSpecifier{
 				TableOrIndex: sqlDollar[9].union.tableIndexName(),
 				Partition:    tree.Name(sqlDollar[6].str),
 			}}
 		}
-	case 1481:
+	case 1677:
 		sqlDollar = sqlS[sqlpt-4 : sqlpt+1]
-//line sql-gen.y:8831
+//line sql-gen.y:9867
 		{
 			return helpWith(sqllex, "SHOW ZONE CONFIGURATION")
 		}
-	case 1482:
+	case 1678:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:8833
+//line sql-gen.y:9869
 		{
 			sqlVAL.union.val = &tree.ShowZoneConfig{}
 		}
-	case 1483:
+	case 1679:
 		sqlDollar = sqlS[sqlpt-4 : sqlpt+1]
-//line sql-gen.y:8836
+//line sql-gen.y:9872
 		{
 			return helpWith(sqllex, "SHOW ZONE CONFIGURATION")
 		}
-	case 1484:
+	case 1680:
 		sqlDollar = sqlS[sqlpt-4 : sqlpt+1]
-//line sql-gen.y:8838
+//line sql-gen.y:9874
 		{
 			sqlVAL.union.val = &tree.ShowZoneConfig{}
 		}
-	case 1485:
+	case 1681:
 		sqlDollar = sqlS[sqlpt-5 : sqlpt+1]
-//line sql-gen.y:8841
+//line sql-gen.y:9877
 		{
 			return helpWith(sqllex, "SHOW ZONE CONFIGURATION")
 		}
-	case 1487:
+	case 1683:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:8845
+//line sql-gen.y:9881
 		{
 		}
-	case 1488:
+	case 1684:
 		sqlDollar = sqlS[sqlpt-10 : sqlpt+1]
-//line sql-gen.y:8854
+//line sql-gen.y:9890
 		{
 			name := sqlDollar[5].union.unresolvedObjectName().ToTableName()
 			sqlVAL.union.val = &tree.ShowRangeForRow{
@@ -37863,115 +41562,115 @@ sqldefault:
 				TableOrIndex: tree.TableIndexName{Table: name},
 			}
 		}
-	case 1489:
+	case 1685:
 		sqlDollar = sqlS[sqlpt-10 : sqlpt+1]
-//line sql-gen.y:8862
+//line sql-gen.y:9898
 		{
 			sqlVAL.union.val = &tree.ShowRangeForRow{
 				Row:          sqlDollar[9].union.exprs(),
 				TableOrIndex: sqlDollar[5].union.tableIndexName(),
 			}
 		}
-	case 1490:
+	case 1686:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:8868
+//line sql-gen.y:9904
 		{
 			return helpWith(sqllex, "SHOW RANGE")
 		}
-	case 1491:
+	case 1687:
 		sqlDollar = sqlS[sqlpt-6 : sqlpt+1]
-//line sql-gen.y:8892
+//line sql-gen.y:9928
 		{
 			sqlVAL.union.val = &tree.ShowRanges{Source: tree.ShowRangesIndex, TableOrIndex: sqlDollar[5].union.tableIndexName(), Options: sqlDollar[6].union.showRangesOpts()}
 		}
-	case 1492:
+	case 1688:
 		sqlDollar = sqlS[sqlpt-6 : sqlpt+1]
-//line sql-gen.y:8896
+//line sql-gen.y:9932
 		{
 			name := sqlDollar[5].union.unresolvedObjectName().ToTableName()
 			sqlVAL.union.val = &tree.ShowRanges{Source: tree.ShowRangesTable, TableOrIndex: tree.TableIndexName{Table: name}, Options: sqlDollar[6].union.showRangesOpts()}
 		}
-	case 1493:
+	case 1689:
 		sqlDollar = sqlS[sqlpt-6 : sqlpt+1]
-//line sql-gen.y:8901
+//line sql-gen.y:9937
 		{
 			sqlVAL.union.val = &tree.ShowRanges{Source: tree.ShowRangesDatabase, DatabaseName: tree.Name(sqlDollar[5].str), Options: sqlDollar[6].union.showRangesOpts()}
 		}
-	case 1494:
+	case 1690:
 		sqlDollar = sqlS[sqlpt-5 : sqlpt+1]
-//line sql-gen.y:8905
+//line sql-gen.y:9941
 		{
 			sqlVAL.union.val = &tree.ShowRanges{Source: tree.ShowRangesCurrentDatabase, Options: sqlDollar[5].union.showRangesOpts()}
 		}
-	case 1495:
+	case 1691:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:8909
+//line sql-gen.y:9945
 		{
 			sqlVAL.union.val = &tree.ShowRanges{Source: tree.ShowRangesCurrentDatabase, Options: sqlDollar[3].union.showRangesOpts()}
 		}
-	case 1496:
+	case 1692:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:8912
+//line sql-gen.y:9948
 		{
 			return helpWith(sqllex, "SHOW RANGES")
 		}
-	case 1497:
+	case 1693:
 		sqlDollar = sqlS[sqlpt-4 : sqlpt+1]
-//line sql-gen.y:8914
+//line sql-gen.y:9950
 		{
 			sqlVAL.union.val = &tree.ShowRanges{Source: tree.ShowRangesCluster, Options: sqlDollar[4].union.showRangesOpts()}
 		}
-	case 1498:
+	case 1694:
 		sqlDollar = sqlS[sqlpt-4 : sqlpt+1]
-//line sql-gen.y:8917
+//line sql-gen.y:9953
 		{
 			return helpWith(sqllex, "SHOW RANGES")
 		}
-	case 1499:
+	case 1695:
 		sqlDollar = sqlS[sqlpt-0 : sqlpt+1]
-//line sql-gen.y:8921
+//line sql-gen.y:9957
 		{
 			sqlVAL.union.val = &tree.ShowRangesOptions{}
 		}
-	case 1500:
+	case 1696:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:8923
+//line sql-gen.y:9959
 		{
 			sqlVAL.union.val = sqlDollar[2].union.showRangesOpts()
 		}
-	case 1501:
+	case 1697:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:8926
+//line sql-gen.y:9962
 		{
 			sqlVAL.union.val = &tree.ShowRangesOptions{Mode: tree.ExpandTables}
 		}
-	case 1502:
+	case 1698:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:8927
+//line sql-gen.y:9963
 		{
 			sqlVAL.union.val = &tree.ShowRangesOptions{Mode: tree.ExpandIndexes}
 		}
-	case 1503:
+	case 1699:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:8928
+//line sql-gen.y:9964
 		{
 			sqlVAL.union.val = &tree.ShowRangesOptions{Details: true}
 		}
-	case 1504:
+	case 1700:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:8929
+//line sql-gen.y:9965
 		{
 			sqlVAL.union.val = &tree.ShowRangesOptions{Keys: true}
 		}
-	case 1505:
+	case 1701:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:8930
+//line sql-gen.y:9966
 		{
 			sqlVAL.union.val = &tree.ShowRangesOptions{Explain: true}
 		}
-	case 1506:
+	case 1702:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:8932
+//line sql-gen.y:9968
 		{
 			o := sqlDollar[1].union.showRangesOpts()
 			if o.Mode != 0 {
@@ -37980,9 +41679,9 @@ sqldefault:
 			o.Mode = tree.ExpandTables
 			sqlVAL.union.val = o
 		}
-	case 1507:
+	case 1703:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:8939
+//line sql-gen.y:9975
 		{
 			o := sqlDollar[1].union.showRangesOpts()
 			if o.Mode != 0 {
@@ -37991,154 +41690,198 @@ sqldefault:
 			o.Mode = tree.ExpandIndexes
 			sqlVAL.union.val = o
 		}
-	case 1508:
+	case 1704:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:8946
+//line sql-gen.y:9982
 		{
 			o := sqlDollar[1].union.showRangesOpts()
 			o.Details = true
 			sqlVAL.union.val = o
 		}
-	case 1509:
+	case 1705:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:8952
+//line sql-gen.y:9988
 		{
 			o := sqlDollar[1].union.showRangesOpts()
 			o.Explain = true
 			sqlVAL.union.val = o
 		}
-	case 1510:
+	case 1706:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:8958
+//line sql-gen.y:9994
 		{
 			o := sqlDollar[1].union.showRangesOpts()
 			o.Keys = true
 			sqlVAL.union.val = o
 		}
-	case 1511:
+	case 1707:
 		sqlDollar = sqlS[sqlpt-5 : sqlpt+1]
-//line sql-gen.y:8972
+//line sql-gen.y:10008
 		{
 			sqlVAL.union.val = &tree.ShowSurvivalGoal{}
 		}
-	case 1512:
+	case 1708:
 		sqlDollar = sqlS[sqlpt-6 : sqlpt+1]
-//line sql-gen.y:8976
+//line sql-gen.y:10012
 		{
 			sqlVAL.union.val = &tree.ShowSurvivalGoal{
 				DatabaseName: tree.Name(sqlDollar[6].str),
 			}
 		}
-	case 1513:
+	case 1709:
 		sqlDollar = sqlS[sqlpt-4 : sqlpt+1]
-//line sql-gen.y:8992
+//line sql-gen.y:10028
 		{
 			sqlVAL.union.val = &tree.ShowRegions{
 				ShowRegionsFrom: tree.ShowRegionsFromCluster,
 			}
 		}
-	case 1514:
+	case 1710:
 		sqlDollar = sqlS[sqlpt-4 : sqlpt+1]
-//line sql-gen.y:8998
+//line sql-gen.y:10034
 		{
 			sqlVAL.union.val = &tree.ShowRegions{
 				ShowRegionsFrom: tree.ShowRegionsFromDatabase,
 			}
 		}
-	case 1515:
+	case 1711:
 		sqlDollar = sqlS[sqlpt-5 : sqlpt+1]
-//line sql-gen.y:9004
+//line sql-gen.y:10040
 		{
 			sqlVAL.union.val = &tree.ShowRegions{
 				ShowRegionsFrom: tree.ShowRegionsFromAllDatabases,
 			}
 		}
-	case 1516:
+	case 1712:
 		sqlDollar = sqlS[sqlpt-5 : sqlpt+1]
-//line sql-gen.y:9010
+//line sql-gen.y:10046
 		{
 			sqlVAL.union.val = &tree.ShowRegions{
 				ShowRegionsFrom: tree.ShowRegionsFromDatabase,
 				DatabaseName:    tree.Name(sqlDollar[5].str),
 			}
 		}
-	case 1517:
+	case 1713:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:9017
+//line sql-gen.y:10053
 		{
 			sqlVAL.union.val = &tree.ShowRegions{
 				ShowRegionsFrom: tree.ShowRegionsFromDefault,
 			}
 		}
-	case 1518:
+	case 1714:
+		sqlDollar = sqlS[sqlpt-6 : sqlpt+1]
+//line sql-gen.y:10059
+		{
+			sqlVAL.union.val = &tree.ShowRegions{
+				ShowRegionsFrom: tree.ShowSuperRegionsFromDatabase,
+				DatabaseName:    tree.Name(sqlDollar[6].str),
+			}
+		}
+	case 1715:
+		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
+//line sql-gen.y:10065
+		{
+			return helpWith(sqllex, "SHOW REGIONS")
+		}
+	case 1716:
+		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
+//line sql-gen.y:10069
+		{
+			sqlVAL.union.val = &tree.ShowVar{Name: "locality"}
+		}
+	case 1717:
+		sqlDollar = sqlS[sqlpt-6 : sqlpt+1]
+//line sql-gen.y:10075
+		{
+
+			sqlVAL.union.val = &tree.ShowFingerprints{Table: sqlDollar[5].union.unresolvedObjectName(), Options: *sqlDollar[6].union.showFingerprintOptions()}
+		}
+	case 1718:
 		sqlDollar = sqlS[sqlpt-6 : sqlpt+1]
-//line sql-gen.y:9023
+//line sql-gen.y:10080
+		{
+
+			sqlVAL.union.val = &tree.ShowFingerprints{TenantSpec: sqlDollar[5].union.tenantSpec(), Options: *sqlDollar[6].union.showFingerprintOptions()}
+		}
+	case 1719:
+		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
+//line sql-gen.y:10087
+		{
+			sqlVAL.union.val = sqlDollar[2].union.showFingerprintOptions()
+		}
+	case 1720:
+		sqlDollar = sqlS[sqlpt-5 : sqlpt+1]
+//line sql-gen.y:10091
+		{
+			sqlVAL.union.val = sqlDollar[4].union.showFingerprintOptions()
+		}
+	case 1721:
+		sqlDollar = sqlS[sqlpt-0 : sqlpt+1]
+//line sql-gen.y:10095
 		{
-			sqlVAL.union.val = &tree.ShowRegions{
-				ShowRegionsFrom: tree.ShowSuperRegionsFromDatabase,
-				DatabaseName:    tree.Name(sqlDollar[6].str),
-			}
+			sqlVAL.union.val = &tree.ShowFingerprintOptions{}
 		}
-	case 1519:
-		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:9029
+	case 1722:
+		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
+//line sql-gen.y:10102
 		{
-			return helpWith(sqllex, "SHOW REGIONS")
+			sqlVAL.union.val = sqlDollar[1].union.showFingerprintOptions()
 		}
-	case 1520:
-		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:9033
+	case 1723:
+		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
+//line sql-gen.y:10106
 		{
-			sqlVAL.union.val = &tree.ShowVar{Name: "locality"}
+			if err := sqlDollar[1].union.showFingerprintOptions().CombineWith(sqlDollar[3].union.showFingerprintOptions()); err != nil {
+				return setErr(sqllex, err)
+			}
 		}
-	case 1521:
-		sqlDollar = sqlS[sqlpt-5 : sqlpt+1]
-//line sql-gen.y:9039
+	case 1724:
+		sqlDollar = sqlS[sqlpt-4 : sqlpt+1]
+//line sql-gen.y:10115
 		{
-
-			sqlVAL.union.val = &tree.ShowFingerprints{Table: sqlDollar[5].union.unresolvedObjectName()}
+			sqlVAL.union.val = &tree.ShowFingerprintOptions{StartTimestamp: sqlDollar[4].union.expr()}
 		}
-	case 1522:
-		sqlDollar = sqlS[sqlpt-5 : sqlpt+1]
-//line sql-gen.y:9045
+	case 1725:
+		sqlDollar = sqlS[sqlpt-4 : sqlpt+1]
+//line sql-gen.y:10119
 		{
-
-			sqlVAL.union.val = &tree.ShowFingerprints{TenantSpec: sqlDollar[5].union.tenantSpec()}
+			sqlVAL.union.val = &tree.ShowFingerprintOptions{ExcludedUserColumns: sqlDollar[4].union.stringOrPlaceholderOptList()}
 		}
-	case 1523:
+	case 1726:
 		sqlDollar = sqlS[sqlpt-4 : sqlpt+1]
-//line sql-gen.y:9052
+//line sql-gen.y:10127
 		{
 			sqlVAL.union.val = &tree.ShowFullTableScans{}
 		}
-	case 1524:
+	case 1727:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:9058
+//line sql-gen.y:10133
 		{
 			tmp := sqlDollar[2].union.grantTargetList()
 			sqlVAL.union.val = &tmp
 		}
-	case 1525:
+	case 1728:
 		sqlDollar = sqlS[sqlpt-0 : sqlpt+1]
-//line sql-gen.y:9063
+//line sql-gen.y:10138
 		{
 			sqlVAL.union.val = (*tree.GrantTargetList)(nil)
 		}
-	case 1526:
+	case 1729:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:9185
+//line sql-gen.y:10260
 		{
 			sqlVAL.union.val = tree.GrantTargetList{Tables: tree.TableAttrs{SequenceOnly: false, TablePatterns: tree.TablePatterns{&tree.UnresolvedName{NumParts: 1, Parts: tree.NameParts{sqlDollar[1].str}}}}}
 		}
-	case 1527:
+	case 1730:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:9189
+//line sql-gen.y:10264
 		{
 			sqlVAL.union.val = tree.GrantTargetList{Tables: tree.TableAttrs{SequenceOnly: false, TablePatterns: tree.TablePatterns{&tree.UnresolvedName{NumParts: 1, Parts: tree.NameParts{sqlDollar[1].str}}}}}
 		}
-	case 1528:
+	case 1731:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:9193
+//line sql-gen.y:10268
 		{
 
 			sqlVAL.union.val = tree.GrantTargetList{
@@ -38146,97 +41889,97 @@ sqldefault:
 				ForRoles: sqlDollar[1].str == "role",
 			}
 		}
-	case 1529:
+	case 1732:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:9232
+//line sql-gen.y:10307
 		{
 			sqlVAL.union.val = tree.GrantTargetList{Tables: tree.TableAttrs{SequenceOnly: false, TablePatterns: tree.TablePatterns{sqlDollar[1].union.unresolvedName()}}}
 		}
-	case 1530:
+	case 1733:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:9236
+//line sql-gen.y:10311
 		{
 			sqlVAL.union.val = tree.GrantTargetList{Tables: tree.TableAttrs{SequenceOnly: true, TablePatterns: sqlDollar[2].union.tablePatterns()}}
 		}
-	case 1531:
+	case 1734:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:9240
+//line sql-gen.y:10315
 		{
 			remainderPats := sqlDollar[3].union.tablePatterns()
 			sqlVAL.union.val = tree.GrantTargetList{Tables: tree.TableAttrs{SequenceOnly: false, TablePatterns: append(tree.TablePatterns{sqlDollar[1].union.unresolvedName()}, remainderPats...)}}
 		}
-	case 1532:
+	case 1735:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:9245
+//line sql-gen.y:10320
 		{
 			sqlVAL.union.val = tree.GrantTargetList{Tables: tree.TableAttrs{SequenceOnly: false, TablePatterns: sqlDollar[2].union.tablePatterns()}}
 		}
-	case 1533:
+	case 1736:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:9249
+//line sql-gen.y:10324
 		{
 			sqlVAL.union.val = tree.GrantTargetList{Databases: sqlDollar[2].union.nameList()}
 		}
-	case 1534:
+	case 1737:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:9253
+//line sql-gen.y:10328
 		{
 			sqlVAL.union.val = tree.GrantTargetList{ExternalConnections: sqlDollar[3].union.nameList()}
 		}
-	case 1535:
+	case 1738:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:9257
+//line sql-gen.y:10332
 		{
 			sqlVAL.union.val = tree.GrantTargetList{Functions: sqlDollar[2].union.routineObjs()}
 		}
-	case 1536:
+	case 1739:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:9261
+//line sql-gen.y:10336
 		{
 			sqlVAL.union.val = tree.GrantTargetList{Procedures: sqlDollar[2].union.routineObjs()}
 		}
-	case 1537:
+	case 1740:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:9271
+//line sql-gen.y:10346
 		{
 			sqlVAL.union.val = tree.BackupTargetList{Tables: tree.TableAttrs{SequenceOnly: false, TablePatterns: tree.TablePatterns{&tree.UnresolvedName{NumParts: 1, Parts: tree.NameParts{sqlDollar[1].str}}}}}
 		}
-	case 1538:
+	case 1741:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:9275
+//line sql-gen.y:10350
 		{
 			sqlVAL.union.val = tree.BackupTargetList{Tables: tree.TableAttrs{SequenceOnly: false, TablePatterns: tree.TablePatterns{&tree.UnresolvedName{NumParts: 1, Parts: tree.NameParts{sqlDollar[1].str}}}}}
 		}
-	case 1539:
+	case 1742:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:9279
+//line sql-gen.y:10354
 		{
 			sqlVAL.union.val = tree.BackupTargetList{
 				Tables: tree.TableAttrs{SequenceOnly: false, TablePatterns: tree.TablePatterns{&tree.UnresolvedName{NumParts: 1, Parts: tree.NameParts{sqlDollar[1].str}}}},
 			}
 		}
-	case 1540:
+	case 1743:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:9285
+//line sql-gen.y:10360
 		{
 			sqlVAL.union.val = tree.BackupTargetList{Tables: tree.TableAttrs{SequenceOnly: false, TablePatterns: tree.TablePatterns{sqlDollar[1].union.unresolvedName()}}}
 		}
-	case 1541:
+	case 1744:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:9289
+//line sql-gen.y:10364
 		{
 			remainderPats := sqlDollar[3].union.tablePatterns()
 			sqlVAL.union.val = tree.BackupTargetList{Tables: tree.TableAttrs{SequenceOnly: false, TablePatterns: append(tree.TablePatterns{sqlDollar[1].union.unresolvedName()}, remainderPats...)}}
 		}
-	case 1542:
+	case 1745:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:9294
+//line sql-gen.y:10369
 		{
 			sqlVAL.union.val = tree.BackupTargetList{Tables: tree.TableAttrs{SequenceOnly: false, TablePatterns: sqlDollar[2].union.tablePatterns()}}
 		}
-	case 1543:
+	case 1746:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:9300
+//line sql-gen.y:10375
 		{
 
 			tenID := uint64(sqlDollar[2].union.int64())
@@ -38245,9 +41988,9 @@ sqldefault:
 			}
 			sqlVAL.union.val = tree.BackupTargetList{TenantID: tree.TenantID{Specified: true, ID: tenID}}
 		}
-	case 1544:
+	case 1747:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:9309
+//line sql-gen.y:10384
 		{
 
 			if sqlDollar[2].str != "_" {
@@ -38255,111 +41998,111 @@ sqldefault:
 			}
 			sqlVAL.union.val = tree.BackupTargetList{TenantID: tree.TenantID{Specified: true}}
 		}
-	case 1545:
+	case 1748:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:9319
+//line sql-gen.y:10394
 		{
 			sqlVAL.union.val = tree.BackupTargetList{Databases: sqlDollar[2].union.nameList()}
 		}
-	case 1546:
+	case 1749:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:9328
+//line sql-gen.y:10403
 		{
 			sqlVAL.union.val = tree.GrantTargetList{ForRoles: true, Roles: sqlDollar[2].union.roleSpecList()}
 		}
-	case 1547:
+	case 1750:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:9332
+//line sql-gen.y:10407
 		{
 			sqlVAL.union.val = tree.GrantTargetList{Schemas: sqlDollar[2].union.objectNamePrefixList()}
 		}
-	case 1548:
+	case 1751:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:9336
+//line sql-gen.y:10411
 		{
 			sqlVAL.union.val = tree.GrantTargetList{Schemas: sqlDollar[2].union.objectNamePrefixList()}
 		}
-	case 1549:
+	case 1752:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:9340
+//line sql-gen.y:10415
 		{
 			sqlVAL.union.val = tree.GrantTargetList{Types: sqlDollar[2].union.unresolvedObjectNames()}
 		}
-	case 1551:
+	case 1754:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:9348
+//line sql-gen.y:10423
 		{
 			sqlVAL.union.val = sqlDollar[2].union.roleSpecList()
 		}
-	case 1552:
+	case 1755:
 		sqlDollar = sqlS[sqlpt-0 : sqlpt+1]
-//line sql-gen.y:9352
+//line sql-gen.y:10427
 		{
 			sqlVAL.union.val = tree.RoleSpecList(nil)
 		}
-	case 1554:
+	case 1757:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:9360
+//line sql-gen.y:10435
 		{
 			return helpWith(sqllex, "PAUSE JOBS")
 		}
-	case 1556:
+	case 1759:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:9361
+//line sql-gen.y:10436
 		{
 			return helpWith(sqllex, "PAUSE SCHEDULES")
 		}
-	case 1558:
+	case 1761:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:9362
+//line sql-gen.y:10437
 		{
 			return helpWith(sqllex, "PAUSE ALL JOBS")
 		}
-	case 1559:
+	case 1762:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:9363
+//line sql-gen.y:10438
 		{
 			return helpWith(sqllex, "PAUSE")
 		}
-	case 1561:
+	case 1764:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:9369
+//line sql-gen.y:10444
 		{
 			return helpWith(sqllex, "RESUME JOBS")
 		}
-	case 1563:
+	case 1766:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:9370
+//line sql-gen.y:10445
 		{
 			return helpWith(sqllex, "RESUME SCHEDULES")
 		}
-	case 1565:
+	case 1768:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:9371
+//line sql-gen.y:10446
 		{
 			return helpWith(sqllex, "RESUME ALL JOBS")
 		}
-	case 1566:
+	case 1769:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:9372
+//line sql-gen.y:10447
 		{
 			return helpWith(sqllex, "RESUME")
 		}
-	case 1567:
+	case 1770:
 		sqlDollar = sqlS[sqlpt-4 : sqlpt+1]
-//line sql-gen.y:9380
+//line sql-gen.y:10455
 		{
 			sqlVAL.union.val = &tree.ControlJobsOfType{Type: sqlDollar[3].str, Command: tree.ResumeJob}
 		}
-	case 1568:
+	case 1771:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:9383
+//line sql-gen.y:10458
 		{
 			return helpWith(sqllex, "RESUME ALL JOBS")
 		}
-	case 1569:
+	case 1772:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:9393
+//line sql-gen.y:10468
 		{
 			sqlVAL.union.val = &tree.ControlJobs{
 				Jobs: &tree.Select{
@@ -38368,9 +42111,9 @@ sqldefault:
 				Command: tree.PauseJob,
 			}
 		}
-	case 1570:
+	case 1773:
 		sqlDollar = sqlS[sqlpt-7 : sqlpt+1]
-//line sql-gen.y:9402
+//line sql-gen.y:10477
 		{
 			sqlVAL.union.val = &tree.ControlJobs{
 				Jobs: &tree.Select{
@@ -38380,53 +42123,53 @@ sqldefault:
 				Reason:  sqlDollar[7].union.expr(),
 			}
 		}
-	case 1571:
+	case 1774:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:9411
+//line sql-gen.y:10486
 		{
 			return helpWith(sqllex, "PAUSE JOBS")
 		}
-	case 1572:
+	case 1775:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:9413
+//line sql-gen.y:10488
 		{
 			sqlVAL.union.val = &tree.ControlJobs{Jobs: sqlDollar[3].union.slct(), Command: tree.PauseJob}
 		}
-	case 1573:
+	case 1776:
 		sqlDollar = sqlS[sqlpt-7 : sqlpt+1]
-//line sql-gen.y:9417
+//line sql-gen.y:10492
 		{
 			sqlVAL.union.val = &tree.ControlJobs{Jobs: sqlDollar[3].union.slct(), Command: tree.PauseJob, Reason: sqlDollar[7].union.expr()}
 		}
-	case 1574:
+	case 1777:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:9421
+//line sql-gen.y:10496
 		{
 			sqlVAL.union.val = &tree.ControlJobsForSchedules{Schedules: sqlDollar[3].union.slct(), Command: tree.PauseJob}
 		}
-	case 1575:
+	case 1778:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:9424
+//line sql-gen.y:10499
 		{
 			return helpWith(sqllex, "PAUSE JOBS")
 		}
-	case 1576:
+	case 1779:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:9429
+//line sql-gen.y:10504
 		{
 			sqlVAL.union.val = sqlDollar[3].union.slct()
 		}
-	case 1577:
+	case 1780:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:9433
+//line sql-gen.y:10508
 		{
 			sqlVAL.union.val = &tree.Select{
 				Select: &tree.ValuesClause{Rows: []tree.Exprs{tree.Exprs{sqlDollar[3].union.expr()}}},
 			}
 		}
-	case 1578:
+	case 1781:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:9448
+//line sql-gen.y:10523
 		{
 			sqlVAL.union.val = &tree.ControlSchedules{
 				Schedules: &tree.Select{
@@ -38435,68 +42178,68 @@ sqldefault:
 				Command: tree.PauseSchedule,
 			}
 		}
-	case 1579:
+	case 1782:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:9456
+//line sql-gen.y:10531
 		{
 			return helpWith(sqllex, "PAUSE SCHEDULES")
 		}
-	case 1580:
+	case 1783:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:9458
+//line sql-gen.y:10533
 		{
 			sqlVAL.union.val = &tree.ControlSchedules{
 				Schedules: sqlDollar[3].union.slct(),
 				Command:   tree.PauseSchedule,
 			}
 		}
-	case 1581:
+	case 1784:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:9464
+//line sql-gen.y:10539
 		{
 			return helpWith(sqllex, "PAUSE SCHEDULES")
 		}
-	case 1582:
+	case 1785:
 		sqlDollar = sqlS[sqlpt-4 : sqlpt+1]
-//line sql-gen.y:9472
+//line sql-gen.y:10547
 		{
 			sqlVAL.union.val = &tree.ControlJobsOfType{Type: sqlDollar[3].str, Command: tree.PauseJob}
 		}
-	case 1583:
+	case 1786:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:9475
+//line sql-gen.y:10550
 		{
 			return helpWith(sqllex, "PAUSE ALL JOBS")
 		}
-	case 1584:
+	case 1787:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:9484
+//line sql-gen.y:10559
 		{
 			sqlVAL.union.val = &tree.CreateSchema{
 				Schema: sqlDollar[3].union.objectNamePrefix(),
 			}
 		}
-	case 1585:
+	case 1788:
 		sqlDollar = sqlS[sqlpt-6 : sqlpt+1]
-//line sql-gen.y:9490
+//line sql-gen.y:10565
 		{
 			sqlVAL.union.val = &tree.CreateSchema{
 				Schema:      sqlDollar[6].union.objectNamePrefix(),
 				IfNotExists: true,
 			}
 		}
-	case 1586:
+	case 1789:
 		sqlDollar = sqlS[sqlpt-5 : sqlpt+1]
-//line sql-gen.y:9497
+//line sql-gen.y:10572
 		{
 			sqlVAL.union.val = &tree.CreateSchema{
 				Schema:   sqlDollar[3].union.objectNamePrefix(),
 				AuthRole: sqlDollar[5].union.roleSpec(),
 			}
 		}
-	case 1587:
+	case 1790:
 		sqlDollar = sqlS[sqlpt-8 : sqlpt+1]
-//line sql-gen.y:9504
+//line sql-gen.y:10579
 		{
 			sqlVAL.union.val = &tree.CreateSchema{
 				Schema:      sqlDollar[6].union.objectNamePrefix(),
@@ -38504,15 +42247,15 @@ sqldefault:
 				AuthRole:    sqlDollar[8].union.roleSpec(),
 			}
 		}
-	case 1588:
+	case 1791:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:9511
+//line sql-gen.y:10586
 		{
 			return helpWith(sqllex, "CREATE SCHEMA")
 		}
-	case 1589:
+	case 1792:
 		sqlDollar = sqlS[sqlpt-6 : sqlpt+1]
-//line sql-gen.y:9522
+//line sql-gen.y:10597
 		{
 			sqlVAL.union.val = &tree.AlterSchema{
 				Schema: sqlDollar[3].union.objectNamePrefix(),
@@ -38521,9 +42264,9 @@ sqldefault:
 				},
 			}
 		}
-	case 1590:
+	case 1793:
 		sqlDollar = sqlS[sqlpt-6 : sqlpt+1]
-//line sql-gen.y:9531
+//line sql-gen.y:10606
 		{
 			sqlVAL.union.val = &tree.AlterSchema{
 				Schema: sqlDollar[3].union.objectNamePrefix(),
@@ -38532,15 +42275,15 @@ sqldefault:
 				},
 			}
 		}
-	case 1591:
+	case 1794:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:9539
+//line sql-gen.y:10614
 		{
 			return helpWith(sqllex, "ALTER SCHEMA")
 		}
-	case 1592:
+	case 1795:
 		sqlDollar = sqlS[sqlpt-12 : sqlpt+1]
-//line sql-gen.y:9575
+//line sql-gen.y:10650
 		{
 			name := sqlDollar[4].union.unresolvedObjectName().ToTableName()
 			sqlVAL.union.val = &tree.CreateTable{
@@ -38555,9 +42298,9 @@ sqldefault:
 				Locality:         sqlDollar[12].union.locality(),
 			}
 		}
-	case 1593:
+	case 1796:
 		sqlDollar = sqlS[sqlpt-15 : sqlpt+1]
-//line sql-gen.y:9590
+//line sql-gen.y:10665
 		{
 			name := sqlDollar[7].union.unresolvedObjectName().ToTableName()
 			sqlVAL.union.val = &tree.CreateTable{
@@ -38572,113 +42315,113 @@ sqldefault:
 				Locality:         sqlDollar[15].union.locality(),
 			}
 		}
-	case 1594:
+	case 1797:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:9607
+//line sql-gen.y:10682
 		{
 			sqlVAL.union.val = sqlDollar[1].union.locality()
 		}
-	case 1595:
+	case 1798:
 		sqlDollar = sqlS[sqlpt-0 : sqlpt+1]
-//line sql-gen.y:9611
+//line sql-gen.y:10686
 		{
 			sqlVAL.union.val = (*tree.Locality)(nil)
 		}
-	case 1597:
+	case 1800:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:9618
+//line sql-gen.y:10693
 		{
 
 			sqlVAL.union.val = nil
 		}
-	case 1598:
+	case 1801:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:9624
+//line sql-gen.y:10699
 		{
 			return unimplemented(sqllex, "create table with oids")
 		}
-	case 1599:
+	case 1802:
 		sqlDollar = sqlS[sqlpt-0 : sqlpt+1]
-//line sql-gen.y:9630
+//line sql-gen.y:10705
 		{
 			sqlVAL.str = ""
 		}
-	case 1600:
+	case 1803:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:9634
+//line sql-gen.y:10709
 		{
 
 			return unimplementedWithIssueDetail(sqllex, 22456, "create table inherits")
 		}
-	case 1601:
+	case 1804:
 		sqlDollar = sqlS[sqlpt-0 : sqlpt+1]
-//line sql-gen.y:9640
+//line sql-gen.y:10715
 		{
 			sqlVAL.union.val = nil
 		}
-	case 1602:
+	case 1805:
 		sqlDollar = sqlS[sqlpt-4 : sqlpt+1]
-//line sql-gen.y:9644
+//line sql-gen.y:10719
 		{
 			sqlVAL.union.val = sqlDollar[3].union.storageParams()
 		}
-	case 1603:
+	case 1806:
 		sqlDollar = sqlS[sqlpt-0 : sqlpt+1]
-//line sql-gen.y:9649
+//line sql-gen.y:10724
 		{
 			sqlVAL.union.val = tree.CreateTableOnCommitUnset
 		}
-	case 1604:
+	case 1807:
 		sqlDollar = sqlS[sqlpt-4 : sqlpt+1]
-//line sql-gen.y:9653
+//line sql-gen.y:10728
 		{
 			sqlVAL.union.val = tree.CreateTableOnCommitPreserveRows
 		}
-	case 1605:
+	case 1808:
 		sqlDollar = sqlS[sqlpt-5 : sqlpt+1]
-//line sql-gen.y:9657
+//line sql-gen.y:10732
 		{
 			return unimplementedWithIssueDetail(sqllex, 46556, "delete rows")
 		}
-	case 1606:
+	case 1809:
 		sqlDollar = sqlS[sqlpt-4 : sqlpt+1]
-//line sql-gen.y:9661
+//line sql-gen.y:10736
 		{
 			return unimplementedWithIssueDetail(sqllex, 46556, "drop")
 		}
-	case 1609:
+	case 1812:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:9671
+//line sql-gen.y:10746
 		{
-			sqlVAL.union.val = []tree.Name{tree.Name(sqlDollar[1].str)}
+			sqlVAL.union.val = []string{sqlDollar[1].str}
 		}
-	case 1610:
+	case 1813:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:9675
+//line sql-gen.y:10750
 		{
-			sqlVAL.union.val = append(sqlDollar[1].union.storageParamKeys(), tree.Name(sqlDollar[3].str))
+			sqlVAL.union.val = append(sqlDollar[1].union.storageParamKeys(), sqlDollar[3].str)
 		}
-	case 1611:
+	case 1814:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:9681
+//line sql-gen.y:10756
 		{
-			sqlVAL.union.val = tree.StorageParam{Key: tree.Name(sqlDollar[1].str), Value: sqlDollar[3].union.expr()}
+			sqlVAL.union.val = tree.StorageParam{Key: sqlDollar[1].str, Value: sqlDollar[3].union.expr()}
 		}
-	case 1612:
+	case 1815:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:9687
+//line sql-gen.y:10762
 		{
 			sqlVAL.union.val = []tree.StorageParam{sqlDollar[1].union.storageParam()}
 		}
-	case 1613:
+	case 1816:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:9691
+//line sql-gen.y:10766
 		{
 			sqlVAL.union.val = append(sqlDollar[1].union.storageParams(), sqlDollar[3].union.storageParam())
 		}
-	case 1614:
+	case 1817:
 		sqlDollar = sqlS[sqlpt-10 : sqlpt+1]
-//line sql-gen.y:9697
+//line sql-gen.y:10772
 		{
 			name := sqlDollar[4].union.unresolvedObjectName().ToTableName()
 			sqlVAL.union.val = &tree.CreateTable{
@@ -38691,9 +42434,9 @@ sqldefault:
 				Persistence:   sqlDollar[2].union.persistence(),
 			}
 		}
-	case 1615:
+	case 1818:
 		sqlDollar = sqlS[sqlpt-13 : sqlpt+1]
-//line sql-gen.y:9710
+//line sql-gen.y:10785
 		{
 			name := sqlDollar[7].union.unresolvedObjectName().ToTableName()
 			sqlVAL.union.val = &tree.CreateTable{
@@ -38706,101 +42449,101 @@ sqldefault:
 				Persistence:   sqlDollar[2].union.persistence(),
 			}
 		}
-	case 1616:
+	case 1819:
 		sqlDollar = sqlS[sqlpt-0 : sqlpt+1]
-//line sql-gen.y:9724
+//line sql-gen.y:10799
 		{
 		}
-	case 1617:
+	case 1820:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:9725
+//line sql-gen.y:10800
 		{
 		}
-	case 1618:
+	case 1821:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:9726
+//line sql-gen.y:10801
 		{
 			return unimplemented(sqllex, "create table as with no data")
 		}
-	case 1619:
+	case 1822:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:9744
+//line sql-gen.y:10819
 		{
 			sqlVAL.union.val = tree.PersistenceTemporary
 		}
-	case 1620:
+	case 1823:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:9745
+//line sql-gen.y:10820
 		{
 			sqlVAL.union.val = tree.PersistenceTemporary
 		}
-	case 1621:
+	case 1824:
 		sqlDollar = sqlS[sqlpt-0 : sqlpt+1]
-//line sql-gen.y:9746
+//line sql-gen.y:10821
 		{
 			sqlVAL.union.val = tree.PersistencePermanent
 		}
-	case 1623:
+	case 1826:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:9750
+//line sql-gen.y:10825
 		{
 			sqlVAL.union.val = tree.PersistenceTemporary
 		}
-	case 1624:
+	case 1827:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:9751
+//line sql-gen.y:10826
 		{
 			sqlVAL.union.val = tree.PersistenceTemporary
 		}
-	case 1625:
+	case 1828:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:9752
+//line sql-gen.y:10827
 		{
 			sqlVAL.union.val = tree.PersistenceTemporary
 		}
-	case 1626:
+	case 1829:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:9753
+//line sql-gen.y:10828
 		{
 			sqlVAL.union.val = tree.PersistenceTemporary
 		}
-	case 1627:
+	case 1830:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:9754
+//line sql-gen.y:10829
 		{
 			sqlVAL.union.val = tree.PersistenceUnlogged
 		}
-	case 1629:
+	case 1832:
 		sqlDollar = sqlS[sqlpt-0 : sqlpt+1]
-//line sql-gen.y:9759
+//line sql-gen.y:10834
 		{
 			sqlVAL.union.val = tree.TableDefs(nil)
 		}
-	case 1630:
+	case 1833:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:9765
+//line sql-gen.y:10840
 		{
 			sqlVAL.union.val = tree.TableDefs{sqlDollar[1].union.tblDef()}
 		}
-	case 1631:
+	case 1834:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:9769
+//line sql-gen.y:10844
 		{
 			sqlVAL.union.val = append(sqlDollar[1].union.tblDefs(), sqlDollar[3].union.tblDef())
 		}
-	case 1632:
+	case 1835:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:9775
+//line sql-gen.y:10850
 		{
 			sqlVAL.union.val = sqlDollar[1].union.colTableDef()
 		}
-	case 1635:
+	case 1838:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:9781
+//line sql-gen.y:10856
 		{
 			def := sqlDollar[1].union.constraintDef()
 			valBehavior := sqlDollar[2].union.validationBehavior()
-			if u, ok := def.(*tree.UniqueConstraintTableDef); ok && valBehavior == tree.ValidationSkip {
+			if u, ok := def.(*tree.UniqueConstraintTableDef); ok && valBehavior == tree.ValidationSkip && !u.WithoutIndex {
 				typ := "PRIMARY KEY"
 				if !u.PrimaryKey {
 					typ = "UNIQUE"
@@ -38809,197 +42552,197 @@ sqldefault:
 			}
 			sqlVAL.union.val = def
 		}
-	case 1636:
+	case 1839:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:9794
+//line sql-gen.y:10869
 		{
 			sqlVAL.union.val = &tree.LikeTableDef{
 				Name:    sqlDollar[2].union.unresolvedObjectName().ToTableName(),
 				Options: sqlDollar[3].union.likeTableOptionList(),
 			}
 		}
-	case 1637:
+	case 1840:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:9803
+//line sql-gen.y:10878
 		{
 			sqlVAL.union.val = append(sqlDollar[1].union.likeTableOptionList(), sqlDollar[3].union.likeTableOption())
 		}
-	case 1638:
+	case 1841:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:9807
+//line sql-gen.y:10882
 		{
 			opt := sqlDollar[3].union.likeTableOption()
 			opt.Excluded = true
 			sqlVAL.union.val = append(sqlDollar[1].union.likeTableOptionList(), opt)
 		}
-	case 1639:
+	case 1842:
 		sqlDollar = sqlS[sqlpt-0 : sqlpt+1]
-//line sql-gen.y:9813
+//line sql-gen.y:10888
 		{
 			sqlVAL.union.val = []tree.LikeTableOption(nil)
 		}
-	case 1640:
+	case 1843:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:9818
+//line sql-gen.y:10893
 		{
 			return unimplementedWithIssueDetail(sqllex, 47071, "like table in/excluding comments")
 		}
-	case 1641:
+	case 1844:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:9819
+//line sql-gen.y:10894
 		{
 			sqlVAL.union.val = tree.LikeTableOption{Opt: tree.LikeTableOptConstraints}
 		}
-	case 1642:
+	case 1845:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:9820
+//line sql-gen.y:10895
 		{
 			sqlVAL.union.val = tree.LikeTableOption{Opt: tree.LikeTableOptDefaults}
 		}
-	case 1643:
+	case 1846:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:9821
+//line sql-gen.y:10896
 		{
 			return unimplementedWithIssueDetail(sqllex, 47071, "like table in/excluding identity")
 		}
-	case 1644:
+	case 1847:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:9822
+//line sql-gen.y:10897
 		{
 			sqlVAL.union.val = tree.LikeTableOption{Opt: tree.LikeTableOptGenerated}
 		}
-	case 1645:
+	case 1848:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:9823
+//line sql-gen.y:10898
 		{
 			sqlVAL.union.val = tree.LikeTableOption{Opt: tree.LikeTableOptIndexes}
 		}
-	case 1646:
+	case 1849:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:9824
+//line sql-gen.y:10899
 		{
 			return unimplementedWithIssueDetail(sqllex, 47071, "like table in/excluding statistics")
 		}
-	case 1647:
+	case 1850:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:9825
+//line sql-gen.y:10900
 		{
 			return unimplementedWithIssueDetail(sqllex, 47071, "like table in/excluding storage")
 		}
-	case 1648:
+	case 1851:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:9826
+//line sql-gen.y:10901
 		{
 			sqlVAL.union.val = tree.LikeTableOption{Opt: tree.LikeTableOptAll}
 		}
-	case 1649:
+	case 1852:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:9831
+//line sql-gen.y:10906
 		{
 			sqlVAL.str = sqlDollar[2].str
 		}
-	case 1651:
+	case 1854:
 		sqlDollar = sqlS[sqlpt-0 : sqlpt+1]
-//line sql-gen.y:9838
+//line sql-gen.y:10913
 		{
 			sqlVAL.str = ""
 		}
-	case 1653:
+	case 1856:
 		sqlDollar = sqlS[sqlpt-0 : sqlpt+1]
-//line sql-gen.y:9845
+//line sql-gen.y:10920
 		{
 			sqlVAL.union.val = (*tree.PartitionBy)(nil)
 		}
-	case 1654:
+	case 1857:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:9851
+//line sql-gen.y:10926
 		{
 			sqlVAL.union.val = &tree.PartitionByIndex{
 				PartitionBy: sqlDollar[1].union.partitionBy(),
 			}
 		}
-	case 1655:
+	case 1858:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:9859
+//line sql-gen.y:10934
 		{
 			sqlVAL.union.val = &tree.PartitionByIndex{
 				PartitionBy: sqlDollar[1].union.partitionBy(),
 			}
 		}
-	case 1656:
+	case 1859:
 		sqlDollar = sqlS[sqlpt-0 : sqlpt+1]
-//line sql-gen.y:9865
+//line sql-gen.y:10940
 		{
 			sqlVAL.union.val = (*tree.PartitionByIndex)(nil)
 		}
-	case 1657:
+	case 1860:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:9871
+//line sql-gen.y:10946
 		{
 			sqlVAL.union.val = &tree.PartitionByTable{
 				PartitionBy: sqlDollar[1].union.partitionBy(),
 			}
 		}
-	case 1658:
+	case 1861:
 		sqlDollar = sqlS[sqlpt-4 : sqlpt+1]
-//line sql-gen.y:9877
+//line sql-gen.y:10952
 		{
 			sqlVAL.union.val = &tree.PartitionByTable{
 				All:         true,
 				PartitionBy: sqlDollar[4].union.partitionBy(),
 			}
 		}
-	case 1660:
+	case 1863:
 		sqlDollar = sqlS[sqlpt-0 : sqlpt+1]
-//line sql-gen.y:9887
+//line sql-gen.y:10962
 		{
 			sqlVAL.union.val = (*tree.PartitionByTable)(nil)
 		}
-	case 1661:
+	case 1864:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:9893
+//line sql-gen.y:10968
 		{
 			sqlVAL.union.val = sqlDollar[3].union.partitionBy()
 		}
-	case 1662:
+	case 1865:
 		sqlDollar = sqlS[sqlpt-7 : sqlpt+1]
-//line sql-gen.y:9899
+//line sql-gen.y:10974
 		{
 			sqlVAL.union.val = &tree.PartitionBy{
 				Fields: sqlDollar[3].union.nameList(),
 				List:   sqlDollar[6].union.listPartitions(),
 			}
 		}
-	case 1663:
+	case 1866:
 		sqlDollar = sqlS[sqlpt-7 : sqlpt+1]
-//line sql-gen.y:9906
+//line sql-gen.y:10981
 		{
 			sqlVAL.union.val = &tree.PartitionBy{
 				Fields: sqlDollar[3].union.nameList(),
 				Range:  sqlDollar[6].union.rangePartitions(),
 			}
 		}
-	case 1664:
+	case 1867:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:9913
+//line sql-gen.y:10988
 		{
 			sqlVAL.union.val = (*tree.PartitionBy)(nil)
 		}
-	case 1665:
+	case 1868:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:9919
+//line sql-gen.y:10994
 		{
 			sqlVAL.union.val = []tree.ListPartition{sqlDollar[1].union.listPartition()}
 		}
-	case 1666:
+	case 1869:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:9923
+//line sql-gen.y:10998
 		{
 			sqlVAL.union.val = append(sqlDollar[1].union.listPartitions(), sqlDollar[3].union.listPartition())
 		}
-	case 1667:
+	case 1870:
 		sqlDollar = sqlS[sqlpt-7 : sqlpt+1]
-//line sql-gen.y:9929
+//line sql-gen.y:11004
 		{
 			sqlVAL.union.val = tree.ListPartition{
 				Name:         tree.Name(sqlDollar[1].str),
@@ -39007,21 +42750,21 @@ sqldefault:
 				Subpartition: sqlDollar[7].union.partitionBy(),
 			}
 		}
-	case 1668:
+	case 1871:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:9939
+//line sql-gen.y:11014
 		{
 			sqlVAL.union.val = []tree.RangePartition{sqlDollar[1].union.rangePartition()}
 		}
-	case 1669:
+	case 1872:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:9943
+//line sql-gen.y:11018
 		{
 			sqlVAL.union.val = append(sqlDollar[1].union.rangePartitions(), sqlDollar[3].union.rangePartition())
 		}
-	case 1670:
+	case 1873:
 		sqlDollar = sqlS[sqlpt-11 : sqlpt+1]
-//line sql-gen.y:9949
+//line sql-gen.y:11024
 		{
 			sqlVAL.union.val = tree.RangePartition{
 				Name:         tree.Name(sqlDollar[1].str),
@@ -39030,9 +42773,9 @@ sqldefault:
 				Subpartition: sqlDollar[11].union.partitionBy(),
 			}
 		}
-	case 1671:
+	case 1874:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:9963
+//line sql-gen.y:11038
 		{
 			typ := sqlDollar[2].union.typeReference()
 			tableDef, err := tree.NewColumnTableDef(tree.Name(sqlDollar[1].str), typ, tree.IsReferenceSerialType(typ), sqlDollar[3].union.colQuals())
@@ -39041,97 +42784,97 @@ sqldefault:
 			}
 			sqlVAL.union.val = tableDef
 		}
-	case 1672:
+	case 1875:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:9974
+//line sql-gen.y:11049
 		{
 			sqlVAL.union.val = append(sqlDollar[1].union.colQuals(), sqlDollar[2].union.colQual())
 		}
-	case 1673:
+	case 1876:
 		sqlDollar = sqlS[sqlpt-0 : sqlpt+1]
-//line sql-gen.y:9978
+//line sql-gen.y:11053
 		{
 			sqlVAL.union.val = []tree.NamedColumnQualification(nil)
 		}
-	case 1674:
+	case 1877:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:9984
+//line sql-gen.y:11059
 		{
 			sqlVAL.union.val = tree.NamedColumnQualification{Name: tree.Name(sqlDollar[2].str), Qualification: sqlDollar[3].union.colQualElem()}
 		}
-	case 1675:
+	case 1878:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:9988
+//line sql-gen.y:11063
 		{
 			sqlVAL.union.val = tree.NamedColumnQualification{Qualification: sqlDollar[1].union.colQualElem()}
 		}
-	case 1676:
+	case 1879:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:9992
+//line sql-gen.y:11067
 		{
 			sqlVAL.union.val = tree.NamedColumnQualification{Qualification: tree.ColumnCollation(sqlDollar[2].str)}
 		}
-	case 1677:
+	case 1880:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:9996
+//line sql-gen.y:11071
 		{
 			sqlVAL.union.val = tree.NamedColumnQualification{Qualification: &tree.ColumnFamilyConstraint{Family: tree.Name(sqlDollar[2].str)}}
 		}
-	case 1678:
+	case 1881:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:10000
+//line sql-gen.y:11075
 		{
 			sqlVAL.union.val = tree.NamedColumnQualification{Qualification: &tree.ColumnFamilyConstraint{Family: tree.Name(sqlDollar[3].str), Create: true}}
 		}
-	case 1679:
+	case 1882:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:10004
+//line sql-gen.y:11079
 		{
 			sqlVAL.union.val = tree.NamedColumnQualification{Qualification: &tree.ColumnFamilyConstraint{Create: true}}
 		}
-	case 1680:
+	case 1883:
 		sqlDollar = sqlS[sqlpt-6 : sqlpt+1]
-//line sql-gen.y:10008
+//line sql-gen.y:11083
 		{
 			sqlVAL.union.val = tree.NamedColumnQualification{Qualification: &tree.ColumnFamilyConstraint{Family: tree.Name(sqlDollar[6].str), Create: true, IfNotExists: true}}
 		}
-	case 1681:
+	case 1884:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:10026
+//line sql-gen.y:11101
 		{
 			sqlVAL.union.val = tree.NotNullConstraint{}
 		}
-	case 1682:
+	case 1885:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:10030
+//line sql-gen.y:11105
 		{
 			sqlVAL.union.val = tree.NullConstraint{}
 		}
-	case 1683:
+	case 1886:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:10034
+//line sql-gen.y:11109
 		{
 			sqlVAL.union.val = tree.HiddenConstraint{}
 		}
-	case 1684:
+	case 1887:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:10038
+//line sql-gen.y:11113
 		{
 			sqlVAL.union.val = tree.UniqueConstraint{
 				WithoutIndex: sqlDollar[2].union.bool(),
 			}
 		}
-	case 1685:
+	case 1888:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:10044
+//line sql-gen.y:11119
 		{
 			sqlVAL.union.val = tree.PrimaryKeyConstraint{
 				StorageParams: sqlDollar[3].union.storageParams(),
 			}
 		}
-	case 1686:
+	case 1889:
 		sqlDollar = sqlS[sqlpt-6 : sqlpt+1]
-//line sql-gen.y:10050
+//line sql-gen.y:11125
 		{
 			sqlVAL.union.val = tree.ShardedPrimaryKeyConstraint{
 				Sharded:       true,
@@ -39139,27 +42882,27 @@ sqldefault:
 				StorageParams: sqlDollar[6].union.storageParams(),
 			}
 		}
-	case 1687:
+	case 1890:
 		sqlDollar = sqlS[sqlpt-4 : sqlpt+1]
-//line sql-gen.y:10058
+//line sql-gen.y:11133
 		{
 			sqlVAL.union.val = &tree.ColumnCheckConstraint{Expr: sqlDollar[3].union.expr()}
 		}
-	case 1688:
+	case 1891:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:10062
+//line sql-gen.y:11137
 		{
 			sqlVAL.union.val = &tree.ColumnDefault{Expr: sqlDollar[2].union.expr()}
 		}
-	case 1689:
+	case 1892:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:10066
+//line sql-gen.y:11141
 		{
 			sqlVAL.union.val = &tree.ColumnOnUpdate{Expr: sqlDollar[3].union.expr()}
 		}
-	case 1690:
+	case 1893:
 		sqlDollar = sqlS[sqlpt-5 : sqlpt+1]
-//line sql-gen.y:10070
+//line sql-gen.y:11145
 		{
 			name := sqlDollar[2].union.unresolvedObjectName().ToTableName()
 			sqlVAL.union.val = &tree.ColumnFKConstraint{
@@ -39169,84 +42912,84 @@ sqldefault:
 				Match:   sqlDollar[4].union.compositeKeyMatchMethod(),
 			}
 		}
-	case 1691:
+	case 1894:
 		sqlDollar = sqlS[sqlpt-5 : sqlpt+1]
-//line sql-gen.y:10080
+//line sql-gen.y:11155
 		{
 			sqlVAL.union.val = &tree.ColumnComputedDef{Expr: sqlDollar[3].union.expr(), Virtual: false}
 		}
-	case 1692:
+	case 1895:
 		sqlDollar = sqlS[sqlpt-5 : sqlpt+1]
-//line sql-gen.y:10084
+//line sql-gen.y:11159
 		{
 			sqlVAL.union.val = &tree.ColumnComputedDef{Expr: sqlDollar[3].union.expr(), Virtual: true}
 		}
-	case 1693:
+	case 1896:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:10088
+//line sql-gen.y:11163
 		{
 			sqllex.Error("use AS ( <expr> ) STORED or AS ( <expr> ) VIRTUAL")
 			return 1
 		}
-	case 1694:
+	case 1897:
 		sqlDollar = sqlS[sqlpt-5 : sqlpt+1]
-//line sql-gen.y:10093
+//line sql-gen.y:11168
 		{
 			sqlVAL.union.val = &tree.GeneratedAlwaysAsIdentity{
 				SeqOptions: sqlDollar[4].union.seqOpts(),
 			}
 		}
-	case 1695:
+	case 1898:
 		sqlDollar = sqlS[sqlpt-5 : sqlpt+1]
-//line sql-gen.y:10099
+//line sql-gen.y:11174
 		{
 			sqlVAL.union.val = &tree.GeneratedByDefAsIdentity{
 				SeqOptions: sqlDollar[4].union.seqOpts(),
 			}
 		}
-	case 1696:
+	case 1899:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:10105
+//line sql-gen.y:11180
 		{
 			sqlVAL.union.val = &tree.GeneratedAlwaysAsIdentity{}
 		}
-	case 1697:
+	case 1900:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:10109
+//line sql-gen.y:11184
 		{
 			sqlVAL.union.val = &tree.GeneratedByDefAsIdentity{}
 		}
-	case 1698:
+	case 1901:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:10115
+//line sql-gen.y:11190
 		{
 
 			sqlVAL.union.val = true
 		}
-	case 1699:
+	case 1902:
 		sqlDollar = sqlS[sqlpt-0 : sqlpt+1]
-//line sql-gen.y:10120
+//line sql-gen.y:11195
 		{
 			sqlVAL.union.val = false
 		}
-	case 1700:
+	case 1903:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:10125
+//line sql-gen.y:11200
 		{
 		}
-	case 1702:
+	case 1907:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:10129
+//line sql-gen.y:11210
 		{
 		}
-	case 1703:
+	case 1908:
 		sqlDollar = sqlS[sqlpt-4 : sqlpt+1]
-//line sql-gen.y:10132
+//line sql-gen.y:11213
 		{
 		}
-	case 1704:
+	case 1909:
 		sqlDollar = sqlS[sqlpt-10 : sqlpt+1]
-//line sql-gen.y:10136
+//line sql-gen.y:11217
 		{
 			sqlVAL.union.val = &tree.IndexTableDef{
 				Name:             "",
@@ -39259,9 +43002,9 @@ sqldefault:
 				Invisibility:     sqlDollar[10].union.indexInvisibility(),
 			}
 		}
-	case 1705:
+	case 1910:
 		sqlDollar = sqlS[sqlpt-11 : sqlpt+1]
-//line sql-gen.y:10149
+//line sql-gen.y:11230
 		{
 			sqlVAL.union.val = &tree.IndexTableDef{
 				Name:             tree.Name(sqlDollar[2].str),
@@ -39274,9 +43017,9 @@ sqldefault:
 				Invisibility:     sqlDollar[11].union.indexInvisibility(),
 			}
 		}
-	case 1706:
+	case 1911:
 		sqlDollar = sqlS[sqlpt-12 : sqlpt+1]
-//line sql-gen.y:10162
+//line sql-gen.y:11243
 		{
 			sqlVAL.union.val = &tree.UniqueConstraintTableDef{
 				IndexTableDef: tree.IndexTableDef{
@@ -39289,69 +43032,98 @@ sqldefault:
 					Predicate:        sqlDollar[11].union.expr(),
 					Invisibility:     sqlDollar[12].union.indexInvisibility(),
 				},
+				FormatAsIndex: true,
 			}
 		}
-	case 1707:
+	case 1912:
 		sqlDollar = sqlS[sqlpt-9 : sqlpt+1]
-//line sql-gen.y:10177
+//line sql-gen.y:11259
 		{
 			sqlVAL.union.val = &tree.IndexTableDef{
 				Name:             "",
 				Columns:          sqlDollar[4].union.idxElems(),
-				Inverted:         true,
+				Type:             idxtype.INVERTED,
 				PartitionByIndex: sqlDollar[6].union.partitionByIndex(),
 				StorageParams:    sqlDollar[7].union.storageParams(),
 				Predicate:        sqlDollar[8].union.expr(),
 				Invisibility:     sqlDollar[9].union.indexInvisibility(),
 			}
 		}
-	case 1708:
+	case 1913:
 		sqlDollar = sqlS[sqlpt-10 : sqlpt+1]
-//line sql-gen.y:10189
+//line sql-gen.y:11271
 		{
 			sqlVAL.union.val = &tree.IndexTableDef{
 				Name:             tree.Name(sqlDollar[3].str),
 				Columns:          sqlDollar[5].union.idxElems(),
-				Inverted:         true,
+				Type:             idxtype.INVERTED,
 				PartitionByIndex: sqlDollar[7].union.partitionByIndex(),
 				StorageParams:    sqlDollar[8].union.storageParams(),
 				Predicate:        sqlDollar[9].union.expr(),
 				Invisibility:     sqlDollar[10].union.indexInvisibility(),
 			}
 		}
-	case 1709:
+	case 1914:
+		sqlDollar = sqlS[sqlpt-9 : sqlpt+1]
+//line sql-gen.y:11283
+		{
+			sqlVAL.union.val = &tree.IndexTableDef{
+				Name:             "",
+				Columns:          sqlDollar[4].union.idxElems(),
+				Type:             idxtype.VECTOR,
+				PartitionByIndex: sqlDollar[6].union.partitionByIndex(),
+				StorageParams:    sqlDollar[7].union.storageParams(),
+				Predicate:        sqlDollar[8].union.expr(),
+				Invisibility:     sqlDollar[9].union.indexInvisibility(),
+			}
+		}
+	case 1915:
+		sqlDollar = sqlS[sqlpt-10 : sqlpt+1]
+//line sql-gen.y:11295
+		{
+			sqlVAL.union.val = &tree.IndexTableDef{
+				Name:             tree.Name(sqlDollar[3].str),
+				Columns:          sqlDollar[5].union.idxElems(),
+				Type:             idxtype.VECTOR,
+				PartitionByIndex: sqlDollar[7].union.partitionByIndex(),
+				StorageParams:    sqlDollar[8].union.storageParams(),
+				Predicate:        sqlDollar[9].union.expr(),
+				Invisibility:     sqlDollar[10].union.indexInvisibility(),
+			}
+		}
+	case 1916:
 		sqlDollar = sqlS[sqlpt-5 : sqlpt+1]
-//line sql-gen.y:10203
+//line sql-gen.y:11309
 		{
 			sqlVAL.union.val = &tree.FamilyTableDef{
 				Name:    tree.Name(sqlDollar[2].str),
 				Columns: sqlDollar[4].union.nameList(),
 			}
 		}
-	case 1710:
+	case 1917:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:10215
+//line sql-gen.y:11321
 		{
 			sqlVAL.union.val = sqlDollar[3].union.constraintDef()
 			sqlVAL.union.val.(tree.ConstraintTableDef).SetName(tree.Name(sqlDollar[2].str))
 		}
-	case 1711:
+	case 1918:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:10220
+//line sql-gen.y:11326
 		{
 			sqlVAL.union.val = sqlDollar[1].union.constraintDef()
 		}
-	case 1712:
+	case 1919:
 		sqlDollar = sqlS[sqlpt-5 : sqlpt+1]
-//line sql-gen.y:10226
+//line sql-gen.y:11332
 		{
 			sqlVAL.union.val = &tree.CheckConstraintTableDef{
 				Expr: sqlDollar[3].union.expr(),
 			}
 		}
-	case 1713:
+	case 1920:
 		sqlDollar = sqlS[sqlpt-9 : sqlpt+1]
-//line sql-gen.y:10233
+//line sql-gen.y:11339
 		{
 			sqlVAL.union.val = &tree.UniqueConstraintTableDef{
 				WithoutIndex: sqlDollar[2].union.bool(),
@@ -39363,9 +43135,9 @@ sqldefault:
 				},
 			}
 		}
-	case 1714:
+	case 1921:
 		sqlDollar = sqlS[sqlpt-7 : sqlpt+1]
-//line sql-gen.y:10245
+//line sql-gen.y:11351
 		{
 			sqlVAL.union.val = &tree.UniqueConstraintTableDef{
 				IndexTableDef: tree.IndexTableDef{
@@ -39376,9 +43148,9 @@ sqldefault:
 				PrimaryKey: true,
 			}
 		}
-	case 1715:
+	case 1922:
 		sqlDollar = sqlS[sqlpt-11 : sqlpt+1]
-//line sql-gen.y:10257
+//line sql-gen.y:11363
 		{
 			name := sqlDollar[7].union.unresolvedObjectName().ToTableName()
 			sqlVAL.union.val = &tree.ForeignKeyConstraintTableDef{
@@ -39389,27 +43161,27 @@ sqldefault:
 				Actions:  sqlDollar[10].union.referenceActions(),
 			}
 		}
-	case 1716:
+	case 1923:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:10268
+//line sql-gen.y:11374
 		{
 			return unimplementedWithIssueDetail(sqllex, 46657, "add constraint exclude using")
 		}
-	case 1717:
+	case 1924:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:10275
+//line sql-gen.y:11381
 		{
 			sqlVAL.union.val = sqlDollar[2].union.val
 		}
-	case 1718:
+	case 1925:
 		sqlDollar = sqlS[sqlpt-0 : sqlpt+1]
-//line sql-gen.y:10279
+//line sql-gen.y:11385
 		{
 			sqlVAL.union.val = tree.TableDefs(nil)
 		}
-	case 1719:
+	case 1926:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:10285
+//line sql-gen.y:11391
 		{
 			tableDef, err := tree.NewColumnTableDef(tree.Name(sqlDollar[1].str), nil, false, sqlDollar[2].union.colQuals())
 			if err != nil {
@@ -39419,9 +43191,9 @@ sqldefault:
 			var colToTableDef tree.TableDef = tableDef
 			sqlVAL.union.val = tree.TableDefs{colToTableDef}
 		}
-	case 1720:
+	case 1927:
 		sqlDollar = sqlS[sqlpt-4 : sqlpt+1]
-//line sql-gen.y:10295
+//line sql-gen.y:11401
 		{
 			tableDef, err := tree.NewColumnTableDef(tree.Name(sqlDollar[3].str), nil, false, sqlDollar[4].union.colQuals())
 			if err != nil {
@@ -39432,28 +43204,28 @@ sqldefault:
 
 			sqlVAL.union.val = append(sqlDollar[1].union.tblDefs(), colToTableDef)
 		}
-	case 1721:
+	case 1928:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:10306
+//line sql-gen.y:11412
 		{
 			sqlVAL.union.val = append(sqlDollar[1].union.tblDefs(), sqlDollar[3].union.tblDef())
 		}
-	case 1722:
+	case 1929:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:10310
+//line sql-gen.y:11416
 		{
 			var constraintToTableDef tree.TableDef = sqlDollar[3].union.constraintDef()
 			sqlVAL.union.val = append(sqlDollar[1].union.tblDefs(), constraintToTableDef)
 		}
-	case 1723:
+	case 1930:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:10317
+//line sql-gen.y:11423
 		{
 			sqlVAL.union.val = sqlDollar[1].union.constraintDef()
 		}
-	case 1724:
+	case 1931:
 		sqlDollar = sqlS[sqlpt-6 : sqlpt+1]
-//line sql-gen.y:10323
+//line sql-gen.y:11429
 		{
 			sqlVAL.union.val = &tree.UniqueConstraintTableDef{
 				IndexTableDef: tree.IndexTableDef{
@@ -39463,240 +43235,240 @@ sqldefault:
 				PrimaryKey: true,
 			}
 		}
-	case 1725:
+	case 1932:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:10335
+//line sql-gen.y:11441
 		{
 			sqlVAL.union.val = tree.IndexElemList{sqlDollar[1].union.idxElem()}
 		}
-	case 1726:
+	case 1933:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:10339
+//line sql-gen.y:11445
 		{
 			sqlVAL.union.val = append(sqlDollar[1].union.idxElems(), sqlDollar[3].union.idxElem())
 		}
-	case 1727:
+	case 1934:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:10345
+//line sql-gen.y:11451
 		{
 			sqlVAL.union.val = tree.IndexElem{Column: tree.Name(sqlDollar[1].str)}
 		}
-	case 1728:
+	case 1935:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:10351
+//line sql-gen.y:11457
 		{
 			sqlVAL.union.val = append(sqlDollar[1].union.colQuals(), sqlDollar[2].union.colQual())
 		}
-	case 1729:
+	case 1936:
 		sqlDollar = sqlS[sqlpt-0 : sqlpt+1]
-//line sql-gen.y:10355
+//line sql-gen.y:11461
 		{
 			sqlVAL.union.val = []tree.NamedColumnQualification(nil)
 		}
-	case 1730:
+	case 1937:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:10361
+//line sql-gen.y:11467
 		{
 			sqlVAL.union.val = tree.NamedColumnQualification{Qualification: sqlDollar[1].union.colQualElem()}
 		}
-	case 1731:
+	case 1938:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:10365
+//line sql-gen.y:11471
 		{
 			sqlVAL.union.val = tree.NamedColumnQualification{Qualification: &tree.ColumnFamilyConstraint{Family: tree.Name(sqlDollar[2].str)}}
 		}
-	case 1732:
+	case 1939:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:10371
+//line sql-gen.y:11477
 		{
 			sqlVAL.union.val = tree.PrimaryKeyConstraint{
 				StorageParams: sqlDollar[3].union.storageParams(),
 			}
 		}
-	case 1733:
+	case 1940:
 		sqlDollar = sqlS[sqlpt-0 : sqlpt+1]
-//line sql-gen.y:10378
+//line sql-gen.y:11484
 		{
 		}
-	case 1734:
+	case 1941:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:10379
+//line sql-gen.y:11485
 		{
 			return unimplementedWithIssueDetail(sqllex, 31632, "deferrable")
 		}
-	case 1735:
+	case 1942:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:10380
+//line sql-gen.y:11486
 		{
 			return unimplementedWithIssueDetail(sqllex, 31632, "def initially deferred")
 		}
-	case 1736:
+	case 1943:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:10381
+//line sql-gen.y:11487
 		{
 			return unimplementedWithIssueDetail(sqllex, 31632, "def initially immediate")
 		}
-	case 1737:
+	case 1944:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:10382
+//line sql-gen.y:11488
 		{
 			return unimplementedWithIssueDetail(sqllex, 31632, "initially deferred")
 		}
-	case 1738:
+	case 1945:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:10383
+//line sql-gen.y:11489
 		{
 			return unimplementedWithIssueDetail(sqllex, 31632, "initially immediate")
 		}
-	case 1742:
+	case 1949:
 		sqlDollar = sqlS[sqlpt-4 : sqlpt+1]
-//line sql-gen.y:10401
+//line sql-gen.y:11507
 		{
 			sqlVAL.union.val = sqlDollar[3].union.nameList()
 		}
-	case 1743:
+	case 1950:
 		sqlDollar = sqlS[sqlpt-0 : sqlpt+1]
-//line sql-gen.y:10405
+//line sql-gen.y:11511
 		{
 			sqlVAL.union.val = tree.NameList(nil)
 		}
-	case 1744:
+	case 1951:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:10411
+//line sql-gen.y:11517
 		{
 			sqlVAL.union.val = &tree.ShardedIndexDef{
 				ShardBuckets: sqlDollar[3].union.expr(),
 			}
 		}
-	case 1745:
+	case 1952:
 		sqlDollar = sqlS[sqlpt-0 : sqlpt+1]
-//line sql-gen.y:10417
+//line sql-gen.y:11523
 		{
 			sqlVAL.union.val = (*tree.ShardedIndexDef)(nil)
 		}
-	case 1746:
+	case 1953:
 		sqlDollar = sqlS[sqlpt-4 : sqlpt+1]
-//line sql-gen.y:10423
+//line sql-gen.y:11529
 		{
 			sqlVAL.union.val = sqlDollar[4].union.expr()
 		}
-	case 1747:
+	case 1954:
 		sqlDollar = sqlS[sqlpt-0 : sqlpt+1]
-//line sql-gen.y:10427
+//line sql-gen.y:11533
 		{
 			sqlVAL.union.val = tree.DefaultVal{}
 		}
-	case 1748:
+	case 1955:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:10433
+//line sql-gen.y:11539
 		{
 			sqlVAL.union.val = sqlDollar[2].union.nameList()
 		}
-	case 1749:
+	case 1956:
 		sqlDollar = sqlS[sqlpt-0 : sqlpt+1]
-//line sql-gen.y:10437
+//line sql-gen.y:11543
 		{
 			sqlVAL.union.val = tree.NameList(nil)
 		}
-	case 1750:
+	case 1957:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:10457
+//line sql-gen.y:11563
 		{
 			sqlVAL.union.val = tree.MatchSimple
 		}
-	case 1751:
+	case 1958:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:10461
+//line sql-gen.y:11567
 		{
 			sqlVAL.union.val = tree.MatchFull
 		}
-	case 1752:
+	case 1959:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:10465
+//line sql-gen.y:11571
 		{
 			return unimplementedWithIssueDetail(sqllex, 20305, "match partial")
 		}
-	case 1753:
+	case 1960:
 		sqlDollar = sqlS[sqlpt-0 : sqlpt+1]
-//line sql-gen.y:10469
+//line sql-gen.y:11575
 		{
 			sqlVAL.union.val = tree.MatchSimple
 		}
-	case 1754:
+	case 1961:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:10478
+//line sql-gen.y:11584
 		{
 			sqlVAL.union.val = tree.ReferenceActions{Update: sqlDollar[1].union.referenceAction()}
 		}
-	case 1755:
+	case 1962:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:10482
+//line sql-gen.y:11588
 		{
 			sqlVAL.union.val = tree.ReferenceActions{Delete: sqlDollar[1].union.referenceAction()}
 		}
-	case 1756:
+	case 1963:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:10486
+//line sql-gen.y:11592
 		{
 			sqlVAL.union.val = tree.ReferenceActions{Update: sqlDollar[1].union.referenceAction(), Delete: sqlDollar[2].union.referenceAction()}
 		}
-	case 1757:
+	case 1964:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:10490
+//line sql-gen.y:11596
 		{
 			sqlVAL.union.val = tree.ReferenceActions{Delete: sqlDollar[1].union.referenceAction(), Update: sqlDollar[2].union.referenceAction()}
 		}
-	case 1758:
+	case 1965:
 		sqlDollar = sqlS[sqlpt-0 : sqlpt+1]
-//line sql-gen.y:10494
+//line sql-gen.y:11600
 		{
 			sqlVAL.union.val = tree.ReferenceActions{}
 		}
-	case 1759:
+	case 1966:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:10500
+//line sql-gen.y:11606
 		{
 			sqlVAL.union.val = sqlDollar[3].union.referenceAction()
 		}
-	case 1760:
+	case 1967:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:10506
+//line sql-gen.y:11612
 		{
 			sqlVAL.union.val = sqlDollar[3].union.referenceAction()
 		}
-	case 1761:
+	case 1968:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:10514
+//line sql-gen.y:11620
 		{
 			sqlVAL.union.val = tree.NoAction
 		}
-	case 1762:
+	case 1969:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:10518
+//line sql-gen.y:11624
 		{
 			sqlVAL.union.val = tree.Restrict
 		}
-	case 1763:
+	case 1970:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:10522
+//line sql-gen.y:11628
 		{
 			sqlVAL.union.val = tree.Cascade
 		}
-	case 1764:
+	case 1971:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:10526
+//line sql-gen.y:11632
 		{
 			sqlVAL.union.val = tree.SetNull
 		}
-	case 1765:
+	case 1972:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:10530
+//line sql-gen.y:11636
 		{
 			sqlVAL.union.val = tree.SetDefault
 		}
-	case 1766:
+	case 1973:
 		sqlDollar = sqlS[sqlpt-5 : sqlpt+1]
-//line sql-gen.y:10550
+//line sql-gen.y:11656
 		{
 			name := sqlDollar[4].union.unresolvedObjectName().ToTableName()
 			sqlVAL.union.val = &tree.CreateSequence{
@@ -39705,9 +43477,9 @@ sqldefault:
 				Options:     sqlDollar[5].union.seqOpts(),
 			}
 		}
-	case 1767:
+	case 1974:
 		sqlDollar = sqlS[sqlpt-8 : sqlpt+1]
-//line sql-gen.y:10559
+//line sql-gen.y:11665
 		{
 			name := sqlDollar[7].union.unresolvedObjectName().ToTableName()
 			sqlVAL.union.val = &tree.CreateSequence{
@@ -39716,33 +43488,33 @@ sqldefault:
 				IfNotExists: true,
 			}
 		}
-	case 1768:
+	case 1975:
 		sqlDollar = sqlS[sqlpt-4 : sqlpt+1]
-//line sql-gen.y:10567
+//line sql-gen.y:11673
 		{
 			return helpWith(sqllex, "CREATE SEQUENCE")
 		}
-	case 1770:
+	case 1977:
 		sqlDollar = sqlS[sqlpt-0 : sqlpt+1]
-//line sql-gen.y:10571
+//line sql-gen.y:11677
 		{
 			sqlVAL.union.val = []tree.SequenceOption(nil)
 		}
-	case 1771:
+	case 1978:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:10574
+//line sql-gen.y:11680
 		{
 			sqlVAL.union.val = []tree.SequenceOption{sqlDollar[1].union.seqOpt()}
 		}
-	case 1772:
+	case 1979:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:10575
+//line sql-gen.y:11681
 		{
 			sqlVAL.union.val = append(sqlDollar[1].union.seqOpts(), sqlDollar[2].union.seqOpt())
 		}
-	case 1773:
+	case 1980:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:10578
+//line sql-gen.y:11684
 		{
 
 			parsedType := sqlDollar[2].union.colType()
@@ -39757,27 +43529,27 @@ sqldefault:
 			}
 			sqlVAL.union.val = tree.SequenceOption{Name: tree.SeqOptAs, AsIntegerType: parsedType}
 		}
-	case 1774:
+	case 1981:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:10592
+//line sql-gen.y:11698
 		{
 			sqlVAL.union.val = tree.SequenceOption{Name: tree.SeqOptCycle}
 		}
-	case 1775:
+	case 1982:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:10594
+//line sql-gen.y:11700
 		{
 			sqlVAL.union.val = tree.SequenceOption{Name: tree.SeqOptNoCycle}
 		}
-	case 1776:
+	case 1983:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:10595
+//line sql-gen.y:11701
 		{
 			sqlVAL.union.val = tree.SequenceOption{Name: tree.SeqOptOwnedBy, ColumnItemVal: nil}
 		}
-	case 1777:
+	case 1984:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:10596
+//line sql-gen.y:11702
 		{
 			varName, err := sqlDollar[3].union.unresolvedName().NormalizeVarName()
 			if err != nil {
@@ -39790,243 +43562,250 @@ sqldefault:
 			}
 			sqlVAL.union.val = tree.SequenceOption{Name: tree.SeqOptOwnedBy, ColumnItemVal: columnItem}
 		}
-	case 1778:
+	case 1985:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:10606
+//line sql-gen.y:11712
 		{
 			x := sqlDollar[2].union.int64()
 			sqlVAL.union.val = tree.SequenceOption{Name: tree.SeqOptCache, IntVal: &x}
 		}
-	case 1779:
+	case 1986:
+		sqlDollar = sqlS[sqlpt-4 : sqlpt+1]
+//line sql-gen.y:11714
+		{
+			x := sqlDollar[4].union.int64()
+			sqlVAL.union.val = tree.SequenceOption{Name: tree.SeqOptCacheNode, IntVal: &x}
+		}
+	case 1987:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:10608
+//line sql-gen.y:11716
 		{
 			x := sqlDollar[2].union.int64()
 			sqlVAL.union.val = tree.SequenceOption{Name: tree.SeqOptIncrement, IntVal: &x}
 		}
-	case 1780:
+	case 1988:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:10610
+//line sql-gen.y:11718
 		{
 			x := sqlDollar[3].union.int64()
 			sqlVAL.union.val = tree.SequenceOption{Name: tree.SeqOptIncrement, IntVal: &x, OptionalWord: true}
 		}
-	case 1781:
+	case 1989:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:10612
+//line sql-gen.y:11720
 		{
 			x := sqlDollar[2].union.int64()
 			sqlVAL.union.val = tree.SequenceOption{Name: tree.SeqOptMinValue, IntVal: &x}
 		}
-	case 1782:
+	case 1990:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:10614
+//line sql-gen.y:11722
 		{
 			sqlVAL.union.val = tree.SequenceOption{Name: tree.SeqOptMinValue}
 		}
-	case 1783:
+	case 1991:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:10615
+//line sql-gen.y:11723
 		{
 			x := sqlDollar[2].union.int64()
 			sqlVAL.union.val = tree.SequenceOption{Name: tree.SeqOptMaxValue, IntVal: &x}
 		}
-	case 1784:
+	case 1992:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:10617
+//line sql-gen.y:11725
 		{
 			sqlVAL.union.val = tree.SequenceOption{Name: tree.SeqOptMaxValue}
 		}
-	case 1785:
+	case 1993:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:10618
+//line sql-gen.y:11726
 		{
 			x := sqlDollar[2].union.int64()
 			sqlVAL.union.val = tree.SequenceOption{Name: tree.SeqOptStart, IntVal: &x}
 		}
-	case 1786:
+	case 1994:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:10620
+//line sql-gen.y:11728
 		{
 			x := sqlDollar[3].union.int64()
 			sqlVAL.union.val = tree.SequenceOption{Name: tree.SeqOptStart, IntVal: &x, OptionalWord: true}
 		}
-	case 1787:
+	case 1995:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:10622
+//line sql-gen.y:11730
 		{
 			sqlVAL.union.val = tree.SequenceOption{Name: tree.SeqOptRestart}
 		}
-	case 1788:
+	case 1996:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:10623
+//line sql-gen.y:11731
 		{
 			x := sqlDollar[2].union.int64()
 			sqlVAL.union.val = tree.SequenceOption{Name: tree.SeqOptRestart, IntVal: &x}
 		}
-	case 1789:
+	case 1997:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:10625
+//line sql-gen.y:11733
 		{
 			x := sqlDollar[3].union.int64()
 			sqlVAL.union.val = tree.SequenceOption{Name: tree.SeqOptRestart, IntVal: &x, OptionalWord: true}
 		}
-	case 1790:
+	case 1998:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:10628
+//line sql-gen.y:11736
 		{
 			sqlVAL.union.val = tree.SequenceOption{Name: tree.SeqOptVirtual}
 		}
-	case 1791:
+	case 1999:
 		sqlDollar = sqlS[sqlpt-4 : sqlpt+1]
-//line sql-gen.y:10636
+//line sql-gen.y:11744
 		{
 			sqlVAL.union.val = &tree.Truncate{Tables: sqlDollar[3].union.tableNames(), DropBehavior: sqlDollar[4].union.dropBehavior()}
 		}
-	case 1792:
+	case 2000:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:10639
+//line sql-gen.y:11747
 		{
 			return helpWith(sqllex, "TRUNCATE")
 		}
-	case 1793:
+	case 2001:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:10643
+//line sql-gen.y:11751
 		{
 
 			sqlVAL.union.val = tree.KVOption{Key: tree.Name(sqlDollar[2].str), Value: sqlDollar[3].union.expr()}
 		}
-	case 1794:
+	case 2002:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:10649
+//line sql-gen.y:11757
 		{
 			sqlVAL.union.val = tree.KVOption{Key: tree.Name(sqlDollar[1].str), Value: sqlDollar[2].union.expr()}
 		}
-	case 1795:
+	case 2003:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:10653
+//line sql-gen.y:11761
 		{
 			sqlVAL.union.val = tree.KVOption{Key: tree.Name(sqlDollar[1].str), Value: tree.DNull}
 		}
-	case 1796:
+	case 2004:
 		sqlDollar = sqlS[sqlpt-4 : sqlpt+1]
-//line sql-gen.y:10663
+//line sql-gen.y:11771
 		{
 			sqlVAL.union.val = &tree.CreateRole{Name: sqlDollar[3].union.roleSpec(), KVOptions: sqlDollar[4].union.kvOptions(), IsRole: sqlDollar[2].union.bool()}
 		}
-	case 1797:
+	case 2005:
 		sqlDollar = sqlS[sqlpt-7 : sqlpt+1]
-//line sql-gen.y:10667
+//line sql-gen.y:11775
 		{
 			sqlVAL.union.val = &tree.CreateRole{Name: sqlDollar[6].union.roleSpec(), IfNotExists: true, KVOptions: sqlDollar[7].union.kvOptions(), IsRole: sqlDollar[2].union.bool()}
 		}
-	case 1798:
+	case 2006:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:10670
+//line sql-gen.y:11778
 		{
 			return helpWith(sqllex, "CREATE ROLE")
 		}
-	case 1799:
+	case 2007:
 		sqlDollar = sqlS[sqlpt-4 : sqlpt+1]
-//line sql-gen.y:10681
+//line sql-gen.y:11789
 		{
 			sqlVAL.union.val = &tree.AlterRole{Name: sqlDollar[3].union.roleSpec(), KVOptions: sqlDollar[4].union.kvOptions(), IsRole: sqlDollar[2].union.bool()}
 		}
-	case 1800:
+	case 2008:
 		sqlDollar = sqlS[sqlpt-6 : sqlpt+1]
-//line sql-gen.y:10685
+//line sql-gen.y:11793
 		{
 			sqlVAL.union.val = &tree.AlterRole{Name: sqlDollar[5].union.roleSpec(), IfExists: true, KVOptions: sqlDollar[6].union.kvOptions(), IsRole: sqlDollar[2].union.bool()}
 		}
-	case 1801:
+	case 2009:
 		sqlDollar = sqlS[sqlpt-5 : sqlpt+1]
-//line sql-gen.y:10689
+//line sql-gen.y:11797
 		{
 			sqlVAL.union.val = &tree.AlterRoleSet{RoleName: sqlDollar[3].union.roleSpec(), DatabaseName: tree.Name(sqlDollar[4].str), IsRole: sqlDollar[2].union.bool(), SetOrReset: sqlDollar[5].union.setVar()}
 		}
-	case 1802:
+	case 2010:
 		sqlDollar = sqlS[sqlpt-7 : sqlpt+1]
-//line sql-gen.y:10693
+//line sql-gen.y:11801
 		{
 			sqlVAL.union.val = &tree.AlterRoleSet{RoleName: sqlDollar[5].union.roleSpec(), IfExists: true, DatabaseName: tree.Name(sqlDollar[6].str), IsRole: sqlDollar[2].union.bool(), SetOrReset: sqlDollar[7].union.setVar()}
 		}
-	case 1803:
+	case 2011:
 		sqlDollar = sqlS[sqlpt-5 : sqlpt+1]
-//line sql-gen.y:10697
+//line sql-gen.y:11805
 		{
 			sqlVAL.union.val = &tree.AlterRoleSet{AllRoles: true, DatabaseName: tree.Name(sqlDollar[4].str), IsRole: true, SetOrReset: sqlDollar[5].union.setVar()}
 		}
-	case 1804:
+	case 2012:
 		sqlDollar = sqlS[sqlpt-5 : sqlpt+1]
-//line sql-gen.y:10701
+//line sql-gen.y:11809
 		{
 			sqlVAL.union.val = &tree.AlterRoleSet{AllRoles: true, DatabaseName: tree.Name(sqlDollar[4].str), IsRole: false, SetOrReset: sqlDollar[5].union.setVar()}
 		}
-	case 1805:
+	case 2013:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:10704
+//line sql-gen.y:11812
 		{
 			return helpWith(sqllex, "ALTER ROLE")
 		}
-	case 1806:
+	case 2014:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:10708
+//line sql-gen.y:11816
 		{
 			sqlVAL.str = sqlDollar[3].str
 		}
-	case 1807:
+	case 2015:
 		sqlDollar = sqlS[sqlpt-0 : sqlpt+1]
-//line sql-gen.y:10712
+//line sql-gen.y:11820
 		{
 			sqlVAL.str = ""
 		}
-	case 1808:
+	case 2016:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:10720
+//line sql-gen.y:11828
 		{
 			sqlVAL.union.val = sqlDollar[2].union.setVar()
 		}
-	case 1809:
+	case 2017:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:10724
+//line sql-gen.y:11832
 		{
 
 			sqlVAL.union.val = sqlDollar[2].union.setVar()
 		}
-	case 1810:
+	case 2018:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:10731
+//line sql-gen.y:11839
 		{
 			sqlVAL.union.val = &tree.SetVar{ResetAll: true}
 		}
-	case 1811:
+	case 2019:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:10735
+//line sql-gen.y:11843
 		{
 			sqlVAL.union.val = &tree.SetVar{Name: sqlDollar[2].str, Values: tree.Exprs{tree.DefaultVal{}}}
 		}
-	case 1812:
+	case 2020:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:10743
+//line sql-gen.y:11851
 		{
 			sqlVAL.union.val = true
 		}
-	case 1813:
+	case 2021:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:10747
+//line sql-gen.y:11855
 		{
 
 			sqlVAL.union.val = true
 		}
-	case 1814:
+	case 2022:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:10752
+//line sql-gen.y:11860
 		{
 			sqlVAL.union.val = false
 		}
-	case 1815:
+	case 2023:
 		sqlDollar = sqlS[sqlpt-8 : sqlpt+1]
-//line sql-gen.y:10764
+//line sql-gen.y:11872
 		{
 			name := sqlDollar[5].union.unresolvedObjectName().ToTableName()
 			sqlVAL.union.val = &tree.CreateView{
@@ -40038,9 +43817,9 @@ sqldefault:
 				Replace:     false,
 			}
 		}
-	case 1816:
+	case 2024:
 		sqlDollar = sqlS[sqlpt-10 : sqlpt+1]
-//line sql-gen.y:10778
+//line sql-gen.y:11886
 		{
 			name := sqlDollar[7].union.unresolvedObjectName().ToTableName()
 			sqlVAL.union.val = &tree.CreateView{
@@ -40052,9 +43831,9 @@ sqldefault:
 				Replace:     true,
 			}
 		}
-	case 1817:
+	case 2025:
 		sqlDollar = sqlS[sqlpt-11 : sqlpt+1]
-//line sql-gen.y:10790
+//line sql-gen.y:11898
 		{
 			name := sqlDollar[8].union.unresolvedObjectName().ToTableName()
 			sqlVAL.union.val = &tree.CreateView{
@@ -40066,9 +43845,9 @@ sqldefault:
 				Replace:     false,
 			}
 		}
-	case 1818:
+	case 2026:
 		sqlDollar = sqlS[sqlpt-8 : sqlpt+1]
-//line sql-gen.y:10802
+//line sql-gen.y:11910
 		{
 			name := sqlDollar[4].union.unresolvedObjectName().ToTableName()
 			sqlVAL.union.val = &tree.CreateView{
@@ -40079,9 +43858,9 @@ sqldefault:
 				WithData:     sqlDollar[8].union.bool(),
 			}
 		}
-	case 1819:
+	case 2027:
 		sqlDollar = sqlS[sqlpt-11 : sqlpt+1]
-//line sql-gen.y:10813
+//line sql-gen.y:11921
 		{
 			name := sqlDollar[7].union.unresolvedObjectName().ToTableName()
 			sqlVAL.union.val = &tree.CreateView{
@@ -40093,236 +43872,260 @@ sqldefault:
 				WithData:     sqlDollar[11].union.bool(),
 			}
 		}
-	case 1820:
+	case 2028:
 		sqlDollar = sqlS[sqlpt-5 : sqlpt+1]
-//line sql-gen.y:10824
+//line sql-gen.y:11932
 		{
 			return helpWith(sqllex, "CREATE VIEW")
 		}
-	case 1821:
+	case 2029:
 		sqlDollar = sqlS[sqlpt-4 : sqlpt+1]
-//line sql-gen.y:10828
+//line sql-gen.y:11936
 		{
 			sqlVAL.union.val = false
 		}
-	case 1822:
+	case 2030:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:10832
+//line sql-gen.y:11940
 		{
 			sqlVAL.union.val = true
 		}
-	case 1823:
+	case 2031:
 		sqlDollar = sqlS[sqlpt-0 : sqlpt+1]
-//line sql-gen.y:10836
+//line sql-gen.y:11944
 		{
 			sqlVAL.union.val = true
 		}
-	case 1824:
+	case 2032:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:10842
+//line sql-gen.y:11950
 		{
 			sqlVAL.union.val = tree.KVOption{Key: tree.Name(sqlDollar[1].str), Value: nil}
 		}
-	case 1825:
+	case 2033:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:10846
+//line sql-gen.y:11954
 		{
 			sqlVAL.union.val = tree.KVOption{Key: tree.Name(sqlDollar[1].str), Value: nil}
 		}
-	case 1826:
+	case 2034:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:10850
+//line sql-gen.y:11958
 		{
 			sqlVAL.union.val = tree.KVOption{Key: tree.Name(sqlDollar[1].str), Value: nil}
 		}
-	case 1827:
+	case 2035:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:10854
+//line sql-gen.y:11962
 		{
 			sqlVAL.union.val = tree.KVOption{Key: tree.Name(sqlDollar[1].str), Value: nil}
 		}
-	case 1828:
+	case 2036:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:10858
+//line sql-gen.y:11966
 		{
 			sqlVAL.union.val = tree.KVOption{Key: tree.Name(sqlDollar[1].str), Value: nil}
 		}
-	case 1829:
+	case 2037:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:10862
+//line sql-gen.y:11970
 		{
 			sqlVAL.union.val = tree.KVOption{Key: tree.Name(sqlDollar[1].str), Value: nil}
 		}
-	case 1830:
+	case 2038:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:10866
+//line sql-gen.y:11974
 		{
 			sqlVAL.union.val = tree.KVOption{Key: tree.Name(sqlDollar[1].str), Value: nil}
 		}
-	case 1831:
+	case 2039:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:10870
+//line sql-gen.y:11978
 		{
 			sqlVAL.union.val = tree.KVOption{Key: tree.Name(sqlDollar[1].str), Value: nil}
 		}
-	case 1832:
+	case 2040:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:10874
+//line sql-gen.y:11982
 		{
 			sqlVAL.union.val = tree.KVOption{Key: tree.Name(sqlDollar[1].str), Value: nil}
 		}
-	case 1833:
+	case 2041:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:10878
+//line sql-gen.y:11986
 		{
 			sqlVAL.union.val = tree.KVOption{Key: tree.Name(sqlDollar[1].str), Value: nil}
 		}
-	case 1834:
+	case 2042:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:10882
+//line sql-gen.y:11990
 		{
 			sqlVAL.union.val = tree.KVOption{Key: tree.Name(sqlDollar[1].str), Value: nil}
 		}
-	case 1835:
+	case 2043:
+		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
+//line sql-gen.y:11994
+		{
+			sqlVAL.union.val = tree.KVOption{Key: tree.Name(sqlDollar[1].str), Value: nil}
+		}
+	case 2044:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:10886
+//line sql-gen.y:11998
 		{
 			sqlVAL.union.val = tree.KVOption{Key: tree.Name(sqlDollar[1].str), Value: nil}
 		}
-	case 1836:
+	case 2045:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:10890
+//line sql-gen.y:12002
 		{
 			sqlVAL.union.val = tree.KVOption{Key: tree.Name(sqlDollar[1].str), Value: nil}
 		}
-	case 1837:
+	case 2046:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:10894
+//line sql-gen.y:12006
 		{
 			sqlVAL.union.val = tree.KVOption{Key: tree.Name(sqlDollar[1].str), Value: nil}
 		}
-	case 1838:
+	case 2047:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:10898
+//line sql-gen.y:12010
 		{
 			sqlVAL.union.val = tree.KVOption{Key: tree.Name(sqlDollar[1].str), Value: nil}
 		}
-	case 1839:
+	case 2048:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:10902
+//line sql-gen.y:12014
 		{
 			sqlVAL.union.val = tree.KVOption{Key: tree.Name(sqlDollar[1].str), Value: nil}
 		}
-	case 1840:
+	case 2049:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:10906
+//line sql-gen.y:12018
 		{
 			sqlVAL.union.val = tree.KVOption{Key: tree.Name(sqlDollar[1].str), Value: nil}
 		}
-	case 1841:
+	case 2050:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:10910
+//line sql-gen.y:12022
 		{
 			sqlVAL.union.val = tree.KVOption{Key: tree.Name(sqlDollar[1].str), Value: nil}
 		}
-	case 1842:
+	case 2051:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:10914
+//line sql-gen.y:12026
 		{
 			sqlVAL.union.val = tree.KVOption{Key: tree.Name(sqlDollar[1].str), Value: nil}
 		}
-	case 1843:
+	case 2052:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:10918
+//line sql-gen.y:12030
 		{
 			sqlVAL.union.val = tree.KVOption{Key: tree.Name(sqlDollar[1].str), Value: nil}
 		}
-	case 1844:
+	case 2053:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:10922
+//line sql-gen.y:12034
 		{
 			sqlVAL.union.val = tree.KVOption{Key: tree.Name(sqlDollar[1].str), Value: nil}
 		}
-	case 1845:
+	case 2054:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:10926
+//line sql-gen.y:12038
 		{
 			sqlVAL.union.val = tree.KVOption{Key: tree.Name(sqlDollar[1].str), Value: nil}
 		}
-	case 1846:
+	case 2055:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:10930
+//line sql-gen.y:12042
 		{
 			sqlVAL.union.val = tree.KVOption{Key: tree.Name(sqlDollar[1].str), Value: nil}
 		}
-	case 1847:
+	case 2059:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:10934
+//line sql-gen.y:12049
 		{
 			sqlVAL.union.val = tree.KVOption{Key: tree.Name(sqlDollar[1].str), Value: nil}
 		}
-	case 1850:
+	case 2060:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:10940
+//line sql-gen.y:12053
 		{
 			sqlVAL.union.val = tree.KVOption{Key: tree.Name(sqlDollar[1].str), Value: nil}
 		}
-	case 1851:
+	case 2061:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:10944
+//line sql-gen.y:12057
 		{
 			sqlVAL.union.val = tree.KVOption{Key: tree.Name(sqlDollar[1].str), Value: nil}
 		}
-	case 1852:
+	case 2062:
+		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
+//line sql-gen.y:12061
+		{
+			sqlVAL.union.val = tree.KVOption{Key: tree.Name(sqlDollar[1].str), Value: nil}
+		}
+	case 2063:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:10950
+//line sql-gen.y:12067
 		{
 			sqlVAL.union.val = []tree.KVOption{sqlDollar[1].union.kvOption()}
 		}
-	case 1853:
+	case 2064:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:10954
+//line sql-gen.y:12071
 		{
 			sqlVAL.union.val = append(sqlDollar[1].union.kvOptions(), sqlDollar[2].union.kvOption())
 		}
-	case 1854:
+	case 2065:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:10960
+//line sql-gen.y:12077
 		{
 			sqlVAL.union.val = sqlDollar[2].union.kvOptions()
 		}
-	case 1855:
+	case 2066:
 		sqlDollar = sqlS[sqlpt-0 : sqlpt+1]
-//line sql-gen.y:10964
+//line sql-gen.y:12081
 		{
 			sqlVAL.union.val = nil
 		}
-	case 1856:
+	case 2067:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:10970
+//line sql-gen.y:12087
 		{
 			sqlVAL.union.val = tree.KVOption{Key: tree.Name("valid until"), Value: sqlDollar[3].union.expr()}
 		}
-	case 1857:
+	case 2068:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:10974
+//line sql-gen.y:12091
 		{
 			sqlVAL.union.val = tree.KVOption{Key: tree.Name("valid until"), Value: tree.DNull}
 		}
-	case 1858:
+	case 2069:
+		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
+//line sql-gen.y:12097
+		{
+			sqlVAL.union.val = tree.KVOption{Key: tree.Name("subject"), Value: sqlDollar[2].union.expr()}
+		}
+	case 2070:
+		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
+//line sql-gen.y:12101
+		{
+			sqlVAL.union.val = tree.KVOption{Key: tree.Name("subject"), Value: tree.DNull}
+		}
+	case 2071:
 		sqlDollar = sqlS[sqlpt-0 : sqlpt+1]
-//line sql-gen.y:10979
+//line sql-gen.y:12106
 		{
 		}
-	case 1859:
+	case 2072:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:10980
+//line sql-gen.y:12107
 		{
 			return unimplemented(sqllex, "create recursive view")
 		}
-	case 1860:
+	case 2073:
 		sqlDollar = sqlS[sqlpt-8 : sqlpt+1]
-//line sql-gen.y:10989
+//line sql-gen.y:12116
 		{
 			sqlVAL.union.val = &tree.CreateType{
 				TypeName:   sqlDollar[3].union.unresolvedObjectName(),
@@ -40330,9 +44133,9 @@ sqldefault:
 				EnumLabels: sqlDollar[7].union.enumValueList(),
 			}
 		}
-	case 1861:
+	case 2074:
 		sqlDollar = sqlS[sqlpt-11 : sqlpt+1]
-//line sql-gen.y:10997
+//line sql-gen.y:12124
 		{
 			sqlVAL.union.val = &tree.CreateType{
 				TypeName:    sqlDollar[6].union.unresolvedObjectName(),
@@ -40341,15 +44144,15 @@ sqldefault:
 				IfNotExists: true,
 			}
 		}
-	case 1862:
+	case 2075:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:11005
+//line sql-gen.y:12132
 		{
 			return helpWith(sqllex, "CREATE TYPE")
 		}
-	case 1863:
+	case 2076:
 		sqlDollar = sqlS[sqlpt-7 : sqlpt+1]
-//line sql-gen.y:11008
+//line sql-gen.y:12135
 		{
 			sqlVAL.union.val = &tree.CreateType{
 				TypeName:          sqlDollar[3].union.unresolvedObjectName(),
@@ -40357,9 +44160,9 @@ sqldefault:
 				CompositeTypeList: sqlDollar[6].union.compositeTypeList(),
 			}
 		}
-	case 1864:
+	case 2077:
 		sqlDollar = sqlS[sqlpt-10 : sqlpt+1]
-//line sql-gen.y:11016
+//line sql-gen.y:12143
 		{
 			sqlVAL.union.val = &tree.CreateType{
 				TypeName:          sqlDollar[6].union.unresolvedObjectName(),
@@ -40368,69 +44171,69 @@ sqldefault:
 				CompositeTypeList: sqlDollar[9].union.compositeTypeList(),
 			}
 		}
-	case 1865:
+	case 2078:
 		sqlDollar = sqlS[sqlpt-6 : sqlpt+1]
-//line sql-gen.y:11025
+//line sql-gen.y:12152
 		{
 			return unimplementedWithIssue(sqllex, 27791)
 		}
-	case 1866:
+	case 2079:
 		sqlDollar = sqlS[sqlpt-5 : sqlpt+1]
-//line sql-gen.y:11027
+//line sql-gen.y:12154
 		{
 			return unimplementedWithIssueDetail(sqllex, 27793, "base")
 		}
-	case 1867:
+	case 2080:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:11029
+//line sql-gen.y:12156
 		{
 			return unimplementedWithIssueDetail(sqllex, 27793, "shell")
 		}
-	case 1868:
+	case 2081:
 		sqlDollar = sqlS[sqlpt-4 : sqlpt+1]
-//line sql-gen.y:11031
+//line sql-gen.y:12158
 		{
 			return unimplementedWithIssueDetail(sqllex, 27796, "create")
 		}
-	case 1869:
+	case 2082:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:11035
+//line sql-gen.y:12162
 		{
 			sqlVAL.union.val = sqlDollar[1].union.enumValueList()
 		}
-	case 1870:
+	case 2083:
 		sqlDollar = sqlS[sqlpt-0 : sqlpt+1]
-//line sql-gen.y:11039
+//line sql-gen.y:12166
 		{
 			sqlVAL.union.val = tree.EnumValueList(nil)
 		}
-	case 1871:
+	case 2084:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:11045
+//line sql-gen.y:12172
 		{
 			sqlVAL.union.val = tree.EnumValueList{tree.EnumValue(sqlDollar[1].str)}
 		}
-	case 1872:
+	case 2085:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:11049
+//line sql-gen.y:12176
 		{
 			sqlVAL.union.val = append(sqlDollar[1].union.enumValueList(), tree.EnumValue(sqlDollar[3].str))
 		}
-	case 1873:
+	case 2086:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:11055
+//line sql-gen.y:12182
 		{
 			sqlVAL.union.val = sqlDollar[1].union.compositeTypeList()
 		}
-	case 1874:
+	case 2087:
 		sqlDollar = sqlS[sqlpt-0 : sqlpt+1]
-//line sql-gen.y:11059
+//line sql-gen.y:12186
 		{
 			sqlVAL.union.val = []tree.CompositeTypeElem{}
 		}
-	case 1875:
+	case 2088:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:11065
+//line sql-gen.y:12192
 		{
 			sqlVAL.union.val = []tree.CompositeTypeElem{
 				tree.CompositeTypeElem{
@@ -40439,9 +44242,9 @@ sqldefault:
 				},
 			}
 		}
-	case 1876:
+	case 2089:
 		sqlDollar = sqlS[sqlpt-4 : sqlpt+1]
-//line sql-gen.y:11074
+//line sql-gen.y:12201
 		{
 			sqlVAL.union.val = append(sqlDollar[1].union.compositeTypeList(),
 				tree.CompositeTypeElem{
@@ -40450,11 +44253,12 @@ sqldefault:
 				},
 			)
 		}
-	case 1877:
+	case 2090:
 		sqlDollar = sqlS[sqlpt-17 : sqlpt+1]
-//line sql-gen.y:11096
+//line sql-gen.y:12223
 		{
 			table := sqlDollar[7].union.unresolvedObjectName().ToTableName()
+			indexType := sqlDollar[8].union.indexType()
 			sqlVAL.union.val = &tree.CreateIndex{
 				Name:             tree.Name(sqlDollar[5].str),
 				Table:            table,
@@ -40465,16 +44269,17 @@ sqldefault:
 				PartitionByIndex: sqlDollar[14].union.partitionByIndex(),
 				StorageParams:    sqlDollar[15].union.storageParams(),
 				Predicate:        sqlDollar[16].union.expr(),
-				Inverted:         sqlDollar[8].union.bool(),
+				Type:             indexType,
 				Concurrently:     sqlDollar[4].union.bool(),
 				Invisibility:     sqlDollar[17].union.indexInvisibility(),
 			}
 		}
-	case 1878:
+	case 2091:
 		sqlDollar = sqlS[sqlpt-20 : sqlpt+1]
-//line sql-gen.y:11114
+//line sql-gen.y:12242
 		{
 			table := sqlDollar[10].union.unresolvedObjectName().ToTableName()
+			indexType := sqlDollar[11].union.indexType()
 			sqlVAL.union.val = &tree.CreateIndex{
 				Name:             tree.Name(sqlDollar[8].str),
 				Table:            table,
@@ -40484,23 +44289,23 @@ sqldefault:
 				Sharded:          sqlDollar[15].union.shardedIndexDef(),
 				Storing:          sqlDollar[16].union.nameList(),
 				PartitionByIndex: sqlDollar[17].union.partitionByIndex(),
-				Inverted:         sqlDollar[11].union.bool(),
+				Type:             indexType,
 				StorageParams:    sqlDollar[18].union.storageParams(),
 				Predicate:        sqlDollar[19].union.expr(),
 				Concurrently:     sqlDollar[4].union.bool(),
 				Invisibility:     sqlDollar[20].union.indexInvisibility(),
 			}
 		}
-	case 1879:
+	case 2092:
 		sqlDollar = sqlS[sqlpt-16 : sqlpt+1]
-//line sql-gen.y:11133
+//line sql-gen.y:12262
 		{
 			table := sqlDollar[8].union.unresolvedObjectName().ToTableName()
 			sqlVAL.union.val = &tree.CreateIndex{
 				Name:             tree.Name(sqlDollar[6].str),
 				Table:            table,
 				Unique:           sqlDollar[2].union.bool(),
-				Inverted:         true,
+				Type:             idxtype.INVERTED,
 				Columns:          sqlDollar[10].union.idxElems(),
 				Storing:          sqlDollar[12].union.nameList(),
 				PartitionByIndex: sqlDollar[13].union.partitionByIndex(),
@@ -40510,16 +44315,16 @@ sqldefault:
 				Invisibility:     sqlDollar[16].union.indexInvisibility(),
 			}
 		}
-	case 1880:
+	case 2093:
 		sqlDollar = sqlS[sqlpt-19 : sqlpt+1]
-//line sql-gen.y:11150
+//line sql-gen.y:12279
 		{
 			table := sqlDollar[11].union.unresolvedObjectName().ToTableName()
 			sqlVAL.union.val = &tree.CreateIndex{
 				Name:             tree.Name(sqlDollar[9].str),
 				Table:            table,
 				Unique:           sqlDollar[2].union.bool(),
-				Inverted:         true,
+				Type:             idxtype.INVERTED,
 				IfNotExists:      true,
 				Columns:          sqlDollar[13].union.idxElems(),
 				Storing:          sqlDollar[15].union.nameList(),
@@ -40530,98 +44335,141 @@ sqldefault:
 				Invisibility:     sqlDollar[19].union.indexInvisibility(),
 			}
 		}
-	case 1881:
+	case 2094:
+		sqlDollar = sqlS[sqlpt-16 : sqlpt+1]
+//line sql-gen.y:12297
+		{
+			table := sqlDollar[8].union.unresolvedObjectName().ToTableName()
+			sqlVAL.union.val = &tree.CreateIndex{
+				Name:             tree.Name(sqlDollar[6].str),
+				Table:            table,
+				Unique:           sqlDollar[2].union.bool(),
+				Type:             idxtype.VECTOR,
+				Columns:          sqlDollar[10].union.idxElems(),
+				Storing:          sqlDollar[12].union.nameList(),
+				PartitionByIndex: sqlDollar[13].union.partitionByIndex(),
+				StorageParams:    sqlDollar[14].union.storageParams(),
+				Predicate:        sqlDollar[15].union.expr(),
+				Concurrently:     sqlDollar[5].union.bool(),
+				Invisibility:     sqlDollar[16].union.indexInvisibility(),
+			}
+		}
+	case 2095:
+		sqlDollar = sqlS[sqlpt-19 : sqlpt+1]
+//line sql-gen.y:12314
+		{
+			table := sqlDollar[11].union.unresolvedObjectName().ToTableName()
+			sqlVAL.union.val = &tree.CreateIndex{
+				Name:             tree.Name(sqlDollar[9].str),
+				Table:            table,
+				Unique:           sqlDollar[2].union.bool(),
+				Type:             idxtype.VECTOR,
+				IfNotExists:      true,
+				Columns:          sqlDollar[13].union.idxElems(),
+				Storing:          sqlDollar[15].union.nameList(),
+				PartitionByIndex: sqlDollar[16].union.partitionByIndex(),
+				StorageParams:    sqlDollar[17].union.storageParams(),
+				Predicate:        sqlDollar[18].union.expr(),
+				Concurrently:     sqlDollar[5].union.bool(),
+				Invisibility:     sqlDollar[19].union.indexInvisibility(),
+			}
+		}
+	case 2096:
 		sqlDollar = sqlS[sqlpt-4 : sqlpt+1]
-//line sql-gen.y:11167
+//line sql-gen.y:12331
 		{
 			return helpWith(sqllex, "CREATE INDEX")
 		}
-	case 1882:
+	case 2097:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:11171
+//line sql-gen.y:12335
 		{
 
+			var val idxtype.T
 			switch sqlDollar[2].str {
 			case "gin", "gist":
-				sqlVAL.union.val = true
+				val = idxtype.INVERTED
 			case "btree":
-				sqlVAL.union.val = false
+				val = idxtype.FORWARD
+			case "cspann", "hnsw":
+				val = idxtype.VECTOR
 			case "hash", "spgist", "brin":
 				return unimplemented(sqllex, "index using "+sqlDollar[2].str)
 			default:
 				sqllex.Error("unrecognized access method: " + sqlDollar[2].str)
 				return 1
 			}
+			sqlVAL.union.val = val
 		}
-	case 1883:
+	case 2098:
 		sqlDollar = sqlS[sqlpt-0 : sqlpt+1]
-//line sql-gen.y:11186
+//line sql-gen.y:12354
 		{
-			sqlVAL.union.val = false
+			sqlVAL.union.val = idxtype.FORWARD
 		}
-	case 1884:
+	case 2099:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:11192
+//line sql-gen.y:12360
 		{
 			sqlVAL.union.val = true
 		}
-	case 1885:
+	case 2100:
 		sqlDollar = sqlS[sqlpt-0 : sqlpt+1]
-//line sql-gen.y:11196
+//line sql-gen.y:12364
 		{
 			sqlVAL.union.val = false
 		}
-	case 1886:
+	case 2101:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:11202
+//line sql-gen.y:12370
 		{
 			sqlVAL.union.val = true
 		}
-	case 1887:
+	case 2102:
 		sqlDollar = sqlS[sqlpt-0 : sqlpt+1]
-//line sql-gen.y:11206
+//line sql-gen.y:12374
 		{
 			sqlVAL.union.val = false
 		}
-	case 1888:
+	case 2103:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:11212
+//line sql-gen.y:12380
 		{
 			sqlVAL.union.val = tree.IndexElemList{sqlDollar[1].union.idxElem()}
 		}
-	case 1889:
+	case 2104:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:11216
+//line sql-gen.y:12384
 		{
 			sqlVAL.union.val = append(sqlDollar[1].union.idxElems(), sqlDollar[3].union.idxElem())
 		}
-	case 1890:
+	case 2105:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:11225
+//line sql-gen.y:12393
 		{
 			e := sqlDollar[2].union.idxElem()
 			e.Expr = sqlDollar[1].union.expr()
 			sqlVAL.union.val = e
 		}
-	case 1891:
+	case 2106:
 		sqlDollar = sqlS[sqlpt-4 : sqlpt+1]
-//line sql-gen.y:11231
+//line sql-gen.y:12399
 		{
 			e := sqlDollar[4].union.idxElem()
 			e.Expr = sqlDollar[2].union.expr()
 			sqlVAL.union.val = e
 		}
-	case 1892:
+	case 2107:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:11237
+//line sql-gen.y:12405
 		{
 			e := sqlDollar[2].union.idxElem()
 			e.Column = tree.Name(sqlDollar[1].str)
 			sqlVAL.union.val = e
 		}
-	case 1893:
+	case 2108:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:11245
+//line sql-gen.y:12413
 		{
 
 			opClass := sqlDollar[1].str
@@ -40638,69 +44486,69 @@ sqldefault:
 			}
 			sqlVAL.union.val = tree.IndexElem{Direction: dir, NullsOrder: nullsOrder, OpClass: tree.Name(opClass)}
 		}
-	case 1894:
+	case 2109:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:11263
+//line sql-gen.y:12431
 		{
 			sqlVAL.str = sqlDollar[1].str
 		}
-	case 1895:
+	case 2110:
 		sqlDollar = sqlS[sqlpt-0 : sqlpt+1]
-//line sql-gen.y:11264
+//line sql-gen.y:12432
 		{
 			sqlVAL.str = ""
 		}
-	case 1896:
+	case 2111:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:11267
+//line sql-gen.y:12435
 		{
 			sqlVAL.str = sqlDollar[2].str
 		}
-	case 1897:
+	case 2112:
 		sqlDollar = sqlS[sqlpt-0 : sqlpt+1]
-//line sql-gen.y:11268
+//line sql-gen.y:12436
 		{
 			sqlVAL.str = ""
 		}
-	case 1898:
+	case 2113:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:11272
+//line sql-gen.y:12440
 		{
 			sqlVAL.union.val = tree.Ascending
 		}
-	case 1899:
+	case 2114:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:11276
+//line sql-gen.y:12444
 		{
 			sqlVAL.union.val = tree.Descending
 		}
-	case 1900:
+	case 2115:
 		sqlDollar = sqlS[sqlpt-0 : sqlpt+1]
-//line sql-gen.y:11280
+//line sql-gen.y:12448
 		{
 			sqlVAL.union.val = tree.DefaultDirection
 		}
-	case 1901:
+	case 2116:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:11286
+//line sql-gen.y:12454
 		{
 			sqlVAL.union.val = tree.IndexInvisibility{Value: 1.0}
 		}
-	case 1902:
+	case 2117:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:11290
+//line sql-gen.y:12458
 		{
 			sqlVAL.union.val = tree.IndexInvisibility{Value: 1.0}
 		}
-	case 1903:
+	case 2118:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:11294
+//line sql-gen.y:12462
 		{
 			sqlVAL.union.val = tree.IndexInvisibility{Value: 0.0}
 		}
-	case 1904:
+	case 2119:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:11298
+//line sql-gen.y:12466
 		{
 			visibilityConst, _ := constant.Float64Val(sqlDollar[2].union.numVal().AsConstantValue())
 			if visibilityConst < 0.0 || visibilityConst > 1.0 {
@@ -40710,59 +44558,59 @@ sqldefault:
 			invisibilityConst := 1.0 - visibilityConst
 			sqlVAL.union.val = tree.IndexInvisibility{Value: invisibilityConst, FloatProvided: true}
 		}
-	case 1905:
+	case 2120:
 		sqlDollar = sqlS[sqlpt-0 : sqlpt+1]
-//line sql-gen.y:11308
+//line sql-gen.y:12476
 		{
 			sqlVAL.union.val = tree.IndexInvisibility{Value: 0.0}
 		}
-	case 1906:
+	case 2121:
 		sqlDollar = sqlS[sqlpt-9 : sqlpt+1]
-//line sql-gen.y:11314
+//line sql-gen.y:12482
 		{
 			sqlVAL.union.val = &tree.ReparentDatabase{Name: tree.Name(sqlDollar[3].str), Parent: tree.Name(sqlDollar[9].str)}
 		}
-	case 1907:
+	case 2122:
 		sqlDollar = sqlS[sqlpt-6 : sqlpt+1]
-//line sql-gen.y:11320
+//line sql-gen.y:12488
 		{
 			sqlVAL.union.val = &tree.RenameDatabase{Name: tree.Name(sqlDollar[3].str), NewName: tree.Name(sqlDollar[6].str)}
 		}
-	case 1908:
+	case 2123:
 		sqlDollar = sqlS[sqlpt-6 : sqlpt+1]
-//line sql-gen.y:11326
+//line sql-gen.y:12494
 		{
 			name := sqlDollar[3].union.unresolvedObjectName()
 			newName := sqlDollar[6].union.unresolvedObjectName()
 			sqlVAL.union.val = &tree.RenameTable{Name: name, NewName: newName, IfExists: false, IsView: false}
 		}
-	case 1909:
+	case 2124:
 		sqlDollar = sqlS[sqlpt-8 : sqlpt+1]
-//line sql-gen.y:11332
+//line sql-gen.y:12500
 		{
 			name := sqlDollar[5].union.unresolvedObjectName()
 			newName := sqlDollar[8].union.unresolvedObjectName()
 			sqlVAL.union.val = &tree.RenameTable{Name: name, NewName: newName, IfExists: true, IsView: false}
 		}
-	case 1910:
+	case 2125:
 		sqlDollar = sqlS[sqlpt-6 : sqlpt+1]
-//line sql-gen.y:11340
+//line sql-gen.y:12508
 		{
 			sqlVAL.union.val = &tree.AlterTableSetSchema{
 				Name: sqlDollar[3].union.unresolvedObjectName(), Schema: tree.Name(sqlDollar[6].str), IfExists: false,
 			}
 		}
-	case 1911:
+	case 2126:
 		sqlDollar = sqlS[sqlpt-8 : sqlpt+1]
-//line sql-gen.y:11346
+//line sql-gen.y:12514
 		{
 			sqlVAL.union.val = &tree.AlterTableSetSchema{
 				Name: sqlDollar[5].union.unresolvedObjectName(), Schema: tree.Name(sqlDollar[8].str), IfExists: true,
 			}
 		}
-	case 1912:
+	case 2127:
 		sqlDollar = sqlS[sqlpt-5 : sqlpt+1]
-//line sql-gen.y:11354
+//line sql-gen.y:12522
 		{
 			sqlVAL.union.val = &tree.AlterTableLocality{
 				Name:     sqlDollar[3].union.unresolvedObjectName(),
@@ -40770,9 +44618,9 @@ sqldefault:
 				IfExists: false,
 			}
 		}
-	case 1913:
+	case 2128:
 		sqlDollar = sqlS[sqlpt-7 : sqlpt+1]
-//line sql-gen.y:11362
+//line sql-gen.y:12530
 		{
 			sqlVAL.union.val = &tree.AlterTableLocality{
 				Name:     sqlDollar[5].union.unresolvedObjectName(),
@@ -40780,84 +44628,84 @@ sqldefault:
 				IfExists: true,
 			}
 		}
-	case 1914:
+	case 2129:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:11372
+//line sql-gen.y:12540
 		{
 			sqlVAL.union.val = &tree.Locality{
 				LocalityLevel: tree.LocalityLevelGlobal,
 			}
 		}
-	case 1915:
+	case 2130:
 		sqlDollar = sqlS[sqlpt-6 : sqlpt+1]
-//line sql-gen.y:11378
+//line sql-gen.y:12546
 		{
 			sqlVAL.union.val = &tree.Locality{
 				TableRegion:   tree.Name(sqlDollar[6].str),
 				LocalityLevel: tree.LocalityLevelTable,
 			}
 		}
-	case 1916:
+	case 2131:
 		sqlDollar = sqlS[sqlpt-7 : sqlpt+1]
-//line sql-gen.y:11385
+//line sql-gen.y:12553
 		{
 			sqlVAL.union.val = &tree.Locality{
 				LocalityLevel: tree.LocalityLevelTable,
 			}
 		}
-	case 1917:
+	case 2132:
 		sqlDollar = sqlS[sqlpt-4 : sqlpt+1]
-//line sql-gen.y:11391
+//line sql-gen.y:12559
 		{
 			sqlVAL.union.val = &tree.Locality{
 				LocalityLevel: tree.LocalityLevelTable,
 			}
 		}
-	case 1918:
+	case 2133:
 		sqlDollar = sqlS[sqlpt-4 : sqlpt+1]
-//line sql-gen.y:11397
+//line sql-gen.y:12565
 		{
 			sqlVAL.union.val = &tree.Locality{
 				TableRegion:   tree.Name(sqlDollar[4].str),
 				LocalityLevel: tree.LocalityLevelTable,
 			}
 		}
-	case 1919:
+	case 2134:
 		sqlDollar = sqlS[sqlpt-5 : sqlpt+1]
-//line sql-gen.y:11404
+//line sql-gen.y:12572
 		{
 			sqlVAL.union.val = &tree.Locality{
 				LocalityLevel: tree.LocalityLevelTable,
 			}
 		}
-	case 1920:
+	case 2135:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:11410
+//line sql-gen.y:12578
 		{
 			sqlVAL.union.val = &tree.Locality{
 				LocalityLevel: tree.LocalityLevelTable,
 			}
 		}
-	case 1921:
+	case 2136:
 		sqlDollar = sqlS[sqlpt-4 : sqlpt+1]
-//line sql-gen.y:11416
+//line sql-gen.y:12584
 		{
 			sqlVAL.union.val = &tree.Locality{
 				LocalityLevel: tree.LocalityLevelRow,
 			}
 		}
-	case 1922:
+	case 2137:
 		sqlDollar = sqlS[sqlpt-6 : sqlpt+1]
-//line sql-gen.y:11422
+//line sql-gen.y:12590
 		{
 			sqlVAL.union.val = &tree.Locality{
 				LocalityLevel:       tree.LocalityLevelRow,
 				RegionalByRowColumn: tree.Name(sqlDollar[6].str),
 			}
 		}
-	case 1923:
+	case 2138:
 		sqlDollar = sqlS[sqlpt-6 : sqlpt+1]
-//line sql-gen.y:11431
+//line sql-gen.y:12599
 		{
 			sqlVAL.union.val = &tree.AlterTableOwner{
 				Name:     sqlDollar[3].union.unresolvedObjectName(),
@@ -40865,9 +44713,9 @@ sqldefault:
 				IfExists: false,
 			}
 		}
-	case 1924:
+	case 2139:
 		sqlDollar = sqlS[sqlpt-8 : sqlpt+1]
-//line sql-gen.y:11439
+//line sql-gen.y:12607
 		{
 			sqlVAL.union.val = &tree.AlterTableOwner{
 				Name:     sqlDollar[5].union.unresolvedObjectName(),
@@ -40875,17 +44723,17 @@ sqldefault:
 				IfExists: true,
 			}
 		}
-	case 1925:
+	case 2140:
 		sqlDollar = sqlS[sqlpt-6 : sqlpt+1]
-//line sql-gen.y:11449
+//line sql-gen.y:12617
 		{
 			sqlVAL.union.val = &tree.AlterTableSetSchema{
 				Name: sqlDollar[3].union.unresolvedObjectName(), Schema: tree.Name(sqlDollar[6].str), IfExists: false, IsView: true,
 			}
 		}
-	case 1926:
+	case 2141:
 		sqlDollar = sqlS[sqlpt-7 : sqlpt+1]
-//line sql-gen.y:11455
+//line sql-gen.y:12623
 		{
 			sqlVAL.union.val = &tree.AlterTableSetSchema{
 				Name:           sqlDollar[4].union.unresolvedObjectName(),
@@ -40895,17 +44743,17 @@ sqldefault:
 				IsMaterialized: true,
 			}
 		}
-	case 1927:
+	case 2142:
 		sqlDollar = sqlS[sqlpt-8 : sqlpt+1]
-//line sql-gen.y:11465
+//line sql-gen.y:12633
 		{
 			sqlVAL.union.val = &tree.AlterTableSetSchema{
 				Name: sqlDollar[5].union.unresolvedObjectName(), Schema: tree.Name(sqlDollar[8].str), IfExists: true, IsView: true,
 			}
 		}
-	case 1928:
+	case 2143:
 		sqlDollar = sqlS[sqlpt-9 : sqlpt+1]
-//line sql-gen.y:11471
+//line sql-gen.y:12639
 		{
 			sqlVAL.union.val = &tree.AlterTableSetSchema{
 				Name:           sqlDollar[6].union.unresolvedObjectName(),
@@ -40915,9 +44763,9 @@ sqldefault:
 				IsMaterialized: true,
 			}
 		}
-	case 1929:
+	case 2144:
 		sqlDollar = sqlS[sqlpt-6 : sqlpt+1]
-//line sql-gen.y:11483
+//line sql-gen.y:12651
 		{
 			sqlVAL.union.val = &tree.AlterTableOwner{
 				Name:     sqlDollar[3].union.unresolvedObjectName(),
@@ -40926,9 +44774,9 @@ sqldefault:
 				IsView:   true,
 			}
 		}
-	case 1930:
+	case 2145:
 		sqlDollar = sqlS[sqlpt-7 : sqlpt+1]
-//line sql-gen.y:11492
+//line sql-gen.y:12660
 		{
 			sqlVAL.union.val = &tree.AlterTableOwner{
 				Name:           sqlDollar[4].union.unresolvedObjectName(),
@@ -40938,9 +44786,9 @@ sqldefault:
 				IsMaterialized: true,
 			}
 		}
-	case 1931:
+	case 2146:
 		sqlDollar = sqlS[sqlpt-8 : sqlpt+1]
-//line sql-gen.y:11502
+//line sql-gen.y:12670
 		{
 			sqlVAL.union.val = &tree.AlterTableOwner{
 				Name:     sqlDollar[5].union.unresolvedObjectName(),
@@ -40949,9 +44797,9 @@ sqldefault:
 				IsView:   true,
 			}
 		}
-	case 1932:
+	case 2147:
 		sqlDollar = sqlS[sqlpt-9 : sqlpt+1]
-//line sql-gen.y:11511
+//line sql-gen.y:12679
 		{
 			sqlVAL.union.val = &tree.AlterTableOwner{
 				Name:           sqlDollar[6].union.unresolvedObjectName(),
@@ -40961,25 +44809,25 @@ sqldefault:
 				IsMaterialized: true,
 			}
 		}
-	case 1933:
+	case 2148:
 		sqlDollar = sqlS[sqlpt-6 : sqlpt+1]
-//line sql-gen.y:11523
+//line sql-gen.y:12691
 		{
 			sqlVAL.union.val = &tree.AlterTableSetSchema{
 				Name: sqlDollar[3].union.unresolvedObjectName(), Schema: tree.Name(sqlDollar[6].str), IfExists: false, IsSequence: true,
 			}
 		}
-	case 1934:
+	case 2149:
 		sqlDollar = sqlS[sqlpt-8 : sqlpt+1]
-//line sql-gen.y:11529
+//line sql-gen.y:12697
 		{
 			sqlVAL.union.val = &tree.AlterTableSetSchema{
 				Name: sqlDollar[5].union.unresolvedObjectName(), Schema: tree.Name(sqlDollar[8].str), IfExists: true, IsSequence: true,
 			}
 		}
-	case 1935:
+	case 2150:
 		sqlDollar = sqlS[sqlpt-6 : sqlpt+1]
-//line sql-gen.y:11537
+//line sql-gen.y:12705
 		{
 			sqlVAL.union.val = &tree.AlterTableOwner{
 				Name:       sqlDollar[3].union.unresolvedObjectName(),
@@ -40988,9 +44836,9 @@ sqldefault:
 				IsSequence: true,
 			}
 		}
-	case 1936:
+	case 2151:
 		sqlDollar = sqlS[sqlpt-8 : sqlpt+1]
-//line sql-gen.y:11546
+//line sql-gen.y:12714
 		{
 			sqlVAL.union.val = &tree.AlterTableOwner{
 				Name:       sqlDollar[5].union.unresolvedObjectName(),
@@ -40999,17 +44847,17 @@ sqldefault:
 				IsSequence: true,
 			}
 		}
-	case 1937:
+	case 2152:
 		sqlDollar = sqlS[sqlpt-6 : sqlpt+1]
-//line sql-gen.y:11557
+//line sql-gen.y:12725
 		{
 			name := sqlDollar[3].union.unresolvedObjectName()
 			newName := sqlDollar[6].union.unresolvedObjectName()
 			sqlVAL.union.val = &tree.RenameTable{Name: name, NewName: newName, IfExists: false, IsView: true}
 		}
-	case 1938:
+	case 2153:
 		sqlDollar = sqlS[sqlpt-7 : sqlpt+1]
-//line sql-gen.y:11563
+//line sql-gen.y:12731
 		{
 			name := sqlDollar[4].union.unresolvedObjectName()
 			newName := sqlDollar[7].union.unresolvedObjectName()
@@ -41021,17 +44869,17 @@ sqldefault:
 				IsMaterialized: true,
 			}
 		}
-	case 1939:
+	case 2154:
 		sqlDollar = sqlS[sqlpt-8 : sqlpt+1]
-//line sql-gen.y:11575
+//line sql-gen.y:12743
 		{
 			name := sqlDollar[5].union.unresolvedObjectName()
 			newName := sqlDollar[8].union.unresolvedObjectName()
 			sqlVAL.union.val = &tree.RenameTable{Name: name, NewName: newName, IfExists: true, IsView: true}
 		}
-	case 1940:
+	case 2155:
 		sqlDollar = sqlS[sqlpt-9 : sqlpt+1]
-//line sql-gen.y:11581
+//line sql-gen.y:12749
 		{
 			name := sqlDollar[6].union.unresolvedObjectName()
 			newName := sqlDollar[9].union.unresolvedObjectName()
@@ -41043,37 +44891,37 @@ sqldefault:
 				IsMaterialized: true,
 			}
 		}
-	case 1941:
+	case 2156:
 		sqlDollar = sqlS[sqlpt-6 : sqlpt+1]
-//line sql-gen.y:11595
+//line sql-gen.y:12763
 		{
 			name := sqlDollar[3].union.unresolvedObjectName()
 			newName := sqlDollar[6].union.unresolvedObjectName()
 			sqlVAL.union.val = &tree.RenameTable{Name: name, NewName: newName, IfExists: false, IsSequence: true}
 		}
-	case 1942:
+	case 2157:
 		sqlDollar = sqlS[sqlpt-8 : sqlpt+1]
-//line sql-gen.y:11601
+//line sql-gen.y:12769
 		{
 			name := sqlDollar[5].union.unresolvedObjectName()
 			newName := sqlDollar[8].union.unresolvedObjectName()
 			sqlVAL.union.val = &tree.RenameTable{Name: name, NewName: newName, IfExists: true, IsSequence: true}
 		}
-	case 1943:
+	case 2158:
 		sqlDollar = sqlS[sqlpt-6 : sqlpt+1]
-//line sql-gen.y:11609
+//line sql-gen.y:12777
 		{
 			sqlVAL.union.val = &tree.RenameIndex{Index: sqlDollar[3].union.newTableIndexName(), NewName: tree.UnrestrictedName(sqlDollar[6].str), IfExists: false}
 		}
-	case 1944:
+	case 2159:
 		sqlDollar = sqlS[sqlpt-8 : sqlpt+1]
-//line sql-gen.y:11613
+//line sql-gen.y:12781
 		{
 			sqlVAL.union.val = &tree.RenameIndex{Index: sqlDollar[5].union.newTableIndexName(), NewName: tree.UnrestrictedName(sqlDollar[8].str), IfExists: true}
 		}
-	case 1945:
+	case 2160:
 		sqlDollar = sqlS[sqlpt-6 : sqlpt+1]
-//line sql-gen.y:11625
+//line sql-gen.y:12793
 		{
 			sqlVAL.union.val = &tree.AlterDefaultPrivileges{
 				Roles:   sqlDollar[4].union.roleSpecList(),
@@ -41082,9 +44930,9 @@ sqldefault:
 				IsGrant: true,
 			}
 		}
-	case 1946:
+	case 2161:
 		sqlDollar = sqlS[sqlpt-6 : sqlpt+1]
-//line sql-gen.y:11634
+//line sql-gen.y:12802
 		{
 			sqlVAL.union.val = &tree.AlterDefaultPrivileges{
 				Roles:   sqlDollar[4].union.roleSpecList(),
@@ -41093,9 +44941,9 @@ sqldefault:
 				IsGrant: false,
 			}
 		}
-	case 1947:
+	case 2162:
 		sqlDollar = sqlS[sqlpt-8 : sqlpt+1]
-//line sql-gen.y:11643
+//line sql-gen.y:12811
 		{
 			sqlVAL.union.val = &tree.AlterDefaultPrivileges{
 				ForAllRoles: true,
@@ -41104,9 +44952,9 @@ sqldefault:
 				IsGrant:     true,
 			}
 		}
-	case 1948:
+	case 2163:
 		sqlDollar = sqlS[sqlpt-8 : sqlpt+1]
-//line sql-gen.y:11652
+//line sql-gen.y:12820
 		{
 			sqlVAL.union.val = &tree.AlterDefaultPrivileges{
 				ForAllRoles: true,
@@ -41115,15 +44963,15 @@ sqldefault:
 				IsGrant:     false,
 			}
 		}
-	case 1949:
+	case 2164:
 		sqlDollar = sqlS[sqlpt-4 : sqlpt+1]
-//line sql-gen.y:11660
+//line sql-gen.y:12828
 		{
 			return helpWith(sqllex, "ALTER DEFAULT PRIVILEGES")
 		}
-	case 1950:
+	case 2165:
 		sqlDollar = sqlS[sqlpt-7 : sqlpt+1]
-//line sql-gen.y:11664
+//line sql-gen.y:12832
 		{
 			sqlVAL.union.val = tree.AbbreviatedGrant{
 				Privileges:      sqlDollar[2].union.privilegeList(),
@@ -41132,21 +44980,21 @@ sqldefault:
 				WithGrantOption: sqlDollar[7].union.bool(),
 			}
 		}
-	case 1951:
+	case 2166:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:11675
+//line sql-gen.y:12843
 		{
 			sqlVAL.union.val = true
 		}
-	case 1952:
+	case 2167:
 		sqlDollar = sqlS[sqlpt-0 : sqlpt+1]
-//line sql-gen.y:11679
+//line sql-gen.y:12847
 		{
 			sqlVAL.union.val = false
 		}
-	case 1953:
+	case 2168:
 		sqlDollar = sqlS[sqlpt-7 : sqlpt+1]
-//line sql-gen.y:11685
+//line sql-gen.y:12853
 		{
 			sqlVAL.union.val = tree.AbbreviatedRevoke{
 				Privileges: sqlDollar[2].union.privilegeList(),
@@ -41154,9 +45002,9 @@ sqldefault:
 				Grantees:   sqlDollar[6].union.roleSpecList(),
 			}
 		}
-	case 1954:
+	case 2169:
 		sqlDollar = sqlS[sqlpt-10 : sqlpt+1]
-//line sql-gen.y:11693
+//line sql-gen.y:12861
 		{
 			sqlVAL.union.val = tree.AbbreviatedRevoke{
 				Privileges:     sqlDollar[5].union.privilegeList(),
@@ -41165,113 +45013,113 @@ sqldefault:
 				GrantOptionFor: true,
 			}
 		}
-	case 1955:
+	case 2170:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:11704
+//line sql-gen.y:12872
 		{
 			sqlVAL.union.val = privilege.Tables
 		}
-	case 1956:
+	case 2171:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:11708
+//line sql-gen.y:12876
 		{
 			sqlVAL.union.val = privilege.Sequences
 		}
-	case 1957:
+	case 2172:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:11712
+//line sql-gen.y:12880
 		{
 			sqlVAL.union.val = privilege.Types
 		}
-	case 1958:
+	case 2173:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:11716
+//line sql-gen.y:12884
 		{
 			sqlVAL.union.val = privilege.Schemas
 		}
-	case 1959:
+	case 2174:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:11720
+//line sql-gen.y:12888
 		{
 			sqlVAL.union.val = privilege.Routines
 		}
-	case 1960:
+	case 2175:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:11724
+//line sql-gen.y:12892
 		{
 			return unimplemented(sqllex, "ALTER DEFAULT PRIVILEGES ... ON ROUTINES ...")
 		}
-	case 1961:
+	case 2176:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:11730
+//line sql-gen.y:12898
 		{
 			sqlVAL.union.val = sqlDollar[3].union.roleSpecList()
 		}
-	case 1962:
+	case 2177:
 		sqlDollar = sqlS[sqlpt-0 : sqlpt+1]
-//line sql-gen.y:11733
+//line sql-gen.y:12901
 		{
 			sqlVAL.union.val = tree.RoleSpecList(nil)
 		}
-	case 1963:
+	case 2178:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:11739
+//line sql-gen.y:12907
 		{
 			sqlVAL.str = sqlDollar[3].str
 		}
-	case 1964:
+	case 2179:
 		sqlDollar = sqlS[sqlpt-0 : sqlpt+1]
-//line sql-gen.y:11743
+//line sql-gen.y:12911
 		{
 			sqlVAL.str = ""
 		}
-	case 1965:
+	case 2180:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:11750
+//line sql-gen.y:12918
 		{
 			sqlVAL.union.val = sqlDollar[3].union.objectNamePrefixList()
 		}
-	case 1966:
+	case 2181:
 		sqlDollar = sqlS[sqlpt-0 : sqlpt+1]
-//line sql-gen.y:11754
+//line sql-gen.y:12922
 		{
 			sqlVAL.union.val = tree.ObjectNamePrefixList{}
 		}
-	case 1967:
+	case 2182:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:11759
+//line sql-gen.y:12927
 		{
 		}
-	case 1968:
+	case 2183:
 		sqlDollar = sqlS[sqlpt-0 : sqlpt+1]
-//line sql-gen.y:11760
+//line sql-gen.y:12928
 		{
 		}
-	case 1969:
+	case 2184:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:11763
+//line sql-gen.y:12931
 		{
 		}
-	case 1970:
+	case 2185:
 		sqlDollar = sqlS[sqlpt-0 : sqlpt+1]
-//line sql-gen.y:11764
+//line sql-gen.y:12932
 		{
 		}
-	case 1971:
+	case 2186:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:11772
+//line sql-gen.y:12940
 		{
 			sqlVAL.union.val = &tree.ReleaseSavepoint{Savepoint: tree.Name(sqlDollar[2].str)}
 		}
-	case 1972:
+	case 2187:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:11775
+//line sql-gen.y:12943
 		{
 			return helpWith(sqllex, "RELEASE")
 		}
-	case 1973:
+	case 2188:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:11785
+//line sql-gen.y:12953
 		{
 			sqlVAL.union.val = &tree.ControlJobs{
 				Jobs: &tree.Select{
@@ -41280,33 +45128,33 @@ sqldefault:
 				Command: tree.ResumeJob,
 			}
 		}
-	case 1974:
+	case 2189:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:11793
+//line sql-gen.y:12961
 		{
 			return helpWith(sqllex, "RESUME JOBS")
 		}
-	case 1975:
+	case 2190:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:11795
+//line sql-gen.y:12963
 		{
 			sqlVAL.union.val = &tree.ControlJobs{Jobs: sqlDollar[3].union.slct(), Command: tree.ResumeJob}
 		}
-	case 1976:
+	case 2191:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:11799
+//line sql-gen.y:12967
 		{
 			sqlVAL.union.val = &tree.ControlJobsForSchedules{Schedules: sqlDollar[3].union.slct(), Command: tree.ResumeJob}
 		}
-	case 1977:
+	case 2192:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:11802
+//line sql-gen.y:12970
 		{
 			return helpWith(sqllex, "RESUME JOBS")
 		}
-	case 1978:
+	case 2193:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:11815
+//line sql-gen.y:12983
 		{
 			sqlVAL.union.val = &tree.ControlSchedules{
 				Schedules: &tree.Select{
@@ -41315,30 +45163,30 @@ sqldefault:
 				Command: tree.ResumeSchedule,
 			}
 		}
-	case 1979:
+	case 2194:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:11823
+//line sql-gen.y:12991
 		{
 			return helpWith(sqllex, "RESUME SCHEDULES")
 		}
-	case 1980:
+	case 2195:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:11825
+//line sql-gen.y:12993
 		{
 			sqlVAL.union.val = &tree.ControlSchedules{
 				Schedules: sqlDollar[3].union.slct(),
 				Command:   tree.ResumeSchedule,
 			}
 		}
-	case 1981:
+	case 2196:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:11831
+//line sql-gen.y:12999
 		{
 			return helpWith(sqllex, "RESUME SCHEDULES")
 		}
-	case 1982:
+	case 2197:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:11844
+//line sql-gen.y:13012
 		{
 			sqlVAL.union.val = &tree.ControlSchedules{
 				Schedules: &tree.Select{
@@ -41347,201 +45195,219 @@ sqldefault:
 				Command: tree.DropSchedule,
 			}
 		}
-	case 1983:
+	case 2198:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:11852
+//line sql-gen.y:13020
 		{
 			return helpWith(sqllex, "DROP SCHEDULES")
 		}
-	case 1984:
+	case 2199:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:11854
+//line sql-gen.y:13022
 		{
 			sqlVAL.union.val = &tree.ControlSchedules{
 				Schedules: sqlDollar[3].union.slct(),
 				Command:   tree.DropSchedule,
 			}
 		}
-	case 1985:
+	case 2200:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:11860
+//line sql-gen.y:13028
 		{
 			return helpWith(sqllex, "DROP SCHEDULES")
 		}
-	case 1986:
+	case 2201:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:11868
+//line sql-gen.y:13036
 		{
 			sqlVAL.union.val = &tree.Savepoint{Name: tree.Name(sqlDollar[2].str)}
 		}
-	case 1987:
+	case 2202:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:11871
+//line sql-gen.y:13039
 		{
 			return helpWith(sqllex, "SAVEPOINT")
 		}
-	case 1989:
+	case 2204:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:11875
+//line sql-gen.y:13043
 		{
 			return helpWith(sqllex, "BEGIN")
 		}
-	case 1991:
+	case 2206:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:11876
+//line sql-gen.y:13044
 		{
 			return helpWith(sqllex, "COMMIT")
 		}
-	case 1993:
+	case 2208:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:11877
+//line sql-gen.y:13045
 		{
 			return helpWith(sqllex, "ROLLBACK")
 		}
-	case 1995:
+	case 2211:
+		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
+//line sql-gen.y:13047
+		{
+			return helpWith(sqllex, "PREPARE TRANSACTION")
+		}
+	case 2213:
+		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
+//line sql-gen.y:13048
+		{
+			return helpWith(sqllex, "COMMIT PREPARED")
+		}
+	case 2215:
+		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
+//line sql-gen.y:13049
+		{
+			return helpWith(sqllex, "ROLLBACK PREPARED")
+		}
+	case 2216:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:11893
+//line sql-gen.y:13064
 		{
 			s := sqlDollar[3].union.beginTransaction()
 			s.FormatWithStart = true
 			sqlVAL.union.val = s
 		}
-	case 1996:
+	case 2217:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:11898
+//line sql-gen.y:13069
 		{
 			return helpWith(sqllex, "BEGIN")
 		}
-	case 1997:
+	case 2218:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:11908
+//line sql-gen.y:13079
 		{
 			sqlVAL.union.val = &tree.CommitTransaction{}
 		}
-	case 1998:
+	case 2219:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:11911
+//line sql-gen.y:13082
 		{
 			return helpWith(sqllex, "COMMIT")
 		}
-	case 1999:
+	case 2220:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:11915
+//line sql-gen.y:13086
 		{
 			sqlVAL.union.val = &tree.RollbackTransaction{}
 		}
-	case 2000:
+	case 2221:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:11920
+//line sql-gen.y:13091
 		{
 		}
-	case 2001:
+	case 2222:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:11921
+//line sql-gen.y:13092
 		{
 		}
-	case 2002:
+	case 2223:
 		sqlDollar = sqlS[sqlpt-0 : sqlpt+1]
-//line sql-gen.y:11922
+//line sql-gen.y:13093
 		{
 		}
-	case 2003:
+	case 2224:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:11932
+//line sql-gen.y:13103
 		{
 			sqlVAL.union.val = &tree.RollbackTransaction{}
 		}
-	case 2004:
+	case 2225:
 		sqlDollar = sqlS[sqlpt-4 : sqlpt+1]
-//line sql-gen.y:11936
+//line sql-gen.y:13107
 		{
 			sqlVAL.union.val = &tree.RollbackToSavepoint{Savepoint: tree.Name(sqlDollar[4].str)}
 		}
-	case 2005:
+	case 2226:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:11939
+//line sql-gen.y:13110
 		{
 			return helpWith(sqllex, "ROLLBACK")
 		}
-	case 2007:
+	case 2228:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:11945
+//line sql-gen.y:13116
 		{
 			return helpWith(sqllex, "BEGIN")
 		}
-	case 2009:
+	case 2230:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:11946
+//line sql-gen.y:13117
 		{
 			return helpWith(sqllex, "COMMIT")
 		}
-	case 2010:
+	case 2231:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:11950
+//line sql-gen.y:13121
 		{
 			sqlVAL.union.val = sqlDollar[3].union.stmt()
 		}
-	case 2011:
+	case 2232:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:11953
+//line sql-gen.y:13124
 		{
 			return helpWith(sqllex, "BEGIN")
 		}
-	case 2012:
+	case 2233:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:11957
+//line sql-gen.y:13128
 		{
 			sqlVAL.union.val = &tree.CommitTransaction{}
 		}
-	case 2013:
+	case 2234:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:11960
+//line sql-gen.y:13131
 		{
 			return helpWith(sqllex, "COMMIT")
 		}
-	case 2014:
+	case 2235:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:11964
+//line sql-gen.y:13135
 		{
 		}
-	case 2015:
+	case 2236:
 		sqlDollar = sqlS[sqlpt-0 : sqlpt+1]
-//line sql-gen.y:11965
+//line sql-gen.y:13136
 		{
 		}
-	case 2016:
+	case 2237:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:11969
+//line sql-gen.y:13140
 		{
 			sqlVAL.str = sqlDollar[2].str
 		}
-	case 2017:
+	case 2238:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:11973
+//line sql-gen.y:13144
 		{
 			sqlVAL.str = sqlDollar[1].str
 		}
-	case 2018:
+	case 2239:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:11979
+//line sql-gen.y:13150
 		{
 			sqlVAL.union.val = &tree.BeginTransaction{Modes: sqlDollar[1].union.transactionModes()}
 		}
-	case 2019:
+	case 2240:
 		sqlDollar = sqlS[sqlpt-0 : sqlpt+1]
-//line sql-gen.y:11983
+//line sql-gen.y:13154
 		{
 			sqlVAL.union.val = &tree.BeginTransaction{}
 		}
-	case 2020:
+	case 2241:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:11989
+//line sql-gen.y:13160
 		{
 			sqlVAL.union.val = sqlDollar[1].union.transactionModes()
 		}
-	case 2021:
+	case 2242:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:11993
+//line sql-gen.y:13164
 		{
 			a := sqlDollar[1].union.transactionModes()
 			b := sqlDollar[3].union.transactionModes()
@@ -41551,86 +45417,103 @@ sqldefault:
 			}
 			sqlVAL.union.val = a
 		}
-	case 2022:
+	case 2243:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:12006
+//line sql-gen.y:13177
 		{
 		}
-	case 2023:
+	case 2244:
 		sqlDollar = sqlS[sqlpt-0 : sqlpt+1]
-//line sql-gen.y:12008
+//line sql-gen.y:13179
 		{
 		}
-	case 2024:
+	case 2245:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:12012
+//line sql-gen.y:13183
 		{
-
 			sqlVAL.union.val = tree.TransactionModes{Isolation: sqlDollar[1].union.isoLevel()}
 		}
-	case 2025:
+	case 2246:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:12017
+//line sql-gen.y:13187
 		{
 			sqlVAL.union.val = tree.TransactionModes{UserPriority: sqlDollar[1].union.userPriority()}
 		}
-	case 2026:
+	case 2247:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:12021
+//line sql-gen.y:13191
 		{
 			sqlVAL.union.val = tree.TransactionModes{ReadWriteMode: sqlDollar[1].union.readWriteMode()}
 		}
-	case 2027:
+	case 2248:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:12025
+//line sql-gen.y:13195
 		{
 			sqlVAL.union.val = tree.TransactionModes{AsOf: sqlDollar[1].union.asOfClause()}
 		}
-	case 2028:
+	case 2249:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:12029
+//line sql-gen.y:13199
 		{
 			sqlVAL.union.val = tree.TransactionModes{Deferrable: sqlDollar[1].union.deferrableMode()}
 		}
-	case 2029:
+	case 2250:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:12035
+//line sql-gen.y:13205
 		{
 			sqlVAL.union.val = sqlDollar[2].union.userPriority()
 		}
-	case 2030:
+	case 2251:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:12041
+//line sql-gen.y:13211
 		{
 			sqlVAL.union.val = sqlDollar[3].union.isoLevel()
 		}
-	case 2031:
+	case 2252:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:12047
+//line sql-gen.y:13217
 		{
 			sqlVAL.union.val = tree.ReadOnly
 		}
-	case 2032:
+	case 2253:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:12051
+//line sql-gen.y:13221
 		{
 			sqlVAL.union.val = tree.ReadWrite
 		}
-	case 2033:
+	case 2254:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:12057
+//line sql-gen.y:13227
 		{
 			sqlVAL.union.val = tree.Deferrable
 		}
-	case 2034:
+	case 2255:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:12061
+//line sql-gen.y:13231
 		{
 			sqlVAL.union.val = tree.NotDeferrable
 		}
-	case 2035:
+	case 2256:
+		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
+//line sql-gen.y:13241
+		{
+			sqlVAL.union.val = &tree.PrepareTransaction{Transaction: tree.NewStrVal(sqlDollar[3].str)}
+		}
+	case 2257:
+		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
+//line sql-gen.y:13251
+		{
+			sqlVAL.union.val = &tree.CommitPrepared{Transaction: tree.NewStrVal(sqlDollar[3].str)}
+		}
+	case 2258:
+		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
+//line sql-gen.y:13261
+		{
+			sqlVAL.union.val = &tree.RollbackPrepared{Transaction: tree.NewStrVal(sqlDollar[3].str)}
+		}
+	case 2259:
 		sqlDollar = sqlS[sqlpt-16 : sqlpt+1]
-//line sql-gen.y:12071
+//line sql-gen.y:13271
 		{
 			sqlVAL.union.val = &tree.CreateDatabase{
 				Name:            tree.Name(sqlDollar[3].str),
@@ -41648,9 +45531,9 @@ sqldefault:
 				SecondaryRegion: tree.Name(sqlDollar[16].str),
 			}
 		}
-	case 2036:
+	case 2260:
 		sqlDollar = sqlS[sqlpt-19 : sqlpt+1]
-//line sql-gen.y:12089
+//line sql-gen.y:13289
 		{
 			sqlVAL.union.val = &tree.CreateDatabase{
 				IfNotExists:     true,
@@ -41669,160 +45552,160 @@ sqldefault:
 				SecondaryRegion: tree.Name(sqlDollar[19].str),
 			}
 		}
-	case 2037:
+	case 2261:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:12107
+//line sql-gen.y:13307
 		{
 			return helpWith(sqllex, "CREATE DATABASE")
 		}
-	case 2039:
+	case 2263:
 		sqlDollar = sqlS[sqlpt-0 : sqlpt+1]
-//line sql-gen.y:12112
+//line sql-gen.y:13312
 		{
 			sqlVAL.str = ""
 		}
-	case 2040:
+	case 2264:
 		sqlDollar = sqlS[sqlpt-4 : sqlpt+1]
-//line sql-gen.y:12117
+//line sql-gen.y:13317
 		{
 			sqlVAL.str = sqlDollar[4].str
 		}
-	case 2042:
+	case 2266:
 		sqlDollar = sqlS[sqlpt-0 : sqlpt+1]
-//line sql-gen.y:12124
+//line sql-gen.y:13324
 		{
 			sqlVAL.str = ""
 		}
-	case 2043:
+	case 2267:
 		sqlDollar = sqlS[sqlpt-4 : sqlpt+1]
-//line sql-gen.y:12129
+//line sql-gen.y:13329
 		{
 			sqlVAL.str = sqlDollar[4].str
 		}
-	case 2045:
+	case 2269:
 		sqlDollar = sqlS[sqlpt-0 : sqlpt+1]
-//line sql-gen.y:12136
+//line sql-gen.y:13336
 		{
 			sqlVAL.union.val = tree.SuperRegion{}
 		}
-	case 2046:
+	case 2270:
 		sqlDollar = sqlS[sqlpt-5 : sqlpt+1]
-//line sql-gen.y:12142
+//line sql-gen.y:13342
 		{
 			sqlVAL.union.val = tree.SuperRegion{Name: tree.Name(sqlDollar[3].str), Regions: sqlDollar[5].union.nameList()}
 		}
-	case 2048:
+	case 2272:
 		sqlDollar = sqlS[sqlpt-0 : sqlpt+1]
-//line sql-gen.y:12149
+//line sql-gen.y:13349
 		{
 			sqlVAL.union.val = tree.DataPlacementUnspecified
 		}
-	case 2049:
+	case 2273:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:12155
+//line sql-gen.y:13355
 		{
 			sqlVAL.union.val = tree.DataPlacementRestricted
 		}
-	case 2050:
+	case 2274:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:12159
+//line sql-gen.y:13359
 		{
 			sqlVAL.union.val = tree.DataPlacementDefault
 		}
-	case 2051:
+	case 2275:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:12165
+//line sql-gen.y:13365
 		{
 			sqlVAL.union.val = sqlDollar[3].union.nameList()
 		}
-	case 2052:
+	case 2276:
 		sqlDollar = sqlS[sqlpt-0 : sqlpt+1]
-//line sql-gen.y:12169
+//line sql-gen.y:13369
 		{
 			sqlVAL.union.val = tree.NameList(nil)
 		}
-	case 2053:
+	case 2277:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:12175
+//line sql-gen.y:13375
 		{
 
 		}
-	case 2055:
+	case 2279:
 		sqlDollar = sqlS[sqlpt-4 : sqlpt+1]
-//line sql-gen.y:12182
+//line sql-gen.y:13382
 		{
 			sqlVAL.union.val = tree.SurvivalGoalRegionFailure
 		}
-	case 2056:
+	case 2280:
 		sqlDollar = sqlS[sqlpt-4 : sqlpt+1]
-//line sql-gen.y:12186
+//line sql-gen.y:13386
 		{
 			sqlVAL.union.val = tree.SurvivalGoalZoneFailure
 		}
-	case 2057:
+	case 2281:
 		sqlDollar = sqlS[sqlpt-5 : sqlpt+1]
-//line sql-gen.y:12190
+//line sql-gen.y:13390
 		{
 
 			sqlVAL.union.val = tree.SurvivalGoalZoneFailure
 		}
-	case 2059:
+	case 2283:
 		sqlDollar = sqlS[sqlpt-0 : sqlpt+1]
-//line sql-gen.y:12199
+//line sql-gen.y:13399
 		{
 			sqlVAL.union.val = tree.SurvivalGoalDefault
 		}
-	case 2060:
+	case 2284:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:12205
+//line sql-gen.y:13405
 		{
 			sqlVAL.str = sqlDollar[3].str
 		}
-	case 2061:
+	case 2285:
 		sqlDollar = sqlS[sqlpt-0 : sqlpt+1]
-//line sql-gen.y:12209
+//line sql-gen.y:13409
 		{
 			sqlVAL.str = ""
 		}
-	case 2062:
+	case 2286:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:12215
+//line sql-gen.y:13415
 		{
 			sqlVAL.str = sqlDollar[3].str
 		}
-	case 2063:
+	case 2287:
 		sqlDollar = sqlS[sqlpt-0 : sqlpt+1]
-//line sql-gen.y:12219
+//line sql-gen.y:13419
 		{
 			sqlVAL.str = ""
 		}
-	case 2064:
+	case 2288:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:12225
+//line sql-gen.y:13425
 		{
 			sqlVAL.str = sqlDollar[3].str
 		}
-	case 2065:
+	case 2289:
 		sqlDollar = sqlS[sqlpt-0 : sqlpt+1]
-//line sql-gen.y:12229
+//line sql-gen.y:13429
 		{
 			sqlVAL.str = ""
 		}
-	case 2066:
+	case 2290:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:12235
+//line sql-gen.y:13435
 		{
 			sqlVAL.str = sqlDollar[3].str
 		}
-	case 2067:
+	case 2291:
 		sqlDollar = sqlS[sqlpt-0 : sqlpt+1]
-//line sql-gen.y:12239
+//line sql-gen.y:13439
 		{
 			sqlVAL.str = ""
 		}
-	case 2068:
+	case 2292:
 		sqlDollar = sqlS[sqlpt-4 : sqlpt+1]
-//line sql-gen.y:12245
+//line sql-gen.y:13445
 		{
 			ret, err := sqlDollar[4].union.numVal().AsInt32()
 			if err != nil {
@@ -41830,48 +45713,48 @@ sqldefault:
 			}
 			sqlVAL.union.val = ret
 		}
-	case 2069:
+	case 2293:
 		sqlDollar = sqlS[sqlpt-0 : sqlpt+1]
-//line sql-gen.y:12253
+//line sql-gen.y:13453
 		{
 			sqlVAL.union.val = int32(-1)
 		}
-	case 2070:
+	case 2294:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:12259
+//line sql-gen.y:13459
 		{
 			sqlVAL.union = sqlDollar[3].union
 		}
-	case 2071:
+	case 2295:
 		sqlDollar = sqlS[sqlpt-0 : sqlpt+1]
-//line sql-gen.y:12263
+//line sql-gen.y:13463
 		{
 			sqlVAL.union.val = tree.RoleSpec{
 				RoleSpecType: tree.CurrentUser,
 			}
 		}
-	case 2072:
+	case 2296:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:12270
+//line sql-gen.y:13470
 		{
 		}
-	case 2073:
+	case 2297:
 		sqlDollar = sqlS[sqlpt-0 : sqlpt+1]
-//line sql-gen.y:12271
+//line sql-gen.y:13471
 		{
 		}
-	case 2074:
+	case 2298:
 		sqlDollar = sqlS[sqlpt-6 : sqlpt+1]
-//line sql-gen.y:12286
+//line sql-gen.y:13486
 		{
 			sqlVAL.union.val = sqlDollar[5].union.stmt()
 			sqlVAL.union.val.(*tree.Insert).With = sqlDollar[1].union.with()
 			sqlVAL.union.val.(*tree.Insert).Table = sqlDollar[4].union.tblExpr()
 			sqlVAL.union.val.(*tree.Insert).Returning = sqlDollar[6].union.retClause()
 		}
-	case 2075:
+	case 2299:
 		sqlDollar = sqlS[sqlpt-7 : sqlpt+1]
-//line sql-gen.y:12293
+//line sql-gen.y:13493
 		{
 			sqlVAL.union.val = sqlDollar[5].union.stmt()
 			sqlVAL.union.val.(*tree.Insert).With = sqlDollar[1].union.with()
@@ -41879,15 +45762,15 @@ sqldefault:
 			sqlVAL.union.val.(*tree.Insert).OnConflict = sqlDollar[6].union.onConflict()
 			sqlVAL.union.val.(*tree.Insert).Returning = sqlDollar[7].union.retClause()
 		}
-	case 2076:
+	case 2300:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:12300
+//line sql-gen.y:13500
 		{
 			return helpWith(sqllex, "INSERT")
 		}
-	case 2077:
+	case 2301:
 		sqlDollar = sqlS[sqlpt-6 : sqlpt+1]
-//line sql-gen.y:12311
+//line sql-gen.y:13511
 		{
 			sqlVAL.union.val = sqlDollar[5].union.stmt()
 			sqlVAL.union.val.(*tree.Insert).With = sqlDollar[1].union.with()
@@ -41895,80 +45778,84 @@ sqldefault:
 			sqlVAL.union.val.(*tree.Insert).OnConflict = &tree.OnConflict{}
 			sqlVAL.union.val.(*tree.Insert).Returning = sqlDollar[6].union.retClause()
 		}
-	case 2078:
+	case 2302:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:12318
+//line sql-gen.y:13518
 		{
 			return helpWith(sqllex, "UPSERT")
 		}
-	case 2079:
+	case 2303:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:12322
+//line sql-gen.y:13522
 		{
-			name := sqlDollar[1].union.unresolvedObjectName().ToTableName()
-			sqlVAL.union.val = &name
+			sqlVAL.union.val = sqlDollar[1].union.tblExpr()
 		}
-	case 2080:
+	case 2304:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:12331
+//line sql-gen.y:13530
 		{
-			name := sqlDollar[1].union.unresolvedObjectName().ToTableName()
-			sqlVAL.union.val = &tree.AliasedTableExpr{Expr: &name, As: tree.AliasClause{Alias: tree.Name(sqlDollar[3].str)}}
+			alias := sqlDollar[1].union.tblExpr().(*tree.AliasedTableExpr)
+			alias.As = tree.AliasClause{Alias: tree.Name(sqlDollar[3].str)}
+			sqlVAL.union.val = alias
 		}
-	case 2081:
-		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:12336
+	case 2305:
+		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
+//line sql-gen.y:13536
 		{
-			sqlVAL.union.val = sqlDollar[1].union.tblExpr()
+
+			sqlVAL.union.val = &tree.AliasedTableExpr{
+				Expr:       sqlDollar[1].union.tblExpr(),
+				IndexFlags: sqlDollar[2].union.indexFlags(),
+			}
 		}
-	case 2082:
+	case 2306:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:12342
+//line sql-gen.y:13546
 		{
 			sqlVAL.union.val = &tree.Insert{Rows: sqlDollar[1].union.slct()}
 		}
-	case 2083:
+	case 2307:
 		sqlDollar = sqlS[sqlpt-4 : sqlpt+1]
-//line sql-gen.y:12346
+//line sql-gen.y:13550
 		{
 			sqlVAL.union.val = &tree.Insert{Columns: sqlDollar[2].union.nameList(), Rows: sqlDollar[4].union.slct()}
 		}
-	case 2084:
+	case 2308:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:12350
+//line sql-gen.y:13554
 		{
 			sqlVAL.union.val = &tree.Insert{Rows: &tree.Select{}}
 		}
-	case 2085:
+	case 2309:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:12356
+//line sql-gen.y:13560
 		{
 			sqlVAL.union.val = tree.NameList{tree.Name(sqlDollar[1].str)}
 		}
-	case 2086:
+	case 2310:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:12360
+//line sql-gen.y:13564
 		{
 			sqlVAL.union.val = append(sqlDollar[1].union.nameList(), tree.Name(sqlDollar[3].str))
 		}
-	case 2088:
+	case 2312:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:12380
+//line sql-gen.y:13584
 		{
 			return unimplementedWithIssue(sqllex, 27792)
 		}
-	case 2089:
+	case 2313:
 		sqlDollar = sqlS[sqlpt-4 : sqlpt+1]
-//line sql-gen.y:12384
+//line sql-gen.y:13588
 		{
 			sqlVAL.union.val = &tree.OnConflict{
 				Columns:   tree.NameList(nil),
 				DoNothing: true,
 			}
 		}
-	case 2090:
+	case 2314:
 		sqlDollar = sqlS[sqlpt-8 : sqlpt+1]
-//line sql-gen.y:12391
+//line sql-gen.y:13595
 		{
 			sqlVAL.union.val = &tree.OnConflict{
 				Columns:          sqlDollar[4].union.nameList(),
@@ -41976,9 +45863,9 @@ sqldefault:
 				DoNothing:        true,
 			}
 		}
-	case 2091:
+	case 2315:
 		sqlDollar = sqlS[sqlpt-11 : sqlpt+1]
-//line sql-gen.y:12399
+//line sql-gen.y:13603
 		{
 			sqlVAL.union.val = &tree.OnConflict{
 				Columns:          sqlDollar[4].union.nameList(),
@@ -41987,18 +45874,18 @@ sqldefault:
 				Where:            tree.NewWhere(tree.AstWhere, sqlDollar[11].union.expr()),
 			}
 		}
-	case 2092:
+	case 2316:
 		sqlDollar = sqlS[sqlpt-7 : sqlpt+1]
-//line sql-gen.y:12408
+//line sql-gen.y:13612
 		{
 			sqlVAL.union.val = &tree.OnConflict{
 				Constraint: tree.Name(sqlDollar[5].str),
 				DoNothing:  true,
 			}
 		}
-	case 2093:
+	case 2317:
 		sqlDollar = sqlS[sqlpt-10 : sqlpt+1]
-//line sql-gen.y:12415
+//line sql-gen.y:13619
 		{
 			sqlVAL.union.val = &tree.OnConflict{
 				Constraint: tree.Name(sqlDollar[5].str),
@@ -42006,28 +45893,28 @@ sqldefault:
 				Where:      tree.NewWhere(tree.AstWhere, sqlDollar[10].union.expr()),
 			}
 		}
-	case 2094:
+	case 2318:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:12425
+//line sql-gen.y:13629
 		{
 			ret := tree.ReturningExprs(sqlDollar[2].union.selExprs())
 			sqlVAL.union.val = &ret
 		}
-	case 2095:
+	case 2319:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:12430
+//line sql-gen.y:13634
 		{
 			sqlVAL.union.val = tree.ReturningNothingClause
 		}
-	case 2096:
+	case 2320:
 		sqlDollar = sqlS[sqlpt-0 : sqlpt+1]
-//line sql-gen.y:12434
+//line sql-gen.y:13638
 		{
 			sqlVAL.union.val = tree.AbsentReturningClause
 		}
-	case 2097:
+	case 2321:
 		sqlDollar = sqlS[sqlpt-10 : sqlpt+1]
-//line sql-gen.y:12452
+//line sql-gen.y:13656
 		{
 			sqlVAL.union.val = &tree.Update{
 				With:      sqlDollar[1].union.with(),
@@ -42040,189 +45927,189 @@ sqldefault:
 				Returning: sqlDollar[10].union.retClause(),
 			}
 		}
-	case 2098:
+	case 2322:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:12464
+//line sql-gen.y:13668
 		{
 			return helpWith(sqllex, "UPDATE")
 		}
-	case 2099:
+	case 2323:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:12467
+//line sql-gen.y:13671
 		{
 			sqlVAL.union.val = sqlDollar[2].union.tblExprs()
 		}
-	case 2100:
+	case 2324:
 		sqlDollar = sqlS[sqlpt-0 : sqlpt+1]
-//line sql-gen.y:12470
+//line sql-gen.y:13674
 		{
 			sqlVAL.union.val = tree.TableExprs{}
 		}
-	case 2101:
+	case 2325:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:12476
+//line sql-gen.y:13680
 		{
 			sqlVAL.union.val = tree.UpdateExprs{sqlDollar[1].union.updateExpr()}
 		}
-	case 2102:
+	case 2326:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:12480
+//line sql-gen.y:13684
 		{
 			sqlVAL.union.val = append(sqlDollar[1].union.updateExprs(), sqlDollar[3].union.updateExpr())
 		}
-	case 2105:
+	case 2329:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:12493
+//line sql-gen.y:13697
 		{
 			sqlVAL.union.val = &tree.UpdateExpr{Names: tree.NameList{tree.Name(sqlDollar[1].str)}, Expr: sqlDollar[3].union.expr()}
 		}
-	case 2106:
+	case 2330:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:12496
+//line sql-gen.y:13700
 		{
 			return unimplementedWithIssue(sqllex, 27792)
 		}
-	case 2107:
+	case 2331:
 		sqlDollar = sqlS[sqlpt-5 : sqlpt+1]
-//line sql-gen.y:12500
+//line sql-gen.y:13704
 		{
 			sqlVAL.union.val = &tree.UpdateExpr{Tuple: true, Names: sqlDollar[2].union.nameList(), Expr: sqlDollar[5].union.expr()}
 		}
-	case 2108:
+	case 2332:
 		sqlDollar = sqlS[sqlpt-6 : sqlpt+1]
-//line sql-gen.y:12511
+//line sql-gen.y:13715
 		{
 			sqlVAL.union.val = &tree.ReassignOwnedBy{
 				OldRoles: sqlDollar[4].union.roleSpecList(),
 				NewRole:  sqlDollar[6].union.roleSpec(),
 			}
 		}
-	case 2109:
+	case 2333:
 		sqlDollar = sqlS[sqlpt-4 : sqlpt+1]
-//line sql-gen.y:12517
+//line sql-gen.y:13721
 		{
 			return helpWith(sqllex, "REASSIGN OWNED BY")
 		}
-	case 2110:
+	case 2334:
 		sqlDollar = sqlS[sqlpt-5 : sqlpt+1]
-//line sql-gen.y:12526
+//line sql-gen.y:13730
 		{
 			sqlVAL.union.val = &tree.DropOwnedBy{
 				Roles:        sqlDollar[4].union.roleSpecList(),
 				DropBehavior: sqlDollar[5].union.dropBehavior(),
 			}
 		}
-	case 2111:
+	case 2335:
 		sqlDollar = sqlS[sqlpt-4 : sqlpt+1]
-//line sql-gen.y:12532
+//line sql-gen.y:13736
 		{
 			return helpWith(sqllex, "DROP OWNED BY")
 		}
-	case 2113:
+	case 2337:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:12573
+//line sql-gen.y:13777
 		{
 			sqlVAL.union.val = &tree.Select{Select: sqlDollar[1].union.selectStmt()}
 		}
-	case 2114:
+	case 2338:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:12579
+//line sql-gen.y:13783
 		{
 			sqlVAL.union.val = &tree.ParenSelect{Select: sqlDollar[2].union.slct()}
 		}
-	case 2115:
+	case 2339:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:12583
+//line sql-gen.y:13787
 		{
 			sqlVAL.union.val = &tree.ParenSelect{Select: &tree.Select{Select: sqlDollar[2].union.selectStmt()}}
 		}
-	case 2116:
+	case 2340:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:12598
+//line sql-gen.y:13802
 		{
 			sqlVAL.union.val = &tree.Select{Select: sqlDollar[1].union.selectStmt()}
 		}
-	case 2117:
+	case 2341:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:12602
+//line sql-gen.y:13806
 		{
 			sqlVAL.union.val = &tree.Select{Select: sqlDollar[1].union.selectStmt(), OrderBy: sqlDollar[2].union.orderBy()}
 		}
-	case 2118:
+	case 2342:
 		sqlDollar = sqlS[sqlpt-4 : sqlpt+1]
-//line sql-gen.y:12606
+//line sql-gen.y:13810
 		{
 			sqlVAL.union.val = &tree.Select{Select: sqlDollar[1].union.selectStmt(), OrderBy: sqlDollar[2].union.orderBy(), Limit: sqlDollar[4].union.limit(), Locking: sqlDollar[3].union.lockingClause()}
 		}
-	case 2119:
+	case 2343:
 		sqlDollar = sqlS[sqlpt-4 : sqlpt+1]
-//line sql-gen.y:12610
+//line sql-gen.y:13814
 		{
 			sqlVAL.union.val = &tree.Select{Select: sqlDollar[1].union.selectStmt(), OrderBy: sqlDollar[2].union.orderBy(), Limit: sqlDollar[3].union.limit(), Locking: sqlDollar[4].union.lockingClause()}
 		}
-	case 2120:
+	case 2344:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:12614
+//line sql-gen.y:13818
 		{
 			sqlVAL.union.val = &tree.Select{With: sqlDollar[1].union.with(), Select: sqlDollar[2].union.selectStmt()}
 		}
-	case 2121:
+	case 2345:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:12618
+//line sql-gen.y:13822
 		{
 			sqlVAL.union.val = &tree.Select{With: sqlDollar[1].union.with(), Select: sqlDollar[2].union.selectStmt(), OrderBy: sqlDollar[3].union.orderBy()}
 		}
-	case 2122:
+	case 2346:
 		sqlDollar = sqlS[sqlpt-5 : sqlpt+1]
-//line sql-gen.y:12622
+//line sql-gen.y:13826
 		{
 			sqlVAL.union.val = &tree.Select{With: sqlDollar[1].union.with(), Select: sqlDollar[2].union.selectStmt(), OrderBy: sqlDollar[3].union.orderBy(), Limit: sqlDollar[5].union.limit(), Locking: sqlDollar[4].union.lockingClause()}
 		}
-	case 2123:
+	case 2347:
 		sqlDollar = sqlS[sqlpt-5 : sqlpt+1]
-//line sql-gen.y:12626
+//line sql-gen.y:13830
 		{
 			sqlVAL.union.val = &tree.Select{With: sqlDollar[1].union.with(), Select: sqlDollar[2].union.selectStmt(), OrderBy: sqlDollar[3].union.orderBy(), Limit: sqlDollar[4].union.limit(), Locking: sqlDollar[5].union.lockingClause()}
 		}
-	case 2124:
+	case 2348:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:12631
+//line sql-gen.y:13835
 		{
 			sqlVAL.union.val = sqlDollar[1].union.lockingClause()
 		}
-	case 2125:
+	case 2349:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:12632
+//line sql-gen.y:13836
 		{
 			sqlVAL.union.val = (tree.LockingClause)(nil)
 		}
-	case 2126:
+	case 2350:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:12635
+//line sql-gen.y:13839
 		{
 			sqlVAL.union.val = sqlDollar[1].union.lockingClause()
 		}
-	case 2127:
+	case 2351:
 		sqlDollar = sqlS[sqlpt-0 : sqlpt+1]
-//line sql-gen.y:12636
+//line sql-gen.y:13840
 		{
 			sqlVAL.union.val = (tree.LockingClause)(nil)
 		}
-	case 2128:
+	case 2352:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:12640
+//line sql-gen.y:13844
 		{
 			sqlVAL.union.val = tree.LockingClause{sqlDollar[1].union.lockingItem()}
 		}
-	case 2129:
+	case 2353:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:12644
+//line sql-gen.y:13848
 		{
 			sqlVAL.union.val = append(sqlDollar[1].union.lockingClause(), sqlDollar[2].union.lockingItem())
 		}
-	case 2130:
+	case 2354:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:12650
+//line sql-gen.y:13854
 		{
 			sqlVAL.union.val = &tree.LockingItem{
 				Strength:   sqlDollar[1].union.lockingStrength(),
@@ -42230,87 +46117,87 @@ sqldefault:
 				WaitPolicy: sqlDollar[3].union.lockingWaitPolicy(),
 			}
 		}
-	case 2131:
+	case 2355:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:12659
+//line sql-gen.y:13863
 		{
 			sqlVAL.union.val = tree.ForUpdate
 		}
-	case 2132:
+	case 2356:
 		sqlDollar = sqlS[sqlpt-4 : sqlpt+1]
-//line sql-gen.y:12660
+//line sql-gen.y:13864
 		{
 			sqlVAL.union.val = tree.ForNoKeyUpdate
 		}
-	case 2133:
+	case 2357:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:12661
+//line sql-gen.y:13865
 		{
 			sqlVAL.union.val = tree.ForShare
 		}
-	case 2134:
+	case 2358:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:12662
+//line sql-gen.y:13866
 		{
 			sqlVAL.union.val = tree.ForKeyShare
 		}
-	case 2135:
+	case 2359:
 		sqlDollar = sqlS[sqlpt-0 : sqlpt+1]
-//line sql-gen.y:12665
+//line sql-gen.y:13869
 		{
 			sqlVAL.union.val = tree.TableNames{}
 		}
-	case 2136:
+	case 2360:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:12666
+//line sql-gen.y:13870
 		{
 			sqlVAL.union.val = sqlDollar[2].union.tableNames()
 		}
-	case 2137:
+	case 2361:
 		sqlDollar = sqlS[sqlpt-0 : sqlpt+1]
-//line sql-gen.y:12669
+//line sql-gen.y:13873
 		{
 			sqlVAL.union.val = tree.LockWaitBlock
 		}
-	case 2138:
+	case 2362:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:12670
+//line sql-gen.y:13874
 		{
 			sqlVAL.union.val = tree.LockWaitSkipLocked
 		}
-	case 2139:
+	case 2363:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:12671
+//line sql-gen.y:13875
 		{
 			sqlVAL.union.val = tree.LockWaitError
 		}
-	case 2140:
+	case 2364:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:12676
+//line sql-gen.y:13880
 		{
 			return helpWith(sqllex, "<SELECTCLAUSE>")
 		}
-	case 2144:
+	case 2368:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:12711
+//line sql-gen.y:13915
 		{
 			return helpWith(sqllex, "SELECT")
 		}
-	case 2146:
+	case 2370:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:12712
+//line sql-gen.y:13916
 		{
 			return helpWith(sqllex, "VALUES")
 		}
-	case 2148:
+	case 2372:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:12713
+//line sql-gen.y:13917
 		{
 			return helpWith(sqllex, "TABLE")
 		}
-	case 2150:
+	case 2374:
 		sqlDollar = sqlS[sqlpt-8 : sqlpt+1]
-//line sql-gen.y:12735
+//line sql-gen.y:13939
 		{
 			sqlVAL.union.val = &tree.SelectClause{
 				Exprs:   sqlDollar[3].union.selExprs(),
@@ -42321,9 +46208,9 @@ sqldefault:
 				Window:  sqlDollar[8].union.window(),
 			}
 		}
-	case 2151:
+	case 2375:
 		sqlDollar = sqlS[sqlpt-8 : sqlpt+1]
-//line sql-gen.y:12748
+//line sql-gen.y:13952
 		{
 			sqlVAL.union.val = &tree.SelectClause{
 				Distinct: sqlDollar[2].union.bool(),
@@ -42335,9 +46222,9 @@ sqldefault:
 				Window:   sqlDollar[8].union.window(),
 			}
 		}
-	case 2152:
+	case 2376:
 		sqlDollar = sqlS[sqlpt-8 : sqlpt+1]
-//line sql-gen.y:12762
+//line sql-gen.y:13966
 		{
 			sqlVAL.union.val = &tree.SelectClause{
 				Distinct:   true,
@@ -42350,15 +46237,9 @@ sqldefault:
 				Window:     sqlDollar[8].union.window(),
 			}
 		}
-	case 2153:
-		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:12774
-		{
-			return helpWith(sqllex, "SELECT")
-		}
-	case 2154:
+	case 2377:
 		sqlDollar = sqlS[sqlpt-4 : sqlpt+1]
-//line sql-gen.y:12778
+//line sql-gen.y:13981
 		{
 			sqlVAL.union.val = &tree.UnionClause{
 				Type:  tree.UnionOp,
@@ -42367,9 +46248,9 @@ sqldefault:
 				All:   sqlDollar[3].union.bool(),
 			}
 		}
-	case 2155:
+	case 2378:
 		sqlDollar = sqlS[sqlpt-4 : sqlpt+1]
-//line sql-gen.y:12787
+//line sql-gen.y:13990
 		{
 			sqlVAL.union.val = &tree.UnionClause{
 				Type:  tree.IntersectOp,
@@ -42378,9 +46259,9 @@ sqldefault:
 				All:   sqlDollar[3].union.bool(),
 			}
 		}
-	case 2156:
+	case 2379:
 		sqlDollar = sqlS[sqlpt-4 : sqlpt+1]
-//line sql-gen.y:12796
+//line sql-gen.y:13999
 		{
 			sqlVAL.union.val = &tree.UnionClause{
 				Type:  tree.ExceptOp,
@@ -42389,9 +46270,9 @@ sqldefault:
 				All:   sqlDollar[3].union.bool(),
 			}
 		}
-	case 2157:
+	case 2380:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:12811
+//line sql-gen.y:14014
 		{
 			sqlVAL.union.val = &tree.SelectClause{
 				Exprs:       tree.SelectExprs{tree.StarSelectExpr()},
@@ -42399,64 +46280,64 @@ sqldefault:
 				TableSelect: true,
 			}
 		}
-	case 2158:
+	case 2381:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:12818
+//line sql-gen.y:14021
 		{
 			return helpWith(sqllex, "TABLE")
 		}
-	case 2159:
+	case 2382:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:12830
+//line sql-gen.y:14033
 		{
 			sqlVAL.union.val = &tree.With{CTEList: sqlDollar[2].union.ctes()}
 		}
-	case 2160:
+	case 2383:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:12834
+//line sql-gen.y:14037
 		{
 
 			sqlVAL.union.val = &tree.With{CTEList: sqlDollar[2].union.ctes()}
 		}
-	case 2161:
+	case 2384:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:12839
+//line sql-gen.y:14042
 		{
 			sqlVAL.union.val = &tree.With{Recursive: true, CTEList: sqlDollar[3].union.ctes()}
 		}
-	case 2162:
+	case 2385:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:12845
+//line sql-gen.y:14048
 		{
 			sqlVAL.union.val = []*tree.CTE{sqlDollar[1].union.cte()}
 		}
-	case 2163:
+	case 2386:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:12849
+//line sql-gen.y:14052
 		{
 			sqlVAL.union.val = append(sqlDollar[1].union.ctes(), sqlDollar[3].union.cte())
 		}
-	case 2164:
+	case 2387:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:12855
+//line sql-gen.y:14058
 		{
 			sqlVAL.union.val = tree.CTEMaterializeAlways
 		}
-	case 2165:
+	case 2388:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:12859
+//line sql-gen.y:14062
 		{
 			sqlVAL.union.val = tree.CTEMaterializeNever
 		}
-	case 2166:
+	case 2389:
 		sqlDollar = sqlS[sqlpt-0 : sqlpt+1]
-//line sql-gen.y:12862
+//line sql-gen.y:14065
 		{
 			sqlVAL.union.val = tree.CTEMaterializeDefault
 		}
-	case 2167:
+	case 2390:
 		sqlDollar = sqlS[sqlpt-7 : sqlpt+1]
-//line sql-gen.y:12868
+//line sql-gen.y:14071
 		{
 			sqlVAL.union.val = &tree.CTE{
 				Name: tree.AliasClause{Alias: tree.Name(sqlDollar[1].str), Cols: sqlDollar[2].union.colDefList()},
@@ -42464,202 +46345,202 @@ sqldefault:
 				Stmt: sqlDollar[6].union.stmt(),
 			}
 		}
-	case 2168:
+	case 2391:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:12877
+//line sql-gen.y:14080
 		{
 		}
-	case 2169:
+	case 2392:
 		sqlDollar = sqlS[sqlpt-0 : sqlpt+1]
-//line sql-gen.y:12878
+//line sql-gen.y:14081
 		{
 		}
-	case 2170:
+	case 2393:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:12882
+//line sql-gen.y:14085
 		{
 			sqlVAL.union.val = sqlDollar[1].union.with()
 		}
-	case 2171:
+	case 2394:
 		sqlDollar = sqlS[sqlpt-0 : sqlpt+1]
-//line sql-gen.y:12886
+//line sql-gen.y:14089
 		{
 			sqlVAL.union.val = nil
 		}
-	case 2172:
+	case 2395:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:12891
+//line sql-gen.y:14094
 		{
 		}
-	case 2173:
+	case 2396:
 		sqlDollar = sqlS[sqlpt-0 : sqlpt+1]
-//line sql-gen.y:12892
+//line sql-gen.y:14095
 		{
 		}
-	case 2174:
+	case 2397:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:12896
+//line sql-gen.y:14099
 		{
 			sqlVAL.union.val = true
 		}
-	case 2175:
+	case 2398:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:12900
+//line sql-gen.y:14103
 		{
 			sqlVAL.union.val = false
 		}
-	case 2176:
+	case 2399:
 		sqlDollar = sqlS[sqlpt-0 : sqlpt+1]
-//line sql-gen.y:12904
+//line sql-gen.y:14107
 		{
 			sqlVAL.union.val = false
 		}
-	case 2177:
+	case 2400:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:12910
+//line sql-gen.y:14113
 		{
 			sqlVAL.union.val = true
 		}
-	case 2178:
+	case 2401:
 		sqlDollar = sqlS[sqlpt-5 : sqlpt+1]
-//line sql-gen.y:12916
+//line sql-gen.y:14119
 		{
 			sqlVAL.union.val = tree.DistinctOn(sqlDollar[4].union.exprs())
 		}
-	case 2179:
+	case 2402:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:12921
+//line sql-gen.y:14124
 		{
 		}
-	case 2180:
+	case 2403:
 		sqlDollar = sqlS[sqlpt-0 : sqlpt+1]
-//line sql-gen.y:12922
+//line sql-gen.y:14125
 		{
 		}
-	case 2181:
+	case 2404:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:12925
+//line sql-gen.y:14128
 		{
 		}
-	case 2182:
+	case 2405:
 		sqlDollar = sqlS[sqlpt-0 : sqlpt+1]
-//line sql-gen.y:12926
+//line sql-gen.y:14129
 		{
 		}
-	case 2183:
+	case 2406:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:12930
+//line sql-gen.y:14133
 		{
 			sqlVAL.union.val = sqlDollar[1].union.orderBy()
 		}
-	case 2184:
+	case 2407:
 		sqlDollar = sqlS[sqlpt-0 : sqlpt+1]
-//line sql-gen.y:12934
+//line sql-gen.y:14137
 		{
 			sqlVAL.union.val = tree.OrderBy(nil)
 		}
-	case 2185:
+	case 2408:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:12940
+//line sql-gen.y:14143
 		{
 			sqlVAL.union.val = sqlDollar[1].union.orderBy()
 		}
-	case 2186:
+	case 2409:
 		sqlDollar = sqlS[sqlpt-0 : sqlpt+1]
-//line sql-gen.y:12944
+//line sql-gen.y:14147
 		{
 			sqlVAL.union.val = tree.OrderBy(nil)
 		}
-	case 2187:
+	case 2410:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:12950
+//line sql-gen.y:14153
 		{
 			sqlVAL.union.val = tree.OrderBy(sqlDollar[3].union.orders())
 		}
-	case 2188:
+	case 2411:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:12956
+//line sql-gen.y:14159
 		{
 			sqlVAL.union.val = tree.OrderBy(sqlDollar[3].union.orders())
 		}
-	case 2189:
+	case 2412:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:12962
+//line sql-gen.y:14165
 		{
 			sqlVAL.union.val = tree.OrderBy([]*tree.Order{sqlDollar[3].union.order()})
 		}
-	case 2190:
+	case 2413:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:12966
+//line sql-gen.y:14169
 		{
 			return unimplementedWithIssueDetail(sqllex, 109847, "order by index")
 		}
-	case 2191:
+	case 2414:
 		sqlDollar = sqlS[sqlpt-5 : sqlpt+1]
-//line sql-gen.y:12970
+//line sql-gen.y:14173
 		{
 			sqllex.Error("multiple ORDER BY clauses are not supported in this function")
 			return 1
 		}
-	case 2192:
+	case 2415:
 		sqlDollar = sqlS[sqlpt-5 : sqlpt+1]
-//line sql-gen.y:12975
+//line sql-gen.y:14178
 		{
 			sqllex.Error("multiple ORDER BY clauses are not supported in this function")
 			return 1
 		}
-	case 2193:
+	case 2416:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:12982
+//line sql-gen.y:14185
 		{
 			sqlVAL.union.val = []*tree.Order{sqlDollar[1].union.order()}
 		}
-	case 2194:
+	case 2417:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:12986
+//line sql-gen.y:14189
 		{
 			sqlVAL.union.val = []*tree.Order{sqlDollar[1].union.order()}
 		}
-	case 2195:
+	case 2418:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:12990
+//line sql-gen.y:14193
 		{
 			sqlVAL.union.val = append(sqlDollar[1].union.orders(), sqlDollar[3].union.order())
 		}
-	case 2196:
+	case 2419:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:12994
+//line sql-gen.y:14197
 		{
 			sqlVAL.union.val = append(sqlDollar[1].union.orders(), sqlDollar[3].union.order())
 		}
-	case 2197:
+	case 2420:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:13000
+//line sql-gen.y:14203
 		{
 			sqlVAL.union.val = []*tree.Order{sqlDollar[1].union.order()}
 		}
-	case 2198:
+	case 2421:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:13004
+//line sql-gen.y:14207
 		{
 			sqlVAL.union.val = append(sqlDollar[1].union.orders(), sqlDollar[3].union.order())
 		}
-	case 2199:
+	case 2422:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:13008
+//line sql-gen.y:14211
 		{
 			sqlVAL.union.val = append(sqlDollar[1].union.orders(), sqlDollar[3].union.order())
 		}
-	case 2200:
+	case 2423:
 		sqlDollar = sqlS[sqlpt-4 : sqlpt+1]
-//line sql-gen.y:13014
+//line sql-gen.y:14217
 		{
 			name := sqlDollar[3].union.unresolvedObjectName().ToTableName()
 			sqlVAL.union.val = &tree.Order{OrderType: tree.OrderByIndex, Direction: sqlDollar[4].union.dir(), Table: name}
 		}
-	case 2201:
+	case 2424:
 		sqlDollar = sqlS[sqlpt-5 : sqlpt+1]
-//line sql-gen.y:13019
+//line sql-gen.y:14222
 		{
 			name := sqlDollar[2].union.unresolvedObjectName().ToTableName()
 			sqlVAL.union.val = &tree.Order{
@@ -42669,9 +46550,9 @@ sqldefault:
 				Index:     tree.UnrestrictedName(sqlDollar[4].str),
 			}
 		}
-	case 2202:
+	case 2425:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:13031
+//line sql-gen.y:14234
 		{
 
 			dir := sqlDollar[2].union.dir()
@@ -42683,27 +46564,27 @@ sqldefault:
 				NullsOrder: nullsOrder,
 			}
 		}
-	case 2203:
+	case 2426:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:13045
+//line sql-gen.y:14248
 		{
 			sqlVAL.union.val = tree.NullsFirst
 		}
-	case 2204:
+	case 2427:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:13049
+//line sql-gen.y:14252
 		{
 			sqlVAL.union.val = tree.NullsLast
 		}
-	case 2205:
+	case 2428:
 		sqlDollar = sqlS[sqlpt-0 : sqlpt+1]
-//line sql-gen.y:13053
+//line sql-gen.y:14256
 		{
 			sqlVAL.union.val = tree.DefaultNullsOrder
 		}
-	case 2206:
+	case 2429:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:13059
+//line sql-gen.y:14262
 		{
 			if sqlDollar[1].union.limit() == nil {
 				sqlVAL.union.val = sqlDollar[2].union.limit()
@@ -42712,9 +46593,9 @@ sqldefault:
 				sqlVAL.union.val.(*tree.Limit).Offset = sqlDollar[2].union.limit().Offset
 			}
 		}
-	case 2207:
+	case 2430:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:13068
+//line sql-gen.y:14271
 		{
 			sqlVAL.union.val = sqlDollar[1].union.limit()
 			if sqlDollar[2].union.limit() != nil {
@@ -42722,33 +46603,33 @@ sqldefault:
 				sqlVAL.union.val.(*tree.Limit).LimitAll = sqlDollar[2].union.limit().LimitAll
 			}
 		}
-	case 2210:
+	case 2433:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:13079
+//line sql-gen.y:14282
 		{
 			sqlVAL.union.val = sqlDollar[1].union.limit()
 		}
-	case 2211:
+	case 2434:
 		sqlDollar = sqlS[sqlpt-0 : sqlpt+1]
-//line sql-gen.y:13080
+//line sql-gen.y:14283
 		{
 			sqlVAL.union.val = (*tree.Limit)(nil)
 		}
-	case 2213:
+	case 2436:
 		sqlDollar = sqlS[sqlpt-0 : sqlpt+1]
-//line sql-gen.y:13084
+//line sql-gen.y:14287
 		{
 			sqlVAL.union.val = (*tree.Limit)(nil)
 		}
-	case 2214:
+	case 2437:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:13088
+//line sql-gen.y:14291
 		{
 			sqlVAL.union.val = &tree.Limit{LimitAll: true}
 		}
-	case 2215:
+	case 2438:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:13092
+//line sql-gen.y:14295
 		{
 			if sqlDollar[2].union.expr() == nil {
 				sqlVAL.union.val = (*tree.Limit)(nil)
@@ -42756,250 +46637,263 @@ sqldefault:
 				sqlVAL.union.val = &tree.Limit{Count: sqlDollar[2].union.expr()}
 			}
 		}
-	case 2216:
+	case 2439:
 		sqlDollar = sqlS[sqlpt-5 : sqlpt+1]
-//line sql-gen.y:13106
+//line sql-gen.y:14309
 		{
 			sqlVAL.union.val = &tree.Limit{Count: sqlDollar[3].union.expr()}
 		}
-	case 2217:
+	case 2440:
 		sqlDollar = sqlS[sqlpt-4 : sqlpt+1]
-//line sql-gen.y:13110
+//line sql-gen.y:14313
 		{
 			sqlVAL.union.val = &tree.Limit{
 				Count: tree.NewNumVal(constant.MakeInt64(1), "", false),
 			}
 		}
-	case 2218:
+	case 2441:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:13118
+//line sql-gen.y:14321
 		{
 			sqlVAL.union.val = &tree.Limit{Offset: sqlDollar[2].union.expr()}
 		}
-	case 2219:
+	case 2442:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:13125
+//line sql-gen.y:14328
 		{
 			sqlVAL.union.val = &tree.Limit{Offset: sqlDollar[2].union.expr()}
 		}
-	case 2223:
+	case 2446:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:13147
+//line sql-gen.y:14350
 		{
 		}
-	case 2224:
+	case 2447:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:13148
+//line sql-gen.y:14351
 		{
 		}
-	case 2225:
+	case 2448:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:13151
+//line sql-gen.y:14354
 		{
 		}
-	case 2226:
+	case 2449:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:13152
+//line sql-gen.y:14355
 		{
 		}
-	case 2227:
+	case 2450:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:13169
+//line sql-gen.y:14372
 		{
 			sqlVAL.union.val = tree.GroupBy(sqlDollar[3].union.exprs())
 		}
-	case 2228:
+	case 2451:
 		sqlDollar = sqlS[sqlpt-0 : sqlpt+1]
-//line sql-gen.y:13173
+//line sql-gen.y:14376
 		{
 			sqlVAL.union.val = tree.GroupBy(nil)
 		}
-	case 2229:
+	case 2452:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:13178
+//line sql-gen.y:14381
 		{
 			sqlVAL.union.val = tree.Exprs{sqlDollar[1].union.expr()}
 		}
-	case 2230:
+	case 2453:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:13179
+//line sql-gen.y:14382
 		{
 			sqlVAL.union.val = append(sqlDollar[1].union.exprs(), sqlDollar[3].union.expr())
 		}
-	case 2231:
+	case 2454:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:13185
+//line sql-gen.y:14388
 		{
 			sqlVAL.union.val = sqlDollar[1].union.expr()
 		}
-	case 2232:
+	case 2455:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:13186
+//line sql-gen.y:14389
 		{
 			return unimplementedWithIssueDetail(sqllex, 46280, "rollup")
 		}
-	case 2233:
+	case 2456:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:13187
+//line sql-gen.y:14390
 		{
 			return unimplementedWithIssueDetail(sqllex, 46280, "cube")
 		}
-	case 2234:
+	case 2457:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:13188
+//line sql-gen.y:14391
 		{
 			return unimplementedWithIssueDetail(sqllex, 46280, "grouping sets")
 		}
-	case 2235:
+	case 2458:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:13192
+//line sql-gen.y:14395
 		{
 			sqlVAL.union.val = sqlDollar[2].union.expr()
 		}
-	case 2236:
+	case 2459:
 		sqlDollar = sqlS[sqlpt-0 : sqlpt+1]
-//line sql-gen.y:13196
+//line sql-gen.y:14399
 		{
 			sqlVAL.union.val = tree.Expr(nil)
 		}
-	case 2237:
+	case 2460:
 		sqlDollar = sqlS[sqlpt-4 : sqlpt+1]
-//line sql-gen.y:13215
+//line sql-gen.y:14418
 		{
 			sqlVAL.union.val = &tree.ValuesClause{Rows: []tree.Exprs{sqlDollar[3].union.exprs()}}
 		}
-	case 2238:
+	case 2461:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:13218
+//line sql-gen.y:14421
 		{
 			return helpWith(sqllex, "VALUES")
 		}
-	case 2239:
+	case 2462:
 		sqlDollar = sqlS[sqlpt-5 : sqlpt+1]
-//line sql-gen.y:13220
+//line sql-gen.y:14423
 		{
 			valNode := sqlDollar[1].union.selectStmt().(*tree.ValuesClause)
 			valNode.Rows = append(valNode.Rows, sqlDollar[4].union.exprs())
 			sqlVAL.union.val = valNode
 		}
-	case 2240:
+	case 2463:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:13232
+//line sql-gen.y:14435
 		{
 			sqlVAL.union.val = tree.From{Tables: sqlDollar[2].union.tblExprs(), AsOf: sqlDollar[3].union.asOfClause()}
 		}
-	case 2241:
+	case 2464:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:13235
+//line sql-gen.y:14438
 		{
 			return helpWith(sqllex, "<SOURCE>")
 		}
-	case 2242:
+	case 2465:
 		sqlDollar = sqlS[sqlpt-0 : sqlpt+1]
-//line sql-gen.y:13237
+//line sql-gen.y:14440
 		{
 			sqlVAL.union.val = tree.From{}
 		}
-	case 2243:
+	case 2466:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:13243
+//line sql-gen.y:14446
 		{
 			sqlVAL.union.val = tree.TableExprs{sqlDollar[1].union.tblExpr()}
 		}
-	case 2244:
+	case 2467:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:13247
+//line sql-gen.y:14450
 		{
 			sqlVAL.union.val = append(sqlDollar[1].union.tblExprs(), sqlDollar[3].union.tblExpr())
 		}
-	case 2245:
+	case 2468:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:13253
+//line sql-gen.y:14456
 		{
 			sqlVAL.union.val = &tree.IndexFlags{Index: tree.UnrestrictedName(sqlDollar[3].str)}
 		}
-	case 2246:
+	case 2469:
 		sqlDollar = sqlS[sqlpt-5 : sqlpt+1]
-//line sql-gen.y:13257
+//line sql-gen.y:14460
 		{
 
 			sqlVAL.union.val = &tree.IndexFlags{IndexID: tree.IndexID(sqlDollar[4].union.int64())}
 		}
-	case 2247:
+	case 2470:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:13262
+//line sql-gen.y:14465
 		{
 
 			sqlVAL.union.val = &tree.IndexFlags{Direction: tree.Ascending}
 		}
-	case 2248:
+	case 2471:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:13267
+//line sql-gen.y:14470
 		{
 
 			sqlVAL.union.val = &tree.IndexFlags{Direction: tree.Descending}
 		}
-	case 2249:
+	case 2472:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:13273
+//line sql-gen.y:14476
 		{
 			sqlVAL.union.val = &tree.IndexFlags{NoIndexJoin: true}
 		}
-	case 2250:
+	case 2473:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:13278
+//line sql-gen.y:14480
 		{
 			sqlVAL.union.val = &tree.IndexFlags{NoZigzagJoin: true}
 		}
-	case 2251:
+	case 2474:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:13283
+//line sql-gen.y:14484
 		{
 			sqlVAL.union.val = &tree.IndexFlags{NoFullScan: true}
 		}
-	case 2252:
+	case 2475:
+		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
+//line sql-gen.y:14488
+		{
+			sqlVAL.union.val = &tree.IndexFlags{AvoidFullScan: true}
+		}
+	case 2476:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:13288
+//line sql-gen.y:14492
 		{
 
 			sqlVAL.union.val = &tree.IndexFlags{IgnoreForeignKeys: true}
 		}
-	case 2253:
+	case 2477:
+		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
+//line sql-gen.y:14497
+		{
+
+			sqlVAL.union.val = &tree.IndexFlags{ForceInvertedIndex: true}
+		}
+	case 2478:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:13294
+//line sql-gen.y:14502
 		{
 			sqlVAL.union.val = &tree.IndexFlags{ForceZigzag: true}
 		}
-	case 2254:
+	case 2479:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:13299
+//line sql-gen.y:14506
 		{
 			sqlVAL.union.val = &tree.IndexFlags{ZigzagIndexes: []tree.UnrestrictedName{tree.UnrestrictedName(sqlDollar[3].str)}}
 		}
-	case 2255:
+	case 2480:
 		sqlDollar = sqlS[sqlpt-5 : sqlpt+1]
-//line sql-gen.y:13304
+//line sql-gen.y:14510
 		{
 
 			sqlVAL.union.val = &tree.IndexFlags{ZigzagIndexIDs: []tree.IndexID{tree.IndexID(sqlDollar[4].union.int64())}}
 		}
-	case 2256:
+	case 2481:
 		sqlDollar = sqlS[sqlpt-5 : sqlpt+1]
-//line sql-gen.y:13309
+//line sql-gen.y:14515
 		{
 
 			id := tree.FamilyID(uint32(sqlDollar[4].union.int64()))
 			sqlVAL.union.val = &tree.IndexFlags{FamilyID: &id}
 		}
-	case 2257:
+	case 2482:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:13317
+//line sql-gen.y:14523
 		{
 			sqlVAL.union.val = sqlDollar[1].union.indexFlags()
 		}
-	case 2258:
+	case 2483:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:13322
+//line sql-gen.y:14528
 		{
 			a := sqlDollar[1].union.indexFlags()
 			b := sqlDollar[3].union.indexFlags()
@@ -43008,21 +46902,21 @@ sqldefault:
 			}
 			sqlVAL.union.val = a
 		}
-	case 2259:
+	case 2484:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:13333
+//line sql-gen.y:14539
 		{
 			sqlVAL.union.val = &tree.IndexFlags{Index: tree.UnrestrictedName(sqlDollar[2].str)}
 		}
-	case 2260:
+	case 2485:
 		sqlDollar = sqlS[sqlpt-4 : sqlpt+1]
-//line sql-gen.y:13337
+//line sql-gen.y:14543
 		{
 			sqlVAL.union.val = &tree.IndexFlags{IndexID: tree.IndexID(sqlDollar[3].union.int64())}
 		}
-	case 2261:
+	case 2486:
 		sqlDollar = sqlS[sqlpt-4 : sqlpt+1]
-//line sql-gen.y:13341
+//line sql-gen.y:14547
 		{
 			flags := sqlDollar[3].union.indexFlags()
 			if err := flags.Check(); err != nil {
@@ -43030,15 +46924,15 @@ sqldefault:
 			}
 			sqlVAL.union.val = flags
 		}
-	case 2262:
+	case 2487:
 		sqlDollar = sqlS[sqlpt-0 : sqlpt+1]
-//line sql-gen.y:13349
+//line sql-gen.y:14555
 		{
 			sqlVAL.union.val = (*tree.IndexFlags)(nil)
 		}
-	case 2263:
+	case 2488:
 		sqlDollar = sqlS[sqlpt-4 : sqlpt+1]
-//line sql-gen.y:13383
+//line sql-gen.y:14590
 		{
 
 			sqlVAL.union.val = &tree.AliasedTableExpr{
@@ -43048,9 +46942,9 @@ sqldefault:
 				As:         sqlDollar[4].union.aliasClause(),
 			}
 		}
-	case 2264:
+	case 2489:
 		sqlDollar = sqlS[sqlpt-4 : sqlpt+1]
-//line sql-gen.y:13393
+//line sql-gen.y:14600
 		{
 			name := sqlDollar[1].union.unresolvedObjectName().ToTableName()
 			sqlVAL.union.val = &tree.AliasedTableExpr{
@@ -43060,9 +46954,9 @@ sqldefault:
 				As:         sqlDollar[4].union.aliasClause(),
 			}
 		}
-	case 2265:
+	case 2490:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:13403
+//line sql-gen.y:14610
 		{
 			sqlVAL.union.val = &tree.AliasedTableExpr{
 				Expr:       &tree.Subquery{Select: sqlDollar[1].union.selectStmt()},
@@ -43070,9 +46964,9 @@ sqldefault:
 				As:         sqlDollar[3].union.aliasClause(),
 			}
 		}
-	case 2266:
+	case 2491:
 		sqlDollar = sqlS[sqlpt-4 : sqlpt+1]
-//line sql-gen.y:13411
+//line sql-gen.y:14618
 		{
 			sqlVAL.union.val = &tree.AliasedTableExpr{
 				Expr:       &tree.Subquery{Select: sqlDollar[2].union.selectStmt()},
@@ -43081,21 +46975,21 @@ sqldefault:
 				As:         sqlDollar[4].union.aliasClause(),
 			}
 		}
-	case 2267:
+	case 2492:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:13420
+//line sql-gen.y:14627
 		{
 			sqlVAL.union.val = sqlDollar[1].union.tblExpr()
 		}
-	case 2268:
+	case 2493:
 		sqlDollar = sqlS[sqlpt-5 : sqlpt+1]
-//line sql-gen.y:13424
+//line sql-gen.y:14631
 		{
 			sqlVAL.union.val = &tree.AliasedTableExpr{Expr: &tree.ParenTableExpr{Expr: sqlDollar[2].union.tblExpr()}, Ordinality: sqlDollar[4].union.bool(), As: sqlDollar[5].union.aliasClause()}
 		}
-	case 2269:
+	case 2494:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:13428
+//line sql-gen.y:14635
 		{
 			f := sqlDollar[1].union.tblExpr()
 			sqlVAL.union.val = &tree.AliasedTableExpr{
@@ -43105,9 +46999,9 @@ sqldefault:
 				As: sqlDollar[3].union.aliasClause(),
 			}
 		}
-	case 2270:
+	case 2495:
 		sqlDollar = sqlS[sqlpt-4 : sqlpt+1]
-//line sql-gen.y:13439
+//line sql-gen.y:14646
 		{
 			f := sqlDollar[2].union.tblExpr()
 			sqlVAL.union.val = &tree.AliasedTableExpr{
@@ -43117,15 +47011,15 @@ sqldefault:
 				As:         sqlDollar[4].union.aliasClause(),
 			}
 		}
-	case 2271:
+	case 2496:
 		sqlDollar = sqlS[sqlpt-5 : sqlpt+1]
-//line sql-gen.y:13463
+//line sql-gen.y:14670
 		{
 			sqlVAL.union.val = &tree.AliasedTableExpr{Expr: &tree.StatementSource{Statement: sqlDollar[2].union.stmt()}, Ordinality: sqlDollar[4].union.bool(), As: sqlDollar[5].union.aliasClause()}
 		}
-	case 2272:
+	case 2497:
 		sqlDollar = sqlS[sqlpt-5 : sqlpt+1]
-//line sql-gen.y:13469
+//line sql-gen.y:14676
 		{
 
 			sqlVAL.union.val = &tree.TableRef{
@@ -43134,373 +47028,379 @@ sqldefault:
 				As:      sqlDollar[4].union.aliasClause(),
 			}
 		}
-	case 2273:
+	case 2498:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:13480
+//line sql-gen.y:14687
 		{
 			sqlVAL.union.val = &tree.RowsFromExpr{Items: tree.Exprs{sqlDollar[1].union.expr()}}
 		}
-	case 2274:
+	case 2499:
 		sqlDollar = sqlS[sqlpt-5 : sqlpt+1]
-//line sql-gen.y:13484
+//line sql-gen.y:14691
 		{
 			sqlVAL.union.val = &tree.RowsFromExpr{Items: sqlDollar[4].union.exprs()}
 		}
-	case 2275:
+	case 2500:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:13490
+//line sql-gen.y:14697
 		{
 			sqlVAL.union.val = tree.Exprs{sqlDollar[1].union.expr()}
 		}
-	case 2276:
+	case 2501:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:13492
+//line sql-gen.y:14699
 		{
 			sqlVAL.union.val = append(sqlDollar[1].union.exprs(), sqlDollar[3].union.expr())
 		}
-	case 2277:
+	case 2502:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:13496
+//line sql-gen.y:14703
 		{
 			sqlVAL.union.val = sqlDollar[1].union.expr()
 		}
-	case 2278:
+	case 2503:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:13502
+//line sql-gen.y:14709
 		{
 			sqlVAL.union.val = sqlDollar[2].union.colDefList()
 		}
-	case 2279:
+	case 2504:
 		sqlDollar = sqlS[sqlpt-0 : sqlpt+1]
-//line sql-gen.y:13506
+//line sql-gen.y:14713
 		{
 			sqlVAL.union.val = tree.ColumnDefList(nil)
 		}
-	case 2280:
+	case 2505:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:13512
+//line sql-gen.y:14719
 		{
 			sqlVAL.union.val = tree.ColumnDefList{tree.ColumnDef{Name: tree.Name(sqlDollar[1].str)}}
 		}
-	case 2281:
+	case 2506:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:13516
+//line sql-gen.y:14723
 		{
 			sqlVAL.union.val = append(sqlDollar[1].union.colDefList(), tree.ColumnDef{Name: tree.Name(sqlDollar[3].str)})
 		}
-	case 2282:
+	case 2507:
 		sqlDollar = sqlS[sqlpt-0 : sqlpt+1]
-//line sql-gen.y:13523
+//line sql-gen.y:14730
 		{
 			sqlVAL.union.val = tree.ColumnDefList(nil)
 		}
-	case 2283:
+	case 2508:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:13527
+//line sql-gen.y:14734
 		{
 			sqlVAL.union.val = sqlDollar[2].union.colDefList()
 		}
-	case 2284:
+	case 2509:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:13533
+//line sql-gen.y:14740
 		{
 			sqlVAL.union.val = tree.ColumnDefList{sqlDollar[1].union.colDef()}
 		}
-	case 2285:
+	case 2510:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:13537
+//line sql-gen.y:14744
 		{
 			sqlVAL.union.val = append(sqlDollar[1].union.colDefList(), sqlDollar[3].union.colDef())
 		}
-	case 2286:
+	case 2511:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:13543
+//line sql-gen.y:14750
 		{
 			sqlVAL.union.val = tree.ColumnDef{Name: tree.Name(sqlDollar[1].str)}
 		}
-	case 2287:
+	case 2512:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:13547
+//line sql-gen.y:14754
 		{
 			sqlVAL.union.val = tree.ColumnDef{Name: tree.Name(sqlDollar[1].str), Type: sqlDollar[2].union.typeReference()}
 		}
-	case 2288:
+	case 2513:
 		sqlDollar = sqlS[sqlpt-0 : sqlpt+1]
-//line sql-gen.y:13552
+//line sql-gen.y:14759
 		{
 			sqlVAL.union.val = nil
 		}
-	case 2289:
+	case 2514:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:13553
+//line sql-gen.y:14760
 		{
 			sqlVAL.union.val = []tree.ColumnID{}
 		}
-	case 2290:
+	case 2515:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:13554
+//line sql-gen.y:14761
 		{
 			sqlVAL.union.val = sqlDollar[2].union.tableRefCols()
 		}
-	case 2291:
+	case 2516:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:13558
+//line sql-gen.y:14765
 		{
 			sqlVAL.union.val = []tree.ColumnID{tree.ColumnID(sqlDollar[1].union.int64())}
 		}
-	case 2292:
+	case 2517:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:13562
+//line sql-gen.y:14769
 		{
 			sqlVAL.union.val = append(sqlDollar[1].union.tableRefCols(), tree.ColumnID(sqlDollar[3].union.int64()))
 		}
-	case 2293:
+	case 2518:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:13568
+//line sql-gen.y:14775
 		{
 			sqlVAL.union.val = true
 		}
-	case 2294:
+	case 2519:
 		sqlDollar = sqlS[sqlpt-0 : sqlpt+1]
-//line sql-gen.y:13572
+//line sql-gen.y:14779
 		{
 			sqlVAL.union.val = false
 		}
-	case 2295:
+	case 2520:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:13592
+//line sql-gen.y:14799
 		{
 			sqlVAL.union.val = &tree.ParenTableExpr{Expr: sqlDollar[2].union.tblExpr()}
 		}
-	case 2296:
+	case 2521:
 		sqlDollar = sqlS[sqlpt-5 : sqlpt+1]
-//line sql-gen.y:13596
+//line sql-gen.y:14803
 		{
 			sqlVAL.union.val = &tree.JoinTableExpr{JoinType: tree.AstCross, Left: sqlDollar[1].union.tblExpr(), Right: sqlDollar[5].union.tblExpr(), Hint: sqlDollar[3].str}
 		}
-	case 2297:
+	case 2522:
 		sqlDollar = sqlS[sqlpt-6 : sqlpt+1]
-//line sql-gen.y:13600
+//line sql-gen.y:14807
 		{
 			sqlVAL.union.val = &tree.JoinTableExpr{JoinType: sqlDollar[2].str, Left: sqlDollar[1].union.tblExpr(), Right: sqlDollar[5].union.tblExpr(), Cond: sqlDollar[6].union.joinCond(), Hint: sqlDollar[3].str}
 		}
-	case 2298:
+	case 2523:
 		sqlDollar = sqlS[sqlpt-4 : sqlpt+1]
-//line sql-gen.y:13604
+//line sql-gen.y:14811
 		{
 			sqlVAL.union.val = &tree.JoinTableExpr{Left: sqlDollar[1].union.tblExpr(), Right: sqlDollar[3].union.tblExpr(), Cond: sqlDollar[4].union.joinCond()}
 		}
-	case 2299:
+	case 2524:
 		sqlDollar = sqlS[sqlpt-6 : sqlpt+1]
-//line sql-gen.y:13608
+//line sql-gen.y:14815
 		{
 			sqlVAL.union.val = &tree.JoinTableExpr{JoinType: sqlDollar[3].str, Left: sqlDollar[1].union.tblExpr(), Right: sqlDollar[6].union.tblExpr(), Cond: tree.NaturalJoinCond{}, Hint: sqlDollar[4].str}
 		}
-	case 2300:
+	case 2525:
 		sqlDollar = sqlS[sqlpt-4 : sqlpt+1]
-//line sql-gen.y:13612
+//line sql-gen.y:14819
 		{
 			sqlVAL.union.val = &tree.JoinTableExpr{Left: sqlDollar[1].union.tblExpr(), Right: sqlDollar[4].union.tblExpr(), Cond: tree.NaturalJoinCond{}}
 		}
-	case 2301:
+	case 2526:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:13618
+//line sql-gen.y:14825
 		{
 			sqlVAL.union.val = tree.AliasClause{Alias: tree.Name(sqlDollar[2].str), Cols: sqlDollar[3].union.colDefList()}
 		}
-	case 2302:
+	case 2527:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:13622
+//line sql-gen.y:14829
 		{
 			sqlVAL.union.val = tree.AliasClause{Alias: tree.Name(sqlDollar[1].str), Cols: sqlDollar[2].union.colDefList()}
 		}
-	case 2304:
+	case 2529:
 		sqlDollar = sqlS[sqlpt-0 : sqlpt+1]
-//line sql-gen.y:13629
+//line sql-gen.y:14836
 		{
 			sqlVAL.union.val = tree.AliasClause{}
 		}
-	case 2305:
+	case 2530:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:13635
+//line sql-gen.y:14842
 		{
 			sqlVAL.union.val = tree.AliasClause{Alias: tree.Name(sqlDollar[2].str), Cols: sqlDollar[3].union.colDefList()}
 		}
-	case 2306:
+	case 2531:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:13639
+//line sql-gen.y:14846
 		{
 			sqlVAL.union.val = tree.AliasClause{Alias: tree.Name(sqlDollar[1].str), Cols: sqlDollar[2].union.colDefList()}
 		}
-	case 2308:
+	case 2533:
 		sqlDollar = sqlS[sqlpt-0 : sqlpt+1]
-//line sql-gen.y:13646
+//line sql-gen.y:14853
 		{
 			sqlVAL.union.val = tree.AliasClause{}
 		}
-	case 2309:
+	case 2534:
 		sqlDollar = sqlS[sqlpt-5 : sqlpt+1]
-//line sql-gen.y:13652
+//line sql-gen.y:14859
 		{
 			sqlVAL.union.val = tree.AsOfClause{Expr: sqlDollar[5].union.expr()}
 		}
-	case 2311:
+	case 2536:
 		sqlDollar = sqlS[sqlpt-0 : sqlpt+1]
-//line sql-gen.y:13659
+//line sql-gen.y:14866
 		{
 			sqlVAL.union.val = tree.AsOfClause{}
 		}
-	case 2312:
+	case 2537:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:13665
+//line sql-gen.y:14872
 		{
 			sqlVAL.str = tree.AstFull
 		}
-	case 2313:
+	case 2538:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:13669
+//line sql-gen.y:14876
 		{
 			sqlVAL.str = tree.AstLeft
 		}
-	case 2314:
+	case 2539:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:13673
+//line sql-gen.y:14880
 		{
 			sqlVAL.str = tree.AstRight
 		}
-	case 2315:
+	case 2540:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:13677
+//line sql-gen.y:14884
 		{
 			sqlVAL.str = tree.AstInner
 		}
-	case 2316:
+	case 2541:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:13683
+//line sql-gen.y:14890
 		{
 		}
-	case 2317:
+	case 2542:
 		sqlDollar = sqlS[sqlpt-0 : sqlpt+1]
-//line sql-gen.y:13684
+//line sql-gen.y:14891
 		{
 		}
-	case 2318:
+	case 2543:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:13708
+//line sql-gen.y:14916
 		{
 			sqlVAL.str = tree.AstHash
 		}
-	case 2319:
+	case 2544:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:13712
+//line sql-gen.y:14920
 		{
 			sqlVAL.str = tree.AstMerge
 		}
-	case 2320:
+	case 2545:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:13716
+//line sql-gen.y:14924
 		{
 			sqlVAL.str = tree.AstLookup
 		}
-	case 2321:
+	case 2546:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:13720
+//line sql-gen.y:14928
 		{
 			sqlVAL.str = tree.AstInverted
 		}
-	case 2322:
+	case 2547:
+		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
+//line sql-gen.y:14932
+		{
+			sqlVAL.str = tree.AstStraight
+		}
+	case 2548:
 		sqlDollar = sqlS[sqlpt-0 : sqlpt+1]
-//line sql-gen.y:13724
+//line sql-gen.y:14936
 		{
 			sqlVAL.str = ""
 		}
-	case 2323:
+	case 2549:
 		sqlDollar = sqlS[sqlpt-4 : sqlpt+1]
-//line sql-gen.y:13737
+//line sql-gen.y:14949
 		{
 			sqlVAL.union.val = &tree.UsingJoinCond{Cols: sqlDollar[3].union.nameList()}
 		}
-	case 2324:
+	case 2550:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:13741
+//line sql-gen.y:14953
 		{
 			sqlVAL.union.val = &tree.OnJoinCond{Expr: sqlDollar[2].union.expr()}
 		}
-	case 2325:
+	case 2551:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:13746
+//line sql-gen.y:14958
 		{
 			sqlVAL.union.val = sqlDollar[1].union.unresolvedObjectName()
 		}
-	case 2326:
+	case 2552:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:13747
+//line sql-gen.y:14959
 		{
 			sqlVAL.union.val = sqlDollar[1].union.unresolvedObjectName()
 		}
-	case 2327:
+	case 2553:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:13748
+//line sql-gen.y:14960
 		{
 			sqlVAL.union.val = sqlDollar[2].union.unresolvedObjectName()
 		}
-	case 2328:
+	case 2554:
 		sqlDollar = sqlS[sqlpt-4 : sqlpt+1]
-//line sql-gen.y:13749
+//line sql-gen.y:14961
 		{
 			sqlVAL.union.val = sqlDollar[3].union.unresolvedObjectName()
 		}
-	case 2329:
+	case 2555:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:13753
+//line sql-gen.y:14965
 		{
 			name := sqlDollar[1].union.unresolvedObjectName().ToTableName()
 			sqlVAL.union.val = tree.TableNames{name}
 		}
-	case 2330:
+	case 2556:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:13758
+//line sql-gen.y:14970
 		{
 			name := sqlDollar[3].union.unresolvedObjectName().ToTableName()
 			sqlVAL.union.val = append(sqlDollar[1].union.tableNames(), name)
 		}
-	case 2331:
+	case 2557:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:13766
+//line sql-gen.y:14978
 		{
 			sqlVAL.union.val = &tree.Unlisten{ChannelName: sqlDollar[2].union.unresolvedObjectName(), Star: false}
 		}
-	case 2332:
+	case 2558:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:13770
+//line sql-gen.y:14982
 		{
 			sqlVAL.union.val = &tree.Unlisten{ChannelName: nil, Star: true}
 		}
-	case 2333:
+	case 2559:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:13784
+//line sql-gen.y:14996
 		{
 			sqlVAL.union.val = sqlDollar[1].union.tblExpr()
 		}
-	case 2334:
+	case 2560:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:13788
+//line sql-gen.y:15000
 		{
 			alias := sqlDollar[1].union.tblExpr().(*tree.AliasedTableExpr)
 			alias.As = tree.AliasClause{Alias: tree.Name(sqlDollar[2].str)}
 			sqlVAL.union.val = alias
 		}
-	case 2335:
+	case 2561:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:13794
+//line sql-gen.y:15006
 		{
 			alias := sqlDollar[1].union.tblExpr().(*tree.AliasedTableExpr)
 			alias.As = tree.AliasClause{Alias: tree.Name(sqlDollar[3].str)}
 			sqlVAL.union.val = alias
 		}
-	case 2336:
+	case 2562:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:13800
+//line sql-gen.y:15012
 		{
 
 			sqlVAL.union.val = &tree.AliasedTableExpr{
@@ -43508,9 +47408,9 @@ sqldefault:
 				IndexFlags: sqlDollar[2].union.indexFlags(),
 			}
 		}
-	case 2337:
+	case 2563:
 		sqlDollar = sqlS[sqlpt-4 : sqlpt+1]
-//line sql-gen.y:13810
+//line sql-gen.y:15022
 		{
 			name := sqlDollar[2].union.unresolvedObjectName().ToTableName()
 			sqlVAL.union.val = &tree.AliasedTableExpr{
@@ -43518,45 +47418,45 @@ sqldefault:
 				IndexFlags: sqlDollar[3].union.indexFlags(),
 			}
 		}
-	case 2338:
+	case 2564:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:13820
+//line sql-gen.y:15032
 		{
 			sqlVAL.union.val = true
 		}
-	case 2339:
+	case 2565:
 		sqlDollar = sqlS[sqlpt-0 : sqlpt+1]
-//line sql-gen.y:13824
+//line sql-gen.y:15036
 		{
 			sqlVAL.union.val = false
 		}
-	case 2340:
+	case 2566:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:13830
+//line sql-gen.y:15042
 		{
 			sqlVAL.union.val = true
 		}
-	case 2341:
+	case 2567:
 		sqlDollar = sqlS[sqlpt-0 : sqlpt+1]
-//line sql-gen.y:13834
+//line sql-gen.y:15046
 		{
 			sqlVAL.union.val = false
 		}
-	case 2342:
+	case 2568:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:13840
+//line sql-gen.y:15052
 		{
 			sqlVAL.union.val = sqlDollar[2].union.expr()
 		}
-	case 2344:
+	case 2570:
 		sqlDollar = sqlS[sqlpt-0 : sqlpt+1]
-//line sql-gen.y:13847
+//line sql-gen.y:15059
 		{
 			sqlVAL.union.val = tree.Expr(nil)
 		}
-	case 2345:
+	case 2571:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:13859
+//line sql-gen.y:15071
 		{
 			if bounds := sqlDollar[2].union.int32s(); bounds != nil {
 				var err error
@@ -43568,9 +47468,9 @@ sqldefault:
 				sqlVAL.union.val = sqlDollar[1].union.typeReference()
 			}
 		}
-	case 2346:
+	case 2572:
 		sqlDollar = sqlS[sqlpt-5 : sqlpt+1]
-//line sql-gen.y:13872
+//line sql-gen.y:15084
 		{
 
 			var err error
@@ -43579,15 +47479,15 @@ sqldefault:
 				return setErr(sqllex, err)
 			}
 		}
-	case 2347:
+	case 2573:
 		sqlDollar = sqlS[sqlpt-7 : sqlpt+1]
-//line sql-gen.y:13880
+//line sql-gen.y:15092
 		{
 			return unimplementedWithIssue(sqllex, 32552)
 		}
-	case 2348:
+	case 2574:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:13881
+//line sql-gen.y:15093
 		{
 			var err error
 			sqlVAL.union.val, err = arrayOf(sqlDollar[1].union.typeReference(), nil)
@@ -43595,27 +47495,27 @@ sqldefault:
 				return setErr(sqllex, err)
 			}
 		}
-	case 2349:
+	case 2575:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:13891
+//line sql-gen.y:15103
 		{
 			sqlVAL.union.val = sqlDollar[1].union.typeReference()
 		}
-	case 2350:
+	case 2576:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:13898
+//line sql-gen.y:15110
 		{
 			sqlVAL.union.val = []int32{-1}
 		}
-	case 2351:
+	case 2577:
 		sqlDollar = sqlS[sqlpt-4 : sqlpt+1]
-//line sql-gen.y:13899
+//line sql-gen.y:15111
 		{
 			return unimplementedWithIssue(sqllex, 32552)
 		}
-	case 2352:
+	case 2578:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:13901
+//line sql-gen.y:15113
 		{
 
 			bound, err := sqlDollar[2].union.numVal().AsInt32()
@@ -43624,21 +47524,21 @@ sqldefault:
 			}
 			sqlVAL.union.val = []int32{bound}
 		}
-	case 2353:
+	case 2579:
 		sqlDollar = sqlS[sqlpt-5 : sqlpt+1]
-//line sql-gen.y:13909
+//line sql-gen.y:15121
 		{
 			return unimplementedWithIssue(sqllex, 32552)
 		}
-	case 2354:
+	case 2580:
 		sqlDollar = sqlS[sqlpt-0 : sqlpt+1]
-//line sql-gen.y:13910
+//line sql-gen.y:15122
 		{
 			sqlVAL.union.val = []int32(nil)
 		}
-	case 2356:
+	case 2582:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:13922
+//line sql-gen.y:15134
 		{
 			aIdx := sqllex.(*lexer).NewAnnotation()
 			res, err := tree.NewUnresolvedObjectName(2, [3]string{sqlDollar[3].str, sqlDollar[1].str}, aIdx)
@@ -43647,9 +47547,9 @@ sqldefault:
 			}
 			sqlVAL.union.val = res
 		}
-	case 2357:
+	case 2583:
 		sqlDollar = sqlS[sqlpt-5 : sqlpt+1]
-//line sql-gen.y:13929
+//line sql-gen.y:15141
 		{
 			aIdx := sqllex.(*lexer).NewAnnotation()
 			res, err := tree.NewUnresolvedObjectName(3, [3]string{sqlDollar[5].str, sqlDollar[3].str, sqlDollar[1].str}, aIdx)
@@ -43658,9 +47558,9 @@ sqldefault:
 			}
 			sqlVAL.union.val = res
 		}
-	case 2358:
+	case 2584:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:13938
+//line sql-gen.y:15150
 		{
 
 			if sqlDollar[1].str == "char" {
@@ -43695,256 +47595,256 @@ sqldefault:
 				}
 			}
 		}
-	case 2359:
+	case 2585:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:13978
+//line sql-gen.y:15190
 		{
 			id := sqlDollar[2].union.int32()
 			sqlVAL.union.val = &tree.OIDTypeReference{OID: oid.Oid(id)}
 		}
-	case 2360:
+	case 2586:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:13983
+//line sql-gen.y:15195
 		{
 			sqlVAL.union.val = sqlDollar[1].union.typeReference()
 		}
-	case 2363:
+	case 2589:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:13988
+//line sql-gen.y:15200
 		{
 			return unimplementedWithIssueDetail(sqllex, 21286, "point")
 		}
-	case 2364:
+	case 2590:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:13989
+//line sql-gen.y:15201
 		{
 			return unimplementedWithIssueDetail(sqllex, 21286, "polygon")
 		}
-	case 2365:
+	case 2591:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:13992
+//line sql-gen.y:15204
 		{
 			sqlVAL.union.val = geopb.ShapeType_Point
 		}
-	case 2366:
+	case 2592:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:13993
+//line sql-gen.y:15205
 		{
 			sqlVAL.union.val = geopb.ShapeType_PointM
 		}
-	case 2367:
+	case 2593:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:13994
+//line sql-gen.y:15206
 		{
 			sqlVAL.union.val = geopb.ShapeType_PointZ
 		}
-	case 2368:
+	case 2594:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:13995
+//line sql-gen.y:15207
 		{
 			sqlVAL.union.val = geopb.ShapeType_PointZM
 		}
-	case 2369:
+	case 2595:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:13996
+//line sql-gen.y:15208
 		{
 			sqlVAL.union.val = geopb.ShapeType_LineString
 		}
-	case 2370:
+	case 2596:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:13997
+//line sql-gen.y:15209
 		{
 			sqlVAL.union.val = geopb.ShapeType_LineStringM
 		}
-	case 2371:
+	case 2597:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:13998
+//line sql-gen.y:15210
 		{
 			sqlVAL.union.val = geopb.ShapeType_LineStringZ
 		}
-	case 2372:
+	case 2598:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:13999
+//line sql-gen.y:15211
 		{
 			sqlVAL.union.val = geopb.ShapeType_LineStringZM
 		}
-	case 2373:
+	case 2599:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:14000
+//line sql-gen.y:15212
 		{
 			sqlVAL.union.val = geopb.ShapeType_Polygon
 		}
-	case 2374:
+	case 2600:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:14001
+//line sql-gen.y:15213
 		{
 			sqlVAL.union.val = geopb.ShapeType_PolygonM
 		}
-	case 2375:
+	case 2601:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:14002
+//line sql-gen.y:15214
 		{
 			sqlVAL.union.val = geopb.ShapeType_PolygonZ
 		}
-	case 2376:
+	case 2602:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:14003
+//line sql-gen.y:15215
 		{
 			sqlVAL.union.val = geopb.ShapeType_PolygonZM
 		}
-	case 2377:
+	case 2603:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:14004
+//line sql-gen.y:15216
 		{
 			sqlVAL.union.val = geopb.ShapeType_MultiPoint
 		}
-	case 2378:
+	case 2604:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:14005
+//line sql-gen.y:15217
 		{
 			sqlVAL.union.val = geopb.ShapeType_MultiPointM
 		}
-	case 2379:
+	case 2605:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:14006
+//line sql-gen.y:15218
 		{
 			sqlVAL.union.val = geopb.ShapeType_MultiPointZ
 		}
-	case 2380:
+	case 2606:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:14007
+//line sql-gen.y:15219
 		{
 			sqlVAL.union.val = geopb.ShapeType_MultiPointZM
 		}
-	case 2381:
+	case 2607:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:14008
+//line sql-gen.y:15220
 		{
 			sqlVAL.union.val = geopb.ShapeType_MultiLineString
 		}
-	case 2382:
+	case 2608:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:14009
+//line sql-gen.y:15221
 		{
 			sqlVAL.union.val = geopb.ShapeType_MultiLineStringM
 		}
-	case 2383:
+	case 2609:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:14010
+//line sql-gen.y:15222
 		{
 			sqlVAL.union.val = geopb.ShapeType_MultiLineStringZ
 		}
-	case 2384:
+	case 2610:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:14011
+//line sql-gen.y:15223
 		{
 			sqlVAL.union.val = geopb.ShapeType_MultiLineStringZM
 		}
-	case 2385:
+	case 2611:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:14012
+//line sql-gen.y:15224
 		{
 			sqlVAL.union.val = geopb.ShapeType_MultiPolygon
 		}
-	case 2386:
+	case 2612:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:14013
+//line sql-gen.y:15225
 		{
 			sqlVAL.union.val = geopb.ShapeType_MultiPolygonM
 		}
-	case 2387:
+	case 2613:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:14014
+//line sql-gen.y:15226
 		{
 			sqlVAL.union.val = geopb.ShapeType_MultiPolygonZ
 		}
-	case 2388:
+	case 2614:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:14015
+//line sql-gen.y:15227
 		{
 			sqlVAL.union.val = geopb.ShapeType_MultiPolygonZM
 		}
-	case 2389:
+	case 2615:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:14016
+//line sql-gen.y:15228
 		{
 			sqlVAL.union.val = geopb.ShapeType_GeometryCollection
 		}
-	case 2390:
+	case 2616:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:14017
+//line sql-gen.y:15229
 		{
 			sqlVAL.union.val = geopb.ShapeType_GeometryCollectionM
 		}
-	case 2391:
+	case 2617:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:14018
+//line sql-gen.y:15230
 		{
 			sqlVAL.union.val = geopb.ShapeType_GeometryCollectionZ
 		}
-	case 2392:
+	case 2618:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:14019
+//line sql-gen.y:15231
 		{
 			sqlVAL.union.val = geopb.ShapeType_GeometryCollectionZM
 		}
-	case 2393:
+	case 2619:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:14020
+//line sql-gen.y:15232
 		{
 			sqlVAL.union.val = geopb.ShapeType_Geometry
 		}
-	case 2394:
+	case 2620:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:14021
+//line sql-gen.y:15233
 		{
 			sqlVAL.union.val = geopb.ShapeType_GeometryM
 		}
-	case 2395:
+	case 2621:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:14022
+//line sql-gen.y:15234
 		{
 			sqlVAL.union.val = geopb.ShapeType_GeometryZ
 		}
-	case 2396:
+	case 2622:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:14023
+//line sql-gen.y:15235
 		{
 			sqlVAL.union.val = geopb.ShapeType_GeometryZM
 		}
-	case 2397:
+	case 2623:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:14026
+//line sql-gen.y:15238
 		{
 			sqlVAL.union.val = types.Geography
 		}
-	case 2398:
+	case 2624:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:14027
+//line sql-gen.y:15239
 		{
 			sqlVAL.union.val = types.Geometry
 		}
-	case 2399:
+	case 2625:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:14028
+//line sql-gen.y:15240
 		{
 			sqlVAL.union.val = types.Box2D
 		}
-	case 2400:
+	case 2626:
 		sqlDollar = sqlS[sqlpt-4 : sqlpt+1]
-//line sql-gen.y:14030
+//line sql-gen.y:15242
 		{
 			sqlVAL.union.val = types.MakeGeometry(sqlDollar[3].union.geoShapeType(), 0)
 		}
-	case 2401:
+	case 2627:
 		sqlDollar = sqlS[sqlpt-4 : sqlpt+1]
-//line sql-gen.y:14034
+//line sql-gen.y:15246
 		{
 			sqlVAL.union.val = types.MakeGeography(sqlDollar[3].union.geoShapeType(), 0)
 		}
-	case 2402:
+	case 2628:
 		sqlDollar = sqlS[sqlpt-6 : sqlpt+1]
-//line sql-gen.y:14038
+//line sql-gen.y:15250
 		{
 			val, err := sqlDollar[5].union.numVal().AsInt32()
 			if err != nil {
@@ -43952,9 +47852,9 @@ sqldefault:
 			}
 			sqlVAL.union.val = types.MakeGeometry(sqlDollar[3].union.geoShapeType(), geopb.SRID(val))
 		}
-	case 2403:
+	case 2629:
 		sqlDollar = sqlS[sqlpt-6 : sqlpt+1]
-//line sql-gen.y:14046
+//line sql-gen.y:15258
 		{
 			val, err := sqlDollar[5].union.numVal().AsInt32()
 			if err != nil {
@@ -43962,9 +47862,29 @@ sqldefault:
 			}
 			sqlVAL.union.val = types.MakeGeography(sqlDollar[3].union.geoShapeType(), geopb.SRID(val))
 		}
-	case 2411:
+	case 2630:
+		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
+//line sql-gen.y:15267
+		{
+			sqlVAL.union.val = types.PGVector
+		}
+	case 2631:
+		sqlDollar = sqlS[sqlpt-4 : sqlpt+1]
+//line sql-gen.y:15269
+		{
+			dims := sqlDollar[3].union.int32()
+			if dims <= 0 {
+				sqllex.Error("dimensions for type vector must be at least 1")
+				return 1
+			} else if dims > vector.MaxDim {
+				sqllex.Error(fmt.Sprintf("dimensions for type vector cannot exceed %d", vector.MaxDim))
+				return 1
+			}
+			sqlVAL.union.val = types.MakePGVector(dims)
+		}
+	case 2640:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:14074
+//line sql-gen.y:15302
 		{
 			dec, err := newDecimal(sqlDollar[2].union.int32(), 0)
 			if err != nil {
@@ -43972,9 +47892,9 @@ sqldefault:
 			}
 			sqlVAL.union.val = dec
 		}
-	case 2412:
+	case 2641:
 		sqlDollar = sqlS[sqlpt-5 : sqlpt+1]
-//line sql-gen.y:14082
+//line sql-gen.y:15310
 		{
 			dec, err := newDecimal(sqlDollar[2].union.int32(), sqlDollar[4].union.int32())
 			if err != nil {
@@ -43982,57 +47902,57 @@ sqldefault:
 			}
 			sqlVAL.union.val = dec
 		}
-	case 2413:
+	case 2642:
 		sqlDollar = sqlS[sqlpt-0 : sqlpt+1]
-//line sql-gen.y:14090
+//line sql-gen.y:15318
 		{
 			sqlVAL.union.val = nil
 		}
-	case 2414:
+	case 2643:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:14097
+//line sql-gen.y:15325
 		{
 			sqlVAL.union.val = sqllex.(*lexer).nakedIntType
 		}
-	case 2415:
+	case 2644:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:14101
+//line sql-gen.y:15329
 		{
 			sqlVAL.union.val = sqllex.(*lexer).nakedIntType
 		}
-	case 2416:
+	case 2645:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:14105
+//line sql-gen.y:15333
 		{
 			sqlVAL.union.val = types.Int2
 		}
-	case 2417:
+	case 2646:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:14109
+//line sql-gen.y:15337
 		{
 			sqlVAL.union.val = types.Int
 		}
-	case 2418:
+	case 2647:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:14113
+//line sql-gen.y:15341
 		{
 			sqlVAL.union.val = types.Float4
 		}
-	case 2419:
+	case 2648:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:14117
+//line sql-gen.y:15345
 		{
 			sqlVAL.union.val = sqlDollar[2].union.colType()
 		}
-	case 2420:
+	case 2649:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:14121
+//line sql-gen.y:15349
 		{
 			sqlVAL.union.val = types.Float
 		}
-	case 2421:
+	case 2650:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:14125
+//line sql-gen.y:15353
 		{
 			typ := sqlDollar[2].union.colType()
 			if typ == nil {
@@ -44040,9 +47960,9 @@ sqldefault:
 			}
 			sqlVAL.union.val = typ
 		}
-	case 2422:
+	case 2651:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:14133
+//line sql-gen.y:15361
 		{
 			typ := sqlDollar[2].union.colType()
 			if typ == nil {
@@ -44050,9 +47970,9 @@ sqldefault:
 			}
 			sqlVAL.union.val = typ
 		}
-	case 2423:
+	case 2652:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:14141
+//line sql-gen.y:15369
 		{
 			typ := sqlDollar[2].union.colType()
 			if typ == nil {
@@ -44060,15 +47980,15 @@ sqldefault:
 			}
 			sqlVAL.union.val = typ
 		}
-	case 2424:
+	case 2653:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:14149
+//line sql-gen.y:15377
 		{
 			sqlVAL.union.val = types.Bool
 		}
-	case 2425:
+	case 2654:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:14155
+//line sql-gen.y:15383
 		{
 			nv := sqlDollar[2].union.numVal()
 			prec, err := nv.AsInt64()
@@ -44081,15 +48001,15 @@ sqldefault:
 			}
 			sqlVAL.union.val = typ
 		}
-	case 2426:
+	case 2655:
 		sqlDollar = sqlS[sqlpt-0 : sqlpt+1]
-//line sql-gen.y:14168
+//line sql-gen.y:15396
 		{
 			sqlVAL.union.val = types.Float
 		}
-	case 2427:
+	case 2656:
 		sqlDollar = sqlS[sqlpt-5 : sqlpt+1]
-//line sql-gen.y:14174
+//line sql-gen.y:15402
 		{
 			bit, err := newBitType(sqlDollar[4].union.int32(), sqlDollar[2].union.bool())
 			if err != nil {
@@ -44097,9 +48017,9 @@ sqldefault:
 			}
 			sqlVAL.union.val = bit
 		}
-	case 2428:
+	case 2657:
 		sqlDollar = sqlS[sqlpt-4 : sqlpt+1]
-//line sql-gen.y:14180
+//line sql-gen.y:15408
 		{
 			bit, err := newBitType(sqlDollar[3].union.int32(), true)
 			if err != nil {
@@ -44107,27 +48027,27 @@ sqldefault:
 			}
 			sqlVAL.union.val = bit
 		}
-	case 2429:
+	case 2658:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:14188
+//line sql-gen.y:15416
 		{
 			sqlVAL.union.val = types.MakeBit(1)
 		}
-	case 2430:
+	case 2659:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:14192
+//line sql-gen.y:15420
 		{
 			sqlVAL.union.val = types.VarBit
 		}
-	case 2431:
+	case 2660:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:14196
+//line sql-gen.y:15424
 		{
 			sqlVAL.union.val = types.VarBit
 		}
-	case 2432:
+	case 2661:
 		sqlDollar = sqlS[sqlpt-4 : sqlpt+1]
-//line sql-gen.y:14202
+//line sql-gen.y:15430
 		{
 			colTyp := *sqlDollar[1].union.colType()
 			n := sqlDollar[3].union.int32()
@@ -44137,57 +48057,57 @@ sqldefault:
 			}
 			sqlVAL.union.val = types.MakeScalar(types.StringFamily, colTyp.Oid(), colTyp.Precision(), n, colTyp.Locale())
 		}
-	case 2433:
+	case 2662:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:14214
+//line sql-gen.y:15442
 		{
 			sqlVAL.union.val = sqlDollar[1].union.colType()
 		}
-	case 2434:
+	case 2663:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:14220
+//line sql-gen.y:15448
 		{
 			sqlVAL.union.val = types.MakeChar(1)
 		}
-	case 2435:
+	case 2664:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:14224
+//line sql-gen.y:15452
 		{
 			sqlVAL.union.val = types.VarChar
 		}
-	case 2436:
+	case 2665:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:14228
+//line sql-gen.y:15456
 		{
 			sqlVAL.union.val = types.VarChar
 		}
-	case 2437:
+	case 2666:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:14232
+//line sql-gen.y:15460
 		{
 			sqlVAL.union.val = types.String
 		}
-	case 2440:
+	case 2669:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:14241
+//line sql-gen.y:15469
 		{
 			sqlVAL.union.val = true
 		}
-	case 2441:
+	case 2670:
 		sqlDollar = sqlS[sqlpt-0 : sqlpt+1]
-//line sql-gen.y:14242
+//line sql-gen.y:15470
 		{
 			sqlVAL.union.val = false
 		}
-	case 2442:
+	case 2671:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:14247
+//line sql-gen.y:15475
 		{
 			sqlVAL.union.val = types.Date
 		}
-	case 2443:
+	case 2672:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:14251
+//line sql-gen.y:15479
 		{
 			if sqlDollar[2].union.bool() {
 				sqlVAL.union.val = types.TimeTZ
@@ -44195,9 +48115,9 @@ sqldefault:
 				sqlVAL.union.val = types.Time
 			}
 		}
-	case 2444:
+	case 2673:
 		sqlDollar = sqlS[sqlpt-5 : sqlpt+1]
-//line sql-gen.y:14259
+//line sql-gen.y:15487
 		{
 			prec := sqlDollar[3].union.int32()
 			if prec < 0 || prec > 6 {
@@ -44210,15 +48130,15 @@ sqldefault:
 				sqlVAL.union.val = types.MakeTime(prec)
 			}
 		}
-	case 2445:
+	case 2674:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:14271
+//line sql-gen.y:15499
 		{
 			sqlVAL.union.val = types.TimeTZ
 		}
-	case 2446:
+	case 2675:
 		sqlDollar = sqlS[sqlpt-4 : sqlpt+1]
-//line sql-gen.y:14273
+//line sql-gen.y:15501
 		{
 			prec := sqlDollar[3].union.int32()
 			if prec < 0 || prec > 6 {
@@ -44227,9 +48147,9 @@ sqldefault:
 			}
 			sqlVAL.union.val = types.MakeTimeTZ(prec)
 		}
-	case 2447:
+	case 2676:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:14282
+//line sql-gen.y:15510
 		{
 			if sqlDollar[2].union.bool() {
 				sqlVAL.union.val = types.TimestampTZ
@@ -44237,9 +48157,9 @@ sqldefault:
 				sqlVAL.union.val = types.Timestamp
 			}
 		}
-	case 2448:
+	case 2677:
 		sqlDollar = sqlS[sqlpt-5 : sqlpt+1]
-//line sql-gen.y:14290
+//line sql-gen.y:15518
 		{
 			prec := sqlDollar[3].union.int32()
 			if prec < 0 || prec > 6 {
@@ -44252,15 +48172,15 @@ sqldefault:
 				sqlVAL.union.val = types.MakeTimestamp(prec)
 			}
 		}
-	case 2449:
+	case 2678:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:14303
+//line sql-gen.y:15531
 		{
 			sqlVAL.union.val = types.TimestampTZ
 		}
-	case 2450:
+	case 2679:
 		sqlDollar = sqlS[sqlpt-4 : sqlpt+1]
-//line sql-gen.y:14307
+//line sql-gen.y:15535
 		{
 			prec := sqlDollar[3].union.int32()
 			if prec < 0 || prec > 6 {
@@ -44269,39 +48189,39 @@ sqldefault:
 			}
 			sqlVAL.union.val = types.MakeTimestampTZ(prec)
 		}
-	case 2451:
+	case 2680:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:14317
+//line sql-gen.y:15545
 		{
 			sqlVAL.union.val = true
 		}
-	case 2452:
+	case 2681:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:14318
+//line sql-gen.y:15546
 		{
 			sqlVAL.union.val = false
 		}
-	case 2453:
+	case 2682:
 		sqlDollar = sqlS[sqlpt-0 : sqlpt+1]
-//line sql-gen.y:14319
+//line sql-gen.y:15547
 		{
 			sqlVAL.union.val = false
 		}
-	case 2454:
+	case 2683:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:14323
+//line sql-gen.y:15551
 		{
 			sqlVAL.union.val = types.Interval
 		}
-	case 2455:
+	case 2684:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:14327
+//line sql-gen.y:15555
 		{
 			sqlVAL.union.val = types.MakeInterval(sqlDollar[2].union.intervalTypeMetadata())
 		}
-	case 2456:
+	case 2685:
 		sqlDollar = sqlS[sqlpt-4 : sqlpt+1]
-//line sql-gen.y:14331
+//line sql-gen.y:15559
 		{
 			prec := sqlDollar[3].union.int32()
 			if prec < 0 || prec > 6 {
@@ -44310,9 +48230,9 @@ sqldefault:
 			}
 			sqlVAL.union.val = types.MakeInterval(types.IntervalTypeMetadata{Precision: prec, PrecisionIsSet: true})
 		}
-	case 2457:
+	case 2686:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:14342
+//line sql-gen.y:15570
 		{
 			sqlVAL.union.val = types.IntervalTypeMetadata{
 				DurationField: types.IntervalDurationField{
@@ -44320,9 +48240,9 @@ sqldefault:
 				},
 			}
 		}
-	case 2458:
+	case 2687:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:14350
+//line sql-gen.y:15578
 		{
 			sqlVAL.union.val = types.IntervalTypeMetadata{
 				DurationField: types.IntervalDurationField{
@@ -44330,9 +48250,9 @@ sqldefault:
 				},
 			}
 		}
-	case 2459:
+	case 2688:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:14358
+//line sql-gen.y:15586
 		{
 			sqlVAL.union.val = types.IntervalTypeMetadata{
 				DurationField: types.IntervalDurationField{
@@ -44340,9 +48260,9 @@ sqldefault:
 				},
 			}
 		}
-	case 2460:
+	case 2689:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:14366
+//line sql-gen.y:15594
 		{
 			sqlVAL.union.val = types.IntervalTypeMetadata{
 				DurationField: types.IntervalDurationField{
@@ -44350,9 +48270,9 @@ sqldefault:
 				},
 			}
 		}
-	case 2461:
+	case 2690:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:14374
+//line sql-gen.y:15602
 		{
 			sqlVAL.union.val = types.IntervalTypeMetadata{
 				DurationField: types.IntervalDurationField{
@@ -44360,15 +48280,15 @@ sqldefault:
 				},
 			}
 		}
-	case 2462:
+	case 2691:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:14382
+//line sql-gen.y:15610
 		{
 			sqlVAL.union.val = sqlDollar[1].union.intervalTypeMetadata()
 		}
-	case 2463:
+	case 2692:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:14388
+//line sql-gen.y:15616
 		{
 			sqlVAL.union.val = types.IntervalTypeMetadata{
 				DurationField: types.IntervalDurationField{
@@ -44377,9 +48297,9 @@ sqldefault:
 				},
 			}
 		}
-	case 2464:
+	case 2693:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:14397
+//line sql-gen.y:15625
 		{
 			sqlVAL.union.val = types.IntervalTypeMetadata{
 				DurationField: types.IntervalDurationField{
@@ -44388,9 +48308,9 @@ sqldefault:
 				},
 			}
 		}
-	case 2465:
+	case 2694:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:14406
+//line sql-gen.y:15634
 		{
 			sqlVAL.union.val = types.IntervalTypeMetadata{
 				DurationField: types.IntervalDurationField{
@@ -44399,17 +48319,17 @@ sqldefault:
 				},
 			}
 		}
-	case 2466:
+	case 2695:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:14415
+//line sql-gen.y:15643
 		{
 			ret := sqlDollar[3].union.intervalTypeMetadata()
 			ret.DurationField.FromDurationType = types.IntervalDurationType_DAY
 			sqlVAL.union.val = ret
 		}
-	case 2467:
+	case 2696:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:14421
+//line sql-gen.y:15649
 		{
 			sqlVAL.union.val = types.IntervalTypeMetadata{
 				DurationField: types.IntervalDurationField{
@@ -44418,32 +48338,32 @@ sqldefault:
 				},
 			}
 		}
-	case 2468:
+	case 2697:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:14430
+//line sql-gen.y:15658
 		{
 			ret := sqlDollar[3].union.intervalTypeMetadata()
 			ret.DurationField.FromDurationType = types.IntervalDurationType_HOUR
 			sqlVAL.union.val = ret
 		}
-	case 2469:
+	case 2698:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:14436
+//line sql-gen.y:15664
 		{
 			sqlVAL.union.val = sqlDollar[3].union.intervalTypeMetadata()
 			ret := sqlDollar[3].union.intervalTypeMetadata()
 			ret.DurationField.FromDurationType = types.IntervalDurationType_MINUTE
 			sqlVAL.union.val = ret
 		}
-	case 2471:
+	case 2700:
 		sqlDollar = sqlS[sqlpt-0 : sqlpt+1]
-//line sql-gen.y:14446
+//line sql-gen.y:15674
 		{
 			sqlVAL.union.val = nil
 		}
-	case 2472:
+	case 2701:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:14452
+//line sql-gen.y:15680
 		{
 			sqlVAL.union.val = types.IntervalTypeMetadata{
 				DurationField: types.IntervalDurationField{
@@ -44451,9 +48371,9 @@ sqldefault:
 				},
 			}
 		}
-	case 2473:
+	case 2702:
 		sqlDollar = sqlS[sqlpt-4 : sqlpt+1]
-//line sql-gen.y:14460
+//line sql-gen.y:15688
 		{
 			prec := sqlDollar[3].union.int32()
 			if prec < 0 || prec > 6 {
@@ -44468,262 +48388,280 @@ sqldefault:
 				Precision:      prec,
 			}
 		}
-	case 2475:
+	case 2704:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:14497
+//line sql-gen.y:15725
 		{
 			sqlVAL.union.val = &tree.CastExpr{Expr: sqlDollar[1].union.expr(), Type: sqlDollar[3].union.typeReference(), SyntaxMode: tree.CastShort}
 		}
-	case 2476:
+	case 2705:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:14501
+//line sql-gen.y:15729
 		{
 			sqlVAL.union.val = &tree.AnnotateTypeExpr{Expr: sqlDollar[1].union.expr(), Type: sqlDollar[3].union.typeReference(), SyntaxMode: tree.AnnotateShort}
 		}
-	case 2477:
+	case 2706:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:14505
+//line sql-gen.y:15733
 		{
 			sqlVAL.union.val = &tree.CollateExpr{Expr: sqlDollar[1].union.expr(), Locale: sqlDollar[3].str}
 		}
-	case 2478:
+	case 2707:
 		sqlDollar = sqlS[sqlpt-5 : sqlpt+1]
-//line sql-gen.y:14509
+//line sql-gen.y:15737
 		{
 			sqlVAL.union.val = &tree.FuncExpr{Func: tree.WrapFunction("timezone"), Exprs: tree.Exprs{sqlDollar[5].union.expr(), sqlDollar[1].union.expr()}}
 		}
-	case 2479:
+	case 2708:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:14520
+//line sql-gen.y:15748
 		{
 
 			sqlVAL.union.val = sqlDollar[2].union.expr()
 		}
-	case 2480:
+	case 2709:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:14525
+//line sql-gen.y:15753
 		{
 			sqlVAL.union.val = unaryNegation(sqlDollar[2].union.expr())
 		}
-	case 2481:
+	case 2710:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:14529
+//line sql-gen.y:15757
 		{
 			sqlVAL.union.val = &tree.UnaryExpr{Operator: tree.MakeUnaryOperator(tree.UnaryComplement), Expr: sqlDollar[2].union.expr()}
 		}
-	case 2482:
+	case 2711:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:14533
+//line sql-gen.y:15761
 		{
 			sqlVAL.union.val = &tree.UnaryExpr{Operator: tree.MakeUnaryOperator(tree.UnarySqrt), Expr: sqlDollar[2].union.expr()}
 		}
-	case 2483:
+	case 2712:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:14537
+//line sql-gen.y:15765
 		{
 			sqlVAL.union.val = &tree.UnaryExpr{Operator: tree.MakeUnaryOperator(tree.UnaryCbrt), Expr: sqlDollar[2].union.expr()}
 		}
-	case 2484:
+	case 2713:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:14541
+//line sql-gen.y:15769
 		{
 			sqlVAL.union.val = &tree.BinaryExpr{Operator: treebin.MakeBinaryOperator(treebin.Plus), Left: sqlDollar[1].union.expr(), Right: sqlDollar[3].union.expr()}
 		}
-	case 2485:
+	case 2714:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:14545
+//line sql-gen.y:15773
 		{
 			sqlVAL.union.val = &tree.BinaryExpr{Operator: treebin.MakeBinaryOperator(treebin.Minus), Left: sqlDollar[1].union.expr(), Right: sqlDollar[3].union.expr()}
 		}
-	case 2486:
+	case 2715:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:14549
+//line sql-gen.y:15777
 		{
 			sqlVAL.union.val = &tree.BinaryExpr{Operator: treebin.MakeBinaryOperator(treebin.Mult), Left: sqlDollar[1].union.expr(), Right: sqlDollar[3].union.expr()}
 		}
-	case 2487:
+	case 2716:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:14553
+//line sql-gen.y:15781
 		{
 			sqlVAL.union.val = &tree.BinaryExpr{Operator: treebin.MakeBinaryOperator(treebin.Div), Left: sqlDollar[1].union.expr(), Right: sqlDollar[3].union.expr()}
 		}
-	case 2488:
+	case 2717:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:14557
+//line sql-gen.y:15785
 		{
 			sqlVAL.union.val = &tree.BinaryExpr{Operator: treebin.MakeBinaryOperator(treebin.FloorDiv), Left: sqlDollar[1].union.expr(), Right: sqlDollar[3].union.expr()}
 		}
-	case 2489:
+	case 2718:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:14561
+//line sql-gen.y:15789
 		{
 			sqlVAL.union.val = &tree.BinaryExpr{Operator: treebin.MakeBinaryOperator(treebin.Mod), Left: sqlDollar[1].union.expr(), Right: sqlDollar[3].union.expr()}
 		}
-	case 2490:
+	case 2719:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:14565
+//line sql-gen.y:15793
 		{
 			sqlVAL.union.val = &tree.BinaryExpr{Operator: treebin.MakeBinaryOperator(treebin.Pow), Left: sqlDollar[1].union.expr(), Right: sqlDollar[3].union.expr()}
 		}
-	case 2491:
+	case 2720:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:14569
+//line sql-gen.y:15797
 		{
 			sqlVAL.union.val = &tree.BinaryExpr{Operator: treebin.MakeBinaryOperator(treebin.Bitxor), Left: sqlDollar[1].union.expr(), Right: sqlDollar[3].union.expr()}
 		}
-	case 2492:
+	case 2721:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:14573
+//line sql-gen.y:15801
 		{
 			sqlVAL.union.val = &tree.BinaryExpr{Operator: treebin.MakeBinaryOperator(treebin.Bitand), Left: sqlDollar[1].union.expr(), Right: sqlDollar[3].union.expr()}
 		}
-	case 2493:
+	case 2722:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:14577
+//line sql-gen.y:15805
 		{
 			sqlVAL.union.val = &tree.BinaryExpr{Operator: treebin.MakeBinaryOperator(treebin.Bitor), Left: sqlDollar[1].union.expr(), Right: sqlDollar[3].union.expr()}
 		}
-	case 2494:
+	case 2723:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:14581
+//line sql-gen.y:15809
 		{
 			sqlVAL.union.val = &tree.ComparisonExpr{Operator: treecmp.MakeComparisonOperator(treecmp.LT), Left: sqlDollar[1].union.expr(), Right: sqlDollar[3].union.expr()}
 		}
-	case 2495:
+	case 2724:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:14585
+//line sql-gen.y:15813
 		{
 			sqlVAL.union.val = &tree.ComparisonExpr{Operator: treecmp.MakeComparisonOperator(treecmp.GT), Left: sqlDollar[1].union.expr(), Right: sqlDollar[3].union.expr()}
 		}
-	case 2496:
+	case 2725:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:14589
+//line sql-gen.y:15817
 		{
 			sqlVAL.union.val = &tree.ComparisonExpr{Operator: treecmp.MakeComparisonOperator(treecmp.JSONExists), Left: sqlDollar[1].union.expr(), Right: sqlDollar[3].union.expr()}
 		}
-	case 2497:
+	case 2726:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:14593
+//line sql-gen.y:15821
 		{
 			sqlVAL.union.val = &tree.ComparisonExpr{Operator: treecmp.MakeComparisonOperator(treecmp.JSONSomeExists), Left: sqlDollar[1].union.expr(), Right: sqlDollar[3].union.expr()}
 		}
-	case 2498:
+	case 2727:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:14597
+//line sql-gen.y:15825
 		{
 			sqlVAL.union.val = &tree.ComparisonExpr{Operator: treecmp.MakeComparisonOperator(treecmp.JSONAllExists), Left: sqlDollar[1].union.expr(), Right: sqlDollar[3].union.expr()}
 		}
-	case 2499:
+	case 2728:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:14601
+//line sql-gen.y:15829
 		{
 			sqlVAL.union.val = &tree.ComparisonExpr{Operator: treecmp.MakeComparisonOperator(treecmp.Contains), Left: sqlDollar[1].union.expr(), Right: sqlDollar[3].union.expr()}
 		}
-	case 2500:
+	case 2729:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:14605
+//line sql-gen.y:15833
 		{
 			sqlVAL.union.val = &tree.ComparisonExpr{Operator: treecmp.MakeComparisonOperator(treecmp.ContainedBy), Left: sqlDollar[1].union.expr(), Right: sqlDollar[3].union.expr()}
 		}
-	case 2501:
+	case 2730:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:14609
+//line sql-gen.y:15837
 		{
 			sqlVAL.union.val = &tree.ComparisonExpr{Operator: treecmp.MakeComparisonOperator(treecmp.EQ), Left: sqlDollar[1].union.expr(), Right: sqlDollar[3].union.expr()}
 		}
-	case 2502:
+	case 2731:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:14613
+//line sql-gen.y:15841
 		{
 			sqlVAL.union.val = &tree.BinaryExpr{Operator: treebin.MakeBinaryOperator(treebin.Concat), Left: sqlDollar[1].union.expr(), Right: sqlDollar[3].union.expr()}
 		}
-	case 2503:
+	case 2732:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:14617
+//line sql-gen.y:15845
 		{
 			sqlVAL.union.val = &tree.BinaryExpr{Operator: treebin.MakeBinaryOperator(treebin.LShift), Left: sqlDollar[1].union.expr(), Right: sqlDollar[3].union.expr()}
 		}
-	case 2504:
+	case 2733:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:14621
+//line sql-gen.y:15849
 		{
 			sqlVAL.union.val = &tree.BinaryExpr{Operator: treebin.MakeBinaryOperator(treebin.RShift), Left: sqlDollar[1].union.expr(), Right: sqlDollar[3].union.expr()}
 		}
-	case 2505:
+	case 2734:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:14625
+//line sql-gen.y:15853
 		{
 			sqlVAL.union.val = &tree.BinaryExpr{Operator: treebin.MakeBinaryOperator(treebin.JSONFetchVal), Left: sqlDollar[1].union.expr(), Right: sqlDollar[3].union.expr()}
 		}
-	case 2506:
+	case 2735:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:14629
+//line sql-gen.y:15857
 		{
 			sqlVAL.union.val = &tree.BinaryExpr{Operator: treebin.MakeBinaryOperator(treebin.JSONFetchText), Left: sqlDollar[1].union.expr(), Right: sqlDollar[3].union.expr()}
 		}
-	case 2507:
+	case 2736:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:14633
+//line sql-gen.y:15861
 		{
 			sqlVAL.union.val = &tree.BinaryExpr{Operator: treebin.MakeBinaryOperator(treebin.JSONFetchValPath), Left: sqlDollar[1].union.expr(), Right: sqlDollar[3].union.expr()}
 		}
-	case 2508:
+	case 2737:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:14637
+//line sql-gen.y:15865
 		{
 			sqlVAL.union.val = &tree.BinaryExpr{Operator: treebin.MakeBinaryOperator(treebin.JSONFetchTextPath), Left: sqlDollar[1].union.expr(), Right: sqlDollar[3].union.expr()}
 		}
-	case 2509:
+	case 2738:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:14641
+//line sql-gen.y:15869
 		{
 			sqlVAL.union.val = &tree.FuncExpr{Func: tree.WrapFunction("json_remove_path"), Exprs: tree.Exprs{sqlDollar[1].union.expr(), sqlDollar[3].union.expr()}}
 		}
-	case 2510:
+	case 2739:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:14645
+//line sql-gen.y:15873
 		{
 			sqlVAL.union.val = &tree.FuncExpr{Func: tree.WrapFunction("inet_contained_by_or_equals"), Exprs: tree.Exprs{sqlDollar[1].union.expr(), sqlDollar[3].union.expr()}}
 		}
-	case 2511:
+	case 2740:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:14649
+//line sql-gen.y:15877
 		{
 			sqlVAL.union.val = &tree.ComparisonExpr{Operator: treecmp.MakeComparisonOperator(treecmp.Overlaps), Left: sqlDollar[1].union.expr(), Right: sqlDollar[3].union.expr()}
 		}
-	case 2512:
+	case 2741:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:14653
+//line sql-gen.y:15881
 		{
 			sqlVAL.union.val = &tree.ComparisonExpr{Operator: treecmp.MakeComparisonOperator(treecmp.TSMatches), Left: sqlDollar[1].union.expr(), Right: sqlDollar[3].union.expr()}
 		}
-	case 2513:
+	case 2742:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:14657
+//line sql-gen.y:15885
+		{
+			sqlVAL.union.val = &tree.BinaryExpr{Operator: treebin.MakeBinaryOperator(treebin.Distance), Left: sqlDollar[1].union.expr(), Right: sqlDollar[3].union.expr()}
+		}
+	case 2743:
+		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
+//line sql-gen.y:15889
+		{
+			sqlVAL.union.val = &tree.BinaryExpr{Operator: treebin.MakeBinaryOperator(treebin.CosDistance), Left: sqlDollar[1].union.expr(), Right: sqlDollar[3].union.expr()}
+		}
+	case 2744:
+		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
+//line sql-gen.y:15893
+		{
+			sqlVAL.union.val = &tree.BinaryExpr{Operator: treebin.MakeBinaryOperator(treebin.NegInnerProduct), Left: sqlDollar[1].union.expr(), Right: sqlDollar[3].union.expr()}
+		}
+	case 2745:
+		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
+//line sql-gen.y:15897
 		{
 			sqlVAL.union.val = &tree.FuncExpr{Func: tree.WrapFunction("inet_contains_or_equals"), Exprs: tree.Exprs{sqlDollar[1].union.expr(), sqlDollar[3].union.expr()}}
 		}
-	case 2514:
+	case 2746:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:14661
+//line sql-gen.y:15901
 		{
 			sqlVAL.union.val = &tree.ComparisonExpr{Operator: treecmp.MakeComparisonOperator(treecmp.LE), Left: sqlDollar[1].union.expr(), Right: sqlDollar[3].union.expr()}
 		}
-	case 2515:
+	case 2747:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:14665
+//line sql-gen.y:15905
 		{
 			sqlVAL.union.val = &tree.ComparisonExpr{Operator: treecmp.MakeComparisonOperator(treecmp.GE), Left: sqlDollar[1].union.expr(), Right: sqlDollar[3].union.expr()}
 		}
-	case 2516:
+	case 2748:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:14669
+//line sql-gen.y:15909
 		{
 			sqlVAL.union.val = &tree.ComparisonExpr{Operator: treecmp.MakeComparisonOperator(treecmp.NE), Left: sqlDollar[1].union.expr(), Right: sqlDollar[3].union.expr()}
 		}
-	case 2517:
+	case 2749:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:14673
+//line sql-gen.y:15913
 		{
 			var retCode int
 			sqlVAL.union.val, retCode = processUnaryQualOp(sqllex, sqlDollar[1].union.op(), sqlDollar[2].union.expr())
@@ -44731,9 +48669,9 @@ sqldefault:
 				return retCode
 			}
 		}
-	case 2518:
+	case 2750:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:14681
+//line sql-gen.y:15921
 		{
 			{
 				var retCode int
@@ -44743,129 +48681,129 @@ sqldefault:
 				}
 			}
 		}
-	case 2519:
+	case 2751:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:14691
+//line sql-gen.y:15931
 		{
 			sqlVAL.union.val = &tree.AndExpr{Left: sqlDollar[1].union.expr(), Right: sqlDollar[3].union.expr()}
 		}
-	case 2520:
+	case 2752:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:14695
+//line sql-gen.y:15935
 		{
 			sqlVAL.union.val = &tree.OrExpr{Left: sqlDollar[1].union.expr(), Right: sqlDollar[3].union.expr()}
 		}
-	case 2521:
+	case 2753:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:14699
+//line sql-gen.y:15939
 		{
 			sqlVAL.union.val = &tree.NotExpr{Expr: sqlDollar[2].union.expr()}
 		}
-	case 2522:
+	case 2754:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:14703
+//line sql-gen.y:15943
 		{
 			sqlVAL.union.val = &tree.NotExpr{Expr: sqlDollar[2].union.expr()}
 		}
-	case 2523:
+	case 2755:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:14707
+//line sql-gen.y:15947
 		{
 			sqlVAL.union.val = &tree.ComparisonExpr{Operator: treecmp.MakeComparisonOperator(treecmp.Like), Left: sqlDollar[1].union.expr(), Right: sqlDollar[3].union.expr()}
 		}
-	case 2524:
+	case 2756:
 		sqlDollar = sqlS[sqlpt-5 : sqlpt+1]
-//line sql-gen.y:14711
+//line sql-gen.y:15951
 		{
 			sqlVAL.union.val = &tree.FuncExpr{Func: tree.WrapFunction("like_escape"), Exprs: tree.Exprs{sqlDollar[1].union.expr(), sqlDollar[3].union.expr(), sqlDollar[5].union.expr()}}
 		}
-	case 2525:
+	case 2757:
 		sqlDollar = sqlS[sqlpt-4 : sqlpt+1]
-//line sql-gen.y:14715
+//line sql-gen.y:15955
 		{
 			sqlVAL.union.val = &tree.ComparisonExpr{Operator: treecmp.MakeComparisonOperator(treecmp.NotLike), Left: sqlDollar[1].union.expr(), Right: sqlDollar[4].union.expr()}
 		}
-	case 2526:
+	case 2758:
 		sqlDollar = sqlS[sqlpt-6 : sqlpt+1]
-//line sql-gen.y:14719
+//line sql-gen.y:15959
 		{
 			sqlVAL.union.val = &tree.FuncExpr{Func: tree.WrapFunction("not_like_escape"), Exprs: tree.Exprs{sqlDollar[1].union.expr(), sqlDollar[4].union.expr(), sqlDollar[6].union.expr()}}
 		}
-	case 2527:
+	case 2759:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:14723
+//line sql-gen.y:15963
 		{
 			sqlVAL.union.val = &tree.ComparisonExpr{Operator: treecmp.MakeComparisonOperator(treecmp.ILike), Left: sqlDollar[1].union.expr(), Right: sqlDollar[3].union.expr()}
 		}
-	case 2528:
+	case 2760:
 		sqlDollar = sqlS[sqlpt-5 : sqlpt+1]
-//line sql-gen.y:14727
+//line sql-gen.y:15967
 		{
 			sqlVAL.union.val = &tree.FuncExpr{Func: tree.WrapFunction("ilike_escape"), Exprs: tree.Exprs{sqlDollar[1].union.expr(), sqlDollar[3].union.expr(), sqlDollar[5].union.expr()}}
 		}
-	case 2529:
+	case 2761:
 		sqlDollar = sqlS[sqlpt-4 : sqlpt+1]
-//line sql-gen.y:14731
+//line sql-gen.y:15971
 		{
 			sqlVAL.union.val = &tree.ComparisonExpr{Operator: treecmp.MakeComparisonOperator(treecmp.NotILike), Left: sqlDollar[1].union.expr(), Right: sqlDollar[4].union.expr()}
 		}
-	case 2530:
+	case 2762:
 		sqlDollar = sqlS[sqlpt-6 : sqlpt+1]
-//line sql-gen.y:14735
+//line sql-gen.y:15975
 		{
 			sqlVAL.union.val = &tree.FuncExpr{Func: tree.WrapFunction("not_ilike_escape"), Exprs: tree.Exprs{sqlDollar[1].union.expr(), sqlDollar[4].union.expr(), sqlDollar[6].union.expr()}}
 		}
-	case 2531:
+	case 2763:
 		sqlDollar = sqlS[sqlpt-4 : sqlpt+1]
-//line sql-gen.y:14739
+//line sql-gen.y:15979
 		{
 			sqlVAL.union.val = &tree.ComparisonExpr{Operator: treecmp.MakeComparisonOperator(treecmp.SimilarTo), Left: sqlDollar[1].union.expr(), Right: sqlDollar[4].union.expr()}
 		}
-	case 2532:
+	case 2764:
 		sqlDollar = sqlS[sqlpt-6 : sqlpt+1]
-//line sql-gen.y:14743
+//line sql-gen.y:15983
 		{
 			sqlVAL.union.val = &tree.FuncExpr{Func: tree.WrapFunction("similar_to_escape"), Exprs: tree.Exprs{sqlDollar[1].union.expr(), sqlDollar[4].union.expr(), sqlDollar[6].union.expr()}}
 		}
-	case 2533:
+	case 2765:
 		sqlDollar = sqlS[sqlpt-5 : sqlpt+1]
-//line sql-gen.y:14747
+//line sql-gen.y:15987
 		{
 			sqlVAL.union.val = &tree.ComparisonExpr{Operator: treecmp.MakeComparisonOperator(treecmp.NotSimilarTo), Left: sqlDollar[1].union.expr(), Right: sqlDollar[5].union.expr()}
 		}
-	case 2534:
+	case 2766:
 		sqlDollar = sqlS[sqlpt-7 : sqlpt+1]
-//line sql-gen.y:14751
+//line sql-gen.y:15991
 		{
 			sqlVAL.union.val = &tree.FuncExpr{Func: tree.WrapFunction("not_similar_to_escape"), Exprs: tree.Exprs{sqlDollar[1].union.expr(), sqlDollar[5].union.expr(), sqlDollar[7].union.expr()}}
 		}
-	case 2535:
+	case 2767:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:14755
+//line sql-gen.y:15995
 		{
 			sqlVAL.union.val = &tree.ComparisonExpr{Operator: treecmp.MakeComparisonOperator(treecmp.RegMatch), Left: sqlDollar[1].union.expr(), Right: sqlDollar[3].union.expr()}
 		}
-	case 2536:
+	case 2768:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:14759
+//line sql-gen.y:15999
 		{
 			sqlVAL.union.val = &tree.ComparisonExpr{Operator: treecmp.MakeComparisonOperator(treecmp.NotRegMatch), Left: sqlDollar[1].union.expr(), Right: sqlDollar[3].union.expr()}
 		}
-	case 2537:
+	case 2769:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:14763
+//line sql-gen.y:16003
 		{
 			sqlVAL.union.val = &tree.ComparisonExpr{Operator: treecmp.MakeComparisonOperator(treecmp.RegIMatch), Left: sqlDollar[1].union.expr(), Right: sqlDollar[3].union.expr()}
 		}
-	case 2538:
+	case 2770:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:14767
+//line sql-gen.y:16007
 		{
 			sqlVAL.union.val = &tree.ComparisonExpr{Operator: treecmp.MakeComparisonOperator(treecmp.NotRegIMatch), Left: sqlDollar[1].union.expr(), Right: sqlDollar[3].union.expr()}
 		}
-	case 2539:
+	case 2771:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:14771
+//line sql-gen.y:16011
 		{
 			sqlVAL.union.val = &tree.ComparisonExpr{
 				Operator: treecmp.MakeComparisonOperator(treecmp.EQ),
@@ -44873,9 +48811,9 @@ sqldefault:
 				Right:    tree.NewNumVal(constant.MakeFloat64(math.NaN()), "NaN", false),
 			}
 		}
-	case 2540:
+	case 2772:
 		sqlDollar = sqlS[sqlpt-4 : sqlpt+1]
-//line sql-gen.y:14779
+//line sql-gen.y:16019
 		{
 			sqlVAL.union.val = &tree.ComparisonExpr{
 				Operator: treecmp.MakeComparisonOperator(treecmp.NE),
@@ -44883,33 +48821,33 @@ sqldefault:
 				Right:    tree.NewNumVal(constant.MakeFloat64(math.NaN()), "NaN", false),
 			}
 		}
-	case 2541:
+	case 2773:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:14787
+//line sql-gen.y:16027
 		{
 			sqlVAL.union.val = &tree.IsNullExpr{Expr: sqlDollar[1].union.expr()}
 		}
-	case 2542:
+	case 2774:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:14791
+//line sql-gen.y:16031
 		{
 			sqlVAL.union.val = &tree.IsNullExpr{Expr: sqlDollar[1].union.expr()}
 		}
-	case 2543:
+	case 2775:
 		sqlDollar = sqlS[sqlpt-4 : sqlpt+1]
-//line sql-gen.y:14795
+//line sql-gen.y:16035
 		{
 			sqlVAL.union.val = &tree.IsNotNullExpr{Expr: sqlDollar[1].union.expr()}
 		}
-	case 2544:
+	case 2776:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:14799
+//line sql-gen.y:16039
 		{
 			sqlVAL.union.val = &tree.IsNotNullExpr{Expr: sqlDollar[1].union.expr()}
 		}
-	case 2545:
+	case 2777:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:14803
+//line sql-gen.y:16043
 		{
 			t1, t2 := sqlDollar[1].union.tuple(), sqlDollar[3].union.tuple()
 			if len(t1.Exprs) != 2 {
@@ -44922,105 +48860,105 @@ sqldefault:
 			}
 			sqlVAL.union.val = &tree.FuncExpr{Func: tree.WrapFunction("overlaps"), Exprs: tree.Exprs{t1.Exprs[0], t1.Exprs[1], t2.Exprs[0], t2.Exprs[1]}}
 		}
-	case 2546:
+	case 2778:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:14816
+//line sql-gen.y:16056
 		{
 			sqlVAL.union.val = &tree.ComparisonExpr{Operator: treecmp.MakeComparisonOperator(treecmp.IsNotDistinctFrom), Left: sqlDollar[1].union.expr(), Right: tree.MakeDBool(true)}
 		}
-	case 2547:
+	case 2779:
 		sqlDollar = sqlS[sqlpt-4 : sqlpt+1]
-//line sql-gen.y:14820
+//line sql-gen.y:16060
 		{
 			sqlVAL.union.val = &tree.ComparisonExpr{Operator: treecmp.MakeComparisonOperator(treecmp.IsDistinctFrom), Left: sqlDollar[1].union.expr(), Right: tree.MakeDBool(true)}
 		}
-	case 2548:
+	case 2780:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:14824
+//line sql-gen.y:16064
 		{
 			sqlVAL.union.val = &tree.ComparisonExpr{Operator: treecmp.MakeComparisonOperator(treecmp.IsNotDistinctFrom), Left: sqlDollar[1].union.expr(), Right: tree.MakeDBool(false)}
 		}
-	case 2549:
+	case 2781:
 		sqlDollar = sqlS[sqlpt-4 : sqlpt+1]
-//line sql-gen.y:14828
+//line sql-gen.y:16068
 		{
 			sqlVAL.union.val = &tree.ComparisonExpr{Operator: treecmp.MakeComparisonOperator(treecmp.IsDistinctFrom), Left: sqlDollar[1].union.expr(), Right: tree.MakeDBool(false)}
 		}
-	case 2550:
+	case 2782:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:14832
+//line sql-gen.y:16072
 		{
 			sqlVAL.union.val = &tree.ComparisonExpr{Operator: treecmp.MakeComparisonOperator(treecmp.IsNotDistinctFrom), Left: sqlDollar[1].union.expr(), Right: tree.DNull}
 		}
-	case 2551:
+	case 2783:
 		sqlDollar = sqlS[sqlpt-4 : sqlpt+1]
-//line sql-gen.y:14836
+//line sql-gen.y:16076
 		{
 			sqlVAL.union.val = &tree.ComparisonExpr{Operator: treecmp.MakeComparisonOperator(treecmp.IsDistinctFrom), Left: sqlDollar[1].union.expr(), Right: tree.DNull}
 		}
-	case 2552:
+	case 2784:
 		sqlDollar = sqlS[sqlpt-5 : sqlpt+1]
-//line sql-gen.y:14840
+//line sql-gen.y:16080
 		{
 			sqlVAL.union.val = &tree.ComparisonExpr{Operator: treecmp.MakeComparisonOperator(treecmp.IsDistinctFrom), Left: sqlDollar[1].union.expr(), Right: sqlDollar[5].union.expr()}
 		}
-	case 2553:
+	case 2785:
 		sqlDollar = sqlS[sqlpt-6 : sqlpt+1]
-//line sql-gen.y:14844
+//line sql-gen.y:16084
 		{
 			sqlVAL.union.val = &tree.ComparisonExpr{Operator: treecmp.MakeComparisonOperator(treecmp.IsNotDistinctFrom), Left: sqlDollar[1].union.expr(), Right: sqlDollar[6].union.expr()}
 		}
-	case 2554:
+	case 2786:
 		sqlDollar = sqlS[sqlpt-6 : sqlpt+1]
-//line sql-gen.y:14848
+//line sql-gen.y:16088
 		{
 			sqlVAL.union.val = &tree.IsOfTypeExpr{Expr: sqlDollar[1].union.expr(), Types: sqlDollar[5].union.typeReferences()}
 		}
-	case 2555:
+	case 2787:
 		sqlDollar = sqlS[sqlpt-7 : sqlpt+1]
-//line sql-gen.y:14852
+//line sql-gen.y:16092
 		{
 			sqlVAL.union.val = &tree.IsOfTypeExpr{Not: true, Expr: sqlDollar[1].union.expr(), Types: sqlDollar[6].union.typeReferences()}
 		}
-	case 2556:
+	case 2788:
 		sqlDollar = sqlS[sqlpt-6 : sqlpt+1]
-//line sql-gen.y:14856
+//line sql-gen.y:16096
 		{
 			sqlVAL.union.val = &tree.RangeCond{Left: sqlDollar[1].union.expr(), From: sqlDollar[4].union.expr(), To: sqlDollar[6].union.expr()}
 		}
-	case 2557:
+	case 2789:
 		sqlDollar = sqlS[sqlpt-7 : sqlpt+1]
-//line sql-gen.y:14860
+//line sql-gen.y:16100
 		{
 			sqlVAL.union.val = &tree.RangeCond{Not: true, Left: sqlDollar[1].union.expr(), From: sqlDollar[5].union.expr(), To: sqlDollar[7].union.expr()}
 		}
-	case 2558:
+	case 2790:
 		sqlDollar = sqlS[sqlpt-6 : sqlpt+1]
-//line sql-gen.y:14864
+//line sql-gen.y:16104
 		{
 			sqlVAL.union.val = &tree.RangeCond{Symmetric: true, Left: sqlDollar[1].union.expr(), From: sqlDollar[4].union.expr(), To: sqlDollar[6].union.expr()}
 		}
-	case 2559:
+	case 2791:
 		sqlDollar = sqlS[sqlpt-7 : sqlpt+1]
-//line sql-gen.y:14868
+//line sql-gen.y:16108
 		{
 			sqlVAL.union.val = &tree.RangeCond{Not: true, Symmetric: true, Left: sqlDollar[1].union.expr(), From: sqlDollar[5].union.expr(), To: sqlDollar[7].union.expr()}
 		}
-	case 2560:
+	case 2792:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:14872
+//line sql-gen.y:16112
 		{
 			sqlVAL.union.val = &tree.ComparisonExpr{Operator: treecmp.MakeComparisonOperator(treecmp.In), Left: sqlDollar[1].union.expr(), Right: sqlDollar[3].union.expr()}
 		}
-	case 2561:
+	case 2793:
 		sqlDollar = sqlS[sqlpt-4 : sqlpt+1]
-//line sql-gen.y:14876
+//line sql-gen.y:16116
 		{
 			sqlVAL.union.val = &tree.ComparisonExpr{Operator: treecmp.MakeComparisonOperator(treecmp.NotIn), Left: sqlDollar[1].union.expr(), Right: sqlDollar[4].union.expr()}
 		}
-	case 2562:
+	case 2794:
 		sqlDollar = sqlS[sqlpt-4 : sqlpt+1]
-//line sql-gen.y:14880
+//line sql-gen.y:16120
 		{
 			op := sqlDollar[3].union.cmpOp()
 			subOp := sqlDollar[2].union.op()
@@ -45042,165 +48980,165 @@ sqldefault:
 				Right:       sqlDollar[4].union.expr(),
 			}
 		}
-	case 2563:
+	case 2795:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:14904
+//line sql-gen.y:16144
 		{
 			sqlVAL.union.val = tree.DefaultVal{}
 		}
-	case 2564:
+	case 2796:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:14909
+//line sql-gen.y:16149
 		{
 			return unimplemented(sqllex, "UNIQUE predicate")
 		}
-	case 2566:
+	case 2798:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:14921
+//line sql-gen.y:16161
 		{
 			sqlVAL.union.val = &tree.CastExpr{Expr: sqlDollar[1].union.expr(), Type: sqlDollar[3].union.typeReference(), SyntaxMode: tree.CastShort}
 		}
-	case 2567:
+	case 2799:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:14925
+//line sql-gen.y:16165
 		{
 			sqlVAL.union.val = &tree.AnnotateTypeExpr{Expr: sqlDollar[1].union.expr(), Type: sqlDollar[3].union.typeReference(), SyntaxMode: tree.AnnotateShort}
 		}
-	case 2568:
+	case 2800:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:14929
+//line sql-gen.y:16169
 		{
 			sqlVAL.union.val = sqlDollar[2].union.expr()
 		}
-	case 2569:
+	case 2801:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:14933
+//line sql-gen.y:16173
 		{
 			sqlVAL.union.val = unaryNegation(sqlDollar[2].union.expr())
 		}
-	case 2570:
+	case 2802:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:14937
+//line sql-gen.y:16177
 		{
 			sqlVAL.union.val = &tree.UnaryExpr{Operator: tree.MakeUnaryOperator(tree.UnaryComplement), Expr: sqlDollar[2].union.expr()}
 		}
-	case 2571:
+	case 2803:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:14941
+//line sql-gen.y:16181
 		{
 			sqlVAL.union.val = &tree.BinaryExpr{Operator: treebin.MakeBinaryOperator(treebin.Plus), Left: sqlDollar[1].union.expr(), Right: sqlDollar[3].union.expr()}
 		}
-	case 2572:
+	case 2804:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:14945
+//line sql-gen.y:16185
 		{
 			sqlVAL.union.val = &tree.BinaryExpr{Operator: treebin.MakeBinaryOperator(treebin.Minus), Left: sqlDollar[1].union.expr(), Right: sqlDollar[3].union.expr()}
 		}
-	case 2573:
+	case 2805:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:14949
+//line sql-gen.y:16189
 		{
 			sqlVAL.union.val = &tree.BinaryExpr{Operator: treebin.MakeBinaryOperator(treebin.Mult), Left: sqlDollar[1].union.expr(), Right: sqlDollar[3].union.expr()}
 		}
-	case 2574:
+	case 2806:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:14953
+//line sql-gen.y:16193
 		{
 			sqlVAL.union.val = &tree.BinaryExpr{Operator: treebin.MakeBinaryOperator(treebin.Div), Left: sqlDollar[1].union.expr(), Right: sqlDollar[3].union.expr()}
 		}
-	case 2575:
+	case 2807:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:14957
+//line sql-gen.y:16197
 		{
 			sqlVAL.union.val = &tree.BinaryExpr{Operator: treebin.MakeBinaryOperator(treebin.FloorDiv), Left: sqlDollar[1].union.expr(), Right: sqlDollar[3].union.expr()}
 		}
-	case 2576:
+	case 2808:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:14961
+//line sql-gen.y:16201
 		{
 			sqlVAL.union.val = &tree.BinaryExpr{Operator: treebin.MakeBinaryOperator(treebin.Mod), Left: sqlDollar[1].union.expr(), Right: sqlDollar[3].union.expr()}
 		}
-	case 2577:
+	case 2809:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:14965
+//line sql-gen.y:16205
 		{
 			sqlVAL.union.val = &tree.BinaryExpr{Operator: treebin.MakeBinaryOperator(treebin.Pow), Left: sqlDollar[1].union.expr(), Right: sqlDollar[3].union.expr()}
 		}
-	case 2578:
+	case 2810:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:14969
+//line sql-gen.y:16209
 		{
 			sqlVAL.union.val = &tree.BinaryExpr{Operator: treebin.MakeBinaryOperator(treebin.Bitxor), Left: sqlDollar[1].union.expr(), Right: sqlDollar[3].union.expr()}
 		}
-	case 2579:
+	case 2811:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:14973
+//line sql-gen.y:16213
 		{
 			sqlVAL.union.val = &tree.BinaryExpr{Operator: treebin.MakeBinaryOperator(treebin.Bitand), Left: sqlDollar[1].union.expr(), Right: sqlDollar[3].union.expr()}
 		}
-	case 2580:
+	case 2812:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:14977
+//line sql-gen.y:16217
 		{
 			sqlVAL.union.val = &tree.BinaryExpr{Operator: treebin.MakeBinaryOperator(treebin.Bitor), Left: sqlDollar[1].union.expr(), Right: sqlDollar[3].union.expr()}
 		}
-	case 2581:
+	case 2813:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:14981
+//line sql-gen.y:16221
 		{
 			sqlVAL.union.val = &tree.ComparisonExpr{Operator: treecmp.MakeComparisonOperator(treecmp.LT), Left: sqlDollar[1].union.expr(), Right: sqlDollar[3].union.expr()}
 		}
-	case 2582:
+	case 2814:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:14985
+//line sql-gen.y:16225
 		{
 			sqlVAL.union.val = &tree.ComparisonExpr{Operator: treecmp.MakeComparisonOperator(treecmp.GT), Left: sqlDollar[1].union.expr(), Right: sqlDollar[3].union.expr()}
 		}
-	case 2583:
+	case 2815:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:14989
+//line sql-gen.y:16229
 		{
 			sqlVAL.union.val = &tree.ComparisonExpr{Operator: treecmp.MakeComparisonOperator(treecmp.EQ), Left: sqlDollar[1].union.expr(), Right: sqlDollar[3].union.expr()}
 		}
-	case 2584:
+	case 2816:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:14993
+//line sql-gen.y:16233
 		{
 			sqlVAL.union.val = &tree.BinaryExpr{Operator: treebin.MakeBinaryOperator(treebin.Concat), Left: sqlDollar[1].union.expr(), Right: sqlDollar[3].union.expr()}
 		}
-	case 2585:
+	case 2817:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:14997
+//line sql-gen.y:16237
 		{
 			sqlVAL.union.val = &tree.BinaryExpr{Operator: treebin.MakeBinaryOperator(treebin.LShift), Left: sqlDollar[1].union.expr(), Right: sqlDollar[3].union.expr()}
 		}
-	case 2586:
+	case 2818:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:15001
+//line sql-gen.y:16241
 		{
 			sqlVAL.union.val = &tree.BinaryExpr{Operator: treebin.MakeBinaryOperator(treebin.RShift), Left: sqlDollar[1].union.expr(), Right: sqlDollar[3].union.expr()}
 		}
-	case 2587:
+	case 2819:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:15005
+//line sql-gen.y:16245
 		{
 			sqlVAL.union.val = &tree.ComparisonExpr{Operator: treecmp.MakeComparisonOperator(treecmp.LE), Left: sqlDollar[1].union.expr(), Right: sqlDollar[3].union.expr()}
 		}
-	case 2588:
+	case 2820:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:15009
+//line sql-gen.y:16249
 		{
 			sqlVAL.union.val = &tree.ComparisonExpr{Operator: treecmp.MakeComparisonOperator(treecmp.GE), Left: sqlDollar[1].union.expr(), Right: sqlDollar[3].union.expr()}
 		}
-	case 2589:
+	case 2821:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:15013
+//line sql-gen.y:16253
 		{
 			sqlVAL.union.val = &tree.ComparisonExpr{Operator: treecmp.MakeComparisonOperator(treecmp.NE), Left: sqlDollar[1].union.expr(), Right: sqlDollar[3].union.expr()}
 		}
-	case 2590:
+	case 2822:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:15017
+//line sql-gen.y:16257
 		{
 			var retCode int
 			sqlVAL.union.val, retCode = processUnaryQualOp(sqllex, sqlDollar[1].union.op(), sqlDollar[2].union.expr())
@@ -45208,9 +49146,9 @@ sqldefault:
 				return retCode
 			}
 		}
-	case 2591:
+	case 2823:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:15025
+//line sql-gen.y:16265
 		{
 			{
 				var retCode int
@@ -45220,72 +49158,72 @@ sqldefault:
 				}
 			}
 		}
-	case 2592:
+	case 2824:
 		sqlDollar = sqlS[sqlpt-5 : sqlpt+1]
-//line sql-gen.y:15035
+//line sql-gen.y:16275
 		{
 			sqlVAL.union.val = &tree.ComparisonExpr{Operator: treecmp.MakeComparisonOperator(treecmp.IsDistinctFrom), Left: sqlDollar[1].union.expr(), Right: sqlDollar[5].union.expr()}
 		}
-	case 2593:
+	case 2825:
 		sqlDollar = sqlS[sqlpt-6 : sqlpt+1]
-//line sql-gen.y:15039
+//line sql-gen.y:16279
 		{
 			sqlVAL.union.val = &tree.ComparisonExpr{Operator: treecmp.MakeComparisonOperator(treecmp.IsNotDistinctFrom), Left: sqlDollar[1].union.expr(), Right: sqlDollar[6].union.expr()}
 		}
-	case 2594:
+	case 2826:
 		sqlDollar = sqlS[sqlpt-6 : sqlpt+1]
-//line sql-gen.y:15043
+//line sql-gen.y:16283
 		{
 			sqlVAL.union.val = &tree.IsOfTypeExpr{Expr: sqlDollar[1].union.expr(), Types: sqlDollar[5].union.typeReferences()}
 		}
-	case 2595:
+	case 2827:
 		sqlDollar = sqlS[sqlpt-7 : sqlpt+1]
-//line sql-gen.y:15047
+//line sql-gen.y:16287
 		{
 			sqlVAL.union.val = &tree.IsOfTypeExpr{Not: true, Expr: sqlDollar[1].union.expr(), Types: sqlDollar[6].union.typeReferences()}
 		}
-	case 2597:
+	case 2829:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:15061
+//line sql-gen.y:16301
 		{
 			sqlVAL.union.val = &tree.IndirectionExpr{
 				Expr:        sqlDollar[1].union.expr(),
 				Indirection: sqlDollar[2].union.arraySubscripts(),
 			}
 		}
-	case 2599:
+	case 2831:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:15069
+//line sql-gen.y:16309
 		{
 			sqlVAL.union.val = &tree.Subquery{Select: sqlDollar[2].union.selectStmt(), Exists: true}
 		}
-	case 2600:
+	case 2832:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:15105
+//line sql-gen.y:16345
 		{
 			sqlVAL.union.val = sqlDollar[1].union.numVal()
 		}
-	case 2601:
+	case 2833:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:15109
+//line sql-gen.y:16349
 		{
 			sqlVAL.union.val = sqlDollar[1].union.numVal()
 		}
-	case 2602:
+	case 2834:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:15113
+//line sql-gen.y:16353
 		{
 			sqlVAL.union.val = tree.NewStrVal(sqlDollar[1].str)
 		}
-	case 2603:
+	case 2835:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:15117
+//line sql-gen.y:16357
 		{
 			sqlVAL.union.val = tree.NewBytesStrVal(sqlDollar[1].str)
 		}
-	case 2604:
+	case 2836:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:15121
+//line sql-gen.y:16361
 		{
 			d, err := tree.ParseDBitArray(sqlDollar[1].str)
 			if err != nil {
@@ -45293,51 +49231,51 @@ sqldefault:
 			}
 			sqlVAL.union.val = d
 		}
-	case 2605:
+	case 2837:
 		sqlDollar = sqlS[sqlpt-6 : sqlpt+1]
-//line sql-gen.y:15126
+//line sql-gen.y:16366
 		{
 			return unimplemented(sqllex, sqlDollar[1].union.resolvableFuncRef().String()+"(...) SCONST")
 		}
-	case 2606:
+	case 2838:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:15128
+//line sql-gen.y:16368
 		{
 			sqlVAL.union.val = sqlDollar[1].union.expr()
 		}
-	case 2607:
+	case 2839:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:15132
+//line sql-gen.y:16372
 		{
 			sqlVAL.union.val = sqlDollar[1].union.expr()
 		}
-	case 2608:
+	case 2840:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:15136
+//line sql-gen.y:16376
 		{
 			sqlVAL.union.val = tree.MakeDBool(true)
 		}
-	case 2609:
+	case 2841:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:15140
+//line sql-gen.y:16380
 		{
 			sqlVAL.union.val = tree.MakeDBool(false)
 		}
-	case 2610:
+	case 2842:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:15144
+//line sql-gen.y:16384
 		{
 			sqlVAL.union.val = tree.DNull
 		}
-	case 2611:
+	case 2843:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:15148
+//line sql-gen.y:16388
 		{
 			sqlVAL.union.val = tree.Expr(sqlDollar[1].union.unresolvedName())
 		}
-	case 2612:
+	case 2844:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:15152
+//line sql-gen.y:16392
 		{
 			colNum := sqlDollar[2].union.int64()
 			if colNum < 1 || colNum > int64(MaxInt) {
@@ -45346,29 +49284,29 @@ sqldefault:
 			}
 			sqlVAL.union.val = tree.NewOrdinalReference(int(colNum - 1))
 		}
-	case 2613:
+	case 2845:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:15161
+//line sql-gen.y:16401
 		{
 			p := sqlDollar[1].union.placeholder()
 			sqllex.(*lexer).UpdateNumPlaceholders(p)
 			sqlVAL.union.val = p
 		}
-	case 2614:
+	case 2846:
 		sqlDollar = sqlS[sqlpt-5 : sqlpt+1]
-//line sql-gen.y:15168
+//line sql-gen.y:16408
 		{
 			sqlVAL.union.val = &tree.TupleStar{Expr: sqlDollar[2].union.expr()}
 		}
-	case 2615:
+	case 2847:
 		sqlDollar = sqlS[sqlpt-5 : sqlpt+1]
-//line sql-gen.y:15172
+//line sql-gen.y:16412
 		{
 			sqlVAL.union.val = &tree.ColumnAccessExpr{Expr: sqlDollar[2].union.expr(), ColName: tree.Name(sqlDollar[5].str)}
 		}
-	case 2616:
+	case 2848:
 		sqlDollar = sqlS[sqlpt-6 : sqlpt+1]
-//line sql-gen.y:15176
+//line sql-gen.y:16416
 		{
 			idx, err := sqlDollar[6].union.numVal().AsInt32()
 			if err != nil {
@@ -45380,114 +49318,114 @@ sqldefault:
 			}
 			sqlVAL.union.val = &tree.ColumnAccessExpr{Expr: sqlDollar[2].union.expr(), ByIndex: true, ColIndex: int(idx - 1)}
 		}
-	case 2617:
+	case 2849:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:15186
+//line sql-gen.y:16426
 		{
 			sqlVAL.union.val = &tree.ParenExpr{Expr: sqlDollar[2].union.expr()}
 		}
-	case 2619:
+	case 2851:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:15191
+//line sql-gen.y:16431
 		{
 			sqlVAL.union.val = &tree.Subquery{Select: sqlDollar[1].union.selectStmt()}
 		}
-	case 2620:
+	case 2852:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:15195
+//line sql-gen.y:16435
 		{
 			sqlVAL.union.val = sqlDollar[1].union.tuple()
 		}
-	case 2621:
+	case 2853:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:15199
+//line sql-gen.y:16439
 		{
 			sqlVAL.union.val = &tree.ArrayFlatten{Subquery: &tree.Subquery{Select: sqlDollar[2].union.selectStmt()}}
 		}
-	case 2622:
+	case 2854:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:15203
+//line sql-gen.y:16443
 		{
 			sqlVAL.union.val = &tree.Array{Exprs: sqlDollar[2].union.tuple().Exprs}
 		}
-	case 2623:
+	case 2855:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:15207
+//line sql-gen.y:16447
 		{
 			sqlVAL.union.val = sqlDollar[2].union.expr()
 		}
-	case 2624:
+	case 2856:
 		sqlDollar = sqlS[sqlpt-4 : sqlpt+1]
-//line sql-gen.y:15210
+//line sql-gen.y:16450
 		{
 			return unimplemented(sqllex, "d_expr grouping")
 		}
-	case 2625:
+	case 2857:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:15214
+//line sql-gen.y:16454
 		{
 			sqlVAL.union.val = &tree.FuncExpr{Func: sqlDollar[1].union.resolvableFuncRef()}
 		}
-	case 2626:
+	case 2858:
 		sqlDollar = sqlS[sqlpt-5 : sqlpt+1]
-//line sql-gen.y:15218
+//line sql-gen.y:16458
 		{
 			sqlVAL.union.val = &tree.FuncExpr{Func: sqlDollar[1].union.resolvableFuncRef(), Exprs: sqlDollar[3].union.exprs(), OrderBy: sqlDollar[4].union.orderBy(), AggType: tree.GeneralAgg}
 		}
-	case 2627:
+	case 2859:
 		sqlDollar = sqlS[sqlpt-6 : sqlpt+1]
-//line sql-gen.y:15221
+//line sql-gen.y:16461
 		{
 			return unimplemented(sqllex, "variadic")
 		}
-	case 2628:
+	case 2860:
 		sqlDollar = sqlS[sqlpt-8 : sqlpt+1]
-//line sql-gen.y:15222
+//line sql-gen.y:16462
 		{
 			return unimplemented(sqllex, "variadic")
 		}
-	case 2629:
+	case 2861:
 		sqlDollar = sqlS[sqlpt-6 : sqlpt+1]
-//line sql-gen.y:15224
+//line sql-gen.y:16464
 		{
 			sqlVAL.union.val = &tree.FuncExpr{Func: sqlDollar[1].union.resolvableFuncRef(), Type: tree.AllFuncType, Exprs: sqlDollar[4].union.exprs(), OrderBy: sqlDollar[5].union.orderBy(), AggType: tree.GeneralAgg}
 		}
-	case 2630:
+	case 2862:
 		sqlDollar = sqlS[sqlpt-5 : sqlpt+1]
-//line sql-gen.y:15230
+//line sql-gen.y:16470
 		{
 			sqlVAL.union.val = &tree.FuncExpr{Func: sqlDollar[1].union.resolvableFuncRef(), Type: tree.DistinctFuncType, Exprs: sqlDollar[4].union.exprs()}
 		}
-	case 2631:
+	case 2863:
 		sqlDollar = sqlS[sqlpt-4 : sqlpt+1]
-//line sql-gen.y:15234
+//line sql-gen.y:16474
 		{
 			sqlVAL.union.val = &tree.FuncExpr{Func: sqlDollar[1].union.resolvableFuncRef(), Exprs: tree.Exprs{tree.StarExpr()}}
 		}
-	case 2632:
+	case 2864:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:15237
+//line sql-gen.y:16477
 		{
 			return helpWithFunction(sqllex, sqlDollar[1].union.resolvableFuncRef())
 		}
-	case 2633:
+	case 2865:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:15241
+//line sql-gen.y:16481
 		{
 			sqlVAL.union.val = sqlDollar[1].union.resolvableFuncRefFromName()
 		}
-	case 2634:
+	case 2866:
 		sqlDollar = sqlS[sqlpt-4 : sqlpt+1]
-//line sql-gen.y:15245
+//line sql-gen.y:16485
 		{
 			id := sqlDollar[3].union.int32()
 			sqlVAL.union.val = tree.ResolvableFunctionReference{
 				FunctionReference: &tree.FunctionOID{OID: oid.Oid(id)},
 			}
 		}
-	case 2635:
+	case 2867:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:15259
+//line sql-gen.y:16499
 		{
 			name := sqlDollar[1].union.unresolvedName()
 			if name.NumParts == 1 {
@@ -45535,15 +49473,15 @@ sqldefault:
 				sqlVAL.union.val = &tree.CastExpr{Expr: tree.NewStrVal(sqlDollar[2].str), Type: &res, SyntaxMode: tree.CastPrepend}
 			}
 		}
-	case 2636:
+	case 2868:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:15312
+//line sql-gen.y:16552
 		{
 			sqlVAL.union.val = &tree.CastExpr{Expr: tree.NewStrVal(sqlDollar[2].str), Type: sqlDollar[1].union.colType(), SyntaxMode: tree.CastPrepend}
 		}
-	case 2637:
+	case 2869:
 		sqlDollar = sqlS[sqlpt-4 : sqlpt+1]
-//line sql-gen.y:15325
+//line sql-gen.y:16565
 		{
 			f := sqlDollar[1].union.expr().(*tree.FuncExpr)
 			w := sqlDollar[2].union.expr().(*tree.FuncExpr)
@@ -45555,461 +49493,461 @@ sqldefault:
 			f.WindowDef = sqlDollar[4].union.windowDef()
 			sqlVAL.union.val = f
 		}
-	case 2638:
+	case 2870:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:15337
+//line sql-gen.y:16577
 		{
 			sqlVAL.union.val = sqlDollar[1].union.expr()
 		}
-	case 2639:
+	case 2871:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:15346
+//line sql-gen.y:16586
 		{
 			sqlVAL.union.val = sqlDollar[1].union.expr()
 		}
-	case 2640:
+	case 2872:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:15347
+//line sql-gen.y:16587
 		{
 			sqlVAL.union.val = sqlDollar[1].union.expr()
 		}
-	case 2641:
+	case 2873:
 		sqlDollar = sqlS[sqlpt-5 : sqlpt+1]
-//line sql-gen.y:15352
+//line sql-gen.y:16592
 		{
 			sqlVAL.union.val = &tree.FuncExpr{Func: tree.WrapFunction("pg_collation_for"), Exprs: tree.Exprs{sqlDollar[4].union.expr()}}
 		}
-	case 2642:
+	case 2874:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:15356
+//line sql-gen.y:16596
 		{
 			sqlVAL.union.val = &tree.FuncExpr{Func: tree.WrapFunction(sqlDollar[1].str)}
 		}
-	case 2643:
+	case 2875:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:15360
+//line sql-gen.y:16600
 		{
 			sqlVAL.union.val = &tree.FuncExpr{Func: tree.WrapFunction(sqlDollar[1].str)}
 		}
-	case 2644:
+	case 2876:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:15366
+//line sql-gen.y:16606
 		{
 			sqlVAL.union.val = &tree.FuncExpr{Func: tree.WrapFunction("current_database")}
 		}
-	case 2645:
+	case 2877:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:15370
+//line sql-gen.y:16610
 		{
 			sqlVAL.union.val = &tree.FuncExpr{Func: tree.WrapFunction(sqlDollar[1].str)}
 		}
-	case 2646:
+	case 2878:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:15374
+//line sql-gen.y:16614
 		{
 			sqlVAL.union.val = &tree.FuncExpr{Func: tree.WrapFunction(sqlDollar[1].str)}
 		}
-	case 2647:
+	case 2879:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:15378
+//line sql-gen.y:16618
 		{
 			sqlVAL.union.val = &tree.FuncExpr{Func: tree.WrapFunction(sqlDollar[1].str)}
 		}
-	case 2648:
+	case 2880:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:15382
+//line sql-gen.y:16622
 		{
 			sqlVAL.union.val = &tree.FuncExpr{Func: tree.WrapFunction(sqlDollar[1].str)}
 		}
-	case 2649:
+	case 2881:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:15386
+//line sql-gen.y:16626
 		{
 			sqlVAL.union.val = &tree.FuncExpr{Func: tree.WrapFunction(sqlDollar[1].str)}
 		}
-	case 2650:
+	case 2882:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:15392
+//line sql-gen.y:16632
 		{
 			sqlVAL.union.val = &tree.FuncExpr{Func: tree.WrapFunction("current_user")}
 		}
-	case 2651:
+	case 2883:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:15396
+//line sql-gen.y:16636
 		{
 			sqlVAL.union.val = &tree.FuncExpr{Func: tree.WrapFunction("session_user")}
 		}
-	case 2652:
+	case 2884:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:15400
+//line sql-gen.y:16640
 		{
 			sqlVAL.union.val = &tree.FuncExpr{Func: tree.WrapFunction("current_user")}
 		}
-	case 2653:
+	case 2885:
 		sqlDollar = sqlS[sqlpt-6 : sqlpt+1]
-//line sql-gen.y:15404
+//line sql-gen.y:16644
 		{
 			sqlVAL.union.val = &tree.CastExpr{Expr: sqlDollar[3].union.expr(), Type: sqlDollar[5].union.typeReference(), SyntaxMode: tree.CastExplicit}
 		}
-	case 2654:
+	case 2886:
 		sqlDollar = sqlS[sqlpt-6 : sqlpt+1]
-//line sql-gen.y:15408
+//line sql-gen.y:16648
 		{
 			sqlVAL.union.val = &tree.AnnotateTypeExpr{Expr: sqlDollar[3].union.expr(), Type: sqlDollar[5].union.typeReference(), SyntaxMode: tree.AnnotateExplicit}
 		}
-	case 2655:
+	case 2887:
 		sqlDollar = sqlS[sqlpt-8 : sqlpt+1]
-//line sql-gen.y:15412
+//line sql-gen.y:16652
 		{
 			sqlVAL.union.val = &tree.IfExpr{Cond: sqlDollar[3].union.expr(), True: sqlDollar[5].union.expr(), Else: sqlDollar[7].union.expr()}
 		}
-	case 2656:
+	case 2888:
 		sqlDollar = sqlS[sqlpt-8 : sqlpt+1]
-//line sql-gen.y:15416
+//line sql-gen.y:16656
 		{
 			sqlVAL.union.val = &tree.IfErrExpr{Cond: sqlDollar[3].union.expr(), Else: sqlDollar[5].union.expr(), ErrCode: sqlDollar[7].union.expr()}
 		}
-	case 2657:
+	case 2889:
 		sqlDollar = sqlS[sqlpt-6 : sqlpt+1]
-//line sql-gen.y:15420
+//line sql-gen.y:16660
 		{
 			sqlVAL.union.val = &tree.IfErrExpr{Cond: sqlDollar[3].union.expr(), Else: sqlDollar[5].union.expr()}
 		}
-	case 2658:
+	case 2890:
 		sqlDollar = sqlS[sqlpt-4 : sqlpt+1]
-//line sql-gen.y:15424
+//line sql-gen.y:16664
 		{
 			sqlVAL.union.val = &tree.IfErrExpr{Cond: sqlDollar[3].union.expr()}
 		}
-	case 2659:
+	case 2891:
 		sqlDollar = sqlS[sqlpt-6 : sqlpt+1]
-//line sql-gen.y:15428
+//line sql-gen.y:16668
 		{
 			sqlVAL.union.val = &tree.IfErrExpr{Cond: sqlDollar[3].union.expr(), ErrCode: sqlDollar[5].union.expr()}
 		}
-	case 2660:
+	case 2892:
 		sqlDollar = sqlS[sqlpt-6 : sqlpt+1]
-//line sql-gen.y:15432
+//line sql-gen.y:16672
 		{
 			sqlVAL.union.val = &tree.NullIfExpr{Expr1: sqlDollar[3].union.expr(), Expr2: sqlDollar[5].union.expr()}
 		}
-	case 2661:
+	case 2893:
 		sqlDollar = sqlS[sqlpt-6 : sqlpt+1]
-//line sql-gen.y:15436
+//line sql-gen.y:16676
 		{
 			sqlVAL.union.val = &tree.CoalesceExpr{Name: "IFNULL", Exprs: tree.Exprs{sqlDollar[3].union.expr(), sqlDollar[5].union.expr()}}
 		}
-	case 2662:
+	case 2894:
 		sqlDollar = sqlS[sqlpt-4 : sqlpt+1]
-//line sql-gen.y:15440
+//line sql-gen.y:16680
 		{
 			sqlVAL.union.val = &tree.CoalesceExpr{Name: "COALESCE", Exprs: sqlDollar[3].union.exprs()}
 		}
-	case 2664:
+	case 2896:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:15447
+//line sql-gen.y:16687
 		{
 			sqlVAL.union.val = &tree.FuncExpr{Func: tree.WrapFunction(sqlDollar[1].str)}
 		}
-	case 2665:
+	case 2897:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:15450
+//line sql-gen.y:16690
 		{
 			return helpWithFunctionByName(sqllex, sqlDollar[1].str)
 		}
-	case 2666:
+	case 2898:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:15452
+//line sql-gen.y:16692
 		{
 			sqlVAL.union.val = &tree.FuncExpr{Func: tree.WrapFunction(sqlDollar[1].str)}
 		}
-	case 2667:
+	case 2899:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:15455
+//line sql-gen.y:16695
 		{
 			return helpWithFunctionByName(sqllex, sqlDollar[1].str)
 		}
-	case 2668:
+	case 2900:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:15457
+//line sql-gen.y:16697
 		{
 			sqlVAL.union.val = &tree.FuncExpr{Func: tree.WrapFunction(sqlDollar[1].str)}
 		}
-	case 2669:
+	case 2901:
 		sqlDollar = sqlS[sqlpt-4 : sqlpt+1]
-//line sql-gen.y:15461
+//line sql-gen.y:16701
 		{
 			sqlVAL.union.val = &tree.FuncExpr{Func: tree.WrapFunction(sqlDollar[1].str), Exprs: tree.Exprs{sqlDollar[3].union.expr()}}
 		}
-	case 2670:
+	case 2902:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:15464
+//line sql-gen.y:16704
 		{
 			return helpWithFunctionByName(sqllex, sqlDollar[1].str)
 		}
-	case 2671:
+	case 2903:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:15466
+//line sql-gen.y:16706
 		{
 			sqlVAL.union.val = &tree.FuncExpr{Func: tree.WrapFunction(sqlDollar[1].str)}
 		}
-	case 2672:
+	case 2904:
 		sqlDollar = sqlS[sqlpt-4 : sqlpt+1]
-//line sql-gen.y:15470
+//line sql-gen.y:16710
 		{
 			sqlVAL.union.val = &tree.FuncExpr{Func: tree.WrapFunction(sqlDollar[1].str), Exprs: tree.Exprs{sqlDollar[3].union.expr()}}
 		}
-	case 2673:
+	case 2905:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:15473
+//line sql-gen.y:16713
 		{
 			return helpWithFunctionByName(sqllex, sqlDollar[1].str)
 		}
-	case 2674:
+	case 2906:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:15475
+//line sql-gen.y:16715
 		{
 			sqlVAL.union.val = &tree.FuncExpr{Func: tree.WrapFunction(sqlDollar[1].str)}
 		}
-	case 2675:
+	case 2907:
 		sqlDollar = sqlS[sqlpt-4 : sqlpt+1]
-//line sql-gen.y:15479
+//line sql-gen.y:16719
 		{
 			sqlVAL.union.val = &tree.FuncExpr{Func: tree.WrapFunction(sqlDollar[1].str), Exprs: tree.Exprs{sqlDollar[3].union.expr()}}
 		}
-	case 2676:
+	case 2908:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:15482
+//line sql-gen.y:16722
 		{
 			return helpWithFunctionByName(sqllex, sqlDollar[1].str)
 		}
-	case 2677:
+	case 2909:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:15484
+//line sql-gen.y:16724
 		{
 			sqlVAL.union.val = &tree.FuncExpr{Func: tree.WrapFunction(sqlDollar[1].str)}
 		}
-	case 2678:
+	case 2910:
 		sqlDollar = sqlS[sqlpt-4 : sqlpt+1]
-//line sql-gen.y:15488
+//line sql-gen.y:16728
 		{
 			sqlVAL.union.val = &tree.FuncExpr{Func: tree.WrapFunction(sqlDollar[1].str), Exprs: tree.Exprs{sqlDollar[3].union.expr()}}
 		}
-	case 2679:
+	case 2911:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:15491
+//line sql-gen.y:16731
 		{
 			return helpWithFunctionByName(sqllex, sqlDollar[1].str)
 		}
-	case 2680:
+	case 2912:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:15493
+//line sql-gen.y:16733
 		{
 			sqlVAL.union.val = &tree.FuncExpr{Func: tree.WrapFunction(sqlDollar[1].str)}
 		}
-	case 2681:
+	case 2913:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:15496
+//line sql-gen.y:16736
 		{
 			return helpWithFunctionByName(sqllex, sqlDollar[1].str)
 		}
-	case 2682:
+	case 2914:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:15498
+//line sql-gen.y:16738
 		{
 			sqlVAL.union.val = &tree.FuncExpr{Func: tree.WrapFunction(sqlDollar[1].str)}
 		}
-	case 2683:
+	case 2915:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:15501
+//line sql-gen.y:16741
 		{
 			return helpWithFunctionByName(sqllex, sqlDollar[1].str)
 		}
-	case 2684:
+	case 2916:
 		sqlDollar = sqlS[sqlpt-4 : sqlpt+1]
-//line sql-gen.y:15503
+//line sql-gen.y:16743
 		{
 			sqlVAL.union.val = &tree.FuncExpr{Func: tree.WrapFunction(sqlDollar[1].str), Exprs: sqlDollar[3].union.exprs()}
 		}
-	case 2685:
+	case 2917:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:15506
+//line sql-gen.y:16746
 		{
 			return helpWithFunctionByName(sqllex, sqlDollar[1].str)
 		}
-	case 2686:
+	case 2918:
 		sqlDollar = sqlS[sqlpt-4 : sqlpt+1]
-//line sql-gen.y:15508
+//line sql-gen.y:16748
 		{
 			sqlVAL.union.val = &tree.FuncExpr{Func: tree.WrapFunction(sqlDollar[1].str), Exprs: sqlDollar[3].union.exprs()}
 		}
-	case 2687:
+	case 2919:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:15511
+//line sql-gen.y:16751
 		{
 			return helpWithFunctionByName(sqllex, sqlDollar[1].str)
 		}
-	case 2688:
+	case 2920:
 		sqlDollar = sqlS[sqlpt-4 : sqlpt+1]
-//line sql-gen.y:15513
+//line sql-gen.y:16753
 		{
 			sqlVAL.union.val = &tree.FuncExpr{Func: tree.WrapFunction(sqlDollar[1].str), Exprs: sqlDollar[3].union.exprs()}
 		}
-	case 2689:
+	case 2921:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:15516
+//line sql-gen.y:16756
 		{
 			return helpWithFunctionByName(sqllex, sqlDollar[1].str)
 		}
-	case 2690:
+	case 2922:
 		sqlDollar = sqlS[sqlpt-4 : sqlpt+1]
-//line sql-gen.y:15518
+//line sql-gen.y:16758
 		{
 			sqlVAL.union.val = &tree.FuncExpr{Func: tree.WrapFunction("strpos"), Exprs: sqlDollar[3].union.exprs()}
 		}
-	case 2691:
+	case 2923:
 		sqlDollar = sqlS[sqlpt-4 : sqlpt+1]
-//line sql-gen.y:15522
+//line sql-gen.y:16762
 		{
 			sqlVAL.union.val = &tree.FuncExpr{Func: tree.WrapFunction(sqlDollar[1].str), Exprs: sqlDollar[3].union.exprs()}
 		}
-	case 2692:
+	case 2924:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:15525
+//line sql-gen.y:16765
 		{
 			return helpWithFunctionByName(sqllex, sqlDollar[1].str)
 		}
-	case 2693:
+	case 2925:
 		sqlDollar = sqlS[sqlpt-6 : sqlpt+1]
-//line sql-gen.y:15526
+//line sql-gen.y:16766
 		{
 			return unimplemented(sqllex, "treat")
 		}
-	case 2694:
+	case 2926:
 		sqlDollar = sqlS[sqlpt-5 : sqlpt+1]
-//line sql-gen.y:15528
+//line sql-gen.y:16768
 		{
 			sqlVAL.union.val = &tree.FuncExpr{Func: tree.WrapFunction("btrim"), Exprs: sqlDollar[4].union.exprs()}
 		}
-	case 2695:
+	case 2927:
 		sqlDollar = sqlS[sqlpt-5 : sqlpt+1]
-//line sql-gen.y:15532
+//line sql-gen.y:16772
 		{
 			sqlVAL.union.val = &tree.FuncExpr{Func: tree.WrapFunction("ltrim"), Exprs: sqlDollar[4].union.exprs()}
 		}
-	case 2696:
+	case 2928:
 		sqlDollar = sqlS[sqlpt-5 : sqlpt+1]
-//line sql-gen.y:15536
+//line sql-gen.y:16776
 		{
 			sqlVAL.union.val = &tree.FuncExpr{Func: tree.WrapFunction("rtrim"), Exprs: sqlDollar[4].union.exprs()}
 		}
-	case 2697:
+	case 2929:
 		sqlDollar = sqlS[sqlpt-4 : sqlpt+1]
-//line sql-gen.y:15540
+//line sql-gen.y:16780
 		{
 			sqlVAL.union.val = &tree.FuncExpr{Func: tree.WrapFunction("btrim"), Exprs: sqlDollar[3].union.exprs()}
 		}
-	case 2698:
+	case 2930:
 		sqlDollar = sqlS[sqlpt-4 : sqlpt+1]
-//line sql-gen.y:15544
+//line sql-gen.y:16784
 		{
 			sqlVAL.union.val = &tree.FuncExpr{Func: tree.WrapFunction(sqlDollar[1].str), Exprs: sqlDollar[3].union.exprs()}
 		}
-	case 2699:
+	case 2931:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:15547
+//line sql-gen.y:16787
 		{
 			return helpWithFunctionByName(sqllex, sqlDollar[1].str)
 		}
-	case 2700:
+	case 2932:
 		sqlDollar = sqlS[sqlpt-4 : sqlpt+1]
-//line sql-gen.y:15549
+//line sql-gen.y:16789
 		{
 			sqlVAL.union.val = &tree.FuncExpr{Func: tree.WrapFunction(sqlDollar[1].str), Exprs: sqlDollar[3].union.exprs()}
 		}
-	case 2701:
+	case 2933:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:15552
+//line sql-gen.y:16792
 		{
 			return helpWithFunctionByName(sqllex, sqlDollar[1].str)
 		}
-	case 2702:
+	case 2934:
 		sqlDollar = sqlS[sqlpt-5 : sqlpt+1]
-//line sql-gen.y:15558
+//line sql-gen.y:16798
 		{
 			sqlVAL.union.val = &tree.FuncExpr{OrderBy: sqlDollar[4].union.orderBy(), AggType: tree.OrderedSetAgg}
 		}
-	case 2703:
+	case 2935:
 		sqlDollar = sqlS[sqlpt-0 : sqlpt+1]
-//line sql-gen.y:15562
+//line sql-gen.y:16802
 		{
 			sqlVAL.union.val = &tree.FuncExpr{}
 		}
-	case 2704:
+	case 2936:
 		sqlDollar = sqlS[sqlpt-5 : sqlpt+1]
-//line sql-gen.y:15568
+//line sql-gen.y:16808
 		{
 			sqlVAL.union.val = sqlDollar[4].union.expr()
 		}
-	case 2705:
+	case 2937:
 		sqlDollar = sqlS[sqlpt-0 : sqlpt+1]
-//line sql-gen.y:15572
+//line sql-gen.y:16812
 		{
 			sqlVAL.union.val = tree.Expr(nil)
 		}
-	case 2706:
+	case 2938:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:15579
+//line sql-gen.y:16819
 		{
 			sqlVAL.union.val = sqlDollar[2].union.window()
 		}
-	case 2707:
+	case 2939:
 		sqlDollar = sqlS[sqlpt-0 : sqlpt+1]
-//line sql-gen.y:15583
+//line sql-gen.y:16823
 		{
 			sqlVAL.union.val = tree.Window(nil)
 		}
-	case 2708:
+	case 2940:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:15589
+//line sql-gen.y:16829
 		{
 			sqlVAL.union.val = tree.Window{sqlDollar[1].union.windowDef()}
 		}
-	case 2709:
+	case 2941:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:15593
+//line sql-gen.y:16833
 		{
 			sqlVAL.union.val = append(sqlDollar[1].union.window(), sqlDollar[3].union.windowDef())
 		}
-	case 2710:
+	case 2942:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:15599
+//line sql-gen.y:16839
 		{
 			n := sqlDollar[3].union.windowDef()
 			n.Name = tree.Name(sqlDollar[1].str)
 			sqlVAL.union.val = n
 		}
-	case 2711:
+	case 2943:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:15607
+//line sql-gen.y:16847
 		{
 			sqlVAL.union.val = sqlDollar[2].union.windowDef()
 		}
-	case 2712:
+	case 2944:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:15611
+//line sql-gen.y:16851
 		{
 			sqlVAL.union.val = &tree.WindowDef{Name: tree.Name(sqlDollar[2].str)}
 		}
-	case 2713:
+	case 2945:
 		sqlDollar = sqlS[sqlpt-0 : sqlpt+1]
-//line sql-gen.y:15615
+//line sql-gen.y:16855
 		{
 			sqlVAL.union.val = (*tree.WindowDef)(nil)
 		}
-	case 2714:
+	case 2946:
 		sqlDollar = sqlS[sqlpt-6 : sqlpt+1]
-//line sql-gen.y:15622
+//line sql-gen.y:16862
 		{
 			sqlVAL.union.val = &tree.WindowDef{
 				RefName:    tree.Name(sqlDollar[2].str),
@@ -46018,27 +49956,27 @@ sqldefault:
 				Frame:      sqlDollar[5].union.windowFrame(),
 			}
 		}
-	case 2716:
+	case 2948:
 		sqlDollar = sqlS[sqlpt-0 : sqlpt+1]
-//line sql-gen.y:15642
+//line sql-gen.y:16882
 		{
 			sqlVAL.str = ""
 		}
-	case 2717:
+	case 2949:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:15648
+//line sql-gen.y:16888
 		{
 			sqlVAL.union.val = sqlDollar[3].union.exprs()
 		}
-	case 2718:
+	case 2950:
 		sqlDollar = sqlS[sqlpt-0 : sqlpt+1]
-//line sql-gen.y:15652
+//line sql-gen.y:16892
 		{
 			sqlVAL.union.val = tree.Exprs(nil)
 		}
-	case 2719:
+	case 2951:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:15658
+//line sql-gen.y:16898
 		{
 			sqlVAL.union.val = &tree.WindowFrame{
 				Mode:      treewindow.RANGE,
@@ -46046,9 +49984,9 @@ sqldefault:
 				Exclusion: sqlDollar[3].union.windowFrameExclusion(),
 			}
 		}
-	case 2720:
+	case 2952:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:15666
+//line sql-gen.y:16906
 		{
 			sqlVAL.union.val = &tree.WindowFrame{
 				Mode:      treewindow.ROWS,
@@ -46056,9 +49994,9 @@ sqldefault:
 				Exclusion: sqlDollar[3].union.windowFrameExclusion(),
 			}
 		}
-	case 2721:
+	case 2953:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:15674
+//line sql-gen.y:16914
 		{
 			sqlVAL.union.val = &tree.WindowFrame{
 				Mode:      treewindow.GROUPS,
@@ -46066,15 +50004,15 @@ sqldefault:
 				Exclusion: sqlDollar[3].union.windowFrameExclusion(),
 			}
 		}
-	case 2722:
+	case 2954:
 		sqlDollar = sqlS[sqlpt-0 : sqlpt+1]
-//line sql-gen.y:15682
+//line sql-gen.y:16922
 		{
 			sqlVAL.union.val = (*tree.WindowFrame)(nil)
 		}
-	case 2723:
+	case 2955:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:15688
+//line sql-gen.y:16928
 		{
 			startBound := sqlDollar[1].union.windowFrameBound()
 			switch {
@@ -46087,9 +50025,9 @@ sqldefault:
 			}
 			sqlVAL.union.val = tree.WindowFrameBounds{StartBound: startBound}
 		}
-	case 2724:
+	case 2956:
 		sqlDollar = sqlS[sqlpt-4 : sqlpt+1]
-//line sql-gen.y:15701
+//line sql-gen.y:16941
 		{
 			startBound := sqlDollar[2].union.windowFrameBound()
 			endBound := sqlDollar[4].union.windowFrameBound()
@@ -46112,88 +50050,88 @@ sqldefault:
 			}
 			sqlVAL.union.val = tree.WindowFrameBounds{StartBound: startBound, EndBound: endBound}
 		}
-	case 2725:
+	case 2957:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:15729
+//line sql-gen.y:16969
 		{
 			sqlVAL.union.val = &tree.WindowFrameBound{BoundType: treewindow.UnboundedPreceding}
 		}
-	case 2726:
+	case 2958:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:15733
+//line sql-gen.y:16973
 		{
 			sqlVAL.union.val = &tree.WindowFrameBound{BoundType: treewindow.UnboundedFollowing}
 		}
-	case 2727:
+	case 2959:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:15737
+//line sql-gen.y:16977
 		{
 			sqlVAL.union.val = &tree.WindowFrameBound{BoundType: treewindow.CurrentRow}
 		}
-	case 2728:
+	case 2960:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:15741
+//line sql-gen.y:16981
 		{
 			sqlVAL.union.val = &tree.WindowFrameBound{
 				OffsetExpr: sqlDollar[1].union.expr(),
 				BoundType:  treewindow.OffsetPreceding,
 			}
 		}
-	case 2729:
+	case 2961:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:15748
+//line sql-gen.y:16988
 		{
 			sqlVAL.union.val = &tree.WindowFrameBound{
 				OffsetExpr: sqlDollar[1].union.expr(),
 				BoundType:  treewindow.OffsetFollowing,
 			}
 		}
-	case 2730:
+	case 2962:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:15757
+//line sql-gen.y:16997
 		{
 			sqlVAL.union.val = treewindow.ExcludeCurrentRow
 		}
-	case 2731:
+	case 2963:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:15761
+//line sql-gen.y:17001
 		{
 			sqlVAL.union.val = treewindow.ExcludeGroup
 		}
-	case 2732:
+	case 2964:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:15765
+//line sql-gen.y:17005
 		{
 			sqlVAL.union.val = treewindow.ExcludeTies
 		}
-	case 2733:
+	case 2965:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:15769
+//line sql-gen.y:17009
 		{
 
 			sqlVAL.union.val = treewindow.NoExclusion
 		}
-	case 2734:
+	case 2966:
 		sqlDollar = sqlS[sqlpt-0 : sqlpt+1]
-//line sql-gen.y:15774
+//line sql-gen.y:17014
 		{
 			sqlVAL.union.val = treewindow.NoExclusion
 		}
-	case 2735:
+	case 2967:
 		sqlDollar = sqlS[sqlpt-4 : sqlpt+1]
-//line sql-gen.y:15787
+//line sql-gen.y:17027
 		{
 			sqlVAL.union.val = &tree.Tuple{Exprs: sqlDollar[3].union.exprs(), Row: true}
 		}
-	case 2736:
+	case 2968:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:15791
+//line sql-gen.y:17031
 		{
 			sqlVAL.union.val = sqlDollar[1].union.tuple()
 		}
-	case 2738:
+	case 2970:
 		sqlDollar = sqlS[sqlpt-5 : sqlpt+1]
-//line sql-gen.y:15798
+//line sql-gen.y:17038
 		{
 			t := sqlDollar[2].union.tuple()
 			labels := sqlDollar[4].union.nameList()
@@ -46203,243 +50141,261 @@ sqldefault:
 			}
 			sqlVAL.union.val = t
 		}
-	case 2739:
+	case 2971:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:15810
+//line sql-gen.y:17050
 		{
 			sqlVAL.union.val = treecmp.MakeComparisonOperator(treecmp.Any)
 		}
-	case 2740:
+	case 2972:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:15814
+//line sql-gen.y:17054
 		{
 			sqlVAL.union.val = treecmp.MakeComparisonOperator(treecmp.Some)
 		}
-	case 2741:
+	case 2973:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:15818
+//line sql-gen.y:17058
 		{
 			sqlVAL.union.val = treecmp.MakeComparisonOperator(treecmp.All)
 		}
-	case 2742:
+	case 2974:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:15834
+//line sql-gen.y:17074
 		{
 			sqlVAL.union.val = treebin.MakeBinaryOperator(treebin.Plus)
 		}
-	case 2743:
+	case 2975:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:15835
+//line sql-gen.y:17075
 		{
 			sqlVAL.union.val = treebin.MakeBinaryOperator(treebin.Minus)
 		}
-	case 2744:
+	case 2976:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:15836
+//line sql-gen.y:17076
 		{
 			sqlVAL.union.val = treebin.MakeBinaryOperator(treebin.Mult)
 		}
-	case 2745:
+	case 2977:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:15837
+//line sql-gen.y:17077
 		{
 			sqlVAL.union.val = treebin.MakeBinaryOperator(treebin.Div)
 		}
-	case 2746:
+	case 2978:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:15838
+//line sql-gen.y:17078
 		{
 			sqlVAL.union.val = treebin.MakeBinaryOperator(treebin.Mod)
 		}
-	case 2747:
+	case 2979:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:15839
+//line sql-gen.y:17079
 		{
 			sqlVAL.union.val = treebin.MakeBinaryOperator(treebin.Pow)
 		}
-	case 2748:
+	case 2980:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:15840
+//line sql-gen.y:17080
 		{
 			sqlVAL.union.val = treecmp.MakeComparisonOperator(treecmp.LT)
 		}
-	case 2749:
+	case 2981:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:15841
+//line sql-gen.y:17081
 		{
 			sqlVAL.union.val = treecmp.MakeComparisonOperator(treecmp.GT)
 		}
-	case 2750:
+	case 2982:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:15842
+//line sql-gen.y:17082
 		{
 			sqlVAL.union.val = treecmp.MakeComparisonOperator(treecmp.EQ)
 		}
-	case 2751:
+	case 2983:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:15843
+//line sql-gen.y:17083
 		{
 			sqlVAL.union.val = treecmp.MakeComparisonOperator(treecmp.LE)
 		}
-	case 2752:
+	case 2984:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:15844
+//line sql-gen.y:17084
 		{
 			sqlVAL.union.val = treecmp.MakeComparisonOperator(treecmp.GE)
 		}
-	case 2753:
+	case 2985:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:15845
+//line sql-gen.y:17085
 		{
 			sqlVAL.union.val = treecmp.MakeComparisonOperator(treecmp.NE)
 		}
-	case 2754:
+	case 2986:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:15847
+//line sql-gen.y:17087
 		{
 			sqlVAL.union.val = treecmp.MakeComparisonOperator(treecmp.JSONExists)
 		}
-	case 2755:
+	case 2987:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:15848
+//line sql-gen.y:17088
 		{
 			sqlVAL.union.val = treebin.MakeBinaryOperator(treebin.Bitand)
 		}
-	case 2756:
+	case 2988:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:15849
+//line sql-gen.y:17089
 		{
 			sqlVAL.union.val = treebin.MakeBinaryOperator(treebin.Bitor)
 		}
-	case 2757:
+	case 2989:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:15850
+//line sql-gen.y:17090
 		{
 			sqlVAL.union.val = treebin.MakeBinaryOperator(treebin.Bitxor)
 		}
-	case 2758:
+	case 2990:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:15851
+//line sql-gen.y:17091
 		{
 			sqlVAL.union.val = treebin.MakeBinaryOperator(treebin.FloorDiv)
 		}
-	case 2759:
+	case 2991:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:15852
+//line sql-gen.y:17092
 		{
 			sqlVAL.union.val = treecmp.MakeComparisonOperator(treecmp.Contains)
 		}
-	case 2760:
+	case 2992:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:15853
+//line sql-gen.y:17093
 		{
 			sqlVAL.union.val = treecmp.MakeComparisonOperator(treecmp.ContainedBy)
 		}
-	case 2761:
+	case 2993:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:15854
+//line sql-gen.y:17094
 		{
 			sqlVAL.union.val = treebin.MakeBinaryOperator(treebin.LShift)
 		}
-	case 2762:
+	case 2994:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:15855
+//line sql-gen.y:17095
 		{
 			sqlVAL.union.val = treebin.MakeBinaryOperator(treebin.RShift)
 		}
-	case 2763:
+	case 2995:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:15856
+//line sql-gen.y:17096
 		{
 			sqlVAL.union.val = treebin.MakeBinaryOperator(treebin.Concat)
 		}
-	case 2764:
+	case 2996:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:15857
+//line sql-gen.y:17097
 		{
 			sqlVAL.union.val = treebin.MakeBinaryOperator(treebin.JSONFetchVal)
 		}
-	case 2765:
+	case 2997:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:15858
+//line sql-gen.y:17098
 		{
 			sqlVAL.union.val = treebin.MakeBinaryOperator(treebin.JSONFetchText)
 		}
-	case 2766:
+	case 2998:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:15859
+//line sql-gen.y:17099
 		{
 			sqlVAL.union.val = treebin.MakeBinaryOperator(treebin.JSONFetchValPath)
 		}
-	case 2767:
+	case 2999:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:15860
+//line sql-gen.y:17100
 		{
 			sqlVAL.union.val = treebin.MakeBinaryOperator(treebin.JSONFetchTextPath)
 		}
-	case 2768:
+	case 3000:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:15861
+//line sql-gen.y:17101
 		{
 			sqlVAL.union.val = treecmp.MakeComparisonOperator(treecmp.JSONSomeExists)
 		}
-	case 2769:
+	case 3001:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:15862
+//line sql-gen.y:17102
 		{
 			sqlVAL.union.val = treecmp.MakeComparisonOperator(treecmp.JSONAllExists)
 		}
-	case 2770:
+	case 3002:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:15863
+//line sql-gen.y:17103
 		{
 			sqlVAL.union.val = treecmp.MakeComparisonOperator(treecmp.NotRegMatch)
 		}
-	case 2771:
+	case 3003:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:15864
+//line sql-gen.y:17104
 		{
 			sqlVAL.union.val = treecmp.MakeComparisonOperator(treecmp.RegIMatch)
 		}
-	case 2772:
+	case 3004:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:15865
+//line sql-gen.y:17105
 		{
 			sqlVAL.union.val = treecmp.MakeComparisonOperator(treecmp.NotRegIMatch)
 		}
-	case 2773:
+	case 3005:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:15866
+//line sql-gen.y:17106
 		{
 			sqlVAL.union.val = treecmp.MakeComparisonOperator(treecmp.Overlaps)
 		}
-	case 2774:
+	case 3006:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:15867
+//line sql-gen.y:17107
 		{
 			sqlVAL.union.val = treecmp.MakeComparisonOperator(treecmp.TSMatches)
 		}
-	case 2775:
+	case 3007:
+		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
+//line sql-gen.y:17108
+		{
+			sqlVAL.union.val = treebin.MakeBinaryOperator(treebin.Distance)
+		}
+	case 3008:
+		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
+//line sql-gen.y:17109
+		{
+			sqlVAL.union.val = treebin.MakeBinaryOperator(treebin.CosDistance)
+		}
+	case 3009:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:15868
+//line sql-gen.y:17110
+		{
+			sqlVAL.union.val = treebin.MakeBinaryOperator(treebin.NegInnerProduct)
+		}
+	case 3010:
+		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
+//line sql-gen.y:17111
 		{
 			sqlVAL.union.val = tree.MakeUnaryOperator(tree.UnaryComplement)
 		}
-	case 2776:
+	case 3011:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:15869
+//line sql-gen.y:17112
 		{
 			sqlVAL.union.val = tree.MakeUnaryOperator(tree.UnarySqrt)
 		}
-	case 2777:
+	case 3012:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:15870
+//line sql-gen.y:17113
 		{
 			sqlVAL.union.val = tree.MakeUnaryOperator(tree.UnaryCbrt)
 		}
-	case 2779:
+	case 3014:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:15875
+//line sql-gen.y:17118
 		{
 
 			if sqlDollar[1].str != "pg_catalog" {
@@ -46447,403 +50403,415 @@ sqldefault:
 			}
 			sqlVAL.union = sqlDollar[3].union
 		}
-	case 2780:
+	case 3015:
 		sqlDollar = sqlS[sqlpt-4 : sqlpt+1]
-//line sql-gen.y:15891
+//line sql-gen.y:17134
 		{
 			sqlVAL.union = sqlDollar[3].union
 		}
-	case 2783:
+	case 3018:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:15898
+//line sql-gen.y:17141
 		{
 			sqlVAL.union.val = treecmp.MakeComparisonOperator(treecmp.Like)
 		}
-	case 2784:
+	case 3019:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:15899
+//line sql-gen.y:17142
 		{
 			sqlVAL.union.val = treecmp.MakeComparisonOperator(treecmp.NotLike)
 		}
-	case 2785:
+	case 3020:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:15900
+//line sql-gen.y:17143
 		{
 			sqlVAL.union.val = treecmp.MakeComparisonOperator(treecmp.ILike)
 		}
-	case 2786:
+	case 3021:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:15901
+//line sql-gen.y:17144
 		{
 			sqlVAL.union.val = treecmp.MakeComparisonOperator(treecmp.NotILike)
 		}
-	case 2787:
+	case 3022:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:15924
+//line sql-gen.y:17167
 		{
 			sqlVAL.union.val = &tree.Tuple{}
 		}
-	case 2788:
+	case 3023:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:15928
+//line sql-gen.y:17171
 		{
 			sqlVAL.union.val = &tree.Tuple{Exprs: sqlDollar[2].union.exprs()}
 		}
-	case 2789:
+	case 3024:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:15934
+//line sql-gen.y:17177
 		{
 			sqlVAL.union.val = tree.Exprs{sqlDollar[1].union.expr()}
 		}
-	case 2790:
+	case 3025:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:15938
+//line sql-gen.y:17181
 		{
 			sqlVAL.union.val = tree.Exprs{sqlDollar[1].union.expr()}
 		}
-	case 2791:
+	case 3026:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:15942
+//line sql-gen.y:17185
 		{
 			sqlVAL.union.val = append(tree.Exprs{sqlDollar[1].union.expr()}, sqlDollar[3].union.exprs()...)
 		}
-	case 2792:
+	case 3027:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:15953
+//line sql-gen.y:17196
 		{
 			sqlVAL.union.val = &tree.Tuple{}
 		}
-	case 2793:
+	case 3028:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:15957
+//line sql-gen.y:17200
 		{
 			sqlVAL.union.val = &tree.Tuple{Exprs: sqlDollar[2].union.exprs()}
 		}
-	case 2794:
+	case 3029:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:15963
+//line sql-gen.y:17206
 		{
 			sqlVAL.union.val = tree.Exprs{sqlDollar[1].union.expr()}
 		}
-	case 2795:
+	case 3030:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:15967
+//line sql-gen.y:17210
 		{
 			sqlVAL.union.val = append(tree.Exprs{sqlDollar[1].union.expr()}, sqlDollar[3].union.exprs()...)
 		}
-	case 2797:
+	case 3032:
 		sqlDollar = sqlS[sqlpt-0 : sqlpt+1]
-//line sql-gen.y:15974
+//line sql-gen.y:17217
 		{
 			sqlVAL.union.val = tree.Exprs(nil)
 		}
-	case 2798:
+	case 3033:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:15980
+//line sql-gen.y:17223
 		{
 			sqlVAL.union.val = tree.Exprs{sqlDollar[1].union.expr()}
 		}
-	case 2799:
+	case 3034:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:15984
+//line sql-gen.y:17227
 		{
 			sqlVAL.union.val = append(sqlDollar[1].union.exprs(), sqlDollar[3].union.expr())
 		}
-	case 2800:
+	case 3035:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:15990
+//line sql-gen.y:17233
 		{
 			sqlVAL.union.val = []tree.ResolvableTypeReference{sqlDollar[1].union.typeReference()}
 		}
-	case 2801:
+	case 3036:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:15994
+//line sql-gen.y:17237
 		{
 			sqlVAL.union.val = append(sqlDollar[1].union.typeReferences(), sqlDollar[3].union.typeReference())
 		}
-	case 2802:
+	case 3037:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:16000
+//line sql-gen.y:17243
 		{
 			sqlVAL.union.val = &tree.Array{Exprs: sqlDollar[2].union.exprs()}
 		}
-	case 2803:
+	case 3038:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:16004
+//line sql-gen.y:17247
 		{
 			sqlVAL.union.val = &tree.Array{Exprs: sqlDollar[2].union.exprs()}
 		}
-	case 2804:
+	case 3039:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:16010
+//line sql-gen.y:17253
 		{
 			sqlVAL.union.val = tree.Exprs{sqlDollar[1].union.expr()}
 		}
-	case 2805:
+	case 3040:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:16014
+//line sql-gen.y:17257
 		{
 			sqlVAL.union.val = append(sqlDollar[1].union.exprs(), sqlDollar[3].union.expr())
 		}
-	case 2806:
+	case 3041:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:16020
+//line sql-gen.y:17263
 		{
 			sqlVAL.union.val = tree.Exprs{tree.NewStrVal(strings.ToLower(sqlDollar[1].str)), sqlDollar[3].union.expr()}
 		}
-	case 2807:
+	case 3042:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:16024
+//line sql-gen.y:17267
 		{
 			sqlVAL.union.val = sqlDollar[1].union.exprs()
 		}
-	case 2816:
+	case 3051:
 		sqlDollar = sqlS[sqlpt-4 : sqlpt+1]
-//line sql-gen.y:16047
+//line sql-gen.y:17290
 		{
 			sqlVAL.union.val = tree.Exprs{sqlDollar[1].union.expr(), sqlDollar[2].union.expr(), sqlDollar[3].union.expr(), sqlDollar[4].union.expr()}
 		}
-	case 2817:
+	case 3052:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:16051
+//line sql-gen.y:17294
 		{
 			sqlVAL.union.val = tree.Exprs{sqlDollar[1].union.expr(), sqlDollar[2].union.expr(), sqlDollar[3].union.expr()}
 		}
-	case 2818:
+	case 3053:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:16055
+//line sql-gen.y:17298
 		{
 			sqlVAL.union.val = sqlDollar[1].union.exprs()
 		}
-	case 2819:
+	case 3054:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:16061
+//line sql-gen.y:17304
 		{
 			sqlVAL.union.val = sqlDollar[2].union.expr()
 		}
-	case 2820:
+	case 3055:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:16068
+//line sql-gen.y:17311
 		{
 			sqlVAL.union.val = tree.Exprs{sqlDollar[3].union.expr(), sqlDollar[1].union.expr()}
 		}
-	case 2821:
+	case 3056:
 		sqlDollar = sqlS[sqlpt-0 : sqlpt+1]
-//line sql-gen.y:16072
+//line sql-gen.y:17315
 		{
 			sqlVAL.union.val = tree.Exprs(nil)
 		}
-	case 2822:
+	case 3057:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:16089
+//line sql-gen.y:17332
 		{
 			sqlVAL.union.val = tree.Exprs{sqlDollar[1].union.expr(), sqlDollar[2].union.expr(), sqlDollar[3].union.expr()}
 		}
-	case 2823:
+	case 3058:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:16093
+//line sql-gen.y:17336
 		{
 			sqlVAL.union.val = tree.Exprs{sqlDollar[1].union.expr(), sqlDollar[3].union.expr(), sqlDollar[2].union.expr()}
 		}
-	case 2824:
+	case 3059:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:16097
+//line sql-gen.y:17340
 		{
 			sqlVAL.union.val = tree.Exprs{sqlDollar[1].union.expr(), sqlDollar[2].union.expr()}
 		}
-	case 2825:
+	case 3060:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:16101
+//line sql-gen.y:17344
 		{
 			sqlVAL.union.val = tree.Exprs{sqlDollar[1].union.expr(), tree.NewDInt(1), sqlDollar[2].union.expr()}
 		}
-	case 2826:
+	case 3061:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:16105
+//line sql-gen.y:17348
 		{
 			sqlVAL.union.val = sqlDollar[1].union.exprs()
 		}
-	case 2827:
+	case 3062:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:16111
+//line sql-gen.y:17354
 		{
 			sqlVAL.union.val = sqlDollar[2].union.expr()
 		}
-	case 2828:
+	case 3063:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:16117
+//line sql-gen.y:17360
 		{
 			sqlVAL.union.val = sqlDollar[2].union.expr()
 		}
-	case 2829:
+	case 3064:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:16123
+//line sql-gen.y:17366
 		{
 			sqlVAL.union.val = append(sqlDollar[3].union.exprs(), sqlDollar[1].union.expr())
 		}
-	case 2830:
+	case 3065:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:16127
+//line sql-gen.y:17370
 		{
 			sqlVAL.union.val = sqlDollar[2].union.exprs()
 		}
-	case 2831:
+	case 3066:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:16131
+//line sql-gen.y:17374
 		{
 			sqlVAL.union.val = sqlDollar[1].union.exprs()
 		}
-	case 2832:
+	case 3067:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:16137
+//line sql-gen.y:17380
 		{
 			sqlVAL.union.val = &tree.Subquery{Select: sqlDollar[1].union.selectStmt()}
 		}
-	case 2834:
+	case 3069:
 		sqlDollar = sqlS[sqlpt-5 : sqlpt+1]
-//line sql-gen.y:16149
+//line sql-gen.y:17392
 		{
 			sqlVAL.union.val = &tree.CaseExpr{Expr: sqlDollar[2].union.expr(), Whens: sqlDollar[3].union.whens(), Else: sqlDollar[4].union.expr()}
 		}
-	case 2835:
+	case 3070:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:16156
+//line sql-gen.y:17399
 		{
 			sqlVAL.union.val = []*tree.When{sqlDollar[1].union.when()}
 		}
-	case 2836:
+	case 3071:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:16160
+//line sql-gen.y:17403
 		{
 			sqlVAL.union.val = append(sqlDollar[1].union.whens(), sqlDollar[2].union.when())
 		}
-	case 2837:
+	case 3072:
 		sqlDollar = sqlS[sqlpt-4 : sqlpt+1]
-//line sql-gen.y:16166
+//line sql-gen.y:17409
 		{
 			sqlVAL.union.val = &tree.When{Cond: sqlDollar[2].union.expr(), Val: sqlDollar[4].union.expr()}
 		}
-	case 2838:
+	case 3073:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:16172
+//line sql-gen.y:17415
 		{
 			sqlVAL.union.val = sqlDollar[2].union.expr()
 		}
-	case 2839:
+	case 3074:
 		sqlDollar = sqlS[sqlpt-0 : sqlpt+1]
-//line sql-gen.y:16176
+//line sql-gen.y:17419
 		{
 			sqlVAL.union.val = tree.Expr(nil)
 		}
-	case 2841:
+	case 3076:
 		sqlDollar = sqlS[sqlpt-0 : sqlpt+1]
-//line sql-gen.y:16183
+//line sql-gen.y:17426
 		{
 			sqlVAL.union.val = tree.Expr(nil)
 		}
-	case 2842:
+	case 3077:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:16189
+//line sql-gen.y:17432
 		{
 			sqlVAL.union.val = &tree.ArraySubscript{Begin: sqlDollar[2].union.expr()}
 		}
-	case 2843:
+	case 3078:
 		sqlDollar = sqlS[sqlpt-5 : sqlpt+1]
-//line sql-gen.y:16193
+//line sql-gen.y:17436
 		{
 			sqlVAL.union.val = &tree.ArraySubscript{Begin: sqlDollar[2].union.expr(), End: sqlDollar[4].union.expr(), Slice: true}
 		}
-	case 2845:
+	case 3080:
 		sqlDollar = sqlS[sqlpt-0 : sqlpt+1]
-//line sql-gen.y:16200
+//line sql-gen.y:17443
 		{
 			sqlVAL.union.val = tree.Expr(nil)
 		}
-	case 2846:
+	case 3081:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:16206
+//line sql-gen.y:17449
 		{
 			sqlVAL.union.val = tree.ArraySubscripts{sqlDollar[1].union.arraySubscript()}
 		}
-	case 2847:
+	case 3082:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:16210
+//line sql-gen.y:17453
 		{
 			sqlVAL.union.val = append(sqlDollar[1].union.arraySubscripts(), sqlDollar[2].union.arraySubscript())
 		}
-	case 2848:
+	case 3083:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:16215
+//line sql-gen.y:17458
 		{
 		}
-	case 2849:
+	case 3084:
 		sqlDollar = sqlS[sqlpt-0 : sqlpt+1]
-//line sql-gen.y:16216
+//line sql-gen.y:17459
 		{
 		}
-	case 2850:
+	case 3085:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:16220
+//line sql-gen.y:17463
 		{
 			sqlVAL.union.val = tree.SelectExprs{sqlDollar[1].union.selExpr()}
 		}
-	case 2851:
+	case 3086:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:16224
+//line sql-gen.y:17467
 		{
 			sqlVAL.union.val = append(sqlDollar[1].union.selExprs(), sqlDollar[3].union.selExpr())
 		}
-	case 2852:
+	case 3087:
+		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
+//line sql-gen.y:17473
+		{
+			sqlVAL.union.val = sqlDollar[1].union.selExprs()
+		}
+	case 3088:
+		sqlDollar = sqlS[sqlpt-0 : sqlpt+1]
+//line sql-gen.y:17477
+		{
+			sqlVAL.union.val = tree.SelectExprs{}
+		}
+	case 3089:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:16230
+//line sql-gen.y:17483
 		{
 			sqlVAL.union.val = tree.SelectExpr{Expr: sqlDollar[1].union.expr(), As: tree.UnrestrictedName(sqlDollar[3].str)}
 		}
-	case 2853:
+	case 3090:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:16239
+//line sql-gen.y:17492
 		{
 			sqlVAL.union.val = tree.SelectExpr{Expr: sqlDollar[1].union.expr(), As: tree.UnrestrictedName(sqlDollar[2].str)}
 		}
-	case 2854:
+	case 3091:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:16243
+//line sql-gen.y:17496
 		{
 			sqlVAL.union.val = tree.SelectExpr{Expr: sqlDollar[1].union.expr()}
 		}
-	case 2855:
+	case 3092:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:16247
+//line sql-gen.y:17500
 		{
 			sqlVAL.union.val = tree.StarSelectExpr()
 		}
-	case 2858:
+	case 3095:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:16259
+//line sql-gen.y:17512
 		{
 			sqlVAL.union.val = tree.TableIndexNames{sqlDollar[1].union.newTableIndexName()}
 		}
-	case 2859:
+	case 3096:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:16263
+//line sql-gen.y:17516
 		{
 			sqlVAL.union.val = append(sqlDollar[1].union.newTableIndexNames(), sqlDollar[3].union.newTableIndexName())
 		}
-	case 2860:
+	case 3097:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:16269
+//line sql-gen.y:17522
 		{
 			sqlVAL.union.val = tree.TablePatterns{sqlDollar[1].union.unresolvedName()}
 		}
-	case 2861:
+	case 3098:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:16273
+//line sql-gen.y:17526
 		{
 			sqlVAL.union.val = append(sqlDollar[1].union.tablePatterns(), sqlDollar[3].union.unresolvedName())
 		}
-	case 2862:
+	case 3099:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:16292
+//line sql-gen.y:17545
 		{
 			name := sqlDollar[1].union.unresolvedObjectName().ToTableName()
 			sqlVAL.union.val = tree.TableIndexName{
@@ -46851,9 +50819,9 @@ sqldefault:
 				Index: tree.UnrestrictedName(sqlDollar[3].str),
 			}
 		}
-	case 2863:
+	case 3100:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:16300
+//line sql-gen.y:17553
 		{
 
 			name := sqlDollar[1].union.unresolvedObjectName().ToTableName()
@@ -46864,79 +50832,79 @@ sqldefault:
 				Index: indexName,
 			}
 		}
-	case 2864:
+	case 3101:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:16323
+//line sql-gen.y:17576
 		{
 			sqlVAL.union.val = sqlDollar[1].union.unresolvedObjectName().ToUnresolvedName()
 		}
-	case 2866:
+	case 3103:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:16332
+//line sql-gen.y:17585
 		{
 			sqlVAL.union.val = sqlDollar[1].union.unresolvedObjectName().ToUnresolvedName()
 		}
-	case 2867:
+	case 3104:
 		sqlDollar = sqlS[sqlpt-5 : sqlpt+1]
-//line sql-gen.y:16336
+//line sql-gen.y:17589
 		{
 			sqlVAL.union.val = &tree.UnresolvedName{Star: true, NumParts: 3, Parts: tree.NameParts{"", sqlDollar[3].str, sqlDollar[1].str}}
 		}
-	case 2868:
+	case 3105:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:16340
+//line sql-gen.y:17593
 		{
 			sqlVAL.union.val = &tree.UnresolvedName{Star: true, NumParts: 2, Parts: tree.NameParts{"", sqlDollar[1].str}}
 		}
-	case 2869:
+	case 3106:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:16344
+//line sql-gen.y:17597
 		{
 			sqlVAL.union.val = &tree.UnresolvedName{Star: true, NumParts: 1}
 		}
-	case 2870:
+	case 3107:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:16350
+//line sql-gen.y:17603
 		{
 			sqlVAL.union.val = tree.NameList{tree.Name(sqlDollar[1].str)}
 		}
-	case 2871:
+	case 3108:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:16354
+//line sql-gen.y:17607
 		{
 			sqlVAL.union.val = append(sqlDollar[1].union.nameList(), tree.Name(sqlDollar[3].str))
 		}
-	case 2876:
+	case 3113:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:16369
+//line sql-gen.y:17622
 		{
 			sqlVAL.union.val = sqlDollar[2].union.numVal()
 		}
-	case 2877:
+	case 3114:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:16373
+//line sql-gen.y:17626
 		{
 			n := sqlDollar[2].union.numVal()
 			n.SetNegative()
 			sqlVAL.union.val = n
 		}
-	case 2880:
+	case 3117:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:16385
+//line sql-gen.y:17638
 		{
 			sqlVAL.union.val = sqlDollar[2].union.numVal()
 		}
-	case 2881:
+	case 3118:
 		sqlDollar = sqlS[sqlpt-2 : sqlpt+1]
-//line sql-gen.y:16389
+//line sql-gen.y:17642
 		{
 			n := sqlDollar[2].union.numVal()
 			n.SetNegative()
 			sqlVAL.union.val = n
 		}
-	case 2882:
+	case 3119:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:16398
+//line sql-gen.y:17651
 		{
 			val, err := sqlDollar[1].union.numVal().AsInt32()
 			if err != nil {
@@ -46944,9 +50912,9 @@ sqldefault:
 			}
 			sqlVAL.union.val = val
 		}
-	case 2883:
+	case 3120:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:16409
+//line sql-gen.y:17662
 		{
 			val, err := sqlDollar[1].union.numVal().AsInt64()
 			if err != nil {
@@ -46954,9 +50922,9 @@ sqldefault:
 			}
 			sqlVAL.union.val = val
 		}
-	case 2884:
+	case 3121:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:16418
+//line sql-gen.y:17671
 		{
 			val, err := sqlDollar[1].union.numVal().AsInt64()
 			if err != nil {
@@ -46964,9 +50932,9 @@ sqldefault:
 			}
 			sqlVAL.union.val = val
 		}
-	case 2885:
+	case 3122:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:16426
+//line sql-gen.y:17679
 		{
 			var t *types.T
 			if sqlDollar[3].union.val == nil {
@@ -46981,9 +50949,9 @@ sqldefault:
 				SyntaxMode: tree.CastShort,
 			}
 		}
-	case 2886:
+	case 3123:
 		sqlDollar = sqlS[sqlpt-5 : sqlpt+1]
-//line sql-gen.y:16443
+//line sql-gen.y:17696
 		{
 			prec := sqlDollar[3].union.int32()
 			if prec < 0 || prec > 6 {
@@ -46999,123 +50967,123 @@ sqldefault:
 				SyntaxMode: tree.CastShort,
 			}
 		}
-	case 2906:
+	case 3143:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:16531
+//line sql-gen.y:17784
 		{
 			sqlVAL.union.val = tree.NameList{tree.Name(sqlDollar[1].str)}
 		}
-	case 2907:
+	case 3144:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:16535
+//line sql-gen.y:17788
 		{
 			sqlVAL.union.val = append(sqlDollar[1].union.nameList(), tree.Name(sqlDollar[3].str))
 		}
-	case 2909:
+	case 3146:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:16543
+//line sql-gen.y:17796
 		{
 			sqlVAL.union.val = tree.ObjectNamePrefix{SchemaName: tree.Name(sqlDollar[1].str), ExplicitSchema: true}
 		}
-	case 2910:
+	case 3147:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:16547
+//line sql-gen.y:17800
 		{
 			sqlVAL.union.val = tree.ObjectNamePrefix{CatalogName: tree.Name(sqlDollar[1].str), SchemaName: tree.Name(sqlDollar[3].str), ExplicitCatalog: true, ExplicitSchema: true}
 		}
-	case 2911:
+	case 3148:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:16553
+//line sql-gen.y:17806
 		{
 			sqlVAL.union.val = tree.ObjectNamePrefixList{sqlDollar[1].union.objectNamePrefix()}
 		}
-	case 2912:
+	case 3149:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:16557
+//line sql-gen.y:17810
 		{
 			sqlVAL.union.val = append(sqlDollar[1].union.objectNamePrefixList(), sqlDollar[3].union.objectNamePrefix())
 		}
-	case 2913:
+	case 3150:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:16563
+//line sql-gen.y:17816
 		{
 			sqlVAL.union.val = tree.ObjectNamePrefixList{sqlDollar[1].union.objectNamePrefix()}
 		}
-	case 2914:
+	case 3151:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:16569
+//line sql-gen.y:17822
 		{
 			sqlVAL.union.val = tree.ObjectNamePrefix{CatalogName: tree.Name(sqlDollar[1].str), SchemaName: tree.Name('*'), ExplicitCatalog: true, ExplicitSchema: true}
 		}
-	case 2916:
+	case 3153:
 		sqlDollar = sqlS[sqlpt-0 : sqlpt+1]
-//line sql-gen.y:16576
+//line sql-gen.y:17829
 		{
 			sqlVAL.union.val = tree.ObjectNamePrefix{ExplicitSchema: false}
 		}
-	case 2922:
+	case 3159:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:16603
+//line sql-gen.y:17856
 		{
 			sqlVAL.union.val = &tree.UnresolvedName{NumParts: 1, Parts: tree.NameParts{sqlDollar[1].str}}
 		}
-	case 2924:
+	case 3161:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:16610
+//line sql-gen.y:17863
 		{
 			sqlVAL.union.val = &tree.UnresolvedName{NumParts: 2, Parts: tree.NameParts{sqlDollar[3].str, sqlDollar[1].str}}
 		}
-	case 2925:
+	case 3162:
 		sqlDollar = sqlS[sqlpt-5 : sqlpt+1]
-//line sql-gen.y:16614
+//line sql-gen.y:17867
 		{
 			sqlVAL.union.val = &tree.UnresolvedName{NumParts: 3, Parts: tree.NameParts{sqlDollar[5].str, sqlDollar[3].str, sqlDollar[1].str}}
 		}
-	case 2926:
+	case 3163:
 		sqlDollar = sqlS[sqlpt-7 : sqlpt+1]
-//line sql-gen.y:16618
+//line sql-gen.y:17871
 		{
 			sqlVAL.union.val = &tree.UnresolvedName{NumParts: 4, Parts: tree.NameParts{sqlDollar[7].str, sqlDollar[5].str, sqlDollar[3].str, sqlDollar[1].str}}
 		}
-	case 2928:
+	case 3165:
 		sqlDollar = sqlS[sqlpt-7 : sqlpt+1]
-//line sql-gen.y:16632
+//line sql-gen.y:17885
 		{
 			sqlVAL.union.val = &tree.UnresolvedName{Star: true, NumParts: 4, Parts: tree.NameParts{"", sqlDollar[5].str, sqlDollar[3].str, sqlDollar[1].str}}
 		}
-	case 2929:
+	case 3166:
 		sqlDollar = sqlS[sqlpt-5 : sqlpt+1]
-//line sql-gen.y:16636
+//line sql-gen.y:17889
 		{
 			sqlVAL.union.val = &tree.UnresolvedName{Star: true, NumParts: 3, Parts: tree.NameParts{"", sqlDollar[3].str, sqlDollar[1].str}}
 		}
-	case 2930:
+	case 3167:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:16640
+//line sql-gen.y:17893
 		{
 			sqlVAL.union.val = &tree.UnresolvedName{Star: true, NumParts: 2, Parts: tree.NameParts{"", sqlDollar[1].str}}
 		}
-	case 2931:
+	case 3168:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:16653
+//line sql-gen.y:17906
 		{
 			sqlVAL.union.val = &tree.UnresolvedName{NumParts: 1, Parts: tree.NameParts{sqlDollar[1].str}}
 		}
-	case 2933:
+	case 3170:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:16658
+//line sql-gen.y:17911
 		{
 			sqlVAL.union.val = &tree.UnresolvedName{NumParts: 1, Parts: tree.NameParts{sqlDollar[1].str}}
 		}
-	case 2934:
+	case 3171:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:16666
+//line sql-gen.y:17919
 		{
 			sqlVAL.union.val = &tree.UnresolvedName{NumParts: 1, Parts: tree.NameParts{sqlDollar[1].str}}
 		}
-	case 2938:
+	case 3175:
 		sqlDollar = sqlS[sqlpt-1 : sqlpt+1]
-//line sql-gen.y:16684
+//line sql-gen.y:17937
 		{
 			aIdx := sqllex.(*lexer).NewAnnotation()
 			res, err := tree.NewUnresolvedObjectName(1, [3]string{sqlDollar[1].str}, aIdx)
@@ -47124,9 +51092,9 @@ sqldefault:
 			}
 			sqlVAL.union.val = res
 		}
-	case 2939:
+	case 3176:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:16697
+//line sql-gen.y:17950
 		{
 			aIdx := sqllex.(*lexer).NewAnnotation()
 			res, err := tree.NewUnresolvedObjectName(2, [3]string{sqlDollar[3].str, sqlDollar[1].str}, aIdx)
@@ -47135,9 +51103,9 @@ sqldefault:
 			}
 			sqlVAL.union.val = res
 		}
-	case 2940:
+	case 3177:
 		sqlDollar = sqlS[sqlpt-5 : sqlpt+1]
-//line sql-gen.y:16704
+//line sql-gen.y:17957
 		{
 			aIdx := sqllex.(*lexer).NewAnnotation()
 			res, err := tree.NewUnresolvedObjectName(3, [3]string{sqlDollar[5].str, sqlDollar[3].str, sqlDollar[1].str}, aIdx)
@@ -47146,21 +51114,21 @@ sqldefault:
 			}
 			sqlVAL.union.val = res
 		}
-	case 2948:
+	case 3185:
 		sqlDollar = sqlS[sqlpt-0 : sqlpt+1]
-//line sql-gen.y:16729
+//line sql-gen.y:17982
 		{
 			sqlVAL.str = ""
 		}
-	case 2949:
+	case 3186:
 		sqlDollar = sqlS[sqlpt-3 : sqlpt+1]
-//line sql-gen.y:16735
+//line sql-gen.y:17988
 		{
 			sqlVAL.str = sqlDollar[2].str
 		}
-	case 2950:
+	case 3187:
 		sqlDollar = sqlS[sqlpt-0 : sqlpt+1]
-//line sql-gen.y:16739
+//line sql-gen.y:17992
 		{
 			sqlVAL.str = ""
 		}
diff --git a/pkg/sql/parser/sql.y b/pkg/sql/parser/sql.y
index 1c228ca..7ffb39f 100644
--- a/pkg/sql/parser/sql.y
+++ b/pkg/sql/parser/sql.y
@@ -40,7 +40,9 @@ import (
     "github.com/cockroachdb/cockroach/pkg/sql/sem/tree/treebin"
     "github.com/cockroachdb/cockroach/pkg/sql/sem/tree/treecmp"
     "github.com/cockroachdb/cockroach/pkg/sql/sem/tree/treewindow"
+    "github.com/cockroachdb/cockroach/pkg/sql/sem/idxtype"
     "github.com/cockroachdb/cockroach/pkg/sql/types"
+    "github.com/cockroachdb/cockroach/pkg/util/vector"
     "github.com/cockroachdb/errors"
     "github.com/lib/pq/oid"
 )
@@ -65,6 +67,11 @@ func setErr(sqllex sqlLexer, err error) int {
     return 1
 }
 
+func setErrNoDetails(sqllex sqlLexer, err error) int {
+    sqllex.(*lexer).setErrNoDetails(err)
+    return 1
+}
+
 func unimplementedWithIssue(sqllex sqlLexer, issue int) int {
     sqllex.(*lexer).UnimplementedWithIssue(issue)
     return 1
@@ -402,8 +409,8 @@ func (u *sqlSymUnion) storageParams() []tree.StorageParam {
     }
     return nil
 }
-func (u *sqlSymUnion) storageParamKeys() []tree.Name {
-    if params, ok := u.val.([]tree.Name); ok {
+func (u *sqlSymUnion) storageParamKeys() []string {
+    if params, ok := u.val.([]string); ok {
         return params
     }
     return nil
@@ -645,6 +652,24 @@ func (u *sqlSymUnion) indexInvisibility() tree.IndexInvisibility {
 func (u *sqlSymUnion) dropBehavior() tree.DropBehavior {
     return u.val.(tree.DropBehavior)
 }
+func (u *sqlSymUnion) rlsTableMode() tree.TableRLSMode {
+    return u.val.(tree.TableRLSMode)
+}
+func (u *sqlSymUnion) alterPolicy() tree.AlterPolicy {
+    return u.val.(tree.AlterPolicy)
+}
+func (u *sqlSymUnion) createPolicy() tree.CreatePolicy {
+    return u.val.(tree.CreatePolicy)
+}
+func (u *sqlSymUnion) policyType() tree.PolicyType {
+  return u.val.(tree.PolicyType)
+}
+func (u *sqlSymUnion) policyCommand() tree.PolicyCommand {
+  return u.val.(tree.PolicyCommand)
+}
+func (u *sqlSymUnion) policyExpressions() tree.PolicyExpressions {
+	return u.val.(tree.PolicyExpressions)
+}
 func (u *sqlSymUnion) validationBehavior() tree.ValidationBehavior {
     return u.val.(tree.ValidationBehavior)
 }
@@ -723,6 +748,9 @@ func (u *sqlSymUnion) showBackupDetails() tree.ShowBackupDetails {
 func (u *sqlSymUnion) showBackupOptions() *tree.ShowBackupOptions {
   return u.val.(*tree.ShowBackupOptions)
 }
+func (u *sqlSymUnion) checkExternalConnectionOptions() *tree.CheckExternalConnectionOptions {
+  return u.val.(*tree.CheckExternalConnectionOptions)
+}
 func (u *sqlSymUnion) restoreOptions() *tree.RestoreOptions {
   return u.val.(*tree.RestoreOptions)
 }
@@ -871,21 +899,57 @@ func (u *sqlSymUnion) showRangesOpts() *tree.ShowRangesOptions {
 func (u *sqlSymUnion) tenantSpec() *tree.TenantSpec {
     return u.val.(*tree.TenantSpec)
 }
-func (u *sqlSymUnion) likeTenantSpec() *tree.LikeTenantSpec {
-    return u.val.(*tree.LikeTenantSpec)
-}
 func (u *sqlSymUnion) cteMaterializeClause() tree.CTEMaterializeClause {
     return u.val.(tree.CTEMaterializeClause)
 }
 func (u *sqlSymUnion) showTenantOpts() tree.ShowTenantOptions {
     return u.val.(tree.ShowTenantOptions)
 }
+func (u *sqlSymUnion) showLogicalReplicationJobsOpts() tree.ShowLogicalReplicationJobsOptions {
+		return u.val.(tree.ShowLogicalReplicationJobsOptions)
+}
 func (u *sqlSymUnion) showCreateFormatOption() tree.ShowCreateFormatOption {
     return u.val.(tree.ShowCreateFormatOption)
 }
 func (u *sqlSymUnion) beginTransaction() *tree.BeginTransaction {
     return u.val.(*tree.BeginTransaction)
 }
+func (u *sqlSymUnion) showFingerprintOptions() *tree.ShowFingerprintOptions {
+    return u.val.(*tree.ShowFingerprintOptions)
+}
+func (u *sqlSymUnion) logicalReplicationResources() tree.LogicalReplicationResources {
+    return u.val.(tree.LogicalReplicationResources)
+}
+func (u *sqlSymUnion) logicalReplicationOptions() *tree.LogicalReplicationOptions {
+  return u.val.(*tree.LogicalReplicationOptions)
+}
+func (u *sqlSymUnion) triggerActionTime() tree.TriggerActionTime {
+  return u.val.(tree.TriggerActionTime)
+}
+func (u *sqlSymUnion) triggerEvent() *tree.TriggerEvent {
+  return u.val.(*tree.TriggerEvent)
+}
+func (u *sqlSymUnion) triggerEvents() []*tree.TriggerEvent {
+  return u.val.([]*tree.TriggerEvent)
+}
+func (u *sqlSymUnion) triggerTransition() *tree.TriggerTransition {
+  return u.val.(*tree.TriggerTransition)
+}
+func (u *sqlSymUnion) triggerTransitions() []*tree.TriggerTransition {
+  return u.val.([]*tree.TriggerTransition)
+}
+func (u *sqlSymUnion) triggerForEach() tree.TriggerForEach {
+  return u.val.(tree.TriggerForEach)
+}
+func (u *sqlSymUnion) indexType() idxtype.T {
+  return u.val.(idxtype.T)
+}
+func (u *sqlSymUnion) doBlockOptions() tree.DoBlockOptions {
+    return u.val.(tree.DoBlockOptions)
+}
+func (u *sqlSymUnion) doBlockOption() tree.DoBlockOption {
+    return u.val.(tree.DoBlockOption)
+}
 %}
 
 // NB: the %token definitions must come before the %type definitions in this
@@ -907,27 +971,27 @@ func (u *sqlSymUnion) beginTransaction() *tree.BeginTransaction {
 // Ordinary key words in alphabetical order.
 %token <str> ABORT ABSOLUTE ACCESS ACTION ADD ADMIN AFTER AGGREGATE
 %token <str> ALL ALTER ALWAYS ANALYSE ANALYZE AND AND_AND ANY ANNOTATE_TYPE ARRAY AS ASC AS_JSON AT_AT
-%token <str> ASENSITIVE ASYMMETRIC AT ATOMIC ATTRIBUTE AUTHORIZATION AUTOMATIC AVAILABILITY
+%token <str> ASENSITIVE ASYMMETRIC AT ATOMIC ATTRIBUTE AUTHORIZATION AUTOMATIC AVAILABILITY AVOID_FULL_SCAN
 
-%token <str> BACKUP BACKUPS BACKWARD BATCH BEFORE BEGIN BETWEEN BIGINT BIGSERIAL BINARY BIT
+%token <str> BACKUP BACKUPS BACKWARD BATCH BEFORE BEGIN BETWEEN BIDIRECTIONAL BIGINT BIGSERIAL BINARY BIT
 %token <str> BUCKET_COUNT
-%token <str> BOOLEAN BOTH BOX2D BUNDLE BY
+%token <str> BOOLEAN BOTH BOX2D BUNDLE BY BYPASSRLS
 
 %token <str> CACHE CALL CALLED CANCEL CANCELQUERY CAPABILITIES CAPABILITY CASCADE CASE CAST CBRT CHANGEFEED CHAR
 %token <str> CHARACTER CHARACTERISTICS CHECK CHECK_FILES CLOSE
 %token <str> CLUSTER CLUSTERS COALESCE COLLATE COLLATION COLUMN COLUMNS COMMENT COMMENTS COMMIT
 %token <str> COMMITTED COMPACT COMPLETE COMPLETIONS CONCAT CONCURRENTLY CONFIGURATION CONFIGURATIONS CONFIGURE
 %token <str> CONFLICT CONNECTION CONNECTIONS CONSTRAINT CONSTRAINTS CONTAINS CONTROLCHANGEFEED CONTROLJOB
-%token <str> CONVERSION CONVERT COPY COST COVERING CREATE CREATEDB CREATELOGIN CREATEROLE
+%token <str> CONVERSION CONVERT COPY COS_DISTANCE COST COVERING CREATE CREATEDB CREATELOGIN CREATEROLE
 %token <str> CROSS CSV CUBE CURRENT CURRENT_CATALOG CURRENT_DATE CURRENT_SCHEMA
 %token <str> CURRENT_ROLE CURRENT_TIME CURRENT_TIMESTAMP
 %token <str> CURRENT_USER CURSOR CYCLE
 
-%token <str> DATA DATABASE DATABASES DATE DAY DEBUG_IDS DEBUG_PAUSE_ON DEC DEBUG_DUMP_METADATA_SST DECIMAL DEFAULT DEFAULTS DEFINER
+%token <str> DATA DATABASE DATABASES DATE DAY DEBUG_IDS DEC DECIMAL DEFAULT DEFAULTS DEFINER
 %token <str> DEALLOCATE DECLARE DEFERRABLE DEFERRED DELETE DELIMITER DEPENDS DESC DESTINATION DETACHED DETAILS
-%token <str> DISCARD DISTINCT DO DOMAIN DOUBLE DROP
+%token <str> DISABLE DISCARD DISTANCE DISTINCT DO DOMAIN DOUBLE DROP
 
-%token <str> ELSE ENCODING ENCRYPTED ENCRYPTION_INFO_DIR ENCRYPTION_PASSPHRASE END ENUM ENUMS ESCAPE EXCEPT EXCLUDE EXCLUDING
+%token <str> EACH ELSE ENABLE ENCODING ENCRYPTED ENCRYPTION_INFO_DIR ENCRYPTION_PASSPHRASE END ENUM ENUMS ESCAPE EXCEPT EXCLUDE EXCLUDING
 %token <str> EXISTS EXECUTE EXECUTION EXPERIMENTAL
 %token <str> EXPERIMENTAL_FINGERPRINTS EXPERIMENTAL_REPLICA
 %token <str> EXPERIMENTAL_AUDIT EXPERIMENTAL_RELOCATE
@@ -935,7 +999,7 @@ func (u *sqlSymUnion) beginTransaction() *tree.BeginTransaction {
 
 %token <str> FAILURE FALSE FAMILY FETCH FETCHVAL FETCHTEXT FETCHVAL_PATH FETCHTEXT_PATH
 %token <str> FILES FILTER
-%token <str> FIRST FLOAT FLOAT4 FLOAT8 FLOORDIV FOLLOWING FOR FORCE FORCE_INDEX
+%token <str> FIRST FLOAT FLOAT4 FLOAT8 FLOORDIV FOLLOWING FOR FORCE FORCE_INDEX FORCE_INVERTED_INDEX
 %token <str> FORCE_NOT_NULL FORCE_NULL FORCE_QUOTE FORCE_ZIGZAG
 %token <str> FOREIGN FORMAT FORWARD FREEZE FROM FULL FUNCTION FUNCTIONS
 
@@ -946,12 +1010,12 @@ func (u *sqlSymUnion) beginTransaction() *tree.BeginTransaction {
 %token <str> HAVING HASH HEADER HIGH HISTOGRAM HOLD HOUR
 
 %token <str> IDENTITY
-%token <str> IF IFERROR IFNULL IGNORE_FOREIGN_KEYS ILIKE IMMEDIATE IMMUTABLE IMPORT IN INCLUDE
+%token <str> IF IFERROR IFNULL IGNORE_FOREIGN_KEYS ILIKE IMMEDIATE IMMEDIATELY IMMUTABLE IMPORT IN INCLUDE
 %token <str> INCLUDING INCLUDE_ALL_SECONDARY_TENANTS INCLUDE_ALL_VIRTUAL_CLUSTERS INCREMENT INCREMENTAL INCREMENTAL_LOCATION
 %token <str> INET INET_CONTAINED_BY_OR_EQUALS
 %token <str> INET_CONTAINS_OR_EQUALS INDEX INDEXES INHERITS INJECT INITIALLY
 %token <str> INDEX_BEFORE_PAREN INDEX_BEFORE_NAME_THEN_PAREN INDEX_AFTER_ORDER_BY_BEFORE_AT
-%token <str> INNER INOUT INPUT INSENSITIVE INSERT INT INTEGER
+%token <str> INNER INOUT INPUT INSENSITIVE INSERT INSTEAD INT INTEGER
 %token <str> INTERSECT INTERVAL INTO INTO_DB INVERTED INVOKER IS ISERROR ISNULL ISOLATION
 
 %token <str> JOB JOBS JOIN JSON JSONB JSON_SOME_EXISTS JSON_ALL_EXISTS
@@ -961,34 +1025,34 @@ func (u *sqlSymUnion) beginTransaction() *tree.BeginTransaction {
 %token <str> LABEL LANGUAGE LAST LATERAL LATEST LC_CTYPE LC_COLLATE
 %token <str> LEADING LEASE LEAST LEAKPROOF LEFT LESS LEVEL LIKE LIMIT
 %token <str> LINESTRING LINESTRINGM LINESTRINGZ LINESTRINGZM
-%token <str> LIST LOCAL LOCALITY LOCALTIME LOCALTIMESTAMP LOCKED LOGIN LOOKUP LOW LSHIFT
+%token <str> LIST LOCAL LOCALITY LOCALTIME LOCALTIMESTAMP LOCKED LOGICAL LOGICALLY LOGIN LOOKUP LOW LSHIFT
 
-%token <str> MATCH MATERIALIZED MERGE MINVALUE MAXVALUE METHOD MINUTE MODIFYCLUSTERSETTING MODIFYSQLCLUSTERSETTING MONTH MOVE
+%token <str> MATCH MATERIALIZED MERGE MINVALUE MAXVALUE METHOD MINUTE MODIFYCLUSTERSETTING MODIFYSQLCLUSTERSETTING MODE MONTH MOVE
 %token <str> MULTILINESTRING MULTILINESTRINGM MULTILINESTRINGZ MULTILINESTRINGZM
 %token <str> MULTIPOINT MULTIPOINTM MULTIPOINTZ MULTIPOINTZM
 %token <str> MULTIPOLYGON MULTIPOLYGONM MULTIPOLYGONZ MULTIPOLYGONZM
 
-%token <str> NAN NAME NAMES NATURAL NEVER NEW_DB_NAME NEW_KMS NEXT NO NOCANCELQUERY NOCONTROLCHANGEFEED
-%token <str> NOCONTROLJOB NOCREATEDB NOCREATELOGIN NOCREATEROLE NOLOGIN NOMODIFYCLUSTERSETTING NOREPLICATION
+%token <str> NAN NAME NAMES NATURAL NEG_INNER_PRODUCT NEVER NEW NEW_DB_NAME NEW_KMS NEXT NO NOBYPASSRLS NOCANCELQUERY NOCONTROLCHANGEFEED
+%token <str> NOCONTROLJOB NOCREATEDB NOCREATELOGIN NOCREATEROLE NODE NOLOGIN NOMODIFYCLUSTERSETTING NOREPLICATION
 %token <str> NOSQLLOGIN NO_INDEX_JOIN NO_ZIGZAG_JOIN NO_FULL_SCAN NONE NONVOTERS NORMAL NOT
 %token <str> NOTHING NOTHING_AFTER_RETURNING
 %token <str> NOTNULL
 %token <str> NOVIEWACTIVITY NOVIEWACTIVITYREDACTED NOVIEWCLUSTERSETTING NOWAIT NULL NULLIF NULLS NUMERIC
 
-%token <str> OF OFF OFFSET OID OIDS OIDVECTOR OLD_KMS ON ONLY OPT OPTION OPTIONS OR
+%token <str> OF OFF OFFSET OID OIDS OIDVECTOR OLD OLD_KMS ON ONLY OPT OPTION OPTIONS OR
 %token <str> ORDER ORDINALITY OTHERS OUT OUTER OVER OVERLAPS OVERLAY OWNED OWNER OPERATOR
 
-%token <str> PARALLEL PARENT PARTIAL PARTITION PARTITIONS PASSWORD PAUSE PAUSED PHYSICAL PLACEMENT PLACING
-%token <str> PLAN PLANS POINT POINTM POINTZ POINTZM POLYGON POLYGONM POLYGONZ POLYGONZM
-%token <str> POSITION PRECEDING PRECISION PREPARE PRESERVE PRIMARY PRIOR PRIORITY PRIVILEGES
+%token <str> PARALLEL PARENT PARTIAL PARTITION PARTITIONS PASSWORD PAUSE PAUSED PER PERMISSIVE PHYSICAL PLACEMENT PLACING
+%token <str> PLAN PLANS POINT POINTM POINTZ POINTZM POLICIES POLICY POLYGON POLYGONM POLYGONZ POLYGONZM
+%token <str> POSITION PRECEDING PRECISION PREPARE PREPARED PRESERVE PRIMARY PRIOR PRIORITY PRIVILEGES
 %token <str> PROCEDURAL PROCEDURE PROCEDURES PUBLIC PUBLICATION
 
 %token <str> QUERIES QUERY QUOTE
 
-%token <str> RANGE RANGES READ REAL REASON REASSIGN RECURSIVE RECURRING REDACT REF REFERENCES REFRESH
+%token <str> RANGE RANGES READ REAL REASON REASSIGN RECURSIVE RECURRING REDACT REF REFERENCES REFERENCING REFRESH
 %token <str> REGCLASS REGION REGIONAL REGIONS REGNAMESPACE REGPROC REGPROCEDURE REGROLE REGTYPE REINDEX
-%token <str> RELATIVE RELOCATE REMOVE_PATH REMOVE_REGIONS RENAME REPEATABLE REPLACE REPLICATION
-%token <str> RELEASE RESET RESTART RESTORE RESTRICT RESTRICTED RESUME RETENTION RETURNING RETURN RETURNS RETRY REVISION_HISTORY
+%token <str> RELATIVE RELOCATE REMOVE_PATH REMOVE_REGIONS RENAME REPEATABLE REPLACE REPLICATED REPLICATION
+%token <str> RELEASE RESET RESTART RESTORE RESTRICT RESTRICTED RESTRICTIVE RESUME RETENTION RETURNING RETURN RETURNS RETRY REVISION_HISTORY
 %token <str> REVOKE RIGHT ROLE ROLES ROLLBACK ROLLUP ROUTINES ROW ROWS RSHIFT RULE RUNNING
 
 %token <str> SAVEPOINT SCANS SCATTER SCHEDULE SCHEDULES SCROLL SCHEMA SCHEMA_ONLY SCHEMAS SCRUB
@@ -996,20 +1060,20 @@ func (u *sqlSymUnion) beginTransaction() *tree.BeginTransaction {
 %token <str> SERIALIZABLE SERVER SERVICE SESSION SESSIONS SESSION_USER SET SETOF SETS SETTING SETTINGS
 %token <str> SHARE SHARED SHOW SIMILAR SIMPLE SIZE SKIP SKIP_LOCALITIES_CHECK SKIP_MISSING_FOREIGN_KEYS
 %token <str> SKIP_MISSING_SEQUENCES SKIP_MISSING_SEQUENCE_OWNERS SKIP_MISSING_VIEWS SKIP_MISSING_UDFS SMALLINT SMALLSERIAL
-%token <str> SNAPSHOT SOME SPLIT SQL SQLLOGIN
-%token <str> STABLE START STATE STATISTICS STATUS STDIN STDOUT STOP STREAM STRICT STRING STORAGE STORE STORED STORING SUBSTRING SUPER
+%token <str> SNAPSHOT SOME SOURCE SPLIT SQL SQLLOGIN
+%token <str> STABLE START STATE STATEMENT STATISTICS STATUS STDIN STDOUT STOP STRAIGHT STREAM STRICT STRING STORAGE STORE STORED STORING SUBJECT SUBSTRING SUPER
 %token <str> SUPPORT SURVIVE SURVIVAL SYMMETRIC SYNTAX SYSTEM SQRT SUBSCRIPTION STATEMENTS
 
 %token <str> TABLE TABLES TABLESPACE TEMP TEMPLATE TEMPORARY TENANT TENANT_NAME TENANTS TESTING_RELOCATE TEXT THEN
 %token <str> TIES TIME TIMETZ TIMESTAMP TIMESTAMPTZ TO THROTTLING TRAILING TRACE
-%token <str> TRANSACTION TRANSACTIONS TRANSFER TRANSFORM TREAT TRIGGER TRIM TRUE
+%token <str> TRANSACTION TRANSACTIONS TRANSFER TRANSFORM TREAT TRIGGER TRIGGERS TRIM TRUE
 %token <str> TRUNCATE TRUSTED TYPE TYPES
 %token <str> TRACING
 
-%token <str> UNBOUNDED UNCOMMITTED UNION UNIQUE UNKNOWN UNLISTEN UNLOGGED UNSAFE_RESTORE_INCOMPATIBLE_VERSION UNSPLIT
+%token <str> UNBOUNDED UNCOMMITTED UNIDIRECTIONAL UNION UNIQUE UNKNOWN UNLISTEN UNLOGGED UNSAFE_RESTORE_INCOMPATIBLE_VERSION UNSPLIT
 %token <str> UPDATE UPDATES_CLUSTER_MONITORING_METRICS UPSERT UNSET UNTIL USE USER USERS USING UUID
 
-%token <str> VALID VALIDATE VALUE VALUES VARBIT VARCHAR VARIADIC VERIFY_BACKUP_TABLE_DATA VIEW VARYING VIEWACTIVITY VIEWACTIVITYREDACTED VIEWDEBUG
+%token <str> VALID VALIDATE VALUE VALUES VARBIT VARCHAR VARIADIC VECTOR VERIFY_BACKUP_TABLE_DATA VIEW VARIABLES VARYING VIEWACTIVITY VIEWACTIVITYREDACTED VIEWDEBUG
 %token <str> VIEWCLUSTERMETADATA VIEWCLUSTERSETTING VIRTUAL VISIBLE INVISIBLE VISIBILITY VOLATILE VOTERS
 %token <str> VIRTUAL_CLUSTER_NAME VIRTUAL_CLUSTER
 
@@ -1032,7 +1096,7 @@ func (u *sqlSymUnion) beginTransaction() *tree.BeginTransaction {
 // columns along with our family related extensions (CREATE FAMILY/CREATE FAMILY
 // family_name).
 // - RESET_ALL is used to differentiate `RESET var` from `RESET ALL`.
-// - ROLE_ALL and USER_ALL are used in ALTER ROLE statements that affect all
+// - ROLE_ALL and USER_ALL are used in ALTER ROLE and SHOW DEFAULT SESSION VARIABLES FOR ROLE statements that affect all
 // roles.
 // - ON_LA is needed for ON UPDATE and ON DELETE expressions for foreign key
 // references.
@@ -1070,6 +1134,7 @@ func (u *sqlSymUnion) beginTransaction() *tree.BeginTransaction {
 %type <tree.Statement> alter_unsupported_stmt
 %type <tree.Statement> alter_func_stmt
 %type <tree.Statement> alter_proc_stmt
+%type <tree.Statement> alter_policy_stmt
 
 // ALTER RANGE
 %type <tree.Statement> alter_zone_range_stmt
@@ -1102,6 +1167,7 @@ func (u *sqlSymUnion) beginTransaction() *tree.BeginTransaction {
 // Other ALTER VIRTUAL CLUSTER statements.
 %type <tree.Statement> alter_virtual_cluster_replication_stmt
 %type <tree.Statement> alter_virtual_cluster_rename_stmt
+%type <tree.Statement> alter_virtual_cluster_reset_stmt
 %type <tree.Statement> alter_virtual_cluster_service_stmt
 
 // ALTER PARTITION
@@ -1199,17 +1265,25 @@ func (u *sqlSymUnion) beginTransaction() *tree.BeginTransaction {
 %type <tree.Statement> create_table_stmt
 %type <tree.Statement> create_table_as_stmt
 %type <tree.Statement> create_virtual_cluster_stmt
+%type <tree.Statement> create_logical_replication_stream_stmt
 %type <tree.Statement> create_view_stmt
 %type <tree.Statement> create_sequence_stmt
 %type <tree.Statement> create_func_stmt
 %type <tree.Statement> create_proc_stmt
+%type <tree.Statement> create_trigger_stmt
+%type <tree.Statement> create_policy_stmt
 
-%type <*tree.LikeTenantSpec> opt_like_virtual_cluster
+%type <tree.Statement> check_stmt
+%type <tree.Statement> check_external_connection_stmt
+
+%type <tree.LogicalReplicationResources> logical_replication_resources logical_replication_resources_list
+%type <*tree.LogicalReplicationOptions> opt_logical_replication_options logical_replication_options logical_replication_options_list opt_logical_replication_create_table_options logical_replication_create_table_options logical_replication_create_table_options_list
 
 %type <tree.Statement> create_stats_stmt
 %type <*tree.CreateStatsOptions> opt_create_stats_options
 %type <*tree.CreateStatsOptions> create_stats_option_list
 %type <*tree.CreateStatsOptions> create_stats_option
+%type <*tree.CheckExternalConnectionOptions> opt_with_check_external_connection_options_list check_external_connection_options_list check_external_connection_options
 
 %type <tree.Statement> create_type_stmt
 %type <tree.Statement> delete_stmt
@@ -1227,7 +1301,9 @@ func (u *sqlSymUnion) beginTransaction() *tree.BeginTransaction {
 %type <tree.Statement> drop_view_stmt
 %type <tree.Statement> drop_sequence_stmt
 %type <tree.Statement> drop_func_stmt
+%type <tree.Statement> drop_policy_stmt
 %type <tree.Statement> drop_proc_stmt
+%type <tree.Statement> drop_trigger_stmt
 %type <tree.Statement> drop_virtual_cluster_stmt
 %type <bool>           opt_immediate
 
@@ -1238,13 +1314,14 @@ func (u *sqlSymUnion) beginTransaction() *tree.BeginTransaction {
 %type <tree.Statement> explainable_stmt
 %type <tree.Statement> row_source_extension_stmt
 %type <tree.Statement> copy_to_stmt
+%type <tree.Statement> do_stmt
 %type <tree.Statement> export_stmt
 %type <tree.Statement> execute_stmt
 %type <tree.Statement> deallocate_stmt
 %type <tree.Statement> grant_stmt
 %type <tree.Statement> insert_stmt
 %type <tree.Statement> import_stmt
-%type <tree.Statement> pause_stmt pause_jobs_stmt pause_schedules_stmt pause_all_jobs_stmt
+%type <tree.Statement> pause_stmt pause_jobs_stmt pause_schedules_stmt pause_all_jobs_stmt alter_job_stmt
 %type <*tree.Select>   for_schedules_clause
 %type <tree.Statement> reassign_owned_by_stmt
 %type <tree.Statement> drop_owned_by_stmt
@@ -1254,13 +1331,15 @@ func (u *sqlSymUnion) beginTransaction() *tree.BeginTransaction {
 %type <tree.Statement> drop_schedule_stmt
 %type <tree.Statement> restore_stmt
 %type <tree.StringOrPlaceholderOptList> string_or_placeholder_opt_list
-%type <[]tree.StringOrPlaceholderOptList> list_of_string_or_placeholder_opt_list
 %type <tree.Statement> revoke_stmt
 %type <tree.Statement> refresh_stmt
 %type <*tree.Select> select_stmt
 %type <tree.Statement> abort_stmt
 %type <tree.Statement> rollback_stmt
 %type <tree.Statement> savepoint_stmt
+%type <tree.Statement> prepare_transaction_stmt
+%type <tree.Statement> commit_prepared_stmt
+%type <tree.Statement> rollback_prepared_stmt
 
 %type <tree.Statement> preparable_set_stmt nonpreparable_set_stmt
 %type <tree.Statement> set_local_stmt
@@ -1278,6 +1357,7 @@ func (u *sqlSymUnion) beginTransaction() *tree.BeginTransaction {
 %type <tree.Statement> show_columns_stmt
 %type <tree.Statement> show_commit_timestamp_stmt
 %type <tree.Statement> show_constraints_stmt
+%type <tree.Statement> show_triggers_stmt
 %type <tree.Statement> show_create_stmt
 %type <tree.ShowCreateFormatOption> opt_show_create_format_options
 %type <tree.Statement> show_create_schedules_stmt
@@ -1286,7 +1366,8 @@ func (u *sqlSymUnion) beginTransaction() *tree.BeginTransaction {
 %type <tree.Statement> show_databases_stmt
 %type <tree.Statement> show_default_privileges_stmt
 %type <tree.Statement> show_enums_stmt
-%type <tree.Statement> show_fingerprints_stmt
+%type <tree.Statement> show_external_connections_stmt
+%type <tree.Statement> show_fingerprints_stmt opt_with_show_fingerprints_options fingerprint_options_list fingerprint_options
 %type <tree.Statement> show_functions_stmt
 %type <tree.Statement> show_procedures_stmt
 %type <tree.Statement> show_grants_stmt
@@ -1317,10 +1398,13 @@ func (u *sqlSymUnion) beginTransaction() *tree.BeginTransaction {
 %type <tree.Statement> show_transfer_stmt
 %type <tree.Statement> show_types_stmt
 %type <tree.Statement> show_users_stmt
+%type <tree.Statement> show_default_session_variables_for_role_stmt
 %type <tree.Statement> show_zone_stmt
 %type <tree.Statement> show_schedules_stmt
 %type <tree.Statement> show_full_scans_stmt
 %type <tree.Statement> show_completions_stmt
+%type <tree.Statement> show_logical_replication_jobs_stmt opt_show_logical_replication_jobs_options show_logical_replication_jobs_options
+%type <tree.Statement> show_policies_stmt
 
 %type <str> statements_or_queries
 
@@ -1347,19 +1431,18 @@ func (u *sqlSymUnion) beginTransaction() *tree.BeginTransaction {
 
 %type <tree.Statement> reindex_stmt
 
-%type <[]string> opt_incremental
 %type <tree.KVOption> kv_option
 %type <[]tree.KVOption> kv_option_list opt_with_options var_set_list opt_with_schedule_options
 %type <*tree.BackupOptions> opt_with_backup_options backup_options backup_options_list
 %type <*tree.RestoreOptions> opt_with_restore_options restore_options restore_options_list
-%type <*tree.TenantReplicationOptions> opt_with_replication_options replication_options replication_options_list
+%type <*tree.TenantReplicationOptions> opt_with_replication_options replication_options replication_options_list source_replication_options source_replication_options_list
 %type <tree.ShowBackupDetails> show_backup_details
 %type <*tree.ShowJobOptions> show_job_options show_job_options_list
-%type <*tree.ShowBackupOptions> opt_with_show_backup_options show_backup_options show_backup_options_list show_backup_connection_options opt_with_show_backup_connection_options_list show_backup_connection_options_list
+%type <*tree.ShowBackupOptions> opt_with_show_backup_options show_backup_options show_backup_options_list
 %type <*tree.CopyOptions> opt_with_copy_options copy_options copy_options_list copy_generic_options copy_generic_options_list
 %type <str> import_format
 %type <str> storage_parameter_key
-%type <tree.NameList> storage_parameter_key_list
+%type <[]string> storage_parameter_key_list
 %type <tree.StorageParam> storage_parameter
 %type <[]tree.StorageParam> storage_parameter_list opt_table_with opt_with_storage_parameter_list
 
@@ -1412,7 +1495,7 @@ func (u *sqlSymUnion) beginTransaction() *tree.BeginTransaction {
 
 %type <str> name opt_name opt_name_parens
 %type <str> privilege savepoint_name
-%type <tree.KVOption> role_option password_clause valid_until_clause
+%type <tree.KVOption> role_option password_clause valid_until_clause subject_clause
 %type <tree.Operator> subquery_op
 %type <*tree.UnresolvedName> func_name func_name_no_crdb_extra
 %type <tree.ResolvableFunctionReference> func_application_name
@@ -1464,6 +1547,7 @@ func (u *sqlSymUnion) beginTransaction() *tree.BeginTransaction {
 %type <[]*tree.Order> sortby_list sortby_no_index_list
 %type <tree.IndexElemList> index_params create_as_params
 %type <tree.IndexInvisibility> opt_index_visible alter_index_visible
+%type <idxtype.T> opt_index_access_method
 %type <tree.NameList> name_list privilege_list
 %type <[]int32> opt_array_bounds
 %type <*tree.Batch> opt_batch_clause
@@ -1475,7 +1559,7 @@ func (u *sqlSymUnion) beginTransaction() *tree.BeginTransaction {
 %type <*tree.Tuple> expr_tuple1_ambiguous expr_tuple_unambiguous
 %type <tree.NameList> attrs
 %type <[]string> session_var_parts
-%type <tree.SelectExprs> target_list
+%type <tree.SelectExprs> opt_target_list target_list
 %type <tree.UpdateExprs> set_clause_list
 %type <*tree.UpdateExpr> set_clause multiple_set_clause
 %type <tree.ArraySubscripts> array_subscripts
@@ -1494,6 +1578,9 @@ func (u *sqlSymUnion) beginTransaction() *tree.BeginTransaction {
 %type <[]tree.SequenceOption> sequence_option_list opt_sequence_option_list
 %type <tree.SequenceOption> sequence_option_elem
 
+%type <[]tree.SequenceOption> identity_option_list
+%type <tree.SequenceOption> identity_option_elem
+
 %type <bool> all_or_distinct
 %type <bool> with_comment
 %type <empty> join_outer
@@ -1512,7 +1599,6 @@ func (u *sqlSymUnion) beginTransaction() *tree.BeginTransaction {
 %type <*tree.TenantSpec> virtual_cluster_spec virtual_cluster_spec_opt_all
 
 %type <bool> opt_unique opt_concurrently opt_cluster opt_without_index
-%type <bool> opt_index_access_method
 
 %type <*tree.Limit> limit_clause offset_clause opt_limit_clause
 %type <tree.Expr> select_fetch_first_value
@@ -1585,6 +1671,7 @@ func (u *sqlSymUnion) beginTransaction() *tree.BeginTransaction {
 %type <*types.T> character_base
 %type <*types.T> geo_shape_type
 %type <*types.T> const_geo
+%type <*types.T> const_vector
 %type <str> extract_arg
 %type <bool> opt_varying
 
@@ -1678,19 +1765,27 @@ func (u *sqlSymUnion) beginTransaction() *tree.BeginTransaction {
 %type <tree.AbbreviatedRevoke> abbreviated_revoke_stmt
 %type <bool> opt_with_grant_option
 %type <tree.NameList> opt_for_roles
+%type <tree.NameList> opt_policy_roles
+%type <tree.PolicyExpressions> opt_policy_exprs
+%type <tree.PolicyType> opt_policy_type
+%type <tree.PolicyCommand> opt_policy_command
+%type <tree.TableRLSMode> table_rls_mode
 %type <tree.ObjectNamePrefixList>  opt_in_schemas
 %type <privilege.TargetObjectType> target_object_type
 
-// User defined function relevant components.
-%type <bool> opt_or_replace opt_return_table opt_return_set opt_no
+// Routine (UDF/SP) relevant components.
+%type <bool> opt_or_replace opt_return_set opt_no
 %type <str> param_name routine_as
-%type <tree.RoutineParams> opt_routine_param_with_default_list routine_param_with_default_list func_params func_params_list
-%type <tree.RoutineParam> routine_param_with_default routine_param
+%type <tree.RoutineParams> opt_routine_param_with_default_list routine_param_with_default_list
+%type <tree.RoutineParams> func_params func_params_list table_func_column_list
+%type <tree.RoutineParam> routine_param_with_default routine_param table_func_column
 %type <tree.ResolvableTypeReference> routine_return_type routine_param_type
 %type <tree.RoutineOptions> opt_create_routine_opt_list create_routine_opt_list alter_func_opt_list
 %type <tree.RoutineOption> create_routine_opt_item common_routine_opt_item
 %type <tree.RoutineParamClass> routine_param_class
 %type <*tree.UnresolvedObjectName> routine_create_name
+%type <tree.DoBlockOptions> do_stmt_opt_list
+%type <tree.DoBlockOption> do_stmt_opt_item
 %type <tree.Statement> routine_return_stmt routine_body_stmt
 %type <tree.Statements> routine_body_stmt_list
 %type <*tree.RoutineBody> opt_routine_body
@@ -1698,6 +1793,18 @@ func (u *sqlSymUnion) beginTransaction() *tree.BeginTransaction {
 %type <tree.RoutineObjs> function_with_paramtypes_list
 %type <empty> opt_link_sym
 
+// Trigger relevant components.
+%type <tree.TriggerActionTime> trigger_action_time
+%type <*tree.TriggerEvent> trigger_event
+%type <[]*tree.TriggerEvent> trigger_event_list
+%type <*tree.TriggerTransition> trigger_transition
+%type <[]*tree.TriggerTransition> trigger_transition_list opt_trigger_transition_list
+%type <bool> transition_is_new transition_is_row
+%type <tree.TriggerForEach> trigger_for_each trigger_for_type
+%type <tree.Expr> trigger_when
+%type <str> trigger_func_arg opt_as function_or_procedure
+%type <[]string> trigger_func_args
+
 %type <*tree.LabelSpec> label_spec
 
 %type <*tree.ShowRangesOptions> opt_show_ranges_options show_ranges_options
@@ -1742,7 +1849,7 @@ func (u *sqlSymUnion) beginTransaction() *tree.BeginTransaction {
 // funny behavior of UNBOUNDED on the SQL standard, though.
 %nonassoc  UNBOUNDED         // ideally should have same precedence as IDENT
 %nonassoc  IDENT NULL PARTITION RANGE ROWS GROUPS PRECEDING FOLLOWING CUBE ROLLUP
-%left      CONCAT FETCHVAL FETCHTEXT FETCHVAL_PATH FETCHTEXT_PATH REMOVE_PATH AT_AT  // multi-character ops
+%left      CONCAT FETCHVAL FETCHTEXT FETCHVAL_PATH FETCHTEXT_PATH REMOVE_PATH AT_AT DISTANCE COS_DISTANCE NEG_INNER_PRODUCT // multi-character ops
 %left      '|'
 %left      '#'
 %left      '&'
@@ -1796,6 +1903,7 @@ stmt_without_legacy_transaction:
 | execute_stmt               // EXTEND WITH HELP: EXECUTE
 | deallocate_stmt            // EXTEND WITH HELP: DEALLOCATE
 | discard_stmt               // EXTEND WITH HELP: DISCARD
+| do_stmt                    // EXTEND WITH HELP: DO
 | grant_stmt                 // EXTEND WITH HELP: GRANT
 | prepare_stmt               // EXTEND WITH HELP: PREPARE
 | revoke_stmt                // EXTEND WITH HELP: REVOKE
@@ -1840,6 +1948,8 @@ alter_ddl_stmt:
 | alter_func_stmt               // EXTEND WITH HELP: ALTER FUNCTION
 | alter_proc_stmt               // EXTEND WITH HELP: ALTER PROCEDURE
 | alter_backup_schedule  // EXTEND WITH HELP: ALTER BACKUP SCHEDULE
+| alter_policy_stmt             // EXTEND WITH HELP: ALTER POLICY
+| alter_job_stmt                // EXTEND WITH HELP: ALTER JOB
 
 // %Help: ALTER TABLE - change the definition of a table
 // %Category: DDL
@@ -1855,6 +1965,10 @@ alter_ddl_stmt:
 //   ALTER TABLE ... ALTER [COLUMN] <colname> {SET ON UPDATE <expr> | DROP ON UPDATE}
 //   ALTER TABLE ... ALTER [COLUMN] <colname> DROP NOT NULL
 //   ALTER TABLE ... ALTER [COLUMN] <colname> DROP STORED
+//   ALTER TABLE ... ALTER [COLUMN] <colname> ADD GENERATED { ALWAYS | BY DEFAULT } AS IDENTITY [ ( opt_sequence_option_list ) ]
+//   ALTER TABLE ... ALTER [COLUMN] <colname> SET GENERATED { ALWAYS | BY DEFAULT }
+//   ALTER TABLE ... ALTER [COLUMN] <colname> <identity_option_list>
+//   ALTER TABLE ... ALTER [COLUMN] <colname> DROP IDENTITY [ IF EXISTS ]
 //   ALTER TABLE ... ALTER [COLUMN] <colname> [SET DATA] TYPE <type> [COLLATE <collation>]
 //   ALTER TABLE ... ALTER PRIMARY KEY USING COLUMNS ( <colnames...> )
 //   ALTER TABLE ... RENAME TO <newname>
@@ -1873,6 +1987,7 @@ alter_ddl_stmt:
 //   ALTER TABLE ... CONFIGURE ZONE <zoneconfig>
 //   ALTER TABLE ... SET SCHEMA <newschemaname>
 //   ALTER TABLE ... SET LOCALITY [REGIONAL BY [TABLE IN <region> | ROW] | GLOBAL]
+//   ALTER TABLE ... {ENABLE | DISABLE | FORCE | NO FORCE} ROW LEVEL SECURITY
 //
 // Column qualifiers:
 //   [CONSTRAINT <constraintname>] {NULL | NOT NULL | UNIQUE | PRIMARY KEY | CHECK (<expr>) | DEFAULT <expr>}
@@ -1923,7 +2038,7 @@ alter_table_stmt:
 //   USING <var> = COPY FROM PARENT [, ...]
 //   { TO | = } <expr>
 //
-// %SeeAlso: WEBDOCS/configure-zone.html
+// %SeeAlso: WEBDOCS/alter-partition.html
 alter_partition_stmt:
   alter_zone_partition_stmt
 | ALTER PARTITION error // SHOW HELP: ALTER PARTITION
@@ -2024,6 +2139,7 @@ alter_database_stmt:
 //    CALLED ON NULL INPUT | RETURNS NULL ON NULL INPUT | STRICT
 //    IMMUTABLE | STABLE | VOLATILE
 //    [ NOT ] LEAKPROOF
+//    [ EXTERNAL ] SECURITY { INVOKER | DEFINER }
 // %SeeAlso: WEBDOCS/alter-function.html
 alter_func_stmt:
   alter_func_options_stmt
@@ -2568,6 +2684,7 @@ set_zone_config:
   {
     $$.val = &tree.SetZoneConfig{
       ZoneConfigSettings: tree.ZoneConfigSettings {
+        Discard: true,
         YAMLConfig: tree.DNull,
       },
     }
@@ -2629,8 +2746,8 @@ alter_zone_partition_stmt:
     s.ZoneSpecifier = tree.ZoneSpecifier{
        TableOrIndex: tree.TableIndexName{Table: name},
        Partition: tree.Name($3),
+       StarIndex: true,
     }
-    s.AllIndexes = true
     $$.val = s
   }
 | ALTER PARTITION partition_name OF TABLE table_name '@' error
@@ -2751,6 +2868,53 @@ alter_table_cmd:
   {
     $$.val = &tree.AlterTableDropNotNull{Column: tree.Name($3)}
   }
+  // ALTER TABLE <name> ALTER [COLUMN] <colname> ADD GENERATED ALWAYS AS IDENTITY
+| ALTER opt_column column_name ADD generated_always_as IDENTITY {
+    qualification := tree.GeneratedAlwaysAsIdentity{}
+    $$.val = &tree.AlterTableAddIdentity{Column: tree.Name($3), Qualification: &qualification}
+  }
+  // ALTER TABLE <name> ALTER [COLUMN] <colname> ADD GENERATED BY DEFAULT AS IDENTITY
+| ALTER opt_column column_name ADD generated_by_default_as IDENTITY {
+    qualification := tree.GeneratedByDefAsIdentity{}
+    $$.val = &tree.AlterTableAddIdentity{Column: tree.Name($3), Qualification: &qualification}
+  }
+  // ALTER TABLE <name> ALTER [COLUMN] <colname> ADD GENERATED ALWAYS AS IDENTITY ( <opt_sequence_option_list> )
+| ALTER opt_column column_name ADD generated_always_as IDENTITY '(' opt_sequence_option_list ')' {
+    qualification := tree.GeneratedAlwaysAsIdentity{
+      SeqOptions: $8.seqOpts(),
+    }
+    $$.val = &tree.AlterTableAddIdentity{Column: tree.Name($3), Qualification: &qualification}
+  }
+  // ALTER TABLE <name> ALTER [COLUMN] <colname> ADD GENERATED BY DEFAULT AS IDENTITY ( <opt_sequence_option_list> )
+| ALTER opt_column column_name ADD generated_by_default_as IDENTITY '(' opt_sequence_option_list ')' {
+    qualification := tree.GeneratedByDefAsIdentity{
+      SeqOptions: $8.seqOpts(),
+    }
+    $$.val = &tree.AlterTableAddIdentity{Column: tree.Name($3), Qualification: &qualification}
+}
+  // ALTER TABLE <name> ALTER [COLUMN] <colname> SET GENERATED ALWAYS
+| ALTER opt_column column_name set_generated_always {
+    $$.val = &tree.AlterTableSetIdentity{Column: tree.Name($3), GeneratedAsIdentityType: tree.GeneratedAlways}
+  }
+  // ALTER TABLE <name> ALTER [COLUMN] <colname> SET GENERATED BY DEFAULT
+| ALTER opt_column column_name set_generated_default {
+    $$.val = &tree.AlterTableSetIdentity{Column: tree.Name($3), GeneratedAsIdentityType: tree.GeneratedByDefault}
+  }
+  // ALTER TABLE <name> ALTER [COLUMN] <colname> <identity_option_list>
+| ALTER opt_column column_name identity_option_list
+  {
+    $$.val = &tree.AlterTableIdentity{Column: tree.Name($3), SeqOptions: $4.seqOpts()}
+  }
+  // ALTER TABLE <name> ALTER [COLUMN] <colname> DROP IDENTITY
+| ALTER opt_column column_name DROP IDENTITY
+  {
+    $$.val = &tree.AlterTableDropIdentity{Column: tree.Name($3), IfExists: false}
+  }
+  // ALTER TABLE <name> ALTER [COLUMN] <colname> DROP IDENTITY IF EXISTS
+| ALTER opt_column column_name DROP IDENTITY IF EXISTS
+  {
+    $$.val = &tree.AlterTableDropIdentity{Column: tree.Name($3), IfExists: true}
+  }
   // ALTER TABLE <name> ALTER [COLUMN] <colname> DROP STORED
 | ALTER opt_column column_name DROP STORED
   {
@@ -2895,6 +3059,12 @@ alter_table_cmd:
       Params: $3.storageParamKeys(),
     }
   }
+| table_rls_mode ROW LEVEL SECURITY
+  {
+    $$.val = &tree.AlterTableSetRLSMode{
+      Mode: $1.rlsTableMode(),
+    }
+  }
 
 audit_mode:
   READ WRITE { $$.val = tree.AuditModeReadWrite }
@@ -2929,7 +3099,7 @@ alter_column_default:
   }
 
 alter_column_on_update:
-  SET ON UPDATE b_expr
+  SET ON UPDATE a_expr
   {
     $$.val = $4.expr()
   }
@@ -2983,6 +3153,37 @@ opt_validate_behavior:
     $$.val = tree.ValidationDefault
   }
 
+identity_option_elem:
+  SET CYCLE                        { /* SKIP DOC */
+                                  $$.val = tree.SequenceOption{Name: tree.SeqOptCycle} }
+  | SET NO CYCLE                     { $$.val = tree.SequenceOption{Name: tree.SeqOptNoCycle} }
+  | SET CACHE signed_iconst64        { x := $3.int64()
+                                  $$.val = tree.SequenceOption{Name: tree.SeqOptCache, IntVal: &x} }
+  | SET INCREMENT signed_iconst64    { x := $3.int64()
+                                  $$.val = tree.SequenceOption{Name: tree.SeqOptIncrement, IntVal: &x} }
+  | SET INCREMENT BY signed_iconst64 { x := $4.int64()
+                                  $$.val = tree.SequenceOption{Name: tree.SeqOptIncrement, IntVal: &x, OptionalWord: true} }
+  | SET MINVALUE signed_iconst64     { x := $3.int64()
+                                  $$.val = tree.SequenceOption{Name: tree.SeqOptMinValue, IntVal: &x} }
+  | SET NO MINVALUE                  { $$.val = tree.SequenceOption{Name: tree.SeqOptMinValue} }
+  | SET MAXVALUE signed_iconst64     { x := $3.int64()
+                                  $$.val = tree.SequenceOption{Name: tree.SeqOptMaxValue, IntVal: &x} }
+  | SET NO MAXVALUE                  { $$.val = tree.SequenceOption{Name: tree.SeqOptMaxValue} }
+  | SET START signed_iconst64        { x := $3.int64()
+                                  $$.val = tree.SequenceOption{Name: tree.SeqOptStart, IntVal: &x} }
+  | SET START WITH signed_iconst64   { x := $4.int64()
+                                  $$.val = tree.SequenceOption{Name: tree.SeqOptStart, IntVal: &x, OptionalWord: true} }
+  | RESTART                      { $$.val = tree.SequenceOption{Name: tree.SeqOptRestart} }
+  | RESTART signed_iconst64      { x := $2.int64()
+                                  $$.val = tree.SequenceOption{Name: tree.SeqOptRestart, IntVal: &x} }
+  | RESTART WITH signed_iconst64 { x := $3.int64()
+                                  $$.val = tree.SequenceOption{Name: tree.SeqOptRestart, IntVal: &x, OptionalWord: true} }
+  | SET sequence_option_elem error                      { return setErr(sqllex, errors.Newf("sequence option \"%s\" not supported here", $2.seqOpt().Name)) }
+
+identity_option_list:
+  identity_option_elem                       { $$.val = []tree.SequenceOption{$1.seqOpt()} }
+| identity_option_list identity_option_elem  { $$.val = append($1.seqOpts(), $2.seqOpt()) }
+
 // %Help: ALTER TYPE - change the definition of a type.
 // %Category: DDL
 // %Text: ALTER TYPE <typename> <command>
@@ -3153,14 +3354,15 @@ alter_attribute_action:
 // %Help: REFRESH - recalculate a materialized view
 // %Category: Misc
 // %Text:
-// REFRESH MATERIALIZED VIEW [CONCURRENTLY] view_name [WITH [NO] DATA]
+// REFRESH MATERIALIZED VIEW [CONCURRENTLY] view_name [AS OF SYSTEM TIME <expr>>] [WITH [NO] DATA]
 refresh_stmt:
-  REFRESH MATERIALIZED VIEW opt_concurrently view_name opt_clear_data
+  REFRESH MATERIALIZED VIEW opt_concurrently view_name opt_as_of_clause opt_clear_data
   {
     $$.val = &tree.RefreshMaterializedView{
       Name: $5.unresolvedObjectName(),
       Concurrently: $4.bool(),
-      RefreshDataOption: $6.refreshDataOption(),
+      AsOf: $6.asOfClause(),
+      RefreshDataOption: $7.refreshDataOption(),
     }
   }
 | REFRESH error // SHOW HELP: REFRESH
@@ -3223,7 +3425,6 @@ backup_stmt:
     $$.val = &tree.Backup{
       Targets: $2.backupTargetListPtr(),
       To: $6.stringOrPlaceholderOptList(),
-      Nested: true,
       AppendToLatest: false,
       Subdir: $4.expr(),
       AsOf: $7.asOfClause(),
@@ -3235,7 +3436,6 @@ backup_stmt:
     $$.val = &tree.Backup{
       Targets: $2.backupTargetListPtr(),
       To: $4.stringOrPlaceholderOptList(),
-      Nested: true,
       AsOf: $5.asOfClause(),
       Options: *$6.backupOptions(),
     }
@@ -3245,21 +3445,15 @@ backup_stmt:
     $$.val = &tree.Backup{
       Targets: $2.backupTargetListPtr(),
       To: $6.stringOrPlaceholderOptList(),
-      Nested: true,
       AppendToLatest: true,
       AsOf: $7.asOfClause(),
       Options: *$8.backupOptions(),
     }
   }
-| BACKUP opt_backup_targets TO string_or_placeholder_opt_list opt_as_of_clause opt_incremental opt_with_backup_options
+| BACKUP opt_backup_targets TO error
   {
-    $$.val = &tree.Backup{
-      Targets: $2.backupTargetListPtr(),
-      To: $4.stringOrPlaceholderOptList(),
-      IncrementalFrom: $6.exprs(),
-      AsOf: $5.asOfClause(),
-      Options: *$7.backupOptions(),
-    }
+    setErr(sqllex, errors.New("The `BACKUP TO` syntax is no longer supported. Please use `BACKUP INTO` to create a backup collection."))
+    return helpWith(sqllex, "BACKUP")
   }
 | BACKUP error // SHOW HELP: BACKUP
 
@@ -3532,6 +3726,14 @@ alter_backup_schedule_cmd:
 		  Option:  $4.kvOption(),
 		}
   }
+| EXECUTE IMMEDIATELY
+  {
+    $$.val = &tree.AlterBackupScheduleNextRun{}
+  }
+| EXECUTE FULL IMMEDIATELY
+  {
+    $$.val = &tree.AlterBackupScheduleNextRun{Full: true}
+  }
 
 // sconst_or_placeholder matches a simple string, or a placeholder.
 sconst_or_placeholder:
@@ -3626,6 +3828,64 @@ create_external_connection_stmt:
 	}
  | CREATE EXTERNAL CONNECTION error // SHOW HELP: CREATE EXTERNAL CONNECTION
 
+// %Help: CHECK EXTERNAL CONNECTION - check the status of an external connection
+// %Category: Misc
+// %Text:
+// CREATE EXTERNAL CONNECTION <uri> [WITH <options>]
+//
+// Uri:
+//   Uri for the external connection.
+check_external_connection_stmt:
+	CHECK EXTERNAL CONNECTION string_or_placeholder opt_with_check_external_connection_options_list
+	{
+	$$.val = &tree.CheckExternalConnection{
+		URI: $4.expr(),
+		Options: *($5.checkExternalConnectionOptions()),
+	}
+	}
+ | CHECK EXTERNAL CONNECTION error // SHOW HELP: CHECK EXTERNAL CONNECTION
+
+opt_with_check_external_connection_options_list:
+  WITH check_external_connection_options_list
+  {
+    $$.val = $2.checkExternalConnectionOptions()
+  }
+| WITH OPTIONS '(' check_external_connection_options_list ')'
+  {
+    $$.val = $4.checkExternalConnectionOptions()
+  }
+| /* EMPTY */
+  {
+    $$.val = &tree.CheckExternalConnectionOptions{}
+  }
+
+check_external_connection_options_list:
+  // Require at least one option
+  check_external_connection_options
+  {
+    $$.val = $1.checkExternalConnectionOptions()
+  }
+| check_external_connection_options_list ',' check_external_connection_options
+  {
+    if err := $1.checkExternalConnectionOptions().CombineWith($3.checkExternalConnectionOptions()); err != nil {
+      return setErr(sqllex, err)
+    }
+  }
+
+check_external_connection_options:
+  TRANSFER '=' string_or_placeholder
+ {
+  $$.val = &tree.CheckExternalConnectionOptions{TransferSize: $3.expr()}
+ }
+ | TIME '=' string_or_placeholder
+ {
+  $$.val = &tree.CheckExternalConnectionOptions{Duration: $3.expr()}
+ }
+ | CONCURRENTLY '=' a_expr
+ {
+  $$.val = &tree.CheckExternalConnectionOptions{Concurrency: $3.expr()}
+ }
+
 // %Help: DROP EXTERNAL CONNECTION - drop an existing external connection
 // %Category: Misc
 // %Text:
@@ -3636,9 +3896,9 @@ create_external_connection_stmt:
 drop_external_connection_stmt:
 	DROP EXTERNAL CONNECTION string_or_placeholder
 	{
-      $$.val = &tree.DropExternalConnection{
-            ConnectionLabel: $4.expr(),
-      }
+	$$.val = &tree.DropExternalConnection{
+	    ConnectionLabel: $4.expr(),
+	}
 	}
 	| DROP EXTERNAL CONNECTION error // SHOW HELP: DROP EXTERNAL CONNECTION
 
@@ -3671,64 +3931,51 @@ drop_external_connection_stmt:
 //    kms="[kms_provider]://[kms_host]/[master_key_identifier]?[parameters]" : decrypt backups using KMS
 //    detached: execute restore job asynchronously, without waiting for its completion
 //    skip_localities_check: ignore difference of zone configuration between restore cluster and backup cluster
-//    debug_pause_on: describes the events that the job should pause itself on for debugging purposes.
 //    new_db_name: renames the restored database. only applies to database restores
 //    include_all_virtual_clusters: enable backups of all virtual clusters during a cluster backup
 // %SeeAlso: BACKUP, WEBDOCS/restore.html
 restore_stmt:
-  RESTORE FROM list_of_string_or_placeholder_opt_list opt_as_of_clause opt_with_restore_options
+  RESTORE FROM error
   {
-    $$.val = &tree.Restore{
-    DescriptorCoverage: tree.AllDescriptors,
-    From: $3.listOfStringOrPlaceholderOptList(),
-    AsOf: $4.asOfClause(),
-    Options: *($5.restoreOptions()),
-    }
+    setErr(sqllex, errors.New("The `RESTORE FROM <backupURI>` syntax is no longer supported. Please use `RESTORE FROM <subdirectory> IN <collectionURI>`."))
+    return helpWith(sqllex, "RESTORE")
   }
-| RESTORE FROM string_or_placeholder IN list_of_string_or_placeholder_opt_list opt_as_of_clause opt_with_restore_options
+| RESTORE FROM string_or_placeholder IN string_or_placeholder_opt_list opt_as_of_clause opt_with_restore_options
   {
     $$.val = &tree.Restore{
     DescriptorCoverage: tree.AllDescriptors,
 		Subdir: $3.expr(),
-		From: $5.listOfStringOrPlaceholderOptList(),
+		From: $5.stringOrPlaceholderOptList(),
 		AsOf: $6.asOfClause(),
 		Options: *($7.restoreOptions()),
     }
   }
-| RESTORE backup_targets FROM list_of_string_or_placeholder_opt_list opt_as_of_clause opt_with_restore_options
+| RESTORE backup_targets FROM error
   {
-    $$.val = &tree.Restore{
-    Targets: $2.backupTargetList(),
-    From: $4.listOfStringOrPlaceholderOptList(),
-    AsOf: $5.asOfClause(),
-    Options: *($6.restoreOptions()),
-    }
+    setErr(sqllex, errors.New("The `RESTORE <targets> FROM <backupURI>` syntax is no longer supported. Please use `RESTORE <targets> FROM <subdirectory> IN <collectionURI>`."))
+    return helpWith(sqllex, "RESTORE")
   }
-| RESTORE backup_targets FROM string_or_placeholder IN list_of_string_or_placeholder_opt_list opt_as_of_clause opt_with_restore_options
+| RESTORE backup_targets FROM string_or_placeholder IN string_or_placeholder_opt_list opt_as_of_clause opt_with_restore_options
   {
     $$.val = &tree.Restore{
       Targets: $2.backupTargetList(),
       Subdir: $4.expr(),
-      From: $6.listOfStringOrPlaceholderOptList(),
+      From: $6.stringOrPlaceholderOptList(),
       AsOf: $7.asOfClause(),
       Options: *($8.restoreOptions()),
     }
   }
-| RESTORE SYSTEM USERS FROM list_of_string_or_placeholder_opt_list opt_as_of_clause opt_with_restore_options
+| RESTORE SYSTEM USERS FROM error
   {
-    $$.val = &tree.Restore{
-      DescriptorCoverage: tree.SystemUsers,
-      From: $5.listOfStringOrPlaceholderOptList(),
-      AsOf: $6.asOfClause(),
-      Options: *($7.restoreOptions()),
-    }
+    setErr(sqllex, errors.New("The `RESTORE <targets> FROM <backupURI>` syntax is no longer supported. Please use `RESTORE <targets> FROM <subdirectory> IN <collectionURI>`."))
+    return helpWith(sqllex, "RESTORE")
   }
-| RESTORE SYSTEM USERS FROM string_or_placeholder IN list_of_string_or_placeholder_opt_list opt_as_of_clause opt_with_restore_options
+| RESTORE SYSTEM USERS FROM string_or_placeholder IN string_or_placeholder_opt_list opt_as_of_clause opt_with_restore_options
   {
     $$.val = &tree.Restore{
       DescriptorCoverage: tree.SystemUsers,
       Subdir: $5.expr(),
-      From: $7.listOfStringOrPlaceholderOptList(),
+      From: $7.stringOrPlaceholderOptList(),
       AsOf: $8.asOfClause(),
       Options: *($9.restoreOptions()),
     }
@@ -3745,16 +3992,6 @@ string_or_placeholder_opt_list:
     $$.val = tree.StringOrPlaceholderOptList($2.exprs())
   }
 
-list_of_string_or_placeholder_opt_list:
-  string_or_placeholder_opt_list
-  {
-    $$.val = []tree.StringOrPlaceholderOptList{$1.stringOrPlaceholderOptList()}
-  }
-| list_of_string_or_placeholder_opt_list ',' string_or_placeholder_opt_list
-  {
-    $$.val = append($1.listOfStringOrPlaceholderOptList(), $3.stringOrPlaceholderOptList())
-  }
-
 // Optional restore options.
 opt_with_restore_options:
   WITH restore_options_list
@@ -3825,22 +4062,10 @@ restore_options:
   {
     $$.val = &tree.RestoreOptions{SkipLocalitiesCheck: true}
   }
-| DEBUG_PAUSE_ON '=' string_or_placeholder
-  {
-    $$.val = &tree.RestoreOptions{DebugPauseOn: $3.expr()}
-  }
 | NEW_DB_NAME '=' string_or_placeholder
   {
     $$.val = &tree.RestoreOptions{NewDBName: $3.expr()}
   }
-| include_all_clusters
-  {
-    $$.val = &tree.RestoreOptions{IncludeAllSecondaryTenants: tree.MakeDBool(true)}
-  }
-| include_all_clusters '=' a_expr
-  {
-    $$.val = &tree.RestoreOptions{IncludeAllSecondaryTenants: $3.expr()}
-  }
 | INCREMENTAL_LOCATION '=' string_or_placeholder_opt_list
 	{
 		$$.val = &tree.RestoreOptions{IncrementalStorage: $3.stringOrPlaceholderOptList()}
@@ -3873,6 +4098,10 @@ restore_options:
   {
     $$.val = &tree.RestoreOptions{ExperimentalOnline: true}
   }
+| EXPERIMENTAL COPY
+{
+  $$.val = &tree.RestoreOptions{ExperimentalCopy: true}
+}
 | REMOVE_REGIONS
   {
     $$.val = &tree.RestoreOptions{RemoveRegions: true, SkipLocalitiesCheck: true}
@@ -3998,16 +4227,6 @@ string_or_placeholder_list:
     $$.val = append($1.exprs(), $3.expr())
   }
 
-opt_incremental:
-  INCREMENTAL FROM string_or_placeholder_list
-  {
-    $$.val = $3.exprs()
-  }
-| /* EMPTY */
-  {
-    $$.val = tree.Exprs(nil)
-  }
-
 kv_option:
   name '=' string_or_placeholder
   {
@@ -4205,9 +4424,9 @@ copy_options:
   {
     return unimplementedWithIssueDetail(sqllex, 41608, "force_null")
   }
-| ENCODING SCONST error
+| ENCODING SCONST
   {
-    return unimplementedWithIssueDetail(sqllex, 41608, "encoding")
+    $$.val = &tree.CopyOptions{Encoding: tree.NewStrVal($2)}
   }
 
 copy_generic_options:
@@ -4290,9 +4509,9 @@ copy_generic_options:
   {
     return unimplementedWithIssueDetail(sqllex, 41608, "force_null")
   }
-| ENCODING SCONST error
+| ENCODING SCONST
   {
-    return unimplementedWithIssueDetail(sqllex, 41608, "encoding")
+    $$.val = &tree.CopyOptions{Encoding: tree.NewStrVal($2)}
   }
 
 // %Help: CANCEL
@@ -4424,6 +4643,10 @@ comment_stmt:
   {
     $$.val = &tree.CommentOnSchema{Name: $4.objectNamePrefix(), Comment: $6.strPtr()}
   }
+| COMMENT ON TYPE type_name IS comment_text
+  {
+    $$.val = &tree.CommentOnType{Name: $4.unresolvedObjectName(), Comment: $6.strPtr()}
+  }
 | COMMENT ON TABLE table_name IS comment_text
   {
     $$.val = &tree.CommentOnTable{Table: $4.unresolvedObjectName(), Comment: $6.strPtr()}
@@ -4483,56 +4706,250 @@ create_stmt:
 | create_extension_stmt  // EXTEND WITH HELP: CREATE EXTENSION
 | create_external_connection_stmt // EXTEND WITH HELP: CREATE EXTERNAL CONNECTION
 | create_virtual_cluster_stmt     // EXTEND WITH HELP: CREATE VIRTUAL CLUSTER
+| create_logical_replication_stream_stmt     // EXTEND WITH HELP: CREATE LOGICAL REPLICATION STREAM
 | create_schedule_stmt   // help texts in sub-rule
 | create_unsupported     {}
 | CREATE error           // SHOW HELP: CREATE
 
+// %Help: CHECK
+// %Category: Group
+// %Text:
+// CHECK EXTERNAL CONNECTION
+check_stmt:
+  check_external_connection_stmt // EXTEND WITH HELP: CHECK EXTERNAL CONNECTION
+| CHECK error // SHOW HELP: CHECK
+
+// %Help: CREATE LOGICAL REPLICATION STREAM - create a new logical replication stream
+// %Category: Experimental
+// %Text:
+// CREATE LOGICAL REPLICATION STREAM
+//  FROM <TABLE remote_name | TABLES (remote_name, ...) | DATABASE remote_name>
+//  ON 'stream_uri'
+//  INTO <TABLE remote_name | TABLES (remote_name, ...) | DATABASE remote_name>
+//  [WITH
+//  < MODE = immediate | validated > |
+//  < CURSOR = start_time > |
+//  < DEFAULT FUNCTION = lww | dlq | udf
+//  < FUNCTION 'udf' FOR TABLE local_name  , ... > |
+//  < DISCARD = 'ttl-deletes' >
+// ]
+create_logical_replication_stream_stmt:
+  CREATE LOGICAL REPLICATION STREAM FROM logical_replication_resources ON string_or_placeholder INTO logical_replication_resources opt_logical_replication_options
+  {
+    /* SKIP DOC */
+    $$.val = &tree.CreateLogicalReplicationStream{
+      From: $6.logicalReplicationResources(),
+      PGURL: $8.expr(),
+      Into: $10.logicalReplicationResources(),
+      Options: *$11.logicalReplicationOptions(),
+    }
+  }
+| CREATE LOGICALLY REPLICATED logical_replication_resources FROM logical_replication_resources ON string_or_placeholder opt_logical_replication_create_table_options
+  {
+    $$.val = &tree.CreateLogicalReplicationStream{
+      Into: $4.logicalReplicationResources(),
+      From: $6.logicalReplicationResources(),
+      PGURL: $8.expr(),
+      CreateTable: true,
+      Options: *$9.logicalReplicationOptions(),
+    }
+  }
+| CREATE LOGICAL REPLICATION STREAM error // SHOW HELP: CREATE LOGICAL REPLICATION STREAM
+
+logical_replication_resources:
+  TABLE db_object_name
+  {
+    $$.val = tree.LogicalReplicationResources{
+      Tables: []*tree.UnresolvedName{
+        $2.unresolvedObjectName().ToUnresolvedName(),
+      },
+    }
+  }
+| TABLES '(' logical_replication_resources_list ')'
+  {
+    $$.val = $3.logicalReplicationResources()
+  }
+| DATABASE database_name
+  {
+    $$.val = tree.LogicalReplicationResources{
+      Database: tree.Name($2),
+    }
+  }
+
+logical_replication_resources_list:
+  db_object_name
+  {
+    $$.val = tree.LogicalReplicationResources{
+      Tables: []*tree.UnresolvedName{
+        $1.unresolvedObjectName().ToUnresolvedName(),
+      },
+    }
+  }
+| logical_replication_resources_list ',' db_object_name
+  {
+    $$.val = tree.LogicalReplicationResources{
+      Tables: append($1.logicalReplicationResources().Tables, $3.unresolvedObjectName().ToUnresolvedName()),
+    }
+  }
+
+// Optional logical replication options.
+opt_logical_replication_options:
+  WITH logical_replication_options_list
+  {
+    $$.val = $2.logicalReplicationOptions()
+  }
+| WITH OPTIONS '(' logical_replication_options_list ')'
+  {
+    $$.val = $4.logicalReplicationOptions()
+  }
+| /* EMPTY */
+  {
+    $$.val = &tree.LogicalReplicationOptions{}
+  }
+
+opt_logical_replication_create_table_options:
+  WITH logical_replication_create_table_options_list
+  {
+    $$.val = $2.logicalReplicationOptions()
+  }
+| WITH OPTIONS '(' logical_replication_create_table_options_list ')'
+  {
+    $$.val = $4.logicalReplicationOptions()
+  }
+| /* EMPTY */
+  {
+    $$.val = &tree.LogicalReplicationOptions{}
+  }
+
+logical_replication_options_list:
+  // Require at least one option
+  logical_replication_options
+  {
+    $$.val = $1.logicalReplicationOptions()
+  }
+| logical_replication_options_list ',' logical_replication_options
+  {
+    if err := $1.logicalReplicationOptions().CombineWith($3.logicalReplicationOptions()); err != nil {
+      return setErr(sqllex, err)
+    }
+  }
+
+logical_replication_create_table_options_list:
+  // Require at least one option
+  logical_replication_create_table_options
+  {
+    $$.val = $1.logicalReplicationOptions()
+  }
+| logical_replication_create_table_options_list ',' logical_replication_create_table_options
+  {
+    if err := $1.logicalReplicationOptions().CombineWith($3.logicalReplicationOptions()); err != nil {
+      return setErr(sqllex, err)
+    }
+  }
+
+// List of valid logical replication options.
+logical_replication_options:
+  CURSOR '=' string_or_placeholder
+  {
+    $$.val = &tree.LogicalReplicationOptions{Cursor: $3.expr()}
+  }
+|
+  MODE '=' string_or_placeholder
+  {
+    $$.val = &tree.LogicalReplicationOptions{Mode: $3.expr()}
+  }
+| DEFAULT FUNCTION '=' string_or_placeholder
+  {
+    $$.val = &tree.LogicalReplicationOptions{DefaultFunction: $4.expr()}
+  }
+| FUNCTION db_object_name FOR TABLE db_object_name
+  {
+     $$.val = &tree.LogicalReplicationOptions{UserFunctions: map[tree.UnresolvedName]tree.RoutineName{*$5.unresolvedObjectName().ToUnresolvedName():$2.unresolvedObjectName().ToRoutineName()}}
+  }
+ | DISCARD '=' string_or_placeholder
+  {
+    $$.val = &tree.LogicalReplicationOptions{Discard: $3.expr()}
+  }
+| SKIP SCHEMA CHECK
+  {
+    $$.val = &tree.LogicalReplicationOptions{SkipSchemaCheck: tree.MakeDBool(true)}
+  }
+| LABEL '=' string_or_placeholder
+  {
+    $$.val = &tree.LogicalReplicationOptions{MetricsLabel: $3.expr()}
+  }
+| PARENT '=' string_or_placeholder
+  /* SKIP DOC */
+  {
+    $$.val = &tree.LogicalReplicationOptions{ParentID: $3.expr()}
+  }
+
+
+logical_replication_create_table_options:
+  MODE '=' string_or_placeholder
+  {
+    $$.val = &tree.LogicalReplicationOptions{Mode: $3.expr()}
+  }
+ | DISCARD '=' string_or_placeholder
+  {
+    $$.val = &tree.LogicalReplicationOptions{Discard: $3.expr()}
+  }
+| LABEL '=' string_or_placeholder
+  {
+    $$.val = &tree.LogicalReplicationOptions{MetricsLabel: $3.expr()}
+  }
+| UNIDIRECTIONAL
+  {
+   $$.val = &tree.LogicalReplicationOptions{Unidirectional: tree.MakeDBool(true)} 
+  }
+| BIDIRECTIONAL ON string_or_placeholder
+  {
+   $$.val = &tree.LogicalReplicationOptions{BidirectionalURI: $3.expr()} 
+  }
+
+
 // %Help: CREATE VIRTUAL CLUSTER - create a new virtual cluster
 // %Category: Experimental
 // %Text:
-// CREATE VIRTUAL CLUSTER [ IF NOT EXISTS ] name [ LIKE <virtual_cluster_spec> ] [ <replication> ]
+// CREATE VIRTUAL CLUSTER [ IF NOT EXISTS ] name [ <replication> ]
 //
 // Replication option:
-//    FROM REPLICATION OF <virtual_cluster_spec> ON <location> [ WITH OPTIONS ... ]
+//    FROM REPLICATION OF name ON <location> [ WITH OPTIONS ... ]
 create_virtual_cluster_stmt:
-  CREATE virtual_cluster d_expr opt_like_virtual_cluster
+  CREATE virtual_cluster virtual_cluster_spec
   {
     /* SKIP DOC */
     $$.val = &tree.CreateTenant{
-      TenantSpec: &tree.TenantSpec{IsName: true, Expr: $3.expr()},
-      Like: $4.likeTenantSpec(),
+      TenantSpec: $3.tenantSpec(),
     }
   }
-| CREATE virtual_cluster IF NOT EXISTS d_expr opt_like_virtual_cluster
+| CREATE virtual_cluster IF NOT EXISTS virtual_cluster_spec
   {
     /* SKIP DOC */
     $$.val = &tree.CreateTenant{
       IfNotExists: true,
-      TenantSpec: &tree.TenantSpec{IsName: true, Expr: $6.expr()},
-      Like: $7.likeTenantSpec(),
+      TenantSpec: $6.tenantSpec(),
     }
   }
-| CREATE virtual_cluster d_expr opt_like_virtual_cluster FROM REPLICATION OF d_expr ON d_expr opt_with_replication_options
+| CREATE virtual_cluster virtual_cluster_spec FROM REPLICATION OF d_expr ON d_expr opt_with_replication_options
   {
     /* SKIP DOC */
     $$.val = &tree.CreateTenantFromReplication{
-      TenantSpec: &tree.TenantSpec{IsName: true, Expr: $3.expr()},
-      ReplicationSourceTenantName: &tree.TenantSpec{IsName: true, Expr: $8.expr()},
-      ReplicationSourceAddress: $10.expr(),
-      Options: *$11.tenantReplicationOptions(),
-      Like: $4.likeTenantSpec(),
+      TenantSpec: $3.tenantSpec(),
+      ReplicationSourceTenantName: &tree.TenantSpec{IsName: true, Expr: $7.expr()},
+      ReplicationSourceConnUri: $9.expr(),
+      Options: *$10.tenantReplicationOptions(),
     }
   }
-| CREATE virtual_cluster IF NOT EXISTS d_expr opt_like_virtual_cluster FROM REPLICATION OF d_expr ON d_expr opt_with_replication_options
+| CREATE virtual_cluster IF NOT EXISTS virtual_cluster_spec FROM REPLICATION OF d_expr ON d_expr opt_with_replication_options
   {
     /* SKIP DOC */
     $$.val = &tree.CreateTenantFromReplication{
       IfNotExists: true,
-      TenantSpec: &tree.TenantSpec{IsName: true, Expr: $6.expr()},
-      ReplicationSourceTenantName: &tree.TenantSpec{IsName: true, Expr: $11.expr()},
-      ReplicationSourceAddress: $13.expr(),
-      Options: *$14.tenantReplicationOptions(),
-      Like: $7.likeTenantSpec(),
+      TenantSpec: $6.tenantSpec(),
+      ReplicationSourceTenantName: &tree.TenantSpec{IsName: true, Expr: $10.expr()},
+      ReplicationSourceConnUri: $12.expr(),
+      Options: *$13.tenantReplicationOptions(),
     }
   }
 | CREATE virtual_cluster error // SHOW HELP: CREATE VIRTUAL CLUSTER
@@ -4541,19 +4958,6 @@ virtual_cluster:
   TENANT { /* SKIP DOC */ }
 | VIRTUAL CLUSTER
 
-// opt_like_virtual_cluster defines a LIKE clause for CREATE VIRTUAL CLUSTER.
-// Eventually this can grow to support INCLUDING/EXCLUDING options
-// like in CREATE TABLE.
-opt_like_virtual_cluster:
-  /* EMPTY */
-  {
-     $$.val = &tree.LikeTenantSpec{}
-  }
-| LIKE virtual_cluster_spec
-  {
-      $$.val = &tree.LikeTenantSpec{OtherTenant: $2.tenantSpec()}
-  }
-
 // Optional tenant replication options.
 opt_with_replication_options:
   WITH replication_options_list
@@ -4588,10 +4992,29 @@ replication_options:
   {
     $$.val = &tree.TenantReplicationOptions{Retention: $3.expr()}
   }
-|
-  RESUME TIMESTAMP '=' d_expr
+| READ VIRTUAL CLUSTER
+  {
+    $$.val = &tree.TenantReplicationOptions{EnableReaderTenant: tree.MakeDBool(true)}
+  }
+
+source_replication_options_list:
+  // Require at least one option
+  source_replication_options
+  {
+    $$.val = $1.tenantReplicationOptions()
+  }
+| source_replication_options_list ',' source_replication_options
+  {
+    if err := $1.tenantReplicationOptions().CombineWith($3.tenantReplicationOptions()); err != nil {
+      return setErr(sqllex, err)
+    }
+  }
+
+  // List of valid tenant replication options.
+source_replication_options:
+  EXPIRATION WINDOW '=' d_expr
   {
-    $$.val = &tree.TenantReplicationOptions{ResumeTimestamp: $4.expr()}
+      $$.val = &tree.TenantReplicationOptions{ExpirationWindow: $4.expr()}
   }
 
 // %Help: CREATE SCHEDULE
@@ -4624,38 +5047,278 @@ create_extension_stmt:
   }
 | CREATE EXTENSION error // SHOW HELP: CREATE EXTENSION
 
-// %Help: CREATE FUNCTION - define a new function
+// %Help: ALTER POLICY - alter an existing row-level security policy
 // %Category: DDL
 // %Text:
-// CREATE [ OR REPLACE ] FUNCTION
-//    name ( [ [ argmode ] [ argname ] argtype [, ...] ] )
-//    [ RETURNS rettype ]
-//  { LANGUAGE lang_name
-//    | { IMMUTABLE | STABLE | VOLATILE }
-//    | [ NOT ] LEAKPROOF
-//    | { CALLED ON NULL INPUT | RETURNS NULL ON NULL INPUT | STRICT }
-//    | AS 'definition'
-//  } ...
-// %SeeAlso: WEBDOCS/create-function.html
-create_func_stmt:
-  CREATE opt_or_replace FUNCTION routine_create_name '(' opt_routine_param_with_default_list ')'
-  RETURNS opt_return_table opt_return_set routine_return_type
-  opt_create_routine_opt_list opt_routine_body
-  {
+// ALTER POLICY name ON table_name RENAME TO new_policy_name
+//
+// ALTER POLICY name ON table_name
+//       [ TO { role_name | PUBLIC | CURRENT_USER | SESSION_USER } [, ...] ]
+//       [ USING ( using_expression ) ]
+//       [ WITH CHECK ( check_expression ) ]
+//
+// %SeeAlso: CREATE POLICY, DROP POLICY
+alter_policy_stmt:
+  ALTER POLICY name ON table_name RENAME TO name
+  {
+    $$.val = &tree.AlterPolicy{
+      PolicyName: tree.Name($3),
+      TableName: $5.unresolvedObjectName(),
+      NewPolicyName: tree.Name($8),
+    }
+  }
+| ALTER POLICY name ON table_name opt_policy_roles opt_policy_exprs
+  {
+    $$.val = &tree.AlterPolicy{
+      PolicyName: tree.Name($3),
+      TableName: $5.unresolvedObjectName(),
+      Roles: $6.roleSpecList(),
+      Exprs: $7.policyExpressions(),
+    }
+  }
+| ALTER POLICY error // SHOW HELP: ALTER POLICY
+
+// %Help: CREATE POLICY - define a new row-level security policy for a table
+// %Category: DDL
+// %Text:
+// CREATE POLICY [IF NOT EXISTS] name ON table_name
+//     [ AS { PERMISSIVE | RESTRICTIVE } ]
+//     [ FOR { ALL | SELECT | INSERT | UPDATE | DELETE } ]
+//     [ TO { role_name | PUBLIC | CURRENT_USER | SESSION_USER } [, ...] ]
+//     [ USING ( using_expression ) ]
+//     [ WITH CHECK ( check_expression ) ]
+//
+// %SeeAlso: ALTER POLICY, DROP POLICY
+create_policy_stmt:
+  CREATE POLICY name ON table_name opt_policy_type opt_policy_command opt_policy_roles opt_policy_exprs
+  {
+    $$.val = &tree.CreatePolicy{
+      IfNotExists: false,
+      PolicyName: tree.Name($3),
+      TableName: $5.unresolvedObjectName(),
+      Type: $6.policyType(),
+      Cmd: $7.policyCommand(),
+      Roles: $8.roleSpecList(),
+      Exprs: $9.policyExpressions(),
+    }
+  }
+ | CREATE POLICY IF NOT EXISTS name ON table_name opt_policy_type opt_policy_command opt_policy_roles opt_policy_exprs
+  {
+    $$.val = &tree.CreatePolicy{
+      IfNotExists: true,
+      PolicyName: tree.Name($6),
+      TableName: $8.unresolvedObjectName(),
+      Type: $9.policyType(),
+      Cmd: $10.policyCommand(),
+      Roles: $11.roleSpecList(),
+      Exprs: $12.policyExpressions(),
+    }
+  }
+ | CREATE POLICY error // SHOW HELP: CREATE POLICY
+
+// %Help: DROP POLICY - remove an existing row-level security policy from a table
+// %Category: DDL
+// %Text:
+// DROP POLICY [ IF EXISTS ] name ON table_name [ CASCADE | RESTRICT ]
+//
+// %SeeAlso: CREATE POLICY, ALTER POLICY
+drop_policy_stmt:
+  DROP POLICY name ON table_name opt_drop_behavior
+  {
+    $$.val = &tree.DropPolicy{
+      PolicyName: tree.Name($3),
+      TableName: $5.unresolvedObjectName(),
+      DropBehavior: $6.dropBehavior(),
+      IfExists: false,
+    }
+  }
+| DROP POLICY IF EXISTS name ON table_name opt_drop_behavior
+  {
+    $$.val = &tree.DropPolicy{
+      PolicyName: tree.Name($5),
+      TableName: $7.unresolvedObjectName(),
+      DropBehavior: $8.dropBehavior(),
+      IfExists: true,
+    }
+  }
+| DROP POLICY error // SHOW HELP: DROP POLICY
+
+opt_policy_type:
+  AS PERMISSIVE
+  {
+    $$.val = tree.PolicyTypePermissive
+  }
+| AS RESTRICTIVE
+  {
+    $$.val = tree.PolicyTypeRestrictive
+  }
+| /* EMPTY */
+  {
+    $$.val = tree.PolicyTypeDefault
+  }
+
+opt_policy_command:
+  FOR ALL
+  {
+    $$.val = tree.PolicyCommandAll
+  }
+| FOR SELECT
+  {
+    $$.val = tree.PolicyCommandSelect
+  }
+| FOR INSERT
+  {
+    $$.val = tree.PolicyCommandInsert
+  }
+| FOR UPDATE
+  {
+    $$.val = tree.PolicyCommandUpdate
+  }
+| FOR DELETE
+  {
+    $$.val = tree.PolicyCommandDelete
+  }
+| /* EMPTY */
+  {
+    $$.val = tree.PolicyCommandDefault
+  }
+
+opt_policy_roles:
+ TO role_spec_list
+ {
+   $$.val = $2.roleSpecList()
+ }
+| /* EMPTY */ {
+   $$.val = tree.RoleSpecList(nil)
+}
+
+opt_policy_exprs:
+  USING '(' a_expr ')' WITH CHECK '(' a_expr ')'
+  {
+    $$.val = tree.PolicyExpressions{
+      Using: $3.expr(),
+      WithCheck: $8.expr(),
+    }
+  }
+| WITH CHECK '(' a_expr ')' USING '(' a_expr ')'
+  {
+    $$.val = tree.PolicyExpressions{
+      Using: $8.expr(),
+      WithCheck: $4.expr(),
+    }
+  }
+| WITH CHECK '(' a_expr ')'
+  {
+    $$.val = tree.PolicyExpressions{
+      WithCheck: $4.expr(),
+    }
+ 	}
+| USING '(' a_expr ')'
+  {
+    $$.val = tree.PolicyExpressions{
+      Using: $3.expr(),
+    }
+ 	}
+| /* EMPTY */ {
+   $$.val = tree.PolicyExpressions{}
+}
+
+table_rls_mode:
+  ENABLE
+  {
+    $$.val = tree.TableRLSEnable
+  }
+| DISABLE
+  {
+    $$.val = tree.TableRLSDisable
+  }
+| FORCE
+  {
+    $$.val = tree.TableRLSForce
+  }
+| NO FORCE
+  {
+    $$.val = tree.TableRLSNoForce
+  }
+
+// %Help: CREATE FUNCTION - define a new function
+// %Category: DDL
+// %Text:
+// CREATE [ OR REPLACE ] FUNCTION
+//    name ( [ [ argmode ] [ argname ] argtype [, ...] ] )
+//    [ RETURNS rettype ]
+//  { LANGUAGE lang_name
+//    | { IMMUTABLE | STABLE | VOLATILE }
+//    | [ NOT ] LEAKPROOF
+//    | { CALLED ON NULL INPUT | RETURNS NULL ON NULL INPUT | STRICT }
+//    | AS 'definition'
+//    | { [ EXTERNAL ] SECURITY { INVOKER | DEFINER } }
+//  } ...
+// %SeeAlso: WEBDOCS/create-function.html
+create_func_stmt:
+  CREATE opt_or_replace FUNCTION routine_create_name '(' opt_routine_param_with_default_list ')'
+  RETURNS opt_return_set routine_return_type opt_create_routine_opt_list opt_routine_body
+  {
     name := $4.unresolvedObjectName().ToRoutineName()
     $$.val = &tree.CreateRoutine{
       IsProcedure: false,
       Replace: $2.bool(),
       Name: name,
       Params: $6.routineParams(),
-      ReturnType: tree.RoutineReturnType{
-        Type: $11.typeReference(),
-        SetOf: $10.bool(),
+      ReturnType: &tree.RoutineReturnType{
+        Type: $10.typeReference(),
+        SetOf: $9.bool(),
       },
-      Options: $12.routineOptions(),
-      RoutineBody: $13.routineBody(),
+      Options: $11.routineOptions(),
+      RoutineBody: $12.routineBody(),
+    }
+  }
+| CREATE opt_or_replace FUNCTION routine_create_name '(' opt_routine_param_with_default_list ')'
+  RETURNS TABLE '(' table_func_column_list ')' opt_create_routine_opt_list opt_routine_body
+  {
+    // RETURNS TABLE is syntactic sugar for RETURNS SETOF with:
+    // - RECORD if there are multiple TABLE parameters, or
+    // - the type of the single TABLE parameter.
+    // The TABLE parameters are added to the list of routine parameters.
+    tableParams := $11.routineParams()
+    returnType := tree.ResolvableTypeReference(types.AnyTuple)
+    if len(tableParams) == 1 {
+      returnType = tableParams[0].Type
+    }
+    routineParams := $6.routineParams()
+    for i := range routineParams {
+      // OUT parameters are not allowed in table functions.
+      if tree.IsOutParamClass(routineParams[i].Class) {
+        return setErrNoDetails(sqllex, errors.New("OUT and INOUT arguments aren't allowed in TABLE functions"))
+      }
+    }
+    $$.val = &tree.CreateRoutine{
+      IsProcedure: false,
+      Replace: $2.bool(),
+      Name: $4.unresolvedObjectName().ToRoutineName(),
+      Params: append(routineParams, tableParams...),
+      ReturnType: &tree.RoutineReturnType{
+        Type: returnType,
+        SetOf: true,
+      },
+      Options: $13.routineOptions(),
+      RoutineBody: $14.routineBody(),
     }
   }
+| CREATE opt_or_replace FUNCTION routine_create_name '(' opt_routine_param_with_default_list ')'
+    opt_create_routine_opt_list opt_routine_body
+    {
+        name := $4.unresolvedObjectName().ToRoutineName()
+        $$.val = &tree.CreateRoutine{
+          IsProcedure: false,
+          Replace: $2.bool(),
+          Name: name,
+          Params: $6.routineParams(),
+          ReturnType: (*tree.RoutineReturnType)(nil),
+          Options: $8.routineOptions(),
+          RoutineBody: $9.routineBody(),
+        }
+    }
 | CREATE opt_or_replace FUNCTION error // SHOW HELP: CREATE FUNCTION
 
 // %Help: CREATE PROCEDURE - define a new procedure
@@ -4679,9 +5342,7 @@ create_proc_stmt:
       Params: $6.routineParams(),
       Options: $8.routineOptions(),
       RoutineBody: $9.routineBody(),
-      ReturnType: tree.RoutineReturnType{
-        Type: types.Void,
-      },
+      ReturnType: (*tree.RoutineReturnType)(nil),
     }
   }
 | CREATE opt_or_replace PROCEDURE error // SHOW HELP: CREATE PROCEDURE
@@ -4690,10 +5351,6 @@ opt_or_replace:
   OR REPLACE { $$.val = true }
 | /* EMPTY */ { $$.val = false }
 
-opt_return_table:
-  TABLE { return unimplementedWithIssueDetail(sqllex, 100226, "UDF returning TABLE") }
-| /* EMPTY */ { $$.val = false }
-
 opt_return_set:
   SETOF { $$.val = true}
 | /* EMPTY */ { $$.val = false }
@@ -4749,7 +5406,7 @@ routine_param:
     $$.val = tree.RoutineParam{
       Name: tree.Name($1),
       Type: $2.typeReference(),
-      Class: tree.RoutineParamIn,
+      Class: tree.RoutineParamDefault,
     }
   }
 | routine_param_class routine_param_type
@@ -4763,15 +5420,15 @@ routine_param:
   {
     $$.val = tree.RoutineParam{
       Type: $1.typeReference(),
-      Class: tree.RoutineParamIn,
+      Class: tree.RoutineParamDefault,
     }
   }
 
 routine_param_class:
   IN { $$.val = tree.RoutineParamIn }
-| OUT { return unimplementedWithIssueDetail(sqllex, 100405, "create function with 'OUT' argument class") }
-| INOUT { return unimplementedWithIssueDetail(sqllex, 100405, "create function with 'INOUT' argument class") }
-| IN OUT { return unimplementedWithIssueDetail(sqllex, 100405, "create function with 'IN OUT' argument class") }
+| OUT { $$.val = tree.RoutineParamOut }
+| INOUT { $$.val = tree.RoutineParamInOut }
+| IN OUT { $$.val = tree.RoutineParamInOut }
 | VARIADIC { return unimplementedWithIssueDetail(sqllex, 88947, "variadic user-defined functions") }
 
 routine_param_type:
@@ -4780,6 +5437,25 @@ routine_param_type:
 routine_return_type:
   routine_param_type
 
+table_func_column: param_name routine_param_type
+  {
+    $$.val = tree.RoutineParam{
+      Name: tree.Name($1),
+      Type: $2.typeReference(),
+      Class: tree.RoutineParamOut,
+    }
+  }
+
+table_func_column_list:
+  table_func_column
+  {
+    $$.val = tree.RoutineParams{$1.routineParam()}
+  }
+| table_func_column_list ',' table_func_column
+  {
+    $$.val = append($1.routineParams(), $3.routineParam())
+  }
+
 opt_create_routine_opt_list:
   create_routine_opt_list { $$.val = $1.routineOptions() }
 | /* EMPTY */ { $$.val = tree.RoutineOptions{} }
@@ -4838,19 +5514,19 @@ common_routine_opt_item:
   }
 | EXTERNAL SECURITY DEFINER
   {
-    return unimplemented(sqllex, "create function...security")
+    $$.val = tree.RoutineDefiner
   }
 | EXTERNAL SECURITY INVOKER
   {
-    return unimplemented(sqllex, "create function...security")
+    $$.val = tree.RoutineInvoker
   }
 | SECURITY DEFINER
   {
-    return unimplemented(sqllex, "create function...security")
+    $$.val = tree.RoutineDefiner
   }
 | SECURITY INVOKER
   {
-    return unimplemented(sqllex, "create function...security")
+    $$.val = tree.RoutineInvoker
   }
 | LEAKPROOF
   {
@@ -4930,6 +5606,45 @@ opt_link_sym:
   {
   }
 
+// %Help: DO - execute an anonymous code block
+// %Category: Misc
+// %Text:
+// DO [LANGUAGE lang_name] code
+do_stmt:
+  DO do_stmt_opt_list
+  {
+    doBlockBody, err := ParseDoBlockFn($2.doBlockOptions())
+    if err != nil {
+      return setErrNoDetails(sqllex, err)
+    }
+    $$.val = &tree.DoBlock{Code: doBlockBody}
+  }
+| DO error // SHOW HELP: DO
+
+do_stmt_opt_list:
+  do_stmt_opt_item
+  {
+    $$.val = tree.DoBlockOptions{$1.doBlockOption()}
+  }
+| do_stmt_opt_list do_stmt_opt_item
+  {
+    $$.val = append($1.doBlockOptions(), $2.doBlockOption())
+  }
+
+do_stmt_opt_item:
+  SCONST
+  {
+    $$.val = tree.RoutineBodyStr($1)
+  }
+| LANGUAGE non_reserved_word_or_sconst
+  {
+    lang, err := tree.AsRoutineLanguage($2)
+    if err != nil {
+      return setErr(sqllex, err)
+    }
+    $$.val = lang
+  }
+
 // %Help: DROP FUNCTION - remove a function
 // %Category: DDL
 // %Text:
@@ -5125,6 +5840,217 @@ opt_no:
     $$.val = false
   }
 
+// %Help: CREATE TRIGGER - define a new trigger
+// %Category: DDL
+// %Text:
+// CREATE [ OR REPLACE ] TRIGGER name { BEFORE | AFTER | INSTEAD OF }
+//  { INSERT | DELETE | UPDATE [ OF column_name [, ...] ] | TRUNCATE | UPSERT }
+//  ON table_name [ REFERENCING { NEW | OLD } TABLE [ AS ] table_alias_name [...] ]
+//  [ FOR { EACH ROW | EACH STATEMENT } ]
+//  [ WHEN a_expr ]
+//  EXECUTE FUNCTION func_name ( trigger_func_args )
+create_trigger_stmt:
+  CREATE opt_or_replace TRIGGER name trigger_action_time trigger_event_list
+  ON table_name opt_trigger_transition_list trigger_for_each trigger_when
+  EXECUTE function_or_procedure func_name '(' trigger_func_args ')'
+  {
+    $$.val = &tree.CreateTrigger{
+      Replace: $2.bool(),
+      Name: tree.Name($4),
+      ActionTime: $5.triggerActionTime(),
+      Events: $6.triggerEvents(),
+      TableName: $8.unresolvedObjectName(),
+      Transitions: $9.triggerTransitions(),
+      ForEach: $10.triggerForEach(),
+      When: $11.expr(),
+      FuncName: $14.unresolvedName(),
+      FuncArgs: $16.strs(),
+    }
+  }
+| CREATE opt_or_replace TRIGGER error // SHOW HELP: CREATE TRIGGER
+
+trigger_action_time:
+  BEFORE { $$.val = tree.TriggerActionTimeBefore }
+| AFTER { $$.val = tree.TriggerActionTimeAfter }
+| INSTEAD OF { $$.val = tree.TriggerActionTimeInsteadOf }
+
+trigger_event_list:
+  trigger_event
+  {
+    $$.val = []*tree.TriggerEvent{$1.triggerEvent()}
+  }
+| trigger_event_list OR trigger_event
+  {
+    events := append($1.triggerEvents(), $3.triggerEvent())
+
+    // Validate that the trigger events are unique.
+    var seenEvents tree.TriggerEventTypeSet
+    for i := range events {
+      if seenEvents.Contains(events[i].EventType) {
+        return setErr(sqllex, errors.New("duplicate trigger events specified"))
+      }
+      seenEvents.Add(events[i].EventType)
+    }
+    $$.val = events
+  }
+
+trigger_event:
+  INSERT
+  {
+    $$.val = &tree.TriggerEvent{EventType: tree.TriggerEventInsert}
+  }
+| DELETE
+  {
+    $$.val = &tree.TriggerEvent{EventType: tree.TriggerEventDelete}
+  }
+| UPDATE
+  {
+    $$.val = &tree.TriggerEvent{EventType: tree.TriggerEventUpdate}
+  }
+| UPDATE OF name_list
+  {
+    $$.val = &tree.TriggerEvent{EventType: tree.TriggerEventUpdate, Columns: $3.nameList()}
+  }
+| TRUNCATE
+  {
+    $$.val = &tree.TriggerEvent{EventType: tree.TriggerEventTruncate}
+  }
+
+opt_trigger_transition_list:
+  REFERENCING trigger_transition_list
+  {
+    $$.val = $2.triggerTransitions()
+  }
+| /* EMPTY */
+  {
+    $$.val = []*tree.TriggerTransition{}
+  }
+
+trigger_transition_list:
+  trigger_transition
+  {
+    $$.val = []*tree.TriggerTransition{$1.triggerTransition()}
+  }
+| trigger_transition_list trigger_transition
+  {
+    $$.val = append($1.triggerTransitions(), $2.triggerTransition())
+  }
+
+trigger_transition:
+  transition_is_new transition_is_row opt_as table_alias_name
+  {
+    $$.val = &tree.TriggerTransition{
+      Name: tree.Name($4),
+      IsNew: $1.bool(),
+      IsRow: $2.bool(),
+    }
+  }
+
+opt_as:
+  AS {}
+| /* EMPTY */ {}
+
+transition_is_new:
+  NEW { $$.val = true }
+| OLD { $$.val = false }
+
+transition_is_row:
+  ROW { $$.val = true }
+| TABLE { $$.val = false }
+
+trigger_for_each:
+  FOR trigger_for_opt_each trigger_for_type
+  {
+    $$.val = $3.triggerForEach()
+  }
+| /* EMPTY */
+  {
+    // FOR EACH STATEMENT is the default.
+    $$.val = tree.TriggerForEachStatement
+  }
+
+trigger_for_opt_each:
+  EACH {}
+| /* EMPTY */ {}
+
+trigger_for_type:
+  ROW { $$.val = tree.TriggerForEachRow }
+| STATEMENT { $$.val = tree.TriggerForEachStatement }
+
+trigger_when:
+  WHEN a_expr
+  {
+    $$.val = $2.expr()
+  }
+| /* EMPTY */
+  {
+    $$.val = nil
+  }
+
+function_or_procedure:
+  FUNCTION {}
+| PROCEDURE {}
+
+trigger_func_args:
+  trigger_func_arg
+  {
+    $$.val = []string{$1}
+  }
+| trigger_func_args ',' trigger_func_arg
+  {
+    $$.val = append($1.strs(), $3)
+  }
+| /* EMPTY */
+  {
+    $$.val = []string{}
+  }
+
+trigger_func_arg:
+  ICONST
+  {
+    // NOTE: Calling OrigString() ignores the sign for signed constants.
+    // However, this doesn't matter because postgres doesn't parse a signed
+    // numerical constant, and so neither do we. This applies to the FCONST
+    // case too.
+    $$ = $1.numVal().OrigString()
+  }
+| FCONST
+  {
+    $$ = $1.numVal().OrigString()
+  }
+| SCONST
+  {
+    $$ = $1
+  }
+| unrestricted_name
+  {
+    $$ = $1
+  }
+
+// %Help: DROP TRIGGER - remove a trigger
+// %Category: DDL
+// %Text:
+// DROP TRIGGER [ IF EXISTS ] name ON table_name [ CASCADE | RESTRICT ]
+drop_trigger_stmt:
+  DROP TRIGGER name ON table_name opt_drop_behavior
+  {
+    $$.val = &tree.DropTrigger{
+      Trigger: tree.Name($3),
+      Table: $5.unresolvedObjectName(),
+      DropBehavior: $6.dropBehavior(),
+    }
+  }
+| DROP TRIGGER IF EXISTS name ON table_name opt_drop_behavior
+  {
+    $$.val = &tree.DropTrigger{
+      IfExists: true,
+      Trigger: tree.Name($5),
+      Table: $7.unresolvedObjectName(),
+      DropBehavior: $8.dropBehavior(),
+    }
+  }
+| DROP TRIGGER error // SHOW HELP: DROP TRIGGER
+
 create_unsupported:
   CREATE ACCESS METHOD error { return unimplemented(sqllex, "create access method") }
 | CREATE AGGREGATE error { return unimplementedWithIssueDetail(sqllex, 74775, "create aggregate") }
@@ -5142,7 +6068,6 @@ create_unsupported:
 | CREATE SUBSCRIPTION error { return unimplemented(sqllex, "create subscription") }
 | CREATE TABLESPACE error { return unimplementedWithIssueDetail(sqllex, 54113, "create tablespace") }
 | CREATE TEXT error { return unimplementedWithIssueDetail(sqllex, 7821, "create text") }
-| CREATE TRIGGER error { return unimplementedWithIssueDetail(sqllex, 28296, "create trigger") }
 
 opt_trusted:
   TRUSTED {}
@@ -5170,7 +6095,6 @@ drop_unsupported:
 | DROP SERVER error { return unimplemented(sqllex, "drop server") }
 | DROP SUBSCRIPTION error { return unimplemented(sqllex, "drop subscription") }
 | DROP TEXT error { return unimplementedWithIssueDetail(sqllex, 7821, "drop text") }
-| DROP TRIGGER error { return unimplementedWithIssueDetail(sqllex, 28296, "drop") }
 
 create_ddl_stmt:
   create_database_stmt // EXTEND WITH HELP: CREATE DATABASE
@@ -5185,6 +6109,8 @@ create_ddl_stmt:
 | create_sequence_stmt // EXTEND WITH HELP: CREATE SEQUENCE
 | create_func_stmt     // EXTEND WITH HELP: CREATE FUNCTION
 | create_proc_stmt     // EXTEND WITH HELP: CREATE PROCEDURE
+| create_trigger_stmt  // EXTEND WITH HELP: CREATE TRIGGER
+| create_policy_stmt   // EXTEND WITH HELP: CREATE POLICY
 
 // %Help: CREATE STATISTICS - create a new table statistic
 // %Category: Misc
@@ -5571,6 +6497,8 @@ drop_ddl_stmt:
 | drop_type_stmt     // EXTEND WITH HELP: DROP TYPE
 | drop_func_stmt     // EXTEND WITH HELP: DROP FUNCTION
 | drop_proc_stmt     // EXTEND WITH HELP: DROP FUNCTION
+| drop_trigger_stmt  // EXTEND WITH HELP: DROP TRIGGER
+| drop_policy_stmt   // EXTEND WITH HELP: DROP POLICY
 
 // %Help: DROP VIEW - remove a view
 // %Category: DDL
@@ -5915,12 +6843,14 @@ explainable_stmt:
 | comment_stmt
 | execute_stmt
 | call_stmt
+| do_stmt
 
 preparable_stmt:
   alter_stmt     // help texts in sub-rule
 | backup_stmt    // EXTEND WITH HELP: BACKUP
 | cancel_stmt    // help texts in sub-rule
 | create_stmt    // help texts in sub-rule
+| check_stmt	 // help texts in sub-rule
 | delete_stmt    // EXTEND WITH HELP: DELETE
 | drop_stmt      // help texts in sub-rule
 | explain_stmt   // EXTEND WITH HELP: EXPLAIN
@@ -5976,6 +6906,22 @@ explain_option_list:
     $$.val = append($1.strs(), $3)
   }
 
+// %Help: ALTER JOB - alter an existing job
+// %Category: Misc
+// %Text:
+// ALTER JOB <jobid> <cmd>
+// %SeeAlso: SHOW JOBS, CANCEL JOBS, RESUME JOBS
+alter_job_stmt:
+  ALTER JOB a_expr OWNER TO role_spec
+  {
+    $$.val = &tree.AlterJobOwner{
+      Job: $3.expr(),
+      Owner: $6.roleSpec(),
+    }
+  }
+| ALTER JOB error // SHOW HELP: ALTER JOB
+
+
 // %Help: ALTER CHANGEFEED - alter an existing changefeed
 // %Category: CCL
 // %Text:
@@ -6157,6 +7103,11 @@ show_virtual_cluster_options:
     /* SKIP DOC */
     $$.val = tree.ShowTenantOptions{WithCapabilities: true}
   }
+| PRIOR REPLICATION DETAILS
+  {
+    /* SKIP DOC */
+    $$.val = tree.ShowTenantOptions{WithPriorReplication: true}
+  }
 | show_virtual_cluster_options ',' REPLICATION STATUS
   {
     /* SKIP DOC */
@@ -6171,6 +7122,48 @@ show_virtual_cluster_options:
     o.WithCapabilities = true
     $$.val = o
   }
+| show_virtual_cluster_options ',' PRIOR REPLICATION DETAILS
+  {
+    /* SKIP DOC */
+    o := $1.showTenantOpts()
+    o.WithPriorReplication = true
+    $$.val = o
+  }
+
+// %Help: SHOW LOGICAL REPLICATION JOBS - display metadata about logical replication jobs
+// %Category: Experimental
+// %Text: SHOW LOGICAL REPLICATION JOBS [ WITH <options> ]
+//
+// Options:
+//     DETAILS
+show_logical_replication_jobs_stmt:
+	SHOW LOGICAL REPLICATION JOBS opt_show_logical_replication_jobs_options
+	{
+		/* SKIP DOC */
+		$$.val = &tree.ShowLogicalReplicationJobs{
+			ShowLogicalReplicationJobsOptions: $5.showLogicalReplicationJobsOpts(),
+		}
+	}
+| SHOW LOGICAL REPLICATION JOBS error // SHOW HELP: SHOW LOGICAL REPLICATION JOBS
+
+opt_show_logical_replication_jobs_options:
+  /* EMPTY */
+  {
+    /* SKIP DOC */
+    $$.val = tree.ShowLogicalReplicationJobsOptions{}
+  }
+| WITH show_logical_replication_jobs_options
+  {
+    /* SKIP DOC */
+    $$.val = $2.showLogicalReplicationJobsOpts()
+  }
+
+show_logical_replication_jobs_options:
+  DETAILS
+  {
+    /* SKIP DOC */
+    $$.val = tree.ShowLogicalReplicationJobsOptions{WithDetails: true}
+  }
 
 // %Help: PREPARE - prepare a statement for later execution
 // %Category: Misc
@@ -6769,12 +7762,13 @@ set_csetting_stmt:
 // %Text:
 // ALTER VIRTUAL CLUSTER REPLICATION, ALTER VIRTUAL CLUSTER SETTING,
 // ALTER VIRTUAL CLUSTER CAPABILITY, ALTER VIRTUAL CLUSTER RENAME,
-// ALTER VIRTUAL CLUSTER SERVICE
+// ALTER VIRTUAL CLUSTER RESET, ALTER VIRTUAL CLUSTER SERVICE
 alter_virtual_cluster_stmt:
   alter_virtual_cluster_replication_stmt // EXTEND WITH HELP: ALTER VIRTUAL CLUSTER REPLICATION
 | alter_virtual_cluster_csetting_stmt    // EXTEND WITH HELP: ALTER VIRTUAL CLUSTER SETTING
 | alter_virtual_cluster_capability_stmt  // EXTEND WITH HELP: ALTER VIRTUAL CLUSTER CAPABILITY
 | alter_virtual_cluster_rename_stmt      // EXTEND WITH HELP: ALTER VIRTUAL CLUSTER RENAME
+| alter_virtual_cluster_reset_stmt       // EXTEND WITH HELP: ALTER VIRTUAL CLUSTER RESET
 | alter_virtual_cluster_service_stmt     // EXTEND WITH HELP: ALTER VIRTUAL CLUSTER SERVICE
 | ALTER virtual_cluster error   // SHOW HELP: ALTER VIRTUAL CLUSTER
 
@@ -6784,6 +7778,21 @@ virtual_cluster_spec:
 | '[' a_expr ']'
   { $$.val = &tree.TenantSpec{IsName: false, Expr: $2.expr()} }
 
+
+// %Help: ALTER VIRTUAL CLUSTER RESET - reset data state of a virtual cluster
+// %Category: Experimental
+// %Text:
+// ALTER VIRTUAL CLUSTER <virtual_cluster_spec> RESET DATA TO SYSTEM TIME <time>
+alter_virtual_cluster_reset_stmt:
+  ALTER virtual_cluster virtual_cluster_spec  RESET DATA TO SYSTEM TIME a_expr
+  {
+    /* SKIP DOC */
+    $$.val = &tree.AlterTenantReset{
+      TenantSpec: $3.tenantSpec(),
+      Timestamp: $9.expr(),
+    }
+  }
+
 // %Help: ALTER VIRTUAL CLUSTER RENAME - rename a virtual cluster
 // %Category: Experimental
 // %Text:
@@ -6791,7 +7800,6 @@ virtual_cluster_spec:
 alter_virtual_cluster_rename_stmt:
   ALTER virtual_cluster virtual_cluster_spec RENAME TO d_expr
   {
-    /* SKIP DOC */
     $$.val = &tree.AlterTenantRename{
       TenantSpec: $3.tenantSpec(),
       NewName: &tree.TenantSpec{IsName: true, Expr: $6.expr()},
@@ -6815,7 +7823,6 @@ alter_virtual_cluster_service_stmt:
   }
 | ALTER virtual_cluster virtual_cluster_spec START SERVICE SHARED
   {
-    /* SKIP DOC */
     $$.val = &tree.AlterTenantService{
       TenantSpec: $3.tenantSpec(),
       Command: tree.TenantStartServiceShared,
@@ -6823,7 +7830,6 @@ alter_virtual_cluster_service_stmt:
   }
 | ALTER virtual_cluster virtual_cluster_spec STOP SERVICE
   {
-    /* SKIP DOC */
     $$.val = &tree.AlterTenantService{
       TenantSpec: $3.tenantSpec(),
       Command: tree.TenantStopService,
@@ -6841,10 +7847,10 @@ alter_virtual_cluster_service_stmt:
 // ALTER VIRTUAL CLUSTER <virtual_cluster_spec> COMPLETE REPLICATION TO LATEST
 // ALTER VIRTUAL CLUSTER <virtual_cluster_spec> COMPLETE REPLICATION TO SYSTEM TIME 'time'
 // ALTER VIRTUAL CLUSTER <virtual_cluster_spec> SET REPLICATION opt=value,...
+// ALTER VIRTUAL CLUSTER <virtual_cluster_spec> SET SOURCE REPLICATION opt=value,...
 alter_virtual_cluster_replication_stmt:
   ALTER virtual_cluster virtual_cluster_spec PAUSE REPLICATION
   {
-    /* SKIP DOC */
     $$.val = &tree.AlterTenantReplication{
       TenantSpec: $3.tenantSpec(),
       Command: tree.PauseJob,
@@ -6852,7 +7858,6 @@ alter_virtual_cluster_replication_stmt:
   }
 | ALTER virtual_cluster virtual_cluster_spec RESUME REPLICATION
   {
-    /* SKIP DOC */
     $$.val = &tree.AlterTenantReplication{
       TenantSpec: $3.tenantSpec(),
       Command: tree.ResumeJob,
@@ -6860,7 +7865,6 @@ alter_virtual_cluster_replication_stmt:
   }
 | ALTER virtual_cluster virtual_cluster_spec COMPLETE REPLICATION TO SYSTEM TIME a_expr
   {
-    /* SKIP DOC */
     $$.val = &tree.AlterTenantReplication{
       TenantSpec: $3.tenantSpec(),
       Cutover: &tree.ReplicationCutoverTime{
@@ -6870,7 +7874,6 @@ alter_virtual_cluster_replication_stmt:
   }
 | ALTER virtual_cluster virtual_cluster_spec COMPLETE REPLICATION TO LATEST
   {
-    /* SKIP DOC */
     $$.val = &tree.AlterTenantReplication{
       TenantSpec: $3.tenantSpec(),
       Cutover: &tree.ReplicationCutoverTime{
@@ -6880,12 +7883,28 @@ alter_virtual_cluster_replication_stmt:
   }
 | ALTER virtual_cluster virtual_cluster_spec SET REPLICATION replication_options_list
   {
-    /* SKIP DOC */
     $$.val = &tree.AlterTenantReplication{
       TenantSpec: $3.tenantSpec(),
       Options: *$6.tenantReplicationOptions(),
     }
   }
+| ALTER virtual_cluster virtual_cluster_spec SET REPLICATION SOURCE source_replication_options_list
+  {
+    $$.val = &tree.AlterTenantReplication{
+      TenantSpec: $3.tenantSpec(),
+      Producer: true,
+      Options: *$7.tenantReplicationOptions(),
+    }
+  }
+| ALTER virtual_cluster virtual_cluster_spec START REPLICATION OF d_expr ON d_expr opt_with_replication_options
+  {
+    $$.val = &tree.AlterTenantReplication{
+      TenantSpec: $3.tenantSpec(),
+      ReplicationSourceTenantName: &tree.TenantSpec{IsName: true, Expr: $7.expr()},
+      ReplicationSourceConnUri: $9.expr(),
+      Options: *$10.tenantReplicationOptions(),
+    }
+  }
 
 
 // %Help: ALTER VIRTUAL CLUSTER SETTING - alter cluster setting overrides for virtual clusters
@@ -6941,7 +7960,6 @@ to_or_eq:
 alter_virtual_cluster_capability_stmt:
   ALTER virtual_cluster virtual_cluster_spec GRANT CAPABILITY virtual_cluster_capability_list
   {
-    /* SKIP DOC */
     $$.val = &tree.AlterTenantCapability{
       TenantSpec: $3.tenantSpec(),
       Capabilities: $6.tenantCapabilities(),
@@ -6949,7 +7967,6 @@ alter_virtual_cluster_capability_stmt:
   }
 | ALTER virtual_cluster virtual_cluster_spec GRANT ALL CAPABILITIES
   {
-    /* SKIP DOC */
     $$.val = &tree.AlterTenantCapability{
       TenantSpec: $3.tenantSpec(),
       AllCapabilities: true,
@@ -6957,7 +7974,6 @@ alter_virtual_cluster_capability_stmt:
   }
 | ALTER virtual_cluster virtual_cluster_spec REVOKE CAPABILITY virtual_cluster_capability_list
   {
-    /* SKIP DOC */
     $$.val = &tree.AlterTenantCapability{
       TenantSpec: $3.tenantSpec(),
       Capabilities: $6.tenantCapabilities(),
@@ -6966,7 +7982,6 @@ alter_virtual_cluster_capability_stmt:
   }
 | ALTER virtual_cluster virtual_cluster_spec REVOKE ALL CAPABILITIES
   {
-    /* SKIP DOC */
     $$.val = &tree.AlterTenantCapability{
       TenantSpec: $3.tenantSpec(),
       AllCapabilities: true,
@@ -7018,7 +8033,7 @@ set_exprs_internal:
 // %Text:
 // SET [SESSION] <var> { TO | = } <values...>
 // SET [SESSION] TIME ZONE <tz>
-// SET [SESSION] CHARACTERISTICS AS TRANSACTION ISOLATION LEVEL { READ COMMITTED | SERIALIZABLE }
+// SET [SESSION] CHARACTERISTICS AS TRANSACTION ISOLATION LEVEL { READ COMMITTED | REPEATABLE READ | SERIALIZABLE }
 // SET [SESSION] TRACING { TO | = } { on | off | cluster | kv | results } [,...]
 //
 // %SeeAlso: SHOW SESSION, RESET, DISCARD, SHOW, SET CLUSTER SETTING, SET TRANSACTION, SET LOCAL
@@ -7075,7 +8090,7 @@ set_local_stmt:
 // SET [SESSION] TRANSACTION <txnparameters...>
 //
 // Transaction parameters:
-//    ISOLATION LEVEL { READ COMMITTED | SERIALIZABLE }
+//    ISOLATION LEVEL { READ COMMITTED | REPEATABLE READ | SERIALIZABLE }
 //    PRIORITY { LOW | NORMAL | HIGH }
 //    AS OF SYSTEM TIME <expr>
 //    [NOT] DEFERRABLE
@@ -7282,25 +8297,28 @@ zone_value:
 // %Help: SHOW
 // %Category: Group
 // %Text:
-// SHOW BACKUP, SHOW CLUSTER SETTING, SHOW COLUMNS, SHOW CONSTRAINTS,
-// SHOW CREATE, SHOW CREATE SCHEDULES, SHOW DATABASES, SHOW ENUMS, SHOW
-// FUNCTION, SHOW FUNCTIONS, SHOW HISTOGRAM, SHOW INDEXES, SHOW PARTITIONS, SHOW JOBS,
-// SHOW STATEMENTS, SHOW RANGE, SHOW RANGES, SHOW REGIONS, SHOW SURVIVAL GOAL,
+// SHOW BACKUP, SHOW CLUSTER SETTING, SHOW COLUMNS, SHOW CONSTRAINTS, SHOW TRIGGERS,
+// SHOW CREATE, SHOW CREATE SCHEDULES, SHOW DATABASES, SHOW DEFAULT SESSION VARIABLES,
+// SHOW ENUMS, SHOW FUNCTION, SHOW FUNCTIONS, SHOW HISTOGRAM, SHOW INDEXES, SHOW PARTITIONS,
+// SHOW JOBS, SHOW STATEMENTS, SHOW RANGE, SHOW RANGES, SHOW REGIONS, SHOW SURVIVAL GOAL,
 // SHOW ROLES, SHOW SCHEMAS, SHOW SEQUENCES, SHOW SESSION, SHOW SESSIONS,
 // SHOW STATISTICS, SHOW SYNTAX, SHOW TABLES, SHOW TRACE, SHOW TRANSACTION,
 // SHOW TRANSACTIONS, SHOW TRANSFER, SHOW TYPES, SHOW USERS, SHOW LAST QUERY STATISTICS,
 // SHOW SCHEDULES, SHOW LOCALITY, SHOW ZONE CONFIGURATION, SHOW COMMIT TIMESTAMP,
-// SHOW FULL TABLE SCANS, SHOW CREATE EXTERNAL CONNECTIONS
+// SHOW FULL TABLE SCANS, SHOW CREATE EXTERNAL CONNECTIONS, SHOW EXTERNAL CONNECTIONS
 show_stmt:
   show_backup_stmt           // EXTEND WITH HELP: SHOW BACKUP
 | show_columns_stmt          // EXTEND WITH HELP: SHOW COLUMNS
 | show_constraints_stmt      // EXTEND WITH HELP: SHOW CONSTRAINTS
+| show_triggers_stmt         // EXTEND WITH HELP: SHOW TRIGGERS
 | show_create_stmt           // EXTEND WITH HELP: SHOW CREATE
 | show_create_schedules_stmt // EXTEND WITH HELP: SHOW CREATE SCHEDULES
 | show_create_external_connections_stmt // EXTEND WITH HELP: SHOW CREATE EXTERNAL CONNECTIONS
 | show_local_or_virtual_cluster_csettings_stmt // EXTEND WITH HELP: SHOW CLUSTER SETTING
+| show_logical_replication_jobs_stmt	// EXTEND WITH HELP: SHOW LOGICAL REPLICATION JOBS
 | show_databases_stmt        // EXTEND WITH HELP: SHOW DATABASES
 | show_enums_stmt            // EXTEND WITH HELP: SHOW ENUMS
+| show_external_connections_stmt // EXTEND WITH HELP: SHOW EXTERNAL CONNECTIONS
 | show_types_stmt            // EXTEND WITH HELP: SHOW TYPES
 | show_fingerprints_stmt
 | show_functions_stmt        // EXTEND WITH HELP: SHOW FUNCTIONS
@@ -7332,7 +8350,9 @@ show_stmt:
 | show_transactions_stmt     // EXTEND WITH HELP: SHOW TRANSACTIONS
 | show_transfer_stmt         // EXTEND WITH HELP: SHOW TRANSFER
 | show_users_stmt            // EXTEND WITH HELP: SHOW USERS
+| show_default_session_variables_for_role_stmt // EXTEND WITH HELP: SHOW DEFAULT SESSION VARIABLES FOR ROLE
 | show_zone_stmt             // EXTEND WITH HELP: SHOW ZONE CONFIGURATION
+| show_policies_stmt         // EXTEND WITH HELP: SHOW POLICIES
 | SHOW error                 // SHOW HELP: SHOW
 | show_last_query_stats_stmt
 | show_full_scans_stmt
@@ -7714,54 +8734,40 @@ show_backup_stmt:
 			Options: *$6.showBackupOptions(),
 		}
 	}
-| SHOW BACKUP string_or_placeholder opt_with_show_backup_options
+| SHOW BACKUP string_or_placeholder opt_with_show_backup_options error
 	{
-		$$.val = &tree.ShowBackup{
-		  Details:  tree.BackupDefaultDetails,
-			Path:    $3.expr(),
-			Options: *$4.showBackupOptions(),
-		}
+    setErr(sqllex, errors.New("The `SHOW BACKUP` syntax without the `IN` keyword is no longer supported. Please use `SHOW BACKUP FROM <subdirectory> IN <collectionURI>`."))
+    return helpWith(sqllex, "SHOW BACKUP")
 	}
-| SHOW BACKUP SCHEMAS string_or_placeholder opt_with_show_backup_options
+| SHOW BACKUP SCHEMAS string_or_placeholder opt_with_show_backup_options error
 	{
-		$$.val = &tree.ShowBackup{
-		  Details:  tree.BackupSchemaDetails,
-			Path:    $4.expr(),
-			Options: *$5.showBackupOptions(),
-		}
+    setErr(sqllex, errors.New("The `SHOW BACKUP SCHEMAS` syntax without the `IN` keyword is no longer supported. Please use `SHOW BACKUP SCHEMAS FROM <subdirectory> IN <collectionURI>`."))
+    return helpWith(sqllex, "SHOW BACKUP")
 	}
-| SHOW BACKUP FILES string_or_placeholder opt_with_show_backup_options
+| SHOW BACKUP FILES string_or_placeholder opt_with_show_backup_options error
 	{
-		$$.val = &tree.ShowBackup{
-		  Details:  tree.BackupFileDetails,
-			Path:    $4.expr(),
-			Options: *$5.showBackupOptions(),
-		}
+    /* SKIP DOC */
+    setErr(sqllex, errors.New("The `SHOW BACKUP FILES` syntax without the `IN` keyword is no longer supported. Please use `SHOW BACKUP FILES FROM <subdirectory> IN <collectionURI>`."))
+    return helpWith(sqllex, "SHOW BACKUP")
 	}
-| SHOW BACKUP RANGES string_or_placeholder opt_with_show_backup_options
+| SHOW BACKUP RANGES string_or_placeholder opt_with_show_backup_options error
 	{
-		$$.val = &tree.ShowBackup{
-		  Details:  tree.BackupRangeDetails,
-			Path:    $4.expr(),
-			Options: *$5.showBackupOptions(),
-		}
+    /* SKIP DOC */
+    setErr(sqllex, errors.New("The `SHOW BACKUP RANGES` syntax without the `IN` keyword is no longer supported. Please use `SHOW BACKUP RANGES FROM <subdirectory> IN <collectionURI>`."))
+    return helpWith(sqllex, "SHOW BACKUP")
+	}
+| SHOW BACKUP VALIDATE string_or_placeholder opt_with_show_backup_options error
+	{
+		/* SKIP DOC */
+		setErr(sqllex, errors.New("The `SHOW BACKUP VALIDATE` syntax without the `IN` keyword is no longer supported. Please use `SHOW BACKUP VALIDATE FROM <subdirectory> IN <collectionURI>`."))
+    return helpWith(sqllex, "SHOW BACKUP")
+	}
+| SHOW BACKUP CONNECTION string_or_placeholder error
+	{
+		/* SKIP DOC */
+		setErr(sqllex, errors.New("The `SHOW BACKUP CONNECTION` syntax is no longer supported. Please use `CHECK EXTERNAL CONNECTION`."))
+		return helpWith(sqllex, "CHECK EXTERNAL CONNECTION")
 	}
-| SHOW BACKUP VALIDATE string_or_placeholder opt_with_show_backup_options
-  	{
-  		$$.val = &tree.ShowBackup{
-  		  Details:  tree.BackupValidateDetails,
-  			Path:    $4.expr(),
-  			Options: *$5.showBackupOptions(),
-  		}
-  	}
-| SHOW BACKUP CONNECTION string_or_placeholder opt_with_show_backup_connection_options_list
-  	{
-  		$$.val = &tree.ShowBackup{
-  		  Details:  tree.BackupConnectionTest,
-  			Path:    $4.expr(),
-  			Options: *$5.showBackupOptions(),
-  		}
-  	}
 | SHOW BACKUP error // SHOW HELP: SHOW BACKUP
 
 show_backup_details:
@@ -7775,14 +8781,17 @@ show_backup_details:
   }
 | FILES
 	{
+    /* SKIP DOC */
 	$$.val = tree.BackupFileDetails
 	}
 | RANGES
 	{
+    /* SKIP DOC */
 	$$.val = tree.BackupRangeDetails
 	}
 | VALIDATE
 	{
+    /* SKIP DOC */
 	$$.val = tree.BackupValidateDetails
 	}
 
@@ -7855,51 +8864,6 @@ show_backup_options:
  {
  $$.val = &tree.ShowBackupOptions{EncryptionInfoDir: $3.expr()}
  }
- | DEBUG_DUMP_METADATA_SST
- {
- $$.val = &tree.ShowBackupOptions{DebugMetadataSST: true}
- }
-
-opt_with_show_backup_connection_options_list:
-  WITH show_backup_connection_options_list
-  {
-    $$.val = $2.showBackupOptions()
-  }
-| WITH OPTIONS '(' show_backup_connection_options_list ')'
-  {
-    $$.val = $4.showBackupOptions()
-  }
-| /* EMPTY */
-  {
-    $$.val = &tree.ShowBackupOptions{}
-  }
-
-show_backup_connection_options_list:
-  // Require at least one option
-  show_backup_connection_options
-  {
-    $$.val = $1.showBackupOptions()
-  }
-| show_backup_connection_options_list ',' show_backup_connection_options
-  {
-    if err := $1.showBackupOptions().CombineWith($3.showBackupOptions()); err != nil {
-      return setErr(sqllex, err)
-    }
-  }
-
-show_backup_connection_options:
-  TRANSFER '=' string_or_placeholder
- {
-  $$.val = &tree.ShowBackupOptions{CheckConnectionTransferSize: $3.expr()}
- }
- | TIME '=' string_or_placeholder
- {
-  $$.val = &tree.ShowBackupOptions{CheckConnectionDuration: $3.expr()}
- }
- | CONCURRENTLY '=' a_expr
- {
-  $$.val = &tree.ShowBackupOptions{CheckConnectionConcurrency: $3.expr()}
- }
 
 // %Help: SHOW CLUSTER SETTING - display cluster settings
 // %Category: Cfg
@@ -8057,13 +9021,30 @@ show_enums_stmt:
 }
 | SHOW ENUMS error // SHOW HELP: SHOW ENUMS
 
+// %Help: SHOW EXTERNAL CONNECTIONS - list external connections
+// %Category: Misc
+// %Text:
+// SHOW EXTERNAL CONNECTIONS
+// SHOW EXTERNAL CONNECTION <connection_name>
+show_external_connections_stmt:
+  SHOW EXTERNAL CONNECTIONS
+  {
+    $$.val = &tree.ShowExternalConnections{}
+  }
+| SHOW EXTERNAL CONNECTIONS error // SHOW HELP: SHOW EXTERNAL CONNECTIONS
+| SHOW EXTERNAL CONNECTION string_or_placeholder
+ {
+   $$.val = &tree.ShowExternalConnections{ConnectionLabel: $4.expr()}
+ }
+| SHOW EXTERNAL CONNECTION error // SHOW HELP: SHOW EXTERNAL CONNECTIONS
+
 // %Help: SHOW TYPES - list user defined types
 // %Category: Misc
-// %Text: SHOW TYPES
+// %Text: SHOW TYPES [WITH_COMMENT]
 show_types_stmt:
-  SHOW TYPES
+  SHOW TYPES with_comment
   {
-    $$.val = &tree.ShowTypes{}
+    $$.val = &tree.ShowTypes{WithComment: $3.bool()}
   }
 | SHOW TYPES error // SHOW HELP: SHOW TYPES
 
@@ -8160,6 +9141,18 @@ show_constraints_stmt:
   }
 | SHOW CONSTRAINTS error // SHOW HELP: SHOW CONSTRAINTS
 
+// %Help: SHOW TRIGGERS - list triggers on a table
+// %Category: DDL
+// %Text: SHOW TRIGGERS FROM <tablename>
+// TODO(drewk): Add docs link.
+show_triggers_stmt:
+  SHOW TRIGGERS FROM table_name
+  {
+    $$.val = &tree.ShowTriggers{Table: $4.unresolvedObjectName()}
+  }
+| SHOW TRIGGER error // SHOW HELP: SHOW TRIGGERS
+| SHOW TRIGGERS error // SHOW HELP: SHOW TRIGGERS
+
 // %Help: SHOW STATEMENTS - list running statements
 // %Category: Misc
 // %Text: SHOW [ALL] [CLUSTER | LOCAL] STATEMENTS
@@ -8517,15 +9510,15 @@ with_comment:
 
 // %Help: SHOW SCHEMAS - list schemas
 // %Category: DDL
-// %Text: SHOW SCHEMAS [FROM <databasename> ]
+// %Text: SHOW SCHEMAS [FROM <databasename> ] [WITH COMMENT]
 show_schemas_stmt:
-  SHOW SCHEMAS FROM name
+  SHOW SCHEMAS FROM name with_comment
   {
-    $$.val = &tree.ShowSchemas{Database: tree.Name($4)}
+    $$.val = &tree.ShowSchemas{Database: tree.Name($4), WithComment: $5.bool()}
   }
-| SHOW SCHEMAS
+| SHOW SCHEMAS with_comment
   {
-    $$.val = &tree.ShowSchemas{}
+    $$.val = &tree.ShowSchemas{WithComment: $3.bool()}
   }
 | SHOW SCHEMAS error // SHOW HELP: SHOW SCHEMAS
 
@@ -8564,6 +9557,19 @@ show_completions_stmt:
     }
   }
 
+// %Help: SHOW POLICIES - list row-level security policies defined for a table
+// %Category: DDL
+// %Text: SHOW POLICIES FOR <table_name>
+show_policies_stmt:
+  SHOW POLICIES FOR table_name
+  {
+    /* SKIP DOC */
+    $$.val = &tree.ShowPolicies{
+      Table: $4.unresolvedObjectName(),
+    }
+  }
+| SHOW POLICIES error // SHOW HELP: SHOW POLICIES
+
 show_last_query_stats_stmt:
   SHOW LAST QUERY STATISTICS query_stats_cols
   {
@@ -8702,6 +9708,14 @@ show_create_stmt:
       Procedure: true,
     }
   }
+| SHOW CREATE TRIGGER name ON table_name
+  {
+    /* SKIP DOC */
+    $$.val = &tree.ShowCreateTrigger{
+      Name: tree.Name($4),
+      TableName: $6.unresolvedObjectName(),
+    }
+  }
 | SHOW CREATE ALL SCHEMAS
   {
     $$.val = &tree.ShowCreateAllSchemas{}
@@ -8725,6 +9739,10 @@ opt_show_create_format_options:
   {
     $$.val = tree.ShowCreateFormatOptionRedactedValues
   }
+| WITH IGNORE_FOREIGN_KEYS
+  {
+    $$.val = tree.ShowCreateFormatOptionIgnoreFKs
+  }
 
 // %Help: SHOW CREATE SCHEDULES - list CREATE statements for scheduled jobs
 // %Category: DDL
@@ -8772,6 +9790,24 @@ show_users_stmt:
   }
 | SHOW USERS error // SHOW HELP: SHOW USERS
 
+// %Help: SHOW DEFAULT SESSION VARIABLES FOR ROLE - list default session variables for role
+// %Category: Priv
+// %Text: SHOW DEFAULT SESSION VARIABLES FOR ROLE <name>
+show_default_session_variables_for_role_stmt:
+ SHOW DEFAULT SESSION VARIABLES FOR role_or_group_or_user role_spec
+    {
+      $$.val = &tree.ShowDefaultSessionVariablesForRole{Name: $7.roleSpec(), IsRole: $6.bool()}
+    }
+| SHOW DEFAULT SESSION VARIABLES FOR ROLE_ALL ALL
+     {
+       $$.val = &tree.ShowDefaultSessionVariablesForRole{All: true, IsRole: true}
+     }
+| SHOW DEFAULT SESSION VARIABLES FOR USER_ALL ALL
+     {
+       $$.val = &tree.ShowDefaultSessionVariablesForRole{All: true, IsRole: false}
+     }
+| SHOW DEFAULT SESSION VARIABLES FOR role_or_group_or_user error // SHOW HELP: SHOW DEFAULT SESSION VARIABLES FOR ROLE
+
 // %Help: SHOW ROLES - list defined roles
 // %Category: Priv
 // %Text: SHOW ROLES
@@ -9035,18 +10071,57 @@ show_locality_stmt:
   }
 
 show_fingerprints_stmt:
-  SHOW EXPERIMENTAL_FINGERPRINTS FROM TABLE table_name
+  SHOW EXPERIMENTAL_FINGERPRINTS FROM TABLE table_name opt_with_show_fingerprints_options
   {
     /* SKIP DOC */
-    $$.val = &tree.ShowFingerprints{Table: $5.unresolvedObjectName()}
+    $$.val = &tree.ShowFingerprints{Table: $5.unresolvedObjectName(), Options: *$6.showFingerprintOptions()}
   }
-|
-  SHOW EXPERIMENTAL_FINGERPRINTS FROM virtual_cluster virtual_cluster_spec
+| SHOW EXPERIMENTAL_FINGERPRINTS FROM virtual_cluster virtual_cluster_spec opt_with_show_fingerprints_options
   {
     /* SKIP DOC */
-    $$.val = &tree.ShowFingerprints{TenantSpec: $5.tenantSpec()}
+    $$.val = &tree.ShowFingerprints{TenantSpec: $5.tenantSpec(), Options: *$6.showFingerprintOptions()}
+  }
+
+opt_with_show_fingerprints_options:
+  WITH fingerprint_options_list
+  {
+    $$.val = $2.showFingerprintOptions()
+  }
+| WITH OPTIONS '(' fingerprint_options_list ')'
+  {
+    $$.val = $4.showFingerprintOptions()
+  }
+| /* EMPTY */
+  {
+    $$.val = &tree.ShowFingerprintOptions{}
+  }
+
+fingerprint_options_list:
+  // Require at least one option
+  fingerprint_options
+  {
+    $$.val = $1.showFingerprintOptions()
+  }
+| fingerprint_options_list ',' fingerprint_options
+  {
+    if err := $1.showFingerprintOptions().CombineWith($3.showFingerprintOptions()); err != nil {
+      return setErr(sqllex, err)
+    }
+  }
+
+// List of valid backup options.
+fingerprint_options:
+  START TIMESTAMP '=' d_expr
+  {
+    $$.val = &tree.ShowFingerprintOptions{StartTimestamp: $4.expr()}
+  }
+| EXCLUDE COLUMNS '=' string_or_placeholder_opt_list
+  {
+    $$.val = &tree.ShowFingerprintOptions{ExcludedUserColumns: $4.stringOrPlaceholderOptList()}
   }
 
+
+
 show_full_scans_stmt:
   SHOW FULL TABLE SCANS
   {
@@ -9546,7 +10621,7 @@ alter_schema_stmt:
 //
 // Table elements:
 //    <name> <type> [<qualifiers...>]
-//    [UNIQUE | INVERTED] INDEX [<name>] ( <colname> [ASC | DESC] [, ...] )
+//    [UNIQUE | INVERTED | VECTOR] INDEX [<name>] ( <colname> [ASC | DESC] [, ...] )
 //                            [USING HASH] [{STORING | INCLUDE | COVERING} ( <colnames...> )]
 //    FAMILY [<name>] ( <colnames...> )
 //    [CONSTRAINT <name>] <constraint>
@@ -9669,17 +10744,17 @@ storage_parameter_key:
 storage_parameter_key_list:
   storage_parameter_key
   {
-    $$.val = []tree.Name{tree.Name($1)}
+    $$.val = []string{$1}
   }
 | storage_parameter_key_list ',' storage_parameter_key
   {
-    $$.val = append($1.storageParamKeys(), tree.Name($3))
+    $$.val = append($1.storageParamKeys(), $3)
   }
 
 storage_parameter:
   storage_parameter_key '=' var_value
   {
-    $$.val = tree.StorageParam{Key: tree.Name($1), Value: $3.expr()}
+    $$.val = tree.StorageParam{Key: $1, Value: $3.expr()}
   }
 
 storage_parameter_list:
@@ -9781,7 +10856,7 @@ table_elem:
   {
     def := $1.constraintDef()
     valBehavior := $2.validationBehavior()
-    if u, ok := def.(*tree.UniqueConstraintTableDef); ok && valBehavior == tree.ValidationSkip {
+    if u, ok := def.(*tree.UniqueConstraintTableDef); ok && valBehavior == tree.ValidationSkip && !u.WithoutIndex {
       typ := "PRIMARY KEY"
       if !u.PrimaryKey {
         typ = "UNIQUE"
@@ -10125,6 +11200,12 @@ generated_as:
   AS {}
 | generated_always_as
 
+set_generated_always:
+  SET GENERATED_ALWAYS ALWAYS
+
+set_generated_default:
+  SET GENERATED_BY_DEFAULT BY DEFAULT
+
 generated_always_as:
   GENERATED_ALWAYS ALWAYS AS {}
 
@@ -10171,6 +11252,7 @@ index_def:
         Predicate:        $11.expr(),
         Invisibility:     $12.indexInvisibility(),
       },
+      FormatAsIndex:    true,
     }
   }
 | INVERTED INDEX_BEFORE_PAREN '(' index_params ')' opt_partition_by_index opt_with_storage_parameter_list opt_where_clause opt_index_visible
@@ -10178,7 +11260,7 @@ index_def:
     $$.val = &tree.IndexTableDef{
       Name:             "",
       Columns:          $4.idxElems(),
-      Inverted:         true,
+      Type:             idxtype.INVERTED,
       PartitionByIndex: $6.partitionByIndex(),
       StorageParams:    $7.storageParams(),
       Predicate:        $8.expr(),
@@ -10190,7 +11272,31 @@ index_def:
     $$.val = &tree.IndexTableDef{
       Name:             tree.Name($3),
       Columns:          $5.idxElems(),
-      Inverted:         true,
+      Type:             idxtype.INVERTED,
+      PartitionByIndex: $7.partitionByIndex(),
+      StorageParams:    $8.storageParams(),
+      Predicate:        $9.expr(),
+      Invisibility:     $10.indexInvisibility(),
+    }
+  }
+| VECTOR INDEX_BEFORE_PAREN '(' index_params ')' opt_partition_by_index opt_with_storage_parameter_list opt_where_clause opt_index_visible
+  {
+    $$.val = &tree.IndexTableDef{
+      Name:             "",
+      Columns:          $4.idxElems(),
+      Type:             idxtype.VECTOR,
+      PartitionByIndex: $6.partitionByIndex(),
+      StorageParams:    $7.storageParams(),
+      Predicate:        $8.expr(),
+      Invisibility:     $9.indexInvisibility(),
+    }
+  }
+| VECTOR INDEX_BEFORE_NAME_THEN_PAREN name '(' index_params ')' opt_partition_by_index opt_with_storage_parameter_list opt_where_clause opt_index_visible
+  {
+    $$.val = &tree.IndexTableDef{
+      Name:             tree.Name($3),
+      Columns:          $5.idxElems(),
+      Type:             idxtype.VECTOR,
       PartitionByIndex: $7.partitionByIndex(),
       StorageParams:    $8.storageParams(),
       Predicate:        $9.expr(),
@@ -10605,6 +11711,8 @@ sequence_option_elem:
                                  $$.val = tree.SequenceOption{Name: tree.SeqOptOwnedBy, ColumnItemVal: columnItem} }
 | CACHE signed_iconst64        { x := $2.int64()
                                  $$.val = tree.SequenceOption{Name: tree.SeqOptCache, IntVal: &x} }
+| PER NODE CACHE signed_iconst64  { x := $4.int64()
+                                    $$.val = tree.SequenceOption{Name: tree.SeqOptCacheNode, IntVal: &x} }
 | INCREMENT signed_iconst64    { x := $2.int64()
                                  $$.val = tree.SequenceOption{Name: tree.SeqOptIncrement, IntVal: &x} }
 | INCREMENT BY signed_iconst64 { x := $3.int64()
@@ -10936,6 +12044,7 @@ role_option:
   }
 | password_clause
 | valid_until_clause
+| subject_clause
 | REPLICATION
   {
     $$.val = tree.KVOption{Key: tree.Name($1), Value: nil}
@@ -10944,6 +12053,14 @@ role_option:
   {
     $$.val = tree.KVOption{Key: tree.Name($1), Value: nil}
   }
+| BYPASSRLS
+  {
+    $$.val = tree.KVOption{Key: tree.Name($1), Value: nil}
+  }
+| NOBYPASSRLS
+  {
+    $$.val = tree.KVOption{Key: tree.Name($1), Value: nil}
+  }
 
 role_options:
   role_option
@@ -10975,6 +12092,16 @@ valid_until_clause:
     $$.val = tree.KVOption{Key: tree.Name("valid until"), Value: tree.DNull}
   }
 
+subject_clause:
+  SUBJECT string_or_placeholder
+  {
+    $$.val = tree.KVOption{Key: tree.Name("subject"), Value: $2.expr()}
+  }
+| SUBJECT NULL
+  {
+    $$.val = tree.KVOption{Key: tree.Name("subject"), Value: tree.DNull}
+  }
+
 opt_view_recursive:
   /* EMPTY */ { /* no error */ }
 | RECURSIVE { return unimplemented(sqllex, "create recursive view") }
@@ -11083,7 +12210,7 @@ composite_type_list:
 // %Help: CREATE INDEX - create a new index
 // %Category: DDL
 // %Text:
-// CREATE [UNIQUE | INVERTED] INDEX [CONCURRENTLY] [IF NOT EXISTS] [<idxname>]
+// CREATE [UNIQUE | INVERTED | VECTOR] INDEX [CONCURRENTLY] [IF NOT EXISTS] [<idxname>]
 //        ON <tablename> ( <colname> [ASC | DESC] [, ...] )
 //        [USING HASH] [STORING ( <colnames...> )]
 //        [PARTITION BY <partition params>]
@@ -11095,6 +12222,7 @@ create_index_stmt:
   CREATE opt_unique INDEX opt_concurrently opt_index_name ON table_name opt_index_access_method '(' index_params ')' opt_hash_sharded opt_storing opt_partition_by_index opt_with_storage_parameter_list opt_where_clause opt_index_visible
   {
     table := $7.unresolvedObjectName().ToTableName()
+    indexType := $8.indexType()
     $$.val = &tree.CreateIndex{
       Name:             tree.Name($5),
       Table:            table,
@@ -11105,7 +12233,7 @@ create_index_stmt:
       PartitionByIndex: $14.partitionByIndex(),
       StorageParams:    $15.storageParams(),
       Predicate:        $16.expr(),
-      Inverted:         $8.bool(),
+      Type:             indexType,
       Concurrently:     $4.bool(),
       Invisibility:     $17.indexInvisibility(),
     }
@@ -11113,6 +12241,7 @@ create_index_stmt:
 | CREATE opt_unique INDEX opt_concurrently IF NOT EXISTS index_name ON table_name opt_index_access_method '(' index_params ')' opt_hash_sharded opt_storing opt_partition_by_index opt_with_storage_parameter_list opt_where_clause opt_index_visible
   {
     table := $10.unresolvedObjectName().ToTableName()
+    indexType := $11.indexType()
     $$.val = &tree.CreateIndex{
       Name:             tree.Name($8),
       Table:            table,
@@ -11122,7 +12251,7 @@ create_index_stmt:
       Sharded:          $15.shardedIndexDef(),
       Storing:          $16.nameList(),
       PartitionByIndex: $17.partitionByIndex(),
-      Inverted:         $11.bool(),
+      Type:             indexType,
       StorageParams:    $18.storageParams(),
       Predicate:        $19.expr(),
       Concurrently:     $4.bool(),
@@ -11136,7 +12265,7 @@ create_index_stmt:
       Name:             tree.Name($6),
       Table:            table,
       Unique:           $2.bool(),
-      Inverted:         true,
+      Type:             idxtype.INVERTED,
       Columns:          $10.idxElems(),
       Storing:          $12.nameList(),
       PartitionByIndex: $13.partitionByIndex(),
@@ -11153,7 +12282,42 @@ create_index_stmt:
       Name:             tree.Name($9),
       Table:            table,
       Unique:           $2.bool(),
-      Inverted:         true,
+      Type:             idxtype.INVERTED,
+      IfNotExists:      true,
+      Columns:          $13.idxElems(),
+      Storing:          $15.nameList(),
+      PartitionByIndex: $16.partitionByIndex(),
+      StorageParams:    $17.storageParams(),
+      Predicate:        $18.expr(),
+      Concurrently:     $5.bool(),
+      Invisibility:     $19.indexInvisibility(),
+    }
+  }
+| CREATE opt_unique VECTOR INDEX opt_concurrently opt_index_name ON table_name '(' index_params ')' opt_storing opt_partition_by_index opt_with_storage_parameter_list opt_where_clause opt_index_visible
+  {
+    table := $8.unresolvedObjectName().ToTableName()
+    $$.val = &tree.CreateIndex{
+      Name:             tree.Name($6),
+      Table:            table,
+      Unique:           $2.bool(),
+      Type:             idxtype.VECTOR,
+      Columns:          $10.idxElems(),
+      Storing:          $12.nameList(),
+      PartitionByIndex: $13.partitionByIndex(),
+      StorageParams:    $14.storageParams(),
+      Predicate:        $15.expr(),
+      Concurrently:     $5.bool(),
+      Invisibility:     $16.indexInvisibility(),
+    }
+  }
+| CREATE opt_unique VECTOR INDEX opt_concurrently IF NOT EXISTS index_name ON table_name '(' index_params ')' opt_storing opt_partition_by_index opt_with_storage_parameter_list opt_where_clause opt_index_visible
+  {
+    table := $11.unresolvedObjectName().ToTableName()
+    $$.val = &tree.CreateIndex{
+      Name:             tree.Name($9),
+      Table:            table,
+      Unique:           $2.bool(),
+      Type:             idxtype.VECTOR,
       IfNotExists:      true,
       Columns:          $13.idxElems(),
       Storing:          $15.nameList(),
@@ -11170,21 +12334,25 @@ opt_index_access_method:
   USING name
   {
     /* FORCE DOC */
+    var val idxtype.T
     switch $2 {
       case "gin", "gist":
-        $$.val = true
+        val = idxtype.INVERTED
       case "btree":
-        $$.val = false
+        val = idxtype.FORWARD
+      case "cspann", "hnsw":
+        val = idxtype.VECTOR
       case "hash", "spgist", "brin":
         return unimplemented(sqllex, "index using " + $2)
       default:
         sqllex.Error("unrecognized access method: " + $2)
         return 1
     }
+    $$.val = val
   }
 | /* EMPTY */
   {
-    $$.val = false
+    $$.val = idxtype.FORWARD
   }
 
 opt_concurrently:
@@ -11870,12 +13038,15 @@ savepoint_stmt:
   }
 | SAVEPOINT error // SHOW HELP: SAVEPOINT
 
-// BEGIN / START / COMMIT / END / ROLLBACK / ...
+// BEGIN / START / COMMIT / END / ROLLBACK / PREPARE TRANSACTION / COMMIT PREPARED / ROLLBACK PREPARED / ...
 transaction_stmt:
-  begin_stmt    // EXTEND WITH HELP: BEGIN
-| commit_stmt   // EXTEND WITH HELP: COMMIT
-| rollback_stmt // EXTEND WITH HELP: ROLLBACK
-| abort_stmt    /* SKIP DOC */
+  begin_stmt               // EXTEND WITH HELP: BEGIN
+| commit_stmt              // EXTEND WITH HELP: COMMIT
+| rollback_stmt            // EXTEND WITH HELP: ROLLBACK
+| abort_stmt               /* SKIP DOC */
+| prepare_transaction_stmt // EXTEND WITH HELP: PREPARE TRANSACTION
+| commit_prepared_stmt     // EXTEND WITH HELP: COMMIT PREPARED
+| rollback_prepared_stmt   // EXTEND WITH HELP: ROLLBACK PREPARED
 
 // %Help: BEGIN - start a transaction
 // %Category: Txn
@@ -11884,7 +13055,7 @@ transaction_stmt:
 // START TRANSACTION [ <txnparameter> [[,] ...] ]
 //
 // Transaction parameters:
-//    ISOLATION LEVEL { READ COMMITTED | SERIALIZABLE }
+//    ISOLATION LEVEL { READ COMMITTED | REPEATABLE READ | SERIALIZABLE }
 //    PRIORITY { LOW | NORMAL | HIGH }
 //
 // %SeeAlso: COMMIT, ROLLBACK, WEBDOCS/begin-transaction.html
@@ -12010,7 +13181,6 @@ opt_comma:
 transaction_mode:
   transaction_iso_level
   {
-    /* SKIP DOC */
     $$.val = tree.TransactionModes{Isolation: $1.isoLevel()}
   }
 | transaction_user_priority
@@ -12062,6 +13232,36 @@ transaction_deferrable_mode:
     $$.val = tree.NotDeferrable
   }
 
+// %Help: PREPARE TRANSACTION - prepare the current transaction for two-phase commit
+// %Category: Txn
+// %Text: PREPARE TRANSACTION <transaction-id>
+// %SeeAlso: COMMIT PREPARED, ROLLBACK PREPARED
+prepare_transaction_stmt:
+  PREPARE TRANSACTION SCONST
+  {
+    $$.val = &tree.PrepareTransaction{Transaction: tree.NewStrVal($3)}
+  }
+
+// %Help: COMMIT PREPARED - commit the named transaction as part of two-phase commit
+// %Category: Txn
+// %Text: COMMIT PREPARED <transaction-id>
+// %SeeAlso: PREPARE TRANSACTION, ROLLBACK PREPARED
+commit_prepared_stmt:
+  COMMIT PREPARED SCONST
+  {
+    $$.val = &tree.CommitPrepared{Transaction: tree.NewStrVal($3)}
+  }
+
+// %Help: ROLLBACK PREPARED - rollback the named transaction as part of two-phase commit
+// %Category: Txn
+// %Text: ROLLBACK PREPARED <transaction-id>
+// %SeeAlso: PREPARE TRANSACTION, COMMIT PREPARED
+rollback_prepared_stmt:
+  ROLLBACK PREPARED SCONST
+  {
+    $$.val = &tree.RollbackPrepared{Transaction: tree.NewStrVal($3)}
+  }
+
 // %Help: CREATE DATABASE - create a new database
 // %Category: DDL
 // %Text: CREATE DATABASE [IF NOT EXISTS] <name>
@@ -12318,23 +13518,27 @@ upsert_stmt:
 | opt_with_clause UPSERT error // SHOW HELP: UPSERT
 
 insert_target:
-  table_name
+  table_name_opt_idx
   {
-    name := $1.unresolvedObjectName().ToTableName()
-    $$.val = &name
+    $$.val = $1.tblExpr()
   }
 // Can't easily make AS optional here, because VALUES in insert_rest would have
 // a shift/reduce conflict with VALUES as an optional alias. We could easily
 // allow unreserved_keywords as optional aliases, but that'd be an odd
 // divergence from other places. So just require AS for now.
-| table_name AS table_alias_name
+| table_name_opt_idx AS table_alias_name
   {
-    name := $1.unresolvedObjectName().ToTableName()
-    $$.val = &tree.AliasedTableExpr{Expr: &name, As: tree.AliasClause{Alias: tree.Name($3)}}
+    alias := $1.tblExpr().(*tree.AliasedTableExpr)
+    alias.As = tree.AliasClause{Alias: tree.Name($3)}
+    $$.val = alias
   }
-| numeric_table_ref
+| numeric_table_ref opt_index_flags
   {
-    $$.val = $1.tblExpr()
+    /* SKIP DOC */
+    $$.val = &tree.AliasedTableExpr{
+      Expr: $1.tblExpr(),
+      IndexFlags: $2.indexFlags(),
+    }
   }
 
 insert_rest:
@@ -12729,7 +13933,7 @@ simple_select:
 //        [ OFFSET <expr> [ ROW | ROWS ] ]
 // %SeeAlso: WEBDOCS/select-clause.html
 simple_select_clause:
-  SELECT opt_all_clause target_list
+  SELECT opt_all_clause opt_target_list
     from_clause opt_where_clause
     group_clause having_clause window_clause
   {
@@ -12771,7 +13975,6 @@ simple_select_clause:
       Window:     $8.window(),
     }
   }
-| SELECT error // SHOW HELP: SELECT
 
 set_operation:
   select_clause UNION all_or_distinct select_clause
@@ -13273,34 +14476,37 @@ index_flags_param:
   {
     $$.val = &tree.IndexFlags{NoIndexJoin: true}
   }
-|
-  NO_ZIGZAG_JOIN
+| NO_ZIGZAG_JOIN
   {
     $$.val = &tree.IndexFlags{NoZigzagJoin: true}
   }
-|
-  NO_FULL_SCAN
+| NO_FULL_SCAN
   {
     $$.val = &tree.IndexFlags{NoFullScan: true}
   }
-|
-  IGNORE_FOREIGN_KEYS
+| AVOID_FULL_SCAN
+  {
+    $$.val = &tree.IndexFlags{AvoidFullScan: true}
+  }
+| IGNORE_FOREIGN_KEYS
   {
     /* SKIP DOC */
     $$.val = &tree.IndexFlags{IgnoreForeignKeys: true}
   }
-|
-  FORCE_ZIGZAG
+| FORCE_INVERTED_INDEX
+  {
+    /* SKIP DOC */
+     $$.val = &tree.IndexFlags{ForceInvertedIndex: true}
+  }
+| FORCE_ZIGZAG
   {
      $$.val = &tree.IndexFlags{ForceZigzag: true}
   }
-|
-  FORCE_ZIGZAG '=' index_name
+| FORCE_ZIGZAG '=' index_name
   {
      $$.val = &tree.IndexFlags{ZigzagIndexes: []tree.UnrestrictedName{tree.UnrestrictedName($3)}}
   }
-|
-  FORCE_ZIGZAG '=' '[' iconst64 ']'
+| FORCE_ZIGZAG '=' '[' iconst64 ']'
   {
     /* SKIP DOC */
      $$.val = &tree.IndexFlags{ZigzagIndexIDs: []tree.IndexID{tree.IndexID($4.int64())}}
@@ -13371,11 +14577,12 @@ opt_index_flags:
 //   '{' NO_INDEX_JOIN [, ...] '}'
 //   '{' NO_ZIGZAG_JOIN [, ...] '}'
 //   '{' NO_FULL_SCAN [, ...] '}'
+//   '{' AVOID_FULL_SCAN [, ...] '}'
 //   '{' IGNORE_FOREIGN_KEYS [, ...] '}'
 //   '{' FORCE_ZIGZAG = <idxname> [, ...]  '}'
 //
 // Join types:
-//   { INNER | { LEFT | RIGHT | FULL } [OUTER] } [ { HASH | MERGE | LOOKUP | INVERTED } ]
+//   { INNER | { LEFT | RIGHT | FULL } [OUTER] } [ { HASH | MERGE | LOOKUP | INVERTED | STRAIGHT } ]
 //
 // %SeeAlso: WEBDOCS/table-expressions.html
 table_ref:
@@ -13699,6 +14906,7 @@ join_outer:
 //  - INVERTED forces an inverted join into the right side; the right side must
 //    be a table with a suitable inverted index. `INVERTED` can only be used
 //    with INNER and LEFT joins (though this is not enforced by the syntax).
+//  - STRAIGHT forces the join order, but not the algorithm.
 //  - If it is not possible to use the algorithm in the hint, an error is
 //    returned.
 //  - When a join hint is specified, the two tables will not be reordered
@@ -13720,6 +14928,10 @@ opt_join_hint:
   {
     $$ = tree.AstInverted
   }
+| STRAIGHT
+  {
+    $$ = tree.AstStraight
+  }
 | /* EMPTY */
   {
     $$ = ""
@@ -14051,6 +15263,21 @@ const_geo:
     $$.val = types.MakeGeography($3.geoShapeType(), geopb.SRID(val))
   }
 
+const_vector:
+  VECTOR { $$.val = types.PGVector }
+| VECTOR '(' iconst32 ')'
+  {
+    dims := $3.int32()
+    if dims <= 0 {
+      sqllex.Error("dimensions for type vector must be at least 1")
+      return 1
+    } else if dims > vector.MaxDim {
+      sqllex.Error(fmt.Sprintf("dimensions for type vector cannot exceed %d", vector.MaxDim))
+      return 1
+    }
+    $$.val = types.MakePGVector(dims)
+  }
+
 // We have a separate const_typename to allow defaulting fixed-length types such
 // as CHAR() and BIT() to an unspecified length. SQL9x requires that these
 // default to a length of one, but this makes no sense for constructs like CHAR
@@ -14068,6 +15295,7 @@ const_typename:
 | character_with_length
 | const_datetime
 | const_geo
+| const_vector
 
 opt_numeric_modifiers:
   '(' iconst32 ')'
@@ -14653,6 +15881,18 @@ a_expr:
   {
     $$.val = &tree.ComparisonExpr{Operator: treecmp.MakeComparisonOperator(treecmp.TSMatches), Left: $1.expr(), Right: $3.expr()}
   }
+| a_expr DISTANCE a_expr
+  {
+    $$.val = &tree.BinaryExpr{Operator: treebin.MakeBinaryOperator(treebin.Distance), Left: $1.expr(), Right: $3.expr()}
+  }
+| a_expr COS_DISTANCE a_expr
+  {
+    $$.val = &tree.BinaryExpr{Operator: treebin.MakeBinaryOperator(treebin.CosDistance), Left: $1.expr(), Right: $3.expr()}
+  }
+| a_expr NEG_INNER_PRODUCT a_expr
+  {
+    $$.val = &tree.BinaryExpr{Operator: treebin.MakeBinaryOperator(treebin.NegInnerProduct), Left: $1.expr(), Right: $3.expr()}
+  }
 | a_expr INET_CONTAINS_OR_EQUALS a_expr
   {
     $$.val = &tree.FuncExpr{Func: tree.WrapFunction("inet_contains_or_equals"), Exprs: tree.Exprs{$1.expr(), $3.expr()}}
@@ -15865,6 +17105,9 @@ all_op:
 | NOT_REGIMATCH { $$.val = treecmp.MakeComparisonOperator(treecmp.NotRegIMatch) }
 | AND_AND { $$.val = treecmp.MakeComparisonOperator(treecmp.Overlaps) }
 | AT_AT { $$.val = treecmp.MakeComparisonOperator(treecmp.TSMatches) }
+| DISTANCE { $$.val = treebin.MakeBinaryOperator(treebin.Distance) }
+| COS_DISTANCE { $$.val = treebin.MakeBinaryOperator(treebin.CosDistance) }
+| NEG_INNER_PRODUCT { $$.val = treebin.MakeBinaryOperator(treebin.NegInnerProduct) }
 | '~' { $$.val = tree.MakeUnaryOperator(tree.UnaryComplement) }
 | SQRT { $$.val = tree.MakeUnaryOperator(tree.UnarySqrt) }
 | CBRT { $$.val = tree.MakeUnaryOperator(tree.UnaryCbrt) }
@@ -16225,6 +17468,16 @@ target_list:
     $$.val = append($1.selExprs(), $3.selExpr())
   }
 
+opt_target_list:
+  target_list
+  {
+    $$.val = $1.selExprs()
+  }
+| /* EMPTY */
+  {
+    $$.val = tree.SelectExprs{}
+  }
+
 target_elem:
   a_expr AS target_name
   {
@@ -16807,16 +18060,19 @@ unreserved_keyword:
 | ATTRIBUTE
 | AUTOMATIC
 | AVAILABILITY
+| AVOID_FULL_SCAN
 | BACKUP
 | BACKUPS
 | BACKWARD
 | BATCH
 | BEFORE
 | BEGIN
+| BIDIRECTIONAL
 | BINARY
 | BUCKET_COUNT
 | BUNDLE
 | BY
+| BYPASSRLS
 | CACHE
 | CALL
 | CALLED
@@ -16866,8 +18122,6 @@ unreserved_keyword:
 | DAY
 | DEALLOCATE
 | DEBUG_IDS
-| DEBUG_PAUSE_ON
-| DEBUG_DUMP_METADATA_SST
 | DECLARE
 | DELETE
 | DEFAULTS
@@ -16878,10 +18132,13 @@ unreserved_keyword:
 | DESTINATION
 | DETACHED
 | DETAILS
+| DISABLE
 | DISCARD
 | DOMAIN
 | DOUBLE
 | DROP
+| EACH
+| ENABLE
 | ENCODING
 | ENCRYPTED
 | ENCRYPTION_PASSPHRASE
@@ -16915,6 +18172,7 @@ unreserved_keyword:
 | FORCE_NULL
 | FORCE_QUOTE
 | FORCE_INDEX
+| FORCE_INVERTED_INDEX
 | FORCE_ZIGZAG
 | FORWARD
 | FREEZE
@@ -16941,6 +18199,7 @@ unreserved_keyword:
 | HOUR
 | IDENTITY
 | IMMEDIATE
+| IMMEDIATELY
 | IMMUTABLE
 | IMPORT
 | INCLUDE
@@ -16956,6 +18215,7 @@ unreserved_keyword:
 | INJECT
 | INPUT
 | INSERT
+| INSTEAD
 | INTO_DB
 | INVERTED
 | INVISIBLE
@@ -16985,6 +18245,8 @@ unreserved_keyword:
 | LIST
 | LOCAL
 | LOCKED
+| LOGICAL
+| LOGICALLY
 | LOGIN
 | LOCALITY
 | LOOKUP
@@ -17010,11 +18272,13 @@ unreserved_keyword:
 | MULTIPOLYGONM
 | MULTIPOLYGONZ
 | MULTIPOLYGONZM
+| MODE
 | MONTH
 | MOVE
 | NAMES
 | NAN
 | NEVER
+| NEW
 | NEW_DB_NAME
 | NEW_KMS
 | NEXT
@@ -17024,12 +18288,14 @@ unreserved_keyword:
 | NO_INDEX_JOIN
 | NO_ZIGZAG_JOIN
 | NO_FULL_SCAN
+| NOBYPASSRLS
 | NOCREATEDB
 | NOCREATELOGIN
 | NOCANCELQUERY
 | NOCREATEROLE
 | NOCONTROLCHANGEFEED
 | NOCONTROLJOB
+| NODE
 | NOLOGIN
 | NOMODIFYCLUSTERSETTING
 | NONVOTERS
@@ -17045,6 +18311,7 @@ unreserved_keyword:
 | OF
 | OFF
 | OIDS
+| OLD
 | OLD_KMS
 | OPERATOR
 | OPT
@@ -17063,6 +18330,8 @@ unreserved_keyword:
 | PASSWORD
 | PAUSE
 | PAUSED
+| PER
+| PERMISSIVE
 | PHYSICAL
 | PLACEMENT
 | PLAN
@@ -17070,11 +18339,14 @@ unreserved_keyword:
 | POINTM
 | POINTZ
 | POINTZM
+| POLICIES
+| POLICY
 | POLYGONM
 | POLYGONZ
 | POLYGONZM
 | PRECEDING
 | PREPARE
+| PREPARED
 | PRESERVE
 | PRIOR
 | PRIORITY
@@ -17095,6 +18367,7 @@ unreserved_keyword:
 | RECURSIVE
 | REDACT
 | REF
+| REFERENCING
 | REFRESH
 | REGION
 | REGIONAL
@@ -17107,12 +18380,14 @@ unreserved_keyword:
 | RENAME
 | REPEATABLE
 | REPLACE
+| REPLICATED
 | REPLICATION
 | RESET
 | RESTART
 | RESTORE
 | RESTRICT
 | RESTRICTED
+| RESTRICTIVE
 | RESUME
 | RETENTION
 | RETRY
@@ -17166,6 +18441,7 @@ unreserved_keyword:
 | SKIP_MISSING_SEQUENCE_OWNERS
 | SKIP_MISSING_VIEWS
 | SKIP_MISSING_UDFS
+| SOURCE
 | SNAPSHOT
 | SPLIT
 | SQL
@@ -17173,6 +18449,7 @@ unreserved_keyword:
 | STABLE
 | START
 | STATE
+| STATEMENT
 | STATEMENTS
 | STATISTICS
 | STDIN
@@ -17182,9 +18459,11 @@ unreserved_keyword:
 | STORE
 | STORED
 | STORING
+| STRAIGHT
 | STREAM
 | STRICT
 | SUBSCRIPTION
+| SUBJECT
 | SUPER
 | SUPPORT
 | SURVIVE
@@ -17209,11 +18488,13 @@ unreserved_keyword:
 | TRANSFER
 | TRANSFORM
 | TRIGGER
+| TRIGGERS
 | TRUNCATE
 | TRUSTED
 | TYPE
 | TYPES
 | THROTTLING
+| UNIDIRECTIONAL
 | UNBOUNDED
 | UNCOMMITTED
 | UNKNOWN
@@ -17231,6 +18512,7 @@ unreserved_keyword:
 | VALID
 | VALIDATE
 | VALUE
+| VARIABLES
 | VARYING
 | VERIFY_BACKUP_TABLE_DATA
 | VIEW
@@ -17282,6 +18564,7 @@ bare_label_keywords:
 | AUTHORIZATION
 | AUTOMATIC
 | AVAILABILITY
+| AVOID_FULL_SCAN
 | BACKUP
 | BACKUPS
 | BACKWARD
@@ -17289,6 +18572,7 @@ bare_label_keywords:
 | BEFORE
 | BEGIN
 | BETWEEN
+| BIDIRECTIONAL
 | BIGINT
 | BINARY
 | BIT
@@ -17298,6 +18582,7 @@ bare_label_keywords:
 | BUCKET_COUNT
 | BUNDLE
 | BY
+| BYPASSRLS
 | CACHE
 | CALL
 | CALLED
@@ -17362,9 +18647,7 @@ bare_label_keywords:
 | DATABASE
 | DATABASES
 | DEALLOCATE
-| DEBUG_DUMP_METADATA_SST
 | DEBUG_IDS
-| DEBUG_PAUSE_ON
 | DEC
 | DECIMAL
 | DECLARE
@@ -17380,13 +18663,16 @@ bare_label_keywords:
 | DESTINATION
 | DETACHED
 | DETAILS
+| DISABLE
 | DISCARD
 | DISTINCT
 | DO
 | DOMAIN
 | DOUBLE
 | DROP
+| EACH
 | ELSE
+| ENABLE
 | ENCODING
 | ENCRYPTED
 | ENCRYPTION_INFO_DIR
@@ -17425,6 +18711,7 @@ bare_label_keywords:
 | FORCE_NULL
 | FORCE_QUOTE
 | FORCE_INDEX
+| FORCE_INVERTED_INDEX
 | FORCE_ZIGZAG
 | FOREIGN
 | FORMAT
@@ -17462,6 +18749,7 @@ bare_label_keywords:
 | IGNORE_FOREIGN_KEYS
 | ILIKE
 | IMMEDIATE
+| IMMEDIATELY
 | IMMUTABLE
 | IMPORT
 | IN
@@ -17485,6 +18773,7 @@ bare_label_keywords:
 | INPUT
 | INSENSITIVE
 | INSERT
+| INSTEAD
 | INT
 | INTEGER
 | INTERVAL
@@ -17528,6 +18817,8 @@ bare_label_keywords:
 | LOCALTIME
 | LOCALTIMESTAMP
 | LOCKED
+| LOGICAL
+| LOGICALLY
 | LOGIN
 | LOOKUP
 | LOW
@@ -17537,6 +18828,7 @@ bare_label_keywords:
 | MERGE
 | METHOD
 | MINVALUE
+| MODE
 | MODIFYCLUSTERSETTING
 | MODIFYSQLCLUSTERSETTING
 | MOVE
@@ -17556,16 +18848,19 @@ bare_label_keywords:
 | NAN
 | NATURAL
 | NEVER
+| NEW
 | NEW_DB_NAME
 | NEW_KMS
 | NEXT
 | NO
+| NOBYPASSRLS
 | NOCANCELQUERY
 | NOCONTROLCHANGEFEED
 | NOCONTROLJOB
 | NOCREATEDB
 | NOCREATELOGIN
 | NOCREATEROLE
+| NODE
 | NOLOGIN
 | NOMODIFYCLUSTERSETTING
 | NONE
@@ -17590,6 +18885,7 @@ bare_label_keywords:
 | OF
 | OFF
 | OIDS
+| OLD
 | OLD_KMS
 | ONLY
 | OPERATOR
@@ -17612,6 +18908,8 @@ bare_label_keywords:
 | PASSWORD
 | PAUSE
 | PAUSED
+| PER
+| PERMISSIVE
 | PHYSICAL
 | PLACEMENT
 | PLACING
@@ -17621,6 +18919,8 @@ bare_label_keywords:
 | POINTM
 | POINTZ
 | POINTZM
+| POLICIES
+| POLICY
 | POLYGON
 | POLYGONM
 | POLYGONZ
@@ -17628,6 +18928,7 @@ bare_label_keywords:
 | POSITION
 | PRECEDING
 | PREPARE
+| PREPARED
 | PRESERVE
 | PRIMARY
 | PRIOR
@@ -17651,6 +18952,7 @@ bare_label_keywords:
 | REDACT
 | REF
 | REFERENCES
+| REFERENCING
 | REFRESH
 | REGION
 | REGIONAL
@@ -17663,12 +18965,14 @@ bare_label_keywords:
 | RENAME
 | REPEATABLE
 | REPLACE
+| REPLICATED
 | REPLICATION
 | RESET
 | RESTART
 | RESTORE
 | RESTRICT
 | RESTRICTED
+| RESTRICTIVE
 | RESUME
 | RETENTION
 | RETRY
@@ -17729,12 +19033,14 @@ bare_label_keywords:
 | SMALLINT
 | SNAPSHOT
 | SOME
+| SOURCE
 | SPLIT
 | SQL
 | SQLLOGIN
 | STABLE
 | START
 | STATE
+| STATEMENT
 | STATEMENTS
 | STATISTICS
 | STATUS
@@ -17745,11 +19051,13 @@ bare_label_keywords:
 | STORE
 | STORED
 | STORING
+| STRAIGHT
 | STREAM
 | STRICT
 | STRING
 | SUBSCRIPTION
 | SUBSTRING
+| SUBJECT
 | SUPER
 | SUPPORT
 | SURVIVAL
@@ -17784,6 +19092,7 @@ bare_label_keywords:
 | TRANSFORM
 | TREAT
 | TRIGGER
+| TRIGGERS
 | TRIM
 | TRUE
 | TRUNCATE
@@ -17792,6 +19101,7 @@ bare_label_keywords:
 | TYPES
 | UNBOUNDED
 | UNCOMMITTED
+| UNIDIRECTIONAL
 | UNIQUE
 | UNKNOWN
 | UNLISTEN
@@ -17813,7 +19123,9 @@ bare_label_keywords:
 | VALUES
 | VARBIT
 | VARCHAR
+| VARIABLES
 | VARIADIC
+| VECTOR
 | VERIFY_BACKUP_TABLE_DATA
 | VIEW
 | VIEWACTIVITY
@@ -17899,6 +19211,7 @@ col_name_keyword:
 | VALUES
 | VARBIT
 | VARCHAR
+| VECTOR
 | VIRTUAL
 | WORK
 
diff --git a/pkg/sql/parser/statements/statement.go b/pkg/sql/parser/statements/statement.go
index b38efa7..64a9da9 100644
--- a/pkg/sql/parser/statements/statement.go
+++ b/pkg/sql/parser/statements/statement.go
@@ -1,23 +1,16 @@
 // Copyright 2023 The Cockroach Authors.
 //
-// Use of this software is governed by the Business Source License
-// included in the file licenses/BSL.txt.
-//
-// As of the Change Date specified in that file, in accordance with
-// the Business Source License, use of this software will be governed
-// by the Apache License, Version 2.0, included in the file
-// licenses/APL.txt.
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
 
 package statements
 
 import (
 	"github.com/cockroachdb/cockroachdb-parser/pkg/sql/sem/plpgsqltree"
 	"github.com/cockroachdb/cockroachdb-parser/pkg/sql/sem/tree"
+	"github.com/cockroachdb/cockroachdb-parser/pkg/util/jsonpath"
 )
 
-type AST interface {
-}
-
 // Statement is the result of parsing a single statement. It contains the AST
 // node along with other information.
 type Statement[T any] struct {
@@ -68,6 +61,8 @@ type Statements []Statement[tree.Statement]
 
 type PLpgStatement Statement[*plpgsqltree.Block]
 
+type JsonpathStatement Statement[*jsonpath.Jsonpath]
+
 // String returns the AST formatted as a string.
 func (stmts Statements) String() string {
 	return stmts.StringWithFlags(tree.FmtSimple)
@@ -96,6 +91,18 @@ func (stmt PLpgStatement) StringWithFlags(flags tree.FmtFlags) string {
 	return ctx.CloseAndGetString()
 }
 
+func (stmt JsonpathStatement) String() string {
+	return stmt.StringWithFlags(tree.FmtSimple)
+}
+
+// StringWithFlags returns the AST formatted as a string (with the given flags).
+func (stmt JsonpathStatement) StringWithFlags(flags tree.FmtFlags) string {
+	ctx := tree.NewFmtCtx(flags)
+	// TODO(#22513): Create a specific Format method for jsonpath that redacts constants.
+	ctx.FormatStringConstant(stmt.AST.String())
+	return ctx.CloseAndGetString()
+}
+
 type ParsedStmts interface {
 	String() string
 	StringWithFlags(flags tree.FmtFlags) string
@@ -103,3 +110,4 @@ type ParsedStmts interface {
 
 var _ ParsedStmts = Statements{}
 var _ ParsedStmts = PLpgStatement{}
+var _ ParsedStmts = JsonpathStatement{}
diff --git a/pkg/sql/pgrepl/lsn/lsn.go b/pkg/sql/pgrepl/lsn/lsn.go
index 2357277..33425e1 100644
--- a/pkg/sql/pgrepl/lsn/lsn.go
+++ b/pkg/sql/pgrepl/lsn/lsn.go
@@ -1,12 +1,7 @@
 // Copyright 2023 The Cockroach Authors.
 //
-// Use of this software is governed by the Business Source License
-// included in the file licenses/BSL.txt.
-//
-// As of the Change Date specified in that file, in accordance with
-// the Business Source License, use of this software will be governed
-// by the Apache License, Version 2.0, included in the file
-// licenses/APL.txt.
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
 
 // Package lsn contains logic for handling the pg_lsn type.
 package lsn
diff --git a/pkg/sql/pgwire/pgcode/codes.go b/pkg/sql/pgwire/pgcode/codes.go
index 29650dd..9930d22 100644
--- a/pkg/sql/pgwire/pgcode/codes.go
+++ b/pkg/sql/pgwire/pgcode/codes.go
@@ -1,12 +1,7 @@
 // Copyright 2019 The Cockroach Authors.
 //
-// Use of this software is governed by the Business Source License
-// included in the file licenses/BSL.txt.
-//
-// As of the Change Date specified in that file, in accordance with
-// the Business Source License, use of this software will be governed
-// by the Apache License, Version 2.0, included in the file
-// licenses/APL.txt.
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
 
 package pgcode
 
@@ -129,6 +124,20 @@ var (
 	InvalidXMLContent                     = MakeCode("2200N")
 	InvalidXMLComment                     = MakeCode("2200S")
 	InvalidXMLProcessingInstruction       = MakeCode("2200T")
+	InvalidSQLJSONSubscript               = MakeCode("22033")
+	MoreThanOneSQLJSONItem                = MakeCode("22034")
+	NoSQLJSONItem                         = MakeCode("22035")
+	NonNumericSQLJSONItem                 = MakeCode("22036")
+	NonUniqueKeysInJSONObject             = MakeCode("22037")
+	SingletonSQLJSONItemRequired          = MakeCode("22038")
+	SQLJSONArrayNotFound                  = MakeCode("22039")
+	SQLJSONMemberNotFound                 = MakeCode("2203A")
+	SQLJSONNumberNotFound                 = MakeCode("2203B")
+	SQLJSONObjectNotFound                 = MakeCode("2203C")
+	TooManyJSONArrayElements              = MakeCode("2203D")
+	TooManyJSONObjectMembers              = MakeCode("2203E")
+	SQLJSONScalarRequired                 = MakeCode("2203F")
+	SQLJSONItemCannotBeCastToTargetType   = MakeCode("2203G")
 	// Section: Class 23 - Integrity Constraint Violation
 	IntegrityConstraintViolation = MakeCode("23000")
 	RestrictViolation            = MakeCode("23001")
diff --git a/pkg/sql/pgwire/pgcode/doc.go b/pkg/sql/pgwire/pgcode/doc.go
index 90bdd26..eab82cd 100644
--- a/pkg/sql/pgwire/pgcode/doc.go
+++ b/pkg/sql/pgwire/pgcode/doc.go
@@ -1,12 +1,7 @@
 // Copyright 2019 The Cockroach Authors.
 //
-// Use of this software is governed by the Business Source License
-// included in the file licenses/BSL.txt.
-//
-// As of the Change Date specified in that file, in accordance with
-// the Business Source License, use of this software will be governed
-// by the Apache License, Version 2.0, included in the file
-// licenses/APL.txt.
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
 
 // Package pgcode defines the PostgreSQL 5-character support codes
 // used throughout the CockroachDB source tree.
diff --git a/pkg/sql/pgwire/pgcode/generate.sh b/pkg/sql/pgwire/pgcode/generate.sh
index 7006eb8..6e24a3e 100755
--- a/pkg/sql/pgwire/pgcode/generate.sh
+++ b/pkg/sql/pgwire/pgcode/generate.sh
@@ -1,5 +1,11 @@
 #!/bin/sh
 
+# Copyright 2019 The Cockroach Authors.
+#
+# Use of this software is governed by the CockroachDB Software License
+# included in the /LICENSE file.
+
+
 set -eu
 
 # This script will generate a list of error codes. It will not perform
diff --git a/pkg/sql/pgwire/pgcode/generate_names.sh b/pkg/sql/pgwire/pgcode/generate_names.sh
index 1d4b316..d2ea06d 100644
--- a/pkg/sql/pgwire/pgcode/generate_names.sh
+++ b/pkg/sql/pgwire/pgcode/generate_names.sh
@@ -1,5 +1,11 @@
 #!/bin/sh
 
+# Copyright 2023 The Cockroach Authors.
+#
+# Use of this software is governed by the CockroachDB Software License
+# included in the /LICENSE file.
+
+
 set -eu
 
 # This script will generate a mapping from condition names to error codes.
diff --git a/pkg/sql/pgwire/pgcode/plpgsql_codenames.go b/pkg/sql/pgwire/pgcode/plpgsql_codenames.go
index bc3958e..ae48efc 100644
--- a/pkg/sql/pgwire/pgcode/plpgsql_codenames.go
+++ b/pkg/sql/pgwire/pgcode/plpgsql_codenames.go
@@ -1,12 +1,7 @@
 // Copyright 2023 The Cockroach Authors.
 //
-// Use of this software is governed by the Business Source License
-// included in the file licenses/BSL.txt.
-//
-// As of the Change Date specified in that file, in accordance with
-// the Business Source License, use of this software will be governed
-// by the Apache License, Version 2.0, included in the file
-// licenses/APL.txt.
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
 
 package pgcode
 
diff --git a/pkg/sql/pgwire/pgerror/constraint_name.go b/pkg/sql/pgwire/pgerror/constraint_name.go
index c294ffa..e3f77b3 100644
--- a/pkg/sql/pgwire/pgerror/constraint_name.go
+++ b/pkg/sql/pgwire/pgerror/constraint_name.go
@@ -1,12 +1,7 @@
 // Copyright 2020 The Cockroach Authors.
 //
-// Use of this software is governed by the Business Source License
-// included in the file licenses/BSL.txt.
-//
-// As of the Change Date specified in that file, in accordance with
-// the Business Source License, use of this software will be governed
-// by the Apache License, Version 2.0, included in the file
-// licenses/APL.txt.
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
 
 package pgerror
 
diff --git a/pkg/sql/pgwire/pgerror/errors.go b/pkg/sql/pgwire/pgerror/errors.go
index 60d22d3..c901d97 100644
--- a/pkg/sql/pgwire/pgerror/errors.go
+++ b/pkg/sql/pgwire/pgerror/errors.go
@@ -1,12 +1,7 @@
 // Copyright 2016 The Cockroach Authors.
 //
-// Use of this software is governed by the Business Source License
-// included in the file licenses/BSL.txt.
-//
-// As of the Change Date specified in that file, in accordance with
-// the Business Source License, use of this software will be governed
-// by the Apache License, Version 2.0, included in the file
-// licenses/APL.txt.
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
 
 package pgerror
 
diff --git a/pkg/sql/pgwire/pgerror/errors.pb.go b/pkg/sql/pgwire/pgerror/errors.pb.go
index b8b4757..a54552d 100644
--- a/pkg/sql/pgwire/pgerror/errors.pb.go
+++ b/pkg/sql/pgwire/pgerror/errors.pb.go
@@ -322,7 +322,7 @@ func (m *Error_Source) Size() (n int) {
 }
 
 func sovErrors(x uint64) (n int) {
-	return (math_bits.Len64(x|1) + 6) / 7
+	return int((uint32(math_bits.Len64(x|1)+6) * 37) >> 8)
 }
 func sozErrors(x uint64) (n int) {
 	return sovErrors(uint64((x << 1) ^ uint64((int64(x) >> 63))))
diff --git a/pkg/sql/pgwire/pgerror/errors.proto b/pkg/sql/pgwire/pgerror/errors.proto
index 5a90aa4..67a4adb 100644
--- a/pkg/sql/pgwire/pgerror/errors.proto
+++ b/pkg/sql/pgwire/pgerror/errors.proto
@@ -1,12 +1,7 @@
 // Copyright 2016 The Cockroach Authors.
 //
-// Use of this software is governed by the Business Source License
-// included in the file licenses/BSL.txt.
-//
-// As of the Change Date specified in that file, in accordance with
-// the Business Source License, use of this software will be governed
-// by the Apache License, Version 2.0, included in the file
-// licenses/APL.txt.
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
 
 syntax = "proto3";
 package cockroach.pgerror;
diff --git a/pkg/sql/pgwire/pgerror/flatten.go b/pkg/sql/pgwire/pgerror/flatten.go
index 4c103f4..a90314e 100644
--- a/pkg/sql/pgwire/pgerror/flatten.go
+++ b/pkg/sql/pgwire/pgerror/flatten.go
@@ -1,12 +1,7 @@
 // Copyright 2019 The Cockroach Authors.
 //
-// Use of this software is governed by the Business Source License
-// included in the file licenses/BSL.txt.
-//
-// As of the Change Date specified in that file, in accordance with
-// the Business Source License, use of this software will be governed
-// by the Apache License, Version 2.0, included in the file
-// licenses/APL.txt.
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
 
 package pgerror
 
diff --git a/pkg/sql/pgwire/pgerror/internal_errors.go b/pkg/sql/pgwire/pgerror/internal_errors.go
index e11005e..6238d23 100644
--- a/pkg/sql/pgwire/pgerror/internal_errors.go
+++ b/pkg/sql/pgwire/pgerror/internal_errors.go
@@ -1,18 +1,14 @@
 // Copyright 2019 The Cockroach Authors.
 //
-// Use of this software is governed by the Business Source License
-// included in the file licenses/BSL.txt.
-//
-// As of the Change Date specified in that file, in accordance with
-// the Business Source License, use of this software will be governed
-// by the Apache License, Version 2.0, included in the file
-// licenses/APL.txt.
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
 
 package pgerror
 
 import (
 	"fmt"
 
+	"github.com/cockroachdb/cockroachdb-parser/pkg/build"
 	"github.com/cockroachdb/errors"
 )
 
@@ -27,6 +23,6 @@ func NewInternalTrackingError(issue int, detail string) error {
 	key := fmt.Sprintf("#%d.%s", issue, detail)
 	err := errors.AssertionFailedWithDepthf(1, "%s", errors.Safe(key))
 	err = errors.WithTelemetry(err, key)
-	err = errors.WithIssueLink(err, errors.IssueLink{IssueURL: fmt.Sprintf("https://github.com/cockroachdb/cockroachdb-parser/issues/%d", issue)})
+	err = errors.WithIssueLink(err, errors.IssueLink{IssueURL: build.MakeIssueURL(issue)})
 	return err
 }
diff --git a/pkg/sql/pgwire/pgerror/pgcode.go b/pkg/sql/pgwire/pgerror/pgcode.go
index 30ab21c..51427ba 100644
--- a/pkg/sql/pgwire/pgerror/pgcode.go
+++ b/pkg/sql/pgwire/pgerror/pgcode.go
@@ -1,12 +1,7 @@
 // Copyright 2019 The Cockroach Authors.
 //
-// Use of this software is governed by the Business Source License
-// included in the file licenses/BSL.txt.
-//
-// As of the Change Date specified in that file, in accordance with
-// the Business Source License, use of this software will be governed
-// by the Apache License, Version 2.0, included in the file
-// licenses/APL.txt.
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
 
 package pgerror
 
diff --git a/pkg/sql/pgwire/pgerror/severity.go b/pkg/sql/pgwire/pgerror/severity.go
index 6d282c4..2790c98 100644
--- a/pkg/sql/pgwire/pgerror/severity.go
+++ b/pkg/sql/pgwire/pgerror/severity.go
@@ -1,12 +1,7 @@
 // Copyright 2020 The Cockroach Authors.
 //
-// Use of this software is governed by the Business Source License
-// included in the file licenses/BSL.txt.
-//
-// As of the Change Date specified in that file, in accordance with
-// the Business Source License, use of this software will be governed
-// by the Apache License, Version 2.0, included in the file
-// licenses/APL.txt.
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
 
 package pgerror
 
diff --git a/pkg/sql/pgwire/pgerror/with_candidate_code.go b/pkg/sql/pgwire/pgerror/with_candidate_code.go
index ef51088..ce97762 100644
--- a/pkg/sql/pgwire/pgerror/with_candidate_code.go
+++ b/pkg/sql/pgwire/pgerror/with_candidate_code.go
@@ -1,12 +1,7 @@
 // Copyright 2019 The Cockroach Authors.
 //
-// Use of this software is governed by the Business Source License
-// included in the file licenses/BSL.txt.
-//
-// As of the Change Date specified in that file, in accordance with
-// the Business Source License, use of this software will be governed
-// by the Apache License, Version 2.0, included in the file
-// licenses/APL.txt.
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
 
 package pgerror
 
diff --git a/pkg/sql/pgwire/pgerror/wrap.go b/pkg/sql/pgwire/pgerror/wrap.go
index ac95620..4371ffe 100644
--- a/pkg/sql/pgwire/pgerror/wrap.go
+++ b/pkg/sql/pgwire/pgerror/wrap.go
@@ -1,12 +1,7 @@
 // Copyright 2019 The Cockroach Authors.
 //
-// Use of this software is governed by the Business Source License
-// included in the file licenses/BSL.txt.
-//
-// As of the Change Date specified in that file, in accordance with
-// the Business Source License, use of this software will be governed
-// by the Apache License, Version 2.0, included in the file
-// licenses/APL.txt.
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
 
 package pgerror
 
diff --git a/pkg/sql/plpgsql/parser/lexbase/keywords.go b/pkg/sql/plpgsql/parser/lexbase/keywords.go
new file mode 100644
index 0000000..22ccc20
--- /dev/null
+++ b/pkg/sql/plpgsql/parser/lexbase/keywords.go
@@ -0,0 +1,359 @@
+// Code generated by pkg/sql/lexbase/allkeywords. DO NOT EDIT.
+
+package lexbase
+
+var KeywordsCategories = map[string]string{
+"absolute": "U",
+"alias": "U",
+"all": "R",
+"and": "U",
+"array": "U",
+"assert": "U",
+"backward": "U",
+"begin": "R",
+"by": "R",
+"call": "U",
+"case": "R",
+"chain": "U",
+"close": "U",
+"collate": "U",
+"column": "U",
+"column_name": "U",
+"commit": "U",
+"constant": "U",
+"constraint": "U",
+"constraint_name": "U",
+"continue": "U",
+"current": "U",
+"cursor": "U",
+"datatype": "U",
+"debug": "U",
+"declare": "R",
+"default": "U",
+"detail": "U",
+"diagnostics": "U",
+"do": "U",
+"dump": "U",
+"else": "R",
+"elsif": "U",
+"end": "R",
+"end_case": "R",
+"end_if": "R",
+"errcode": "U",
+"error": "U",
+"exception": "U",
+"execute": "R",
+"exit": "U",
+"fetch": "U",
+"first": "U",
+"for": "R",
+"foreach": "R",
+"forward": "U",
+"from": "R",
+"get": "U",
+"hint": "U",
+"if": "R",
+"import": "U",
+"in": "R",
+"info": "U",
+"insert": "U",
+"into": "R",
+"is": "U",
+"language": "U",
+"last": "U",
+"log": "U",
+"loop": "R",
+"merge": "U",
+"message": "U",
+"message_text": "U",
+"move": "U",
+"next": "U",
+"no": "U",
+"not": "R",
+"notice": "U",
+"no_scroll": "U",
+"null": "R",
+"open": "U",
+"option": "U",
+"or": "R",
+"perform": "U",
+"pg_context": "U",
+"pg_datatype_name": "U",
+"pg_exception_context": "U",
+"pg_exception_detail": "U",
+"pg_exception_hint": "U",
+"print_strict_params": "U",
+"prior": "U",
+"query": "U",
+"raise": "U",
+"relative": "U",
+"return": "U",
+"returned_sqlstate": "U",
+"return_next": "U",
+"return_query": "U",
+"reverse": "U",
+"rollback": "U",
+"rowtype": "U",
+"row_count": "U",
+"schema": "U",
+"schema_name": "U",
+"scroll": "U",
+"slice": "U",
+"sqlstate": "U",
+"stacked": "U",
+"strict": "R",
+"table": "U",
+"table_name": "U",
+"then": "R",
+"to": "R",
+"type": "U",
+"upsert": "U",
+"use_column": "U",
+"use_variable": "U",
+"using": "R",
+"variable_conflict": "U",
+"warning": "U",
+"when": "R",
+"while": "R",
+}
+
+// KeywordNames contains all keywords sorted, so that pg_get_keywords returns
+// deterministic results.
+var KeywordNames = []string{
+"absolute",
+"alias",
+"all",
+"and",
+"array",
+"assert",
+"backward",
+"begin",
+"by",
+"call",
+"case",
+"chain",
+"close",
+"collate",
+"column",
+"column_name",
+"commit",
+"constant",
+"constraint",
+"constraint_name",
+"continue",
+"current",
+"cursor",
+"datatype",
+"debug",
+"declare",
+"default",
+"detail",
+"diagnostics",
+"do",
+"dump",
+"else",
+"elsif",
+"end",
+"end_case",
+"end_if",
+"errcode",
+"error",
+"exception",
+"execute",
+"exit",
+"fetch",
+"first",
+"for",
+"foreach",
+"forward",
+"from",
+"get",
+"hint",
+"if",
+"import",
+"in",
+"info",
+"insert",
+"into",
+"is",
+"language",
+"last",
+"log",
+"loop",
+"merge",
+"message",
+"message_text",
+"move",
+"next",
+"no",
+"not",
+"notice",
+"no_scroll",
+"null",
+"open",
+"option",
+"or",
+"perform",
+"pg_context",
+"pg_datatype_name",
+"pg_exception_context",
+"pg_exception_detail",
+"pg_exception_hint",
+"print_strict_params",
+"prior",
+"query",
+"raise",
+"relative",
+"return",
+"returned_sqlstate",
+"return_next",
+"return_query",
+"reverse",
+"rollback",
+"rowtype",
+"row_count",
+"schema",
+"schema_name",
+"scroll",
+"slice",
+"sqlstate",
+"stacked",
+"strict",
+"table",
+"table_name",
+"then",
+"to",
+"type",
+"upsert",
+"use_column",
+"use_variable",
+"using",
+"variable_conflict",
+"warning",
+"when",
+"while",
+}
+
+// GetKeywordID returns the lex id of the SQL keyword k or IDENT if k is
+// not a keyword.
+func GetKeywordID(k string) int32 {
+	// The previous implementation generated a map that did a string ->
+	// id lookup. Various ideas were benchmarked and the implementation below
+	// was the fastest of those, between 3% and 10% faster (at parsing, so the
+	// scanning speedup is even more) than the map implementation.
+	switch k {
+	case "absolute": return ABSOLUTE
+	case "alias": return ALIAS
+	case "all": return ALL
+	case "and": return AND
+	case "array": return ARRAY
+	case "assert": return ASSERT
+	case "backward": return BACKWARD
+	case "begin": return BEGIN
+	case "by": return BY
+	case "call": return CALL
+	case "case": return CASE
+	case "chain": return CHAIN
+	case "close": return CLOSE
+	case "collate": return COLLATE
+	case "column": return COLUMN
+	case "column_name": return COLUMN_NAME
+	case "commit": return COMMIT
+	case "constant": return CONSTANT
+	case "constraint": return CONSTRAINT
+	case "constraint_name": return CONSTRAINT_NAME
+	case "continue": return CONTINUE
+	case "current": return CURRENT
+	case "cursor": return CURSOR
+	case "datatype": return DATATYPE
+	case "debug": return DEBUG
+	case "declare": return DECLARE
+	case "default": return DEFAULT
+	case "detail": return DETAIL
+	case "diagnostics": return DIAGNOSTICS
+	case "do": return DO
+	case "dump": return DUMP
+	case "else": return ELSE
+	case "elsif": return ELSIF
+	case "end": return END
+	case "end_case": return END_CASE
+	case "end_if": return END_IF
+	case "errcode": return ERRCODE
+	case "error": return ERROR
+	case "exception": return EXCEPTION
+	case "execute": return EXECUTE
+	case "exit": return EXIT
+	case "fetch": return FETCH
+	case "first": return FIRST
+	case "for": return FOR
+	case "foreach": return FOREACH
+	case "forward": return FORWARD
+	case "from": return FROM
+	case "get": return GET
+	case "hint": return HINT
+	case "if": return IF
+	case "import": return IMPORT
+	case "in": return IN
+	case "info": return INFO
+	case "insert": return INSERT
+	case "into": return INTO
+	case "is": return IS
+	case "language": return LANGUAGE
+	case "last": return LAST
+	case "log": return LOG
+	case "loop": return LOOP
+	case "merge": return MERGE
+	case "message": return MESSAGE
+	case "message_text": return MESSAGE_TEXT
+	case "move": return MOVE
+	case "next": return NEXT
+	case "no": return NO
+	case "not": return NOT
+	case "notice": return NOTICE
+	case "no_scroll": return NO_SCROLL
+	case "null": return NULL
+	case "open": return OPEN
+	case "option": return OPTION
+	case "or": return OR
+	case "perform": return PERFORM
+	case "pg_context": return PG_CONTEXT
+	case "pg_datatype_name": return PG_DATATYPE_NAME
+	case "pg_exception_context": return PG_EXCEPTION_CONTEXT
+	case "pg_exception_detail": return PG_EXCEPTION_DETAIL
+	case "pg_exception_hint": return PG_EXCEPTION_HINT
+	case "print_strict_params": return PRINT_STRICT_PARAMS
+	case "prior": return PRIOR
+	case "query": return QUERY
+	case "raise": return RAISE
+	case "relative": return RELATIVE
+	case "return": return RETURN
+	case "returned_sqlstate": return RETURNED_SQLSTATE
+	case "return_next": return RETURN_NEXT
+	case "return_query": return RETURN_QUERY
+	case "reverse": return REVERSE
+	case "rollback": return ROLLBACK
+	case "rowtype": return ROWTYPE
+	case "row_count": return ROW_COUNT
+	case "schema": return SCHEMA
+	case "schema_name": return SCHEMA_NAME
+	case "scroll": return SCROLL
+	case "slice": return SLICE
+	case "sqlstate": return SQLSTATE
+	case "stacked": return STACKED
+	case "strict": return STRICT
+	case "table": return TABLE
+	case "table_name": return TABLE_NAME
+	case "then": return THEN
+	case "to": return TO
+	case "type": return TYPE
+	case "upsert": return UPSERT
+	case "use_column": return USE_COLUMN
+	case "use_variable": return USE_VARIABLE
+	case "using": return USING
+	case "variable_conflict": return VARIABLE_CONFLICT
+	case "warning": return WARNING
+	case "when": return WHEN
+	case "while": return WHILE
+	default: return IDENT
+	}
+}
diff --git a/pkg/sql/plpgsql/parser/lexbase/tokens.go b/pkg/sql/plpgsql/parser/lexbase/tokens.go
new file mode 100644
index 0000000..fd01718
--- /dev/null
+++ b/pkg/sql/plpgsql/parser/lexbase/tokens.go
@@ -0,0 +1,135 @@
+// Code generated by make. DO NOT EDIT.
+// GENERATED FILE DO NOT EDIT
+
+package lexbase
+
+const IDENT = 57346
+const UIDENT = 57347
+const FCONST = 57348
+const SCONST = 57349
+const USCONST = 57350
+const BCONST = 57351
+const XCONST = 57352
+const ICONST = 57354
+const PARAM = 57355
+const TYPECAST = 57356
+const DOT_DOT = 57357
+const COLON_EQUALS = 57358
+const EQUALS_GREATER = 57359
+const LESS_EQUALS = 57360
+const GREATER_EQUALS = 57361
+const NOT_EQUALS = 57362
+const LESS_LESS = 57363
+const GREATER_GREATER = 57364
+const ABSOLUTE = 57365
+const ALIAS = 57366
+const ALL = 57367
+const AND = 57368
+const ARRAY = 57369
+const ASSERT = 57370
+const BACKWARD = 57371
+const BEGIN = 57372
+const BY = 57373
+const CALL = 57374
+const CASE = 57375
+const CHAIN = 57376
+const CLOSE = 57377
+const COLLATE = 57378
+const COLUMN = 57379
+const COLUMN_NAME = 57380
+const COMMIT = 57381
+const CONSTANT = 57382
+const CONSTRAINT = 57383
+const CONSTRAINT_NAME = 57384
+const CONTINUE = 57385
+const CURRENT = 57386
+const CURSOR = 57387
+const DATATYPE = 57388
+const DEBUG = 57389
+const DECLARE = 57390
+const DEFAULT = 57391
+const DETAIL = 57392
+const DIAGNOSTICS = 57393
+const DO = 57394
+const DUMP = 57395
+const ELSE = 57396
+const ELSIF = 57397
+const END = 57398
+const END_CASE = 57399
+const END_IF = 57400
+const ERRCODE = 57401
+const ERROR = 57402
+const EXCEPTION = 57403
+const EXECUTE = 57404
+const EXIT = 57405
+const FETCH = 57406
+const FIRST = 57407
+const FOR = 57408
+const FOREACH = 57409
+const FORWARD = 57410
+const FROM = 57411
+const GET = 57412
+const HINT = 57413
+const IF = 57414
+const IMPORT = 57415
+const IN = 57416
+const INFO = 57417
+const INSERT = 57418
+const INTO = 57419
+const IS = 57420
+const LANGUAGE = 57421
+const LAST = 57422
+const LOG = 57423
+const LOOP = 57424
+const MERGE = 57425
+const MESSAGE = 57426
+const MESSAGE_TEXT = 57427
+const MOVE = 57428
+const NEXT = 57429
+const NO = 57430
+const NO_SCROLL = 57431
+const NOT = 57432
+const NOTICE = 57433
+const NULL = 57434
+const OPEN = 57435
+const OPTION = 57436
+const OR = 57437
+const PERFORM = 57438
+const PG_CONTEXT = 57439
+const PG_DATATYPE_NAME = 57440
+const PG_EXCEPTION_CONTEXT = 57441
+const PG_EXCEPTION_DETAIL = 57442
+const PG_EXCEPTION_HINT = 57443
+const PRINT_STRICT_PARAMS = 57444
+const PRIOR = 57445
+const QUERY = 57446
+const RAISE = 57447
+const RELATIVE = 57448
+const RETURN = 57449
+const RETURN_NEXT = 57450
+const RETURN_QUERY = 57451
+const RETURNED_SQLSTATE = 57452
+const REVERSE = 57453
+const ROLLBACK = 57454
+const ROW_COUNT = 57455
+const ROWTYPE = 57456
+const SCHEMA = 57457
+const SCHEMA_NAME = 57458
+const SCROLL = 57459
+const SLICE = 57460
+const SQLSTATE = 57461
+const STACKED = 57462
+const STRICT = 57463
+const TABLE = 57464
+const TABLE_NAME = 57465
+const THEN = 57466
+const TO = 57467
+const TYPE = 57468
+const UPSERT = 57469
+const USE_COLUMN = 57470
+const USE_VARIABLE = 57471
+const USING = 57472
+const VARIABLE_CONFLICT = 57473
+const WARNING = 57474
+const WHEN = 57475
+const WHILE = 57476
diff --git a/pkg/sql/plpgsql/parser/lexbase/utils.go b/pkg/sql/plpgsql/parser/lexbase/utils.go
new file mode 100644
index 0000000..56681df
--- /dev/null
+++ b/pkg/sql/plpgsql/parser/lexbase/utils.go
@@ -0,0 +1,7 @@
+// Copyright 2023 The Cockroach Authors.
+//
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
+
+// Package lexbase contains utilities for lexing plpgsql.
+package lexbase
diff --git a/pkg/sql/plpgsql/parser/lexer.go b/pkg/sql/plpgsql/parser/lexer.go
new file mode 100644
index 0000000..f87a883
--- /dev/null
+++ b/pkg/sql/plpgsql/parser/lexer.go
@@ -0,0 +1,677 @@
+// Copyright 2023 The Cockroach Authors.
+//
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
+
+package parser
+
+import (
+	"strings"
+
+	"github.com/cockroachdb/cockroachdb-parser/pkg/sql/parser"
+	"github.com/cockroachdb/cockroachdb-parser/pkg/sql/pgwire/pgcode"
+	"github.com/cockroachdb/cockroachdb-parser/pkg/sql/pgwire/pgerror"
+	"github.com/cockroachdb/cockroachdb-parser/pkg/sql/sem/plpgsqltree"
+	"github.com/cockroachdb/cockroachdb-parser/pkg/sql/sem/tree"
+	"github.com/cockroachdb/cockroachdb-parser/pkg/sql/types"
+	unimp "github.com/cockroachdb/cockroachdb-parser/pkg/util/errorutil/unimplemented"
+	"github.com/cockroachdb/errors"
+)
+
+type lexer struct {
+	in string
+	// tokens contains tokens generated by the scanner.
+	tokens []plpgsqlSymType
+
+	// The type that should be used when an INT or SERIAL is encountered.
+	nakedIntType *types.T
+
+	// lastPos is the position into the tokens slice of the last
+	// token returned by Lex().
+	lastPos int
+
+	stmt *plpgsqltree.Block
+
+	// numPlaceholders is 1 + the highest placeholder index encountered.
+	numPlaceholders int
+	numAnnotations  tree.AnnotationIdx
+
+	lastError error
+
+	parser plpgsqlParser
+}
+
+func (l *lexer) init(sql string, tokens []plpgsqlSymType, nakedIntType *types.T, p plpgsqlParser) {
+	l.in = sql
+	l.tokens = tokens
+	l.lastPos = -1
+	l.stmt = nil
+	l.numPlaceholders = 0
+	l.numAnnotations = 0
+	l.lastError = nil
+	l.nakedIntType = nakedIntType
+	l.parser = p
+}
+
+// cleanup is used to avoid holding on to memory unnecessarily (for the cases
+// where we reuse a scanner).
+func (l *lexer) cleanup() {
+	l.tokens = nil
+	l.stmt = nil
+	l.lastError = nil
+}
+
+// Lex lexes a token from input.
+// to push the tokens back (move l.pos back).
+func (l *lexer) Lex(lval *plpgsqlSymType) int {
+	l.lastPos++
+	// The core lexing takes place in the scanner. Here we do a small bit of post
+	// processing of the lexical tokens so that the grammar only requires
+	// one-token lookahead despite SQL requiring multi-token lookahead in some
+	// cases. These special cases are handled below and the returned tokens are
+	// adjusted to reflect the lookahead (LA) that occurred.
+	if l.lastPos >= len(l.tokens) {
+		lval.id = 0
+		lval.pos = int32(len(l.in))
+		lval.str = "EOF"
+		return 0
+	}
+	*lval = l.tokens[l.lastPos]
+
+	switch lval.id {
+	case RETURN:
+		nextToken := plpgsqlSymType{}
+		if l.lastPos+1 < len(l.tokens) {
+			nextToken = l.tokens[l.lastPos+1]
+		}
+		switch nextToken.id {
+		case NEXT:
+			lval.id = RETURN_NEXT
+		case QUERY:
+			lval.id = RETURN_QUERY
+		}
+	case END:
+		nextToken := plpgsqlSymType{}
+		if l.lastPos+1 < len(l.tokens) {
+			nextToken = l.tokens[l.lastPos+1]
+		}
+		switch nextToken.id {
+		case IF:
+			lval.id = END_IF
+		case CASE:
+			lval.id = END_CASE
+		}
+	case NO:
+		nextToken := plpgsqlSymType{}
+		if l.lastPos+1 < len(l.tokens) {
+			nextToken = l.tokens[l.lastPos+1]
+		}
+		switch nextToken.id {
+		case SCROLL:
+			lval.id = NO_SCROLL
+		}
+	}
+
+	return int(lval.id)
+}
+
+// MakeExecSqlStmt makes an Execute node.
+func (l *lexer) MakeExecSqlStmt() (*plpgsqltree.Execute, error) {
+	if l.parser.Lookahead() != -1 {
+		// Push back the lookahead token so that it can be included.
+		l.PushBack(1)
+	}
+	// Push back the first token so that it's included in the SQL string.
+	l.PushBack(1)
+	startPos, endPos, _, err := l.readSQLConstruct(false /* isExpr */, false /* allowEmpty */, ';')
+	if err != nil {
+		return nil, err
+	}
+	// Move past the semicolon.
+	l.lastPos++
+
+	var haveInto, haveStrict bool
+	var intoStartPos, intoEndPos int
+	var target []plpgsqltree.Variable
+	firstTok := l.tokens[startPos]
+	tok := firstTok
+	for pos := startPos; pos < endPos; pos++ {
+		prevTok := tok
+		tok = l.tokens[pos]
+		if tok.id == INTO {
+			if prevTok.id == INSERT || prevTok.id == UPSERT ||
+				prevTok.id == MERGE || firstTok.id == IMPORT {
+				// INSERT INTO, UPSERT INTO, MERGE INTO, and IMPORT ... INTO are not
+				// INTO-targets.
+				continue
+			}
+			if haveInto {
+				return nil, errors.New("INTO specified more than once")
+			}
+			haveInto = true
+			intoStartPos = pos
+			pos++
+			if pos+1 < endPos && l.tokens[pos].id == STRICT {
+				haveStrict = true
+				pos++
+			}
+			// Read in one or more comma-separated variables as the INTO target.
+			target, intoEndPos, err = l.readTarget(pos, endPos)
+			if err != nil {
+				return nil, err
+			}
+		}
+	}
+
+	var sql string
+	if haveInto {
+		sql = l.getStr(startPos, intoStartPos) + l.getStr(intoEndPos, endPos)
+	} else {
+		sql = l.getStr(startPos, endPos)
+	}
+	sqlStmt, err := parser.ParseOne(sql)
+	if err != nil {
+		return nil, err
+	}
+
+	// Note: PG disallows directly writing SQL statements that return rows, like
+	// a SELECT or a mutation with RETURNING. It is difficult to determine this
+	// for all possible statements, and execution is able to handle it, so we
+	// allow SQL statements that return rows.
+	if target != nil && sqlStmt.AST.StatementReturnType() != tree.Rows {
+		return nil, pgerror.New(pgcode.Syntax, "INTO used with a command that cannot return data")
+	}
+	ann := tree.MakeAnnotations(sqlStmt.NumAnnotations)
+	return &plpgsqltree.Execute{
+		SqlStmt:     sqlStmt.AST,
+		Strict:      haveStrict,
+		Target:      target,
+		Annotations: &ann,
+	}, nil
+}
+
+func (l *lexer) MakeDynamicExecuteStmt() (*plpgsqltree.DynamicExecute, error) {
+	cmdStr, _, err := l.ReadSqlStatement(INTO, USING, ';')
+	if err != nil {
+		return nil, err
+	}
+	ret := &plpgsqltree.DynamicExecute{
+		Query: cmdStr,
+	}
+
+	var lval plpgsqlSymType
+	l.Lex(&lval)
+	for {
+		if lval.id == INTO {
+			if ret.Into {
+				return nil, errors.New("multiple INTO keywords")
+			}
+			ret.Into = true
+			nextTok := l.Peek()
+			if nextTok.id == int32(STRICT) {
+				l.Lex(&lval)
+				ret.Strict = true
+			}
+			// TODO we need to read each "INTO" variable name instead of just a
+			// string.
+			_, _, err = l.ReadSqlExpr(USING, ';')
+			if err != nil {
+				return nil, err
+			}
+			l.Lex(&lval)
+		} else if lval.id == USING {
+			if ret.Params != nil {
+				return nil, errors.New("multiple USING keywords")
+			}
+			ret.Params = make([]plpgsqltree.Expr, 0)
+			for {
+				_, _, err = l.ReadSqlExpr(',', ';', INTO)
+				if err != nil {
+					return nil, err
+				}
+				ret.Params = append(ret.Params, nil)
+				l.Lex(&lval)
+				if lval.id == ';' {
+					break
+				}
+			}
+		} else if lval.id == ';' {
+			break
+		} else {
+			return nil, errors.Newf("unexpected token: %s", lval.id)
+		}
+	}
+
+	return ret, nil
+}
+
+func (l *lexer) MakeFetchOrMoveStmt(isMove bool) (plpgsqltree.Statement, error) {
+	if l.parser.Lookahead() != -1 {
+		// Push back the lookahead token so that it can be included.
+		l.PushBack(1)
+	}
+	prefix := "FETCH "
+	if isMove {
+		prefix = "MOVE "
+	}
+	sqlStr, terminator, err := l.ReadSqlStatement(INTO, ';')
+	if err != nil {
+		return nil, err
+	}
+	sqlStr = prefix + sqlStr
+	sqlStmt, err := parser.ParseOne(sqlStr)
+	if err != nil {
+		return nil, err
+	}
+	var cursor tree.CursorStmt
+	switch t := sqlStmt.AST.(type) {
+	case *tree.FetchCursor:
+		cursor = t.CursorStmt
+	case *tree.MoveCursor:
+		cursor = t.CursorStmt
+	default:
+		return nil, errors.Newf("invalid FETCH or MOVE syntax")
+	}
+	var target []plpgsqltree.Variable
+	if !isMove {
+		if terminator != INTO {
+			return nil, errors.Newf("invalid syntax for FETCH")
+		}
+		// Read past the INTO.
+		l.lastPos++
+		startPos, endPos, _, err := l.readSQLConstruct(true /* isExpr */, false /* allowEmpty */, ';')
+		if err != nil {
+			return nil, err
+		}
+		var targetEnd int
+		target, targetEnd, err = l.readTarget(startPos, endPos)
+		if err != nil {
+			return nil, err
+		}
+		if targetEnd != endPos {
+			return nil, errors.Newf("expected INTO target to be a comma-separated list")
+		}
+		if len(target) == 0 {
+			return nil, errors.Newf("expected INTO target")
+		}
+	}
+	// Move past the semicolon.
+	l.lastPos++
+	ann := tree.MakeAnnotations(sqlStmt.NumAnnotations)
+	return &plpgsqltree.Fetch{
+		Cursor:      cursor,
+		Target:      target,
+		IsMove:      isMove,
+		Annotations: &ann,
+	}, nil
+}
+
+// ReadIntegerForLoopControl reads a loop control statement that uses integer
+// bounds. Syntax:
+//
+//	[ REVERSE ] expression .. expression [ BY expression ] LOOP
+func (l *lexer) ReadIntegerForLoopControl() (plpgsqltree.ForLoopControl, error) {
+	if l.parser.Lookahead() != -1 {
+		// Push back the lookahead token so that it can be included.
+		l.PushBack(1)
+	}
+	var reverse bool
+	var byExprStr string
+	if l.Peek().id == REVERSE {
+		reverse = true
+		l.lastPos++
+	}
+	lowerBoundStr, _, err := l.ReadSqlExpr(DOT_DOT)
+	if err != nil {
+		return nil, err
+	}
+	l.lastPos++
+	upperBoundStr, terminator, err := l.ReadSqlExpr(LOOP, BY)
+	if err != nil {
+		return nil, err
+	}
+	l.lastPos++
+	if terminator == BY {
+		byExprStr, terminator, err = l.ReadSqlExpr(LOOP)
+		if err != nil {
+			return nil, err
+		}
+		l.lastPos++
+	}
+	if terminator == 0 {
+		return nil, errors.New("missing LOOP keyword")
+	}
+	var lowerBound, upperBound, byExpr plpgsqltree.Expr
+	lowerBound, err = l.ParseExpr(lowerBoundStr)
+	if err != nil {
+		return nil, err
+	}
+	upperBound, err = l.ParseExpr(upperBoundStr)
+	if err != nil {
+		return nil, err
+	}
+	if byExprStr != "" {
+		byExpr, err = l.ParseExpr(byExprStr)
+		if err != nil {
+			return nil, err
+		}
+	}
+	return &plpgsqltree.IntForLoopControl{
+		Reverse: reverse,
+		Lower:   lowerBound,
+		Upper:   upperBound,
+		Step:    byExpr,
+	}, err
+}
+
+// makeDoStmt analyzes and parses the options supplied to a DO statement.
+func makeDoStmt(options tree.DoBlockOptions) (*plpgsqltree.DoBlock, error) {
+	doBlockBodyStr, err := tree.AnalyzeDoBlockOptions(options)
+	if err != nil {
+		return nil, err
+	}
+	parsedStmt, err := Parse(string(doBlockBodyStr))
+	if err != nil {
+		return nil, err
+	}
+	return &plpgsqltree.DoBlock{Block: parsedStmt.AST}, nil
+}
+
+// ParseReturnExpr handles reading and parsing the expression for a RETURN or
+// RETURN NEXT statement, which can be nonexistent.
+func (l *lexer) ParseReturnExpr() (plpgsqltree.Expr, error) {
+	startPos, endPos, _, err := l.readSQLConstruct(true /* isExpr */, true /* allowEmpty */, ';')
+	if err != nil || startPos == endPos {
+		return nil, err
+	}
+	exprStr := l.getStr(startPos, endPos)
+	return l.ParseExpr(exprStr)
+}
+
+// ParseReturnQuery handles reading and parsing the query for a RETURN QUERY
+// statement, which can be nonexistent.
+func (l *lexer) ParseReturnQuery() (plpgsqltree.Statement, error) {
+	startPos, endPos, _, err := l.readSQLConstruct(false /* isExpr */, false /* allowEmpty */, ';')
+	if err != nil || startPos == endPos {
+		return nil, err
+	}
+	queryStr := l.getStr(startPos, endPos)
+	stmt, err := parser.ParseOne(queryStr)
+	if err != nil {
+		return nil, err
+	}
+	ann := tree.MakeAnnotations(stmt.NumAnnotations)
+	return &plpgsqltree.ReturnQuery{
+		SqlStmt:     stmt.AST,
+		Annotations: &ann,
+	}, nil
+}
+
+// peekForExecute checks whether the next token is EXECUTE, used to identify
+// dynamic SQL statements.
+func (l *lexer) peekForExecute() bool {
+	if l.parser.Lookahead() != -1 {
+		// Push back the lookahead token so that it can be included.
+		l.PushBack(1)
+	}
+	return l.Peek().id == EXECUTE
+}
+
+func (l *lexer) ReadSqlExpr(
+	terminator1 int, terminators ...int,
+) (sqlStr string, terminatorMet int, err error) {
+	var startPos, endPos int
+	startPos, endPos, terminatorMet, err = l.readSQLConstruct(
+		true /* isExpr */, false /* allowEmpty */, terminator1, terminators...,
+	)
+	return l.getStr(startPos, endPos), terminatorMet, err
+}
+
+func (l *lexer) ReadSqlStatement(
+	terminator1 int, terminators ...int,
+) (sqlStr string, terminatorMet int, err error) {
+	var startPos, endPos int
+	startPos, endPos, terminatorMet, err = l.readSQLConstruct(
+		false /* isExpr */, false /* allowEmpty */, terminator1, terminators...,
+	)
+	return l.getStr(startPos, endPos), terminatorMet, err
+}
+
+// findFirstOccurrence searches from the current position for occurrences of the
+// supplied tokens, returning the first one found. The cursor is not advanced
+// unless there is an error. If the given terminators are not found, the
+// function returns 0.
+func (l *lexer) findFirstOccurrence(
+	terminator1 int, terminators ...int,
+) (foundToken int, err error) {
+	if l.parser.Lookahead() != -1 {
+		// Push back the lookahead token so that it can be included.
+		l.PushBack(1)
+	}
+	originalPos := l.lastPos
+	_, _, terminatorMet, err := l.readSQLConstruct(
+		true /* isExpr */, true /* allowEmpty */, terminator1, terminators...,
+	)
+	if err == nil {
+		// Restore the original position.
+		l.lastPos = originalPos
+	}
+	return terminatorMet, err
+}
+
+func (l *lexer) readSQLConstruct(
+	isExpr, allowEmpty bool, terminator1 int, terminators ...int,
+) (startPos, endPos, terminatorMet int, err error) {
+	if l.parser.Lookahead() != -1 {
+		// Push back the lookahead token so that it can be included.
+		l.PushBack(1)
+	}
+	parenLevel := 0
+	startPos = l.lastPos + 1
+	for l.lastPos < len(l.tokens) {
+		tok := l.Peek()
+		if tok.id == ERROR {
+			// This is a tokenizer (lexical) error: the scanner
+			// will have stored the error message in the string field.
+			return 0, 0, 0, errors.Newf("%s", tok.str)
+		}
+		if int(tok.id) == terminator1 && parenLevel == 0 {
+			terminatorMet = terminator1
+			break
+		}
+		for _, term := range terminators {
+			if int(tok.id) == term && parenLevel == 0 {
+				terminatorMet = term
+			}
+		}
+		if terminatorMet != 0 {
+			break
+		}
+		if tok.id == '(' || tok.id == '[' {
+			parenLevel++
+		} else if tok.id == ')' || tok.id == ']' {
+			parenLevel--
+			if parenLevel < 0 {
+				return 0, 0, 0, errors.New("mismatched parentheses")
+			}
+		}
+		l.lastPos++
+	}
+	if parenLevel != 0 {
+		return 0, 0, 0, errors.New("mismatched parentheses")
+	}
+	endPos = l.lastPos + 1
+	if endPos > len(l.tokens) {
+		endPos = len(l.tokens)
+	}
+	if endPos < startPos || (!allowEmpty && endPos == startPos) {
+		if isExpr {
+			return 0, 0, 0, errors.New("missing expression")
+		} else {
+			return 0, 0, 0, errors.New("missing SQL statement")
+		}
+	}
+	return startPos, endPos, terminatorMet, nil
+}
+
+func (l *lexer) getStr(startPos, endPos int) string {
+	if endPos <= startPos {
+		return ""
+	}
+	end := len(l.in)
+	if endPos < len(l.tokens) {
+		end = int(l.tokens[endPos].Pos())
+	}
+	start := int(l.tokens[startPos].Pos())
+	return l.in[start:end]
+}
+
+// Peek peeks
+func (l *lexer) Peek() plpgsqlSymType {
+	if l.lastPos+1 < len(l.tokens) {
+		return l.tokens[l.lastPos+1]
+	}
+	return plpgsqlSymType{}
+}
+
+// PushBack rewinds the lexer by n tokens.
+func (l *lexer) PushBack(n int) {
+	if n < 0 {
+		panic(errors.AssertionFailedf("negative n provided to PushBack"))
+	}
+	l.lastPos -= n
+	if l.lastPos < -1 {
+		// Return to the initialized state.
+		l.lastPos = -1
+	}
+	if n >= 1 {
+		// Invalidate the parser lookahead token.
+		l.parser.(*plpgsqlParserImpl).char = -1
+	}
+}
+
+// Advance advances the lexer by n tokens.
+func (l *lexer) Advance(n int) {
+	if n < 0 {
+		panic(errors.AssertionFailedf("negative n provided to Advance"))
+	}
+	l.lastPos += n
+	if l.lastPos > len(l.tokens) {
+		l.lastPos = len(l.tokens)
+	}
+	if n >= 1 {
+		// Invalidate the parser lookahead token.
+		l.parser.(*plpgsqlParserImpl).char = -1
+	}
+}
+
+func (l *lexer) lastToken() plpgsqlSymType {
+	if l.lastPos < 0 {
+		return plpgsqlSymType{}
+	}
+
+	if l.lastPos >= len(l.tokens) {
+		return plpgsqlSymType{
+			id:  0,
+			pos: int32(len(l.in)),
+			str: "EOF",
+		}
+	}
+	return l.tokens[l.lastPos]
+}
+
+// SetStmt is called from the parser when the statement is constructed.
+func (l *lexer) SetStmt(stmt plpgsqltree.Statement) {
+	l.stmt = stmt.(*plpgsqltree.Block)
+}
+
+// setErr is called from parsing action rules to register an error observed
+// while running the action. That error becomes the actual "cause" of the
+// syntax error.
+func (l *lexer) setErr(err error) {
+	err = pgerror.WithCandidateCode(err, pgcode.Syntax)
+	l.lastError = err
+	lastTok := l.lastToken()
+	l.lastError = parser.PopulateErrorDetails(lastTok.id, lastTok.str, lastTok.pos, l.lastError, l.in)
+}
+
+// setErrNoDetails is similar to setErr, but is used for an error that should
+// not be further annotated with details. If there is no candidate code for the
+// error, it is annotated with pgcode.Syntax.
+func (l *lexer) setErrNoDetails(err error) {
+	if !pgerror.HasCandidateCode(err) {
+		err = pgerror.WithCandidateCode(err, pgcode.Syntax)
+	}
+	l.lastError = err
+}
+
+func (l *lexer) Error(e string) {
+	e = strings.TrimPrefix(e, "syntax error: ") // we'll add it again below.
+	err := pgerror.WithCandidateCode(errors.Newf("%s", e), pgcode.Syntax)
+	lastTok := l.lastToken()
+	l.lastError = parser.PopulateErrorDetails(lastTok.id, lastTok.str, lastTok.pos, err, l.in)
+}
+
+// Unimplemented wraps Error, setting lastUnimplementedError.
+func (l *lexer) Unimplemented(feature string) {
+	l.lastError = unimp.New(feature, "this syntax")
+	lastTok := l.lastToken()
+	l.lastError = parser.PopulateErrorDetails(lastTok.id, lastTok.str, lastTok.pos, l.lastError, l.in)
+	l.lastError = &tree.UnsupportedError{
+		Err:         l.lastError,
+		FeatureName: feature,
+	}
+}
+
+func (l *lexer) ParseExpr(sqlStr string) (plpgsqltree.Expr, error) {
+	// Use ParseExprs instead of ParseExpr in order to correctly handle the case
+	// when multiple expressions are incorrectly passed.
+	exprs, err := parser.ParseExprs([]string{sqlStr})
+	if err != nil {
+		return nil, err
+	}
+	if len(exprs) != 1 {
+		return nil, pgerror.Newf(pgcode.Syntax, "query returned %d columns", len(exprs))
+	}
+	return exprs[0], nil
+}
+
+// ReadTarget reads a comma-separated list of target variables from the current
+// position.
+func (l *lexer) ReadTarget() ([]plpgsqltree.Variable, error) {
+	startPos, endPos := l.lastPos+1, len(l.tokens)
+	target, targetEnd, err := l.readTarget(startPos, endPos)
+	l.lastPos = targetEnd - 1
+	return target, err
+}
+
+// readTarget reads a comma-separated list of target variables from the given
+// start position to the given end position. It returns the target list and its
+// end position.
+func (l *lexer) readTarget(
+	pos, endPos int,
+) (target []plpgsqltree.Variable, targetEnd int, err error) {
+	for ; pos < endPos; pos += 2 {
+		tok := l.tokens[pos]
+		if tok.id != IDENT {
+			return nil, 0, errors.Newf("\"%s\" is not a scalar variable", tok.str)
+		}
+		variable := plpgsqltree.Variable(strings.TrimSpace(l.getStr(pos, pos+1)))
+		target = append(target, variable)
+		if pos+1 == endPos || l.tokens[pos+1].id != ',' {
+			// This is the end of the target list.
+			break
+		}
+	}
+	return target, pos + 1, nil
+}
+
+func checkLoopLabels(start, end string) error {
+	if start == "" && end != "" {
+		return errors.Newf("end label \"%s\" specified for unlabeled block", end)
+	}
+	if end != "" && start != end {
+		return errors.Newf("end label \"%s\" differs from block's label \"%s\"", end, start)
+	}
+	return nil
+}
diff --git a/pkg/sql/plpgsql/parser/parse.go b/pkg/sql/plpgsql/parser/parse.go
new file mode 100644
index 0000000..ba1d7c1
--- /dev/null
+++ b/pkg/sql/plpgsql/parser/parse.go
@@ -0,0 +1,139 @@
+// Copyright 2023 The Cockroach Authors.
+//
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
+
+// Package parser exposes a parser for plpgsql.
+package parser
+
+import (
+	"go/constant"
+
+	"github.com/cockroachdb/cockroachdb-parser/pkg/sql/parser"
+	"github.com/cockroachdb/cockroachdb-parser/pkg/sql/parser/statements"
+	"github.com/cockroachdb/cockroachdb-parser/pkg/sql/scanner"
+	"github.com/cockroachdb/cockroachdb-parser/pkg/sql/sem/tree"
+	"github.com/cockroachdb/cockroachdb-parser/pkg/sql/types"
+	"github.com/cockroachdb/errors"
+)
+
+func init() {
+	scanner.NewNumValFn = func(a constant.Value, s string, b bool) interface{} { return tree.NewNumVal(a, s, b) }
+	scanner.NewPlaceholderFn = func(s string) (interface{}, error) { return tree.NewPlaceholder(s) }
+	parser.ParseDoBlockFn = func(options tree.DoBlockOptions) (tree.DoBlockBody, error) {
+		doBlockBody, err := makeDoStmt(options)
+		if err != nil {
+			return nil, err
+		}
+		return doBlockBody, nil
+	}
+}
+
+// Parser wraps a scanner, parser and other utilities present in the parser
+// package.
+type Parser struct {
+	scanner    scanner.PLpgSQLScanner
+	lexer      lexer
+	parserImpl plpgsqlParserImpl
+	tokBuf     [8]plpgsqlSymType
+}
+
+// INT8 is the historical interpretation of INT. This should be left
+// alone in the future, since there are many sql fragments stored
+// in various descriptors. Any user input that was created after
+// INT := INT4 will simply use INT4 in any resulting code.
+var defaultNakedIntType = types.Int
+
+// Parse parses the sql and returns a list of statements.
+func (p *Parser) Parse(sql string) (statements.PLpgStatement, error) {
+	return p.parseWithDepth(1, sql, defaultNakedIntType)
+}
+
+func (p *Parser) scanFnBlock() (sql string, tokens []plpgsqlSymType, done bool) {
+	var lval plpgsqlSymType
+	tokens = p.tokBuf[:0]
+
+	// Scan the first token.
+	p.scanner.Scan(&lval)
+	if lval.id == 0 {
+		return "", nil, true
+	}
+
+	startPos := lval.pos
+	// We make the resulting token positions match the returned string.
+	lval.pos = 0
+	tokens = append(tokens, lval)
+	for {
+		if lval.id == ERROR {
+			return p.scanner.In()[startPos:], tokens, true
+		}
+		// Reset the plpgsqlSymType struct before scanning.
+		lval = plpgsqlSymType{}
+		posBeforeScan := p.scanner.Pos()
+		p.scanner.Scan(&lval)
+		if lval.id == 0 {
+			return p.scanner.In()[startPos:posBeforeScan], tokens, (lval.id == 0)
+		}
+		lval.pos -= startPos
+		tokens = append(tokens, lval)
+	}
+}
+
+func (p *Parser) parseWithDepth(
+	depth int, plpgsql string, nakedIntType *types.T,
+) (statements.PLpgStatement, error) {
+	p.scanner.Init(plpgsql)
+	defer p.scanner.Cleanup()
+	sql, tokens, done := p.scanFnBlock()
+	stmt, err := p.parse(depth+1, sql, tokens, nakedIntType)
+	if err != nil {
+		return statements.PLpgStatement{}, err
+	}
+	if !done {
+		return statements.PLpgStatement{}, errors.AssertionFailedf("invalid plpgsql function: %s", plpgsql)
+	}
+	return stmt, nil
+}
+
+// parse parses a statement from the given scanned tokens.
+func (p *Parser) parse(
+	depth int, sql string, tokens []plpgsqlSymType, nakedIntType *types.T,
+) (statements.PLpgStatement, error) {
+	p.lexer.init(sql, tokens, nakedIntType, &p.parserImpl)
+	defer p.lexer.cleanup()
+	if p.parserImpl.Parse(&p.lexer) != 0 {
+		if p.lexer.lastError == nil {
+			// This should never happen -- there should be an error object
+			// every time Parse() returns nonzero. We're just playing safe
+			// here.
+			p.lexer.Error("syntax error")
+		}
+		err := p.lexer.lastError
+
+		// Compatibility with 19.1 telemetry: prefix the telemetry keys
+		// with the "syntax." prefix.
+		// TODO(knz): move the auto-prefixing of feature names to a
+		// higher level in the call stack.
+		tkeys := errors.GetTelemetryKeys(err)
+		if len(tkeys) > 0 {
+			for i := range tkeys {
+				tkeys[i] = "syntax." + tkeys[i]
+			}
+			err = errors.WithTelemetry(err, tkeys...)
+		}
+
+		return statements.PLpgStatement{}, err
+	}
+	return statements.PLpgStatement{
+		AST:             p.lexer.stmt,
+		SQL:             sql,
+		NumPlaceholders: p.lexer.numPlaceholders,
+		NumAnnotations:  p.lexer.numAnnotations,
+	}, nil
+}
+
+// Parse parses a sql statement string and returns a list of Statements.
+func Parse(sql string) (statements.PLpgStatement, error) {
+	var p Parser
+	return p.parseWithDepth(1, sql, defaultNakedIntType)
+}
diff --git a/pkg/sql/plpgsql/parser/plpgsql.go b/pkg/sql/plpgsql/parser/plpgsql.go
new file mode 100644
index 0000000..85f2ca2
--- /dev/null
+++ b/pkg/sql/plpgsql/parser/plpgsql.go
@@ -0,0 +1,2592 @@
+// Code generated by goyacc -p plpgsql -o bazel-out/darwin_arm64-fastbuild/bin/pkg/sql/plpgsql/parser/plpgsql.go plpgsql-gen.y. DO NOT EDIT.
+
+//line plpgsql-gen.y:2
+package parser
+
+import __yyfmt__ "fmt"
+
+//line plpgsql-gen.y:2
+
+import (
+	"strings"
+
+	"github.com/cockroachdb/cockroachdb-parser/pkg/build"
+	"github.com/cockroachdb/cockroachdb-parser/pkg/sql/parser"
+	"github.com/cockroachdb/cockroachdb-parser/pkg/sql/parser/statements"
+	"github.com/cockroachdb/cockroachdb-parser/pkg/sql/scanner"
+	"github.com/cockroachdb/cockroachdb-parser/pkg/sql/sem/plpgsqltree"
+	"github.com/cockroachdb/cockroachdb-parser/pkg/sql/sem/tree"
+	"github.com/cockroachdb/cockroachdb-parser/pkg/sql/types"
+	"github.com/cockroachdb/errors"
+	"github.com/cockroachdb/redact"
+)
+
+//line plpgsql-gen.y:20
+func setErr(plpgsqllex plpgsqlLexer, err error) int {
+	plpgsqllex.(*lexer).setErr(err)
+	return 1
+}
+
+func setErrNoDetails(plpgsqllex plpgsqlLexer, err error) int {
+	plpgsqllex.(*lexer).setErrNoDetails(err)
+	return 1
+}
+
+func unimplemented(plpgsqllex plpgsqlLexer, feature string) int {
+	plpgsqllex.(*lexer).Unimplemented(feature)
+	return 1
+}
+
+var _ scanner.ScanSymType = &plpgsqlSymType{}
+
+func (s *plpgsqlSymType) ID() int32 {
+	return s.id
+}
+
+func (s *plpgsqlSymType) SetID(id int32) {
+	s.id = id
+}
+
+func (s *plpgsqlSymType) Pos() int32 {
+	return s.pos
+}
+
+func (s *plpgsqlSymType) SetPos(pos int32) {
+	s.pos = pos
+}
+
+func (s *plpgsqlSymType) Str() string {
+	return s.str
+}
+
+func (s *plpgsqlSymType) SetStr(str string) {
+	s.str = str
+}
+
+func (s *plpgsqlSymType) UnionVal() interface{} {
+	return s.union.val
+}
+
+func (s *plpgsqlSymType) SetUnionVal(val interface{}) {
+	s.union.val = val
+}
+
+func (s *plpgsqlSymType) plpgsqlScanSymType() {}
+
+type plpgsqlSymUnion struct {
+	val interface{}
+}
+
+func (u *plpgsqlSymUnion) block() *plpgsqltree.Block {
+	return u.val.(*plpgsqltree.Block)
+}
+
+func (u *plpgsqlSymUnion) caseWhen() *plpgsqltree.CaseWhen {
+	return u.val.(*plpgsqltree.CaseWhen)
+}
+
+func (u *plpgsqlSymUnion) caseWhens() []*plpgsqltree.CaseWhen {
+	return u.val.([]*plpgsqltree.CaseWhen)
+}
+
+func (u *plpgsqlSymUnion) statement() plpgsqltree.Statement {
+	return u.val.(plpgsqltree.Statement)
+}
+
+func (u *plpgsqlSymUnion) statements() []plpgsqltree.Statement {
+	return u.val.([]plpgsqltree.Statement)
+}
+
+func (u *plpgsqlSymUnion) int32() int32 {
+	return u.val.(int32)
+}
+
+func (u *plpgsqlSymUnion) uint32() uint32 {
+	return u.val.(uint32)
+}
+
+func (u *plpgsqlSymUnion) bool() bool {
+	return u.val.(bool)
+}
+
+func (u *plpgsqlSymUnion) numVal() *tree.NumVal {
+	return u.val.(*tree.NumVal)
+}
+
+func (u *plpgsqlSymUnion) typ() tree.ResolvableTypeReference {
+	return u.val.(tree.ResolvableTypeReference)
+}
+
+func (u *plpgsqlSymUnion) getDiagnosticsKind() plpgsqltree.GetDiagnosticsKind {
+	return u.val.(plpgsqltree.GetDiagnosticsKind)
+}
+
+func (u *plpgsqlSymUnion) getDiagnosticsItem() *plpgsqltree.GetDiagnosticsItem {
+	return u.val.(*plpgsqltree.GetDiagnosticsItem)
+}
+
+func (u *plpgsqlSymUnion) getDiagnosticsItemList() plpgsqltree.GetDiagnosticsItemList {
+	return u.val.(plpgsqltree.GetDiagnosticsItemList)
+}
+
+func (u *plpgsqlSymUnion) elseIf() []plpgsqltree.ElseIf {
+	return u.val.([]plpgsqltree.ElseIf)
+}
+
+func (u *plpgsqlSymUnion) open() *plpgsqltree.Open {
+	return u.val.(*plpgsqltree.Open)
+}
+
+func (u *plpgsqlSymUnion) expr() plpgsqltree.Expr {
+	if u.val == nil {
+		return nil
+	}
+	return u.val.(plpgsqltree.Expr)
+}
+
+func (u *plpgsqlSymUnion) exprs() []plpgsqltree.Expr {
+	return u.val.([]plpgsqltree.Expr)
+}
+
+func (u *plpgsqlSymUnion) raiseOption() *plpgsqltree.RaiseOption {
+	return u.val.(*plpgsqltree.RaiseOption)
+}
+
+func (u *plpgsqlSymUnion) raiseOptions() []plpgsqltree.RaiseOption {
+	return u.val.([]plpgsqltree.RaiseOption)
+}
+
+func (u *plpgsqlSymUnion) exception() *plpgsqltree.Exception {
+	return u.val.(*plpgsqltree.Exception)
+}
+
+func (u *plpgsqlSymUnion) exceptions() []plpgsqltree.Exception {
+	return u.val.([]plpgsqltree.Exception)
+}
+
+func (u *plpgsqlSymUnion) condition() *plpgsqltree.Condition {
+	return u.val.(*plpgsqltree.Condition)
+}
+
+func (u *plpgsqlSymUnion) conditions() []plpgsqltree.Condition {
+	return u.val.([]plpgsqltree.Condition)
+}
+
+func (u *plpgsqlSymUnion) cursorScrollOption() tree.CursorScrollOption {
+	return u.val.(tree.CursorScrollOption)
+}
+
+func (u *plpgsqlSymUnion) sqlStatement() tree.Statement {
+	return u.val.(statements.Statement[tree.Statement]).AST
+}
+
+func (u *plpgsqlSymUnion) numAnnotations() tree.AnnotationIdx {
+	return u.val.(statements.Statement[tree.Statement]).NumAnnotations
+}
+
+func (u *plpgsqlSymUnion) variables() []plpgsqltree.Variable {
+	return u.val.([]plpgsqltree.Variable)
+}
+
+func (u *plpgsqlSymUnion) forLoopControl() plpgsqltree.ForLoopControl {
+	return u.val.(plpgsqltree.ForLoopControl)
+}
+
+func (u *plpgsqlSymUnion) doBlockOptions() tree.DoBlockOptions {
+	return u.val.(tree.DoBlockOptions)
+}
+
+func (u *plpgsqlSymUnion) doBlockOption() tree.DoBlockOption {
+	return u.val.(tree.DoBlockOption)
+}
+
+//line plpgsql-gen.y:338
+type plpgsqlSymType struct {
+	yys   int
+	id    int32
+	pos   int32
+	str   string
+	union plpgsqlSymUnion
+}
+
+const IDENT = 57346
+const UIDENT = 57347
+const FCONST = 57348
+const SCONST = 57349
+const USCONST = 57350
+const BCONST = 57351
+const XCONST = 57352
+const Op = 57353
+const ICONST = 57354
+const PARAM = 57355
+const TYPECAST = 57356
+const DOT_DOT = 57357
+const COLON_EQUALS = 57358
+const EQUALS_GREATER = 57359
+const LESS_EQUALS = 57360
+const GREATER_EQUALS = 57361
+const NOT_EQUALS = 57362
+const LESS_LESS = 57363
+const GREATER_GREATER = 57364
+const ABSOLUTE = 57365
+const ALIAS = 57366
+const ALL = 57367
+const AND = 57368
+const ARRAY = 57369
+const ASSERT = 57370
+const BACKWARD = 57371
+const BEGIN = 57372
+const BY = 57373
+const CALL = 57374
+const CASE = 57375
+const CHAIN = 57376
+const CLOSE = 57377
+const COLLATE = 57378
+const COLUMN = 57379
+const COLUMN_NAME = 57380
+const COMMIT = 57381
+const CONSTANT = 57382
+const CONSTRAINT = 57383
+const CONSTRAINT_NAME = 57384
+const CONTINUE = 57385
+const CURRENT = 57386
+const CURSOR = 57387
+const DATATYPE = 57388
+const DEBUG = 57389
+const DECLARE = 57390
+const DEFAULT = 57391
+const DETAIL = 57392
+const DIAGNOSTICS = 57393
+const DO = 57394
+const DUMP = 57395
+const ELSE = 57396
+const ELSIF = 57397
+const END = 57398
+const END_CASE = 57399
+const END_IF = 57400
+const ERRCODE = 57401
+const ERROR = 57402
+const EXCEPTION = 57403
+const EXECUTE = 57404
+const EXIT = 57405
+const FETCH = 57406
+const FIRST = 57407
+const FOR = 57408
+const FOREACH = 57409
+const FORWARD = 57410
+const FROM = 57411
+const GET = 57412
+const HINT = 57413
+const IF = 57414
+const IMPORT = 57415
+const IN = 57416
+const INFO = 57417
+const INSERT = 57418
+const INTO = 57419
+const IS = 57420
+const LANGUAGE = 57421
+const LAST = 57422
+const LOG = 57423
+const LOOP = 57424
+const MERGE = 57425
+const MESSAGE = 57426
+const MESSAGE_TEXT = 57427
+const MOVE = 57428
+const NEXT = 57429
+const NO = 57430
+const NO_SCROLL = 57431
+const NOT = 57432
+const NOTICE = 57433
+const NULL = 57434
+const OPEN = 57435
+const OPTION = 57436
+const OR = 57437
+const PERFORM = 57438
+const PG_CONTEXT = 57439
+const PG_DATATYPE_NAME = 57440
+const PG_EXCEPTION_CONTEXT = 57441
+const PG_EXCEPTION_DETAIL = 57442
+const PG_EXCEPTION_HINT = 57443
+const PRINT_STRICT_PARAMS = 57444
+const PRIOR = 57445
+const QUERY = 57446
+const RAISE = 57447
+const RELATIVE = 57448
+const RETURN = 57449
+const RETURN_NEXT = 57450
+const RETURN_QUERY = 57451
+const RETURNED_SQLSTATE = 57452
+const REVERSE = 57453
+const ROLLBACK = 57454
+const ROW_COUNT = 57455
+const ROWTYPE = 57456
+const SCHEMA = 57457
+const SCHEMA_NAME = 57458
+const SCROLL = 57459
+const SLICE = 57460
+const SQLSTATE = 57461
+const STACKED = 57462
+const STRICT = 57463
+const TABLE = 57464
+const TABLE_NAME = 57465
+const THEN = 57466
+const TO = 57467
+const TYPE = 57468
+const UPSERT = 57469
+const USE_COLUMN = 57470
+const USE_VARIABLE = 57471
+const USING = 57472
+const VARIABLE_CONFLICT = 57473
+const WARNING = 57474
+const WHEN = 57475
+const WHILE = 57476
+
+var plpgsqlToknames = [...]string{
+	"$end",
+	"error",
+	"$unk",
+	"IDENT",
+	"UIDENT",
+	"FCONST",
+	"SCONST",
+	"USCONST",
+	"BCONST",
+	"XCONST",
+	"Op",
+	"ICONST",
+	"PARAM",
+	"TYPECAST",
+	"DOT_DOT",
+	"COLON_EQUALS",
+	"EQUALS_GREATER",
+	"LESS_EQUALS",
+	"GREATER_EQUALS",
+	"NOT_EQUALS",
+	"LESS_LESS",
+	"GREATER_GREATER",
+	"ABSOLUTE",
+	"ALIAS",
+	"ALL",
+	"AND",
+	"ARRAY",
+	"ASSERT",
+	"BACKWARD",
+	"BEGIN",
+	"BY",
+	"CALL",
+	"CASE",
+	"CHAIN",
+	"CLOSE",
+	"COLLATE",
+	"COLUMN",
+	"COLUMN_NAME",
+	"COMMIT",
+	"CONSTANT",
+	"CONSTRAINT",
+	"CONSTRAINT_NAME",
+	"CONTINUE",
+	"CURRENT",
+	"CURSOR",
+	"DATATYPE",
+	"DEBUG",
+	"DECLARE",
+	"DEFAULT",
+	"DETAIL",
+	"DIAGNOSTICS",
+	"DO",
+	"DUMP",
+	"ELSE",
+	"ELSIF",
+	"END",
+	"END_CASE",
+	"END_IF",
+	"ERRCODE",
+	"ERROR",
+	"EXCEPTION",
+	"EXECUTE",
+	"EXIT",
+	"FETCH",
+	"FIRST",
+	"FOR",
+	"FOREACH",
+	"FORWARD",
+	"FROM",
+	"GET",
+	"HINT",
+	"IF",
+	"IMPORT",
+	"IN",
+	"INFO",
+	"INSERT",
+	"INTO",
+	"IS",
+	"LANGUAGE",
+	"LAST",
+	"LOG",
+	"LOOP",
+	"MERGE",
+	"MESSAGE",
+	"MESSAGE_TEXT",
+	"MOVE",
+	"NEXT",
+	"NO",
+	"NO_SCROLL",
+	"NOT",
+	"NOTICE",
+	"NULL",
+	"OPEN",
+	"OPTION",
+	"OR",
+	"PERFORM",
+	"PG_CONTEXT",
+	"PG_DATATYPE_NAME",
+	"PG_EXCEPTION_CONTEXT",
+	"PG_EXCEPTION_DETAIL",
+	"PG_EXCEPTION_HINT",
+	"PRINT_STRICT_PARAMS",
+	"PRIOR",
+	"QUERY",
+	"RAISE",
+	"RELATIVE",
+	"RETURN",
+	"RETURN_NEXT",
+	"RETURN_QUERY",
+	"RETURNED_SQLSTATE",
+	"REVERSE",
+	"ROLLBACK",
+	"ROW_COUNT",
+	"ROWTYPE",
+	"SCHEMA",
+	"SCHEMA_NAME",
+	"SCROLL",
+	"SLICE",
+	"SQLSTATE",
+	"STACKED",
+	"STRICT",
+	"TABLE",
+	"TABLE_NAME",
+	"THEN",
+	"TO",
+	"TYPE",
+	"UPSERT",
+	"USE_COLUMN",
+	"USE_VARIABLE",
+	"USING",
+	"VARIABLE_CONFLICT",
+	"WARNING",
+	"WHEN",
+	"WHILE",
+	"';'",
+	"'('",
+	"','",
+	"'='",
+	"'.'",
+}
+
+var plpgsqlStatenames = [...]string{}
+
+const plpgsqlEofCode = 1
+const plpgsqlErrCode = 2
+const plpgsqlInitialStackSize = 16
+
+//line plpgsql-gen.y:1756
+
+//line yacctab:1
+var plpgsqlExca = [...]int16{
+	-1, 1,
+	1, -1,
+	-2, 0,
+	-1, 100,
+	30, 7,
+	-2, 10,
+	-1, 102,
+	45, 16,
+	-2, 31,
+	-1, 106,
+	30, 185,
+	48, 185,
+	56, 171,
+	-2, 187,
+	-1, 244,
+	30, 185,
+	48, 185,
+	-2, 187,
+	-1, 272,
+	30, 186,
+	48, 186,
+	-2, 188,
+	-1, 286,
+	30, 185,
+	48, 185,
+	54, 92,
+	55, 92,
+	58, 92,
+	-2, 187,
+	-1, 330,
+	30, 185,
+	48, 185,
+	56, 175,
+	133, 175,
+	-2, 187,
+	-1, 335,
+	30, 185,
+	48, 185,
+	57, 102,
+	-2, 187,
+	-1, 362,
+	30, 185,
+	48, 185,
+	54, 100,
+	57, 100,
+	133, 100,
+	-2, 187,
+	-1, 374,
+	30, 185,
+	48, 185,
+	58, 95,
+	-2, 187,
+	-1, 382,
+	30, 185,
+	48, 185,
+	54, 93,
+	55, 93,
+	58, 93,
+	-2, 187,
+}
+
+const plpgsqlPrivate = 57344
+
+const plpgsqlLast = 1237
+
+var plpgsqlAct = [...]int16{
+	244, 193, 11, 187, 318, 306, 243, 208, 302, 183,
+	305, 104, 300, 209, 234, 241, 111, 196, 194, 211,
+	247, 180, 220, 9, 144, 348, 186, 186, 301, 113,
+	201, 186, 350, 347, 351, 348, 212, 249, 230, 248,
+	381, 168, 380, 376, 206, 375, 191, 192, 154, 371,
+	366, 365, 158, 146, 357, 164, 356, 114, 203, 166,
+	326, 355, 189, 149, 202, 344, 341, 337, 297, 296,
+	284, 277, 159, 271, 204, 265, 292, 268, 267, 260,
+	259, 258, 156, 148, 162, 251, 219, 182, 6, 289,
+	160, 255, 145, 169, 254, 242, 170, 181, 303, 106,
+	379, 282, 336, 172, 177, 239, 163, 215, 213, 198,
+	104, 101, 165, 161, 190, 205, 157, 110, 199, 327,
+	274, 197, 269, 338, 293, 153, 212, 150, 151, 152,
+	281, 280, 167, 112, 294, 320, 378, 175, 353, 372,
+	334, 178, 264, 279, 360, 359, 323, 171, 185, 185,
+	108, 195, 8, 185, 184, 176, 361, 312, 225, 321,
+	98, 313, 221, 272, 261, 105, 314, 4, 242, 304,
+	309, 283, 319, 238, 218, 217, 270, 155, 228, 311,
+	231, 207, 113, 216, 118, 2, 278, 223, 229, 226,
+	222, 310, 107, 5, 1, 299, 298, 237, 213, 369,
+	235, 232, 317, 214, 308, 287, 256, 240, 233, 179,
+	114, 115, 100, 99, 7, 252, 250, 257, 253, 173,
+	125, 121, 143, 142, 141, 140, 139, 138, 276, 137,
+	262, 136, 263, 135, 266, 316, 134, 133, 124, 132,
+	286, 131, 315, 130, 129, 291, 290, 128, 285, 127,
+	126, 123, 122, 120, 119, 116, 288, 358, 333, 210,
+	307, 200, 147, 295, 3, 340, 246, 188, 245, 224,
+	174, 328, 322, 273, 109, 324, 102, 0, 0, 0,
+	0, 0, 330, 325, 0, 0, 329, 0, 0, 0,
+	335, 0, 0, 0, 0, 0, 0, 331, 0, 332,
+	339, 235, 0, 0, 0, 0, 0, 342, 0, 0,
+	0, 0, 343, 346, 345, 0, 0, 349, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 354, 352,
+	0, 0, 0, 0, 0, 0, 0, 362, 0, 0,
+	0, 363, 0, 0, 0, 0, 0, 364, 0, 0,
+	0, 10, 0, 0, 367, 370, 368, 0, 0, 0,
+	0, 374, 0, 373, 0, 0, 377, 0, 0, 0,
+	12, 13, 0, 14, 15, 16, 17, 0, 0, 18,
+	382, 19, 20, 21, 22, 23, 24, 25, 26, 27,
+	28, 29, 30, 31, 32, 0, 33, 34, 35, 36,
+	37, 0, 38, 0, 0, 0, 39, 40, 41, 0,
+	42, 43, 44, 0, 0, 45, 0, 46, 47, 0,
+	48, 0, 49, 50, 0, 51, 52, 53, 54, 0,
+	55, 56, 57, 58, 59, 60, 61, 0, 62, 0,
+	63, 64, 0, 65, 66, 67, 68, 69, 70, 71,
+	72, 73, 74, 75, 76, 77, 78, 79, 80, 81,
+	82, 83, 84, 85, 86, 87, 88, 89, 10, 90,
+	91, 0, 0, 92, 93, 94, 95, 0, 96, 97,
+	0, 0, 0, 0, 0, 0, 0, 12, 13, 0,
+	14, 15, 16, 17, 0, 0, 18, 0, 19, 20,
+	21, 22, 23, 24, 25, 26, 27, 28, 29, 30,
+	31, 32, 0, 33, 34, 35, 36, 37, 0, 38,
+	0, 0, 0, 39, 40, 41, 0, 42, 43, 44,
+	0, 0, 45, 0, 46, 47, 0, 48, 0, 49,
+	50, 0, 51, 52, 53, 54, 0, 55, 56, 57,
+	58, 59, 60, 61, 0, 62, 0, 63, 64, 0,
+	65, 66, 67, 68, 69, 70, 71, 72, 73, 74,
+	75, 76, 77, 78, 79, 80, 81, 82, 83, 84,
+	85, 86, 87, 236, 89, 275, 90, 91, 0, 0,
+	92, 93, 94, 95, 0, 96, 97, 0, 0, 0,
+	0, 0, 0, 0, 12, 13, 0, 14, 15, 16,
+	17, 0, 0, 18, 0, 19, 20, 21, 22, 23,
+	24, 25, 26, 27, 28, 29, 30, 31, 32, 0,
+	33, 34, 35, 36, 37, 0, 38, 0, 0, 0,
+	39, 40, 41, 0, 42, 43, 44, 0, 0, 45,
+	0, 46, 47, 0, 48, 0, 49, 50, 0, 51,
+	52, 53, 54, 0, 55, 56, 57, 58, 59, 60,
+	61, 0, 62, 0, 63, 64, 0, 65, 66, 67,
+	68, 69, 70, 71, 72, 73, 74, 75, 76, 77,
+	78, 79, 80, 81, 82, 83, 84, 85, 86, 87,
+	88, 89, 227, 90, 91, 0, 0, 92, 93, 94,
+	95, 0, 96, 97, 0, 0, 0, 0, 0, 0,
+	0, 12, 13, 0, 14, 15, 16, 17, 0, 0,
+	18, 0, 19, 20, 21, 22, 23, 24, 25, 26,
+	27, 28, 29, 30, 31, 32, 0, 33, 34, 35,
+	36, 37, 0, 38, 0, 0, 0, 39, 40, 41,
+	0, 42, 43, 44, 0, 0, 45, 0, 46, 47,
+	0, 48, 0, 49, 50, 0, 51, 52, 53, 54,
+	0, 55, 56, 57, 58, 59, 60, 61, 0, 62,
+	0, 63, 64, 0, 65, 66, 67, 68, 69, 70,
+	71, 72, 73, 74, 75, 76, 77, 78, 79, 80,
+	81, 82, 83, 84, 85, 86, 87, 88, 89, 103,
+	90, 91, 0, 0, 92, 93, 94, 95, 0, 96,
+	97, 0, 0, 0, 0, 0, 0, 0, 12, 13,
+	0, 14, 15, 16, 17, 0, 0, 18, 0, 19,
+	20, 21, 22, 23, 24, 25, 26, 27, 28, 29,
+	30, 31, 32, 0, 33, 34, 35, 36, 37, 0,
+	38, 0, 0, 0, 39, 40, 41, 0, 42, 43,
+	44, 0, 0, 45, 0, 46, 47, 0, 48, 0,
+	49, 50, 0, 51, 52, 53, 54, 0, 55, 56,
+	57, 58, 59, 60, 61, 0, 62, 0, 63, 64,
+	0, 65, 66, 67, 68, 69, 70, 71, 72, 73,
+	74, 75, 76, 77, 78, 79, 80, 81, 82, 83,
+	84, 85, 86, 87, 88, 89, 0, 90, 91, 0,
+	0, 92, 93, 94, 95, 0, 96, 97, 12, 13,
+	0, 14, 15, 16, 17, 0, 0, 18, 0, 19,
+	20, 21, 22, 23, 24, 25, 26, 27, 28, 29,
+	30, 31, 32, 0, 33, 34, 35, 36, 37, 0,
+	38, 0, 0, 0, 39, 40, 41, 0, 42, 43,
+	44, 0, 0, 45, 0, 46, 47, 0, 48, 0,
+	49, 50, 0, 51, 52, 53, 54, 0, 55, 56,
+	57, 58, 59, 60, 61, 0, 62, 0, 63, 64,
+	0, 65, 66, 67, 68, 69, 70, 71, 72, 73,
+	74, 75, 76, 77, 78, 79, 80, 81, 82, 83,
+	84, 85, 86, 87, 88, 89, 144, 90, 91, 0,
+	0, 92, 93, 94, 95, 0, 96, 97, 0, 0,
+	0, 0, 0, 168, 0, 0, 0, 0, 0, 0,
+	154, 0, 0, 0, 158, 146, 0, 164, 0, 0,
+	0, 166, 0, 0, 0, 149, 0, 0, 0, 0,
+	0, 0, 0, 0, 159, 0, 0, 0, 0, 0,
+	0, 0, 0, 117, 156, 148, 162, 0, 0, 0,
+	0, 0, 160, 144, 145, 169, 0, 0, 170, 0,
+	0, 0, 0, 0, 0, 172, 0, 0, 163, 0,
+	168, 0, 0, 0, 165, 161, 0, 154, 157, 0,
+	0, 158, 146, 0, 164, 0, 0, 153, 166, 150,
+	151, 152, 149, 0, 167, 0, 0, 0, 0, 0,
+	0, 159, 0, 0, 0, 0, 0, 0, 0, 171,
+	0, 156, 148, 162, 0, 0, 0, 0, 0, 160,
+	0, 145, 169, 0, 0, 170, 0, 0, 0, 0,
+	0, 0, 172, 0, 0, 163, 0, 0, 0, 0,
+	0, 165, 161, 0, 0, 157, 0, 0, 0, 0,
+	0, 0, 0, 0, 153, 0, 150, 151, 152, 0,
+	0, 167, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 171,
+}
+
+var plpgsqlPact = [...]int16{
+	146, -1000, -47, 104, 347, -1000, -1000, 130, 815, 143,
+	-1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000,
+	-1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000,
+	-1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000,
+	-1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000,
+	-1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000,
+	-1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000,
+	-1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000,
+	-1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000,
+	-1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000,
+	102, -1000, 93, -1000, -1000, -1000, 1042, 815, -1000, -1000,
+	71, 110, -1000, -13, -1000, 85, -1000, -36, -48, -1000,
+	-1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000,
+	-1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000,
+	-1000, -1000, -1000, -1000, 15, -1000, -1000, -20, 347, 347,
+	-1000, 34, 5, -17, -1000, -1000, -1000, -1000, -1000, 119,
+	63, 171, -1000, -1000, 170, -49, 136, 136, 347, -1000,
+	-1000, -1000, -1000, -1000, 122, 698, -98, -1000, 347, -36,
+	-1000, 464, -1000, -1000, 169, -1000, -1000, -19, -38, -1000,
+	-1000, -1000, -1000, -96, -1000, -96, -50, -1000, -1000, -1000,
+	87, -1000, -1000, -1000, -1000, -1000, -1000, -54, -55, -56,
+	29, -1000, -1000, 347, 91, -1000, -1000, -60, -57, -1000,
+	-58, 88, -62, 141, 30, 581, -64, -1000, -1000, 65,
+	-1000, -1000, -1000, 6, -1000, -1000, 164, -65, 10, -1000,
+	35, -1000, -1000, 347, 20, 42, 60, -1000, -1000, -1000,
+	-1000, -1000, -66, -67, -109, -32, 162, 120, -1000, -1000,
+	-1000, -1000, -1000, -1000, 168, -1000, 69, -1000, -1000, -1000,
+	125, -1000, -1000, 11, 27, -1000, -1000, -1000, -1000, -1000,
+	-1000, -1000, 464, -1000, -1000, -1000, 1109, 83, -1000, -1000,
+	-22, -68, 41, -1000, -1000, -69, -1000, -1000, -32, -109,
+	-1000, -1000, -70, 120, -32, -102, -1000, 10, -1000, -1000,
+	-1000, -1000, -1000, -1000, -1000, -1000, -1000, -103, -1000, 10,
+	76, -1000, -1000, -1000, -74, -1000, -1000, -1000, -1000, -79,
+	1109, -1000, -81, 90, 123, 1109, -1000, -1000, -1000, 347,
+	-1000, -1000, -84, -1000, -1000, -112, -85, -1000, 120, -1000,
+	-1000, 168, 925, -1000, -86, -1000, -1000, -1000, 81, -1000,
+	-1000, -90, 1109, -92, 347, -1000, -1000, -1000, -1000, -1000,
+	-1000, -1000, 64, -24, 1109, -1000, -1000, -93, -95, -1000,
+	-1000, -1000, 1109,
+}
+
+var plpgsqlPgo = [...]int16{
+	0, 276, 275, 274, 273, 272, 271, 270, 269, 13,
+	269, 7, 3, 268, 267, 17, 20, 266, 266, 265,
+	18, 264, 262, 1, 261, 260, 259, 19, 0, 258,
+	257, 6, 184, 255, 254, 253, 252, 251, 250, 249,
+	247, 244, 243, 241, 239, 238, 237, 236, 233, 231,
+	229, 227, 226, 225, 224, 223, 222, 221, 220, 218,
+	111, 214, 213, 212, 211, 209, 21, 208, 14, 15,
+	207, 205, 203, 202, 4, 199, 5, 10, 8, 12,
+	196, 195, 16, 22, 2, 194, 193, 192, 189, 188,
+	186, 186, 186, 9, 186, 181, 177, 177,
+}
+
+var plpgsqlR1 = [...]int8{
+	0, 85, 86, 86, 32, 61, 61, 62, 62, 87,
+	87, 63, 63, 60, 60, 60, 82, 82, 82, 6,
+	89, 89, 91, 91, 92, 90, 90, 88, 88, 1,
+	1, 3, 3, 7, 8, 8, 8, 4, 4, 5,
+	5, 2, 2, 93, 93, 28, 28, 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, 46, 47, 48, 26, 26, 27, 27,
+	34, 34, 49, 72, 72, 72, 73, 73, 74, 75,
+	94, 35, 29, 29, 30, 30, 57, 14, 70, 70,
+	69, 71, 71, 36, 37, 45, 19, 17, 58, 18,
+	18, 38, 39, 40, 40, 40, 15, 59, 41, 41,
+	41, 41, 41, 24, 24, 24, 24, 24, 24, 24,
+	78, 78, 77, 77, 76, 25, 25, 25, 25, 25,
+	25, 25, 25, 25, 80, 80, 81, 81, 79, 42,
+	95, 31, 43, 96, 96, 96, 96, 96, 44, 50,
+	50, 50, 51, 52, 53, 54, 55, 56, 83, 83,
+	83, 64, 64, 65, 65, 66, 67, 67, 68, 68,
+	9, 11, 12, 13, 10, 21, 21, 22, 22, 23,
+	23, 16, 16, 20, 20, 84, 84, 84, 84, 84,
+	84, 84, 84, 84, 84, 84, 84, 84, 84, 84,
+	84, 84, 84, 84, 84, 84, 84, 84, 84, 84,
+	84, 84, 84, 84, 84, 84, 84, 84, 84, 84,
+	84, 84, 84, 84, 84, 84, 84, 84, 84, 84,
+	84, 84, 84, 84, 84, 84, 84, 84, 84, 84,
+	84, 84, 84, 84, 84, 84, 84, 84, 84, 84,
+	84, 84, 84, 84, 84, 84, 84, 84, 84, 84,
+	84, 84, 84, 84, 84, 84, 84, 84, 84, 84,
+	84, 97, 97, 97, 97, 97, 97, 97, 97, 97,
+	97, 97, 97, 97, 97, 97, 97, 97, 97, 97,
+	97, 97, 97, 97, 97, 97, 97,
+}
+
+var plpgsqlR2 = [...]int8{
+	0, 2, 0, 1, 7, 2, 0, 1, 0, 1,
+	0, 3, 1, 6, 5, 6, 0, 2, 1, 2,
+	1, 0, 1, 3, 2, 1, 1, 1, 1, 1,
+	1, 0, 1, 0, 0, 2, 2, 0, 2, 1,
+	2, 1, 1, 1, 1, 0, 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, 3, 3, 3, 1, 2, 1, 2,
+	4, 6, 5, 0, 1, 1, 3, 1, 3, 1,
+	1, 9, 0, 5, 0, 2, 7, 0, 2, 1,
+	4, 0, 2, 5, 7, 8, 0, 0, 2, 0,
+	2, 3, 3, 3, 4, 4, 0, 0, 2, 6,
+	5, 6, 5, 1, 1, 1, 1, 1, 1, 0,
+	2, 0, 3, 1, 2, 1, 1, 1, 1, 1,
+	1, 1, 1, 1, 1, 0, 1, 2, 1, 3,
+	0, 3, 1, 1, 1, 1, 1, 1, 1, 3,
+	5, 6, 1, 1, 3, 2, 3, 3, 2, 3,
+	0, 0, 2, 2, 1, 4, 3, 1, 1, 2,
+	0, 0, 0, 0, 0, 0, 3, 0, 3, 0,
+	1, 1, 3, 1, 1, 1, 1, 1, 1, 1,
+	1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+	1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+	1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+	1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+	1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+	1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+	1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+	1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+	1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+	1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+	1, 1, 1, 1, 1, 1, 1,
+}
+
+var plpgsqlChk = [...]int16{
+	-1000, -85, -32, -21, 21, -86, 135, -61, 48, -20,
+	4, -84, 23, 24, 26, 27, 28, 29, 32, 34,
+	35, 36, 37, 38, 39, 40, 41, 42, 43, 44,
+	45, 46, 47, 49, 50, 51, 52, 53, 55, 59,
+	60, 61, 63, 64, 65, 68, 70, 71, 73, 75,
+	76, 78, 79, 80, 81, 83, 84, 85, 86, 87,
+	88, 89, 91, 93, 94, 96, 97, 98, 99, 100,
+	101, 102, 103, 104, 105, 106, 107, 108, 109, 110,
+	111, 112, 113, 114, 115, 116, 117, 118, 119, 120,
+	122, 123, 126, 127, 128, 129, 131, 132, 30, -62,
+	-63, -60, -1, 4, -84, 22, -28, -87, 48, -3,
+	24, -82, 40, 89, 117, -64, -33, 61, -32, -34,
+	-35, -57, -36, -37, -45, -58, -38, -39, -40, -41,
+	-42, -43, -44, -46, -47, -48, -49, -50, -51, -52,
+	-53, -54, -55, -56, 4, 72, 33, -22, 63, 43,
+	107, 108, 109, 105, 28, -96, 62, 96, 32, 52,
+	70, 93, 64, 86, 35, 92, 39, 112, 21, 73,
+	76, 127, 83, -60, -7, 66, 45, 117, 56, -65,
+	-66, 133, 135, -93, 139, 138, 16, -12, -14, 82,
+	134, 66, 67, -23, -20, -23, -15, 87, 104, 135,
+	-24, 47, 81, 75, 91, 132, 61, -95, -11, -9,
+	-26, -27, 7, 79, -72, 44, 120, 4, 4, 135,
+	-83, 26, -83, -20, -8, 36, -88, 4, -84, -89,
+	136, -23, -66, -67, -68, -20, 119, -9, 4, 124,
+	-70, -69, 133, -31, -28, -13, -17, -16, 135, 133,
+	-16, 135, -15, -59, 7, 4, 119, 130, 135, 135,
+	135, 135, -27, -20, 51, 135, -82, 135, 135, 34,
+	88, 135, 22, -4, 90, 4, -84, 135, -90, 78,
+	66, 124, 95, 7, 135, -93, -28, -71, -69, 54,
+	-12, -23, 56, 82, 74, -9, 135, 135, -80, -81,
+	-79, 137, -78, 130, 7, -77, -76, -25, 84, 50,
+	71, 59, 37, 41, 46, 122, 115, -73, -74, 4,
+	66, 34, -5, 135, -2, -93, 49, 92, -6, -11,
+	-28, -68, -9, -29, 57, -28, 124, 135, 82, -31,
+	-19, 135, -78, -79, 135, -77, -78, 135, 137, -93,
+	135, 137, -93, 62, -11, 135, 135, 135, -30, 55,
+	54, 33, -28, -23, -31, 135, 135, -76, -74, -75,
+	-84, 135, 58, -12, -28, 135, 135, -23, 72, 124,
+	135, 135, -28,
+}
+
+var plpgsqlDef = [...]int16{
+	185, -2, 2, 6, 0, 1, 3, 0, 8, 0,
+	193, 194, 195, 196, 197, 198, 199, 200, 201, 202,
+	203, 204, 205, 206, 207, 208, 209, 210, 211, 212,
+	213, 214, 215, 216, 217, 218, 219, 220, 221, 222,
+	223, 224, 225, 226, 227, 228, 229, 230, 231, 232,
+	233, 234, 235, 236, 237, 238, 239, 240, 241, 242,
+	243, 244, 245, 246, 247, 248, 249, 250, 251, 252,
+	253, 254, 255, 256, 257, 258, 259, 260, 261, 262,
+	263, 264, 265, 266, 267, 268, 269, 270, 271, 272,
+	273, 274, 275, 276, 277, 278, 279, 280, 45, 5,
+	-2, 12, -2, 29, 30, 186, -2, 0, 9, 33,
+	0, 0, 32, 0, 18, 0, 46, 0, 0, 48,
+	49, 50, 51, 52, 53, 54, 55, 56, 57, 58,
+	59, 60, 61, 62, 63, 64, 65, 66, 67, 68,
+	69, 70, 71, 72, 157, 182, 97, 0, 189, 189,
+	116, 0, 0, 129, 150, 152, 158, 181, 180, 0,
+	83, 0, 162, 163, 0, 0, 170, 170, 0, 153,
+	154, 155, 156, 11, 34, 0, 21, 17, 189, 172,
+	174, 0, 47, 180, 0, 43, 44, 0, 0, 45,
+	183, 107, 108, 0, 190, 0, 0, 116, 117, 118,
+	0, 123, 124, 125, 126, 127, 128, 0, 0, 0,
+	0, 76, 78, 0, 0, 84, 85, 16, 0, 165,
+	0, 0, 0, 0, 37, 0, 0, 27, 28, 0,
+	20, 4, 173, 0, 177, 178, 271, 0, 0, 45,
+	101, 99, 182, 189, -2, 0, 0, 111, 191, 180,
+	112, 113, 0, 0, 145, 131, 0, 0, 149, 73,
+	74, 75, 77, 79, 0, 159, 0, 164, 166, 168,
+	0, 167, -2, 0, 0, 35, 36, 14, 181, 25,
+	26, 45, 0, 179, 80, 180, -2, 0, 98, 45,
+	0, 0, 0, 45, 106, 0, 114, 115, 131, 144,
+	146, 148, 0, 0, 131, 0, 133, 0, 135, 136,
+	137, 138, 139, 140, 141, 142, 143, 0, 87, 0,
+	181, 169, 13, 39, 0, 41, 42, 38, 15, 0,
+	-2, 176, 0, 94, 0, -2, 45, 103, 151, 189,
+	45, 192, 0, 147, 120, 130, 0, 122, 0, 134,
+	82, 0, 0, 160, 0, 40, 19, 81, 0, 182,
+	45, 0, -2, 0, 189, 119, 121, 132, 86, 88,
+	89, 161, 0, 0, -2, 96, 104, 0, 0, 45,
+	105, 91, -2,
+}
+
+var plpgsqlTok1 = [...]uint8{
+	1, 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,
+	136, 3, 3, 3, 137, 3, 139, 3, 3, 3,
+	3, 3, 3, 3, 3, 3, 3, 3, 3, 135,
+	3, 138,
+}
+
+var plpgsqlTok2 = [...]uint8{
+	2, 3, 4, 5, 6, 7, 8, 9, 10, 11,
+	12, 13, 14, 15, 16, 17, 18, 19, 20, 21,
+	22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
+	32, 33, 34, 35, 36, 37, 38, 39, 40, 41,
+	42, 43, 44, 45, 46, 47, 48, 49, 50, 51,
+	52, 53, 54, 55, 56, 57, 58, 59, 60, 61,
+	62, 63, 64, 65, 66, 67, 68, 69, 70, 71,
+	72, 73, 74, 75, 76, 77, 78, 79, 80, 81,
+	82, 83, 84, 85, 86, 87, 88, 89, 90, 91,
+	92, 93, 94, 95, 96, 97, 98, 99, 100, 101,
+	102, 103, 104, 105, 106, 107, 108, 109, 110, 111,
+	112, 113, 114, 115, 116, 117, 118, 119, 120, 121,
+	122, 123, 124, 125, 126, 127, 128, 129, 130, 131,
+	132, 133, 134,
+}
+
+var plpgsqlTok3 = [...]int8{
+	0,
+}
+
+var plpgsqlErrorMessages = [...]struct {
+	state int
+	token int
+	msg   string
+}{}
+
+//line yaccpar:1
+
+/*	parser for yacc output	*/
+
+var (
+	plpgsqlDebug        = 0
+	plpgsqlErrorVerbose = false
+)
+
+type plpgsqlLexer interface {
+	Lex(lval *plpgsqlSymType) int
+	Error(s string)
+}
+
+type plpgsqlParser interface {
+	Parse(plpgsqlLexer) int
+	Lookahead() int
+}
+
+type plpgsqlParserImpl struct {
+	lval  plpgsqlSymType
+	stack [plpgsqlInitialStackSize]plpgsqlSymType
+	char  int
+}
+
+func (p *plpgsqlParserImpl) Lookahead() int {
+	return p.char
+}
+
+func plpgsqlNewParser() plpgsqlParser {
+	return &plpgsqlParserImpl{}
+}
+
+const plpgsqlFlag = -1000
+
+func plpgsqlTokname(c int) string {
+	if c >= 1 && c-1 < len(plpgsqlToknames) {
+		if plpgsqlToknames[c-1] != "" {
+			return plpgsqlToknames[c-1]
+		}
+	}
+	return __yyfmt__.Sprintf("tok-%v", c)
+}
+
+func plpgsqlStatname(s int) string {
+	if s >= 0 && s < len(plpgsqlStatenames) {
+		if plpgsqlStatenames[s] != "" {
+			return plpgsqlStatenames[s]
+		}
+	}
+	return __yyfmt__.Sprintf("state-%v", s)
+}
+
+func plpgsqlErrorMessage(state, lookAhead int) string {
+	const TOKSTART = 4
+
+	if !plpgsqlErrorVerbose {
+		return "syntax error"
+	}
+
+	for _, e := range plpgsqlErrorMessages {
+		if e.state == state && e.token == lookAhead {
+			return "syntax error: " + e.msg
+		}
+	}
+
+	res := "syntax error: unexpected " + plpgsqlTokname(lookAhead)
+
+	// To match Bison, suggest at most four expected tokens.
+	expected := make([]int, 0, 4)
+
+	// Look for shiftable tokens.
+	base := int(plpgsqlPact[state])
+	for tok := TOKSTART; tok-1 < len(plpgsqlToknames); tok++ {
+		if n := base + tok; n >= 0 && n < plpgsqlLast && int(plpgsqlChk[int(plpgsqlAct[n])]) == tok {
+			if len(expected) == cap(expected) {
+				return res
+			}
+			expected = append(expected, tok)
+		}
+	}
+
+	if plpgsqlDef[state] == -2 {
+		i := 0
+		for plpgsqlExca[i] != -1 || int(plpgsqlExca[i+1]) != state {
+			i += 2
+		}
+
+		// Look for tokens that we accept or reduce.
+		for i += 2; plpgsqlExca[i] >= 0; i += 2 {
+			tok := int(plpgsqlExca[i])
+			if tok < TOKSTART || plpgsqlExca[i+1] == 0 {
+				continue
+			}
+			if len(expected) == cap(expected) {
+				return res
+			}
+			expected = append(expected, tok)
+		}
+
+		// If the default action is to accept or reduce, give up.
+		if plpgsqlExca[i+1] != 0 {
+			return res
+		}
+	}
+
+	for i, tok := range expected {
+		if i == 0 {
+			res += ", expecting "
+		} else {
+			res += " or "
+		}
+		res += plpgsqlTokname(tok)
+	}
+	return res
+}
+
+func plpgsqllex1(lex plpgsqlLexer, lval *plpgsqlSymType) (char, token int) {
+	token = 0
+	char = lex.Lex(lval)
+	if char <= 0 {
+		token = int(plpgsqlTok1[0])
+		goto out
+	}
+	if char < len(plpgsqlTok1) {
+		token = int(plpgsqlTok1[char])
+		goto out
+	}
+	if char >= plpgsqlPrivate {
+		if char < plpgsqlPrivate+len(plpgsqlTok2) {
+			token = int(plpgsqlTok2[char-plpgsqlPrivate])
+			goto out
+		}
+	}
+	for i := 0; i < len(plpgsqlTok3); i += 2 {
+		token = int(plpgsqlTok3[i+0])
+		if token == char {
+			token = int(plpgsqlTok3[i+1])
+			goto out
+		}
+	}
+
+out:
+	if token == 0 {
+		token = int(plpgsqlTok2[1]) /* unknown char */
+	}
+	if plpgsqlDebug >= 3 {
+		__yyfmt__.Printf("lex %s(%d)\n", plpgsqlTokname(token), uint(char))
+	}
+	return char, token
+}
+
+func plpgsqlParse(plpgsqllex plpgsqlLexer) int {
+	return plpgsqlNewParser().Parse(plpgsqllex)
+}
+
+func (plpgsqlrcvr *plpgsqlParserImpl) Parse(plpgsqllex plpgsqlLexer) int {
+	var plpgsqln int
+	var plpgsqlVAL plpgsqlSymType
+	var plpgsqlDollar []plpgsqlSymType
+	_ = plpgsqlDollar // silence set and not used
+	plpgsqlS := plpgsqlrcvr.stack[:]
+
+	Nerrs := 0   /* number of errors */
+	Errflag := 0 /* error recovery flag */
+	plpgsqlstate := 0
+	plpgsqlrcvr.char = -1
+	plpgsqltoken := -1 // plpgsqlrcvr.char translated into internal numbering
+	defer func() {
+		// Make sure we report no lookahead when not parsing.
+		plpgsqlstate = -1
+		plpgsqlrcvr.char = -1
+		plpgsqltoken = -1
+	}()
+	plpgsqlp := -1
+	goto plpgsqlstack
+
+ret0:
+	return 0
+
+ret1:
+	return 1
+
+plpgsqlstack:
+	/* put a state and value onto the stack */
+	if plpgsqlDebug >= 4 {
+		__yyfmt__.Printf("char %v in %v\n", plpgsqlTokname(plpgsqltoken), plpgsqlStatname(plpgsqlstate))
+	}
+
+	plpgsqlp++
+	if plpgsqlp >= len(plpgsqlS) {
+		nyys := make([]plpgsqlSymType, len(plpgsqlS)*2)
+		copy(nyys, plpgsqlS)
+		plpgsqlS = nyys
+	}
+	plpgsqlS[plpgsqlp] = plpgsqlVAL
+	plpgsqlS[plpgsqlp].yys = plpgsqlstate
+
+plpgsqlnewstate:
+	plpgsqln = int(plpgsqlPact[plpgsqlstate])
+	if plpgsqln <= plpgsqlFlag {
+		goto plpgsqldefault /* simple state */
+	}
+	if plpgsqlrcvr.char < 0 {
+		plpgsqlrcvr.char, plpgsqltoken = plpgsqllex1(plpgsqllex, &plpgsqlrcvr.lval)
+	}
+	plpgsqln += plpgsqltoken
+	if plpgsqln < 0 || plpgsqln >= plpgsqlLast {
+		goto plpgsqldefault
+	}
+	plpgsqln = int(plpgsqlAct[plpgsqln])
+	if int(plpgsqlChk[plpgsqln]) == plpgsqltoken { /* valid shift */
+		plpgsqlrcvr.char = -1
+		plpgsqltoken = -1
+		plpgsqlVAL = plpgsqlrcvr.lval
+		plpgsqlstate = plpgsqln
+		if Errflag > 0 {
+			Errflag--
+		}
+		goto plpgsqlstack
+	}
+
+plpgsqldefault:
+	/* default state action */
+	plpgsqln = int(plpgsqlDef[plpgsqlstate])
+	if plpgsqln == -2 {
+		if plpgsqlrcvr.char < 0 {
+			plpgsqlrcvr.char, plpgsqltoken = plpgsqllex1(plpgsqllex, &plpgsqlrcvr.lval)
+		}
+
+		/* look through exception table */
+		xi := 0
+		for {
+			if plpgsqlExca[xi+0] == -1 && int(plpgsqlExca[xi+1]) == plpgsqlstate {
+				break
+			}
+			xi += 2
+		}
+		for xi += 2; ; xi += 2 {
+			plpgsqln = int(plpgsqlExca[xi+0])
+			if plpgsqln < 0 || plpgsqln == plpgsqltoken {
+				break
+			}
+		}
+		plpgsqln = int(plpgsqlExca[xi+1])
+		if plpgsqln < 0 {
+			goto ret0
+		}
+	}
+	if plpgsqln == 0 {
+		/* error ... attempt to resume parsing */
+		switch Errflag {
+		case 0: /* brand new error */
+			plpgsqllex.Error(plpgsqlErrorMessage(plpgsqlstate, plpgsqltoken))
+			Nerrs++
+			if plpgsqlDebug >= 1 {
+				__yyfmt__.Printf("%s", plpgsqlStatname(plpgsqlstate))
+				__yyfmt__.Printf(" saw %s\n", plpgsqlTokname(plpgsqltoken))
+			}
+			fallthrough
+
+		case 1, 2: /* incompletely recovered error ... try again */
+			Errflag = 3
+
+			/* find a state where "error" is a legal shift action */
+			for plpgsqlp >= 0 {
+				plpgsqln = int(plpgsqlPact[plpgsqlS[plpgsqlp].yys]) + plpgsqlErrCode
+				if plpgsqln >= 0 && plpgsqln < plpgsqlLast {
+					plpgsqlstate = int(plpgsqlAct[plpgsqln]) /* simulate a shift of "error" */
+					if int(plpgsqlChk[plpgsqlstate]) == plpgsqlErrCode {
+						goto plpgsqlstack
+					}
+				}
+
+				/* the current p has no shift on "error", pop stack */
+				if plpgsqlDebug >= 2 {
+					__yyfmt__.Printf("error recovery pops state %d\n", plpgsqlS[plpgsqlp].yys)
+				}
+				plpgsqlp--
+			}
+			/* there is no state on the stack with an error shift ... abort */
+			goto ret1
+
+		case 3: /* no shift yet; clobber input char */
+			if plpgsqlDebug >= 2 {
+				__yyfmt__.Printf("error recovery discards %s\n", plpgsqlTokname(plpgsqltoken))
+			}
+			if plpgsqltoken == plpgsqlEofCode {
+				goto ret1
+			}
+			plpgsqlrcvr.char = -1
+			plpgsqltoken = -1
+			goto plpgsqlnewstate /* try again in the same state */
+		}
+	}
+
+	/* reduction by production plpgsqln */
+	if plpgsqlDebug >= 2 {
+		__yyfmt__.Printf("reduce %v in:\n\t%v\n", plpgsqln, plpgsqlStatname(plpgsqlstate))
+	}
+
+	plpgsqlnt := plpgsqln
+	plpgsqlpt := plpgsqlp
+	_ = plpgsqlpt // guard against "declared and not used"
+
+	plpgsqlp -= int(plpgsqlR2[plpgsqln])
+	// plpgsqlp is now the index of $0. Perform the default action. Iff the
+	// reduced production is ε, $1 is possibly out of range.
+	if plpgsqlp+1 >= len(plpgsqlS) {
+		nyys := make([]plpgsqlSymType, len(plpgsqlS)*2)
+		copy(nyys, plpgsqlS)
+		plpgsqlS = nyys
+	}
+	plpgsqlVAL = plpgsqlS[plpgsqlp+1]
+
+	/* consult goto table to find next state */
+	plpgsqln = int(plpgsqlR1[plpgsqln])
+	plpgsqlg := int(plpgsqlPgo[plpgsqln])
+	plpgsqlj := plpgsqlg + plpgsqlS[plpgsqlp].yys + 1
+
+	if plpgsqlj >= plpgsqlLast {
+		plpgsqlstate = int(plpgsqlAct[plpgsqlg])
+	} else {
+		plpgsqlstate = int(plpgsqlAct[plpgsqlj])
+		if int(plpgsqlChk[plpgsqlstate]) != -plpgsqln {
+			plpgsqlstate = int(plpgsqlAct[plpgsqlg])
+		}
+	}
+	// dummy call; replaced with literal code
+	switch plpgsqlnt {
+
+	case 1:
+		plpgsqlDollar = plpgsqlS[plpgsqlpt-2 : plpgsqlpt+1]
+//line plpgsql-gen.y:409
+		{
+			plpgsqllex.(*lexer).SetStmt(plpgsqlDollar[1].union.statement())
+		}
+	case 4:
+		plpgsqlDollar = plpgsqlS[plpgsqlpt-7 : plpgsqlpt+1]
+//line plpgsql-gen.y:418
+		{
+			blockLabel, blockEndLabel := plpgsqlDollar[1].str, plpgsqlDollar[7].str
+			if err := checkLoopLabels(blockLabel, blockEndLabel); err != nil {
+				return setErr(plpgsqllex, err)
+			}
+			plpgsqlVAL.union.val = &plpgsqltree.Block{
+				Label:      plpgsqlDollar[1].str,
+				Decls:      plpgsqlDollar[2].union.statements(),
+				Body:       plpgsqlDollar[4].union.statements(),
+				Exceptions: plpgsqlDollar[5].union.exceptions(),
+			}
+		}
+	case 5:
+		plpgsqlDollar = plpgsqlS[plpgsqlpt-2 : plpgsqlpt+1]
+//line plpgsql-gen.y:433
+		{
+			plpgsqlVAL.union.val = plpgsqlDollar[2].union.statements()
+		}
+	case 6:
+		plpgsqlDollar = plpgsqlS[plpgsqlpt-0 : plpgsqlpt+1]
+//line plpgsql-gen.y:437
+		{
+
+			plpgsqlVAL.union.val = []plpgsqltree.Statement(nil)
+		}
+	case 7:
+		plpgsqlDollar = plpgsqlS[plpgsqlpt-1 : plpgsqlpt+1]
+//line plpgsql-gen.y:444
+		{
+			plpgsqlVAL.union.val = plpgsqlDollar[1].union.statements()
+		}
+	case 8:
+		plpgsqlDollar = plpgsqlS[plpgsqlpt-0 : plpgsqlpt+1]
+//line plpgsql-gen.y:448
+		{
+			plpgsqlVAL.union.val = []plpgsqltree.Statement{}
+		}
+	case 9:
+		plpgsqlDollar = plpgsqlS[plpgsqlpt-1 : plpgsqlpt+1]
+//line plpgsql-gen.y:453
+		{
+		}
+	case 10:
+		plpgsqlDollar = plpgsqlS[plpgsqlpt-0 : plpgsqlpt+1]
+//line plpgsql-gen.y:454
+		{
+		}
+	case 11:
+		plpgsqlDollar = plpgsqlS[plpgsqlpt-3 : plpgsqlpt+1]
+//line plpgsql-gen.y:458
+		{
+			decs := plpgsqlDollar[1].union.statements()
+			dec := plpgsqlDollar[3].union.statement()
+			plpgsqlVAL.union.val = append(decs, dec)
+		}
+	case 12:
+		plpgsqlDollar = plpgsqlS[plpgsqlpt-1 : plpgsqlpt+1]
+//line plpgsql-gen.y:464
+		{
+			dec := plpgsqlDollar[1].union.statement()
+			plpgsqlVAL.union.val = []plpgsqltree.Statement{dec}
+		}
+	case 13:
+		plpgsqlDollar = plpgsqlS[plpgsqlpt-6 : plpgsqlpt+1]
+//line plpgsql-gen.y:471
+		{
+			plpgsqlVAL.union.val = &plpgsqltree.Declaration{
+				Var:      plpgsqltree.Variable(plpgsqlDollar[1].str),
+				Constant: plpgsqlDollar[2].union.bool(),
+				Typ:      plpgsqlDollar[3].union.typ(),
+				Collate:  plpgsqlDollar[4].str,
+				NotNull:  plpgsqlDollar[5].union.bool(),
+				Expr:     plpgsqlDollar[6].union.expr(),
+			}
+		}
+	case 14:
+		plpgsqlDollar = plpgsqlS[plpgsqlpt-5 : plpgsqlpt+1]
+//line plpgsql-gen.y:482
+		{
+			return unimplemented(plpgsqllex, "alias for")
+		}
+	case 15:
+		plpgsqlDollar = plpgsqlS[plpgsqlpt-6 : plpgsqlpt+1]
+//line plpgsql-gen.y:486
+		{
+			ann := tree.MakeAnnotations(plpgsqlDollar[6].union.numAnnotations())
+			plpgsqlVAL.union.val = &plpgsqltree.CursorDeclaration{
+				Name:        plpgsqltree.Variable(plpgsqlDollar[1].str),
+				Scroll:      plpgsqlDollar[2].union.cursorScrollOption(),
+				Query:       plpgsqlDollar[6].union.sqlStatement(),
+				Annotations: &ann,
+			}
+		}
+	case 16:
+		plpgsqlDollar = plpgsqlS[plpgsqlpt-0 : plpgsqlpt+1]
+//line plpgsql-gen.y:498
+		{
+			plpgsqlVAL.union.val = tree.UnspecifiedScroll
+		}
+	case 17:
+		plpgsqlDollar = plpgsqlS[plpgsqlpt-2 : plpgsqlpt+1]
+//line plpgsql-gen.y:502
+		{
+			plpgsqlVAL.union.val = tree.NoScroll
+		}
+	case 18:
+		plpgsqlDollar = plpgsqlS[plpgsqlpt-1 : plpgsqlpt+1]
+//line plpgsql-gen.y:506
+		{
+			plpgsqlVAL.union.val = tree.Scroll
+		}
+	case 19:
+		plpgsqlDollar = plpgsqlS[plpgsqlpt-2 : plpgsqlpt+1]
+//line plpgsql-gen.y:512
+		{
+			stmts, err := parser.Parse(plpgsqlDollar[1].str)
+			if err != nil {
+				return setErr(plpgsqllex, err)
+			}
+			if len(stmts) != 1 {
+				return setErr(plpgsqllex, errors.New("expected exactly one SQL statement for cursor"))
+			}
+			plpgsqlVAL.union.val = stmts[0]
+		}
+	case 20:
+		plpgsqlDollar = plpgsqlS[plpgsqlpt-1 : plpgsqlpt+1]
+//line plpgsql-gen.y:525
+		{
+			return unimplemented(plpgsqllex, "cursor arguments")
+		}
+	case 21:
+		plpgsqlDollar = plpgsqlS[plpgsqlpt-0 : plpgsqlpt+1]
+//line plpgsql-gen.y:529
+		{
+		}
+	case 22:
+		plpgsqlDollar = plpgsqlS[plpgsqlpt-1 : plpgsqlpt+1]
+//line plpgsql-gen.y:534
+		{
+		}
+	case 23:
+		plpgsqlDollar = plpgsqlS[plpgsqlpt-3 : plpgsqlpt+1]
+//line plpgsql-gen.y:537
+		{
+		}
+	case 24:
+		plpgsqlDollar = plpgsqlS[plpgsqlpt-2 : plpgsqlpt+1]
+//line plpgsql-gen.y:542
+		{
+		}
+	case 27:
+		plpgsqlDollar = plpgsqlS[plpgsqlpt-1 : plpgsqlpt+1]
+//line plpgsql-gen.y:551
+		{
+		}
+	case 28:
+		plpgsqlDollar = plpgsqlS[plpgsqlpt-1 : plpgsqlpt+1]
+//line plpgsql-gen.y:554
+		{
+		}
+	case 31:
+		plpgsqlDollar = plpgsqlS[plpgsqlpt-0 : plpgsqlpt+1]
+//line plpgsql-gen.y:563
+		{
+			plpgsqlVAL.union.val = false
+		}
+	case 32:
+		plpgsqlDollar = plpgsqlS[plpgsqlpt-1 : plpgsqlpt+1]
+//line plpgsql-gen.y:567
+		{
+			plpgsqlVAL.union.val = true
+		}
+	case 33:
+		plpgsqlDollar = plpgsqlS[plpgsqlpt-0 : plpgsqlpt+1]
+//line plpgsql-gen.y:573
+		{
+
+			sqlStr, _, err := plpgsqllex.(*lexer).ReadSqlExpr(
+				';', COLLATE, NOT, '=', COLON_EQUALS, DECLARE,
+			)
+			if err != nil {
+				return setErr(plpgsqllex, err)
+			}
+
+			castExpr, err := plpgsqllex.(*lexer).ParseExpr("1::" + sqlStr)
+			if err != nil {
+				return setErr(plpgsqllex, errors.New("unable to parse type of variable declaration"))
+			}
+			switch t := castExpr.(type) {
+			case *tree.CollateExpr:
+				plpgsqlVAL.union.val = types.MakeCollatedString(types.String, t.Locale)
+			case *tree.CastExpr:
+				plpgsqlVAL.union.val = t.Type
+			default:
+				err := errors.New("unable to parse type of variable declaration")
+				if strings.Contains(sqlStr, "%") {
+					err = errors.WithIssueLink(errors.WithHint(err,
+						"you may have attempted to use %TYPE or %ROWTYPE syntax, which is unsupported.",
+					), errors.IssueLink{IssueURL: build.MakeIssueURL(114676)})
+				}
+				return setErr(plpgsqllex, err)
+			}
+		}
+	case 34:
+		plpgsqlDollar = plpgsqlS[plpgsqlpt-0 : plpgsqlpt+1]
+//line plpgsql-gen.y:606
+		{
+			plpgsqlVAL.str = ""
+		}
+	case 35:
+		plpgsqlDollar = plpgsqlS[plpgsqlpt-2 : plpgsqlpt+1]
+//line plpgsql-gen.y:610
+		{
+			plpgsqlVAL.str = plpgsqlDollar[2].str
+		}
+	case 36:
+		plpgsqlDollar = plpgsqlS[plpgsqlpt-2 : plpgsqlpt+1]
+//line plpgsql-gen.y:614
+		{
+			plpgsqlVAL.str = plpgsqlDollar[2].str
+		}
+	case 37:
+		plpgsqlDollar = plpgsqlS[plpgsqlpt-0 : plpgsqlpt+1]
+//line plpgsql-gen.y:620
+		{
+			plpgsqlVAL.union.val = false
+		}
+	case 38:
+		plpgsqlDollar = plpgsqlS[plpgsqlpt-2 : plpgsqlpt+1]
+//line plpgsql-gen.y:624
+		{
+			plpgsqlVAL.union.val = true
+		}
+	case 39:
+		plpgsqlDollar = plpgsqlS[plpgsqlpt-1 : plpgsqlpt+1]
+//line plpgsql-gen.y:630
+		{
+			plpgsqlVAL.union.val = (plpgsqltree.Expr)(nil)
+		}
+	case 40:
+		plpgsqlDollar = plpgsqlS[plpgsqlpt-2 : plpgsqlpt+1]
+//line plpgsql-gen.y:634
+		{
+			expr, err := plpgsqllex.(*lexer).ParseExpr(plpgsqlDollar[1].str)
+			if err != nil {
+				return setErr(plpgsqllex, err)
+			}
+			plpgsqlVAL.union.val = expr
+		}
+	case 41:
+		plpgsqlDollar = plpgsqlS[plpgsqlpt-1 : plpgsqlpt+1]
+//line plpgsql-gen.y:644
+		{
+			sqlStr, _, err := plpgsqllex.(*lexer).ReadSqlExpr(';')
+			if err != nil {
+				return setErr(plpgsqllex, err)
+			}
+			plpgsqlVAL.str = sqlStr
+		}
+	case 42:
+		plpgsqlDollar = plpgsqlS[plpgsqlpt-1 : plpgsqlpt+1]
+//line plpgsql-gen.y:652
+		{
+			sqlStr, _, err := plpgsqllex.(*lexer).ReadSqlExpr(';')
+			if err != nil {
+				return setErr(plpgsqllex, err)
+			}
+			plpgsqlVAL.str = sqlStr
+		}
+	case 45:
+		plpgsqlDollar = plpgsqlS[plpgsqlpt-0 : plpgsqlpt+1]
+//line plpgsql-gen.y:671
+		{
+			plpgsqlVAL.union.val = []plpgsqltree.Statement{}
+		}
+	case 46:
+		plpgsqlDollar = plpgsqlS[plpgsqlpt-2 : plpgsqlpt+1]
+//line plpgsql-gen.y:675
+		{
+			stmts := plpgsqlDollar[1].union.statements()
+			stmts = append(stmts, plpgsqlDollar[2].union.statement())
+			plpgsqlVAL.union.val = stmts
+		}
+	case 47:
+		plpgsqlDollar = plpgsqlS[plpgsqlpt-2 : plpgsqlpt+1]
+//line plpgsql-gen.y:683
+		{
+			plpgsqlVAL.union.val = plpgsqlDollar[1].union.block()
+		}
+	case 48:
+		plpgsqlDollar = plpgsqlS[plpgsqlpt-1 : plpgsqlpt+1]
+//line plpgsql-gen.y:687
+		{
+			plpgsqlVAL.union.val = plpgsqlDollar[1].union.statement()
+		}
+	case 49:
+		plpgsqlDollar = plpgsqlS[plpgsqlpt-1 : plpgsqlpt+1]
+//line plpgsql-gen.y:691
+		{
+			plpgsqlVAL.union.val = plpgsqlDollar[1].union.statement()
+		}
+	case 50:
+		plpgsqlDollar = plpgsqlS[plpgsqlpt-1 : plpgsqlpt+1]
+//line plpgsql-gen.y:695
+		{
+			plpgsqlVAL.union.val = plpgsqlDollar[1].union.statement()
+		}
+	case 51:
+		plpgsqlDollar = plpgsqlS[plpgsqlpt-1 : plpgsqlpt+1]
+//line plpgsql-gen.y:699
+		{
+			plpgsqlVAL.union.val = plpgsqlDollar[1].union.statement()
+		}
+	case 52:
+		plpgsqlDollar = plpgsqlS[plpgsqlpt-1 : plpgsqlpt+1]
+//line plpgsql-gen.y:703
+		{
+			plpgsqlVAL.union.val = plpgsqlDollar[1].union.statement()
+		}
+	case 53:
+		plpgsqlDollar = plpgsqlS[plpgsqlpt-1 : plpgsqlpt+1]
+//line plpgsql-gen.y:707
+		{
+		}
+	case 54:
+		plpgsqlDollar = plpgsqlS[plpgsqlpt-1 : plpgsqlpt+1]
+//line plpgsql-gen.y:709
+		{
+		}
+	case 55:
+		plpgsqlDollar = plpgsqlS[plpgsqlpt-1 : plpgsqlpt+1]
+//line plpgsql-gen.y:711
+		{
+			plpgsqlVAL.union.val = plpgsqlDollar[1].union.statement()
+		}
+	case 56:
+		plpgsqlDollar = plpgsqlS[plpgsqlpt-1 : plpgsqlpt+1]
+//line plpgsql-gen.y:715
+		{
+			plpgsqlVAL.union.val = plpgsqlDollar[1].union.statement()
+		}
+	case 57:
+		plpgsqlDollar = plpgsqlS[plpgsqlpt-1 : plpgsqlpt+1]
+//line plpgsql-gen.y:719
+		{
+			plpgsqlVAL.union.val = plpgsqlDollar[1].union.statement()
+		}
+	case 58:
+		plpgsqlDollar = plpgsqlS[plpgsqlpt-1 : plpgsqlpt+1]
+//line plpgsql-gen.y:723
+		{
+			plpgsqlVAL.union.val = plpgsqlDollar[1].union.statement()
+		}
+	case 59:
+		plpgsqlDollar = plpgsqlS[plpgsqlpt-1 : plpgsqlpt+1]
+//line plpgsql-gen.y:727
+		{
+			plpgsqlVAL.union.val = plpgsqlDollar[1].union.statement()
+		}
+	case 60:
+		plpgsqlDollar = plpgsqlS[plpgsqlpt-1 : plpgsqlpt+1]
+//line plpgsql-gen.y:731
+		{
+			plpgsqlVAL.union.val = plpgsqlDollar[1].union.statement()
+		}
+	case 61:
+		plpgsqlDollar = plpgsqlS[plpgsqlpt-1 : plpgsqlpt+1]
+//line plpgsql-gen.y:735
+		{
+			plpgsqlVAL.union.val = plpgsqlDollar[1].union.statement()
+		}
+	case 62:
+		plpgsqlDollar = plpgsqlS[plpgsqlpt-1 : plpgsqlpt+1]
+//line plpgsql-gen.y:739
+		{
+		}
+	case 63:
+		plpgsqlDollar = plpgsqlS[plpgsqlpt-1 : plpgsqlpt+1]
+//line plpgsql-gen.y:741
+		{
+			plpgsqlVAL.union.val = plpgsqlDollar[1].union.statement()
+		}
+	case 64:
+		plpgsqlDollar = plpgsqlS[plpgsqlpt-1 : plpgsqlpt+1]
+//line plpgsql-gen.y:745
+		{
+			plpgsqlVAL.union.val = plpgsqlDollar[1].union.statement()
+		}
+	case 65:
+		plpgsqlDollar = plpgsqlS[plpgsqlpt-1 : plpgsqlpt+1]
+//line plpgsql-gen.y:749
+		{
+		}
+	case 66:
+		plpgsqlDollar = plpgsqlS[plpgsqlpt-1 : plpgsqlpt+1]
+//line plpgsql-gen.y:751
+		{
+			plpgsqlVAL.union.val = plpgsqlDollar[1].union.statement()
+		}
+	case 67:
+		plpgsqlDollar = plpgsqlS[plpgsqlpt-1 : plpgsqlpt+1]
+//line plpgsql-gen.y:755
+		{
+			plpgsqlVAL.union.val = plpgsqlDollar[1].union.statement()
+		}
+	case 68:
+		plpgsqlDollar = plpgsqlS[plpgsqlpt-1 : plpgsqlpt+1]
+//line plpgsql-gen.y:759
+		{
+			plpgsqlVAL.union.val = plpgsqlDollar[1].union.statement()
+		}
+	case 69:
+		plpgsqlDollar = plpgsqlS[plpgsqlpt-1 : plpgsqlpt+1]
+//line plpgsql-gen.y:763
+		{
+			plpgsqlVAL.union.val = plpgsqlDollar[1].union.statement()
+		}
+	case 70:
+		plpgsqlDollar = plpgsqlS[plpgsqlpt-1 : plpgsqlpt+1]
+//line plpgsql-gen.y:767
+		{
+			plpgsqlVAL.union.val = plpgsqlDollar[1].union.statement()
+		}
+	case 71:
+		plpgsqlDollar = plpgsqlS[plpgsqlpt-1 : plpgsqlpt+1]
+//line plpgsql-gen.y:771
+		{
+			plpgsqlVAL.union.val = plpgsqlDollar[1].union.statement()
+		}
+	case 72:
+		plpgsqlDollar = plpgsqlS[plpgsqlpt-1 : plpgsqlpt+1]
+//line plpgsql-gen.y:775
+		{
+			plpgsqlVAL.union.val = plpgsqlDollar[1].union.statement()
+		}
+	case 73:
+		plpgsqlDollar = plpgsqlS[plpgsqlpt-3 : plpgsqlpt+1]
+//line plpgsql-gen.y:781
+		{
+			return unimplemented(plpgsqllex, "perform")
+		}
+	case 74:
+		plpgsqlDollar = plpgsqlS[plpgsqlpt-3 : plpgsqlpt+1]
+//line plpgsql-gen.y:787
+		{
+			expr, err := plpgsqllex.(*lexer).ParseExpr(plpgsqlDollar[2].str)
+			if err != nil {
+				return setErr(plpgsqllex, err)
+			}
+			proc, ok := expr.(*tree.FuncExpr)
+			if !ok {
+				return setErr(plpgsqllex,
+					errors.New("CALL statement target must be a stored procedure"),
+				)
+			}
+
+			proc.InCall = true
+			plpgsqlVAL.union.val = &plpgsqltree.Call{Proc: proc}
+		}
+	case 75:
+		plpgsqlDollar = plpgsqlS[plpgsqlpt-3 : plpgsqlpt+1]
+//line plpgsql-gen.y:806
+		{
+			doBlock, err := makeDoStmt(plpgsqlDollar[2].union.doBlockOptions())
+			if err != nil {
+				return setErrNoDetails(plpgsqllex, err)
+			}
+			plpgsqlVAL.union.val = doBlock
+		}
+	case 76:
+		plpgsqlDollar = plpgsqlS[plpgsqlpt-1 : plpgsqlpt+1]
+//line plpgsql-gen.y:817
+		{
+			plpgsqlVAL.union.val = tree.DoBlockOptions{plpgsqlDollar[1].union.doBlockOption()}
+		}
+	case 77:
+		plpgsqlDollar = plpgsqlS[plpgsqlpt-2 : plpgsqlpt+1]
+//line plpgsql-gen.y:821
+		{
+			plpgsqlVAL.union.val = append(plpgsqlDollar[1].union.doBlockOptions(), plpgsqlDollar[2].union.doBlockOption())
+		}
+	case 78:
+		plpgsqlDollar = plpgsqlS[plpgsqlpt-1 : plpgsqlpt+1]
+//line plpgsql-gen.y:828
+		{
+			plpgsqlVAL.union.val = tree.RoutineBodyStr(plpgsqlDollar[1].str)
+		}
+	case 79:
+		plpgsqlDollar = plpgsqlS[plpgsqlpt-2 : plpgsqlpt+1]
+//line plpgsql-gen.y:832
+		{
+			lang, err := tree.AsRoutineLanguage(plpgsqlDollar[2].str)
+			if err != nil {
+				return setErr(plpgsqllex, err)
+			}
+			plpgsqlVAL.union.val = lang
+		}
+	case 80:
+		plpgsqlDollar = plpgsqlS[plpgsqlpt-4 : plpgsqlpt+1]
+//line plpgsql-gen.y:842
+		{
+			expr, err := plpgsqllex.(*lexer).ParseExpr(plpgsqlDollar[3].str)
+			if err != nil {
+				return setErr(plpgsqllex, err)
+			}
+			plpgsqlVAL.union.val = &plpgsqltree.Assignment{
+				Var:   plpgsqltree.Variable(plpgsqlDollar[1].str),
+				Value: expr,
+			}
+		}
+	case 81:
+		plpgsqlDollar = plpgsqlS[plpgsqlpt-6 : plpgsqlpt+1]
+//line plpgsql-gen.y:853
+		{
+
+			expr, err := plpgsqllex.(*lexer).ParseExpr(plpgsqlDollar[5].str)
+			if err != nil {
+				return setErr(plpgsqllex, err)
+			}
+			plpgsqlVAL.union.val = &plpgsqltree.Assignment{
+				Var:         plpgsqltree.Variable(plpgsqlDollar[1].str),
+				Value:       expr,
+				Indirection: tree.Name(plpgsqlDollar[3].str),
+			}
+		}
+	case 82:
+		plpgsqlDollar = plpgsqlS[plpgsqlpt-5 : plpgsqlpt+1]
+//line plpgsql-gen.y:868
+		{
+			plpgsqlVAL.union.val = &plpgsqltree.GetDiagnostics{
+				IsStacked: plpgsqlDollar[2].union.bool(),
+				DiagItems: plpgsqlDollar[4].union.getDiagnosticsItemList(),
+			}
+
+		}
+	case 83:
+		plpgsqlDollar = plpgsqlS[plpgsqlpt-0 : plpgsqlpt+1]
+//line plpgsql-gen.y:878
+		{
+			plpgsqlVAL.union.val = false
+		}
+	case 84:
+		plpgsqlDollar = plpgsqlS[plpgsqlpt-1 : plpgsqlpt+1]
+//line plpgsql-gen.y:882
+		{
+			plpgsqlVAL.union.val = false
+		}
+	case 85:
+		plpgsqlDollar = plpgsqlS[plpgsqlpt-1 : plpgsqlpt+1]
+//line plpgsql-gen.y:886
+		{
+			plpgsqlVAL.union.val = true
+		}
+	case 86:
+		plpgsqlDollar = plpgsqlS[plpgsqlpt-3 : plpgsqlpt+1]
+//line plpgsql-gen.y:892
+		{
+			plpgsqlVAL.union.val = append(plpgsqlDollar[1].union.getDiagnosticsItemList(), plpgsqlDollar[3].union.getDiagnosticsItem())
+		}
+	case 87:
+		plpgsqlDollar = plpgsqlS[plpgsqlpt-1 : plpgsqlpt+1]
+//line plpgsql-gen.y:896
+		{
+			plpgsqlVAL.union.val = plpgsqltree.GetDiagnosticsItemList{plpgsqlDollar[1].union.getDiagnosticsItem()}
+		}
+	case 88:
+		plpgsqlDollar = plpgsqlS[plpgsqlpt-3 : plpgsqlpt+1]
+//line plpgsql-gen.y:902
+		{
+			plpgsqlVAL.union.val = &plpgsqltree.GetDiagnosticsItem{
+				Kind:       plpgsqlDollar[3].union.getDiagnosticsKind(),
+				TargetName: plpgsqlDollar[1].str,
+			}
+		}
+	case 89:
+		plpgsqlDollar = plpgsqlS[plpgsqlpt-1 : plpgsqlpt+1]
+//line plpgsql-gen.y:911
+		{
+			switch plpgsqlDollar[1].str {
+			case "row_count":
+				plpgsqlVAL.union.val = plpgsqltree.GetDiagnosticsRowCount
+			case "pg_context":
+				plpgsqlVAL.union.val = plpgsqltree.GetDiagnosticsContext
+			case "pg_exception_detail":
+				plpgsqlVAL.union.val = plpgsqltree.GetDiagnosticsErrorDetail
+			case "pg_exception_hint":
+				plpgsqlVAL.union.val = plpgsqltree.GetDiagnosticsErrorHint
+			case "pg_exception_context":
+				plpgsqlVAL.union.val = plpgsqltree.GetDiagnosticsErrorContext
+			case "column_name":
+				plpgsqlVAL.union.val = plpgsqltree.GetDiagnosticsColumnName
+			case "constraint_name":
+				plpgsqlVAL.union.val = plpgsqltree.GetDiagnosticsConstraintName
+			case "pg_datatype_name":
+				plpgsqlVAL.union.val = plpgsqltree.GetDiagnosticsDatatypeName
+			case "message_text":
+				plpgsqlVAL.union.val = plpgsqltree.GetDiagnosticsMessageText
+			case "table_name":
+				plpgsqlVAL.union.val = plpgsqltree.GetDiagnosticsTableName
+			case "schema_name":
+				plpgsqlVAL.union.val = plpgsqltree.GetDiagnosticsSchemaName
+			case "returned_sqlstate":
+				plpgsqlVAL.union.val = plpgsqltree.GetDiagnosticsReturnedSQLState
+			default:
+
+				return setErr(plpgsqllex, errors.Newf("unrecognized GET DIAGNOSTICS item: %s", redact.Safe(plpgsqlDollar[1].str)))
+			}
+		}
+	case 90:
+		plpgsqlDollar = plpgsqlS[plpgsqlpt-1 : plpgsqlpt+1]
+//line plpgsql-gen.y:947
+		{
+		}
+	case 91:
+		plpgsqlDollar = plpgsqlS[plpgsqlpt-9 : plpgsqlpt+1]
+//line plpgsql-gen.y:952
+		{
+			cond, err := plpgsqllex.(*lexer).ParseExpr(plpgsqlDollar[2].str)
+			if err != nil {
+				return setErr(plpgsqllex, err)
+			}
+			plpgsqlVAL.union.val = &plpgsqltree.If{
+				Condition:  cond,
+				ThenBody:   plpgsqlDollar[4].union.statements(),
+				ElseIfList: plpgsqlDollar[5].union.elseIf(),
+				ElseBody:   plpgsqlDollar[6].union.statements(),
+			}
+		}
+	case 92:
+		plpgsqlDollar = plpgsqlS[plpgsqlpt-0 : plpgsqlpt+1]
+//line plpgsql-gen.y:967
+		{
+			plpgsqlVAL.union.val = []plpgsqltree.ElseIf{}
+		}
+	case 93:
+		plpgsqlDollar = plpgsqlS[plpgsqlpt-5 : plpgsqlpt+1]
+//line plpgsql-gen.y:971
+		{
+			cond, err := plpgsqllex.(*lexer).ParseExpr(plpgsqlDollar[3].str)
+			if err != nil {
+				return setErr(plpgsqllex, err)
+			}
+			newStmt := plpgsqltree.ElseIf{
+				Condition: cond,
+				Stmts:     plpgsqlDollar[5].union.statements(),
+			}
+			plpgsqlVAL.union.val = append(plpgsqlDollar[1].union.elseIf(), newStmt)
+		}
+	case 94:
+		plpgsqlDollar = plpgsqlS[plpgsqlpt-0 : plpgsqlpt+1]
+//line plpgsql-gen.y:985
+		{
+			plpgsqlVAL.union.val = []plpgsqltree.Statement{}
+		}
+	case 95:
+		plpgsqlDollar = plpgsqlS[plpgsqlpt-2 : plpgsqlpt+1]
+//line plpgsql-gen.y:989
+		{
+			plpgsqlVAL.union.val = plpgsqlDollar[2].union.statements()
+		}
+	case 96:
+		plpgsqlDollar = plpgsqlS[plpgsqlpt-7 : plpgsqlpt+1]
+//line plpgsql-gen.y:995
+		{
+			expr := &plpgsqltree.Case{
+				TestExpr:     plpgsqlDollar[2].str,
+				CaseWhenList: plpgsqlDollar[3].union.caseWhens(),
+			}
+			if plpgsqlDollar[4].union.val != nil {
+				expr.HaveElse = true
+				expr.ElseStmts = plpgsqlDollar[4].union.statements()
+			}
+			plpgsqlVAL.union.val = expr
+		}
+	case 97:
+		plpgsqlDollar = plpgsqlS[plpgsqlpt-0 : plpgsqlpt+1]
+//line plpgsql-gen.y:1009
+		{
+			if plpgsqllex.(*lexer).Peek().id != WHEN {
+				sqlStr, _, err := plpgsqllex.(*lexer).ReadSqlExpr(WHEN)
+				if err != nil {
+					return setErr(plpgsqllex, err)
+				}
+				plpgsqlVAL.str = sqlStr
+			} else {
+				plpgsqlVAL.str = ""
+			}
+		}
+	case 98:
+		plpgsqlDollar = plpgsqlS[plpgsqlpt-2 : plpgsqlpt+1]
+//line plpgsql-gen.y:1023
+		{
+			stmts := plpgsqlDollar[1].union.caseWhens()
+			stmts = append(stmts, plpgsqlDollar[2].union.caseWhen())
+			plpgsqlVAL.union.val = stmts
+		}
+	case 99:
+		plpgsqlDollar = plpgsqlS[plpgsqlpt-1 : plpgsqlpt+1]
+//line plpgsql-gen.y:1029
+		{
+			stmts := []*plpgsqltree.CaseWhen{}
+			stmts = append(stmts, plpgsqlDollar[1].union.caseWhen())
+			plpgsqlVAL.union.val = stmts
+		}
+	case 100:
+		plpgsqlDollar = plpgsqlS[plpgsqlpt-4 : plpgsqlpt+1]
+//line plpgsql-gen.y:1037
+		{
+			expr := &plpgsqltree.CaseWhen{
+				Expr:  plpgsqlDollar[2].str,
+				Stmts: plpgsqlDollar[4].union.statements(),
+			}
+			plpgsqlVAL.union.val = expr
+		}
+	case 101:
+		plpgsqlDollar = plpgsqlS[plpgsqlpt-0 : plpgsqlpt+1]
+//line plpgsql-gen.y:1047
+		{
+			plpgsqlVAL.union.val = nil
+		}
+	case 102:
+		plpgsqlDollar = plpgsqlS[plpgsqlpt-2 : plpgsqlpt+1]
+//line plpgsql-gen.y:1051
+		{
+			plpgsqlVAL.union.val = plpgsqlDollar[2].union.statements()
+		}
+	case 103:
+		plpgsqlDollar = plpgsqlS[plpgsqlpt-5 : plpgsqlpt+1]
+//line plpgsql-gen.y:1057
+		{
+			loopLabel, loopEndLabel := plpgsqlDollar[1].str, plpgsqlDollar[4].str
+			if err := checkLoopLabels(loopLabel, loopEndLabel); err != nil {
+				return setErr(plpgsqllex, err)
+			}
+			plpgsqlVAL.union.val = &plpgsqltree.Loop{
+				Label: loopLabel,
+				Body:  plpgsqlDollar[3].union.statements(),
+			}
+		}
+	case 104:
+		plpgsqlDollar = plpgsqlS[plpgsqlpt-7 : plpgsqlpt+1]
+//line plpgsql-gen.y:1070
+		{
+			loopLabel, loopEndLabel := plpgsqlDollar[1].str, plpgsqlDollar[6].str
+			if err := checkLoopLabels(loopLabel, loopEndLabel); err != nil {
+				return setErr(plpgsqllex, err)
+			}
+			cond, err := plpgsqllex.(*lexer).ParseExpr(plpgsqlDollar[3].str)
+			if err != nil {
+				return setErr(plpgsqllex, err)
+			}
+			plpgsqlVAL.union.val = &plpgsqltree.While{
+				Label:     loopLabel,
+				Condition: cond,
+				Body:      plpgsqlDollar[5].union.statements(),
+			}
+		}
+	case 105:
+		plpgsqlDollar = plpgsqlS[plpgsqlpt-8 : plpgsqlpt+1]
+//line plpgsql-gen.y:1088
+		{
+			loopLabel, loopEndLabel := plpgsqlDollar[1].str, plpgsqlDollar[7].str
+			if err := checkLoopLabels(loopLabel, loopEndLabel); err != nil {
+				return setErr(plpgsqllex, err)
+			}
+			plpgsqlVAL.union.val = &plpgsqltree.ForLoop{
+				Label:   loopLabel,
+				Target:  plpgsqlDollar[3].union.variables(),
+				Control: plpgsqlDollar[5].union.forLoopControl(),
+				Body:    plpgsqlDollar[6].union.statements(),
+			}
+		}
+	case 106:
+		plpgsqlDollar = plpgsqlS[plpgsqlpt-0 : plpgsqlpt+1]
+//line plpgsql-gen.y:1103
+		{
+			foundToken, err := plpgsqllex.(*lexer).findFirstOccurrence(DOT_DOT, LOOP)
+			if err != nil {
+				return setErr(plpgsqllex, err)
+			}
+			switch foundToken {
+			case DOT_DOT:
+
+				forLoopControl, err := plpgsqllex.(*lexer).ReadIntegerForLoopControl()
+				if err != nil {
+					return setErr(plpgsqllex, err)
+				}
+				plpgsqlVAL.union.val = forLoopControl
+			case LOOP:
+				return unimplemented(plpgsqllex, "for loop over query or cursor")
+			default:
+				return setErr(plpgsqllex, errors.New("unterminated FOR loop definition"))
+			}
+		}
+	case 107:
+		plpgsqlDollar = plpgsqlS[plpgsqlpt-0 : plpgsqlpt+1]
+//line plpgsql-gen.y:1125
+		{
+			target, err := plpgsqllex.(*lexer).ReadTarget()
+			if err != nil {
+				return setErr(plpgsqllex, err)
+			}
+			plpgsqlVAL.union.val = target
+		}
+	case 108:
+		plpgsqlDollar = plpgsqlS[plpgsqlpt-2 : plpgsqlpt+1]
+//line plpgsql-gen.y:1135
+		{
+			return unimplemented(plpgsqllex, "for each loop")
+		}
+	case 109:
+		plpgsqlDollar = plpgsqlS[plpgsqlpt-0 : plpgsqlpt+1]
+//line plpgsql-gen.y:1141
+		{
+		}
+	case 110:
+		plpgsqlDollar = plpgsqlS[plpgsqlpt-2 : plpgsqlpt+1]
+//line plpgsql-gen.y:1144
+		{
+		}
+	case 111:
+		plpgsqlDollar = plpgsqlS[plpgsqlpt-3 : plpgsqlpt+1]
+//line plpgsql-gen.y:1149
+		{
+			plpgsqlVAL.union.val = &plpgsqltree.Exit{
+				Label:     plpgsqlDollar[2].str,
+				Condition: plpgsqlDollar[3].union.expr(),
+			}
+		}
+	case 112:
+		plpgsqlDollar = plpgsqlS[plpgsqlpt-3 : plpgsqlpt+1]
+//line plpgsql-gen.y:1158
+		{
+			plpgsqlVAL.union.val = &plpgsqltree.Continue{
+				Label:     plpgsqlDollar[2].str,
+				Condition: plpgsqlDollar[3].union.expr(),
+			}
+		}
+	case 113:
+		plpgsqlDollar = plpgsqlS[plpgsqlpt-3 : plpgsqlpt+1]
+//line plpgsql-gen.y:1167
+		{
+			plpgsqlVAL.union.val = &plpgsqltree.Return{Expr: plpgsqlDollar[2].union.expr()}
+		}
+	case 114:
+		plpgsqlDollar = plpgsqlS[plpgsqlpt-4 : plpgsqlpt+1]
+//line plpgsql-gen.y:1171
+		{
+			plpgsqlVAL.union.val = &plpgsqltree.ReturnNext{Expr: plpgsqlDollar[3].union.expr()}
+		}
+	case 115:
+		plpgsqlDollar = plpgsqlS[plpgsqlpt-4 : plpgsqlpt+1]
+//line plpgsql-gen.y:1175
+		{
+			plpgsqlVAL.union.val = plpgsqlDollar[3].union.statement()
+		}
+	case 116:
+		plpgsqlDollar = plpgsqlS[plpgsqlpt-0 : plpgsqlpt+1]
+//line plpgsql-gen.y:1181
+		{
+			retExpr, err := plpgsqllex.(*lexer).ParseReturnExpr()
+			if err != nil {
+				return setErr(plpgsqllex, err)
+			}
+			plpgsqlVAL.union.val = retExpr
+		}
+	case 117:
+		plpgsqlDollar = plpgsqlS[plpgsqlpt-0 : plpgsqlpt+1]
+//line plpgsql-gen.y:1191
+		{
+			if plpgsqllex.(*lexer).peekForExecute() {
+
+				plpgsqllex.(*lexer).Advance(1)
+				return unimplemented(plpgsqllex, "return dynamic sql query")
+			}
+			retQuery, err := plpgsqllex.(*lexer).ParseReturnQuery()
+			if err != nil {
+				return setErr(plpgsqllex, err)
+			}
+			plpgsqlVAL.union.val = retQuery
+		}
+	case 118:
+		plpgsqlDollar = plpgsqlS[plpgsqlpt-2 : plpgsqlpt+1]
+//line plpgsql-gen.y:1208
+		{
+			return unimplemented(plpgsqllex, "empty RAISE statement")
+		}
+	case 119:
+		plpgsqlDollar = plpgsqlS[plpgsqlpt-6 : plpgsqlpt+1]
+//line plpgsql-gen.y:1212
+		{
+			plpgsqlVAL.union.val = &plpgsqltree.Raise{
+				LogLevel: plpgsqlDollar[2].str,
+				Message:  plpgsqlDollar[3].str,
+				Params:   plpgsqlDollar[4].union.exprs(),
+				Options:  plpgsqlDollar[5].union.raiseOptions(),
+			}
+		}
+	case 120:
+		plpgsqlDollar = plpgsqlS[plpgsqlpt-5 : plpgsqlpt+1]
+//line plpgsql-gen.y:1221
+		{
+			plpgsqlVAL.union.val = &plpgsqltree.Raise{
+				LogLevel: plpgsqlDollar[2].str,
+				CodeName: plpgsqlDollar[3].str,
+				Options:  plpgsqlDollar[4].union.raiseOptions(),
+			}
+		}
+	case 121:
+		plpgsqlDollar = plpgsqlS[plpgsqlpt-6 : plpgsqlpt+1]
+//line plpgsql-gen.y:1229
+		{
+			plpgsqlVAL.union.val = &plpgsqltree.Raise{
+				LogLevel: plpgsqlDollar[2].str,
+				Code:     plpgsqlDollar[4].str,
+				Options:  plpgsqlDollar[5].union.raiseOptions(),
+			}
+		}
+	case 122:
+		plpgsqlDollar = plpgsqlS[plpgsqlpt-5 : plpgsqlpt+1]
+//line plpgsql-gen.y:1237
+		{
+			plpgsqlVAL.union.val = &plpgsqltree.Raise{
+				LogLevel: plpgsqlDollar[2].str,
+				Options:  plpgsqlDollar[4].union.raiseOptions(),
+			}
+		}
+	case 129:
+		plpgsqlDollar = plpgsqlS[plpgsqlpt-0 : plpgsqlpt+1]
+//line plpgsql-gen.y:1253
+		{
+			plpgsqlVAL.str = ""
+		}
+	case 130:
+		plpgsqlDollar = plpgsqlS[plpgsqlpt-2 : plpgsqlpt+1]
+//line plpgsql-gen.y:1260
+		{
+			plpgsqlVAL.union.val = plpgsqlDollar[2].union.raiseOptions()
+		}
+	case 131:
+		plpgsqlDollar = plpgsqlS[plpgsqlpt-0 : plpgsqlpt+1]
+//line plpgsql-gen.y:1264
+		{
+			plpgsqlVAL.union.val = []plpgsqltree.RaiseOption{}
+		}
+	case 132:
+		plpgsqlDollar = plpgsqlS[plpgsqlpt-3 : plpgsqlpt+1]
+//line plpgsql-gen.y:1271
+		{
+			option := plpgsqlDollar[3].union.raiseOption()
+			plpgsqlVAL.union.val = append(plpgsqlDollar[1].union.raiseOptions(), *option)
+		}
+	case 133:
+		plpgsqlDollar = plpgsqlS[plpgsqlpt-1 : plpgsqlpt+1]
+//line plpgsql-gen.y:1276
+		{
+			option := plpgsqlDollar[1].union.raiseOption()
+			plpgsqlVAL.union.val = []plpgsqltree.RaiseOption{*option}
+		}
+	case 134:
+		plpgsqlDollar = plpgsqlS[plpgsqlpt-2 : plpgsqlpt+1]
+//line plpgsql-gen.y:1284
+		{
+
+			sqlStr, _, err := plpgsqllex.(*lexer).ReadSqlExpr(',', ';')
+			if err != nil {
+				return setErr(plpgsqllex, err)
+			}
+			optionExpr, err := plpgsqllex.(*lexer).ParseExpr(sqlStr)
+			if err != nil {
+				return setErr(plpgsqllex, err)
+			}
+			plpgsqlVAL.union.val = &plpgsqltree.RaiseOption{
+				OptType: plpgsqlDollar[1].str,
+				Expr:    optionExpr,
+			}
+		}
+	case 144:
+		plpgsqlDollar = plpgsqlS[plpgsqlpt-1 : plpgsqlpt+1]
+//line plpgsql-gen.y:1315
+		{
+			plpgsqlVAL.union.val = plpgsqlDollar[1].union.exprs()
+		}
+	case 145:
+		plpgsqlDollar = plpgsqlS[plpgsqlpt-0 : plpgsqlpt+1]
+//line plpgsql-gen.y:1319
+		{
+			plpgsqlVAL.union.val = []plpgsqltree.Expr{}
+		}
+	case 146:
+		plpgsqlDollar = plpgsqlS[plpgsqlpt-1 : plpgsqlpt+1]
+//line plpgsql-gen.y:1326
+		{
+			plpgsqlVAL.union.val = []plpgsqltree.Expr{plpgsqlDollar[1].union.expr()}
+		}
+	case 147:
+		plpgsqlDollar = plpgsqlS[plpgsqlpt-2 : plpgsqlpt+1]
+//line plpgsql-gen.y:1330
+		{
+			plpgsqlVAL.union.val = append(plpgsqlDollar[1].union.exprs(), plpgsqlDollar[2].union.expr())
+		}
+	case 148:
+		plpgsqlDollar = plpgsqlS[plpgsqlpt-1 : plpgsqlpt+1]
+//line plpgsql-gen.y:1336
+		{
+
+			sqlStr, _, err := plpgsqllex.(*lexer).ReadSqlExpr(',', ';', USING)
+			if err != nil {
+				return setErr(plpgsqllex, err)
+			}
+			param, err := plpgsqllex.(*lexer).ParseExpr(sqlStr)
+			if err != nil {
+				return setErr(plpgsqllex, err)
+			}
+			plpgsqlVAL.union.val = param
+		}
+	case 149:
+		plpgsqlDollar = plpgsqlS[plpgsqlpt-3 : plpgsqlpt+1]
+//line plpgsql-gen.y:1351
+		{
+			plpgsqlVAL.union.val = &plpgsqltree.Assert{}
+		}
+	case 150:
+		plpgsqlDollar = plpgsqlS[plpgsqlpt-0 : plpgsqlpt+1]
+//line plpgsql-gen.y:1357
+		{
+			_, terminator, err := plpgsqllex.(*lexer).ReadSqlExpr(',', ';')
+			if err != nil {
+				return setErr(plpgsqllex, err)
+			}
+			if terminator == ',' {
+				_, _, err = plpgsqllex.(*lexer).ReadSqlExpr(';')
+				if err != nil {
+					return setErr(plpgsqllex, err)
+				}
+			}
+		}
+	case 151:
+		plpgsqlDollar = plpgsqlS[plpgsqlpt-3 : plpgsqlpt+1]
+//line plpgsql-gen.y:1372
+		{
+			plpgsqlVAL.union.val = plpgsqlDollar[1].union.statements()
+		}
+	case 152:
+		plpgsqlDollar = plpgsqlS[plpgsqlpt-1 : plpgsqlpt+1]
+//line plpgsql-gen.y:1378
+		{
+			stmt, err := plpgsqllex.(*lexer).MakeExecSqlStmt()
+			if err != nil {
+				return setErr(plpgsqllex, err)
+			}
+			plpgsqlVAL.union.val = stmt
+		}
+	case 158:
+		plpgsqlDollar = plpgsqlS[plpgsqlpt-1 : plpgsqlpt+1]
+//line plpgsql-gen.y:1396
+		{
+			stmt, err := plpgsqllex.(*lexer).MakeDynamicExecuteStmt()
+			if err != nil {
+				return setErr(plpgsqllex, err)
+			}
+			plpgsqlVAL.union.val = stmt
+		}
+	case 159:
+		plpgsqlDollar = plpgsqlS[plpgsqlpt-3 : plpgsqlpt+1]
+//line plpgsql-gen.y:1406
+		{
+			plpgsqlVAL.union.val = &plpgsqltree.Open{CurVar: plpgsqltree.Variable(plpgsqlDollar[2].str)}
+		}
+	case 160:
+		plpgsqlDollar = plpgsqlS[plpgsqlpt-5 : plpgsqlpt+1]
+//line plpgsql-gen.y:1410
+		{
+			return unimplemented(plpgsqllex, "cursor for execute")
+		}
+	case 161:
+		plpgsqlDollar = plpgsqlS[plpgsqlpt-6 : plpgsqlpt+1]
+//line plpgsql-gen.y:1414
+		{
+			stmts, err := parser.Parse(plpgsqlDollar[5].str)
+			if err != nil {
+				return setErr(plpgsqllex, err)
+			}
+			if len(stmts) != 1 {
+				return setErr(plpgsqllex, errors.New("expected exactly one SQL statement for cursor"))
+			}
+			ann := tree.MakeAnnotations(stmts[0].NumAnnotations)
+			plpgsqlVAL.union.val = &plpgsqltree.Open{
+				CurVar:      plpgsqltree.Variable(plpgsqlDollar[2].str),
+				Scroll:      plpgsqlDollar[3].union.cursorScrollOption(),
+				Query:       stmts[0].AST,
+				Annotations: &ann,
+			}
+		}
+	case 162:
+		plpgsqlDollar = plpgsqlS[plpgsqlpt-1 : plpgsqlpt+1]
+//line plpgsql-gen.y:1433
+		{
+			fetch, err := plpgsqllex.(*lexer).MakeFetchOrMoveStmt(false)
+			if err != nil {
+				return setErr(plpgsqllex, err)
+			}
+			plpgsqlVAL.union.val = fetch
+		}
+	case 163:
+		plpgsqlDollar = plpgsqlS[plpgsqlpt-1 : plpgsqlpt+1]
+//line plpgsql-gen.y:1443
+		{
+			move, err := plpgsqllex.(*lexer).MakeFetchOrMoveStmt(true)
+			if err != nil {
+				return setErr(plpgsqllex, err)
+			}
+			plpgsqlVAL.union.val = move
+		}
+	case 164:
+		plpgsqlDollar = plpgsqlS[plpgsqlpt-3 : plpgsqlpt+1]
+//line plpgsql-gen.y:1453
+		{
+			plpgsqlVAL.union.val = &plpgsqltree.Close{CurVar: plpgsqltree.Variable(plpgsqlDollar[2].str)}
+		}
+	case 165:
+		plpgsqlDollar = plpgsqlS[plpgsqlpt-2 : plpgsqlpt+1]
+//line plpgsql-gen.y:1459
+		{
+			plpgsqlVAL.union.val = &plpgsqltree.Null{}
+		}
+	case 166:
+		plpgsqlDollar = plpgsqlS[plpgsqlpt-3 : plpgsqlpt+1]
+//line plpgsql-gen.y:1465
+		{
+			plpgsqlVAL.union.val = &plpgsqltree.TransactionControl{Chain: plpgsqlDollar[2].union.bool()}
+		}
+	case 167:
+		plpgsqlDollar = plpgsqlS[plpgsqlpt-3 : plpgsqlpt+1]
+//line plpgsql-gen.y:1471
+		{
+			plpgsqlVAL.union.val = &plpgsqltree.TransactionControl{Chain: plpgsqlDollar[2].union.bool(), Rollback: true}
+		}
+	case 168:
+		plpgsqlDollar = plpgsqlS[plpgsqlpt-2 : plpgsqlpt+1]
+//line plpgsql-gen.y:1478
+		{
+			plpgsqlVAL.union.val = true
+		}
+	case 169:
+		plpgsqlDollar = plpgsqlS[plpgsqlpt-3 : plpgsqlpt+1]
+//line plpgsql-gen.y:1482
+		{
+			plpgsqlVAL.union.val = false
+		}
+	case 170:
+		plpgsqlDollar = plpgsqlS[plpgsqlpt-0 : plpgsqlpt+1]
+//line plpgsql-gen.y:1486
+		{
+			plpgsqlVAL.union.val = false
+		}
+	case 171:
+		plpgsqlDollar = plpgsqlS[plpgsqlpt-0 : plpgsqlpt+1]
+//line plpgsql-gen.y:1491
+		{
+			plpgsqlVAL.union.val = []plpgsqltree.Exception(nil)
+		}
+	case 172:
+		plpgsqlDollar = plpgsqlS[plpgsqlpt-2 : plpgsqlpt+1]
+//line plpgsql-gen.y:1495
+		{
+			plpgsqlVAL.union.val = plpgsqlDollar[2].union.exceptions()
+		}
+	case 173:
+		plpgsqlDollar = plpgsqlS[plpgsqlpt-2 : plpgsqlpt+1]
+//line plpgsql-gen.y:1501
+		{
+			e := plpgsqlDollar[2].union.exception()
+			plpgsqlVAL.union.val = append(plpgsqlDollar[1].union.exceptions(), *e)
+		}
+	case 174:
+		plpgsqlDollar = plpgsqlS[plpgsqlpt-1 : plpgsqlpt+1]
+//line plpgsql-gen.y:1506
+		{
+			e := plpgsqlDollar[1].union.exception()
+			plpgsqlVAL.union.val = []plpgsqltree.Exception{*e}
+		}
+	case 175:
+		plpgsqlDollar = plpgsqlS[plpgsqlpt-4 : plpgsqlpt+1]
+//line plpgsql-gen.y:1513
+		{
+			plpgsqlVAL.union.val = &plpgsqltree.Exception{
+				Conditions: plpgsqlDollar[2].union.conditions(),
+				Action:     plpgsqlDollar[4].union.statements(),
+			}
+		}
+	case 176:
+		plpgsqlDollar = plpgsqlS[plpgsqlpt-3 : plpgsqlpt+1]
+//line plpgsql-gen.y:1522
+		{
+			c := plpgsqlDollar[3].union.condition()
+			plpgsqlVAL.union.val = append(plpgsqlDollar[1].union.conditions(), *c)
+		}
+	case 177:
+		plpgsqlDollar = plpgsqlS[plpgsqlpt-1 : plpgsqlpt+1]
+//line plpgsql-gen.y:1527
+		{
+			c := plpgsqlDollar[1].union.condition()
+			plpgsqlVAL.union.val = []plpgsqltree.Condition{*c}
+		}
+	case 178:
+		plpgsqlDollar = plpgsqlS[plpgsqlpt-1 : plpgsqlpt+1]
+//line plpgsql-gen.y:1534
+		{
+			plpgsqlVAL.union.val = &plpgsqltree.Condition{SqlErrName: plpgsqlDollar[1].str}
+		}
+	case 179:
+		plpgsqlDollar = plpgsqlS[plpgsqlpt-2 : plpgsqlpt+1]
+//line plpgsql-gen.y:1538
+		{
+			plpgsqlVAL.union.val = &plpgsqltree.Condition{SqlErrState: plpgsqlDollar[2].str}
+		}
+	case 180:
+		plpgsqlDollar = plpgsqlS[plpgsqlpt-0 : plpgsqlpt+1]
+//line plpgsql-gen.y:1544
+		{
+			sqlStr, _, err := plpgsqllex.(*lexer).ReadSqlExpr(';')
+			if err != nil {
+				return setErr(plpgsqllex, err)
+			}
+			plpgsqlVAL.str = sqlStr
+		}
+	case 181:
+		plpgsqlDollar = plpgsqlS[plpgsqlpt-0 : plpgsqlpt+1]
+//line plpgsql-gen.y:1554
+		{
+			sqlStr, _, err := plpgsqllex.(*lexer).ReadSqlStatement(';')
+			if err != nil {
+				return setErr(plpgsqllex, err)
+			}
+			plpgsqlVAL.str = sqlStr
+		}
+	case 182:
+		plpgsqlDollar = plpgsqlS[plpgsqlpt-0 : plpgsqlpt+1]
+//line plpgsql-gen.y:1564
+		{
+			sqlStr, _, err := plpgsqllex.(*lexer).ReadSqlExpr(THEN)
+			if err != nil {
+				return setErr(plpgsqllex, err)
+			}
+			plpgsqlVAL.str = sqlStr
+		}
+	case 183:
+		plpgsqlDollar = plpgsqlS[plpgsqlpt-0 : plpgsqlpt+1]
+//line plpgsql-gen.y:1574
+		{
+			sqlStr, _, err := plpgsqllex.(*lexer).ReadSqlExpr(LOOP)
+			if err != nil {
+				return setErr(plpgsqllex, err)
+			}
+			plpgsqlVAL.str = sqlStr
+		}
+	case 184:
+		plpgsqlDollar = plpgsqlS[plpgsqlpt-0 : plpgsqlpt+1]
+//line plpgsql-gen.y:1584
+		{
+			sqlStr, _, err := plpgsqllex.(*lexer).ReadSqlExpr(')')
+			if err != nil {
+				return setErr(plpgsqllex, err)
+			}
+			plpgsqlVAL.str = sqlStr
+		}
+	case 185:
+		plpgsqlDollar = plpgsqlS[plpgsqlpt-0 : plpgsqlpt+1]
+//line plpgsql-gen.y:1594
+		{
+			plpgsqlVAL.str = ""
+		}
+	case 186:
+		plpgsqlDollar = plpgsqlS[plpgsqlpt-3 : plpgsqlpt+1]
+//line plpgsql-gen.y:1598
+		{
+			plpgsqlVAL.str = plpgsqlDollar[2].str
+		}
+	case 187:
+		plpgsqlDollar = plpgsqlS[plpgsqlpt-0 : plpgsqlpt+1]
+//line plpgsql-gen.y:1604
+		{
+			plpgsqlVAL.str = ""
+		}
+	case 188:
+		plpgsqlDollar = plpgsqlS[plpgsqlpt-3 : plpgsqlpt+1]
+//line plpgsql-gen.y:1608
+		{
+			plpgsqlVAL.str = plpgsqlDollar[2].str
+		}
+	case 189:
+		plpgsqlDollar = plpgsqlS[plpgsqlpt-0 : plpgsqlpt+1]
+//line plpgsql-gen.y:1614
+		{
+			plpgsqlVAL.str = ""
+		}
+	case 190:
+		plpgsqlDollar = plpgsqlS[plpgsqlpt-1 : plpgsqlpt+1]
+//line plpgsql-gen.y:1618
+		{
+			plpgsqlVAL.str = plpgsqlDollar[1].str
+		}
+	case 191:
+		plpgsqlDollar = plpgsqlS[plpgsqlpt-1 : plpgsqlpt+1]
+//line plpgsql-gen.y:1624
+		{
+		}
+	case 192:
+		plpgsqlDollar = plpgsqlS[plpgsqlpt-3 : plpgsqlpt+1]
+//line plpgsql-gen.y:1626
+		{
+			expr, err := plpgsqllex.(*lexer).ParseExpr(plpgsqlDollar[2].str)
+			if err != nil {
+				return setErr(plpgsqllex, err)
+			}
+			plpgsqlVAL.union.val = expr
+		}
+	}
+	goto plpgsqlstack /* stack new state and value */
+}
diff --git a/pkg/sql/plpgsql/parser/plpgsql.y b/pkg/sql/plpgsql/parser/plpgsql.y
new file mode 100644
index 0000000..3534a77
--- /dev/null
+++ b/pkg/sql/plpgsql/parser/plpgsql.y
@@ -0,0 +1,1756 @@
+%{
+package parser
+
+import (
+  "strings"
+
+  "github.com/cockroachdb/cockroach/pkg/build"
+  "github.com/cockroachdb/cockroach/pkg/sql/parser"
+  "github.com/cockroachdb/cockroach/pkg/sql/parser/statements"
+  "github.com/cockroachdb/cockroach/pkg/sql/scanner"
+  "github.com/cockroachdb/cockroach/pkg/sql/sem/tree"
+  "github.com/cockroachdb/cockroach/pkg/sql/sem/plpgsqltree"
+  "github.com/cockroachdb/cockroach/pkg/sql/types"
+  "github.com/cockroachdb/errors"
+  "github.com/cockroachdb/redact"
+)
+%}
+
+%{
+func setErr(plpgsqllex plpgsqlLexer, err error) int {
+    plpgsqllex.(*lexer).setErr(err)
+    return 1
+}
+
+func setErrNoDetails(plpgsqllex plpgsqlLexer, err error) int {
+    plpgsqllex.(*lexer).setErrNoDetails(err)
+    return 1
+}
+
+func unimplemented(plpgsqllex plpgsqlLexer, feature string) int {
+    plpgsqllex.(*lexer).Unimplemented(feature)
+    return 1
+}
+
+//functions to cast plpgsqlSymType/sqlSymUnion to other types.
+var _ scanner.ScanSymType = &plpgsqlSymType{}
+
+func (s *plpgsqlSymType) ID() int32 {
+  return s.id
+}
+
+func (s *plpgsqlSymType) SetID(id int32) {
+  s.id = id
+}
+
+func (s *plpgsqlSymType) Pos() int32 {
+  return s.pos
+}
+
+func (s *plpgsqlSymType) SetPos(pos int32) {
+  s.pos = pos
+}
+
+func (s *plpgsqlSymType) Str() string {
+  return s.str
+}
+
+func (s *plpgsqlSymType) SetStr(str string) {
+  s.str = str
+}
+
+func (s *plpgsqlSymType) UnionVal() interface{} {
+  return s.union.val
+}
+
+func (s *plpgsqlSymType) SetUnionVal(val interface{}) {
+  s.union.val = val
+}
+
+func (s *plpgsqlSymType) plpgsqlScanSymType() {}
+
+type plpgsqlSymUnion struct {
+    val interface{}
+}
+
+func (u *plpgsqlSymUnion) block() *plpgsqltree.Block {
+    return u.val.(*plpgsqltree.Block)
+}
+
+func (u *plpgsqlSymUnion) caseWhen() *plpgsqltree.CaseWhen {
+    return u.val.(*plpgsqltree.CaseWhen)
+}
+
+func (u *plpgsqlSymUnion) caseWhens() []*plpgsqltree.CaseWhen {
+    return u.val.([]*plpgsqltree.CaseWhen)
+}
+
+func (u *plpgsqlSymUnion) statement() plpgsqltree.Statement {
+    return u.val.(plpgsqltree.Statement)
+}
+
+func (u *plpgsqlSymUnion) statements() []plpgsqltree.Statement {
+    return u.val.([]plpgsqltree.Statement)
+}
+
+func (u *plpgsqlSymUnion) int32() int32 {
+    return u.val.(int32)
+}
+
+func (u *plpgsqlSymUnion) uint32() uint32 {
+    return u.val.(uint32)
+}
+
+func (u *plpgsqlSymUnion) bool() bool {
+    return u.val.(bool)
+}
+
+func (u *plpgsqlSymUnion) numVal() *tree.NumVal {
+    return u.val.(*tree.NumVal)
+}
+
+func (u *plpgsqlSymUnion) typ() tree.ResolvableTypeReference {
+    return u.val.(tree.ResolvableTypeReference)
+}
+
+func (u *plpgsqlSymUnion) getDiagnosticsKind() plpgsqltree.GetDiagnosticsKind {
+    return u.val.(plpgsqltree.GetDiagnosticsKind)
+}
+
+func (u *plpgsqlSymUnion) getDiagnosticsItem() *plpgsqltree.GetDiagnosticsItem {
+    return u.val.(*plpgsqltree.GetDiagnosticsItem)
+}
+
+func (u *plpgsqlSymUnion) getDiagnosticsItemList() plpgsqltree.GetDiagnosticsItemList {
+    return u.val.(plpgsqltree.GetDiagnosticsItemList)
+}
+
+func (u *plpgsqlSymUnion) elseIf() []plpgsqltree.ElseIf {
+    return u.val.([]plpgsqltree.ElseIf)
+}
+
+func (u *plpgsqlSymUnion) open() *plpgsqltree.Open {
+    return u.val.(*plpgsqltree.Open)
+}
+
+func (u *plpgsqlSymUnion) expr() plpgsqltree.Expr {
+    if u.val == nil {
+        return nil
+    }
+    return u.val.(plpgsqltree.Expr)
+}
+
+func (u *plpgsqlSymUnion) exprs() []plpgsqltree.Expr {
+    return u.val.([]plpgsqltree.Expr)
+}
+
+func (u *plpgsqlSymUnion) raiseOption() *plpgsqltree.RaiseOption {
+    return u.val.(*plpgsqltree.RaiseOption)
+}
+
+func (u *plpgsqlSymUnion) raiseOptions() []plpgsqltree.RaiseOption {
+    return u.val.([]plpgsqltree.RaiseOption)
+}
+
+
+func (u *plpgsqlSymUnion) exception() *plpgsqltree.Exception {
+    return u.val.(*plpgsqltree.Exception)
+}
+
+func (u *plpgsqlSymUnion) exceptions() []plpgsqltree.Exception {
+    return u.val.([]plpgsqltree.Exception)
+}
+
+func (u *plpgsqlSymUnion) condition() *plpgsqltree.Condition {
+    return u.val.(*plpgsqltree.Condition)
+}
+
+func (u *plpgsqlSymUnion) conditions() []plpgsqltree.Condition {
+    return u.val.([]plpgsqltree.Condition)
+}
+
+func (u *plpgsqlSymUnion) cursorScrollOption() tree.CursorScrollOption {
+    return u.val.(tree.CursorScrollOption)
+}
+
+func (u *plpgsqlSymUnion) sqlStatement() tree.Statement {
+    return u.val.(statements.Statement[tree.Statement]).AST
+}
+
+func (u *plpgsqlSymUnion) numAnnotations() tree.AnnotationIdx {
+    return u.val.(statements.Statement[tree.Statement]).NumAnnotations
+}
+
+func (u *plpgsqlSymUnion) variables() []plpgsqltree.Variable {
+		return u.val.([]plpgsqltree.Variable)
+}
+
+func (u *plpgsqlSymUnion) forLoopControl() plpgsqltree.ForLoopControl {
+		return u.val.(plpgsqltree.ForLoopControl)
+}
+
+func (u *plpgsqlSymUnion) doBlockOptions() tree.DoBlockOptions {
+    return u.val.(tree.DoBlockOptions)
+}
+
+func (u *plpgsqlSymUnion) doBlockOption() tree.DoBlockOption {
+    return u.val.(tree.DoBlockOption)
+}
+
+%}
+/*
+ * Basic non-keyword token types.  These are hard-wired into the core lexer.
+ * They must be listed first so that their numeric codes do not depend on
+ * the set of keywords.  Keep this list in sync with backend/parser/gram.y!
+ *
+ * Some of these are not directly referenced in this file, but they must be
+ * here anyway.
+ */
+%token <str> IDENT UIDENT FCONST SCONST USCONST BCONST XCONST Op
+%token <*tree.NumVal>	ICONST PARAM
+%token <str> TYPECAST DOT_DOT COLON_EQUALS EQUALS_GREATER
+%token <str> LESS_EQUALS GREATER_EQUALS NOT_EQUALS
+
+/*
+ * Other tokens recognized by plpgsql's lexer interface layer (pl_scanner.c).
+ */
+%token <str> LESS_LESS GREATER_GREATER
+
+/*
+ * Keyword tokens.  Some of these are reserved and some are not;
+ * see pl_scanner.c for info.  Be sure unreserved keywords are listed
+ * in the "unreserved_keyword" production below.
+ */
+%token <str>  ABSOLUTE
+%token <str>  ALIAS
+%token <str>  ALL
+%token <str>  AND
+%token <str>  ARRAY
+%token <str>  ASSERT
+%token <str>  BACKWARD
+%token <str>  BEGIN
+%token <str>  BY
+%token <str>  CALL
+%token <str>  CASE
+%token <str>  CHAIN
+%token <str>  CLOSE
+%token <str>  COLLATE
+%token <str>  COLUMN
+%token <str>  COLUMN_NAME
+%token <str>  COMMIT
+%token <str>  CONSTANT
+%token <str>  CONSTRAINT
+%token <str>  CONSTRAINT_NAME
+%token <str>  CONTINUE
+%token <str>  CURRENT
+%token <str>  CURSOR
+%token <str>  DATATYPE
+%token <str>  DEBUG
+%token <str>  DECLARE
+%token <str>  DEFAULT
+%token <str>  DETAIL
+%token <str>  DIAGNOSTICS
+%token <str>  DO
+%token <str>  DUMP
+%token <str>  ELSE
+%token <str>  ELSIF
+%token <str>  END
+%token <str>  END_CASE
+%token <str>  END_IF
+%token <str>  ERRCODE
+%token <str>  ERROR
+%token <str>  EXCEPTION
+%token <str>  EXECUTE
+%token <str>  EXIT
+%token <str>  FETCH
+%token <str>  FIRST
+%token <str>  FOR
+%token <str>  FOREACH
+%token <str>  FORWARD
+%token <str>  FROM
+%token <str>  GET
+%token <str>  HINT
+%token <str>  IF
+%token <str>  IMPORT
+%token <str>  IN
+%token <str>  INFO
+%token <str>  INSERT
+%token <str>  INTO
+%token <str>  IS
+%token <str>  LANGUAGE
+%token <str>  LAST
+%token <str>  LOG
+%token <str>  LOOP
+%token <str>  MERGE
+%token <str>  MESSAGE
+%token <str>  MESSAGE_TEXT
+%token <str>  MOVE
+%token <str>  NEXT
+%token <str>  NO
+%token <str>  NO_SCROLL
+%token <str>  NOT
+%token <str>  NOTICE
+%token <str>  NULL
+%token <str>  OPEN
+%token <str>  OPTION
+%token <str>  OR
+%token <str>  PERFORM
+%token <str>  PG_CONTEXT
+%token <str>  PG_DATATYPE_NAME
+%token <str>  PG_EXCEPTION_CONTEXT
+%token <str>  PG_EXCEPTION_DETAIL
+%token <str>  PG_EXCEPTION_HINT
+%token <str>  PRINT_STRICT_PARAMS
+%token <str>  PRIOR
+%token <str>  QUERY
+%token <str>  RAISE
+%token <str>  RELATIVE
+%token <str>  RETURN
+%token <str>  RETURN_NEXT
+%token <str>  RETURN_QUERY
+%token <str>  RETURNED_SQLSTATE
+%token <str>  REVERSE
+%token <str>  ROLLBACK
+%token <str>  ROW_COUNT
+%token <str>  ROWTYPE
+%token <str>  SCHEMA
+%token <str>  SCHEMA_NAME
+%token <str>  SCROLL
+%token <str>  SLICE
+%token <str>  SQLSTATE
+%token <str>  STACKED
+%token <str>  STRICT
+%token <str>  TABLE
+%token <str>  TABLE_NAME
+%token <str>  THEN
+%token <str>  TO
+%token <str>  TYPE
+%token <str>  UPSERT
+%token <str>  USE_COLUMN
+%token <str>  USE_VARIABLE
+%token <str>  USING
+%token <str>  VARIABLE_CONFLICT
+%token <str>  WARNING
+%token <str>  WHEN
+%token <str>  WHILE
+
+
+%union {
+  id    int32
+  pos   int32
+  str   string
+  union plpgsqlSymUnion
+}
+
+%type <str> decl_varname decl_defkey
+%type <bool> decl_const decl_notnull
+%type <plpgsqltree.Expr>	decl_defval decl_cursor_query
+%type <tree.ResolvableTypeReference>	decl_datatype
+%type <str>	decl_collate
+
+%type <str>	expr_until_semi expr_until_paren stmt_until_semi
+%type <str>	expr_until_then expr_until_loop opt_expr_until_when
+%type <plpgsqltree.Expr> return_expr opt_exitcond
+
+%type <[]plpgsqltree.Variable> for_target
+%type <*tree.NumVal> foreach_slice
+%type <plpgsqltree.ForLoopControl> for_control
+
+%type <str> any_identifier opt_block_label opt_loop_label opt_label
+%type <str> opt_error_level option_type
+
+%type <tree.DoBlockOptions> do_stmt_opt_list
+%type <tree.DoBlockOption> do_stmt_opt_item
+
+%type <[]plpgsqltree.Statement> proc_sect
+%type <[]plpgsqltree.ElseIf> stmt_elsifs
+%type <[]plpgsqltree.Statement> stmt_else loop_body
+%type <plpgsqltree.Statement>  pl_block
+%type <plpgsqltree.Statement>	proc_stmt
+%type <plpgsqltree.Statement>	stmt_assign stmt_if stmt_loop stmt_while stmt_exit stmt_continue
+%type <plpgsqltree.Statement>	stmt_return stmt_raise stmt_assert stmt_execsql
+%type <plpgsqltree.Statement>	stmt_dynexecute stmt_for stmt_perform stmt_call stmt_do stmt_getdiag
+%type <plpgsqltree.Statement>	stmt_open stmt_fetch stmt_move stmt_close stmt_null
+%type <plpgsqltree.Statement>	stmt_commit stmt_rollback
+%type <plpgsqltree.Statement>	stmt_case stmt_foreach_a
+%type <plpgsqltree.Statement> return_query
+
+%type <plpgsqltree.Statement> decl_statement
+%type <[]plpgsqltree.Statement> decl_sect opt_decl_stmts decl_stmts
+
+%type <[]plpgsqltree.Exception> exception_sect proc_exceptions
+%type <*plpgsqltree.Exception>	proc_exception
+%type <[]plpgsqltree.Condition> proc_conditions
+%type <*plpgsqltree.Condition> proc_condition
+
+%type <*plpgsqltree.CaseWhen>	case_when
+%type <[]*plpgsqltree.CaseWhen>	case_when_list
+%type <[]plpgsqltree.Statement> opt_case_else
+
+%type <bool>	getdiag_area_opt
+%type <plpgsqltree.GetDiagnosticsItemList>	getdiag_list
+%type <*plpgsqltree.GetDiagnosticsItem> getdiag_list_item
+%type <int32> getdiag_item
+
+%type <*plpgsqltree.RaiseOption> option_expr
+%type <[]plpgsqltree.RaiseOption> option_exprs opt_option_exprs
+%type <plpgsqltree.Expr> format_expr
+%type <[]plpgsqltree.Expr> opt_format_exprs format_exprs
+
+%type <tree.CursorScrollOption>	opt_scrollable
+
+%type <bool>	opt_transaction_chain
+
+%type <str>	unreserved_keyword
+%%
+
+pl_function:
+  pl_block opt_semi
+  {
+    plpgsqllex.(*lexer).SetStmt($1.statement())
+  }
+
+opt_semi:
+| ';'
+;
+
+pl_block: opt_block_label decl_sect BEGIN proc_sect exception_sect END opt_label
+  {
+    blockLabel, blockEndLabel := $1, $7
+    if err := checkLoopLabels(blockLabel, blockEndLabel); err != nil {
+      return setErr(plpgsqllex, err)
+    }
+    $$.val = &plpgsqltree.Block{
+      Label: $1,
+      Decls: $2.statements(),
+      Body: $4.statements(),
+      Exceptions: $5.exceptions(),
+    }
+  }
+;
+
+decl_sect: DECLARE opt_decl_stmts
+  {
+    $$.val = $2.statements()
+  }
+| /* EMPTY */
+  {
+    // Use a nil slice to indicate DECLARE was not used.
+    $$.val = []plpgsqltree.Statement(nil)
+  }
+;
+
+opt_decl_stmts: decl_stmts
+  {
+    $$.val = $1.statements()
+  }
+| /* EMPTY */
+  {
+    $$.val = []plpgsqltree.Statement{}
+  }
+;
+
+opt_declare: DECLARE {}
+| {}
+;
+
+decl_stmts: decl_stmts opt_declare decl_statement
+  {
+    decs := $1.statements()
+    dec := $3.statement()
+    $$.val = append(decs, dec)
+  }
+| decl_statement
+  {
+    dec := $1.statement()
+    $$.val = []plpgsqltree.Statement{dec}
+	}
+;
+
+decl_statement: decl_varname decl_const decl_datatype decl_collate decl_notnull decl_defval
+  {
+    $$.val = &plpgsqltree.Declaration{
+      Var: plpgsqltree.Variable($1),
+      Constant: $2.bool(),
+      Typ: $3.typ(),
+      Collate: $4,
+      NotNull: $5.bool(),
+      Expr: $6.expr(),
+    }
+  }
+| decl_varname ALIAS FOR decl_aliasitem ';'
+  {
+    return unimplemented(plpgsqllex, "alias for")
+  }
+| decl_varname opt_scrollable CURSOR decl_cursor_args decl_is_for decl_cursor_query
+  {
+    ann := tree.MakeAnnotations($6.numAnnotations())
+    $$.val = &plpgsqltree.CursorDeclaration{
+      Name: plpgsqltree.Variable($1),
+      Scroll: $2.cursorScrollOption(),
+      Query: $6.sqlStatement(),
+      Annotations: &ann,
+    }
+  }
+;
+
+opt_scrollable:
+  {
+    $$.val = tree.UnspecifiedScroll
+  }
+| NO_SCROLL SCROLL
+  {
+    $$.val = tree.NoScroll
+  }
+| SCROLL
+  {
+    $$.val = tree.Scroll
+  }
+;
+
+decl_cursor_query: stmt_until_semi ';'
+  {
+    stmts, err := parser.Parse($1)
+    if err != nil {
+      return setErr(plpgsqllex, err)
+    }
+    if len(stmts) != 1 {
+      return setErr(plpgsqllex, errors.New("expected exactly one SQL statement for cursor"))
+    }
+    $$.val = stmts[0]
+  }
+;
+
+decl_cursor_args: '('
+  {
+    return unimplemented(plpgsqllex, "cursor arguments")
+  }
+| /* EMPTY */
+  {
+  }
+;
+
+decl_cursor_arglist: decl_cursor_arg
+  {
+  }
+| decl_cursor_arglist ',' decl_cursor_arg
+  {
+  }
+;
+
+decl_cursor_arg: decl_varname decl_datatype
+  {
+  }
+;
+
+decl_is_for:
+  IS   /* Oracle */
+| FOR  /* SQL standard */
+
+decl_aliasitem: IDENT
+  {
+  }
+| unreserved_keyword
+  {
+  }
+;
+
+decl_varname: IDENT
+| unreserved_keyword
+;
+
+decl_const:
+  {
+    $$.val = false
+  }
+| CONSTANT
+  {
+    $$.val = true
+  }
+;
+
+decl_datatype:
+  {
+    // Read until reaching one of the tokens that can follow a declaration
+    // data type.
+    sqlStr, _, err := plpgsqllex.(*lexer).ReadSqlExpr(
+      ';', COLLATE, NOT, '=', COLON_EQUALS, DECLARE,
+    )
+    if err != nil {
+      return setErr(plpgsqllex, err)
+    }
+    // This is an inlined version of GetTypeFromValidSQLSyntax which doesn't
+    // return an assertion failure.
+    castExpr, err := plpgsqllex.(*lexer).ParseExpr("1::" + sqlStr)
+    if err != nil {
+      return setErr(plpgsqllex, errors.New("unable to parse type of variable declaration"))
+    }
+    switch t := castExpr.(type) {
+    case *tree.CollateExpr:
+      $$.val = types.MakeCollatedString(types.String, t.Locale)
+    case *tree.CastExpr:
+      $$.val = t.Type
+    default:
+      err := errors.New("unable to parse type of variable declaration")
+      if strings.Contains(sqlStr, "%") {
+        err = errors.WithIssueLink(errors.WithHint(err,
+          "you may have attempted to use %TYPE or %ROWTYPE syntax, which is unsupported.",
+        ), errors.IssueLink{IssueURL: build.MakeIssueURL(114676)})
+      }
+      return setErr(plpgsqllex, err)
+    }
+  }
+;
+
+decl_collate:
+  {
+    $$ = ""
+  }
+| COLLATE IDENT
+  {
+    $$ = $2
+  }
+| COLLATE unreserved_keyword
+  {
+    $$ = $2
+  }
+;
+
+decl_notnull:
+  {
+    $$.val = false
+  }
+| NOT NULL
+  {
+    $$.val = true
+  }
+;
+
+decl_defval: ';'
+  {
+    $$.val = (plpgsqltree.Expr)(nil)
+  }
+| decl_defkey ';'
+  {
+    expr, err := plpgsqllex.(*lexer).ParseExpr($1)
+    if err != nil {
+      return setErr(plpgsqllex, err)
+    }
+    $$.val = expr
+  }
+;
+
+decl_defkey: assign_operator
+  {
+    sqlStr, _, err := plpgsqllex.(*lexer).ReadSqlExpr(';')
+    if err != nil {
+      return setErr(plpgsqllex, err)
+    }
+    $$ = sqlStr
+  }
+| DEFAULT
+  {
+    sqlStr, _, err := plpgsqllex.(*lexer).ReadSqlExpr(';')
+    if err != nil {
+      return setErr(plpgsqllex, err)
+    }
+    $$ = sqlStr
+  }
+;
+
+/*
+ * Ada-based PL/SQL uses := for assignment and variable defaults, while
+ * the SQL standard uses equals for these cases and for GET
+ * DIAGNOSTICS, so we support both.  FOR and OPEN only support :=.
+ */
+assign_operator: '='
+| COLON_EQUALS
+;
+
+proc_sect:
+  {
+    $$.val = []plpgsqltree.Statement{}
+  }
+| proc_sect proc_stmt
+  {
+    stmts := $1.statements()
+    stmts = append(stmts, $2.statement())
+    $$.val = stmts
+  }
+;
+
+proc_stmt:pl_block ';'
+  {
+    $$.val = $1.block()
+  }
+| stmt_assign
+  {
+    $$.val = $1.statement()
+  }
+| stmt_if
+  {
+    $$.val = $1.statement()
+  }
+| stmt_case
+  {
+    $$.val = $1.statement()
+  }
+| stmt_loop
+  {
+    $$.val = $1.statement()
+  }
+| stmt_while
+  {
+    $$.val = $1.statement()
+  }
+| stmt_for
+  { }
+| stmt_foreach_a
+  { }
+| stmt_exit
+  {
+    $$.val = $1.statement()
+  }
+| stmt_continue
+  {
+    $$.val = $1.statement()
+  }
+| stmt_return
+  {
+    $$.val = $1.statement()
+  }
+| stmt_raise
+  {
+    $$.val = $1.statement()
+  }
+| stmt_assert
+  {
+    $$.val = $1.statement()
+  }
+| stmt_execsql
+  {
+    $$.val = $1.statement()
+  }
+| stmt_dynexecute
+  {
+    $$.val = $1.statement()
+  }
+| stmt_perform
+  { }
+| stmt_call
+  {
+    $$.val = $1.statement()
+  }
+| stmt_do
+  {
+    $$.val = $1.statement()
+  }
+| stmt_getdiag
+  { }
+| stmt_open
+  {
+    $$.val = $1.statement()
+  }
+| stmt_fetch
+  {
+    $$.val = $1.statement()
+  }
+| stmt_move
+  {
+    $$.val = $1.statement()
+  }
+| stmt_close
+  {
+    $$.val = $1.statement()
+  }
+| stmt_null
+  {
+    $$.val = $1.statement()
+  }
+| stmt_commit
+  {
+    $$.val = $1.statement()
+  }
+| stmt_rollback
+  {
+    $$.val = $1.statement()
+  }
+;
+
+stmt_perform: PERFORM stmt_until_semi ';'
+  {
+    return unimplemented(plpgsqllex, "perform")
+  }
+;
+
+stmt_call: CALL expr_until_semi ';'
+  {
+    expr, err := plpgsqllex.(*lexer).ParseExpr($2)
+    if err != nil {
+      return setErr(plpgsqllex, err)
+    }
+    proc, ok := expr.(*tree.FuncExpr)
+    if !ok {
+      return setErr(plpgsqllex,
+        errors.New("CALL statement target must be a stored procedure"),
+      )
+    }
+    // Set the InCall flag to true to indicate that this is a CALL statement.
+    proc.InCall = true
+    $$.val = &plpgsqltree.Call{Proc: proc}
+  }
+;
+
+stmt_do:
+  DO do_stmt_opt_list ';'
+  {
+    doBlock, err := makeDoStmt($2.doBlockOptions())
+    if err != nil {
+      return setErrNoDetails(plpgsqllex, err)
+    }
+    $$.val = doBlock
+  }
+;
+
+do_stmt_opt_list:
+  do_stmt_opt_item
+  {
+    $$.val = tree.DoBlockOptions{$1.doBlockOption()}
+  }
+| do_stmt_opt_list do_stmt_opt_item
+  {
+    $$.val = append($1.doBlockOptions(), $2.doBlockOption())
+  }
+;
+
+do_stmt_opt_item:
+  SCONST
+  {
+    $$.val = tree.RoutineBodyStr($1)
+  }
+| LANGUAGE any_identifier
+  {
+    lang, err := tree.AsRoutineLanguage($2)
+    if err != nil {
+      return setErr(plpgsqllex, err)
+    }
+    $$.val = lang
+  }
+;
+
+stmt_assign: IDENT assign_operator expr_until_semi ';'
+  {
+    expr, err := plpgsqllex.(*lexer).ParseExpr($3)
+    if err != nil {
+      return setErr(plpgsqllex, err)
+    }
+    $$.val = &plpgsqltree.Assignment{
+      Var: plpgsqltree.Variable($1),
+      Value: expr,
+    }
+  }
+| IDENT '.' IDENT assign_operator expr_until_semi ';'
+  {
+    // TODO(#91779, #122322): allow arbitrary nesting of indirection.
+    expr, err := plpgsqllex.(*lexer).ParseExpr($5)
+    if err != nil {
+      return setErr(plpgsqllex, err)
+    }
+    $$.val = &plpgsqltree.Assignment{
+      Var: plpgsqltree.Variable($1),
+      Value: expr,
+      Indirection: tree.Name($3),
+    }
+  }
+;
+
+stmt_getdiag: GET getdiag_area_opt DIAGNOSTICS getdiag_list ';'
+  {
+  $$.val = &plpgsqltree.GetDiagnostics{
+    IsStacked: $2.bool(),
+    DiagItems: $4.getDiagnosticsItemList(),
+  }
+  // TODO(drewk): Check information items are valid for area option.
+  }
+;
+
+getdiag_area_opt:
+  {
+    $$.val = false
+  }
+| CURRENT
+  {
+    $$.val = false
+  }
+| STACKED
+  {
+    $$.val = true
+  }
+;
+
+getdiag_list: getdiag_list ',' getdiag_list_item
+  {
+    $$.val = append($1.getDiagnosticsItemList(), $3.getDiagnosticsItem())
+  }
+| getdiag_list_item
+  {
+    $$.val = plpgsqltree.GetDiagnosticsItemList{$1.getDiagnosticsItem()}
+  }
+;
+
+getdiag_list_item: IDENT assign_operator getdiag_item
+  {
+    $$.val = &plpgsqltree.GetDiagnosticsItem{
+      Kind : $3.getDiagnosticsKind(),
+      TargetName: $1,
+      // TODO(drewk): set the target from $1.
+    }
+  }
+;
+
+getdiag_item: unreserved_keyword {
+  switch $1 {
+    case "row_count":
+      $$.val = plpgsqltree.GetDiagnosticsRowCount;
+    case "pg_context":
+      $$.val = plpgsqltree.GetDiagnosticsContext;
+    case "pg_exception_detail":
+      $$.val = plpgsqltree.GetDiagnosticsErrorDetail;
+    case "pg_exception_hint":
+      $$.val = plpgsqltree.GetDiagnosticsErrorHint;
+    case "pg_exception_context":
+      $$.val = plpgsqltree.GetDiagnosticsErrorContext;
+    case "column_name":
+      $$.val = plpgsqltree.GetDiagnosticsColumnName;
+    case "constraint_name":
+      $$.val = plpgsqltree.GetDiagnosticsConstraintName;
+    case "pg_datatype_name":
+      $$.val = plpgsqltree.GetDiagnosticsDatatypeName;
+    case "message_text":
+      $$.val = plpgsqltree.GetDiagnosticsMessageText;
+    case "table_name":
+      $$.val = plpgsqltree.GetDiagnosticsTableName;
+    case "schema_name":
+      $$.val = plpgsqltree.GetDiagnosticsSchemaName;
+    case "returned_sqlstate":
+      $$.val = plpgsqltree.GetDiagnosticsReturnedSQLState;
+    default:
+      // TODO(drewk): Should this use an unimplemented error instead?
+      return setErr(plpgsqllex, errors.Newf("unrecognized GET DIAGNOSTICS item: %s", redact.Safe($1)))
+  }
+}
+;
+
+getdiag_target:
+// TODO(drewk): remove ident.
+IDENT
+  {
+  }
+;
+
+stmt_if: IF expr_until_then THEN proc_sect stmt_elsifs stmt_else END_IF IF ';'
+  {
+    cond, err := plpgsqllex.(*lexer).ParseExpr($2)
+    if err != nil {
+      return setErr(plpgsqllex, err)
+    }
+    $$.val = &plpgsqltree.If{
+      Condition: cond,
+      ThenBody: $4.statements(),
+      ElseIfList: $5.elseIf(),
+      ElseBody: $6.statements(),
+    }
+  }
+;
+
+stmt_elsifs:
+  {
+    $$.val = []plpgsqltree.ElseIf{};
+  }
+| stmt_elsifs ELSIF expr_until_then THEN proc_sect
+  {
+    cond, err := plpgsqllex.(*lexer).ParseExpr($3)
+    if err != nil {
+      return setErr(plpgsqllex, err)
+    }
+    newStmt := plpgsqltree.ElseIf{
+      Condition: cond,
+      Stmts: $5.statements(),
+    }
+    $$.val = append($1.elseIf() , newStmt)
+  }
+;
+
+stmt_else:
+  {
+    $$.val = []plpgsqltree.Statement{};
+  }
+| ELSE proc_sect
+  {
+    $$.val = $2.statements();
+  }
+;
+
+stmt_case: CASE opt_expr_until_when case_when_list opt_case_else END_CASE CASE ';'
+  {
+    expr := &plpgsqltree.Case {
+      TestExpr: $2,
+      CaseWhenList: $3.caseWhens(),
+    }
+    if $4.val != nil {
+       expr.HaveElse = true
+       expr.ElseStmts = $4.statements()
+    }
+    $$.val = expr
+  }
+;
+
+opt_expr_until_when:
+  {
+    if plpgsqllex.(*lexer).Peek().id != WHEN {
+      sqlStr, _, err := plpgsqllex.(*lexer).ReadSqlExpr(WHEN)
+      if err != nil {
+        return setErr(plpgsqllex, err)
+      }
+      $$ = sqlStr
+    } else {
+      $$ = ""
+    }
+  }
+;
+
+case_when_list: case_when_list case_when
+  {
+    stmts := $1.caseWhens()
+    stmts = append(stmts, $2.caseWhen())
+    $$.val = stmts
+  }
+| case_when
+  {
+    stmts := []*plpgsqltree.CaseWhen{}
+    stmts = append(stmts, $1.caseWhen())
+    $$.val = stmts
+  }
+;
+
+case_when: WHEN expr_until_then THEN proc_sect
+  {
+     expr := &plpgsqltree.CaseWhen{
+       Expr: $2,
+       Stmts: $4.statements(),
+     }
+     $$.val = expr
+  }
+;
+
+opt_case_else:
+  {
+    $$.val = nil
+  }
+| ELSE proc_sect
+  {
+    $$.val = $2.statements()
+  }
+;
+
+stmt_loop: opt_loop_label LOOP loop_body opt_label ';'
+  {
+    loopLabel, loopEndLabel := $1, $4
+    if err := checkLoopLabels(loopLabel, loopEndLabel); err != nil {
+      return setErr(plpgsqllex, err)
+    }
+    $$.val = &plpgsqltree.Loop{
+      Label: loopLabel,
+      Body: $3.statements(),
+    }
+  }
+;
+
+stmt_while: opt_loop_label WHILE expr_until_loop LOOP loop_body opt_label ';'
+  {
+    loopLabel, loopEndLabel := $1, $6
+    if err := checkLoopLabels(loopLabel, loopEndLabel); err != nil {
+      return setErr(plpgsqllex, err)
+    }
+    cond, err := plpgsqllex.(*lexer).ParseExpr($3)
+    if err != nil {
+      return setErr(plpgsqllex, err)
+    }
+    $$.val = &plpgsqltree.While{
+      Label: loopLabel,
+      Condition: cond,
+      Body: $5.statements(),
+    }
+  }
+;
+
+stmt_for: opt_loop_label FOR for_target IN for_control loop_body opt_label ';'
+  {
+    loopLabel, loopEndLabel := $1, $7
+    if err := checkLoopLabels(loopLabel, loopEndLabel); err != nil {
+      return setErr(plpgsqllex, err)
+    }
+    $$.val = &plpgsqltree.ForLoop{
+			Label: loopLabel,
+			Target: $3.variables(),
+			Control: $5.forLoopControl(),
+			Body: $6.statements(),
+		}
+  }
+;
+
+for_control:
+  {
+	  foundToken, err := plpgsqllex.(*lexer).findFirstOccurrence(DOT_DOT, LOOP)
+	  if err != nil {
+	    return setErr(plpgsqllex, err)
+	  }
+	  switch foundToken {
+	  case DOT_DOT:
+	    // This is an iteration over an integer range.
+	    forLoopControl, err := plpgsqllex.(*lexer).ReadIntegerForLoopControl()
+	    if err != nil {
+	      return setErr(plpgsqllex, err)
+	    }
+	    $$.val = forLoopControl
+	  case LOOP:
+	    return unimplemented(plpgsqllex, "for loop over query or cursor")
+	  default:
+	    return setErr(plpgsqllex, errors.New("unterminated FOR loop definition"))
+	  }
+  }
+;
+
+for_target:
+  {
+    target, err := plpgsqllex.(*lexer).ReadTarget()
+    if err != nil {
+      return setErr(plpgsqllex, err)
+    }
+    $$.val = target
+  }
+;
+
+stmt_foreach_a: opt_loop_label FOREACH
+  {
+    return unimplemented(plpgsqllex, "for each loop")
+  }
+;
+
+foreach_slice:
+  {
+  }
+| SLICE ICONST
+  {
+  }
+;
+
+stmt_exit: EXIT opt_label opt_exitcond
+  {
+    $$.val = &plpgsqltree.Exit{
+      Label: $2,
+      Condition: $3.expr(),
+    }
+  }
+;
+
+stmt_continue: CONTINUE opt_label opt_exitcond
+  {
+    $$.val = &plpgsqltree.Continue{
+      Label: $2,
+      Condition: $3.expr(),
+    }
+  }
+;
+
+stmt_return: RETURN return_expr ';'
+  {
+    $$.val = &plpgsqltree.Return{Expr: $2.expr()}
+  }
+| RETURN_NEXT NEXT return_expr ';'
+  {
+    $$.val = &plpgsqltree.ReturnNext{Expr: $3.expr()}
+  }
+| RETURN_QUERY QUERY return_query ';'
+  {
+    $$.val = $3.statement()
+  }
+;
+
+return_expr:
+  {
+    retExpr, err := plpgsqllex.(*lexer).ParseReturnExpr()
+    if err != nil {
+      return setErr(plpgsqllex, err)
+    }
+    $$.val = retExpr
+  }
+;
+
+return_query:
+  {
+    if plpgsqllex.(*lexer).peekForExecute() {
+      // Advance the lexer by one token so that the error correctly points to
+      // the EXECUTE keyword.
+      plpgsqllex.(*lexer).Advance(1)
+      return unimplemented (plpgsqllex, "return dynamic sql query")
+    }
+    retQuery, err := plpgsqllex.(*lexer).ParseReturnQuery()
+    if err != nil {
+      return setErr(plpgsqllex, err)
+    }
+    $$.val = retQuery
+  }
+;
+
+stmt_raise:
+  RAISE ';'
+  {
+    return unimplemented(plpgsqllex, "empty RAISE statement")
+  }
+| RAISE opt_error_level SCONST opt_format_exprs opt_option_exprs ';'
+  {
+    $$.val = &plpgsqltree.Raise{
+      LogLevel: $2,
+      Message: $3,
+      Params: $4.exprs(),
+      Options: $5.raiseOptions(),
+    }
+  }
+| RAISE opt_error_level IDENT opt_option_exprs ';'
+  {
+    $$.val = &plpgsqltree.Raise{
+      LogLevel: $2,
+      CodeName: $3,
+      Options: $4.raiseOptions(),
+    }
+  }
+| RAISE opt_error_level SQLSTATE SCONST opt_option_exprs ';'
+  {
+    $$.val = &plpgsqltree.Raise{
+      LogLevel: $2,
+      Code: $4,
+      Options: $5.raiseOptions(),
+    }
+  }
+| RAISE opt_error_level USING option_exprs ';'
+  {
+    $$.val = &plpgsqltree.Raise{
+      LogLevel: $2,
+      Options: $4.raiseOptions(),
+    }
+  }
+;
+
+opt_error_level:
+  DEBUG
+| LOG
+| INFO
+| NOTICE
+| WARNING
+| EXCEPTION
+| /* EMPTY */
+  {
+    $$ = ""
+  }
+;
+
+opt_option_exprs:
+  USING option_exprs
+  {
+    $$.val = $2.raiseOptions()
+  }
+| /* EMPTY */
+  {
+    $$.val = []plpgsqltree.RaiseOption{}
+  }
+;
+
+option_exprs:
+  option_exprs ',' option_expr
+  {
+    option := $3.raiseOption()
+    $$.val = append($1.raiseOptions(), *option)
+  }
+| option_expr
+  {
+    option := $1.raiseOption()
+    $$.val = []plpgsqltree.RaiseOption{*option}
+  }
+;
+
+option_expr:
+  option_type assign_operator
+  {
+    // Read until reaching one of the tokens that can follow a raise option.
+    sqlStr, _, err := plpgsqllex.(*lexer).ReadSqlExpr(',', ';')
+    if err != nil {
+      return setErr(plpgsqllex, err)
+    }
+    optionExpr, err := plpgsqllex.(*lexer).ParseExpr(sqlStr)
+    if err != nil {
+      return setErr(plpgsqllex, err)
+    }
+    $$.val = &plpgsqltree.RaiseOption{
+      OptType: $1,
+      Expr: optionExpr,
+    }
+  }
+;
+
+option_type:
+  MESSAGE
+| DETAIL
+| HINT
+| ERRCODE
+| COLUMN
+| CONSTRAINT
+| DATATYPE
+| TABLE
+| SCHEMA
+;
+
+opt_format_exprs:
+  format_exprs
+  {
+    $$.val = $1.exprs()
+  }
+ | /* EMPTY */
+  {
+    $$.val = []plpgsqltree.Expr{}
+  }
+;
+
+format_exprs:
+  format_expr
+  {
+    $$.val = []plpgsqltree.Expr{$1.expr()}
+  }
+| format_exprs format_expr
+  {
+    $$.val = append($1.exprs(), $2.expr())
+  }
+;
+
+format_expr: ','
+  {
+    // Read until reaching a token that can follow a raise format parameter.
+    sqlStr, _, err := plpgsqllex.(*lexer).ReadSqlExpr(',', ';', USING)
+    if err != nil {
+      return setErr(plpgsqllex, err)
+    }
+    param, err := plpgsqllex.(*lexer).ParseExpr(sqlStr)
+    if err != nil {
+      return setErr(plpgsqllex, err)
+    }
+    $$.val = param
+  }
+;
+
+stmt_assert: ASSERT assert_cond ';'
+  {
+    $$.val = &plpgsqltree.Assert{}
+  }
+;
+
+assert_cond:
+  {
+    _, terminator, err := plpgsqllex.(*lexer).ReadSqlExpr(',', ';')
+    if err != nil {
+      return setErr(plpgsqllex, err)
+    }
+    if terminator == ',' {
+      _, _, err = plpgsqllex.(*lexer).ReadSqlExpr(';')
+      if err != nil {
+        return setErr(plpgsqllex, err)
+      }
+    }
+  }
+;
+
+loop_body: proc_sect END LOOP
+  {
+    $$.val = $1.statements()
+  }
+;
+
+stmt_execsql: stmt_execsql_start
+  {
+    stmt, err := plpgsqllex.(*lexer).MakeExecSqlStmt()
+    if err != nil {
+      return setErr(plpgsqllex, err)
+    }
+    $$.val = stmt
+  }
+;
+
+stmt_execsql_start:
+  IMPORT
+| INSERT
+| UPSERT
+| MERGE
+| IDENT
+;
+
+stmt_dynexecute: EXECUTE
+  {
+    stmt, err := plpgsqllex.(*lexer).MakeDynamicExecuteStmt()
+    if err != nil {
+      return setErr(plpgsqllex, err)
+    }
+    $$.val = stmt
+  }
+;
+
+stmt_open: OPEN IDENT ';'
+  {
+    $$.val = &plpgsqltree.Open{CurVar: plpgsqltree.Variable($2)}
+  }
+| OPEN IDENT opt_scrollable FOR EXECUTE 
+  {
+    return unimplemented(plpgsqllex, "cursor for execute")
+  }
+| OPEN IDENT opt_scrollable FOR stmt_until_semi ';'
+  {
+    stmts, err := parser.Parse($5)
+    if err != nil {
+      return setErr(plpgsqllex, err)
+    }
+    if len(stmts) != 1 {
+      return setErr(plpgsqllex, errors.New("expected exactly one SQL statement for cursor"))
+    }
+    ann := tree.MakeAnnotations(stmts[0].NumAnnotations)
+    $$.val = &plpgsqltree.Open{
+      CurVar: plpgsqltree.Variable($2),
+      Scroll: $3.cursorScrollOption(),
+      Query: stmts[0].AST,
+      Annotations: &ann,
+    }
+  }
+;
+
+stmt_fetch: FETCH
+  {
+    fetch, err := plpgsqllex.(*lexer).MakeFetchOrMoveStmt(false)
+    if err != nil {
+      return setErr(plpgsqllex, err)
+    }
+    $$.val = fetch
+  }
+;
+
+stmt_move: MOVE
+  {
+    move, err := plpgsqllex.(*lexer).MakeFetchOrMoveStmt(true)
+    if err != nil {
+      return setErr(plpgsqllex, err)
+    }
+    $$.val = move
+  }
+;
+
+stmt_close: CLOSE IDENT ';'
+  {
+    $$.val = &plpgsqltree.Close{CurVar: plpgsqltree.Variable($2)}
+  }
+;
+
+stmt_null: NULL ';'
+  {
+    $$.val = &plpgsqltree.Null{};
+  }
+;
+
+stmt_commit: COMMIT opt_transaction_chain ';'
+  {
+    $$.val = &plpgsqltree.TransactionControl{Chain: $2.bool()}
+  }
+;
+
+stmt_rollback: ROLLBACK opt_transaction_chain ';'
+  {
+    $$.val = &plpgsqltree.TransactionControl{Chain: $2.bool(), Rollback: true}
+  }
+;
+
+opt_transaction_chain:
+AND CHAIN
+  {
+    $$.val = true
+  }
+| AND NO CHAIN
+  {
+    $$.val = false
+  }
+| /* EMPTY */
+  {
+    $$.val = false
+  }
+
+exception_sect: /* EMPTY */
+  {
+    $$.val = []plpgsqltree.Exception(nil)
+  }
+| EXCEPTION proc_exceptions
+  {
+    $$.val = $2.exceptions()
+  }
+;
+
+proc_exceptions: proc_exceptions proc_exception
+  {
+    e := $2.exception()
+    $$.val = append($1.exceptions(), *e)
+  }
+| proc_exception
+  {
+    e := $1.exception()
+    $$.val = []plpgsqltree.Exception{*e}
+  }
+;
+
+proc_exception: WHEN proc_conditions THEN proc_sect
+  {
+    $$.val = &plpgsqltree.Exception{
+      Conditions: $2.conditions(),
+      Action: $4.statements(),
+    }
+  }
+;
+
+proc_conditions: proc_conditions OR proc_condition
+  {
+    c := $3.condition()
+    $$.val = append($1.conditions(), *c)
+  }
+| proc_condition
+  {
+    c := $1.condition()
+    $$.val = []plpgsqltree.Condition{*c}
+  }
+;
+
+proc_condition: any_identifier
+  {
+    $$.val = &plpgsqltree.Condition{SqlErrName: $1}
+  }
+| SQLSTATE SCONST
+  {
+    $$.val = &plpgsqltree.Condition{SqlErrState: $2}
+  }
+;
+
+expr_until_semi:
+  {
+    sqlStr, _, err := plpgsqllex.(*lexer).ReadSqlExpr(';')
+    if err != nil {
+      return setErr(plpgsqllex, err)
+    }
+    $$ = sqlStr
+  }
+;
+
+stmt_until_semi:
+  {
+    sqlStr, _, err := plpgsqllex.(*lexer).ReadSqlStatement(';')
+    if err != nil {
+      return setErr(plpgsqllex, err)
+    }
+    $$ = sqlStr
+  }
+;
+
+expr_until_then:
+  {
+    sqlStr, _, err := plpgsqllex.(*lexer).ReadSqlExpr(THEN)
+    if err != nil {
+      return setErr(plpgsqllex, err)
+    }
+    $$ = sqlStr
+  }
+;
+
+expr_until_loop:
+  {
+    sqlStr, _, err := plpgsqllex.(*lexer).ReadSqlExpr(LOOP)
+    if err != nil {
+      return setErr(plpgsqllex, err)
+    }
+    $$ = sqlStr
+  }
+;
+
+expr_until_paren :
+  {
+    sqlStr, _, err := plpgsqllex.(*lexer).ReadSqlExpr(')')
+    if err != nil {
+      return setErr(plpgsqllex, err)
+    }
+    $$ = sqlStr
+  }
+;
+
+opt_block_label	:
+  {
+    $$ = ""
+  }
+| LESS_LESS any_identifier GREATER_GREATER
+  {
+    $$ = $2
+  }
+;
+
+opt_loop_label:
+  {
+    $$ = ""
+  }
+| LESS_LESS any_identifier GREATER_GREATER
+  {
+    $$ = $2
+  }
+;
+
+opt_label:
+  {
+    $$ = ""
+  }
+| any_identifier
+  {
+    $$ = $1
+  }
+;
+
+opt_exitcond: ';'
+  { }
+| WHEN expr_until_semi ';'
+  {
+    expr, err := plpgsqllex.(*lexer).ParseExpr($2)
+    if err != nil {
+      return setErr(plpgsqllex, err)
+    }
+    $$.val = expr
+  }
+;
+
+any_identifier:
+  IDENT
+| unreserved_keyword
+;
+
+unreserved_keyword:
+  ABSOLUTE
+| ALIAS
+| AND
+| ARRAY
+| ASSERT
+| BACKWARD
+| CALL
+| CHAIN
+| CLOSE
+| COLLATE
+| COLUMN
+| COLUMN_NAME
+| COMMIT
+| CONSTANT
+| CONSTRAINT
+| CONSTRAINT_NAME
+| CONTINUE
+| CURRENT
+| CURSOR
+| DATATYPE
+| DEBUG
+| DEFAULT
+| DETAIL
+| DIAGNOSTICS
+| DO
+| DUMP
+| ELSIF
+| ERRCODE
+| ERROR
+| EXCEPTION
+| EXIT
+| FETCH
+| FIRST
+| FORWARD
+| GET
+| HINT
+| IMPORT
+| INFO
+| INSERT
+| IS
+| LANGUAGE
+| LAST
+| LOG
+| MERGE
+| MESSAGE
+| MESSAGE_TEXT
+| MOVE
+| NEXT
+| NO
+| NO_SCROLL
+| NOTICE
+| OPEN
+| OPTION
+| PERFORM
+| PG_CONTEXT
+| PG_DATATYPE_NAME
+| PG_EXCEPTION_CONTEXT
+| PG_EXCEPTION_DETAIL
+| PG_EXCEPTION_HINT
+| PRINT_STRICT_PARAMS
+| PRIOR
+| QUERY
+| RAISE
+| RELATIVE
+| RETURN
+| RETURN_NEXT
+| RETURN_QUERY
+| RETURNED_SQLSTATE
+| REVERSE
+| ROLLBACK
+| ROW_COUNT
+| ROWTYPE
+| SCHEMA
+| SCHEMA_NAME
+| SCROLL
+| SLICE
+| SQLSTATE
+| STACKED
+| TABLE
+| TABLE_NAME
+| TYPE
+| UPSERT
+| USE_COLUMN
+| USE_VARIABLE
+| VARIABLE_CONFLICT
+| WARNING
+
+reserved_keyword:
+  ALL
+| BEGIN
+| BY
+| CASE
+| DECLARE
+| ELSE
+| END
+| END_CASE
+| END_IF
+| EXECUTE
+| FOR
+| FOREACH
+| FROM
+| IF
+| IN
+| INTO
+| LOOP
+| NOT
+| NULL
+| OR
+| STRICT
+| THEN
+| TO
+| USING
+| WHEN
+| WHILE
+
+%%
diff --git a/pkg/sql/privilege/kind.go b/pkg/sql/privilege/kind.go
index f8f8e4c..908d1bc 100644
--- a/pkg/sql/privilege/kind.go
+++ b/pkg/sql/privilege/kind.go
@@ -1,12 +1,7 @@
 // Copyright 2023 The Cockroach Authors.
 //
-// Use of this software is governed by the Business Source License
-// included in the file licenses/BSL.txt.
-//
-// As of the Change Date specified in that file, in accordance with
-// the Business Source License, use of this software will be governed
-// by the Apache License, Version 2.0, included in the file
-// licenses/APL.txt.
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
 
 package privilege
 
@@ -65,8 +60,12 @@ const (
 	CREATELOGIN              Kind = 33
 	CREATEDB                 Kind = 34
 	CONTROLJOB               Kind = 35
-	REPAIRCLUSTERMETADATA    Kind = 36
-	largestKind                   = REPAIRCLUSTERMETADATA
+	REPAIRCLUSTER            Kind = 36
+	TRIGGER                  Kind = 37
+	BYPASSRLS                Kind = 38
+	REPLICATIONDEST          Kind = 39
+	REPLICATIONSOURCE        Kind = 40
+	largestKind                   = REPLICATIONSOURCE
 )
 
 var isDeprecatedKind = map[Kind]bool{
@@ -77,6 +76,8 @@ var isDeprecatedKind = map[Kind]bool{
 // privilege internally. It is not visible to end-users.
 type KindInternalKey string
 
+// InternalKey returns the KindInternalKey for a Kind (see docs on
+// KindInternalKey). The InternalKey must not change between releases.
 func (k Kind) InternalKey() KindInternalKey {
 	switch k {
 	case ALL:
@@ -148,8 +149,16 @@ func (k Kind) InternalKey() KindInternalKey {
 		return "CREATEDB"
 	case CONTROLJOB:
 		return "CONTROLJOB"
-	case REPAIRCLUSTERMETADATA:
+	case REPAIRCLUSTER:
 		return "REPAIRCLUSTERMETADATA"
+	case TRIGGER:
+		return "TRIGGER"
+	case BYPASSRLS:
+		return "BYPASSRLS"
+	case REPLICATIONDEST:
+		return "REPLICATIONDEST"
+	case REPLICATIONSOURCE:
+		return "REPLICATIONSOURCE"
 	default:
 		panic(errors.AssertionFailedf("unhandled kind: %d", int(k)))
 	}
@@ -165,6 +174,8 @@ func (k Kind) DisplayName() KindDisplayName {
 	switch k {
 	case MANAGEVIRTUALCLUSTER:
 		return "MANAGEVIRTUALCLUSTER"
+	case REPAIRCLUSTER:
+		return "REPAIRCLUSTER"
 	default:
 		// Unless we have an exception above, the internal
 		// key is also a valid display name.
diff --git a/pkg/sql/privilege/privilege.go b/pkg/sql/privilege/privilege.go
index bbc9c5f..3e367d8 100644
--- a/pkg/sql/privilege/privilege.go
+++ b/pkg/sql/privilege/privilege.go
@@ -1,12 +1,7 @@
 // Copyright 2015 The Cockroach Authors.
 //
-// Use of this software is governed by the Business Source License
-// included in the file licenses/BSL.txt.
-//
-// As of the Change Date specified in that file, in accordance with
-// the Business Source License, use of this software will be governed
-// by the Apache License, Version 2.0, included in the file
-// licenses/APL.txt.
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
 
 // Package privilege outlines the basic privilege system for cockroach.
 package privilege
@@ -92,7 +87,7 @@ var (
 	ReadWriteData         = List{SELECT, INSERT, DELETE, UPDATE}
 	ReadWriteSequenceData = List{SELECT, UPDATE, USAGE}
 	DBPrivileges          = List{ALL, BACKUP, CONNECT, CREATE, DROP, RESTORE, ZONECONFIG}
-	TablePrivileges       = List{ALL, BACKUP, CHANGEFEED, CREATE, DROP, SELECT, INSERT, DELETE, UPDATE, ZONECONFIG}
+	TablePrivileges       = List{ALL, BACKUP, CHANGEFEED, CREATE, DROP, SELECT, INSERT, DELETE, UPDATE, ZONECONFIG, TRIGGER, REPLICATIONDEST, REPLICATIONSOURCE}
 	SchemaPrivileges      = List{ALL, CREATE, USAGE}
 	TypePrivileges        = List{ALL, USAGE}
 	RoutinePrivileges     = List{ALL, EXECUTE}
@@ -105,7 +100,7 @@ var (
 		ALL, BACKUP, RESTORE, MODIFYCLUSTERSETTING, EXTERNALCONNECTION, VIEWACTIVITY, VIEWACTIVITYREDACTED,
 		VIEWCLUSTERSETTING, CANCELQUERY, NOSQLLOGIN, VIEWCLUSTERMETADATA, VIEWDEBUG, EXTERNALIOIMPLICITACCESS, VIEWJOB,
 		MODIFYSQLCLUSTERSETTING, REPLICATION, MANAGEVIRTUALCLUSTER, VIEWSYSTEMTABLE, CREATEROLE, CREATELOGIN, CREATEDB, CONTROLJOB,
-		REPAIRCLUSTERMETADATA,
+		REPAIRCLUSTER, BYPASSRLS, REPLICATIONDEST, REPLICATIONSOURCE,
 	}
 	VirtualTablePrivileges       = List{ALL, SELECT}
 	ExternalConnectionPrivileges = List{ALL, USAGE, DROP}
@@ -366,10 +361,11 @@ var privToACL = map[Kind]string{
 	USAGE:   "U",
 	CONNECT: "c",
 	EXECUTE: "X",
+	TRIGGER: "t",
 }
 
-// orderedPrivs is the list of privileges sorted in alphanumeric order based on the ACL character -> CUacdrwX
-var orderedPrivs = List{CREATE, USAGE, INSERT, CONNECT, DELETE, SELECT, UPDATE, EXECUTE}
+// orderedPrivs is the list of privileges sorted in alphanumeric order based on the ACL character -> CUacdrtwX
+var orderedPrivs = List{CREATE, USAGE, INSERT, CONNECT, DELETE, SELECT, TRIGGER, UPDATE, EXECUTE}
 
 // ListToACL converts a list of privileges to a list of Postgres
 // ACL items.
diff --git a/pkg/sql/privilege/target_object_type.go b/pkg/sql/privilege/target_object_type.go
index 3b64651..3a196ba 100644
--- a/pkg/sql/privilege/target_object_type.go
+++ b/pkg/sql/privilege/target_object_type.go
@@ -1,12 +1,7 @@
 // Copyright 2022 The Cockroach Authors.
 //
-// Use of this software is governed by the Business Source License
-// included in the file licenses/BSL.txt.
-//
-// As of the Change Date specified in that file, in accordance with
-// the Business Source License, use of this software will be governed
-// by the Apache License, Version 2.0, included in the file
-// licenses/APL.txt.
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
 
 package privilege
 
diff --git a/pkg/sql/scanner/jsonpath_scan.go b/pkg/sql/scanner/jsonpath_scan.go
new file mode 100644
index 0000000..51c6bbe
--- /dev/null
+++ b/pkg/sql/scanner/jsonpath_scan.go
@@ -0,0 +1,147 @@
+// Copyright 2025 The Cockroach Authors.
+//
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
+
+package scanner
+
+import (
+	sqllexbase "github.com/cockroachdb/cockroachdb-parser/pkg/sql/lexbase"
+	"github.com/cockroachdb/cockroachdb-parser/pkg/util/jsonpath/parser/lexbase"
+)
+
+// JSONPathScanner is a scanner with a jsonpath-specific scan function.
+type JSONPathScanner struct {
+	Scanner
+}
+
+// Scan scans the next token and populates its information into lval.
+// This scan function contains rules for jsonpath.
+func (s *JSONPathScanner) Scan(lval ScanSymType) {
+	ch, skipWhiteSpace := s.scanSetup(lval, false /* allowComments */)
+	if skipWhiteSpace {
+		return
+	}
+
+	// TODO(normanchenn): We still need to handle $.Xe where X is any digit.
+	switch ch {
+	case '$':
+		// Root path ($)
+		if s.peek() == '.' || s.peek() == eof || s.peek() == ' ' || s.peek() == '[' || s.peek() == ')' || s.peek() == '?' {
+			lval.SetID(lexbase.ROOT)
+			return
+		}
+
+		// Handle variables like $var, $1a, $"var", etc.
+		if s.peek() == identQuote {
+			s.pos++
+			if s.scanString(lval, identQuote, false /* allowEscapes */, true /* requireUTF8 */) {
+				lval.SetID(lexbase.VARIABLE)
+			}
+			return
+		}
+		s.pos++
+		s.scanIdent(lval)
+		lval.SetID(lexbase.VARIABLE)
+		return
+	case identQuote:
+		// "[^"]"
+		// When scanning string literals for like_regex patterns, we need to
+		// consider how to handle escape characters similarly to Postgres.
+		// See: https://www.postgresql.org/docs/current/functions-json.html#JSONPATH-REGULAR-EXPRESSIONS,
+		// "any backslashes you want to use in the regular expression must be doubled".
+		//
+		// With allowEscapes == true,
+		//  - String literal input "^\\$" is scanned as "^\\$" (one escaped backslash)
+		//  - This matches the behaviour of Postgres.
+		// With allowEscapes == false,
+		//  - String literal input "^\\$" is scanned as "^\\\\$" (two escaped backslashes)
+		if s.scanString(lval, identQuote, true /* allowEscapes */, true /* requireUTF8 */) {
+			lval.SetID(lexbase.STR)
+		}
+		return
+	case '=':
+		if s.peek() == '=' { // ==
+			s.pos++
+			lval.SetID(lexbase.EQUAL)
+			return
+		}
+		return
+	case '!':
+		if s.peek() == '=' { // !=
+			s.pos++
+			lval.SetID(lexbase.NOT_EQUAL)
+			return
+		}
+		lval.SetID(lexbase.NOT)
+		return
+	case '>':
+		if s.peek() == '=' { // >=
+			s.pos++
+			lval.SetID(lexbase.GREATER_EQUAL)
+			return
+		}
+		lval.SetID(lexbase.GREATER)
+		return
+	case '<':
+		if s.peek() == '=' { // <=
+			s.pos++
+			lval.SetID(lexbase.LESS_EQUAL)
+			return
+		}
+		lval.SetID(lexbase.LESS)
+		return
+	case '&':
+		if s.peek() == '&' { // &&
+			s.pos++
+			lval.SetID(lexbase.AND)
+			return
+		}
+		return
+	case '|':
+		if s.peek() == '|' { // ||
+			s.pos++
+			lval.SetID(lexbase.OR)
+			return
+		}
+		return
+	case '@':
+		lval.SetID(lexbase.CURRENT)
+		return
+	case '*':
+		if s.peek() == '*' { // **
+			s.pos++
+			lval.SetID(lexbase.ANY)
+			return
+		}
+		return
+	default:
+		if sqllexbase.IsDigit(ch) {
+			s.scanNumber(lval, ch)
+			return
+		}
+		if sqllexbase.IsIdentStart(ch) {
+			s.scanIdent(lval)
+			return
+		}
+	}
+	// Everything else is a single character token which we already initialized
+	// lval for above.
+}
+
+// isIdentMiddle returns true if the character is valid inside an identifier.
+func isIdentMiddle(ch int) bool {
+	return sqllexbase.IsIdentStart(ch) || sqllexbase.IsDigit(ch)
+}
+
+// scanIdent is similar to Scanner.scanIdent, but uses Jsonpath tokens.
+func (s *JSONPathScanner) scanIdent(lval ScanSymType) {
+	// TODO(normanchenn): Allow any case for specific identifiers (strict, lax, to)
+	s.normalizeIdent(lval, isIdentMiddle, false /* toLower */)
+	lval.SetID(lexbase.GetKeywordID(lval.Str()))
+}
+
+// scanNumber is similar to Scanner.scanNumber, but uses Jsonpath tokens.
+func (s *JSONPathScanner) scanNumber(lval ScanSymType, ch int) {
+	s.scanNumberImpl(lval, ch, lexbase.ERROR, lexbase.FCONST, lexbase.ICONST)
+}
diff --git a/pkg/sql/scanner/plpgsql_scan.go b/pkg/sql/scanner/plpgsql_scan.go
new file mode 100644
index 0000000..a74d864
--- /dev/null
+++ b/pkg/sql/scanner/plpgsql_scan.go
@@ -0,0 +1,341 @@
+// Copyright 2023 The Cockroach Authors.
+//
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
+
+package scanner
+
+import (
+	"strconv"
+	"unicode/utf8"
+
+	sqllex "github.com/cockroachdb/cockroachdb-parser/pkg/sql/lexbase"
+	"github.com/cockroachdb/cockroachdb-parser/pkg/sql/plpgsql/parser/lexbase"
+)
+
+// PLpgSQLScanner is a scanner with a PLPGSQL specific scan function
+type PLpgSQLScanner struct {
+	Scanner
+}
+
+// Scan scans the next token and populates its information into lval.
+// This scan function contains rules for plpgsql.
+func (s *PLpgSQLScanner) Scan(lval ScanSymType) {
+	ch, skipWhiteSpace := s.scanSetup(lval, true /* allowComments */)
+
+	if skipWhiteSpace {
+		return
+	}
+
+	switch ch {
+	case '$':
+		if s.scanDollarQuotedString(lval) {
+			lval.SetID(lexbase.SCONST)
+			return
+		}
+		return
+
+	case identQuote:
+		// "[^"]"
+		if s.scanString(lval, identQuote, false /* allowEscapes */, true /* requireUTF8 */) {
+			lval.SetID(lexbase.IDENT)
+		}
+		return
+
+	case singleQuote:
+		// '[^']'
+		if s.scanString(lval, ch, false /* allowEscapes */, true /* requireUTF8 */) {
+			lval.SetID(lexbase.SCONST)
+		}
+		return
+
+	case 'b':
+		// Bytes?
+		if s.peek() == singleQuote {
+			// b'[^']'
+			s.pos++
+			if s.scanString(lval, singleQuote, true /* allowEscapes */, false /* requireUTF8 */) {
+				lval.SetID(lexbase.BCONST)
+			}
+			return
+		}
+		s.scanIdent(lval)
+		return
+
+	case 'e', 'E':
+		// Escaped string?
+		if s.peek() == singleQuote {
+			// [eE]'[^']'
+			s.lastAttemptedID = int32(lexbase.SCONST)
+			s.pos++
+			if s.scanString(lval, singleQuote, true /* allowEscapes */, true /* requireUTF8 */) {
+				lval.SetID(lexbase.SCONST)
+			}
+			return
+		}
+		s.scanIdent(lval)
+		return
+
+	case '.':
+		switch t := s.peek(); {
+		case t == '.': // ..
+			s.pos++
+			lval.SetID(lexbase.DOT_DOT)
+			return
+		case sqllex.IsDigit(t):
+			s.scanNumber(lval, ch)
+			return
+		}
+		return
+
+	case '!':
+		switch s.peek() {
+		case '=': // !=
+			s.pos++
+			lval.SetID(lexbase.NOT_EQUALS)
+			return
+		}
+		return
+
+	case '<':
+		switch s.peek() {
+		case '<': // <<
+			s.pos++
+			lval.SetID(lexbase.LESS_LESS)
+			return
+		case '=': // <=
+			s.pos++
+			lval.SetID(lexbase.LESS_EQUALS)
+			return
+		}
+		return
+
+	case '>':
+		switch s.peek() {
+		case '>': // >>
+			s.pos++
+			lval.SetID(lexbase.GREATER_GREATER)
+			return
+		case '=': // >=
+			s.pos++
+			lval.SetID(lexbase.GREATER_EQUALS)
+			return
+		}
+		return
+
+	case ':':
+		switch s.peek() {
+		case ':':
+			s.pos++
+			lval.SetID(lexbase.TYPECAST)
+			return
+		case '=':
+			s.pos++
+			lval.SetID(lexbase.COLON_EQUALS)
+			return
+		}
+		return
+
+	default:
+		if sqllex.IsDigit(ch) {
+			s.scanNumber(lval, ch)
+			return
+		}
+		if sqllex.IsIdentStart(ch) {
+			s.scanIdent(lval)
+			return
+		}
+	}
+	// Everything else is a single character token which we already initialized
+	// lval for above.
+}
+
+// scanString is similar to Scanner.scanString, but uses PL/pgSQL tokens.
+func (s *PLpgSQLScanner) scanString(lval ScanSymType, ch int, allowEscapes, requireUTF8 bool) bool {
+	buf := s.buffer()
+	var runeTmp [utf8.UTFMax]byte
+	start := s.pos
+outer:
+	for {
+		switch s.next() {
+		case ch:
+			buf = append(buf, s.in[start:s.pos-1]...)
+			if s.peek() == ch {
+				// Double quote is translated into a single quote that is part of the
+				// string.
+				start = s.pos
+				s.pos++
+				continue
+			}
+
+			newline, ok := s.skipWhitespace(lval, false)
+			if !ok {
+				return false
+			}
+
+			// SQL allows joining adjacent single-quoted strings separated by
+			// whitespace as long as that whitespace contains at least one
+			// newline. Kind of strange to require the newline, but that is the
+			// standard.
+			if ch == singleQuote && s.peek() == singleQuote && newline {
+				s.pos++
+				start = s.pos
+				continue
+			}
+			break outer
+
+		case '\\':
+			t := s.peek()
+
+			if allowEscapes {
+				buf = append(buf, s.in[start:s.pos-1]...)
+				if t == ch {
+					start = s.pos
+					s.pos++
+					continue
+				}
+
+				switch t {
+				case 'a', 'b', 'f', 'n', 'r', 't', 'v', 'x', 'X', 'u', 'U', '\\',
+					'0', '1', '2', '3', '4', '5', '6', '7':
+					var tmp string
+					if t == 'X' && len(s.in[s.pos:]) >= 3 {
+						// UnquoteChar doesn't handle 'X' so we create a temporary string
+						// for it to parse.
+						tmp = "\\x" + s.in[s.pos+1:s.pos+3]
+					} else {
+						tmp = s.in[s.pos-1:]
+					}
+					v, multibyte, tail, err := strconv.UnquoteChar(tmp, byte(ch))
+					if err != nil {
+						lval.SetID(lexbase.ERROR)
+						lval.SetStr(err.Error())
+						return false
+					}
+					if v < utf8.RuneSelf || !multibyte {
+						buf = append(buf, byte(v))
+					} else {
+						n := utf8.EncodeRune(runeTmp[:], v)
+						buf = append(buf, runeTmp[:n]...)
+					}
+					s.pos += len(tmp) - len(tail) - 1
+					start = s.pos
+					continue
+				}
+
+				// If we end up here, it's a redundant escape - simply drop the
+				// backslash. For example, e'\"' is equivalent to e'"', and
+				// e'\d\b' to e'd\b'. This is what Postgres does:
+				// http://www.postgresql.org/docs/9.4/static/sql-syntax-lexical.html#SQL-SYNTAX-STRINGS-ESCAPE
+				start = s.pos
+			}
+
+		case eof:
+			lval.SetID(lexbase.ERROR)
+			lval.SetStr(errUnterminated)
+			return false
+		}
+	}
+
+	if requireUTF8 && !utf8.Valid(buf) {
+		lval.SetID(lexbase.ERROR)
+		lval.SetStr(errInvalidUTF8)
+		return false
+	}
+
+	if ch == identQuote {
+		lval.SetStr(sqllex.NormalizeString(s.finishString(buf)))
+	} else {
+		lval.SetStr(s.finishString(buf))
+	}
+	return true
+}
+
+// scanDollarQuotedString is similar to Scanner.scanDollarQuotedString, but uses
+// PL/pgSQL tokens.
+func (s *PLpgSQLScanner) scanDollarQuotedString(lval ScanSymType) bool {
+	s.lastAttemptedID = int32(lexbase.SCONST)
+	buf := s.buffer()
+	start := s.pos
+
+	foundStartTag := false
+	possibleEndTag := false
+	startTagIndex := -1
+	var startTag string
+
+outer:
+	for {
+		ch := s.peek()
+		switch ch {
+		case '$':
+			s.pos++
+			if foundStartTag {
+				if possibleEndTag {
+					if len(startTag) == startTagIndex {
+						// Found end tag.
+						buf = append(buf, s.in[start+len(startTag)+1:s.pos-len(startTag)-2]...)
+						break outer
+					} else {
+						// Was not the end tag but the current $ might be the start of the end tag we are looking for, so
+						// just reset the startTagIndex.
+						startTagIndex = 0
+					}
+				} else {
+					possibleEndTag = true
+					startTagIndex = 0
+				}
+			} else {
+				startTag = s.in[start : s.pos-1]
+				foundStartTag = true
+			}
+
+		case eof:
+			if foundStartTag {
+				// A start tag was found, therefore we expect an end tag before the eof, otherwise it is an error.
+				lval.SetID(lexbase.ERROR)
+				lval.SetStr(errUnterminated)
+			} else {
+				// This is not a dollar-quoted string, reset the pos back to the start.
+				s.pos = start
+			}
+			return false
+
+		default:
+			// If we haven't found a start tag yet, check whether the current characters is a valid for a tag.
+			if !foundStartTag && !sqllex.IsIdentStart(ch) && !sqllex.IsDigit(ch) {
+				return false
+			}
+			s.pos++
+			if possibleEndTag {
+				// Check whether this could be the end tag.
+				if startTagIndex >= len(startTag) || ch != int(startTag[startTagIndex]) {
+					// This is not the end tag we are looking for.
+					possibleEndTag = false
+					startTagIndex = -1
+				} else {
+					startTagIndex++
+				}
+			}
+		}
+	}
+
+	if !utf8.Valid(buf) {
+		lval.SetID(lexbase.ERROR)
+		lval.SetStr(errInvalidUTF8)
+		return false
+	}
+
+	lval.SetStr(s.finishString(buf))
+	return true
+}
+
+// scanNumber is similar to Scanner.scanNumber, but uses PL/pgSQL tokens.
+func (s *PLpgSQLScanner) scanNumber(lval ScanSymType, ch int) {
+	s.scanNumberImpl(lval, ch, lexbase.ERROR, lexbase.FCONST, lexbase.ICONST)
+}
+
+// scanIdent is similar to Scanner.scanIdent, but uses PL/pgSQL tokens.
+func (s *PLpgSQLScanner) scanIdent(lval ScanSymType) {
+	s.normalizeIdent(lval, sqllex.IsIdentMiddle, true /* toLower */)
+	lval.SetID(lexbase.GetKeywordID(lval.Str()))
+}
diff --git a/pkg/sql/scanner/scan.go b/pkg/sql/scanner/scan.go
index 7c2313a..aa9a120 100644
--- a/pkg/sql/scanner/scan.go
+++ b/pkg/sql/scanner/scan.go
@@ -1,12 +1,7 @@
 // Copyright 2015 The Cockroach Authors.
 //
-// Use of this software is governed by the Business Source License
-// included in the file licenses/BSL.txt.
-//
-// As of the Change Date specified in that file, in accordance with
-// the Business Source License, use of this software will be governed
-// by the Apache License, Version 2.0, included in the file
-// licenses/APL.txt.
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
 
 package scanner
 
@@ -52,13 +47,13 @@ type ScanSymType interface {
 	SetUnionVal(interface{})
 }
 
-// Scanner lexes SQL statements.
+// Scanner lexes statements.
 type Scanner struct {
 	in            string
 	pos           int
 	bytesPrealloc []byte
 
-	// Comments is the list of parsed comments from the SQL statement.
+	// Comments is the list of parsed comments from the statement.
 	Comments []string
 
 	// lastAttemptedID indicates the ID of the last attempted
@@ -69,6 +64,9 @@ type Scanner struct {
 	// quoted. Used to distinguish between quoted and non-quoted in
 	// Inspect.
 	quoted bool
+	// retainComments indicates that comments should be collected in the
+	// Comments field. If it is false, they are discarded.
+	retainComments bool
 }
 
 // SQLScanner is a scanner with a SQL specific scan function
@@ -88,16 +86,26 @@ func (s *Scanner) Pos() int {
 
 // Init initializes a new Scanner that will process str.
 func (s *Scanner) Init(str string) {
-	s.in = str
-	s.pos = 0
-	// Preallocate some buffer space for identifiers etc.
-	s.bytesPrealloc = make([]byte, len(str))
+	*s = Scanner{
+		in:  str,
+		pos: 0,
+		// Preallocate some buffer space for identifiers etc.
+		bytesPrealloc: make([]byte, len(str)),
+	}
+}
+
+// RetainComments instructs the scanner to collect SQL comments in the Comments
+// field.
+func (s *Scanner) RetainComments() {
+	s.retainComments = true
 }
 
 // Cleanup is used to avoid holding on to memory unnecessarily (for the cases
 // where we reuse a Scanner).
 func (s *Scanner) Cleanup() {
 	s.bytesPrealloc = nil
+	s.Comments = nil
+	s.retainComments = false
 }
 
 func (s *Scanner) allocBytes(length int) []byte {
@@ -133,14 +141,14 @@ func (s *Scanner) finishString(buf []byte) string {
 	return str
 }
 
-func (s *Scanner) scanSetup(lval ScanSymType) (int, bool) {
+func (s *Scanner) scanSetup(lval ScanSymType, allowComments bool) (int, bool) {
 	lval.SetID(0)
 	lval.SetPos(int32(s.pos))
 	lval.SetStr("EOF")
 	s.quoted = false
 	s.lastAttemptedID = 0
 
-	if _, ok := s.skipWhitespace(lval, true); !ok {
+	if _, ok := s.skipWhitespace(lval, allowComments); !ok {
 		return 0, true
 	}
 
@@ -159,7 +167,7 @@ func (s *Scanner) scanSetup(lval ScanSymType) (int, bool) {
 
 // Scan scans the next token and populates its information into lval.
 func (s *SQLScanner) Scan(lval ScanSymType) {
-	ch, skipWhiteSpace := s.scanSetup(lval)
+	ch, skipWhiteSpace := s.scanSetup(lval, true /* allowComments */)
 
 	if skipWhiteSpace {
 		return
@@ -315,12 +323,32 @@ func (s *SQLScanner) Scan(lval ScanSymType) {
 			return
 		case '=': // <=
 			s.pos++
+			switch s.peek() {
+			case '>': // <=>
+				s.pos++
+				lval.SetID(lexbase.COS_DISTANCE)
+				return
+			}
 			lval.SetID(lexbase.LESS_EQUALS)
 			return
 		case '@': // <@
 			s.pos++
 			lval.SetID(lexbase.CONTAINED_BY)
 			return
+		case '-': // <-
+			switch s.peekN(1) {
+			case '>': // <->
+				s.pos += 2
+				lval.SetID(lexbase.DISTANCE)
+				return
+			}
+		case '#': // <#
+			switch s.peekN(1) {
+			case '>': // <#>
+				s.pos += 2
+				lval.SetID(lexbase.NEG_INNER_PRODUCT)
+				return
+			}
 		}
 		return
 
@@ -508,8 +536,10 @@ func (s *Scanner) skipWhitespace(lval ScanSymType, allowComments bool) (newline,
 			if present, cok := s.ScanComment(lval); !cok {
 				return false, false
 			} else if present {
-				// Mark down the comments that we found.
-				s.Comments = append(s.Comments, s.in[startPos:s.pos])
+				if s.retainComments {
+					// Mark down the comments that we found.
+					s.Comments = append(s.Comments, s.in[startPos:s.pos])
+				}
 				continue
 			}
 		}
@@ -576,7 +606,10 @@ func (s *Scanner) ScanComment(lval ScanSymType) (present, ok bool) {
 	return false, true
 }
 
-func (s *Scanner) lowerCaseAndNormalizeIdent(lval ScanSymType) {
+// normalizeIdent takes in a function that determines if a character is a legal
+// identifier character, and a boolean toLower that indicates whether to set the
+// identifier to lowercase when normalizing.
+func (s *Scanner) normalizeIdent(lval ScanSymType, isIdentMiddle func(int) bool, toLower bool) {
 	s.lastAttemptedID = int32(lexbase.IDENT)
 	s.pos--
 	start := s.pos
@@ -597,18 +630,15 @@ func (s *Scanner) lowerCaseAndNormalizeIdent(lval ScanSymType) {
 			isLower = false
 		}
 
-		if !lexbase.IsIdentMiddle(ch) {
+		if !isIdentMiddle(ch) {
 			break
 		}
 
 		s.pos++
 	}
 
-	if isLower && isASCII {
-		// Already lowercased - nothing to do.
-		lval.SetStr(s.in[start:s.pos])
-	} else if isASCII {
-		// We know that the identifier we've seen so far is ASCII, so we don't need
+	if toLower && !isLower && isASCII {
+		// We know that the identifier we've seen so far is ASCII, so we don't
 		// to unicode normalize. Instead, just lowercase as normal.
 		b := s.allocBytes(s.pos - start)
 		_ = b[s.pos-start-1] // For bounds check elimination.
@@ -619,14 +649,20 @@ func (s *Scanner) lowerCaseAndNormalizeIdent(lval ScanSymType) {
 			b[i] = byte(c)
 		}
 		lval.SetStr(*(*string)(unsafe.Pointer(&b)))
-	} else {
-		// The string has unicode in it. No choice but to run Normalize.
+	} else if toLower && !isASCII {
+		// The string has unicode in it. No choice but to normalize and lowercase.
 		lval.SetStr(lexbase.NormalizeName(s.in[start:s.pos]))
+	} else if !toLower && !isASCII {
+		// The string has unicode in it. No choice but to normalize.
+		lval.SetStr(lexbase.NormalizeString(s.in[start:s.pos]))
+	} else {
+		// Don't do anything.
+		lval.SetStr(s.in[start:s.pos])
 	}
 }
 
 func (s *Scanner) scanIdent(lval ScanSymType) {
-	s.lowerCaseAndNormalizeIdent(lval)
+	s.normalizeIdent(lval, lexbase.IsIdentMiddle, true /* toLower */)
 
 	isExperimental := false
 	kw := lval.Str()
@@ -661,6 +697,10 @@ func (s *Scanner) scanIdent(lval ScanSymType) {
 }
 
 func (s *Scanner) scanNumber(lval ScanSymType, ch int) {
+	s.scanNumberImpl(lval, ch, lexbase.ERROR, lexbase.FCONST, lexbase.ICONST)
+}
+
+func (s *Scanner) scanNumberImpl(lval ScanSymType, ch int, errorID, fconstID, iconstID int32) {
 	start := s.pos - 1
 	isHex := false
 	hasDecimal := ch == '.'
@@ -674,7 +714,7 @@ func (s *Scanner) scanNumber(lval ScanSymType, ch int) {
 		}
 		if ch == 'x' || ch == 'X' {
 			if isHex || s.in[start] != '0' || s.pos != start+1 {
-				lval.SetID(lexbase.ERROR)
+				lval.SetID(errorID)
 				lval.SetStr(errInvalidHexNumeric)
 				return
 			}
@@ -708,10 +748,10 @@ func (s *Scanner) scanNumber(lval ScanSymType, ch int) {
 			ch = s.peek()
 			if ch == '-' || ch == '+' {
 				s.pos++
+				ch = s.peek()
 			}
-			ch = s.peek()
 			if !lexbase.IsDigit(ch) {
-				lval.SetID(lexbase.ERROR)
+				lval.SetID(errorID)
 				lval.SetStr("invalid floating point literal")
 				return
 			}
@@ -722,17 +762,17 @@ func (s *Scanner) scanNumber(lval ScanSymType, ch int) {
 
 	// Disallow identifier after numerical constants e.g. "124foo".
 	if lexbase.IsIdentStart(s.peek()) {
-		lval.SetID(lexbase.ERROR)
+		lval.SetID(errorID)
 		lval.SetStr(fmt.Sprintf("trailing junk after numeric literal at or near %q", s.in[start:s.pos+1]))
 		return
 	}
 
 	lval.SetStr(s.in[start:s.pos])
 	if hasDecimal || hasExponent {
-		lval.SetID(lexbase.FCONST)
+		lval.SetID(fconstID)
 		floatConst := constant.MakeFromLiteral(lval.Str(), token.FLOAT, 0)
 		if floatConst.Kind() == constant.Unknown {
-			lval.SetID(lexbase.ERROR)
+			lval.SetID(errorID)
 			lval.SetStr(fmt.Sprintf("could not make constant float from literal %q", lval.Str()))
 			return
 		}
@@ -754,10 +794,10 @@ func (s *Scanner) scanNumber(lval ScanSymType, ch int) {
 			}
 		}
 
-		lval.SetID(lexbase.ICONST)
+		lval.SetID(iconstID)
 		intConst := constant.MakeFromLiteral(lval.Str(), token.INT, 0)
 		if intConst.Kind() == constant.Unknown {
-			lval.SetID(lexbase.ERROR)
+			lval.SetID(errorID)
 			lval.SetStr(fmt.Sprintf("could not make constant int from literal %q", lval.Str()))
 			return
 		}
diff --git a/pkg/sql/sem/builtins/builtinsregistry/builtins_registry.go b/pkg/sql/sem/builtins/builtinsregistry/builtins_registry.go
index abbde77..3a5450e 100644
--- a/pkg/sql/sem/builtins/builtinsregistry/builtins_registry.go
+++ b/pkg/sql/sem/builtins/builtinsregistry/builtins_registry.go
@@ -1,12 +1,7 @@
 // Copyright 2022 The Cockroach Authors.
 //
-// Use of this software is governed by the Business Source License
-// included in the file licenses/BSL.txt.
-//
-// As of the Change Date specified in that file, in accordance with
-// the Business Source License, use of this software will be governed
-// by the Apache License, Version 2.0, included in the file
-// licenses/APL.txt.
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
 
 // Package builtinsregistry stores the definitions of builtin functions.
 //
@@ -31,10 +26,6 @@ func Register(name string, props *tree.FunctionProperties, overloads []tree.Over
 	if _, exists := registry[name]; exists {
 		panic("duplicate builtin: " + name)
 	}
-	for i := range overloads {
-		var hook func()
-		overloads[i].OnTypeCheck = &hook
-	}
 	registry[name] = definition{
 		props:     props,
 		overloads: overloads,
diff --git a/pkg/sql/sem/cast/cast.go b/pkg/sql/sem/cast/cast.go
index e827b70..44689cc 100644
--- a/pkg/sql/sem/cast/cast.go
+++ b/pkg/sql/sem/cast/cast.go
@@ -1,12 +1,7 @@
 // Copyright 2022 The Cockroach Authors.
 //
-// Use of this software is governed by the Business Source License
-// included in the file licenses/BSL.txt.
-//
-// As of the Change Date specified in that file, in accordance with
-// the Business Source License, use of this software will be governed
-// by the Apache License, Version 2.0, included in the file
-// licenses/APL.txt.
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
 
 // Package cast defines the semantically allowed casts and their information.
 //
@@ -15,6 +10,8 @@
 package cast
 
 import (
+	"sort"
+
 	"github.com/cockroachdb/cockroachdb-parser/pkg/sql/sem/volatility"
 	"github.com/cockroachdb/cockroachdb-parser/pkg/sql/types"
 	"github.com/lib/pq/oid"
@@ -133,14 +130,31 @@ type Cast struct {
 }
 
 // ForEachCast calls fn for every valid cast from a source type to a target
-// type.
+// type. Iteration order is deterministic.
 func ForEachCast(
 	fn func(
 		src oid.Oid, tgt oid.Oid, castCtx Context, ctxOrigin ContextOrigin, v volatility.V,
 	),
 ) {
-	for src, tgts := range castMap {
-		for tgt, cast := range tgts {
+	srcOids := make([]oid.Oid, 0, len(castMap))
+	for src := range castMap {
+		srcOids = append(srcOids, src)
+	}
+	sort.Slice(srcOids, func(i, j int) bool {
+		return srcOids[i] < srcOids[j]
+	})
+	var tgtOids []oid.Oid
+	for _, src := range srcOids {
+		tgts := castMap[src]
+		tgtOids = tgtOids[:0]
+		for tgt := range tgts {
+			tgtOids = append(tgtOids, tgt)
+		}
+		sort.Slice(tgtOids, func(i, j int) bool {
+			return tgtOids[i] < tgtOids[j]
+		})
+		for _, tgt := range tgtOids {
+			cast := tgts[tgt]
 			fn(src, tgt, cast.MaxContext, cast.origin, cast.Volatility)
 		}
 	}
@@ -164,7 +178,8 @@ func ValidCast(src, tgt *types.T, ctx Context) bool {
 	// Casts from a tuple type to AnyTuple are a no-op so they are always valid.
 	// If tgt is AnyTuple, we continue to LookupCast below which contains a
 	// special case for these casts.
-	if srcFamily == types.TupleFamily && tgtFamily == types.TupleFamily && tgt != types.AnyTuple {
+	if srcFamily == types.TupleFamily && tgtFamily == types.TupleFamily &&
+		!tgt.Identical(types.AnyTuple) {
 		srcTypes := src.TupleContents()
 		tgtTypes := tgt.TupleContents()
 		// The tuple types must have the same number of elements.
@@ -250,6 +265,23 @@ func LookupCast(src, tgt *types.T) (Cast, bool) {
 		}, true
 	}
 
+	if srcFamily == types.ArrayFamily && tgtFamily == types.PGVectorFamily {
+		return Cast{
+			MaxContext: ContextAssignment,
+			Volatility: volatility.Stable,
+		}, true
+	}
+	if srcFamily == types.PGVectorFamily && tgtFamily == types.ArrayFamily &&
+		tgt.ArrayContents().Family() == types.FloatFamily {
+		// Note that postgres only allows casts to FLOAT4[], but given that
+		// under the hood FLOAT8 and FLOAT4 represented exactly the same way in
+		// CRDB we'll allow both.
+		return Cast{
+			MaxContext: ContextAssignment,
+			Volatility: volatility.Stable,
+		}, true
+	}
+
 	// Casts from array and tuple types to string types are immutable and
 	// allowed in assignment contexts.
 	// TODO(mgartner): Tuple to string casts should be stable. They are
@@ -265,7 +297,7 @@ func LookupCast(src, tgt *types.T) (Cast, bool) {
 
 	// Casts from any tuple type to AnyTuple are no-ops, so they are implicit
 	// and immutable.
-	if srcFamily == types.TupleFamily && tgt == types.AnyTuple {
+	if srcFamily == types.TupleFamily && tgt.Identical(types.AnyTuple) {
 		return Cast{
 			MaxContext: ContextImplicit,
 			Volatility: volatility.Immutable,
diff --git a/pkg/sql/sem/cast/cast_map.go b/pkg/sql/sem/cast/cast_map.go
index 8799640..e0fd892 100644
--- a/pkg/sql/sem/cast/cast_map.go
+++ b/pkg/sql/sem/cast/cast_map.go
@@ -1,12 +1,7 @@
 // Copyright 2022 The Cockroach Authors.
 //
-// Use of this software is governed by the Business Source License
-// included in the file licenses/BSL.txt.
-//
-// As of the Change Date specified in that file, in accordance with
-// the Business Source License, use of this software will be governed
-// by the Apache License, Version 2.0, included in the file
-// licenses/APL.txt.
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
 
 package cast
 
@@ -72,6 +67,13 @@ var castMap = map[oid.Oid]map[oid.Oid]Cast{
 		oid.T_varchar: {MaxContext: ContextAssignment, origin: ContextOriginAutomaticIOConversion, Volatility: volatility.Immutable},
 		oid.T_text:    {MaxContext: ContextAssignment, origin: ContextOriginAutomaticIOConversion, Volatility: volatility.Immutable},
 	},
+	oidext.T_pgvector: {
+		oid.T_bpchar:  {MaxContext: ContextAssignment, origin: ContextOriginAutomaticIOConversion, Volatility: volatility.Immutable},
+		oid.T_char:    {MaxContext: ContextAssignment, origin: ContextOriginAutomaticIOConversion, Volatility: volatility.Immutable},
+		oid.T_name:    {MaxContext: ContextAssignment, origin: ContextOriginAutomaticIOConversion, Volatility: volatility.Immutable},
+		oid.T_varchar: {MaxContext: ContextAssignment, origin: ContextOriginAutomaticIOConversion, Volatility: volatility.Immutable},
+		oid.T_text:    {MaxContext: ContextAssignment, origin: ContextOriginAutomaticIOConversion, Volatility: volatility.Immutable},
+	},
 	oid.T_bpchar: {
 		oid.T_bpchar:  {MaxContext: ContextImplicit, origin: ContextOriginPgCast, Volatility: volatility.Immutable},
 		oid.T_char:    {MaxContext: ContextAssignment, origin: ContextOriginPgCast, Volatility: volatility.Immutable},
@@ -79,11 +81,12 @@ var castMap = map[oid.Oid]map[oid.Oid]Cast{
 		oid.T_text:    {MaxContext: ContextImplicit, origin: ContextOriginPgCast, Volatility: volatility.Immutable},
 		oid.T_varchar: {MaxContext: ContextImplicit, origin: ContextOriginPgCast, Volatility: volatility.Immutable},
 		// Automatic I/O conversions from bpchar to other types.
-		oid.T_bit:      {MaxContext: ContextExplicit, origin: ContextOriginAutomaticIOConversion, Volatility: volatility.Immutable},
-		oid.T_bool:     {MaxContext: ContextExplicit, origin: ContextOriginAutomaticIOConversion, Volatility: volatility.Immutable},
-		oidext.T_box2d: {MaxContext: ContextExplicit, origin: ContextOriginAutomaticIOConversion, Volatility: volatility.Immutable},
-		oid.T_pg_lsn:   {MaxContext: ContextExplicit, origin: ContextOriginAutomaticIOConversion, Volatility: volatility.Immutable},
-		oid.T_bytea:    {MaxContext: ContextExplicit, origin: ContextOriginAutomaticIOConversion, Volatility: volatility.Immutable},
+		oid.T_bit:         {MaxContext: ContextExplicit, origin: ContextOriginAutomaticIOConversion, Volatility: volatility.Immutable},
+		oid.T_bool:        {MaxContext: ContextExplicit, origin: ContextOriginAutomaticIOConversion, Volatility: volatility.Immutable},
+		oidext.T_box2d:    {MaxContext: ContextExplicit, origin: ContextOriginAutomaticIOConversion, Volatility: volatility.Immutable},
+		oid.T_pg_lsn:      {MaxContext: ContextExplicit, origin: ContextOriginAutomaticIOConversion, Volatility: volatility.Immutable},
+		oidext.T_pgvector: {MaxContext: ContextExplicit, origin: ContextOriginAutomaticIOConversion, Volatility: volatility.Immutable},
+		oid.T_bytea:       {MaxContext: ContextExplicit, origin: ContextOriginAutomaticIOConversion, Volatility: volatility.Immutable},
 		oid.T_date: {
 			MaxContext:     ContextExplicit,
 			origin:         ContextOriginAutomaticIOConversion,
@@ -105,6 +108,7 @@ var castMap = map[oid.Oid]map[oid.Oid]Cast{
 			VolatilityHint: "CHAR to INTERVAL casts depend on session IntervalStyle; use parse_interval(string) instead",
 		},
 		oid.T_jsonb:        {MaxContext: ContextExplicit, origin: ContextOriginAutomaticIOConversion, Volatility: volatility.Immutable},
+		oidext.T_jsonpath:  {MaxContext: ContextExplicit, origin: ContextOriginAutomaticIOConversion, Volatility: volatility.Immutable},
 		oid.T_numeric:      {MaxContext: ContextExplicit, origin: ContextOriginAutomaticIOConversion, Volatility: volatility.Immutable},
 		oid.T_oid:          {MaxContext: ContextExplicit, origin: ContextOriginAutomaticIOConversion, Volatility: volatility.Immutable},
 		oid.T_record:       {MaxContext: ContextExplicit, origin: ContextOriginAutomaticIOConversion, Volatility: volatility.Stable},
@@ -166,11 +170,12 @@ var castMap = map[oid.Oid]map[oid.Oid]Cast{
 		// Automatic I/O conversions to string types.
 		oid.T_name: {MaxContext: ContextAssignment, origin: ContextOriginAutomaticIOConversion, Volatility: volatility.Immutable},
 		// Automatic I/O conversions from "char" to other types.
-		oid.T_bit:      {MaxContext: ContextExplicit, origin: ContextOriginAutomaticIOConversion, Volatility: volatility.Immutable},
-		oid.T_bool:     {MaxContext: ContextExplicit, origin: ContextOriginAutomaticIOConversion, Volatility: volatility.Immutable},
-		oidext.T_box2d: {MaxContext: ContextExplicit, origin: ContextOriginAutomaticIOConversion, Volatility: volatility.Immutable},
-		oid.T_pg_lsn:   {MaxContext: ContextExplicit, origin: ContextOriginAutomaticIOConversion, Volatility: volatility.Immutable},
-		oid.T_bytea:    {MaxContext: ContextExplicit, origin: ContextOriginAutomaticIOConversion, Volatility: volatility.Immutable},
+		oid.T_bit:         {MaxContext: ContextExplicit, origin: ContextOriginAutomaticIOConversion, Volatility: volatility.Immutable},
+		oid.T_bool:        {MaxContext: ContextExplicit, origin: ContextOriginAutomaticIOConversion, Volatility: volatility.Immutable},
+		oidext.T_box2d:    {MaxContext: ContextExplicit, origin: ContextOriginAutomaticIOConversion, Volatility: volatility.Immutable},
+		oid.T_pg_lsn:      {MaxContext: ContextExplicit, origin: ContextOriginAutomaticIOConversion, Volatility: volatility.Immutable},
+		oidext.T_pgvector: {MaxContext: ContextExplicit, origin: ContextOriginAutomaticIOConversion, Volatility: volatility.Immutable},
+		oid.T_bytea:       {MaxContext: ContextExplicit, origin: ContextOriginAutomaticIOConversion, Volatility: volatility.Immutable},
 		oid.T_date: {
 			MaxContext:     ContextExplicit,
 			origin:         ContextOriginAutomaticIOConversion,
@@ -191,6 +196,7 @@ var castMap = map[oid.Oid]map[oid.Oid]Cast{
 			VolatilityHint: `"char" to INTERVAL casts depend on session IntervalStyle; use parse_interval(string) instead`,
 		},
 		oid.T_jsonb:        {MaxContext: ContextExplicit, origin: ContextOriginAutomaticIOConversion, Volatility: volatility.Immutable},
+		oidext.T_jsonpath:  {MaxContext: ContextExplicit, origin: ContextOriginAutomaticIOConversion, Volatility: volatility.Immutable},
 		oid.T_numeric:      {MaxContext: ContextExplicit, origin: ContextOriginAutomaticIOConversion, Volatility: volatility.Immutable},
 		oid.T_oid:          {MaxContext: ContextExplicit, origin: ContextOriginAutomaticIOConversion, Volatility: volatility.Immutable},
 		oid.T_record:       {MaxContext: ContextExplicit, origin: ContextOriginAutomaticIOConversion, Volatility: volatility.Stable},
@@ -479,6 +485,14 @@ var castMap = map[oid.Oid]map[oid.Oid]Cast{
 		oid.T_text:    {MaxContext: ContextAssignment, origin: ContextOriginAutomaticIOConversion, Volatility: volatility.Immutable},
 		oid.T_varchar: {MaxContext: ContextAssignment, origin: ContextOriginAutomaticIOConversion, Volatility: volatility.Immutable},
 	},
+	oidext.T_jsonpath: {
+		// Automatic I/O conversions to string types.
+		oid.T_bpchar:  {MaxContext: ContextAssignment, origin: ContextOriginAutomaticIOConversion, Volatility: volatility.Immutable},
+		oid.T_char:    {MaxContext: ContextAssignment, origin: ContextOriginAutomaticIOConversion, Volatility: volatility.Immutable},
+		oid.T_name:    {MaxContext: ContextAssignment, origin: ContextOriginAutomaticIOConversion, Volatility: volatility.Immutable},
+		oid.T_text:    {MaxContext: ContextAssignment, origin: ContextOriginAutomaticIOConversion, Volatility: volatility.Immutable},
+		oid.T_varchar: {MaxContext: ContextAssignment, origin: ContextOriginAutomaticIOConversion, Volatility: volatility.Immutable},
+	},
 	oid.T_name: {
 		oid.T_bpchar:  {MaxContext: ContextAssignment, origin: ContextOriginPgCast, Volatility: volatility.Immutable},
 		oid.T_text:    {MaxContext: ContextImplicit, origin: ContextOriginPgCast, Volatility: volatility.Leakproof},
@@ -486,11 +500,12 @@ var castMap = map[oid.Oid]map[oid.Oid]Cast{
 		// Automatic I/O conversions to string types.
 		oid.T_char: {MaxContext: ContextAssignment, origin: ContextOriginAutomaticIOConversion, Volatility: volatility.Immutable},
 		// Automatic I/O conversions from NAME to other types.
-		oid.T_bit:      {MaxContext: ContextExplicit, origin: ContextOriginAutomaticIOConversion, Volatility: volatility.Immutable},
-		oid.T_bool:     {MaxContext: ContextExplicit, origin: ContextOriginAutomaticIOConversion, Volatility: volatility.Immutable},
-		oidext.T_box2d: {MaxContext: ContextExplicit, origin: ContextOriginAutomaticIOConversion, Volatility: volatility.Immutable},
-		oid.T_pg_lsn:   {MaxContext: ContextExplicit, origin: ContextOriginAutomaticIOConversion, Volatility: volatility.Immutable},
-		oid.T_bytea:    {MaxContext: ContextExplicit, origin: ContextOriginAutomaticIOConversion, Volatility: volatility.Immutable},
+		oid.T_bit:         {MaxContext: ContextExplicit, origin: ContextOriginAutomaticIOConversion, Volatility: volatility.Immutable},
+		oid.T_bool:        {MaxContext: ContextExplicit, origin: ContextOriginAutomaticIOConversion, Volatility: volatility.Immutable},
+		oidext.T_box2d:    {MaxContext: ContextExplicit, origin: ContextOriginAutomaticIOConversion, Volatility: volatility.Immutable},
+		oid.T_pg_lsn:      {MaxContext: ContextExplicit, origin: ContextOriginAutomaticIOConversion, Volatility: volatility.Immutable},
+		oidext.T_pgvector: {MaxContext: ContextExplicit, origin: ContextOriginAutomaticIOConversion, Volatility: volatility.Immutable},
+		oid.T_bytea:       {MaxContext: ContextExplicit, origin: ContextOriginAutomaticIOConversion, Volatility: volatility.Immutable},
 		oid.T_date: {
 			MaxContext:     ContextExplicit,
 			origin:         ContextOriginAutomaticIOConversion,
@@ -512,6 +527,7 @@ var castMap = map[oid.Oid]map[oid.Oid]Cast{
 			VolatilityHint: "NAME to INTERVAL casts depend on session IntervalStyle; use parse_interval(string) instead",
 		},
 		oid.T_jsonb:        {MaxContext: ContextExplicit, origin: ContextOriginAutomaticIOConversion, Volatility: volatility.Immutable},
+		oidext.T_jsonpath:  {MaxContext: ContextExplicit, origin: ContextOriginAutomaticIOConversion, Volatility: volatility.Immutable},
 		oid.T_numeric:      {MaxContext: ContextExplicit, origin: ContextOriginAutomaticIOConversion, Volatility: volatility.Immutable},
 		oid.T_oid:          {MaxContext: ContextExplicit, origin: ContextOriginAutomaticIOConversion, Volatility: volatility.Immutable},
 		oid.T_record:       {MaxContext: ContextExplicit, origin: ContextOriginAutomaticIOConversion, Volatility: volatility.Stable},
@@ -733,11 +749,12 @@ var castMap = map[oid.Oid]map[oid.Oid]Cast{
 		oid.T_text:    {MaxContext: ContextImplicit, origin: ContextOriginPgCast, Volatility: volatility.Immutable},
 		oid.T_varchar: {MaxContext: ContextImplicit, origin: ContextOriginPgCast, Volatility: volatility.Immutable},
 		// Automatic I/O conversions from TEXT to other types.
-		oid.T_bit:      {MaxContext: ContextExplicit, origin: ContextOriginAutomaticIOConversion, Volatility: volatility.Immutable},
-		oid.T_bool:     {MaxContext: ContextExplicit, origin: ContextOriginAutomaticIOConversion, Volatility: volatility.Immutable},
-		oidext.T_box2d: {MaxContext: ContextExplicit, origin: ContextOriginAutomaticIOConversion, Volatility: volatility.Immutable},
-		oid.T_pg_lsn:   {MaxContext: ContextExplicit, origin: ContextOriginAutomaticIOConversion, Volatility: volatility.Immutable},
-		oid.T_bytea:    {MaxContext: ContextExplicit, origin: ContextOriginAutomaticIOConversion, Volatility: volatility.Immutable},
+		oid.T_bit:         {MaxContext: ContextExplicit, origin: ContextOriginAutomaticIOConversion, Volatility: volatility.Immutable},
+		oid.T_bool:        {MaxContext: ContextExplicit, origin: ContextOriginAutomaticIOConversion, Volatility: volatility.Immutable},
+		oidext.T_box2d:    {MaxContext: ContextExplicit, origin: ContextOriginAutomaticIOConversion, Volatility: volatility.Immutable},
+		oid.T_pg_lsn:      {MaxContext: ContextExplicit, origin: ContextOriginAutomaticIOConversion, Volatility: volatility.Immutable},
+		oidext.T_pgvector: {MaxContext: ContextExplicit, origin: ContextOriginAutomaticIOConversion, Volatility: volatility.Immutable},
+		oid.T_bytea:       {MaxContext: ContextExplicit, origin: ContextOriginAutomaticIOConversion, Volatility: volatility.Immutable},
 		oid.T_date: {
 			MaxContext:     ContextExplicit,
 			origin:         ContextOriginAutomaticIOConversion,
@@ -758,6 +775,7 @@ var castMap = map[oid.Oid]map[oid.Oid]Cast{
 			VolatilityHint: "STRING to INTERVAL casts depend on session IntervalStyle; use parse_interval(string) instead",
 		},
 		oid.T_jsonb:        {MaxContext: ContextExplicit, origin: ContextOriginAutomaticIOConversion, Volatility: volatility.Immutable},
+		oidext.T_jsonpath:  {MaxContext: ContextExplicit, origin: ContextOriginAutomaticIOConversion, Volatility: volatility.Immutable},
 		oid.T_numeric:      {MaxContext: ContextExplicit, origin: ContextOriginAutomaticIOConversion, Volatility: volatility.Immutable},
 		oid.T_oid:          {MaxContext: ContextExplicit, origin: ContextOriginAutomaticIOConversion, Volatility: volatility.Immutable},
 		oid.T_record:       {MaxContext: ContextExplicit, origin: ContextOriginAutomaticIOConversion, Volatility: volatility.Stable},
@@ -966,11 +984,12 @@ var castMap = map[oid.Oid]map[oid.Oid]Cast{
 		oid.T_text:     {MaxContext: ContextImplicit, origin: ContextOriginPgCast, Volatility: volatility.Immutable},
 		oid.T_varchar:  {MaxContext: ContextImplicit, origin: ContextOriginPgCast, Volatility: volatility.Immutable},
 		// Automatic I/O conversions from VARCHAR to other types.
-		oid.T_bit:      {MaxContext: ContextExplicit, origin: ContextOriginAutomaticIOConversion, Volatility: volatility.Immutable},
-		oid.T_bool:     {MaxContext: ContextExplicit, origin: ContextOriginAutomaticIOConversion, Volatility: volatility.Immutable},
-		oidext.T_box2d: {MaxContext: ContextExplicit, origin: ContextOriginAutomaticIOConversion, Volatility: volatility.Immutable},
-		oid.T_pg_lsn:   {MaxContext: ContextExplicit, origin: ContextOriginAutomaticIOConversion, Volatility: volatility.Immutable},
-		oid.T_bytea:    {MaxContext: ContextExplicit, origin: ContextOriginAutomaticIOConversion, Volatility: volatility.Immutable},
+		oid.T_bit:         {MaxContext: ContextExplicit, origin: ContextOriginAutomaticIOConversion, Volatility: volatility.Immutable},
+		oid.T_bool:        {MaxContext: ContextExplicit, origin: ContextOriginAutomaticIOConversion, Volatility: volatility.Immutable},
+		oidext.T_box2d:    {MaxContext: ContextExplicit, origin: ContextOriginAutomaticIOConversion, Volatility: volatility.Immutable},
+		oid.T_pg_lsn:      {MaxContext: ContextExplicit, origin: ContextOriginAutomaticIOConversion, Volatility: volatility.Immutable},
+		oidext.T_pgvector: {MaxContext: ContextExplicit, origin: ContextOriginAutomaticIOConversion, Volatility: volatility.Immutable},
+		oid.T_bytea:       {MaxContext: ContextExplicit, origin: ContextOriginAutomaticIOConversion, Volatility: volatility.Immutable},
 		oid.T_date: {
 			MaxContext:     ContextExplicit,
 			origin:         ContextOriginAutomaticIOConversion,
@@ -992,6 +1011,7 @@ var castMap = map[oid.Oid]map[oid.Oid]Cast{
 			VolatilityHint: "VARCHAR to INTERVAL casts depend on session IntervalStyle; use parse_interval(string) instead",
 		},
 		oid.T_jsonb:        {MaxContext: ContextExplicit, origin: ContextOriginAutomaticIOConversion, Volatility: volatility.Immutable},
+		oidext.T_jsonpath:  {MaxContext: ContextExplicit, origin: ContextOriginAutomaticIOConversion, Volatility: volatility.Immutable},
 		oid.T_numeric:      {MaxContext: ContextExplicit, origin: ContextOriginAutomaticIOConversion, Volatility: volatility.Immutable},
 		oid.T_oid:          {MaxContext: ContextExplicit, origin: ContextOriginAutomaticIOConversion, Volatility: volatility.Immutable},
 		oid.T_record:       {MaxContext: ContextExplicit, origin: ContextOriginAutomaticIOConversion, Volatility: volatility.Stable},
diff --git a/pkg/sql/sem/cast/cast_map_gen.sh b/pkg/sql/sem/cast/cast_map_gen.sh
index 99597d1..a9feca5 100755
--- a/pkg/sql/sem/cast/cast_map_gen.sh
+++ b/pkg/sql/sem/cast/cast_map_gen.sh
@@ -1,5 +1,11 @@
 #!/bin/bash
 
+# Copyright 2022 The Cockroach Authors.
+#
+# Use of this software is governed by the CockroachDB Software License
+# included in the /LICENSE file.
+
+
 # casts_gen.sh generates castMap entries by reading from Postgres's pg_cast
 # table. To use this script, Postgres must be installed with the PostGIS
 # extension and already running.
diff --git a/pkg/sql/sem/cast/type_name.go b/pkg/sql/sem/cast/type_name.go
index 1bef0df..71d1ed5 100644
--- a/pkg/sql/sem/cast/type_name.go
+++ b/pkg/sql/sem/cast/type_name.go
@@ -1,12 +1,7 @@
 // Copyright 2023 The Cockroach Authors.
 //
-// Use of this software is governed by the Business Source License
-// included in the file licenses/BSL.txt.
-//
-// As of the Change Date specified in that file, in accordance with
-// the Business Source License, use of this software will be governed
-// by the Apache License, Version 2.0, included in the file
-// licenses/APL.txt.
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
 
 package cast
 
@@ -33,6 +28,9 @@ func CastTypeName(t *types.T) string {
 	case oid.T_text:
 		// SQLString returns `string`
 		return "text"
+	case oid.T_bit:
+		// SQLString returns `decimal`
+		return "bit"
 	}
 	return strings.ToLower(t.SQLString())
 }
diff --git a/pkg/sql/sem/catconstants/constants.go b/pkg/sql/sem/catconstants/constants.go
index 5c4b59c..afa1c3c 100644
--- a/pkg/sql/sem/catconstants/constants.go
+++ b/pkg/sql/sem/catconstants/constants.go
@@ -1,12 +1,7 @@
 // Copyright 2017 The Cockroach Authors.
 //
-// Use of this software is governed by the Business Source License
-// included in the file licenses/BSL.txt.
-//
-// As of the Change Date specified in that file, in accordance with
-// the Business Source License, use of this software will be governed
-// by the Apache License, Version 2.0, included in the file
-// licenses/APL.txt.
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
 
 package catconstants
 
@@ -23,6 +18,11 @@ const ReportableAppNamePrefix = "$ "
 // names are used to classify queries in different categories.
 const InternalAppNamePrefix = ReportableAppNamePrefix + "internal"
 
+// AttributedToUserInternalAppNamePrefix indicates that the application name
+// identifies an internally-executed query that should be attributed to the
+// user. Specifically, this means having the queries show up in SQL activity pages.
+const AttributedToUserInternalAppNamePrefix = ReportableAppNamePrefix + "public-internal"
+
 // DelegatedAppNamePrefix is added to a regular client application
 // name for SQL queries that are ran internally on behalf of other SQL
 // queries inside that application. This is not the same as
@@ -58,6 +58,10 @@ const (
 	RangeEventTableName                    SystemTableName = "rangelog"
 	UITableName                            SystemTableName = "ui"
 	JobsTableName                          SystemTableName = "jobs"
+	JobsProgressTableName                  SystemTableName = "job_progress"
+	JobsProgressHistoryTableName           SystemTableName = "job_progress_history"
+	JobsStatusTableName                    SystemTableName = "job_status"
+	JobsMessageTableName                   SystemTableName = "job_message"
 	WebSessionsTableName                   SystemTableName = "web_sessions"
 	TableStatisticsTableName               SystemTableName = "table_statistics"
 	LocationsTableName                     SystemTableName = "locations"
@@ -101,6 +105,8 @@ const (
 	MVCCStatistics                         SystemTableName = "mvcc_statistics"
 	StmtExecInsightsTableName              SystemTableName = "statement_execution_insights"
 	TxnExecInsightsTableName               SystemTableName = "transaction_execution_insights"
+	TableMetadata                          SystemTableName = "table_metadata"
+	PreparedTransactionsTableName          SystemTableName = "prepared_transactions"
 )
 
 // Oid for virtual database and table.
@@ -200,10 +206,26 @@ const (
 	CrdbInternalInheritedRoleMembersTableID
 	CrdbInternalKVSystemPrivilegesViewID
 	CrdbInternalKVFlowControllerID
+	CrdbInternalKVFlowControllerIDV2
 	CrdbInternalKVFlowHandlesID
+	CrdbInternalKVFlowHandlesIDV2
 	CrdbInternalKVFlowTokenDeductions
+	CrdbInternalKVFlowTokenDeductionsV2
 	CrdbInternalRepairableCatalogCorruptionsViewID
 	CrdbInternalKVProtectedTS
+	CrdbInternalKVSessionBasedLeases
+	CrdbInternalClusterReplicationResolvedViewID
+	CrdbInternalLogicalReplicationResolvedViewID
+	CrdbInternalPCRStreamsTableID
+	CrdbInternalPCRStreamSpansTableID
+	CrdbInternalPCRStreamCheckpointsTableID
+	CrdbInternalLDRProcessorTableID
+	CrdbInternalFullyQualifiedNamesViewID
+	CrdbInternalStoreLivenessSupportFrom
+	CrdbInternalStoreLivenessSupportFor
+	// CrdbInternalTestID is reserved for tests that need to inject virtual tables
+	// into crdb_internal.
+	CrdbInternalTestID
 	InformationSchemaID
 	InformationSchemaAdministrableRoleAuthorizationsID
 	InformationSchemaApplicableRolesID
diff --git a/pkg/sql/sem/catconstants/namespace.go b/pkg/sql/sem/catconstants/namespace.go
index 7a81068..a5ab773 100644
--- a/pkg/sql/sem/catconstants/namespace.go
+++ b/pkg/sql/sem/catconstants/namespace.go
@@ -1,12 +1,7 @@
 // Copyright 2018 The Cockroach Authors.
 //
-// Use of this software is governed by the Business Source License
-// included in the file licenses/BSL.txt.
-//
-// As of the Change Date specified in that file, in accordance with
-// the Business Source License, use of this software will be governed
-// by the Apache License, Version 2.0, included in the file
-// licenses/APL.txt.
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
 
 package catconstants
 
diff --git a/pkg/sql/sem/catconstants/schemas.go b/pkg/sql/sem/catconstants/schemas.go
index df686f7..3b23767 100644
--- a/pkg/sql/sem/catconstants/schemas.go
+++ b/pkg/sql/sem/catconstants/schemas.go
@@ -1,12 +1,7 @@
 // Copyright 2021 The Cockroach Authors.
 //
-// Use of this software is governed by the Business Source License
-// included in the file licenses/BSL.txt.
-//
-// As of the Change Date specified in that file, in accordance with
-// the Business Source License, use of this software will be governed
-// by the Apache License, Version 2.0, included in the file
-// licenses/APL.txt.
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
 
 package catconstants
 
diff --git a/pkg/sql/sem/catid/ids.go b/pkg/sql/sem/catid/ids.go
index aa7bc06..f30ce08 100644
--- a/pkg/sql/sem/catid/ids.go
+++ b/pkg/sql/sem/catid/ids.go
@@ -1,12 +1,7 @@
 // Copyright 2017 The Cockroach Authors.
 //
-// Use of this software is governed by the Business Source License
-// included in the file licenses/BSL.txt.
-//
-// As of the Change Date specified in that file, in accordance with
-// the Business Source License, use of this software will be governed
-// by the Apache License, Version 2.0, included in the file
-// licenses/APL.txt.
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
 
 // Package catid is a low-level package exporting ID types.
 package catid
@@ -72,12 +67,18 @@ type IndexID uint32
 // SafeValue implements the redact.SafeValue interface.
 func (IndexID) SafeValue() {}
 
-// ConstraintID is a custom type for TableDeascriptor constraint IDs.
+// ConstraintID is a custom type for TableDescriptor constraint IDs.
 type ConstraintID uint32
 
 // SafeValue implements the redact.SafeValue interface.
 func (ConstraintID) SafeValue() {}
 
+// TriggerID is a custom type for TableDescriptor trigger IDs.
+type TriggerID uint32
+
+// SafeValue implements the redact.SafeValue interface.
+func (TriggerID) SafeValue() {}
+
 // PGAttributeNum is a custom type for Column's logical order.
 type PGAttributeNum uint32
 
@@ -86,3 +87,9 @@ func (PGAttributeNum) SafeValue() {}
 
 // RoleID is a custom type for a role id.
 type RoleID uint32
+
+// PolicyID is a custom type for TableDescriptor policy IDs.
+type PolicyID uint32
+
+// SafeValue implements the redact.SafeValue interface.
+func (PolicyID) SafeValue() {}
diff --git a/pkg/sql/sem/catid/index_id_set.go b/pkg/sql/sem/catid/index_id_set.go
index 5e3d33d..9f15627 100644
--- a/pkg/sql/sem/catid/index_id_set.go
+++ b/pkg/sql/sem/catid/index_id_set.go
@@ -1,12 +1,7 @@
 // Copyright 2022 The Cockroach Authors.
 //
-// Use of this software is governed by the Business Source License
-// included in the file licenses/BSL.txt.
-//
-// As of the Change Date specified in that file, in accordance with
-// the Business Source License, use of this software will be governed
-// by the Apache License, Version 2.0, included in the file
-// licenses/APL.txt.
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
 
 package catid
 
diff --git a/pkg/sql/sem/idxtype/idxtype.go b/pkg/sql/sem/idxtype/idxtype.go
new file mode 100644
index 0000000..4f718e6
--- /dev/null
+++ b/pkg/sql/sem/idxtype/idxtype.go
@@ -0,0 +1,75 @@
+// Copyright 2025 The Cockroach Authors.
+//
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
+
+package idxtype
+
+import "github.com/cockroachdb/redact"
+
+// CanBePrimary is true if this index type can be the primary index that always
+// contains unique keys sorted according to the primary ordering of the table.
+// Secondary indexes refer to rows in the primary index by unique key value.
+func (t T) CanBePrimary() bool {
+	return t == FORWARD
+}
+
+// CanBeUnique is true if this index type can be declared as UNIQUE, meaning it
+// never contains duplicate keys.
+func (t T) CanBeUnique() bool {
+	return t == FORWARD
+}
+
+// HasLinearOrdering is true if this index type does not define a linear
+// ordering on the last key column in the index. For example, a vector index
+// groups nearby vectors, but does not define a linear ordering among them. As
+// another example, an inverted index only defines a linear ordering for tokens,
+// not for the original JSONB or ARRAY data type.
+func (t T) HasLinearOrdering() bool {
+	return t == FORWARD
+}
+
+// AllowsPrefixColumns is true if this index type allows other columns from the
+// table to act as a key prefix that separates indexed values into distinct
+// groupings, e.g. by user or customer.
+func (t T) AllowsPrefixColumns() bool {
+	return t == INVERTED || t == VECTOR
+}
+
+// SupportsSharding is true if this index type can be hash sharded, meaning that
+// its rows are grouped according to a hash value and spread across the
+// keyspace.
+func (t T) SupportsSharding() bool {
+	return t == FORWARD
+}
+
+// SupportsStoring is true if this index type allows STORING values, which are
+// un-indexed columns from the table that are stored directly in the index for
+// faster retrieval.
+func (t T) SupportsStoring() bool {
+	return t == FORWARD
+}
+
+// SupportsOpClass is true if this index type allows columns to specify an
+// operator class, which defines an alternate set of operators used when sorting
+// and querying those columns.
+//
+// NOTE: Currently, only inverted and vector indexes support operator classes,
+// and only on the last column of the index.
+func (t T) SupportsOpClass() bool {
+	return t == INVERTED || t == VECTOR
+}
+
+// ErrorText describes the type of the index using the phrase "an inverted
+// index" or "a vector index". This is intended to be included in errors that
+// apply to multiple index types.
+func ErrorText(t T) redact.SafeString {
+	switch t {
+	case INVERTED:
+		return "an inverted index"
+	case VECTOR:
+		return "a vector index"
+	default:
+		return "an index"
+	}
+}
diff --git a/pkg/sql/sem/idxtype/idxtype.pb.go b/pkg/sql/sem/idxtype/idxtype.pb.go
new file mode 100644
index 0000000..e55a2c3
--- /dev/null
+++ b/pkg/sql/sem/idxtype/idxtype.pb.go
@@ -0,0 +1,83 @@
+// Code generated by protoc-gen-gogo. DO NOT EDIT.
+// source: sql/sem/idxtype/idxtype.proto
+
+package idxtype
+
+import (
+	fmt "fmt"
+	_ "github.com/gogo/protobuf/gogoproto"
+	proto "github.com/gogo/protobuf/proto"
+	math "math"
+)
+
+// Reference imports to suppress errors if they are not otherwise used.
+var _ = proto.Marshal
+var _ = fmt.Errorf
+var _ = math.Inf
+
+// This is a compile-time assertion to ensure that this generated file
+// is compatible with the proto package it is being compiled against.
+// A compilation error at this line likely means your copy of the
+// proto package needs to be updated.
+const _ = proto.GoGoProtoPackageIsVersion3 // please upgrade the proto package
+
+// T represents different types of indexes that can be defined on a table.
+type T int32
+
+const (
+	// FORWARD is a standard relational index, containing at most one entry for
+	// each row in the table (if a partial index, a table row may not have a
+	// corresponding entry in the index).
+	FORWARD T = 0
+	// INVERTED indexes can contain multiple entries for each row in the table,
+	// which is useful for indexing collection or composite data types like JSONB,
+	// ARRAY, and GEOGRAPHY.
+	INVERTED T = 1
+	// VECTOR indexes high-dimensional vectors to enable rapid similarity search
+	// using an approximate nearest neighbor (ANN) algorithm.
+	VECTOR T = 2
+)
+
+var T_name = map[int32]string{
+	0: "FORWARD",
+	1: "INVERTED",
+	2: "VECTOR",
+}
+
+var T_value = map[string]int32{
+	"FORWARD":  0,
+	"INVERTED": 1,
+	"VECTOR":   2,
+}
+
+func (x T) String() string {
+	return proto.EnumName(T_name, int32(x))
+}
+
+func (T) EnumDescriptor() ([]byte, []int) {
+	return fileDescriptor_f11c9d993fdc9c28, []int{0}
+}
+
+func init() {
+	proto.RegisterEnum("cockroach.parser.sql.sem.idxtype.T", T_name, T_value)
+}
+
+func init() { proto.RegisterFile("sql/sem/idxtype/idxtype.proto", fileDescriptor_f11c9d993fdc9c28) }
+
+var fileDescriptor_f11c9d993fdc9c28 = []byte{
+	// 201 bytes of a gzipped FileDescriptorProto
+	0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0x92, 0x2d, 0x2e, 0xcc, 0xd1,
+	0x2f, 0x4e, 0xcd, 0xd5, 0xcf, 0x4c, 0xa9, 0x28, 0xa9, 0x2c, 0x48, 0x85, 0xd1, 0x7a, 0x05, 0x45,
+	0xf9, 0x25, 0xf9, 0x42, 0x92, 0xc9, 0xf9, 0xc9, 0xd9, 0x45, 0xf9, 0x89, 0xc9, 0x19, 0x7a, 0xc5,
+	0x85, 0x39, 0x7a, 0xc5, 0xa9, 0xb9, 0x7a, 0x50, 0x05, 0x52, 0x22, 0xe9, 0xf9, 0xe9, 0xf9, 0x60,
+	0x55, 0xfa, 0x20, 0x16, 0x44, 0x83, 0x96, 0x01, 0x17, 0x63, 0x88, 0x10, 0x37, 0x17, 0xbb, 0x9b,
+	0x7f, 0x50, 0xb8, 0x63, 0x90, 0x8b, 0x00, 0x83, 0x10, 0x0f, 0x17, 0x87, 0xa7, 0x5f, 0x98, 0x6b,
+	0x50, 0x88, 0xab, 0x8b, 0x00, 0xa3, 0x10, 0x17, 0x17, 0x5b, 0x98, 0xab, 0x73, 0x88, 0x7f, 0x90,
+	0x00, 0x93, 0x14, 0x4b, 0xc7, 0x62, 0x39, 0x06, 0xa7, 0xb0, 0x13, 0x0f, 0xe5, 0x18, 0x4e, 0x3c,
+	0x92, 0x63, 0xbc, 0xf0, 0x48, 0x8e, 0xf1, 0xc6, 0x23, 0x39, 0xc6, 0x07, 0x8f, 0xe4, 0x18, 0x27,
+	0x3c, 0x96, 0x63, 0xb8, 0xf0, 0x58, 0x8e, 0xe1, 0xc6, 0x63, 0x39, 0x86, 0x28, 0x93, 0xf4, 0xcc,
+	0x92, 0x8c, 0xd2, 0x24, 0xbd, 0xe4, 0xfc, 0x5c, 0x7d, 0xb8, 0x7b, 0x52, 0x92, 0x10, 0x6c, 0xfd,
+	0x82, 0xec, 0x74, 0x7d, 0x34, 0x8f, 0x24, 0xb1, 0x81, 0x1d, 0x64, 0x0c, 0x08, 0x00, 0x00, 0xff,
+	0xff, 0x16, 0x50, 0xca, 0xe4, 0xe2, 0x00, 0x00, 0x00,
+}
+
diff --git a/pkg/sql/sem/idxtype/idxtype.proto b/pkg/sql/sem/idxtype/idxtype.proto
new file mode 100644
index 0000000..e7b34e0
--- /dev/null
+++ b/pkg/sql/sem/idxtype/idxtype.proto
@@ -0,0 +1,27 @@
+// Copyright 2025 The Cockroach Authors.
+//
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
+
+syntax = "proto3";
+package cockroach.sql.sem.idxtype;
+option go_package = "github.com/cockroachdb/cockroach/pkg/sql/sem/idxtype";
+
+import "gogoproto/gogo.proto";
+
+// T represents different types of indexes that can be defined on a table.
+enum T {
+  option (gogoproto.goproto_enum_prefix) = false;
+
+  // FORWARD is a standard relational index, containing at most one entry for
+  // each row in the table (if a partial index, a table row may not have a
+  // corresponding entry in the index).
+  FORWARD = 0;
+  // INVERTED indexes can contain multiple entries for each row in the table,
+  // which is useful for indexing collection or composite data types like JSONB,
+  // ARRAY, and GEOGRAPHY.
+  INVERTED = 1;
+  // VECTOR indexes high-dimensional vectors to enable rapid similarity search
+  // using an approximate nearest neighbor (ANN) algorithm.
+  VECTOR = 2;
+};
diff --git a/pkg/sql/sem/plpgsqltree/constants.go b/pkg/sql/sem/plpgsqltree/constants.go
index 67ebc34..a0aa05c 100644
--- a/pkg/sql/sem/plpgsqltree/constants.go
+++ b/pkg/sql/sem/plpgsqltree/constants.go
@@ -1,12 +1,7 @@
 // Copyright 2023 The Cockroach Authors.
 //
-// Use of this software is governed by the Business Source License
-// included in the file licenses/BSL.txt.
-//
-// As of the Change Date specified in that file, in accordance with
-// the Business Source License, use of this software will be governed
-// by the Apache License, Version 2.0, included in the file
-// licenses/APL.txt.
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
 
 package plpgsqltree
 
diff --git a/pkg/sql/sem/plpgsqltree/exception.go b/pkg/sql/sem/plpgsqltree/exception.go
index bb8bab0..7fbb7ee 100644
--- a/pkg/sql/sem/plpgsqltree/exception.go
+++ b/pkg/sql/sem/plpgsqltree/exception.go
@@ -1,12 +1,7 @@
 // Copyright 2023 The Cockroach Authors.
 //
-// Use of this software is governed by the Business Source License
-// included in the file licenses/BSL.txt.
-//
-// As of the Change Date specified in that file, in accordance with
-// the Business Source License, use of this software will be governed
-// by the Apache License, Version 2.0, included in the file
-// licenses/APL.txt.
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
 
 package plpgsqltree
 
@@ -48,19 +43,20 @@ func (s *Exception) PlpgSQLStatementTag() string {
 	return "proc_exception"
 }
 
-func (s *Exception) WalkStmt(visitor StatementVisitor) (newStmt Statement, changed bool) {
-	newStmt, changed = visitor.Visit(s)
-	for i, stmt := range s.Action {
-		ns, ch := stmt.WalkStmt(visitor)
-		if ch {
-			changed = true
-			if newStmt == s {
-				newStmt = s.CopyNode()
+func (s *Exception) WalkStmt(visitor StatementVisitor) Statement {
+	newStmt, recurse := visitor.Visit(s)
+	if recurse {
+		for i, actionStmt := range s.Action {
+			newActionStmt := actionStmt.WalkStmt(visitor)
+			if newActionStmt != actionStmt {
+				if newStmt == s {
+					newStmt = s.CopyNode()
+				}
+				newStmt.(*Exception).Action[i] = newActionStmt
 			}
-			newStmt.(*Exception).Action[i] = ns
 		}
 	}
-	return newStmt, changed
+	return newStmt
 }
 
 type Condition struct {
diff --git a/pkg/sql/sem/plpgsqltree/statements.go b/pkg/sql/sem/plpgsqltree/statements.go
index 6265b22..8beb89c 100644
--- a/pkg/sql/sem/plpgsqltree/statements.go
+++ b/pkg/sql/sem/plpgsqltree/statements.go
@@ -1,12 +1,7 @@
 // Copyright 2023 The Cockroach Authors.
 //
-// Use of this software is governed by the Business Source License
-// included in the file licenses/BSL.txt.
-//
-// As of the Change Date specified in that file, in accordance with
-// the Business Source License, use of this software will be governed
-// by the Apache License, Version 2.0, included in the file
-// licenses/APL.txt.
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
 
 package plpgsqltree
 
@@ -26,22 +21,19 @@ type Statement interface {
 	GetLineNo() int
 	GetStmtID() uint
 	plpgsqlStmt()
-	WalkStmt(StatementVisitor) (newStmt Statement, changed bool)
-}
-
-type TaggedStatement interface {
+	WalkStmt(StatementVisitor) Statement
 	PlpgSQLStatementTag() string
 }
 
 type StatementImpl struct {
-	// TODO(Chengxiong): figure out how to get line number from scanner.
+	// TODO(drewk): figure out how to get line number from scanner.
 	LineNo int
 	/*
 	 * Unique statement ID in this function (starting at 1; 0 is invalid/not
 	 * set).  This can be used by a profiler as the index for an array of
 	 * per-statement metrics.
 	 */
-	// TODO(Chengxiong): figure out how to get statement id from parser.
+	// TODO(drewk): figure out how to get statement id from parser.
 	StmtID uint
 }
 
@@ -72,8 +64,12 @@ func (s *Block) CopyNode() *Block {
 	return &copyNode
 }
 
-// TODO(drewk): format Label and Exceptions fields.
 func (s *Block) Format(ctx *tree.FmtCtx) {
+	if s.Label != "" {
+		ctx.WriteString("<<")
+		ctx.FormatNameP(&s.Label)
+		ctx.WriteString(">>\n")
+	}
 	if s.Decls != nil {
 		ctx.WriteString("DECLARE\n")
 		for _, dec := range s.Decls {
@@ -92,46 +88,51 @@ func (s *Block) Format(ctx *tree.FmtCtx) {
 			ctx.FormatNode(&e)
 		}
 	}
-	ctx.WriteString("END\n")
+	ctx.WriteString("END")
+	if s.Label != "" {
+		ctx.WriteString(" ")
+		ctx.FormatNameP(&s.Label)
+	}
+	ctx.WriteString(";\n")
 }
 
 func (s *Block) PlpgSQLStatementTag() string {
 	return "stmt_block"
 }
 
-func (s *Block) WalkStmt(visitor StatementVisitor) (newStmt Statement, changed bool) {
-	newStmt, changed = visitor.Visit(s)
-	for i, stmt := range s.Decls {
-		ns, ch := stmt.WalkStmt(visitor)
-		if ch {
-			changed = true
-			if newStmt == s {
-				newStmt = s.CopyNode()
+func (s *Block) WalkStmt(visitor StatementVisitor) Statement {
+	newStmt, recurse := visitor.Visit(s)
+	if recurse {
+		for i, decl := range s.Decls {
+			newDecl := decl.WalkStmt(visitor)
+			if newDecl != decl {
+				if newStmt == s {
+					newStmt = s.CopyNode()
+				}
+				newStmt.(*Block).Decls[i] = newDecl
 			}
-			newStmt.(*Block).Decls[i] = ns
 		}
-	}
-	for i, stmt := range s.Body {
-		ns, ch := stmt.WalkStmt(visitor)
-		if ch {
-			changed = true
-			if newStmt == s {
-				newStmt = s.CopyNode()
+		for i, bodyStmt := range s.Body {
+			newBodyStmt := bodyStmt.WalkStmt(visitor)
+			if newBodyStmt != bodyStmt {
+				if newStmt == s {
+					newStmt = s.CopyNode()
+				}
+				newStmt.(*Block).Body[i] = newBodyStmt
 			}
-			newStmt.(*Block).Body[i] = ns
 		}
-	}
-	for i, stmt := range s.Exceptions {
-		ns, ch := stmt.WalkStmt(visitor)
-		if ch {
-			changed = true
-			if newStmt == s {
-				newStmt = s.CopyNode()
+		for i := range s.Exceptions {
+			exception := &s.Exceptions[i]
+			newException := exception.WalkStmt(visitor)
+			if newException != exception {
+				if newStmt == s {
+					newStmt = s.CopyNode()
+				}
+				newStmt.(*Block).Exceptions[i] = *(newException.(*Exception))
 			}
-			newStmt.(*Block).Exceptions[i] = *(ns.(*Exception))
 		}
 	}
-	return newStmt, changed
+	return newStmt
 }
 
 // decl_stmt
@@ -151,7 +152,7 @@ func (s *Declaration) CopyNode() *Declaration {
 }
 
 func (s *Declaration) Format(ctx *tree.FmtCtx) {
-	ctx.WriteString(string(s.Var))
+	ctx.FormatNode(&s.Var)
 	if s.Constant {
 		ctx.WriteString(" CONSTANT")
 	}
@@ -175,16 +176,17 @@ func (s *Declaration) PlpgSQLStatementTag() string {
 	return "decl_stmt"
 }
 
-func (s *Declaration) WalkStmt(visitor StatementVisitor) (newStmt Statement, changed bool) {
-	newStmt, changed = visitor.Visit(s)
-	return newStmt, changed
+func (s *Declaration) WalkStmt(visitor StatementVisitor) Statement {
+	newStmt, _ := visitor.Visit(s)
+	return newStmt
 }
 
 type CursorDeclaration struct {
 	StatementImpl
-	Name   Variable
-	Scroll tree.CursorScrollOption
-	Query  tree.Statement
+	Name        Variable
+	Scroll      tree.CursorScrollOption
+	Query       tree.Statement
+	Annotations *tree.Annotations
 }
 
 func (s *CursorDeclaration) CopyNode() *CursorDeclaration {
@@ -193,32 +195,38 @@ func (s *CursorDeclaration) CopyNode() *CursorDeclaration {
 }
 
 func (s *CursorDeclaration) Format(ctx *tree.FmtCtx) {
-	ctx.WriteString(string(s.Name))
-	switch s.Scroll {
-	case tree.Scroll:
-		ctx.WriteString(" SCROLL")
-	case tree.NoScroll:
-		ctx.WriteString(" NO SCROLL")
-	}
-	ctx.WriteString(" CURSOR FOR ")
-	ctx.FormatNode(s.Query)
-	ctx.WriteString(";\n")
+	ctx.WithAnnotations(s.Annotations, func() {
+		ctx.FormatNode(&s.Name)
+		switch s.Scroll {
+		case tree.Scroll:
+			ctx.WriteString(" SCROLL")
+		case tree.NoScroll:
+			ctx.WriteString(" NO SCROLL")
+		}
+		ctx.WriteString(" CURSOR FOR ")
+		ctx.FormatNode(s.Query)
+		ctx.WriteString(";\n")
+	})
 }
 
 func (s *CursorDeclaration) PlpgSQLStatementTag() string {
 	return "decl_cursor_stmt"
 }
 
-func (s *CursorDeclaration) WalkStmt(visitor StatementVisitor) (newStmt Statement, changed bool) {
-	newStmt, changed = visitor.Visit(s)
-	return newStmt, changed
+func (s *CursorDeclaration) WalkStmt(visitor StatementVisitor) Statement {
+	newStmt, _ := visitor.Visit(s)
+	return newStmt
 }
 
 // stmt_assign
 type Assignment struct {
-	Statement
+	StatementImpl
 	Var   Variable
 	Value Expr
+
+	// Indirection is the optional name of a field in a composite variable. For
+	// example, in the assignment "foo.bar := 1", Indirection would be "bar".
+	Indirection tree.Name
 }
 
 func (s *Assignment) CopyNode() *Assignment {
@@ -232,14 +240,18 @@ func (s *Assignment) PlpgSQLStatementTag() string {
 
 func (s *Assignment) Format(ctx *tree.FmtCtx) {
 	ctx.FormatNode(&s.Var)
+	if s.Indirection != "" {
+		ctx.WriteByte('.')
+		ctx.FormatNode(&s.Indirection)
+	}
 	ctx.WriteString(" := ")
 	ctx.FormatNode(s.Value)
 	ctx.WriteString(";\n")
 }
 
-func (s *Assignment) WalkStmt(visitor StatementVisitor) (newStmt Statement, changed bool) {
-	newStmt, changed = visitor.Visit(s)
-	return newStmt, changed
+func (s *Assignment) WalkStmt(visitor StatementVisitor) Statement {
+	newStmt, _ := visitor.Visit(s)
+	return newStmt
 }
 
 // stmt_if
@@ -289,43 +301,40 @@ func (s *If) PlpgSQLStatementTag() string {
 	return "stmt_if"
 }
 
-func (s *If) WalkStmt(visitor StatementVisitor) (newStmt Statement, changed bool) {
-	newStmt, changed = visitor.Visit(s)
+func (s *If) WalkStmt(visitor StatementVisitor) Statement {
+	newStmt, recurse := visitor.Visit(s)
 
-	for i, thenStmt := range s.ThenBody {
-		ns, ch := thenStmt.WalkStmt(visitor)
-		if ch {
-			changed = true
-			if newStmt == s {
-				newStmt = s.CopyNode()
+	if recurse {
+		for i, thenStmt := range s.ThenBody {
+			newThenStmt := thenStmt.WalkStmt(visitor)
+			if newThenStmt != thenStmt {
+				if newStmt == s {
+					newStmt = s.CopyNode()
+				}
+				newStmt.(*If).ThenBody[i] = newThenStmt
 			}
-			newStmt.(*If).ThenBody[i] = ns
 		}
-	}
-
-	for i, elseIf := range s.ElseIfList {
-		ns, ch := elseIf.WalkStmt(visitor)
-		if ch {
-			changed = true
-			if newStmt == s {
-				newStmt = s.CopyNode()
+		for i := range s.ElseIfList {
+			elseIf := &s.ElseIfList[i]
+			newElseIf := elseIf.WalkStmt(visitor)
+			if newElseIf != elseIf {
+				if newStmt == s {
+					newStmt = s.CopyNode()
+				}
+				newStmt.(*If).ElseIfList[i] = *newElseIf.(*ElseIf)
 			}
-			newStmt.(*If).ElseIfList[i] = *ns.(*ElseIf)
 		}
-	}
-
-	for i, elseStmt := range s.ElseBody {
-		ns, ch := elseStmt.WalkStmt(visitor)
-		if ch {
-			changed = true
-			if newStmt == s {
-				newStmt = s.CopyNode()
+		for i, elseStmt := range s.ElseBody {
+			newElseStmt := elseStmt.WalkStmt(visitor)
+			if newElseStmt != elseStmt {
+				if newStmt == s {
+					newStmt = s.CopyNode()
+				}
+				newStmt.(*If).ElseBody[i] = newElseStmt
 			}
-			newStmt.(*If).ElseBody[i] = ns
 		}
 	}
-
-	return newStmt, changed
+	return newStmt
 }
 
 type ElseIf struct {
@@ -354,20 +363,21 @@ func (s *ElseIf) PlpgSQLStatementTag() string {
 	return "stmt_if_else_if"
 }
 
-func (s *ElseIf) WalkStmt(visitor StatementVisitor) (newStmt Statement, changed bool) {
-	newStmt, changed = visitor.Visit(s)
+func (s *ElseIf) WalkStmt(visitor StatementVisitor) Statement {
+	newStmt, recurse := visitor.Visit(s)
 
-	for i, stmt := range s.Stmts {
-		ns, ch := stmt.WalkStmt(visitor)
-		if ch {
-			changed = true
-			if newStmt == s {
-				newStmt = s.CopyNode()
+	if recurse {
+		for i, bodyStmt := range s.Stmts {
+			newBodyStmt := bodyStmt.WalkStmt(visitor)
+			if newBodyStmt != bodyStmt {
+				if newStmt == s {
+					newStmt = s.CopyNode()
+				}
+				newStmt.(*ElseIf).Stmts[i] = newBodyStmt
 			}
-			newStmt.(*ElseIf).Stmts[i] = ns
 		}
 	}
-	return newStmt, changed
+	return newStmt
 }
 
 // stmt_case
@@ -418,33 +428,32 @@ func (s *Case) PlpgSQLStatementTag() string {
 	return "stmt_case"
 }
 
-func (s *Case) WalkStmt(visitor StatementVisitor) (newStmt Statement, changed bool) {
-	newStmt, changed = visitor.Visit(s)
-
-	for i, when := range s.CaseWhenList {
-		ns, ch := when.WalkStmt(visitor)
-		if ch {
-			changed = true
-			if newStmt == s {
-				newStmt = s.CopyNode()
-			}
-			newStmt.(*Case).CaseWhenList[i] = ns.(*CaseWhen)
-		}
-	}
+func (s *Case) WalkStmt(visitor StatementVisitor) Statement {
+	newStmt, recurse := visitor.Visit(s)
 
-	if s.HaveElse {
-		for i, stmt := range s.ElseStmts {
-			ns, ch := stmt.WalkStmt(visitor)
-			if ch {
-				changed = true
+	if recurse {
+		for i, when := range s.CaseWhenList {
+			newWhen := when.WalkStmt(visitor)
+			if newWhen != when {
 				if newStmt == s {
 					newStmt = s.CopyNode()
 				}
-				newStmt.(*Case).ElseStmts[i] = ns
+				newStmt.(*Case).CaseWhenList[i] = newWhen.(*CaseWhen)
+			}
+		}
+		if s.HaveElse {
+			for i, elseStmt := range s.ElseStmts {
+				newElseStmt := elseStmt.WalkStmt(visitor)
+				if newElseStmt != elseStmt {
+					if newStmt == s {
+						newStmt = s.CopyNode()
+					}
+					newStmt.(*Case).ElseStmts[i] = newElseStmt
+				}
 			}
 		}
 	}
-	return newStmt, changed
+	return newStmt
 }
 
 type CaseWhen struct {
@@ -475,20 +484,21 @@ func (s *CaseWhen) PlpgSQLStatementTag() string {
 	return "stmt_when"
 }
 
-func (s *CaseWhen) WalkStmt(visitor StatementVisitor) (newStmt Statement, changed bool) {
-	newStmt, changed = visitor.Visit(s)
+func (s *CaseWhen) WalkStmt(visitor StatementVisitor) Statement {
+	newStmt, recurse := visitor.Visit(s)
 
-	for i, stmt := range s.Stmts {
-		ns, ch := stmt.WalkStmt(visitor)
-		if ch {
-			changed = true
-			if newStmt == s {
-				newStmt = s.CopyNode()
+	if recurse {
+		for i, bodyStmt := range s.Stmts {
+			newBodyStmt := bodyStmt.WalkStmt(visitor)
+			if newBodyStmt != bodyStmt {
+				if newStmt == s {
+					newStmt = s.CopyNode()
+				}
+				newStmt.(*CaseWhen).Stmts[i] = newBodyStmt
 			}
-			newStmt.(*CaseWhen).Stmts[i] = ns
 		}
 	}
-	return newStmt, changed
+	return newStmt
 }
 
 // stmt_loop
@@ -526,19 +536,21 @@ func (s *Loop) Format(ctx *tree.FmtCtx) {
 	ctx.WriteString(";\n")
 }
 
-func (s *Loop) WalkStmt(visitor StatementVisitor) (newStmt Statement, changed bool) {
-	newStmt, changed = visitor.Visit(s)
-	for i, stmt := range s.Body {
-		ns, ch := stmt.WalkStmt(visitor)
-		if ch {
-			changed = true
-			if newStmt == s {
-				newStmt = s.CopyNode()
+func (s *Loop) WalkStmt(visitor StatementVisitor) Statement {
+	newStmt, recurse := visitor.Visit(s)
+
+	if recurse {
+		for i, bodyStmt := range s.Body {
+			newBodyStmt := bodyStmt.WalkStmt(visitor)
+			if newBodyStmt != bodyStmt {
+				if newStmt == s {
+					newStmt = s.CopyNode()
+				}
+				newStmt.(*Loop).Body[i] = newBodyStmt
 			}
-			newStmt.(*Loop).Body[i] = ns
 		}
 	}
-	return newStmt, changed
+	return newStmt
 }
 
 // stmt_while
@@ -579,110 +591,119 @@ func (s *While) PlpgSQLStatementTag() string {
 	return "stmt_while"
 }
 
-func (s *While) WalkStmt(visitor StatementVisitor) (newStmt Statement, changed bool) {
-	newStmt, changed = visitor.Visit(s)
-	for i, stmt := range s.Body {
-		ns, ch := stmt.WalkStmt(visitor)
-		if ch {
-			changed = true
-			if newStmt == s {
-				newStmt = s.CopyNode()
+func (s *While) WalkStmt(visitor StatementVisitor) Statement {
+	newStmt, recurse := visitor.Visit(s)
+
+	if recurse {
+		for i, bodyStmt := range s.Body {
+			newBodyStmt := bodyStmt.WalkStmt(visitor)
+			if newBodyStmt != bodyStmt {
+				if newStmt == s {
+					newStmt = s.CopyNode()
+				}
+				newStmt.(*While).Body[i] = newBodyStmt
 			}
-			newStmt.(*While).Body[i] = ns
 		}
 	}
-	return newStmt, changed
+	return newStmt
 }
 
-// stmt_for
-type ForInt struct {
-	StatementImpl
-	Label   string
-	Var     Variable
+// ForLoopControl is an interface covering the loop control structures for the
+// integer range, query, and cursor FOR loops.
+type ForLoopControl interface {
+	isForLoopControl()
+	Format(ctx *tree.FmtCtx)
+}
+
+type IntForLoopControl struct {
+	Reverse bool
 	Lower   Expr
 	Upper   Expr
 	Step    Expr
-	Reverse int
-	Body    []Statement
 }
 
-func (s *ForInt) Format(ctx *tree.FmtCtx) {
-}
+var _ ForLoopControl = &IntForLoopControl{}
 
-func (s *ForInt) PlpgSQLStatementTag() string {
-	return "stmt_for_int_loop"
-}
+func (c *IntForLoopControl) isForLoopControl() {}
 
-func (s *ForInt) WalkStmt(visitor StatementVisitor) (newStmt Statement, changed bool) {
-	panic(unimplemented.New("plpgsql visitor", "Unimplemented PLpgSQL visitor pattern"))
+func (c *IntForLoopControl) Format(ctx *tree.FmtCtx) {
+	if c.Reverse {
+		ctx.WriteString("REVERSE ")
+	}
+	ctx.FormatNode(c.Lower)
+	ctx.WriteString("..")
+	ctx.FormatNode(c.Upper)
+	if c.Step != nil {
+		ctx.WriteString(" BY ")
+		ctx.FormatNode(c.Step)
+	}
 }
 
-type ForQuery struct {
+// stmt_for
+type ForLoop struct {
 	StatementImpl
-	Label string
-	Var   Variable
-	Body  []Statement
-}
-
-func (s *ForQuery) Format(ctx *tree.FmtCtx) {
-}
-
-func (s *ForQuery) PlpgSQLStatementTag() string {
-	return "stmt_for_query_loop"
-}
-
-func (s *ForQuery) WalkStmt(visitor StatementVisitor) (newStmt Statement, changed bool) {
-	panic(unimplemented.New("plpgsql visitor", "Unimplemented PLpgSQL visitor pattern"))
-}
-
-type ForSelect struct {
-	ForQuery
-	Query Expr
-}
-
-func (s *ForSelect) Format(ctx *tree.FmtCtx) {
-}
-
-func (s *ForSelect) PlpgSQLStatementTag() string {
-	return "stmt_query_select_loop"
-}
-
-func (s *ForSelect) WalkStmt(visitor StatementVisitor) (newStmt Statement, changed bool) {
-	panic(unimplemented.New("plpgsql visitor", "Unimplemented PLpgSQL visitor pattern"))
-}
-
-type ForCursor struct {
-	ForQuery
-	CurVar   int // TODO(drewk): is this CursorVariable?
-	ArgQuery Expr
-}
-
-func (s *ForCursor) Format(ctx *tree.FmtCtx) {
-}
-
-func (s *ForCursor) PlpgSQLStatementTag() string {
-	return "stmt_for_query_cursor_loop"
+	Label   string
+	Target  []Variable
+	Control ForLoopControl
+	Body    []Statement
 }
 
-func (s *ForCursor) WalkStmt(visitor StatementVisitor) (newStmt Statement, changed bool) {
-	panic(unimplemented.New("plpgsql visitor", "Unimplemented PLpgSQL visitor pattern"))
+func (s *ForLoop) CopyNode() *ForLoop {
+	copyNode := *s
+	copyNode.Body = append([]Statement(nil), copyNode.Body...)
+	return &copyNode
 }
 
-type ForDynamic struct {
-	ForQuery
-	Query  Expr
-	Params []Expr
+func (s *ForLoop) Format(ctx *tree.FmtCtx) {
+	if s.Label != "" {
+		ctx.WriteString("<<")
+		ctx.FormatNameP(&s.Label)
+		ctx.WriteString(">>\n")
+	}
+	ctx.WriteString("FOR ")
+	for i, target := range s.Target {
+		if i > 0 {
+			ctx.WriteString(", ")
+		}
+		ctx.FormatName(string(target))
+	}
+	ctx.WriteString(" IN ")
+	ctx.FormatNode(s.Control)
+	ctx.WriteString(" LOOP\n")
+	for _, stmt := range s.Body {
+		ctx.FormatNode(stmt)
+	}
+	ctx.WriteString("END LOOP")
+	if s.Label != "" {
+		ctx.WriteString(" ")
+		ctx.FormatNameP(&s.Label)
+	}
+	ctx.WriteString(";\n")
 }
 
-func (s *ForDynamic) Format(ctx *tree.FmtCtx) {
+func (s *ForLoop) PlpgSQLStatementTag() string {
+	switch s.Control.(type) {
+	case *IntForLoopControl:
+		return "stmt_for_int_loop"
+	}
+	return "stmt_for_unknown"
 }
 
-func (s *ForDynamic) PlpgSQLStatementTag() string {
-	return "stmt_for_dyn_loop"
-}
+func (s *ForLoop) WalkStmt(visitor StatementVisitor) Statement {
+	newStmt, recurse := visitor.Visit(s)
 
-func (s *ForDynamic) WalkStmt(visitor StatementVisitor) (newStmt Statement, changed bool) {
-	panic(unimplemented.New("plpgsql visitor", "Unimplemented PLpgSQL visitor pattern"))
+	if recurse {
+		for i, bodyStmt := range s.Body {
+			newBodyStmt := bodyStmt.WalkStmt(visitor)
+			if newBodyStmt != bodyStmt {
+				if newStmt == s {
+					newStmt = s.CopyNode()
+				}
+				newStmt.(*ForLoop).Body[i] = newBodyStmt
+			}
+		}
+	}
+	return newStmt
 }
 
 // stmt_foreach_a
@@ -702,7 +723,7 @@ func (s *ForEachArray) PlpgSQLStatementTag() string {
 	return "stmt_for_each_a"
 }
 
-func (s *ForEachArray) WalkStmt(visitor StatementVisitor) (newStmt Statement, changed bool) {
+func (s *ForEachArray) WalkStmt(visitor StatementVisitor) Statement {
 	panic(unimplemented.New("plpgsql visitor", "Unimplemented PLpgSQL visitor pattern"))
 }
 
@@ -736,9 +757,9 @@ func (s *Exit) PlpgSQLStatementTag() string {
 	return "stmt_exit"
 }
 
-func (s *Exit) WalkStmt(visitor StatementVisitor) (newStmt Statement, changed bool) {
-	newStmt, changed = visitor.Visit(s)
-	return newStmt, changed
+func (s *Exit) WalkStmt(visitor StatementVisitor) Statement {
+	newStmt, _ := visitor.Visit(s)
+	return newStmt
 }
 
 // stmt_continue
@@ -770,16 +791,15 @@ func (s *Continue) PlpgSQLStatementTag() string {
 	return "stmt_continue"
 }
 
-func (s *Continue) WalkStmt(visitor StatementVisitor) (newStmt Statement, changed bool) {
-	newStmt, changed = visitor.Visit(s)
-	return newStmt, changed
+func (s *Continue) WalkStmt(visitor StatementVisitor) Statement {
+	newStmt, _ := visitor.Visit(s)
+	return newStmt
 }
 
 // stmt_return
 type Return struct {
 	StatementImpl
-	Expr   Expr
-	RetVar Variable
+	Expr Expr
 }
 
 func (s *Return) CopyNode() *Return {
@@ -788,10 +808,9 @@ func (s *Return) CopyNode() *Return {
 }
 
 func (s *Return) Format(ctx *tree.FmtCtx) {
-	ctx.WriteString("RETURN ")
-	if s.Expr == nil {
-		ctx.FormatNode(&s.RetVar)
-	} else {
+	ctx.WriteString("RETURN")
+	if s.Expr != nil {
+		ctx.WriteByte(' ')
 		ctx.FormatNode(s.Expr)
 	}
 	ctx.WriteString(";\n")
@@ -801,44 +820,68 @@ func (s *Return) PlpgSQLStatementTag() string {
 	return "stmt_return"
 }
 
-func (s *Return) WalkStmt(visitor StatementVisitor) (newStmt Statement, changed bool) {
-	newStmt, changed = visitor.Visit(s)
-	return newStmt, changed
+func (s *Return) WalkStmt(visitor StatementVisitor) Statement {
+	newStmt, _ := visitor.Visit(s)
+	return newStmt
 }
 
 type ReturnNext struct {
 	StatementImpl
-	Expr   Expr
-	RetVar Variable
+	Expr Expr
+}
+
+func (s *ReturnNext) CopyNode() *ReturnNext {
+	copyNode := *s
+	return &copyNode
 }
 
 func (s *ReturnNext) Format(ctx *tree.FmtCtx) {
+	ctx.WriteString("RETURN NEXT")
+	if s.Expr != nil {
+		ctx.WriteByte(' ')
+		ctx.FormatNode(s.Expr)
+	}
+	ctx.WriteString(";\n")
 }
 
 func (s *ReturnNext) PlpgSQLStatementTag() string {
 	return "stmt_return_next"
 }
 
-func (s *ReturnNext) WalkStmt(visitor StatementVisitor) (newStmt Statement, changed bool) {
-	panic(unimplemented.New("plpgsql visitor", "Unimplemented PLpgSQL visitor pattern"))
+func (s *ReturnNext) WalkStmt(visitor StatementVisitor) Statement {
+	newStmt, _ := visitor.Visit(s)
+	return newStmt
 }
 
 type ReturnQuery struct {
 	StatementImpl
-	Query        Expr
-	DynamicQuery Expr
-	Params       []Expr
+	SqlStmt     tree.Statement
+	Annotations *tree.Annotations
+}
+
+func (s *ReturnQuery) CopyNode() *ReturnQuery {
+	copyNode := *s
+	return &copyNode
 }
 
 func (s *ReturnQuery) Format(ctx *tree.FmtCtx) {
+	ctx.WithAnnotations(s.Annotations, func() {
+		ctx.WriteString("RETURN QUERY")
+		if s.SqlStmt != nil {
+			ctx.WriteByte(' ')
+			ctx.FormatNode(s.SqlStmt)
+		}
+		ctx.WriteString(";\n")
+	})
 }
 
 func (s *ReturnQuery) PlpgSQLStatementTag() string {
 	return "stmt_return_query"
 }
 
-func (s *ReturnQuery) WalkStmt(visitor StatementVisitor) (newStmt Statement, changed bool) {
-	panic(unimplemented.New("plpgsql visitor", "Unimplemented PLpgSQL visitor pattern"))
+func (s *ReturnQuery) WalkStmt(visitor StatementVisitor) Statement {
+	newStmt, _ := visitor.Visit(s)
+	return newStmt
 }
 
 // stmt_raise
@@ -863,7 +906,7 @@ func (s *Raise) Format(ctx *tree.FmtCtx) {
 	ctx.WriteString("RAISE")
 	if s.LogLevel != "" {
 		ctx.WriteString(" ")
-		ctx.WriteString(s.LogLevel)
+		ctx.WriteString(strings.ToUpper(s.LogLevel))
 	}
 	if s.Code != "" {
 		ctx.WriteString(" SQLSTATE ")
@@ -906,9 +949,9 @@ func (s *Raise) PlpgSQLStatementTag() string {
 	return "stmt_raise"
 }
 
-func (s *Raise) WalkStmt(visitor StatementVisitor) (newStmt Statement, changed bool) {
-	newStmt, changed = visitor.Visit(s)
-	return newStmt, changed
+func (s *Raise) WalkStmt(visitor StatementVisitor) Statement {
+	newStmt, _ := visitor.Visit(s)
+	return newStmt
 }
 
 // stmt_assert
@@ -932,17 +975,18 @@ func (s *Assert) PlpgSQLStatementTag() string {
 	return "stmt_assert"
 }
 
-func (s *Assert) WalkStmt(visitor StatementVisitor) (newStmt Statement, changed bool) {
-	newStmt, changed = visitor.Visit(s)
-	return newStmt, changed
+func (s *Assert) WalkStmt(visitor StatementVisitor) Statement {
+	newStmt, _ := visitor.Visit(s)
+	return newStmt
 }
 
 // stmt_execsql
 type Execute struct {
 	StatementImpl
-	SqlStmt tree.Statement
-	Strict  bool // INTO STRICT flag
-	Target  []Variable
+	SqlStmt     tree.Statement
+	Strict      bool // INTO STRICT flag
+	Target      []Variable
+	Annotations *tree.Annotations
 }
 
 func (s *Execute) CopyNode() *Execute {
@@ -952,29 +996,31 @@ func (s *Execute) CopyNode() *Execute {
 }
 
 func (s *Execute) Format(ctx *tree.FmtCtx) {
-	ctx.FormatNode(s.SqlStmt)
-	if s.Target != nil {
-		ctx.WriteString(" INTO ")
-		if s.Strict {
-			ctx.WriteString("STRICT ")
-		}
-		for i := range s.Target {
-			if i > 0 {
-				ctx.WriteString(", ")
+	ctx.WithAnnotations(s.Annotations, func() {
+		ctx.FormatNode(s.SqlStmt)
+		if s.Target != nil {
+			ctx.WriteString(" INTO ")
+			if s.Strict {
+				ctx.WriteString("STRICT ")
+			}
+			for i := range s.Target {
+				if i > 0 {
+					ctx.WriteString(", ")
+				}
+				ctx.FormatNode(&s.Target[i])
 			}
-			ctx.FormatNode(&s.Target[i])
 		}
-	}
-	ctx.WriteString(";\n")
+		ctx.WriteString(";\n")
+	})
 }
 
 func (s *Execute) PlpgSQLStatementTag() string {
 	return "stmt_exec_sql"
 }
 
-func (s *Execute) WalkStmt(visitor StatementVisitor) (newStmt Statement, changed bool) {
-	newStmt, changed = visitor.Visit(s)
-	return newStmt, changed
+func (s *Execute) WalkStmt(visitor StatementVisitor) Statement {
+	newStmt, _ := visitor.Visit(s)
+	return newStmt
 }
 
 // stmt_dynexecute
@@ -1013,9 +1059,9 @@ func (s *DynamicExecute) PlpgSQLStatementTag() string {
 	return "stmt_dyn_exec"
 }
 
-func (s *DynamicExecute) WalkStmt(visitor StatementVisitor) (newStmt Statement, changed bool) {
-	newStmt, changed = visitor.Visit(s)
-	return newStmt, changed
+func (s *DynamicExecute) WalkStmt(visitor StatementVisitor) Statement {
+	newStmt, _ := visitor.Visit(s)
+	return newStmt
 }
 
 // stmt_perform
@@ -1031,16 +1077,14 @@ func (s *Perform) PlpgSQLStatementTag() string {
 	return "stmt_perform"
 }
 
-func (s *Perform) WalkStmt(visitor StatementVisitor) (newStmt Statement, changed bool) {
+func (s *Perform) WalkStmt(visitor StatementVisitor) Statement {
 	panic(unimplemented.New("plpgsql visitor", "Unimplemented PLpgSQL visitor pattern"))
 }
 
 // stmt_call
 type Call struct {
 	StatementImpl
-	Expr   Expr
-	IsCall bool
-	Target Variable
+	Proc *tree.FuncExpr
 }
 
 func (s *Call) CopyNode() *Call {
@@ -1049,21 +1093,79 @@ func (s *Call) CopyNode() *Call {
 }
 
 func (s *Call) Format(ctx *tree.FmtCtx) {
-	// TODO(drewk): Correct the Call field and print the Expr and Target.
-	if s.IsCall {
-		ctx.WriteString("CALL a function/procedure\n")
-	} else {
-		ctx.WriteString("DO a code block\n")
-	}
+	ctx.WriteString("CALL ")
+	ctx.FormatNode(s.Proc)
+	ctx.WriteString(";\n")
 }
 
 func (s *Call) PlpgSQLStatementTag() string {
 	return "stmt_call"
 }
 
-func (s *Call) WalkStmt(visitor StatementVisitor) (newStmt Statement, changed bool) {
-	newStmt, changed = visitor.Visit(s)
-	return newStmt, changed
+func (s *Call) WalkStmt(visitor StatementVisitor) Statement {
+	newStmt, _ := visitor.Visit(s)
+	return newStmt
+}
+
+// stmt_do
+type DoBlock struct {
+	StatementImpl
+
+	// Block is the code block that defines the logic of the DO statement.
+	Block *Block
+}
+
+var _ Statement = (*DoBlock)(nil)
+var _ tree.DoBlockBody = (*DoBlock)(nil)
+
+func (s *DoBlock) Format(ctx *tree.FmtCtx) {
+	ctx.WriteString("DO ")
+
+	// Format the body of the DO block separately so that FormatStringDollarQuotes
+	// can examine the resulting string and determine how to quote the block.
+	bodyCtx := ctx.Clone()
+	bodyCtx.FormatNode(s.Block)
+	bodyStr := "\n" + bodyCtx.CloseAndGetString()
+
+	// Avoid replacing the entire formatted string with '_' if any redaction flags
+	// are set. They will have already been applied when the body was formatted.
+	ctx.WithoutConstantRedaction(func() {
+		ctx.FormatStringDollarQuotes(bodyStr)
+	})
+	ctx.WriteString(";\n")
+}
+
+func (s *DoBlock) IsDoBlockBody() {}
+
+func (s *DoBlock) VisitBody(v tree.Visitor) tree.DoBlockBody {
+	plVisitor := SQLStmtVisitor{Visitor: v}
+	newBlock := Walk(&plVisitor, s.Block)
+	if newBlock != s.Block {
+		return &DoBlock{Block: newBlock.(*Block)}
+	}
+	return s
+}
+
+func (s *DoBlock) CopyNode() *DoBlock {
+	copyNode := *s
+	copyNode.Block = s.Block.CopyNode()
+	return &copyNode
+}
+
+func (s *DoBlock) PlpgSQLStatementTag() string {
+	return "stmt_do"
+}
+
+func (s *DoBlock) WalkStmt(visitor StatementVisitor) Statement {
+	newStmt, _ := visitor.Visit(s)
+	newBlock := s.Block.WalkStmt(visitor)
+	if newBlock != s.Block {
+		if newStmt == s {
+			newStmt = s.CopyNode()
+		}
+		newStmt.(*DoBlock).Block = newBlock.(*Block)
+	}
+	return newStmt
 }
 
 // stmt_getdiag
@@ -1090,7 +1192,7 @@ func (s *GetDiagnostics) Format(ctx *tree.FmtCtx) {
 
 type GetDiagnosticsItem struct {
 	Kind GetDiagnosticsKind
-	// TODO(jane): TargetName is temporary -- should be removed and use Target.
+	// TODO(drewk): TargetName is temporary -- should be removed and use Target.
 	TargetName string
 	Target     int // where to assign it?
 }
@@ -1105,17 +1207,18 @@ func (s *GetDiagnostics) PlpgSQLStatementTag() string {
 	return "stmt_get_diag"
 }
 
-func (s *GetDiagnostics) WalkStmt(visitor StatementVisitor) (newStmt Statement, changed bool) {
-	newStmt, changed = visitor.Visit(s)
-	return newStmt, changed
+func (s *GetDiagnostics) WalkStmt(visitor StatementVisitor) Statement {
+	newStmt, _ := visitor.Visit(s)
+	return newStmt
 }
 
 // stmt_open
 type Open struct {
 	StatementImpl
-	CurVar Variable
-	Scroll tree.CursorScrollOption
-	Query  tree.Statement
+	CurVar      Variable
+	Scroll      tree.CursorScrollOption
+	Query       tree.Statement
+	Annotations *tree.Annotations
 }
 
 func (s *Open) CopyNode() *Open {
@@ -1124,65 +1227,70 @@ func (s *Open) CopyNode() *Open {
 }
 
 func (s *Open) Format(ctx *tree.FmtCtx) {
-	ctx.WriteString("OPEN ")
-	ctx.FormatNode(&s.CurVar)
-	switch s.Scroll {
-	case tree.Scroll:
-		ctx.WriteString(" SCROLL")
-	case tree.NoScroll:
-		ctx.WriteString(" NO SCROLL")
-	}
-	if s.Query != nil {
-		ctx.WriteString(" FOR ")
-		ctx.FormatNode(s.Query)
-	}
-	ctx.WriteString(";\n")
+	ctx.WithAnnotations(s.Annotations, func() {
+		ctx.WriteString("OPEN ")
+		ctx.FormatNode(&s.CurVar)
+		switch s.Scroll {
+		case tree.Scroll:
+			ctx.WriteString(" SCROLL")
+		case tree.NoScroll:
+			ctx.WriteString(" NO SCROLL")
+		}
+		if s.Query != nil {
+			ctx.WriteString(" FOR ")
+			ctx.FormatNode(s.Query)
+		}
+		ctx.WriteString(";\n")
+	})
 }
 
 func (s *Open) PlpgSQLStatementTag() string {
 	return "stmt_open"
 }
 
-func (s *Open) WalkStmt(visitor StatementVisitor) (newStmt Statement, changed bool) {
-	newStmt, changed = visitor.Visit(s)
-	return newStmt, changed
+func (s *Open) WalkStmt(visitor StatementVisitor) Statement {
+	newStmt, _ := visitor.Visit(s)
+	return newStmt
 }
 
 // stmt_fetch
 // stmt_move (where IsMove = true)
 type Fetch struct {
 	StatementImpl
-	Cursor tree.CursorStmt
-	Target []Variable
-	IsMove bool
+	Cursor      tree.CursorStmt
+	Target      []Variable
+	IsMove      bool
+	Annotations *tree.Annotations
 }
 
 func (s *Fetch) Format(ctx *tree.FmtCtx) {
-	if s.IsMove {
-		ctx.WriteString("MOVE ")
-	} else {
-		ctx.WriteString("FETCH ")
-	}
-	if dir := s.Cursor.FetchType.String(); dir != "" {
-		ctx.WriteString(dir)
-		ctx.WriteString(" ")
-	}
-	if s.Cursor.FetchType.HasCount() {
-		ctx.WriteString(strconv.Itoa(int(s.Cursor.Count)))
-		ctx.WriteString(" ")
-	}
-	ctx.WriteString("FROM ")
-	ctx.FormatName(string(s.Cursor.Name))
-	if s.Target != nil {
-		ctx.WriteString(" INTO ")
-		for i := range s.Target {
-			if i > 0 {
-				ctx.WriteString(", ")
+	ctx.WithAnnotations(s.Annotations, func() {
+		if s.IsMove {
+			ctx.WriteString("MOVE ")
+		} else {
+			ctx.WriteString("FETCH ")
+		}
+		if dir := s.Cursor.FetchType.String(); dir != "" {
+			ctx.WriteString(dir)
+			ctx.WriteString(" ")
+		}
+		if s.Cursor.FetchType.HasCount() {
+			ctx.WriteString(strconv.Itoa(int(s.Cursor.Count)))
+			ctx.WriteString(" ")
+		}
+		ctx.WriteString("FROM ")
+		ctx.FormatName(string(s.Cursor.Name))
+		if s.Target != nil {
+			ctx.WriteString(" INTO ")
+			for i := range s.Target {
+				if i > 0 {
+					ctx.WriteString(", ")
+				}
+				ctx.FormatNode(&s.Target[i])
 			}
-			ctx.FormatNode(&s.Target[i])
 		}
-	}
-	ctx.WriteString(";\n")
+		ctx.WriteString(";\n")
+	})
 }
 
 func (s *Fetch) PlpgSQLStatementTag() string {
@@ -1192,9 +1300,9 @@ func (s *Fetch) PlpgSQLStatementTag() string {
 	return "stmt_fetch"
 }
 
-func (s *Fetch) WalkStmt(visitor StatementVisitor) (newStmt Statement, changed bool) {
-	newStmt, changed = visitor.Visit(s)
-	return newStmt, changed
+func (s *Fetch) WalkStmt(visitor StatementVisitor) Statement {
+	newStmt, _ := visitor.Visit(s)
+	return newStmt
 }
 
 // stmt_close
@@ -1213,45 +1321,40 @@ func (s *Close) PlpgSQLStatementTag() string {
 	return "stmt_close"
 }
 
-func (s *Close) WalkStmt(visitor StatementVisitor) (newStmt Statement, changed bool) {
-	newStmt, changed = visitor.Visit(s)
-	return newStmt, changed
+func (s *Close) WalkStmt(visitor StatementVisitor) Statement {
+	newStmt, _ := visitor.Visit(s)
+	return newStmt
 }
 
-// stmt_commit
-type Commit struct {
+// stmt_commit and stmt_rollback
+type TransactionControl struct {
 	StatementImpl
-	Chain bool
+	Rollback bool
+	Chain    bool
 }
 
-func (s *Commit) Format(ctx *tree.FmtCtx) {
+func (s *TransactionControl) Format(ctx *tree.FmtCtx) {
+	if s.Rollback {
+		ctx.WriteString("ROLLBACK")
+	} else {
+		ctx.WriteString("COMMIT")
+	}
+	if s.Chain {
+		ctx.WriteString(" AND CHAIN")
+	}
+	ctx.WriteString(";\n")
 }
 
-func (s *Commit) PlpgSQLStatementTag() string {
+func (s *TransactionControl) PlpgSQLStatementTag() string {
+	if s.Rollback {
+		return "stmt_rollback"
+	}
 	return "stmt_commit"
 }
 
-func (s *Commit) WalkStmt(visitor StatementVisitor) (newStmt Statement, changed bool) {
-	newStmt, changed = visitor.Visit(s)
-	return newStmt, changed
-}
-
-// stmt_rollback
-type Rollback struct {
-	StatementImpl
-	Chain bool
-}
-
-func (s *Rollback) Format(ctx *tree.FmtCtx) {
-}
-
-func (s *Rollback) PlpgSQLStatementTag() string {
-	return "stmt_rollback"
-}
-
-func (s *Rollback) WalkStmt(visitor StatementVisitor) (newStmt Statement, changed bool) {
-	newStmt, changed = visitor.Visit(s)
-	return newStmt, changed
+func (s *TransactionControl) WalkStmt(visitor StatementVisitor) Statement {
+	newStmt, _ := visitor.Visit(s)
+	return newStmt
 }
 
 // stmt_null
@@ -1267,9 +1370,9 @@ func (s *Null) PlpgSQLStatementTag() string {
 	return "stmt_null"
 }
 
-func (s *Null) WalkStmt(visitor StatementVisitor) (newStmt Statement, changed bool) {
-	newStmt, changed = visitor.Visit(s)
-	return newStmt, changed
+func (s *Null) WalkStmt(visitor StatementVisitor) Statement {
+	newStmt, _ := visitor.Visit(s)
+	return newStmt
 }
 
 // formatString is a helper function that prints "_" if FmtHideConstants is set,
diff --git a/pkg/sql/sem/plpgsqltree/variable.go b/pkg/sql/sem/plpgsqltree/variable.go
index abed539..1bb6df4 100644
--- a/pkg/sql/sem/plpgsqltree/variable.go
+++ b/pkg/sql/sem/plpgsqltree/variable.go
@@ -1,12 +1,7 @@
 // Copyright 2023 The Cockroach Authors.
 //
-// Use of this software is governed by the Business Source License
-// included in the file licenses/BSL.txt.
-//
-// As of the Change Date specified in that file, in accordance with
-// the Business Source License, use of this software will be governed
-// by the Apache License, Version 2.0, included in the file
-// licenses/APL.txt.
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
 
 package plpgsqltree
 
diff --git a/pkg/sql/sem/plpgsqltree/visitor.go b/pkg/sql/sem/plpgsqltree/visitor.go
index 9526d48..dbefeb1 100644
--- a/pkg/sql/sem/plpgsqltree/visitor.go
+++ b/pkg/sql/sem/plpgsqltree/visitor.go
@@ -1,24 +1,348 @@
 // Copyright 2023 The Cockroach Authors.
 //
-// Use of this software is governed by the Business Source License
-// included in the file licenses/BSL.txt.
-//
-// As of the Change Date specified in that file, in accordance with
-// the Business Source License, use of this software will be governed
-// by the Apache License, Version 2.0, included in the file
-// licenses/APL.txt.
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
 
 package plpgsqltree
 
+import (
+	"github.com/cockroachdb/cockroachdb-parser/pkg/sql/sem/tree"
+	unimp "github.com/cockroachdb/cockroachdb-parser/pkg/util/errorutil/unimplemented"
+)
+
 // StatementVisitor defines methods that are called plpgsql statements during
 // a statement walk.
 type StatementVisitor interface {
-	// Visit is called during a statement walk.
-	Visit(stmt Statement) (newStmt Statement, changed bool)
+	// Visit is called during a statement walk. If recurse is false for a given
+	// node, the node's children (if any) will not be visited.
+	Visit(stmt Statement) (newStmt Statement, recurse bool)
 }
 
 // Walk traverses the plpgsql statement.
 func Walk(v StatementVisitor, stmt Statement) Statement {
-	newStmt, _ := stmt.WalkStmt(v)
+	newStmt := stmt.WalkStmt(v)
 	return newStmt
 }
+
+// SQLStmtVisitor applies a visitor to every SQL statement and expression found
+// while walking the PL/pgSQL AST. SQLStmtVisitor supports using
+// tree.v.visitExprFn for callers that don't need the full Visitor interface.
+//
+// *Only one of Fn or Visitor can be set.*
+type SQLStmtVisitor struct {
+	Fn      tree.SimpleVisitFn
+	Visitor tree.Visitor
+	Err     error
+}
+
+var _ StatementVisitor = &SQLStmtVisitor{}
+
+// visitExpr calls the visitor function on the given expression. The updated
+// expression could be nil, so SQLStmtVisitor must be prepared to handle that.
+func (v *SQLStmtVisitor) visitExpr(expr tree.Expr) (newExpr tree.Expr, err error) {
+	if expr == nil {
+		return nil, nil
+	}
+	if v.Fn != nil {
+		newExpr, err = tree.SimpleVisit(expr, v.Fn)
+	} else {
+		newExpr, _ = tree.WalkExpr(v.Visitor, expr)
+	}
+	if err != nil {
+		v.Err = err
+	}
+	return newExpr, v.Err
+}
+
+// visitStmt calls the visitor function on the given statement. The updated
+// expression could be nil, so SQLStmtVisitor must be prepared to handle that.
+func (v *SQLStmtVisitor) visitStmt(stmt tree.Statement) (newStmt tree.Statement, err error) {
+	if stmt == nil {
+		return nil, nil
+	}
+	if v.Fn != nil {
+		newStmt, err = tree.SimpleStmtVisit(stmt, v.Fn)
+	} else {
+		newStmt, _ = tree.WalkStmt(v.Visitor, stmt)
+	}
+	if err != nil {
+		v.Err = err
+	}
+	return newStmt, v.Err
+}
+
+func (v *SQLStmtVisitor) Visit(stmt Statement) (newStmt Statement, recurse bool) {
+	if v.Err != nil {
+		return stmt, false
+	}
+	newStmt = stmt
+	var s tree.Statement
+	var e tree.Expr
+	switch t := stmt.(type) {
+	case *CursorDeclaration:
+		s, v.Err = v.visitStmt(t.Query)
+		if v.Err != nil {
+			return stmt, false
+		}
+		if t.Query != s {
+			cpy := t.CopyNode()
+			cpy.Query = s
+			newStmt = cpy
+		}
+	case *Execute:
+		s, v.Err = v.visitStmt(t.SqlStmt)
+		if v.Err != nil {
+			return stmt, false
+		}
+		if t.SqlStmt != s {
+			cpy := t.CopyNode()
+			cpy.SqlStmt = s
+			newStmt = cpy
+		}
+	case *Open:
+		s, v.Err = v.visitStmt(t.Query)
+		if v.Err != nil {
+			return stmt, false
+		}
+		if t.Query != s {
+			cpy := t.CopyNode()
+			cpy.Query = s
+			newStmt = cpy
+		}
+	case *Declaration:
+		e, v.Err = v.visitExpr(t.Expr)
+		if v.Err != nil {
+			return stmt, false
+		}
+		if t.Expr != e {
+			cpy := t.CopyNode()
+			cpy.Expr = e
+			newStmt = cpy
+		}
+
+	case *Assignment:
+		e, v.Err = v.visitExpr(t.Value)
+		if v.Err != nil {
+			return stmt, false
+		}
+		if t.Value != e {
+			cpy := t.CopyNode()
+			cpy.Value = e
+			newStmt = cpy
+		}
+	case *If:
+		e, v.Err = v.visitExpr(t.Condition)
+		if v.Err != nil {
+			return stmt, false
+		}
+		if t.Condition != e {
+			cpy := t.CopyNode()
+			cpy.Condition = e
+			newStmt = cpy
+		}
+	case *ElseIf:
+		e, v.Err = v.visitExpr(t.Condition)
+		if v.Err != nil {
+			return stmt, false
+		}
+		if t.Condition != e {
+			cpy := t.CopyNode()
+			cpy.Condition = e
+			newStmt = cpy
+		}
+	case *While:
+		e, v.Err = v.visitExpr(t.Condition)
+		if v.Err != nil {
+			return stmt, false
+		}
+		if t.Condition != e {
+			cpy := t.CopyNode()
+			cpy.Condition = e
+			newStmt = cpy
+		}
+	case *Exit:
+		e, v.Err = v.visitExpr(t.Condition)
+		if v.Err != nil {
+			return stmt, false
+		}
+		if t.Condition != e {
+			cpy := t.CopyNode()
+			cpy.Condition = e
+			newStmt = cpy
+		}
+	case *Continue:
+		e, v.Err = v.visitExpr(t.Condition)
+		if v.Err != nil {
+			return stmt, false
+		}
+		if t.Condition != e {
+			cpy := t.CopyNode()
+			cpy.Condition = e
+			newStmt = cpy
+		}
+	case *Return:
+		e, v.Err = v.visitExpr(t.Expr)
+		if v.Err != nil {
+			return stmt, false
+		}
+		if t.Expr != e {
+			cpy := t.CopyNode()
+			cpy.Expr = e
+			newStmt = cpy
+		}
+	case *ReturnNext:
+		e, v.Err = v.visitExpr(t.Expr)
+		if v.Err != nil {
+			return stmt, false
+		}
+		if t.Expr != e {
+			cpy := t.CopyNode()
+			cpy.Expr = e
+			newStmt = cpy
+		}
+	case *ReturnQuery:
+		s, v.Err = v.visitStmt(t.SqlStmt)
+		if v.Err != nil {
+			return stmt, false
+		}
+		if t.SqlStmt != s {
+			cpy := t.CopyNode()
+			cpy.SqlStmt = s
+			newStmt = cpy
+		}
+	case *Raise:
+		for i, p := range t.Params {
+			e, v.Err = v.visitExpr(p)
+			if v.Err != nil {
+				return stmt, false
+			}
+			if t.Params[i] != e {
+				if newStmt != stmt {
+					cpy := t.CopyNode()
+					newStmt = cpy
+				}
+				newStmt.(*Raise).Params[i] = e
+			}
+		}
+		for i, p := range t.Options {
+			e, v.Err = v.visitExpr(p.Expr)
+			if v.Err != nil {
+				return stmt, false
+			}
+			if t.Options[i].Expr != e {
+				if newStmt != stmt {
+					cpy := t.CopyNode()
+					newStmt = cpy
+				}
+				newStmt.(*Raise).Options[i].Expr = e
+			}
+		}
+	case *Assert:
+		e, v.Err = v.visitExpr(t.Condition)
+		if v.Err != nil {
+			return stmt, false
+		}
+		if t.Condition != e {
+			cpy := t.CopyNode()
+			cpy.Condition = e
+			newStmt = cpy
+		}
+
+	case *DynamicExecute:
+		for i, p := range t.Params {
+			e, v.Err = v.visitExpr(p)
+			if v.Err != nil {
+				return stmt, false
+			}
+			if t.Params[i] != e {
+				if newStmt != stmt {
+					cpy := t.CopyNode()
+					newStmt = cpy
+				}
+				newStmt.(*DynamicExecute).Params[i] = e
+			}
+		}
+	case *Call:
+		e, v.Err = v.visitExpr(t.Proc)
+		if v.Err != nil {
+			return stmt, false
+		}
+		if t.Proc != e {
+			cpy := t.CopyNode()
+			if e == nil {
+				cpy.Proc = nil
+			} else {
+				cpy.Proc = e.(*tree.FuncExpr)
+			}
+			newStmt = cpy
+		}
+
+	case *ForLoop:
+		switch c := t.Control.(type) {
+		case *IntForLoopControl:
+			var newLower, newUpper, newStep tree.Expr
+			newLower, v.Err = v.visitExpr(c.Lower)
+			if v.Err != nil {
+				return stmt, false
+			}
+			newUpper, v.Err = v.visitExpr(c.Upper)
+			if v.Err != nil {
+				return stmt, false
+			}
+			if c.Step != nil {
+				newStep, v.Err = v.visitExpr(c.Step)
+				if v.Err != nil {
+					return stmt, false
+				}
+			}
+			if newLower != c.Lower || newUpper != c.Upper || newStep != c.Step {
+				cpy := t.CopyNode()
+				cpy.Control = &IntForLoopControl{
+					Reverse: c.Reverse,
+					Lower:   newLower,
+					Upper:   newUpper,
+					Step:    newStep,
+				}
+				newStmt = cpy
+			}
+		}
+
+	case *ForEachArray, *Perform:
+		panic(unimp.New("plpgsql visitor", "Unimplemented PLpgSQL visitor"))
+	}
+	if v.Err != nil {
+		return stmt, false
+	}
+	return newStmt, true
+}
+
+// TypeRefVisitor calls the given replace function on each type reference
+// contained in the visited PLpgSQL statements. Note that this currently only
+// includes `Declaration`. SQL statements and expressions are not visited.
+type TypeRefVisitor struct {
+	Fn  func(typ tree.ResolvableTypeReference) (newTyp tree.ResolvableTypeReference, err error)
+	Err error
+}
+
+var _ StatementVisitor = &TypeRefVisitor{}
+
+func (v *TypeRefVisitor) Visit(stmt Statement) (newStmt Statement, recurse bool) {
+	if v.Err != nil {
+		return stmt, false
+	}
+	newStmt = stmt
+	if t, ok := stmt.(*Declaration); ok {
+		var newTyp tree.ResolvableTypeReference
+		newTyp, v.Err = v.Fn(t.Typ)
+		if v.Err != nil {
+			return stmt, false
+		}
+		if t.Typ != newTyp {
+			if newStmt == stmt {
+				newStmt = t.CopyNode()
+				newStmt.(*Declaration).Typ = newTyp
+			}
+		}
+	}
+	return newStmt, true
+}
diff --git a/pkg/sql/sem/semenumpb/constraint.go b/pkg/sql/sem/semenumpb/constraint.go
deleted file mode 100644
index 799b481..0000000
--- a/pkg/sql/sem/semenumpb/constraint.go
+++ /dev/null
@@ -1,18 +0,0 @@
-// Copyright 2022 The Cockroach Authors.
-//
-// Use of this software is governed by the Business Source License
-// included in the file licenses/BSL.txt.
-//
-// As of the Change Date specified in that file, in accordance with
-// the Business Source License, use of this software will be governed
-// by the Apache License, Version 2.0, included in the file
-// licenses/APL.txt.
-
-package semenumpb
-
-import "github.com/cockroachdb/redact"
-
-var _ redact.SafeValue = ForeignKeyAction(0)
-
-// SafeValue implements redact.SafeValue.
-func (x ForeignKeyAction) SafeValue() {}
diff --git a/pkg/sql/sem/semenumpb/constraint.pb.go b/pkg/sql/sem/semenumpb/constraint.pb.go
index fc671a5..4ace31d 100644
--- a/pkg/sql/sem/semenumpb/constraint.pb.go
+++ b/pkg/sql/sem/semenumpb/constraint.pb.go
@@ -5,7 +5,6 @@ package semenumpb
 
 import (
 	fmt "fmt"
-	_ "github.com/gogo/protobuf/gogoproto"
 	proto "github.com/gogo/protobuf/proto"
 	math "math"
 )
@@ -96,25 +95,24 @@ func init() {
 }
 
 var fileDescriptor_8e3e948e264df145 = []byte{
-	// 289 bytes of a gzipped FileDescriptorProto
-	0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0x52, 0x2a, 0x2e, 0xcc, 0xd1,
-	0x2f, 0x4e, 0xcd, 0x05, 0xe1, 0xd4, 0xbc, 0xd2, 0xdc, 0x82, 0x24, 0xfd, 0xe4, 0xfc, 0xbc, 0xe2,
-	0x92, 0xa2, 0xc4, 0xcc, 0xbc, 0x12, 0xbd, 0x82, 0xa2, 0xfc, 0x92, 0x7c, 0x21, 0xe9, 0xe4, 0xfc,
-	0xe4, 0xec, 0xa2, 0xfc, 0xc4, 0xe4, 0x0c, 0xbd, 0xe2, 0xc2, 0x1c, 0xbd, 0xe2, 0xd4, 0x5c, 0x3d,
-	0xb8, 0x6a, 0x29, 0x91, 0xf4, 0xfc, 0xf4, 0x7c, 0xb0, 0x3a, 0x7d, 0x10, 0x0b, 0xa2, 0x45, 0x2b,
-	0x9a, 0x4b, 0xc0, 0x2d, 0xbf, 0x28, 0x35, 0x33, 0x3d, 0xcf, 0x3b, 0xb5, 0xd2, 0x31, 0xb9, 0x24,
-	0x33, 0x3f, 0x4f, 0x88, 0x97, 0x8b, 0xd3, 0xcf, 0x3f, 0xde, 0xd1, 0x39, 0xc4, 0xd3, 0xdf, 0x4f,
-	0x80, 0x41, 0x88, 0x87, 0x8b, 0x23, 0xc8, 0x35, 0x38, 0x24, 0xc8, 0xd3, 0x39, 0x44, 0x80, 0x11,
-	0xc4, 0x0b, 0x76, 0x0d, 0x89, 0xf7, 0x0b, 0xf5, 0xf1, 0x11, 0x60, 0x12, 0xe2, 0xe7, 0xe2, 0x06,
-	0xf1, 0x5c, 0x5c, 0xdd, 0x1c, 0x43, 0x7d, 0x42, 0x04, 0x98, 0x85, 0xb8, 0xb9, 0xd8, 0x9d, 0x1d,
-	0x83, 0x9d, 0x1d, 0x5d, 0x5c, 0x05, 0x58, 0xb4, 0xb4, 0xb8, 0x58, 0x7d, 0x13, 0x4b, 0x92, 0x33,
-	0x84, 0xb8, 0xb8, 0xd8, 0x82, 0x3d, 0x7d, 0x03, 0x7c, 0x5c, 0x05, 0x18, 0x84, 0x38, 0xb8, 0x58,
-	0xdc, 0x40, 0x9a, 0x19, 0x41, 0x6a, 0x03, 0x1c, 0x83, 0x42, 0x3c, 0x1d, 0x7d, 0x04, 0x98, 0x9c,
-	0x22, 0x4e, 0x3c, 0x94, 0x63, 0x38, 0xf1, 0x48, 0x8e, 0xf1, 0xc2, 0x23, 0x39, 0xc6, 0x1b, 0x8f,
-	0xe4, 0x18, 0x1f, 0x3c, 0x92, 0x63, 0x9c, 0xf0, 0x58, 0x8e, 0xe1, 0xc2, 0x63, 0x39, 0x86, 0x1b,
-	0x8f, 0xe5, 0x18, 0xa2, 0xcc, 0xd2, 0x33, 0x4b, 0x32, 0x4a, 0x93, 0xf4, 0x92, 0xf3, 0x73, 0xf5,
-	0xe1, 0x1e, 0x4d, 0x49, 0x42, 0xb0, 0xf5, 0x0b, 0xb2, 0xd3, 0xf5, 0x31, 0x82, 0x29, 0x89, 0x0d,
-	0xec, 0x53, 0x63, 0x40, 0x00, 0x00, 0x00, 0xff, 0xff, 0x3f, 0x07, 0x88, 0xb6, 0x42, 0x01, 0x00,
-	0x00,
+	// 275 bytes of a gzipped FileDescriptorProto
+	0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x64, 0x90, 0x31, 0x4f, 0x83, 0x40,
+	0x14, 0x80, 0xef, 0x6a, 0xad, 0xf5, 0xaa, 0xf1, 0x72, 0xab, 0xc9, 0x0d, 0x8e, 0x0c, 0x30, 0x98,
+	0xb8, 0x9f, 0x14, 0x12, 0x22, 0xa5, 0x0d, 0x5c, 0x13, 0xa3, 0x43, 0x03, 0x27, 0x01, 0xd2, 0xc2,
+	0x51, 0xb8, 0x0e, 0xfe, 0x0b, 0x7f, 0x56, 0xc7, 0x8e, 0x1d, 0x15, 0xfe, 0x88, 0x39, 0x87, 0x3a,
+	0x74, 0x78, 0xc9, 0xfb, 0x92, 0xef, 0x0d, 0xef, 0x43, 0x0f, 0xed, 0x76, 0x63, 0xb5, 0x69, 0xa9,
+	0x27, 0xad, 0x76, 0x65, 0x9d, 0x58, 0x42, 0x56, 0xad, 0x6a, 0xe2, 0xa2, 0x52, 0x66, 0xdd, 0x48,
+	0x25, 0xc9, 0xbd, 0x90, 0x62, 0xdd, 0xc8, 0x58, 0xe4, 0x66, 0xbb, 0xdd, 0x98, 0x6d, 0x5a, 0x9a,
+	0x27, 0xdb, 0x78, 0x47, 0xd8, 0x95, 0x4d, 0x5a, 0x64, 0xd5, 0x4b, 0xfa, 0xc9, 0x84, 0x2a, 0x64,
+	0x45, 0x6e, 0xd1, 0x75, 0x30, 0x5f, 0x31, 0x9b, 0x7b, 0xf3, 0x00, 0x03, 0x72, 0x83, 0xc6, 0xa1,
+	0x13, 0xf1, 0xd0, 0xb3, 0x39, 0x86, 0x9a, 0x22, 0x87, 0xaf, 0x82, 0xa5, 0xef, 0xe3, 0x01, 0xb9,
+	0x43, 0x13, 0x4d, 0x53, 0xc7, 0x65, 0x4b, 0x9f, 0xe3, 0x0b, 0x32, 0x41, 0x57, 0x36, 0x8b, 0x6c,
+	0x36, 0x75, 0xf0, 0xd0, 0x30, 0xd0, 0xe5, 0x2c, 0x56, 0x22, 0x27, 0x08, 0x8d, 0x22, 0x6f, 0xb6,
+	0xf0, 0x1d, 0x0c, 0xc8, 0x18, 0x0d, 0x5d, 0x7d, 0x0c, 0xb5, 0xbb, 0x60, 0x21, 0xf7, 0x98, 0x8f,
+	0x07, 0xcf, 0xaf, 0xfb, 0x1f, 0x0a, 0xf6, 0x1d, 0x85, 0x87, 0x8e, 0xc2, 0x63, 0x47, 0xe1, 0x77,
+	0x47, 0xe1, 0x57, 0x4f, 0xc1, 0xa1, 0xa7, 0xe0, 0xd8, 0x53, 0xf0, 0xf6, 0x94, 0x15, 0x2a, 0xdf,
+	0x25, 0xa6, 0x90, 0xa5, 0x75, 0x7a, 0xe9, 0x23, 0xf9, 0xdf, 0xad, 0x7a, 0x9d, 0x59, 0x67, 0x41,
+	0x92, 0xd1, 0x5f, 0x86, 0xc7, 0xdf, 0x00, 0x00, 0x00, 0xff, 0xff, 0xac, 0xa0, 0xdf, 0xc2, 0x2c,
+	0x01, 0x00, 0x00,
 }
 
diff --git a/pkg/sql/sem/semenumpb/constraint.proto b/pkg/sql/sem/semenumpb/constraint.proto
index 7e36d61..ef2f0b8 100644
--- a/pkg/sql/sem/semenumpb/constraint.proto
+++ b/pkg/sql/sem/semenumpb/constraint.proto
@@ -1,14 +1,9 @@
 // Copyright 2022 The Cockroach Authors.
 //
-// Use of this software is governed by the Business Source License
-// included in the file licenses/BSL.txt.
-//
-// As of the Change Date specified in that file, in accordance with
-// the Business Source License, use of this software will be governed
-// by the Apache License, Version 2.0, included in the file
-// licenses/APL.txt.
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
 
-// This file should contain only EMUN definitions for concepts that
+// This file should contain only ENUM definitions for concepts that
 // are visible in the SQL layer (i.e. concepts that can be configured
 // in a SQL query).
 // It uses proto3 so other packages can import those enum definitions
@@ -17,8 +12,6 @@ syntax = "proto3";
 package cockroach.sql.sem.semenumpb;
 option go_package = "github.com/cockroachdb/cockroach/pkg/sql/sem/semenumpb";
 
-import "gogoproto/gogo.proto";
-
 // ForeignKeyAction describes the action which should be taken when a foreign
 // key constraint reference is acted upon.
 enum ForeignKeyAction {
diff --git a/pkg/sql/sem/semenumpb/enum.go b/pkg/sql/sem/semenumpb/enum.go
new file mode 100644
index 0000000..fa2fab8
--- /dev/null
+++ b/pkg/sql/sem/semenumpb/enum.go
@@ -0,0 +1,23 @@
+// Copyright 2022 The Cockroach Authors.
+//
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
+
+package semenumpb
+
+import "github.com/cockroachdb/redact"
+
+var (
+	_ redact.SafeValue = ForeignKeyAction(0)
+	_ redact.SafeValue = TriggerActionTime(0)
+	_ redact.SafeValue = TriggerEventType(0)
+)
+
+// SafeValue implements redact.SafeValue.
+func (x ForeignKeyAction) SafeValue() {}
+
+// SafeValue implements redact.SafeValue
+func (TriggerActionTime) SafeValue() {}
+
+// SafeValue implements redact.SafeValue
+func (TriggerEventType) SafeValue() {}
diff --git a/pkg/sql/sem/semenumpb/trigger.pb.go b/pkg/sql/sem/semenumpb/trigger.pb.go
new file mode 100644
index 0000000..7af9e77
--- /dev/null
+++ b/pkg/sql/sem/semenumpb/trigger.pb.go
@@ -0,0 +1,120 @@
+// Code generated by protoc-gen-gogo. DO NOT EDIT.
+// source: sql/sem/semenumpb/trigger.proto
+
+package semenumpb
+
+import (
+	fmt "fmt"
+	proto "github.com/gogo/protobuf/proto"
+	math "math"
+)
+
+// Reference imports to suppress errors if they are not otherwise used.
+var _ = proto.Marshal
+var _ = fmt.Errorf
+var _ = math.Inf
+
+// This is a compile-time assertion to ensure that this generated file
+// is compatible with the proto package it is being compiled against.
+// A compilation error at this line likely means your copy of the
+// proto package needs to be updated.
+const _ = proto.GoGoProtoPackageIsVersion3 // please upgrade the proto package
+
+// TriggerActionTime describes the timing of a trigger: before, after, or
+// instead of the event.
+type TriggerActionTime int32
+
+const (
+	TriggerActionTime_ACTION_UNKNOWN TriggerActionTime = 0
+	TriggerActionTime_BEFORE         TriggerActionTime = 1
+	TriggerActionTime_AFTER          TriggerActionTime = 2
+	TriggerActionTime_INSTEAD_OF     TriggerActionTime = 3
+)
+
+var TriggerActionTime_name = map[int32]string{
+	0: "ACTION_UNKNOWN",
+	1: "BEFORE",
+	2: "AFTER",
+	3: "INSTEAD_OF",
+}
+
+var TriggerActionTime_value = map[string]int32{
+	"ACTION_UNKNOWN": 0,
+	"BEFORE":         1,
+	"AFTER":          2,
+	"INSTEAD_OF":     3,
+}
+
+func (x TriggerActionTime) String() string {
+	return proto.EnumName(TriggerActionTime_name, int32(x))
+}
+
+func (TriggerActionTime) EnumDescriptor() ([]byte, []int) {
+	return fileDescriptor_677c5490404e076b, []int{0}
+}
+
+// TriggerEventType describes the event that will cause a trigger to fire:
+// insert, update, delete, truncate, or upsert.
+type TriggerEventType int32
+
+const (
+	TriggerEventType_EVENT_UNKNOWN TriggerEventType = 0
+	TriggerEventType_INSERT        TriggerEventType = 1
+	TriggerEventType_UPDATE        TriggerEventType = 2
+	TriggerEventType_DELETE        TriggerEventType = 3
+	TriggerEventType_TRUNCATE      TriggerEventType = 4
+)
+
+var TriggerEventType_name = map[int32]string{
+	0: "EVENT_UNKNOWN",
+	1: "INSERT",
+	2: "UPDATE",
+	3: "DELETE",
+	4: "TRUNCATE",
+}
+
+var TriggerEventType_value = map[string]int32{
+	"EVENT_UNKNOWN": 0,
+	"INSERT":        1,
+	"UPDATE":        2,
+	"DELETE":        3,
+	"TRUNCATE":      4,
+}
+
+func (x TriggerEventType) String() string {
+	return proto.EnumName(TriggerEventType_name, int32(x))
+}
+
+func (TriggerEventType) EnumDescriptor() ([]byte, []int) {
+	return fileDescriptor_677c5490404e076b, []int{1}
+}
+
+func init() {
+	proto.RegisterEnum("cockroach.parser.sql.sem.semenumpb.TriggerActionTime", TriggerActionTime_name, TriggerActionTime_value)
+	proto.RegisterEnum("cockroach.parser.sql.sem.semenumpb.TriggerEventType", TriggerEventType_name, TriggerEventType_value)
+}
+
+func init() { proto.RegisterFile("sql/sem/semenumpb/trigger.proto", fileDescriptor_677c5490404e076b) }
+
+var fileDescriptor_677c5490404e076b = []byte{
+	// 281 bytes of a gzipped FileDescriptorProto
+	0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x64, 0x90, 0xc1, 0x4a, 0xc3, 0x40,
+	0x14, 0x45, 0x33, 0xad, 0x16, 0x1d, 0xb4, 0x4c, 0x67, 0x2b, 0x8c, 0xfb, 0x2e, 0x92, 0x85, 0xe0,
+	0x3e, 0x6d, 0x5f, 0x20, 0x28, 0x13, 0x49, 0x5f, 0xac, 0xb8, 0x29, 0x26, 0x0e, 0x69, 0x68, 0x93,
+	0x49, 0x93, 0x54, 0xf0, 0x2f, 0xfc, 0xac, 0x2e, 0xbb, 0xec, 0x52, 0x93, 0x1f, 0x91, 0xa8, 0x54,
+	0xc4, 0xc5, 0x83, 0x03, 0xef, 0x72, 0xe1, 0x1e, 0x7a, 0x59, 0xae, 0x57, 0x56, 0xa9, 0xd2, 0xf6,
+	0x54, 0xb6, 0x49, 0xf3, 0xd0, 0xaa, 0x8a, 0x24, 0x8e, 0x55, 0x61, 0xe6, 0x85, 0xae, 0x34, 0xbf,
+	0x88, 0x74, 0xb4, 0x2c, 0xf4, 0x53, 0xb4, 0x30, 0xcb, 0xf5, 0xca, 0x2c, 0x55, 0x6a, 0x1e, 0xa2,
+	0x43, 0x49, 0x07, 0xf8, 0x9d, 0xb6, 0xa3, 0x2a, 0xd1, 0x19, 0x26, 0xa9, 0xe2, 0x9c, 0xf6, 0xed,
+	0x31, 0xba, 0x9e, 0x9c, 0x07, 0xf2, 0x46, 0x7a, 0x33, 0xc9, 0x0c, 0x4e, 0x69, 0x6f, 0x04, 0x8e,
+	0xe7, 0x03, 0x23, 0xfc, 0x94, 0x1e, 0xdb, 0x0e, 0x82, 0xcf, 0x3a, 0xbc, 0x4f, 0xa9, 0x2b, 0xa7,
+	0x08, 0xf6, 0x64, 0xee, 0x39, 0xac, 0x3b, 0x9c, 0x51, 0xf6, 0xd3, 0x07, 0x2f, 0x2a, 0xab, 0xf0,
+	0x35, 0x57, 0x7c, 0x40, 0xcf, 0xe1, 0x1e, 0x24, 0xfe, 0x6d, 0x73, 0xe5, 0x14, 0x7c, 0x64, 0xa4,
+	0xe5, 0xe0, 0x6e, 0x62, 0x23, 0xb0, 0x4e, 0xcb, 0x13, 0xb8, 0x05, 0x04, 0xd6, 0xe5, 0x67, 0xf4,
+	0x04, 0xfd, 0x40, 0x8e, 0xdb, 0xcf, 0xd1, 0xe8, 0x61, 0xfb, 0x21, 0x8c, 0x6d, 0x2d, 0xc8, 0xae,
+	0x16, 0x64, 0x5f, 0x0b, 0xf2, 0x5e, 0x0b, 0xf2, 0xd6, 0x08, 0x63, 0xd7, 0x08, 0x63, 0xdf, 0x08,
+	0xe3, 0xf1, 0x3a, 0x4e, 0xaa, 0xc5, 0x26, 0x34, 0x23, 0x9d, 0x5a, 0x87, 0xc9, 0xcf, 0xe1, 0x2f,
+	0x5b, 0xf9, 0x32, 0xb6, 0xfe, 0xd9, 0x0a, 0x7b, 0x5f, 0x9a, 0xae, 0x3e, 0x03, 0x00, 0x00, 0xff,
+	0xff, 0xeb, 0xfb, 0x65, 0xd8, 0x49, 0x01, 0x00, 0x00,
+}
+
diff --git a/pkg/sql/sem/semenumpb/trigger.proto b/pkg/sql/sem/semenumpb/trigger.proto
new file mode 100644
index 0000000..db49026
--- /dev/null
+++ b/pkg/sql/sem/semenumpb/trigger.proto
@@ -0,0 +1,32 @@
+// Copyright 2024 The Cockroach Authors.
+//
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
+
+// This file should contain only ENUM definitions for concepts that
+// are visible in the SQL layer (i.e. concepts that can be configured
+// in a SQL query).
+// It uses proto3 so other packages can import those enum definitions
+// when needed.
+syntax = "proto3";
+package cockroach.sql.sem.semenumpb;
+option go_package = "github.com/cockroachdb/cockroach/pkg/sql/sem/semenumpb";
+
+// TriggerActionTime describes the timing of a trigger: before, after, or
+// instead of the event.
+enum TriggerActionTime {
+  ACTION_UNKNOWN = 0;
+  BEFORE = 1;
+  AFTER = 2;
+  INSTEAD_OF = 3;
+}
+
+// TriggerEventType describes the event that will cause a trigger to fire:
+// insert, update, delete, truncate, or upsert.
+enum TriggerEventType {
+  EVENT_UNKNOWN = 0;
+  INSERT = 1;
+  UPDATE = 2;
+  DELETE = 3;
+  TRUNCATE = 4;
+}
diff --git a/pkg/sql/sem/tree/adjust_constants.go b/pkg/sql/sem/tree/adjust_constants.go
new file mode 100644
index 0000000..062cc9e
--- /dev/null
+++ b/pkg/sql/sem/tree/adjust_constants.go
@@ -0,0 +1,366 @@
+// Copyright 2017 The Cockroach Authors.
+//
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
+//
+//
+
+package tree
+
+import (
+	"fmt"
+	"strings"
+)
+
+// formatNodeOrAdjustConstants recurses into a node for pretty-printing, unless
+// FmtHideConstants or FmtShortenConstants is set in the flags and the node is
+// affected by that format.
+func (ctx *FmtCtx) formatNodeOrAdjustConstants(n NodeFormatter) {
+	if ctx.HasFlags(FmtConstantsAsUnderscores) {
+		switch n.(type) {
+		case *Placeholder, *StrVal, Datum, Constant:
+			// If we have a placeholder, a string literal, a datum or a constant,
+			// we want to print the same special character for all of them. This
+			// is to avoid creating different fingerprints for queries that are
+			// actually equivalent.
+			ctx.WriteByte(StmtFingerprintPlaceholder)
+			return
+		}
+	}
+	if ctx.flags.HasFlags(FmtCollapseLists) {
+		// This is a more aggressive form of collapsing lists than the cases
+		// provided by FmtHideConstants and FmtShortenConstants.
+		switch v := n.(type) {
+		case *ValuesClause:
+			v.formatForFingerprint(ctx)
+			return
+		case *Tuple:
+			v.formatForFingerprint(ctx)
+			return
+		case *Array:
+			v.formatForFingerprint(ctx)
+			return
+		}
+	}
+	if ctx.flags.HasFlags(FmtHideConstants) {
+		switch v := n.(type) {
+		case *ValuesClause:
+			v.formatHideConstants(ctx)
+			return
+		case *Tuple:
+			v.formatHideConstants(ctx)
+			return
+		case *Array:
+			v.formatHideConstants(ctx)
+			return
+		case *Placeholder:
+			// Placeholders should be printed as placeholder markers.
+			// Using always '$1' so we limit the amount of different
+			// fingerprints created.
+			ctx.WriteString("$1")
+			return
+		case *StrVal:
+			ctx.WriteString("'_'")
+			return
+		case Datum, Constant:
+			ctx.WriteByte('_')
+			return
+		}
+	} else if ctx.flags.HasFlags(FmtShortenConstants) {
+		switch v := n.(type) {
+		case *ValuesClause:
+			v.formatShortenConstants(ctx)
+			return
+		case *Tuple:
+			v.formatShortenConstants(ctx)
+			return
+		case *Array:
+			v.formatShortenConstants(ctx)
+			return
+		case *DTuple:
+			v.formatShortenConstants(ctx)
+			return
+		case *DArray:
+			v.formatShortenConstants(ctx)
+			return
+		}
+	}
+	n.Format(ctx)
+}
+
+// numElementsForShortenedList determines the number of elements included into
+// the shortened lists for tuples, arrays, and VALUES. In particular, first
+// numElementsForShortenedList-1 and the very last one will be included.
+//
+// Only used for FmtShortenConstants.
+const numElementsForShortenedList = 3
+
+// formatHideConstants shortens multi-valued VALUES clauses to a
+// VALUES clause with a single scrubbed value.
+// e.g. VALUES (a,b,c), (d,e,f) -> VALUES (_, _, _), (__more__)
+func (node *ValuesClause) formatHideConstants(ctx *FmtCtx) {
+	ctx.WriteString("VALUES (")
+	node.Rows[0].formatHideConstants(ctx)
+	ctx.WriteByte(')')
+	if len(node.Rows) > 1 {
+		ctx.Printf(", (%s)", arityString(len(node.Rows)-1))
+	}
+}
+
+// formatShortenConstants shortens multi-valued VALUES clauses to a VALUES
+// clause with at most 3 values.
+// e.g. VALUES (a), (b), (c), (d), (e), ... (z) -> VALUES (a), (b), (__more__), (z)
+func (node *ValuesClause) formatShortenConstants(ctx *FmtCtx) {
+	if len(node.Rows) <= numElementsForShortenedList {
+		node.Format(ctx)
+		return
+	}
+	ctx.WriteString("VALUES (")
+	for i := 0; i < numElementsForShortenedList-1; i++ {
+		node.Rows[i].Format(ctx)
+		ctx.WriteString("), (")
+	}
+	ctx.Printf("%s), (", arityString(len(node.Rows)-numElementsForShortenedList))
+	node.Rows[len(node.Rows)-1].Format(ctx)
+	ctx.WriteByte(')')
+}
+
+// formatHideConstants is used exclusively by ValuesClause above.
+// Other AST that contain Exprs do not use this.
+func (node *Exprs) formatHideConstants(ctx *FmtCtx) {
+	exprs := *node
+	if len(exprs) < 2 {
+		node.Format(ctx)
+		return
+	}
+
+	// Determine if there are only literals/placeholders and use the special
+	// representation if so.
+	for _, expr := range exprs {
+		switch expr.(type) {
+		case Datum, Constant, *Placeholder:
+			continue
+		}
+		node.Format(ctx)
+		return
+	}
+	v2 := append(make(Exprs, 0, 3), exprs[:2]...)
+	if len(exprs) > 2 {
+		v2 = append(v2, arityIndicator(len(exprs)-2))
+	}
+	v2.Format(ctx)
+}
+
+// formatHideConstants formats tuples containing only literals or
+// placeholders and longer than 1 element as a tuple of its first
+// two elements, scrubbed. For example:
+//
+//	(1)               -> (_)
+//	(1, 2)            -> (_, _)
+//	(1, 2, 3)         -> (_, _, __more1_10__)
+//	ROW()             -> ROW()
+//	ROW($1, $2, $3)   -> ROW($1, $2, __more1_10__)
+//	(1+2, 2+3, 3+4)   -> (_ + _, _ + _, _ + _)
+//	(1+2, b, c)       -> (_ + _, b, c)
+func (node *Tuple) formatHideConstants(ctx *FmtCtx) {
+	if len(node.Exprs) < 2 {
+		node.Format(ctx)
+		return
+	}
+
+	// Determine if there are only literals/placeholders and use the special
+	// representation if so.
+	for _, expr := range node.Exprs {
+		switch expr.(type) {
+		case Datum, Constant, *Placeholder:
+			continue
+		}
+		node.Format(ctx)
+		return
+	}
+	// We copy the node to preserve the "row" boolean flag.
+	v2 := *node
+	v2.Exprs = append(make(Exprs, 0, 3), v2.Exprs[:2]...)
+	if len(node.Exprs) > 2 {
+		v2.Exprs = append(v2.Exprs, arityIndicator(len(node.Exprs)-2))
+		if len(node.Labels) > 2 {
+			v2.Labels = node.Labels[:2]
+		}
+	}
+	v2.Format(ctx)
+}
+
+// formatShortenConstants formats tuples containing only literals or
+// placeholders and longer than 3 elements as a tuple of its first two elements
+// and the last one. For example:
+//
+//	(1, 2)             -> (1, 2)
+//	(1, 2, 3)          -> (1, 2, 3)
+//	(1, 2, 3, 4)       -> (1, 2, __more1_10__, 4)
+//	(1, 2, 3, ..., 20) -> (1, 2, __more10_100__, 20)
+func (node *Tuple) formatShortenConstants(ctx *FmtCtx) {
+	if len(node.Exprs) <= numElementsForShortenedList {
+		node.Format(ctx)
+		return
+	}
+	// Determine if there are only literals/placeholders and use the special
+	// representation if so.
+	for _, expr := range node.Exprs {
+		switch expr.(type) {
+		case Datum, Constant, *Placeholder:
+			continue
+		}
+		node.Format(ctx)
+		return
+	}
+	// We copy the node to preserve the "row" boolean flag.
+	v2 := *node
+	v2.Exprs = append(make(Exprs, 0, numElementsForShortenedList+1), v2.Exprs[:numElementsForShortenedList-1]...)
+	v2.Exprs = append(v2.Exprs, arityIndicator(len(node.Exprs)-numElementsForShortenedList))
+	v2.Exprs = append(v2.Exprs, node.Exprs[len(node.Exprs)-1])
+	if len(node.Labels) > numElementsForShortenedList-1 {
+		v2.Labels = node.Labels[:numElementsForShortenedList-1]
+	}
+	v2.Format(ctx)
+}
+
+// formatShortenConstants formats the tuple containing more than 3 datums to
+// print out only first two and the last one. For example,
+//
+//	(1, 2)             -> (1, 2)
+//	(1, 2, 3)          -> (1, 2, 3)
+//	(1, 2, 3, 4)       -> (1, 2, __more1_10__, 4)
+//	(1, 2, 3, ..., 20) -> (1, 2, __more10_100__, 20)
+func (node *DTuple) formatShortenConstants(ctx *FmtCtx) {
+	if len(node.D) <= numElementsForShortenedList {
+		node.Format(ctx)
+		return
+	}
+	ctx.WriteByte('(')
+	for i := 0; i < numElementsForShortenedList-1; i++ {
+		ctx.FormatNode(node.D[i])
+		ctx.WriteString(", ")
+	}
+	ctx.Printf("%s, ", arityIndicator(len(node.D)-numElementsForShortenedList))
+	ctx.FormatNode(node.D[len(node.D)-1])
+	ctx.WriteByte(')')
+}
+
+// formatHideConstants formats array expressions containing only literals or
+// placeholders and longer than 1 element as an array expression of its first
+// two elements, scrubbed. For example:
+//
+//	array[1]             -> array[_]
+//	array[1, 2]          -> array[_,_]
+//	array[1, 2, 3]       -> array[_,_,__more1_10__]
+//	array[1+2, 2+3, 3+4] -> array[_ + _,_ + _,_ + _]
+func (node *Array) formatHideConstants(ctx *FmtCtx) {
+	if len(node.Exprs) < 2 {
+		node.Format(ctx)
+		return
+	}
+	// Determine if there are only literals/placeholders and use the special
+	// representation if so.
+	for _, expr := range node.Exprs {
+		switch expr.(type) {
+		case Datum, Constant, *Placeholder:
+			continue
+		}
+		node.Format(ctx)
+		return
+	}
+	v2 := *node
+	v2.Exprs = append(make(Exprs, 0, 3), v2.Exprs[:2]...)
+	if len(node.Exprs) > 2 {
+		v2.Exprs = append(v2.Exprs, arityIndicator(len(node.Exprs)-2))
+	}
+	v2.Format(ctx)
+}
+
+// formatShortenConstants formats array expressions containing only literals or
+// placeholders and longer than 3 elements as an array of its first two elements
+// and the last one. For example:
+//
+//	array[1]                -> array[1]
+//	array[1, 2]             -> array[1,2]
+//	array[1, 2, 3]          -> array[1,2,3]
+//	array[1, 2, 3, 4]       -> array[1,2,__more1_10__,4]
+//	array[1, 2, 3, ..., 20] -> array[1,2,__more10_100__,20]
+func (node *Array) formatShortenConstants(ctx *FmtCtx) {
+	if len(node.Exprs) <= numElementsForShortenedList {
+		node.Format(ctx)
+		return
+	}
+	// Determine if there are only literals/placeholders and use the special
+	// representation if so.
+	for _, expr := range node.Exprs {
+		switch expr.(type) {
+		case Datum, Constant, *Placeholder:
+			continue
+		}
+		node.Format(ctx)
+		return
+	}
+	v2 := *node
+	v2.Exprs = append(make(Exprs, 0, numElementsForShortenedList+1), v2.Exprs[:numElementsForShortenedList-1]...)
+	v2.Exprs = append(v2.Exprs, arityIndicator(len(node.Exprs)-numElementsForShortenedList))
+	v2.Exprs = append(v2.Exprs, node.Exprs[len(node.Exprs)-1])
+	v2.Format(ctx)
+}
+
+// formatShortenConstants formats arrays longer than 3 elements as an array of
+// its first two elements and the last one. For example:
+//
+//	array[1]                -> array[1]
+//	array[1, 2]             -> array[1,2]
+//	array[1, 2, 3]          -> array[1,2,3]
+//	array[1, 2, 3, 4]       -> array[1,2,__more1_10__,4]
+//	array[1, 2, 3, ..., 20] -> array[1,2,__more10_100__,20]
+func (node *DArray) formatShortenConstants(ctx *FmtCtx) {
+	if len(node.Array) <= numElementsForShortenedList {
+		node.Format(ctx)
+		return
+	}
+	ctx.WriteString(`ARRAY[`)
+	for i := 0; i < numElementsForShortenedList-1; i++ {
+		ctx.FormatNode(node.Array[i])
+		ctx.WriteByte(',')
+	}
+	ctx.Printf("%s,", arityIndicator(len(node.Array)-numElementsForShortenedList))
+	ctx.FormatNode(node.Array[len(node.Array)-1])
+	ctx.WriteByte(']')
+}
+
+func arityIndicator(n int) Expr {
+	return NewUnresolvedName(arityString(n))
+}
+
+// arityIndicatorNoBounds is like arityIndicator, but it does not include the
+// bounds in the name. It's used when we don't care about differentiating
+// between different bounds, such as in formatting the statement as a
+// representative query for fingerprint generation.
+func arityIndicatorNoBounds() Expr {
+	return NewUnresolvedName(genericArityIndicator)
+}
+
+func arityString(n int) string {
+	var v int
+	if n <= 10 {
+		return "__more1_10__"
+	}
+	if n <= 100 {
+		return "__more10_100__"
+	}
+	if n <= 1000 {
+		for v = 1; n >= 10; n /= 10 {
+			v = v * 10
+		}
+		v = v * n
+		return fmt.Sprintf("__more%d__", v)
+	}
+	return "__more1000_plus__"
+}
+
+func isArityIndicatorString(s string) bool {
+	return strings.HasPrefix(s, "__more")
+}
diff --git a/pkg/sql/sem/tree/alter_backup.go b/pkg/sql/sem/tree/alter_backup.go
index 51a9a0a..a89e37a 100644
--- a/pkg/sql/sem/tree/alter_backup.go
+++ b/pkg/sql/sem/tree/alter_backup.go
@@ -1,12 +1,7 @@
 // Copyright 2022 The Cockroach Authors.
 //
-// Use of this software is governed by the Business Source License
-// included in the file licenses/BSL.txt.
-//
-// As of the Change Date specified in that file, in accordance with
-// the Business Source License, use of this software will be governed
-// by the Apache License, Version 2.0, included in the file
-// licenses/APL.txt.
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
 
 package tree
 
@@ -29,7 +24,7 @@ func (node *AlterBackup) Format(ctx *FmtCtx) {
 		ctx.WriteString(" IN ")
 	}
 
-	ctx.FormatNode(node.Backup)
+	ctx.FormatURI(node.Backup)
 	ctx.FormatNode(&node.Cmds)
 }
 
@@ -64,10 +59,10 @@ type AlterBackupKMS struct {
 // Format implements the NodeFormatter interface.
 func (node *AlterBackupKMS) Format(ctx *FmtCtx) {
 	ctx.WriteString(" ADD NEW_KMS=")
-	ctx.FormatNode(&node.KMSInfo.NewKMSURI)
+	ctx.FormatURIs(node.KMSInfo.NewKMSURI)
 
 	ctx.WriteString(" WITH OLD_KMS=")
-	ctx.FormatNode(&node.KMSInfo.OldKMSURI)
+	ctx.FormatURIs(node.KMSInfo.OldKMSURI)
 }
 
 // BackupKMS represents possible options used when altering a backup KMS
diff --git a/pkg/sql/sem/tree/alter_backup_schedule.go b/pkg/sql/sem/tree/alter_backup_schedule.go
index d189741..14ed5f8 100644
--- a/pkg/sql/sem/tree/alter_backup_schedule.go
+++ b/pkg/sql/sem/tree/alter_backup_schedule.go
@@ -1,12 +1,7 @@
 // Copyright 2022 The Cockroach Authors.
 //
-// Use of this software is governed by the Business Source License
-// included in the file licenses/BSL.txt.
-//
-// As of the Change Date specified in that file, in accordance with
-// the Business Source License, use of this software will be governed
-// by the Apache License, Version 2.0, included in the file
-// licenses/APL.txt.
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
 
 package tree
 
@@ -59,6 +54,7 @@ func (*AlterBackupScheduleSetWith) alterBackupScheduleCmd()           {}
 func (*AlterBackupScheduleSetRecurring) alterBackupScheduleCmd()      {}
 func (*AlterBackupScheduleSetFullBackup) alterBackupScheduleCmd()     {}
 func (*AlterBackupScheduleSetScheduleOption) alterBackupScheduleCmd() {}
+func (*AlterBackupScheduleNextRun) alterBackupScheduleCmd()           {}
 
 var _ AlterBackupScheduleCmd = &AlterBackupScheduleSetLabel{}
 var _ AlterBackupScheduleCmd = &AlterBackupScheduleSetInto{}
@@ -66,6 +62,7 @@ var _ AlterBackupScheduleCmd = &AlterBackupScheduleSetWith{}
 var _ AlterBackupScheduleCmd = &AlterBackupScheduleSetRecurring{}
 var _ AlterBackupScheduleCmd = &AlterBackupScheduleSetFullBackup{}
 var _ AlterBackupScheduleCmd = &AlterBackupScheduleSetScheduleOption{}
+var _ AlterBackupScheduleCmd = &AlterBackupScheduleNextRun{}
 
 // AlterBackupScheduleSetLabel represents an ADD <label> command
 type AlterBackupScheduleSetLabel struct {
@@ -86,7 +83,7 @@ type AlterBackupScheduleSetInto struct {
 // Format implements the NodeFormatter interface.
 func (node *AlterBackupScheduleSetInto) Format(ctx *FmtCtx) {
 	ctx.WriteString("SET INTO ")
-	ctx.FormatNode(&node.Into)
+	ctx.FormatURIs(node.Into)
 }
 
 // AlterBackupScheduleSetWith represents an SET <options> command
@@ -150,3 +147,17 @@ func (node *AlterBackupScheduleSetScheduleOption) Format(ctx *FmtCtx) {
 		ctx.FormatNode(o.Value)
 	}
 }
+
+// AlterBackupScheduleRunNow represents a RUN NOW command.
+type AlterBackupScheduleNextRun struct {
+	Full bool
+}
+
+// Format implements the NodeFormatter interface.
+func (node *AlterBackupScheduleNextRun) Format(ctx *FmtCtx) {
+	if node.Full {
+		ctx.WriteString("EXECUTE FULL IMMEDIATELY")
+	} else {
+		ctx.WriteString("EXECUTE IMMEDIATELY")
+	}
+}
diff --git a/pkg/sql/sem/tree/alter_changefeed.go b/pkg/sql/sem/tree/alter_changefeed.go
index a7c5945..e00f04d 100644
--- a/pkg/sql/sem/tree/alter_changefeed.go
+++ b/pkg/sql/sem/tree/alter_changefeed.go
@@ -1,12 +1,7 @@
 // Copyright 2022 The Cockroach Authors.
 //
-// Use of this software is governed by the Business Source License
-// included in the file licenses/BSL.txt.
-//
-// As of the Change Date specified in that file, in accordance with
-// the Business Source License, use of this software will be governed
-// by the Apache License, Version 2.0, included in the file
-// licenses/APL.txt.
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
 
 package tree
 
@@ -91,7 +86,15 @@ type AlterChangefeedSetOptions struct {
 // Format implements the NodeFormatter interface.
 func (node *AlterChangefeedSetOptions) Format(ctx *FmtCtx) {
 	ctx.WriteString(" SET ")
-	ctx.FormatNode(&node.Options)
+	node.Options.formatEach(ctx, func(n *KVOption, ctx *FmtCtx) {
+		// The "sink" option is a URL. (Use a literal here to avoid pulling in
+		// changefeedbase as a dependency.)
+		if string(n.Key) == "sink" {
+			ctx.FormatURI(n.Value)
+		} else {
+			ctx.FormatNode(n.Value)
+		}
+	})
 }
 
 // AlterChangefeedUnsetOptions represents an UNSET <options> command
diff --git a/pkg/sql/sem/tree/alter_database.go b/pkg/sql/sem/tree/alter_database.go
index 95cd85f..39658ae 100644
--- a/pkg/sql/sem/tree/alter_database.go
+++ b/pkg/sql/sem/tree/alter_database.go
@@ -1,12 +1,7 @@
 // Copyright 2020 The Cockroach Authors.
 //
-// Use of this software is governed by the Business Source License
-// included in the file licenses/BSL.txt.
-//
-// As of the Change Date specified in that file, in accordance with
-// the Business Source License, use of this software will be governed
-// by the Apache License, Version 2.0, included in the file
-// licenses/APL.txt.
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
 
 package tree
 
diff --git a/pkg/sql/sem/tree/alter_default_privileges.go b/pkg/sql/sem/tree/alter_default_privileges.go
index 65de804..aff29a6 100644
--- a/pkg/sql/sem/tree/alter_default_privileges.go
+++ b/pkg/sql/sem/tree/alter_default_privileges.go
@@ -1,12 +1,7 @@
 // Copyright 2021 The Cockroach Authors.
 //
-// Use of this software is governed by the Business Source License
-// included in the file licenses/BSL.txt.
-//
-// As of the Change Date specified in that file, in accordance with
-// the Business Source License, use of this software will be governed
-// by the Apache License, Version 2.0, included in the file
-// licenses/APL.txt.
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
 
 package tree
 
diff --git a/pkg/sql/sem/tree/alter_index.go b/pkg/sql/sem/tree/alter_index.go
index 8bd7afd..12b9fd0 100644
--- a/pkg/sql/sem/tree/alter_index.go
+++ b/pkg/sql/sem/tree/alter_index.go
@@ -1,12 +1,7 @@
 // Copyright 2017 The Cockroach Authors.
 //
-// Use of this software is governed by the Business Source License
-// included in the file licenses/BSL.txt.
-//
-// As of the Change Date specified in that file, in accordance with
-// the Business Source License, use of this software will be governed
-// by the Apache License, Version 2.0, included in the file
-// licenses/APL.txt.
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
 
 package tree
 
diff --git a/pkg/sql/sem/tree/alter_policy.go b/pkg/sql/sem/tree/alter_policy.go
new file mode 100644
index 0000000..54c260b
--- /dev/null
+++ b/pkg/sql/sem/tree/alter_policy.go
@@ -0,0 +1,37 @@
+// Copyright 2024 The Cockroach Authors.
+//
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
+
+package tree
+
+var _ Statement = &AlterPolicy{}
+
+// AlterPolicy is a tree struct for the ALTER POLICY DDL statement
+type AlterPolicy struct {
+	PolicyName    Name
+	TableName     *UnresolvedObjectName
+	NewPolicyName Name
+	Roles         RoleSpecList
+	Exprs         PolicyExpressions
+}
+
+// Format implements the NodeFormatter interface.
+func (node *AlterPolicy) Format(ctx *FmtCtx) {
+	ctx.WriteString("ALTER POLICY ")
+	ctx.FormatNode(&node.PolicyName)
+	ctx.WriteString(" ON ")
+	ctx.FormatNode(node.TableName)
+
+	if node.NewPolicyName != "" {
+		ctx.WriteString(" RENAME TO ")
+		ctx.FormatNode(&node.NewPolicyName)
+		return
+	}
+
+	if len(node.Roles) > 0 {
+		ctx.WriteString(" TO ")
+		ctx.FormatNode(&node.Roles)
+	}
+	ctx.FormatNode(&node.Exprs)
+}
diff --git a/pkg/sql/sem/tree/alter_range.go b/pkg/sql/sem/tree/alter_range.go
index b353d3b..a7d8bc5 100644
--- a/pkg/sql/sem/tree/alter_range.go
+++ b/pkg/sql/sem/tree/alter_range.go
@@ -1,12 +1,7 @@
 // Copyright 2021 The Cockroach Authors.
 //
-// Use of this software is governed by the Business Source License
-// included in the file licenses/BSL.txt.
-//
-// As of the Change Date specified in that file, in accordance with
-// the Business Source License, use of this software will be governed
-// by the Apache License, Version 2.0, included in the file
-// licenses/APL.txt.
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
 
 package tree
 
diff --git a/pkg/sql/sem/tree/alter_role.go b/pkg/sql/sem/tree/alter_role.go
index 04c723a..dcaca16 100644
--- a/pkg/sql/sem/tree/alter_role.go
+++ b/pkg/sql/sem/tree/alter_role.go
@@ -1,12 +1,7 @@
 // Copyright 2021 The Cockroach Authors.
 //
-// Use of this software is governed by the Business Source License
-// included in the file licenses/BSL.txt.
-//
-// As of the Change Date specified in that file, in accordance with
-// the Business Source License, use of this software will be governed
-// by the Apache License, Version 2.0, included in the file
-// licenses/APL.txt.
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
 
 package tree
 
diff --git a/pkg/sql/sem/tree/alter_schema.go b/pkg/sql/sem/tree/alter_schema.go
index fc3982e..df80cd4 100644
--- a/pkg/sql/sem/tree/alter_schema.go
+++ b/pkg/sql/sem/tree/alter_schema.go
@@ -1,12 +1,7 @@
 // Copyright 2020 The Cockroach Authors.
 //
-// Use of this software is governed by the Business Source License
-// included in the file licenses/BSL.txt.
-//
-// As of the Change Date specified in that file, in accordance with
-// the Business Source License, use of this software will be governed
-// by the Apache License, Version 2.0, included in the file
-// licenses/APL.txt.
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
 
 package tree
 
diff --git a/pkg/sql/sem/tree/alter_sequence.go b/pkg/sql/sem/tree/alter_sequence.go
index afb8621..755be1b 100644
--- a/pkg/sql/sem/tree/alter_sequence.go
+++ b/pkg/sql/sem/tree/alter_sequence.go
@@ -1,12 +1,7 @@
 // Copyright 2015 The Cockroach Authors.
 //
-// Use of this software is governed by the Business Source License
-// included in the file licenses/BSL.txt.
-//
-// As of the Change Date specified in that file, in accordance with
-// the Business Source License, use of this software will be governed
-// by the Apache License, Version 2.0, included in the file
-// licenses/APL.txt.
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
 
 package tree
 
diff --git a/pkg/sql/sem/tree/alter_table.go b/pkg/sql/sem/tree/alter_table.go
index d54067f..26a2891 100644
--- a/pkg/sql/sem/tree/alter_table.go
+++ b/pkg/sql/sem/tree/alter_table.go
@@ -1,19 +1,16 @@
 // Copyright 2015 The Cockroach Authors.
 //
-// Use of this software is governed by the Business Source License
-// included in the file licenses/BSL.txt.
-//
-// As of the Change Date specified in that file, in accordance with
-// the Business Source License, use of this software will be governed
-// by the Apache License, Version 2.0, included in the file
-// licenses/APL.txt.
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
 
 package tree
 
 import (
+	"fmt"
 	"strings"
 
 	"github.com/cockroachdb/cockroachdb-parser/pkg/sql/lex"
+	"github.com/cockroachdb/cockroachdb-parser/pkg/sql/lexbase"
 )
 
 // AlterTable represents an ALTER TABLE statement.
@@ -76,6 +73,11 @@ func (*AlterTablePartitionByTable) alterTableCmd()   {}
 func (*AlterTableInjectStats) alterTableCmd()        {}
 func (*AlterTableSetStorageParams) alterTableCmd()   {}
 func (*AlterTableResetStorageParams) alterTableCmd() {}
+func (*AlterTableAddIdentity) alterTableCmd()        {}
+func (*AlterTableSetIdentity) alterTableCmd()        {}
+func (*AlterTableIdentity) alterTableCmd()           {}
+func (*AlterTableDropIdentity) alterTableCmd()       {}
+func (*AlterTableSetRLSMode) alterTableCmd()         {}
 
 var _ AlterTableCmd = &AlterTableAddColumn{}
 var _ AlterTableCmd = &AlterTableAddConstraint{}
@@ -96,6 +98,11 @@ var _ AlterTableCmd = &AlterTablePartitionByTable{}
 var _ AlterTableCmd = &AlterTableInjectStats{}
 var _ AlterTableCmd = &AlterTableSetStorageParams{}
 var _ AlterTableCmd = &AlterTableResetStorageParams{}
+var _ AlterTableCmd = &AlterTableAddIdentity{}
+var _ AlterTableCmd = &AlterTableSetIdentity{}
+var _ AlterTableCmd = &AlterTableIdentity{}
+var _ AlterTableCmd = &AlterTableDropIdentity{}
+var _ AlterTableCmd = &AlterTableSetRLSMode{}
 
 // ColumnMutationCmd is the subset of AlterTableCmds that modify an
 // existing column.
@@ -629,7 +636,7 @@ func (node *AlterTableSetStorageParams) Format(ctx *FmtCtx) {
 
 // AlterTableResetStorageParams represents a ALTER TABLE RESET command.
 type AlterTableResetStorageParams struct {
-	Params NameList
+	Params []string
 }
 
 // TelemetryName implements the AlterTableCmd interface.
@@ -639,8 +646,14 @@ func (node *AlterTableResetStorageParams) TelemetryName() string {
 
 // Format implements the NodeFormatter interface.
 func (node *AlterTableResetStorageParams) Format(ctx *FmtCtx) {
+	buf, f := &ctx.Buffer, ctx.flags
 	ctx.WriteString(" RESET (")
-	ctx.FormatNode(&node.Params)
+	for i, param := range node.Params {
+		if i > 0 {
+			ctx.WriteString(", ")
+		}
+		lexbase.EncodeSQLStringWithFlags(buf, param, f.EncodeFlags())
+	}
 	ctx.WriteString(")")
 }
 
@@ -738,6 +751,175 @@ func (node *AlterTableOwner) Format(ctx *FmtCtx) {
 	ctx.FormatNode(&node.Owner)
 }
 
+// AlterTableAddIdentity represents commands to alter a column to an identity.
+type AlterTableAddIdentity struct {
+	Column        Name
+	Qualification ColumnQualification
+}
+
+// GetColumn implemnets the ColumnMutationCmd interface.
+func (node *AlterTableAddIdentity) GetColumn() Name {
+	return node.Column
+}
+
+// TelemetryName implements the AlterTableCmd interface.
+func (node *AlterTableAddIdentity) TelemetryName() string {
+	return "add_identity"
+}
+
+// Format implements the NodeFormatter interface.
+func (node *AlterTableAddIdentity) Format(ctx *FmtCtx) {
+	ctx.WriteString(" ALTER COLUMN ")
+	ctx.FormatNode(&node.Column)
+	var options SequenceOptions
+	switch t := (node.Qualification).(type) {
+	case *GeneratedAlwaysAsIdentity:
+		ctx.WriteString(" ADD GENERATED ALWAYS AS IDENTITY")
+		options = t.SeqOptions
+	case *GeneratedByDefAsIdentity:
+		ctx.WriteString(" ADD GENERATED BY DEFAULT AS IDENTITY")
+		options = t.SeqOptions
+	}
+	if len(options) > 0 {
+		ctx.WriteString(" (")
+		ctx.FormatNode(&options)
+		ctx.WriteString(" )")
+	}
+}
+
+// AlterTableSetIdentity represents commands to alter a column identity type.
+type AlterTableSetIdentity struct {
+	Column                  Name
+	GeneratedAsIdentityType GeneratedIdentityType
+}
+
+// GetColumn implemnets the ColumnMutationCmd interface.
+func (node *AlterTableSetIdentity) GetColumn() Name {
+	return node.Column
+}
+
+// TelemetryName implements the AlterTableCmd interface.
+func (node *AlterTableSetIdentity) TelemetryName() string {
+	return "set_identity"
+}
+
+// Format implements the NodeFormatter interface.
+func (node *AlterTableSetIdentity) Format(ctx *FmtCtx) {
+	ctx.WriteString(" ALTER COLUMN ")
+	ctx.FormatNode(&node.Column)
+	switch node.GeneratedAsIdentityType {
+	case GeneratedAlways:
+		ctx.WriteString(" SET GENERATED ALWAYS")
+	case GeneratedByDefault:
+		ctx.WriteString(" SET GENERATED BY DEFAULT")
+	}
+}
+
+// AlterTableIdentity represents commands to alter a column identity
+// sequence options.
+type AlterTableIdentity struct {
+	Column     Name
+	SeqOptions SequenceOptions
+}
+
+// GetColumn implemnets the ColumnMutationCmd interface.
+func (node *AlterTableIdentity) GetColumn() Name {
+	return node.Column
+}
+
+// TelemetryName implements the AlterTableCmd interface.
+func (node *AlterTableIdentity) TelemetryName() string {
+	return "alter_identity"
+}
+
+// Format implements the NodeFormatter interface.
+func (node *AlterTableIdentity) Format(ctx *FmtCtx) {
+	ctx.WriteString(" ALTER COLUMN ")
+	ctx.FormatNode(&node.Column)
+	for i := range node.SeqOptions {
+		option := node.SeqOptions[i]
+		if option.Name != SeqOptRestart {
+			ctx.WriteString(" SET")
+		}
+		ctx.FormatNode(&SequenceOptions{option})
+	}
+
+}
+
+// AlterTableDropIdentity represents an ALTER COLUMN DROP IDENTITY [ IF EXISTS ].
+type AlterTableDropIdentity struct {
+	Column   Name
+	IfExists bool
+}
+
+// GetColumn implemnets the ColumnMutationCmd interface.
+func (node *AlterTableDropIdentity) GetColumn() Name {
+	return node.Column
+}
+
+// TelemetryName implements the AlterTableCmd interface.
+func (node *AlterTableDropIdentity) TelemetryName() string {
+	return "drop_identity"
+}
+
+// Format implements the NodeFormatter interface.
+func (node *AlterTableDropIdentity) Format(ctx *FmtCtx) {
+	ctx.WriteString(" ALTER COLUMN ")
+	ctx.FormatNode(&node.Column)
+	ctx.WriteString(" DROP IDENTITY")
+	if node.IfExists {
+		ctx.WriteString(" IF EXISTS")
+	}
+}
+
+// TableRLSMode represents different modes that the table can be in for
+// row-level security.
+type TableRLSMode int
+
+// TableRLSMode values
+const (
+	TableRLSEnable TableRLSMode = iota
+	TableRLSDisable
+	TableRLSForce
+	TableRLSNoForce
+)
+
+func (r TableRLSMode) String() string {
+	var rlsTableModeName = [...]string{
+		TableRLSEnable:  "ENABLE",
+		TableRLSDisable: "DISABLE",
+		TableRLSForce:   "FORCE",
+		TableRLSNoForce: "NO FORCE",
+	}
+	return rlsTableModeName[r]
+}
+
+// TelemetryName implements the AlterTableCmd interface.
+func (r TableRLSMode) TelemetryName() string {
+	return strings.ReplaceAll(strings.ToLower(r.String()), " ", "_")
+}
+
+// SafeValue implements the redact.SafeValue interface.
+func (r TableRLSMode) SafeValue() {}
+
+// AlterTableSetRLSMode represents the following alter table command:
+// {ENABLE | DISABLE | FORCE | NO FORCE} ROW LEVEL SECURITY
+type AlterTableSetRLSMode struct {
+	Mode TableRLSMode
+}
+
+// TelemetryName implements the AlterTableCmd interface
+func (node *AlterTableSetRLSMode) TelemetryName() string {
+	return fmt.Sprintf("%s_row_level_security", node.Mode.TelemetryName())
+}
+
+// Format implements the NodeFormatter interface
+func (node *AlterTableSetRLSMode) Format(ctx *FmtCtx) {
+	ctx.WriteString(" ")
+	ctx.WriteString(node.Mode.String())
+	ctx.WriteString(" ROW LEVEL SECURITY")
+}
+
 // GetTableType returns a string representing the type of table the command
 // is operating on.
 // It is assumed if the table is not a sequence or a view, then it is a
diff --git a/pkg/sql/sem/tree/alter_tenant.go b/pkg/sql/sem/tree/alter_tenant.go
index 410bc2e..b1a28ff 100644
--- a/pkg/sql/sem/tree/alter_tenant.go
+++ b/pkg/sql/sem/tree/alter_tenant.go
@@ -1,12 +1,7 @@
 // Copyright 2022 The Cockroach Authors.
 //
-// Use of this software is governed by the Business Source License
-// included in the file licenses/BSL.txt.
-//
-// As of the Change Date specified in that file, in accordance with
-// the Business Source License, use of this software will be governed
-// by the Apache License, Version 2.0, included in the file
-// licenses/APL.txt.
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
 
 package tree
 
@@ -18,10 +13,16 @@ type ReplicationCutoverTime struct {
 
 // AlterTenantReplication represents an ALTER VIRTUAL CLUSTER REPLICATION statement.
 type AlterTenantReplication struct {
-	TenantSpec *TenantSpec
-	Command    JobCommand
-	Cutover    *ReplicationCutoverTime
-	Options    TenantReplicationOptions
+	TenantSpec                  *TenantSpec
+	Command                     JobCommand
+	Cutover                     *ReplicationCutoverTime
+	Producer                    bool
+	ReplicationSourceTenantName *TenantSpec
+	// ReplicationSourceConnUri is a connection uri of the source cluster that we
+	// are replicating data from.
+	ReplicationSourceConnUri Expr
+
+	Options TenantReplicationOptions
 }
 
 var _ Statement = &AlterTenantReplication{}
@@ -39,8 +40,28 @@ func (n *AlterTenantReplication) Format(ctx *FmtCtx) {
 			ctx.WriteString("SYSTEM TIME ")
 			ctx.FormatNode(n.Cutover.Timestamp)
 		}
+	} else if n.ReplicationSourceTenantName != nil {
+		ctx.WriteString("START REPLICATION OF ")
+		ctx.FormatNode(n.ReplicationSourceTenantName)
+		ctx.WriteString(" ON ")
+		_, canOmitParentheses := n.ReplicationSourceConnUri.(alreadyDelimitedAsSyntacticDExpr)
+		if !canOmitParentheses {
+			ctx.WriteByte('(')
+		}
+		ctx.FormatNode(n.ReplicationSourceConnUri)
+		if !canOmitParentheses {
+			ctx.WriteByte(')')
+		}
+
+		if !n.Options.IsDefault() {
+			ctx.WriteString(" WITH ")
+			ctx.FormatNode(&n.Options)
+		}
 	} else if !n.Options.IsDefault() {
 		ctx.WriteString("SET REPLICATION ")
+		if n.Producer {
+			ctx.WriteString("SOURCE ")
+		}
 		ctx.FormatNode(&n.Options)
 	} else if n.Command == PauseJob || n.Command == ResumeJob {
 		ctx.WriteString(JobCommandToStatement[n.Command])
@@ -222,3 +243,19 @@ func (n *AlterTenantService) Format(ctx *FmtCtx) {
 		ctx.WriteString(" STOP SERVICE")
 	}
 }
+
+// AlterTenantReset represents an ALTER VIRTUAL CLUSTER RESET statement.
+type AlterTenantReset struct {
+	TenantSpec *TenantSpec
+	Timestamp  Expr
+}
+
+var _ Statement = &AlterTenantReset{}
+
+// Format implements the NodeFormatter interface.
+func (n *AlterTenantReset) Format(ctx *FmtCtx) {
+	ctx.WriteString("ALTER VIRTUAL CLUSTER ")
+	ctx.FormatNode(n.TenantSpec)
+	ctx.WriteString(" RESET DATA TO SYSTEM TIME ")
+	ctx.FormatNode(n.Timestamp)
+}
diff --git a/pkg/sql/sem/tree/alter_type.go b/pkg/sql/sem/tree/alter_type.go
index fa179cf..5b86dd5 100644
--- a/pkg/sql/sem/tree/alter_type.go
+++ b/pkg/sql/sem/tree/alter_type.go
@@ -1,12 +1,7 @@
 // Copyright 2020 The Cockroach Authors.
 //
-// Use of this software is governed by the Business Source License
-// included in the file licenses/BSL.txt.
-//
-// As of the Change Date specified in that file, in accordance with
-// the Business Source License, use of this software will be governed
-// by the Apache License, Version 2.0, included in the file
-// licenses/APL.txt.
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
 
 package tree
 
diff --git a/pkg/sql/sem/tree/analyze.go b/pkg/sql/sem/tree/analyze.go
index 7bc71a1..f39c5da 100644
--- a/pkg/sql/sem/tree/analyze.go
+++ b/pkg/sql/sem/tree/analyze.go
@@ -1,12 +1,7 @@
 // Copyright 2020 The Cockroach Authors.
 //
-// Use of this software is governed by the Business Source License
-// included in the file licenses/BSL.txt.
-//
-// As of the Change Date specified in that file, in accordance with
-// the Business Source License, use of this software will be governed
-// by the Apache License, Version 2.0, included in the file
-// licenses/APL.txt.
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
 
 package tree
 
diff --git a/pkg/sql/sem/tree/annotation.go b/pkg/sql/sem/tree/annotation.go
index 3cda324..62ef914 100644
--- a/pkg/sql/sem/tree/annotation.go
+++ b/pkg/sql/sem/tree/annotation.go
@@ -1,12 +1,7 @@
 // Copyright 2018 The Cockroach Authors.
 //
-// Use of this software is governed by the Business Source License
-// included in the file licenses/BSL.txt.
-//
-// As of the Change Date specified in that file, in accordance with
-// the Business Source License, use of this software will be governed
-// by the Apache License, Version 2.0, included in the file
-// licenses/APL.txt.
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
 
 package tree
 
diff --git a/pkg/sql/sem/tree/backup.go b/pkg/sql/sem/tree/backup.go
index 6b1441d..4ed4f0a 100644
--- a/pkg/sql/sem/tree/backup.go
+++ b/pkg/sql/sem/tree/backup.go
@@ -1,12 +1,7 @@
 // Copyright 2016 The Cockroach Authors.
 //
-// Use of this software is governed by the Business Source License
-// included in the file licenses/BSL.txt.
-//
-// As of the Change Date specified in that file, in accordance with
-// the Business Source License, use of this software will be governed
-// by the Apache License, Version 2.0, included in the file
-// licenses/APL.txt.
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
 
 package tree
 
@@ -60,24 +55,17 @@ type Backup struct {
 	// the docs).
 	To StringOrPlaceholderOptList
 
-	// IncrementalFrom is only set for the old 'BACKUP .... TO ...' syntax.
-	IncrementalFrom Exprs
-
 	AsOf    AsOfClause
 	Options BackupOptions
 
-	// Nested is set to true when the user creates a backup with
-	//`BACKUP ... INTO... ` syntax.
-	Nested bool
-
 	// AppendToLatest is set to true if the user creates a backup with
 	//`BACKUP...INTO LATEST...`
 	AppendToLatest bool
 
 	// Subdir may be set by the parser when the SQL query is of the form `BACKUP
-	// INTO 'subdir' IN...`. Alternatively, if Nested is true but a subdir was not
-	// explicitly specified by the user, then this will be set during BACKUP
-	// planning once the destination has been resolved.
+	// INTO 'subdir' IN...`. Alternatively, if a subdir was not explicitly specified
+	// by the user, then this will be set during BACKUP planning once the destination
+	// has been resolved.
 	Subdir Expr
 }
 
@@ -90,26 +78,18 @@ func (node *Backup) Format(ctx *FmtCtx) {
 		ctx.FormatNode(node.Targets)
 		ctx.WriteString(" ")
 	}
-	if node.Nested {
-		ctx.WriteString("INTO ")
-		if node.Subdir != nil {
-			ctx.FormatNode(node.Subdir)
-			ctx.WriteString(" IN ")
-		} else if node.AppendToLatest {
-			ctx.WriteString("LATEST IN ")
-		}
-	} else {
-		ctx.WriteString("TO ")
+	ctx.WriteString("INTO ")
+	if node.Subdir != nil {
+		ctx.FormatNode(node.Subdir)
+		ctx.WriteString(" IN ")
+	} else if node.AppendToLatest {
+		ctx.WriteString("LATEST IN ")
 	}
-	ctx.FormatNode(&node.To)
+	ctx.FormatURIs(node.To)
 	if node.AsOf.Expr != nil {
 		ctx.WriteString(" ")
 		ctx.FormatNode(&node.AsOf)
 	}
-	if node.IncrementalFrom != nil {
-		ctx.WriteString(" INCREMENTAL FROM ")
-		ctx.FormatNode(&node.IncrementalFrom)
-	}
 
 	if !node.Options.IsDefault() {
 		ctx.WriteString(" WITH OPTIONS (")
@@ -138,9 +118,7 @@ type RestoreOptions struct {
 	SkipMissingUDFs                  bool
 	Detached                         bool
 	SkipLocalitiesCheck              bool
-	DebugPauseOn                     Expr
 	NewDBName                        Expr
-	IncludeAllSecondaryTenants       Expr
 	IncrementalStorage               StringOrPlaceholderOptList
 	AsTenant                         Expr
 	ForceTenantID                    Expr
@@ -149,9 +127,14 @@ type RestoreOptions struct {
 	UnsafeRestoreIncompatibleVersion bool
 	ExecutionLocality                Expr
 	ExperimentalOnline               bool
+	ExperimentalCopy                 bool
 	RemoveRegions                    bool
 }
 
+func (opts *RestoreOptions) OnlineImpl() bool {
+	return opts.ExperimentalCopy || opts.ExperimentalOnline
+}
+
 var _ NodeFormatter = &RestoreOptions{}
 
 // Restore represents a RESTORE statement.
@@ -159,20 +142,16 @@ type Restore struct {
 	Targets            BackupTargetList
 	DescriptorCoverage DescriptorCoverage
 
-	// From contains the URIs for the backup(s) we seek to restore.
-	//   - len(From)>1 implies the user explicitly passed incremental backup paths,
-	//     which is only allowed using the old syntax, `RESTORE <targets> FROM <destination>.
-	//     In this case, From[0] contains the URI(s) for the full backup.
-	//   - len(From)==1 implies we'll have to look for incremental backups in planning
-	//   - len(From[0]) > 1 implies the backups are locality aware
-	//   - From[i][0] must be the default locality.
-	From    []StringOrPlaceholderOptList
+	// From contains the URIs for the backup we seek to restore.
+	//   - len(From) > 1 implies the backups are locality aware
+	//   - From[0] must be the default locality.
+	From    StringOrPlaceholderOptList
 	AsOf    AsOfClause
 	Options RestoreOptions
 
 	// Subdir may be set by the parser when the SQL query is of the form `RESTORE
-	// ... FROM 'from' IN 'subdir'...`. Alternatively, restore_planning.go will set
-	// it for the query `RESTORE ... FROM 'from' IN LATEST...`
+	// ... FROM 'subdir' IN 'from'...`. Alternatively, restore_planning.go will set
+	// it for the query `RESTORE ... FROM LATEST IN 'from'...`
 	Subdir Expr
 }
 
@@ -190,26 +169,15 @@ func (node *Restore) Format(ctx *FmtCtx) {
 		ctx.FormatNode(node.Subdir)
 		ctx.WriteString(" IN ")
 	}
-	for i := range node.From {
-		if i > 0 {
-			ctx.WriteString(", ")
-		}
-		ctx.FormatNode(&node.From[i])
-	}
+	ctx.FormatURIs(node.From)
 	if node.AsOf.Expr != nil {
 		ctx.WriteString(" ")
 		ctx.FormatNode(&node.AsOf)
 	}
 	if !node.Options.IsDefault() {
-		if ctx.HasFlags(FmtHideConstants) {
-			ctx.WriteString(" WITH OPTIONS (")
-			ctx.FormatNode(&node.Options)
-			ctx.WriteString(")")
-		} else {
-			ctx.WriteString(" WITH OPTIONS (")
-			ctx.FormatNode(&node.Options)
-			ctx.WriteString(")")
-		}
+		ctx.WriteString(" WITH OPTIONS (")
+		ctx.FormatNode(&node.Options)
+		ctx.WriteString(")")
 	}
 }
 
@@ -234,6 +202,13 @@ func (o *KVOptions) HasKey(key Name) bool {
 
 // Format implements the NodeFormatter interface.
 func (o *KVOptions) Format(ctx *FmtCtx) {
+	o.formatEach(ctx, func(n *KVOption, ctx *FmtCtx) {
+		ctx.FormatNode(n.Value)
+	})
+}
+
+// formatEach is like Format but allows custom formatting of the value part.
+func (o *KVOptions) formatEach(ctx *FmtCtx, formatValue func(*KVOption, *FmtCtx)) {
 	for i := range *o {
 		n := &(*o)[i]
 		if i > 0 {
@@ -246,7 +221,7 @@ func (o *KVOptions) Format(ctx *FmtCtx) {
 		})
 		if n.Value != nil {
 			ctx.WriteString(` = `)
-			ctx.FormatNode(n.Value)
+			formatValue(n, ctx)
 		}
 	}
 }
@@ -301,13 +276,13 @@ func (o *BackupOptions) Format(ctx *FmtCtx) {
 	if o.EncryptionKMSURI != nil {
 		maybeAddSep()
 		ctx.WriteString("kms = ")
-		ctx.FormatNode(&o.EncryptionKMSURI)
+		ctx.FormatURIs(o.EncryptionKMSURI)
 	}
 
 	if o.IncrementalStorage != nil {
 		maybeAddSep()
 		ctx.WriteString("incremental_location = ")
-		ctx.FormatNode(&o.IncrementalStorage)
+		ctx.FormatURIs(o.IncrementalStorage)
 	}
 
 	if o.ExecutionLocality != nil {
@@ -425,7 +400,7 @@ func (o *RestoreOptions) Format(ctx *FmtCtx) {
 	if o.DecryptionKMSURI != nil {
 		maybeAddSep()
 		ctx.WriteString("kms = ")
-		ctx.FormatNode(&o.DecryptionKMSURI)
+		ctx.FormatURIs(o.DecryptionKMSURI)
 	}
 
 	if o.IntoDB != nil {
@@ -434,12 +409,6 @@ func (o *RestoreOptions) Format(ctx *FmtCtx) {
 		ctx.FormatNode(o.IntoDB)
 	}
 
-	if o.DebugPauseOn != nil {
-		maybeAddSep()
-		ctx.WriteString("debug_pause_on = ")
-		ctx.FormatNode(o.DebugPauseOn)
-	}
-
 	if o.SkipMissingFKs {
 		maybeAddSep()
 		ctx.WriteString("skip_missing_foreign_keys")
@@ -481,16 +450,10 @@ func (o *RestoreOptions) Format(ctx *FmtCtx) {
 		ctx.FormatNode(o.NewDBName)
 	}
 
-	if o.IncludeAllSecondaryTenants != nil {
-		maybeAddSep()
-		ctx.WriteString("include_all_virtual_clusters = ")
-		ctx.FormatNode(o.IncludeAllSecondaryTenants)
-	}
-
 	if o.IncrementalStorage != nil {
 		maybeAddSep()
 		ctx.WriteString("incremental_location = ")
-		ctx.FormatNode(&o.IncrementalStorage)
+		ctx.FormatURIs(o.IncrementalStorage)
 	}
 
 	if o.AsTenant != nil {
@@ -520,15 +483,9 @@ func (o *RestoreOptions) Format(ctx *FmtCtx) {
 	}
 
 	if o.ExecutionLocality != nil {
-		if ctx.HasFlags(FmtHideConstants) {
-			maybeAddSep()
-			ctx.WriteString("execution locality = ")
-			ctx.FormatNode(o.ExecutionLocality)
-		} else {
-			maybeAddSep()
-			ctx.WriteString("execution locality = ")
-			ctx.FormatNode(o.ExecutionLocality)
-		}
+		maybeAddSep()
+		ctx.WriteString("execution locality = ")
+		ctx.FormatNode(o.ExecutionLocality)
 	}
 
 	if o.ExperimentalOnline {
@@ -536,6 +493,11 @@ func (o *RestoreOptions) Format(ctx *FmtCtx) {
 		ctx.WriteString("experimental deferred copy")
 	}
 
+	if o.ExperimentalCopy {
+		maybeAddSep()
+		ctx.WriteString("experimental copy")
+	}
+
 	if o.RemoveRegions {
 		maybeAddSep()
 		ctx.WriteString("remove_regions")
@@ -620,12 +582,6 @@ func (o *RestoreOptions) CombineWith(other *RestoreOptions) error {
 		o.SkipLocalitiesCheck = other.SkipLocalitiesCheck
 	}
 
-	if o.DebugPauseOn == nil {
-		o.DebugPauseOn = other.DebugPauseOn
-	} else if other.DebugPauseOn != nil {
-		return errors.New("debug_pause_on specified multiple times")
-	}
-
 	if o.NewDBName == nil {
 		o.NewDBName = other.NewDBName
 	} else if other.NewDBName != nil {
@@ -665,14 +621,6 @@ func (o *RestoreOptions) CombineWith(other *RestoreOptions) error {
 		o.VerifyData = other.VerifyData
 	}
 
-	if o.IncludeAllSecondaryTenants != nil {
-		if other.IncludeAllSecondaryTenants != nil {
-			return errors.New("include_all_virtual_clusters specified multiple times")
-		}
-	} else {
-		o.IncludeAllSecondaryTenants = other.IncludeAllSecondaryTenants
-	}
-
 	if o.UnsafeRestoreIncompatibleVersion {
 		if other.UnsafeRestoreIncompatibleVersion {
 			return errors.New("unsafe_restore_incompatible_version specified multiple times")
@@ -695,6 +643,14 @@ func (o *RestoreOptions) CombineWith(other *RestoreOptions) error {
 		o.ExperimentalOnline = other.ExperimentalOnline
 	}
 
+	if o.ExperimentalCopy {
+		if other.ExperimentalCopy {
+			return errors.New("experimental copy specified multiple times")
+		}
+	} else {
+		o.ExperimentalCopy = other.ExperimentalCopy
+	}
+
 	if o.RemoveRegions {
 		if other.RemoveRegions {
 			return errors.New("remove_regions specified multiple times")
@@ -719,17 +675,16 @@ func (o RestoreOptions) IsDefault() bool {
 		o.IntoDB == options.IntoDB &&
 		o.Detached == options.Detached &&
 		o.SkipLocalitiesCheck == options.SkipLocalitiesCheck &&
-		o.DebugPauseOn == options.DebugPauseOn &&
 		o.NewDBName == options.NewDBName &&
 		cmp.Equal(o.IncrementalStorage, options.IncrementalStorage) &&
 		o.AsTenant == options.AsTenant &&
 		o.ForceTenantID == options.ForceTenantID &&
 		o.SchemaOnly == options.SchemaOnly &&
 		o.VerifyData == options.VerifyData &&
-		o.IncludeAllSecondaryTenants == options.IncludeAllSecondaryTenants &&
 		o.UnsafeRestoreIncompatibleVersion == options.UnsafeRestoreIncompatibleVersion &&
 		o.ExecutionLocality == options.ExecutionLocality &&
 		o.ExperimentalOnline == options.ExperimentalOnline &&
+		o.ExperimentalCopy == options.ExperimentalCopy &&
 		o.RemoveRegions == options.RemoveRegions
 }
 
diff --git a/pkg/sql/sem/tree/batch.go b/pkg/sql/sem/tree/batch.go
index 3bd53b0..88316a9 100644
--- a/pkg/sql/sem/tree/batch.go
+++ b/pkg/sql/sem/tree/batch.go
@@ -1,12 +1,7 @@
 // Copyright 2023 The Cockroach Authors.
 //
-// Use of this software is governed by the Business Source License
-// included in the file licenses/BSL.txt.
-//
-// As of the Change Date specified in that file, in accordance with
-// the Business Source License, use of this software will be governed
-// by the Apache License, Version 2.0, included in the file
-// licenses/APL.txt.
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
 
 package tree
 
diff --git a/pkg/sql/sem/tree/call.go b/pkg/sql/sem/tree/call.go
index dadd65d..1f14a8c 100644
--- a/pkg/sql/sem/tree/call.go
+++ b/pkg/sql/sem/tree/call.go
@@ -1,12 +1,7 @@
 // Copyright 2023 The Cockroach Authors.
 //
-// Use of this software is governed by the Business Source License
-// included in the file licenses/BSL.txt.
-//
-// As of the Change Date specified in that file, in accordance with
-// the Business Source License, use of this software will be governed
-// by the Apache License, Version 2.0, included in the file
-// licenses/APL.txt.
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
 
 package tree
 
diff --git a/pkg/sql/sem/tree/changefeed.go b/pkg/sql/sem/tree/changefeed.go
index c1fb451..c002d21 100644
--- a/pkg/sql/sem/tree/changefeed.go
+++ b/pkg/sql/sem/tree/changefeed.go
@@ -1,12 +1,7 @@
 // Copyright 2018 The Cockroach Authors.
 //
-// Use of this software is governed by the Business Source License
-// included in the file licenses/BSL.txt.
-//
-// As of the Change Date specified in that file, in accordance with
-// the Business Source License, use of this software will be governed
-// by the Apache License, Version 2.0, included in the file
-// licenses/APL.txt.
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
 
 package tree
 
@@ -44,7 +39,7 @@ func (node *CreateChangefeed) Format(ctx *FmtCtx) {
 	ctx.FormatNode(&node.Targets)
 	if node.SinkURI != nil {
 		ctx.WriteString(" INTO ")
-		ctx.FormatNode(node.SinkURI)
+		ctx.FormatURI(node.SinkURI)
 	}
 	if node.Options != nil {
 		ctx.WriteString(" WITH OPTIONS (")
diff --git a/pkg/sql/sem/tree/check.go b/pkg/sql/sem/tree/check.go
new file mode 100644
index 0000000..36e28b0
--- /dev/null
+++ b/pkg/sql/sem/tree/check.go
@@ -0,0 +1,81 @@
+// Copyright 2025 The Cockroach Authors.
+//
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
+
+package tree
+
+type CheckExternalConnection struct {
+	URI     Expr
+	Options CheckExternalConnectionOptions
+}
+
+func (c *CheckExternalConnection) Format(ctx *FmtCtx) {
+	ctx.WriteString("CHECK EXTERNAL CONNECTION ")
+	ctx.FormatURI(c.URI)
+	if !c.Options.IsDefault() {
+		ctx.WriteString(" WITH OPTIONS (")
+		ctx.FormatNode(&c.Options)
+		ctx.WriteString(")")
+	}
+}
+
+var _ Statement = &CheckExternalConnection{}
+
+type CheckExternalConnectionOptions struct {
+	TransferSize Expr
+	Duration     Expr
+	Concurrency  Expr
+}
+
+var _ NodeFormatter = &CheckExternalConnectionOptions{}
+
+func (c *CheckExternalConnectionOptions) Format(ctx *FmtCtx) {
+	var addSep bool
+	maybeAddSep := func() {
+		if addSep {
+			ctx.WriteString(", ")
+		}
+		addSep = true
+	}
+	if c.Concurrency != nil {
+		maybeAddSep()
+		ctx.WriteString("CONCURRENTLY = ")
+		ctx.FormatNode(c.Concurrency)
+	}
+	if c.TransferSize != nil {
+		maybeAddSep()
+		ctx.WriteString("TRANSFER = ")
+		ctx.FormatNode(c.TransferSize)
+	}
+	if c.Duration != nil {
+		maybeAddSep()
+		ctx.WriteString("TIME = ")
+		ctx.FormatNode(c.Duration)
+	}
+}
+
+func (c *CheckExternalConnectionOptions) CombineWith(other *CheckExternalConnectionOptions) error {
+	var err error
+	c.TransferSize, err = combineExpr(c.TransferSize, other.TransferSize, "transfer")
+	if err != nil {
+		return err
+	}
+	c.Concurrency, err = combineExpr(c.Concurrency, other.Concurrency, "concurrently")
+	if err != nil {
+		return err
+	}
+	c.Duration, err = combineExpr(c.Duration, other.Duration, "time")
+	if err != nil {
+		return err
+	}
+	return nil
+}
+
+// IsDefault returns true if this options object is empty.
+func (c *CheckExternalConnectionOptions) IsDefault() bool {
+	options := CheckExternalConnectionOptions{}
+	return c.Duration == options.Duration &&
+		c.TransferSize == options.TransferSize &&
+		c.Concurrency == options.Concurrency
+}
diff --git a/pkg/sql/sem/tree/col_name.go b/pkg/sql/sem/tree/col_name.go
index aaf9292..aa3c4f8 100644
--- a/pkg/sql/sem/tree/col_name.go
+++ b/pkg/sql/sem/tree/col_name.go
@@ -1,12 +1,7 @@
 // Copyright 2018 The Cockroach Authors.
 //
-// Use of this software is governed by the Business Source License
-// included in the file licenses/BSL.txt.
-//
-// As of the Change Date specified in that file, in accordance with
-// the Business Source License, use of this software will be governed
-// by the Apache License, Version 2.0, included in the file
-// licenses/APL.txt.
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
 
 package tree
 
diff --git a/pkg/sql/sem/tree/comment_on_column.go b/pkg/sql/sem/tree/comment_on_column.go
index 3c723f6..a830dcd 100644
--- a/pkg/sql/sem/tree/comment_on_column.go
+++ b/pkg/sql/sem/tree/comment_on_column.go
@@ -1,12 +1,7 @@
 // Copyright 2018 The Cockroach Authors.
 //
-// Use of this software is governed by the Business Source License
-// included in the file licenses/BSL.txt.
-//
-// As of the Change Date specified in that file, in accordance with
-// the Business Source License, use of this software will be governed
-// by the Apache License, Version 2.0, included in the file
-// licenses/APL.txt.
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
 
 package tree
 
diff --git a/pkg/sql/sem/tree/comment_on_constraint.go b/pkg/sql/sem/tree/comment_on_constraint.go
index a5acf5b..7e198a0 100644
--- a/pkg/sql/sem/tree/comment_on_constraint.go
+++ b/pkg/sql/sem/tree/comment_on_constraint.go
@@ -1,12 +1,7 @@
 // Copyright 2018 The Cockroach Authors.
 //
-// Use of this software is governed by the Business Source License
-// included in the file licenses/BSL.txt.
-//
-// As of the Change Date specified in that file, in accordance with
-// the Business Source License, use of this software will be governed
-// by the Apache License, Version 2.0, included in the file
-// licenses/APL.txt.
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
 
 package tree
 
diff --git a/pkg/sql/sem/tree/comment_on_database.go b/pkg/sql/sem/tree/comment_on_database.go
index ed5182f..852fe6e 100644
--- a/pkg/sql/sem/tree/comment_on_database.go
+++ b/pkg/sql/sem/tree/comment_on_database.go
@@ -1,12 +1,7 @@
 // Copyright 2018 The Cockroach Authors.
 //
-// Use of this software is governed by the Business Source License
-// included in the file licenses/BSL.txt.
-//
-// As of the Change Date specified in that file, in accordance with
-// the Business Source License, use of this software will be governed
-// by the Apache License, Version 2.0, included in the file
-// licenses/APL.txt.
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
 
 package tree
 
diff --git a/pkg/sql/sem/tree/comment_on_index.go b/pkg/sql/sem/tree/comment_on_index.go
index b55c20d..d5486ff 100644
--- a/pkg/sql/sem/tree/comment_on_index.go
+++ b/pkg/sql/sem/tree/comment_on_index.go
@@ -1,12 +1,7 @@
 // Copyright 2019 The Cockroach Authors.
 //
-// Use of this software is governed by the Business Source License
-// included in the file licenses/BSL.txt.
-//
-// As of the Change Date specified in that file, in accordance with
-// the Business Source License, use of this software will be governed
-// by the Apache License, Version 2.0, included in the file
-// licenses/APL.txt.
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
 
 package tree
 
diff --git a/pkg/sql/sem/tree/comment_on_schema.go b/pkg/sql/sem/tree/comment_on_schema.go
index 5d1e932..dc2b492 100644
--- a/pkg/sql/sem/tree/comment_on_schema.go
+++ b/pkg/sql/sem/tree/comment_on_schema.go
@@ -1,12 +1,7 @@
 // Copyright 2021 The Cockroach Authors.
 //
-// Use of this software is governed by the Business Source License
-// included in the file licenses/BSL.txt.
-//
-// As of the Change Date specified in that file, in accordance with
-// the Business Source License, use of this software will be governed
-// by the Apache License, Version 2.0, included in the file
-// licenses/APL.txt.
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
 
 package tree
 
diff --git a/pkg/sql/sem/tree/comment_on_table.go b/pkg/sql/sem/tree/comment_on_table.go
index 7c2b393..755304e 100644
--- a/pkg/sql/sem/tree/comment_on_table.go
+++ b/pkg/sql/sem/tree/comment_on_table.go
@@ -1,12 +1,7 @@
 // Copyright 2018 The Cockroach Authors.
 //
-// Use of this software is governed by the Business Source License
-// included in the file licenses/BSL.txt.
-//
-// As of the Change Date specified in that file, in accordance with
-// the Business Source License, use of this software will be governed
-// by the Apache License, Version 2.0, included in the file
-// licenses/APL.txt.
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
 
 package tree
 
diff --git a/pkg/sql/sem/tree/comment_on_type.go b/pkg/sql/sem/tree/comment_on_type.go
new file mode 100644
index 0000000..6e68af1
--- /dev/null
+++ b/pkg/sql/sem/tree/comment_on_type.go
@@ -0,0 +1,32 @@
+// Copyright 2024 The Cockroach Authors.
+//
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
+
+package tree
+
+import "github.com/cockroachdb/cockroachdb-parser/pkg/sql/lexbase"
+
+// CommentOnType represents a COMMENT ON TYPE statement.
+type CommentOnType struct {
+	Name    *UnresolvedObjectName
+	Comment *string
+}
+
+// Format implements the NodeFormatter interface.
+func (n *CommentOnType) Format(ctx *FmtCtx) {
+	ctx.WriteString("COMMENT ON TYPE ")
+	ctx.FormatNode(n.Name)
+	ctx.WriteString(" IS ")
+	if n.Comment != nil {
+		// TODO(knz): Replace all this with ctx.FormatNode
+		// when COMMENT supports expressions.
+		if ctx.flags.HasFlags(FmtHideConstants) {
+			ctx.WriteString("'_'")
+		} else {
+			lexbase.EncodeSQLStringWithFlags(&ctx.Buffer, *n.Comment, ctx.flags.EncodeFlags())
+		}
+	} else {
+		ctx.WriteString("NULL")
+	}
+}
diff --git a/pkg/sql/sem/tree/compare.go b/pkg/sql/sem/tree/compare.go
index 78c4b3d..15cf0b7 100644
--- a/pkg/sql/sem/tree/compare.go
+++ b/pkg/sql/sem/tree/compare.go
@@ -1,12 +1,7 @@
 // Copyright 2022 The Cockroach Authors.
 //
-// Use of this software is governed by the Business Source License
-// included in the file licenses/BSL.txt.
-//
-// As of the Change Date specified in that file, in accordance with
-// the Business Source License, use of this software will be governed
-// by the Apache License, Version 2.0, included in the file
-// licenses/APL.txt.
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
 
 package tree
 
diff --git a/pkg/sql/sem/tree/constant.go b/pkg/sql/sem/tree/constant.go
index 2e1baaa..8a54190 100644
--- a/pkg/sql/sem/tree/constant.go
+++ b/pkg/sql/sem/tree/constant.go
@@ -1,12 +1,7 @@
 // Copyright 2016 The Cockroach Authors.
 //
-// Use of this software is governed by the Business Source License
-// included in the file licenses/BSL.txt.
-//
-// As of the Change Date specified in that file, in accordance with
-// the Business Source License, use of this software will be governed
-// by the Apache License, Version 2.0, included in the file
-// licenses/APL.txt.
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
 
 package tree
 
@@ -412,8 +407,8 @@ func (expr *NumVal) ResolveAsType(
 		if err != nil {
 			return nil, err
 		}
-		dInt := MustBeDInt(d)
-		return IntToOid(dInt)
+		o, err := IntToOid(MustBeDInt(d))
+		return NewDOid(o), err
 	default:
 		return nil, errors.AssertionFailedf("could not resolve %T %v into a %s", expr, expr, typ.SQLStringForError())
 	}
@@ -461,9 +456,6 @@ func commonConstantType(vals []Expr, idxs intsets.Fast) (*types.T, bool) {
 
 // StrVal represents a constant string value.
 type StrVal struct {
-	// We could embed a constant.Value here (like NumVal) and use the stringVal implementation,
-	// but that would have extra overhead without much of a benefit. However, it would make
-	// constant folding (below) a little more straightforward.
 	s string
 
 	// scannedAsBytes is true iff the input syntax was using b'...' or
@@ -512,6 +504,8 @@ var (
 		// default type that raw strings get parsed into, without any casts or type
 		// assertions.
 		types.String,
+		types.BPChar,
+		types.AnyCollatedString,
 		types.Bytes,
 		types.Bool,
 		types.Int,
@@ -542,8 +536,11 @@ var (
 		types.UUIDArray,
 		types.INet,
 		types.Jsonb,
+		types.Jsonpath,
 		types.PGLSN,
 		types.PGLSNArray,
+		types.PGVector,
+		types.PGVectorArray,
 		types.RefCursor,
 		types.RefCursorArray,
 		types.TSQuery,
@@ -555,6 +552,7 @@ var (
 		types.VarBitArray,
 		types.AnyTuple,
 		types.AnyTupleArray,
+		// TODO(normanchenn): Reevaluate conversions for jsonpath array.
 	}
 	// StrValAvailBytes is the set of types convertible to byte array.
 	StrValAvailBytes = []*types.T{types.Bytes, types.Uuid, types.String, types.AnyEnum}
@@ -629,13 +627,26 @@ func (expr *StrVal) ResolveAsType(
 
 	// Typing a string literal constant into some value type.
 	switch typ.Family() {
+	// If we don't care about output type, just pick the low effort conversion.
+	case types.AnyFamily:
+		fallthrough
 	case types.StringFamily:
-		if typ.Oid() == oid.T_name {
+		switch typ.Oid() {
+		case oid.T_name:
 			expr.resString = DString(expr.s)
 			return NewDNameFromDString(&expr.resString), nil
+		case oid.T_bpchar:
+			// TODO(mgartner): This should probably use the same logic in
+			// tree.AdjustValueToType and/or
+			// eval.performCastWithoutPrecisionTruncation. casts use (see the
+			// cast package). We might be able to replace this entire function
+			// with logic in those functions.
+			expr.resString = DString(strings.TrimRight(expr.s, " "))
+			return &expr.resString, nil
+		default:
+			expr.resString = DString(expr.s)
+			return &expr.resString, nil
 		}
-		expr.resString = DString(expr.s)
-		return &expr.resString, nil
 
 	case types.BytesFamily:
 		return ParseDByte(expr.s)
diff --git a/pkg/sql/sem/tree/constant_eval.go b/pkg/sql/sem/tree/constant_eval.go
index 47e012a..5386a2a 100644
--- a/pkg/sql/sem/tree/constant_eval.go
+++ b/pkg/sql/sem/tree/constant_eval.go
@@ -1,12 +1,7 @@
 // Copyright 2018 The Cockroach Authors.
 //
-// Use of this software is governed by the Business Source License
-// included in the file licenses/BSL.txt.
-//
-// As of the Change Date specified in that file, in accordance with
-// the Business Source License, use of this software will be governed
-// by the Apache License, Version 2.0, included in the file
-// licenses/APL.txt.
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
 
 package tree
 
diff --git a/pkg/sql/sem/tree/constants.go b/pkg/sql/sem/tree/constants.go
index 3b90bef..da4b70c 100644
--- a/pkg/sql/sem/tree/constants.go
+++ b/pkg/sql/sem/tree/constants.go
@@ -1,12 +1,7 @@
 // Copyright 2020 The Cockroach Authors.
 //
-// Use of this software is governed by the Business Source License
-// included in the file licenses/BSL.txt.
-//
-// As of the Change Date specified in that file, in accordance with
-// the Business Source License, use of this software will be governed
-// by the Apache License, Version 2.0, included in the file
-// licenses/APL.txt.
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
 
 package tree
 
diff --git a/pkg/sql/sem/tree/constraint.go b/pkg/sql/sem/tree/constraint.go
index 3fdc775..ec3b31f 100644
--- a/pkg/sql/sem/tree/constraint.go
+++ b/pkg/sql/sem/tree/constraint.go
@@ -1,12 +1,7 @@
 // Copyright 2022 The Cockroach Authors.
 //
-// Use of this software is governed by the Business Source License
-// included in the file licenses/BSL.txt.
-//
-// As of the Change Date specified in that file, in accordance with
-// the Business Source License, use of this software will be governed
-// by the Apache License, Version 2.0, included in the file
-// licenses/APL.txt.
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
 
 package tree
 
@@ -48,6 +43,22 @@ func (node *ReferenceActions) Format(ctx *FmtCtx) {
 	}
 }
 
+// HasUpdateAction returns true if any update action is set.
+func (node *ReferenceActions) HasUpdateAction() bool {
+	// NoAction and Restrict are currently equivalent.
+	return node.Update != NoAction && node.Update != Restrict
+}
+
+// HasDisallowedActionForComputedFKCol return true if an action is set that
+// isn't compatible with an FK over computed columns.
+func (node *ReferenceActions) HasDisallowedActionForComputedFKCol() bool {
+	// We disallow any actions that modify column values. NoAction and Restrict
+	// are equivalent and always allowed. 'ON DELETE CASCADE' is also allowed
+	// since it removes the entire row instead of modifying the computed column.
+	return node.HasUpdateAction() ||
+		(node.Delete != NoAction && node.Delete != Restrict && node.Delete != Cascade)
+}
+
 // ForeignKeyReferenceActionType allows the conversion between a
 // tree.ReferenceAction and a ForeignKeyReference_Action.
 var ForeignKeyReferenceActionType = [...]ReferenceAction{
diff --git a/pkg/sql/sem/tree/copy.go b/pkg/sql/sem/tree/copy.go
index c63474e..7b08605 100644
--- a/pkg/sql/sem/tree/copy.go
+++ b/pkg/sql/sem/tree/copy.go
@@ -1,12 +1,7 @@
 // Copyright 2016 The Cockroach Authors.
 //
-// Use of this software is governed by the Business Source License
-// included in the file licenses/BSL.txt.
-//
-// As of the Change Date specified in that file, in accordance with
-// the Business Source License, use of this software will be governed
-// by the Apache License, Version 2.0, included in the file
-// licenses/APL.txt.
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
 
 package tree
 
@@ -62,6 +57,7 @@ type CopyOptions struct {
 	Escape      *StrVal
 	Header      bool
 	Quote       *StrVal
+	Encoding    *StrVal
 
 	// Additional flags are needed to keep track of whether explicit default
 	// values were already set.
@@ -117,6 +113,12 @@ func (o *CopyOptions) Format(ctx *FmtCtx) {
 		ctx.FormatNode(o.Delimiter)
 		addSep = true
 	}
+	if o.Encoding != nil {
+		maybeAddSep()
+		ctx.WriteString("ENCODING ")
+		ctx.FormatNode(o.Encoding)
+		addSep = true
+	}
 	if o.Null != nil {
 		maybeAddSep()
 		ctx.WriteString("NULL ")
@@ -129,7 +131,7 @@ func (o *CopyOptions) Format(ctx *FmtCtx) {
 		// by copy_file_upload.go, so this will provide backward
 		// compatibility with older servers.
 		ctx.WriteString("DESTINATION ")
-		ctx.FormatNode(o.Destination)
+		ctx.FormatURI(o.Destination)
 		addSep = true
 	}
 	if o.Escape != nil {
@@ -181,6 +183,12 @@ func (o *CopyOptions) CombineWith(other *CopyOptions) error {
 		}
 		o.Delimiter = other.Delimiter
 	}
+	if other.Encoding != nil {
+		if o.Encoding != nil {
+			return pgerror.Newf(pgcode.Syntax, "encoding option specified multiple times")
+		}
+		o.Encoding = other.Encoding
+	}
 	if other.Null != nil {
 		if o.Null != nil {
 			return pgerror.Newf(pgcode.Syntax, "null option specified multiple times")
diff --git a/pkg/sql/sem/tree/create.go b/pkg/sql/sem/tree/create.go
index cc98b62..1d0f86f 100644
--- a/pkg/sql/sem/tree/create.go
+++ b/pkg/sql/sem/tree/create.go
@@ -7,13 +7,8 @@
 //
 // Copyright 2015 The Cockroach Authors.
 //
-// Use of this software is governed by the Business Source License
-// included in the file licenses/BSL.txt.
-//
-// As of the Change Date specified in that file, in accordance with
-// the Business Source License, use of this software will be governed
-// by the Apache License, Version 2.0, included in the file
-// licenses/APL.txt.
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
 
 // This code was derived from https://github.com/youtube/vitess.
 
@@ -28,6 +23,7 @@ import (
 	"github.com/cockroachdb/cockroachdb-parser/pkg/sql/lexbase"
 	"github.com/cockroachdb/cockroachdb-parser/pkg/sql/pgwire/pgcode"
 	"github.com/cockroachdb/cockroachdb-parser/pkg/sql/pgwire/pgerror"
+	"github.com/cockroachdb/cockroachdb-parser/pkg/sql/sem/idxtype"
 	"github.com/cockroachdb/cockroachdb-parser/pkg/sql/types"
 	"github.com/cockroachdb/cockroachdb-parser/pkg/util/collatedstring"
 	"github.com/cockroachdb/cockroachdb-parser/pkg/util/pretty"
@@ -238,7 +234,7 @@ type CreateIndex struct {
 	Name        Name
 	Table       TableName
 	Unique      bool
-	Inverted    bool
+	Type        idxtype.T
 	IfNotExists bool
 	Columns     IndexElemList
 	Sharded     *ShardedIndexDef
@@ -261,8 +257,11 @@ func (node *CreateIndex) Format(ctx *FmtCtx) {
 	if node.Unique {
 		ctx.WriteString("UNIQUE ")
 	}
-	if node.Inverted {
+	switch node.Type {
+	case idxtype.INVERTED:
 		ctx.WriteString("INVERTED ")
+	case idxtype.VECTOR:
+		ctx.WriteString("VECTOR ")
 	}
 	ctx.WriteString("INDEX ")
 	if node.Concurrently {
@@ -371,7 +370,7 @@ type CreateType struct {
 	Variety  CreateTypeVariety
 	// EnumLabels is set when this represents a CREATE TYPE ... AS ENUM statement.
 	EnumLabels EnumValueList
-	// CompositeTypeList is set when this repesnets a CREATE TYPE ... AS ( )
+	// CompositeTypeList is set when this represents a CREATE TYPE ... AS ( )
 	// statement.
 	CompositeTypeList []CompositeTypeElem
 	// IfNotExists is true if IF NOT EXISTS was requested.
@@ -1035,7 +1034,7 @@ type IndexTableDef struct {
 	Columns          IndexElemList
 	Sharded          *ShardedIndexDef
 	Storing          NameList
-	Inverted         bool
+	Type             idxtype.T
 	PartitionByIndex *PartitionByIndex
 	StorageParams    StorageParams
 	Predicate        Expr
@@ -1044,8 +1043,11 @@ type IndexTableDef struct {
 
 // Format implements the NodeFormatter interface.
 func (node *IndexTableDef) Format(ctx *FmtCtx) {
-	if node.Inverted {
+	switch node.Type {
+	case idxtype.INVERTED:
 		ctx.WriteString("INVERTED ")
+	case idxtype.VECTOR:
+		ctx.WriteString("VECTOR ")
 	}
 	ctx.WriteString("INDEX ")
 	if node.Name != "" {
@@ -1110,6 +1112,10 @@ type UniqueConstraintTableDef struct {
 	PrimaryKey   bool
 	WithoutIndex bool
 	IfNotExists  bool
+	// FormatAsIndex indicates if the constraint should be formatted as an index
+	// definition. This is needed since indexes support syntax for things like
+	// storage parameters and sharding, while constraints do not.
+	FormatAsIndex bool
 }
 
 // SetName implements the TableDef interface.
@@ -1124,7 +1130,7 @@ func (node *UniqueConstraintTableDef) SetIfNotExists() {
 
 // Format implements the NodeFormatter interface.
 func (node *UniqueConstraintTableDef) Format(ctx *FmtCtx) {
-	if node.Name != "" {
+	if node.Name != "" && !node.FormatAsIndex {
 		ctx.WriteString("CONSTRAINT ")
 		if node.IfNotExists {
 			ctx.WriteString("IF NOT EXISTS ")
@@ -1136,6 +1142,13 @@ func (node *UniqueConstraintTableDef) Format(ctx *FmtCtx) {
 		ctx.WriteString("PRIMARY KEY ")
 	} else {
 		ctx.WriteString("UNIQUE ")
+		if node.FormatAsIndex {
+			ctx.WriteString("INDEX ")
+			if node.Name != "" {
+				ctx.FormatNode(&node.Name)
+				ctx.WriteByte(' ')
+			}
+		}
 	}
 	if node.WithoutIndex {
 		ctx.WriteString("WITHOUT INDEX ")
@@ -1441,7 +1454,7 @@ func (node *RangePartition) Format(ctx *FmtCtx) {
 
 // StorageParam is a key-value parameter for table storage.
 type StorageParam struct {
-	Key   Name
+	Key   string
 	Value Expr
 }
 
@@ -1450,14 +1463,13 @@ type StorageParams []StorageParam
 
 // Format implements the NodeFormatter interface.
 func (o *StorageParams) Format(ctx *FmtCtx) {
+	buf, f := &ctx.Buffer, ctx.flags
 	for i := range *o {
 		n := &(*o)[i]
 		if i > 0 {
 			ctx.WriteString(", ")
 		}
-		// TODO(knz): the key may need to be formatted differently
-		// if we want to de-anonymize it.
-		ctx.FormatNode(&n.Key)
+		lexbase.EncodeSQLStringWithFlags(buf, n.Key, f.EncodeFlags())
 		if n.Value != nil {
 			ctx.WriteString(` = `)
 			ctx.FormatNode(n.Value)
@@ -1468,9 +1480,8 @@ func (o *StorageParams) Format(ctx *FmtCtx) {
 // GetVal returns corresponding value if a key exists, otherwise nil is
 // returned.
 func (o *StorageParams) GetVal(key string) Expr {
-	k := Name(key)
 	for _, param := range *o {
-		if param.Key == k {
+		if param.Key == key {
 			return param.Value
 		}
 	}
@@ -1701,7 +1712,7 @@ func (node *SequenceOptions) Format(ctx *FmtCtx) {
 			ctx.WriteString(option.AsIntegerType.SQLString())
 		case SeqOptCycle, SeqOptNoCycle:
 			ctx.WriteString(option.Name)
-		case SeqOptCache:
+		case SeqOptCache, SeqOptCacheNode:
 			ctx.WriteString(option.Name)
 			ctx.WriteByte(' ')
 			// TODO(knz): replace all this with ctx.FormatNode if/when
@@ -1803,6 +1814,7 @@ const (
 	SeqOptNoCycle   = "NO CYCLE"
 	SeqOptOwnedBy   = "OWNED BY"
 	SeqOptCache     = "CACHE"
+	SeqOptCacheNode = "PER NODE CACHE"
 	SeqOptIncrement = "INCREMENT"
 	SeqOptMinValue  = "MINVALUE"
 	SeqOptMaxValue  = "MAXVALUE"
@@ -1866,9 +1878,9 @@ const (
 // LikeTableOptAll is the full LikeTableOpt bitmap.
 const LikeTableOptAll = ^likeTableOptInvalid
 
-// Has returns true if the receiver has the other options bits set.
+// Has returns true if the receiver has all of the given option bits set.
 func (o LikeTableOpt) Has(other LikeTableOpt) bool {
-	return int(o)&int(other) != 0
+	return int(o)&int(other) == int(other)
 }
 
 func (o LikeTableOpt) String() string {
@@ -1997,6 +2009,7 @@ type RefreshMaterializedView struct {
 	Name              *UnresolvedObjectName
 	Concurrently      bool
 	RefreshDataOption RefreshDataOption
+	AsOf              AsOfClause
 }
 
 // RefreshDataOption corresponds to arguments for the REFRESH MATERIALIZED VIEW
@@ -2022,6 +2035,10 @@ func (node *RefreshMaterializedView) Format(ctx *FmtCtx) {
 		ctx.WriteString("CONCURRENTLY ")
 	}
 	ctx.FormatNode(node.Name)
+	if node.AsOf.Expr != nil {
+		ctx.WriteString(" ")
+		ctx.FormatNode(&node.AsOf)
+	}
 	switch node.RefreshDataOption {
 	case RefreshDataWithData:
 		ctx.WriteString(" WITH DATA")
@@ -2178,14 +2195,13 @@ func (node *CreateExternalConnection) Format(ctx *FmtCtx) {
 	ctx.WriteString("CREATE EXTERNAL CONNECTION")
 	ctx.FormatNode(&node.ConnectionLabelSpec)
 	ctx.WriteString(" AS ")
-	ctx.FormatNode(node.As)
+	ctx.FormatURI(node.As)
 }
 
 // CreateTenant represents a CREATE VIRTUAL CLUSTER statement.
 type CreateTenant struct {
 	IfNotExists bool
 	TenantSpec  *TenantSpec
-	Like        *LikeTenantSpec
 }
 
 // Format implements the NodeFormatter interface.
@@ -2195,20 +2211,6 @@ func (node *CreateTenant) Format(ctx *FmtCtx) {
 		ctx.WriteString("IF NOT EXISTS ")
 	}
 	ctx.FormatNode(node.TenantSpec)
-	ctx.FormatNode(node.Like)
-}
-
-// LikeTenantSpec represents a LIKE clause in CREATE VIRTUAL CLUSTER.
-type LikeTenantSpec struct {
-	OtherTenant *TenantSpec
-}
-
-func (node *LikeTenantSpec) Format(ctx *FmtCtx) {
-	if node.OtherTenant == nil {
-		return
-	}
-	ctx.WriteString(" LIKE ")
-	ctx.FormatNode(node.OtherTenant)
 }
 
 // CreateTenantFromReplication represents a CREATE VIRTUAL CLUSTER...FROM REPLICATION
@@ -2224,19 +2226,18 @@ type CreateTenantFromReplication struct {
 	// to use the TenantSpec type. This supports the auto-promotion
 	// of simple identifiers to strings.
 	ReplicationSourceTenantName *TenantSpec
-	// ReplicationSourceAddress is the address of the source cluster that we are
+	// ReplicationSourceConnUri is the address of the source cluster that we are
 	// replicating data from.
-	ReplicationSourceAddress Expr
+	ReplicationSourceConnUri Expr
 
 	Options TenantReplicationOptions
-
-	Like *LikeTenantSpec
 }
 
-// TenantReplicationOptions  options for the CREATE VIRTUAL CLUSTER FROM REPLICATION command.
+// TenantReplicationOptions  options for the CREATE/ALTER VIRTUAL CLUSTER FROM REPLICATION command.
 type TenantReplicationOptions struct {
-	Retention       Expr
-	ResumeTimestamp Expr
+	Retention          Expr
+	ExpirationWindow   Expr
+	EnableReaderTenant *DBool
 }
 
 var _ NodeFormatter = &TenantReplicationOptions{}
@@ -2250,17 +2251,16 @@ func (node *CreateTenantFromReplication) Format(ctx *FmtCtx) {
 	// NB: we do not anonymize the tenant name because we assume that tenant names
 	// do not contain sensitive information.
 	ctx.FormatNode(node.TenantSpec)
-	ctx.FormatNode(node.Like)
 
-	if node.ReplicationSourceAddress != nil {
+	if node.ReplicationSourceConnUri != nil {
 		ctx.WriteString(" FROM REPLICATION OF ")
 		ctx.FormatNode(node.ReplicationSourceTenantName)
 		ctx.WriteString(" ON ")
-		_, canOmitParentheses := node.ReplicationSourceAddress.(alreadyDelimitedAsSyntacticDExpr)
+		_, canOmitParentheses := node.ReplicationSourceConnUri.(alreadyDelimitedAsSyntacticDExpr)
 		if !canOmitParentheses {
 			ctx.WriteByte('(')
 		}
-		ctx.FormatNode(node.ReplicationSourceAddress)
+		ctx.FormatNode(node.ReplicationSourceConnUri)
 		if !canOmitParentheses {
 			ctx.WriteByte(')')
 		}
@@ -2293,18 +2293,22 @@ func (o *TenantReplicationOptions) Format(ctx *FmtCtx) {
 			ctx.WriteByte(')')
 		}
 	}
-	if o.ResumeTimestamp != nil {
+	if o.ExpirationWindow != nil {
 		maybeAddSep()
-		ctx.WriteString("RESUME TIMESTAMP = ")
-		_, canOmitParentheses := o.ResumeTimestamp.(alreadyDelimitedAsSyntacticDExpr)
+		ctx.WriteString("EXPIRATION WINDOW = ")
+		_, canOmitParentheses := o.ExpirationWindow.(alreadyDelimitedAsSyntacticDExpr)
 		if !canOmitParentheses {
 			ctx.WriteByte('(')
 		}
-		ctx.FormatNode(o.ResumeTimestamp)
+		ctx.FormatNode(o.ExpirationWindow)
 		if !canOmitParentheses {
 			ctx.WriteByte(')')
 		}
 	}
+	if o.EnableReaderTenant != nil {
+		maybeAddSep()
+		ctx.WriteString("READ VIRTUAL CLUSTER")
+	}
 }
 
 // CombineWith merges other TenantReplicationOptions into this struct.
@@ -2318,12 +2322,20 @@ func (o *TenantReplicationOptions) CombineWith(other *TenantReplicationOptions)
 		o.Retention = other.Retention
 	}
 
-	if o.ResumeTimestamp != nil {
-		if other.ResumeTimestamp != nil {
-			return errors.New("RESUME TIMESTAMP option specified multiple times")
+	if o.ExpirationWindow != nil {
+		if other.ExpirationWindow != nil {
+			return errors.New("EXPIRATION WINDOW option specified multiple times")
 		}
 	} else {
-		o.ResumeTimestamp = other.ResumeTimestamp
+		o.ExpirationWindow = other.ExpirationWindow
+	}
+
+	if o.EnableReaderTenant != nil {
+		if other.EnableReaderTenant != nil {
+			return errors.New("READ VIRTUAL CLUSTER option specified multiple times")
+		} else {
+			o.EnableReaderTenant = other.EnableReaderTenant
+		}
 	}
 
 	return nil
@@ -2333,7 +2345,13 @@ func (o *TenantReplicationOptions) CombineWith(other *TenantReplicationOptions)
 func (o TenantReplicationOptions) IsDefault() bool {
 	options := TenantReplicationOptions{}
 	return o.Retention == options.Retention &&
-		o.ResumeTimestamp == options.ResumeTimestamp
+		o.ExpirationWindow == options.ExpirationWindow &&
+		o.EnableReaderTenant == options.EnableReaderTenant
+}
+
+func (o TenantReplicationOptions) ExpirationWindowSet() bool {
+	options := TenantReplicationOptions{}
+	return o.ExpirationWindow != options.ExpirationWindow
 }
 
 type SuperRegion struct {
diff --git a/pkg/sql/sem/tree/create_logical_replication.go b/pkg/sql/sem/tree/create_logical_replication.go
new file mode 100644
index 0000000..0950bf0
--- /dev/null
+++ b/pkg/sql/sem/tree/create_logical_replication.go
@@ -0,0 +1,270 @@
+// Copyright 2024 The Cockroach Authors.
+//
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
+
+package tree
+
+import (
+	"sort"
+
+	"github.com/cockroachdb/errors"
+)
+
+type CreateLogicalReplicationStream struct {
+	PGURL       Expr
+	From        LogicalReplicationResources
+	Into        LogicalReplicationResources
+	CreateTable bool
+	Options     LogicalReplicationOptions
+}
+
+type LogicalReplicationResources struct {
+	Tables   []*UnresolvedName
+	Database Name
+}
+
+type LogicalReplicationOptions struct {
+	// Mapping of table name to UDF name
+	UserFunctions    map[UnresolvedName]RoutineName
+	Cursor           Expr
+	MetricsLabel     Expr
+	Mode             Expr
+	DefaultFunction  Expr
+	Discard          Expr
+	SkipSchemaCheck  *DBool
+	Unidirectional   *DBool
+	BidirectionalURI Expr
+	ParentID         Expr
+}
+
+var _ Statement = &CreateLogicalReplicationStream{}
+var _ NodeFormatter = &LogicalReplicationOptions{}
+
+// Format implements the NodeFormatter interface.
+func (node *CreateLogicalReplicationStream) Format(ctx *FmtCtx) {
+	if node.CreateTable {
+		ctx.WriteString("CREATE LOGICALLY REPLICATED ")
+		ctx.FormatNode(&node.Into)
+		ctx.WriteString(" FROM ")
+		ctx.FormatNode(&node.From)
+		ctx.WriteString(" ON ")
+		ctx.FormatNode(node.PGURL)
+	} else {
+		ctx.WriteString("CREATE LOGICAL REPLICATION STREAM FROM ")
+		ctx.FormatNode(&node.From)
+		ctx.WriteString(" ON ")
+		ctx.FormatNode(node.PGURL)
+		ctx.WriteString(" INTO ")
+		ctx.FormatNode(&node.Into)
+	}
+
+	if !node.Options.IsDefault() {
+		ctx.WriteString(" WITH OPTIONS (")
+		ctx.FormatNode(&node.Options)
+		ctx.WriteString(")")
+	}
+}
+
+func (lrr *LogicalReplicationResources) Format(ctx *FmtCtx) {
+	if lrr.Database != "" {
+		ctx.WriteString("DATABASE ")
+		lrr.Database.Format(ctx)
+	} else if len(lrr.Tables) > 1 {
+		ctx.WriteString("TABLES (")
+		for i := range lrr.Tables {
+			if i > 0 {
+				ctx.WriteString(", ")
+			}
+			ctx.FormatNode(lrr.Tables[i])
+		}
+		ctx.WriteString(")")
+	} else {
+		ctx.WriteString("TABLE ")
+		ctx.FormatNode(lrr.Tables[0])
+	}
+}
+
+func (lro *LogicalReplicationOptions) Format(ctx *FmtCtx) {
+	var addSep bool
+	maybeAddSep := func() {
+		if addSep {
+			ctx.WriteString(", ")
+		}
+		addSep = true
+	}
+
+	if lro.Cursor != nil {
+		maybeAddSep()
+		ctx.WriteString("CURSOR = ")
+		ctx.FormatNode(lro.Cursor)
+	}
+
+	if lro.DefaultFunction != nil {
+		maybeAddSep()
+		ctx.WriteString("DEFAULT FUNCTION = ")
+		ctx.FormatNode(lro.DefaultFunction)
+	}
+
+	if lro.Mode != nil {
+		maybeAddSep()
+		ctx.WriteString("MODE = ")
+		ctx.FormatNode(lro.Mode)
+	}
+
+	if lro.UserFunctions != nil {
+		maybeAddSep()
+		addSep = false
+
+		// In order to make tests deterministic, the ordering of map keys
+		// needs to be the same each time.
+		keys := make([]UnresolvedName, 0, len(lro.UserFunctions))
+		for k := range lro.UserFunctions {
+			keys = append(keys, k)
+		}
+		sort.Slice(keys, func(i, j int) bool {
+			return keys[i].String() < keys[j].String()
+		})
+
+		for _, k := range keys {
+			maybeAddSep()
+			ctx.WriteString("FUNCTION ")
+			r := lro.UserFunctions[k]
+			ctx.FormatNode(&r)
+			ctx.WriteString(" FOR TABLE ")
+			ctx.FormatNode(&k)
+		}
+	}
+	if lro.Discard != nil {
+		maybeAddSep()
+		ctx.WriteString("DISCARD = ")
+		ctx.FormatNode(lro.Discard)
+	}
+
+	if lro.SkipSchemaCheck != nil && *lro.SkipSchemaCheck {
+		maybeAddSep()
+		ctx.WriteString("SKIP SCHEMA CHECK")
+	}
+
+	if lro.MetricsLabel != nil {
+		maybeAddSep()
+		ctx.WriteString("LABEL = ")
+		ctx.FormatNode(lro.MetricsLabel)
+	}
+
+	if lro.Unidirectional != nil {
+		maybeAddSep()
+		ctx.WriteString("UNIDIRECTIONAL")
+	}
+	if lro.BidirectionalURI != nil {
+		maybeAddSep()
+		ctx.WriteString("BIDIRECTIONAL ON ")
+		ctx.FormatNode(lro.BidirectionalURI)
+	}
+	if lro.ParentID != nil {
+		maybeAddSep()
+		ctx.WriteString("PARENT = ")
+		ctx.FormatNode(lro.ParentID)
+	}
+
+}
+
+func (o *LogicalReplicationOptions) CombineWith(other *LogicalReplicationOptions) error {
+	if o.Cursor != nil {
+		if other.Cursor != nil {
+			return errors.New("CURSOR option specified multiple times")
+		}
+	} else {
+		o.Cursor = other.Cursor
+	}
+
+	if o.Mode != nil {
+		if other.Mode != nil {
+			return errors.New("MODE option specified multiple times")
+		}
+	} else {
+		o.Mode = other.Mode
+	}
+
+	if o.DefaultFunction != nil {
+		if other.DefaultFunction != nil {
+			return errors.New("DEFAULT FUNCTION option specified multiple times")
+		}
+	} else {
+		o.DefaultFunction = other.DefaultFunction
+	}
+
+	if other.UserFunctions != nil {
+		for tbl := range other.UserFunctions {
+			if _, ok := o.UserFunctions[tbl]; ok {
+				return errors.Newf("multiple user functions specified for table %s", tbl.String())
+			}
+			if o.UserFunctions == nil {
+				o.UserFunctions = make(map[UnresolvedName]RoutineName)
+			}
+			o.UserFunctions[tbl] = other.UserFunctions[tbl]
+		}
+	}
+
+	if o.Discard != nil {
+		if other.Discard != nil {
+			return errors.New("DISCARD option specified multiple times")
+		}
+	} else {
+		o.Discard = other.Discard
+	}
+	if o.SkipSchemaCheck != nil {
+		if other.SkipSchemaCheck != nil {
+			return errors.New("SKIP SCHEMA CHECK option specified multiple times")
+		}
+	} else {
+		o.SkipSchemaCheck = other.SkipSchemaCheck
+	}
+
+	if o.MetricsLabel != nil {
+		if other.MetricsLabel != nil {
+			return errors.New("LABEL option specified multiple times")
+		}
+	} else {
+		o.MetricsLabel = other.MetricsLabel
+	}
+
+	if o.Unidirectional != nil {
+		if other.Unidirectional != nil {
+			return errors.New("UNIDIRECTIONAL option specified multiple times")
+		}
+	} else {
+		o.Unidirectional = other.Unidirectional
+	}
+	if o.BidirectionalURI != nil {
+		if other.BidirectionalURI != nil {
+			return errors.New("BIDIRECTIONAL option specified multiple times")
+		}
+	} else {
+		o.BidirectionalURI = other.BidirectionalURI
+	}
+	if o.ParentID != nil {
+		if other.ParentID != nil {
+			return errors.New("PARENT option specified multiple times")
+		}
+	} else {
+		o.ParentID = other.ParentID
+	}
+
+	return nil
+}
+
+// IsDefault returns true if this logical options struct has default value.
+func (o LogicalReplicationOptions) IsDefault() bool {
+	options := LogicalReplicationOptions{}
+	return o.Cursor == options.Cursor &&
+		o.Mode == options.Mode &&
+		o.DefaultFunction == options.DefaultFunction &&
+		o.UserFunctions == nil &&
+		o.Discard == options.Discard &&
+		o.SkipSchemaCheck == options.SkipSchemaCheck &&
+		o.MetricsLabel == options.MetricsLabel &&
+		o.Unidirectional == options.Unidirectional &&
+		o.BidirectionalURI == options.BidirectionalURI &&
+		o.ParentID == options.ParentID
+}
diff --git a/pkg/sql/sem/tree/create_policy.go b/pkg/sql/sem/tree/create_policy.go
new file mode 100644
index 0000000..5f10972
--- /dev/null
+++ b/pkg/sql/sem/tree/create_policy.go
@@ -0,0 +1,113 @@
+// Copyright 2024 The Cockroach Authors.
+//
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
+
+package tree
+
+var _ Statement = &CreatePolicy{}
+
+// PolicyCommand represents the type of commands a row-level security policy
+// will apply against.
+type PolicyCommand int
+
+// PolicyCommand values
+const (
+	PolicyCommandDefault PolicyCommand = iota
+	PolicyCommandAll
+	PolicyCommandSelect
+	PolicyCommandInsert
+	PolicyCommandUpdate
+	PolicyCommandDelete
+)
+
+var policyCommandName = [...]string{
+	PolicyCommandDefault: "",
+	PolicyCommandAll:     "ALL",
+	PolicyCommandSelect:  "SELECT",
+	PolicyCommandInsert:  "INSERT",
+	PolicyCommandUpdate:  "UPDATE",
+	PolicyCommandDelete:  "DELETE",
+}
+
+func (p PolicyCommand) String() string { return policyCommandName[p] }
+
+// SafeValue implements the redact.SafeValue interface.
+func (p PolicyCommand) SafeValue() {}
+
+// PolicyType represents the type of the row-level security policy.
+type PolicyType int
+
+// PolicyType values
+const (
+	PolicyTypeDefault PolicyType = iota
+	PolicyTypePermissive
+	PolicyTypeRestrictive
+)
+
+var policyTypeName = [...]string{
+	PolicyTypeDefault:     "",
+	PolicyTypePermissive:  "PERMISSIVE",
+	PolicyTypeRestrictive: "RESTRICTIVE",
+}
+
+func (p PolicyType) String() string { return policyTypeName[p] }
+
+// SafeValue implements the redact.SafeValue interface.
+func (p PolicyType) SafeValue() {}
+
+type PolicyExpressions struct {
+	Using     Expr
+	WithCheck Expr
+}
+
+// Format implements the NodeFormatter interface
+func (node *PolicyExpressions) Format(ctx *FmtCtx) {
+	if node.Using != nil {
+		ctx.WriteString(" USING (")
+		ctx.FormatNode(node.Using)
+		ctx.WriteString(")")
+	}
+
+	if node.WithCheck != nil {
+		ctx.WriteString(" WITH CHECK (")
+		ctx.FormatNode(node.WithCheck)
+		ctx.WriteString(")")
+	}
+}
+
+// CreatePolicy is a tree struct for the CREATE POLICY DDL statement
+type CreatePolicy struct {
+	IfNotExists bool
+	PolicyName  Name
+	TableName   *UnresolvedObjectName
+	Type        PolicyType
+	Cmd         PolicyCommand
+	Roles       RoleSpecList
+	Exprs       PolicyExpressions
+}
+
+// Format implements the NodeFormatter interface.
+func (node *CreatePolicy) Format(ctx *FmtCtx) {
+	ctx.WriteString("CREATE POLICY ")
+	if node.IfNotExists {
+		ctx.WriteString("IF NOT EXISTS ")
+	}
+	ctx.FormatNode(&node.PolicyName)
+	ctx.WriteString(" ON ")
+	ctx.FormatNode(node.TableName)
+	if node.Type != PolicyTypeDefault {
+		ctx.WriteString(" AS ")
+		ctx.WriteString(node.Type.String())
+	}
+	if node.Cmd != PolicyCommandDefault {
+		ctx.WriteString(" FOR ")
+		ctx.WriteString(node.Cmd.String())
+	}
+
+	if len(node.Roles) > 0 {
+		ctx.WriteString(" TO ")
+		ctx.FormatNode(&node.Roles)
+	}
+	ctx.FormatNode(&node.Exprs)
+}
diff --git a/pkg/sql/sem/tree/create_routine.go b/pkg/sql/sem/tree/create_routine.go
index 6e7d757..ce35079 100644
--- a/pkg/sql/sem/tree/create_routine.go
+++ b/pkg/sql/sem/tree/create_routine.go
@@ -1,22 +1,15 @@
 // Copyright 2022 The Cockroach Authors.
 //
-// Use of this software is governed by the Business Source License
-// included in the file licenses/BSL.txt.
-//
-// As of the Change Date specified in that file, in accordance with
-// the Business Source License, use of this software will be governed
-// by the Apache License, Version 2.0, included in the file
-// licenses/APL.txt.
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
 
 package tree
 
 import (
-	"context"
 	"strings"
 
 	"github.com/cockroachdb/cockroachdb-parser/pkg/sql/pgwire/pgcode"
 	"github.com/cockroachdb/cockroachdb-parser/pkg/sql/pgwire/pgerror"
-	"github.com/cockroachdb/cockroachdb-parser/pkg/sql/types"
 	"github.com/cockroachdb/errors"
 )
 
@@ -85,7 +78,7 @@ type CreateRoutine struct {
 	Replace     bool
 	Name        RoutineName
 	Params      RoutineParams
-	ReturnType  RoutineReturnType
+	ReturnType  *RoutineReturnType
 	Options     RoutineOptions
 	RoutineBody *RoutineBody
 	// BodyStatements is not assigned during initial parsing of user input. It's
@@ -114,7 +107,7 @@ func (node *CreateRoutine) Format(ctx *FmtCtx) {
 	ctx.WriteByte('(')
 	ctx.FormatNode(node.Params)
 	ctx.WriteString(")\n\t")
-	if !node.IsProcedure {
+	if !node.IsProcedure && node.ReturnType != nil {
 		ctx.WriteString("RETURNS ")
 		if node.ReturnType.SetOf {
 			ctx.WriteString("SETOF ")
@@ -122,6 +115,7 @@ func (node *CreateRoutine) Format(ctx *FmtCtx) {
 		ctx.FormatTypeReference(node.ReturnType.Type)
 		ctx.WriteString("\n\t")
 	}
+	var isPLpgSQL bool
 	var funcBody RoutineBodyStr
 	for _, option := range node.Options {
 		switch t := option.(type) {
@@ -132,6 +126,8 @@ func (node *CreateRoutine) Format(ctx *FmtCtx) {
 			if node.IsProcedure {
 				continue
 			}
+		case RoutineLanguage:
+			isPLpgSQL = t == RoutineLangPLpgSQL
 		}
 		ctx.FormatNode(option)
 		ctx.WriteString("\n\t")
@@ -144,18 +140,24 @@ func (node *CreateRoutine) Format(ctx *FmtCtx) {
 			if i > 0 {
 				ctx.WriteByte(' ')
 			}
-			oldAnn := ctx.ann
-			ctx.ann = node.BodyAnnotations[i]
-			ctx.FormatNode(stmt)
-			ctx.WriteByte(';')
-			ctx.ann = oldAnn
+			ctx.WithAnnotations(node.BodyAnnotations[i], func() {
+				ctx.FormatNode(stmt)
+				if !isPLpgSQL {
+					// PL/pgSQL statements handle printing semicolons themselves.
+					ctx.WriteByte(';')
+				}
+			})
 		}
 		ctx.WriteString("$$")
 	} else if node.RoutineBody != nil {
 		ctx.WriteString("BEGIN ATOMIC ")
 		for _, stmt := range node.RoutineBody.Stmts {
 			ctx.FormatNode(stmt)
-			ctx.WriteString("; ")
+			if !isPLpgSQL {
+				// PL/pgSQL statements handle printing semicolons themselves.
+				ctx.WriteByte(';')
+			}
+			ctx.WriteByte(' ')
 		}
 		ctx.WriteString("END")
 	} else {
@@ -195,6 +197,7 @@ func (RoutineVolatility) routineOption()        {}
 func (RoutineLeakproof) routineOption()         {}
 func (RoutineBodyStr) routineOption()           {}
 func (RoutineLanguage) routineOption()          {}
+func (RoutineSecurity) routineOption()          {}
 
 // RoutineNullInputBehavior represent the UDF property on null parameters.
 type RoutineNullInputBehavior int
@@ -302,27 +305,40 @@ func AsRoutineLanguage(lang string) (RoutineLanguage, error) {
 	return RoutineLanguage(lang), nil
 }
 
+// RoutineSecurity indicates the mode of security that the routine will
+// be executed with.
+type RoutineSecurity int
+
+const (
+	// RoutineInvoker indicates that the routine is run with the privileges of
+	// the user invoking it. This is the default security mode if none is
+	// provided.
+	RoutineInvoker RoutineSecurity = iota
+	// RoutineDefiner indicates that the routine is run with the privileges of
+	// the user who defined it.
+	RoutineDefiner
+)
+
+// Format implements the NodeFormatter interface.
+func (node RoutineSecurity) Format(ctx *FmtCtx) {
+	ctx.WriteString("SECURITY ")
+	switch node {
+	case RoutineInvoker:
+		ctx.WriteString("INVOKER")
+	case RoutineDefiner:
+		ctx.WriteString("DEFINER")
+	default:
+		panic(pgerror.New(pgcode.InvalidParameterValue, "unknown routine option"))
+	}
+}
+
 // RoutineBodyStr is a string containing all statements in a UDF body.
 type RoutineBodyStr string
 
 // Format implements the NodeFormatter interface.
 func (node RoutineBodyStr) Format(ctx *FmtCtx) {
 	ctx.WriteString("AS ")
-	if ctx.flags.HasFlags(FmtTagDollarQuotes) {
-		ctx.WriteString("$funcbody$")
-	} else {
-		ctx.WriteString("$$")
-	}
-	if ctx.flags.HasFlags(FmtAnonymize) || ctx.flags.HasFlags(FmtHideConstants) {
-		ctx.WriteString("_")
-	} else {
-		ctx.WriteString(string(node))
-	}
-	if ctx.flags.HasFlags(FmtTagDollarQuotes) {
-		ctx.WriteString("$funcbody$")
-	} else {
-		ctx.WriteString("$$")
-	}
+	ctx.FormatStringDollarQuotes(string(node))
 }
 
 // RoutineParams represents a list of RoutineParam.
@@ -349,18 +365,18 @@ type RoutineParam struct {
 // Format implements the NodeFormatter interface.
 func (node *RoutineParam) Format(ctx *FmtCtx) {
 	switch node.Class {
+	case RoutineParamDefault:
 	case RoutineParamIn:
-		ctx.WriteString("IN")
+		ctx.WriteString("IN ")
 	case RoutineParamOut:
-		ctx.WriteString("OUT")
+		ctx.WriteString("OUT ")
 	case RoutineParamInOut:
-		ctx.WriteString("INOUT")
+		ctx.WriteString("INOUT ")
 	case RoutineParamVariadic:
-		ctx.WriteString("VARIADIC")
+		ctx.WriteString("VARIADIC ")
 	default:
 		panic(pgerror.New(pgcode.InvalidParameterValue, "unknown routine option"))
 	}
-	ctx.WriteString(" ")
 	if node.Name != "" {
 		ctx.FormatNode(&node.Name)
 		ctx.WriteString(" ")
@@ -376,8 +392,11 @@ func (node *RoutineParam) Format(ctx *FmtCtx) {
 type RoutineParamClass int
 
 const (
+	// RoutineParamDefault indicates that RoutineParamClass was unspecified
+	// (in almost all cases it is equivalent to RoutineParamIn).
+	RoutineParamDefault RoutineParamClass = iota
 	// RoutineParamIn args can only be used as input.
-	RoutineParamIn RoutineParamClass = iota
+	RoutineParamIn
 	// RoutineParamOut args can only be used as output.
 	RoutineParamOut
 	// RoutineParamInOut args can be used as both input and output.
@@ -386,6 +405,40 @@ const (
 	RoutineParamVariadic
 )
 
+// IsInParamClass returns true if the given parameter class specifies an input
+// parameter (i.e. either unspecified, IN or, INOUT).
+func IsInParamClass(class RoutineParamClass) bool {
+	switch class {
+	case RoutineParamDefault, RoutineParamIn, RoutineParamInOut:
+		return true
+	default:
+		return false
+	}
+}
+
+// IsOutParamClass returns true if the given parameter class specifies an output
+// parameter (i.e. either OUT or INOUT).
+func IsOutParamClass(class RoutineParamClass) bool {
+	switch class {
+	case RoutineParamOut, RoutineParamInOut:
+		return true
+	default:
+		return false
+	}
+}
+
+// IsInParam returns true if the parameter is an input parameter (i.e. either IN
+// or INOUT).
+func (node *RoutineParam) IsInParam() bool {
+	return IsInParamClass(node.Class)
+}
+
+// IsOutParam returns true if the parameter is an output parameter (i.e. either
+// OUT or INOUT).
+func (node *RoutineParam) IsOutParam() bool {
+	return IsOutParamClass(node.Class)
+}
+
 // RoutineReturnType represent the return type of UDF.
 type RoutineReturnType struct {
 	Type  ResolvableTypeReference
@@ -447,27 +500,6 @@ func (node *RoutineObj) Format(ctx *FmtCtx) {
 	}
 }
 
-// ParamTypes returns a slice of parameter types of the routine.
-func (node RoutineObj) ParamTypes(
-	ctx context.Context, res TypeReferenceResolver,
-) ([]*types.T, error) {
-	// TODO(chengxiong): handle INOUT, OUT and VARIADIC argument classes when we
-	// support them. This is because only IN and INOUT arg types need to be
-	// considered to match a overload.
-	var argTypes []*types.T
-	if node.Params != nil {
-		argTypes = make([]*types.T, len(node.Params))
-		for i, arg := range node.Params {
-			typ, err := ResolveType(ctx, arg.Type, res)
-			if err != nil {
-				return nil, err
-			}
-			argTypes[i] = typ
-		}
-	}
-	return argTypes, nil
-}
-
 // AlterFunctionOptions represents a ALTER FUNCTION...action statement.
 type AlterFunctionOptions struct {
 	Function RoutineObj
@@ -604,6 +636,8 @@ const (
 	TTLExpirationExpr               SchemaExprContext = "TTL EXPIRATION EXPRESSION"
 	TTLDefaultExpr                  SchemaExprContext = "TTL DEFAULT"
 	TTLUpdateExpr                   SchemaExprContext = "TTL UPDATE"
+	PolicyUsingExpr                 SchemaExprContext = "POLICY USING"
+	PolicyWithCheckExpr             SchemaExprContext = "POLICY WITH CHECK"
 )
 
 func ComputedColumnExprContext(isVirtual bool) SchemaExprContext {
@@ -615,8 +649,8 @@ func ComputedColumnExprContext(isVirtual bool) SchemaExprContext {
 
 // ValidateRoutineOptions checks whether there are conflicting or redundant
 // routine options in the given slice.
-func ValidateRoutineOptions(options RoutineOptions) error {
-	var hasLang, hasBody, hasLeakProof, hasVolatility, hasNullInputBehavior bool
+func ValidateRoutineOptions(options RoutineOptions, isProc bool) error {
+	var hasLang, hasBody, hasLeakProof, hasVolatility, hasNullInputBehavior, hasSecurity bool
 	conflictingErr := func(opt RoutineOption) error {
 		return errors.Wrapf(ErrConflictingRoutineOption, "%s", AsString(opt))
 	}
@@ -633,20 +667,34 @@ func ValidateRoutineOptions(options RoutineOptions) error {
 			}
 			hasBody = true
 		case RoutineLeakproof:
+			if isProc {
+				return pgerror.Newf(pgcode.InvalidFunctionDefinition, "leakproof attribute not allowed in procedure definition")
+			}
 			if hasLeakProof {
 				return conflictingErr(option)
 			}
 			hasLeakProof = true
 		case RoutineVolatility:
+			if isProc {
+				return pgerror.Newf(pgcode.InvalidFunctionDefinition, "volatility attribute not allowed in procedure definition")
+			}
 			if hasVolatility {
 				return conflictingErr(option)
 			}
 			hasVolatility = true
 		case RoutineNullInputBehavior:
+			if isProc {
+				return pgerror.Newf(pgcode.InvalidFunctionDefinition, "null input attribute not allowed in procedure definition")
+			}
 			if hasNullInputBehavior {
 				return conflictingErr(option)
 			}
 			hasNullInputBehavior = true
+		case RoutineSecurity:
+			if hasSecurity {
+				return conflictingErr(option)
+			}
+			hasSecurity = true
 		default:
 			return pgerror.Newf(pgcode.InvalidParameterValue, "unknown function option: ", AsString(option))
 		}
diff --git a/pkg/sql/sem/tree/create_trigger.go b/pkg/sql/sem/tree/create_trigger.go
new file mode 100644
index 0000000..47bcddc
--- /dev/null
+++ b/pkg/sql/sem/tree/create_trigger.go
@@ -0,0 +1,270 @@
+// Copyright 2024 The Cockroach Authors.
+//
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
+
+package tree
+
+import "github.com/cockroachdb/cockroachdb-parser/pkg/sql/sem/semenumpb"
+
+type CreateTrigger struct {
+	Replace     bool
+	Name        Name
+	ActionTime  TriggerActionTime
+	Events      []*TriggerEvent
+	TableName   *UnresolvedObjectName
+	Transitions []*TriggerTransition
+	ForEach     TriggerForEach
+	When        Expr
+	FuncName    *UnresolvedName
+	FuncArgs    []string
+
+	// FuncBody is the body of the trigger function with fully-qualified names.
+	// TODO(#128536): Pass this information through `memo.CreateTriggerExpr`
+	// instead.
+	FuncBody string
+}
+
+var _ Statement = &CreateTrigger{}
+
+// Format implements the NodeFormatter interface.
+func (node *CreateTrigger) Format(ctx *FmtCtx) {
+	if node.Replace {
+		ctx.WriteString("CREATE OR REPLACE TRIGGER ")
+	} else {
+		ctx.WriteString("CREATE TRIGGER ")
+	}
+	node.Name.Format(ctx)
+	ctx.WriteString(" ")
+	node.ActionTime.Format(ctx)
+	ctx.WriteString(" ")
+	for i := range node.Events {
+		if i > 0 {
+			ctx.WriteString(" OR ")
+		}
+		node.Events[i].Format(ctx)
+	}
+	ctx.WriteString(" ON ")
+	ctx.FormatNode(node.TableName)
+	if len(node.Transitions) > 0 {
+		ctx.WriteString(" REFERENCING ")
+		for i := range node.Transitions {
+			if i > 0 {
+				ctx.WriteString(" ")
+			}
+			node.Transitions[i].Format(ctx)
+		}
+	}
+	ctx.WriteString(" ")
+	node.ForEach.Format(ctx)
+	if node.When != nil {
+		ctx.WriteString(" WHEN ")
+		ctx.FormatNode(node.When)
+	}
+	ctx.WriteString(" EXECUTE FUNCTION ")
+	ctx.FormatNode(node.FuncName)
+	ctx.WriteString("(")
+	for i, arg := range node.FuncArgs {
+		if i > 0 {
+			ctx.WriteString(", ")
+		}
+		ctx.FormatStringConstant(arg)
+	}
+	ctx.WriteString(")")
+}
+
+type TriggerActionTime uint8
+
+const (
+	TriggerActionTimeUnknown TriggerActionTime = iota
+	TriggerActionTimeBefore
+	TriggerActionTimeAfter
+	TriggerActionTimeInsteadOf
+)
+
+// TriggerActionTimeFromTree allows the conversion from a
+// semenumpb.TriggerActionTime to a tree.TriggerActionTime.
+var TriggerActionTimeFromTree = [...]semenumpb.TriggerActionTime{
+	TriggerActionTimeUnknown:   semenumpb.TriggerActionTime_ACTION_UNKNOWN,
+	TriggerActionTimeBefore:    semenumpb.TriggerActionTime_BEFORE,
+	TriggerActionTimeAfter:     semenumpb.TriggerActionTime_AFTER,
+	TriggerActionTimeInsteadOf: semenumpb.TriggerActionTime_INSTEAD_OF,
+}
+
+// TriggerActionTimeToTree allows the conversion from a
+// tree.TriggerActionTime to a semenumpb.TriggerActionTime.
+var TriggerActionTimeToTree = [...]TriggerActionTime{
+	semenumpb.TriggerActionTime_ACTION_UNKNOWN: TriggerActionTimeUnknown,
+	semenumpb.TriggerActionTime_BEFORE:         TriggerActionTimeBefore,
+	semenumpb.TriggerActionTime_AFTER:          TriggerActionTimeAfter,
+	semenumpb.TriggerActionTime_INSTEAD_OF:     TriggerActionTimeInsteadOf,
+}
+
+// Format implements the NodeFormatter interface.
+func (node *TriggerActionTime) Format(ctx *FmtCtx) {
+	switch *node {
+	case TriggerActionTimeUnknown:
+		ctx.WriteString("UNKNOWN")
+	case TriggerActionTimeBefore:
+		ctx.WriteString("BEFORE")
+	case TriggerActionTimeAfter:
+		ctx.WriteString("AFTER")
+	case TriggerActionTimeInsteadOf:
+		ctx.WriteString("INSTEAD OF")
+	}
+}
+
+type TriggerEventType uint8
+
+const (
+	TriggerEventTypeUnknown TriggerEventType = iota
+	TriggerEventInsert
+	TriggerEventUpdate
+	TriggerEventDelete
+	TriggerEventTruncate
+	TriggerEventTypeMax = iota - 1
+)
+
+// TriggerEventTypeFromTree allows the conversion from a
+// tree.TriggerEventType to a semenumpb.TriggerEventType.
+var TriggerEventTypeFromTree = [...]semenumpb.TriggerEventType{
+	TriggerEventTypeUnknown: semenumpb.TriggerEventType_EVENT_UNKNOWN,
+	TriggerEventInsert:      semenumpb.TriggerEventType_INSERT,
+	TriggerEventUpdate:      semenumpb.TriggerEventType_UPDATE,
+	TriggerEventDelete:      semenumpb.TriggerEventType_DELETE,
+	TriggerEventTruncate:    semenumpb.TriggerEventType_TRUNCATE,
+}
+
+// TriggerEventTypeToTree allows the conversion from a
+// semenumpb.TriggerEventType to a tree.TriggerEventType.
+var TriggerEventTypeToTree = [...]TriggerEventType{
+	semenumpb.TriggerEventType_EVENT_UNKNOWN: TriggerEventTypeUnknown,
+	semenumpb.TriggerEventType_INSERT:        TriggerEventInsert,
+	semenumpb.TriggerEventType_UPDATE:        TriggerEventUpdate,
+	semenumpb.TriggerEventType_DELETE:        TriggerEventDelete,
+	semenumpb.TriggerEventType_TRUNCATE:      TriggerEventTruncate,
+}
+
+// Format implements the NodeFormatter interface.
+func (node *TriggerEventType) Format(ctx *FmtCtx) {
+	switch *node {
+	case TriggerEventTypeUnknown:
+		ctx.WriteString("UNKNOWN")
+	case TriggerEventInsert:
+		ctx.WriteString("INSERT")
+	case TriggerEventUpdate:
+		ctx.WriteString("UPDATE")
+	case TriggerEventDelete:
+		ctx.WriteString("DELETE")
+	case TriggerEventTruncate:
+		ctx.WriteString("TRUNCATE")
+	}
+}
+
+// String implements the Stringer interface.
+func (node *TriggerEventType) String() string {
+	return AsString(node)
+}
+
+// TriggerEventTypeSet is a set of TriggerEventType values, used to conveniently
+// check for the presence of a given event type in a trigger definition.
+type TriggerEventTypeSet uint8
+
+// Ensure that TriggerEventTypeSet can contain all TriggerEventTypes.
+const _ = TriggerEventTypeSet(1) << TriggerEventTypeMax
+
+// MakeTriggerEventTypeSet creates a TriggerEventTypeSet from a list of
+// TriggerEventType values.
+func MakeTriggerEventTypeSet(types ...TriggerEventType) TriggerEventTypeSet {
+	var s TriggerEventTypeSet
+	for _, t := range types {
+		s.Add(t)
+	}
+	return s
+}
+
+// Add adds a TriggerEventType value to the set.
+func (s *TriggerEventTypeSet) Add(t TriggerEventType) {
+	*s |= 1 << t
+}
+
+// Contains returns true if the set contains the given TriggerEventType value.
+func (s TriggerEventTypeSet) Contains(t TriggerEventType) bool {
+	return s&(1<<t) != 0
+}
+
+type TriggerEvent struct {
+	EventType TriggerEventType
+	Columns   NameList
+}
+
+// Format implements the NodeFormatter interface.
+func (node *TriggerEvent) Format(ctx *FmtCtx) {
+	node.EventType.Format(ctx)
+	if len(node.Columns) > 0 {
+		ctx.WriteString(" OF ")
+		ctx.FormatNode(&node.Columns)
+	}
+}
+
+type TriggerTransition struct {
+	Name  Name
+	IsNew bool
+	IsRow bool
+}
+
+// Format implements the NodeFormatter interface.
+func (node *TriggerTransition) Format(ctx *FmtCtx) {
+	if node.IsNew {
+		ctx.WriteString("NEW")
+	} else {
+		ctx.WriteString("OLD")
+	}
+	if node.IsRow {
+		ctx.WriteString(" ROW")
+	} else {
+		ctx.WriteString(" TABLE")
+	}
+	ctx.WriteString(" AS ")
+	node.Name.Format(ctx)
+}
+
+type TriggerForEach uint8
+
+const (
+	TriggerForEachStatement TriggerForEach = iota
+	TriggerForEachRow
+)
+
+// Format implements the NodeFormatter interface.
+func (node *TriggerForEach) Format(ctx *FmtCtx) {
+	switch *node {
+	case TriggerForEachStatement:
+		ctx.WriteString("FOR EACH STATEMENT")
+	case TriggerForEachRow:
+		ctx.WriteString("FOR EACH ROW")
+	}
+}
+
+// DropTrigger represents a DROP TRIGGER statement.
+type DropTrigger struct {
+	IfExists     bool
+	Trigger      Name
+	Table        *UnresolvedObjectName
+	DropBehavior DropBehavior
+}
+
+// Format implements the NodeFormatter interface.
+func (node *DropTrigger) Format(ctx *FmtCtx) {
+	ctx.WriteString("DROP TRIGGER ")
+	if node.IfExists {
+		ctx.WriteString("IF EXISTS ")
+	}
+	ctx.FormatName(string(node.Trigger))
+	ctx.WriteString(" ON ")
+	ctx.FormatNode(node.Table)
+	if node.DropBehavior != DropDefault {
+		ctx.WriteString(" ")
+		ctx.WriteString(node.DropBehavior.String())
+	}
+}
diff --git a/pkg/sql/sem/tree/createtypevariety_string.go b/pkg/sql/sem/tree/createtypevariety_string.go
index 1efd319..c0200e3 100644
--- a/pkg/sql/sem/tree/createtypevariety_string.go
+++ b/pkg/sql/sem/tree/createtypevariety_string.go
@@ -1,3 +1,8 @@
+// Copyright 2023 The Cockroach Authors.
+//
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
+
 // Code generated by "stringer"; DO NOT EDIT.
 
 package tree
diff --git a/pkg/sql/sem/tree/cursor.go b/pkg/sql/sem/tree/cursor.go
index 157d46b..84c0f35 100644
--- a/pkg/sql/sem/tree/cursor.go
+++ b/pkg/sql/sem/tree/cursor.go
@@ -1,12 +1,7 @@
 // Copyright 2021 The Cockroach Authors.
 //
-// Use of this software is governed by the Business Source License
-// included in the file licenses/BSL.txt.
-//
-// As of the Change Date specified in that file, in accordance with
-// the Business Source License, use of this software will be governed
-// by the Apache License, Version 2.0, included in the file
-// licenses/APL.txt.
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
 
 package tree
 
diff --git a/pkg/sql/sem/tree/data_placement.go b/pkg/sql/sem/tree/data_placement.go
index 3e11461..a48ff30 100644
--- a/pkg/sql/sem/tree/data_placement.go
+++ b/pkg/sql/sem/tree/data_placement.go
@@ -1,12 +1,7 @@
 // Copyright 2020 The Cockroach Authors.
 //
-// Use of this software is governed by the Business Source License
-// included in the file licenses/BSL.txt.
-//
-// As of the Change Date specified in that file, in accordance with
-// the Business Source License, use of this software will be governed
-// by the Apache License, Version 2.0, included in the file
-// licenses/APL.txt.
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
 
 package tree
 
diff --git a/pkg/sql/sem/tree/datum.go b/pkg/sql/sem/tree/datum.go
index b994ddd..c8047f3 100644
--- a/pkg/sql/sem/tree/datum.go
+++ b/pkg/sql/sem/tree/datum.go
@@ -1,21 +1,18 @@
 // Copyright 2015 The Cockroach Authors.
 //
-// Use of this software is governed by the Business Source License
-// included in the file licenses/BSL.txt.
-//
-// As of the Change Date specified in that file, in accordance with
-// the Business Source License, use of this software will be governed
-// by the Apache License, Version 2.0, included in the file
-// licenses/APL.txt.
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
 
 package tree
 
 import (
 	"bytes"
+	"context"
 	"encoding/hex"
 	"fmt"
 	"math"
 	"regexp"
+	"slices"
 	"sort"
 	"strconv"
 	"strings"
@@ -25,6 +22,7 @@ import (
 
 	"github.com/cockroachdb/apd/v3"
 	"github.com/cockroachdb/cockroachdb-parser/pkg/geo"
+	"github.com/cockroachdb/cockroachdb-parser/pkg/geo/geopb"
 	"github.com/cockroachdb/cockroachdb-parser/pkg/sql/lex"
 	"github.com/cockroachdb/cockroachdb-parser/pkg/sql/lexbase"
 	"github.com/cockroachdb/cockroachdb-parser/pkg/sql/pgrepl/lsn"
@@ -38,6 +36,7 @@ import (
 	"github.com/cockroachdb/cockroachdb-parser/pkg/util/encoding"
 	"github.com/cockroachdb/cockroachdb-parser/pkg/util/ipaddr"
 	"github.com/cockroachdb/cockroachdb-parser/pkg/util/json"
+	"github.com/cockroachdb/cockroachdb-parser/pkg/util/jsonpath"
 	"github.com/cockroachdb/cockroachdb-parser/pkg/util/stringencoding"
 	"github.com/cockroachdb/cockroachdb-parser/pkg/util/timeofday"
 	"github.com/cockroachdb/cockroachdb-parser/pkg/util/timetz"
@@ -46,6 +45,7 @@ import (
 	"github.com/cockroachdb/cockroachdb-parser/pkg/util/tsearch"
 	"github.com/cockroachdb/cockroachdb-parser/pkg/util/uint128"
 	"github.com/cockroachdb/cockroachdb-parser/pkg/util/uuid"
+	"github.com/cockroachdb/cockroachdb-parser/pkg/util/vector"
 	"github.com/cockroachdb/errors"
 	"github.com/cockroachdb/redact"
 	"github.com/lib/pq/oid"
@@ -83,9 +83,23 @@ var (
 	// postgres 4714 BC (JULIAN = 0) - 4713 in their docs - and 294276 AD.
 
 	// MaxSupportedTime is the maximum time we support parsing.
-	MaxSupportedTime = timeutil.Unix(9224318016000-1, 999999000) // 294276-12-31 23:59:59.999999
+	//
+	// Refer to the doc comments of the function "timeutil.Unix" for the process of
+	// deriving the arguments to construct a specific time.Time.
+	MaxSupportedTime    = timeutil.Unix(9224318016000-1, 999999000) // 294276-12-31 23:59:59.999999
+	MaxSupportedTimeSec = float64(MaxSupportedTime.Unix())
 	// MinSupportedTime is the minimum time we support parsing.
-	MinSupportedTime = timeutil.Unix(-210866803200, 0) // 4714-11-24 00:00:00+00 BC
+	//
+	// Refer to the doc comments of the function "timeutil.Unix" for the process of
+	// deriving the arguments to construct a specific time.Time.
+	MinSupportedTime    = timeutil.Unix(-210866803200, 0) // 4714-11-24 00:00:00+00 BC
+	MinSupportedTimeSec = float64(MinSupportedTime.Unix())
+
+	// ValidateJSONPath is injected from pkg/util/jsonpath/parser/parse.go.
+	ValidateJSONPath func(string) (*jsonpath.Jsonpath, error)
+
+	// EmptyDJSON is an empty JSON object.
+	EmptyDJSON = *NewDJSON(json.EmptyJSONValue)
 )
 
 // CompareContext represents the dependencies used to evaluate comparisons
@@ -93,12 +107,12 @@ var (
 type CompareContext interface {
 
 	// UnwrapDatum will unwrap the OIDs and potentially the placeholders.
-	UnwrapDatum(d Datum) Datum
+	UnwrapDatum(ctx context.Context, d Datum) Datum
 	GetLocation() *time.Location
 	GetRelativeParseTime() time.Time
 
 	// MustGetPlaceholderValue is used to compare Datum
-	MustGetPlaceholderValue(p *Placeholder) Datum
+	MustGetPlaceholderValue(ctx context.Context, p *Placeholder) Datum
 }
 
 // Datum represents a SQL value.
@@ -111,13 +125,10 @@ type Datum interface {
 	AmbiguousFormat() bool
 
 	// Compare returns -1 if the receiver is less than other, 0 if receiver is
-	// equal to other and +1 if receiver is greater than other.
-	// TODO(rafi): Migrate all usages of this to CompareError, then delete this.
-	Compare(ctx CompareContext, other Datum) int
-
-	// CompareError is the same as Compare, but it returns an error instead of
-	// panicking.
-	CompareError(ctx CompareContext, other Datum) (int, error)
+	// equal to other and +1 if receiver is greater than 'other'. Compare is safe
+	// to use with a nil eval.Context and results in default behavior, except for
+	// when comparing tree.Placeholder datums.
+	Compare(ctx context.Context, cmpCtx CompareContext, other Datum) (int, error)
 
 	// Prev returns the previous datum and true, if one exists, or nil and false.
 	// The previous datum satisfies the following definition: if the receiver is
@@ -133,11 +144,11 @@ type Datum interface {
 	// uses .Compare/encoding order and is guaranteed to be large enough by this
 	// weaker contract. The original filter expression is left in place to catch
 	// false positives.
-	Prev(ctx CompareContext) (Datum, bool)
+	Prev(ctx context.Context, cmpCtx CompareContext) (Datum, bool)
 
 	// IsMin returns true if the datum is equal to the minimum value the datum
 	// type can hold.
-	IsMin(ctx CompareContext) bool
+	IsMin(ctx context.Context, cmpCtx CompareContext) bool
 
 	// Next returns the next datum and true, if one exists, or nil and false
 	// otherwise. The next datum satisfies the following definition: if the
@@ -153,19 +164,19 @@ type Datum interface {
 	// uses .Compare/encoding order and is guaranteed to be large enough by this
 	// weaker contract. The original filter expression is left in place to catch
 	// false positives.
-	Next(ctx CompareContext) (Datum, bool)
+	Next(ctx context.Context, cmpCtx CompareContext) (Datum, bool)
 
 	// IsMax returns true if the datum is equal to the maximum value the datum
 	// type can hold.
-	IsMax(ctx CompareContext) bool
+	IsMax(ctx context.Context, cmpCtx CompareContext) bool
 
 	// Max returns the upper value and true, if one exists, otherwise
 	// nil and false. Used By Prev().
-	Max(ctx CompareContext) (Datum, bool)
+	Max(ctx context.Context, cmpCtx CompareContext) (Datum, bool)
 
 	// Min returns the lower value, if one exists, otherwise nil and
 	// false. Used by Next().
-	Min(ctx CompareContext) (Datum, bool)
+	Min(ctx context.Context, cmpCtx CompareContext) (Datum, bool)
 
 	// Size returns a lower bound on the total size of the receiver in bytes,
 	// including memory that is pointed at (even if shared between Datum
@@ -196,7 +207,7 @@ func (d *Datums) Format(ctx *FmtCtx) {
 // Compare does a lexicographical comparison and returns -1 if the receiver
 // is less than other, 0 if receiver is equal to other and +1 if receiver is
 // greater than other.
-func (d Datums) Compare(evalCtx CompareContext, other Datums) int {
+func (d Datums) Compare(ctx context.Context, evalCtx CompareContext, other Datums) int {
 	if len(d) == 0 {
 		panic(errors.AssertionFailedf("empty Datums being compared to other"))
 	}
@@ -206,7 +217,10 @@ func (d Datums) Compare(evalCtx CompareContext, other Datums) int {
 			return 1
 		}
 
-		compareDatum := d[i].Compare(evalCtx, other[i])
+		compareDatum, err := d[i].Compare(ctx, evalCtx, other[i])
+		if err != nil {
+			panic(err)
+		}
 		if compareDatum != 0 {
 			return compareDatum
 		}
@@ -218,30 +232,9 @@ func (d Datums) Compare(evalCtx CompareContext, other Datums) int {
 	return 0
 }
 
-// IsDistinctFrom checks to see if two datums are distinct from each other. Any
-// change in value is considered distinct, however, a NULL value is NOT
-// considered distinct from another NULL value.
-func (d Datums) IsDistinctFrom(evalCtx CompareContext, other Datums) bool {
-	if len(d) != len(other) {
-		return true
-	}
-	for i, val := range d {
-		if val == DNull {
-			if other[i] != DNull {
-				return true
-			}
-		} else {
-			if val.Compare(evalCtx, other[i]) != 0 {
-				return true
-			}
-		}
-	}
-	return false
-}
-
 // CompositeDatum is a Datum that may require composite encoding in
 // indexes. Any Datum implementing this interface must also add itself to
-// colinfo.HasCompositeKeyEncoding.
+// colinfo.CanHaveCompositeKeyEncoding.
 type CompositeDatum interface {
 	Datum
 	// IsComposite returns true if this datum is not round-tripable in a key
@@ -430,21 +423,12 @@ func (*DBool) ResolvedType() *types.T {
 }
 
 // Compare implements the Datum interface.
-func (d *DBool) Compare(ctx CompareContext, other Datum) int {
-	res, err := d.CompareError(ctx, other)
-	if err != nil {
-		panic(err)
-	}
-	return res
-}
-
-// CompareError implements the Datum interface.
-func (d *DBool) CompareError(ctx CompareContext, other Datum) (int, error) {
+func (d *DBool) Compare(ctx context.Context, cmpCtx CompareContext, other Datum) (int, error) {
 	if other == DNull {
 		// NULL is less than any non-NULL value.
 		return 1, nil
 	}
-	v, ok := ctx.UnwrapDatum(other).(*DBool)
+	v, ok := cmpCtx.UnwrapDatum(ctx, other).(*DBool)
 	if !ok {
 		return 0, makeUnsupportedComparisonMessage(d, other)
 	}
@@ -464,32 +448,32 @@ func CompareBools(d, v bool) int {
 }
 
 // Prev implements the Datum interface.
-func (*DBool) Prev(ctx CompareContext) (Datum, bool) {
+func (*DBool) Prev(ctx context.Context, cmpCtx CompareContext) (Datum, bool) {
 	return DBoolFalse, true
 }
 
 // Next implements the Datum interface.
-func (*DBool) Next(ctx CompareContext) (Datum, bool) {
+func (*DBool) Next(ctx context.Context, cmpCtx CompareContext) (Datum, bool) {
 	return DBoolTrue, true
 }
 
 // IsMax implements the Datum interface.
-func (d *DBool) IsMax(ctx CompareContext) bool {
+func (d *DBool) IsMax(ctx context.Context, cmpCtx CompareContext) bool {
 	return bool(*d)
 }
 
 // IsMin implements the Datum interface.
-func (d *DBool) IsMin(ctx CompareContext) bool {
+func (d *DBool) IsMin(ctx context.Context, cmpCtx CompareContext) bool {
 	return !bool(*d)
 }
 
 // Min implements the Datum interface.
-func (d *DBool) Min(ctx CompareContext) (Datum, bool) {
+func (d *DBool) Min(ctx context.Context, cmpCtx CompareContext) (Datum, bool) {
 	return DBoolFalse, true
 }
 
 // Max implements the Datum interface.
-func (d *DBool) Max(ctx CompareContext) (Datum, bool) {
+func (d *DBool) Max(ctx context.Context, cmpCtx CompareContext) (Datum, bool) {
 	return DBoolTrue, true
 }
 
@@ -603,21 +587,12 @@ func (*DBitArray) ResolvedType() *types.T {
 }
 
 // Compare implements the Datum interface.
-func (d *DBitArray) Compare(ctx CompareContext, other Datum) int {
-	res, err := d.CompareError(ctx, other)
-	if err != nil {
-		panic(err)
-	}
-	return res
-}
-
-// CompareError implements the Datum interface.
-func (d *DBitArray) CompareError(ctx CompareContext, other Datum) (int, error) {
+func (d *DBitArray) Compare(ctx context.Context, cmpCtx CompareContext, other Datum) (int, error) {
 	if other == DNull {
 		// NULL is less than any non-NULL value.
 		return 1, nil
 	}
-	v, ok := ctx.UnwrapDatum(other).(*DBitArray)
+	v, ok := cmpCtx.UnwrapDatum(ctx, other).(*DBitArray)
 	if !ok {
 		return 0, makeUnsupportedComparisonMessage(d, other)
 	}
@@ -626,35 +601,35 @@ func (d *DBitArray) CompareError(ctx CompareContext, other Datum) (int, error) {
 }
 
 // Prev implements the Datum interface.
-func (d *DBitArray) Prev(ctx CompareContext) (Datum, bool) {
+func (d *DBitArray) Prev(ctx context.Context, cmpCtx CompareContext) (Datum, bool) {
 	return nil, false
 }
 
 // Next implements the Datum interface.
-func (d *DBitArray) Next(ctx CompareContext) (Datum, bool) {
+func (d *DBitArray) Next(ctx context.Context, cmpCtx CompareContext) (Datum, bool) {
 	a := bitarray.Next(d.BitArray)
 	return &DBitArray{BitArray: a}, true
 }
 
 // IsMax implements the Datum interface.
-func (d *DBitArray) IsMax(ctx CompareContext) bool {
+func (d *DBitArray) IsMax(ctx context.Context, cmpCtx CompareContext) bool {
 	return false
 }
 
 // IsMin implements the Datum interface.
-func (d *DBitArray) IsMin(ctx CompareContext) bool {
+func (d *DBitArray) IsMin(ctx context.Context, cmpCtx CompareContext) bool {
 	return d.BitArray.IsEmpty()
 }
 
 var bitArrayZero = NewDBitArray(0)
 
 // Min implements the Datum interface.
-func (d *DBitArray) Min(ctx CompareContext) (Datum, bool) {
+func (d *DBitArray) Min(ctx context.Context, cmpCtx CompareContext) (Datum, bool) {
 	return bitArrayZero, true
 }
 
 // Max implements the Datum interface.
-func (d *DBitArray) Max(ctx CompareContext) (Datum, bool) {
+func (d *DBitArray) Max(ctx context.Context, cmpCtx CompareContext) (Datum, bool) {
 	return nil, false
 }
 
@@ -731,27 +706,18 @@ func (*DInt) ResolvedType() *types.T {
 }
 
 // Compare implements the Datum interface.
-func (d *DInt) Compare(ctx CompareContext, other Datum) int {
-	res, err := d.CompareError(ctx, other)
-	if err != nil {
-		panic(err)
-	}
-	return res
-}
-
-// CompareError implements the Datum interface.
-func (d *DInt) CompareError(ctx CompareContext, other Datum) (int, error) {
+func (d *DInt) Compare(ctx context.Context, cmpCtx CompareContext, other Datum) (int, error) {
 	if other == DNull {
 		// NULL is less than any non-NULL value.
 		return 1, nil
 	}
 	thisInt := *d
 	var v DInt
-	switch t := ctx.UnwrapDatum(other).(type) {
+	switch t := cmpCtx.UnwrapDatum(ctx, other).(type) {
 	case *DInt:
 		v = *t
 	case *DFloat, *DDecimal:
-		res, err := t.CompareError(ctx, d)
+		res, err := t.Compare(ctx, cmpCtx, d)
 		if err != nil {
 			return 0, err
 		}
@@ -764,7 +730,7 @@ func (d *DInt) CompareError(ctx CompareContext, other Datum) (int, error) {
 		if err != nil {
 			return 0, err
 		}
-		thisInt = DInt(o.Oid)
+		thisInt = DInt(o)
 		v = DInt(t.Oid)
 	default:
 		return 0, makeUnsupportedComparisonMessage(d, other)
@@ -779,22 +745,22 @@ func (d *DInt) CompareError(ctx CompareContext, other Datum) (int, error) {
 }
 
 // Prev implements the Datum interface.
-func (d *DInt) Prev(ctx CompareContext) (Datum, bool) {
+func (d *DInt) Prev(ctx context.Context, cmpCtx CompareContext) (Datum, bool) {
 	return NewDInt(*d - 1), true
 }
 
 // Next implements the Datum interface.
-func (d *DInt) Next(ctx CompareContext) (Datum, bool) {
+func (d *DInt) Next(ctx context.Context, cmpCtx CompareContext) (Datum, bool) {
 	return NewDInt(*d + 1), true
 }
 
 // IsMax implements the Datum interface.
-func (d *DInt) IsMax(ctx CompareContext) bool {
+func (d *DInt) IsMax(ctx context.Context, cmpCtx CompareContext) bool {
 	return *d == math.MaxInt64
 }
 
 // IsMin implements the Datum interface.
-func (d *DInt) IsMin(ctx CompareContext) bool {
+func (d *DInt) IsMin(ctx context.Context, cmpCtx CompareContext) bool {
 	return *d == math.MinInt64
 }
 
@@ -802,12 +768,12 @@ var dMaxInt = NewDInt(math.MaxInt64)
 var dMinInt = NewDInt(math.MinInt64)
 
 // Max implements the Datum interface.
-func (d *DInt) Max(ctx CompareContext) (Datum, bool) {
+func (d *DInt) Max(ctx context.Context, cmpCtx CompareContext) (Datum, bool) {
 	return dMaxInt, true
 }
 
 // Min implements the Datum interface.
-func (d *DInt) Min(ctx CompareContext) (Datum, bool) {
+func (d *DInt) Min(ctx context.Context, cmpCtx CompareContext) (Datum, bool) {
 	return dMinInt, true
 }
 
@@ -884,28 +850,19 @@ func (*DFloat) ResolvedType() *types.T {
 }
 
 // Compare implements the Datum interface.
-func (d *DFloat) Compare(ctx CompareContext, other Datum) int {
-	res, err := d.CompareError(ctx, other)
-	if err != nil {
-		panic(err)
-	}
-	return res
-}
-
-// CompareError implements the Datum interface.
-func (d *DFloat) CompareError(ctx CompareContext, other Datum) (int, error) {
+func (d *DFloat) Compare(ctx context.Context, cmpCtx CompareContext, other Datum) (int, error) {
 	if other == DNull {
 		// NULL is less than any non-NULL value.
 		return 1, nil
 	}
 	var v DFloat
-	switch t := ctx.UnwrapDatum(other).(type) {
+	switch t := cmpCtx.UnwrapDatum(ctx, other).(type) {
 	case *DFloat:
 		v = *t
 	case *DInt:
 		v = DFloat(MustBeDInt(t))
 	case *DDecimal:
-		res, err := t.CompareError(ctx, d)
+		res, err := t.Compare(ctx, cmpCtx, d)
 		if err != nil {
 			return 0, err
 		}
@@ -933,7 +890,7 @@ func (d *DFloat) CompareError(ctx CompareContext, other Datum) (int, error) {
 }
 
 // Prev implements the Datum interface.
-func (d *DFloat) Prev(ctx CompareContext) (Datum, bool) {
+func (d *DFloat) Prev(ctx context.Context, cmpCtx CompareContext) (Datum, bool) {
 	f := float64(*d)
 	if math.IsNaN(f) {
 		return nil, false
@@ -945,7 +902,7 @@ func (d *DFloat) Prev(ctx CompareContext) (Datum, bool) {
 }
 
 // Next implements the Datum interface.
-func (d *DFloat) Next(ctx CompareContext) (Datum, bool) {
+func (d *DFloat) Next(ctx context.Context, cmpCtx CompareContext) (Datum, bool) {
 	f := float64(*d)
 	if math.IsNaN(f) {
 		return DNegInfFloat, true
@@ -968,22 +925,22 @@ var (
 )
 
 // IsMax implements the Datum interface.
-func (d *DFloat) IsMax(ctx CompareContext) bool {
+func (d *DFloat) IsMax(ctx context.Context, cmpCtx CompareContext) bool {
 	return *d == *DPosInfFloat
 }
 
 // IsMin implements the Datum interface.
-func (d *DFloat) IsMin(ctx CompareContext) bool {
+func (d *DFloat) IsMin(ctx context.Context, cmpCtx CompareContext) bool {
 	return math.IsNaN(float64(*d))
 }
 
 // Max implements the Datum interface.
-func (d *DFloat) Max(ctx CompareContext) (Datum, bool) {
+func (d *DFloat) Max(ctx context.Context, cmpCtx CompareContext) (Datum, bool) {
 	return DPosInfFloat, true
 }
 
 // Min implements the Datum interface.
-func (d *DFloat) Min(ctx CompareContext) (Datum, bool) {
+func (d *DFloat) Min(ctx context.Context, cmpCtx CompareContext) (Datum, bool) {
 	return DNaNFloat, true
 }
 
@@ -1105,22 +1062,13 @@ func (*DDecimal) ResolvedType() *types.T {
 }
 
 // Compare implements the Datum interface.
-func (d *DDecimal) Compare(ctx CompareContext, other Datum) int {
-	res, err := d.CompareError(ctx, other)
-	if err != nil {
-		panic(err)
-	}
-	return res
-}
-
-// CompareError implements the Datum interface.
-func (d *DDecimal) CompareError(ctx CompareContext, other Datum) (int, error) {
+func (d *DDecimal) Compare(ctx context.Context, cmpCtx CompareContext, other Datum) (int, error) {
 	if other == DNull {
 		// NULL is less than any non-NULL value.
 		return 1, nil
 	}
 	var v apd.Decimal
-	switch t := ctx.UnwrapDatum(other).(type) {
+	switch t := cmpCtx.UnwrapDatum(ctx, other).(type) {
 	case *DDecimal:
 		v.Set(&t.Decimal)
 	case *DInt:
@@ -1151,12 +1099,12 @@ func CompareDecimals(d *apd.Decimal, v *apd.Decimal) int {
 }
 
 // Prev implements the Datum interface.
-func (d *DDecimal) Prev(ctx CompareContext) (Datum, bool) {
+func (d *DDecimal) Prev(ctx context.Context, cmpCtx CompareContext) (Datum, bool) {
 	return nil, false
 }
 
 // Next implements the Datum interface.
-func (d *DDecimal) Next(ctx CompareContext) (Datum, bool) {
+func (d *DDecimal) Next(ctx context.Context, cmpCtx CompareContext) (Datum, bool) {
 	return nil, false
 }
 
@@ -1164,31 +1112,34 @@ var (
 	// DZeroDecimal is the decimal constant '0'.
 	DZeroDecimal = &DDecimal{Decimal: apd.Decimal{}}
 
-	// dNaNDecimal is the decimal constant 'NaN'.
-	dNaNDecimal = &DDecimal{Decimal: apd.Decimal{Form: apd.NaN}}
+	// DNaNDecimal is the decimal constant 'NaN'.
+	DNaNDecimal = &DDecimal{Decimal: apd.Decimal{Form: apd.NaN}}
+
+	// DPosInfDecimal is the decimal constant 'inf'.
+	DPosInfDecimal = &DDecimal{Decimal: apd.Decimal{Form: apd.Infinite, Negative: false}}
 
-	// dPosInfDecimal is the decimal constant 'inf'.
-	dPosInfDecimal = &DDecimal{Decimal: apd.Decimal{Form: apd.Infinite, Negative: false}}
+	// DNegInfDecimal is the decimal constant '-inf'.
+	DNegInfDecimal = &DDecimal{Decimal: apd.Decimal{Form: apd.Infinite, Negative: true}}
 )
 
 // IsMax implements the Datum interface.
-func (d *DDecimal) IsMax(ctx CompareContext) bool {
+func (d *DDecimal) IsMax(ctx context.Context, cmpCtx CompareContext) bool {
 	return d.Form == apd.Infinite && !d.Negative
 }
 
 // IsMin implements the Datum interface.
-func (d *DDecimal) IsMin(ctx CompareContext) bool {
+func (d *DDecimal) IsMin(ctx context.Context, cmpCtx CompareContext) bool {
 	return d.Form == apd.NaN
 }
 
 // Max implements the Datum interface.
-func (d *DDecimal) Max(ctx CompareContext) (Datum, bool) {
-	return dPosInfDecimal, true
+func (d *DDecimal) Max(ctx context.Context, cmpCtx CompareContext) (Datum, bool) {
+	return DPosInfDecimal, true
 }
 
 // Min implements the Datum interface.
-func (d *DDecimal) Min(ctx CompareContext) (Datum, bool) {
-	return dNaNDecimal, true
+func (d *DDecimal) Min(ctx context.Context, cmpCtx CompareContext) (Datum, bool) {
+	return DNaNDecimal, true
 }
 
 // AmbiguousFormat implements the Datum interface.
@@ -1290,21 +1241,12 @@ func (*DString) ResolvedType() *types.T {
 }
 
 // Compare implements the Datum interface.
-func (d *DString) Compare(ctx CompareContext, other Datum) int {
-	res, err := d.CompareError(ctx, other)
-	if err != nil {
-		panic(err)
-	}
-	return res
-}
-
-// CompareError implements the Datum interface.
-func (d *DString) CompareError(ctx CompareContext, other Datum) (int, error) {
+func (d *DString) Compare(ctx context.Context, cmpCtx CompareContext, other Datum) (int, error) {
 	if other == DNull {
 		// NULL is less than any non-NULL value.
 		return 1, nil
 	}
-	v, ok := ctx.UnwrapDatum(other).(*DString)
+	v, ok := cmpCtx.UnwrapDatum(ctx, other).(*DString)
 	if !ok {
 		return 0, makeUnsupportedComparisonMessage(d, other)
 	}
@@ -1318,34 +1260,34 @@ func (d *DString) CompareError(ctx CompareContext, other Datum) (int, error) {
 }
 
 // Prev implements the Datum interface.
-func (d *DString) Prev(ctx CompareContext) (Datum, bool) {
+func (d *DString) Prev(ctx context.Context, cmpCtx CompareContext) (Datum, bool) {
 	return nil, false
 }
 
 // Next implements the Datum interface.
-func (d *DString) Next(ctx CompareContext) (Datum, bool) {
+func (d *DString) Next(ctx context.Context, cmpCtx CompareContext) (Datum, bool) {
 	return NewDString(string(encoding.BytesNext([]byte(*d)))), true
 }
 
 // IsMax implements the Datum interface.
-func (*DString) IsMax(ctx CompareContext) bool {
+func (*DString) IsMax(ctx context.Context, cmpCtx CompareContext) bool {
 	return false
 }
 
 // IsMin implements the Datum interface.
-func (d *DString) IsMin(ctx CompareContext) bool {
+func (d *DString) IsMin(ctx context.Context, cmpCtx CompareContext) bool {
 	return len(*d) == 0
 }
 
 var dEmptyString = NewDString("")
 
 // Min implements the Datum interface.
-func (d *DString) Min(ctx CompareContext) (Datum, bool) {
+func (d *DString) Min(ctx context.Context, cmpCtx CompareContext) (Datum, bool) {
 	return dEmptyString, true
 }
 
 // Max implements the Datum interface.
-func (d *DString) Max(ctx CompareContext) (Datum, bool) {
+func (d *DString) Max(ctx context.Context, cmpCtx CompareContext) (Datum, bool) {
 	return nil, false
 }
 
@@ -1466,21 +1408,14 @@ func (d *DCollatedString) ResolvedType() *types.T {
 }
 
 // Compare implements the Datum interface.
-func (d *DCollatedString) Compare(ctx CompareContext, other Datum) int {
-	res, err := d.CompareError(ctx, other)
-	if err != nil {
-		panic(err)
-	}
-	return res
-}
-
-// CompareError implements the Datum interface.
-func (d *DCollatedString) CompareError(ctx CompareContext, other Datum) (int, error) {
+func (d *DCollatedString) Compare(
+	ctx context.Context, cmpCtx CompareContext, other Datum,
+) (int, error) {
 	if other == DNull {
 		// NULL is less than any non-NULL value.
 		return 1, nil
 	}
-	v, ok := ctx.UnwrapDatum(other).(*DCollatedString)
+	v, ok := cmpCtx.UnwrapDatum(ctx, other).(*DCollatedString)
 	if !ok || !lex.LocaleNamesAreEqual(d.Locale, v.Locale) {
 		return 0, makeUnsupportedComparisonMessage(d, other)
 	}
@@ -1489,32 +1424,32 @@ func (d *DCollatedString) CompareError(ctx CompareContext, other Datum) (int, er
 }
 
 // Prev implements the Datum interface.
-func (d *DCollatedString) Prev(ctx CompareContext) (Datum, bool) {
+func (d *DCollatedString) Prev(ctx context.Context, cmpCtx CompareContext) (Datum, bool) {
 	return nil, false
 }
 
 // Next implements the Datum interface.
-func (d *DCollatedString) Next(ctx CompareContext) (Datum, bool) {
+func (d *DCollatedString) Next(ctx context.Context, cmpCtx CompareContext) (Datum, bool) {
 	return nil, false
 }
 
 // IsMax implements the Datum interface.
-func (*DCollatedString) IsMax(ctx CompareContext) bool {
+func (*DCollatedString) IsMax(ctx context.Context, cmpCtx CompareContext) bool {
 	return false
 }
 
 // IsMin implements the Datum interface.
-func (d *DCollatedString) IsMin(ctx CompareContext) bool {
+func (d *DCollatedString) IsMin(ctx context.Context, cmpCtx CompareContext) bool {
 	return d.Contents == ""
 }
 
 // Min implements the Datum interface.
-func (d *DCollatedString) Min(ctx CompareContext) (Datum, bool) {
+func (d *DCollatedString) Min(ctx context.Context, cmpCtx CompareContext) (Datum, bool) {
 	return &DCollatedString{"", d.Locale, nil}, true
 }
 
 // Max implements the Datum interface.
-func (d *DCollatedString) Max(ctx CompareContext) (Datum, bool) {
+func (d *DCollatedString) Max(ctx context.Context, cmpCtx CompareContext) (Datum, bool) {
 	return nil, false
 }
 
@@ -1570,62 +1505,65 @@ func (*DBytes) ResolvedType() *types.T {
 }
 
 // Compare implements the Datum interface.
-func (d *DBytes) Compare(ctx CompareContext, other Datum) int {
-	res, err := d.CompareError(ctx, other)
-	if err != nil {
-		panic(err)
-	}
-	return res
-}
-
-// CompareError implements the Datum interface.
-func (d *DBytes) CompareError(ctx CompareContext, other Datum) (int, error) {
+func (d *DBytes) Compare(ctx context.Context, cmpCtx CompareContext, other Datum) (int, error) {
 	if other == DNull {
 		// NULL is less than any non-NULL value.
 		return 1, nil
 	}
-	v, ok := ctx.UnwrapDatum(other).(*DBytes)
-	if !ok {
+	var o string
+	switch t := cmpCtx.UnwrapDatum(ctx, other).(type) {
+	case *DBytes:
+		o = string(*t)
+	case *DEncodedKey:
+		// Allow comparison with DEncodedKeys. This is required for now because
+		// histogram upper-bound values in table statistics are DBytes, but
+		// constraints with DEncodedKeys are built. When row count estimates are
+		// computed, values of these two types are compared.
+		//
+		// TODO(mgartner): We should use DEncodedKeys for histogram
+		// upper-bounds, then we can remove this case.
+		o = string(*t)
+	default:
 		return 0, makeUnsupportedComparisonMessage(d, other)
 	}
-	if *d < *v {
+	if string(*d) < o {
 		return -1, nil
 	}
-	if *d > *v {
+	if string(*d) > o {
 		return 1, nil
 	}
 	return 0, nil
 }
 
 // Prev implements the Datum interface.
-func (d *DBytes) Prev(ctx CompareContext) (Datum, bool) {
+func (d *DBytes) Prev(ctx context.Context, cmpCtx CompareContext) (Datum, bool) {
 	return nil, false
 }
 
 // Next implements the Datum interface.
-func (d *DBytes) Next(ctx CompareContext) (Datum, bool) {
+func (d *DBytes) Next(ctx context.Context, cmpCtx CompareContext) (Datum, bool) {
 	return NewDBytes(DBytes(encoding.BytesNext([]byte(*d)))), true
 }
 
 // IsMax implements the Datum interface.
-func (*DBytes) IsMax(ctx CompareContext) bool {
+func (*DBytes) IsMax(ctx context.Context, cmpCtx CompareContext) bool {
 	return false
 }
 
 // IsMin implements the Datum interface.
-func (d *DBytes) IsMin(ctx CompareContext) bool {
+func (d *DBytes) IsMin(ctx context.Context, cmpCtx CompareContext) bool {
 	return len(*d) == 0
 }
 
 var dEmptyBytes = NewDBytes(DBytes(""))
 
 // Min implements the Datum interface.
-func (d *DBytes) Min(ctx CompareContext) (Datum, bool) {
+func (d *DBytes) Min(ctx context.Context, cmpCtx CompareContext) (Datum, bool) {
 	return dEmptyBytes, true
 }
 
 // Max implements the Datum interface.
-func (d *DBytes) Max(ctx CompareContext) (Datum, bool) {
+func (d *DBytes) Max(ctx context.Context, cmpCtx CompareContext) (Datum, bool) {
 	return nil, false
 }
 
@@ -1650,7 +1588,7 @@ func (d *DBytes) Format(ctx *FmtCtx) {
 		_, _ = hex.NewEncoder(ctx).Write([]byte(*d))
 		ctx.WriteByte('\'')
 	} else {
-		withQuotes := !f.HasFlags(FmtFlags(lexbase.EncBareStrings))
+		withQuotes := !f.HasFlags(FmtBareStrings)
 		if withQuotes {
 			ctx.WriteByte('\'')
 		}
@@ -1692,42 +1630,65 @@ func (*DEncodedKey) ResolvedType() *types.T {
 }
 
 // Compare implements the Datum interface.
-func (d *DEncodedKey) Compare(ctx CompareContext, other Datum) int {
-	panic(errors.AssertionFailedf("not implemented"))
-}
-
-// CompareError implements the Datum interface.
-func (d *DEncodedKey) CompareError(ctx CompareContext, other Datum) (int, error) {
-	panic(errors.AssertionFailedf("not implemented"))
+func (d *DEncodedKey) Compare(
+	ctx context.Context, cmpCtx CompareContext, other Datum,
+) (int, error) {
+	if other == DNull {
+		// NULL is less than any non-NULL value.
+		return 1, nil
+	}
+	var o string
+	switch t := cmpCtx.UnwrapDatum(ctx, other).(type) {
+	case *DBytes:
+		// Allow comparison with DBytes. This is required for now because
+		// histogram upper-bound values in table statistics are DBytes, but
+		// constraints with DEncodedKeys are built. When row count estimates are
+		// computed, values of these two types are compared.
+		//
+		// TODO(mgartner): We should use DEncodedKeys for histogram
+		// upper-bounds, then we can remove this case.
+		o = string(*t)
+	case *DEncodedKey:
+		o = string(*t)
+	default:
+		return 0, makeUnsupportedComparisonMessage(d, other)
+	}
+	if string(*d) < o {
+		return -1, nil
+	}
+	if string(*d) > o {
+		return 1, nil
+	}
+	return 0, nil
 }
 
 // Prev implements the Datum interface.
-func (d *DEncodedKey) Prev(ctx CompareContext) (Datum, bool) {
+func (d *DEncodedKey) Prev(ctx context.Context, cmpCtx CompareContext) (Datum, bool) {
 	return nil, false
 }
 
 // Next implements the Datum interface.
-func (d *DEncodedKey) Next(ctx CompareContext) (Datum, bool) {
+func (d *DEncodedKey) Next(ctx context.Context, cmpCtx CompareContext) (Datum, bool) {
 	return nil, false
 }
 
 // IsMax implements the Datum interface.
-func (*DEncodedKey) IsMax(ctx CompareContext) bool {
+func (*DEncodedKey) IsMax(ctx context.Context, cmpCtx CompareContext) bool {
 	return false
 }
 
 // IsMin implements the Datum interface.
-func (d *DEncodedKey) IsMin(ctx CompareContext) bool {
+func (d *DEncodedKey) IsMin(ctx context.Context, cmpCtx CompareContext) bool {
 	return false
 }
 
 // Min implements the Datum interface.
-func (d *DEncodedKey) Min(ctx CompareContext) (Datum, bool) {
+func (d *DEncodedKey) Min(ctx context.Context, cmpCtx CompareContext) (Datum, bool) {
 	return nil, false
 }
 
 // Max implements the Datum interface.
-func (d *DEncodedKey) Max(ctx CompareContext) (Datum, bool) {
+func (d *DEncodedKey) Max(ctx context.Context, cmpCtx CompareContext) (Datum, bool) {
 	return nil, false
 }
 
@@ -1790,21 +1751,12 @@ func (*DUuid) ResolvedType() *types.T {
 }
 
 // Compare implements the Datum interface.
-func (d *DUuid) Compare(ctx CompareContext, other Datum) int {
-	res, err := d.CompareError(ctx, other)
-	if err != nil {
-		panic(err)
-	}
-	return res
-}
-
-// CompareError implements the Datum interface.
-func (d *DUuid) CompareError(ctx CompareContext, other Datum) (int, error) {
+func (d *DUuid) Compare(ctx context.Context, cmpCtx CompareContext, other Datum) (int, error) {
 	if other == DNull {
 		// NULL is less than any non-NULL value.
 		return 1, nil
 	}
-	v, ok := ctx.UnwrapDatum(other).(*DUuid)
+	v, ok := cmpCtx.UnwrapDatum(ctx, other).(*DUuid)
 	if !ok {
 		return 0, makeUnsupportedComparisonMessage(d, other)
 	}
@@ -1817,26 +1769,26 @@ func (d *DUuid) equal(other *DUuid) bool {
 }
 
 // Prev implements the Datum interface.
-func (d *DUuid) Prev(ctx CompareContext) (Datum, bool) {
+func (d *DUuid) Prev(ctx context.Context, cmpCtx CompareContext) (Datum, bool) {
 	i := d.ToUint128()
 	u := uuid.FromUint128(i.Sub(1))
 	return NewDUuid(DUuid{u}), true
 }
 
 // Next implements the Datum interface.
-func (d *DUuid) Next(ctx CompareContext) (Datum, bool) {
+func (d *DUuid) Next(ctx context.Context, cmpCtx CompareContext) (Datum, bool) {
 	i := d.ToUint128()
 	u := uuid.FromUint128(i.Add(1))
 	return NewDUuid(DUuid{u}), true
 }
 
 // IsMax implements the Datum interface.
-func (d *DUuid) IsMax(ctx CompareContext) bool {
+func (d *DUuid) IsMax(ctx context.Context, cmpCtx CompareContext) bool {
 	return d.equal(DMaxUUID)
 }
 
 // IsMin implements the Datum interface.
-func (d *DUuid) IsMin(ctx CompareContext) bool {
+func (d *DUuid) IsMin(ctx context.Context, cmpCtx CompareContext) bool {
 	return d.equal(DMinUUID)
 }
 
@@ -1848,12 +1800,12 @@ var DMaxUUID = NewDUuid(DUuid{uuid.UUID{0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF
 	0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}})
 
 // Min implements the Datum interface.
-func (*DUuid) Min(ctx CompareContext) (Datum, bool) {
+func (*DUuid) Min(ctx context.Context, cmpCtx CompareContext) (Datum, bool) {
 	return DMinUUID, true
 }
 
 // Max implements the Datum interface.
-func (*DUuid) Max(ctx CompareContext) (Datum, bool) {
+func (*DUuid) Max(ctx context.Context, cmpCtx CompareContext) (Datum, bool) {
 	return DMaxUUID, true
 }
 
@@ -1923,21 +1875,12 @@ func (*DIPAddr) ResolvedType() *types.T {
 }
 
 // Compare implements the Datum interface.
-func (d *DIPAddr) Compare(ctx CompareContext, other Datum) int {
-	res, err := d.CompareError(ctx, other)
-	if err != nil {
-		panic(err)
-	}
-	return res
-}
-
-// CompareError implements the Datum interface.
-func (d *DIPAddr) CompareError(ctx CompareContext, other Datum) (int, error) {
+func (d *DIPAddr) Compare(ctx context.Context, cmpCtx CompareContext, other Datum) (int, error) {
 	if other == DNull {
 		// NULL is less than any non-NULL value.
 		return 1, nil
 	}
-	v, ok := ctx.UnwrapDatum(other).(*DIPAddr)
+	v, ok := cmpCtx.UnwrapDatum(ctx, other).(*DIPAddr)
 	if !ok {
 		return 0, makeUnsupportedComparisonMessage(d, other)
 	}
@@ -1951,7 +1894,7 @@ func (d DIPAddr) equal(other *DIPAddr) bool {
 }
 
 // Prev implements the Datum interface.
-func (d *DIPAddr) Prev(ctx CompareContext) (Datum, bool) {
+func (d *DIPAddr) Prev(ctx context.Context, cmpCtx CompareContext) (Datum, bool) {
 	// We will do one of the following to get the Prev IPAddr:
 	//	- Decrement IP address if we won't underflow the IP.
 	//	- Decrement mask and set the IP to max in family if we will underflow.
@@ -1972,7 +1915,7 @@ func (d *DIPAddr) Prev(ctx CompareContext) (Datum, bool) {
 }
 
 // Next implements the Datum interface.
-func (d *DIPAddr) Next(ctx CompareContext) (Datum, bool) {
+func (d *DIPAddr) Next(ctx context.Context, cmpCtx CompareContext) (Datum, bool) {
 	// We will do one of a few things to get the Next IP address:
 	//	- Increment IP address if we won't overflow the IP.
 	//	- Increment mask and set the IP to min in family if we will overflow.
@@ -1993,12 +1936,12 @@ func (d *DIPAddr) Next(ctx CompareContext) (Datum, bool) {
 }
 
 // IsMax implements the Datum interface.
-func (d *DIPAddr) IsMax(ctx CompareContext) bool {
+func (d *DIPAddr) IsMax(ctx context.Context, cmpCtx CompareContext) bool {
 	return d.equal(DMaxIPAddr)
 }
 
 // IsMin implements the Datum interface.
-func (d *DIPAddr) IsMin(ctx CompareContext) bool {
+func (d *DIPAddr) IsMin(ctx context.Context, cmpCtx CompareContext) bool {
 	return d.equal(DMinIPAddr)
 }
 
@@ -2022,12 +1965,12 @@ var DMinIPAddr = NewDIPAddr(DIPAddr{ipaddr.IPAddr{Family: ipaddr.IPv4family, Add
 var DMaxIPAddr = NewDIPAddr(DIPAddr{ipaddr.IPAddr{Family: ipaddr.IPv6family, Addr: dIPv6max, Mask: 128}})
 
 // Min implements the Datum interface.
-func (*DIPAddr) Min(ctx CompareContext) (Datum, bool) {
+func (*DIPAddr) Min(ctx context.Context, cmpCtx CompareContext) (Datum, bool) {
 	return DMinIPAddr, true
 }
 
 // Max implements the Datum interface.
-func (*DIPAddr) Max(ctx CompareContext) (Datum, bool) {
+func (*DIPAddr) Max(ctx context.Context, cmpCtx CompareContext) (Datum, bool) {
 	return DMaxIPAddr, true
 }
 
@@ -2093,7 +2036,7 @@ type ParseContext interface {
 	GetIntervalStyle() duration.IntervalStyle
 	// GetDateStyle returns the date style in the session.
 	GetDateStyle() pgdate.DateStyle
-	// GetParseHelper returns a helper to optmize date parsing.
+	// GetDateHelper returns a helper to optimize parsing of datetime types.
 	GetDateHelper() *pgdate.ParseHelper
 }
 
@@ -2225,26 +2168,17 @@ func (*DDate) ResolvedType() *types.T {
 }
 
 // Compare implements the Datum interface.
-func (d *DDate) Compare(ctx CompareContext, other Datum) int {
-	res, err := d.CompareError(ctx, other)
-	if err != nil {
-		panic(err)
-	}
-	return res
-}
-
-// CompareError implements the Datum interface.
-func (d *DDate) CompareError(ctx CompareContext, other Datum) (int, error) {
+func (d *DDate) Compare(ctx context.Context, cmpCtx CompareContext, other Datum) (int, error) {
 	if other == DNull {
 		// NULL is less than any non-NULL value.
 		return 1, nil
 	}
 	var v DDate
-	switch t := ctx.UnwrapDatum(other).(type) {
+	switch t := cmpCtx.UnwrapDatum(ctx, other).(type) {
 	case *DDate:
 		v = *t
 	case *DTimestamp, *DTimestampTZ:
-		return compareTimestamps(ctx, d, other)
+		return compareTimestamps(ctx, cmpCtx, d, other)
 	default:
 		return 0, makeUnsupportedComparisonMessage(d, other)
 	}
@@ -2262,7 +2196,7 @@ var (
 )
 
 // Prev implements the Datum interface.
-func (d *DDate) Prev(ctx CompareContext) (Datum, bool) {
+func (d *DDate) Prev(ctx context.Context, cmpCtx CompareContext) (Datum, bool) {
 	switch d.Date {
 	case pgdate.PosInfDate:
 		return dHighDate, true
@@ -2279,7 +2213,7 @@ func (d *DDate) Prev(ctx CompareContext) (Datum, bool) {
 }
 
 // Next implements the Datum interface.
-func (d *DDate) Next(ctx CompareContext) (Datum, bool) {
+func (d *DDate) Next(ctx context.Context, cmpCtx CompareContext) (Datum, bool) {
 	switch d.Date {
 	case pgdate.NegInfDate:
 		return dLowDate, true
@@ -2296,22 +2230,22 @@ func (d *DDate) Next(ctx CompareContext) (Datum, bool) {
 }
 
 // IsMax implements the Datum interface.
-func (d *DDate) IsMax(ctx CompareContext) bool {
+func (d *DDate) IsMax(ctx context.Context, cmpCtx CompareContext) bool {
 	return d.PGEpochDays() == pgdate.PosInfDate.PGEpochDays()
 }
 
 // IsMin implements the Datum interface.
-func (d *DDate) IsMin(ctx CompareContext) bool {
+func (d *DDate) IsMin(ctx context.Context, cmpCtx CompareContext) bool {
 	return d.PGEpochDays() == pgdate.NegInfDate.PGEpochDays()
 }
 
 // Max implements the Datum interface.
-func (d *DDate) Max(ctx CompareContext) (Datum, bool) {
+func (d *DDate) Max(ctx context.Context, cmpCtx CompareContext) (Datum, bool) {
 	return dMaxDate, true
 }
 
 // Min implements the Datum interface.
-func (d *DDate) Min(ctx CompareContext) (Datum, bool) {
+func (d *DDate) Min(ctx context.Context, cmpCtx CompareContext) (Datum, bool) {
 	return dMinDate, true
 }
 
@@ -2382,7 +2316,7 @@ func ParseDTime(
 
 	s = timeutil.ReplaceLibPQTimePrefix(s)
 
-	t, dependsOnContext, err := pgdate.ParseTimeWithoutTimezone(now, dateStyle(ctx), s)
+	t, dependsOnContext, err := pgdate.ParseTimeWithoutTimezone(now, dateStyle(ctx), s, dateParseHelper(ctx))
 	if err != nil {
 		return nil, false, MakeParseError(s, types.Time, err)
 	}
@@ -2395,26 +2329,17 @@ func (*DTime) ResolvedType() *types.T {
 }
 
 // Compare implements the Datum interface.
-func (d *DTime) Compare(ctx CompareContext, other Datum) int {
-	res, err := d.CompareError(ctx, other)
-	if err != nil {
-		panic(err)
-	}
-	return res
-}
-
-// CompareError implements the Datum interface.
-func (d *DTime) CompareError(ctx CompareContext, other Datum) (int, error) {
+func (d *DTime) Compare(ctx context.Context, cmpCtx CompareContext, other Datum) (int, error) {
 	if other == DNull {
 		// NULL is less than any non-NULL value.
 		return 1, nil
 	}
-	return compareTimestamps(ctx, d, other)
+	return compareTimestamps(ctx, cmpCtx, d, other)
 }
 
 // Prev implements the Datum interface.
-func (d *DTime) Prev(ctx CompareContext) (Datum, bool) {
-	if d.IsMin(ctx) {
+func (d *DTime) Prev(ctx context.Context, cmpCtx CompareContext) (Datum, bool) {
+	if d.IsMin(ctx, cmpCtx) {
 		return nil, false
 	}
 	prev := *d - 1
@@ -2427,8 +2352,8 @@ func (d *DTime) Round(precision time.Duration) *DTime {
 }
 
 // Next implements the Datum interface.
-func (d *DTime) Next(ctx CompareContext) (Datum, bool) {
-	if d.IsMax(ctx) {
+func (d *DTime) Next(ctx context.Context, cmpCtx CompareContext) (Datum, bool) {
+	if d.IsMax(ctx, cmpCtx) {
 		return nil, false
 	}
 	next := *d + 1
@@ -2439,22 +2364,22 @@ var dTimeMin = MakeDTime(timeofday.Min)
 var dTimeMax = MakeDTime(timeofday.Max)
 
 // IsMax implements the Datum interface.
-func (d *DTime) IsMax(ctx CompareContext) bool {
+func (d *DTime) IsMax(ctx context.Context, cmpCtx CompareContext) bool {
 	return *d == *dTimeMax
 }
 
 // IsMin implements the Datum interface.
-func (d *DTime) IsMin(ctx CompareContext) bool {
+func (d *DTime) IsMin(ctx context.Context, cmpCtx CompareContext) bool {
 	return *d == *dTimeMin
 }
 
 // Max implements the Datum interface.
-func (d *DTime) Max(ctx CompareContext) (Datum, bool) {
+func (d *DTime) Max(ctx context.Context, cmpCtx CompareContext) (Datum, bool) {
 	return dTimeMax, true
 }
 
 // Min implements the Datum interface.
-func (d *DTime) Min(ctx CompareContext) (Datum, bool) {
+func (d *DTime) Min(ctx context.Context, cmpCtx CompareContext) (Datum, bool) {
 	return dTimeMin, true
 }
 
@@ -2548,26 +2473,17 @@ func (*DTimeTZ) ResolvedType() *types.T {
 }
 
 // Compare implements the Datum interface.
-func (d *DTimeTZ) Compare(ctx CompareContext, other Datum) int {
-	res, err := d.CompareError(ctx, other)
-	if err != nil {
-		panic(err)
-	}
-	return res
-}
-
-// CompareError implements the Datum interface.
-func (d *DTimeTZ) CompareError(ctx CompareContext, other Datum) (int, error) {
+func (d *DTimeTZ) Compare(ctx context.Context, cmpCtx CompareContext, other Datum) (int, error) {
 	if other == DNull {
 		// NULL is less than any non-NULL value.
 		return 1, nil
 	}
-	return compareTimestamps(ctx, d, other)
+	return compareTimestamps(ctx, cmpCtx, d, other)
 }
 
 // Prev implements the Datum interface.
-func (d *DTimeTZ) Prev(ctx CompareContext) (Datum, bool) {
-	if d.IsMin(ctx) {
+func (d *DTimeTZ) Prev(ctx context.Context, cmpCtx CompareContext) (Datum, bool) {
+	if d.IsMin(ctx, cmpCtx) {
 		return nil, false
 	}
 	// In the common case, the absolute time doesn't change, we simply decrement
@@ -2595,8 +2511,8 @@ func (d *DTimeTZ) Prev(ctx CompareContext) (Datum, bool) {
 }
 
 // Next implements the Datum interface.
-func (d *DTimeTZ) Next(ctx CompareContext) (Datum, bool) {
-	if d.IsMax(ctx) {
+func (d *DTimeTZ) Next(ctx context.Context, cmpCtx CompareContext) (Datum, bool) {
+	if d.IsMax(ctx, cmpCtx) {
 		return nil, false
 	}
 	// In the common case, the absolute time doesn't change, we simply increment
@@ -2624,17 +2540,17 @@ func (d *DTimeTZ) Next(ctx CompareContext) (Datum, bool) {
 }
 
 // IsMax implements the Datum interface.
-func (d *DTimeTZ) IsMax(ctx CompareContext) bool {
+func (d *DTimeTZ) IsMax(ctx context.Context, cmpCtx CompareContext) bool {
 	return d.TimeOfDay == DMaxTimeTZ.TimeOfDay && d.OffsetSecs == timetz.MaxTimeTZOffsetSecs
 }
 
 // IsMin implements the Datum interface.
-func (d *DTimeTZ) IsMin(ctx CompareContext) bool {
+func (d *DTimeTZ) IsMin(ctx context.Context, cmpCtx CompareContext) bool {
 	return d.TimeOfDay == DMinTimeTZ.TimeOfDay && d.OffsetSecs == timetz.MinTimeTZOffsetSecs
 }
 
 // Max implements the Datum interface.
-func (d *DTimeTZ) Max(ctx CompareContext) (Datum, bool) {
+func (d *DTimeTZ) Max(ctx context.Context, cmpCtx CompareContext) (Datum, bool) {
 	return DMaxTimeTZ, true
 }
 
@@ -2644,7 +2560,7 @@ func (d *DTimeTZ) Round(precision time.Duration) *DTimeTZ {
 }
 
 // Min implements the Datum interface.
-func (d *DTimeTZ) Min(ctx CompareContext) (Datum, bool) {
+func (d *DTimeTZ) Min(ctx context.Context, cmpCtx CompareContext) (Datum, bool) {
 	return DMinTimeTZ, true
 }
 
@@ -2689,12 +2605,11 @@ type DTimestamp struct {
 }
 
 // MakeDTimestamp creates a DTimestamp with specified precision.
-func MakeDTimestamp(t time.Time, precision time.Duration) (*DTimestamp, error) {
-	ret := t.Round(precision)
-	if ret.After(MaxSupportedTime) || ret.Before(MinSupportedTime) {
-		return nil, NewTimestampExceedsBoundsError(ret)
+func MakeDTimestamp(t time.Time, precision time.Duration) (_ *DTimestamp, err error) {
+	if t, err = roundAndCheck(t, precision); err != nil {
+		return nil, err
 	}
-	return &DTimestamp{Time: ret}, nil
+	return &DTimestamp{Time: t}, nil
 }
 
 // MustMakeDTimestamp wraps MakeDTimestamp but panics if there is an error.
@@ -2722,7 +2637,7 @@ func ParseDTimestamp(
 	ctx ParseContext, s string, precision time.Duration,
 ) (_ *DTimestamp, dependsOnContext bool, _ error) {
 	now := relativeParseTime(ctx)
-	t, dependsOnContext, err := pgdate.ParseTimestampWithoutTimezone(now, dateStyle(ctx), s)
+	t, dependsOnContext, err := pgdate.ParseTimestampWithoutTimezone(now, dateStyle(ctx), s, dateParseHelper(ctx))
 	if err != nil {
 		return nil, false, err
 	}
@@ -2766,11 +2681,13 @@ func (*DTimestamp) ResolvedType() *types.T {
 
 // TimeFromDatumForComparison gets the time from a datum object to use
 // strictly for comparison usage.
-func TimeFromDatumForComparison(ctx CompareContext, d Datum) (time.Time, error) {
-	d = ctx.UnwrapDatum(d)
+func TimeFromDatumForComparison(
+	ctx context.Context, cmpCtx CompareContext, d Datum,
+) (time.Time, error) {
+	d = cmpCtx.UnwrapDatum(ctx, d)
 	switch t := d.(type) {
 	case *DDate:
-		ts, err := MakeDTimestampTZFromDate(ctx.GetLocation(), t)
+		ts, err := MakeDTimestampTZFromDate(cmpCtx.GetLocation(), t)
 		if err != nil {
 			return time.Time{}, err
 		}
@@ -2779,14 +2696,14 @@ func TimeFromDatumForComparison(ctx CompareContext, d Datum) (time.Time, error)
 		return t.Time, nil
 	case *DTimestamp:
 		// Normalize to the timezone of the context.
-		_, zoneOffset := t.Time.In(ctx.GetLocation()).Zone()
-		ts := t.Time.In(ctx.GetLocation()).Add(-time.Duration(zoneOffset) * time.Second)
+		_, zoneOffset := t.Time.In(cmpCtx.GetLocation()).Zone()
+		ts := t.Time.In(cmpCtx.GetLocation()).Add(-time.Duration(zoneOffset) * time.Second)
 		return ts, nil
 	case *DTime:
 		// Normalize to the timezone of the context.
 		toTime := timeofday.TimeOfDay(*t).ToTime()
-		_, zoneOffsetSecs := toTime.In(ctx.GetLocation()).Zone()
-		return toTime.In(ctx.GetLocation()).Add(-time.Duration(zoneOffsetSecs) * time.Second), nil
+		_, zoneOffsetSecs := toTime.In(cmpCtx.GetLocation()).Zone()
+		return toTime.In(cmpCtx.GetLocation()).Add(-time.Duration(zoneOffsetSecs) * time.Second), nil
 	case *DTimeTZ:
 		return t.ToTime(), nil
 	default:
@@ -2803,12 +2720,12 @@ const (
 	positiveInfinity
 )
 
-func checkInfiniteDate(ctx CompareContext, d Datum) infiniteDateComparison {
+func checkInfiniteDate(ctx context.Context, cmpCtx CompareContext, d Datum) infiniteDateComparison {
 	if _, isDate := d.(*DDate); isDate {
-		if d.IsMax(ctx) {
+		if d.IsMax(ctx, cmpCtx) {
 			return positiveInfinity
 		}
-		if d.IsMin(ctx) {
+		if d.IsMin(ctx, cmpCtx) {
 			return negativeInfinity
 		}
 	}
@@ -2822,9 +2739,9 @@ func checkInfiniteDate(ctx CompareContext, d Datum) infiniteDateComparison {
 // Datums are allowed to be one of DDate, DTimestamp, DTimestampTZ, DTime,
 // DTimeTZ. For all other datum types it will panic; also, comparing two DDates
 // is not supported.
-func compareTimestamps(ctx CompareContext, l Datum, r Datum) (int, error) {
-	leftInf := checkInfiniteDate(ctx, l)
-	rightInf := checkInfiniteDate(ctx, r)
+func compareTimestamps(ctx context.Context, cmpCtx CompareContext, l Datum, r Datum) (int, error) {
+	leftInf := checkInfiniteDate(ctx, cmpCtx, l)
+	rightInf := checkInfiniteDate(ctx, cmpCtx, r)
 	if leftInf != finite || rightInf != finite {
 		// At least one of the datums is an infinite date.
 		if leftInf != finite && rightInf != finite {
@@ -2837,8 +2754,8 @@ func compareTimestamps(ctx CompareContext, l Datum, r Datum) (int, error) {
 		// values to get the desired result for comparison.
 		return int(leftInf - rightInf), nil
 	}
-	lTime, lErr := TimeFromDatumForComparison(ctx, l)
-	rTime, rErr := TimeFromDatumForComparison(ctx, r)
+	lTime, lErr := TimeFromDatumForComparison(ctx, cmpCtx, l)
+	rTime, rErr := TimeFromDatumForComparison(ctx, cmpCtx, r)
 	if lErr != nil || rErr != nil {
 		return 0, makeUnsupportedComparisonMessage(l, r)
 	}
@@ -2864,7 +2781,7 @@ func compareTimestamps(ctx CompareContext, l Datum, r Datum) (int, error) {
 		return 0, nil
 	}
 
-	_, zoneOffset := ctx.GetRelativeParseTime().Zone()
+	_, zoneOffset := cmpCtx.GetRelativeParseTime().Zone()
 	lOffset := int32(-zoneOffset)
 	rOffset := int32(-zoneOffset)
 
@@ -2885,56 +2802,47 @@ func compareTimestamps(ctx CompareContext, l Datum, r Datum) (int, error) {
 }
 
 // Compare implements the Datum interface.
-func (d *DTimestamp) Compare(ctx CompareContext, other Datum) int {
-	res, err := d.CompareError(ctx, other)
-	if err != nil {
-		panic(err)
-	}
-	return res
-}
-
-// CompareError implements the Datum interface.
-func (d *DTimestamp) CompareError(ctx CompareContext, other Datum) (int, error) {
+func (d *DTimestamp) Compare(ctx context.Context, cmpCtx CompareContext, other Datum) (int, error) {
 	if other == DNull {
 		// NULL is less than any non-NULL value.
 		return 1, nil
 	}
-	return compareTimestamps(ctx, d, other)
+	return compareTimestamps(ctx, cmpCtx, d, other)
 }
 
 // Prev implements the Datum interface.
-func (d *DTimestamp) Prev(ctx CompareContext) (Datum, bool) {
-	if d.IsMin(ctx) {
+func (d *DTimestamp) Prev(ctx context.Context, cmpCtx CompareContext) (Datum, bool) {
+	if d.IsMin(ctx, cmpCtx) {
 		return nil, false
 	}
 	return &DTimestamp{Time: d.Add(-time.Microsecond)}, true
 }
 
 // Next implements the Datum interface.
-func (d *DTimestamp) Next(ctx CompareContext) (Datum, bool) {
-	if d.IsMax(ctx) {
+func (d *DTimestamp) Next(ctx context.Context, cmpCtx CompareContext) (Datum, bool) {
+	if d.IsMax(ctx, cmpCtx) {
 		return nil, false
 	}
 	return &DTimestamp{Time: d.Add(time.Microsecond)}, true
 }
 
 // IsMax implements the Datum interface.
-func (d *DTimestamp) IsMax(ctx CompareContext) bool {
+func (d *DTimestamp) IsMax(ctx context.Context, cmpCtx CompareContext) bool {
 	return d.Equal(MaxSupportedTime)
 }
 
 // IsMin implements the Datum interface.
-func (d *DTimestamp) IsMin(ctx CompareContext) bool {
+func (d *DTimestamp) IsMin(ctx context.Context, cmpCtx CompareContext) bool {
 	return d.Equal(MinSupportedTime)
 }
 
 // Min implements the Datum interface.
-func (d *DTimestamp) Min(ctx CompareContext) (Datum, bool) {
+func (d *DTimestamp) Min(ctx context.Context, cmpCtx CompareContext) (Datum, bool) {
 	return &DTimestamp{Time: MinSupportedTime}, true
 }
 
 // Max implements the Datum interface.
-func (d *DTimestamp) Max(ctx CompareContext) (Datum, bool) {
+func (d *DTimestamp) Max(ctx context.Context, cmpCtx CompareContext) (Datum, bool) {
 	return &DTimestamp{Time: MaxSupportedTime}, true
 }
 
@@ -2972,9 +2880,20 @@ type DTimestampTZ struct {
 	time.Time
 }
 
-func checkTimeBounds(t time.Time, precision time.Duration) (time.Time, error) {
+// roundAndCheck rounds the given time to the specified precision and checks
+// if the rounded time is within the supported bounds.
+//
+// Supported bounds:
+//   - [MinSupportedTime, MaxSupportedTime]
+//   - TimeInfinity
+//   - TimeNegativeInfinity
+func roundAndCheck(t time.Time, precision time.Duration) (time.Time, error) {
 	ret := t.Round(precision)
 	if ret.After(MaxSupportedTime) || ret.Before(MinSupportedTime) {
+		if t == pgdate.TimeInfinity || t == pgdate.TimeNegativeInfinity {
+			return t, nil
+		}
+
 		return time.Time{}, NewTimestampExceedsBoundsError(ret)
 	}
 	return ret, nil
@@ -2982,7 +2901,7 @@ func checkTimeBounds(t time.Time, precision time.Duration) (time.Time, error) {
 
 // MakeDTimestampTZ creates a DTimestampTZ with specified precision.
 func MakeDTimestampTZ(t time.Time, precision time.Duration) (_ *DTimestampTZ, err error) {
-	if t, err = checkTimeBounds(t, precision); err != nil {
+	if t, err = roundAndCheck(t, precision); err != nil {
 		return nil, err
 	}
 	return &DTimestampTZ{Time: t}, nil
@@ -3011,25 +2930,39 @@ func MakeDTimestampTZFromDate(loc *time.Location, d *DDate) (*DTimestampTZ, erro
 	return MakeDTimestampTZ(t.Add(time.Duration(-offset)*time.Second), time.Microsecond)
 }
 
+// ParseTimestampTZ parses and returns the time.Time value represented by the
+// provided string in the provided location, or an error if parsing is
+// unsuccessful.
+//
+// The dependsOnContext return value indicates if we had to consult the
+// ParseContext (either for the time or the local timezone).
+func ParseTimestampTZ(
+	ctx ParseContext, s string, precision time.Duration,
+) (_ time.Time, dependsOnContext bool, _ error) {
+	now := relativeParseTime(ctx)
+	t, dependsOnContext, err := pgdate.ParseTimestamp(now, dateStyle(ctx), s, dateParseHelper(ctx))
+	if err != nil {
+		return time.Time{}, false, err
+	}
+	if t, err = roundAndCheck(t, precision); err != nil {
+		return time.Time{}, false, err
+	}
+	return t, dependsOnContext, nil
+}
+
 // ParseDTimestampTZ parses and returns the *DTimestampTZ Datum value represented by
 // the provided string in the provided location, or an error if parsing is unsuccessful.
 //
 // The dependsOnContext return value indicates if we had to consult the
 // ParseContext (either for the time or the local timezone).
-//
-// Parts of this function are inlined into ParseAndRequireStringHandler, if this
-// changes materially the timestamp case arms there may need to change too.
 func ParseDTimestampTZ(
 	ctx ParseContext, s string, precision time.Duration,
 ) (_ *DTimestampTZ, dependsOnContext bool, _ error) {
-	now := relativeParseTime(ctx)
-	t, dependsOnContext, err := pgdate.ParseTimestamp(now, dateStyle(ctx), s)
+	t, dependsOnContext, err := ParseTimestampTZ(ctx, s, precision)
 	if err != nil {
 		return nil, false, err
 	}
-	// Always normalize time to the current location.
-	d, err := MakeDTimestampTZ(t, precision)
-	return d, dependsOnContext, err
+	return &DTimestampTZ{Time: t}, dependsOnContext, err
 }
 
 // DZeroTimestampTZ is the zero-valued DTimestampTZ.
@@ -3070,56 +3003,49 @@ func (*DTimestampTZ) ResolvedType() *types.T {
 }
 
 // Compare implements the Datum interface.
-func (d *DTimestampTZ) Compare(ctx CompareContext, other Datum) int {
-	res, err := d.CompareError(ctx, other)
-	if err != nil {
-		panic(err)
-	}
-	return res
-}
-
-// CompareError implements the Datum interface.
-func (d *DTimestampTZ) CompareError(ctx CompareContext, other Datum) (int, error) {
+func (d *DTimestampTZ) Compare(
+	ctx context.Context, cmpCtx CompareContext, other Datum,
+) (int, error) {
 	if other == DNull {
 		// NULL is less than any non-NULL value.
 		return 1, nil
 	}
-	return compareTimestamps(ctx, d, other)
+	return compareTimestamps(ctx, cmpCtx, d, other)
 }
 
 // Prev implements the Datum interface.
-func (d *DTimestampTZ) Prev(ctx CompareContext) (Datum, bool) {
-	if d.IsMin(ctx) {
+func (d *DTimestampTZ) Prev(ctx context.Context, cmpCtx CompareContext) (Datum, bool) {
+	if d.IsMin(ctx, cmpCtx) {
 		return nil, false
 	}
 	return &DTimestampTZ{Time: d.Add(-time.Microsecond)}, true
 }
 
 // Next implements the Datum interface.
-func (d *DTimestampTZ) Next(ctx CompareContext) (Datum, bool) {
-	if d.IsMax(ctx) {
+func (d *DTimestampTZ) Next(ctx context.Context, cmpCtx CompareContext) (Datum, bool) {
+	if d.IsMax(ctx, cmpCtx) {
 		return nil, false
 	}
 	return &DTimestampTZ{Time: d.Add(time.Microsecond)}, true
 }
 
 // IsMax implements the Datum interface.
-func (d *DTimestampTZ) IsMax(ctx CompareContext) bool {
+func (d *DTimestampTZ) IsMax(ctx context.Context, cmpCtx CompareContext) bool {
 	return d.Equal(MaxSupportedTime)
 }
 
 // IsMin implements the Datum interface.
-func (d *DTimestampTZ) IsMin(ctx CompareContext) bool {
+func (d *DTimestampTZ) IsMin(ctx context.Context, cmpCtx CompareContext) bool {
 	return d.Equal(MinSupportedTime)
 }
 
 // Min implements the Datum interface.
-func (d *DTimestampTZ) Min(ctx CompareContext) (Datum, bool) {
+func (d *DTimestampTZ) Min(ctx context.Context, cmpCtx CompareContext) (Datum, bool) {
 	return &DTimestampTZ{Time: MinSupportedTime}, true
 }
 
 // Max implements the Datum interface.
-func (d *DTimestampTZ) Max(ctx CompareContext) (Datum, bool) {
+func (d *DTimestampTZ) Max(ctx context.Context, cmpCtx CompareContext) (Datum, bool) {
 	return &DTimestampTZ{Time: MaxSupportedTime}, true
 }
 
@@ -3283,21 +3209,12 @@ func (*DInterval) ResolvedType() *types.T {
 }
 
 // Compare implements the Datum interface.
-func (d *DInterval) Compare(ctx CompareContext, other Datum) int {
-	res, err := d.CompareError(ctx, other)
-	if err != nil {
-		panic(err)
-	}
-	return res
-}
-
-// CompareError implements the Datum interface.
-func (d *DInterval) CompareError(ctx CompareContext, other Datum) (int, error) {
+func (d *DInterval) Compare(ctx context.Context, cmpCtx CompareContext, other Datum) (int, error) {
 	if other == DNull {
 		// NULL is less than any non-NULL value.
 		return 1, nil
 	}
-	v, ok := ctx.UnwrapDatum(other).(*DInterval)
+	v, ok := cmpCtx.UnwrapDatum(ctx, other).(*DInterval)
 	if !ok {
 		return 0, makeUnsupportedComparisonMessage(d, other)
 	}
@@ -3306,22 +3223,22 @@ func (d *DInterval) CompareError(ctx CompareContext, other Datum) (int, error) {
 }
 
 // Prev implements the Datum interface.
-func (d *DInterval) Prev(ctx CompareContext) (Datum, bool) {
+func (d *DInterval) Prev(ctx context.Context, cmpCtx CompareContext) (Datum, bool) {
 	return nil, false
 }
 
 // Next implements the Datum interface.
-func (d *DInterval) Next(ctx CompareContext) (Datum, bool) {
+func (d *DInterval) Next(ctx context.Context, cmpCtx CompareContext) (Datum, bool) {
 	return nil, false
 }
 
 // IsMax implements the Datum interface.
-func (d *DInterval) IsMax(ctx CompareContext) bool {
+func (d *DInterval) IsMax(ctx context.Context, cmpCtx CompareContext) bool {
 	return d.Duration == dMaxInterval.Duration
 }
 
 // IsMin implements the Datum interface.
-func (d *DInterval) IsMin(ctx CompareContext) bool {
+func (d *DInterval) IsMin(ctx context.Context, cmpCtx CompareContext) bool {
 	return d.Duration == dMinInterval.Duration
 }
 
@@ -3332,12 +3249,12 @@ var (
 )
 
 // Max implements the Datum interface.
-func (d *DInterval) Max(ctx CompareContext) (Datum, bool) {
+func (d *DInterval) Max(ctx context.Context, cmpCtx CompareContext) (Datum, bool) {
 	return dMaxInterval, true
 }
 
 // Min implements the Datum interface.
-func (d *DInterval) Min(ctx CompareContext) (Datum, bool) {
+func (d *DInterval) Min(ctx context.Context, cmpCtx CompareContext) (Datum, bool) {
 	return dMinInterval, true
 }
 
@@ -3421,21 +3338,12 @@ func (*DGeography) ResolvedType() *types.T {
 }
 
 // Compare implements the Datum interface.
-func (d *DGeography) Compare(ctx CompareContext, other Datum) int {
-	res, err := d.CompareError(ctx, other)
-	if err != nil {
-		panic(err)
-	}
-	return res
-}
-
-// CompareError implements the Datum interface.
-func (d *DGeography) CompareError(ctx CompareContext, other Datum) (int, error) {
+func (d *DGeography) Compare(ctx context.Context, cmpCtx CompareContext, other Datum) (int, error) {
 	if other == DNull {
 		// NULL is less than any non-NULL value.
 		return 1, nil
 	}
-	v, ok := ctx.UnwrapDatum(other).(*DGeography)
+	v, ok := cmpCtx.UnwrapDatum(ctx, other).(*DGeography)
 	if !ok {
 		return 0, makeUnsupportedComparisonMessage(d, other)
 	}
@@ -3444,32 +3352,32 @@ func (d *DGeography) CompareError(ctx CompareContext, other Datum) (int, error)
 }
 
 // Prev implements the Datum interface.
-func (d *DGeography) Prev(ctx CompareContext) (Datum, bool) {
+func (d *DGeography) Prev(ctx context.Context, cmpCtx CompareContext) (Datum, bool) {
 	return nil, false
 }
 
 // Next implements the Datum interface.
-func (d *DGeography) Next(ctx CompareContext) (Datum, bool) {
+func (d *DGeography) Next(ctx context.Context, cmpCtx CompareContext) (Datum, bool) {
 	return nil, false
 }
 
 // IsMax implements the Datum interface.
-func (d *DGeography) IsMax(ctx CompareContext) bool {
+func (d *DGeography) IsMax(ctx context.Context, cmpCtx CompareContext) bool {
 	return false
 }
 
 // IsMin implements the Datum interface.
-func (d *DGeography) IsMin(ctx CompareContext) bool {
+func (d *DGeography) IsMin(ctx context.Context, cmpCtx CompareContext) bool {
 	return false
 }
 
 // Max implements the Datum interface.
-func (d *DGeography) Max(ctx CompareContext) (Datum, bool) {
+func (d *DGeography) Max(ctx context.Context, cmpCtx CompareContext) (Datum, bool) {
 	return nil, false
 }
 
 // Min implements the Datum interface.
-func (d *DGeography) Min(ctx CompareContext) (Datum, bool) {
+func (d *DGeography) Min(ctx context.Context, cmpCtx CompareContext) (Datum, bool) {
 	return nil, false
 }
 
@@ -3491,7 +3399,19 @@ func (d *DGeography) Format(ctx *FmtCtx) {
 
 // Size implements the Datum interface.
 func (d *DGeography) Size() uintptr {
-	return d.Geography.SpatialObjectRef().MemSize()
+	return d.Geography.SpatialObjectRef().MemSize(false /* deterministic */)
+}
+
+// DeterministicMemSize returns size of this DGeography object that will not
+// depend on runtime conditions like pre-allocated slice capacity. This comes at
+// the expense of having less precise information.
+func (d *DGeography) DeterministicMemSize() uintptr {
+	return d.Geography.SpatialObjectRef().MemSize(true /* deterministic */)
+}
+
+// ToJSON converts the DGeography to JSON.
+func (d *DGeography) ToJSON(maxDecimalDigits int) (json.JSON, error) {
+	return spatialObjectToJSON(d.Geography.SpatialObject(), maxDecimalDigits)
 }
 
 // DGeometry is the Geometry Datum.
@@ -3543,21 +3463,12 @@ func (*DGeometry) ResolvedType() *types.T {
 }
 
 // Compare implements the Datum interface.
-func (d *DGeometry) Compare(ctx CompareContext, other Datum) int {
-	res, err := d.CompareError(ctx, other)
-	if err != nil {
-		panic(err)
-	}
-	return res
-}
-
-// CompareError implements the Datum interface.
-func (d *DGeometry) CompareError(ctx CompareContext, other Datum) (int, error) {
+func (d *DGeometry) Compare(ctx context.Context, cmpCtx CompareContext, other Datum) (int, error) {
 	if other == DNull {
 		// NULL is less than any non-NULL value.
 		return 1, nil
 	}
-	v, ok := ctx.UnwrapDatum(other).(*DGeometry)
+	v, ok := cmpCtx.UnwrapDatum(ctx, other).(*DGeometry)
 	if !ok {
 		return 0, makeUnsupportedComparisonMessage(d, other)
 	}
@@ -3566,32 +3477,32 @@ func (d *DGeometry) CompareError(ctx CompareContext, other Datum) (int, error) {
 }
 
 // Prev implements the Datum interface.
-func (d *DGeometry) Prev(ctx CompareContext) (Datum, bool) {
+func (d *DGeometry) Prev(ctx context.Context, cmpCtx CompareContext) (Datum, bool) {
 	return nil, false
 }
 
 // Next implements the Datum interface.
-func (d *DGeometry) Next(ctx CompareContext) (Datum, bool) {
+func (d *DGeometry) Next(ctx context.Context, cmpCtx CompareContext) (Datum, bool) {
 	return nil, false
 }
 
 // IsMax implements the Datum interface.
-func (d *DGeometry) IsMax(ctx CompareContext) bool {
+func (d *DGeometry) IsMax(ctx context.Context, cmpCtx CompareContext) bool {
 	return false
 }
 
 // IsMin implements the Datum interface.
-func (d *DGeometry) IsMin(ctx CompareContext) bool {
+func (d *DGeometry) IsMin(ctx context.Context, cmpCtx CompareContext) bool {
 	return false
 }
 
 // Max implements the Datum interface.
-func (d *DGeometry) Max(ctx CompareContext) (Datum, bool) {
+func (d *DGeometry) Max(ctx context.Context, cmpCtx CompareContext) (Datum, bool) {
 	return nil, false
 }
 
 // Min implements the Datum interface.
-func (d *DGeometry) Min(ctx CompareContext) (Datum, bool) {
+func (d *DGeometry) Min(ctx context.Context, cmpCtx CompareContext) (Datum, bool) {
 	return nil, false
 }
 
@@ -3613,7 +3524,19 @@ func (d *DGeometry) Format(ctx *FmtCtx) {
 
 // Size implements the Datum interface.
 func (d *DGeometry) Size() uintptr {
-	return d.Geometry.SpatialObjectRef().MemSize()
+	return d.Geometry.SpatialObjectRef().MemSize(false /* deterministic */)
+}
+
+// DeterministicMemSize returns size of this DGeometry object that will not
+// depend on runtime conditions like pre-allocated slice capacity. This comes at
+// the expense of having less precise information.
+func (d *DGeometry) DeterministicMemSize() uintptr {
+	return d.Geometry.SpatialObjectRef().MemSize(true /* deterministic */)
+}
+
+// ToJSON converts the DGeometry to JSON.
+func (d *DGeometry) ToJSON(maxDecimalDigits int) (json.JSON, error) {
+	return spatialObjectToJSON(d.Geometry.SpatialObject(), maxDecimalDigits)
 }
 
 type DPGLSN struct {
@@ -3666,21 +3589,12 @@ func (*DPGLSN) ResolvedType() *types.T {
 }
 
 // Compare implements the Datum interface.
-func (d *DPGLSN) Compare(ctx CompareContext, other Datum) int {
-	res, err := d.CompareError(ctx, other)
-	if err != nil {
-		panic(err)
-	}
-	return res
-}
-
-// CompareError implements the Datum interface.
-func (d *DPGLSN) CompareError(ctx CompareContext, other Datum) (int, error) {
+func (d *DPGLSN) Compare(ctx context.Context, cmpCtx CompareContext, other Datum) (int, error) {
 	if other == DNull {
 		// NULL is less than any non-NULL value.
 		return 1, nil
 	}
-	v, ok := ctx.UnwrapDatum(other).(*DPGLSN)
+	v, ok := cmpCtx.UnwrapDatum(ctx, other).(*DPGLSN)
 	if !ok {
 		return 0, makeUnsupportedComparisonMessage(d, other)
 	}
@@ -3688,38 +3602,38 @@ func (d *DPGLSN) CompareError(ctx CompareContext, other Datum) (int, error) {
 }
 
 // Prev implements the Datum interface.
-func (d *DPGLSN) Prev(ctx CompareContext) (Datum, bool) {
-	if d.IsMin(ctx) {
+func (d *DPGLSN) Prev(ctx context.Context, cmpCtx CompareContext) (Datum, bool) {
+	if d.IsMin(ctx, cmpCtx) {
 		return nil, false
 	}
 	return NewDPGLSN(d.LSN.Sub(1)), true
 }
 
 // Next implements the Datum interface.
-func (d *DPGLSN) Next(ctx CompareContext) (Datum, bool) {
-	if d.IsMax(ctx) {
+func (d *DPGLSN) Next(ctx context.Context, cmpCtx CompareContext) (Datum, bool) {
+	if d.IsMax(ctx, cmpCtx) {
 		return nil, false
 	}
 	return NewDPGLSN(d.LSN.Add(1)), true
 }
 
 // IsMax implements the Datum interface.
-func (d *DPGLSN) IsMax(ctx CompareContext) bool {
+func (d *DPGLSN) IsMax(ctx context.Context, cmpCtx CompareContext) bool {
 	return d.LSN == math.MaxUint64
 }
 
 // IsMin implements the Datum interface.
-func (d *DPGLSN) IsMin(ctx CompareContext) bool {
+func (d *DPGLSN) IsMin(ctx context.Context, cmpCtx CompareContext) bool {
 	return d.LSN == 0
 }
 
 // Max implements the Datum interface.
-func (d *DPGLSN) Max(ctx CompareContext) (Datum, bool) {
+func (d *DPGLSN) Max(ctx context.Context, cmpCtx CompareContext) (Datum, bool) {
 	return NewDPGLSN(math.MaxUint64), false
 }
 
 // Min implements the Datum interface.
-func (d *DPGLSN) Min(ctx CompareContext) (Datum, bool) {
+func (d *DPGLSN) Min(ctx context.Context, cmpCtx CompareContext) (Datum, bool) {
 	return NewDPGLSN(0), false
 }
 
@@ -3744,6 +3658,112 @@ func (d *DPGLSN) Size() uintptr {
 	return unsafe.Sizeof(*d)
 }
 
+// DPGVector is the Datum representation of the PGVector type.
+type DPGVector struct {
+	vector.T
+}
+
+// NewDPGVector returns a new PGVector Datum.
+func NewDPGVector(vector vector.T) *DPGVector { return &DPGVector{vector} }
+
+// AsDPGVector attempts to retrieve a DPGVector from an Expr, returning a
+// DPGVector and a flag signifying whether the assertion was successful. The
+// function should be used instead of direct type assertions wherever a
+// *DPGVector wrapped by a *DOidWrapper is possible.
+func AsDPGVector(e Expr) (*DPGVector, bool) {
+	switch t := e.(type) {
+	case *DPGVector:
+		return t, true
+	case *DOidWrapper:
+		return AsDPGVector(t.Wrapped)
+	}
+	return nil, false
+}
+
+// MustBeDPGVector attempts to retrieve a DPGVector from an Expr, panicking if the
+// assertion fails.
+func MustBeDPGVector(e Expr) *DPGVector {
+	v, ok := AsDPGVector(e)
+	if !ok {
+		panic(errors.AssertionFailedf("expected *DPGVector, found %T", e))
+	}
+	return v
+}
+
+// ParseDPGVector takes a string of PGVector and returns a DPGVector value.
+func ParseDPGVector(s string) (Datum, error) {
+	v, err := vector.ParseVector(s)
+	if err != nil {
+		return nil, pgerror.Wrapf(err, pgcode.Syntax, "could not parse vector")
+	}
+	return NewDPGVector(v), nil
+}
+
+// Format implements the NodeFormatter interface.
+func (d *DPGVector) Format(ctx *FmtCtx) {
+	bareStrings := ctx.HasFlags(FmtFlags(lexbase.EncBareStrings))
+	if !bareStrings {
+		ctx.WriteByte('\'')
+	}
+	ctx.WriteString(d.String())
+	if !bareStrings {
+		ctx.WriteByte('\'')
+	}
+}
+
+// ResolvedType implements the TypedExpr interface.
+func (d *DPGVector) ResolvedType() *types.T { return types.PGVector }
+
+// AmbiguousFormat implements the Datum interface.
+func (d *DPGVector) AmbiguousFormat() bool {
+	return true
+}
+
+func (d *DPGVector) Compare(ctx context.Context, cmpCtx CompareContext, other Datum) (int, error) {
+	if other == DNull {
+		// NULL is less than any non-NULL value.
+		return 1, nil
+	}
+	v, ok := cmpCtx.UnwrapDatum(ctx, other).(*DPGVector)
+	if !ok {
+		return 0, makeUnsupportedComparisonMessage(d, other)
+	}
+	return d.T.Compare(v.T)
+}
+
+// Prev implements the Datum interface.
+func (d *DPGVector) Prev(ctx context.Context, cmpCtx CompareContext) (Datum, bool) {
+	return nil, false
+}
+
+// Next implements the Datum interface.
+func (d *DPGVector) Next(ctx context.Context, cmpCtx CompareContext) (Datum, bool) {
+	return nil, false
+}
+
+// IsMax implements the Datum interface.
+func (d *DPGVector) IsMax(ctx context.Context, cmpCtx CompareContext) bool {
+	return false
+}
+
+// IsMin implements the Datum interface.
+func (d *DPGVector) IsMin(ctx context.Context, cmpCtx CompareContext) bool {
+	return false
+}
+
+// Max implements the Datum interface.
+func (d *DPGVector) Max(ctx context.Context, cmpCtx CompareContext) (Datum, bool) {
+	return nil, false
+}
+
+// Min implements the Datum interface.
+func (d *DPGVector) Min(ctx context.Context, cmpCtx CompareContext) (Datum, bool) { return nil, false }
+
+// Size implements the Datum interface.
+func (d *DPGVector) Size() uintptr {
+	return unsafe.Sizeof(*d) + d.T.Size()
+}
+
 // DBox2D is the Datum representation of the Box2D type.
 type DBox2D struct {
 	geo.CartesianBoundingBox
@@ -3758,7 +3778,7 @@ func NewDBox2D(b geo.CartesianBoundingBox) *DBox2D {
 func ParseDBox2D(str string) (*DBox2D, error) {
 	b, err := geo.ParseCartesianBoundingBox(str)
 	if err != nil {
-		return nil, errors.Wrapf(err, "could not parse geometry")
+		return nil, errors.Wrapf(err, "could not parse bounding box")
 	}
 	return &DBox2D{CartesianBoundingBox: b}, nil
 }
@@ -3793,21 +3813,12 @@ func (*DBox2D) ResolvedType() *types.T {
 }
 
 // Compare implements the Datum interface.
-func (d *DBox2D) Compare(ctx CompareContext, other Datum) int {
-	res, err := d.CompareError(ctx, other)
-	if err != nil {
-		panic(err)
-	}
-	return res
-}
-
-// CompareError implements the Datum interface.
-func (d *DBox2D) CompareError(ctx CompareContext, other Datum) (int, error) {
+func (d *DBox2D) Compare(ctx context.Context, cmpCtx CompareContext, other Datum) (int, error) {
 	if other == DNull {
 		// NULL is less than any non-NULL value.
 		return 1, nil
 	}
-	v, ok := ctx.UnwrapDatum(other).(*DBox2D)
+	v, ok := cmpCtx.UnwrapDatum(ctx, other).(*DBox2D)
 	if !ok {
 		return 0, makeUnsupportedComparisonMessage(d, other)
 	}
@@ -3816,32 +3827,32 @@ func (d *DBox2D) CompareError(ctx CompareContext, other Datum) (int, error) {
 }
 
 // Prev implements the Datum interface.
-func (d *DBox2D) Prev(ctx CompareContext) (Datum, bool) {
+func (d *DBox2D) Prev(ctx context.Context, cmpCtx CompareContext) (Datum, bool) {
 	return nil, false
 }
 
 // Next implements the Datum interface.
-func (d *DBox2D) Next(ctx CompareContext) (Datum, bool) {
+func (d *DBox2D) Next(ctx context.Context, cmpCtx CompareContext) (Datum, bool) {
 	return nil, false
 }
 
 // IsMax implements the Datum interface.
-func (d *DBox2D) IsMax(ctx CompareContext) bool {
+func (d *DBox2D) IsMax(ctx context.Context, cmpCtx CompareContext) bool {
 	return false
 }
 
 // IsMin implements the Datum interface.
-func (d *DBox2D) IsMin(ctx CompareContext) bool {
+func (d *DBox2D) IsMin(ctx context.Context, cmpCtx CompareContext) bool {
 	return false
 }
 
 // Max implements the Datum interface.
-func (d *DBox2D) Max(ctx CompareContext) (Datum, bool) {
+func (d *DBox2D) Max(ctx context.Context, cmpCtx CompareContext) (Datum, bool) {
 	return nil, false
 }
 
 // Min implements the Datum interface.
-func (d *DBox2D) Min(ctx CompareContext) (Datum, bool) {
+func (d *DBox2D) Min(ctx context.Context, cmpCtx CompareContext) (Datum, bool) {
 	return nil, false
 }
 
@@ -3866,6 +3877,115 @@ func (d *DBox2D) Size() uintptr {
 	return unsafe.Sizeof(*d) + unsafe.Sizeof(d.CartesianBoundingBox)
 }
 
+// DJsonpath is the Datum representation of the Jsonpath type.
+type DJsonpath struct {
+	jsonpath.Jsonpath
+}
+
+func NewDJsonpath(d jsonpath.Jsonpath) *DJsonpath {
+	return &DJsonpath{Jsonpath: d}
+}
+
+// ResolvedType implements the TypedExpr interface.
+func (d *DJsonpath) ResolvedType() *types.T {
+	return types.Jsonpath
+}
+
+// Compare implements the Datum interface. While we don't support external
+// comparisons between Jsonpath types, we still need to implement Compare
+// because many internal tests rely on it.
+func (d *DJsonpath) Compare(ctx context.Context, cmpCtx CompareContext, other Datum) (int, error) {
+	if other == DNull {
+		return 1, nil
+	}
+	v, ok := cmpCtx.UnwrapDatum(ctx, other).(*DJsonpath)
+	if !ok {
+		return 0, makeUnsupportedComparisonMessage(d, other)
+	}
+	return strings.Compare(d.String(), v.String()), nil
+}
+
+// Prev implements the Datum interface.
+func (d *DJsonpath) Prev(ctx context.Context, cmpCtx CompareContext) (Datum, bool) {
+	return nil, false
+}
+
+// Next implements the Datum interface.
+func (d *DJsonpath) Next(ctx context.Context, cmpCtx CompareContext) (Datum, bool) {
+	return nil, false
+}
+
+// IsMax implements the Datum interface.
+func (d *DJsonpath) IsMax(ctx context.Context, cmpCtx CompareContext) bool {
+	return false
+}
+
+// IsMin implements the Datum interface.
+func (d *DJsonpath) IsMin(ctx context.Context, cmpCtx CompareContext) bool {
+	return false
+}
+
+// Max implements the Datum interface.
+func (d *DJsonpath) Max(ctx context.Context, cmpCtx CompareContext) (Datum, bool) {
+	return nil, false
+}
+
+// Min implements the Datum interface.
+func (d *DJsonpath) Min(ctx context.Context, cmpCtx CompareContext) (Datum, bool) {
+	return nil, false
+}
+
+// AmbiguousFormat implements the Datum interface.
+func (*DJsonpath) AmbiguousFormat() bool { return true }
+
+// Size implements the Datum interface.
+func (d *DJsonpath) Size() uintptr {
+	// TODO(#22513): add size method for JSONPath
+	return unsafe.Sizeof(*d)
+}
+
+// Format implements the NodeFormatter interface.
+func (d *DJsonpath) Format(ctx *FmtCtx) {
+	buf, f := &ctx.Buffer, ctx.flags
+	if f.HasFlags(fmtRawStrings) || f.HasFlags(fmtPgwireFormat) {
+		buf.WriteString(d.Jsonpath.String())
+	} else {
+		lexbase.EncodeSQLStringWithFlags(buf, d.Jsonpath.String(), f.EncodeFlags())
+	}
+}
+
+func ParseDJsonpath(s string) (Datum, error) {
+	jp, err := ValidateJSONPath(s)
+	if err != nil {
+		return nil, MakeParseError(s, types.Jsonpath, err)
+	}
+	return NewDJsonpath(*jp), nil
+}
+
+// AsDJsonpath attempts to retrieve a *DJsonpath from an Expr, returning a *DJsonpath and
+// a flag signifying whether the assertion was successful. The function should
+// be used instead of direct type assertions wherever a *DJsonpath wrapped by a
+// *DOidWrapper is possible.
+func AsDJsonpath(e Expr) (*DJsonpath, bool) {
+	switch t := e.(type) {
+	case *DJsonpath:
+		return t, true
+	case *DOidWrapper:
+		return AsDJsonpath(t.Wrapped)
+	}
+	return nil, false
+}
+
+// MustBeDJsonpath attempts to retrieve a DJsonpath from an Expr, panicking if the
+// assertion fails.
+func MustBeDJsonpath(e Expr) DJsonpath {
+	i, ok := AsDJsonpath(e)
+	if !ok {
+		panic(errors.AssertionFailedf("expected *DJsonpath, found %T", e))
+	}
+	return *i
+}
+
 // DJSON is the JSON Datum.
 type DJSON struct{ json.JSON }
 
@@ -4027,14 +4147,14 @@ func AsJSON(
 		// This is RFC3339Nano, but without the TZ fields.
 		return json.FromString(formatTime(t.UTC(), "2006-01-02T15:04:05.999999999")), nil
 	case *DDate, *DUuid, *DOid, *DInterval, *DBytes, *DIPAddr, *DTime, *DTimeTZ, *DBitArray, *DBox2D,
-		*DTSVector, *DTSQuery, *DPGLSN:
+		*DTSVector, *DTSQuery, *DPGLSN, *DPGVector:
 		return json.FromString(
 			AsStringWithFlags(t, FmtBareStrings, FmtDataConversionConfig(dcc), FmtLocation(loc)),
 		), nil
 	case *DGeometry:
-		return json.FromSpatialObject(t.Geometry.SpatialObject(), geo.DefaultGeoJSONDecimalDigits)
+		return t.ToJSON(geo.FullPrecisionGeoJSON)
 	case *DGeography:
-		return json.FromSpatialObject(t.Geography.SpatialObject(), geo.DefaultGeoJSONDecimalDigits)
+		return t.ToJSON(geo.FullPrecisionGeoJSON)
 	case *DVoid:
 		return json.FromString(AsStringWithFlags(t, fmtRawStrings)), nil
 	default:
@@ -4046,6 +4166,14 @@ func AsJSON(
 	}
 }
 
+func spatialObjectToJSON(so geopb.SpatialObject, maxDecimalDigits int) (json.JSON, error) {
+	j, err := geo.SpatialObjectToGeoJSON(so, maxDecimalDigits, geo.SpatialObjectToGeoJSONFlagZero)
+	if err != nil {
+		return nil, err
+	}
+	return json.ParseJSON(string(j))
+}
+
 // formatTime formats time with specified layout.
 // TODO(yuzefovich): consider using this function in more places.
 func formatTime(t time.Time, layout string) string {
@@ -4062,21 +4190,12 @@ func (*DJSON) ResolvedType() *types.T {
 }
 
 // Compare implements the Datum interface.
-func (d *DJSON) Compare(ctx CompareContext, other Datum) int {
-	res, err := d.CompareError(ctx, other)
-	if err != nil {
-		panic(err)
-	}
-	return res
-}
-
-// CompareError implements the Datum interface.
-func (d *DJSON) CompareError(ctx CompareContext, other Datum) (int, error) {
+func (d *DJSON) Compare(ctx context.Context, cmpCtx CompareContext, other Datum) (int, error) {
 	if other == DNull {
 		// NULL is less than any non-NULL value.
 		return 1, nil
 	}
-	v, ok := ctx.UnwrapDatum(other).(*DJSON)
+	v, ok := cmpCtx.UnwrapDatum(ctx, other).(*DJSON)
 	if !ok {
 		return 0, makeUnsupportedComparisonMessage(d, other)
 	}
@@ -4088,32 +4207,32 @@ func (d *DJSON) CompareError(ctx CompareContext, other Datum) (int, error) {
 }
 
 // Prev implements the Datum interface.
-func (d *DJSON) Prev(ctx CompareContext) (Datum, bool) {
+func (d *DJSON) Prev(ctx context.Context, cmpCtx CompareContext) (Datum, bool) {
 	return nil, false
 }
 
 // Next implements the Datum interface.
-func (d *DJSON) Next(ctx CompareContext) (Datum, bool) {
+func (d *DJSON) Next(ctx context.Context, cmpCtx CompareContext) (Datum, bool) {
 	return nil, false
 }
 
 // IsMax implements the Datum interface.
-func (d *DJSON) IsMax(ctx CompareContext) bool {
+func (d *DJSON) IsMax(ctx context.Context, cmpCtx CompareContext) bool {
 	return false
 }
 
 // IsMin implements the Datum interface.
-func (d *DJSON) IsMin(ctx CompareContext) bool {
+func (d *DJSON) IsMin(ctx context.Context, cmpCtx CompareContext) bool {
 	return d.JSON == json.NullJSONValue
 }
 
 // Max implements the Datum interface.
-func (d *DJSON) Max(ctx CompareContext) (Datum, bool) {
+func (d *DJSON) Max(ctx context.Context, cmpCtx CompareContext) (Datum, bool) {
 	return nil, false
 }
 
 // Min implements the Datum interface.
-func (d *DJSON) Min(ctx CompareContext) (Datum, bool) {
+func (d *DJSON) Min(ctx context.Context, cmpCtx CompareContext) (Datum, bool) {
 	return &DJSON{json.NullJSONValue}, true
 }
 
@@ -4170,21 +4289,12 @@ func (d *DTSQuery) ResolvedType() *types.T {
 func (d *DTSQuery) AmbiguousFormat() bool { return true }
 
 // Compare implements the Datum interface.
-func (d *DTSQuery) Compare(ctx CompareContext, other Datum) int {
-	res, err := d.CompareError(ctx, other)
-	if err != nil {
-		panic(err)
-	}
-	return res
-}
-
-// CompareError implements the Datum interface.
-func (d *DTSQuery) CompareError(ctx CompareContext, other Datum) (int, error) {
+func (d *DTSQuery) Compare(ctx context.Context, cmpCtx CompareContext, other Datum) (int, error) {
 	if other == DNull {
 		// NULL is less than any non-NULL value.
 		return 1, nil
 	}
-	v, ok := ctx.UnwrapDatum(other).(*DTSQuery)
+	v, ok := cmpCtx.UnwrapDatum(ctx, other).(*DTSQuery)
 	if !ok {
 		return 0, makeUnsupportedComparisonMessage(d, other)
 	}
@@ -4198,32 +4308,32 @@ func (d *DTSQuery) CompareError(ctx CompareContext, other Datum) (int, error) {
 }
 
 // Prev implements the Datum interface.
-func (d *DTSQuery) Prev(_ CompareContext) (Datum, bool) {
+func (d *DTSQuery) Prev(ctx context.Context, cmpCtx CompareContext) (Datum, bool) {
 	return nil, false
 }
 
 // Next implements the Datum interface.
-func (d *DTSQuery) Next(_ CompareContext) (Datum, bool) {
+func (d *DTSQuery) Next(ctx context.Context, cmpCtx CompareContext) (Datum, bool) {
 	return nil, false
 }
 
 // IsMin implements the Datum interface.
-func (d *DTSQuery) IsMin(_ CompareContext) bool {
+func (d *DTSQuery) IsMin(ctx context.Context, cmpCtx CompareContext) bool {
 	return len(d.String()) == 0
 }
 
 // IsMax implements the Datum interface.
-func (d *DTSQuery) IsMax(ctx CompareContext) bool {
+func (d *DTSQuery) IsMax(ctx context.Context, cmpCtx CompareContext) bool {
 	return false
 }
 
 // Max implements the Datum interface.
-func (d *DTSQuery) Max(ctx CompareContext) (Datum, bool) {
+func (d *DTSQuery) Max(ctx context.Context, cmpCtx CompareContext) (Datum, bool) {
 	return nil, false
 }
 
 // Min implements the Datum interface.
-func (d *DTSQuery) Min(ctx CompareContext) (Datum, bool) {
+func (d *DTSQuery) Min(ctx context.Context, cmpCtx CompareContext) (Datum, bool) {
 	return &DTSQuery{}, false
 }
 
@@ -4301,21 +4411,12 @@ func (d *DTSVector) ResolvedType() *types.T {
 func (d *DTSVector) AmbiguousFormat() bool { return true }
 
 // Compare implements the Datum interface.
-func (d *DTSVector) Compare(ctx CompareContext, other Datum) int {
-	res, err := d.CompareError(ctx, other)
-	if err != nil {
-		panic(err)
-	}
-	return res
-}
-
-// CompareError implements the Datum interface.
-func (d *DTSVector) CompareError(ctx CompareContext, other Datum) (int, error) {
+func (d *DTSVector) Compare(ctx context.Context, cmpCtx CompareContext, other Datum) (int, error) {
 	if other == DNull {
 		// NULL is less than any non-NULL value.
 		return 1, nil
 	}
-	v, ok := ctx.UnwrapDatum(other).(*DTSVector)
+	v, ok := cmpCtx.UnwrapDatum(ctx, other).(*DTSVector)
 	if !ok {
 		return 0, makeUnsupportedComparisonMessage(d, other)
 	}
@@ -4329,32 +4430,32 @@ func (d *DTSVector) CompareError(ctx CompareContext, other Datum) (int, error) {
 }
 
 // Prev implements the Datum interface.
-func (d *DTSVector) Prev(_ CompareContext) (Datum, bool) {
+func (d *DTSVector) Prev(ctx context.Context, cmpCtx CompareContext) (Datum, bool) {
 	return nil, false
 }
 
 // Next implements the Datum interface.
-func (d *DTSVector) Next(_ CompareContext) (Datum, bool) {
+func (d *DTSVector) Next(ctx context.Context, cmpCtx CompareContext) (Datum, bool) {
 	return nil, false
 }
 
 // IsMin implements the Datum interface.
-func (d *DTSVector) IsMin(_ CompareContext) bool {
+func (d *DTSVector) IsMin(ctx context.Context, cmpCtx CompareContext) bool {
 	return len(d.String()) == 0
 }
 
 // IsMax implements the Datum interface.
-func (d *DTSVector) IsMax(_ CompareContext) bool {
+func (d *DTSVector) IsMax(ctx context.Context, cmpCtx CompareContext) bool {
 	return false
 }
 
 // Max implements the Datum interface.
-func (d *DTSVector) Max(_ CompareContext) (Datum, bool) {
+func (d *DTSVector) Max(ctx context.Context, cmpCtx CompareContext) (Datum, bool) {
 	return nil, false
 }
 
 // Min implements the Datum interface.
-func (d *DTSVector) Min(_ CompareContext) (Datum, bool) {
+func (d *DTSVector) Min(ctx context.Context, cmpCtx CompareContext) (Datum, bool) {
 	return &DTSVector{}, false
 }
 
@@ -4481,21 +4582,12 @@ func (d *DTuple) ResolvedType() *types.T {
 }
 
 // Compare implements the Datum interface.
-func (d *DTuple) Compare(ctx CompareContext, other Datum) int {
-	res, err := d.CompareError(ctx, other)
-	if err != nil {
-		panic(err)
-	}
-	return res
-}
-
-// CompareError implements the Datum interface.
-func (d *DTuple) CompareError(ctx CompareContext, other Datum) (int, error) {
+func (d *DTuple) Compare(ctx context.Context, cmpCtx CompareContext, other Datum) (int, error) {
 	if other == DNull {
 		// NULL is less than any non-NULL value.
 		return 1, nil
 	}
-	v, ok := ctx.UnwrapDatum(other).(*DTuple)
+	v, ok := cmpCtx.UnwrapDatum(ctx, other).(*DTuple)
 	if !ok {
 		return 0, makeUnsupportedComparisonMessage(d, other)
 	}
@@ -4504,7 +4596,7 @@ func (d *DTuple) CompareError(ctx CompareContext, other Datum) (int, error) {
 		n = len(v.D)
 	}
 	for i := 0; i < n; i++ {
-		c, err := d.D[i].CompareError(ctx, v.D[i])
+		c, err := d.D[i].Compare(ctx, cmpCtx, v.D[i])
 		if err != nil {
 			return 0, errors.WithDetailf(err, "type mismatch at record column %d", redact.SafeInt(i+1))
 		}
@@ -4522,7 +4614,7 @@ func (d *DTuple) CompareError(ctx CompareContext, other Datum) (int, error) {
 }
 
 // Prev implements the Datum interface.
-func (d *DTuple) Prev(ctx CompareContext) (Datum, bool) {
+func (d *DTuple) Prev(ctx context.Context, cmpCtx CompareContext) (Datum, bool) {
 	// Note: (a:decimal, b:int, c:int) has a prev value; that's (a, b,
 	// c-1). With an exception if c is MinInt64, in which case the prev
 	// value is (a, b-1, max(_ *EvalContext)). However, (a:int, b:decimal) does not
@@ -4535,15 +4627,15 @@ func (d *DTuple) Prev(ctx CompareContext) (Datum, bool) {
 	res := NewDTupleWithLen(d.typ, len(d.D))
 	copy(res.D, d.D)
 	for i := len(res.D) - 1; i >= 0; i-- {
-		if !res.D[i].IsMin(ctx) {
-			prevVal, ok := res.D[i].Prev(ctx)
+		if !res.D[i].IsMin(ctx, cmpCtx) {
+			prevVal, ok := res.D[i].Prev(ctx, cmpCtx)
 			if !ok {
 				return nil, false
 			}
 			res.D[i] = prevVal
 			break
 		}
-		maxVal, ok := res.D[i].Max(ctx)
+		maxVal, ok := res.D[i].Max(ctx, cmpCtx)
 		if !ok {
 			return nil, false
 		}
@@ -4553,7 +4645,7 @@ func (d *DTuple) Prev(ctx CompareContext) (Datum, bool) {
 }
 
 // Next implements the Datum interface.
-func (d *DTuple) Next(ctx CompareContext) (Datum, bool) {
+func (d *DTuple) Next(ctx context.Context, cmpCtx CompareContext) (Datum, bool) {
 	// Note: (a:decimal, b:int, c:int) has a next value; that's (a, b,
 	// c+1). With an exception if c is MaxInt64, in which case the next
 	// value is (a, b+1, min(_ *EvalContext)). However, (a:int, b:decimal) does not
@@ -4566,8 +4658,8 @@ func (d *DTuple) Next(ctx CompareContext) (Datum, bool) {
 	res := NewDTupleWithLen(d.typ, len(d.D))
 	copy(res.D, d.D)
 	for i := len(res.D) - 1; i >= 0; i-- {
-		if !res.D[i].IsMax(ctx) {
-			nextVal, ok := res.D[i].Next(ctx)
+		if !res.D[i].IsMax(ctx, cmpCtx) {
+			nextVal, ok := res.D[i].Next(ctx, cmpCtx)
 			if !ok {
 				return nil, false
 			}
@@ -4581,10 +4673,10 @@ func (d *DTuple) Next(ctx CompareContext) (Datum, bool) {
 }
 
 // Max implements the Datum interface.
-func (d *DTuple) Max(ctx CompareContext) (Datum, bool) {
+func (d *DTuple) Max(ctx context.Context, cmpCtx CompareContext) (Datum, bool) {
 	res := NewDTupleWithLen(d.typ, len(d.D))
 	for i, v := range d.D {
-		m, ok := v.Max(ctx)
+		m, ok := v.Max(ctx, cmpCtx)
 		if !ok {
 			return nil, false
 		}
@@ -4594,10 +4686,10 @@ func (d *DTuple) Max(ctx CompareContext) (Datum, bool) {
 }
 
 // Min implements the Datum interface.
-func (d *DTuple) Min(ctx CompareContext) (Datum, bool) {
+func (d *DTuple) Min(ctx context.Context, cmpCtx CompareContext) (Datum, bool) {
 	res := NewDTupleWithLen(d.typ, len(d.D))
 	for i, v := range d.D {
-		m, ok := v.Min(ctx)
+		m, ok := v.Min(ctx, cmpCtx)
 		if !ok {
 			return nil, false
 		}
@@ -4607,9 +4699,9 @@ func (d *DTuple) Min(ctx CompareContext) (Datum, bool) {
 }
 
 // IsMax implements the Datum interface.
-func (d *DTuple) IsMax(ctx CompareContext) bool {
+func (d *DTuple) IsMax(ctx context.Context, cmpCtx CompareContext) bool {
 	for _, v := range d.D {
-		if !v.IsMax(ctx) {
+		if !v.IsMax(ctx, cmpCtx) {
 			return false
 		}
 	}
@@ -4617,9 +4709,9 @@ func (d *DTuple) IsMax(ctx CompareContext) bool {
 }
 
 // IsMin implements the Datum interface.
-func (d *DTuple) IsMin(ctx CompareContext) bool {
+func (d *DTuple) IsMin(ctx context.Context, cmpCtx CompareContext) bool {
 	for _, v := range d.D {
-		if !v.IsMin(ctx) {
+		if !v.IsMin(ctx, cmpCtx) {
 			return false
 		}
 	}
@@ -4715,7 +4807,9 @@ func (d *DTuple) AssertSorted() {
 // The target Datum cannot be NULL or a DTuple that contains NULLs (we cannot
 // binary search in this case; for example `(1, NULL) IN ((1, 2), ..)` needs to
 // be
-func (d *DTuple) SearchSorted(ctx CompareContext, target Datum) (int, bool) {
+func (d *DTuple) SearchSorted(
+	ctx context.Context, cmpCtx CompareContext, target Datum,
+) (int, bool) {
 	d.AssertSorted()
 	if target == DNull {
 		panic(errors.AssertionFailedf("NULL target (d: %s)", d))
@@ -4724,38 +4818,59 @@ func (d *DTuple) SearchSorted(ctx CompareContext, target Datum) (int, bool) {
 		panic(errors.AssertionFailedf("target containing NULLs: %#v (d: %s)", target, d))
 	}
 	i := sort.Search(len(d.D), func(i int) bool {
-		return d.D[i].Compare(ctx, target) >= 0
+		cmp, err := d.D[i].Compare(ctx, cmpCtx, target)
+		if err != nil {
+			panic(err)
+		}
+		return cmp >= 0
 	})
-	found := i < len(d.D) && d.D[i].Compare(ctx, target) == 0
+	var found bool
+	if i < len(d.D) {
+		cmp, err := d.D[i].Compare(ctx, cmpCtx, target)
+		if err != nil {
+			panic(err)
+		}
+		found = cmp == 0
+	}
 	return i, found
 }
 
 // Normalize sorts and uniques the datum tuple.
-func (d *DTuple) Normalize(ctx CompareContext) {
-	d.sort(ctx)
-	d.makeUnique(ctx)
+func (d *DTuple) Normalize(ctx context.Context, cmpCtx CompareContext) {
+	d.sort(ctx, cmpCtx)
+	d.makeUnique(ctx, cmpCtx)
 }
 
-func (d *DTuple) sort(ctx CompareContext) {
+func (d *DTuple) sort(ctx context.Context, cmpCtx CompareContext) {
 	if !d.sorted {
-		lessFn := func(i, j int) bool {
-			return d.D[i].Compare(ctx, d.D[j]) < 0
+		sortFn := func(a, b Datum) int {
+			cmp, err := a.Compare(ctx, cmpCtx, b)
+			if err != nil {
+				panic(err)
+			}
+			return cmp
 		}
 
 		// It is possible for the tuple to be sorted even though the sorted flag
 		// is not true. So before we perform the sort we check that it is not
 		// already sorted.
-		if !sort.SliceIsSorted(d.D, lessFn) {
-			sort.Slice(d.D, lessFn)
+		if !slices.IsSortedFunc(d.D, sortFn) {
+			slices.SortFunc(d.D, sortFn)
 		}
 		d.SetSorted()
 	}
 }
 
-func (d *DTuple) makeUnique(ctx CompareContext) {
-	n := 0
-	for i := 0; i < len(d.D); i++ {
-		if n == 0 || d.D[n-1].Compare(ctx, d.D[i]) < 0 {
+func (d *DTuple) makeUnique(ctx context.Context, cmpCtx CompareContext) {
+	if len(d.D) == 0 {
+		return
+	}
+	n := 1 // always keep the first element
+	for i := 1; i < len(d.D); i++ {
+		cmp, err := d.D[n-1].Compare(ctx, cmpCtx, d.D[i])
+		if err != nil {
+			panic(err)
+		} else if cmp < 0 {
 			d.D[n] = d.D[i]
 			n++
 		}
@@ -4801,16 +4916,7 @@ func (dNull) ResolvedType() *types.T {
 }
 
 // Compare implements the Datum interface.
-func (d dNull) Compare(ctx CompareContext, other Datum) int {
-	res, err := d.CompareError(ctx, other)
-	if err != nil {
-		panic(err)
-	}
-	return res
-}
-
-// CompareError implements the Datum interface.
-func (d dNull) CompareError(ctx CompareContext, other Datum) (int, error) {
+func (d dNull) Compare(ctx context.Context, cmpCtx CompareContext, other Datum) (int, error) {
 	if other == DNull {
 		return 0, nil
 	}
@@ -4818,32 +4924,32 @@ func (d dNull) CompareError(ctx CompareContext, other Datum) (int, error) {
 }
 
 // Prev implements the Datum interface.
-func (d dNull) Prev(ctx CompareContext) (Datum, bool) {
+func (d dNull) Prev(ctx context.Context, cmpCtx CompareContext) (Datum, bool) {
 	return nil, false
 }
 
 // Next implements the Datum interface.
-func (d dNull) Next(ctx CompareContext) (Datum, bool) {
+func (d dNull) Next(ctx context.Context, cmpCtx CompareContext) (Datum, bool) {
 	return nil, false
 }
 
 // IsMax implements the Datum interface.
-func (dNull) IsMax(ctx CompareContext) bool {
+func (dNull) IsMax(ctx context.Context, cmpCtx CompareContext) bool {
 	return true
 }
 
 // IsMin implements the Datum interface.
-func (dNull) IsMin(ctx CompareContext) bool {
+func (dNull) IsMin(ctx context.Context, cmpCtx CompareContext) bool {
 	return true
 }
 
 // Max implements the Datum interface.
-func (dNull) Max(ctx CompareContext) (Datum, bool) {
+func (dNull) Max(ctx context.Context, cmpCtx CompareContext) (Datum, bool) {
 	return DNull, true
 }
 
 // Min implements the Datum interface.
-func (dNull) Min(ctx CompareContext) (Datum, bool) {
+func (dNull) Min(ctx context.Context, cmpCtx CompareContext) (Datum, bool) {
 	return DNull, true
 }
 
@@ -4960,21 +5066,12 @@ func (d *DArray) FirstIndex() int {
 }
 
 // Compare implements the Datum interface.
-func (d *DArray) Compare(ctx CompareContext, other Datum) int {
-	res, err := d.CompareError(ctx, other)
-	if err != nil {
-		panic(err)
-	}
-	return res
-}
-
-// CompareError implements the Datum interface.
-func (d *DArray) CompareError(ctx CompareContext, other Datum) (int, error) {
+func (d *DArray) Compare(ctx context.Context, cmpCtx CompareContext, other Datum) (int, error) {
 	if other == DNull {
 		// NULL is less than any non-NULL value.
 		return 1, nil
 	}
-	v, ok := ctx.UnwrapDatum(other).(*DArray)
+	v, ok := cmpCtx.UnwrapDatum(ctx, other).(*DArray)
 	if !ok {
 		return 0, makeUnsupportedComparisonMessage(d, other)
 	}
@@ -4983,7 +5080,7 @@ func (d *DArray) CompareError(ctx CompareContext, other Datum) (int, error) {
 		n = v.Len()
 	}
 	for i := 0; i < n; i++ {
-		c, err := d.Array[i].CompareError(ctx, v.Array[i])
+		c, err := d.Array[i].Compare(ctx, cmpCtx, v.Array[i])
 		if err != nil {
 			return 0, err
 		}
@@ -5001,12 +5098,12 @@ func (d *DArray) CompareError(ctx CompareContext, other Datum) (int, error) {
 }
 
 // Prev implements the Datum interface.
-func (d *DArray) Prev(ctx CompareContext) (Datum, bool) {
+func (d *DArray) Prev(ctx context.Context, cmpCtx CompareContext) (Datum, bool) {
 	return nil, false
 }
 
 // Next implements the Datum interface.
-func (d *DArray) Next(ctx CompareContext) (Datum, bool) {
+func (d *DArray) Next(ctx context.Context, cmpCtx CompareContext) (Datum, bool) {
 	a := DArray{ParamTyp: d.ParamTyp, Array: make(Datums, d.Len()+1)}
 	copy(a.Array, d.Array)
 	a.Array[len(a.Array)-1] = DNull
@@ -5014,22 +5111,22 @@ func (d *DArray) Next(ctx CompareContext) (Datum, bool) {
 }
 
 // Max implements the Datum interface.
-func (d *DArray) Max(ctx CompareContext) (Datum, bool) {
+func (d *DArray) Max(ctx context.Context, cmpCtx CompareContext) (Datum, bool) {
 	return nil, false
 }
 
 // Min implements the Datum interface.
-func (d *DArray) Min(ctx CompareContext) (Datum, bool) {
+func (d *DArray) Min(ctx context.Context, cmpCtx CompareContext) (Datum, bool) {
 	return &DArray{ParamTyp: d.ParamTyp}, true
 }
 
 // IsMax implements the Datum interface.
-func (d *DArray) IsMax(ctx CompareContext) bool {
+func (d *DArray) IsMax(ctx context.Context, cmpCtx CompareContext) bool {
 	return false
 }
 
 // IsMin implements the Datum interface.
-func (d *DArray) IsMin(ctx CompareContext) bool {
+func (d *DArray) IsMin(ctx context.Context, cmpCtx CompareContext) bool {
 	return d.Len() == 0
 }
 
@@ -5048,7 +5145,10 @@ func (d *DArray) AmbiguousFormat() bool {
 
 // Format implements the NodeFormatter interface.
 func (d *DArray) Format(ctx *FmtCtx) {
-	if ctx.flags.HasAnyFlags(fmtPgwireFormat | FmtPGCatalog) {
+	if ctx.flags.HasAnyFlags(fmtPgwireFormat | fmtPGCatalog) {
+		defer func(f FmtFlags) { ctx.flags = f }(ctx.flags)
+		ctx.flags = ctx.flags & ^fmtPGCatalogCasts
+		ctx.flags = ctx.flags | FmtBareStrings
 		d.pgwireFormat(ctx)
 		return
 	}
@@ -5151,22 +5251,13 @@ func (*DVoid) ResolvedType() *types.T {
 }
 
 // Compare implements the Datum interface.
-func (d *DVoid) Compare(ctx CompareContext, other Datum) int {
-	ret, err := d.CompareError(ctx, other)
-	if err != nil {
-		panic(err)
-	}
-	return ret
-}
-
-// CompareError implements the Datum interface.
-func (d *DVoid) CompareError(ctx CompareContext, other Datum) (int, error) {
+func (d *DVoid) Compare(ctx context.Context, cmpCtx CompareContext, other Datum) (int, error) {
 	if other == DNull {
 		// NULL is less than any non-NULL value.
 		return 1, nil
 	}
 
-	_, ok := ctx.UnwrapDatum(other).(*DVoid)
+	_, ok := cmpCtx.UnwrapDatum(ctx, other).(*DVoid)
 	if !ok {
 		return 0, makeUnsupportedComparisonMessage(d, other)
 	}
@@ -5174,32 +5265,32 @@ func (d *DVoid) CompareError(ctx CompareContext, other Datum) (int, error) {
 }
 
 // Prev implements the Datum interface.
-func (d *DVoid) Prev(ctx CompareContext) (Datum, bool) {
+func (d *DVoid) Prev(ctx context.Context, cmpCtx CompareContext) (Datum, bool) {
 	return nil, false
 }
 
 // Next implements the Datum interface.
-func (d *DVoid) Next(ctx CompareContext) (Datum, bool) {
+func (d *DVoid) Next(ctx context.Context, cmpCtx CompareContext) (Datum, bool) {
 	return nil, false
 }
 
 // IsMax implements the Datum interface.
-func (d *DVoid) IsMax(ctx CompareContext) bool {
+func (d *DVoid) IsMax(ctx context.Context, cmpCtx CompareContext) bool {
 	return false
 }
 
 // IsMin implements the Datum interface.
-func (d *DVoid) IsMin(ctx CompareContext) bool {
+func (d *DVoid) IsMin(ctx context.Context, cmpCtx CompareContext) bool {
 	return false
 }
 
 // Max implements the Datum interface.
-func (d *DVoid) Max(ctx CompareContext) (Datum, bool) {
+func (d *DVoid) Max(ctx context.Context, cmpCtx CompareContext) (Datum, bool) {
 	return nil, false
 }
 
 // Min implements the Datum interface.
-func (d *DVoid) Min(ctx CompareContext) (Datum, bool) {
+func (d *DVoid) Min(ctx context.Context, cmpCtx CompareContext) (Datum, bool) {
 	return nil, false
 }
 
@@ -5369,30 +5460,46 @@ func (d *DEnum) ResolvedType() *types.T {
 	return d.EnumTyp
 }
 
-// Compare implements the Datum interface.
-func (d *DEnum) Compare(ctx CompareContext, other Datum) int {
-	res, err := d.CompareError(ctx, other)
-	if err != nil {
-		panic(err)
-	}
-	return res
-}
+// PlanGistFromCtx returns the plan gist if it is stored in the context. It is
+// injected from the sql package to avoid import cycle.
+var PlanGistFromCtx func(context.Context) string
 
-// CompareError implements the Datum interface.
-func (d *DEnum) CompareError(ctx CompareContext, other Datum) (int, error) {
+// Compare implements the Datum interface.
+func (d *DEnum) Compare(ctx context.Context, cmpCtx CompareContext, other Datum) (int, error) {
 	if other == DNull {
 		return 1, nil
 	}
-	v, ok := ctx.UnwrapDatum(other).(*DEnum)
+	v, ok := cmpCtx.UnwrapDatum(ctx, other).(*DEnum)
 	if !ok {
 		return 0, makeUnsupportedComparisonMessage(d, other)
 	}
+
+	// Different enums count as different types.
+	if v.EnumTyp.Oid() != d.EnumTyp.Oid() {
+		return 0, makeUnsupportedComparisonMessage(d, other)
+	}
+
+	// We should never be comparing two different versions of the same enum.
+	if v.EnumTyp.TypeMeta.Version != d.EnumTyp.TypeMeta.Version {
+		var gist redact.SafeString
+		if PlanGistFromCtx != nil {
+			// Plan gist, by construction, doesn't contain any PII, so it's a
+			// safe string.
+			gist = redact.SafeString(PlanGistFromCtx(ctx))
+		}
+		return 0, errors.AssertionFailedf(
+			"comparison of two different versions of enum %s oid %d: versions %d and %d, gist %q",
+			d.EnumTyp.SQLStringForError(), errors.Safe(d.EnumTyp.Oid()), d.EnumTyp.TypeMeta.Version,
+			v.EnumTyp.TypeMeta.Version, gist,
+		)
+	}
+
 	res := bytes.Compare(d.PhysicalRep, v.PhysicalRep)
 	return res, nil
 }
 
 // Prev implements the Datum interface.
-func (d *DEnum) Prev(ctx CompareContext) (Datum, bool) {
+func (d *DEnum) Prev(ctx context.Context, cmpCtx CompareContext) (Datum, bool) {
 	idx, err := d.EnumTyp.EnumGetIdxOfPhysical(d.PhysicalRep)
 	if err != nil {
 		panic(err)
@@ -5409,7 +5516,7 @@ func (d *DEnum) Prev(ctx CompareContext) (Datum, bool) {
 }
 
 // Next implements the Datum interface.
-func (d *DEnum) Next(ctx CompareContext) (Datum, bool) {
+func (d *DEnum) Next(ctx context.Context, cmpCtx CompareContext) (Datum, bool) {
 	idx, err := d.EnumTyp.EnumGetIdxOfPhysical(d.PhysicalRep)
 	if err != nil {
 		panic(err)
@@ -5426,7 +5533,7 @@ func (d *DEnum) Next(ctx CompareContext) (Datum, bool) {
 }
 
 // Max implements the Datum interface.
-func (d *DEnum) Max(ctx CompareContext) (Datum, bool) {
+func (d *DEnum) Max(ctx context.Context, cmpCtx CompareContext) (Datum, bool) {
 	enumData := d.EnumTyp.TypeMeta.EnumData
 	if len(enumData.PhysicalRepresentations) == 0 {
 		return nil, false
@@ -5440,7 +5547,7 @@ func (d *DEnum) Max(ctx CompareContext) (Datum, bool) {
 }
 
 // Min implements the Datum interface.
-func (d *DEnum) Min(ctx CompareContext) (Datum, bool) {
+func (d *DEnum) Min(ctx context.Context, cmpCtx CompareContext) (Datum, bool) {
 	enumData := d.EnumTyp.TypeMeta.EnumData
 	if len(enumData.PhysicalRepresentations) == 0 {
 		return nil, false
@@ -5453,7 +5560,7 @@ func (d *DEnum) Min(ctx CompareContext) (Datum, bool) {
 }
 
 // IsMax implements the Datum interface.
-func (d *DEnum) IsMax(ctx CompareContext) bool {
+func (d *DEnum) IsMax(ctx context.Context, cmpCtx CompareContext) bool {
 	physReps := d.EnumTyp.TypeMeta.EnumData.PhysicalRepresentations
 	idx, err := d.EnumTyp.EnumGetIdxOfPhysical(d.PhysicalRep)
 	if err != nil {
@@ -5463,7 +5570,7 @@ func (d *DEnum) IsMax(ctx CompareContext) bool {
 }
 
 // IsMin implements the Datum interface.
-func (d *DEnum) IsMin(ctx CompareContext) bool {
+func (d *DEnum) IsMin(ctx context.Context, cmpCtx CompareContext) bool {
 	idx, err := d.EnumTyp.EnumGetIdxOfPhysical(d.PhysicalRep)
 	if err != nil {
 		panic(err)
@@ -5526,15 +5633,24 @@ type DOid struct {
 	name string
 }
 
-// IntToOid is a helper that turns a DInt into a *DOid and checks that the value
-// is in range.
-func IntToOid(i DInt) (*DOid, error) {
+const (
+	// UnknownOidName represents the 0 oid value as '-' for types other than T_oid
+	// in the oid family, which matches the Postgres representation.
+	UnknownOidName = "-"
+
+	// UnknownOidValue is the 0 (unknown) oid value.
+	UnknownOidValue = oid.Oid(0)
+)
+
+// IntToOid is a helper that turns a DInt into an oid.Oid and checks that the
+// value is in range.
+func IntToOid(i DInt) (oid.Oid, error) {
 	if intIsOutOfOIDRange(i) {
-		return nil, pgerror.Newf(
+		return 0, pgerror.Newf(
 			pgcode.NumericValueOutOfRange, "OID out of range: %d", i,
 		)
 	}
-	return NewDOid(oid.Oid(i)), nil
+	return oid.Oid(i), nil
 }
 
 func intIsOutOfOIDRange(i DInt) bool {
@@ -5548,22 +5664,20 @@ func MakeDOid(d oid.Oid, semanticType *types.T) DOid {
 
 // NewDOidWithType constructs a DOid with the given type and no name.
 func NewDOidWithType(d oid.Oid, semanticType *types.T) *DOid {
-	oid := DOid{Oid: d, semanticType: semanticType}
-	return &oid
+	return &DOid{Oid: d, semanticType: semanticType}
 }
 
 // NewDOidWithTypeAndName constructs a DOid with the given type and name.
 func NewDOidWithTypeAndName(d oid.Oid, semanticType *types.T, name string) *DOid {
-	oid := DOid{Oid: d, semanticType: semanticType, name: name}
-	return &oid
+	return &DOid{Oid: d, semanticType: semanticType, name: name}
 }
 
 // NewDOid is a helper routine to create a *DOid initialized from a DInt.
 func NewDOid(d oid.Oid) *DOid {
 	// TODO(yuzefovich): audit the callers of NewDOid to see whether any want to
 	// create a DOid with a semantic type different from types.Oid.
-	oid := MakeDOid(d, types.Oid)
-	return &oid
+	oidDatum := MakeDOid(d, types.Oid)
+	return &oidDatum
 }
 
 // AsDOid attempts to retrieve a DOid from an Expr, returning a DOid and
@@ -5590,16 +5704,6 @@ func MustBeDOid(e Expr) *DOid {
 	return i
 }
 
-// NewDOidWithName is a helper routine to create a *DOid initialized from a DInt
-// and a string.
-func NewDOidWithName(d oid.Oid, typ *types.T, name string) *DOid {
-	return &DOid{
-		Oid:          d,
-		semanticType: typ,
-		name:         name,
-	}
-}
-
 // AsRegProc changes the input DOid into a regproc with the given name and
 // returns it.
 func (d *DOid) AsRegProc(name string) *DOid {
@@ -5612,33 +5716,24 @@ func (d *DOid) AsRegProc(name string) *DOid {
 func (*DOid) AmbiguousFormat() bool { return true }
 
 // Compare implements the Datum interface.
-func (d *DOid) Compare(ctx CompareContext, other Datum) int {
-	res, err := d.CompareError(ctx, other)
-	if err != nil {
-		panic(err)
-	}
-	return res
-}
-
-// CompareError implements the Datum interface.
-func (d *DOid) CompareError(ctx CompareContext, other Datum) (int, error) {
+func (d *DOid) Compare(ctx context.Context, cmpCtx CompareContext, other Datum) (int, error) {
 	if other == DNull {
 		// NULL is less than any non-NULL value.
 		return 1, nil
 	}
 	var v oid.Oid
-	switch t := ctx.UnwrapDatum(other).(type) {
+	switch t := cmpCtx.UnwrapDatum(ctx, other).(type) {
 	case *DOid:
 		v = t.Oid
 	case *DInt:
 		// OIDs are always unsigned 32-bit integers. Some languages, like Java,
 		// compare OIDs to signed 32-bit integers, so we implement the comparison
 		// by converting to a uint32 first. This matches Postgres behavior.
-		o, err := IntToOid(*t)
+		var err error
+		v, err = IntToOid(*t)
 		if err != nil {
 			return 0, err
 		}
-		v = o.Oid
 	default:
 		return 0, makeUnsupportedComparisonMessage(d, other)
 	}
@@ -5654,7 +5749,10 @@ func (d *DOid) CompareError(ctx CompareContext, other Datum) (int, error) {
 
 // Format implements the Datum interface.
 func (d *DOid) Format(ctx *FmtCtx) {
-	if d.semanticType.Oid() == oid.T_oid || d.name == "" {
+	if ctx.HasFlags(FmtPgwireText) && d.semanticType.Oid() != oid.T_oid && d.Oid == UnknownOidValue {
+		// Special case for the "unknown" oid.
+		ctx.WriteString(UnknownOidName)
+	} else if d.semanticType.Oid() == oid.T_oid || d.name == "" {
 		ctx.Write(strconv.AppendUint(ctx.scratch[:0], uint64(d.Oid), 10))
 	} else if ctx.HasFlags(fmtDisambiguateDatumTypes) {
 		ctx.WriteString("crdb_internal.create_")
@@ -5672,23 +5770,23 @@ func (d *DOid) Format(ctx *FmtCtx) {
 }
 
 // IsMax implements the Datum interface.
-func (d *DOid) IsMax(ctx CompareContext) bool {
+func (d *DOid) IsMax(ctx context.Context, cmpCtx CompareContext) bool {
 	return d.Oid == math.MaxUint32
 }
 
 // IsMin implements the Datum interface.
-func (d *DOid) IsMin(ctx CompareContext) bool {
+func (d *DOid) IsMin(ctx context.Context, cmpCtx CompareContext) bool {
 	return d.Oid == 0
 }
 
 // Next implements the Datum interface.
-func (d *DOid) Next(ctx CompareContext) (Datum, bool) {
+func (d *DOid) Next(ctx context.Context, cmpCtx CompareContext) (Datum, bool) {
 	next := d.Oid + 1
 	return &DOid{next, d.semanticType, ""}, true
 }
 
 // Prev implements the Datum interface.
-func (d *DOid) Prev(ctx CompareContext) (Datum, bool) {
+func (d *DOid) Prev(ctx context.Context, cmpCtx CompareContext) (Datum, bool) {
 	prev := d.Oid - 1
 	return &DOid{prev, d.semanticType, ""}, true
 }
@@ -5702,12 +5800,12 @@ func (d *DOid) ResolvedType() *types.T {
 func (d *DOid) Size() uintptr { return unsafe.Sizeof(*d) }
 
 // Max implements the Datum interface.
-func (d *DOid) Max(ctx CompareContext) (Datum, bool) {
+func (d *DOid) Max(ctx context.Context, cmpCtx CompareContext) (Datum, bool) {
 	return &DOid{math.MaxUint32, d.semanticType, ""}, true
 }
 
 // Min implements the Datum interface.
-func (d *DOid) Min(ctx CompareContext) (Datum, bool) {
+func (d *DOid) Min(ctx context.Context, cmpCtx CompareContext) (Datum, bool) {
 	return &DOid{0, d.semanticType, ""}, true
 }
 
@@ -5738,10 +5836,6 @@ type DOidWrapper struct {
 	Oid     oid.Oid
 }
 
-// ZeroOidValue represents the 0 oid value as '-', which matches the Postgres
-// representation.
-const ZeroOidValue = "-"
-
 // wrapWithOid wraps a Datum with a custom Oid.
 func wrapWithOid(d Datum, oid oid.Oid) Datum {
 	switch v := d.(type) {
@@ -5765,16 +5859,6 @@ func wrapWithOid(d Datum, oid oid.Oid) Datum {
 	}
 }
 
-// WrapAsZeroOid wraps ZeroOidValue with a custom Oid.
-func WrapAsZeroOid(t *types.T) Datum {
-	tmpOid := NewDOid(0)
-	tmpOid.semanticType = t
-	if t.Oid() != oid.T_oid {
-		tmpOid.name = ZeroOidValue
-	}
-	return tmpOid
-}
-
 // UnwrapDOidWrapper exposes the wrapped datum from a *DOidWrapper.
 func UnwrapDOidWrapper(d Datum) Datum {
 	if w, ok := d.(*DOidWrapper); ok {
@@ -5789,57 +5873,50 @@ func (d *DOidWrapper) ResolvedType() *types.T {
 }
 
 // Compare implements the Datum interface.
-func (d *DOidWrapper) Compare(ctx CompareContext, other Datum) int {
-	res, err := d.CompareError(ctx, other)
-	if err != nil {
-		panic(err)
-	}
-	return res
-}
-
-// CompareError implements the Datum interface.
-func (d *DOidWrapper) CompareError(ctx CompareContext, other Datum) (int, error) {
+func (d *DOidWrapper) Compare(
+	ctx context.Context, cmpCtx CompareContext, other Datum,
+) (int, error) {
 	if other == DNull {
 		// NULL is less than any non-NULL value.
 		return 1, nil
 	}
 	if v, ok := other.(*DOidWrapper); ok {
-		return d.Wrapped.CompareError(ctx, v.Wrapped)
+		return d.Wrapped.Compare(ctx, cmpCtx, v.Wrapped)
 	}
-	return d.Wrapped.CompareError(ctx, other)
+	return d.Wrapped.Compare(ctx, cmpCtx, other)
 }
 
 // Prev implements the Datum interface.
-func (d *DOidWrapper) Prev(ctx CompareContext) (Datum, bool) {
-	prev, ok := d.Wrapped.Prev(ctx)
+func (d *DOidWrapper) Prev(ctx context.Context, cmpCtx CompareContext) (Datum, bool) {
+	prev, ok := d.Wrapped.Prev(ctx, cmpCtx)
 	return wrapWithOid(prev, d.Oid), ok
 }
 
 // Next implements the Datum interface.
-func (d *DOidWrapper) Next(ctx CompareContext) (Datum, bool) {
-	next, ok := d.Wrapped.Next(ctx)
+func (d *DOidWrapper) Next(ctx context.Context, cmpCtx CompareContext) (Datum, bool) {
+	next, ok := d.Wrapped.Next(ctx, cmpCtx)
 	return wrapWithOid(next, d.Oid), ok
 }
 
 // IsMax implements the Datum interface.
-func (d *DOidWrapper) IsMax(ctx CompareContext) bool {
-	return d.Wrapped.IsMax(ctx)
+func (d *DOidWrapper) IsMax(ctx context.Context, cmpCtx CompareContext) bool {
+	return d.Wrapped.IsMax(ctx, cmpCtx)
 }
 
 // IsMin implements the Datum interface.
-func (d *DOidWrapper) IsMin(ctx CompareContext) bool {
-	return d.Wrapped.IsMin(ctx)
+func (d *DOidWrapper) IsMin(ctx context.Context, cmpCtx CompareContext) bool {
+	return d.Wrapped.IsMin(ctx, cmpCtx)
 }
 
 // Max implements the Datum interface.
-func (d *DOidWrapper) Max(ctx CompareContext) (Datum, bool) {
-	max, ok := d.Wrapped.Max(ctx)
+func (d *DOidWrapper) Max(ctx context.Context, cmpCtx CompareContext) (Datum, bool) {
+	max, ok := d.Wrapped.Max(ctx, cmpCtx)
 	return wrapWithOid(max, d.Oid), ok
 }
 
 // Min implements the Datum interface.
-func (d *DOidWrapper) Min(ctx CompareContext) (Datum, bool) {
-	min, ok := d.Wrapped.Min(ctx)
+func (d *DOidWrapper) Min(ctx context.Context, cmpCtx CompareContext) (Datum, bool) {
+	min, ok := d.Wrapped.Min(ctx, cmpCtx)
 	return wrapWithOid(min, d.Oid), ok
 }
 
@@ -5869,47 +5946,40 @@ func (d *Placeholder) AmbiguousFormat() bool {
 }
 
 // Compare implements the Datum interface.
-func (d *Placeholder) Compare(ctx CompareContext, other Datum) int {
-	res, err := d.CompareError(ctx, other)
-	if err != nil {
-		panic(err)
-	}
-	return res
-}
-
-// CompareError implements the Datum interface.
-func (d *Placeholder) CompareError(ctx CompareContext, other Datum) (int, error) {
-	return ctx.MustGetPlaceholderValue(d).CompareError(ctx, other)
+func (d *Placeholder) Compare(
+	ctx context.Context, cmpCtx CompareContext, other Datum,
+) (int, error) {
+	return cmpCtx.MustGetPlaceholderValue(ctx, d).Compare(ctx, cmpCtx, other)
 }
 
 // Prev implements the Datum interface.
-func (d *Placeholder) Prev(ctx CompareContext) (Datum, bool) {
-	return ctx.MustGetPlaceholderValue(d).Prev(ctx)
+func (d *Placeholder) Prev(ctx context.Context, cmpCtx CompareContext) (Datum, bool) {
+	return cmpCtx.MustGetPlaceholderValue(ctx, d).Prev(ctx, cmpCtx)
 }
 
 // IsMin implements the Datum interface.
-func (d *Placeholder) IsMin(ctx CompareContext) bool {
-	return ctx.MustGetPlaceholderValue(d).IsMin(ctx)
+func (d *Placeholder) IsMin(ctx context.Context, cmpCtx CompareContext) bool {
+	return cmpCtx.MustGetPlaceholderValue(ctx, d).IsMin(ctx, cmpCtx)
 }
 
 // Next implements the Datum interface.
-func (d *Placeholder) Next(ctx CompareContext) (Datum, bool) {
-	return ctx.MustGetPlaceholderValue(d).Next(ctx)
+func (d *Placeholder) Next(ctx context.Context, cmpCtx CompareContext) (Datum, bool) {
+	return cmpCtx.MustGetPlaceholderValue(ctx, d).Next(ctx, cmpCtx)
 }
 
 // IsMax implements the Datum interface.
-func (d *Placeholder) IsMax(ctx CompareContext) bool {
-	return ctx.MustGetPlaceholderValue(d).IsMax(ctx)
+func (d *Placeholder) IsMax(ctx context.Context, cmpCtx CompareContext) bool {
+	return cmpCtx.MustGetPlaceholderValue(ctx, d).IsMax(ctx, cmpCtx)
 }
 
 // Max implements the Datum interface.
-func (d *Placeholder) Max(ctx CompareContext) (Datum, bool) {
-	return ctx.MustGetPlaceholderValue(d).Max(ctx)
+func (d *Placeholder) Max(ctx context.Context, cmpCtx CompareContext) (Datum, bool) {
+	return cmpCtx.MustGetPlaceholderValue(ctx, d).Max(ctx, cmpCtx)
 }
 
 // Min implements the Datum interface.
-func (d *Placeholder) Min(ctx CompareContext) (Datum, bool) {
-	return ctx.MustGetPlaceholderValue(d).Min(ctx)
+func (d *Placeholder) Min(ctx context.Context, cmpCtx CompareContext) (Datum, bool) {
+	return cmpCtx.MustGetPlaceholderValue(ctx, d).Min(ctx, cmpCtx)
 }
 
 // Size implements the Datum interface.
@@ -5945,7 +6015,7 @@ func NewDRefCursor(d string) Datum {
 // initialized from an existing *DArray, with the special oid for IntVector.
 func NewDIntVectorFromDArray(d *DArray) Datum {
 	// Sanity: Validate the type of the array, since it should be int2.
-	if d.ParamTyp != types.Int2 {
+	if !d.ParamTyp.Identical(types.Int2) {
 		panic(errors.AssertionFailedf("int2vector can only be made from int2 not %s", d.ParamTyp.SQLStringForError()))
 	}
 	ret := new(DArray)
@@ -5991,7 +6061,7 @@ func NewDefaultDatum(collationEnv *CollationEnvironment, t *types.T) (d Datum, e
 	case types.CollatedStringFamily:
 		return NewDCollatedString("", t.Locale(), collationEnv)
 	case types.OidFamily:
-		return NewDOidWithName(t.Oid(), t, t.SQLStandardName()), nil
+		return NewDOidWithTypeAndName(t.Oid(), t, t.SQLStandardName()), nil
 	case types.UnknownFamily:
 		return DNull, nil
 	case types.UuidFamily:
@@ -6045,6 +6115,9 @@ func NewDefaultDatum(collationEnv *CollationEnvironment, t *types.T) (d Datum, e
 		}
 		return NewDEnum(e), nil
 	default:
+		// TODO(yuzefovich): think through whether we want to explicitly return
+		// FeatureNotSupported error for types like TSQuery, TSVector, PGVector,
+		// Jsonpath, etc that don't have a minimum value.
 		return nil, errors.AssertionFailedf("unhandled type %s", t.SQLStringForError())
 	}
 }
@@ -6062,6 +6135,9 @@ func PGWireTypeSize(t *types.T) int {
 	if tOid == oid.T_date {
 		return 4
 	}
+	if tOid == oid.T_trigger {
+		return 4
+	}
 	if sz, variable := DatumTypeSize(t); !variable {
 		return int(sz)
 	}
@@ -6135,6 +6211,7 @@ var baseDatumTypeSizes = map[types.Family]struct {
 	types.GeographyFamily:      {unsafe.Sizeof(DGeography{}), variableSize},
 	types.GeometryFamily:       {unsafe.Sizeof(DGeometry{}), variableSize},
 	types.PGLSNFamily:          {unsafe.Sizeof(DPGLSN{}), fixedSize},
+	types.PGVectorFamily:       {unsafe.Sizeof(DPGVector{}), variableSize},
 	types.RefCursorFamily:      {unsafe.Sizeof(DString("")), variableSize},
 	types.TimeFamily:           {unsafe.Sizeof(DTime(0)), fixedSize},
 	types.TimeTZFamily:         {unsafe.Sizeof(DTimeTZ{}), fixedSize},
@@ -6144,6 +6221,7 @@ var baseDatumTypeSizes = map[types.Family]struct {
 	types.TSVectorFamily:       {unsafe.Sizeof(DTSVector{}), variableSize},
 	types.IntervalFamily:       {unsafe.Sizeof(DInterval{}), fixedSize},
 	types.JsonFamily:           {unsafe.Sizeof(DJSON{}), variableSize},
+	types.JsonpathFamily:       {unsafe.Sizeof(DJsonpath{}), variableSize},
 	types.UuidFamily:           {unsafe.Sizeof(DUuid{}), fixedSize},
 	types.INetFamily:           {unsafe.Sizeof(DIPAddr{}), fixedSize},
 	types.OidFamily:            {unsafe.Sizeof(DOid{}.Oid), fixedSize},
@@ -6166,12 +6244,16 @@ var baseDatumTypeSizes = map[types.Family]struct {
 // If neither of these conditions hold, MaxDistinctCount returns ok=false.
 // Additionally, it must be the case that first <= last, otherwise
 // MaxDistinctCount returns ok=false.
-func MaxDistinctCount(evalCtx CompareContext, first, last Datum) (_ int64, ok bool) {
+func MaxDistinctCount(
+	ctx context.Context, evalCtx CompareContext, first, last Datum,
+) (_ int64, ok bool) {
 	if !first.ResolvedType().Equivalent(last.ResolvedType()) {
 		// The datums must be of the same type.
 		return 0, false
 	}
-	if first.Compare(evalCtx, last) == 0 {
+	if cmp, err := first.Compare(ctx, evalCtx, last); err != nil {
+		panic(err)
+	} else if cmp == 0 {
 		// If the datums are equal, the distinct count is 1.
 		return 1, true
 	}
@@ -6321,13 +6403,32 @@ func AdjustValueToType(typ *types.T, inVal Datum) (outVal Datum, err error) {
 			// bpchar types truncate trailing whitespace.
 			sv = strings.TrimRight(sv, " ")
 		}
-		if typ.Width() > 0 && utf8.RuneCountInString(sv) > int(typ.Width()) {
+
+		var overlength int
+		// Fast path. Check for skip counting the number of runes through iteration.
+		if typ.Width() > 0 && len(sv) > int(typ.Width()) {
+			overlength = utf8.RuneCountInString(sv) - int(typ.Width())
+		} else {
+			overlength = 0
+		}
+		if typ.Oid() == oid.T_varchar {
+			// varchar types truncate extra trailing whitespace when
+			// more characters than the varchar size are provided.
+			for overlength > 0 {
+				if sv[len(sv)-1] != ' ' {
+					break
+				}
+				sv = sv[:len(sv)-1]
+				overlength--
+			}
+		}
+		if overlength > 0 {
 			return nil, pgerror.Newf(pgcode.StringDataRightTruncation,
 				"value too long for type %s",
 				typ.SQLString())
 		}
 
-		if typ.Oid() == oid.T_bpchar || typ.Oid() == oid.T_char {
+		if typ.Oid() == oid.T_bpchar || typ.Oid() == oid.T_char || typ.Oid() == oid.T_varchar {
 			if _, ok := AsDString(inVal); ok {
 				return NewDString(sv), nil
 			} else if _, ok := inVal.(*DCollatedString); ok {
@@ -6460,6 +6561,14 @@ func AdjustValueToType(typ *types.T, inVal Datum) (outVal Datum, err error) {
 				return nil, err
 			}
 		}
+	case types.PGVectorFamily:
+		if in, ok := inVal.(*DPGVector); ok {
+			width := int(typ.Width())
+			if width > 0 && len(in.T) != width {
+				return nil, pgerror.Newf(pgcode.DataException,
+					"expected %d dimensions, not %d", typ.Width(), len(in.T))
+			}
+		}
 	}
 	return inVal, nil
 }
@@ -6472,7 +6581,7 @@ func AdjustValueToType(typ *types.T, inVal Datum) (outVal Datum, err error) {
 // The return value is undefined if Datum.IsMin returns true or if the value is
 // NaN or an infinity (for floats and decimals).
 func DatumPrev(
-	datum Datum, cmpCtx CompareContext, collationEnv *CollationEnvironment,
+	ctx context.Context, datum Datum, cmpCtx CompareContext, collationEnv *CollationEnvironment,
 ) (Datum, bool) {
 	datum = UnwrapDOidWrapper(datum)
 	prevString := func(s string) (string, bool) {
@@ -6521,7 +6630,7 @@ func DatumPrev(
 		// TODO(yuzefovich): consider adding support for other datums that don't
 		// have Datum.Prev implementation (DCollatedString, DBitArray,
 		// DGeography, DGeometry, DBox2D, DJSON, DArray).
-		return datum.Prev(cmpCtx)
+		return datum.Prev(ctx, cmpCtx)
 	}
 }
 
@@ -6533,7 +6642,7 @@ func DatumPrev(
 // The return value is undefined if Datum.IsMax returns true or if the value is
 // NaN or an infinity (for floats and decimals).
 func DatumNext(
-	datum Datum, cmpCtx CompareContext, collationEnv *CollationEnvironment,
+	ctx context.Context, datum Datum, cmpCtx CompareContext, collationEnv *CollationEnvironment,
 ) (Datum, bool) {
 	datum = UnwrapDOidWrapper(datum)
 	switch d := datum.(type) {
@@ -6556,6 +6665,6 @@ func DatumNext(
 		// TODO(yuzefovich): consider adding support for other datums that don't
 		// have Datum.Next implementation (DCollatedString, DGeography,
 		// DGeometry, DBox2D, DJSON).
-		return datum.Next(cmpCtx)
+		return datum.Next(ctx, cmpCtx)
 	}
 }
diff --git a/pkg/sql/sem/tree/datum_alloc.go b/pkg/sql/sem/tree/datum_alloc.go
index 224b559..d428e31 100644
--- a/pkg/sql/sem/tree/datum_alloc.go
+++ b/pkg/sql/sem/tree/datum_alloc.go
@@ -1,31 +1,32 @@
 // Copyright 2018 The Cockroach Authors.
 //
-// Use of this software is governed by the Business Source License
-// included in the file licenses/BSL.txt.
-//
-// As of the Change Date specified in that file, in accordance with
-// the Business Source License, use of this software will be governed
-// by the Apache License, Version 2.0, included in the file
-// licenses/APL.txt.
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
 
 package tree
 
 import (
 	"github.com/cockroachdb/cockroachdb-parser/pkg/geo/geopb"
+	"github.com/cockroachdb/cockroachdb-parser/pkg/sql/types"
 	"github.com/cockroachdb/cockroachdb-parser/pkg/util"
 )
 
 // DatumAlloc provides batch allocation of datum pointers, amortizing the cost
-// of the allocations.
+// of the allocations. nil value can be used to indicate that no batching is
+// needed.
 // NOTE: it *must* be passed in by a pointer.
 type DatumAlloc struct {
 	_ util.NoCopy
 
-	// AllocSize determines the number of objects allocated whenever we've used
+	// DefaultAllocSize determines the number of objects allocated whenever we've used
 	// up previously allocated ones. This field is exported so that the caller
 	// could adjust it dynamically. If it is left unchanged by the caller, then
 	// it will be set to defaultDatumAllocSize automatically.
-	AllocSize int
+	DefaultAllocSize int
+
+	// typeAllocSizes stores type-specific allocation sizes. See ResetAllocSizes
+	// and AddAllocSize.
+	typeAllocSizes typeSizes
 
 	datumAlloc        []Datum
 	dintAlloc         []DInt
@@ -45,10 +46,12 @@ type DatumAlloc struct {
 	duuidAlloc        []DUuid
 	dipnetAlloc       []DIPAddr
 	djsonAlloc        []DJSON
+	djsonpathAlloc    []DJsonpath
 	dtupleAlloc       []DTuple
 	doidAlloc         []DOid
 	dvoidAlloc        []DVoid
 	dpglsnAlloc       []DPGLSN
+	// TODO(yuzefovich): add support for TSQuery and TSVector types.
 	// stringAlloc is used by all datum types that are strings (DBytes, DString, DEncodedKey).
 	stringAlloc []string
 	env         CollationEnvironment
@@ -59,19 +62,82 @@ type DatumAlloc struct {
 	lastEWKBBeyondAllocSize bool
 }
 
+// typeSizes stores allocation sizes for each type of buffer in DatumAlloc.
+//
+// NOTE: It currently only supports the types allocated by ColVecToDatum
+// function (except for Bools which are not allocated with DatumAlloc).
+type typeSizes struct {
+	ints         int
+	floats       int
+	decimals     int
+	dates        int
+	enums        int
+	timestamps   int
+	timestamptzs int
+	intervals    int
+	uuids        int
+	jsons        int
+	strings      int
+}
+
 const defaultDatumAllocSize = 16  // Arbitrary, could be tuned.
 const datumAllocMultiplier = 4    // Arbitrary, could be tuned.
 const defaultEWKBAllocSize = 4096 // Arbitrary, could be tuned.
 const maxEWKBAllocSize = 16384    // Arbitrary, could be tuned.
 
+// ResetTypeAllocSizes resets the type-specific allocation sizes.
+func (a *DatumAlloc) ResetTypeAllocSizes() {
+	if a == nil {
+		return
+	}
+	a.typeAllocSizes = typeSizes{}
+}
+
+// AddTypeAllocSize adds the given size to the allocation size for the given
+// type family.
+func (a *DatumAlloc) AddTypeAllocSize(size int, t types.Family) {
+	if a == nil {
+		return
+	}
+	switch t {
+	case types.IntFamily:
+		a.typeAllocSizes.ints += size
+	case types.FloatFamily:
+		a.typeAllocSizes.floats += size
+	case types.DecimalFamily:
+		a.typeAllocSizes.decimals += size
+	case types.DateFamily:
+		a.typeAllocSizes.dates += size
+	case types.EnumFamily:
+		a.typeAllocSizes.enums += size
+	case types.TimestampFamily:
+		a.typeAllocSizes.timestamps += size
+	case types.TimestampTZFamily:
+		a.typeAllocSizes.timestamptzs += size
+	case types.IntervalFamily:
+		a.typeAllocSizes.intervals += size
+	case types.UuidFamily:
+		a.typeAllocSizes.uuids += size
+	case types.JsonFamily:
+		a.typeAllocSizes.jsons += size
+	case types.StringFamily, types.BytesFamily, types.EncodedKeyFamily:
+		a.typeAllocSizes.strings += size
+	default:
+		// No-op for other types.
+	}
+}
+
 // NewDatums allocates Datums of the specified size.
 func (a *DatumAlloc) NewDatums(num int) Datums {
-	if a.AllocSize == 0 {
-		a.AllocSize = defaultDatumAllocSize
+	if a == nil {
+		return make(Datums, num)
 	}
 	buf := &a.datumAlloc
 	if len(*buf) < num {
-		extensionSize := a.AllocSize
+		extensionSize := defaultDatumAllocSize
+		if a.DefaultAllocSize != 0 {
+			extensionSize = a.DefaultAllocSize
+		}
 		if extTupleLen := num * datumAllocMultiplier; extensionSize < extTupleLen {
 			extensionSize = extTupleLen
 		}
@@ -84,12 +150,20 @@ func (a *DatumAlloc) NewDatums(num int) Datums {
 
 // NewDInt allocates a DInt.
 func (a *DatumAlloc) NewDInt(v DInt) *DInt {
-	if a.AllocSize == 0 {
-		a.AllocSize = defaultDatumAllocSize
+	if a == nil {
+		r := new(DInt)
+		*r = v
+		return r
 	}
 	buf := &a.dintAlloc
 	if len(*buf) == 0 {
-		*buf = make([]DInt, a.AllocSize)
+		allocSize := defaultDatumAllocSize
+		if a.typeAllocSizes.ints != 0 {
+			allocSize = a.typeAllocSizes.ints
+		} else if a.DefaultAllocSize != 0 {
+			allocSize = a.DefaultAllocSize
+		}
+		*buf = make([]DInt, allocSize)
 	}
 	r := &(*buf)[0]
 	*r = v
@@ -99,12 +173,18 @@ func (a *DatumAlloc) NewDInt(v DInt) *DInt {
 
 // NewDPGLSN allocates a DPGLSN.
 func (a *DatumAlloc) NewDPGLSN(v DPGLSN) *DPGLSN {
-	if a.AllocSize == 0 {
-		a.AllocSize = defaultDatumAllocSize
+	if a == nil {
+		r := new(DPGLSN)
+		*r = v
+		return r
 	}
 	buf := &a.dpglsnAlloc
 	if len(*buf) == 0 {
-		*buf = make([]DPGLSN, a.AllocSize)
+		allocSize := defaultDatumAllocSize
+		if a.DefaultAllocSize != 0 {
+			allocSize = a.DefaultAllocSize
+		}
+		*buf = make([]DPGLSN, allocSize)
 	}
 	r := &(*buf)[0]
 	*r = v
@@ -114,12 +194,20 @@ func (a *DatumAlloc) NewDPGLSN(v DPGLSN) *DPGLSN {
 
 // NewDFloat allocates a DFloat.
 func (a *DatumAlloc) NewDFloat(v DFloat) *DFloat {
-	if a.AllocSize == 0 {
-		a.AllocSize = defaultDatumAllocSize
+	if a == nil {
+		r := new(DFloat)
+		*r = v
+		return r
 	}
 	buf := &a.dfloatAlloc
 	if len(*buf) == 0 {
-		*buf = make([]DFloat, a.AllocSize)
+		allocSize := defaultDatumAllocSize
+		if a.typeAllocSizes.floats != 0 {
+			allocSize = a.typeAllocSizes.floats
+		} else if a.DefaultAllocSize != 0 {
+			allocSize = a.DefaultAllocSize
+		}
+		*buf = make([]DFloat, allocSize)
 	}
 	r := &(*buf)[0]
 	*r = v
@@ -128,12 +216,15 @@ func (a *DatumAlloc) NewDFloat(v DFloat) *DFloat {
 }
 
 func (a *DatumAlloc) newString() *string {
-	if a.AllocSize == 0 {
-		a.AllocSize = defaultDatumAllocSize
-	}
 	buf := &a.stringAlloc
 	if len(*buf) == 0 {
-		*buf = make([]string, a.AllocSize)
+		allocSize := defaultDatumAllocSize
+		if a.typeAllocSizes.strings != 0 {
+			allocSize = a.typeAllocSizes.strings
+		} else if a.DefaultAllocSize != 0 {
+			allocSize = a.DefaultAllocSize
+		}
+		*buf = make([]string, allocSize)
 	}
 	r := &(*buf)[0]
 	*buf = (*buf)[1:]
@@ -142,6 +233,11 @@ func (a *DatumAlloc) newString() *string {
 
 // NewDString allocates a DString.
 func (a *DatumAlloc) NewDString(v DString) *DString {
+	if a == nil {
+		r := new(DString)
+		*r = v
+		return r
+	}
 	r := (*DString)(a.newString())
 	*r = v
 	return r
@@ -149,6 +245,9 @@ func (a *DatumAlloc) NewDString(v DString) *DString {
 
 // NewDCollatedString allocates a DCollatedString.
 func (a *DatumAlloc) NewDCollatedString(contents string, locale string) (*DCollatedString, error) {
+	if a == nil {
+		return NewDCollatedString(contents, locale, &CollationEnvironment{})
+	}
 	return NewDCollatedString(contents, locale, &a.env)
 }
 
@@ -164,6 +263,11 @@ func (a *DatumAlloc) NewDRefCursor(v DString) Datum {
 
 // NewDBytes allocates a DBytes.
 func (a *DatumAlloc) NewDBytes(v DBytes) *DBytes {
+	if a == nil {
+		r := new(DBytes)
+		*r = v
+		return r
+	}
 	r := (*DBytes)(a.newString())
 	*r = v
 	return r
@@ -171,6 +275,11 @@ func (a *DatumAlloc) NewDBytes(v DBytes) *DBytes {
 
 // NewDEncodedKey allocates a DEncodedKey.
 func (a *DatumAlloc) NewDEncodedKey(v DEncodedKey) *DEncodedKey {
+	if a == nil {
+		r := new(DEncodedKey)
+		*r = v
+		return r
+	}
 	r := (*DEncodedKey)(a.newString())
 	*r = v
 	return r
@@ -178,12 +287,18 @@ func (a *DatumAlloc) NewDEncodedKey(v DEncodedKey) *DEncodedKey {
 
 // NewDBitArray allocates a DBitArray.
 func (a *DatumAlloc) NewDBitArray(v DBitArray) *DBitArray {
-	if a.AllocSize == 0 {
-		a.AllocSize = defaultDatumAllocSize
+	if a == nil {
+		r := new(DBitArray)
+		*r = v
+		return r
 	}
 	buf := &a.dbitArrayAlloc
 	if len(*buf) == 0 {
-		*buf = make([]DBitArray, a.AllocSize)
+		allocSize := defaultDatumAllocSize
+		if a.DefaultAllocSize != 0 {
+			allocSize = a.DefaultAllocSize
+		}
+		*buf = make([]DBitArray, allocSize)
 	}
 	r := &(*buf)[0]
 	*r = v
@@ -193,12 +308,20 @@ func (a *DatumAlloc) NewDBitArray(v DBitArray) *DBitArray {
 
 // NewDDecimal allocates a DDecimal.
 func (a *DatumAlloc) NewDDecimal(v DDecimal) *DDecimal {
-	if a.AllocSize == 0 {
-		a.AllocSize = defaultDatumAllocSize
+	if a == nil {
+		r := new(DDecimal)
+		*r = v
+		return r
 	}
 	buf := &a.ddecimalAlloc
 	if len(*buf) == 0 {
-		*buf = make([]DDecimal, a.AllocSize)
+		allocSize := defaultDatumAllocSize
+		if a.typeAllocSizes.decimals != 0 {
+			allocSize = a.typeAllocSizes.decimals
+		} else if a.DefaultAllocSize != 0 {
+			allocSize = a.DefaultAllocSize
+		}
+		*buf = make([]DDecimal, allocSize)
 	}
 	r := &(*buf)[0]
 	r.Set(&v.Decimal)
@@ -208,12 +331,20 @@ func (a *DatumAlloc) NewDDecimal(v DDecimal) *DDecimal {
 
 // NewDDate allocates a DDate.
 func (a *DatumAlloc) NewDDate(v DDate) *DDate {
-	if a.AllocSize == 0 {
-		a.AllocSize = defaultDatumAllocSize
+	if a == nil {
+		r := new(DDate)
+		*r = v
+		return r
 	}
 	buf := &a.ddateAlloc
 	if len(*buf) == 0 {
-		*buf = make([]DDate, a.AllocSize)
+		allocSize := defaultDatumAllocSize
+		if a.typeAllocSizes.dates != 0 {
+			allocSize = a.typeAllocSizes.dates
+		} else if a.DefaultAllocSize != 0 {
+			allocSize = a.DefaultAllocSize
+		}
+		*buf = make([]DDate, allocSize)
 	}
 	r := &(*buf)[0]
 	*r = v
@@ -223,12 +354,20 @@ func (a *DatumAlloc) NewDDate(v DDate) *DDate {
 
 // NewDEnum allocates a DEnum.
 func (a *DatumAlloc) NewDEnum(v DEnum) *DEnum {
-	if a.AllocSize == 0 {
-		a.AllocSize = defaultDatumAllocSize
+	if a == nil {
+		r := new(DEnum)
+		*r = v
+		return r
 	}
 	buf := &a.denumAlloc
 	if len(*buf) == 0 {
-		*buf = make([]DEnum, a.AllocSize)
+		allocSize := defaultDatumAllocSize
+		if a.typeAllocSizes.enums != 0 {
+			allocSize = a.typeAllocSizes.enums
+		} else if a.DefaultAllocSize != 0 {
+			allocSize = a.DefaultAllocSize
+		}
+		*buf = make([]DEnum, allocSize)
 	}
 	r := &(*buf)[0]
 	*r = v
@@ -238,12 +377,18 @@ func (a *DatumAlloc) NewDEnum(v DEnum) *DEnum {
 
 // NewDBox2D allocates a DBox2D.
 func (a *DatumAlloc) NewDBox2D(v DBox2D) *DBox2D {
-	if a.AllocSize == 0 {
-		a.AllocSize = defaultDatumAllocSize
+	if a == nil {
+		r := new(DBox2D)
+		*r = v
+		return r
 	}
 	buf := &a.dbox2dAlloc
 	if len(*buf) == 0 {
-		*buf = make([]DBox2D, a.AllocSize)
+		allocSize := defaultDatumAllocSize
+		if a.DefaultAllocSize != 0 {
+			allocSize = a.DefaultAllocSize
+		}
+		*buf = make([]DBox2D, allocSize)
 	}
 	r := &(*buf)[0]
 	*r = v
@@ -253,12 +398,18 @@ func (a *DatumAlloc) NewDBox2D(v DBox2D) *DBox2D {
 
 // NewDGeography allocates a DGeography.
 func (a *DatumAlloc) NewDGeography(v DGeography) *DGeography {
-	if a.AllocSize == 0 {
-		a.AllocSize = defaultDatumAllocSize
+	if a == nil {
+		r := new(DGeography)
+		*r = v
+		return r
 	}
 	buf := &a.dgeographyAlloc
 	if len(*buf) == 0 {
-		*buf = make([]DGeography, a.AllocSize)
+		allocSize := defaultDatumAllocSize
+		if a.DefaultAllocSize != 0 {
+			allocSize = a.DefaultAllocSize
+		}
+		*buf = make([]DGeography, allocSize)
 	}
 	r := &(*buf)[0]
 	*r = v
@@ -268,12 +419,16 @@ func (a *DatumAlloc) NewDGeography(v DGeography) *DGeography {
 
 // NewDVoid allocates a new DVoid.
 func (a *DatumAlloc) NewDVoid() *DVoid {
-	if a.AllocSize == 0 {
-		a.AllocSize = defaultDatumAllocSize
+	if a == nil {
+		return &DVoid{}
 	}
 	buf := &a.dvoidAlloc
 	if len(*buf) == 0 {
-		*buf = make([]DVoid, a.AllocSize)
+		allocSize := defaultDatumAllocSize
+		if a.DefaultAllocSize != 0 {
+			allocSize = a.DefaultAllocSize
+		}
+		*buf = make([]DVoid, allocSize)
 	}
 	r := &(*buf)[0]
 	*buf = (*buf)[1:]
@@ -292,6 +447,9 @@ func (a *DatumAlloc) NewDGeographyEmpty() *DGeography {
 // DoneInitNewDGeo is called after unmarshalling a SpatialObject allocated via
 // NewDGeographyEmpty/NewDGeometryEmpty, to return space to the DatumAlloc.
 func (a *DatumAlloc) DoneInitNewDGeo(so *geopb.SpatialObject) {
+	if a == nil {
+		return
+	}
 	// Don't allocate next time if the allocation was wasted and there is no way
 	// to pre-allocate enough. This is just a crude heuristic to avoid wasting
 	// allocations if the EWKBs are very large.
@@ -306,12 +464,18 @@ func (a *DatumAlloc) DoneInitNewDGeo(so *geopb.SpatialObject) {
 
 // NewDGeometry allocates a DGeometry.
 func (a *DatumAlloc) NewDGeometry(v DGeometry) *DGeometry {
-	if a.AllocSize == 0 {
-		a.AllocSize = defaultDatumAllocSize
+	if a == nil {
+		r := new(DGeometry)
+		*r = v
+		return r
 	}
 	buf := &a.dgeometryAlloc
 	if len(*buf) == 0 {
-		*buf = make([]DGeometry, a.AllocSize)
+		allocSize := defaultDatumAllocSize
+		if a.DefaultAllocSize != 0 {
+			allocSize = a.DefaultAllocSize
+		}
+		*buf = make([]DGeometry, allocSize)
 	}
 	r := &(*buf)[0]
 	*r = v
@@ -329,6 +493,9 @@ func (a *DatumAlloc) NewDGeometryEmpty() *DGeometry {
 }
 
 func (a *DatumAlloc) giveBytesToEWKB(so *geopb.SpatialObject) {
+	if a == nil {
+		return
+	}
 	if a.ewkbAlloc == nil && !a.lastEWKBBeyondAllocSize {
 		if a.curEWKBAllocSize == 0 {
 			a.curEWKBAllocSize = defaultEWKBAllocSize
@@ -344,12 +511,18 @@ func (a *DatumAlloc) giveBytesToEWKB(so *geopb.SpatialObject) {
 
 // NewDTime allocates a DTime.
 func (a *DatumAlloc) NewDTime(v DTime) *DTime {
-	if a.AllocSize == 0 {
-		a.AllocSize = defaultDatumAllocSize
+	if a == nil {
+		r := new(DTime)
+		*r = v
+		return r
 	}
 	buf := &a.dtimeAlloc
 	if len(*buf) == 0 {
-		*buf = make([]DTime, a.AllocSize)
+		allocSize := defaultDatumAllocSize
+		if a.DefaultAllocSize != 0 {
+			allocSize = a.DefaultAllocSize
+		}
+		*buf = make([]DTime, allocSize)
 	}
 	r := &(*buf)[0]
 	*r = v
@@ -359,12 +532,18 @@ func (a *DatumAlloc) NewDTime(v DTime) *DTime {
 
 // NewDTimeTZ allocates a DTimeTZ.
 func (a *DatumAlloc) NewDTimeTZ(v DTimeTZ) *DTimeTZ {
-	if a.AllocSize == 0 {
-		a.AllocSize = defaultDatumAllocSize
+	if a == nil {
+		r := new(DTimeTZ)
+		*r = v
+		return r
 	}
 	buf := &a.dtimetzAlloc
 	if len(*buf) == 0 {
-		*buf = make([]DTimeTZ, a.AllocSize)
+		allocSize := defaultDatumAllocSize
+		if a.DefaultAllocSize != 0 {
+			allocSize = a.DefaultAllocSize
+		}
+		*buf = make([]DTimeTZ, allocSize)
 	}
 	r := &(*buf)[0]
 	*r = v
@@ -374,12 +553,20 @@ func (a *DatumAlloc) NewDTimeTZ(v DTimeTZ) *DTimeTZ {
 
 // NewDTimestamp allocates a DTimestamp.
 func (a *DatumAlloc) NewDTimestamp(v DTimestamp) *DTimestamp {
-	if a.AllocSize == 0 {
-		a.AllocSize = defaultDatumAllocSize
+	if a == nil {
+		r := new(DTimestamp)
+		*r = v
+		return r
 	}
 	buf := &a.dtimestampAlloc
 	if len(*buf) == 0 {
-		*buf = make([]DTimestamp, a.AllocSize)
+		allocSize := defaultDatumAllocSize
+		if a.typeAllocSizes.timestamps != 0 {
+			allocSize = a.typeAllocSizes.timestamps
+		} else if a.DefaultAllocSize != 0 {
+			allocSize = a.DefaultAllocSize
+		}
+		*buf = make([]DTimestamp, allocSize)
 	}
 	r := &(*buf)[0]
 	*r = v
@@ -389,12 +576,20 @@ func (a *DatumAlloc) NewDTimestamp(v DTimestamp) *DTimestamp {
 
 // NewDTimestampTZ allocates a DTimestampTZ.
 func (a *DatumAlloc) NewDTimestampTZ(v DTimestampTZ) *DTimestampTZ {
-	if a.AllocSize == 0 {
-		a.AllocSize = defaultDatumAllocSize
+	if a == nil {
+		r := new(DTimestampTZ)
+		*r = v
+		return r
 	}
 	buf := &a.dtimestampTzAlloc
 	if len(*buf) == 0 {
-		*buf = make([]DTimestampTZ, a.AllocSize)
+		allocSize := defaultDatumAllocSize
+		if a.typeAllocSizes.timestamptzs != 0 {
+			allocSize = a.typeAllocSizes.timestamptzs
+		} else if a.DefaultAllocSize != 0 {
+			allocSize = a.DefaultAllocSize
+		}
+		*buf = make([]DTimestampTZ, allocSize)
 	}
 	r := &(*buf)[0]
 	*r = v
@@ -404,12 +599,20 @@ func (a *DatumAlloc) NewDTimestampTZ(v DTimestampTZ) *DTimestampTZ {
 
 // NewDInterval allocates a DInterval.
 func (a *DatumAlloc) NewDInterval(v DInterval) *DInterval {
-	if a.AllocSize == 0 {
-		a.AllocSize = defaultDatumAllocSize
+	if a == nil {
+		r := new(DInterval)
+		*r = v
+		return r
 	}
 	buf := &a.dintervalAlloc
 	if len(*buf) == 0 {
-		*buf = make([]DInterval, a.AllocSize)
+		allocSize := defaultDatumAllocSize
+		if a.typeAllocSizes.intervals != 0 {
+			allocSize = a.typeAllocSizes.intervals
+		} else if a.DefaultAllocSize != 0 {
+			allocSize = a.DefaultAllocSize
+		}
+		*buf = make([]DInterval, allocSize)
 	}
 	r := &(*buf)[0]
 	*r = v
@@ -419,12 +622,20 @@ func (a *DatumAlloc) NewDInterval(v DInterval) *DInterval {
 
 // NewDUuid allocates a DUuid.
 func (a *DatumAlloc) NewDUuid(v DUuid) *DUuid {
-	if a.AllocSize == 0 {
-		a.AllocSize = defaultDatumAllocSize
+	if a == nil {
+		r := new(DUuid)
+		*r = v
+		return r
 	}
 	buf := &a.duuidAlloc
 	if len(*buf) == 0 {
-		*buf = make([]DUuid, a.AllocSize)
+		allocSize := defaultDatumAllocSize
+		if a.typeAllocSizes.uuids != 0 {
+			allocSize = a.typeAllocSizes.uuids
+		} else if a.DefaultAllocSize != 0 {
+			allocSize = a.DefaultAllocSize
+		}
+		*buf = make([]DUuid, allocSize)
 	}
 	r := &(*buf)[0]
 	*r = v
@@ -434,12 +645,18 @@ func (a *DatumAlloc) NewDUuid(v DUuid) *DUuid {
 
 // NewDIPAddr allocates a DIPAddr.
 func (a *DatumAlloc) NewDIPAddr(v DIPAddr) *DIPAddr {
-	if a.AllocSize == 0 {
-		a.AllocSize = defaultDatumAllocSize
+	if a == nil {
+		r := new(DIPAddr)
+		*r = v
+		return r
 	}
 	buf := &a.dipnetAlloc
 	if len(*buf) == 0 {
-		*buf = make([]DIPAddr, a.AllocSize)
+		allocSize := defaultDatumAllocSize
+		if a.DefaultAllocSize != 0 {
+			allocSize = a.DefaultAllocSize
+		}
+		*buf = make([]DIPAddr, allocSize)
 	}
 	r := &(*buf)[0]
 	*r = v
@@ -449,12 +666,40 @@ func (a *DatumAlloc) NewDIPAddr(v DIPAddr) *DIPAddr {
 
 // NewDJSON allocates a DJSON.
 func (a *DatumAlloc) NewDJSON(v DJSON) *DJSON {
-	if a.AllocSize == 0 {
-		a.AllocSize = defaultDatumAllocSize
+	if a == nil {
+		r := new(DJSON)
+		*r = v
+		return r
 	}
 	buf := &a.djsonAlloc
 	if len(*buf) == 0 {
-		*buf = make([]DJSON, a.AllocSize)
+		allocSize := defaultDatumAllocSize
+		if a.typeAllocSizes.jsons != 0 {
+			allocSize = a.typeAllocSizes.jsons
+		} else if a.DefaultAllocSize != 0 {
+			allocSize = a.DefaultAllocSize
+		}
+		*buf = make([]DJSON, allocSize)
+	}
+	r := &(*buf)[0]
+	*r = v
+	*buf = (*buf)[1:]
+	return r
+}
+
+func (a *DatumAlloc) NewDJsonpath(v DJsonpath) *DJsonpath {
+	if a == nil {
+		r := new(DJsonpath)
+		*r = v
+		return r
+	}
+	buf := &a.djsonpathAlloc
+	if len(*buf) == 0 {
+		allocSize := defaultDatumAllocSize
+		if a.DefaultAllocSize != 0 {
+			allocSize = a.DefaultAllocSize
+		}
+		*buf = make([]DJsonpath, allocSize)
 	}
 	r := &(*buf)[0]
 	*r = v
@@ -464,12 +709,18 @@ func (a *DatumAlloc) NewDJSON(v DJSON) *DJSON {
 
 // NewDTuple allocates a DTuple.
 func (a *DatumAlloc) NewDTuple(v DTuple) *DTuple {
-	if a.AllocSize == 0 {
-		a.AllocSize = defaultDatumAllocSize
+	if a == nil {
+		r := new(DTuple)
+		*r = v
+		return r
 	}
 	buf := &a.dtupleAlloc
 	if len(*buf) == 0 {
-		*buf = make([]DTuple, a.AllocSize)
+		allocSize := defaultDatumAllocSize
+		if a.DefaultAllocSize != 0 {
+			allocSize = a.DefaultAllocSize
+		}
+		*buf = make([]DTuple, allocSize)
 	}
 	r := &(*buf)[0]
 	*r = v
@@ -479,12 +730,18 @@ func (a *DatumAlloc) NewDTuple(v DTuple) *DTuple {
 
 // NewDOid allocates a DOid.
 func (a *DatumAlloc) NewDOid(v DOid) Datum {
-	if a.AllocSize == 0 {
-		a.AllocSize = defaultDatumAllocSize
+	if a == nil {
+		r := new(DOid)
+		*r = v
+		return r
 	}
 	buf := &a.doidAlloc
 	if len(*buf) == 0 {
-		*buf = make([]DOid, a.AllocSize)
+		allocSize := defaultDatumAllocSize
+		if a.DefaultAllocSize != 0 {
+			allocSize = a.DefaultAllocSize
+		}
+		*buf = make([]DOid, allocSize)
 	}
 	r := &(*buf)[0]
 	*r = v
diff --git a/pkg/sql/sem/tree/decimal.go b/pkg/sql/sem/tree/decimal.go
index f34af80..1224c07 100644
--- a/pkg/sql/sem/tree/decimal.go
+++ b/pkg/sql/sem/tree/decimal.go
@@ -1,12 +1,7 @@
 // Copyright 2016 The Cockroach Authors.
 //
-// Use of this software is governed by the Business Source License
-// included in the file licenses/BSL.txt.
-//
-// As of the Change Date specified in that file, in accordance with
-// the Business Source License, use of this software will be governed
-// by the Apache License, Version 2.0, included in the file
-// licenses/APL.txt.
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
 
 package tree
 
diff --git a/pkg/sql/sem/tree/delete.go b/pkg/sql/sem/tree/delete.go
index acefa2e..2551b73 100644
--- a/pkg/sql/sem/tree/delete.go
+++ b/pkg/sql/sem/tree/delete.go
@@ -7,13 +7,8 @@
 //
 // Copyright 2015 The Cockroach Authors.
 //
-// Use of this software is governed by the Business Source License
-// included in the file licenses/BSL.txt.
-//
-// As of the Change Date specified in that file, in accordance with
-// the Business Source License, use of this software will be governed
-// by the Apache License, Version 2.0, included in the file
-// licenses/APL.txt.
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
 
 // This code was derived from https://github.com/youtube/vitess.
 
diff --git a/pkg/sql/sem/tree/discard.go b/pkg/sql/sem/tree/discard.go
index db6423e..deb076e 100644
--- a/pkg/sql/sem/tree/discard.go
+++ b/pkg/sql/sem/tree/discard.go
@@ -1,12 +1,7 @@
 // Copyright 2017 The Cockroach Authors.
 //
-// Use of this software is governed by the Business Source License
-// included in the file licenses/BSL.txt.
-//
-// As of the Change Date specified in that file, in accordance with
-// the Business Source License, use of this software will be governed
-// by the Apache License, Version 2.0, included in the file
-// licenses/APL.txt.
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
 
 package tree
 
diff --git a/pkg/sql/sem/tree/do.go b/pkg/sql/sem/tree/do.go
new file mode 100644
index 0000000..9c4a823
--- /dev/null
+++ b/pkg/sql/sem/tree/do.go
@@ -0,0 +1,85 @@
+// Copyright 2025 The Cockroach Authors.
+//
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
+
+package tree
+
+import (
+	"github.com/cockroachdb/cockroachdb-parser/pkg/sql/pgwire/pgcode"
+	"github.com/cockroachdb/cockroachdb-parser/pkg/sql/pgwire/pgerror"
+	"github.com/cockroachdb/errors"
+)
+
+// DoBlock represents a SQL DO statement. It can only exist as a top-level
+// statement.
+type DoBlock struct {
+	Code DoBlockBody
+}
+
+// DoBlockBody represents the fully parsed code body of a DO statement.
+// It currently maps to plpgsqltree.DoBlock.
+type DoBlockBody interface {
+	NodeFormatter
+	VisitBody(v Visitor) DoBlockBody
+	IsDoBlockBody()
+}
+
+var _ Statement = &DoBlock{}
+
+// Format implements the NodeFormatter interface.
+func (n *DoBlock) Format(ctx *FmtCtx) {
+	ctx.FormatNode(n.Code)
+}
+
+// DoBlockOptions represent a list of options for a DO statement.
+type DoBlockOptions []DoBlockOption
+
+// DoBlockOption is an interface representing DO statement properties.
+type DoBlockOption interface {
+	doBlockOption()
+}
+
+func (RoutineBodyStr) doBlockOption()  {}
+func (RoutineLanguage) doBlockOption() {}
+
+// AnalyzeDoBlockOptions checks the list of DO block options for validity, and
+// returns the code string.
+func AnalyzeDoBlockOptions(options DoBlockOptions) (RoutineBodyStr, error) {
+	var doBody RoutineBodyStr
+	var lang RoutineLanguage
+	var foundLanguage, foundBody bool
+	for _, doOption := range options {
+		switch t := doOption.(type) {
+		case RoutineBodyStr:
+			if foundBody {
+				return "", pgerror.New(pgcode.Syntax, "conflicting or redundant options")
+			}
+			doBody = t
+			foundBody = true
+		case RoutineLanguage:
+			if foundLanguage {
+				return "", pgerror.New(pgcode.Syntax, "conflicting or redundant options")
+			}
+			lang = t
+			foundLanguage = true
+		default:
+			return "", errors.AssertionFailedf("unexpected DO statement option: %v", t)
+		}
+	}
+	if !foundBody {
+		return "", pgerror.New(pgcode.Syntax, "no inline code specified")
+	}
+	switch lang {
+	case "", RoutineLangPLpgSQL:
+		// PL/pgSQL is the default, and currently the only supported language.
+	case RoutineLangSQL:
+		// Postgres disallows SQL for DO statements.
+		return "", pgerror.Newf(pgcode.FeatureNotSupported,
+			"language \"%s\" does not support inline code execution", lang,
+		)
+	default:
+		return "", pgerror.Newf(pgcode.UndefinedObject, "language \"%s\" does not exist", lang)
+	}
+	return doBody, nil
+}
diff --git a/pkg/sql/sem/tree/drop.go b/pkg/sql/sem/tree/drop.go
index d6a5809..21585ec 100644
--- a/pkg/sql/sem/tree/drop.go
+++ b/pkg/sql/sem/tree/drop.go
@@ -7,13 +7,8 @@
 //
 // Copyright 2015 The Cockroach Authors.
 //
-// Use of this software is governed by the Business Source License
-// included in the file licenses/BSL.txt.
-//
-// As of the Change Date specified in that file, in accordance with
-// the Business Source License, use of this software will be governed
-// by the Apache License, Version 2.0, included in the file
-// licenses/APL.txt.
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
 
 // This code was derived from https://github.com/youtube/vitess.
 
diff --git a/pkg/sql/sem/tree/drop_owned_by.go b/pkg/sql/sem/tree/drop_owned_by.go
index 4b83bf9..6339bcf 100644
--- a/pkg/sql/sem/tree/drop_owned_by.go
+++ b/pkg/sql/sem/tree/drop_owned_by.go
@@ -1,12 +1,7 @@
 // Copyright 2020 The Cockroach Authors.
 //
-// Use of this software is governed by the Business Source License
-// included in the file licenses/BSL.txt.
-//
-// As of the Change Date specified in that file, in accordance with
-// the Business Source License, use of this software will be governed
-// by the Apache License, Version 2.0, included in the file
-// licenses/APL.txt.
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
 
 package tree
 
diff --git a/pkg/sql/sem/tree/drop_policy.go b/pkg/sql/sem/tree/drop_policy.go
new file mode 100644
index 0000000..9d0d371
--- /dev/null
+++ b/pkg/sql/sem/tree/drop_policy.go
@@ -0,0 +1,31 @@
+// Copyright 2024 The Cockroach Authors.
+//
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
+
+package tree
+
+var _ Statement = &DropPolicy{}
+
+// DropPolicy is a tree struct for the DROP POLICY DDL statement
+type DropPolicy struct {
+	PolicyName   Name
+	TableName    *UnresolvedObjectName
+	DropBehavior DropBehavior
+	IfExists     bool
+}
+
+// Format implements the NodeFormatter interface.
+func (node *DropPolicy) Format(ctx *FmtCtx) {
+	ctx.WriteString("DROP POLICY ")
+	if node.IfExists {
+		ctx.WriteString("IF EXISTS ")
+	}
+	ctx.FormatNode(&node.PolicyName)
+	ctx.WriteString(" ON ")
+	ctx.FormatNode(node.TableName)
+	if node.DropBehavior != DropDefault {
+		ctx.WriteString(" ")
+		ctx.WriteString(node.DropBehavior.String())
+	}
+}
diff --git a/pkg/sql/sem/tree/eval.go b/pkg/sql/sem/tree/eval.go
index f573997..32bf5ea 100644
--- a/pkg/sql/sem/tree/eval.go
+++ b/pkg/sql/sem/tree/eval.go
@@ -1,16 +1,12 @@
 // Copyright 2015 The Cockroach Authors.
 //
-// Use of this software is governed by the Business Source License
-// included in the file licenses/BSL.txt.
-//
-// As of the Change Date specified in that file, in accordance with
-// the Business Source License, use of this software will be governed
-// by the Apache License, Version 2.0, included in the file
-// licenses/APL.txt.
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
 
 package tree
 
 import (
+	"context"
 	"fmt"
 
 	"github.com/cockroachdb/cockroachdb-parser/pkg/geo"
@@ -82,8 +78,16 @@ func (op *UnaryOp) returnType() ReturnTyper {
 	return op.retType
 }
 
-func (*UnaryOp) preferred() bool {
-	return false
+func (*UnaryOp) preference() OverloadPreference {
+	return OverloadPreferenceNone
+}
+
+func (*UnaryOp) outParamInfo() (RoutineType, []int32, TypeList) {
+	return BuiltinRoutine, nil, nil
+}
+
+func (op *UnaryOp) defaultExprs() Exprs {
+	return nil
 }
 
 func unaryOpFixups(
@@ -236,7 +240,7 @@ type BinOp struct {
 	CalledOnNullInput bool
 	EvalOp            BinaryEvalOp
 	Volatility        volatility.V
-	PreferredOverload bool
+	OverloadPreference
 
 	types   TypeList
 	retType ReturnTyper
@@ -256,8 +260,16 @@ func (op *BinOp) returnType() ReturnTyper {
 	return op.retType
 }
 
-func (op *BinOp) preferred() bool {
-	return op.PreferredOverload
+func (op *BinOp) preference() OverloadPreference {
+	return op.OverloadPreference
+}
+
+func (op *BinOp) outParamInfo() (RoutineType, []int32, TypeList) {
+	return BuiltinRoutine, nil, nil
+}
+
+func (op *BinOp) defaultExprs() Exprs {
+	return nil
 }
 
 // AppendToMaybeNullArray appends an element to an array. If the first
@@ -343,7 +355,9 @@ func ConcatArrays(typ *types.T, left Datum, right Datum) (Datum, error) {
 }
 
 // ArrayContains return true if the haystack contains all needles.
-func ArrayContains(ctx CompareContext, haystack *DArray, needles *DArray) (*DBool, error) {
+func ArrayContains(
+	ctx context.Context, cmpCtx CompareContext, haystack *DArray, needles *DArray,
+) (*DBool, error) {
 	if !haystack.ParamTyp.Equivalent(needles.ParamTyp) {
 		return DBoolFalse, pgerror.New(pgcode.DatatypeMismatch, "cannot compare arrays with different element types")
 	}
@@ -354,7 +368,7 @@ func ArrayContains(ctx CompareContext, haystack *DArray, needles *DArray) (*DBoo
 		}
 		var found bool
 		for _, hay := range haystack.Array {
-			if cmp, err := needle.CompareError(ctx, hay); err != nil {
+			if cmp, err := needle.Compare(ctx, cmpCtx, hay); err != nil {
 				return DBoolFalse, err
 			} else if cmp == 0 {
 				found = true
@@ -370,7 +384,9 @@ func ArrayContains(ctx CompareContext, haystack *DArray, needles *DArray) (*DBoo
 
 // ArrayOverlaps return true if there is even one element
 // common between the left and right arrays.
-func ArrayOverlaps(ctx CompareContext, array, other *DArray) (*DBool, error) {
+func ArrayOverlaps(
+	ctx context.Context, cmpCtx CompareContext, array, other *DArray,
+) (*DBool, error) {
 	if !array.ParamTyp.Equivalent(other.ParamTyp) {
 		return nil, pgerror.New(pgcode.DatatypeMismatch, "cannot compare arrays with different element types")
 	}
@@ -380,7 +396,7 @@ func ArrayOverlaps(ctx CompareContext, array, other *DArray) (*DBool, error) {
 			continue
 		}
 		for _, hay := range other.Array {
-			if cmp, err := needle.CompareError(ctx, hay); err != nil {
+			if cmp, err := needle.Compare(ctx, cmpCtx, hay); err != nil {
 				return DBoolFalse, err
 			} else if cmp == 0 {
 				return DBoolTrue, nil
@@ -449,7 +465,7 @@ func initNonArrayToNonArrayConcatenation() {
 	for _, t := range append([]*types.T{types.AnyTuple}, types.Scalar...) {
 		// Do not re-add String+String or String+Bytes, as they already exist
 		// and have predefined correct behavior.
-		if t != types.String && t != types.Bytes {
+		if !t.Identical(types.String) && !t.Identical(types.Bytes) {
 			addConcat(t, types.String, fromTypeToVolatility[t.Oid()])
 			addConcat(types.String, t, fromTypeToVolatility[t.Oid()])
 		}
@@ -780,6 +796,13 @@ var BinOps = map[treebin.BinaryOperatorSymbol]*BinOpOverloads{
 			EvalOp:     &PlusPGLSNDecimalOp{},
 			Volatility: volatility.Immutable,
 		},
+		{
+			LeftType:   types.PGVector,
+			RightType:  types.PGVector,
+			ReturnType: types.PGVector,
+			EvalOp:     &PlusPGVectorOp{},
+			Volatility: volatility.Immutable,
+		},
 	}},
 
 	treebin.Minus: {overloads: []*BinOp{
@@ -966,6 +989,13 @@ var BinOps = map[treebin.BinaryOperatorSymbol]*BinOpOverloads{
 			EvalOp:     &MinusPGLSNOp{},
 			Volatility: volatility.Immutable,
 		},
+		{
+			LeftType:   types.PGVector,
+			RightType:  types.PGVector,
+			ReturnType: types.PGVector,
+			EvalOp:     &MinusPGVectorOp{},
+			Volatility: volatility.Immutable,
+		},
 	}},
 
 	treebin.Mult: {overloads: []*BinOp{
@@ -1049,6 +1079,13 @@ var BinOps = map[treebin.BinaryOperatorSymbol]*BinOpOverloads{
 			EvalOp:     &MultIntervalDecimalOp{},
 			Volatility: volatility.Immutable,
 		},
+		{
+			LeftType:   types.PGVector,
+			RightType:  types.PGVector,
+			ReturnType: types.PGVector,
+			EvalOp:     &MultPGVectorOp{},
+			Volatility: volatility.Immutable,
+		},
 	}},
 
 	treebin.Div: {overloads: []*BinOp{
@@ -1308,12 +1345,12 @@ var BinOps = map[treebin.BinaryOperatorSymbol]*BinOpOverloads{
 
 	treebin.JSONFetchVal: {overloads: []*BinOp{
 		{
-			LeftType:          types.Jsonb,
-			RightType:         types.String,
-			ReturnType:        types.Jsonb,
-			EvalOp:            &JSONFetchValStringOp{},
-			PreferredOverload: true,
-			Volatility:        volatility.Immutable,
+			LeftType:           types.Jsonb,
+			RightType:          types.String,
+			ReturnType:         types.Jsonb,
+			EvalOp:             &JSONFetchValStringOp{},
+			OverloadPreference: OverloadPreferencePreferred,
+			Volatility:         volatility.Immutable,
 		},
 		{
 			LeftType:   types.Jsonb,
@@ -1336,12 +1373,12 @@ var BinOps = map[treebin.BinaryOperatorSymbol]*BinOpOverloads{
 
 	treebin.JSONFetchText: {overloads: []*BinOp{
 		{
-			LeftType:          types.Jsonb,
-			RightType:         types.String,
-			ReturnType:        types.String,
-			PreferredOverload: true,
-			EvalOp:            &JSONFetchTextStringOp{},
-			Volatility:        volatility.Immutable,
+			LeftType:           types.Jsonb,
+			RightType:          types.String,
+			ReturnType:         types.String,
+			OverloadPreference: OverloadPreferencePreferred,
+			EvalOp:             &JSONFetchTextStringOp{},
+			Volatility:         volatility.Immutable,
 		},
 		{
 			LeftType:   types.Jsonb,
@@ -1361,6 +1398,33 @@ var BinOps = map[treebin.BinaryOperatorSymbol]*BinOpOverloads{
 			Volatility: volatility.Immutable,
 		},
 	}},
+	treebin.Distance: {overloads: []*BinOp{
+		{
+			LeftType:   types.PGVector,
+			RightType:  types.PGVector,
+			ReturnType: types.Float,
+			EvalOp:     &DistanceVectorOp{},
+			Volatility: volatility.Immutable,
+		},
+	}},
+	treebin.CosDistance: {overloads: []*BinOp{
+		{
+			LeftType:   types.PGVector,
+			RightType:  types.PGVector,
+			ReturnType: types.Float,
+			EvalOp:     &CosDistanceVectorOp{},
+			Volatility: volatility.Immutable,
+		},
+	}},
+	treebin.NegInnerProduct: {overloads: []*BinOp{
+		{
+			LeftType:   types.PGVector,
+			RightType:  types.PGVector,
+			ReturnType: types.Float,
+			EvalOp:     &NegInnerProductVectorOp{},
+			Volatility: volatility.Immutable,
+		},
+	}},
 }
 
 // CmpOp is a comparison operator.
@@ -1381,7 +1445,7 @@ type CmpOp struct {
 
 	Volatility volatility.V
 
-	PreferredOverload bool
+	OverloadPreference
 }
 
 func (op *CmpOp) params() TypeList {
@@ -1398,15 +1462,23 @@ func (op *CmpOp) returnType() ReturnTyper {
 	return cmpOpReturnType
 }
 
-func (op *CmpOp) preferred() bool {
-	return op.PreferredOverload
+func (op *CmpOp) preference() OverloadPreference {
+	return op.OverloadPreference
+}
+
+func (op *CmpOp) outParamInfo() (RoutineType, []int32, TypeList) {
+	return BuiltinRoutine, nil, nil
+}
+
+func (op *CmpOp) defaultExprs() Exprs {
+	return nil
 }
 
 func cmpOpFixups(
 	cmpOps map[treecmp.ComparisonOperatorSymbol]*CmpOpOverloads,
 ) map[treecmp.ComparisonOperatorSymbol]*CmpOpOverloads {
 	findVolatility := func(op treecmp.ComparisonOperatorSymbol, t *types.T) volatility.V {
-		for _, o := range cmpOps[treecmp.EQ].overloads {
+		for _, o := range cmpOps[op].overloads {
 			if o.LeftType.Equivalent(t) && o.RightType.Equivalent(t) {
 				return o.Volatility
 			}
@@ -1418,7 +1490,7 @@ func cmpOpFixups(
 	}
 
 	// Array equality comparisons.
-	for _, t := range append(types.Scalar, types.AnyEnum) {
+	for _, t := range append(types.Scalar, types.AnyEnum, types.AnyCollatedString) {
 		appendCmpOp := func(sym treecmp.ComparisonOperatorSymbol, cmpOp *CmpOp) {
 			s, ok := cmpOps[sym]
 			if !ok {
@@ -1522,6 +1594,10 @@ func makeLeFn(a, b *types.T, v volatility.V) *CmpOp {
 func makeIsFn(a, b *types.T, v volatility.V) *CmpOp {
 	return makeCmpOpOverload(treecmp.IsNotDistinctFrom, a, b, true, v)
 }
+func unpreferred(cmp *CmpOp) *CmpOp {
+	cmp.OverloadPreference = OverloadPreferenceUnpreferred
+	return cmp
+}
 
 // CmpOps contains the comparison operations indexed by operation type.
 var CmpOps = cmpOpFixups(map[treecmp.ComparisonOperatorSymbol]*CmpOpOverloads{
@@ -1546,8 +1622,13 @@ var CmpOps = cmpOpFixups(map[treecmp.ComparisonOperatorSymbol]*CmpOpOverloads{
 		makeEqFn(types.Jsonb, types.Jsonb, volatility.Immutable),
 		makeEqFn(types.Oid, types.Oid, volatility.Leakproof),
 		makeEqFn(types.PGLSN, types.PGLSN, volatility.Leakproof),
+		makeEqFn(types.PGVector, types.PGVector, volatility.Leakproof),
 		makeEqFn(types.RefCursor, types.RefCursor, volatility.Leakproof),
 		makeEqFn(types.String, types.String, volatility.Leakproof),
+		// NOTE: Using unpreferred here is a hack that avoids some "ambiguous
+		// comparison operator" errors. It is necessary because we do not follow
+		// all of Postgres's type conversion rules. See #75101.
+		unpreferred(makeEqFn(types.BPChar, types.BPChar, volatility.Leakproof)),
 		makeEqFn(types.Time, types.Time, volatility.Leakproof),
 		makeEqFn(types.TimeTZ, types.TimeTZ, volatility.Leakproof),
 		makeEqFn(types.Timestamp, types.Timestamp, volatility.Leakproof),
@@ -1606,8 +1687,13 @@ var CmpOps = cmpOpFixups(map[treecmp.ComparisonOperatorSymbol]*CmpOpOverloads{
 		makeLtFn(types.Interval, types.Interval, volatility.Leakproof),
 		makeLtFn(types.Oid, types.Oid, volatility.Leakproof),
 		makeLtFn(types.PGLSN, types.PGLSN, volatility.Leakproof),
+		makeLtFn(types.PGVector, types.PGVector, volatility.Leakproof),
 		makeLtFn(types.RefCursor, types.RefCursor, volatility.Leakproof),
 		makeLtFn(types.String, types.String, volatility.Leakproof),
+		// NOTE: Using unpreferred here is a hack that avoids some "ambiguous
+		// comparison operator" errors. It is necessary because we do not follow
+		// all of Postgres's type conversion rules. See #75101.
+		unpreferred(makeLtFn(types.BPChar, types.BPChar, volatility.Leakproof)),
 		makeLtFn(types.Time, types.Time, volatility.Leakproof),
 		makeLtFn(types.TimeTZ, types.TimeTZ, volatility.Leakproof),
 		makeLtFn(types.Timestamp, types.Timestamp, volatility.Leakproof),
@@ -1665,8 +1751,13 @@ var CmpOps = cmpOpFixups(map[treecmp.ComparisonOperatorSymbol]*CmpOpOverloads{
 		makeLeFn(types.Interval, types.Interval, volatility.Leakproof),
 		makeLeFn(types.Oid, types.Oid, volatility.Leakproof),
 		makeLeFn(types.PGLSN, types.PGLSN, volatility.Leakproof),
+		makeLeFn(types.PGVector, types.PGVector, volatility.Leakproof),
 		makeLeFn(types.RefCursor, types.RefCursor, volatility.Leakproof),
 		makeLeFn(types.String, types.String, volatility.Leakproof),
+		// NOTE: Using unpreferred here is a hack that avoids some "ambiguous
+		// comparison operator" errors. It is necessary because we do not follow
+		// all of Postgres's type conversion rules. See #75101.
+		unpreferred(makeLeFn(types.BPChar, types.BPChar, volatility.Leakproof)),
 		makeLeFn(types.Time, types.Time, volatility.Leakproof),
 		makeLeFn(types.TimeTZ, types.TimeTZ, volatility.Leakproof),
 		makeLeFn(types.Timestamp, types.Timestamp, volatility.Leakproof),
@@ -1713,8 +1804,8 @@ var CmpOps = cmpOpFixups(map[treecmp.ComparisonOperatorSymbol]*CmpOpOverloads{
 			},
 			CalledOnNullInput: true,
 			// Avoids ambiguous comparison error for NULL IS NOT DISTINCT FROM NULL.
-			PreferredOverload: true,
-			Volatility:        volatility.Leakproof,
+			OverloadPreference: OverloadPreferencePreferred,
+			Volatility:         volatility.Leakproof,
 		},
 		{
 			LeftType:  types.AnyArray,
@@ -1743,10 +1834,16 @@ var CmpOps = cmpOpFixups(map[treecmp.ComparisonOperatorSymbol]*CmpOpOverloads{
 		makeIsFn(types.Int, types.Int, volatility.Leakproof),
 		makeIsFn(types.Interval, types.Interval, volatility.Leakproof),
 		makeIsFn(types.Jsonb, types.Jsonb, volatility.Immutable),
+		makeIsFn(types.Jsonpath, types.Jsonpath, volatility.Leakproof),
 		makeIsFn(types.Oid, types.Oid, volatility.Leakproof),
 		makeIsFn(types.PGLSN, types.PGLSN, volatility.Leakproof),
+		makeIsFn(types.PGVector, types.PGVector, volatility.Leakproof),
 		makeIsFn(types.RefCursor, types.RefCursor, volatility.Leakproof),
 		makeIsFn(types.String, types.String, volatility.Leakproof),
+		// NOTE: Using unpreferred here is a hack that avoids some "ambiguous
+		// comparison operator" errors. It is necessary because we do not follow
+		// all of Postgres's type conversion rules. See #75101.
+		unpreferred(makeIsFn(types.BPChar, types.BPChar, volatility.Leakproof)),
 		makeIsFn(types.Time, types.Time, volatility.Leakproof),
 		makeIsFn(types.TimeTZ, types.TimeTZ, volatility.Leakproof),
 		makeIsFn(types.Timestamp, types.Timestamp, volatility.Leakproof),
@@ -1813,8 +1910,13 @@ var CmpOps = cmpOpFixups(map[treecmp.ComparisonOperatorSymbol]*CmpOpOverloads{
 		makeEvalTupleIn(types.Jsonb, volatility.Leakproof),
 		makeEvalTupleIn(types.Oid, volatility.Leakproof),
 		makeEvalTupleIn(types.PGLSN, volatility.Leakproof),
+		makeEvalTupleIn(types.PGVector, volatility.Leakproof),
 		makeEvalTupleIn(types.RefCursor, volatility.Leakproof),
 		makeEvalTupleIn(types.String, volatility.Leakproof),
+		// NOTE: Using unpreferred here is a hack that avoids some "ambiguous
+		// comparison operator" errors. It is necessary because we do not follow
+		// all of Postgres's type conversion rules. See #75101.
+		unpreferred(makeEvalTupleIn(types.BPChar, volatility.Leakproof)),
 		makeEvalTupleIn(types.Time, volatility.Leakproof),
 		makeEvalTupleIn(types.TimeTZ, volatility.Leakproof),
 		makeEvalTupleIn(types.Timestamp, volatility.Leakproof),
@@ -2066,6 +2168,8 @@ func (expr *FuncExpr) MaybeWrapError(err error) error {
 		return err
 	}
 	// Otherwise, wrap it with context.
+	// TODO(yuzefovich): consider removing this context in order to match
+	// postgres error messages.
 	newErr := errors.Wrapf(err, "%s()", errors.Safe(fName))
 	// Count function errors as it flows out of the system. We need to handle
 	// them this way because if we are facing a retry error, in particular those
diff --git a/pkg/sql/sem/tree/eval_binary_ops.go b/pkg/sql/sem/tree/eval_binary_ops.go
index 0106e57..2cd24f5 100644
--- a/pkg/sql/sem/tree/eval_binary_ops.go
+++ b/pkg/sql/sem/tree/eval_binary_ops.go
@@ -1,12 +1,7 @@
 // Copyright 2022 The Cockroach Authors.
 //
-// Use of this software is governed by the Business Source License
-// included in the file licenses/BSL.txt.
-//
-// As of the Change Date specified in that file, in accordance with
-// the Business Source License, use of this software will be governed
-// by the Apache License, Version 2.0, included in the file
-// licenses/APL.txt.
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
 
 package tree
 
@@ -81,6 +76,15 @@ type TSMatchesVectorQueryOp struct{}
 // TSMatchesQueryVectorOp is a BinaryEvalOp.
 type TSMatchesQueryVectorOp struct{}
 
+type (
+	// DistanceVectorOp is a BinaryEvalOp.
+	DistanceVectorOp struct{}
+	// CosDistanceVectorOp is a BinaryEvalOp.
+	CosDistanceVectorOp struct{}
+	// NegInnerProductVectorOp is a BinaryEvalOp.
+	NegInnerProductVectorOp struct{}
+)
+
 // AppendToMaybeNullArrayOp is a BinaryEvalOp.
 type AppendToMaybeNullArrayOp struct {
 	Typ *types.T
@@ -180,6 +184,8 @@ type (
 	PlusDecimalPGLSNOp struct{}
 	// PlusPGLSNDecimalOp is a BinaryEvalOp.
 	PlusPGLSNDecimalOp struct{}
+	// PlusPGVectorOp is a BinaryEvalOp.
+	PlusPGVectorOp struct{}
 )
 
 type (
@@ -235,6 +241,8 @@ type (
 	MinusPGLSNDecimalOp struct{}
 	// MinusPGLSNOp is a BinaryEvalOp.
 	MinusPGLSNOp struct{}
+	// MinusPGVectorOp is a BinaryEvalOp.
+	MinusPGVectorOp struct{}
 )
 type (
 	// MultDecimalIntOp is a BinaryEvalOp.
@@ -259,6 +267,8 @@ type (
 	MultIntervalFloatOp struct{}
 	// MultIntervalIntOp is a BinaryEvalOp.
 	MultIntervalIntOp struct{}
+	// MultPGVectorOp is a BinaryEvalOp.
+	MultPGVectorOp struct{}
 )
 
 type (
diff --git a/pkg/sql/sem/tree/eval_expr_generated.go b/pkg/sql/sem/tree/eval_expr_generated.go
index 481a498..e6aa560 100644
--- a/pkg/sql/sem/tree/eval_expr_generated.go
+++ b/pkg/sql/sem/tree/eval_expr_generated.go
@@ -1,12 +1,7 @@
 // Copyright 2022 The Cockroach Authors.
 //
-// Use of this software is governed by the Business Source License
-// included in the file licenses/BSL.txt.
-//
-// As of the Change Date specified in that file, in accordance with
-// the Business Source License, use of this software will be governed
-// by the Apache License, Version 2.0, included in the file
-// licenses/APL.txt.
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
 
 // Code generated by eval_gen.go. DO NOT EDIT.
 // Regenerate this file with either of the following commands:
@@ -54,6 +49,7 @@ type ExprEvaluator interface {
 	EvalSubquery(context.Context, *Subquery) (Datum, error)
 	EvalTuple(context.Context, *Tuple) (Datum, error)
 	EvalTupleStar(context.Context, *TupleStar) (Datum, error)
+	EvalTxnControlExpr(context.Context, *TxnControlExpr) (Datum, error)
 	EvalTypedDummy(context.Context, *TypedDummy) (Datum, error)
 	EvalUnaryExpr(context.Context, *UnaryExpr) (Datum, error)
 	EvalUnqualifiedStar(context.Context, UnqualifiedStar) (Datum, error)
@@ -206,6 +202,11 @@ func (node *DJSON) Eval(ctx context.Context, v ExprEvaluator) (Datum, error) {
 	return node, nil
 }
 
+// Eval is part of the TypedExpr interface.
+func (node *DJsonpath) Eval(ctx context.Context, v ExprEvaluator) (Datum, error) {
+	return node, nil
+}
+
 // Eval is part of the TypedExpr interface.
 func (node *DOid) Eval(ctx context.Context, v ExprEvaluator) (Datum, error) {
 	return node, nil
@@ -221,6 +222,11 @@ func (node *DPGLSN) Eval(ctx context.Context, v ExprEvaluator) (Datum, error) {
 	return node, nil
 }
 
+// Eval is part of the TypedExpr interface.
+func (node *DPGVector) Eval(ctx context.Context, v ExprEvaluator) (Datum, error) {
+	return node, nil
+}
+
 // Eval is part of the TypedExpr interface.
 func (node *DString) Eval(ctx context.Context, v ExprEvaluator) (Datum, error) {
 	return node, nil
@@ -366,6 +372,11 @@ func (node *TupleStar) Eval(ctx context.Context, v ExprEvaluator) (Datum, error)
 	return v.EvalTupleStar(ctx, node)
 }
 
+// Eval is part of the TypedExpr interface.
+func (node *TxnControlExpr) Eval(ctx context.Context, v ExprEvaluator) (Datum, error) {
+	return v.EvalTxnControlExpr(ctx, node)
+}
+
 // Eval is part of the TypedExpr interface.
 func (node *TypedDummy) Eval(ctx context.Context, v ExprEvaluator) (Datum, error) {
 	return v.EvalTypedDummy(ctx, node)
diff --git a/pkg/sql/sem/tree/eval_op_generated.go b/pkg/sql/sem/tree/eval_op_generated.go
index a99cd26..54c5473 100644
--- a/pkg/sql/sem/tree/eval_op_generated.go
+++ b/pkg/sql/sem/tree/eval_op_generated.go
@@ -1,12 +1,7 @@
 // Copyright 2022 The Cockroach Authors.
 //
-// Use of this software is governed by the Business Source License
-// included in the file licenses/BSL.txt.
-//
-// As of the Change Date specified in that file, in accordance with
-// the Business Source License, use of this software will be governed
-// by the Apache License, Version 2.0, included in the file
-// licenses/APL.txt.
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
 
 // Code generated by eval_gen.go. DO NOT EDIT.
 // Regenerate this file with either of the following commands:
@@ -77,6 +72,8 @@ type BinaryOpEvaluator interface {
 	EvalContainedByJsonbOp(context.Context, *ContainedByJsonbOp, Datum, Datum) (Datum, error)
 	EvalContainsArrayOp(context.Context, *ContainsArrayOp, Datum, Datum) (Datum, error)
 	EvalContainsJsonbOp(context.Context, *ContainsJsonbOp, Datum, Datum) (Datum, error)
+	EvalCosDistanceVectorOp(context.Context, *CosDistanceVectorOp, Datum, Datum) (Datum, error)
+	EvalDistanceVectorOp(context.Context, *DistanceVectorOp, Datum, Datum) (Datum, error)
 	EvalDivDecimalIntOp(context.Context, *DivDecimalIntOp, Datum, Datum) (Datum, error)
 	EvalDivDecimalOp(context.Context, *DivDecimalOp, Datum, Datum) (Datum, error)
 	EvalDivFloatOp(context.Context, *DivFloatOp, Datum, Datum) (Datum, error)
@@ -121,6 +118,7 @@ type BinaryOpEvaluator interface {
 	EvalMinusJsonbStringOp(context.Context, *MinusJsonbStringOp, Datum, Datum) (Datum, error)
 	EvalMinusPGLSNDecimalOp(context.Context, *MinusPGLSNDecimalOp, Datum, Datum) (Datum, error)
 	EvalMinusPGLSNOp(context.Context, *MinusPGLSNOp, Datum, Datum) (Datum, error)
+	EvalMinusPGVectorOp(context.Context, *MinusPGVectorOp, Datum, Datum) (Datum, error)
 	EvalMinusTimeIntervalOp(context.Context, *MinusTimeIntervalOp, Datum, Datum) (Datum, error)
 	EvalMinusTimeOp(context.Context, *MinusTimeOp, Datum, Datum) (Datum, error)
 	EvalMinusTimeTZIntervalOp(context.Context, *MinusTimeTZIntervalOp, Datum, Datum) (Datum, error)
@@ -147,6 +145,8 @@ type BinaryOpEvaluator interface {
 	EvalMultIntervalDecimalOp(context.Context, *MultIntervalDecimalOp, Datum, Datum) (Datum, error)
 	EvalMultIntervalFloatOp(context.Context, *MultIntervalFloatOp, Datum, Datum) (Datum, error)
 	EvalMultIntervalIntOp(context.Context, *MultIntervalIntOp, Datum, Datum) (Datum, error)
+	EvalMultPGVectorOp(context.Context, *MultPGVectorOp, Datum, Datum) (Datum, error)
+	EvalNegInnerProductVectorOp(context.Context, *NegInnerProductVectorOp, Datum, Datum) (Datum, error)
 	EvalOverlapsArrayOp(context.Context, *OverlapsArrayOp, Datum, Datum) (Datum, error)
 	EvalOverlapsINetOp(context.Context, *OverlapsINetOp, Datum, Datum) (Datum, error)
 	EvalPlusDateIntOp(context.Context, *PlusDateIntOp, Datum, Datum) (Datum, error)
@@ -169,6 +169,7 @@ type BinaryOpEvaluator interface {
 	EvalPlusIntervalTimestampOp(context.Context, *PlusIntervalTimestampOp, Datum, Datum) (Datum, error)
 	EvalPlusIntervalTimestampTZOp(context.Context, *PlusIntervalTimestampTZOp, Datum, Datum) (Datum, error)
 	EvalPlusPGLSNDecimalOp(context.Context, *PlusPGLSNDecimalOp, Datum, Datum) (Datum, error)
+	EvalPlusPGVectorOp(context.Context, *PlusPGVectorOp, Datum, Datum) (Datum, error)
 	EvalPlusTimeDateOp(context.Context, *PlusTimeDateOp, Datum, Datum) (Datum, error)
 	EvalPlusTimeIntervalOp(context.Context, *PlusTimeIntervalOp, Datum, Datum) (Datum, error)
 	EvalPlusTimeTZDateOp(context.Context, *PlusTimeTZDateOp, Datum, Datum) (Datum, error)
@@ -355,6 +356,16 @@ func (op *ContainsJsonbOp) Eval(ctx context.Context, e OpEvaluator, a, b Datum)
 	return e.EvalContainsJsonbOp(ctx, op, a, b)
 }
 
+// Eval is part of the BinaryEvalOp interface.
+func (op *CosDistanceVectorOp) Eval(ctx context.Context, e OpEvaluator, a, b Datum) (Datum, error) {
+	return e.EvalCosDistanceVectorOp(ctx, op, a, b)
+}
+
+// Eval is part of the BinaryEvalOp interface.
+func (op *DistanceVectorOp) Eval(ctx context.Context, e OpEvaluator, a, b Datum) (Datum, error) {
+	return e.EvalDistanceVectorOp(ctx, op, a, b)
+}
+
 // Eval is part of the BinaryEvalOp interface.
 func (op *DivDecimalIntOp) Eval(ctx context.Context, e OpEvaluator, a, b Datum) (Datum, error) {
 	return e.EvalDivDecimalIntOp(ctx, op, a, b)
@@ -575,6 +586,11 @@ func (op *MinusPGLSNOp) Eval(ctx context.Context, e OpEvaluator, a, b Datum) (Da
 	return e.EvalMinusPGLSNOp(ctx, op, a, b)
 }
 
+// Eval is part of the BinaryEvalOp interface.
+func (op *MinusPGVectorOp) Eval(ctx context.Context, e OpEvaluator, a, b Datum) (Datum, error) {
+	return e.EvalMinusPGVectorOp(ctx, op, a, b)
+}
+
 // Eval is part of the BinaryEvalOp interface.
 func (op *MinusTimeIntervalOp) Eval(ctx context.Context, e OpEvaluator, a, b Datum) (Datum, error) {
 	return e.EvalMinusTimeIntervalOp(ctx, op, a, b)
@@ -705,6 +721,16 @@ func (op *MultIntervalIntOp) Eval(ctx context.Context, e OpEvaluator, a, b Datum
 	return e.EvalMultIntervalIntOp(ctx, op, a, b)
 }
 
+// Eval is part of the BinaryEvalOp interface.
+func (op *MultPGVectorOp) Eval(ctx context.Context, e OpEvaluator, a, b Datum) (Datum, error) {
+	return e.EvalMultPGVectorOp(ctx, op, a, b)
+}
+
+// Eval is part of the BinaryEvalOp interface.
+func (op *NegInnerProductVectorOp) Eval(ctx context.Context, e OpEvaluator, a, b Datum) (Datum, error) {
+	return e.EvalNegInnerProductVectorOp(ctx, op, a, b)
+}
+
 // Eval is part of the BinaryEvalOp interface.
 func (op *OverlapsArrayOp) Eval(ctx context.Context, e OpEvaluator, a, b Datum) (Datum, error) {
 	return e.EvalOverlapsArrayOp(ctx, op, a, b)
@@ -815,6 +841,11 @@ func (op *PlusPGLSNDecimalOp) Eval(ctx context.Context, e OpEvaluator, a, b Datu
 	return e.EvalPlusPGLSNDecimalOp(ctx, op, a, b)
 }
 
+// Eval is part of the BinaryEvalOp interface.
+func (op *PlusPGVectorOp) Eval(ctx context.Context, e OpEvaluator, a, b Datum) (Datum, error) {
+	return e.EvalPlusPGVectorOp(ctx, op, a, b)
+}
+
 // Eval is part of the BinaryEvalOp interface.
 func (op *PlusTimeDateOp) Eval(ctx context.Context, e OpEvaluator, a, b Datum) (Datum, error) {
 	return e.EvalPlusTimeDateOp(ctx, op, a, b)
diff --git a/pkg/sql/sem/tree/eval_unary_ops.go b/pkg/sql/sem/tree/eval_unary_ops.go
index 8124a15..f1214eb 100644
--- a/pkg/sql/sem/tree/eval_unary_ops.go
+++ b/pkg/sql/sem/tree/eval_unary_ops.go
@@ -1,12 +1,7 @@
 // Copyright 2022 The Cockroach Authors.
 //
-// Use of this software is governed by the Business Source License
-// included in the file licenses/BSL.txt.
-//
-// As of the Change Date specified in that file, in accordance with
-// the Business Source License, use of this software will be governed
-// by the Apache License, Version 2.0, included in the file
-// licenses/APL.txt.
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
 
 package tree
 
diff --git a/pkg/sql/sem/tree/evalgen/eval_gen.go b/pkg/sql/sem/tree/evalgen/eval_gen.go
index 9074cf4..2bc5afb 100644
--- a/pkg/sql/sem/tree/evalgen/eval_gen.go
+++ b/pkg/sql/sem/tree/evalgen/eval_gen.go
@@ -1,12 +1,7 @@
 // Copyright 2022 The Cockroach Authors.
 //
-// Use of this software is governed by the Business Source License
-// included in the file licenses/BSL.txt.
-//
-// As of the Change Date specified in that file, in accordance with
-// the Business Source License, use of this software will be governed
-// by the Apache License, Version 2.0, included in the file
-// licenses/APL.txt.
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
 
 // Command evalgen is used to generate interfaces and "visitor" methods for
 // expr and op evaluation.
@@ -95,13 +90,8 @@ func writeFile(name string, fn func(f *os.File) error) error {
 
 const header = `// Copyright 2022 The Cockroach Authors.
 //
-// Use of this software is governed by the Business Source License
-// included in the file licenses/BSL.txt.
-//
-// As of the Change Date specified in that file, in accordance with
-// the Business Source License, use of this software will be governed
-// by the Apache License, Version 2.0, included in the file
-// licenses/APL.txt.
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
 
 // Code generated by eval_gen.go. DO NOT EDIT.
 // Regenerate this file with either of the following commands:
diff --git a/pkg/sql/sem/tree/evalgen/expr.go b/pkg/sql/sem/tree/evalgen/expr.go
index 6551fde..4c945e3 100644
--- a/pkg/sql/sem/tree/evalgen/expr.go
+++ b/pkg/sql/sem/tree/evalgen/expr.go
@@ -1,12 +1,7 @@
 // Copyright 2022 The Cockroach Authors.
 //
-// Use of this software is governed by the Business Source License
-// included in the file licenses/BSL.txt.
-//
-// As of the Change Date specified in that file, in accordance with
-// the Business Source License, use of this software will be governed
-// by the Apache License, Version 2.0, included in the file
-// licenses/APL.txt.
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
 
 package main
 
diff --git a/pkg/sql/sem/tree/evalgen/op.go b/pkg/sql/sem/tree/evalgen/op.go
index 85274e7..4ba3025 100644
--- a/pkg/sql/sem/tree/evalgen/op.go
+++ b/pkg/sql/sem/tree/evalgen/op.go
@@ -1,12 +1,7 @@
 // Copyright 2022 The Cockroach Authors.
 //
-// Use of this software is governed by the Business Source License
-// included in the file licenses/BSL.txt.
-//
-// As of the Change Date specified in that file, in accordance with
-// the Business Source License, use of this software will be governed
-// by the Apache License, Version 2.0, included in the file
-// licenses/APL.txt.
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
 
 package main
 
diff --git a/pkg/sql/sem/tree/evalgen/string_set.go b/pkg/sql/sem/tree/evalgen/string_set.go
index b8d4e89..09dcac9 100644
--- a/pkg/sql/sem/tree/evalgen/string_set.go
+++ b/pkg/sql/sem/tree/evalgen/string_set.go
@@ -1,12 +1,7 @@
 // Copyright 2022 The Cockroach Authors.
 //
-// Use of this software is governed by the Business Source License
-// included in the file licenses/BSL.txt.
-//
-// As of the Change Date specified in that file, in accordance with
-// the Business Source License, use of this software will be governed
-// by the Apache License, Version 2.0, included in the file
-// licenses/APL.txt.
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
 
 package main
 
diff --git a/pkg/sql/sem/tree/explain.go b/pkg/sql/sem/tree/explain.go
index a78141e..ba99e2a 100644
--- a/pkg/sql/sem/tree/explain.go
+++ b/pkg/sql/sem/tree/explain.go
@@ -1,12 +1,7 @@
 // Copyright 2015 The Cockroach Authors.
 //
-// Use of this software is governed by the Business Source License
-// included in the file licenses/BSL.txt.
-//
-// As of the Change Date specified in that file, in accordance with
-// the Business Source License, use of this software will be governed
-// by the Apache License, Version 2.0, included in the file
-// licenses/APL.txt.
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
 
 package tree
 
diff --git a/pkg/sql/sem/tree/export.go b/pkg/sql/sem/tree/export.go
index 9b592ff..7cf9e48 100644
--- a/pkg/sql/sem/tree/export.go
+++ b/pkg/sql/sem/tree/export.go
@@ -1,12 +1,7 @@
 // Copyright 2018 The Cockroach Authors.
 //
-// Use of this software is governed by the Business Source License
-// included in the file licenses/BSL.txt.
-//
-// As of the Change Date specified in that file, in accordance with
-// the Business Source License, use of this software will be governed
-// by the Apache License, Version 2.0, included in the file
-// licenses/APL.txt.
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
 
 package tree
 
@@ -25,7 +20,7 @@ func (node *Export) Format(ctx *FmtCtx) {
 	ctx.WriteString("EXPORT INTO ")
 	ctx.WriteString(node.FileFormat)
 	ctx.WriteString(" ")
-	ctx.FormatNode(node.File)
+	ctx.FormatURI(node.File)
 	if node.Options != nil {
 		ctx.WriteString(" WITH OPTIONS(")
 		ctx.FormatNode(&node.Options)
diff --git a/pkg/sql/sem/tree/expr.go b/pkg/sql/sem/tree/expr.go
index af0ce16..dabff21 100644
--- a/pkg/sql/sem/tree/expr.go
+++ b/pkg/sql/sem/tree/expr.go
@@ -1,12 +1,7 @@
 // Copyright 2015 The Cockroach Authors.
 //
-// Use of this software is governed by the Business Source License
-// included in the file licenses/BSL.txt.
-//
-// As of the Change Date specified in that file, in accordance with
-// the Business Source License, use of this software will be governed
-// by the Apache License, Version 2.0, included in the file
-// licenses/APL.txt.
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
 
 package tree
 
@@ -44,7 +39,7 @@ type Expr interface {
 	// The semaCtx parameter defines the context in which to perform type checking.
 	// The desired parameter hints the desired type that the method's caller wants from
 	// the resulting TypedExpr. It is not valid to call TypeCheck with a nil desired
-	// type. Instead, call it with wildcard type types.Any if no specific type is
+	// type. Instead, call it with wildcard type types.AnyElement if no specific type is
 	// desired. This restriction is also true of most methods and functions related
 	// to type checking.
 	TypeCheck(ctx context.Context, semaCtx *SemaContext, desired *types.T) (TypedExpr, error)
@@ -428,7 +423,7 @@ func NewTypedCollateExpr(expr TypedExpr, locale string) *CollateExpr {
 		Expr:   expr,
 		Locale: locale,
 	}
-	node.typ = types.MakeCollatedString(types.String, locale)
+	node.typ = types.MakeCollatedType(expr.ResolvedType(), locale)
 	return node
 }
 
@@ -803,25 +798,17 @@ func NewPlaceholder(name string) (*Placeholder, error) {
 
 // Format implements the NodeFormatter interface.
 func (node *Placeholder) Format(ctx *FmtCtx) {
-	if ctx.HasFlags(FmtHideConstants) {
-		if ctx.placeholderFormat != nil {
-			ctx.placeholderFormat(ctx, node)
-			return
-		}
-		ctx.Printf("$%d", node.Idx+1)
-	} else {
-		if ctx.placeholderFormat != nil {
-			ctx.placeholderFormat(ctx, node)
-			return
-		}
-		ctx.Printf("$%d", node.Idx+1)
+	if ctx.placeholderFormat != nil {
+		ctx.placeholderFormat(ctx, node)
+		return
 	}
+	ctx.Printf("$%d", node.Idx+1)
 }
 
 // ResolvedType implements the TypedExpr interface.
 func (node *Placeholder) ResolvedType() *types.T {
 	if node.typ == nil {
-		return types.Any
+		return types.AnyElement
 	}
 	return node.typ
 }
@@ -979,7 +966,7 @@ type Subquery struct {
 // ResolvedType implements the TypedExpr interface.
 func (node *Subquery) ResolvedType() *types.T {
 	if node.typ == nil {
-		return types.Any
+		return types.AnyElement
 	}
 	return node.typ
 }
@@ -1058,6 +1045,7 @@ var binaryOpPrio = [...]int{
 	treebin.Bitxor: 6,
 	treebin.Bitor:  7,
 	treebin.Concat: 8, treebin.JSONFetchVal: 8, treebin.JSONFetchText: 8, treebin.JSONFetchValPath: 8, treebin.JSONFetchTextPath: 8,
+	treebin.Distance: 8, treebin.CosDistance: 8, treebin.NegInnerProduct: 8,
 }
 
 // binaryOpFullyAssoc indicates whether an operator is fully associative.
@@ -1071,6 +1059,7 @@ var binaryOpFullyAssoc = [...]bool{
 	treebin.Bitxor: true,
 	treebin.Bitor:  true,
 	treebin.Concat: true, treebin.JSONFetchVal: false, treebin.JSONFetchText: false, treebin.JSONFetchValPath: false, treebin.JSONFetchTextPath: false,
+	treebin.Distance: false, treebin.CosDistance: false, treebin.NegInnerProduct: false,
 }
 
 // BinaryExpr represents a binary value expression.
@@ -1375,6 +1364,19 @@ const (
 	OrderedSetAgg
 )
 
+// onlyNameFunc is the list of function who can be compiled with only the
+// name. This is for PG compatibility, where examples such as `CURRENT_TIMESTAMP()`
+// is not allowed, but `CURRENT_TIMESTAMP` is allowed.
+var onlyNameFunc = map[string]bool{
+	"current_timestamp": true,
+}
+
+func isOnlyNameFunc(f *FuncExpr) bool {
+	funcStr := f.Func.String()
+	_, ok := onlyNameFunc[funcStr]
+	return ok
+}
+
 // Format implements the NodeFormatter interface.
 func (node *FuncExpr) Format(ctx *FmtCtx) {
 	var typ string
@@ -1388,45 +1390,51 @@ func (node *FuncExpr) Format(ctx *FmtCtx) {
 	// they are resolved. We conservatively redact function names if requested.
 	// TODO(111385): Investigate ways to identify built-in functions before
 	// type-checking.
-	ctx.WithFlags(ctx.flags|FmtBareIdentifiers, func() {
+	//
+	// Instruct the pretty-printer not to wrap reserved keywords in quotes. Only
+	// builtin functions can have reserved keywords as names, and it is not
+	// necessary (or desirable) to quote them.
+	ctx.WithFlags(ctx.flags|FmtBareReservedKeywords, func() {
 		ctx.FormatNode(&node.Func)
 	})
 
-	ctx.WriteByte('(')
-	ctx.WriteString(typ)
-	ctx.FormatNode(&node.Exprs)
-	if node.AggType == GeneralAgg && len(node.OrderBy) > 0 {
-		ctx.WriteByte(' ')
-		ctx.FormatNode(&node.OrderBy)
-	}
-	ctx.WriteByte(')')
-	if ctx.HasFlags(FmtParsable) && node.typ != nil {
-		if node.fnProps.AmbiguousReturnType {
-			// There's no type annotation available for tuples.
-			// TODO(jordan,knz): clean this up. AmbiguousReturnType should be set only
-			// when we should and can put an annotation here. #28579
-			if node.typ.Family() != types.TupleFamily {
-				ctx.WriteString(":::")
-				ctx.Buffer.WriteString(node.typ.SQLString())
+	if !(ctx.HasFlags(FmtFuncOnlyName) && isOnlyNameFunc(node)) {
+		ctx.WriteByte('(')
+		ctx.WriteString(typ)
+		ctx.FormatNode(&node.Exprs)
+		if node.AggType == GeneralAgg && len(node.OrderBy) > 0 {
+			ctx.WriteByte(' ')
+			ctx.FormatNode(&node.OrderBy)
+		}
+		ctx.WriteByte(')')
+		if ctx.HasFlags(FmtParsable) && node.typ != nil {
+			if node.fnProps.AmbiguousReturnType {
+				// There's no type annotation available for tuples.
+				// TODO(jordan,knz): clean this up. AmbiguousReturnType should be set only
+				// when we should and can put an annotation here. #28579
+				if node.typ.Family() != types.TupleFamily {
+					ctx.WriteString(":::")
+					ctx.Buffer.WriteString(node.typ.SQLString())
+				}
 			}
 		}
-	}
-	if node.AggType == OrderedSetAgg && len(node.OrderBy) > 0 {
-		ctx.WriteString(" WITHIN GROUP (")
-		ctx.FormatNode(&node.OrderBy)
-		ctx.WriteString(")")
-	}
-	if node.Filter != nil {
-		ctx.WriteString(" FILTER (WHERE ")
-		ctx.FormatNode(node.Filter)
-		ctx.WriteString(")")
-	}
-	if window := node.WindowDef; window != nil {
-		ctx.WriteString(" OVER ")
-		if window.Name != "" {
-			ctx.FormatNode(&window.Name)
-		} else {
-			ctx.FormatNode(window)
+		if node.AggType == OrderedSetAgg && len(node.OrderBy) > 0 {
+			ctx.WriteString(" WITHIN GROUP (")
+			ctx.FormatNode(&node.OrderBy)
+			ctx.WriteString(")")
+		}
+		if node.Filter != nil {
+			ctx.WriteString(" FILTER (WHERE ")
+			ctx.FormatNode(node.Filter)
+			ctx.WriteString(")")
+		}
+		if window := node.WindowDef; window != nil {
+			ctx.WriteString(" OVER ")
+			if window.Name != "" {
+				ctx.FormatNode(&window.Name)
+			} else {
+				ctx.FormatNode(window)
+			}
 		}
 	}
 }
@@ -1750,6 +1758,7 @@ func (node *DGeometry) String() string        { return AsString(node) }
 func (node *DInt) String() string             { return AsString(node) }
 func (node *DInterval) String() string        { return AsString(node) }
 func (node *DJSON) String() string            { return AsString(node) }
+func (node *DJsonpath) String() string        { return AsString(node) }
 func (node *DUuid) String() string            { return AsString(node) }
 func (node *DIPAddr) String() string          { return AsString(node) }
 func (node *DString) String() string          { return AsString(node) }
@@ -1779,6 +1788,7 @@ func (node *NumVal) String() string           { return AsString(node) }
 func (node *OrExpr) String() string           { return AsString(node) }
 func (node *ParenExpr) String() string        { return AsString(node) }
 func (node *RangeCond) String() string        { return AsString(node) }
+func (node *TxnControlExpr) String() string   { return AsString(node) }
 func (node *StrVal) String() string           { return AsString(node) }
 func (node *Subquery) String() string         { return AsString(node) }
 func (node *RoutineExpr) String() string      { return AsString(node) }
diff --git a/pkg/sql/sem/tree/format.go b/pkg/sql/sem/tree/format.go
index df89985..ded254a 100644
--- a/pkg/sql/sem/tree/format.go
+++ b/pkg/sql/sem/tree/format.go
@@ -1,12 +1,7 @@
 // Copyright 2016 The Cockroach Authors.
 //
-// Use of this software is governed by the Business Source License
-// included in the file licenses/BSL.txt.
-//
-// As of the Change Date specified in that file, in accordance with
-// the Business Source License, use of this software will be governed
-// by the Apache License, Version 2.0, included in the file
-// licenses/APL.txt.
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
 
 package tree
 
@@ -27,14 +22,14 @@ import (
 )
 
 // FmtFlags carries options for the pretty-printer.
-type FmtFlags int
+type FmtFlags int64
 
 // HasFlags tests whether the given flags are all set.
 func (f FmtFlags) HasFlags(subset FmtFlags) bool {
 	return f&subset == subset
 }
 
-// HasAnyFlags tests whether any of the given flags are all set.
+// HasAnyFlags tests whether any of the given flags are set.
 func (f FmtFlags) HasAnyFlags(subset FmtFlags) bool {
 	return f&subset != 0
 }
@@ -63,6 +58,10 @@ const (
 	// identifiers without wrapping quotes in any case.
 	FmtBareIdentifiers = FmtFlags(lexbase.EncBareIdentifiers)
 
+	// FmtBareReservedKeywords instructs the pretty-printer to print
+	// reserved keywords without wrapping quotes.
+	FmtBareReservedKeywords = FmtFlags(lexbase.EncBareReservedKeywords)
+
 	// FmtShowPasswords instructs the pretty-printer to not suppress passwords.
 	// If not set, passwords are replaced by *****.
 	FmtShowPasswords = FmtFlags(lexbase.EncFirstFreeFlagBit) << iota
@@ -73,7 +72,7 @@ const (
 
 	// FmtHideConstants instructs the pretty-printer to produce a
 	// representation that does not disclose query-specific data. It
-	// also shorten long lists in tuples, VALUES and array expressions.
+	// also shortens long lists in tuples, VALUES and array expressions.
 	FmtHideConstants
 
 	// FmtAnonymize instructs the pretty-printer to remove any name.
@@ -106,10 +105,6 @@ const (
 	// resolutions.
 	fmtDisambiguateDatumTypes
 
-	// fmtSymbolicVars indicates that IndexedVars must be pretty-printed
-	// using numeric notation (@123).
-	fmtSymbolicVars
-
 	// fmtUnicodeStrings prints strings and JSON using the Go string
 	// formatter. This is used e.g. for emitting values to CSV files.
 	fmtRawStrings
@@ -120,13 +115,16 @@ const (
 	// the numeric by enclosing them within parentheses.
 	FmtParsableNumerics
 
-	// FmtPGCatalog is used to produce expressions formatted in a way that's as
-	// close as possible to what clients expect to live in pg_catalog (e.g.
-	// pg_attrdef.adbin, pg_constraint.condef and pg_indexes.indexdef columns).
-	// Specifically, this strips type annotations (Postgres doesn't know what
-	// those are), adds cast expressions for non-numeric constants, and formats
-	// indexes in Postgres-specific syntax.
-	FmtPGCatalog
+	// fmtPGCatalog is used to produce array and bytes expressions formatted in
+	// a way that's as close as possible to what clients expect to live in
+	// pg_catalog (e.g. pg_attrdef.adbin, pg_constraint.condef and
+	// pg_indexes.indexdef columns).
+	fmtPGCatalog
+
+	// fmtPGCatalogCasts adds cast expressions for non-numeric constants and
+	// strips type annotations. This matches Postgres's formatting of
+	// expressions in pg_catalog.
+	fmtPGCatalogCasts
 
 	// If set, user defined types and datums of user defined types will be
 	// formatted in a way that is stable across changes to the underlying type.
@@ -169,11 +167,46 @@ const (
 	// This flag *overrides* `FmtMarkRedactionNode` above.
 	FmtOmitNameRedaction
 
-	// FmtTagDollarQuotes instructs tags to be kept intact in tagged dollar
-	// quotes. It also applies tags when formatting UDFs.
-	FmtTagDollarQuotes
+	// FmtShortenConstants shortens long lists in tuples, VALUES and array
+	// expressions. FmtHideConstants takes precedence over it.
+	FmtShortenConstants
+
+	// FmtCollapseLists instructs the pretty-printer to shorten lists
+	// containing only literals, placeholders and/or similar subexpressions
+	// of literals/placeholders to their first element (scrubbed) followed
+	// by "__more__". E.g.
+	//  SELECT * FROM foo where v IN (1, 2+2, $1, $2*3) => SELECT * FROM foo where v IN (_, __more__)
+	FmtCollapseLists
+
+	// FmtConstantsAsUnderscores instructs the pretty-printer to format
+	// constants (literals, placeholders) as underscores.
+	// e.g.
+	//   SELECT 1, 'a', $1 => SELECT _, _, _
+	FmtConstantsAsUnderscores
+
+	// FmtAlwaysQualifyUserDefinedTypeNames instructs the pretty-printer to include
+	// the name of user-defined types as a three-part name.
+	FmtAlwaysQualifyUserDefinedTypeNames
+
+	// FmtShowFullURIs instructs the pretty-printer to not sanitize URIs. If not
+	// set, URIs are sanitized to prevent leaking secrets.
+	FmtShowFullURIs
+
+	// FmtSkipAsOfSystemTimeClauses prevents the formatter from printing AS OF
+	// SYSTEM TIME clauses.
+	FmtSkipAsOfSystemTimeClauses
+
+	// FmtFuncOnlyName instructs the formating for a function only print
+	// its name, without printing the body of the function nor with the brackets.
+	FmtFuncOnlyName
 )
 
+const genericArityIndicator = "__more__"
+
+// StmtFingerprintPlaceholder is the char that replaces all literals and
+// placeholders in a query when computing its fingerprint.
+const StmtFingerprintPlaceholder = '_'
+
 // PasswordSubstitution is the string that replaces
 // passwords unless FmtShowPasswords is specified.
 const PasswordSubstitution = "'*****'"
@@ -191,6 +224,16 @@ const (
 	// in pgwire_encode.go.
 	FmtPgwireText = fmtPgwireFormat | FmtFlags(lexbase.EncBareStrings)
 
+	// FmtPGCatalog is used to produce expressions formatted in a way that's as
+	// close as possible to what clients expect to live in pg_catalog (e.g.
+	// pg_attrdef.adbin, pg_constraint.condef and pg_indexes.indexdef columns).
+	// Specifically, this strips type annotations (Postgres doesn't know what
+	// those are), adds cast expressions for non-numeric constants, formats
+	// arrays as strings with curly brackets (like FmtPGWireText), formats bytes
+	// with double quotes (also like FmtPGWireText), and formats indexes in
+	// Postgres-specific syntax.
+	FmtPGCatalog = fmtPGCatalog | fmtPGCatalogCasts
+
 	// FmtParsable instructs the pretty-printer to produce a representation that
 	// can be parsed into an equivalent expression. If there is a chance that the
 	// formatted data will be stored durably on disk or sent to other nodes,
@@ -216,8 +259,7 @@ const (
 	//  - user defined types and datums of user defined types are formatted
 	//    using static representations to avoid name resolution and invalidation
 	//    due to changes in the underlying type.
-	FmtCheckEquivalence = fmtSymbolicVars |
-		fmtDisambiguateDatumTypes |
+	FmtCheckEquivalence = fmtDisambiguateDatumTypes |
 		FmtParsableNumerics |
 		fmtStaticallyFormatUserDefinedTypes
 
@@ -241,6 +283,9 @@ const (
 	// with PostgreSQL, whereas EXPORT may evolve over time to support
 	// other things (eg. fixing #33429).
 	FmtExport = FmtBareStrings | fmtRawStrings
+
+	// FmtAlwaysQualifyNames will fully qualify various types of names.
+	FmtAlwaysQualifyNames = FmtAlwaysQualifyTableNames | FmtAlwaysQualifyUserDefinedTypeNames
 )
 
 const flagsRequiringAnnotations = FmtAlwaysQualifyTableNames
@@ -259,7 +304,8 @@ type FmtCtx struct {
 	location             *time.Location
 
 	// NOTE: if you add more flags to this structure, make sure to add
-	// corresponding cleanup code in FmtCtx.Close().
+	// corresponding cleanup code in FmtCtx.Close(), as well as handling in
+	// FmtCtx.Clone().
 
 	// The flags to use for pretty-printing.
 	flags FmtFlags
@@ -350,9 +396,25 @@ func NewFmtCtx(f FmtFlags, opts ...FmtCtxOption) *FmtCtx {
 	if ctx.ann == nil && f&flagsRequiringAnnotations != 0 {
 		panic(errors.AssertionFailedf("no Annotations provided"))
 	}
+
 	return ctx
 }
 
+// Clone returns a new FmtCtx with all the same flags and options as the
+// original.
+func (ctx *FmtCtx) Clone() *FmtCtx {
+	newCtx := fmtCtxPool.Get().(*FmtCtx)
+	newCtx.flags = ctx.flags
+	newCtx.ann = ctx.ann
+	newCtx.indexedVarFormat = ctx.indexedVarFormat
+	newCtx.placeholderFormat = ctx.placeholderFormat
+	newCtx.tableNameFormatter = ctx.tableNameFormatter
+	newCtx.indexedTypeFormatter = ctx.indexedTypeFormatter
+	newCtx.dataConversionConfig = ctx.dataConversionConfig
+	newCtx.location = ctx.location
+	return newCtx
+}
+
 // SetDataConversionConfig sets the DataConversionConfig on ctx and returns the
 // old one.
 func (ctx *FmtCtx) SetDataConversionConfig(
@@ -394,11 +456,41 @@ func (ctx *FmtCtx) WithFlags(flags FmtFlags, fn func()) {
 	fn()
 }
 
-// HasFlags returns true iff the given flags are set in the formatter context.
+// WithoutConstantRedaction modifies FmtCtx to ensure that constants are
+// displayed rather than being replaced by '_', calls fn, then restores the
+// original flags.
+func (ctx *FmtCtx) WithoutConstantRedaction(fn func()) {
+	oldFlags := ctx.flags
+	ctx.flags &= ^FmtHideConstants
+	ctx.flags &= ^FmtAnonymize
+	defer func() { ctx.flags = oldFlags }()
+
+	fn()
+}
+
+// WithAnnotations modifies FmtCtx to use the provided Annotations, calls fn,
+// then restores the original ones.
+func (ctx *FmtCtx) WithAnnotations(ann *Annotations, fn func()) {
+	defer func(oldAnn *Annotations) {
+		ctx.ann = oldAnn
+	}(ctx.ann)
+	ctx.ann = ann
+
+	fn()
+}
+
+// HasFlags returns true iff all of the given flags are set in the formatter
+// context.
 func (ctx *FmtCtx) HasFlags(f FmtFlags) bool {
 	return ctx.flags.HasFlags(f)
 }
 
+// HasAnyFlags returns true iff any of the given flags are set in the formatter
+// context.
+func (ctx *FmtCtx) HasAnyFlags(f FmtFlags) bool {
+	return ctx.flags.HasAnyFlags(f)
+}
+
 // Printf calls fmt.Fprintf on the linked bytes.Buffer. It is provided
 // for convenience, to avoid having to call fmt.Fprintf(&ctx.Buffer, ...).
 //
@@ -430,6 +522,95 @@ func (ctx *FmtCtx) FormatNameP(s *string) {
 	ctx.FormatNode((*Name)(s))
 }
 
+// FormatStringConstant formats a constant string value, redacting it if
+// FmtHideConstants is set.
+func (ctx *FmtCtx) FormatStringConstant(s string) {
+	ctx.WriteString("'")
+	if ctx.HasFlags(FmtHideConstants) {
+		ctx.WriteString("_")
+	} else {
+		ctx.WriteString(s)
+	}
+	ctx.WriteString("'")
+}
+
+// FormatStringDollarQuotes formats a string constant with dollar quotes.
+func (ctx *FmtCtx) FormatStringDollarQuotes(s string) {
+	// Find a delimiter that will not collide with any part of the string. This is
+	// very similar to what Postgres does.
+	delimiter := ""
+	if strings.Contains(s, "$$") {
+		delimiter = "funcbody"
+		for strings.Contains(s, "$"+delimiter+"$") {
+			delimiter = delimiter + "x"
+		}
+	}
+	ctx.WriteByte('$')
+	ctx.WriteString(delimiter)
+	ctx.WriteByte('$')
+	if ctx.flags.HasFlags(FmtAnonymize) || ctx.flags.HasFlags(FmtHideConstants) {
+		ctx.WriteString("_")
+	} else {
+		ctx.WriteString(s)
+	}
+	ctx.WriteByte('$')
+	ctx.WriteString(delimiter)
+	ctx.WriteByte('$')
+}
+
+// FormatURIs formats a list of string literals or placeholders containing URIs.
+func (ctx *FmtCtx) FormatURIs(uris []Expr) {
+	if len(uris) > 1 {
+		ctx.WriteString("(")
+	}
+	for i, uri := range uris {
+		if i > 0 {
+			ctx.WriteString(", ")
+		}
+		ctx.FormatURI(uri)
+	}
+	if len(uris) > 1 {
+		ctx.WriteString(")")
+	}
+}
+
+// FormatURI formats a string literal or placeholder containing a URI. If the
+// node is a string literal, we redact the contents to avoid leaking secrets.
+func (ctx *FmtCtx) FormatURI(uri Expr) {
+	switch n := uri.(type) {
+	case *StrVal, *DString:
+		if ctx.HasAnyFlags(
+			FmtShowPasswords | FmtShowFullURIs | FmtHideConstants | FmtConstantsAsUnderscores,
+		) {
+			ctx.FormatNode(n)
+			return
+		}
+		var raw, elided string
+		if str, ok := n.(*StrVal); ok {
+			raw = str.RawString()
+		} else {
+			raw = string(MustBeDString(uri))
+		}
+		if raw == "" || raw == "_" {
+			// Some commands treat empty URIs as special. And if we've re-parsed a URI
+			// formatted with FmtHideConstants, we should not try to interpret it as a
+			// URL but should leave it as-is.
+			ctx.FormatNode(n)
+			return
+		}
+		// TODO(michae2): Call SanitizeExternalStorageURI for fine-grained
+		// sanitization.
+		elided = strings.Trim(PasswordSubstitution, "'")
+		ctx.FormatNode(NewStrVal(elided))
+	case *Placeholder:
+		ctx.FormatNode(n)
+	default:
+		// We don't want to fail to sanitize other literals, so disallow other types
+		// of expressions (which should already be disallowed by the parser anyway).
+		panic(errors.AssertionFailedf("expected *StrVal, *DString, or *Placeholder, found %T", n))
+	}
+}
+
 // FormatNode recurses into a node for pretty-printing.
 // Flag-driven special cases can hook into this.
 func (ctx *FmtCtx) FormatNode(n NodeFormatter) {
@@ -441,7 +622,7 @@ func (ctx *FmtCtx) FormatNode(n NodeFormatter) {
 			if f.HasFlags(FmtMarkRedactionNode) {
 				ctx.formatNodeMaybeMarkRedaction(n)
 			} else {
-				ctx.formatNodeOrHideConstants(n)
+				ctx.formatNodeOrAdjustConstants(n)
 			}
 
 			ctx.WriteString(")[")
@@ -473,7 +654,7 @@ func (ctx *FmtCtx) FormatNode(n NodeFormatter) {
 	if f.HasFlags(FmtMarkRedactionNode) {
 		ctx.formatNodeMaybeMarkRedaction(n)
 	} else {
-		ctx.formatNodeOrHideConstants(n)
+		ctx.formatNodeOrAdjustConstants(n)
 	}
 
 	if f.HasFlags(FmtAlwaysGroupExprs) {
@@ -481,7 +662,7 @@ func (ctx *FmtCtx) FormatNode(n NodeFormatter) {
 			ctx.WriteByte(')')
 		}
 	}
-	if f.HasAnyFlags(fmtDisambiguateDatumTypes | FmtPGCatalog) {
+	if f.HasAnyFlags(fmtDisambiguateDatumTypes | fmtPGCatalogCasts) {
 		var typ *types.T
 		if d, isDatum := n.(Datum); isDatum {
 			if p, isPlaceholder := d.(*Placeholder); isPlaceholder {
@@ -489,7 +670,7 @@ func (ctx *FmtCtx) FormatNode(n NodeFormatter) {
 				typ = p.typ
 			} else if d.AmbiguousFormat() {
 				typ = d.ResolvedType()
-			} else if _, isArray := d.(*DArray); isArray && f.HasFlags(FmtPGCatalog) {
+			} else if _, isArray := d.(*DArray); isArray && f.HasFlags(fmtPGCatalogCasts) {
 				typ = d.ResolvedType()
 			}
 		}
@@ -497,7 +678,7 @@ func (ctx *FmtCtx) FormatNode(n NodeFormatter) {
 			if f.HasFlags(fmtDisambiguateDatumTypes) {
 				ctx.WriteString(":::")
 				ctx.FormatTypeReference(typ)
-			} else if f.HasFlags(FmtPGCatalog) && !typ.IsNumeric() {
+			} else if f.HasFlags(fmtPGCatalogCasts) && !typ.IsNumeric() {
 				ctx.WriteString("::")
 				ctx.FormatTypeReference(typ)
 			}
@@ -509,7 +690,7 @@ func (ctx *FmtCtx) FormatNode(n NodeFormatter) {
 // number of characters to be printed.
 func (ctx *FmtCtx) formatLimitLength(n NodeFormatter, maxLength int) {
 	temp := NewFmtCtx(ctx.flags)
-	temp.FormatNodeSummary(n)
+	temp.formatNodeSummary(n)
 	s := temp.CloseAndGetString()
 	if len(s) > maxLength {
 		truncated := s[:maxLength] + "..."
@@ -565,7 +746,7 @@ func (ctx *FmtCtx) formatSummaryInsert(node *Insert) {
 	expr := rows.Select
 	if _, ok := expr.(*SelectClause); ok {
 		ctx.WriteByte(' ')
-		ctx.FormatNodeSummary(rows)
+		ctx.formatNodeSummary(rows)
 	} else if node.Columns != nil {
 		ctx.WriteByte('(')
 		ctx.formatLimitLength(&node.Columns, ColumnLimit)
@@ -588,8 +769,8 @@ func (ctx *FmtCtx) formatSummaryUpdate(node *Update) {
 	}
 }
 
-// FormatNodeSummary recurses into a node for pretty-printing a summarized version.
-func (ctx *FmtCtx) FormatNodeSummary(n NodeFormatter) {
+// formatNodeSummary recurses into a node for pretty-printing a summarized version.
+func (ctx *FmtCtx) formatNodeSummary(n NodeFormatter) {
 	switch node := n.(type) {
 	case *Insert:
 		ctx.formatSummaryInsert(node)
@@ -609,7 +790,7 @@ func (ctx *FmtCtx) FormatNodeSummary(n NodeFormatter) {
 func AsStringWithFlags(n NodeFormatter, fl FmtFlags, opts ...FmtCtxOption) string {
 	ctx := NewFmtCtx(fl, opts...)
 	if fl.HasFlags(FmtSummary) {
-		ctx.FormatNodeSummary(n)
+		ctx.formatNodeSummary(n)
 	} else {
 		ctx.FormatNode(n)
 	}
@@ -619,7 +800,7 @@ func AsStringWithFlags(n NodeFormatter, fl FmtFlags, opts ...FmtCtxOption) strin
 // AsStringWithFQNames pretty prints a node to a string with the
 // FmtAlwaysQualifyTableNames flag (which requires annotations).
 func AsStringWithFQNames(n NodeFormatter, ann *Annotations) string {
-	ctx := NewFmtCtx(FmtAlwaysQualifyTableNames, FmtAnnotations(ann))
+	ctx := NewFmtCtx(FmtAlwaysQualifyNames, FmtAnnotations(ann))
 	ctx.FormatNode(n)
 	return ctx.CloseAndGetString()
 }
diff --git a/pkg/sql/sem/tree/format_fingerprint.go b/pkg/sql/sem/tree/format_fingerprint.go
new file mode 100644
index 0000000..ed5c3f7
--- /dev/null
+++ b/pkg/sql/sem/tree/format_fingerprint.go
@@ -0,0 +1,150 @@
+// Copyright 2024 The Cockroach Authors.
+//
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
+
+package tree
+
+// exprContainsOnlyConstantsAndPlaceholders checks if parts of an expression contains only
+// values that would be scrubbed for statement fingerprinting such as literals, placeholders
+// or datums. This can be used to determine if an expression can be shortened since it
+// does not contain any interesting information.
+type exprContainsOnlyConstantsAndPlaceholders struct {
+	containsNonConstExpr bool
+}
+
+var _ Visitor = &exprContainsOnlyConstantsAndPlaceholders{}
+
+func (v *exprContainsOnlyConstantsAndPlaceholders) VisitPre(
+	expr Expr,
+) (recurse bool, newExpr Expr) {
+	switch expr.(type) {
+	case Datum, Constant, *Placeholder:
+		return false, expr
+	case *Tuple, *Array, *CastExpr, *BinaryExpr, *UnaryExpr, *ParenExpr:
+		return !v.containsNonConstExpr, expr
+	default:
+		v.containsNonConstExpr = true
+		return false, expr
+	}
+}
+
+// onlyLiteralsAndPlaceholders is used to determine if the expression only contains
+// literals and/or placeholders. This includes subexpressions such as tuples, arrays
+// casts, binary expressions and unary expressions only containing literals
+// and/or placeholders.
+// See exprContainsOnlyConstantsAndPlaceholders for more details.
+// Examples:
+//
+//	(1+2, 3+4, 5+6)              -> true
+//	(1+2, b, c)                  -> false
+//	ARRAY[$1, 1, 3, 'ok']        -> true
+//	ARRAY[$1, 1, 3, 'ok', b]     -> false
+//	(-$1, 2, 'hello')            -> true
+//	(-$1, (2+$2)::INT, 'hello')  -> true
+func onlyLiteralsAndPlaceholders(exprs Exprs) bool {
+	v := exprContainsOnlyConstantsAndPlaceholders{}
+	for i := 0; i < len(exprs); i++ {
+		WalkExprConst(&v, exprs[i])
+		if v.containsNonConstExpr {
+			return false
+		}
+	}
+
+	return true
+}
+
+func (v *exprContainsOnlyConstantsAndPlaceholders) VisitPost(expr Expr) Expr { return expr }
+
+// Formatting VALUES for a fingerprint shortens multi-value VALUES clauses to a VALUES
+// clause with a single value.
+// Subexpressions containing only literals and/or placeholders in the first element
+// will also be collapsed.
+// Examples:
+// VALUES (a,b,c), (d,e,f) -> VALUES (a, b, c), (__more__)
+// VALUES ((a, b), (c, d)), ((e, f), (g, h)) -> VALUES ((a, b), (__more__)), (__more__)
+func (node *ValuesClause) formatForFingerprint(ctx *FmtCtx) {
+	ctx.WriteString("VALUES (")
+	ok := canCollapseExprs(node.Rows[0])
+	if ok {
+		exprs := Exprs{node.Rows[0][0], arityIndicatorNoBounds()}
+		exprs.Format(ctx)
+	} else {
+		node.Rows[0].Format(ctx)
+	}
+
+	ctx.WriteByte(')')
+	if len(node.Rows) > 1 {
+		ctx.Printf(", (%s)", genericArityIndicator)
+	}
+}
+
+// canCollapseExprs returns true if the list of expressions has more than 1 element and
+// each expression contains only literals, placeholders and/or simple subexpressions
+// containing only literals/placeholders. This is used to determine if the list can
+// be collapsed into a special shortened representation when generating a representative
+// query for statement fingerprints.
+func canCollapseExprs(exprs Exprs) bool {
+	if len(exprs) < 2 {
+		return false
+	}
+
+	return onlyLiteralsAndPlaceholders(exprs)
+}
+
+// formatForFingerprint shortens tuples containing only literals, placeholders
+// and/or simple expressions containing only literals and/or placeholders as a
+// tuple of its first element, and `__more__` indicating the rest of
+// the elements.
+// Examples:
+//
+//	  ()                -> ()
+//	  (1)               -> (1)
+//		(1, 2)            -> (1, __more__)
+//		(1, 2, 3)         -> (1, __more__)
+//		ROW()             -> ROW()
+//		ROW($1, $2, $3)   -> ROW($1, __more__)
+//		(1+2, 2+3, 3+4)   -> (1 + 2, __more__)
+//		(1+2, b, c)       -> (1 + 2, b, c)
+//		($1, 1, 3, 'ok')  -> ($1, __more__)
+func (node *Tuple) formatForFingerprint(ctx *FmtCtx) {
+	ok := canCollapseExprs(node.Exprs)
+	if !ok {
+		node.Format(ctx)
+		return
+	}
+
+	v2 := *node
+	exprs := Exprs{node.Exprs[0], arityIndicatorNoBounds()}
+	v2.Exprs = exprs
+	if len(node.Labels) > 1 {
+		if len(v2.Exprs) >= 2 {
+			v2.Labels = node.Labels
+		} else if len(node.Labels) > 0 {
+			v2.Labels = node.Labels[:1]
+		}
+	}
+	v2.Format(ctx)
+}
+
+// formatForFingerprint formats array expressions containing only
+// literals or placeholders that are longer than 1 element as an array
+// expression of its first element.
+// e.g.
+//
+//	  array[]              -> array[]
+//	  array[1]             -> array[1]
+//		array[1, 2]          -> array[1, __more__]
+//		array[1, 2, 3]       -> array[1, __more__]
+//		array[1+2, 2+3, 3+4] -> array[1 + 2, __more__]
+func (node *Array) formatForFingerprint(ctx *FmtCtx) {
+	ok := canCollapseExprs(node.Exprs)
+	if !ok {
+		node.Format(ctx)
+		return
+	}
+
+	v2 := *node
+	v2.Exprs = Exprs{node.Exprs[0], arityIndicatorNoBounds()}
+	v2.Format(ctx)
+}
diff --git a/pkg/sql/sem/tree/function_definition.go b/pkg/sql/sem/tree/function_definition.go
index 0d8035c..c96b447 100644
--- a/pkg/sql/sem/tree/function_definition.go
+++ b/pkg/sql/sem/tree/function_definition.go
@@ -1,16 +1,12 @@
 // Copyright 2016 The Cockroach Authors.
 //
-// Use of this software is governed by the Business Source License
-// included in the file licenses/BSL.txt.
-//
-// As of the Change Date specified in that file, in accordance with
-// the Business Source License, use of this software will be governed
-// by the Apache License, Version 2.0, included in the file
-// licenses/APL.txt.
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
 
 package tree
 
 import (
+	"context"
 	"strings"
 
 	"github.com/cockroachdb/cockroachdb-parser/pkg/sql/pgwire/pgcode"
@@ -18,6 +14,7 @@ import (
 	"github.com/cockroachdb/cockroachdb-parser/pkg/sql/sem/catconstants"
 	"github.com/cockroachdb/cockroachdb-parser/pkg/sql/sem/catid"
 	"github.com/cockroachdb/cockroachdb-parser/pkg/sql/types"
+	"github.com/cockroachdb/cockroachdb-parser/pkg/util/errorutil/unimplemented"
 	"github.com/cockroachdb/errors"
 	"github.com/lib/pq/oid"
 )
@@ -46,7 +43,26 @@ type ResolvedFunctionDefinition struct {
 	// not qualified.
 	Name string
 
+	// Overloads is the set of overloads for this resolved function. It can be
+	// empty in which case UnsupportedWithIssue is set.
 	Overloads []QualifiedOverload
+
+	// UnsupportedWithIssue, if non-zero, indicates the built-in is not really
+	// supported and provides the issue number to link.
+	UnsupportedWithIssue uint
+}
+
+// MakeUnsupportedError returns an implemented error if UnsupportedWithIssue is
+// non-zero.
+func (fd *ResolvedFunctionDefinition) MakeUnsupportedError() error {
+	if fd.UnsupportedWithIssue == 0 {
+		return nil
+	}
+	const msg = "this function is not yet supported"
+	return pgerror.Wrapf(
+		unimplemented.NewWithIssueDetail(int(fd.UnsupportedWithIssue), fd.Name, msg),
+		pgcode.InvalidParameterValue, "%s()", fd.Name,
+	)
 }
 
 type qualifiedOverloads []QualifiedOverload
@@ -74,11 +90,9 @@ func MakeQualifiedOverload(schema string, overload *Overload) QualifiedOverload
 // FunctionProperties defines the properties of the built-in
 // functions that are common across all overloads.
 type FunctionProperties struct {
-	// UnsupportedWithIssue, if non-zero indicates the built-in is not
-	// really supported; the name is a placeholder. Value -1 just says
-	// "not supported" without an issue to link; values > 0 provide an
-	// issue number to link.
-	UnsupportedWithIssue int
+	// UnsupportedWithIssue, if non-zero, indicates the built-in is not really
+	// supported and provides the issue number to link.
+	UnsupportedWithIssue uint
 
 	// Undocumented, when set to true, indicates that the built-in function is
 	// hidden from documentation. This is currently used to hide experimental
@@ -164,7 +178,7 @@ func NewFunctionDefinition(
 	overloads := make([]*Overload, len(def))
 
 	for i := range def {
-		if def[i].PreferredOverload {
+		if def[i].OverloadPreference == OverloadPreferencePreferred {
 			// Builtins with a preferred overload are always ambiguous.
 			props.AmbiguousReturnType = true
 			break
@@ -213,19 +227,22 @@ func (fd *FunctionDefinition) Format(ctx *FmtCtx) {
 func (fd *FunctionDefinition) String() string { return AsString(fd) }
 
 // Format implements the NodeFormatter interface.
-// ResolvedFunctionDefinitions should always be builtin functions, so we do not
-// need to anonymize them, even if the flag is set.
+//
+// ResolvedFunctionDefinitions can be builtin or user-defined, so we must
+// respect formatting flags.
 func (fd *ResolvedFunctionDefinition) Format(ctx *FmtCtx) {
 	// This is necessary when deserializing function expressions for SHOW CREATE
 	// statements. When deserializing a function expression with function OID
 	// references, it's guaranteed that there'll be always one overload resolved.
-	// There is no need to show prefix for builtin functions since we don't
-	// serialize them.
+	// There is no need to show prefix or use formatting flags for builtin
+	// functions since we don't serialize them.
 	if len(fd.Overloads) == 1 && catid.IsOIDUserDefined(fd.Overloads[0].Oid) {
-		ctx.WriteString(fd.Overloads[0].Schema)
+		ctx.FormatName(fd.Overloads[0].Schema)
 		ctx.WriteString(".")
+		ctx.FormatName(fd.Name)
+	} else {
+		ctx.WriteString(fd.Name)
 	}
-	ctx.WriteString(fd.Name)
 }
 
 // String implements the Stringer interface.
@@ -233,7 +250,7 @@ func (fd *ResolvedFunctionDefinition) String() string { return AsString(fd) }
 
 // MergeWith is used to merge two UDF definitions with same name.
 func (fd *ResolvedFunctionDefinition) MergeWith(
-	another *ResolvedFunctionDefinition,
+	another *ResolvedFunctionDefinition, path SearchPath,
 ) (*ResolvedFunctionDefinition, error) {
 	if fd == nil {
 		return another, nil
@@ -248,26 +265,121 @@ func (fd *ResolvedFunctionDefinition) MergeWith(
 
 	return &ResolvedFunctionDefinition{
 		Name:      fd.Name,
-		Overloads: combineOverloads(fd.Overloads, another.Overloads),
+		Overloads: combineOverloads(fd.Overloads, another.Overloads, path),
 	}, nil
 }
 
-// MatchOverload searches an overload which has exactly the same parameter
-// types. The overload from the most significant schema is returned. If
-// paramTypes==nil, an error is returned if the function name is not unique in
-// the most significant schema. If paramTypes is not nil, an error with
-// ErrRoutineUndefined cause is returned if not matched found. Overloads that
-// don't match the types in routineType are ignored.
+// MatchOverload searches an overload with the given signature. The overload
+// from the most significant schema is returned. If routineObj.Params==nil, an
+// error is returned if the function name is not unique in the most significant
+// schema. If routineObj.Params is not nil, an error with ErrRoutineUndefined
+// cause is returned if not matches found. Overloads that don't match the types
+// in routineType are ignored.
+//
+// If tryDefaultExprs is true, then routineObj.Params might specify the prefix
+// of the input types with remaining input types provided by the overload's
+// DEFAULT expressions.
 func (fd *ResolvedFunctionDefinition) MatchOverload(
-	paramTypes []*types.T, explicitSchema string, searchPath SearchPath, routineType RoutineType,
+	ctx context.Context,
+	typeRes TypeReferenceResolver,
+	routineObj *RoutineObj,
+	searchPath SearchPath,
+	routineType RoutineType,
+	inDropContext bool,
+	tryDefaultExprs bool,
 ) (QualifiedOverload, error) {
+	// includeAll indicates whether all parameters, regardless of the class,
+	// should be included into the signature.
+	getSignatureTypes := func(includeAll bool) (_ []*types.T, onlyDefaultParamClass bool, _ error) {
+		if routineObj.Params == nil {
+			return nil, false, nil
+		}
+		typs := make([]*types.T, 0, len(routineObj.Params))
+		onlyDefaultParamClass = true
+		for _, param := range routineObj.Params {
+			if IsInParamClass(param.Class) || includeAll {
+				typ, err := ResolveType(ctx, param.Type, typeRes)
+				if err != nil {
+					return nil, false, err
+				}
+				typs = append(typs, typ)
+			}
+			onlyDefaultParamClass = onlyDefaultParamClass && param.Class == RoutineParamDefault
+		}
+		return typs, onlyDefaultParamClass, nil
+	}
+	paramTypes, onlyDefaultParamClass, err := getSignatureTypes(false /* includeAll */)
+	if err != nil {
+		return QualifiedOverload{}, err
+	}
+	// allParamTypes, if set, contains types of all parameters (including OUT).
+	var allParamTypes []*types.T
+	if onlyDefaultParamClass && inDropContext {
+		allParamTypes, _, err = getSignatureTypes(true /* includeAll */)
+		if err != nil {
+			return QualifiedOverload{}, err
+		}
+	}
+	// firstMatchParamTypes, if set, contains the type schema of the very first
+	// match.
+	var firstMatchParamTypes []*types.T
 	matched := func(ol QualifiedOverload, schema string) bool {
-		if ol.Type == UDFRoutine || ol.Type == ProcedureRoutine {
-			return schema == ol.Schema && (paramTypes == nil || ol.params().MatchIdentical(paramTypes))
+		if schema != ol.Schema || paramTypes == nil {
+			// Fast-path for the simple case when we have a schema mismatch or
+			// all signatures are accepted.
+			return schema == ol.Schema && paramTypes == nil
 		}
-		return schema == ol.Schema && (paramTypes == nil || ol.params().Match(paramTypes))
+		if ol.Type != UDFRoutine && ol.Type != ProcedureRoutine {
+			return ol.params().Match(paramTypes)
+		}
+		// Special handling of routines.
+		//
+		// First, apply regular postgres resolution approach of using only
+		// the input types.
+		if ol.params().MatchOid(paramTypes) {
+			return true
+		}
+		if tryDefaultExprs && len(ol.defaultExprs()) > 0 {
+			// Check whether any of the input arguments might have been omitted.
+			// TODO(88947): this logic might need to change to support VARIADIC.
+			if inputTypes, ok := ol.Types.(ParamTypes); ok {
+				numOmittedExprs := len(inputTypes) - len(paramTypes)
+				if numOmittedExprs > 0 && numOmittedExprs <= len(inputTypes) {
+					inputTypes = inputTypes[:len(inputTypes)-numOmittedExprs]
+					if inputTypes.MatchOid(paramTypes) {
+						return true
+					}
+				}
+			}
+		}
+		// If we're not in a special code path for DROP PROCEDURE, it's not a
+		// match.
+		if ol.Type == UDFRoutine || !inDropContext || !onlyDefaultParamClass {
+			return false
+		}
+		// Special handling of SQL-compliant resolution logic for DROP
+		// PROCEDURE.
+		_, outParamOrdinals, outParamTypes := ol.outParamInfo()
+		if ol.Types.Length()+len(outParamOrdinals) != len(allParamTypes) {
+			return false
+		}
+		allParams := make(ParamTypes, len(allParamTypes))
+		var outParamsSeen int
+		for i := 0; i < len(allParams); i++ {
+			if outParamsSeen < len(outParamOrdinals) && outParamOrdinals[outParamsSeen] == int32(i) {
+				allParams[i] = ParamType{Typ: outParamTypes.GetAt(outParamsSeen)}
+				outParamsSeen++
+			} else {
+				allParams[i] = ParamType{Typ: ol.Types.GetAt(i - outParamsSeen)}
+			}
+		}
+		match := allParams.MatchOid(allParamTypes)
+		if firstMatchParamTypes == nil && match {
+			firstMatchParamTypes = allParamTypes
+		}
+		return match
 	}
-	typeNames := func() string {
+	typeNames := func(paramTypes []*types.T) string {
 		ns := make([]string, len(paramTypes))
 		for i, t := range paramTypes {
 			ns[i] = t.Name()
@@ -283,12 +395,15 @@ func (fd *ResolvedFunctionDefinition) MatchOverload(
 			if matched(fd.Overloads[i], schema) {
 				found = true
 				ret = append(ret, fd.Overloads[i])
+				if firstMatchParamTypes == nil {
+					firstMatchParamTypes = paramTypes
+				}
 			}
 		}
 	}
 
-	if explicitSchema != "" {
-		findMatches(explicitSchema)
+	if routineObj.FuncName.Schema() != "" {
+		findMatches(routineObj.FuncName.Schema())
 	} else {
 		for i, n := 0, searchPath.NumElements(); i < n; i++ {
 			if findMatches(searchPath.GetSchema(i)); found {
@@ -300,10 +415,10 @@ func (fd *ResolvedFunctionDefinition) MatchOverload(
 	if len(ret) == 1 && ret[0].Type&routineType == 0 {
 		if routineType == ProcedureRoutine {
 			return QualifiedOverload{}, pgerror.Newf(
-				pgcode.WrongObjectType, "%s(%s) is not a procedure", fd.Name, typeNames())
+				pgcode.WrongObjectType, "%s(%s) is not a procedure", fd.Name, typeNames(firstMatchParamTypes))
 		} else {
 			return QualifiedOverload{}, pgerror.Newf(
-				pgcode.WrongObjectType, "%s(%s) is not a function", fd.Name, typeNames())
+				pgcode.WrongObjectType, "%s(%s) is not a function", fd.Name, typeNames(firstMatchParamTypes))
 		}
 	}
 
@@ -322,32 +437,82 @@ func (fd *ResolvedFunctionDefinition) MatchOverload(
 	// Truncate the slice.
 	ret = ret[:i]
 
+	kind := "function"
+	if routineType == ProcedureRoutine {
+		kind = "procedure"
+	}
 	if len(ret) == 0 {
-		if routineType == ProcedureRoutine {
-			return QualifiedOverload{}, errors.Mark(
-				pgerror.Newf(pgcode.UndefinedFunction, "procedure %s(%s) does not exist", fd.Name, typeNames()),
-				ErrRoutineUndefined,
-			)
-		} else {
-			return QualifiedOverload{}, errors.Mark(
-				pgerror.Newf(pgcode.UndefinedFunction, "function %s(%s) does not exist", fd.Name, typeNames()),
-				ErrRoutineUndefined,
-			)
-		}
+		return QualifiedOverload{}, errors.Mark(
+			pgerror.Newf(pgcode.UndefinedFunction, "%s %s(%s) does not exist", kind, fd.Name, typeNames(paramTypes)),
+			ErrRoutineUndefined,
+		)
 	}
-
 	if len(ret) > 1 {
-		if routineType == ProcedureRoutine {
-			return QualifiedOverload{}, pgerror.Newf(pgcode.AmbiguousFunction, "procedure name %q is not unique", fd.Name)
-		} else {
-			return QualifiedOverload{}, pgerror.Newf(pgcode.AmbiguousFunction, "function name %q is not unique", fd.Name)
-		}
+		return QualifiedOverload{}, pgerror.Newf(pgcode.AmbiguousFunction, "%s name %q is not unique", kind, fd.Name)
 	}
 	return ret[0], nil
 }
 
-func combineOverloads(a, b []QualifiedOverload) []QualifiedOverload {
-	return append(append(make([]QualifiedOverload, 0, len(a)+len(b)), a...), b...)
+func combineOverloads(a, b []QualifiedOverload, path SearchPath) []QualifiedOverload {
+	// Corner case: if the path is empty, we can just append a and b.
+	if path == nil || path.NumElements() == 0 {
+		return append(append(make([]QualifiedOverload, 0, len(a)+len(b)), a...), b...)
+	}
+
+	result := make([]QualifiedOverload, 0, len(a)+len(b))
+
+	// Append overloads to the result according to the schema order in the path.
+	isSchemaInSearchPath := make(map[string]bool, path.NumElements())
+	for i := range path.NumElements() {
+		schema := path.GetSchema(i)
+		isSchemaInSearchPath[schema] = true
+
+		for _, overload := range a {
+			if overload.Schema == schema {
+				result = append(result, overload)
+			}
+		}
+
+		for _, overload := range b {
+			if overload.Schema == schema {
+				result = append(result, overload)
+			}
+		}
+	}
+
+	// Append any remaining overloads that are not in the path.
+	for _, overload := range a {
+		if _, ok := isSchemaInSearchPath[overload.Schema]; !ok {
+			result = append(result, overload)
+		}
+	}
+
+	for _, overload := range b {
+		if _, ok := isSchemaInSearchPath[overload.Schema]; !ok {
+			result = append(result, overload)
+		}
+	}
+
+	foundUDFOverload := false
+	for _, overload := range result {
+		if overload.Type == UDFRoutine {
+			foundUDFOverload = true
+		}
+	}
+	// When a UDF overload is found, reset the "preferred" attribute. We need to
+	// copy the overload to avoid modifying the hardcoded definition.
+	if foundUDFOverload {
+		for i, overload := range result {
+			copiedOverload := *overload.Overload
+			copiedOverload.OverloadPreference = OverloadPreferenceNone
+			result[i] = QualifiedOverload{
+				Schema:   overload.Schema,
+				Overload: &copiedOverload,
+			}
+		}
+	}
+
+	return result
 }
 
 // GetClass returns function class by checking each overload's Class and returns
@@ -358,8 +523,8 @@ func combineOverloads(a, b []QualifiedOverload) []QualifiedOverload {
 // method, function is resolved to one overload, so that we can get rid of this
 // function and similar methods below.
 func (fd *ResolvedFunctionDefinition) GetClass() (FunctionClass, error) {
-	if len(fd.Overloads) < 1 {
-		return 0, errors.AssertionFailedf("no overloads found for function %s", fd.Name)
+	if fd.UnsupportedWithIssue != 0 {
+		return 0, fd.MakeUnsupportedError()
 	}
 	ret := fd.Overloads[0].Class
 	for i := range fd.Overloads {
@@ -376,8 +541,8 @@ func (fd *ResolvedFunctionDefinition) GetClass() (FunctionClass, error) {
 // different length. This is good enough since we don't create UDF with
 // ReturnLabel.
 func (fd *ResolvedFunctionDefinition) GetReturnLabel() ([]string, error) {
-	if len(fd.Overloads) < 1 {
-		return nil, errors.AssertionFailedf("no overloads found for function %s", fd.Name)
+	if fd.UnsupportedWithIssue != 0 {
+		return nil, fd.MakeUnsupportedError()
 	}
 	ret := fd.Overloads[0].ReturnLabels
 	for i := range fd.Overloads {
@@ -392,8 +557,8 @@ func (fd *ResolvedFunctionDefinition) GetReturnLabel() ([]string, error) {
 // checking each overload's HasSequenceArguments flag. Ambiguous error is
 // returned if there is any overload has a different flag.
 func (fd *ResolvedFunctionDefinition) GetHasSequenceArguments() (bool, error) {
-	if len(fd.Overloads) < 1 {
-		return false, errors.AssertionFailedf("no overloads found for function %s", fd.Name)
+	if fd.UnsupportedWithIssue != 0 {
+		return false, fd.MakeUnsupportedError()
 	}
 	ret := fd.Overloads[0].HasSequenceArguments
 	for i := range fd.Overloads {
@@ -407,12 +572,21 @@ func (fd *ResolvedFunctionDefinition) GetHasSequenceArguments() (bool, error) {
 // QualifyBuiltinFunctionDefinition qualified all overloads in a function
 // definition with a schema name. Note that this function can only be used for
 // builtin function.
+//
+// It must be called during the initialization of the process.
 func QualifyBuiltinFunctionDefinition(
 	def *FunctionDefinition, schema string,
 ) *ResolvedFunctionDefinition {
+	if len(def.Definition) == 0 && def.UnsupportedWithIssue == 0 {
+		panic(errors.AssertionFailedf("function %s has no overloads yet UnsupportedWithIssue is not set", def.Name))
+	}
+	if len(def.Definition) > 0 && def.UnsupportedWithIssue != 0 {
+		panic(errors.AssertionFailedf("function %s has %d overloads yet UnsupportedWithIssue is set to %d", def.Name, len(def.Definition), def.UnsupportedWithIssue))
+	}
 	ret := &ResolvedFunctionDefinition{
-		Name:      def.Name,
-		Overloads: make([]QualifiedOverload, 0, len(def.Definition)),
+		Name:                 def.Name,
+		Overloads:            make([]QualifiedOverload, 0, len(def.Definition)),
+		UnsupportedWithIssue: def.UnsupportedWithIssue,
 	}
 	for _, o := range def.Definition {
 		ret.Overloads = append(
diff --git a/pkg/sql/sem/tree/function_name.go b/pkg/sql/sem/tree/function_name.go
index c6d48d4..4e74705 100644
--- a/pkg/sql/sem/tree/function_name.go
+++ b/pkg/sql/sem/tree/function_name.go
@@ -1,12 +1,7 @@
 // Copyright 2016 The Cockroach Authors.
 //
-// Use of this software is governed by the Business Source License
-// included in the file licenses/BSL.txt.
-//
-// As of the Change Date specified in that file, in accordance with
-// the Business Source License, use of this software will be governed
-// by the Apache License, Version 2.0, included in the file
-// licenses/APL.txt.
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
 
 package tree
 
@@ -164,6 +159,7 @@ type FunctionReference interface {
 var _ FunctionReference = &UnresolvedName{}
 var _ FunctionReference = &FunctionDefinition{}
 var _ FunctionReference = &ResolvedFunctionDefinition{}
+var _ FunctionReference = &FunctionOID{}
 
 func (*UnresolvedName) functionReference()             {}
 func (*FunctionDefinition) functionReference()         {}
diff --git a/pkg/sql/sem/tree/fuzz.go b/pkg/sql/sem/tree/fuzz.go
index a6fdc80..c771795 100644
--- a/pkg/sql/sem/tree/fuzz.go
+++ b/pkg/sql/sem/tree/fuzz.go
@@ -1,15 +1,9 @@
 // Copyright 2019 The Cockroach Authors.
 //
-// Use of this software is governed by the Business Source License
-// included in the file licenses/BSL.txt.
-//
-// As of the Change Date specified in that file, in accordance with
-// the Business Source License, use of this software will be governed
-// by the Apache License, Version 2.0, included in the file
-// licenses/APL.txt.
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
 
 //go:build gofuzz
-// +build gofuzz
 
 package tree
 
diff --git a/pkg/sql/sem/tree/grant.go b/pkg/sql/sem/tree/grant.go
index 12f0e3e..4d70529 100644
--- a/pkg/sql/sem/tree/grant.go
+++ b/pkg/sql/sem/tree/grant.go
@@ -7,13 +7,8 @@
 //
 // Copyright 2015 The Cockroach Authors.
 //
-// Use of this software is governed by the Business Source License
-// included in the file licenses/BSL.txt.
-//
-// As of the Change Date specified in that file, in accordance with
-// the Business Source License, use of this software will be governed
-// by the Apache License, Version 2.0, included in the file
-// licenses/APL.txt.
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
 
 // This code was derived from https://github.com/youtube/vitess.
 
diff --git a/pkg/sql/sem/tree/hide_constants.go b/pkg/sql/sem/tree/hide_constants.go
deleted file mode 100644
index fedf168..0000000
--- a/pkg/sql/sem/tree/hide_constants.go
+++ /dev/null
@@ -1,199 +0,0 @@
-// Copyright 2017 The Cockroach Authors.
-//
-// Use of this software is governed by the Business Source License
-// included in the file licenses/BSL.txt.
-//
-// As of the Change Date specified in that file, in accordance with
-// the Business Source License, use of this software will be governed
-// by the Apache License, Version 2.0, included in the file
-// licenses/APL.txt.
-//
-//
-
-package tree
-
-import (
-	"fmt"
-	"strings"
-)
-
-// formatNodeOrHideConstants recurses into a node for pretty-printing,
-// unless hideConstants is set in the flags and the node is a datum or
-// a literal.
-func (ctx *FmtCtx) formatNodeOrHideConstants(n NodeFormatter) {
-	if ctx.flags.HasFlags(FmtHideConstants) {
-		switch v := n.(type) {
-		case *ValuesClause:
-			v.formatHideConstants(ctx)
-			return
-		case *Tuple:
-			v.formatHideConstants(ctx)
-			return
-		case *Array:
-			v.formatHideConstants(ctx)
-			return
-		case *Placeholder:
-			// Placeholders should be printed as placeholder markers.
-			// Using always '$1' so we limit the amount of different
-			// fingerprints created.
-			ctx.WriteString("$1")
-			return
-		case *StrVal:
-			ctx.WriteString("'_'")
-			return
-		case Datum, Constant:
-			ctx.WriteByte('_')
-			return
-		}
-	}
-	n.Format(ctx)
-}
-
-// formatHideConstants shortens multi-valued VALUES clauses to a
-// VALUES clause with a single value.
-// e.g. VALUES (a,b,c), (d,e,f) -> VALUES (_, _, _), (__more__)
-func (node *ValuesClause) formatHideConstants(ctx *FmtCtx) {
-	ctx.WriteString("VALUES (")
-	node.Rows[0].formatHideConstants(ctx)
-	ctx.WriteByte(')')
-	if len(node.Rows) > 1 {
-		ctx.Printf(", (%s)", arityString(len(node.Rows)-1))
-	}
-}
-
-// formatHideConstants is used exclusively by ValuesClause above.
-// Other AST that contain Exprs do not use this.
-func (node *Exprs) formatHideConstants(ctx *FmtCtx) {
-	exprs := *node
-	if len(exprs) < 2 {
-		node.Format(ctx)
-		return
-	}
-
-	// First, determine if there are only literals/placeholders.
-	var i int
-	for i = 0; i < len(exprs); i++ {
-		switch exprs[i].(type) {
-		case Datum, Constant, *Placeholder:
-			continue
-		}
-		break
-	}
-	// If so, then use the special representation.
-	if i == len(exprs) {
-		// We copy the node to preserve the "row" boolean flag.
-		v2 := append(make(Exprs, 0, 3), exprs[:2]...)
-		if len(exprs) > 2 {
-			v2 = append(v2, arityIndicator(len(exprs)-2))
-		}
-		v2.Format(ctx)
-		return
-	}
-	node.Format(ctx)
-}
-
-// formatHideConstants formats tuples containing only literals or
-// placeholders and longer than 1 element as a tuple of its first
-// two elements, scrubbed.
-// e.g. (1)               -> (_)
-//
-//	(1, 2)            -> (_, _)
-//	(1, 2, 3)         -> (_, _, __more1_10__)
-//	ROW()             -> ROW()
-//	ROW($1, $2, $3)   -> ROW($1, $2, __more1_10__)
-//	(1+2, 2+3, 3+4)   -> (_ + _, _ + _, _ + _)
-//	(1+2, b, c)       -> (_ + _, b, c)
-func (node *Tuple) formatHideConstants(ctx *FmtCtx) {
-	if len(node.Exprs) < 2 {
-		node.Format(ctx)
-		return
-	}
-
-	// First, determine if there are only literals/placeholders.
-	var i int
-	for i = 0; i < len(node.Exprs); i++ {
-		switch node.Exprs[i].(type) {
-		case Datum, Constant, *Placeholder:
-			continue
-		}
-		break
-	}
-	// If so, then use the special representation.
-	if i == len(node.Exprs) {
-		// We copy the node to preserve the "row" boolean flag.
-		v2 := *node
-		v2.Exprs = append(make(Exprs, 0, 3), v2.Exprs[:2]...)
-		if len(node.Exprs) > 2 {
-			v2.Exprs = append(v2.Exprs, arityIndicator(len(node.Exprs)-2))
-			if len(node.Labels) > 2 {
-				v2.Labels = node.Labels[:2]
-			}
-		}
-		v2.Format(ctx)
-		return
-	}
-	node.Format(ctx)
-}
-
-// formatHideConstants formats array expressions containing only
-// literals or placeholders and longer than 1 element as an array
-// expression of its first two elements, scrubbed.
-// e.g. array[1]             -> array[_]
-//
-//	array[1, 2]          -> array[_, _]
-//	array[1, 2, 3]       -> array[_, _, __more1_10__]
-//	array[1+2, 2+3, 3+4] -> array[_ + _, _ + _, _ + _]
-func (node *Array) formatHideConstants(ctx *FmtCtx) {
-	if len(node.Exprs) < 2 {
-		node.Format(ctx)
-		return
-	}
-
-	// First, determine if there are only literals/placeholders.
-	var i int
-	for i = 0; i < len(node.Exprs); i++ {
-		switch node.Exprs[i].(type) {
-		case Datum, Constant, *Placeholder:
-			continue
-		}
-		break
-	}
-	// If so, then use the special representation.
-	if i == len(node.Exprs) {
-		// We copy the node to preserve the "row" boolean flag.
-		v2 := *node
-		v2.Exprs = append(make(Exprs, 0, 3), v2.Exprs[:2]...)
-		if len(node.Exprs) > 2 {
-			v2.Exprs = append(v2.Exprs, arityIndicator(len(node.Exprs)-2))
-		}
-		v2.Format(ctx)
-		return
-	}
-	node.Format(ctx)
-}
-
-func arityIndicator(n int) Expr {
-	return NewUnresolvedName(arityString(n))
-}
-
-func arityString(n int) string {
-	var v int
-	if n <= 10 {
-		return "__more1_10__"
-	}
-	if n <= 100 {
-		return "__more10_100__"
-	}
-	if n <= 1000 {
-		for v = 1; n >= 10; n /= 10 {
-			v = v * 10
-		}
-		v = v * n
-		return fmt.Sprintf("__more%d__", v)
-	}
-	return "__more1000_plus__"
-}
-
-func isArityIndicatorString(s string) bool {
-	return strings.HasPrefix(s, "__more")
-}
diff --git a/pkg/sql/sem/tree/import.go b/pkg/sql/sem/tree/import.go
index a1510c9..61750da 100644
--- a/pkg/sql/sem/tree/import.go
+++ b/pkg/sql/sem/tree/import.go
@@ -1,12 +1,7 @@
 // Copyright 2017 The Cockroach Authors.
 //
-// Use of this software is governed by the Business Source License
-// included in the file licenses/BSL.txt.
-//
-// As of the Change Date specified in that file, in accordance with
-// the Business Source License, use of this software will be governed
-// by the Apache License, Version 2.0, included in the file
-// licenses/APL.txt.
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
 
 package tree
 
@@ -35,7 +30,7 @@ func (node *Import) Format(ctx *FmtCtx) {
 		}
 		ctx.WriteString(node.FileFormat)
 		ctx.WriteByte(' ')
-		ctx.FormatNode(&node.Files)
+		ctx.FormatURIs(node.Files)
 	} else {
 		if node.Into {
 			ctx.WriteString("INTO ")
@@ -52,9 +47,14 @@ func (node *Import) Format(ctx *FmtCtx) {
 			ctx.FormatNode(node.Table)
 		}
 		ctx.WriteString(node.FileFormat)
-		ctx.WriteString(" DATA (")
-		ctx.FormatNode(&node.Files)
-		ctx.WriteString(")")
+		ctx.WriteString(" DATA ")
+		if len(node.Files) == 1 {
+			ctx.WriteString("(")
+		}
+		ctx.FormatURIs(node.Files)
+		if len(node.Files) == 1 {
+			ctx.WriteString(")")
+		}
 	}
 
 	if node.Options != nil {
diff --git a/pkg/sql/sem/tree/indexed_vars.go b/pkg/sql/sem/tree/indexed_vars.go
index 06ae04f..b7b79d4 100644
--- a/pkg/sql/sem/tree/indexed_vars.go
+++ b/pkg/sql/sem/tree/indexed_vars.go
@@ -1,12 +1,7 @@
 // Copyright 2016 The Cockroach Authors.
 //
-// Use of this software is governed by the Business Source License
-// included in the file licenses/BSL.txt.
-//
-// As of the Change Date specified in that file, in accordance with
-// the Business Source License, use of this software will be governed
-// by the Apache License, Version 2.0, included in the file
-// licenses/APL.txt.
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
 
 package tree
 
@@ -20,26 +15,16 @@ import (
 	"github.com/cockroachdb/redact"
 )
 
-// IndexedVarContainer provides the implementation of TypeCheck, Eval, and
-// String for IndexedVars.
+// IndexedVarContainer provides type-checking for an IndexedVar.
 type IndexedVarContainer interface {
 	IndexedVarResolvedType(idx int) *types.T
-	// IndexedVarNodeFormatter returns a NodeFormatter; if an object that
-	// wishes to implement this interface has lost the textual name that an
-	// IndexedVar originates from, this function can return nil (and the
-	// ordinal syntax "@1, @2, .." will be used).
-	IndexedVarNodeFormatter(idx int) NodeFormatter
 }
 
 // IndexedVar is a VariableExpr that can be used as a leaf in expressions; it
-// represents a dynamic value. It defers calls to TypeCheck, Eval, String to an
+// represents a dynamic value. It defers calls to TypeCheck and Format to an
 // IndexedVarContainer.
 type IndexedVar struct {
-	Idx  int
-	Used bool
-
-	col NodeFormatter
-
+	Idx int
 	typeAnnotation
 }
 
@@ -81,13 +66,10 @@ func (v *IndexedVar) ResolvedType() *types.T {
 
 // Format implements the NodeFormatter interface.
 func (v *IndexedVar) Format(ctx *FmtCtx) {
-	f := ctx.flags
 	if ctx.indexedVarFormat != nil {
 		ctx.indexedVarFormat(ctx, v.Idx)
-	} else if f.HasFlags(fmtSymbolicVars) || v.col == nil {
-		ctx.Printf("@%d", v.Idx+1)
 	} else {
-		ctx.FormatNode(v.col)
+		ctx.Printf("@%d", v.Idx+1)
 	}
 }
 
@@ -119,26 +101,6 @@ func (h *IndexedVarHelper) Container() IndexedVarContainer {
 	return h.container
 }
 
-// BindIfUnbound ensures the IndexedVar is attached to this helper's container.
-// - for freshly created IndexedVars (with a nil container) this will bind in-place.
-// - for already bound IndexedVar, bound to this container, this will return the same ivar unchanged.
-// - for ordinal references (with an explicit unboundContainer) this will return a new var.
-// - for already bound IndexedVars, bound to another container, this will error out.
-func (h *IndexedVarHelper) BindIfUnbound(ivar *IndexedVar) (*IndexedVar, error) {
-	// We perform the range check always, even if the ivar is already
-	// bound, as a form of safety assertion against misreuse of ivars
-	// across containers.
-	if ivar.Idx < 0 || ivar.Idx >= len(h.vars) {
-		return ivar, pgerror.Newf(
-			pgcode.UndefinedColumn, "invalid column ordinal: @%d", ivar.Idx+1)
-	}
-
-	if !ivar.Used {
-		return h.IndexedVar(ivar.Idx), nil
-	}
-	return ivar, nil
-}
-
 // MakeIndexedVarHelper initializes an IndexedVarHelper structure.
 func MakeIndexedVarHelper(container IndexedVarContainer, numVars int) IndexedVarHelper {
 	return IndexedVarHelper{
@@ -167,9 +129,7 @@ func (h *IndexedVarHelper) IndexedVar(idx int) *IndexedVar {
 	h.checkIndex(idx)
 	v := &h.vars[idx]
 	v.Idx = idx
-	v.Used = true
 	v.typ = h.container.IndexedVarResolvedType(idx)
-	v.col = h.container.IndexedVarNodeFormatter(idx)
 	return v
 }
 
@@ -181,48 +141,10 @@ func (h *IndexedVarHelper) IndexedVarWithType(idx int, typ *types.T) *IndexedVar
 	h.checkIndex(idx)
 	v := &h.vars[idx]
 	v.Idx = idx
-	v.Used = true
 	v.typ = typ
 	return v
 }
 
-// IndexedVarUsed returns true if IndexedVar() was called for the given index.
-// The index must be valid.
-func (h *IndexedVarHelper) IndexedVarUsed(idx int) bool {
-	h.checkIndex(idx)
-	return h.vars[idx].Used
-}
-
-// GetIndexedVars returns the indexed var array of this helper.
-// IndexedVars to the caller; unused vars are guaranteed to have
-// a false Used field.
-func (h *IndexedVarHelper) GetIndexedVars() []IndexedVar {
-	return h.vars
-}
-
-// Rebind collects all the IndexedVars in the given expression and re-binds them
-// to this helper.
-func (h *IndexedVarHelper) Rebind(expr TypedExpr) TypedExpr {
-	if expr == nil {
-		return nil
-	}
-	ret, _ := WalkExpr(h, expr)
-	return ret.(TypedExpr)
-}
-
-var _ Visitor = &IndexedVarHelper{}
-
-// VisitPre implements the Visitor interface.
-func (h *IndexedVarHelper) VisitPre(expr Expr) (recurse bool, newExpr Expr) {
-	if iv, ok := expr.(*IndexedVar); ok {
-		return false, h.IndexedVar(iv.Idx)
-	}
-	return true, expr
-}
-
-// VisitPost implements the Visitor interface.
-func (*IndexedVarHelper) VisitPost(expr Expr) Expr { return expr }
-
 type typeContainer struct {
 	types []*types.T
 }
@@ -234,15 +156,9 @@ func (tc *typeContainer) IndexedVarResolvedType(idx int) *types.T {
 	return tc.types[idx]
 }
 
-// IndexedVarNodeFormatter is part of the IndexedVarContainer interface.
-func (tc *typeContainer) IndexedVarNodeFormatter(idx int) NodeFormatter {
-	return nil
-}
-
-// MakeTypesOnlyIndexedVarHelper creates an IndexedVarHelper which provides
-// the given types for indexed vars. It does not support evaluation, unless
-// Rebind is used with another container which supports evaluation.
-func MakeTypesOnlyIndexedVarHelper(types []*types.T) IndexedVarHelper {
+// MakeIndexedVarHelperWithTypes creates an IndexedVarHelper which provides
+// the given types for indexed vars.
+func MakeIndexedVarHelperWithTypes(types []*types.T) IndexedVarHelper {
 	c := &typeContainer{types: types}
 	return MakeIndexedVarHelper(c, len(types))
 }
diff --git a/pkg/sql/sem/tree/insert.go b/pkg/sql/sem/tree/insert.go
index 65dda3e..ce8373e 100644
--- a/pkg/sql/sem/tree/insert.go
+++ b/pkg/sql/sem/tree/insert.go
@@ -7,13 +7,8 @@
 //
 // Copyright 2015 The Cockroach Authors.
 //
-// Use of this software is governed by the Business Source License
-// included in the file licenses/BSL.txt.
-//
-// As of the Change Date specified in that file, in accordance with
-// the Business Source License, use of this software will be governed
-// by the Apache License, Version 2.0, included in the file
-// licenses/APL.txt.
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
 
 // This code was derived from https://github.com/youtube/vitess.
 
@@ -87,6 +82,18 @@ func (node *Insert) DefaultValues() bool {
 	return node.Rows.Select == nil
 }
 
+// VectorInsert returns true iff the input for the insert operation is a
+// materialized columnar batch, in which case the Insert operator will use a
+// vectorized implementation. This should only be true for the Copy fast path.
+func (node *Insert) VectorInsert() bool {
+	literalValues, ok := node.Rows.Select.(*LiteralValuesClause)
+	if !ok {
+		return false
+	}
+	_, vectorRows := literalValues.Rows.(*VectorRows)
+	return vectorRows
+}
+
 // OnConflict represents an `ON CONFLICT (columns) WHERE arbiter DO UPDATE SET
 // exprs WHERE where` clause.
 //
diff --git a/pkg/sql/sem/tree/name_part.go b/pkg/sql/sem/tree/name_part.go
index 0db9991..f4d7651 100644
--- a/pkg/sql/sem/tree/name_part.go
+++ b/pkg/sql/sem/tree/name_part.go
@@ -1,12 +1,7 @@
 // Copyright 2016 The Cockroach Authors.
 //
-// Use of this software is governed by the Business Source License
-// included in the file licenses/BSL.txt.
-//
-// As of the Change Date specified in that file, in accordance with
-// the Business Source License, use of this software will be governed
-// by the Apache License, Version 2.0, included in the file
-// licenses/APL.txt.
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
 
 package tree
 
diff --git a/pkg/sql/sem/tree/name_resolution.go b/pkg/sql/sem/tree/name_resolution.go
index 81a88ac..9bbaca7 100644
--- a/pkg/sql/sem/tree/name_resolution.go
+++ b/pkg/sql/sem/tree/name_resolution.go
@@ -1,12 +1,7 @@
 // Copyright 2018 The Cockroach Authors.
 //
-// Use of this software is governed by the Business Source License
-// included in the file licenses/BSL.txt.
-//
-// As of the Change Date specified in that file, in accordance with
-// the Business Source License, use of this software will be governed
-// by the Apache License, Version 2.0, included in the file
-// licenses/APL.txt.
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
 
 package tree
 
diff --git a/pkg/sql/sem/tree/object_name.go b/pkg/sql/sem/tree/object_name.go
index e3f3639..a05eebb 100644
--- a/pkg/sql/sem/tree/object_name.go
+++ b/pkg/sql/sem/tree/object_name.go
@@ -1,12 +1,7 @@
 // Copyright 2020 The Cockroach Authors.
 //
-// Use of this software is governed by the Business Source License
-// included in the file licenses/BSL.txt.
-//
-// As of the Change Date specified in that file, in accordance with
-// the Business Source License, use of this software will be governed
-// by the Apache License, Version 2.0, included in the file
-// licenses/APL.txt.
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
 
 package tree
 
@@ -294,6 +289,11 @@ func (u *UnresolvedObjectName) ToTableName() TableName {
 	return TableName{u.toObjName()}
 }
 
+// ToTypeName converts the unresolved name to a table name.
+func (u *UnresolvedObjectName) ToTypeName() TypeName {
+	return TypeName{u.toObjName()}
+}
+
 // ToRoutineName converts the unresolved name to a function name.
 func (u *UnresolvedObjectName) ToRoutineName() RoutineName {
 	return RoutineName{u.toObjName()}
diff --git a/pkg/sql/sem/tree/overload.go b/pkg/sql/sem/tree/overload.go
index a86c28e..6c3d4ab 100644
--- a/pkg/sql/sem/tree/overload.go
+++ b/pkg/sql/sem/tree/overload.go
@@ -1,12 +1,7 @@
 // Copyright 2016 The Cockroach Authors.
 //
-// Use of this software is governed by the Business Source License
-// included in the file licenses/BSL.txt.
-//
-// As of the Change Date specified in that file, in accordance with
-// the Business Source License, use of this software will be governed
-// by the Apache License, Version 2.0, included in the file
-// licenses/APL.txt.
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
 
 package tree
 
@@ -43,6 +38,7 @@ const (
 	_ SpecializedVectorizedBuiltin = iota
 	SubstringStringIntInt
 	CrdbInternalRangeStats
+	CrdbInternalRangeStatsWithErrors
 )
 
 // AggregateOverload is an opaque type which is used to box an eval.AggregateOverload.
@@ -156,22 +152,30 @@ func (t RoutineType) String() string {
 	}
 }
 
+// OverloadPreference is used to disambiguate between eligible overload
+// candidates during type-checking. When multiple overloads are eligible based
+// on types even after applying all the other disambiguation heuristics, the
+// overload with the highest preference will be chosen, if no other overloads
+// have the same preference.
+//
+// NOTE: This is a hack that is necessary because we do not follow all of
+// Postgres's type conversion rules. It should be used sparingly.
+// See #75101.
+type OverloadPreference int
+
+const (
+	OverloadPreferenceUnpreferred = OverloadPreference(-1)
+	OverloadPreferenceNone        = OverloadPreference(0)
+	OverloadPreferencePreferred   = OverloadPreference(1)
+)
+
 // Overload is one of the overloads of a built-in function.
 // Each FunctionDefinition may contain one or more overloads.
 type Overload struct {
 	Types      TypeList
 	ReturnType ReturnTyper
 	Volatility volatility.V
-
-	// PreferredOverload determines overload resolution as follows.
-	// When multiple overloads are eligible based on types even after all of of
-	// the heuristics to pick one have been used, if one of the overloads is a
-	// Overload with the `PreferredOverload` flag set to true it can be selected
-	// rather than returning a no-such-method error.
-	// This should generally be avoided -- avoiding introducing ambiguous
-	// overloads in the first place is a much better solution -- and only done
-	// after consultation with @knz @nvanbenschoten.
-	PreferredOverload bool
+	OverloadPreference
 
 	// Info is a description of the function, which is surfaced on the CockroachDB
 	// docs site on the "Functions and Operators" page. Descriptions typically use
@@ -210,10 +214,8 @@ type Overload struct {
 	// statement which will be executed as a common table expression in the query.
 	SQLFn SQLFnOverload
 
-	// OnTypeCheck is called every time this overload is type checked.
-	// This is a pointer so that it can be set in a builtinsregistry hook, which
-	// gets a copy of the overload struct.
-	OnTypeCheck *func()
+	// OnTypeCheck, if set, is called every time this overload is type checked.
+	OnTypeCheck func()
 
 	// SpecializedVecBuiltin is used to let the vectorized engine
 	// know when an Overload has a specialized vectorized operator.
@@ -253,7 +255,7 @@ type Overload struct {
 	FunctionProperties
 
 	// Type indicates if the overload represents a built-in function, a
-	// user-defined function, or a user-define procedure.
+	// user-defined function, or a user-defined procedure.
 	Type RoutineType
 	// Body is the SQL string body of a function. It can be set even if Type is
 	// BuiltinRoutine if a builtin function is defined using a SQL string.
@@ -262,15 +264,46 @@ type Overload struct {
 	// in a Schema descriptor, which means that the full UDF descriptor need to be
 	// fetched to get more info, e.g. function Body.
 	UDFContainsOnlySignature bool
-	// ReturnSet is set to true when a user-defined function is defined to return
-	// a set of values.
-	ReturnSet bool
 	// Version is the descriptor version of the descriptor used to construct
 	// this version of the function overload. Only used for UDFs.
 	Version uint64
 	// Language is the function language that was used to define the UDF.
 	// This is currently either SQL or PL/pgSQL.
 	Language RoutineLanguage
+	// RoutineParams contains all parameter information of the routine.
+	//
+	// Note that unlike Types (which only contains input parameters and defines
+	// the signature of the function), RoutineParams contains all parameters as
+	// well as their class.
+	RoutineParams RoutineParams
+	// OutParamOrdinals contains all ordinals of OUT parameters among all
+	// parameters in the overload definition. For example, if the function /
+	// procedure has a definition like
+	//   (IN p0, INOUT p1, OUT p2, INOUT p3, OUT p4),
+	// then OutParamOrdinals will contain [2, 4] (while ArgTypes will contain
+	// types of [p0, p1, p3]).
+	//
+	// On the main code path it is only set when UDFContainsOnlySignature is
+	// true (meaning that we only had access to the FunctionSignature proto).
+	OutParamOrdinals []int32
+	// OutParamTypes contains types of all OUT parameters (it has 1-to-1 match
+	// with OutParamOrdinals).
+	OutParamTypes TypeList
+	// DefaultExprs specifies all DEFAULT expressions for input parameters.
+	// Since the arguments can only be omitted from the end of the actual
+	// argument list, we know exactly which input parameter each DEFAULT
+	// expression corresponds to.
+	//
+	// On the main code path it is only set when UDFContainsOnlySignature is
+	// true (meaning that we only had access to the FunctionSignature proto). If
+	// UDFContainsOnlySignature is false, then DEFAULT expressions are included
+	// into RoutineParams.
+	DefaultExprs Exprs
+
+	// SecurityMode is true when privilege checks during function execution
+	// should be performed against the function owner rather than the invoking
+	// user.
+	SecurityMode RoutineSecurity
 }
 
 // params implements the overloadImpl interface.
@@ -280,9 +313,17 @@ func (b Overload) params() TypeList { return b.Types }
 func (b Overload) returnType() ReturnTyper { return b.ReturnType }
 
 // preferred implements the overloadImpl interface.
-func (b Overload) preferred() bool { return b.PreferredOverload }
+func (b Overload) preference() OverloadPreference { return b.OverloadPreference }
+
+func (b Overload) outParamInfo() (RoutineType, []int32, TypeList) {
+	return b.Type, b.OutParamOrdinals, b.OutParamTypes
+}
+
+func (b Overload) defaultExprs() Exprs {
+	return b.DefaultExprs
+}
 
-// FixedReturnType returns a fixed type that the function returns, returning Any
+// FixedReturnType returns a fixed type that the function returns, returning AnyElement
 // if the return type is based on the function's arguments.
 func (b Overload) FixedReturnType() *types.T {
 	if b.ReturnType == nil {
@@ -331,13 +372,24 @@ func (b Overload) HasSQLBody() bool {
 // If simplify is bool, tuple-returning functions with just
 // 1 tuple element unwrap the return type in the signature.
 func (b Overload) Signature(simplify bool) string {
+	return b.SignatureWithDefaults(simplify, false /* includeDefault */)
+}
+
+// SignatureWithDefaults is the same as Signature but also allows specifying
+// whether DEFAULT expressions should be included.
+func (b Overload) SignatureWithDefaults(simplify bool, includeDefaults bool) string {
 	retType := b.FixedReturnType()
 	if simplify {
 		if retType.Family() == types.TupleFamily && len(retType.TupleContents()) == 1 {
 			retType = retType.TupleContents()[0]
 		}
 	}
-	return fmt.Sprintf("(%s) -> %s", b.Types.String(), retType)
+	t, ok := b.Types.(ParamTypes)
+	if !includeDefaults || len(b.DefaultExprs) == 0 || !ok {
+		return fmt.Sprintf("(%s) -> %s", b.Types.String(), retType)
+	}
+	return fmt.Sprintf("(%s) -> %s", t.StringWithDefaultExprs(b.DefaultExprs), retType)
+
 }
 
 // overloadImpl is an implementation of an overloaded function. It provides
@@ -348,8 +400,13 @@ func (b Overload) Signature(simplify bool) string {
 type overloadImpl interface {
 	params() TypeList
 	returnType() ReturnTyper
-	// allows manually resolving preference between multiple compatible overloads.
-	preferred() bool
+	preference() OverloadPreference
+	// outParamInfo is only used for routines. See comment on
+	// Overload.OutParamOrdinals and Overload.OutParamTypes for more details.
+	outParamInfo() (_ RoutineType, outParamOrdinals []int32, outParamTypes TypeList)
+	// defaultExprs is only used for routines. See comment on
+	// Overload.DefaultExprs for more details.
+	defaultExprs() Exprs
 }
 
 var _ overloadImpl = &Overload{}
@@ -367,16 +424,16 @@ func GetParamsAndReturnType(impl overloadImpl) (TypeList, ReturnTyper) {
 type TypeList interface {
 	// Match checks if all types in the TypeList match the corresponding elements in types.
 	Match(types []*types.T) bool
-	// MatchIdentical is similar to match but checks that the types are identical matches,
-	//instead of equivalent matches. See types.T.Equivalent and types.T.Identical.
-	MatchIdentical(types []*types.T) bool
+	// MatchOid is similar to match but checks that the types have the same
+	// Oids, instead of being equivalent (in types.T.Equivalent sense) matches.
+	MatchOid(types []*types.T) bool
 	// MatchAt checks if the parameter type at index i of the TypeList matches type typ.
 	// In all implementations, types.Null will match with each parameter type, allowing
 	// NULL values to be used as arguments.
 	MatchAt(typ *types.T, i int) bool
-	// MatchAtIdentical is similar to MatchAt but checks that the type at index i of
-	// the Typelist is identical to typ.
-	MatchAtIdentical(typ *types.T, i int) bool
+	// MatchAtOid is similar to MatchAt but checks that the Oid of the type at
+	// index i of the Typelist is the same as the Oid of typ.
+	MatchAtOid(typ *types.T, i int) bool
 	// MatchLen checks that the TypeList can support l parameters.
 	MatchLen(l int) bool
 	// GetAt returns the type at the given index in the TypeList, or nil if the TypeList
@@ -417,12 +474,12 @@ func (p ParamTypes) Match(types []*types.T) bool {
 }
 
 // MatchIdentical is part of the TypeList interface.
-func (p ParamTypes) MatchIdentical(types []*types.T) bool {
+func (p ParamTypes) MatchOid(types []*types.T) bool {
 	if len(types) != len(p) {
 		return false
 	}
 	for i := range types {
-		if !p.MatchAtIdentical(types[i], i) {
+		if !p.MatchAtOid(types[i], i) {
 			return false
 		}
 	}
@@ -434,7 +491,7 @@ func (p ParamTypes) MatchAt(typ *types.T, i int) bool {
 	// The parameterized types for Tuples are checked in the type checking
 	// routines before getting here, so we only need to check if the parameter
 	// type is p types.TUPLE below. This allows us to avoid defining overloads
-	// for types.Tuple{}, types.Tuple{types.Any}, types.Tuple{types.Any, types.Any},
+	// for types.Tuple{}, types.Tuple{types.AnyElement}, types.Tuple{types.AnyElement, types.AnyElement},
 	// etc. for Tuple operators.
 	if typ.Family() == types.TupleFamily {
 		typ = types.AnyTuple
@@ -443,8 +500,8 @@ func (p ParamTypes) MatchAt(typ *types.T, i int) bool {
 }
 
 // MatchAtIdentical is part of the TypeList interface.
-func (p ParamTypes) MatchAtIdentical(typ *types.T, i int) bool {
-	return i < len(p) && (typ.Family() == types.UnknownFamily || p[i].Typ.Identical(typ))
+func (p ParamTypes) MatchAtOid(typ *types.T, i int) bool {
+	return i < len(p) && (typ.Family() == types.UnknownFamily || p[i].Typ.Oid() == typ.Oid())
 }
 
 // MatchLen is part of the TypeList interface.
@@ -457,12 +514,6 @@ func (p ParamTypes) GetAt(i int) *types.T {
 	return p[i].Typ
 }
 
-// SetAt is part of the TypeList interface.
-func (p ParamTypes) SetAt(i int, name string, t *types.T) {
-	p[i].Name = name
-	p[i].Typ = t
-}
-
 // Length is part of the TypeList interface.
 func (p ParamTypes) Length() int {
 	return len(p)
@@ -491,6 +542,26 @@ func (p ParamTypes) String() string {
 	return s.String()
 }
 
+// StringWithDefaultExprs extends the stringified form of ParamTypes with the
+// corresponding DEFAULT expressions. defaultExprs is expected to have length no
+// longer than p and to correspond to the "suffix" of p.
+func (p ParamTypes) StringWithDefaultExprs(defaultExprs []Expr) string {
+	var s strings.Builder
+	for i, param := range p {
+		if i > 0 {
+			s.WriteString(", ")
+		}
+		s.WriteString(param.Name)
+		s.WriteString(": ")
+		s.WriteString(param.Typ.String())
+		if defaultExprIdx := i - (len(p) - len(defaultExprs)); defaultExprIdx >= 0 {
+			s.WriteString(" DEFAULT ")
+			s.WriteString(defaultExprs[defaultExprIdx].String())
+		}
+	}
+	return s.String()
+}
+
 // HomogeneousType is a TypeList implementation that accepts any arguments, as
 // long as all are the same type or NULL. The homogeneous constraint is enforced
 // in typeCheckOverloadedExprs.
@@ -502,7 +573,7 @@ func (HomogeneousType) Match(types []*types.T) bool {
 }
 
 // MatchIdentical is part of the TypeList interface.
-func (HomogeneousType) MatchIdentical(types []*types.T) bool {
+func (HomogeneousType) MatchOid(types []*types.T) bool {
 	return true
 }
 
@@ -512,7 +583,7 @@ func (HomogeneousType) MatchAt(typ *types.T, i int) bool {
 }
 
 // MatchAtIdentical is part of the TypeList interface.
-func (HomogeneousType) MatchAtIdentical(typ *types.T, i int) bool {
+func (HomogeneousType) MatchAtOid(typ *types.T, i int) bool {
 	return true
 }
 
@@ -523,7 +594,7 @@ func (HomogeneousType) MatchLen(l int) bool {
 
 // GetAt is part of the TypeList interface.
 func (HomogeneousType) GetAt(i int) *types.T {
-	return types.Any
+	return types.AnyElement
 }
 
 // Length is part of the TypeList interface.
@@ -533,7 +604,7 @@ func (HomogeneousType) Length() int {
 
 // Types is part of the TypeList interface.
 func (HomogeneousType) Types() []*types.T {
-	return []*types.T{types.Any}
+	return []*types.T{types.AnyElement}
 }
 
 func (HomogeneousType) String() string {
@@ -559,7 +630,7 @@ func (v VariadicType) Match(types []*types.T) bool {
 }
 
 // MatchIdentical is part of the TypeList interface.
-func (VariadicType) MatchIdentical(types []*types.T) bool {
+func (VariadicType) MatchOid(types []*types.T) bool {
 	return true
 }
 
@@ -573,7 +644,7 @@ func (v VariadicType) MatchAt(typ *types.T, i int) bool {
 
 // MatchAtIdentical is part of the TypeList interface.
 // TODO(mgartner): This will be incorrect once we add support for variadic UDFs
-func (VariadicType) MatchAtIdentical(typ *types.T, i int) bool {
+func (VariadicType) MatchAtOid(typ *types.T, i int) bool {
 	return true
 }
 
@@ -686,7 +757,7 @@ func returnTypeToFixedType(s ReturnTyper, inputTyps []TypedExpr) *types.T {
 	if t := s(inputTyps); t != UnknownReturnType {
 		return t
 	}
-	return types.Any
+	return types.AnyElement
 }
 
 type overloadTypeChecker struct {
@@ -759,6 +830,43 @@ type overloadSet interface {
 	get(i int) overloadImpl
 }
 
+// toParamOrdinal adjusts the provided parameter index to be within the
+// appropriate parameter list and returns whether this parameter has OUT
+// parameter class.
+//
+// It assumes that outParamOrdinals is non-empty.
+func toParamOrdinal(i int, outParamOrdinals []int32) (ordinal int, isOutParam bool) {
+	var outParamsSeen int
+	for _, outParamOrdinal := range outParamOrdinals {
+		if outParamOrdinal == int32(i) {
+			// This expression corresponds to an OUT parameter.
+			return outParamsSeen, true
+		}
+		if outParamOrdinal > int32(i) {
+			break
+		}
+		outParamsSeen++
+	}
+	return i - outParamsSeen, false
+}
+
+// getParamsAndOrdinal returns the parameter list as well as the parameter
+// ordinal within that list for the given routine type and parameter index.
+//
+//gcassert:inline
+func getParamsAndOrdinal(
+	routineType RoutineType, i int, params TypeList, outParamOrdinals []int32, outParams TypeList,
+) (TypeList, int) {
+	if routineType != ProcedureRoutine || len(outParamOrdinals) == 0 {
+		return params, i
+	}
+	ordinal, isOutParam := toParamOrdinal(i, outParamOrdinals)
+	if isOutParam {
+		return outParams, ordinal
+	}
+	return params, ordinal
+}
+
 // typeCheckOverloadedExprs determines the correct overload to use for the given set of
 // expression parameters, along with an optional desired return type. It returns the expression
 // parameters after being type checked, along with a slice of candidate overloadImpls. The
@@ -806,10 +914,48 @@ func (s *overloadTypeChecker) typeCheckOverloadedExprs(
 	}
 	s.constIdxs, s.placeholderIdxs, s.resolvableIdxs = typeCheckSplitExprs(s.exprs)
 
+	// Process variadic functions with unrestrained wildcards as their variadic
+	// parameter. This special cas short circuits the logic below, most of which
+	// assumes AnyElement behavior for untyped parameters.
+	//
+	// TODO(mw5h): This is an ugly special case. Refactor this to use the logic
+	// below. I'd do it now but it's a bit too high risk this close to 25.2.
+	for i := range s.params {
+		if vt, ok := s.params[i].(VariadicType); ok && vt.VarType == types.Any {
+			if semaCtx.UsePre_25_2VariadicBuiltins {
+				vt.VarType = types.AnyElement
+				continue
+			}
+			if numOverloads > 1 {
+				return errors.AssertionFailedf(
+					"only one overload can have VariadicType {types.Any} parameters")
+			} else if !vt.MatchLen(len(s.exprs)) {
+				s.overloadIdxs = s.overloadIdxs[:0]
+				return nil
+			}
+			typeCheckOk := true
+			for j := range s.exprs {
+				typedExpr, err := s.exprs[j].TypeCheck(ctx, semaCtx, vt.GetAt(j))
+				if err != nil {
+					return pgerror.Wrapf(err, pgcode.InvalidParameterValue,
+						"error type checking resolved expression:")
+				} else if !vt.MatchAt(typedExpr.ResolvedType(), j) {
+					typeCheckOk = false
+				}
+				s.typedExprs[j] = typedExpr
+			}
+			s.overloadIdxs = s.overloadIdxs[:0]
+			if typeCheckOk {
+				s.overloadIdxs = append(s.overloadIdxs, uint8(i))
+			}
+			return nil
+		}
+	}
+
 	// If no overloads are provided, just type check parameters and return.
 	if numOverloads == 0 {
 		for i, ok := s.resolvableIdxs.Next(0); ok; i, ok = s.resolvableIdxs.Next(i + 1) {
-			typ, err := s.exprs[i].TypeCheck(ctx, semaCtx, types.Any)
+			typ, err := s.exprs[i].TypeCheck(ctx, semaCtx, types.AnyElement)
 			if err != nil {
 				return pgerror.Wrapf(err, pgcode.InvalidParameterValue,
 					"error type checking resolved expression:")
@@ -827,22 +973,73 @@ func (s *overloadTypeChecker) typeCheckOverloadedExprs(
 		s.overloadIdxs = make([]uint8, 0, numOverloads)
 	}
 	s.overloadIdxs = s.overloadIdxs[:numOverloads]
+	// foundOutParams and foundDefaultExprs indicate whether at least one
+	// overload has non-nil outParamOrdinals mapping and defaultExprs,
+	// respectively. If none are found, we can avoid redundant calls to the
+	// outParamInfo() and defaultExprs() methods.
+	var foundOutParams, foundDefaultExprs bool
 	for i := range s.overloadIdxs {
 		s.overloadIdxs[i] = uint8(i)
+		if !foundOutParams {
+			_, outParamOrdinals, _ := s.overloads[i].outParamInfo()
+			foundOutParams = len(outParamOrdinals) > 0
+		}
+		if !foundDefaultExprs {
+			foundDefaultExprs = len(s.overloads[i].defaultExprs()) > 0
+		}
+	}
+
+	if semaCtx != nil && semaCtx.Properties.IgnoreUnpreferredOverloads {
+		// Filter out unpreferred overloads.
+		s.overloadIdxs = filterOverloads(s.overloadIdxs, s.overloads, func(ov overloadImpl) bool {
+			return ov.preference() != OverloadPreferenceUnpreferred
+		})
 	}
 
 	// Filter out incorrect parameter length overloads.
-	exprsLen := len(s.exprs)
-	matchLen := func(params TypeList) bool { return params.MatchLen(exprsLen) }
-	s.overloadIdxs = filterParams(s.overloadIdxs, s.params, matchLen)
+	matchLen := func(ov overloadImpl, params TypeList) bool {
+		if !foundOutParams && !foundDefaultExprs {
+			return params.MatchLen(len(s.exprs))
+		}
+		routineType, outParamOrdinals, _ := ov.outParamInfo()
+		defaultExprs := ov.defaultExprs()
+		numInputExprs := len(s.exprs)
+		if routineType == ProcedureRoutine {
+			// Ignore all OUT parameters since they are included in exprs but
+			// not in params.
+			numInputExprs = len(s.exprs) - len(outParamOrdinals)
+		}
+		if len(defaultExprs) == 0 {
+			return params.MatchLen(numInputExprs)
+		}
+		// Some "suffix" parameters have DEFAULT expressions, so values for them
+		// can be omitted from the input expressions.
+		// TODO(88947): this logic might need to change to support VARIADIC.
+		paramsLen := params.Length()
+		return paramsLen-len(defaultExprs) <= numInputExprs && numInputExprs <= paramsLen
+	}
+	s.overloadIdxs = filterParams(s.overloadIdxs, s.overloads, s.params, matchLen)
+
+	makeFilter := func(i int, fn func(params TypeList, ordinal int) bool) func(overloadImpl, TypeList) bool {
+		if !foundOutParams {
+			return func(_ overloadImpl, params TypeList) bool {
+				return fn(params, i)
+			}
+		}
+		return func(ov overloadImpl, params TypeList) bool {
+			routineType, outParamOrdinals, outParams := ov.outParamInfo()
+			p, ordinal := getParamsAndOrdinal(routineType, i, params, outParamOrdinals, outParams)
+			return fn(p, ordinal)
+		}
+	}
 
 	// Filter out overloads which constants cannot become.
 	for i, ok := s.constIdxs.Next(0); ok; i, ok = s.constIdxs.Next(i + 1) {
 		constExpr := s.exprs[i].(Constant)
-		filter := func(params TypeList) bool {
-			return canConstantBecome(constExpr, params.GetAt(i))
-		}
-		s.overloadIdxs = filterParams(s.overloadIdxs, s.params, filter)
+		filter := makeFilter(i, func(params TypeList, ordinal int) bool {
+			return canConstantBecome(constExpr, params.GetAt(ordinal))
+		})
+		s.overloadIdxs = filterParams(s.overloadIdxs, s.overloads, s.params, filter)
 	}
 
 	// TODO(nvanbenschoten): We should add a filtering step here to filter
@@ -862,7 +1059,7 @@ func (s *overloadTypeChecker) typeCheckOverloadedExprs(
 		}
 	}
 	for i, ok := typeableIdxs.Next(0); ok; i, ok = typeableIdxs.Next(i + 1) {
-		paramDesired := types.Any
+		paramDesired := types.AnyElement
 
 		// If all remaining candidates require the same type for this parameter,
 		// begin desiring that type for the corresponding argument expression.
@@ -870,7 +1067,12 @@ func (s *overloadTypeChecker) typeCheckOverloadedExprs(
 		var sameType *types.T
 		for _, ovIdx := range s.overloadIdxs {
 			ov := s.overloads[ovIdx]
-			typ := ov.params().GetAt(i)
+			params, ordinal := s.params[ovIdx], i
+			if foundOutParams {
+				routineType, outParamOrdinals, outParams := ov.outParamInfo()
+				params, ordinal = getParamsAndOrdinal(routineType, i, params, outParamOrdinals, outParams)
+			}
+			typ := params.GetAt(ordinal)
 			if sameType == nil {
 				sameType = typ
 			} else if !typ.Identical(sameType) {
@@ -888,33 +1090,94 @@ func (s *overloadTypeChecker) typeCheckOverloadedExprs(
 			return err
 		}
 		s.typedExprs[i] = typ
-		if typ.ResolvedType() == types.AnyCollatedString {
+		if typ.ResolvedType().Identical(types.AnyCollatedString) {
 			ambiguousCollatedTypes = true
 		}
 		rt := typ.ResolvedType()
-		s.overloadIdxs = filterParams(s.overloadIdxs, s.params, func(
-			params TypeList,
-		) bool {
-			return params.MatchAt(rt, i)
+		filter := makeFilter(i, func(params TypeList, ordinal int) bool {
+			return params.MatchAt(rt, ordinal)
 		})
+		s.overloadIdxs = filterParams(s.overloadIdxs, s.overloads, s.params, filter)
 	}
 
+	// Remove any overloads with polymorphic parameters for which the supplied
+	// argument types are invalid.
+	s.overloadIdxs = filterOverloads(s.overloadIdxs, s.overloads, func(o overloadImpl) bool {
+		ol, ok := o.(*Overload)
+		if !ok || ol.Type == BuiltinRoutine {
+			// Don't filter builtin routines.
+			return true
+		}
+		params := ol.Types.(ParamTypes)
+		var outParams ParamTypes
+		if ol.Type == ProcedureRoutine && foundOutParams {
+			outParams = ol.OutParamTypes.(ParamTypes)
+		}
+		hasPolymorphicTyp := false
+		for i := range params {
+			if params[i].Typ.IsPolymorphicType() {
+				hasPolymorphicTyp = true
+				break
+			}
+		}
+		if !hasPolymorphicTyp {
+			return true
+		}
+		argTypes := make([]*types.T, 0, len(params))
+		outArgTypes := make([]*types.T, 0, len(outParams))
+		for i := range s.exprs {
+			typedExpr, err := s.exprs[i].TypeCheck(ctx, semaCtx, types.AnyElement)
+			if err != nil {
+				panic(errors.HandleAsAssertionFailure(err))
+			}
+			if ol.Type == ProcedureRoutine && foundOutParams {
+				if _, isOutParam := toParamOrdinal(i, ol.OutParamOrdinals); isOutParam {
+					// A CALL statement must specify an argument for each OUT parameter
+					// of the procedure.
+					outArgTypes = append(outArgTypes, typedExpr.ResolvedType())
+					continue
+				}
+			}
+			argTypes = append(argTypes, typedExpr.ResolvedType())
+		}
+		// Check the concrete types of the arguments supplied for IN parameters.
+		// Only pass the parameters up to len(argTypes), since polymorphic type
+		// checking for default expressions happens later.
+		var anyElemTyp *types.T
+		if ok, _, anyElemTyp = ResolvePolymorphicArgTypes(
+			params[:len(argTypes)], argTypes, nil /* anyElemTyp */, false, /* enforceConsistency */
+		); !ok {
+			return false
+		}
+		if ol.Type != ProcedureRoutine || !foundOutParams {
+			return true
+		}
+		// Check the concrete types of the arguments supplied for OUT parameters.
+		// Use the concrete type previously resolved from ANYELEMENT IN parameters.
+		// Note that DEFAULT expressions cannot be used for OUT parameters, so there
+		// is no need to truncate the outParams slice.
+		ok, _, _ = ResolvePolymorphicArgTypes(
+			outParams, outArgTypes, anyElemTyp, false, /* enforceConsistency */
+		)
+		return ok
+	})
+
 	// If we typed any exprs as AnyCollatedString but have a concrete collated
-	// string type, redo the types using the contrete type. Note we're probably
+	// string type, redo the types using the concrete type. Note we're probably
 	// still lacking full compliance with PG on collation handling:
 	// https://www.postgresql.org/docs/current/collation.html#id-1.6.11.4.4
 	if ambiguousCollatedTypes {
 		var concreteType *types.T
 		for i, ok := typeableIdxs.Next(0); ok; i, ok = typeableIdxs.Next(i + 1) {
 			typ := s.typedExprs[i].ResolvedType()
-			if typ != types.AnyCollatedString {
+			if !typ.Identical(types.AnyCollatedString) {
 				concreteType = typ
 				break
 			}
 		}
 		if concreteType != nil {
 			for i, ok := typeableIdxs.Next(0); ok; i, ok = typeableIdxs.Next(i + 1) {
-				if s.typedExprs[i].ResolvedType() == types.AnyCollatedString {
+				if s.typedExprs[i].ResolvedType().Identical(types.AnyCollatedString) {
 					typ, err := s.exprs[i].TypeCheck(ctx, semaCtx, concreteType)
 					if err != nil {
 						return err
@@ -926,7 +1189,7 @@ func (s *overloadTypeChecker) typeCheckOverloadedExprs(
 	}
 
 	// At this point, all remaining overload candidates accept the argument list,
-	// so we begin checking for a single remainig candidate implementation to choose.
+	// so we begin checking for a single remaining candidate implementation to choose.
 	// In case there is more than one candidate remaining, the following code uses
 	// heuristics to find a most preferable candidate.
 	if ok, err := checkReturn(ctx, semaCtx, s); ok {
@@ -965,6 +1228,43 @@ func (s *overloadTypeChecker) typeCheckOverloadedExprs(
 		}
 	}
 
+	// If this is a binary operator with one untyped literal or placeholder,
+	// check for a binary operator with parameter types matching the type of the
+	// opposite argument.
+	if inBinOp && len(s.exprs) == 2 {
+		var typ *types.T
+		numConsts := s.constIdxs.Len()
+		numPlaceholders := s.placeholderIdxs.Len()
+		if (numConsts == 1 && numPlaceholders == 0) ||
+			(numConsts == 0 && numPlaceholders == 1) {
+			// If one argument is a constant then it assumes the same type
+			// as the other argument. This matches Postgres's behavior. See
+			// the documentation about "unknown" types (this is how Postgres
+			// initially types constant values):
+			// https://www.postgresql.org/docs/17/typeconv-oper.html.
+			if s.typedExprs[0] != nil {
+				typ = s.typedExprs[0].ResolvedType()
+			} else if s.typedExprs[1] != nil {
+				typ = s.typedExprs[1].ResolvedType()
+			}
+		}
+		if typ != nil {
+			exactOverloads := filterOverloads(s.overloadIdxs, s.overloads,
+				func(ov overloadImpl) bool {
+					typs := ov.params().Types()
+					return typ.Oid() == typs[0].Oid() && typ.Oid() == typs[1].Oid()
+				})
+			if len(exactOverloads) == 1 {
+				prevOverloadIdxs := s.overloadIdxs
+				s.overloadIdxs = exactOverloads
+				if ok, err := checkReturn(ctx, semaCtx, s); ok {
+					return err
+				}
+				s.overloadIdxs = prevOverloadIdxs
+			}
+		}
+	}
+
 	if !s.constIdxs.Empty() {
 		allConstantsAreHomogenous := false
 		if ok, err := filterAttempt(ctx, semaCtx, s, func() {
@@ -982,10 +1282,10 @@ func (s *overloadTypeChecker) typeCheckOverloadedExprs(
 				}
 				if allConstantsAreHomogenous {
 					for i, ok := s.constIdxs.Next(0); ok; i, ok = s.constIdxs.Next(i + 1) {
-						filter := func(params TypeList) bool {
-							return params.GetAt(i).Equivalent(homogeneousTyp)
-						}
-						s.overloadIdxs = filterParams(s.overloadIdxs, s.params, filter)
+						filter := makeFilter(i, func(params TypeList, ordinal int) bool {
+							return params.GetAt(ordinal).Equivalent(homogeneousTyp)
+						})
+						s.overloadIdxs = filterParams(s.overloadIdxs, s.overloads, s.params, filter)
 					}
 				}
 			}
@@ -999,10 +1299,10 @@ func (s *overloadTypeChecker) typeCheckOverloadedExprs(
 			for i, ok := s.constIdxs.Next(0); ok; i, ok = s.constIdxs.Next(i + 1) {
 				natural := naturalConstantType(s.exprs[i].(Constant))
 				if natural != nil {
-					filter := func(params TypeList) bool {
-						return params.GetAt(i).Equivalent(natural)
-					}
-					s.overloadIdxs = filterParams(s.overloadIdxs, s.params, filter)
+					filter := makeFilter(i, func(params TypeList, ordinal int) bool {
+						return params.GetAt(ordinal).Equivalent(natural)
+					})
+					s.overloadIdxs = filterParams(s.overloadIdxs, s.overloads, s.params, filter)
 				}
 			}
 		}); ok {
@@ -1038,9 +1338,11 @@ func (s *overloadTypeChecker) typeCheckOverloadedExprs(
 		// family (like `AnyEnum`).
 		if len(s.overloadIdxs) == 1 && allConstantsAreHomogenous {
 			overloadParamsAreHomogenous := true
-			p := s.overloads[s.overloadIdxs[0]].params()
+			ovIdx := s.overloadIdxs[0]
+			routineType, outParamOrdinals, outParams := s.overloads[ovIdx].outParamInfo()
 			for i, ok := s.constIdxs.Next(0); ok; i, ok = s.constIdxs.Next(i + 1) {
-				if !p.GetAt(i).Equivalent(homogeneousTyp) {
+				params, ordinal := getParamsAndOrdinal(routineType, i, s.params[ovIdx], outParamOrdinals, outParams)
+				if !params.GetAt(ordinal).Equivalent(homogeneousTyp) {
 					overloadParamsAreHomogenous = false
 					break
 				}
@@ -1062,12 +1364,11 @@ func (s *overloadTypeChecker) typeCheckOverloadedExprs(
 		}
 		for i, ok := s.constIdxs.Next(0); ok; i, ok = s.constIdxs.Next(i + 1) {
 			constExpr := s.exprs[i].(Constant)
-			filter := func(params TypeList) bool {
-				semaCtx := MakeSemaContext()
-				_, err := constExpr.ResolveAsType(ctx, &semaCtx, params.GetAt(i))
+			filter := makeFilter(i, func(params TypeList, ordinal int) bool {
+				_, err := constExpr.ResolveAsType(ctx, semaCtx, params.GetAt(ordinal))
 				return err == nil
-			}
-			s.overloadIdxs = filterParams(s.overloadIdxs, s.params, filter)
+			})
+			s.overloadIdxs = filterParams(s.overloadIdxs, s.overloads, s.params, filter)
 		}
 		if ok, err := checkReturn(ctx, semaCtx, s); ok {
 			return err
@@ -1081,10 +1382,10 @@ func (s *overloadTypeChecker) typeCheckOverloadedExprs(
 			// instead of unsupported error (0 overloads) when applicable.
 			prevOverloadIdxs := s.overloadIdxs
 			for i, ok := s.constIdxs.Next(0); ok; i, ok = s.constIdxs.Next(i + 1) {
-				filter := func(params TypeList) bool {
-					return params.GetAt(i).Equivalent(bestConstType)
-				}
-				s.overloadIdxs = filterParams(s.overloadIdxs, s.params, filter)
+				filter := makeFilter(i, func(params TypeList, ordinal int) bool {
+					return params.GetAt(ordinal).Equivalent(bestConstType)
+				})
+				s.overloadIdxs = filterParams(s.overloadIdxs, s.overloads, s.params, filter)
 			}
 			if ok, err := checkReturn(ctx, semaCtx, s); ok {
 				if len(s.overloadIdxs) == 0 {
@@ -1102,11 +1403,19 @@ func (s *overloadTypeChecker) typeCheckOverloadedExprs(
 		}
 	}
 
-	// The fifth heuristic is to defer to preferred candidates, if one has been
-	// specified in the overload list.
+	// The fifth heuristic is to defer to candidates with the highest
+	// preference.
+	maxPreference := OverloadPreferenceUnpreferred
+	for _, idx := range s.overloadIdxs {
+		if p := s.overloads[idx].preference(); p > maxPreference {
+			maxPreference = p
+		}
+	}
 	if ok, err := filterAttempt(ctx, semaCtx, s, func() {
 		s.overloadIdxs = filterOverloads(
-			s.overloadIdxs, s.overloads, overloadImpl.preferred,
+			s.overloadIdxs, s.overloads, func(o overloadImpl) bool {
+				return o.preference() == maxPreference
+			},
 		)
 	}); ok {
 		return err
@@ -1125,10 +1434,10 @@ func (s *overloadTypeChecker) typeCheckOverloadedExprs(
 			if _, err := s.exprs[i].TypeCheck(ctx, semaCtx, homogeneousTyp); err != nil {
 				return err
 			}
-			filter := func(params TypeList) bool {
-				return params.GetAt(i).Equivalent(homogeneousTyp)
-			}
-			s.overloadIdxs = filterParams(s.overloadIdxs, s.params, filter)
+			filter := makeFilter(i, func(params TypeList, ordinal int) bool {
+				return params.GetAt(ordinal).Equivalent(homogeneousTyp)
+			})
+			s.overloadIdxs = filterParams(s.overloadIdxs, s.overloads, s.params, filter)
 		}
 		if ok, err := checkReturn(ctx, semaCtx, s); ok {
 			return err
@@ -1141,67 +1450,71 @@ func (s *overloadTypeChecker) typeCheckOverloadedExprs(
 	// arguments to a known enum and check that the rest match. This is a poor man's
 	// implicit cast / postgres "same argument" resolution clone.
 	if len(s.overloadIdxs) == 1 {
-		params := s.overloads[s.overloadIdxs[0]].params()
+		ovIdx := s.overloadIdxs[0]
+		params := s.params[ovIdx]
 		var knownEnum *types.T
 
-		// Check we have all "AnyEnum" (or "AnyEnum" array) arguments and that
-		// one argument is typed with an enum.
-		attemptAnyEnumCast := func() bool {
-			for i := 0; i < params.Length(); i++ {
-				typ := params.GetAt(i)
-				// Note we are deliberately looking at whether the built-in takes in
-				// AnyEnum as an argument, not the exprs given to the overload itself.
-				if !(typ.Identical(types.AnyEnum) || typ.Identical(types.MakeArray(types.AnyEnum))) {
-					return false
-				}
-				if s.typedExprs[i] != nil {
-					// Assign the known enum if it was previously unassigned.
-					// Otherwise, double check it matches a previously defined enum.
-					posEnum := s.typedExprs[i].ResolvedType()
-					if !posEnum.UserDefined() {
+		// Do not apply this hack to routines for simplicity.
+		if routineType, _, _ := s.overloads[ovIdx].outParamInfo(); routineType == BuiltinRoutine {
+			// Check we have all "AnyEnum" (or "AnyEnum" array) arguments and that
+			// one argument is typed with an enum.
+			attemptAnyEnumCast := func() bool {
+				for i := 0; i < params.Length(); i++ {
+					typ := params.GetAt(i)
+					// Note we are deliberately looking at whether the built-in takes in
+					// AnyEnum as an argument, not the exprs given to the overload itself.
+					if !(typ.Identical(types.AnyEnum) || typ.Identical(types.MakeArray(types.AnyEnum))) {
 						return false
 					}
-					if posEnum.Family() == types.ArrayFamily {
-						posEnum = posEnum.ArrayContents()
-					}
-					if knownEnum == nil {
-						knownEnum = posEnum
-					} else if !posEnum.Identical(knownEnum) {
-						return false
+					if s.typedExprs[i] != nil {
+						// Assign the known enum if it was previously unassigned.
+						// Otherwise, double check it matches a previously defined enum.
+						posEnum := s.typedExprs[i].ResolvedType()
+						if !posEnum.UserDefined() {
+							return false
+						}
+						if posEnum.Family() == types.ArrayFamily {
+							posEnum = posEnum.ArrayContents()
+						}
+						if knownEnum == nil {
+							knownEnum = posEnum
+						} else if !posEnum.Identical(knownEnum) {
+							return false
+						}
 					}
 				}
-			}
-			return knownEnum != nil
-		}()
-
-		// If we have all arguments as AnyEnum, and we know at least one of the
-		// enum's actual type, try type cast the rest.
-		if attemptAnyEnumCast {
-			// Copy exprs to prevent any overwrites of underlying s.exprs array later.
-			sCopy := *s
-			sCopy.exprs = make([]Expr, len(s.exprs))
-			copy(sCopy.exprs, s.exprs)
-
-			if ok, err := filterAttempt(ctx, semaCtx, &sCopy, func() {
-				work := func(idx int) {
-					p := params.GetAt(idx)
-					typCast := knownEnum
-					if p.Family() == types.ArrayFamily {
-						typCast = types.MakeArray(knownEnum)
+				return knownEnum != nil
+			}()
+
+			// If we have all arguments as AnyEnum, and we know at least one of the
+			// enum's actual type, try type cast the rest.
+			if attemptAnyEnumCast {
+				// Copy exprs to prevent any overwrites of underlying s.exprs array later.
+				sCopy := *s
+				sCopy.exprs = make([]Expr, len(s.exprs))
+				copy(sCopy.exprs, s.exprs)
+
+				if ok, err := filterAttempt(ctx, semaCtx, &sCopy, func() {
+					work := func(idx int) {
+						p := params.GetAt(idx)
+						typCast := knownEnum
+						if p.Family() == types.ArrayFamily {
+							typCast = types.MakeArray(knownEnum)
+						}
+						sCopy.exprs[idx] = &CastExpr{Expr: sCopy.exprs[idx], Type: typCast, SyntaxMode: CastShort}
 					}
-					sCopy.exprs[idx] = &CastExpr{Expr: sCopy.exprs[idx], Type: typCast, SyntaxMode: CastShort}
-				}
-				for i, ok := s.constIdxs.Next(0); ok; i, ok = s.constIdxs.Next(i + 1) {
-					work(i)
-				}
-				for i, ok := s.placeholderIdxs.Next(0); ok; i, ok = s.placeholderIdxs.Next(i + 1) {
-					work(i)
+					for i, ok := s.constIdxs.Next(0); ok; i, ok = s.constIdxs.Next(i + 1) {
+						work(i)
+					}
+					for i, ok := s.placeholderIdxs.Next(0); ok; i, ok = s.placeholderIdxs.Next(i + 1) {
+						work(i)
+					}
+				}); ok {
+					s.exprs = sCopy.exprs
+					s.typedExprs = sCopy.typedExprs
+					s.overloadIdxs = append(s.overloadIdxs[:0], sCopy.overloadIdxs...)
+					return err
 				}
-			}); ok {
-				s.exprs = sCopy.exprs
-				s.typedExprs = sCopy.typedExprs
-				s.overloadIdxs = append(s.overloadIdxs[:0], sCopy.overloadIdxs...)
-				return err
 			}
 		}
 	}
@@ -1210,19 +1523,22 @@ func (s *overloadTypeChecker) typeCheckOverloadedExprs(
 	// we prefer overloads where we infer the type of the NULL to be the same as the
 	// other argument. This is used to differentiate the behavior of
 	// STRING[] || NULL and STRING || NULL.
+	// TODO(mgartner): I think we can remove this heuristic in favor of the rule
+	// applied above that types untyped literals and placeholders based on the
+	// input types of overloads.
 	if inBinOp && len(s.exprs) == 2 {
 		if ok, err := filterAttempt(ctx, semaCtx, s, func() {
 			var err error
 			left := s.typedExprs[0]
 			if left == nil {
-				left, err = s.exprs[0].TypeCheck(ctx, semaCtx, types.Any)
+				left, err = s.exprs[0].TypeCheck(ctx, semaCtx, types.AnyElement)
 				if err != nil {
 					return
 				}
 			}
 			right := s.typedExprs[1]
 			if right == nil {
-				right, err = s.exprs[1].TypeCheck(ctx, semaCtx, types.Any)
+				right, err = s.exprs[1].TypeCheck(ctx, semaCtx, types.AnyElement)
 				if err != nil {
 					return
 				}
@@ -1239,11 +1555,11 @@ func (s *overloadTypeChecker) typeCheckOverloadedExprs(
 				if rightIsNull {
 					rightType = leftType
 				}
-				filter := func(params TypeList) bool {
+				filter := func(_ overloadImpl, params TypeList) bool {
 					return params.GetAt(0).Equivalent(leftType) &&
 						params.GetAt(1).Equivalent(rightType)
 				}
-				s.overloadIdxs = filterParams(s.overloadIdxs, s.params, filter)
+				s.overloadIdxs = filterParams(s.overloadIdxs, s.overloads, s.params, filter)
 			}
 		}); ok {
 			return err
@@ -1258,14 +1574,14 @@ func (s *overloadTypeChecker) typeCheckOverloadedExprs(
 			var err error
 			left := s.typedExprs[0]
 			if left == nil {
-				left, err = s.exprs[0].TypeCheck(ctx, semaCtx, types.Any)
+				left, err = s.exprs[0].TypeCheck(ctx, semaCtx, types.AnyElement)
 				if err != nil {
 					return
 				}
 			}
 			right := s.typedExprs[1]
 			if right == nil {
-				right, err = s.exprs[1].TypeCheck(ctx, semaCtx, types.Any)
+				right, err = s.exprs[1].TypeCheck(ctx, semaCtx, types.AnyElement)
 				if err != nil {
 					return
 				}
@@ -1282,11 +1598,11 @@ func (s *overloadTypeChecker) typeCheckOverloadedExprs(
 				if rightIsNull {
 					rightType = types.String
 				}
-				filter := func(params TypeList) bool {
+				filter := func(_ overloadImpl, params TypeList) bool {
 					return params.GetAt(0).Equivalent(leftType) &&
 						params.GetAt(1).Equivalent(rightType)
 				}
-				s.overloadIdxs = filterParams(s.overloadIdxs, s.params, filter)
+				s.overloadIdxs = filterParams(s.overloadIdxs, s.overloads, s.params, filter)
 			}
 		}); ok {
 			return err
@@ -1322,10 +1638,12 @@ func filterAttempt(
 	return false, nil
 }
 
-func filterParams(idxs []uint8, params []TypeList, fn func(i TypeList) bool) []uint8 {
+func filterParams(
+	idxs []uint8, overloads []overloadImpl, params []TypeList, fn func(overloadImpl, TypeList) bool,
+) []uint8 {
 	i, n := 0, len(idxs)
 	for i < n {
-		if fn(params[idxs[i]]) {
+		if fn(overloads[idxs[i]], params[idxs[i]]) {
 			i++
 		} else if n--; i != n {
 			idxs[i], idxs[n] = idxs[n], idxs[i]
@@ -1334,10 +1652,10 @@ func filterParams(idxs []uint8, params []TypeList, fn func(i TypeList) bool) []u
 	return idxs[:n]
 }
 
-func filterOverloads(idxs []uint8, params []overloadImpl, fn func(overloadImpl) bool) []uint8 {
+func filterOverloads(idxs []uint8, overloads []overloadImpl, fn func(overloadImpl) bool) []uint8 {
 	i, n := 0, len(idxs)
 	for i < n {
-		if fn(params[idxs[i]]) {
+		if fn(overloads[idxs[i]]) {
 			i++
 		} else if n--; i != n {
 			idxs[i], idxs[n] = idxs[n], idxs[i]
@@ -1352,7 +1670,7 @@ func defaultTypeCheck(
 	ctx context.Context, semaCtx *SemaContext, s *overloadTypeChecker, errorOnPlaceholders bool,
 ) error {
 	for i, ok := s.constIdxs.Next(0); ok; i, ok = s.constIdxs.Next(i + 1) {
-		typ, err := s.exprs[i].TypeCheck(ctx, semaCtx, types.Any)
+		typ, err := s.exprs[i].TypeCheck(ctx, semaCtx, types.AnyElement)
 		if err != nil {
 			return pgerror.Wrapf(err, pgcode.InvalidParameterValue,
 				"error type checking constant value")
@@ -1361,7 +1679,7 @@ func defaultTypeCheck(
 	}
 	for i, ok := s.placeholderIdxs.Next(0); ok; i, ok = s.placeholderIdxs.Next(i + 1) {
 		if errorOnPlaceholders {
-			if _, err := s.exprs[i].TypeCheck(ctx, semaCtx, types.Any); err != nil {
+			if _, err := s.exprs[i].TypeCheck(ctx, semaCtx, types.AnyElement); err != nil {
 				return err
 			}
 		}
@@ -1392,9 +1710,11 @@ func checkReturn(
 
 	case 1:
 		idx := s.overloadIdxs[0]
-		p := s.params[idx]
+		routineType, outParamOrdinals, outParams := s.overloads[idx].outParamInfo()
+		params := s.params[idx]
 		for i, ok := s.constIdxs.Next(0); ok; i, ok = s.constIdxs.Next(i + 1) {
-			des := p.GetAt(i)
+			p, ordinal := getParamsAndOrdinal(routineType, i, params, outParamOrdinals, outParams)
+			des := p.GetAt(ordinal)
 			typ, err := s.exprs[i].TypeCheck(ctx, semaCtx, des)
 			if err != nil {
 				return false, pgerror.Wrapf(
@@ -1424,9 +1744,11 @@ func checkReturn(
 func checkReturnPlaceholdersAtIdx(
 	ctx context.Context, semaCtx *SemaContext, s *overloadTypeChecker, idx uint8,
 ) (ok bool, _ error) {
-	p := s.params[idx]
+	params := s.params[idx]
+	routineType, outParamOrdinals, outParams := s.overloads[idx].outParamInfo()
 	for i, ok := s.placeholderIdxs.Next(0); ok; i, ok = s.placeholderIdxs.Next(i + 1) {
-		des := p.GetAt(i)
+		p, ordinal := getParamsAndOrdinal(routineType, i, params, outParamOrdinals, outParams)
+		des := p.GetAt(ordinal)
 		typ, err := s.exprs[i].TypeCheck(ctx, semaCtx, des)
 		if err != nil {
 			if des.IsAmbiguous() {
@@ -1450,6 +1772,7 @@ func formatCandidates(prefix string, candidates []overloadImpl, filter []uint8)
 		buf.WriteString(prefix)
 		buf.WriteByte('(')
 		params := candidate.params()
+		defaultExprs := candidate.defaultExprs()
 		tLen := params.Length()
 		inputTyps := make([]TypedExpr, tLen)
 		for i := 0; i < tLen; i++ {
@@ -1459,11 +1782,22 @@ func formatCandidates(prefix string, candidates []overloadImpl, filter []uint8)
 				buf.WriteString(", ")
 			}
 			buf.WriteString(t.String())
+			if len(defaultExprs) > 0 {
+				numParamsWithoutDefaultExpr := tLen - len(defaultExprs)
+				if i >= numParamsWithoutDefaultExpr {
+					defaultExpr := defaultExprs[i-numParamsWithoutDefaultExpr]
+					buf.WriteString(" DEFAULT ")
+					buf.WriteString(defaultExpr.String())
+				}
+			}
 		}
 		buf.WriteString(") -> ")
 		buf.WriteString(returnTypeToFixedType(candidate.returnType(), inputTyps).String())
-		if candidate.preferred() {
+		switch candidate.preference() {
+		case OverloadPreferencePreferred:
 			buf.WriteString(" [preferred]")
+		case OverloadPreferenceUnpreferred:
+			buf.WriteString(" [unpreferred]")
 		}
 		buf.WriteByte('\n')
 	}
@@ -1478,7 +1812,7 @@ func getFuncSig(expr *FuncExpr, typedInputExprs []TypedExpr, desiredType *types.
 	}
 	var desStr string
 	if desiredType.Family() != types.AnyFamily {
-		desStr = fmt.Sprintf(" (desired <%s>)", desiredType)
+		desStr = fmt.Sprintf(" (returning <%s>)", desiredType)
 	}
 	return fmt.Sprintf("%s(%s)%s", &expr.Func, strings.Join(typeNames, ", "), desStr)
 }
diff --git a/pkg/sql/sem/tree/parse_array.go b/pkg/sql/sem/tree/parse_array.go
index 85588d6..e2f6444 100644
--- a/pkg/sql/sem/tree/parse_array.go
+++ b/pkg/sql/sem/tree/parse_array.go
@@ -1,12 +1,7 @@
 // Copyright 2016 The Cockroach Authors.
 //
-// Use of this software is governed by the Business Source License
-// included in the file licenses/BSL.txt.
-//
-// As of the Change Date specified in that file, in accordance with
-// the Business Source License, use of this software will be governed
-// by the Apache License, Version 2.0, included in the file
-// licenses/APL.txt.
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
 
 package tree
 
@@ -31,14 +26,6 @@ func isQuoteChar(ch byte) bool {
 	return ch == '"'
 }
 
-func isControlChar(ch byte) bool {
-	return ch == '{' || ch == '}' || ch == ',' || ch == '"'
-}
-
-func isElementChar(r rune) bool {
-	return r != '{' && r != '}' && r != ','
-}
-
 // isSpaceInParseArray returns true if the rune is a space. To match Postgres,
 // 0x85 and 0xA0 are not treated as whitespace.
 func isSpaceInParseArray(r rune) bool {
@@ -86,6 +73,16 @@ func trimSpaceInParseArray(s string) string {
 	return s[start:stop]
 }
 
+func (p *parseState) isControlChar(ch byte) bool {
+	delim := p.t.Delimiter()[0]
+	return ch == '{' || ch == '}' || ch == delim || ch == '"'
+}
+
+func (p *parseState) isElementChar(r rune) bool {
+	delim, _ := utf8.DecodeRuneInString(p.t.Delimiter())
+	return r != '{' && r != '}' && r != delim
+}
+
 // gobbleString advances the parser for the remainder of the current string
 // until it sees a non-escaped termination character, as specified by
 // isTerminatingChar, returning the resulting string, not including the
@@ -150,7 +147,7 @@ func (p *parseState) parseQuotedString() (string, error) {
 }
 
 func (p *parseState) parseUnquotedString() (string, error) {
-	out, err := p.gobbleString(isControlChar)
+	out, err := p.gobbleString(p.isControlChar)
 	if err != nil {
 		return "", err
 	}
@@ -172,7 +169,7 @@ func (p *parseState) parseElement() error {
 		}
 		p.advance()
 	default:
-		if !isElementChar(r) {
+		if !p.isElementChar(r) {
 			return malformedError
 		}
 		next, err = p.parseUnquotedString()
diff --git a/pkg/sql/sem/tree/parse_string.go b/pkg/sql/sem/tree/parse_string.go
index 045ba67..731020c 100644
--- a/pkg/sql/sem/tree/parse_string.go
+++ b/pkg/sql/sem/tree/parse_string.go
@@ -1,12 +1,7 @@
 // Copyright 2018 The Cockroach Authors.
 //
-// Use of this software is governed by the Business Source License
-// included in the file licenses/BSL.txt.
-//
-// As of the Change Date specified in that file, in accordance with
-// the Business Source License, use of this software will be governed
-// by the Apache License, Version 2.0, included in the file
-// licenses/APL.txt.
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
 
 package tree
 
@@ -69,6 +64,8 @@ func ParseAndRequireString(
 		d, err = ParseDIntervalWithTypeMetadata(intervalStyle(ctx), s, itm)
 	case types.PGLSNFamily:
 		d, err = ParseDPGLSN(s)
+	case types.PGVectorFamily:
+		d, err = ParseDPGVector(s)
 	case types.RefCursorFamily:
 		d = NewDRefCursor(s)
 	case types.Box2DFamily:
@@ -79,9 +76,11 @@ func ParseAndRequireString(
 		d, err = ParseDGeometry(s)
 	case types.JsonFamily:
 		d, err = ParseDJSON(s)
+	case types.JsonpathFamily:
+		d, err = ParseDJsonpath(s)
 	case types.OidFamily:
-		if t.Oid() != oid.T_oid && s == ZeroOidValue {
-			d = WrapAsZeroOid(t)
+		if t.Oid() != oid.T_oid && s == UnknownOidName {
+			d = NewDOidWithType(UnknownOidValue, t)
 		} else {
 			d, err = ParseDOidAsInt(s)
 		}
@@ -141,7 +140,8 @@ func ParseDOidAsInt(s string) (*DOid, error) {
 	if err != nil {
 		return nil, MakeParseError(s, types.Oid, err)
 	}
-	return IntToOid(DInt(i))
+	o, err := IntToOid(DInt(i))
+	return NewDOid(o), err
 }
 
 // FormatBitArrayToType formats bit arrays such that they fill the total width
@@ -256,22 +256,18 @@ func ParseAndRequireStringHandler(
 		s = truncateString(s, t)
 		vh.String(s)
 	case types.TimestampTZFamily:
-		// TODO(cucaroach): can we refactor the next 3 case arms to be simpler
-		// and avoid code duplication?
-		now := relativeParseTime(ctx)
 		var ts time.Time
-		if ts, _, err = pgdate.ParseTimestamp(now, dateStyle(ctx), s); err == nil {
-			// Always normalize time to the current location.
-			if ts, err = checkTimeBounds(ts, TimeFamilyPrecisionToRoundDuration(t.Precision())); err == nil {
-				vh.TimestampTZ(ts)
-			}
+		if ts, _, err = ParseTimestampTZ(ctx, s, TimeFamilyPrecisionToRoundDuration(t.Precision())); err == nil {
+			vh.TimestampTZ(ts)
 		}
 	case types.TimestampFamily:
+		// TODO(yuzefovich): can we refactor the next 2 case arms to be simpler
+		// and avoid code duplication?
 		now := relativeParseTime(ctx)
 		var ts time.Time
-		if ts, _, err = pgdate.ParseTimestampWithoutTimezone(now, dateStyle(ctx), s); err == nil {
+		if ts, _, err = pgdate.ParseTimestampWithoutTimezone(now, dateStyle(ctx), s, dateParseHelper(ctx)); err == nil {
 			// Always normalize time to the current location.
-			if ts, err = checkTimeBounds(ts, TimeFamilyPrecisionToRoundDuration(t.Precision())); err == nil {
+			if ts, err = roundAndCheck(ts, TimeFamilyPrecisionToRoundDuration(t.Precision())); err == nil {
 				vh.TimestampTZ(ts)
 			}
 		}
diff --git a/pkg/sql/sem/tree/parse_tuple.go b/pkg/sql/sem/tree/parse_tuple.go
index 1f6c476..09ecafe 100644
--- a/pkg/sql/sem/tree/parse_tuple.go
+++ b/pkg/sql/sem/tree/parse_tuple.go
@@ -1,12 +1,7 @@
 // Copyright 2016 The Cockroach Authors.
 //
-// Use of this software is governed by the Business Source License
-// included in the file licenses/BSL.txt.
-//
-// As of the Change Date specified in that file, in accordance with
-// the Business Source License, use of this software will be governed
-// by the Apache License, Version 2.0, included in the file
-// licenses/APL.txt.
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
 
 package tree
 
@@ -196,7 +191,7 @@ func doParseDTupleFromString(
 	if t.TupleContents() == nil {
 		return nil, false, errors.AssertionFailedf("not a tuple type %s", t.SQLStringForError())
 	}
-	if t == types.AnyTuple {
+	if t.Identical(types.AnyTuple) {
 		return nil, false, unsupportedRecordError
 	}
 	parser := tupleParseState{
diff --git a/pkg/sql/sem/tree/persistence.go b/pkg/sql/sem/tree/persistence.go
index 4d5a719..4619fd8 100644
--- a/pkg/sql/sem/tree/persistence.go
+++ b/pkg/sql/sem/tree/persistence.go
@@ -1,12 +1,7 @@
 // Copyright 2020 The Cockroach Authors.
 //
-// Use of this software is governed by the Business Source License
-// included in the file licenses/BSL.txt.
-//
-// As of the Change Date specified in that file, in accordance with
-// the Business Source License, use of this software will be governed
-// by the Apache License, Version 2.0, included in the file
-// licenses/APL.txt.
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
 
 package tree
 
diff --git a/pkg/sql/sem/tree/pgwire_encode.go b/pkg/sql/sem/tree/pgwire_encode.go
index 14037e3..5d58fdd 100644
--- a/pkg/sql/sem/tree/pgwire_encode.go
+++ b/pkg/sql/sem/tree/pgwire_encode.go
@@ -1,18 +1,12 @@
 // Copyright 2018 The Cockroach Authors.
 //
-// Use of this software is governed by the Business Source License
-// included in the file licenses/BSL.txt.
-//
-// As of the Change Date specified in that file, in accordance with
-// the Business Source License, use of this software will be governed
-// by the Apache License, Version 2.0, included in the file
-// licenses/APL.txt.
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
 
 package tree
 
 import (
 	"bytes"
-	"fmt"
 	"math"
 	"strconv"
 	"time"
@@ -20,18 +14,32 @@ import (
 
 	"github.com/cockroachdb/cockroachdb-parser/pkg/sql/sessiondatapb"
 	"github.com/cockroachdb/cockroachdb-parser/pkg/sql/types"
+	"github.com/cockroachdb/cockroachdb-parser/pkg/util/encoding"
+	"github.com/cockroachdb/cockroachdb-parser/pkg/util/system"
 	"github.com/cockroachdb/cockroachdb-parser/pkg/util/timeofday"
 	"github.com/cockroachdb/cockroachdb-parser/pkg/util/timetz"
+	"github.com/cockroachdb/cockroachdb-parser/pkg/util/timeutil/pgdate"
 	"github.com/lib/pq/oid"
 )
 
+// spaces is a static slice of spaces used for efficient padding.
+var spaces = bytes.Repeat([]byte{' '}, system.CacheLineSize)
+
 // ResolveBlankPaddedChar pads the given string with spaces if blank padding is
 // required or returns the string unmodified otherwise.
 func ResolveBlankPaddedChar(s string, t *types.T) string {
 	if t.Oid() == oid.T_bpchar && len(s) < int(t.Width()) {
 		// Pad spaces on the right of the string to make it of length specified
 		// in the type t.
-		return fmt.Sprintf("%-*v", t.Width(), s)
+		res := make([]byte, t.Width())
+		copy(res, s)
+		pad := res[len(s):]
+		for len(pad) > len(spaces) {
+			copy(pad, spaces)
+			pad = pad[len(spaces):]
+		}
+		copy(pad, spaces)
+		return encoding.UnsafeConvertBytesToString(res)
 	}
 	return s
 }
@@ -136,7 +144,7 @@ func (d *DArray) pgwireFormat(ctx *FmtCtx) {
 		return
 	}
 
-	if ctx.HasFlags(FmtPGCatalog) {
+	if ctx.HasFlags(fmtPGCatalog) {
 		ctx.WriteByte('\'')
 	}
 	ctx.WriteByte('{')
@@ -172,7 +180,7 @@ func (d *DArray) pgwireFormat(ctx *FmtCtx) {
 		delimiter = d.ParamTyp.Delimiter()
 	}
 	ctx.WriteByte('}')
-	if ctx.HasFlags(FmtPGCatalog) {
+	if ctx.HasFlags(fmtPGCatalog) {
 		ctx.WriteByte('\'')
 	}
 }
@@ -242,7 +250,7 @@ func pgwireFormatStringInArray(ctx *FmtCtx, in string) {
 			// Strings in arrays escape " and \.
 			buf.WriteByte('\\')
 			buf.WriteByte(byte(r))
-		} else if ctx.HasFlags(FmtPGCatalog) && r == '\'' {
+		} else if ctx.HasFlags(fmtPGCatalog) && r == '\'' {
 			buf.WriteByte('\'')
 			buf.WriteByte('\'')
 		} else {
@@ -334,6 +342,13 @@ func PGWireFormatTimeTZ(t timetz.TimeTZ, tmp []byte) []byte {
 // PGWireFormatTimestamp formats t into a format lib/pq understands.
 // If offset is not nil, it will not display the timezone offset.
 func PGWireFormatTimestamp(t time.Time, offset *time.Location, tmp []byte) (b []byte) {
+	if t == pgdate.TimeInfinity {
+		return []byte("infinity")
+	}
+	if t == pgdate.TimeNegativeInfinity {
+		return []byte("-infinity")
+	}
+
 	format := PGTimeStampFormatNoOffset
 	if offset != nil {
 		format = PGTimeStampFormat
diff --git a/pkg/sql/sem/tree/placeholders.go b/pkg/sql/sem/tree/placeholders.go
index 3f7faba..e946f99 100644
--- a/pkg/sql/sem/tree/placeholders.go
+++ b/pkg/sql/sem/tree/placeholders.go
@@ -1,12 +1,7 @@
 // Copyright 2016 The Cockroach Authors.
 //
-// Use of this software is governed by the Business Source License
-// included in the file licenses/BSL.txt.
-//
-// As of the Change Date specified in that file, in accordance with
-// the Business Source License, use of this software will be governed
-// by the Apache License, Version 2.0, included in the file
-// licenses/APL.txt.
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
 
 package tree
 
@@ -18,17 +13,23 @@ import (
 	"github.com/cockroachdb/cockroachdb-parser/pkg/sql/pgwire/pgcode"
 	"github.com/cockroachdb/cockroachdb-parser/pkg/sql/pgwire/pgerror"
 	"github.com/cockroachdb/cockroachdb-parser/pkg/sql/types"
+	"github.com/cockroachdb/redact"
 )
 
 // PlaceholderIdx is the 0-based index of a placeholder. Placeholder "$1"
 // has PlaceholderIdx=0.
 type PlaceholderIdx uint16
 
+var _ redact.SafeValue = PlaceholderIdx(0)
+
 // MaxPlaceholderIdx is the maximum allowed value of a PlaceholderIdx.
 // The pgwire protocol is limited to 2^16 placeholders, so we limit the IDs to
 // this range as well.
 const MaxPlaceholderIdx = math.MaxUint16
 
+// SafeValue implements the redact.SafeValue interface.
+func (idx PlaceholderIdx) SafeValue() {}
+
 // String returns the index as a placeholder string representation ($1, $2 etc).
 func (idx PlaceholderIdx) String() string {
 	return fmt.Sprintf("$%d", idx+1)
@@ -154,7 +155,7 @@ type PlaceholderInfo struct {
 
 // Init initializes a PlaceholderInfo structure appropriate for the given number
 // of placeholders, and with the given (optional) type hints.
-func (p *PlaceholderInfo) Init(numPlaceholders int, typeHints PlaceholderTypes) error {
+func (p *PlaceholderInfo) Init(numPlaceholders int, typeHints PlaceholderTypes) {
 	if typeHints == nil {
 		p.TypeHints = make(PlaceholderTypes, numPlaceholders)
 		p.Types = make(PlaceholderTypes, numPlaceholders)
@@ -163,17 +164,16 @@ func (p *PlaceholderInfo) Init(numPlaceholders int, typeHints PlaceholderTypes)
 		p.TypeHints = typeHints
 	}
 	p.Values = nil
-	return nil
 }
 
 // Assign resets the PlaceholderInfo to the contents of src.
 // If src is nil, a new structure is initialized.
-func (p *PlaceholderInfo) Assign(src *PlaceholderInfo, numPlaceholders int) error {
+func (p *PlaceholderInfo) Assign(src *PlaceholderInfo, numPlaceholders int) {
 	if src != nil {
 		*p = *src
-		return nil
+		return
 	}
-	return p.Init(numPlaceholders, nil /* typeHints */)
+	p.Init(numPlaceholders, nil /* typeHints */)
 }
 
 // MaybeExtendTypes is to fill the nil types with the type hints, if exists.
diff --git a/pkg/sql/sem/tree/prepare.go b/pkg/sql/sem/tree/prepare.go
index c07f3ce..0a1c350 100644
--- a/pkg/sql/sem/tree/prepare.go
+++ b/pkg/sql/sem/tree/prepare.go
@@ -1,12 +1,7 @@
 // Copyright 2016 The Cockroach Authors.
 //
-// Use of this software is governed by the Business Source License
-// included in the file licenses/BSL.txt.
-//
-// As of the Change Date specified in that file, in accordance with
-// the Business Source License, use of this software will be governed
-// by the Apache License, Version 2.0, included in the file
-// licenses/APL.txt.
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
 
 package tree
 
diff --git a/pkg/sql/sem/tree/pretty.go b/pkg/sql/sem/tree/pretty.go
index 725fe5e..a79ecd6 100644
--- a/pkg/sql/sem/tree/pretty.go
+++ b/pkg/sql/sem/tree/pretty.go
@@ -1,12 +1,7 @@
 // Copyright 2018 The Cockroach Authors.
 //
-// Use of this software is governed by the Business Source License
-// included in the file licenses/BSL.txt.
-//
-// As of the Change Date specified in that file, in accordance with
-// the Business Source License, use of this software will be governed
-// by the Apache License, Version 2.0, included in the file
-// licenses/APL.txt.
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
 
 package tree
 
@@ -16,6 +11,7 @@ import (
 	"strconv"
 	"strings"
 
+	"github.com/cockroachdb/cockroachdb-parser/pkg/sql/sem/idxtype"
 	"github.com/cockroachdb/cockroachdb-parser/pkg/sql/sem/tree/treecmp"
 	"github.com/cockroachdb/cockroachdb-parser/pkg/sql/sem/tree/treewindow"
 	"github.com/cockroachdb/cockroachdb-parser/pkg/sql/types"
@@ -64,6 +60,8 @@ type PrettyCfg struct {
 	JSONFmt bool
 	// ValueRedaction, when set, surrounds literal values with redaction markers.
 	ValueRedaction bool
+	// FmtFlags specifies FmtFlags to use when formatting expressions.
+	FmtFlags FmtFlags
 }
 
 // DefaultPrettyCfg returns a PrettyCfg with the default
@@ -186,7 +184,11 @@ func (p *PrettyCfg) docAsString(f NodeFormatter) pretty.Doc {
 }
 
 func (p *PrettyCfg) fmtFlags() FmtFlags {
-	prettyFlags := FmtShowPasswords | FmtParsable | FmtTagDollarQuotes
+	if p.FmtFlags != FmtFlags(0) {
+		return p.FmtFlags
+	}
+
+	prettyFlags := FmtShowPasswords | FmtParsable
 	if p.ValueRedaction {
 		prettyFlags |= FmtMarkRedactionNode | FmtOmitNameRedaction
 	}
@@ -1629,7 +1631,7 @@ func (node *ShardedIndexDef) doc(p *PrettyCfg) pretty.Doc {
 
 func (node *CreateIndex) doc(p *PrettyCfg) pretty.Doc {
 	// Final layout:
-	// CREATE [UNIQUE] [INVERTED] INDEX [name]
+	// CREATE [UNIQUE] [INVERTED | VECTOR] INDEX [name]
 	//    ON tbl (cols...)
 	//    [STORING ( ... )]
 	//    [INTERLEAVE ...]
@@ -1643,8 +1645,11 @@ func (node *CreateIndex) doc(p *PrettyCfg) pretty.Doc {
 	if node.Unique {
 		title = append(title, pretty.Keyword("UNIQUE"))
 	}
-	if node.Inverted {
+	switch node.Type {
+	case idxtype.INVERTED:
 		title = append(title, pretty.Keyword("INVERTED"))
+	case idxtype.VECTOR:
+		title = append(title, pretty.Keyword("VECTOR"))
 	}
 	title = append(title, pretty.Keyword("INDEX"))
 	if node.Concurrently {
@@ -1725,7 +1730,7 @@ func (node *LikeTableDef) doc(p *PrettyCfg) pretty.Doc {
 
 func (node *IndexTableDef) doc(p *PrettyCfg) pretty.Doc {
 	// Final layout:
-	// [INVERTED] INDEX [name] (columns...)
+	// [INVERTED | VECTOR] INDEX [name] (columns...)
 	//    [STORING ( ... )]
 	//    [INTERLEAVE ...]
 	//    [PARTITION BY ...]
@@ -1736,8 +1741,11 @@ func (node *IndexTableDef) doc(p *PrettyCfg) pretty.Doc {
 	if node.Name != "" {
 		title = pretty.ConcatSpace(title, p.Doc(&node.Name))
 	}
-	if node.Inverted {
+	switch node.Type {
+	case idxtype.INVERTED:
 		title = pretty.ConcatSpace(pretty.Keyword("INVERTED"), title)
+	case idxtype.VECTOR:
+		title = pretty.ConcatSpace(pretty.Keyword("VECTOR"), title)
 	}
 	title = pretty.ConcatSpace(title, p.bracket("(", p.Doc(&node.Columns), ")"))
 
@@ -1804,12 +1812,19 @@ func (node *UniqueConstraintTableDef) doc(p *PrettyCfg) pretty.Doc {
 		if node.WithoutIndex {
 			title = pretty.ConcatSpace(title, pretty.Keyword("WITHOUT INDEX"))
 		}
+		if node.FormatAsIndex {
+			title = pretty.ConcatSpace(title, pretty.Keyword("INDEX"))
+		}
 	}
-	title = pretty.ConcatSpace(title, p.bracket("(", p.Doc(&node.Columns), ")"))
 	if node.Name != "" {
-		clauses = append(clauses, title)
-		title = pretty.ConcatSpace(pretty.Keyword("CONSTRAINT"), p.Doc(&node.Name))
+		if node.FormatAsIndex {
+			title = pretty.ConcatSpace(title, p.Doc(&node.Name))
+		} else {
+			constraint := pretty.ConcatSpace(pretty.Keyword("CONSTRAINT"), p.Doc(&node.Name))
+			title = pretty.ConcatSpace(constraint, title)
+		}
 	}
+	title = pretty.ConcatSpace(title, p.bracket("(", p.Doc(&node.Columns), ")"))
 	if node.Sharded != nil {
 		clauses = append(clauses, p.Doc(node.Sharded))
 	}
@@ -2156,25 +2171,18 @@ func (node *Backup) doc(p *PrettyCfg) pretty.Doc {
 	if node.Targets != nil {
 		items = append(items, node.Targets.docRow(p))
 	}
-	if node.Nested {
-		if node.Subdir != nil {
-			items = append(items, p.row("INTO ", p.Doc(node.Subdir)))
-			items = append(items, p.row(" IN ", p.Doc(&node.To)))
-		} else if node.AppendToLatest {
-			items = append(items, p.row("INTO LATEST IN", p.Doc(&node.To)))
-		} else {
-			items = append(items, p.row("INTO", p.Doc(&node.To)))
-		}
+	if node.Subdir != nil {
+		items = append(items, p.row("INTO ", p.Doc(node.Subdir)))
+		items = append(items, p.row(" IN ", p.Doc(&node.To)))
+	} else if node.AppendToLatest {
+		items = append(items, p.row("INTO LATEST IN", p.Doc(&node.To)))
 	} else {
-		items = append(items, p.row("TO", p.Doc(&node.To)))
+		items = append(items, p.row("INTO", p.Doc(&node.To)))
 	}
 
 	if node.AsOf.Expr != nil {
 		items = append(items, node.AsOf.docRow(p))
 	}
-	if node.IncrementalFrom != nil {
-		items = append(items, p.row("INCREMENTAL FROM", p.Doc(&node.IncrementalFrom)))
-	}
 	if !node.Options.IsDefault() {
 		items = append(items, p.row("WITH", p.Doc(&node.Options)))
 	}
@@ -2188,16 +2196,9 @@ func (node *Restore) doc(p *PrettyCfg) pretty.Doc {
 	if node.DescriptorCoverage == RequestedDescriptors {
 		items = append(items, node.Targets.docRow(p))
 	}
-	from := make([]pretty.Doc, len(node.From))
-	for i := range node.From {
-		from[i] = p.Doc(&node.From[i])
-	}
-	if node.Subdir != nil {
-		items = append(items, p.row("FROM", p.Doc(node.Subdir)))
-		items = append(items, p.row("IN", p.commaSeparated(from...)))
-	} else {
-		items = append(items, p.row("FROM", p.commaSeparated(from...)))
-	}
+	from := p.Doc(&node.From)
+	items = append(items, p.row("FROM", p.Doc(node.Subdir)))
+	items = append(items, p.row("IN", from))
 
 	if node.AsOf.Expr != nil {
 		items = append(items, node.AsOf.docRow(p))
diff --git a/pkg/sql/sem/tree/reassign_owned_by.go b/pkg/sql/sem/tree/reassign_owned_by.go
index c2903d3..55e36e8 100644
--- a/pkg/sql/sem/tree/reassign_owned_by.go
+++ b/pkg/sql/sem/tree/reassign_owned_by.go
@@ -1,12 +1,7 @@
 // Copyright 2020 The Cockroach Authors.
 //
-// Use of this software is governed by the Business Source License
-// included in the file licenses/BSL.txt.
-//
-// As of the Change Date specified in that file, in accordance with
-// the Business Source License, use of this software will be governed
-// by the Apache License, Version 2.0, included in the file
-// licenses/APL.txt.
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
 
 package tree
 
diff --git a/pkg/sql/sem/tree/regexp_cache.go b/pkg/sql/sem/tree/regexp_cache.go
index e456fe3..4b2609a 100644
--- a/pkg/sql/sem/tree/regexp_cache.go
+++ b/pkg/sql/sem/tree/regexp_cache.go
@@ -1,17 +1,13 @@
 // Copyright 2015 The Cockroach Authors.
 //
-// Use of this software is governed by the Business Source License
-// included in the file licenses/BSL.txt.
-//
-// As of the Change Date specified in that file, in accordance with
-// the Business Source License, use of this software will be governed
-// by the Apache License, Version 2.0, included in the file
-// licenses/APL.txt.
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
 
 package tree
 
 import (
 	"regexp"
+	"regexp/syntax"
 
 	"github.com/cockroachdb/cockroachdb-parser/pkg/util/cache"
 	"github.com/cockroachdb/cockroachdb-parser/pkg/util/syncutil"
@@ -52,6 +48,22 @@ func NewRegexpCache(size int) *RegexpCache {
 // the given key, compiling the key's pattern if it is not already
 // in the cache.
 func (rc *RegexpCache) GetRegexp(key RegexpCacheKey) (*regexp.Regexp, error) {
+	// syntax.Perl is the default flag for regexp.Compile.
+	return rc.getRegexpInternal(key, syntax.Perl)
+}
+
+// GetRegexpWithFlags consults the cache for the regular expressions stored for
+// the given key, compiling the key's pattern with the given flags if it is not
+// already in the cache.
+func (rc *RegexpCache) GetRegexpWithFlags(
+	key RegexpCacheKey, flags syntax.Flags,
+) (*regexp.Regexp, error) {
+	return rc.getRegexpInternal(key, flags)
+}
+
+func (rc *RegexpCache) getRegexpInternal(
+	key RegexpCacheKey, flags syntax.Flags,
+) (*regexp.Regexp, error) {
 	if rc != nil {
 		re := rc.lookup(key)
 		if re != nil {
@@ -63,8 +75,19 @@ func (rc *RegexpCache) GetRegexp(key RegexpCacheKey) (*regexp.Regexp, error) {
 	if err != nil {
 		return nil, err
 	}
-
-	re, err := regexp.Compile(pattern)
+	var re *regexp.Regexp
+	if flags == syntax.Perl {
+		// Avoid the redundant 'parse - stringify - parse (within Compile)'
+		// sequence in the common case.
+		re, err = regexp.Compile(pattern)
+	} else {
+		var parsed *syntax.Regexp
+		parsed, err = syntax.Parse(pattern, flags)
+		if err != nil {
+			return nil, err
+		}
+		re, err = regexp.Compile(parsed.String())
+	}
 	if err != nil {
 		return nil, err
 	}
diff --git a/pkg/sql/sem/tree/region.go b/pkg/sql/sem/tree/region.go
index 8e7f869..c795fd0 100644
--- a/pkg/sql/sem/tree/region.go
+++ b/pkg/sql/sem/tree/region.go
@@ -1,12 +1,7 @@
 // Copyright 2020 The Cockroach Authors.
 //
-// Use of this software is governed by the Business Source License
-// included in the file licenses/BSL.txt.
-//
-// As of the Change Date specified in that file, in accordance with
-// the Business Source License, use of this software will be governed
-// by the Apache License, Version 2.0, included in the file
-// licenses/APL.txt.
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
 
 package tree
 
diff --git a/pkg/sql/sem/tree/rename.go b/pkg/sql/sem/tree/rename.go
index 850b2f4..2f99d78 100644
--- a/pkg/sql/sem/tree/rename.go
+++ b/pkg/sql/sem/tree/rename.go
@@ -7,13 +7,8 @@
 //
 // Copyright 2015 The Cockroach Authors.
 //
-// Use of this software is governed by the Business Source License
-// included in the file licenses/BSL.txt.
-//
-// As of the Change Date specified in that file, in accordance with
-// the Business Source License, use of this software will be governed
-// by the Apache License, Version 2.0, included in the file
-// licenses/APL.txt.
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
 
 // This code was derived from https://github.com/youtube/vitess.
 
diff --git a/pkg/sql/sem/tree/returning.go b/pkg/sql/sem/tree/returning.go
index 0b4721c..5c9a585 100644
--- a/pkg/sql/sem/tree/returning.go
+++ b/pkg/sql/sem/tree/returning.go
@@ -1,12 +1,7 @@
 // Copyright 2016 The Cockroach Authors.
 //
-// Use of this software is governed by the Business Source License
-// included in the file licenses/BSL.txt.
-//
-// As of the Change Date specified in that file, in accordance with
-// the Business Source License, use of this software will be governed
-// by the Apache License, Version 2.0, included in the file
-// licenses/APL.txt.
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
 
 package tree
 
diff --git a/pkg/sql/sem/tree/revoke.go b/pkg/sql/sem/tree/revoke.go
index e9bac88..692ae26 100644
--- a/pkg/sql/sem/tree/revoke.go
+++ b/pkg/sql/sem/tree/revoke.go
@@ -7,13 +7,8 @@
 //
 // Copyright 2015 The Cockroach Authors.
 //
-// Use of this software is governed by the Business Source License
-// included in the file licenses/BSL.txt.
-//
-// As of the Change Date specified in that file, in accordance with
-// the Business Source License, use of this software will be governed
-// by the Apache License, Version 2.0, included in the file
-// licenses/APL.txt.
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
 
 // This code was derived from https://github.com/youtube/vitess.
 
diff --git a/pkg/sql/sem/tree/role_spec.go b/pkg/sql/sem/tree/role_spec.go
index 65fd408..c59609a 100644
--- a/pkg/sql/sem/tree/role_spec.go
+++ b/pkg/sql/sem/tree/role_spec.go
@@ -1,12 +1,7 @@
 // Copyright 2021 The Cockroach Authors.
 //
-// Use of this software is governed by the Business Source License
-// included in the file licenses/BSL.txt.
-//
-// As of the Change Date specified in that file, in accordance with
-// the Business Source License, use of this software will be governed
-// by the Apache License, Version 2.0, included in the file
-// licenses/APL.txt.
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
 
 package tree
 
diff --git a/pkg/sql/sem/tree/routine.go b/pkg/sql/sem/tree/routine.go
index dfe3320..a134369 100644
--- a/pkg/sql/sem/tree/routine.go
+++ b/pkg/sql/sem/tree/routine.go
@@ -1,20 +1,18 @@
 // Copyright 2022 The Cockroach Authors.
 //
-// Use of this software is governed by the Business Source License
-// included in the file licenses/BSL.txt.
-//
-// As of the Change Date specified in that file, in accordance with
-// the Business Source License, use of this software will be governed
-// by the Apache License, Version 2.0, included in the file
-// licenses/APL.txt.
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
 
 package tree
 
 import (
 	"context"
+	"time"
 
 	"github.com/cockroachdb/cockroachdb-parser/pkg/sql/pgwire/pgcode"
 	"github.com/cockroachdb/cockroachdb-parser/pkg/sql/types"
+	"github.com/cockroachdb/cockroachdb-parser/pkg/util/buildutil"
+	"github.com/cockroachdb/errors"
 )
 
 // RoutinePlanGenerator generates a plan for the execution of each statement
@@ -24,13 +22,20 @@ import (
 // A RoutinePlanGenerator must return an error if the RoutinePlanGeneratedFunc
 // returns an error.
 type RoutinePlanGenerator func(
-	_ context.Context, _ RoutineExecFactory, args Datums, fn RoutinePlanGeneratedFunc,
+	_ context.Context,
+	_ RoutineExecFactory,
+	_ RoutineResultWriter,
+	args Datums,
+	fn RoutinePlanGeneratedFunc,
 ) error
 
 // RoutinePlanGeneratedFunc is the function type that is called for each plan
-// enumerated by a RoutinePlanGenerator. isFinalPlan is true if no more plans
-// will be generated after the current plan.
-type RoutinePlanGeneratedFunc func(plan RoutinePlan, isFinalPlan bool) error
+// enumerated by a RoutinePlanGenerator.
+// - stmtForDistSQLDiagram, if set, will be used when generating DistSQL diagram
+// to specify the SQL stmt corresponding to the plan.
+// - isFinalPlan is true if no more plans will be generated after the current
+// plan.
+type RoutinePlanGeneratedFunc func(plan RoutinePlan, stmtForDistSQLDiagram string, isFinalPlan bool) error
 
 // RoutinePlan represents a plan for a statement in a routine. It currently maps
 // to exec.Plan. We use the empty interface here rather than exec.Plan to avoid
@@ -43,6 +48,12 @@ type RoutinePlan interface{}
 // avoid import cycles.
 type RoutineExecFactory interface{}
 
+// RoutineResultWriter maps to *sql.RowResultWriter. It is used for planning
+// PL/pgSQL set-generating functions, which need to be able to write to the
+// result set at arbitrary points during execution. We use the empty interface
+// here rather than *sql.RowResultWriter to avoid import cycles.
+type RoutineResultWriter interface{}
+
 // RoutineExpr represents sequential execution of multiple statements. For
 // example, it is used to represent execution of statements in the body of a
 // user-defined function. It is only created by execbuilder - it is never
@@ -113,6 +124,12 @@ type RoutineExpr struct {
 	// Generator is true if the function may output a set of rows.
 	Generator bool
 
+	// DiscardLastStmtResult is true if the routine should not add the output of
+	// the last body statement into the result set. This is used for set-returning
+	// PL/pgSQL functions, for which sub-routines will add to the result set
+	// during execution (implementing RETURN NEXT and RETURN QUERY).
+	DiscardLastStmtResult bool
+
 	// TailCall is true if the routine is in a tail-call position in a parent
 	// routine. This means that once execution reaches this routine, the parent
 	// routine will return the result of evaluating this routine with no further
@@ -123,6 +140,16 @@ type RoutineExpr struct {
 	// Procedure is true if the routine is a procedure being invoked by CALL.
 	Procedure bool
 
+	// TriggerFunc is true if this routine is a trigger function. Note that it is
+	// only set for the outermost routine, and not any sub-routines used to
+	// implement the PL/pgSQL body.
+	TriggerFunc bool
+
+	// BlockStart is true if this routine marks the start of a PL/pgSQL block with
+	// an exception handler. It determines when to initialize the state shared
+	// between sub-routines for the block.
+	BlockStart bool
+
 	// BlockState holds the information needed to coordinate error-handling
 	// between the sub-routines that make up a PLpgSQL exception block.
 	BlockState *BlockState
@@ -130,6 +157,11 @@ type RoutineExpr struct {
 	// CursorDeclaration contains the information needed to open a SQL cursor with
 	// the result of the *first* body statement. It may be unset.
 	CursorDeclaration *RoutineOpenCursor
+
+	// FirstStmtResultWriter is the optional result writer that will store the
+	// result of the *first* body statement. It may be unset. Only one of this or
+	// CursorDeclaration may be set.
+	FirstStmtResultWriter RoutineResultWriter
 }
 
 // NewTypedRoutineExpr returns a new RoutineExpr that is well-typed.
@@ -142,24 +174,32 @@ func NewTypedRoutineExpr(
 	calledOnNullInput bool,
 	multiColOutput bool,
 	generator bool,
+	discardLastStmtResult bool,
 	tailCall bool,
 	procedure bool,
+	triggerFunc bool,
+	blockStart bool,
 	blockState *BlockState,
 	cursorDeclaration *RoutineOpenCursor,
+	firstStmtResultWriter RoutineResultWriter,
 ) *RoutineExpr {
 	return &RoutineExpr{
-		Args:              args,
-		ForEachPlan:       gen,
-		Typ:               typ,
-		EnableStepping:    enableStepping,
-		Name:              name,
-		CalledOnNullInput: calledOnNullInput,
-		MultiColOutput:    multiColOutput,
-		Generator:         generator,
-		TailCall:          tailCall,
-		Procedure:         procedure,
-		BlockState:        blockState,
-		CursorDeclaration: cursorDeclaration,
+		Args:                  args,
+		ForEachPlan:           gen,
+		Typ:                   typ,
+		EnableStepping:        enableStepping,
+		Name:                  name,
+		CalledOnNullInput:     calledOnNullInput,
+		MultiColOutput:        multiColOutput,
+		Generator:             generator,
+		DiscardLastStmtResult: discardLastStmtResult,
+		TailCall:              tailCall,
+		Procedure:             procedure,
+		TriggerFunc:           triggerFunc,
+		BlockStart:            blockStart,
+		BlockState:            blockState,
+		CursorDeclaration:     cursorDeclaration,
+		FirstStmtResultWriter: firstStmtResultWriter,
 	}
 }
 
@@ -177,7 +217,8 @@ func (node *RoutineExpr) ResolvedType() *types.T {
 
 // Format is part of the Expr interface.
 func (node *RoutineExpr) Format(ctx *FmtCtx) {
-	ctx.Printf("%s(", node.Name)
+	ctx.FormatName(node.Name)
+	ctx.WriteByte('(')
 	ctx.FormatNode(&node.Args)
 	ctx.WriteByte(')')
 }
@@ -218,6 +259,37 @@ type RoutineOpenCursor struct {
 // BlockState is shared state between all routines that make up a PLpgSQL block.
 // It allows for coordination between the routines for exception handling.
 type BlockState struct {
+	// Parent is a pointer to this block's parent, if any. Note that this refers
+	// to a parent within the same routine; nested routine calls currently do not
+	// interact with one another directly (e.g. through TCO, see #119956).
+	Parent *BlockState
+
+	// VariableCount tracks the number of variables that are in scope for this
+	// block, so that the correct arguments can be supplied to an exception
+	// handler when an error originates from a "descendant" block. Example:
+	//
+	// DECLARE
+	//   x INT := 0;
+	// BEGIN
+	//   DECLARE
+	//     y INT := 1;
+	//   BEGIN
+	//     y = 1 // 0;
+	//   END;
+	// EXCEPTION WHEN division_by_zero THEN
+	//   RETURN 0;
+	// END
+	//
+	// In this example, the error is thrown from the inner block, where variables
+	// "x" and "y" are both in scope. Therefore, we will have access to values for
+	// both variables. However, the error will be caught by the outer block, for
+	// which only "x" is in scope. Therefore, the outer block must truncate the
+	// values before supplying them to its exception handler as arguments.
+	//
+	// NOTE: the list of variables in an outer block *always* form a prefix of the
+	// variables in a nested block.
+	VariableCount int
+
 	// ExceptionHandler is the exception handler for the current block, if any.
 	ExceptionHandler *RoutineExceptionHandler
 
@@ -227,10 +299,106 @@ type BlockState struct {
 	// kv.SavepointToken to avoid import cycles.
 	SavepointTok interface{}
 
-	// Cursors is a list of the names of cursors that have been opened within the
-	// current block. If the exception handler catches an exception, these cursors
-	// must be closed before the handler can proceed.
-	// TODO(111139): Once we support nested routine calls, we may have to track
-	// newly opened cursors differently.
-	Cursors []Name
+	// CursorTimestamp is the timestamp at which control transitioned into this
+	// PL/pgSQL block. It is used to close (only) cursors which were opened within
+	// the scope of the block when an exception is caught.
+	CursorTimestamp *time.Time
+}
+
+// StoredProcTxnOp indicates whether a stored procedure has requested that the
+// current transaction be committed or aborted.
+type StoredProcTxnOp uint8
+
+const (
+	StoredProcTxnNoOp StoredProcTxnOp = iota
+	StoredProcTxnCommit
+	StoredProcTxnRollback
+)
+
+// String returns a string representation of the transaction control statement.
+func (txnOp StoredProcTxnOp) String() string {
+	switch txnOp {
+	case StoredProcTxnNoOp:
+		return "NO-OP"
+	case StoredProcTxnCommit:
+		return "COMMIT"
+	case StoredProcTxnRollback:
+		return "ROLLBACK"
+	default:
+		panic(errors.AssertionFailedf("unknown txn control op: %d", txnOp))
+	}
+}
+
+// StoredProcContinuation represents the plan for a CALL statement that resumes
+// execution of a stored procedure that paused in order to execute a COMMIT or
+// ROLLBACK statement. Currently maps to *memo.Memo.
+type StoredProcContinuation interface{}
+
+// TxnControlPlanGenerator builds the plan for a StoredProcContinuation.
+type TxnControlPlanGenerator func(
+	ctx context.Context, args Datums,
+) (StoredProcContinuation, error)
+
+// TxnControlExpr implements PL/pgSQL COMMIT and ROLLBACK statements. It directs
+// the session to end the current transaction, and provides a plan to resume
+// execution in a new transaction in the form of StoredProcContinuation.
+type TxnControlExpr struct {
+	Op    StoredProcTxnOp
+	Modes TransactionModes
+	Args  TypedExprs
+	Gen   TxnControlPlanGenerator
+
+	Name string
+	Typ  *types.T
+}
+
+var _ Expr = &TxnControlExpr{}
+
+// NewTxnControlExpr returns a new TxnControlExpr that is well-typed.
+func NewTxnControlExpr(
+	opType StoredProcTxnOp,
+	txnModes TransactionModes,
+	args TypedExprs,
+	gen TxnControlPlanGenerator,
+	name string,
+	typ *types.T,
+) *TxnControlExpr {
+	return &TxnControlExpr{
+		Op:    opType,
+		Modes: txnModes,
+		Args:  args,
+		Gen:   gen,
+		Name:  name,
+		Typ:   typ,
+	}
+}
+
+// TypeCheck is part of the Expr interface.
+func (node *TxnControlExpr) TypeCheck(
+	ctx context.Context, semaCtx *SemaContext, desired *types.T,
+) (TypedExpr, error) {
+	return node, nil
+}
+
+// ResolvedType is part of the TypedExpr interface.
+func (node *TxnControlExpr) ResolvedType() *types.T {
+	return node.Typ
+}
+
+// Format is part of the Expr interface.
+func (node *TxnControlExpr) Format(ctx *FmtCtx) {
+	if buildutil.CrdbTestBuild {
+		if node.Op == StoredProcTxnNoOp {
+			panic(errors.AssertionFailedf("called Format for no-op txn control expr"))
+		}
+	}
+	ctx.Printf("%s; CALL %s(", node.Op, node.Name)
+	ctx.FormatNode(&node.Args)
+	ctx.WriteByte(')')
+}
+
+// Walk is part of the Expr interface.
+func (node *TxnControlExpr) Walk(v Visitor) Expr {
+	// Cannot walk into a TxnOp, so this is a no-op.
+	return node
 }
diff --git a/pkg/sql/sem/tree/run_control.go b/pkg/sql/sem/tree/run_control.go
index 428074d..23aad3e 100644
--- a/pkg/sql/sem/tree/run_control.go
+++ b/pkg/sql/sem/tree/run_control.go
@@ -1,12 +1,7 @@
 // Copyright 2017 The Cockroach Authors.
 //
-// Use of this software is governed by the Business Source License
-// included in the file licenses/BSL.txt.
-//
-// As of the Change Date specified in that file, in accordance with
-// the Business Source License, use of this software will be governed
-// by the Apache License, Version 2.0, included in the file
-// licenses/APL.txt.
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
 
 package tree
 
@@ -45,6 +40,20 @@ func (n *ControlJobs) Format(ctx *FmtCtx) {
 	}
 }
 
+// AlterJobOwner represents an ALTER JOB OWNER TO statement.
+type AlterJobOwner struct {
+	Job   Expr
+	Owner RoleSpec
+}
+
+// Format implements the NodeFormatter interface.
+func (n *AlterJobOwner) Format(ctx *FmtCtx) {
+	ctx.WriteString("ALTER JOB ")
+	ctx.FormatNode(n.Job)
+	ctx.WriteString(" OWNER TO ")
+	ctx.FormatNode(&n.Owner)
+}
+
 // CancelQueries represents a CANCEL QUERIES statement.
 type CancelQueries struct {
 	Queries  *Select
diff --git a/pkg/sql/sem/tree/schedule.go b/pkg/sql/sem/tree/schedule.go
index 48a19e5..695b0c6 100644
--- a/pkg/sql/sem/tree/schedule.go
+++ b/pkg/sql/sem/tree/schedule.go
@@ -1,12 +1,7 @@
 // Copyright 2020 The Cockroach Authors.
 //
-// Use of this software is governed by the Business Source License
-// included in the file licenses/BSL.txt.
-//
-// As of the Change Date specified in that file, in accordance with
-// the Business Source License, use of this software will be governed
-// by the Apache License, Version 2.0, included in the file
-// licenses/APL.txt.
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
 
 package tree
 
@@ -60,7 +55,7 @@ func (node *ScheduledBackup) Format(ctx *FmtCtx) {
 	}
 
 	ctx.WriteString(" INTO ")
-	ctx.FormatNode(&node.To)
+	ctx.FormatURIs(node.To)
 
 	if !node.BackupOptions.IsDefault() {
 		ctx.WriteString(" WITH ")
diff --git a/pkg/sql/sem/tree/schema_feature_name.go b/pkg/sql/sem/tree/schema_feature_name.go
index 8dfb9cd..ce69e43 100644
--- a/pkg/sql/sem/tree/schema_feature_name.go
+++ b/pkg/sql/sem/tree/schema_feature_name.go
@@ -1,12 +1,7 @@
 // Copyright 2021 The Cockroach Authors.
 //
-// Use of this software is governed by the Business Source License
-// included in the file licenses/BSL.txt.
-//
-// As of the Change Date specified in that file, in accordance with
-// the Business Source License, use of this software will be governed
-// by the Apache License, Version 2.0, included in the file
-// licenses/APL.txt.
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
 
 package tree
 
diff --git a/pkg/sql/sem/tree/schema_helpers.go b/pkg/sql/sem/tree/schema_helpers.go
new file mode 100644
index 0000000..3a4e85c
--- /dev/null
+++ b/pkg/sql/sem/tree/schema_helpers.go
@@ -0,0 +1,94 @@
+// Copyright 2024 The Cockroach Authors.
+//
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
+
+package tree
+
+import "slices"
+
+// IsSetOrResetSchemaLocked returns true if `n` contains a command to
+// set/reset "schema_locked" storage parameter.
+func IsSetOrResetSchemaLocked(n Statement) bool {
+	alterStmt, ok := n.(*AlterTable)
+	if !ok {
+		return false
+	}
+	for _, cmd := range alterStmt.Cmds {
+		switch cmd := cmd.(type) {
+		case *AlterTableSetStorageParams:
+			if cmd.StorageParams.GetVal("schema_locked") != nil {
+				return true
+			}
+		case *AlterTableResetStorageParams:
+			if slices.Contains(cmd.Params, "schema_locked") {
+				return true
+			}
+		}
+	}
+	return false
+}
+
+// IsAllowedLDRSchemaChange returns true if the schema change statement is
+// allowed to occur while the table is being referenced by a logical data
+// replication job as a destination table.
+func IsAllowedLDRSchemaChange(n Statement, virtualColNames []string, kvWriterEnabled bool) bool {
+	switch s := n.(type) {
+	case *CreateIndex:
+		// Don't allow creating an index on a virtual column.
+		for _, col := range s.Columns {
+			if slices.Contains(virtualColNames, string(col.Column)) {
+				return false
+			}
+		}
+		if s.Predicate != nil && !kvWriterEnabled {
+			// The sql writer supports partial indexes.
+			return true
+		}
+		// Disallow unique, partial, or hash-sharded indexes. Having these indexes
+		// on a destination table could cause inserts to fail.
+		// NB: hash-sharded indexes are disallowed since they create an index on a
+		// virtual column. Since it also implicitly creates the virtual column
+		// at the same time, the check above on virtualColNames would not block it.
+		return !s.Unique && s.Predicate == nil && s.Sharded == nil
+	case *DropIndex:
+		return true
+	case *AlterIndexVisible:
+		return true
+	case *RenameIndex:
+		return true
+	case *SetZoneConfig:
+		return true
+	case *AlterTable:
+		onlySafeStorageParams := true
+		for _, cmd := range s.Cmds {
+			switch c := cmd.(type) {
+			case *AlterTableSetVisible:
+				return true
+			case *AlterTableSetDefault:
+				return true
+			// Allow safe storage parameter changes.
+			case *AlterTableSetStorageParams:
+				// ttl_expire_after is not safe since it creates a new column and
+				// backfills it.
+				if c.StorageParams.GetVal("ttl_expire_after") != nil {
+					onlySafeStorageParams = false
+				}
+			case *AlterTableResetStorageParams:
+				if slices.Contains(c.Params, "ttl_expire_after") {
+					// Resetting `ttl_expire_after` is not safe since it drops a column
+					// and rebuilds the primary index.
+					onlySafeStorageParams = false
+				} else if slices.Contains(c.Params, "ttl") {
+					// Resetting `ttl` can also result in the expiration column being
+					// dropped.
+					onlySafeStorageParams = false
+				}
+			default:
+				onlySafeStorageParams = false
+			}
+		}
+		return onlySafeStorageParams
+	}
+	return false
+}
diff --git a/pkg/sql/sem/tree/scrub.go b/pkg/sql/sem/tree/scrub.go
index 98cb560..5fa5349 100644
--- a/pkg/sql/sem/tree/scrub.go
+++ b/pkg/sql/sem/tree/scrub.go
@@ -1,12 +1,7 @@
 // Copyright 2017 The Cockroach Authors.
 //
-// Use of this software is governed by the Business Source License
-// included in the file licenses/BSL.txt.
-//
-// As of the Change Date specified in that file, in accordance with
-// the Business Source License, use of this software will be governed
-// by the Apache License, Version 2.0, included in the file
-// licenses/APL.txt.
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
 
 package tree
 
diff --git a/pkg/sql/sem/tree/select.go b/pkg/sql/sem/tree/select.go
index 9eacf21..91cb20c 100644
--- a/pkg/sql/sem/tree/select.go
+++ b/pkg/sql/sem/tree/select.go
@@ -7,13 +7,8 @@
 //
 // Copyright 2015 The Cockroach Authors.
 //
-// Use of this software is governed by the Business Source License
-// included in the file licenses/BSL.txt.
-//
-// As of the Change Date specified in that file, in accordance with
-// the Business Source License, use of this software will be governed
-// by the Apache License, Version 2.0, included in the file
-// licenses/APL.txt.
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
 
 // This code was derived from https://github.com/youtube/vitess.
 
@@ -244,8 +239,10 @@ type AsOfClause struct {
 
 // Format implements the NodeFormatter interface.
 func (a *AsOfClause) Format(ctx *FmtCtx) {
-	ctx.WriteString("AS OF SYSTEM TIME ")
-	ctx.FormatNode(a.Expr)
+	if !ctx.flags.HasFlags(FmtSkipAsOfSystemTimeClauses) {
+		ctx.WriteString("AS OF SYSTEM TIME ")
+		ctx.FormatNode(a.Expr)
+	}
 }
 
 // From represents a FROM clause.
@@ -316,7 +313,9 @@ type FamilyID = catid.FamilyID
 //   - NO_INDEX_JOIN
 //   - NO_ZIGZAG_JOIN
 //   - NO_FULL_SCAN
+//   - AVOID_FULL_SCAN
 //   - IGNORE_FOREIGN_KEYS
+//   - FORCE_INVERTED_INDEX
 //   - FORCE_ZIGZAG
 //   - FORCE_ZIGZAG=<index_name|index_id>*
 //   - FAMILY=[family_id]
@@ -334,6 +333,8 @@ type IndexFlags struct {
 	NoZigzagJoin bool
 	// NoFullScan indicates we should constrain this scan.
 	NoFullScan bool
+	// AvoidFullScan indicates we should constrain this scan if possible.
+	AvoidFullScan bool
 	// IgnoreForeignKeys disables optimizations based on outbound foreign key
 	// references from this table. This is useful in particular for scrub queries
 	// used to verify the consistency of foreign key relations.
@@ -341,6 +342,9 @@ type IndexFlags struct {
 	// IgnoreUniqueWithoutIndexKeys disables optimizations based on unique without
 	// index constraints.
 	IgnoreUniqueWithoutIndexKeys bool
+	// ForceInvertedIndex indicates that we should only plan scans over inverted
+	// indexes.
+	ForceInvertedIndex bool
 	// Zigzag hinting fields are distinct:
 	// ForceZigzag means we saw a TABLE@{FORCE_ZIGZAG}
 	// ZigzagIndexes means we saw TABLE@{FORCE_ZIGZAG=name}
@@ -373,19 +377,27 @@ func (ih *IndexFlags) CombineWith(other *IndexFlags) error {
 	if ih.NoFullScan && other.NoFullScan {
 		return errors.New("NO_FULL_SCAN specified multiple times")
 	}
+	if ih.AvoidFullScan && other.AvoidFullScan {
+		return errors.New("AVOID_FULL_SCAN specified multiple times")
+	}
 	if ih.IgnoreForeignKeys && other.IgnoreForeignKeys {
 		return errors.New("IGNORE_FOREIGN_KEYS specified multiple times")
 	}
 	if ih.IgnoreUniqueWithoutIndexKeys && other.IgnoreUniqueWithoutIndexKeys {
 		return errors.New("IGNORE_UNIQUE_WITHOUT_INDEX_KEYS specified multiple times")
 	}
+	if ih.ForceInvertedIndex && other.ForceInvertedIndex {
+		return errors.New("FORCE_INVERTED_INDEX specified multiple times")
+	}
 	result := *ih
 	result.NoIndexJoin = ih.NoIndexJoin || other.NoIndexJoin
 	result.NoZigzagJoin = ih.NoZigzagJoin || other.NoZigzagJoin
 	result.NoFullScan = ih.NoFullScan || other.NoFullScan
+	result.AvoidFullScan = ih.AvoidFullScan || other.AvoidFullScan
 	result.IgnoreForeignKeys = ih.IgnoreForeignKeys || other.IgnoreForeignKeys
 	result.IgnoreUniqueWithoutIndexKeys = ih.IgnoreUniqueWithoutIndexKeys ||
 		other.IgnoreUniqueWithoutIndexKeys
+	result.ForceInvertedIndex = ih.ForceInvertedIndex || other.ForceInvertedIndex
 
 	if other.Direction != 0 {
 		if ih.Direction != 0 {
@@ -441,6 +453,9 @@ func (ih *IndexFlags) Check() error {
 	if ih.Direction != 0 && !ih.ForceIndex() {
 		return errors.New("ASC/DESC must be specified in conjunction with an index")
 	}
+	if ih.ForceInvertedIndex && ih.ForceIndex() {
+		return errors.New("FORCE_INVERTED_INDEX cannot be specified in conjunction with FORCE_INDEX")
+	}
 	if ih.zigzagForced() && ih.NoIndexJoin {
 		return errors.New("FORCE_ZIGZAG cannot be specified in conjunction with NO_INDEX_JOIN")
 	}
@@ -479,8 +494,7 @@ func TestingEnableFamilyIndexHint() func() {
 // Format implements the NodeFormatter interface.
 func (ih *IndexFlags) Format(ctx *FmtCtx) {
 	ctx.WriteByte('@')
-	if !ih.NoIndexJoin && !ih.NoZigzagJoin && !ih.NoFullScan && !ih.IgnoreForeignKeys &&
-		!ih.IgnoreUniqueWithoutIndexKeys && ih.Direction == 0 && !ih.zigzagForced() && ih.FamilyID == nil {
+	if ih.indexOnlyHint() {
 		if ih.Index != "" {
 			ctx.FormatNode(&ih.Index)
 		} else {
@@ -520,6 +534,11 @@ func (ih *IndexFlags) Format(ctx *FmtCtx) {
 			ctx.WriteString("NO_FULL_SCAN")
 		}
 
+		if ih.AvoidFullScan {
+			sep()
+			ctx.WriteString("AVOID_FULL_SCAN")
+		}
+
 		if ih.IgnoreForeignKeys {
 			sep()
 			ctx.WriteString("IGNORE_FOREIGN_KEYS")
@@ -530,6 +549,11 @@ func (ih *IndexFlags) Format(ctx *FmtCtx) {
 			ctx.WriteString("IGNORE_UNIQUE_WITHOUT_INDEX_KEYS")
 		}
 
+		if ih.ForceInvertedIndex {
+			sep()
+			ctx.WriteString("FORCE_INVERTED_INDEX")
+		}
+
 		if ih.ForceZigzag || len(ih.ZigzagIndexes) > 0 || len(ih.ZigzagIndexIDs) > 0 {
 			sep()
 			if ih.ForceZigzag {
@@ -561,6 +585,12 @@ func (ih *IndexFlags) Format(ctx *FmtCtx) {
 	}
 }
 
+func (ih *IndexFlags) indexOnlyHint() bool {
+	return !ih.NoIndexJoin && !ih.NoZigzagJoin && !ih.NoFullScan && !ih.AvoidFullScan &&
+		!ih.IgnoreForeignKeys && !ih.IgnoreUniqueWithoutIndexKeys && ih.Direction == 0 &&
+		!ih.ForceInvertedIndex && !ih.zigzagForced() && ih.FamilyID == nil
+}
+
 func (ih *IndexFlags) zigzagForced() bool {
 	return ih.ForceZigzag || len(ih.ZigzagIndexes) > 0 || len(ih.ZigzagIndexIDs) > 0
 }
@@ -637,6 +667,7 @@ const (
 	AstLookup   = "LOOKUP"
 	AstMerge    = "MERGE"
 	AstInverted = "INVERTED"
+	AstStraight = "STRAIGHT"
 )
 
 // Format implements the NodeFormatter interface.
@@ -1278,10 +1309,3 @@ func (d LockingDurability) String() string {
 func (d LockingDurability) Max(d2 LockingDurability) LockingDurability {
 	return LockingDurability(max(byte(d), byte(d2)))
 }
-
-func max(a, b byte) byte {
-	if a > b {
-		return a
-	}
-	return b
-}
diff --git a/pkg/sql/sem/tree/set.go b/pkg/sql/sem/tree/set.go
index 9e4b6c3..dcf40ea 100644
--- a/pkg/sql/sem/tree/set.go
+++ b/pkg/sql/sem/tree/set.go
@@ -7,13 +7,8 @@
 //
 // Copyright 2015 The Cockroach Authors.
 //
-// Use of this software is governed by the Business Source License
-// included in the file licenses/BSL.txt.
-//
-// As of the Change Date specified in that file, in accordance with
-// the Business Source License, use of this software will be governed
-// by the Apache License, Version 2.0, included in the file
-// licenses/APL.txt.
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
 
 // This code was derived from https://github.com/youtube/vitess.
 
@@ -103,6 +98,25 @@ func (node *SetTransaction) Format(ctx *FmtCtx) {
 	ctx.FormatNode(&node.Modes)
 }
 
+// copyNode makes a copy of this Statement.
+func (stmt *SetTransaction) copyNode() *SetTransaction {
+	stmtCopy := *stmt
+	return &stmtCopy
+}
+
+// walkStmt is part of the walkableStmt interface.
+func (stmt *SetTransaction) walkStmt(v Visitor) Statement {
+	ret := stmt
+	if stmt.Modes.AsOf.Expr != nil {
+		e, changed := WalkExpr(v, stmt.Modes.AsOf.Expr)
+		if changed {
+			ret = stmt.copyNode()
+			ret.Modes.AsOf.Expr = e
+		}
+	}
+	return ret
+}
+
 // SetSessionAuthorizationDefault represents a SET SESSION AUTHORIZATION DEFAULT
 // statement. This can be extended (and renamed) if we ever support names in the
 // last position.
diff --git a/pkg/sql/sem/tree/show.go b/pkg/sql/sem/tree/show.go
index c7aaa36..66eeaad 100644
--- a/pkg/sql/sem/tree/show.go
+++ b/pkg/sql/sem/tree/show.go
@@ -7,13 +7,8 @@
 //
 // Copyright 2015 The Cockroach Authors.
 //
-// Use of this software is governed by the Business Source License
-// included in the file licenses/BSL.txt.
-//
-// As of the Change Date specified in that file, in accordance with
-// the Business Source License, use of this software will be governed
-// by the Apache License, Version 2.0, included in the file
-// licenses/APL.txt.
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
 
 // This code was derived from https://github.com/youtube/vitess.
 
@@ -91,8 +86,6 @@ const (
 	// BackupValidateDetails identifies a SHOW BACKUP VALIDATION
 	// statement.
 	BackupValidateDetails
-	// BackupConnectionTest identifies a SHOW BACKUP CONNECTION statement
-	BackupConnectionTest
 )
 
 // TODO (msbutler): 22.2 after removing old style show backup syntax, rename
@@ -111,9 +104,9 @@ type ShowBackup struct {
 
 // Format implements the NodeFormatter interface.
 func (node *ShowBackup) Format(ctx *FmtCtx) {
-	if node.InCollection != nil && node.Path == nil {
+	if node.Path == nil {
 		ctx.WriteString("SHOW BACKUPS IN ")
-		ctx.FormatNode(&node.InCollection)
+		ctx.FormatURIs(node.InCollection)
 		return
 	}
 	ctx.WriteString("SHOW BACKUP ")
@@ -125,8 +118,6 @@ func (node *ShowBackup) Format(ctx *FmtCtx) {
 		ctx.WriteString("FILES ")
 	case BackupSchemaDetails:
 		ctx.WriteString("SCHEMAS ")
-	case BackupConnectionTest:
-		ctx.WriteString("CONNECTION ")
 	}
 
 	if node.From {
@@ -134,10 +125,9 @@ func (node *ShowBackup) Format(ctx *FmtCtx) {
 	}
 
 	ctx.FormatNode(node.Path)
-	if node.InCollection != nil {
-		ctx.WriteString(" IN ")
-		ctx.FormatNode(&node.InCollection)
-	}
+	ctx.WriteString(" IN ")
+	ctx.FormatURIs(node.InCollection)
+
 	if !node.Options.IsDefault() {
 		ctx.WriteString(" WITH OPTIONS (")
 		ctx.FormatNode(&node.Options)
@@ -164,7 +154,6 @@ type ShowBackupOptions struct {
 	// `ENCRYPTION-INFO` file necessary to decode the incremental backup lives in
 	// the full backup dir.
 	EncryptionInfoDir Expr
-	DebugMetadataSST  bool
 
 	CheckConnectionTransferSize Expr
 	CheckConnectionDuration     Expr
@@ -205,7 +194,7 @@ func (o *ShowBackupOptions) Format(ctx *FmtCtx) {
 	if o.IncrementalStorage != nil {
 		maybeAddSep()
 		ctx.WriteString("incremental_location = ")
-		ctx.FormatNode(&o.IncrementalStorage)
+		ctx.FormatURIs(o.IncrementalStorage)
 	}
 
 	if o.Privileges {
@@ -221,16 +210,12 @@ func (o *ShowBackupOptions) Format(ctx *FmtCtx) {
 	if o.DecryptionKMSURI != nil {
 		maybeAddSep()
 		ctx.WriteString("kms = ")
-		ctx.FormatNode(&o.DecryptionKMSURI)
+		ctx.FormatURIs(o.DecryptionKMSURI)
 	}
 	if o.SkipSize {
 		maybeAddSep()
 		ctx.WriteString("skip size")
 	}
-	if o.DebugMetadataSST {
-		maybeAddSep()
-		ctx.WriteString("debug_dump_metadata_sst")
-	}
 
 	// The following are only used in connection-check SHOW.
 	if o.CheckConnectionConcurrency != nil {
@@ -260,7 +245,6 @@ func (o ShowBackupOptions) IsDefault() bool {
 		o.EncryptionPassphrase == options.EncryptionPassphrase &&
 		o.Privileges == options.Privileges &&
 		o.SkipSize == options.SkipSize &&
-		o.DebugMetadataSST == options.DebugMetadataSST &&
 		o.EncryptionInfoDir == options.EncryptionInfoDir &&
 		o.CheckConnectionTransferSize == options.CheckConnectionTransferSize &&
 		o.CheckConnectionDuration == options.CheckConnectionDuration &&
@@ -333,11 +317,6 @@ func (o *ShowBackupOptions) CombineWith(other *ShowBackupOptions) error {
 	if err != nil {
 		return err
 	}
-	o.DebugMetadataSST, err = combineBools(o.DebugMetadataSST, other.DebugMetadataSST,
-		"debug_dump_metadata_sst")
-	if err != nil {
-		return err
-	}
 	o.EncryptionInfoDir, err = combineExpr(o.EncryptionInfoDir, other.EncryptionInfoDir,
 		"encryption_info_dir")
 	if err != nil {
@@ -406,11 +385,17 @@ func (node *ShowEnums) Format(ctx *FmtCtx) {
 }
 
 // ShowTypes represents a SHOW TYPES statement.
-type ShowTypes struct{}
+type ShowTypes struct {
+	WithComment bool
+}
 
 // Format implements the NodeFormatter interface.
 func (node *ShowTypes) Format(ctx *FmtCtx) {
 	ctx.WriteString("SHOW TYPES")
+
+	if node.WithComment {
+		ctx.WriteString(" WITH COMMENT")
+	}
 }
 
 // ShowTraceType is an enum of SHOW TRACE variants.
@@ -652,7 +637,8 @@ func (node *ShowSessions) Format(ctx *FmtCtx) {
 
 // ShowSchemas represents a SHOW SCHEMAS statement.
 type ShowSchemas struct {
-	Database Name
+	Database    Name
+	WithComment bool
 }
 
 // Format implements the NodeFormatter interface.
@@ -662,6 +648,9 @@ func (node *ShowSchemas) Format(ctx *FmtCtx) {
 		ctx.WriteString(" FROM ")
 		ctx.FormatNode(&node.Database)
 	}
+	if node.WithComment {
+		ctx.WriteString(" WITH COMMENT")
+	}
 }
 
 // ShowSequences represents a SHOW SEQUENCES statement.
@@ -819,6 +808,10 @@ type ShowCreateFormatOption int
 const (
 	ShowCreateFormatOptionNone ShowCreateFormatOption = iota
 	ShowCreateFormatOptionRedactedValues
+	ShowCreateFormatOptionIgnoreFKs
+	// TODO(yuzefovich): consider adding an option that both has redacted values
+	// and ignores the FKs. This will require addition of a new column to
+	// crdb_internal.create_statements virtual table.
 )
 
 // ShowCreate represents a SHOW CREATE statement.
@@ -845,6 +838,8 @@ func (node *ShowCreate) Format(ctx *FmtCtx) {
 	switch node.FmtOpt {
 	case ShowCreateFormatOptionRedactedValues:
 		ctx.WriteString(" WITH REDACT")
+	case ShowCreateFormatOptionIgnoreFKs:
+		ctx.WriteString(" WITH IGNORE_FOREIGN_KEYS")
 	}
 }
 
@@ -969,6 +964,28 @@ func (node *ShowUsers) Format(ctx *FmtCtx) {
 	ctx.WriteString("SHOW USERS")
 }
 
+// ShowDefaultSessionVariablesForRole represents a SHOW DEFAULT SESSION VARIABLES FOR ROLE <name> statement.
+type ShowDefaultSessionVariablesForRole struct {
+	Name   RoleSpec
+	IsRole bool
+	All    bool
+}
+
+// Format implements the NodeFormatter interface.
+func (node *ShowDefaultSessionVariablesForRole) Format(ctx *FmtCtx) {
+	ctx.WriteString("SHOW DEFAULT SESSION VARIABLES FOR")
+	if node.IsRole {
+		ctx.WriteString(" ROLE ")
+	} else {
+		ctx.WriteString(" USER ")
+	}
+	if node.All {
+		ctx.WriteString("ALL")
+	} else {
+		ctx.FormatNode(&node.Name)
+	}
+}
+
 // ShowRoles represents a SHOW ROLES statement.
 type ShowRoles struct {
 }
@@ -1108,6 +1125,8 @@ func (node *ShowRangeForRow) Format(ctx *FmtCtx) {
 type ShowFingerprints struct {
 	TenantSpec *TenantSpec
 	Table      *UnresolvedObjectName
+
+	Options ShowFingerprintOptions
 }
 
 // Format implements the NodeFormatter interface.
@@ -1119,8 +1138,76 @@ func (node *ShowFingerprints) Format(ctx *FmtCtx) {
 		ctx.WriteString("SHOW EXPERIMENTAL_FINGERPRINTS FROM VIRTUAL CLUSTER ")
 		ctx.FormatNode(node.TenantSpec)
 	}
+
+	if !node.Options.IsDefault() {
+		ctx.WriteString(" WITH OPTIONS (")
+		ctx.FormatNode(&node.Options)
+		ctx.WriteString(")")
+	}
+}
+
+// ShowFingerprintOptions describes options for the SHOW EXPERIMENTAL_FINGERPINT
+// execution.
+type ShowFingerprintOptions struct {
+	StartTimestamp      Expr
+	ExcludedUserColumns StringOrPlaceholderOptList
+}
+
+func (s *ShowFingerprintOptions) Format(ctx *FmtCtx) {
+	var addSep bool
+	maybeAddSep := func() {
+		if addSep {
+			ctx.WriteString(", ")
+		}
+		addSep = true
+	}
+
+	if s.StartTimestamp != nil {
+		maybeAddSep()
+		ctx.WriteString("START TIMESTAMP = ")
+		_, canOmitParentheses := s.StartTimestamp.(alreadyDelimitedAsSyntacticDExpr)
+		if !canOmitParentheses {
+			ctx.WriteByte('(')
+		}
+		ctx.FormatNode(s.StartTimestamp)
+		if !canOmitParentheses {
+			ctx.WriteByte(')')
+		}
+	}
+	if s.ExcludedUserColumns != nil {
+		maybeAddSep()
+		ctx.WriteString("EXCLUDE COLUMNS = ")
+		s.ExcludedUserColumns.Format(ctx)
+	}
+}
+
+// CombineWith merges other TenantReplicationOptions into this struct.
+// An error is returned if the same option merged multiple times.
+func (s *ShowFingerprintOptions) CombineWith(other *ShowFingerprintOptions) error {
+	if s.StartTimestamp != nil {
+		if other.StartTimestamp != nil {
+			return errors.New("START TIMESTAMP option specified multiple times")
+		}
+	} else {
+		s.StartTimestamp = other.StartTimestamp
+	}
+
+	var err error
+	s.ExcludedUserColumns, err = combineStringOrPlaceholderOptList(s.ExcludedUserColumns, other.ExcludedUserColumns, "excluded_user_columns")
+	if err != nil {
+		return err
+	}
+	return nil
 }
 
+// IsDefault returns true if this backup options struct has default value.
+func (s ShowFingerprintOptions) IsDefault() bool {
+	options := ShowFingerprintOptions{}
+	return s.StartTimestamp == options.StartTimestamp && cmp.Equal(s.ExcludedUserColumns, options.ExcludedUserColumns)
+}
+
+var _ NodeFormatter = &ShowFingerprintOptions{}
+
 // ShowTableStats represents a SHOW STATISTICS FOR TABLE statement.
 type ShowTableStats struct {
 	Table     *UnresolvedObjectName
@@ -1145,8 +1232,9 @@ func (node *ShowTableStats) Format(ctx *FmtCtx) {
 
 // ShowTenantOptions represents the WITH clause in SHOW VIRTUAL CLUSTER.
 type ShowTenantOptions struct {
-	WithReplication  bool
-	WithCapabilities bool
+	WithReplication      bool
+	WithPriorReplication bool
+	WithCapabilities     bool
 }
 
 // ShowTenant represents a SHOW VIRTUAL CLUSTER statement.
@@ -1164,6 +1252,9 @@ func (node *ShowTenant) Format(ctx *FmtCtx) {
 	if node.WithReplication {
 		withs = append(withs, "REPLICATION STATUS")
 	}
+	if node.WithPriorReplication {
+		withs = append(withs, "PRIOR REPLICATION DETAILS")
+	}
 	if node.WithCapabilities {
 		withs = append(withs, "CAPABILITIES")
 	}
@@ -1173,6 +1264,25 @@ func (node *ShowTenant) Format(ctx *FmtCtx) {
 	}
 }
 
+// ShowLogicalReplicationJobsOptions represents the WITH clause in SHOW LOGICAL REPLICATION JOBS.
+type ShowLogicalReplicationJobsOptions struct {
+	WithDetails bool
+}
+
+// ShowLogicalReplicationJobs represents a SHOW LOGICAL REPLICATION JOBS statement.
+type ShowLogicalReplicationJobs struct {
+	ShowLogicalReplicationJobsOptions
+}
+
+// Format implements the NodeFormatter interface.
+func (node *ShowLogicalReplicationJobs) Format(ctx *FmtCtx) {
+	ctx.WriteString("SHOW LOGICAL REPLICATION JOBS")
+
+	if node.WithDetails {
+		ctx.WriteString(" WITH DETAILS")
+	}
+}
+
 // ShowHistogram represents a SHOW HISTOGRAM statement.
 type ShowHistogram struct {
 	HistogramID int64
@@ -1209,6 +1319,19 @@ func (node *ShowPartitions) Format(ctx *FmtCtx) {
 	}
 }
 
+// ShowPolicies represents a SHOW POLICIES statement.
+type ShowPolicies struct {
+	Table *UnresolvedObjectName
+}
+
+// Format implements the NodeFormatter interface.
+func (node *ShowPolicies) Format(ctx *FmtCtx) {
+	ctx.WriteString("SHOW POLICIES FOR ")
+	ctx.FormatNode(node.Table)
+}
+
+var _ Statement = &ShowPolicies{}
+
 // ScheduledJobExecutorType is a type identifying the names of
 // the supported scheduled job executors.
 type ScheduledJobExecutorType int
@@ -1455,3 +1578,49 @@ func (s ShowCommitTimestamp) Format(ctx *FmtCtx) {
 }
 
 var _ Statement = (*ShowCommitTimestamp)(nil)
+
+// ShowExternalConnections represents a SHOW EXTERNAL CONNECTIONS statement.
+type ShowExternalConnections struct {
+	ConnectionLabel Expr
+}
+
+// Format implements the NodeFormatter interface.
+func (node *ShowExternalConnections) Format(ctx *FmtCtx) {
+	if node.ConnectionLabel != nil {
+		ctx.WriteString("SHOW EXTERNAL CONNECTION ")
+		ctx.FormatNode(node.ConnectionLabel)
+		return
+	}
+	ctx.Printf("SHOW EXTERNAL CONNECTIONS")
+}
+
+var _ Statement = &ShowExternalConnections{}
+
+// ShowTriggers represents a SHOW TRIGGERS statement.
+type ShowTriggers struct {
+	Table *UnresolvedObjectName
+}
+
+// Format implements the NodeFormatter interface.
+func (node *ShowTriggers) Format(ctx *FmtCtx) {
+	ctx.WriteString("SHOW TRIGGERS FROM ")
+	ctx.FormatNode(node.Table)
+}
+
+var _ Statement = &ShowTriggers{}
+
+// ShowCreateTrigger represents a SHOW CREATE TRIGGER statement.
+type ShowCreateTrigger struct {
+	Name      Name
+	TableName *UnresolvedObjectName
+}
+
+// Format implements the NodeFormatter interface.
+func (node *ShowCreateTrigger) Format(ctx *FmtCtx) {
+	ctx.WriteString("SHOW CREATE TRIGGER ")
+	ctx.FormatNode(&node.Name)
+	ctx.WriteString(" ON ")
+	ctx.FormatNode(node.TableName)
+}
+
+var _ Statement = &ShowCreateTrigger{}
diff --git a/pkg/sql/sem/tree/split.go b/pkg/sql/sem/tree/split.go
index 132f2ac..5af973c 100644
--- a/pkg/sql/sem/tree/split.go
+++ b/pkg/sql/sem/tree/split.go
@@ -1,12 +1,7 @@
 // Copyright 2016 The Cockroach Authors.
 //
-// Use of this software is governed by the Business Source License
-// included in the file licenses/BSL.txt.
-//
-// As of the Change Date specified in that file, in accordance with
-// the Business Source License, use of this software will be governed
-// by the Apache License, Version 2.0, included in the file
-// licenses/APL.txt.
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
 
 package tree
 
diff --git a/pkg/sql/sem/tree/statementreturntype_string.go b/pkg/sql/sem/tree/statementreturntype_string.go
index e0be27d..02ca639 100644
--- a/pkg/sql/sem/tree/statementreturntype_string.go
+++ b/pkg/sql/sem/tree/statementreturntype_string.go
@@ -1,3 +1,8 @@
+// Copyright 2023 The Cockroach Authors.
+//
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
+
 // Code generated by "stringer"; DO NOT EDIT.
 
 package tree
diff --git a/pkg/sql/sem/tree/statementtype_string.go b/pkg/sql/sem/tree/statementtype_string.go
index 7d50d0c..ad3841d 100644
--- a/pkg/sql/sem/tree/statementtype_string.go
+++ b/pkg/sql/sem/tree/statementtype_string.go
@@ -1,3 +1,8 @@
+// Copyright 2023 The Cockroach Authors.
+//
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
+
 // Code generated by "stringer"; DO NOT EDIT.
 
 package tree
diff --git a/pkg/sql/sem/tree/stmt.go b/pkg/sql/sem/tree/stmt.go
index bf7ea5c..b84d3a8 100644
--- a/pkg/sql/sem/tree/stmt.go
+++ b/pkg/sql/sem/tree/stmt.go
@@ -7,13 +7,8 @@
 //
 // Copyright 2015 The Cockroach Authors.
 //
-// Use of this software is governed by the Business Source License
-// included in the file licenses/BSL.txt.
-//
-// As of the Change Date specified in that file, in accordance with
-// the Business Source License, use of this software will be governed
-// by the Apache License, Version 2.0, included in the file
-// licenses/APL.txt.
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
 
 // This code was derived from https://github.com/youtube/vitess.
 
@@ -49,8 +44,8 @@ const (
 	//
 	// Note: this is the type indicated back to the client; it is not a
 	// sufficient test for schema mutation for planning purposes. There
-	// are schema-modifying statements (e.g. CREATE TABLE AS) which
-	// report RowsAffected to the client, not DDL.
+	// are schema-modifying statements (e.g. DISCARD ALL) which
+	// report Ack to the client, not DDL.
 	// Use CanModifySchema() below instead.
 	DDL
 	// RowsAffected indicates that the statement returns the count of
@@ -91,21 +86,28 @@ const (
 
 const (
 	AlterTableTag          = "ALTER TABLE"
+	AlterPolicyTag         = "ALTER POLICY"
 	BackupTag              = "BACKUP"
 	CreateIndexTag         = "CREATE INDEX"
 	CreateFunctionTag      = "CREATE FUNCTION"
 	CreateProcedureTag     = "CREATE PROCEDURE"
+	CreateTriggerTag       = "CREATE TRIGGER"
 	CreateSchemaTag        = "CREATE SCHEMA"
 	CreateSequenceTag      = "CREATE SEQUENCE"
+	CreateDatabaseTag      = "CREATE DATABASE"
+	CreatePolicyTag        = "CREATE POLICY"
 	CommentOnColumnTag     = "COMMENT ON COLUMN"
 	CommentOnConstraintTag = "COMMENT ON CONSTRAINT"
 	CommentOnDatabaseTag   = "COMMENT ON DATABASE"
 	CommentOnIndexTag      = "COMMENT ON INDEX"
 	CommentOnSchemaTag     = "COMMENT ON SCHEMA"
 	CommentOnTableTag      = "COMMENT ON TABLE"
+	CommentOnTypeTag       = "COMMENT ON TYPE"
 	DropDatabaseTag        = "DROP DATABASE"
 	DropFunctionTag        = "DROP FUNCTION"
+	DropPolicyTag          = "DROP POLICY"
 	DropProcedureTag       = "DROP PROCEDURE"
+	DropTriggerTag         = "DROP TRIGGER"
 	DropIndexTag           = "DROP INDEX"
 	DropOwnedByTag         = "DROP OWNED BY"
 	DropSchemaTag          = "DROP SCHEMA"
@@ -115,6 +117,7 @@ const (
 	DropViewTag            = "DROP VIEW"
 	ImportTag              = "IMPORT"
 	RestoreTag             = "RESTORE"
+	ConfigureZoneTag       = "CONFIGURE ZONE"
 )
 
 // Statements represent a list of statements.
@@ -148,6 +151,10 @@ type canModifySchema interface {
 // CanModifySchema returns true if the statement can modify
 // the database schema.
 func CanModifySchema(stmt Statement) bool {
+	if stmt == nil {
+		// Some drivers send empty queries to test the connection.
+		return false
+	}
 	if stmt.StatementReturnType() == DDL || stmt.StatementType() == TypeDDL {
 		return true
 	}
@@ -175,7 +182,7 @@ func CanWriteData(stmt Statement) bool {
 	case *Split, *Unsplit, *Relocate, *RelocateRange, *Scatter:
 		return true
 	// Replication operations.
-	case *CreateTenantFromReplication, *AlterTenantReplication:
+	case *CreateTenantFromReplication, *AlterTenantReplication, *CreateLogicalReplicationStream:
 		return true
 	}
 	return false
@@ -183,7 +190,6 @@ func CanWriteData(stmt Statement) bool {
 
 // ReturnsAtMostOneRow returns true if the statement returns either no rows or
 // a single row.
-// TODO(harding): Expand this list.
 func ReturnsAtMostOneRow(stmt Statement) bool {
 	switch stmt.(type) {
 	// Import operations.
@@ -203,6 +209,18 @@ func ReturnsAtMostOneRow(stmt Statement) bool {
 
 }
 
+// UnwrapExplain returns the inner statement if the outer statement is an EXPLAIN
+// or EXPLAIN ANALYZE statement. Otherwise, it just returns the original statemnt.
+func UnwrapExplain(stmt Statement) Statement {
+	switch t := stmt.(type) {
+	case *Explain:
+		return t.Statement
+	case *ExplainAnalyze:
+		return t.Statement
+	}
+	return stmt
+}
+
 // HiddenFromShowQueries is a pseudo-interface to be implemented
 // by statements that should not show up in SHOW QUERIES (and are hence
 // not cancellable using CANCEL QUERIES either). Usually implemented by
@@ -245,6 +263,7 @@ var _ CCLOnlyStatement = &Import{}
 var _ CCLOnlyStatement = &Export{}
 var _ CCLOnlyStatement = &ScheduledBackup{}
 var _ CCLOnlyStatement = &CreateTenantFromReplication{}
+var _ CCLOnlyStatement = &CreateLogicalReplicationStream{}
 
 // StatementReturnType implements the Statement interface.
 func (*AlterChangefeed) StatementReturnType() StatementReturnType { return Rows }
@@ -439,6 +458,20 @@ func (*AlterIndexVisible) StatementTag() string { return "ALTER INDEX" }
 
 func (*AlterIndexVisible) hiddenFromShowQueries() {}
 
+// StatementReturnType implements the Statement interface.
+func (*AlterPolicy) StatementReturnType() StatementReturnType { return DDL }
+
+// StatementType implements the Statement interface.
+func (*AlterPolicy) StatementType() StatementType { return TypeDDL }
+
+// StatementTag returns a short string identifying the type of statement.
+func (*AlterPolicy) StatementTag() string { return AlterPolicyTag }
+
+func (*AlterPolicy) hiddenFromShowQueries() {}
+
+// modifiesSchema implements the canModifySchema interface.
+func (*AlterPolicy) modifiesSchema() bool { return true }
+
 // StatementReturnType implements the Statement interface.
 func (*AlterTable) StatementReturnType() StatementReturnType { return DDL }
 
@@ -544,6 +577,17 @@ func (*AlterTenantRename) StatementType() StatementType { return TypeDCL }
 // StatementTag returns a short string identifying the type of statement.
 func (*AlterTenantRename) StatementTag() string { return "ALTER VIRTUAL CLUSTER RENAME" }
 
+// StatementReturnType implements the Statement interface.
+func (*AlterTenantReset) StatementReturnType() StatementReturnType { return Ack }
+
+// StatementType implements the Statement interface.
+func (*AlterTenantReset) StatementType() StatementType { return TypeDCL }
+
+// StatementTag returns a short string identifying the type of statement.
+func (*AlterTenantReset) StatementTag() string { return "ALTER VIRTUAL CLUSTER RESET" }
+
+func (*AlterTenantReset) cclOnlyStatement() {}
+
 // StatementReturnType implements the Statement interface.
 func (*AlterTenantService) StatementReturnType() StatementReturnType { return Ack }
 
@@ -653,7 +697,7 @@ func (*BeginTransaction) StatementType() StatementType { return TypeTCL }
 func (*BeginTransaction) StatementTag() string { return "BEGIN" }
 
 // StatementReturnType implements the Statement interface.
-func (*Call) StatementReturnType() StatementReturnType { return Ack }
+func (*Call) StatementReturnType() StatementReturnType { return Rows }
 
 // StatementType implements the Statement interface.
 func (*Call) StatementType() StatementType { return TypeTCL }
@@ -672,6 +716,15 @@ func (n *ControlJobs) StatementTag() string {
 	return fmt.Sprintf("%s JOBS", JobCommandToStatement[n.Command])
 }
 
+// StatementReturnType implements the Statement interface.
+func (*AlterJobOwner) StatementReturnType() StatementReturnType { return DDL }
+
+// StatementType implements the Statement interface.
+func (*AlterJobOwner) StatementType() StatementType { return TypeDDL }
+
+// StatementTag returns a short string identifying the type of statement.
+func (*AlterJobOwner) StatementTag() string { return "ALTER JOB OWNER" }
+
 // StatementReturnType implements the Statement interface.
 func (*ControlSchedules) StatementReturnType() StatementReturnType { return RowsAffected }
 
@@ -736,7 +789,7 @@ func (*CannedOptPlan) StatementTag() string { return "PREPARE AS OPT PLAN" }
 func (*CloseCursor) StatementReturnType() StatementReturnType { return Ack }
 
 // StatementType implements the Statement interface.
-func (*CloseCursor) StatementType() StatementType { return TypeDCL }
+func (*CloseCursor) StatementType() StatementType { return TypeDML }
 
 // StatementTag returns a short string identifying the type of statement.
 func (*CloseCursor) StatementTag() string { return "CLOSE" }
@@ -795,6 +848,24 @@ func (*CommentOnTable) StatementType() StatementType { return TypeDDL }
 // StatementTag returns a short string identifying the type of statement.
 func (*CommentOnTable) StatementTag() string { return CommentOnTableTag }
 
+// StatementReturnType implements the Statement interface.
+func (*CommentOnType) StatementReturnType() StatementReturnType { return DDL }
+
+// StatementType implements the Statement interface.
+func (*CommentOnType) StatementType() StatementType { return TypeDDL }
+
+// StatementTag returns a short string identifying the type of statement.
+func (*CommentOnType) StatementTag() string { return CommentOnTypeTag }
+
+// StatementReturnType implements the Statement interface.
+func (*CommitPrepared) StatementReturnType() StatementReturnType { return Ack }
+
+// StatementType implements the Statement interface.
+func (*CommitPrepared) StatementType() StatementType { return TypeTCL }
+
+// StatementTag returns a short string identifying the type of statement.
+func (*CommitPrepared) StatementTag() string { return "COMMIT PREPARED" }
+
 // StatementReturnType implements the Statement interface.
 func (*CommitTransaction) StatementReturnType() StatementReturnType { return Ack }
 
@@ -878,6 +949,15 @@ func (*CreateExternalConnection) StatementType() StatementType { return TypeDDL
 // StatementTag returns a short string identifying the type of statement.
 func (*CreateExternalConnection) StatementTag() string { return "CREATE EXTERNAL CONNECTION" }
 
+// StatementReturnType implements the Statement interface.
+func (*CheckExternalConnection) StatementReturnType() StatementReturnType { return Rows }
+
+// StatementType implements the Statement interface.
+func (*CheckExternalConnection) StatementType() StatementType { return TypeDML }
+
+// StatementTag returns a short string identifying the type of statement.
+func (*CheckExternalConnection) StatementTag() string { return "CHECK EXTERNAL CONNECTION" }
+
 // StatementReturnType implements the Statement interface.
 func (*CreateTenant) StatementReturnType() StatementReturnType { return Ack }
 
@@ -900,6 +980,28 @@ func (*CreateTenantFromReplication) StatementTag() string {
 
 func (*CreateTenantFromReplication) cclOnlyStatement() {}
 
+// StatementReturnType implements the Statement interface.
+func (*CreateLogicalReplicationStream) StatementReturnType() StatementReturnType { return Rows }
+
+// StatementType implements the Statement interface.
+func (*CreateLogicalReplicationStream) StatementType() StatementType { return TypeDML }
+
+// StatementTag returns a short string identifying the type of statement.
+func (*CreateLogicalReplicationStream) StatementTag() string {
+	return "CREATE LOGICAL REPLICATION STREAM"
+}
+
+func (*CreateLogicalReplicationStream) cclOnlyStatement() {}
+
+// StatementReturnType implements the Statement interface.
+func (*DoBlock) StatementReturnType() StatementReturnType { return Ack }
+
+// StatementType implements the Statement interface.
+func (*DoBlock) StatementType() StatementType { return TypeDML }
+
+// StatementTag returns a short string identifying the type of statement.
+func (*DoBlock) StatementTag() string { return "DO" }
+
 // StatementReturnType implements the Statement interface.
 func (*DropExternalConnection) StatementReturnType() StatementReturnType { return Ack }
 
@@ -918,6 +1020,20 @@ func (*CreateIndex) StatementType() StatementType { return TypeDDL }
 // StatementTag returns a short string identifying the type of statement.
 func (*CreateIndex) StatementTag() string { return CreateIndexTag }
 
+// StatementReturnType implements the Statement interface.
+func (*CreatePolicy) StatementReturnType() StatementReturnType { return DDL }
+
+// StatementType implements the Statement interface.
+func (*CreatePolicy) StatementType() StatementType { return TypeDDL }
+
+// StatementTag returns a short string identifying the type of statement.
+func (*CreatePolicy) StatementTag() string { return CreatePolicyTag }
+
+func (*CreatePolicy) hiddenFromShowQueries() {}
+
+// modifiesSchema implements the canModifySchema interface.
+func (*CreatePolicy) modifiesSchema() bool { return true }
+
 // StatementReturnType implements the Statement interface.
 func (n *CreateSchema) StatementReturnType() StatementReturnType { return DDL }
 
@@ -1028,6 +1144,9 @@ func (d *Discard) StatementTag() string {
 	return "DISCARD"
 }
 
+// modifiesSchema implements the canModifySchema interface.
+func (*Discard) modifiesSchema() bool { return true }
+
 // StatementReturnType implements the Statement interface.
 func (n *DeclareCursor) StatementReturnType() StatementReturnType { return Ack }
 
@@ -1064,6 +1183,20 @@ func (*DropIndex) StatementType() StatementType { return TypeDDL }
 // StatementTag returns a short string identifying the type of statement.
 func (*DropIndex) StatementTag() string { return DropIndexTag }
 
+// StatementReturnType implements the Statement interface.
+func (*DropPolicy) StatementReturnType() StatementReturnType { return DDL }
+
+// StatementType implements the Statement interface.
+func (*DropPolicy) StatementType() StatementType { return TypeDDL }
+
+// StatementTag returns a short string identifying the type of statement.
+func (*DropPolicy) StatementTag() string { return DropPolicyTag }
+
+func (*DropPolicy) hiddenFromShowQueries() {}
+
+// modifiesSchema implements the canModifySchema interface.
+func (*DropPolicy) modifiesSchema() bool { return true }
+
 // StatementReturnType implements the Statement interface.
 func (*DropTable) StatementReturnType() StatementReturnType { return DDL }
 
@@ -1250,6 +1383,15 @@ func (*Prepare) StatementType() StatementType { return TypeTCL }
 // StatementTag returns a short string identifying the type of statement.
 func (*Prepare) StatementTag() string { return "PREPARE" }
 
+// StatementReturnType implements the Statement interface.
+func (*PrepareTransaction) StatementReturnType() StatementReturnType { return Ack }
+
+// StatementType implements the Statement interface.
+func (*PrepareTransaction) StatementType() StatementType { return TypeTCL }
+
+// StatementTag returns a short string identifying the type of statement.
+func (*PrepareTransaction) StatementTag() string { return "PREPARE TRANSACTION" }
+
 // StatementReturnType implements the Statement interface.
 func (*ReassignOwnedBy) StatementReturnType() StatementReturnType { return DDL }
 
@@ -1398,6 +1540,15 @@ func (*RevokeRole) StatementType() StatementType { return TypeDCL }
 // StatementTag returns a short string identifying the type of statement.
 func (*RevokeRole) StatementTag() string { return "REVOKE" }
 
+// StatementReturnType implements the Statement interface.
+func (*RollbackPrepared) StatementReturnType() StatementReturnType { return Ack }
+
+// StatementType implements the Statement interface.
+func (*RollbackPrepared) StatementType() StatementType { return TypeTCL }
+
+// StatementTag returns a short string identifying the type of statement.
+func (*RollbackPrepared) StatementTag() string { return "ROLLBACK PREPARED" }
+
 // StatementReturnType implements the Statement interface.
 func (*RollbackToSavepoint) StatementReturnType() StatementReturnType { return Ack }
 
@@ -1714,6 +1865,15 @@ func (*ShowPartitions) StatementType() StatementType { return TypeDML }
 // StatementTag returns a short string identifying the type of the statement.
 func (*ShowPartitions) StatementTag() string { return "SHOW PARTITIONS" }
 
+// StatementReturnType implements the Statement interface.
+func (*ShowPolicies) StatementReturnType() StatementReturnType { return Rows }
+
+// StatementType implements the Statement interface.
+func (*ShowPolicies) StatementType() StatementType { return TypeDML }
+
+// StatementTag returns a short string identifying the type of the statement.
+func (*ShowPolicies) StatementTag() string { return "SHOW POLICIES" }
+
 // StatementReturnType implements the Statement interface.
 func (*ShowQueries) StatementReturnType() StatementReturnType { return Rows }
 
@@ -1850,6 +2010,17 @@ func (*ShowUsers) StatementType() StatementType { return TypeDML }
 // StatementTag returns a short string identifying the type of statement.
 func (*ShowUsers) StatementTag() string { return "SHOW USERS" }
 
+// StatementReturnType implements the Statement interface.
+func (*ShowDefaultSessionVariablesForRole) StatementReturnType() StatementReturnType { return Rows }
+
+// StatementType implements the Statement interface.
+func (*ShowDefaultSessionVariablesForRole) StatementType() StatementType { return TypeDML }
+
+// StatementTag returns a short string identifying the type of statement.
+func (*ShowDefaultSessionVariablesForRole) StatementTag() string {
+	return "SHOW DEFAULT SESSION VARIABLES FOR ROLE"
+}
+
 // StatementReturnType implements the Statement interface.
 func (*ShowFullTableScans) StatementReturnType() StatementReturnType { return Rows }
 
@@ -1931,6 +2102,14 @@ func (*ShowConstraints) StatementType() StatementType { return TypeDML }
 // StatementTag returns a short string identifying the type of statement.
 func (*ShowConstraints) StatementTag() string { return "SHOW CONSTRAINTS" }
 
+func (*ShowLogicalReplicationJobs) StatementReturnType() StatementReturnType { return Rows }
+
+func (*ShowLogicalReplicationJobs) StatementType() StatementType { return TypeDML }
+
+func (*ShowLogicalReplicationJobs) StatementTag() string {
+	return "SHOW LOGICAL REPLICATION JOBS"
+}
+
 // StatementReturnType implements the Statement interface.
 func (*ShowTables) StatementReturnType() StatementReturnType { return Rows }
 
@@ -2038,6 +2217,17 @@ func (*ShowCreateExternalConnections) StatementTag() string {
 	return "SHOW CREATE EXTERNAL CONNECTIONS"
 }
 
+// StatementReturnType implements the Statement interface.
+func (*ShowExternalConnections) StatementReturnType() StatementReturnType { return Rows }
+
+// StatementType implements the Statement interface.
+func (*ShowExternalConnections) StatementType() StatementType { return TypeDML }
+
+// StatementTag returns a short string identifying the type of statement.
+func (*ShowExternalConnections) StatementTag() string {
+	return "SHOW EXTERNAL CONNECTIONS"
+}
+
 // StatementReturnType implements the Statement interface.
 func (*ShowCommitTimestamp) StatementReturnType() StatementReturnType { return Rows }
 
@@ -2049,6 +2239,26 @@ func (*ShowCommitTimestamp) StatementTag() string {
 	return "SHOW COMMIT TIMESTAMP"
 }
 
+// StatementReturnType implements the Statement interface.
+func (*ShowTriggers) StatementReturnType() StatementReturnType { return Rows }
+
+// StatementType implements the Statement interface.
+func (*ShowTriggers) StatementType() StatementType { return TypeDML }
+
+// StatementTag returns a short string identifying the type of statement.
+func (*ShowTriggers) StatementTag() string { return "SHOW TRIGGERS" }
+
+// StatementReturnType implements the Statement interface.
+func (*ShowCreateTrigger) StatementReturnType() StatementReturnType { return Rows }
+
+// StatementType implements the Statement interface.
+func (*ShowCreateTrigger) StatementType() StatementType { return TypeDML }
+
+// StatementTag returns a short string identifying the type of statement.
+func (n *ShowCreateTrigger) StatementTag() string {
+	return "SHOW CREATE TRIGGER"
+}
+
 // StatementReturnType implements the Statement interface.
 func (*Split) StatementReturnType() StatementReturnType { return Rows }
 
@@ -2152,6 +2362,28 @@ func (n *DropRoutine) StatementTag() string {
 	return DropFunctionTag
 }
 
+// StatementReturnType implements the Statement interface.
+func (*CreateTrigger) StatementReturnType() StatementReturnType { return DDL }
+
+// StatementType implements the Statement interface.
+func (*CreateTrigger) StatementType() StatementType { return TypeDDL }
+
+// StatementTag returns a short string identifying the type of statement.
+func (n *CreateTrigger) StatementTag() string {
+	return CreateTriggerTag
+}
+
+// StatementReturnType implements the Statement interface.
+func (*DropTrigger) StatementReturnType() StatementReturnType { return DDL }
+
+// StatementType implements the Statement interface.
+func (*DropTrigger) StatementType() StatementType { return TypeDDL }
+
+// StatementTag returns a short string identifying the type of statement.
+func (n *DropTrigger) StatementTag() string {
+	return DropTriggerTag
+}
+
 // StatementReturnType implements the Statement interface.
 func (*AlterFunctionOptions) StatementReturnType() StatementReturnType { return DDL }
 
@@ -2222,6 +2454,7 @@ func (n *AlterBackupSchedule) String() string                 { return AsString(
 func (n *AlterBackupScheduleCmds) String() string             { return AsString(n) }
 func (n *AlterIndex) String() string                          { return AsString(n) }
 func (n *AlterIndexVisible) String() string                   { return AsString(n) }
+func (n *AlterJobOwner) String() string                       { return AsString(n) }
 func (n *AlterDatabaseOwner) String() string                  { return AsString(n) }
 func (n *AlterDatabaseAddRegion) String() string              { return AsString(n) }
 func (n *AlterDatabaseDropRegion) String() string             { return AsString(n) }
@@ -2236,6 +2469,7 @@ func (n *AlterDatabaseDropSecondaryRegion) String() string    { return AsString(
 func (n *AlterDatabaseSetZoneConfigExtension) String() string { return AsString(n) }
 func (n *AlterDefaultPrivileges) String() string              { return AsString(n) }
 func (n *AlterFunctionOptions) String() string                { return AsString(n) }
+func (n *AlterPolicy) String() string                         { return AsString(n) }
 func (n *AlterRoutineRename) String() string                  { return AsString(n) }
 func (n *AlterRoutineSetSchema) String() string               { return AsString(n) }
 func (n *AlterRoutineSetOwner) String() string                { return AsString(n) }
@@ -2250,6 +2484,8 @@ func (n *AlterTableDropColumn) String() string                { return AsString(
 func (n *AlterTableDropConstraint) String() string            { return AsString(n) }
 func (n *AlterTableDropNotNull) String() string               { return AsString(n) }
 func (n *AlterTableDropStored) String() string                { return AsString(n) }
+func (n *AlterTableAddIdentity) String() string               { return AsString(n) }
+func (n *AlterTableIdentity) String() string                  { return AsString(n) }
 func (n *AlterTableLocality) String() string                  { return AsString(n) }
 func (n *AlterTableSetDefault) String() string                { return AsString(n) }
 func (n *AlterTableSetVisible) String() string                { return AsString(n) }
@@ -2258,6 +2494,7 @@ func (n *AlterTableOwner) String() string                     { return AsString(
 func (n *AlterTableSetSchema) String() string                 { return AsString(n) }
 func (n *AlterTenantCapability) String() string               { return AsString(n) }
 func (n *AlterTenantSetClusterSetting) String() string        { return AsString(n) }
+func (n *AlterTenantReset) String() string                    { return AsString(n) }
 func (n *AlterTenantRename) String() string                   { return AsString(n) }
 func (n *AlterTenantReplication) String() string              { return AsString(n) }
 func (n *AlterTenantService) String() string                  { return AsString(n) }
@@ -2283,6 +2520,8 @@ func (n *CommentOnDatabase) String() string                   { return AsString(
 func (n *CommentOnSchema) String() string                     { return AsString(n) }
 func (n *CommentOnIndex) String() string                      { return AsString(n) }
 func (n *CommentOnTable) String() string                      { return AsString(n) }
+func (n *CommentOnType) String() string                       { return AsString(n) }
+func (n *CommitPrepared) String() string                      { return AsString(n) }
 func (n *CommitTransaction) String() string                   { return AsString(n) }
 func (n *CopyFrom) String() string                            { return AsString(n) }
 func (n *CopyTo) String() string                              { return AsString(n) }
@@ -2290,7 +2529,10 @@ func (n *CreateChangefeed) String() string                    { return AsString(
 func (n *CreateDatabase) String() string                      { return AsString(n) }
 func (n *CreateExtension) String() string                     { return AsString(n) }
 func (n *CreateRoutine) String() string                       { return AsString(n) }
+func (n *CreateTrigger) String() string                       { return AsString(n) }
 func (n *CreateIndex) String() string                         { return AsString(n) }
+func (n *CreateLogicalReplicationStream) String() string      { return AsString(n) }
+func (n *CreatePolicy) String() string                        { return AsString(n) }
 func (n *CreateRole) String() string                          { return AsString(n) }
 func (n *CreateTable) String() string                         { return AsString(n) }
 func (n *CreateTenant) String() string                        { return AsString(n) }
@@ -2302,8 +2544,11 @@ func (n *CreateView) String() string                          { return AsString(
 func (n *Deallocate) String() string                          { return AsString(n) }
 func (n *Delete) String() string                              { return AsString(n) }
 func (n *DeclareCursor) String() string                       { return AsString(n) }
+func (n *DoBlock) String() string                             { return AsString(n) }
 func (n *DropDatabase) String() string                        { return AsString(n) }
+func (n *DropPolicy) String() string                          { return AsString(n) }
 func (n *DropRoutine) String() string                         { return AsString(n) }
+func (n *DropTrigger) String() string                         { return AsString(n) }
 func (n *DropIndex) String() string                           { return AsString(n) }
 func (n *DropOwnedBy) String() string                         { return AsString(n) }
 func (n *DropSchema) String() string                          { return AsString(n) }
@@ -2318,6 +2563,7 @@ func (n *Explain) String() string                             { return AsString(
 func (n *ExplainAnalyze) String() string                      { return AsString(n) }
 func (n *Export) String() string                              { return AsString(n) }
 func (n *CreateExternalConnection) String() string            { return AsString(n) }
+func (n *CheckExternalConnection) String() string             { return AsString(n) }
 func (n *DropExternalConnection) String() string              { return AsString(n) }
 func (n *FetchCursor) String() string                         { return AsString(n) }
 func (n *Grant) String() string                               { return AsString(n) }
@@ -2328,6 +2574,7 @@ func (n *Import) String() string                              { return AsString(
 func (n *LiteralValuesClause) String() string                 { return AsString(n) }
 func (n *ParenSelect) String() string                         { return AsString(n) }
 func (n *Prepare) String() string                             { return AsString(n) }
+func (n *PrepareTransaction) String() string                  { return AsString(n) }
 func (n *ReassignOwnedBy) String() string                     { return AsString(n) }
 func (n *ReleaseSavepoint) String() string                    { return AsString(n) }
 func (n *Relocate) String() string                            { return AsString(n) }
@@ -2342,6 +2589,7 @@ func (n *Restore) String() string                             { return AsString(
 func (n *RoutineReturn) String() string                       { return AsString(n) }
 func (n *Revoke) String() string                              { return AsString(n) }
 func (n *RevokeRole) String() string                          { return AsString(n) }
+func (n *RollbackPrepared) String() string                    { return AsString(n) }
 func (n *RollbackToSavepoint) String() string                 { return AsString(n) }
 func (n *RollbackTransaction) String() string                 { return AsString(n) }
 func (n *Savepoint) String() string                           { return AsString(n) }
@@ -2375,6 +2623,7 @@ func (n *ShowEnums) String() string                           { return AsString(
 func (n *ShowFullTableScans) String() string                  { return AsString(n) }
 func (n *ShowCreateRoutine) String() string                   { return AsString(n) }
 func (n *ShowCreateExternalConnections) String() string       { return AsString(n) }
+func (n *ShowExternalConnections) String() string             { return AsString(n) }
 func (n *ShowRoutines) String() string                        { return AsString(n) }
 func (n *ShowGrants) String() string                          { return AsString(n) }
 func (n *ShowHistogram) String() string                       { return AsString(n) }
@@ -2384,6 +2633,7 @@ func (n *ShowJobs) String() string                            { return AsString(
 func (n *ShowChangefeedJobs) String() string                  { return AsString(n) }
 func (n *ShowLastQueryStatistics) String() string             { return AsString(n) }
 func (n *ShowPartitions) String() string                      { return AsString(n) }
+func (n *ShowPolicies) String() string                        { return AsString(n) }
 func (n *ShowQueries) String() string                         { return AsString(n) }
 func (n *ShowRanges) String() string                          { return AsString(n) }
 func (n *ShowRangeForRow) String() string                     { return AsString(n) }
@@ -2405,12 +2655,16 @@ func (n *ShowTransactionStatus) String() string               { return AsString(
 func (n *ShowTransactions) String() string                    { return AsString(n) }
 func (n *ShowTransferState) String() string                   { return AsString(n) }
 func (n *ShowUsers) String() string                           { return AsString(n) }
+func (n *ShowDefaultSessionVariablesForRole) String() string  { return AsString(n) }
 func (n *ShowVar) String() string                             { return AsString(n) }
 func (n *ShowZoneConfig) String() string                      { return AsString(n) }
 func (n *ShowFingerprints) String() string                    { return AsString(n) }
 func (n *ShowDefaultPrivileges) String() string               { return AsString(n) }
 func (n *ShowCompletions) String() string                     { return AsString(n) }
 func (n *ShowCommitTimestamp) String() string                 { return AsString(n) }
+func (n *ShowLogicalReplicationJobs) String() string          { return AsString(n) }
+func (n *ShowTriggers) String() string                        { return AsString(n) }
+func (n *ShowCreateTrigger) String() string                   { return AsString(n) }
 func (n *Split) String() string                               { return AsString(n) }
 func (n *Truncate) String() string                            { return AsString(n) }
 func (n *TenantSpec) String() string                          { return AsString(n) }
diff --git a/pkg/sql/sem/tree/survival_goal.go b/pkg/sql/sem/tree/survival_goal.go
index b94bbf4..0212d03 100644
--- a/pkg/sql/sem/tree/survival_goal.go
+++ b/pkg/sql/sem/tree/survival_goal.go
@@ -1,12 +1,7 @@
 // Copyright 2020 The Cockroach Authors.
 //
-// Use of this software is governed by the Business Source License
-// included in the file licenses/BSL.txt.
-//
-// As of the Change Date specified in that file, in accordance with
-// the Business Source License, use of this software will be governed
-// by the Apache License, Version 2.0, included in the file
-// licenses/APL.txt.
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
 
 package tree
 
diff --git a/pkg/sql/sem/tree/table_name.go b/pkg/sql/sem/tree/table_name.go
index 2d60e59..2a32191 100644
--- a/pkg/sql/sem/tree/table_name.go
+++ b/pkg/sql/sem/tree/table_name.go
@@ -1,12 +1,7 @@
 // Copyright 2016 The Cockroach Authors.
 //
-// Use of this software is governed by the Business Source License
-// included in the file licenses/BSL.txt.
-//
-// As of the Change Date specified in that file, in accordance with
-// the Business Source License, use of this software will be governed
-// by the Apache License, Version 2.0, included in the file
-// licenses/APL.txt.
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
 
 package tree
 
diff --git a/pkg/sql/sem/tree/table_pattern.go b/pkg/sql/sem/tree/table_pattern.go
index a9bdfba..4ef3d13 100644
--- a/pkg/sql/sem/tree/table_pattern.go
+++ b/pkg/sql/sem/tree/table_pattern.go
@@ -1,12 +1,7 @@
 // Copyright 2016 The Cockroach Authors.
 //
-// Use of this software is governed by the Business Source License
-// included in the file licenses/BSL.txt.
-//
-// As of the Change Date specified in that file, in accordance with
-// the Business Source License, use of this software will be governed
-// by the Apache License, Version 2.0, included in the file
-// licenses/APL.txt.
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
 
 package tree
 
diff --git a/pkg/sql/sem/tree/table_ref.go b/pkg/sql/sem/tree/table_ref.go
index f008517..cc1ce9a 100644
--- a/pkg/sql/sem/tree/table_ref.go
+++ b/pkg/sql/sem/tree/table_ref.go
@@ -1,12 +1,7 @@
 // Copyright 2017 The Cockroach Authors.
 //
-// Use of this software is governed by the Business Source License
-// included in the file licenses/BSL.txt.
-//
-// As of the Change Date specified in that file, in accordance with
-// the Business Source License, use of this software will be governed
-// by the Apache License, Version 2.0, included in the file
-// licenses/APL.txt.
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
 
 package tree
 
diff --git a/pkg/sql/sem/tree/tenant.go b/pkg/sql/sem/tree/tenant.go
index 6957d5c..b1df6dc 100644
--- a/pkg/sql/sem/tree/tenant.go
+++ b/pkg/sql/sem/tree/tenant.go
@@ -1,12 +1,7 @@
 // Copyright 2022 The Cockroach Authors.
 //
-// Use of this software is governed by the Business Source License
-// included in the file licenses/BSL.txt.
-//
-// As of the Change Date specified in that file, in accordance with
-// the Business Source License, use of this software will be governed
-// by the Apache License, Version 2.0, included in the file
-// licenses/APL.txt.
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
 
 package tree
 
diff --git a/pkg/sql/sem/tree/tenant_settings.go b/pkg/sql/sem/tree/tenant_settings.go
index 988f5da..ab1643c 100644
--- a/pkg/sql/sem/tree/tenant_settings.go
+++ b/pkg/sql/sem/tree/tenant_settings.go
@@ -1,12 +1,7 @@
 // Copyright 2022 The Cockroach Authors.
 //
-// Use of this software is governed by the Business Source License
-// included in the file licenses/BSL.txt.
-//
-// As of the Change Date specified in that file, in accordance with
-// the Business Source License, use of this software will be governed
-// by the Apache License, Version 2.0, included in the file
-// licenses/APL.txt.
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
 
 package tree
 
diff --git a/pkg/sql/sem/tree/testutils.go b/pkg/sql/sem/tree/testutils.go
index 8c8c4d6..df5ce9a 100644
--- a/pkg/sql/sem/tree/testutils.go
+++ b/pkg/sql/sem/tree/testutils.go
@@ -1,12 +1,7 @@
 // Copyright 2017 The Cockroach Authors.
 //
-// Use of this software is governed by the Business Source License
-// included in the file licenses/BSL.txt.
-//
-// As of the Change Date specified in that file, in accordance with
-// the Business Source License, use of this software will be governed
-// by the Apache License, Version 2.0, included in the file
-// licenses/APL.txt.
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
 
 package tree
 
@@ -80,7 +75,7 @@ func SampleDatum(t *types.T) Datum {
 		j, _ := ParseDJSON(`{"a": "b"}`)
 		return j
 	case types.OidFamily:
-		return NewDOid(1009)
+		return NewDOidWithType(1009, t)
 	case types.PGLSNFamily:
 		return NewDPGLSN(0x1000000100)
 	case types.RefCursorFamily:
diff --git a/pkg/sql/sem/tree/time.go b/pkg/sql/sem/tree/time.go
index d47f4f7..3e64b14 100644
--- a/pkg/sql/sem/tree/time.go
+++ b/pkg/sql/sem/tree/time.go
@@ -1,12 +1,7 @@
 // Copyright 2019 The Cockroach Authors.
 //
-// Use of this software is governed by the Business Source License
-// included in the file licenses/BSL.txt.
-//
-// As of the Change Date specified in that file, in accordance with
-// the Business Source License, use of this software will be governed
-// by the Apache License, Version 2.0, included in the file
-// licenses/APL.txt.
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
 
 package tree
 
diff --git a/pkg/sql/sem/tree/treebin/binary_operator.go b/pkg/sql/sem/tree/treebin/binary_operator.go
index 332d495..dc7188b 100644
--- a/pkg/sql/sem/tree/treebin/binary_operator.go
+++ b/pkg/sql/sem/tree/treebin/binary_operator.go
@@ -1,12 +1,7 @@
 // Copyright 2022 The Cockroach Authors.
 //
-// Use of this software is governed by the Business Source License
-// included in the file licenses/BSL.txt.
-//
-// As of the Change Date specified in that file, in accordance with
-// the Business Source License, use of this software will be governed
-// by the Apache License, Version 2.0, included in the file
-// licenses/APL.txt.
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
 
 package treebin
 
@@ -61,6 +56,9 @@ const (
 	JSONFetchValPath
 	JSONFetchTextPath
 	TSMatch
+	Distance
+	CosDistance
+	NegInnerProduct
 
 	NumBinaryOperatorSymbols
 )
@@ -86,6 +84,9 @@ var binaryOpName = [...]string{
 	JSONFetchValPath:  "#>",
 	JSONFetchTextPath: "#>>",
 	TSMatch:           "@@",
+	Distance:          "<->",
+	CosDistance:       "<=>",
+	NegInnerProduct:   "<#>",
 }
 
 // IsPadded returns whether the binary operator needs to be padded.
diff --git a/pkg/sql/sem/tree/treebin/doc.go b/pkg/sql/sem/tree/treebin/doc.go
index 38bc7fc..953ee66 100644
--- a/pkg/sql/sem/tree/treebin/doc.go
+++ b/pkg/sql/sem/tree/treebin/doc.go
@@ -1,12 +1,7 @@
 // Copyright 2022 The Cockroach Authors.
 //
-// Use of this software is governed by the Business Source License
-// included in the file licenses/BSL.txt.
-//
-// As of the Change Date specified in that file, in accordance with
-// the Business Source License, use of this software will be governed
-// by the Apache License, Version 2.0, included in the file
-// licenses/APL.txt.
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
 
 // Package treebin contains the implementation-agnostic information about all
 // binary operators that we support.
diff --git a/pkg/sql/sem/tree/treecmp/comparison_operator.go b/pkg/sql/sem/tree/treecmp/comparison_operator.go
index 5b23931..8d8d627 100644
--- a/pkg/sql/sem/tree/treecmp/comparison_operator.go
+++ b/pkg/sql/sem/tree/treecmp/comparison_operator.go
@@ -1,12 +1,7 @@
 // Copyright 2022 The Cockroach Authors.
 //
-// Use of this software is governed by the Business Source License
-// included in the file licenses/BSL.txt.
-//
-// As of the Change Date specified in that file, in accordance with
-// the Business Source License, use of this software will be governed
-// by the Apache License, Version 2.0, included in the file
-// licenses/APL.txt.
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
 
 package treecmp
 
diff --git a/pkg/sql/sem/tree/treecmp/doc.go b/pkg/sql/sem/tree/treecmp/doc.go
index 449f2e1..c051344 100644
--- a/pkg/sql/sem/tree/treecmp/doc.go
+++ b/pkg/sql/sem/tree/treecmp/doc.go
@@ -1,12 +1,7 @@
 // Copyright 2022 The Cockroach Authors.
 //
-// Use of this software is governed by the Business Source License
-// included in the file licenses/BSL.txt.
-//
-// As of the Change Date specified in that file, in accordance with
-// the Business Source License, use of this software will be governed
-// by the Apache License, Version 2.0, included in the file
-// licenses/APL.txt.
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
 
 // Package treecmp contains the implementation-agnostic information about all
 // comparison operators that we support.
diff --git a/pkg/sql/sem/tree/treewindow/constants.go b/pkg/sql/sem/tree/treewindow/constants.go
index c2277c5..765bd65 100644
--- a/pkg/sql/sem/tree/treewindow/constants.go
+++ b/pkg/sql/sem/tree/treewindow/constants.go
@@ -1,12 +1,7 @@
 // Copyright 2022 The Cockroach Authors.
 //
-// Use of this software is governed by the Business Source License
-// included in the file licenses/BSL.txt.
-//
-// As of the Change Date specified in that file, in accordance with
-// the Business Source License, use of this software will be governed
-// by the Apache License, Version 2.0, included in the file
-// licenses/APL.txt.
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
 
 package treewindow
 
diff --git a/pkg/sql/sem/tree/treewindow/doc.go b/pkg/sql/sem/tree/treewindow/doc.go
index 1967bb2..c40370f 100644
--- a/pkg/sql/sem/tree/treewindow/doc.go
+++ b/pkg/sql/sem/tree/treewindow/doc.go
@@ -1,12 +1,7 @@
 // Copyright 2022 The Cockroach Authors.
 //
-// Use of this software is governed by the Business Source License
-// included in the file licenses/BSL.txt.
-//
-// As of the Change Date specified in that file, in accordance with
-// the Business Source License, use of this software will be governed
-// by the Apache License, Version 2.0, included in the file
-// licenses/APL.txt.
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
 
 // Package treewindow contains some constants describing window-function
 // specific options.
diff --git a/pkg/sql/sem/tree/truncate.go b/pkg/sql/sem/tree/truncate.go
index 267420f..f41129d 100644
--- a/pkg/sql/sem/tree/truncate.go
+++ b/pkg/sql/sem/tree/truncate.go
@@ -7,13 +7,8 @@
 //
 // Copyright 2015 The Cockroach Authors.
 //
-// Use of this software is governed by the Business Source License
-// included in the file licenses/BSL.txt.
-//
-// As of the Change Date specified in that file, in accordance with
-// the Business Source License, use of this software will be governed
-// by the Apache License, Version 2.0, included in the file
-// licenses/APL.txt.
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
 
 // This code was derived from https://github.com/youtube/vitess.
 
diff --git a/pkg/sql/sem/tree/txn.go b/pkg/sql/sem/tree/txn.go
index dfac5d8..1fcf2be 100644
--- a/pkg/sql/sem/tree/txn.go
+++ b/pkg/sql/sem/tree/txn.go
@@ -1,12 +1,7 @@
 // Copyright 2015 The Cockroach Authors.
 //
-// Use of this software is governed by the Business Source License
-// included in the file licenses/BSL.txt.
-//
-// As of the Change Date specified in that file, in accordance with
-// the Business Source License, use of this software will be governed
-// by the Apache License, Version 2.0, included in the file
-// licenses/APL.txt.
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
 
 package tree
 
@@ -64,22 +59,74 @@ func (i IsolationLevel) String() string {
 	return isolationLevelNames[i]
 }
 
-// IsolationLevelFromKVTxnIsolationLevel converts a kv level isolation.Level to
-// its SQL semantic equivalent.
-func IsolationLevelFromKVTxnIsolationLevel(level isolation.Level) IsolationLevel {
-	var ret IsolationLevel
+// ToKVIsoLevel converts an IsolationLevel to its isolation.Level equivalent.
+func (i IsolationLevel) ToKVIsoLevel() isolation.Level {
+	switch i {
+	case ReadUncommittedIsolation, ReadCommittedIsolation:
+		return isolation.ReadCommitted
+	case RepeatableReadIsolation, SnapshotIsolation:
+		return isolation.Snapshot
+	case SerializableIsolation:
+		return isolation.Serializable
+	default:
+		panic(fmt.Sprintf("unknown isolation level: %s", i))
+	}
+}
+
+// FromKVIsoLevel converts an isolation.Level to its SQL semantic equivalent.
+func FromKVIsoLevel(level isolation.Level) IsolationLevel {
 	switch level {
-	case isolation.Serializable:
-		ret = SerializableIsolation
 	case isolation.ReadCommitted:
-		ret = ReadCommittedIsolation
+		return ReadCommittedIsolation
 	case isolation.Snapshot:
-		ret = SnapshotIsolation
+		return RepeatableReadIsolation
+	case isolation.Serializable:
+		return SerializableIsolation
+	default:
+		panic(fmt.Sprintf("unknown isolation level: %s", level))
+	}
+}
+
+// UpgradeToEnabledLevel upgrades the isolation level to the weakest enabled
+// isolation level that is stronger than or equal to the input level.
+func (i IsolationLevel) UpgradeToEnabledLevel(
+	allowReadCommitted, allowRepeatableRead, hasLicense bool,
+) (_ IsolationLevel, upgraded, upgradedDueToLicense bool) {
+	switch i {
+	case ReadUncommittedIsolation:
+		// READ UNCOMMITTED is mapped to READ COMMITTED. PostgreSQL also does
+		// this: https://www.postgresql.org/docs/current/transaction-iso.html.
+		upgraded = true
+		fallthrough
+	case ReadCommittedIsolation:
+		// READ COMMITTED is only allowed if the cluster setting is enabled and the
+		// cluster has a license. Otherwise, it is mapped to a stronger isolation
+		// level (REPEATABLE READ if enabled, SERIALIZABLE otherwise).
+		if allowReadCommitted && hasLicense {
+			return ReadCommittedIsolation, upgraded, upgradedDueToLicense
+		}
+		upgraded = true
+		if allowReadCommitted && !hasLicense {
+			upgradedDueToLicense = true
+		}
+		fallthrough
+	case RepeatableReadIsolation, SnapshotIsolation:
+		// REPEATABLE READ and SNAPSHOT are considered aliases. The isolation levels
+		// are only allowed if the cluster setting is enabled and the cluster has a
+		// license. Otherwise, they are mapped to SERIALIZABLE.
+		if allowRepeatableRead && hasLicense {
+			return RepeatableReadIsolation, upgraded, upgradedDueToLicense
+		}
+		upgraded = true
+		if allowRepeatableRead && !hasLicense {
+			upgradedDueToLicense = true
+		}
+		fallthrough
+	case SerializableIsolation:
+		return SerializableIsolation, upgraded, upgradedDueToLicense
 	default:
-		panic("What to do here? Log is a banned import")
-		// log.Fatalf(context.Background(), "unknown isolation level: %s", level)
+		panic(fmt.Sprintf("unknown isolation level: %s", i))
 	}
-	return ret
 }
 
 // UserPriority holds the user priority for a transaction.
@@ -323,3 +370,39 @@ func (node *RollbackToSavepoint) Format(ctx *FmtCtx) {
 	ctx.WriteString("ROLLBACK TRANSACTION TO SAVEPOINT ")
 	ctx.FormatNode(&node.Savepoint)
 }
+
+// PrepareTransaction represents a PREPARE TRANSACTION <transaction-id>
+// statement, used for the first phase of a two-phase commit.
+type PrepareTransaction struct {
+	Transaction *StrVal
+}
+
+// Format implements the NodeFormatter interface.
+func (node *PrepareTransaction) Format(ctx *FmtCtx) {
+	ctx.WriteString("PREPARE TRANSACTION ")
+	ctx.FormatNode(node.Transaction)
+}
+
+// CommitPrepared represents a COMMIT PREPARED <transaction-id> statement, used
+// for the second phase of a two-phase commit.
+type CommitPrepared struct {
+	Transaction *StrVal
+}
+
+// Format implements the NodeFormatter interface.
+func (node *CommitPrepared) Format(ctx *FmtCtx) {
+	ctx.WriteString("COMMIT PREPARED ")
+	ctx.FormatNode(node.Transaction)
+}
+
+// RollbackPrepared represents a ROLLBACK PREPARED <transaction-id> statement,
+// used for the second phase of a two-phase rollback.
+type RollbackPrepared struct {
+	Transaction *StrVal
+}
+
+// Format implements the NodeFormatter interface.
+func (node *RollbackPrepared) Format(ctx *FmtCtx) {
+	ctx.WriteString("ROLLBACK PREPARED ")
+	ctx.FormatNode(node.Transaction)
+}
diff --git a/pkg/sql/sem/tree/type_check.go b/pkg/sql/sem/tree/type_check.go
index e2d1a52..c8e545b 100644
--- a/pkg/sql/sem/tree/type_check.go
+++ b/pkg/sql/sem/tree/type_check.go
@@ -1,12 +1,7 @@
 // Copyright 2015 The Cockroach Authors.
 //
-// Use of this software is governed by the Business Source License
-// included in the file licenses/BSL.txt.
-//
-// As of the Change Date specified in that file, in accordance with
-// the Business Source License, use of this software will be governed
-// by the Apache License, Version 2.0, included in the file
-// licenses/APL.txt.
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
 
 package tree
 
@@ -21,6 +16,7 @@ import (
 	"github.com/cockroachdb/cockroachdb-parser/pkg/sql/sem/tree/treecmp"
 	"github.com/cockroachdb/cockroachdb-parser/pkg/sql/sem/volatility"
 	"github.com/cockroachdb/cockroachdb-parser/pkg/sql/types"
+	"github.com/cockroachdb/cockroachdb-parser/pkg/util/buildutil"
 	"github.com/cockroachdb/cockroachdb-parser/pkg/util/collatedstring"
 	"github.com/cockroachdb/cockroachdb-parser/pkg/util/duration"
 	"github.com/cockroachdb/cockroachdb-parser/pkg/util/errorutil/unimplemented"
@@ -79,6 +75,17 @@ type SemaContext struct {
 	// UnsupportedTypeChecker is used to determine whether a builtin data type is
 	// supported by the current cluster version. It may be unset.
 	UnsupportedTypeChecker UnsupportedTypeChecker
+
+	// UsePre_25_2VariadicBuiltins is set to true when we should use the pre-25.2
+	// variadic builtins behavior.
+	UsePre_25_2VariadicBuiltins bool
+
+	// TestingKnobs only has effect under buildutil.CrdbTestBuild.
+	TestingKnobs struct {
+		// DisallowAlwaysNullShortCut, if set, disables short-circuiting logic
+		// for "always NULL" case during type checking.
+		DisallowAlwaysNullShortCut bool
+	}
 }
 
 // SemaProperties is a holder for required and derived properties
@@ -97,6 +104,16 @@ type SemaProperties struct {
 	// Ancestors is mutated during semantic analysis to provide contextual
 	// information for each descendent during traversal of sub-expressions.
 	Ancestors ScalarAncestors
+
+	// IgnoreUnpreferredOverloads is set to true when "unpreferred" overloads
+	// should not be used during type-checking and overload resolution.
+	IgnoreUnpreferredOverloads bool
+
+	// RoutineUseResolvedType is set to true when type-checking for a routine
+	// should reuse the already resolved type, if any. This is used to handle
+	// "re-type-checking" that occurs for a RECORD-returning routine, for which
+	// the return type is not known until the routine body is built.
+	RoutineUseResolvedType bool
 }
 
 type semaRequirements struct {
@@ -120,14 +137,14 @@ func (s *SemaProperties) Require(context string, rejectFlags SemaRejectFlags) {
 	s.Ancestors.clear()
 }
 
-// Reject adds the given flags to the set of required constraints of s.
+// Reject adds all of the given flags to the set of required constraints of s.
 func (s *SemaProperties) Reject(rejectFlags SemaRejectFlags) {
 	s.required.rejectFlags |= rejectFlags
 }
 
-// IsSet checks if the given rejectFlag is set as a required property.
+// IsSet checks if all of the given rejectFlags are set as a required property.
 func (s *SemaProperties) IsSet(rejectFlags SemaRejectFlags) bool {
-	return s.required.rejectFlags&rejectFlags != 0
+	return s.required.rejectFlags&rejectFlags == rejectFlags
 }
 
 // Restore restores a copy of a SemaProperties. Use with:
@@ -136,6 +153,11 @@ func (s *SemaProperties) Restore(orig SemaProperties) {
 	*s = orig
 }
 
+// Context returns the required context string set by Require.
+func (s *SemaProperties) Context() string {
+	return s.required.context
+}
+
 // SemaRejectFlags contains flags to filter out certain kinds of
 // expressions.
 type SemaRejectFlags int
@@ -229,10 +251,6 @@ const (
 	// checking condition expressions CASE, COALESCE, and IF. Used to reject
 	// set-returning functions within conditional expressions.
 	ConditionalAncestor
-
-	// CallAncestor is added to ScalarAncestors while type checking children of
-	// a CALL statement. Used to print sensible error messages for procedures.
-	CallAncestor
 )
 
 // Push adds the given ancestor to s.
@@ -240,9 +258,9 @@ func (s *ScalarAncestors) Push(other ScalarAncestors) {
 	*s = *s | other
 }
 
-// Has returns true if s has the given ancestor.
+// Has returns true if s has all of the given ancestors.
 func (s ScalarAncestors) Has(other ScalarAncestors) bool {
-	return s&other != 0
+	return s&other == other
 }
 
 // PopTo returns s to the given set of ancestors. Use with:
@@ -257,13 +275,23 @@ func (s *ScalarAncestors) clear() {
 	*s = 0
 }
 
-// MakeSemaContext initializes a simple SemaContext suitable
-// for "lightweight" type checking such as the one performed for default
-// expressions.
+// MakeSemaContext initializes a simple SemaContext suitable for "lightweight"
+// type checking such as the one performed for default expressions.
+//
 // Note: if queries with placeholders are going to be used,
 // SemaContext.Placeholders.Init must be called separately.
-func MakeSemaContext() SemaContext {
-	return SemaContext{}
+//
+// resolver is optional and can implement any number of TypeReferenceResolver,
+// FunctionReferenceResolver, and QualifiedNameResolver interfaces.
+func MakeSemaContext(resolver interface{}) SemaContext {
+	typeResolver, _ := resolver.(TypeReferenceResolver)
+	functionResolver, _ := resolver.(FunctionReferenceResolver)
+	nameResolver, _ := resolver.(QualifiedNameResolver)
+	return SemaContext{
+		TypeResolver:     typeResolver,
+		FunctionResolver: functionResolver,
+		NameResolver:     nameResolver,
+	}
 }
 
 // isUnresolvedPlaceholder provides a nil-safe method to determine whether expr is an
@@ -326,14 +354,14 @@ func decorateTypeCheckError(err error, format string, a ...interface{}) error {
 // their inferred types in the provided context. The optional desired parameter can
 // be used to hint the desired type for the root of the resulting typed expression
 // tree. Like with Expr.TypeCheck, it is not valid to provide a nil desired
-// type. Instead, call it with the wildcard type types.Any if no specific type is
+// type. Instead, call it with the wildcard type types.AnyElement if no specific type is
 // desired.
 func TypeCheck(
 	ctx context.Context, expr Expr, semaCtx *SemaContext, desired *types.T,
 ) (TypedExpr, error) {
 	if desired == nil {
 		return nil, errors.AssertionFailedf(
-			"the desired type for tree.TypeCheck cannot be nil, use types.Any instead: %T", expr)
+			"the desired type for tree.TypeCheck cannot be nil, use types.AnyElement instead: %T", expr)
 	}
 
 	return expr.TypeCheck(ctx, semaCtx, desired)
@@ -413,7 +441,7 @@ func (expr *BinaryExpr) TypeCheck(
 	if len(s.overloadIdxs) != 1 {
 		var desStr string
 		if desired.Family() != types.AnyFamily {
-			desStr = fmt.Sprintf(" (desired <%s>)", desired)
+			desStr = fmt.Sprintf(" (returning <%s>)", desired)
 		}
 		sig := fmt.Sprintf("<%s> %s <%s>%s", leftReturn, expr.Operator, rightReturn, desStr)
 		if len(s.overloadIdxs) == 0 {
@@ -460,7 +488,7 @@ func (expr *CaseExpr) TypeCheck(
 			tmpExprs = append(tmpExprs, when.Cond)
 		}
 
-		typedSubExprs, _, err := typeCheckSameTypedExprs(ctx, semaCtx, types.Any, tmpExprs...)
+		typedSubExprs, _, err := typeCheckSameTypedExprs(ctx, semaCtx, types.AnyElement, tmpExprs...)
 		if err != nil {
 			return nil, decorateTypeCheckError(err, "incompatible condition type:")
 		}
@@ -538,7 +566,7 @@ func resolveCast(context string, castFrom, castTo *types.T, allowStable bool) er
 		// the same, and if there are casts resolvable across all of the elements
 		// pointwise. Casts to AnyTuple are always allowed since they are
 		// implemented as a no-op.
-		if castTo == types.AnyTuple {
+		if castTo.Identical(types.AnyTuple) {
 			return nil
 		}
 		fromTuple := castFrom.TupleContents()
@@ -604,10 +632,10 @@ func isArrayExpr(expr Expr) bool {
 func (expr *CastExpr) TypeCheck(
 	ctx context.Context, semaCtx *SemaContext, _ *types.T,
 ) (TypedExpr, error) {
-	// The desired type provided to a CastExpr is ignored. Instead, types.Any is
+	// The desired type provided to a CastExpr is ignored. Instead, types.AnyElement is
 	// passed to the child of the cast. There are a few exceptions, described
 	// below.
-	desired := types.Any
+	desired := types.AnyElement
 	exprType, err := ResolveType(ctx, expr.Type, semaCtx.GetTypeResolver())
 	if err != nil {
 		return nil, err
@@ -680,6 +708,11 @@ func (expr *CastExpr) TypeCheck(
 	if err != nil {
 		return nil, err
 	}
+	if exprType.Identical(types.Trigger) {
+		// Trigger is not allowed in casts. This happens after resolving the cast to
+		// ensure that we return an "invalid cast" error when postgres does.
+		return nil, CannotAcceptTriggerErr
+	}
 	expr.Expr = typedSubExpr
 	expr.Type = exprType
 	expr.typ = exprType
@@ -724,7 +757,7 @@ func (expr *IndirectionExpr) TypeCheck(
 			if t.Slice {
 				return nil, pgerror.Newf(pgcode.DatatypeMismatch, "jsonb subscript does not support slices")
 			}
-			beginExpr, err := t.Begin.TypeCheck(ctx, semaCtx, types.Any)
+			beginExpr, err := t.Begin.TypeCheck(ctx, semaCtx, types.AnyElement)
 			if err != nil {
 				return nil, err
 			}
@@ -760,6 +793,9 @@ func (expr *AnnotateTypeExpr) TypeCheck(
 	if err != nil {
 		return nil, err
 	}
+	if annotateType.Identical(types.Trigger) {
+		return nil, CannotAcceptTriggerErr
+	}
 	if err = CheckUnsupportedType(ctx, semaCtx, annotateType); err != nil {
 		return nil, err
 	}
@@ -796,18 +832,28 @@ func (expr *CollateExpr) TypeCheck(
 		return nil, pgerror.Wrapf(err, pgcode.InvalidParameterValue,
 			"invalid locale %s", expr.Locale)
 	}
-	t := subExpr.ResolvedType()
-	if types.IsStringType(t) {
-		expr.Expr = subExpr
-		expr.typ = types.MakeCollatedString(t, expr.Locale)
-		return expr, nil
-	} else if t.Family() == types.UnknownFamily {
-		expr.Expr = subExpr
-		expr.typ = types.MakeCollatedString(types.String, expr.Locale)
-		return expr, nil
+	// setType is a recursive helper function to handle type checking of COLLATE
+	// on arrays.
+	var setType func(t *types.T) (*CollateExpr, error)
+	setType = func(t *types.T) (*CollateExpr, error) {
+		if types.IsStringType(t) {
+			expr.Expr = subExpr
+			expr.typ = types.MakeCollatedString(t, expr.Locale)
+			return expr, nil
+		} else if t.Family() == types.ArrayFamily {
+			if e, err := setType(t.ArrayContents()); err == nil {
+				e.typ = types.MakeArray(e.typ)
+				return e, nil
+			}
+		} else if t.Family() == types.UnknownFamily {
+			expr.Expr = subExpr
+			expr.typ = types.MakeCollatedString(types.String, expr.Locale)
+			return expr, nil
+		}
+		return nil, pgerror.Newf(pgcode.DatatypeMismatch,
+			"incompatible type for COLLATE: %s", t)
 	}
-	return nil, pgerror.Newf(pgcode.DatatypeMismatch,
-		"incompatible type for COLLATE: %s", t)
+	return setType(subExpr.ResolvedType())
 }
 
 // NewTypeIsNotCompositeError generates an error suitable to report
@@ -851,7 +897,7 @@ func (expr *ColumnAccessExpr) TypeCheck(
 	// at least this label and the element type T for this label" from
 	// the sub-expression. Of course, our type system does not support
 	// this. So drop the type constraint instead.
-	subExpr, err := expr.Expr.TypeCheck(ctx, semaCtx, types.Any)
+	subExpr, err := expr.Expr.TypeCheck(ctx, semaCtx, types.AnyElement)
 	if err != nil {
 		return nil, err
 	}
@@ -931,6 +977,7 @@ func (expr *ComparisonExpr) TypeCheck(
 ) (TypedExpr, error) {
 	var leftTyped, rightTyped TypedExpr
 	var cmpOp *CmpOp
+	var cmpOpSym treecmp.ComparisonOperatorSymbol
 	var alwaysNull bool
 	var err error
 	if expr.Operator.Symbol.HasSubOperator() {
@@ -942,11 +989,7 @@ func (expr *ComparisonExpr) TypeCheck(
 			expr.Left,
 			expr.Right,
 		)
-		if err == nil {
-			err = checkRefCursorComparison(
-				expr.SubOperator.Symbol, leftTyped.ResolvedType(), rightTyped.ResolvedType(),
-			)
-		}
+		cmpOpSym = expr.SubOperator.Symbol
 	} else {
 		leftTyped, rightTyped, cmpOp, alwaysNull, err = typeCheckComparisonOp(
 			ctx,
@@ -955,11 +998,11 @@ func (expr *ComparisonExpr) TypeCheck(
 			expr.Left,
 			expr.Right,
 		)
-		if err == nil {
-			err = checkRefCursorComparison(
-				expr.Operator.Symbol, leftTyped.ResolvedType(), rightTyped.ResolvedType(),
-			)
-		}
+		cmpOpSym = expr.Operator.Symbol
+	}
+	if err == nil {
+		err = runValidations(cmpOpSym, leftTyped.ResolvedType(), rightTyped.ResolvedType(),
+			[]types.Family{types.RefCursorFamily, types.JsonpathFamily})
 	}
 	if err != nil {
 		return nil, err
@@ -1135,14 +1178,38 @@ func CheckIsWindowOrAgg(def *ResolvedFunctionDefinition) error {
 	return nil
 }
 
+func (expr *FuncExpr) typeCheckWithFuncAncestor(semaCtx *SemaContext, fn func() error) error {
+	if semaCtx != nil {
+		defer semaCtx.Properties.Restore(semaCtx.Properties)
+		// We'll need to remember we are in a function application to generate
+		// suitable errors in checkFunctionUsage().
+		semaCtx.Properties.Ancestors.Push(FuncExprAncestor)
+		if expr.WindowDef != nil {
+			semaCtx.Properties.Ancestors.Push(WindowFuncAncestor)
+		}
+		// Disallow procedures in function arguments.
+		semaCtx.Properties.Reject(RejectProcedures)
+	}
+	return fn()
+}
+
 // TypeCheck implements the Expr interface.
 func (expr *FuncExpr) TypeCheck(
 	ctx context.Context, semaCtx *SemaContext, desired *types.T,
 ) (TypedExpr, error) {
+	if semaCtx != nil && semaCtx.Properties.RoutineUseResolvedType &&
+		expr.typ != nil && !expr.typ.IsWildcardType() {
+		// Don't overwrite the resolved properties for a routine if the routine has
+		// already been resolved (and we are in a context that needs this behavior).
+		return expr, nil
+	}
+
 	searchPath := EmptySearchPath
 	var resolver FunctionReferenceResolver
 	if semaCtx != nil {
-		searchPath = semaCtx.SearchPath
+		if semaCtx.SearchPath != nil {
+			searchPath = semaCtx.SearchPath
+		}
 		resolver = semaCtx.FunctionResolver
 	}
 
@@ -1150,10 +1217,12 @@ func (expr *FuncExpr) TypeCheck(
 
 	def, err := expr.Func.Resolve(ctx, searchPath, resolver)
 	if err != nil {
-		if errors.Is(err, ErrRoutineUndefined) {
-			if procErr := procedureDoesNotExistErr(expr.Func.String(), semaCtx); procErr != nil {
-				return nil, procErr
-			}
+		if errors.Is(err, ErrRoutineUndefined) && expr.InCall {
+			return nil, errors.WithHint(
+				pgerror.Newf(pgcode.UndefinedFunction, "procedure %s does not exist", expr.Func),
+				"No procedure matches the given name and argument types. "+
+					"You might need to add explicit type casts.",
+			)
 		}
 		return nil, err
 	}
@@ -1163,17 +1232,17 @@ func (expr *FuncExpr) TypeCheck(
 			"%s()", def.Name)
 	}
 
-	if semaCtx != nil {
-		// We'll need to remember we are in a function application to generate
-		// suitable errors in checkFunctionUsage(). We cannot enter
-		// FuncExprAncestor earlier (in particular not before the call to
-		// checkFunctionUsage() above) because the top-level FuncExpr must be
-		// acceptable even if it is a SRF and RejectNestedGenerators is set.
-		defer semaCtx.Properties.Ancestors.PopTo(semaCtx.Properties.Ancestors)
-		semaCtx.Properties.Ancestors.Push(FuncExprAncestor)
-		if expr.WindowDef != nil {
-			semaCtx.Properties.Ancestors.Push(WindowFuncAncestor)
+	typeNames := func(typedExprs []TypedExpr) string {
+		var sb strings.Builder
+		sb.WriteByte('(')
+		for i := range typedExprs {
+			if i > 0 {
+				sb.WriteString(", ")
+			}
+			sb.WriteString(typedExprs[i].ResolvedType().Name())
 		}
+		sb.WriteByte(')')
+		return sb.String()
 	}
 
 	s := getOverloadTypeChecker(
@@ -1181,17 +1250,48 @@ func (expr *FuncExpr) TypeCheck(
 	)
 	defer s.release()
 
-	if err := func() error {
-		// Disallow procedures in function arguments.
-		if semaCtx != nil {
-			defer semaCtx.Properties.Restore(semaCtx.Properties)
-			semaCtx.Properties.Reject(RejectProcedures)
-		}
-		if err := s.typeCheckOverloadedExprs(ctx, semaCtx, desired, false); err != nil {
+	if err = expr.typeCheckWithFuncAncestor(semaCtx, func() error {
+		if err := s.typeCheckOverloadedExprs(ctx, semaCtx, desired, false /* inBinOp */); err != nil {
 			return pgerror.Wrapf(err, pgcode.InvalidParameterValue, "%s()", def.Name)
 		}
+		if expr.InCall && len(s.overloadIdxs) == 0 {
+			// Since we didn't find the overload, let's see whether the user
+			// made a mistake and attempted to call a UDF. We attempt this by
+			// temporarily adjusting the RoutineType of each UDF to be
+			// Procedure, then running type-checking on adjusted overloads, and
+			// resetting the UDF overloads to their original state.
+			var functionIdxs []int
+			var functionOverloads []QualifiedOverload
+			for idx, o := range def.Overloads {
+				if o.Type == UDFRoutine {
+					o.Type = ProcedureRoutine
+					functionIdxs = append(functionIdxs, idx)
+					functionOverloads = append(functionOverloads, o)
+				}
+			}
+			if len(functionIdxs) > 0 {
+				defer func() {
+					for _, idx := range functionIdxs {
+						def.Overloads[idx].Type = UDFRoutine
+					}
+				}()
+				s2 := getOverloadTypeChecker((*qualifiedOverloads)(&functionOverloads), expr.Exprs...)
+				defer s2.release()
+				err2 := s2.typeCheckOverloadedExprs(ctx, semaCtx, desired, false /* inBinOp */)
+				if err2 == nil && len(s2.overloadIdxs) > 0 {
+					// This time we found a match, so return the proper error.
+					return errors.WithHint(
+						pgerror.Newf(
+							pgcode.WrongObjectType,
+							"%s%s is not a procedure", def.Name, typeNames(s2.typedExprs),
+						),
+						"To call a function, use SELECT.",
+					)
+				}
+			}
+		}
 		return nil
-	}(); err != nil {
+	}); err != nil {
 		return nil, err
 	}
 
@@ -1249,6 +1349,21 @@ func (expr *FuncExpr) TypeCheck(
 		s.overloadIdxs = truncated
 	}
 
+	if len(s.overloadIdxs) == 0 {
+		if expr.InCall {
+			return nil, errors.WithHint(
+				pgerror.Newf(pgcode.UndefinedFunction, "procedure %s%s does not exist",
+					def.Name, typeNames(s.typedExprs)),
+				"No procedure matches the given name and argument types. "+
+					"You might need to add explicit type casts.",
+			)
+		}
+		return nil, errors.WithHint(
+			pgerror.Newf(pgcode.UndefinedFunction, "unknown signature: %s", getFuncSig(expr, s.typedExprs, desired)),
+			"No function matches the given name and argument types. You might need to add explicit type casts.",
+		)
+	}
+
 	// Return NULL if at least one overload is possible, no overload accepts
 	// NULL arguments, the function isn't a generator or aggregate builtin, and
 	// NULL is given as an argument. We do not perform this transformation
@@ -1257,7 +1372,7 @@ func (expr *FuncExpr) TypeCheck(
 	// type-checking.
 	if len(s.overloadIdxs) > 0 && calledOnNullInputFns.Len() == 0 && funcCls != GeneratorClass &&
 		funcCls != AggregateClass && !hasUDFOverload &&
-		semaCtx != nil && !semaCtx.Properties.Ancestors.Has(CallAncestor) {
+		semaCtx != nil && !expr.InCall {
 		for _, expr := range s.typedExprs {
 			if expr.ResolvedType().Family() == types.UnknownFamily {
 				return DNull, nil
@@ -1265,13 +1380,6 @@ func (expr *FuncExpr) TypeCheck(
 		}
 	}
 
-	if len(s.overloadIdxs) == 0 {
-		if procErr := procedureDoesNotExistErr(expr.Func.String(), semaCtx); procErr != nil {
-			return nil, procErr
-		}
-		return nil, pgerror.Newf(pgcode.UndefinedFunction, "unknown signature: %s", getFuncSig(expr, s.typedExprs, desired))
-	}
-
 	var favoredOverload QualifiedOverload
 	if functionResolvedByID {
 		// If the function is resolved by OID, we know that there is always only one
@@ -1302,13 +1410,17 @@ func (expr *FuncExpr) TypeCheck(
 		}
 	}
 
-	if overloadImpl.Type == BuiltinRoutine && (def.Name == "min" || def.Name == "max") {
-		// Special case: for REFCURSOR, we disallow min/max during type-checking
-		// despite having overloads for REFCURSOR. This maintains compatibility with
-		// postgres without having to add special checks in optimizer rules for
-		// REFCURSOR.
-		if len(s.typedExprs) > 0 && s.typedExprs[0].ResolvedType().Family() == types.RefCursorFamily {
-			return nil, pgerror.Newf(pgcode.UndefinedFunction, "function %s(refcursor) does not exist", def.Name)
+	// Some builtins are disabled in certain contexts for Postgres compatibility.
+	if overloadImpl.Type == BuiltinRoutine {
+		switch def.Name {
+		case "min", "max":
+			// Special case: for REFCURSOR, we disallow min/max during type-checking
+			// despite having overloads for REFCURSOR. This maintains compatibility
+			// with postgres without having to add special checks in optimizer rules
+			// for REFCURSOR.
+			if len(s.typedExprs) > 0 && s.typedExprs[0].ResolvedType().Family() == types.RefCursorFamily {
+				return nil, pgerror.Newf(pgcode.UndefinedFunction, "function %s(refcursor) does not exist", def.Name)
+			}
 		}
 	}
 
@@ -1335,7 +1447,7 @@ func (expr *FuncExpr) TypeCheck(
 		}
 	} else {
 		// Make sure the window function builtins are used as window function applications.
-		if funcCls == WindowClass {
+		if !expr.InCall && funcCls == WindowClass {
 			return nil, pgerror.Newf(pgcode.WrongObjectType,
 				"window function %s() requires an OVER clause", &expr.Func)
 		}
@@ -1349,20 +1461,30 @@ func (expr *FuncExpr) TypeCheck(
 				"FILTER specified but %s() is not an aggregate function", &expr.Func)
 		}
 
-		typedFilter, err := typeCheckAndRequireBoolean(ctx, semaCtx, expr.Filter, "FILTER expression")
-		if err != nil {
+		if err = expr.typeCheckWithFuncAncestor(semaCtx, func() error {
+			typedFilter, err := typeCheckAndRequireBoolean(ctx, semaCtx, expr.Filter, "FILTER expression")
+			if err != nil {
+				return err
+			}
+			expr.Filter = typedFilter
+			return nil
+		}); err != nil {
 			return nil, err
 		}
-		expr.Filter = typedFilter
 	}
 
 	if expr.OrderBy != nil {
-		for i := range expr.OrderBy {
-			typedExpr, err := expr.OrderBy[i].Expr.TypeCheck(ctx, semaCtx, types.Any)
-			if err != nil {
-				return nil, err
+		if err = expr.typeCheckWithFuncAncestor(semaCtx, func() error {
+			for i := range expr.OrderBy {
+				typedExpr, err := expr.OrderBy[i].Expr.TypeCheck(ctx, semaCtx, types.AnyElement)
+				if err != nil {
+					return err
+				}
+				expr.OrderBy[i].Expr = typedExpr
 			}
-			expr.OrderBy[i].Expr = typedExpr
+			return nil
+		}); err != nil {
+			return nil, err
 		}
 	}
 
@@ -1389,31 +1511,12 @@ func (expr *FuncExpr) TypeCheck(
 	if err := semaCtx.checkVolatility(overloadImpl.Volatility); err != nil {
 		return nil, pgerror.Wrapf(err, pgcode.InvalidParameterValue, "%s()", def.Name)
 	}
-	if overloadImpl.OnTypeCheck != nil && *overloadImpl.OnTypeCheck != nil {
-		(*overloadImpl.OnTypeCheck)()
+	if overloadImpl.OnTypeCheck != nil {
+		overloadImpl.OnTypeCheck()
 	}
 	return expr, nil
 }
 
-// procedureDoesNotExistErr returns a "procedure does not exist" error if the
-// current ancestors indicate that type checking is occuring at the top-level
-// child of a CALL statement.
-//
-// TODO(#111139): We'll need to reconsider how we determine that we're looking
-// for a procedure once we support calling procedures from within UDFs.
-func procedureDoesNotExistErr(fnName string, semaCtx *SemaContext) error {
-	if semaCtx != nil &&
-		semaCtx.Properties.Ancestors.Has(CallAncestor) &&
-		!semaCtx.Properties.Ancestors.Has(FuncExprAncestor) {
-		return errors.WithHint(
-			pgerror.Newf(pgcode.UndefinedFunction, "procedure %s does not exist", fnName),
-			"No procedure matches the given name and argument types. "+
-				"You might need to add explicit type casts.",
-		)
-	}
-	return nil
-}
-
 // TypeCheck implements the Expr interface.
 func (expr *IfErrExpr) TypeCheck(
 	ctx context.Context, semaCtx *SemaContext, desired *types.T,
@@ -1422,7 +1525,7 @@ func (expr *IfErrExpr) TypeCheck(
 	var retType *types.T
 	var err error
 	if expr.Else == nil {
-		typedCond, err = expr.Cond.TypeCheck(ctx, semaCtx, types.Any)
+		typedCond, err = expr.Cond.TypeCheck(ctx, semaCtx, types.AnyElement)
 		if err != nil {
 			return nil, err
 		}
@@ -1483,7 +1586,7 @@ func (expr *IfExpr) TypeCheck(
 func (expr *IsOfTypeExpr) TypeCheck(
 	ctx context.Context, semaCtx *SemaContext, desired *types.T,
 ) (TypedExpr, error) {
-	exprTyped, err := expr.Expr.TypeCheck(ctx, semaCtx, types.Any)
+	exprTyped, err := expr.Expr.TypeCheck(ctx, semaCtx, types.AnyElement)
 	if err != nil {
 		return nil, err
 	}
@@ -1518,7 +1621,7 @@ func (expr *NotExpr) TypeCheck(
 func (expr *IsNullExpr) TypeCheck(
 	ctx context.Context, semaCtx *SemaContext, desired *types.T,
 ) (TypedExpr, error) {
-	exprTyped, err := expr.Expr.TypeCheck(ctx, semaCtx, types.Any)
+	exprTyped, err := expr.Expr.TypeCheck(ctx, semaCtx, types.AnyElement)
 	if err != nil {
 		return nil, err
 	}
@@ -1531,7 +1634,7 @@ func (expr *IsNullExpr) TypeCheck(
 func (expr *IsNotNullExpr) TypeCheck(
 	ctx context.Context, semaCtx *SemaContext, desired *types.T,
 ) (TypedExpr, error) {
-	exprTyped, err := expr.Expr.TypeCheck(ctx, semaCtx, types.Any)
+	exprTyped, err := expr.Expr.TypeCheck(ctx, semaCtx, types.AnyElement)
 	if err != nil {
 		return nil, err
 	}
@@ -1558,7 +1661,7 @@ func (expr *NullIfExpr) TypeCheck(
 			leftType, op, rightType)
 		return nil, decorateTypeCheckError(err, "incompatible NULLIF expressions")
 	}
-	err = checkRefCursorComparison(treecmp.EQ, leftType, rightType)
+	err = checkComparison(treecmp.EQ, leftType, rightType, types.RefCursorFamily)
 	if err != nil {
 		return nil, err
 	}
@@ -1651,18 +1754,14 @@ func (expr *RangeCond) TypeCheck(
 ) (TypedExpr, error) {
 	leftFromTyped, fromTyped, _, _, err := typeCheckComparisonOp(ctx, semaCtx, treecmp.MakeComparisonOperator(treecmp.GT), expr.Left, expr.From)
 	if err == nil {
-		err = checkRefCursorComparison(
-			treecmp.GT, leftFromTyped.ResolvedType(), fromTyped.ResolvedType(),
-		)
+		err = checkComparison(treecmp.GT, leftFromTyped.ResolvedType(), fromTyped.ResolvedType(), types.RefCursorFamily)
 	}
 	if err != nil {
 		return nil, err
 	}
 	leftToTyped, toTyped, _, _, err := typeCheckComparisonOp(ctx, semaCtx, treecmp.MakeComparisonOperator(treecmp.LT), expr.Left, expr.To)
 	if err == nil {
-		err = checkRefCursorComparison(
-			treecmp.LT, leftToTyped.ResolvedType(), toTyped.ResolvedType(),
-		)
+		err = checkComparison(treecmp.LT, leftToTyped.ResolvedType(), toTyped.ResolvedType(), types.RefCursorFamily)
 	}
 	if err != nil {
 		return nil, err
@@ -1717,7 +1816,7 @@ func (expr *UnaryExpr) TypeCheck(
 	if numOps != 1 {
 		var desStr string
 		if desired.Family() != types.AnyFamily {
-			desStr = fmt.Sprintf(" (desired <%s>)", desired)
+			desStr = fmt.Sprintf(" (returning <%s>)", desired)
 		}
 		sig := fmt.Sprintf("%s <%s>%s", expr.Operator, exprReturn, desStr)
 		if numOps == 0 {
@@ -1797,7 +1896,7 @@ func (expr *Tuple) TypeCheck(
 	var labels []string
 	contents := make([]*types.T, len(expr.Exprs))
 	for i, subExpr := range expr.Exprs {
-		desiredElem := types.Any
+		desiredElem := types.AnyElement
 		if desired.Family() == types.TupleFamily && len(desired.TupleContents()) > i {
 			desiredElem = desired.TupleContents()[i]
 		}
@@ -1824,16 +1923,18 @@ var errAmbiguousArrayType = pgerror.Newf(pgcode.IndeterminateDatatype, "cannot d
 func (expr *Array) TypeCheck(
 	ctx context.Context, semaCtx *SemaContext, desired *types.T,
 ) (TypedExpr, error) {
-	desiredParam := types.Any
+	desiredParam := types.AnyElement
 	if desired.Family() == types.ArrayFamily {
 		desiredParam = desired.ArrayContents()
 	}
 
 	if len(expr.Exprs) == 0 {
-		if desiredParam.Family() == types.AnyFamily {
-			return nil, errAmbiguousArrayType
+		if expr.typ == nil || expr.typ.Family() != types.ArrayFamily {
+			if desiredParam.Family() == types.AnyFamily {
+				return nil, errAmbiguousArrayType
+			}
+			expr.typ = types.MakeArray(desiredParam)
 		}
-		expr.typ = types.MakeArray(desiredParam)
 		return expr, nil
 	}
 
@@ -1857,7 +1958,7 @@ func (expr *Array) TypeCheck(
 func (expr *ArrayFlatten) TypeCheck(
 	ctx context.Context, semaCtx *SemaContext, desired *types.T,
 ) (TypedExpr, error) {
-	desiredParam := types.Any
+	desiredParam := types.AnyElement
 	if desired.Family() == types.ArrayFamily {
 		desiredParam = desired.ArrayContents()
 	}
@@ -2054,6 +2155,12 @@ func (d *DPGLSN) TypeCheck(_ context.Context, _ *SemaContext, _ *types.T) (Typed
 	return d, nil
 }
 
+// TypeCheck implements the Expr interface. It is implemented as an idempotent
+// identity function for Datum.
+func (d *DPGVector) TypeCheck(_ context.Context, _ *SemaContext, _ *types.T) (TypedExpr, error) {
+	return d, nil
+}
+
 // TypeCheck implements the Expr interface. It is implemented as an idempotent
 // identity function for Datum.
 func (d *DGeography) TypeCheck(_ context.Context, _ *SemaContext, _ *types.T) (TypedExpr, error) {
@@ -2072,6 +2179,12 @@ func (d *DJSON) TypeCheck(_ context.Context, _ *SemaContext, _ *types.T) (TypedE
 	return d, nil
 }
 
+// TypeCheck implements the Expr interface. It is implemented as an idempotent
+// identity function for Datum.
+func (d *DJsonpath) TypeCheck(_ context.Context, _ *SemaContext, _ *types.T) (TypedExpr, error) {
+	return d, nil
+}
+
 // TypeCheck implements the Expr interface. It is implemented as an idempotent
 // identity function for Datum.
 func (d *DTSQuery) TypeCheck(_ context.Context, _ *SemaContext, _ *types.T) (TypedExpr, error) {
@@ -2106,7 +2219,8 @@ func (d *DArray) TypeCheck(_ context.Context, _ *SemaContext, desired *types.T)
 	// mark the array's type as the desired one.
 	// ARRAY[]
 	// ARRAY[NULL, NULL]
-	if (d.ParamTyp == types.Unknown || d.ParamTyp == types.Any) && (!d.HasNonNulls) {
+	if (d.ParamTyp.Family() == types.UnknownFamily || d.ParamTyp.Family() == types.AnyFamily) &&
+		(!d.HasNonNulls) {
 		if desired.Family() != types.ArrayFamily {
 			// We can't desire a non-array type here.
 			return d, nil
@@ -2243,7 +2357,7 @@ func typeCheckComparisonOpWithSubOperator(
 		sameTypeExprs[0] = left
 		copy(sameTypeExprs[1:], array.Exprs)
 
-		typedSubExprs, retType, err := typeCheckSameTypedExprs(ctx, semaCtx, types.Any, sameTypeExprs...)
+		typedSubExprs, retType, err := typeCheckSameTypedExprs(ctx, semaCtx, types.AnyElement, sameTypeExprs...)
 		if err != nil {
 			sigWithErr := fmt.Sprintf(compExprsWithSubOpFmt, left, subOp, op, right, err)
 			return nil, nil, nil, false,
@@ -2264,15 +2378,18 @@ func typeCheckComparisonOpWithSubOperator(
 		rightTyped = array
 		cmpTypeRight = retType
 
-		// Return early without looking up a CmpOp if the comparison type is types.Null.
-		if leftTyped.ResolvedType().Family() == types.UnknownFamily || retType.Family() == types.UnknownFamily {
-			return leftTyped, rightTyped, nil, true /* alwaysNull */, nil
+		// Return early without looking up a CmpOp if the comparison type is types.Null
+		// (unless the short-cut is disabled in tests).
+		if !buildutil.CrdbTestBuild || semaCtx == nil || !semaCtx.TestingKnobs.DisallowAlwaysNullShortCut {
+			if leftTyped.ResolvedType().Family() == types.UnknownFamily || retType.Family() == types.UnknownFamily {
+				return leftTyped, rightTyped, nil, true /* alwaysNull */, nil
+			}
 		}
 	} else {
 		// If the right expression is not an array constructor, we type the left
 		// expression in isolation.
 		var err error
-		leftTyped, err = left.TypeCheck(ctx, semaCtx, types.Any)
+		leftTyped, err = left.TypeCheck(ctx, semaCtx, types.AnyElement)
 		if err != nil {
 			return nil, nil, nil, false, err
 		}
@@ -2297,8 +2414,10 @@ func typeCheckComparisonOpWithSubOperator(
 		}
 
 		rightReturn := rightTyped.ResolvedType()
-		if rightReturn.Family() == types.UnknownFamily {
-			return leftTyped, rightTyped, nil, true /* alwaysNull */, nil
+		if !buildutil.CrdbTestBuild || semaCtx == nil || !semaCtx.TestingKnobs.DisallowAlwaysNullShortCut {
+			if rightReturn.Family() == types.UnknownFamily {
+				return leftTyped, rightTyped, nil, true /* alwaysNull */, nil
+			}
 		}
 
 		switch rightReturn.Family() {
@@ -2413,13 +2532,13 @@ func typeCheckComparisonOp(
 			switched = false
 		}
 		disallowSwitch = true
-		typedLeft, err = foldedLeft.TypeCheck(ctx, semaCtx, types.Any)
+		typedLeft, err = foldedLeft.TypeCheck(ctx, semaCtx, types.AnyElement)
 		if err != nil {
 			sigWithErr := fmt.Sprintf(compExprsFmt, left, op, right, err)
 			return nil, nil, nil, false,
 				pgerror.Newf(pgcode.InvalidParameterValue, unsupportedCompErrFmt, sigWithErr)
 		}
-		typedRight, err = foldedRight.TypeCheck(ctx, semaCtx, types.Any)
+		typedRight, err = foldedRight.TypeCheck(ctx, semaCtx, types.AnyElement)
 		if err != nil {
 			sigWithErr := fmt.Sprintf(compExprsFmt, left, op, right, err)
 			return nil, nil, nil, false,
@@ -2440,7 +2559,7 @@ func typeCheckComparisonOp(
 		sameTypeExprs[0] = foldedLeft
 		copy(sameTypeExprs[1:], rightTuple.Exprs)
 
-		typedSubExprs, retType, err := typeCheckSameTypedExprs(ctx, semaCtx, types.Any, sameTypeExprs...)
+		typedSubExprs, retType, err := typeCheckSameTypedExprs(ctx, semaCtx, types.AnyElement, sameTypeExprs...)
 		if err != nil {
 			sigWithErr := fmt.Sprintf(compExprsFmt, left, op, right, err)
 			return nil, nil, nil, false,
@@ -2468,7 +2587,7 @@ func typeCheckComparisonOp(
 		return typedLeft, rightTuple, fn, false, nil
 
 	case foldedOp.Symbol == treecmp.In && rightIsSubquery:
-		typedLeft, err = foldedLeft.TypeCheck(ctx, semaCtx, types.Any)
+		typedLeft, err = foldedLeft.TypeCheck(ctx, semaCtx, types.AnyElement)
 		if err != nil {
 			sigWithErr := fmt.Sprintf(compExprsFmt, left, op, right, err)
 			return nil, nil, nil, false,
@@ -2519,8 +2638,8 @@ func typeCheckComparisonOp(
 	case leftIsTuple || rightIsTuple:
 		var errLeft, errRight error
 		// Tuple must compare with a tuple type, as handled above.
-		typedLeft, errLeft = foldedLeft.TypeCheck(ctx, semaCtx, types.Any)
-		typedRight, errRight = foldedRight.TypeCheck(ctx, semaCtx, types.Any)
+		typedLeft, errLeft = foldedLeft.TypeCheck(ctx, semaCtx, types.AnyElement)
+		typedRight, errRight = foldedRight.TypeCheck(ctx, semaCtx, types.AnyElement)
 		if errLeft == nil && errRight == nil &&
 			((typedLeft.ResolvedType().Family() == types.TupleFamily &&
 				typedRight.ResolvedType().Family() != types.TupleFamily) ||
@@ -2587,9 +2706,9 @@ func typeCheckComparisonOp(
 		placeholderComparison = true
 	}
 	if !disallowSwitch && !placeholderComparison && !columnComparison {
-		_, _, err := typeCheckSameTypedExprs(ctx, semaCtx, types.Any, foldedLeft, foldedRight)
+		_, _, err := typeCheckSameTypedExprs(ctx, semaCtx, types.AnyElement, foldedLeft, foldedRight)
 		if err != nil {
-			_, _, err = typeCheckSameTypedExprs(ctx, semaCtx, types.Any, foldedRight, foldedLeft)
+			_, _, err = typeCheckSameTypedExprs(ctx, semaCtx, types.AnyElement, foldedRight, foldedLeft)
 			if err == nil {
 				s = getOverloadTypeChecker(ops, foldedRight, foldedLeft)
 				switched = !switched
@@ -2605,7 +2724,7 @@ func typeCheckComparisonOp(
 		}
 	}
 	defer s.release()
-	if err := s.typeCheckOverloadedExprs(ctx, semaCtx, types.Any, true); err != nil {
+	if err := s.typeCheckOverloadedExprs(ctx, semaCtx, types.AnyElement, true); err != nil {
 		return nil, nil, nil, false, err
 	}
 	typedSubExprs := s.typedExprs
@@ -2633,8 +2752,10 @@ func typeCheckComparisonOp(
 					break
 				}
 			}
-			if noneAcceptNull {
-				return leftExpr, rightExpr, nil, true /* alwaysNull */, nil
+			if !buildutil.CrdbTestBuild || semaCtx == nil || !semaCtx.TestingKnobs.DisallowAlwaysNullShortCut {
+				if noneAcceptNull {
+					return leftExpr, rightExpr, nil, true /* alwaysNull */, nil
+				}
 			}
 		}
 	}
@@ -2709,7 +2830,7 @@ func typeCheckSameTypedExprs(
 			return nil, nil, err
 		}
 		typ := typedExpr.ResolvedType()
-		if typ == types.Unknown && desired != types.Any {
+		if typ.Family() == types.UnknownFamily && !desired.IsWildcardType() {
 			// The expression had a NULL type, so we can return the desired type as
 			// the expression type.
 			typ = desired
@@ -2792,7 +2913,7 @@ func typeCheckSameTypedExprs(
 				}
 				return typedExprs, typ, nil
 			default:
-				if desired != types.Any {
+				if !desired.IsWildcardType() {
 					return typedExprs, desired, nil
 				}
 				return typedExprs, types.Unknown, nil
@@ -2887,12 +3008,12 @@ func typeCheckSameTypedConsts(
 	}
 
 	// If typ is not a wildcard, all consts try to become typ.
-	if typ.Family() != types.AnyFamily {
+	if !typ.IsWildcardType() {
 		all := true
 		for i, ok := s.constIdxs.Next(0); ok; i, ok = s.constIdxs.Next(i + 1) {
 			if !canConstantBecome(s.exprs[i].(Constant), typ) {
 				if required {
-					typedExpr, err := s.exprs[i].TypeCheck(s.ctx, s.semaCtx, types.Any)
+					typedExpr, err := s.exprs[i].TypeCheck(s.ctx, s.semaCtx, types.AnyElement)
 					if err != nil {
 						return nil, err
 					}
@@ -2926,7 +3047,7 @@ func typeCheckSameTypedConsts(
 		if typ := typedExpr.ResolvedType(); !typ.Equivalent(reqTyp) {
 			return nil, unexpectedTypeError(s.exprs[i], reqTyp, typ)
 		}
-		if reqTyp.Family() == types.AnyFamily {
+		if reqTyp.IsWildcardType() {
 			reqTyp = typedExpr.ResolvedType()
 		}
 	}
@@ -3068,7 +3189,7 @@ func typeCheckSameTypedTupleExprs(
 			sameTypeExprs = append(sameTypeExprs, expr.(*Tuple).Exprs[elemIdx])
 			sameTypeExprsIndices = append(sameTypeExprsIndices, exprIdx)
 		}
-		desiredElem := types.Any
+		desiredElem := types.AnyElement
 		if len(desired.TupleContents()) > elemIdx {
 			desiredElem = desired.TupleContents()[elemIdx]
 		}
@@ -3116,7 +3237,7 @@ func checkAllExprsAreTuplesOrNulls(ctx context.Context, semaCtx *SemaContext, ex
 		if !(isTuple || isNull) {
 			// We avoid calling TypeCheck on Tuple exprs since that causes the
 			// types to be resolved, which we only want to do later in type-checking.
-			typedExpr, err := expr.TypeCheck(ctx, semaCtx, types.Any)
+			typedExpr, err := expr.TypeCheck(ctx, semaCtx, types.AnyElement)
 			if err != nil {
 				return err
 			}
@@ -3349,7 +3470,7 @@ func ProcessPlaceholderAnnotations(
 		}
 	}
 
-	walkStmt(&v, stmt)
+	WalkStmt(&v, stmt)
 	return v.err
 }
 
@@ -3398,6 +3519,9 @@ func getMostSignificantOverload(
 	getFuncSig func() string,
 ) (QualifiedOverload, error) {
 	ambiguousError := func() error {
+		if expr.InCall {
+			return pgerror.Newf(pgcode.AmbiguousFunction, "procedure %s is not unique", getFuncSig())
+		}
 		return pgerror.Newf(
 			pgcode.AmbiguousFunction,
 			"ambiguous call: %s, candidates are:\n%s",
@@ -3415,16 +3539,61 @@ func getMostSignificantOverload(
 		// Since there are ambiguity errors when udf with the same family
 		// parameter types, function signature has to be sorted out to directly
 		// match a specific UDF overload for execution.
-		var expTypes []*types.T
+		var allArgTypes []*types.T
 		for _, exp := range typedInputExprs {
-			expTypes = append(expTypes, exp.ResolvedType())
+			allArgTypes = append(allArgTypes, exp.ResolvedType())
 		}
 		matchIdx := -1
 		foundMatch := false
 		for k, idx := range oImpls {
 			candidate := overloads[idx]
 			srcParams := candidate.params()
-			if srcParams.MatchIdentical(expTypes) {
+			matches := srcParams.MatchOid(allArgTypes)
+			if !matches {
+				routineType, outParamOrdinals, _ := candidate.outParamInfo()
+				defaultExprs := candidate.defaultExprs()
+				if len(outParamOrdinals) == 0 && len(defaultExprs) == 0 {
+					continue
+				}
+				// When we have some OUT parameters and / or DEFAULT expressions
+				// for input parameters, simply matching against all argument
+				// types might be insufficient.
+				var inputTypes []*types.T
+				if expr.InCall && routineType == ProcedureRoutine && len(outParamOrdinals) > 0 {
+					// OUT parameters for procedures must be specified in the
+					// CALL invocation, but they should be ignored when
+					// comparing against input parameters. (Note that type
+					// coercibility for OUT parameters has already been
+					// performed.)
+					inputTypes = make([]*types.T, 0, len(typedInputExprs)-len(outParamOrdinals))
+					var numOutParamsSeen int
+					for i, t := range allArgTypes {
+						if numOutParamsSeen < len(outParamOrdinals) && i == int(outParamOrdinals[numOutParamsSeen]) {
+							numOutParamsSeen++
+							continue
+						}
+						inputTypes = append(inputTypes, t)
+					}
+				} else {
+					inputTypes = allArgTypes
+				}
+				// TODO(88947): this logic might need to change to support
+				// VARIADIC.
+				ovInputTypes, ok := srcParams.(ParamTypes)
+				if !ok {
+					return QualifiedOverload{}, errors.AssertionFailedf("overload params is %T and not ParamTypes", srcParams)
+				}
+				if len(defaultExprs) > 0 {
+					// Some parameters have DEFAULT expressions, so it might be
+					// the case that some input arguments were omitted.
+					numOmittedExprs := len(ovInputTypes) - len(inputTypes)
+					if numOmittedExprs > 0 && numOmittedExprs <= len(defaultExprs) {
+						ovInputTypes = ovInputTypes[:len(ovInputTypes)-numOmittedExprs]
+					}
+				}
+				matches = ovInputTypes.MatchOid(inputTypes)
+			}
+			if matches {
 				if foundMatch {
 					// Throw ambiguity error if there are more than one
 					// candidate overloads from same schema.
@@ -3482,7 +3651,8 @@ func getMostSignificantOverload(
 		schema := searchPath.GetSchema(i)
 		for _, idx := range filter {
 			if r := qualifiedOverloads[idx]; r.Schema == schema {
-				if found {
+				// Only throw "ambiguous function" error for user-defined functions.
+				if found && r.Type == UDFRoutine {
 					return QualifiedOverload{}, ambiguousError()
 				}
 				found = true
@@ -3502,6 +3672,102 @@ func getMostSignificantOverload(
 	return ret, nil
 }
 
+// ResolvePolymorphicArgTypes iterates through the list of routine parameters
+// and supplied arguments (including default expressions), and attempts to
+// determine the concrete types for any polymorphic-typed parameters. It returns
+// true if the supplied argument types are valid, as well as the determined
+// element type (nil if there were no polymorphic parameters).
+//
+// CRDB currently supports two polymorphic types:
+// * ANYELEMENT allows any argument type.
+// * ANYARRAY allows only array types.
+//
+// The rules for argument validity are as follows:
+//  1. The arguments supplied for ANYELEMENT parameters must all have the same
+//     type.
+//  2. The supplied types for ANYARRAY parameters must match each other, and the
+//     array *element* type must match all ANYELEMENT parameters.
+//  3. NULL arguments are exempt from the above two rules. However, there must
+//     be at least one non-NULL argument in order to resolve a concrete type.
+//
+// anyElemTyp, if non-nil, allows the caller to pass in the expected concrete
+// type for ANYELEMENT parameters.
+//
+// enforceConsistency, if true, indicates that ResolvePolymorphicArgTypes should
+// throw a suitable error in the case of invalid arguments, rather than
+// returning with ok=false. Note: we do this instead of always returning the
+// error because error construction can be expensive.
+func ResolvePolymorphicArgTypes(
+	paramTypes ParamTypes, argTypes []*types.T, anyElemTyp *types.T, enforceConsistency bool,
+) (ok bool, numPolyParams int, _ *types.T) {
+	var anyArrayTyp *types.T
+	for i := range paramTypes {
+		paramTyp := paramTypes[i].Typ
+		if !paramTyp.IsPolymorphicType() {
+			continue
+		}
+		argTyp := argTypes[i]
+		numPolyParams++
+		if argTyp.Family() == types.UnknownFamily {
+			continue
+		}
+		maybeMakeNotAlikeErr := func(polyTypeName string, actualTyp, expectedTyp *types.T) {
+			if enforceConsistency {
+				err := pgerror.Newf(pgcode.DatatypeMismatch,
+					"arguments declared \"%s\" are not all alike", polyTypeName,
+				)
+				panic(errors.WithDetailf(err, "%s versus %s", actualTyp, expectedTyp))
+			}
+		}
+		switch paramTyp.Family() {
+		case types.AnyFamily:
+			if anyElemTyp == nil {
+				anyElemTyp = argTyp
+			} else if !anyElemTyp.Identical(argTyp) {
+				maybeMakeNotAlikeErr("anyelement", anyElemTyp, argTyp)
+				return false, 0, nil
+			}
+		case types.ArrayFamily:
+			if anyArrayTyp == nil {
+				anyArrayTyp = argTyp
+			} else if !anyArrayTyp.Identical(argTyp) {
+				maybeMakeNotAlikeErr("anyarray", anyArrayTyp, argTyp)
+				return false, 0, nil
+			}
+		case types.EnumFamily:
+			panic(unimplemented.NewWithIssue(123048, "ANYENUM is not yet supported"))
+		default:
+			panic(errors.AssertionFailedf("unexpected type: %s", paramTyp.SQLStringForError()))
+		}
+	}
+	if numPolyParams == 0 {
+		return true, 0, nil
+	}
+	if anyArrayTyp != nil {
+		if anyArrayTyp.Family() != types.ArrayFamily {
+			if enforceConsistency {
+				panic(pgerror.Newf(pgcode.DatatypeMismatch,
+					"argument declared anyarray is not an array but type %s", anyArrayTyp,
+				))
+			}
+			return false, 0, nil
+		}
+		if anyElemTyp == nil {
+			// Derive the type from the array element type.
+			anyElemTyp = anyArrayTyp.ArrayContents()
+		} else if !anyArrayTyp.ArrayContents().Identical(anyElemTyp) {
+			if enforceConsistency {
+				err := pgerror.New(pgcode.DatatypeMismatch,
+					"argument declared anyarray is not consistent with argument declared anyelement",
+				)
+				panic(errors.WithDetailf(err, "%s versus %s", anyArrayTyp, anyElemTyp))
+			}
+			return false, 0, nil
+		}
+	}
+	return true, numPolyParams, anyElemTyp
+}
+
 // UnsupportedTypeChecker is used to check that a type is supported by the
 // current cluster version. It is an interface because some packages cannot
 // import the clusterversion package.
@@ -3523,17 +3789,23 @@ func CheckUnsupportedType(ctx context.Context, semaCtx *SemaContext, typ *types.
 	return semaCtx.UnsupportedTypeChecker.CheckType(ctx, typ)
 }
 
-// checkRefCursorComparison checks whether the given types are or contain the
-// REFCURSOR data type, which is invalid for comparison. We don't simply remove
+var CannotAcceptTriggerErr = pgerror.New(pgcode.FeatureNotSupported,
+	"cannot accept a value of type trigger",
+)
+
+// checkComparison checks whether the given types are or contain the
+// given family, which is invalid for comparison. We don't simply remove
 // the relevant comparison overloads because we rely on their existence in
 // various locations throughout the codebase.
-func checkRefCursorComparison(op treecmp.ComparisonOperatorSymbol, left, right *types.T) error {
+func checkComparison(
+	op treecmp.ComparisonOperatorSymbol, left, right *types.T, family types.Family,
+) error {
 	if (op == treecmp.IsNotDistinctFrom || op == treecmp.IsDistinctFrom) &&
-		(left.Family() == types.RefCursorFamily && right == types.Unknown) {
-		// Special case: "REFCURSOR IS [NOT] DISTINCT FROM NULL" is allowed.
+		(left.Family() == family && right.Family() == types.UnknownFamily) {
+		// Special case: "<family> IS [NOT] DISTINCT FROM NULL" is allowed.
 		return nil
 	}
-	if left.Family() == types.RefCursorFamily || right.Family() == types.RefCursorFamily {
+	if left.Family() == family || right.Family() == family {
 		return pgerror.Newf(pgcode.UndefinedFunction,
 			"unsupported comparison operator: %s %s %s", left, op, right,
 		)
@@ -3541,7 +3813,7 @@ func checkRefCursorComparison(op treecmp.ComparisonOperatorSymbol, left, right *
 	var checkRecursive func(*types.T) bool
 	checkRecursive = func(typ *types.T) bool {
 		switch typ.Family() {
-		case types.RefCursorFamily:
+		case family:
 			return true
 		case types.TupleFamily:
 			for _, t := range typ.TupleContents() {
@@ -3556,8 +3828,19 @@ func checkRefCursorComparison(op treecmp.ComparisonOperatorSymbol, left, right *
 	}
 	if checkRecursive(left) || checkRecursive(right) {
 		return pgerror.Newf(pgcode.UndefinedFunction,
-			"could not identify a comparison function for type refcursor",
+			"could not identify a comparison function for family %q", family.String(),
 		)
 	}
 	return nil
 }
+
+func runValidations(
+	op treecmp.ComparisonOperatorSymbol, left, right *types.T, families []types.Family,
+) error {
+	for _, family := range families {
+		if err := checkComparison(op, left, right, family); err != nil {
+			return err
+		}
+	}
+	return nil
+}
diff --git a/pkg/sql/sem/tree/type_name.go b/pkg/sql/sem/tree/type_name.go
index a671b41..98daa0e 100644
--- a/pkg/sql/sem/tree/type_name.go
+++ b/pkg/sql/sem/tree/type_name.go
@@ -1,12 +1,7 @@
 // Copyright 2020 The Cockroach Authors.
 //
-// Use of this software is governed by the Business Source License
-// included in the file licenses/BSL.txt.
-//
-// As of the Change Date specified in that file, in accordance with
-// the Business Source License, use of this software will be governed
-// by the Apache License, Version 2.0, included in the file
-// licenses/APL.txt.
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
 
 package tree
 
@@ -47,8 +42,7 @@ func (t *TypeName) Format(ctx *FmtCtx) {
 
 // SQLString implements the ResolvableTypeReference interface.
 func (t *TypeName) SQLString() string {
-	// FmtBareIdentifiers prevents the TypeName string from being wrapped in quotations.
-	return AsStringWithFlags(t, FmtBareIdentifiers)
+	return AsStringWithFlags(t, FmtSimple)
 }
 
 func (t *TypeName) objectName() {}
@@ -150,11 +144,11 @@ func ResolveType(
 
 // We need to inject the logic for formatting types into the types package.
 func init() {
-	types.FormatTypeName = func(name types.UserDefinedTypeName) string {
+	types.FormatTypeName = func(name types.UserDefinedTypeName, explicitCatalog bool) string {
 		n := MakeTypeNameWithPrefix(ObjectNamePrefix{
 			CatalogName:     Name(name.Catalog),
 			SchemaName:      Name(name.Schema),
-			ExplicitCatalog: name.Catalog != "",
+			ExplicitCatalog: explicitCatalog && name.Catalog != "",
 			ExplicitSchema:  name.ExplicitSchema,
 		}, name.Name)
 		return AsString(&n)
@@ -175,7 +169,13 @@ func (ctx *FmtCtx) FormatTypeReference(ref ResolvableTypeReference) {
 				return
 			}
 		}
-		ctx.WriteString(t.SQLString())
+		// If needed, get the full name of the type for use as a type reference.
+		// We may need the three-part name to properly detect cross-database access.
+		if ctx.HasFlags(FmtAlwaysQualifyUserDefinedTypeNames) {
+			ctx.WriteString(t.SQLStringFullyQualified())
+		} else {
+			ctx.WriteString(t.SQLString())
+		}
 
 	case *OIDTypeReference:
 		if ctx.indexedTypeFormatter != nil {
@@ -239,14 +239,12 @@ func (node *ArrayTypeReference) Format(ctx *FmtCtx) {
 
 // SQLString implements the ResolvableTypeReference interface.
 func (node *ArrayTypeReference) SQLString() string {
-	// FmtBareIdentifiers prevents the TypeName string from being wrapped in quotations.
-	return AsStringWithFlags(node, FmtBareIdentifiers)
+	return AsStringWithFlags(node, FmtSimple)
 }
 
 // SQLString implements the ResolvableTypeReference interface.
 func (name *UnresolvedObjectName) SQLString() string {
-	// FmtBareIdentifiers prevents the TypeName string from being wrapped in quotations.
-	return AsStringWithFlags(name, FmtBareIdentifiers)
+	return AsStringWithFlags(name, FmtSimple)
 }
 
 // IsReferenceSerialType returns whether the input reference is a known
diff --git a/pkg/sql/sem/tree/typing.go b/pkg/sql/sem/tree/typing.go
index ff1d5d6..a72f6ea 100644
--- a/pkg/sql/sem/tree/typing.go
+++ b/pkg/sql/sem/tree/typing.go
@@ -1,12 +1,7 @@
 // Copyright 2022 The Cockroach Authors.
 //
-// Use of this software is governed by the Business Source License
-// included in the file licenses/BSL.txt.
-//
-// As of the Change Date specified in that file, in accordance with
-// the Business Source License, use of this software will be governed
-// by the Apache License, Version 2.0, included in the file
-// licenses/APL.txt.
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
 
 package tree
 
diff --git a/pkg/sql/sem/tree/union.go b/pkg/sql/sem/tree/union.go
index 2b571a5..41a5c07 100644
--- a/pkg/sql/sem/tree/union.go
+++ b/pkg/sql/sem/tree/union.go
@@ -7,13 +7,8 @@
 //
 // Copyright 2015 The Cockroach Authors.
 //
-// Use of this software is governed by the Business Source License
-// included in the file licenses/BSL.txt.
-//
-// As of the Change Date specified in that file, in accordance with
-// the Business Source License, use of this software will be governed
-// by the Apache License, Version 2.0, included in the file
-// licenses/APL.txt.
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
 
 // This code was derived from https://github.com/youtube/vitess.
 
diff --git a/pkg/sql/sem/tree/unlisten.go b/pkg/sql/sem/tree/unlisten.go
index 7a79b37..5b91e2f 100644
--- a/pkg/sql/sem/tree/unlisten.go
+++ b/pkg/sql/sem/tree/unlisten.go
@@ -1,12 +1,7 @@
 // Copyright 2022 The Cockroach Authors.
 //
-// Use of this software is governed by the Business Source License
-// included in the file licenses/BSL.txt.
-//
-// As of the Change Date specified in that file, in accordance with
-// the Business Source License, use of this software will be governed
-// by the Apache License, Version 2.0, included in the file
-// licenses/APL.txt.
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
 
 package tree
 
diff --git a/pkg/sql/sem/tree/unsupported_error.go b/pkg/sql/sem/tree/unsupported_error.go
index ac91e1e..4850179 100644
--- a/pkg/sql/sem/tree/unsupported_error.go
+++ b/pkg/sql/sem/tree/unsupported_error.go
@@ -1,12 +1,7 @@
 // Copyright 2020 The Cockroach Authors.
 //
-// Use of this software is governed by the Business Source License
-// included in the file licenses/BSL.txt.
-//
-// As of the Change Date specified in that file, in accordance with
-// the Business Source License, use of this software will be governed
-// by the Apache License, Version 2.0, included in the file
-// licenses/APL.txt.
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
 
 package tree
 
diff --git a/pkg/sql/sem/tree/update.go b/pkg/sql/sem/tree/update.go
index ce812e2..3ad3e86 100644
--- a/pkg/sql/sem/tree/update.go
+++ b/pkg/sql/sem/tree/update.go
@@ -7,13 +7,8 @@
 //
 // Copyright 2015 The Cockroach Authors.
 //
-// Use of this software is governed by the Business Source License
-// included in the file licenses/BSL.txt.
-//
-// As of the Change Date specified in that file, in accordance with
-// the Business Source License, use of this software will be governed
-// by the Apache License, Version 2.0, included in the file
-// licenses/APL.txt.
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
 
 // This code was derived from https://github.com/youtube/vitess.
 
diff --git a/pkg/sql/sem/tree/values.go b/pkg/sql/sem/tree/values.go
index 78ca6d8..69c7e1f 100644
--- a/pkg/sql/sem/tree/values.go
+++ b/pkg/sql/sem/tree/values.go
@@ -7,13 +7,8 @@
 //
 // Copyright 2015 The Cockroach Authors.
 //
-// Use of this software is governed by the Business Source License
-// included in the file licenses/BSL.txt.
-//
-// As of the Change Date specified in that file, in accordance with
-// the Business Source License, use of this software will be governed
-// by the Apache License, Version 2.0, included in the file
-// licenses/APL.txt.
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
 
 // This code was derived from https://github.com/youtube/vitess.
 
diff --git a/pkg/sql/sem/tree/var_expr.go b/pkg/sql/sem/tree/var_expr.go
index 9f3972e..7be53e1 100644
--- a/pkg/sql/sem/tree/var_expr.go
+++ b/pkg/sql/sem/tree/var_expr.go
@@ -1,12 +1,7 @@
 // Copyright 2015 The Cockroach Authors.
 //
-// Use of this software is governed by the Business Source License
-// included in the file licenses/BSL.txt.
-//
-// As of the Change Date specified in that file, in accordance with
-// the Business Source License, use of this software will be governed
-// by the Apache License, Version 2.0, included in the file
-// licenses/APL.txt.
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
 
 package tree
 
diff --git a/pkg/sql/sem/tree/var_name.go b/pkg/sql/sem/tree/var_name.go
index 06305fc..19a28e8 100644
--- a/pkg/sql/sem/tree/var_name.go
+++ b/pkg/sql/sem/tree/var_name.go
@@ -1,12 +1,7 @@
 // Copyright 2016 The Cockroach Authors.
 //
-// Use of this software is governed by the Business Source License
-// included in the file licenses/BSL.txt.
-//
-// As of the Change Date specified in that file, in accordance with
-// the Business Source License, use of this software will be governed
-// by the Apache License, Version 2.0, included in the file
-// licenses/APL.txt.
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
 
 package tree
 
diff --git a/pkg/sql/sem/tree/walk.go b/pkg/sql/sem/tree/walk.go
index 96980f0..144182a 100644
--- a/pkg/sql/sem/tree/walk.go
+++ b/pkg/sql/sem/tree/walk.go
@@ -1,12 +1,7 @@
 // Copyright 2015 The Cockroach Authors.
 //
-// Use of this software is governed by the Business Source License
-// included in the file licenses/BSL.txt.
-//
-// As of the Change Date specified in that file, in accordance with
-// the Business Source License, use of this software will be governed
-// by the Apache License, Version 2.0, included in the file
-// licenses/APL.txt.
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
 
 package tree
 
@@ -512,7 +507,7 @@ func (expr *RangeCond) Walk(v Visitor) Expr {
 
 // Walk implements the Expr interface.
 func (expr *Subquery) Walk(v Visitor) Expr {
-	sel, changed := walkStmt(v, expr.Select)
+	sel, changed := WalkStmt(v, expr.Select)
 	if changed {
 		exprCopy := *expr
 		exprCopy.Select = sel.(SelectStatement)
@@ -523,7 +518,7 @@ func (expr *Subquery) Walk(v Visitor) Expr {
 
 // WalkTableExpr implements the TableExpr interface.
 func (expr *Subquery) WalkTableExpr(v Visitor) TableExpr {
-	sel, changed := walkStmt(v, expr.Select)
+	sel, changed := WalkStmt(v, expr.Select)
 	if changed {
 		exprCopy := *expr
 		exprCopy.Select = sel.(SelectStatement)
@@ -590,7 +585,7 @@ func (expr *RowsFromExpr) WalkTableExpr(v Visitor) TableExpr {
 
 // WalkTableExpr implements the TableExpr interface.
 func (expr *StatementSource) WalkTableExpr(v Visitor) TableExpr {
-	s, changed := walkStmt(v, expr.Statement)
+	s, changed := WalkStmt(v, expr.Statement)
 	if changed {
 		exprCopy := *expr
 		exprCopy.Statement = s
@@ -762,6 +757,9 @@ func (expr *DBox2D) Walk(_ Visitor) Expr { return expr }
 // Walk implements the Expr interface.
 func (expr *DPGLSN) Walk(_ Visitor) Expr { return expr }
 
+// Walk implements the Expr interface.
+func (expr *DPGVector) Walk(_ Visitor) Expr { return expr }
+
 // Walk implements the Expr interface.
 func (expr *DGeography) Walk(_ Visitor) Expr { return expr }
 
@@ -771,6 +769,9 @@ func (expr *DGeometry) Walk(_ Visitor) Expr { return expr }
 // Walk implements the Expr interface.
 func (expr *DJSON) Walk(_ Visitor) Expr { return expr }
 
+// Walk implements the Expr interface.
+func (expr *DJsonpath) Walk(_ Visitor) Expr { return expr }
+
 // Walk implements the Expr interface.
 func (expr *DTSQuery) Walk(_ Visitor) Expr { return expr }
 
@@ -826,10 +827,10 @@ func (expr *DOidWrapper) Walk(_ Visitor) Expr { return expr }
 
 // WalkExpr traverses the nodes in an expression.
 //
-// NOTE: Do not count on the walkStmt/WalkExpr machinery to visit all
+// NOTE: Do not count on the WalkStmt/WalkExpr machinery to visit all
 // expressions contained in a query. Only a sub-set of all expressions are
-// found by walkStmt and subsequently traversed. See the comment below on
-// walkStmt for details.
+// found by WalkStmt and subsequently traversed. See the comment below on
+// WalkStmt for details.
 func WalkExpr(v Visitor, expr Expr) (newExpr Expr, changed bool) {
 	recurse, newExpr := v.VisitPre(expr)
 
@@ -857,7 +858,7 @@ func WalkExprConst(v Visitor, expr Expr) {
 }
 
 // walkableStmt is implemented by statements that can appear inside an expression (selects) or
-// we want to start a walk from (using walkStmt).
+// we want to start a walk from (using WalkStmt).
 type walkableStmt interface {
 	Statement
 	walkStmt(Visitor) Statement
@@ -912,7 +913,7 @@ func (n *ShowTenantClusterSetting) copyNode() *ShowTenantClusterSetting {
 // walkStmt is part of the walkableStmt interface.
 func (n *ShowTenantClusterSetting) walkStmt(v Visitor) Statement {
 	ret := n
-	sc, changed := walkStmt(v, n.ShowClusterSetting)
+	sc, changed := WalkStmt(v, n.ShowClusterSetting)
 	if changed {
 		ret = n.copyNode()
 		ret.ShowClusterSetting = sc.(*ShowClusterSetting)
@@ -936,7 +937,7 @@ func (n *ShowTenantClusterSettingList) copyNode() *ShowTenantClusterSettingList
 // walkStmt is part of the walkableStmt interface.
 func (n *ShowTenantClusterSettingList) walkStmt(v Visitor) Statement {
 	ret := n
-	sc, changed := walkStmt(v, n.ShowClusterSettingList)
+	sc, changed := WalkStmt(v, n.ShowClusterSettingList)
 	if changed {
 		ret = n.copyNode()
 		ret.ShowClusterSettingList = sc.(*ShowClusterSettingList)
@@ -1032,6 +1033,24 @@ func (n *AlterTenantReplication) walkStmt(v Visitor) Statement {
 			ret.Cutover.Timestamp = e
 		}
 	}
+	if n.ReplicationSourceConnUri != nil {
+		e, changed := WalkExpr(v, n.ReplicationSourceConnUri)
+		if changed {
+			if ret == n {
+				ret = n.copyNode()
+			}
+			ret.ReplicationSourceConnUri = e
+		}
+	}
+	if n.ReplicationSourceTenantName != nil {
+		ts, changed := walkTenantSpec(v, n.ReplicationSourceTenantName)
+		if changed {
+			if ret == n {
+				ret = n.copyNode()
+			}
+			ret.TenantSpec = ts
+		}
+	}
 	if n.Options.Retention != nil {
 		e, changed := WalkExpr(v, n.Options.Retention)
 		if changed {
@@ -1041,25 +1060,18 @@ func (n *AlterTenantReplication) walkStmt(v Visitor) Statement {
 			ret.Options.Retention = e
 		}
 	}
-	if n.Options.ResumeTimestamp != nil {
-		e, changed := WalkExpr(v, n.Options.ResumeTimestamp)
+	if n.Options.ExpirationWindow != nil {
+		e, changed := WalkExpr(v, n.Options.ExpirationWindow)
 		if changed {
 			if ret == n {
 				ret = n.copyNode()
 			}
-			ret.Options.ResumeTimestamp = e
+			ret.Options.ExpirationWindow = e
 		}
 	}
-
 	return ret
 }
 
-// copyNode makes a copy of this node without recursing.
-func (n *LikeTenantSpec) copyNode() *LikeTenantSpec {
-	nodeCopy := *n
-	return &nodeCopy
-}
-
 // copyNode makes a copy of this Statement without recursing in any child Statements.
 func (n *CreateTenant) copyNode() *CreateTenant {
 	stmtCopy := *n
@@ -1069,15 +1081,12 @@ func (n *CreateTenant) copyNode() *CreateTenant {
 // walkStmt is part of the walkableStmt interface.
 func (n *CreateTenant) walkStmt(v Visitor) Statement {
 	ret := n
-	if n.Like.OtherTenant != nil {
-		ts, changed := walkTenantSpec(v, n.TenantSpec)
-		if changed {
-			if ret == n {
-				ret = n.copyNode()
-			}
-			ret.Like = n.Like.copyNode()
-			ret.Like.OtherTenant = ts
+	ts, changed := walkTenantSpec(v, n.TenantSpec)
+	if changed {
+		if ret == n {
+			ret = n.copyNode()
 		}
+		ret.TenantSpec = ts
 	}
 	return ret
 }
@@ -1091,6 +1100,13 @@ func (n *CreateTenantFromReplication) copyNode() *CreateTenantFromReplication {
 // walkStmt is part of the walkableStmt interface.
 func (n *CreateTenantFromReplication) walkStmt(v Visitor) Statement {
 	ret := n
+	ts, changed := walkTenantSpec(v, n.TenantSpec)
+	if changed {
+		if ret == n {
+			ret = n.copyNode()
+		}
+		ret.TenantSpec = ts
+	}
 	e, changed := WalkExpr(v, n.ReplicationSourceTenantName.Expr)
 	if changed {
 		if ret == n {
@@ -1098,12 +1114,12 @@ func (n *CreateTenantFromReplication) walkStmt(v Visitor) Statement {
 		}
 		ret.ReplicationSourceTenantName = &TenantSpec{IsName: true, Expr: e}
 	}
-	e, changed = WalkExpr(v, n.ReplicationSourceAddress)
+	e, changed = WalkExpr(v, n.ReplicationSourceConnUri)
 	if changed {
 		if ret == n {
 			ret = n.copyNode()
 		}
-		ret.ReplicationSourceAddress = e
+		ret.ReplicationSourceConnUri = e
 	}
 	if n.Options.Retention != nil {
 		e, changed := WalkExpr(v, n.Options.Retention)
@@ -1114,24 +1130,13 @@ func (n *CreateTenantFromReplication) walkStmt(v Visitor) Statement {
 			ret.Options.Retention = e
 		}
 	}
-	if n.Options.ResumeTimestamp != nil {
-		e, changed := WalkExpr(v, n.Options.ResumeTimestamp)
-		if changed {
-			if ret == n {
-				ret = n.copyNode()
-			}
-			ret.Options.ResumeTimestamp = e
-		}
-	}
-
-	if n.Like.OtherTenant != nil {
-		ts, changed := walkTenantSpec(v, n.TenantSpec)
+	if n.Options.ExpirationWindow != nil {
+		e, changed := WalkExpr(v, n.Options.ExpirationWindow)
 		if changed {
 			if ret == n {
 				ret = n.copyNode()
 			}
-			ret.Like = n.Like.copyNode()
-			ret.Like.OtherTenant = ts
+			ret.Options.ExpirationWindow = e
 		}
 	}
 	return ret
@@ -1156,6 +1161,37 @@ func (n *ShowTenant) walkStmt(v Visitor) Statement {
 	return ret
 }
 
+// copyNode makes a copy of this Statement without recursing in any child Statements.
+func (n *ShowFingerprints) copyNode() *ShowFingerprints {
+	stmtCopy := *n
+	return &stmtCopy
+}
+
+// walkStmt is part of the walkableStmt interface.
+func (n *ShowFingerprints) walkStmt(v Visitor) Statement {
+	ret := n
+	if n.TenantSpec != nil {
+		ts, changed := walkTenantSpec(v, n.TenantSpec)
+		if changed {
+			if ret == n {
+				ret = n.copyNode()
+			}
+			ret.TenantSpec = ts
+		}
+	}
+	if n.Options.StartTimestamp != nil {
+		e, changed := WalkExpr(v, n.Options.StartTimestamp)
+		if changed {
+			if ret == n {
+				ret = n.copyNode()
+			}
+			ret.Options.StartTimestamp = e
+		}
+	}
+
+	return ret
+}
+
 // copyNode makes a copy of this Statement without recursing in any child Statements.
 func (n *AlterTenantRename) copyNode() *AlterTenantRename {
 	stmtCopy := *n
@@ -1182,6 +1218,35 @@ func (n *AlterTenantRename) walkStmt(v Visitor) Statement {
 	return ret
 }
 
+// copyNode makes a copy of this Statement without recursing in any child Statements.
+func (n *AlterTenantReset) copyNode() *AlterTenantReset {
+	stmtCopy := *n
+	return &stmtCopy
+}
+
+// walkStmt is part of the walkableStmt interface.
+func (n *AlterTenantReset) walkStmt(v Visitor) Statement {
+	ret := n
+	ts, changed := walkTenantSpec(v, n.TenantSpec)
+	if changed {
+		if ret == n {
+			ret = n.copyNode()
+		}
+		ret.TenantSpec = ts
+	}
+	if n.Timestamp != nil {
+		e, changed := WalkExpr(v, n.Timestamp)
+		if changed {
+			if ret == n {
+				ret = n.copyNode()
+			}
+			ret.Timestamp = e
+		}
+	}
+
+	return ret
+}
+
 // copyNode makes a copy of this Statement without recursing in any child Statements.
 func (n *AlterTenantService) copyNode() *AlterTenantService {
 	stmtCopy := *n
@@ -1223,7 +1288,6 @@ func (n *DropTenant) walkStmt(v Visitor) Statement {
 // copyNode makes a copy of this Statement without recursing in any child Statements.
 func (stmt *Backup) copyNode() *Backup {
 	stmtCopy := *stmt
-	stmtCopy.IncrementalFrom = append(Exprs(nil), stmt.IncrementalFrom...)
 	return &stmtCopy
 }
 
@@ -1248,15 +1312,7 @@ func (stmt *Backup) walkStmt(v Visitor) Statement {
 			ret.To[i] = e
 		}
 	}
-	for i, expr := range stmt.IncrementalFrom {
-		e, changed := WalkExpr(v, expr)
-		if changed {
-			if ret == stmt {
-				ret = stmt.copyNode()
-			}
-			ret.IncrementalFrom[i] = e
-		}
-	}
+
 	if stmt.Options.EncryptionPassphrase != nil {
 		pw, changed := WalkExpr(v, stmt.Options.EncryptionPassphrase)
 		if changed {
@@ -1329,6 +1385,17 @@ func (stmt *Delete) walkStmt(v Visitor) Statement {
 	return ret
 }
 
+// walkStmt is part of the walkableStmt interface.
+func (stmt *DoBlock) walkStmt(v Visitor) Statement {
+	body := stmt.Code.VisitBody(v)
+	if body != stmt.Code {
+		stmtCopy := *stmt
+		stmtCopy.Code = body
+		return &stmtCopy
+	}
+	return stmt
+}
+
 // copyNode makes a copy of this Statement without recursing in any child Statements.
 func (stmt *Explain) copyNode() *Explain {
 	stmtCopy := *stmt
@@ -1337,7 +1404,7 @@ func (stmt *Explain) copyNode() *Explain {
 
 // walkStmt is part of the walkableStmt interface.
 func (stmt *Explain) walkStmt(v Visitor) Statement {
-	s, changed := walkStmt(v, stmt.Statement)
+	s, changed := WalkStmt(v, stmt.Statement)
 	if changed {
 		stmt = stmt.copyNode()
 		stmt.Statement = s
@@ -1353,7 +1420,7 @@ func (stmt *ExplainAnalyze) copyNode() *ExplainAnalyze {
 
 // walkStmt is part of the walkableStmt interface.
 func (stmt *ExplainAnalyze) walkStmt(v Visitor) Statement {
-	s, changed := walkStmt(v, stmt.Statement)
+	s, changed := WalkStmt(v, stmt.Statement)
 	if changed {
 		stmt = stmt.copyNode()
 		stmt.Statement = s
@@ -1371,7 +1438,7 @@ func (stmt *Insert) copyNode() *Insert {
 func (stmt *Insert) walkStmt(v Visitor) Statement {
 	ret := stmt
 	if stmt.Rows != nil {
-		rows, changed := walkStmt(v, stmt.Rows)
+		rows, changed := WalkStmt(v, stmt.Rows)
 		if changed {
 			ret = stmt.copyNode()
 			ret.Rows = rows.(*Select)
@@ -1399,7 +1466,7 @@ func (stmt *CreateTable) copyNode() *CreateTable {
 func (stmt *CreateTable) walkStmt(v Visitor) Statement {
 	ret := stmt
 	if stmt.AsSource != nil {
-		rows, changed := walkStmt(v, stmt.AsSource)
+		rows, changed := WalkStmt(v, stmt.AsSource)
 		if changed {
 			ret = stmt.copyNode()
 			ret.AsSource = rows.(*Select)
@@ -1416,7 +1483,7 @@ func (stmt *CancelQueries) copyNode() *CancelQueries {
 
 // walkStmt is part of the walkableStmt interface.
 func (stmt *CancelQueries) walkStmt(v Visitor) Statement {
-	sel, changed := walkStmt(v, stmt.Queries)
+	sel, changed := WalkStmt(v, stmt.Queries)
 	if changed {
 		stmt = stmt.copyNode()
 		stmt.Queries = sel.(*Select)
@@ -1432,7 +1499,7 @@ func (stmt *CancelSessions) copyNode() *CancelSessions {
 
 // walkStmt is part of the walkableStmt interface.
 func (stmt *CancelSessions) walkStmt(v Visitor) Statement {
-	sel, changed := walkStmt(v, stmt.Sessions)
+	sel, changed := WalkStmt(v, stmt.Sessions)
 	if changed {
 		stmt = stmt.copyNode()
 		stmt.Sessions = sel.(*Select)
@@ -1448,7 +1515,7 @@ func (stmt *ControlJobs) copyNode() *ControlJobs {
 
 // walkStmt is part of the walkableStmt interface.
 func (stmt *ControlJobs) walkStmt(v Visitor) Statement {
-	sel, changed := walkStmt(v, stmt.Jobs)
+	sel, changed := WalkStmt(v, stmt.Jobs)
 	if changed {
 		stmt = stmt.copyNode()
 		stmt.Jobs = sel.(*Select)
@@ -1464,7 +1531,7 @@ func (n *ControlSchedules) copyNode() *ControlSchedules {
 
 // walkStmt is part of the walkableStmt interface.
 func (n *ControlSchedules) walkStmt(v Visitor) Statement {
-	sel, changed := walkStmt(v, n.Schedules)
+	sel, changed := WalkStmt(v, n.Schedules)
 	if changed {
 		n = n.copyNode()
 		n.Schedules = sel.(*Select)
@@ -1506,7 +1573,7 @@ func (stmt *Import) walkStmt(v Visitor) Statement {
 
 // walkStmt is part of the walkableStmt interface.
 func (stmt *ParenSelect) walkStmt(v Visitor) Statement {
-	sel, changed := walkStmt(v, stmt.Select)
+	sel, changed := WalkStmt(v, stmt.Select)
 	if changed {
 		return &ParenSelect{sel.(*Select)}
 	}
@@ -1516,7 +1583,6 @@ func (stmt *ParenSelect) walkStmt(v Visitor) Statement {
 // copyNode makes a copy of this Statement without recursing in any child Statements.
 func (stmt *Restore) copyNode() *Restore {
 	stmtCopy := *stmt
-	stmtCopy.From = append([]StringOrPlaceholderOptList(nil), stmt.From...)
 	return &stmtCopy
 }
 
@@ -1532,15 +1598,13 @@ func (stmt *Restore) walkStmt(v Visitor) Statement {
 			ret.AsOf.Expr = e
 		}
 	}
-	for i, backup := range stmt.From {
-		for j, expr := range backup {
-			e, changed := WalkExpr(v, expr)
-			if changed {
-				if ret == stmt {
-					ret = stmt.copyNode()
-				}
-				ret.From[i][j] = e
+	for i, expr := range stmt.From {
+		e, changed := WalkExpr(v, expr)
+		if changed {
+			if ret == stmt {
+				ret = stmt.copyNode()
 			}
+			ret.From[i] = e
 		}
 	}
 
@@ -1564,16 +1628,6 @@ func (stmt *Restore) walkStmt(v Visitor) Statement {
 		}
 	}
 
-	if stmt.Options.IncludeAllSecondaryTenants != nil {
-		include, changed := WalkExpr(v, stmt.Options.IncludeAllSecondaryTenants)
-		if changed {
-			if ret == stmt {
-				ret = stmt.copyNode()
-			}
-			ret.Options.IncludeAllSecondaryTenants = include
-		}
-	}
-
 	if stmt.Options.ExecutionLocality != nil {
 		include, changed := WalkExpr(v, stmt.Options.ExecutionLocality)
 		if changed {
@@ -1634,7 +1688,7 @@ func (stmt *Select) copyNode() *Select {
 }
 
 func (n *CopyTo) walkStmt(v Visitor) Statement {
-	if newStmt, changed := walkStmt(v, n.Statement); changed {
+	if newStmt, changed := WalkStmt(v, n.Statement); changed {
 		// Make a copy of the CopyTo statement.
 		stmtCopy := *n
 		ret := &(stmtCopy)
@@ -1646,7 +1700,7 @@ func (n *CopyTo) walkStmt(v Visitor) Statement {
 // walkStmt is part of the walkableStmt interface.
 func (stmt *Select) walkStmt(v Visitor) Statement {
 	ret := stmt
-	sel, changed := walkStmt(v, stmt.Select)
+	sel, changed := WalkStmt(v, stmt.Select)
 	if changed {
 		ret = stmt.copyNode()
 		ret.Select = sel.(SelectStatement)
@@ -1681,7 +1735,7 @@ func (stmt *Select) walkStmt(v Visitor) Statement {
 	if stmt.With != nil {
 		for i := range stmt.With.CTEList {
 			if stmt.With.CTEList[i] != nil {
-				withStmt, changed := walkStmt(v, stmt.With.CTEList[i].Stmt)
+				withStmt, changed := WalkStmt(v, stmt.With.CTEList[i].Stmt)
 				if changed {
 					if ret == stmt {
 						ret = stmt.copyNode()
@@ -1805,8 +1859,8 @@ func (stmt *SelectClause) walkStmt(v Visitor) Statement {
 }
 
 func (stmt *UnionClause) walkStmt(v Visitor) Statement {
-	left, changedL := walkStmt(v, stmt.Left)
-	right, changedR := walkStmt(v, stmt.Right)
+	left, changedL := WalkStmt(v, stmt.Left)
+	right, changedR := WalkStmt(v, stmt.Right)
 	if changedL || changedR {
 		stmtCopy := *stmt
 		stmtCopy.Left = left.(*Select)
@@ -2001,6 +2055,7 @@ var _ walkableStmt = &CreateTable{}
 var _ walkableStmt = &CreateTenant{}
 var _ walkableStmt = &CreateTenantFromReplication{}
 var _ walkableStmt = &Delete{}
+var _ walkableStmt = &DoBlock{}
 var _ walkableStmt = &DropTenant{}
 var _ walkableStmt = &Explain{}
 var _ walkableStmt = &Import{}
@@ -2010,22 +2065,24 @@ var _ walkableStmt = &Restore{}
 var _ walkableStmt = &SelectClause{}
 var _ walkableStmt = &Select{}
 var _ walkableStmt = &SetClusterSetting{}
+var _ walkableStmt = &SetTransaction{}
 var _ walkableStmt = &SetVar{}
+var _ walkableStmt = &ShowFingerprints{}
 var _ walkableStmt = &ShowTenantClusterSetting{}
 var _ walkableStmt = &ShowTenant{}
 var _ walkableStmt = &UnionClause{}
 var _ walkableStmt = &Update{}
 var _ walkableStmt = &ValuesClause{}
 
-// walkStmt walks the entire parsed stmt calling WalkExpr on each
+// WalkStmt walks the entire parsed stmt calling WalkExpr on each
 // expression, and replacing each expression with the one returned
 // by WalkExpr.
 //
-// NOTE: Beware that walkStmt does not necessarily traverse all parts of a
+// NOTE: Beware that WalkStmt does not necessarily traverse all parts of a
 // statement by itself. For example, it will not walk into Subquery nodes
 // within a FROM clause or into a JoinCond. Walk's logic is pretty
 // interdependent with the logic for constructing a query plan.
-func walkStmt(v Visitor, stmt Statement) (newStmt Statement, changed bool) {
+func WalkStmt(v Visitor, stmt Statement) (newStmt Statement, changed bool) {
 	walkable, ok := stmt.(walkableStmt)
 	if !ok {
 		return stmt, false
@@ -2077,7 +2134,7 @@ func SimpleVisit(expr Expr, preFn SimpleVisitFn) (Expr, error) {
 // for every node. The visitor stops as soon as an error is returned.
 func SimpleStmtVisit(stmt Statement, preFn SimpleVisitFn) (Statement, error) {
 	v := simpleVisitor{fn: preFn}
-	newStmt, changed := walkStmt(&v, stmt)
+	newStmt, changed := WalkStmt(&v, stmt)
 	if v.err != nil {
 		return nil, v.err
 	}
@@ -2121,7 +2178,7 @@ func ExprDebugString(expr Expr) string {
 // expressions that are part of the given statement.
 func StmtDebugString(stmt Statement) string {
 	v := debugVisitor{}
-	walkStmt(&v, stmt)
+	WalkStmt(&v, stmt)
 	return v.buf.String()
 }
 
diff --git a/pkg/sql/sem/tree/with.go b/pkg/sql/sem/tree/with.go
index 04ef398..907985a 100644
--- a/pkg/sql/sem/tree/with.go
+++ b/pkg/sql/sem/tree/with.go
@@ -1,12 +1,7 @@
 // Copyright 2017 The Cockroach Authors.
 //
-// Use of this software is governed by the Business Source License
-// included in the file licenses/BSL.txt.
-//
-// As of the Change Date specified in that file, in accordance with
-// the Business Source License, use of this software will be governed
-// by the Apache License, Version 2.0, included in the file
-// licenses/APL.txt.
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
 
 package tree
 
diff --git a/pkg/sql/sem/tree/zone.go b/pkg/sql/sem/tree/zone.go
index 2446309..f200679 100644
--- a/pkg/sql/sem/tree/zone.go
+++ b/pkg/sql/sem/tree/zone.go
@@ -1,12 +1,7 @@
 // Copyright 2017 The Cockroach Authors.
 //
-// Use of this software is governed by the Business Source License
-// included in the file licenses/BSL.txt.
-//
-// As of the Change Date specified in that file, in accordance with
-// the Business Source License, use of this software will be governed
-// by the Apache License, Version 2.0, included in the file
-// licenses/APL.txt.
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
 
 package tree
 
@@ -21,6 +16,11 @@ type ZoneSpecifier struct {
 
 	// Partition is only respected when Table is set.
 	Partition Name
+
+	// StarIndex is true if the special `table@*` specifier is used. It indicates
+	// that the zone configuration should be applied across all of a table's
+	// indexes. (e.g., ALTER PARTITION ... OF INDEX <tablename>@*)
+	StarIndex bool
 }
 
 // TelemetryName returns a name fitting for telemetry purposes.
@@ -51,7 +51,7 @@ func (node ZoneSpecifier) TargetsTable() bool {
 
 // TargetsIndex returns whether the zone specifier targets an index.
 func (node ZoneSpecifier) TargetsIndex() bool {
-	return node.TargetsTable() && node.TableOrIndex.Index != ""
+	return node.TargetsTable() && (node.TableOrIndex.Index != "" || node.StarIndex)
 }
 
 // TargetsPartition returns whether the zone specifier targets a partition.
@@ -79,6 +79,9 @@ func (node *ZoneSpecifier) Format(ctx *FmtCtx) {
 			ctx.WriteString("TABLE ")
 		}
 		ctx.FormatNode(&node.TableOrIndex)
+		if node.StarIndex {
+			ctx.WriteString("@*")
+		}
 	}
 }
 
@@ -104,9 +107,6 @@ func (node *ShowZoneConfig) Format(ctx *FmtCtx) {
 // statement.
 type SetZoneConfig struct {
 	ZoneSpecifier
-	// AllIndexes indicates that the zone configuration should be applied across
-	// all of a tables indexes. (ALTER PARTITION ... OF INDEX <tablename>@*)
-	AllIndexes bool
 	ZoneConfigSettings
 }
 
@@ -118,11 +118,15 @@ func (node *SetZoneConfig) Format(ctx *FmtCtx) {
 	node.ZoneConfigSettings.Format(ctx)
 }
 
+// modifiesSchema implements the canModifySchema interface.
+func (*SetZoneConfig) modifiesSchema() bool { return true }
+
 // ZoneConfigSettings represents info needed for zone config setting.
 type ZoneConfigSettings struct {
-	SetDefault bool
-	YAMLConfig Expr
-	Options    KVOptions
+	Discard    bool      // True for `CONFIGURE ZONE DISCARD` stmt
+	SetDefault bool      // True for `CONFIGURE ZONE USING DEFAULT` stmt
+	YAMLConfig Expr      // (Deprecated) Non-empty for `CONFIGURE ZONE = '<...yaml...>'` or `CONFIGURE ZONE = NULL` stmt
+	Options    KVOptions // Non-empty for `CONFIGURE ZONE USING var_set_list` stmt
 }
 
 // Format implements the NodeFormatter interface.
diff --git a/pkg/sql/sem/volatility/volatility.go b/pkg/sql/sem/volatility/volatility.go
index f07750a..0790cc6 100644
--- a/pkg/sql/sem/volatility/volatility.go
+++ b/pkg/sql/sem/volatility/volatility.go
@@ -1,12 +1,7 @@
 // Copyright 2020 The Cockroach Authors.
 //
-// Use of this software is governed by the Business Source License
-// included in the file licenses/BSL.txt.
-//
-// As of the Change Date specified in that file, in accordance with
-// the Business Source License, use of this software will be governed
-// by the Apache License, Version 2.0, included in the file
-// licenses/APL.txt.
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
 
 package volatility
 
@@ -46,13 +41,13 @@ const (
 	// Immutable means that the operator cannot modify the database, the
 	// transaction state, or any other state. It cannot depend on configuration
 	// settings and is guaranteed to return the same results given the same
-	// arguments in any context. ImmutableCopy operators can be constant folded.
+	// arguments in any context. Immutable operators can be constant folded.
 	// Examples: log, from_json.
 	Immutable
 	// Stable means that the operator cannot modify the database or the
 	// transaction state and is guaranteed to return the same results given the
-	// same arguments whenever it is evaluated within the same statement. Multiple
-	// calls to a stable operator can be optimized to a single call.
+	// same arguments whenever it is evaluated within the same statement.
+	// Multiple calls to a stable operator can be optimized to a single call.
 	// Examples: current_timestamp, current_date.
 	Stable
 	// Volatile means that the operator can do anything, including
diff --git a/pkg/sql/sessiondatapb/local_only_session_data.go b/pkg/sql/sessiondatapb/local_only_session_data.go
index 23600a5..6bf723d 100644
--- a/pkg/sql/sessiondatapb/local_only_session_data.go
+++ b/pkg/sql/sessiondatapb/local_only_session_data.go
@@ -1,12 +1,7 @@
 // Copyright 2021 The Cockroach Authors.
 //
-// Use of this software is governed by the Business Source License
-// included in the file licenses/BSL.txt.
-//
-// As of the Change Date specified in that file, in accordance with
-// the Business Source License, use of this software will be governed
-// by the Apache License, Version 2.0, included in the file
-// licenses/APL.txt.
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
 
 package sessiondatapb
 
@@ -133,13 +128,20 @@ const (
 	// can impact performance negatively.
 	SerialUsesSQLSequences SerialNormalizationMode = 2
 	// SerialUsesCachedSQLSequences is identical to SerialUsesSQLSequences with
-	// the exception that nodes can cache sequence values. This significantly
+	// the exception that sessions can cache sequence values. This significantly
 	// reduces contention and distributed calls to kv, which results in better
 	// performance. Gaps between sequences may be larger as a result of cached
 	// values being lost to errors and/or node failures.
 	SerialUsesCachedSQLSequences SerialNormalizationMode = 3
 	// SerialUsesUnorderedRowID means use INT NOT NULL DEFAULT unordered_unique_rowid().
 	SerialUsesUnorderedRowID SerialNormalizationMode = 4
+	// SerialUsesCachedNodeSQLSequences is identical to
+	// SerialUsesCachedSQLSequences, except the sequence values are cached per
+	// node instead of per session.
+	SerialUsesCachedNodeSQLSequences SerialNormalizationMode = 5
+	// maxSerialNormalizationMode should always be one larger than the last
+	// public value.
+	maxSerialNormalizationMode = 6
 )
 
 func (m SerialNormalizationMode) String() string {
@@ -154,6 +156,8 @@ func (m SerialNormalizationMode) String() string {
 		return "sql_sequence"
 	case SerialUsesCachedSQLSequences:
 		return "sql_sequence_cached"
+	case SerialUsesCachedNodeSQLSequences:
+		return "sql_sequence_cached_node"
 	default:
 		return fmt.Sprintf("invalid (%d)", m)
 	}
@@ -172,6 +176,8 @@ func SerialNormalizationModeFromString(val string) (_ SerialNormalizationMode, o
 		return SerialUsesSQLSequences, true
 	case "SQL_SEQUENCE_CACHED":
 		return SerialUsesCachedSQLSequences, true
+	case "SQL_SEQUENCE_CACHED_NODE":
+		return SerialUsesCachedNodeSQLSequences, true
 	default:
 		return 0, false
 	}
@@ -279,13 +285,10 @@ const (
 	// session default_transaction_quality_of_service value.
 	SystemLow = QoSLevel(admissionpb.LowPri)
 
-	// TTLStatsLow denotes a QoS level used internally by the TTL feature, which
-	// is not settable as a session default_transaction_quality_of_service value.
-	TTLStatsLow = QoSLevel(admissionpb.TTLLowPri)
-
-	// TTLLow denotes a QoS level used internally by the TTL feature, which is not
-	// settable as a session default_transaction_quality_of_service value.
-	TTLLow = QoSLevel(admissionpb.TTLLowPri)
+	// BulkLow denotes a QoS level used internally by the bulk operations (like
+	// LDR ingestion and TTL), which is not settable as a session
+	// default_transaction_quality_of_service value.
+	BulkLow = QoSLevel(admissionpb.BulkLowPri)
 
 	// UserLow denotes an end user QoS level lower than the default.
 	UserLow = QoSLevel(admissionpb.UserLowPri)
@@ -330,8 +333,8 @@ const (
 	// QoS level.
 	SystemLowName = "minimum"
 
-	// TTLLowName is the string value to display indicating a TTLLow QoS level.
-	TTLLowName = "ttl_low"
+	// BulkLowName is the string value to display indicating a BulkLow QoS level.
+	BulkLowName = "bulk_low"
 
 	// LockingNormalName is the string value to display indicating a
 	// LockingNormal QoS level.
@@ -342,9 +345,19 @@ const (
 	LockingHighName = "locking-high"
 )
 
+// When providing SessionData overrides to the internal executor,
+// we need to use pointers to specify the QoSLevel. Since we can't
+// use pointers to constants, we define these variables to use in
+// those cases.
+var (
+	SystemLowQoS = SystemLow
+	BulkLowQoS   = BulkLow
+	UserLowQoS   = UserLow
+)
+
 var qosLevelsDict = map[QoSLevel]string{
 	SystemLow:     SystemLowName,
-	TTLLow:        TTLLowName,
+	BulkLow:       BulkLowName,
 	UserLow:       UserLowName,
 	Normal:        NormalName,
 	LockingNormal: LockingNormalName,
@@ -353,14 +366,26 @@ var qosLevelsDict = map[QoSLevel]string{
 	SystemHigh:    SystemHighName,
 }
 
+func init() {
+	// Sanity check that all names for QoS levels use lower case (this
+	// assumption is used in ParseQoSLevelFromString).
+	for _, val := range qosLevelsDict {
+		if strings.ToLower(val) != val {
+			panic(errors.AssertionFailedf(
+				"expected only lower case letters in QoS level name %s", val,
+			))
+		}
+	}
+}
+
 // ParseQoSLevelFromString converts a string into a QoSLevel
 func ParseQoSLevelFromString(val string) (_ QoSLevel, ok bool) {
-	switch strings.ToUpper(val) {
-	case strings.ToUpper(UserHighName):
+	switch strings.ToLower(val) {
+	case UserHighName:
 		return UserHigh, true
-	case strings.ToUpper(UserLowName):
+	case UserLowName:
 		return UserLow, true
-	case strings.ToUpper(NormalName):
+	case NormalName:
 		return Normal, true
 	default:
 		return 0, false
diff --git a/pkg/sql/sessiondatapb/local_only_session_data.pb.go b/pkg/sql/sessiondatapb/local_only_session_data.pb.go
index 7dbc95c..fe0dd52 100644
--- a/pkg/sql/sessiondatapb/local_only_session_data.pb.go
+++ b/pkg/sql/sessiondatapb/local_only_session_data.pb.go
@@ -7,6 +7,7 @@ import (
 	encoding_binary "encoding/binary"
 	fmt "fmt"
 	github_com_cockroachdb_cockroach_pkg_security_username "github.com/cockroachdb/cockroachdb-parser/pkg/security/username"
+	hlc "github.com/cockroachdb/cockroachdb-parser/pkg/util/hlc"
 	_ "github.com/gogo/protobuf/gogoproto"
 	proto "github.com/gogo/protobuf/proto"
 	github_com_gogo_protobuf_sortkeys "github.com/gogo/protobuf/sortkeys"
@@ -58,6 +59,36 @@ func (ReplicationMode) EnumDescriptor() ([]byte, []int) {
 	return fileDescriptor_21ead158cf36da28, []int{0}
 }
 
+// PlanCacheMode controls the optimizer's decision to use a custom or generic
+// query plan.
+type PlanCacheMode int32
+
+const (
+	// PlanCacheModeForceCustom forces the optimizer to use a custom query plan.
+	PlanCacheModeForceCustom PlanCacheMode = 0
+	// PlanCacheModeForceCustom forces the optimizer to use a generic query plan.
+	PlanCacheModeForceGeneric PlanCacheMode = 1
+	// PlanCacheModeAuto allows the optimizer to automatically choose between a
+	// custom and generic query plan.
+	PlanCacheModeAuto PlanCacheMode = 2
+)
+
+var PlanCacheMode_name = map[int32]string{
+	0: "force_custom_plan",
+	1: "force_generic_plan",
+	2: "auto",
+}
+
+var PlanCacheMode_value = map[string]int32{
+	"force_custom_plan":  0,
+	"force_generic_plan": 1,
+	"auto":               2,
+}
+
+func (PlanCacheMode) EnumDescriptor() ([]byte, []int) {
+	return fileDescriptor_21ead158cf36da28, []int{1}
+}
+
 // LocalOnlySessionData contains the serializable components of session
 // parameters that only influence execution on the gateway nodes.
 type LocalOnlySessionData struct {
@@ -134,8 +165,7 @@ type LocalOnlySessionData struct {
 	// transaction.
 	ForceSavepointRestart bool `protobuf:"varint,19,opt,name=force_savepoint_restart,json=forceSavepointRestart,proto3" json:"force_savepoint_restart,omitempty"`
 	// AllowPrepareAsOptPlan must be set to allow use of
-	//
-	//	PREPARE name AS OPT PLAN '...'
+	//   PREPARE name AS OPT PLAN '...'
 	AllowPrepareAsOptPlan bool `protobuf:"varint,20,opt,name=allow_prepare_as_opt_plan,json=allowPrepareAsOptPlan,proto3" json:"allow_prepare_as_opt_plan,omitempty"`
 	// TempTablesEnabled indicates whether temporary tables can be created or not.
 	TempTablesEnabled bool `protobuf:"varint,21,opt,name=temp_tables_enabled,json=tempTablesEnabled,proto3" json:"temp_tables_enabled,omitempty"`
@@ -340,7 +370,7 @@ type LocalOnlySessionData struct {
 	TransactionTimeout time.Duration `protobuf:"varint,81,opt,name=transaction_timeout,json=transactionTimeout,proto3,casttype=time.Duration" json:"transaction_timeout,omitempty"`
 	// SystemIdentityProto is the original name of the client presented to pgwire
 	// before it was mapped to a SQL identifier.
-	SystemIdentityProto github_com_cockroachdb_cockroach_pkg_security_username.SQLUsernameProto `protobuf:"bytes,82,opt,name=system_identity_proto,json=systemIdentityProto,proto3,casttype=github.com/cockroachdb/cockroachdb-parser/pkg/security/username.SQLUsernameProto" json:"system_identity_proto,omitempty"`
+	SystemIdentityProto string `protobuf:"bytes,82,opt,name=system_identity_proto,json=systemIdentityProto,proto3" json:"system_identity_proto,omitempty"`
 	// DescriptorValidationMode indicates whether to validate the descriptors at
 	// read and write time, at read time only, or never.
 	DescriptorValidationMode DescriptorValidationMode `protobuf:"varint,83,opt,name=descriptor_validation_mode,json=descriptorValidationMode,proto3,casttype=DescriptorValidationMode" json:"descriptor_validation_mode,omitempty"`
@@ -402,11 +432,6 @@ type LocalOnlySessionData struct {
 	// Execution of these deallocated prepared statements will fail until they are
 	// prepared again.
 	PreparedStatementsCacheSize int64 `protobuf:"varint,97,opt,name=prepared_statements_cache_size,json=preparedStatementsCacheSize,proto3" json:"prepared_statements_cache_size,omitempty"`
-	// StreamerEnabled controls whether the Streamer API can be used.
-	StreamerEnabled bool `protobuf:"varint,98,opt,name=streamer_enabled,json=streamerEnabled,proto3" json:"streamer_enabled,omitempty"`
-	// DisableDropVirtualCluster causes errors when the client
-	// attempts to drop virtual clusters or tenant records.
-	DisableDropVirtualCluster bool `protobuf:"varint,99,opt,name=disable_drop_virtual_cluster,json=disableDropVirtualCluster,proto3" json:"disable_drop_virtual_cluster,omitempty"`
 	// MultipleActivePortalEnabled determines if the pgwire portal execution
 	// for certain queries can be paused. If true, portals with read-only SELECT
 	// query without sub/post queries can be executed in interleaving manner, but
@@ -497,7 +522,8 @@ type LocalOnlySessionData struct {
 	// fixes a bug that incorrectly truncated the provided ordering (see #113072).
 	OptimizerUseProvidedOrderingFix bool `protobuf:"varint,115,opt,name=optimizer_use_provided_ordering_fix,json=optimizerUseProvidedOrderingFix,proto3" json:"optimizer_use_provided_ordering_fix,omitempty"`
 	// DisableChangefeedReplication, when true, disables changefeed events from
-	// being emitted for changes to data made in a session.
+	// being emitted for changes to data made in a session. This will apply only
+	// to new txns created in the session.
 	DisableChangefeedReplication bool `protobuf:"varint,116,opt,name=disable_changefeed_replication,json=disableChangefeedReplication,proto3" json:"disable_changefeed_replication,omitempty"`
 	// CopyTxnQualityOfService indicates the default QoSLevel/WorkPriority of the
 	// transactions used to evaluate COPY commands.
@@ -505,9 +531,221 @@ type LocalOnlySessionData struct {
 	// CopyWritePipeliningEnabled indicates whether the write pipelining is
 	// enabled for implicit txns used by COPY.
 	CopyWritePipeliningEnabled bool `protobuf:"varint,118,opt,name=copy_write_pipelining_enabled,json=copyWritePipeliningEnabled,proto3" json:"copy_write_pipelining_enabled,omitempty"`
+	// OptimizerMergeJoinsEnabled, when true, instructs the optimizer to explore
+	// query plans with merge joins. When false, the optimizer does not attempt
+	// to plan merge joins.
+	OptimizerMergeJoinsEnabled bool `protobuf:"varint,119,opt,name=optimizer_merge_joins_enabled,json=optimizerMergeJoinsEnabled,proto3" json:"optimizer_merge_joins_enabled,omitempty"`
 	// CopyNumRetriesPerBatch determines the number of times a single batch of
 	// rows can be retried for non-atomic COPY.
 	CopyNumRetriesPerBatch int32 `protobuf:"varint,120,opt,name=copy_num_retries_per_batch,json=copyNumRetriesPerBatch,proto3" json:"copy_num_retries_per_batch,omitempty"`
+	// AutoCommitBeforeDDL will cause any DDL statement received during a
+	// multi-statement transaction to make the transaction auto-commit before
+	// executing the DDL statement. After the auto-commit, any other statements
+	// that are in the transaction block will instead be executed in their own
+	// implicit transaction.
+	AutoCommitBeforeDDL bool `protobuf:"varint,121,opt,name=autocommit_before_ddl,json=autocommitBeforeDdl,proto3" json:"autocommit_before_ddl,omitempty"`
+	// CloseCursorsAtCommit determines whether cursors remain open after their
+	// parent transaction closes. This is useful for oracle compatibility.
+	CloseCursorsAtCommit bool `protobuf:"varint,122,opt,name=close_cursors_at_commit,json=closeCursorsAtCommit,proto3" json:"close_cursors_at_commit,omitempty"`
+	// PLpgSQLUseStrictInto causes PL/pgSQL "SELECT ... INTO" and "RETURNING INTO"
+	// syntax to always behave as if they were specified with the STRICT option,
+	// which throws a runtime error when the SQL statement doesn't return exactly
+	// one row. This is useful for oracle compatibility.
+	PLpgSQLUseStrictInto bool `protobuf:"varint,123,opt,name=plpgsql_use_strict_into,json=plpgsqlUseStrictInto,proto3" json:"plpgsql_use_strict_into,omitempty"`
+	// OptimizerUseVirtualComputedColumnStats indicates whether we should use
+	// statistics on virtual computed columns for cardinality estimation in the
+	// optimizer.
+	OptimizerUseVirtualComputedColumnStats bool `protobuf:"varint,124,opt,name=optimizer_use_virtual_computed_column_stats,json=optimizerUseVirtualComputedColumnStats,proto3" json:"optimizer_use_virtual_computed_column_stats,omitempty"`
+	// OptimizerUseTrigramSimilarityOptimization indicates whether the optimizer
+	// should generate improved plans for queries with trigram similarity filters.
+	OptimizerUseTrigramSimilarityOptimization bool `protobuf:"varint,125,opt,name=optimizer_use_trigram_similarity_optimization,json=optimizerUseTrigramSimilarityOptimization,proto3" json:"optimizer_use_trigram_similarity_optimization,omitempty"`
+	// OptimizerUseImprovedDistinctOnLimitHintCosting indicates whether the
+	// optimizer should use an improved costing estimate for DistinctOn operators
+	// with limit hints.
+	OptimizerUseImprovedDistinctOnLimitHintCosting bool `protobuf:"varint,126,opt,name=optimizer_use_improved_distinct_on_limit_hint_costing,json=optimizerUseImprovedDistinctOnLimitHintCosting,proto3" json:"optimizer_use_improved_distinct_on_limit_hint_costing,omitempty"`
+	// OptimizerUseImprovedTrigramSimilaritySelectivity indicates whether the
+	// optimizer should use an improved selectivitiy estimate for trigram
+	// similarity filters.
+	OptimizerUseImprovedTrigramSimilaritySelectivity bool `protobuf:"varint,127,opt,name=optimizer_use_improved_trigram_similarity_selectivity,json=optimizerUseImprovedTrigramSimilaritySelectivity,proto3" json:"optimizer_use_improved_trigram_similarity_selectivity,omitempty"`
+	// OptimizerUseImprovedZigzagJoinCosting, when true, indicates that the
+	// optimizer should use improved logic in the cost model for zigzag joins.
+	OptimizerUseImprovedZigzagJoinCosting bool `protobuf:"varint,128,opt,name=optimizer_use_improved_zigzag_join_costing,json=optimizerUseImprovedZigzagJoinCosting,proto3" json:"optimizer_use_improved_zigzag_join_costing,omitempty"`
+	// OptimizerUseImprovedMultiColumnSelectivityEstimate, when true, indicates
+	// that the optimizer should use an improved selectivity estimate for
+	// multi-column predicates.
+	OptimizerUseImprovedMultiColumnSelectivityEstimate bool `protobuf:"varint,129,opt,name=optimizer_use_improved_multi_column_selectivity_estimate,json=optimizerUseImprovedMultiColumnSelectivityEstimate,proto3" json:"optimizer_use_improved_multi_column_selectivity_estimate,omitempty"`
+	// OptimizerProveImplicationWithVirtualComputedColumns, when true, indicates
+	// that the optimizer should use virtual computed columns to prove partial
+	// index implication.
+	OptimizerProveImplicationWithVirtualComputedColumns bool `protobuf:"varint,130,opt,name=optimizer_prove_implication_with_virtual_computed_columns,json=optimizerProveImplicationWithVirtualComputedColumns,proto3" json:"optimizer_prove_implication_with_virtual_computed_columns,omitempty"`
+	// OptimizerPushOffsetIntoIndexJoin, when true, indicates that the optimizer
+	// should push offset expressions into index joins.
+	OptimizerPushOffsetIntoIndexJoin bool `protobuf:"varint,132,opt,name=optimizer_push_offset_into_index_join,json=optimizerPushOffsetIntoIndexJoin,proto3" json:"optimizer_push_offset_into_index_join,omitempty"`
+	// PlanCacheMode indicates the method that the optimizer should use to choose
+	// between a custom and generic query plan.
+	PlanCacheMode PlanCacheMode `protobuf:"varint,133,opt,name=plan_cache_mode,json=planCacheMode,proto3,enum=cockroach.sql.sessiondatapb.PlanCacheMode" json:"plan_cache_mode,omitempty"`
+	// OptimizerUsePolymorphicParameterFix, when true, causes the optimizer to
+	// validate a routine's polymorphic parameters during overload resolution
+	// and type-checking.
+	OptimizerUsePolymorphicParameterFix bool `protobuf:"varint,134,opt,name=optimizer_use_polymorphic_parameter_fix,json=optimizerUsePolymorphicParameterFix,proto3" json:"optimizer_use_polymorphic_parameter_fix,omitempty"`
+	// OriginIDForLogicalDataReplication is an identifier for the cluster that
+	// originally wrote the data that are being written in this session. An
+	// originID of 0 (the default) identifies a local write, 1 identifies a remote
+	// write of unspecified origin, and 2+ are reserved to identify remote writes
+	// from specific clusters.
+	OriginIDForLogicalDataReplication uint32 `protobuf:"varint,135,opt,name=origin_id_for_logical_data_replication,json=originIdForLogicalDataReplication,proto3" json:"origin_id_for_logical_data_replication,omitempty"`
+	// EnableCreateStatsUsingExtremesBoolEnum, when true, allows the use of CREATE
+	// STATISTICS .. USING EXTREMES on bool and enum columns.
+	EnableCreateStatsUsingExtremesBoolEnum bool `protobuf:"varint,136,opt,name=enable_create_stats_using_extremes_bool_enum,json=enableCreateStatsUsingExtremesBoolEnum,proto3" json:"enable_create_stats_using_extremes_bool_enum,omitempty"`
+	// OptimizerUseMergedPartialStatistics indicates whether we should use
+	// statistics merged from partial and full statistics for cardinality
+	// estimation in the optimizer.
+	OptimizerUseMergedPartialStatistics bool `protobuf:"varint,137,opt,name=optimizer_use_merged_partial_statistics,json=optimizerUseMergedPartialStatistics,proto3" json:"optimizer_use_merged_partial_statistics,omitempty"`
+	// OptimizerUseConditionalHoistFix, when true, prevents the optimizer from
+	// hoisting a volatile expression that is conditionally executed by a CASE,
+	// COALESCE, or IFERR expression.
+	OptimizerUseConditionalHoistFix bool `protobuf:"varint,138,opt,name=optimizer_use_conditional_hoist_fix,json=optimizerUseConditionalHoistFix,proto3" json:"optimizer_use_conditional_hoist_fix,omitempty"`
+	// OptimizerPushLimitIntoProjectFilteredScan, when true, indicates that the
+	// optimizer should push limit expressions into projects of filtered scans.
+	OptimizerPushLimitIntoProjectFilteredScan bool `protobuf:"varint,139,opt,name=optimizer_push_limit_into_project_filtered_scan,json=optimizerPushLimitIntoProjectFilteredScan,proto3" json:"optimizer_push_limit_into_project_filtered_scan,omitempty"`
+	// OriginTimestampForLogicalDataReplication is the mvcc timestamp the data
+	// written in this session were originally written with before being
+	// replicated via Logical Data Replication.
+	OriginTimestampForLogicalDataReplication hlc.Timestamp `protobuf:"bytes,140,opt,name=origin_timestamp_for_logical_data_replication,json=originTimestampForLogicalDataReplication,proto3" json:"origin_timestamp_for_logical_data_replication"`
+	// BypassPCRReaderCatalogAOST disables the AOST used by all user queries on
+	// the PCR reader catalog.
+	BypassPCRReaderCatalogAOST bool `protobuf:"varint,141,opt,name=bypass_pcr_reader_catalog_aost,json=bypassPcrReaderCatalogAost,proto3" json:"bypass_pcr_reader_catalog_aost,omitempty"`
+	// UnsafeAllowTriggersModifyingCascades, when true, allows row-level BEFORE
+	// triggers to modify or filter rows that are being updated or deleted as
+	// part of a cascading foreign key action. This is unsafe because it can
+	// lead to constraint violations.
+	UnsafeAllowTriggersModifyingCascades bool `protobuf:"varint,142,opt,name=unsafe_allow_triggers_modifying_cascades,json=unsafeAllowTriggersModifyingCascades,proto3" json:"unsafe_allow_triggers_modifying_cascades,omitempty"`
+	// DisableVecUnionEagerCancellation disables the eager cancellation that is
+	// performed by the vectorized engine when transitioning into the draining
+	// state in some cases.
+	DisableVecUnionEagerCancellation bool `protobuf:"varint,143,opt,name=disable_vec_union_eager_cancellation,json=disableVecUnionEagerCancellation,proto3" json:"disable_vec_union_eager_cancellation,omitempty"`
+	// RecursionDepthLimit is the maximum depth that nested trigger-function calls
+	// can reach.
+	RecursionDepthLimit int64 `protobuf:"varint,144,opt,name=recursion_depth_limit,json=recursionDepthLimit,proto3" json:"recursion_depth_limit,omitempty"`
+	// DistributeGroupByRowCountThreshold is the minimum number of rows estimated
+	// to be processed by the GroupBy operator so that we choose to distribute the
+	// plan because of this aggregator stage of DistSQL processors.
+	DistributeGroupByRowCountThreshold uint64 `protobuf:"varint,145,opt,name=distribute_group_by_row_count_threshold,json=distributeGroupByRowCountThreshold,proto3" json:"distribute_group_by_row_count_threshold,omitempty"`
+	// DistributeSortRowCountThreshold is the minimum number of rows estimated
+	// to be processed by the Sort operator so that we choose to distribute the
+	// plan because of this sorter stage of DistSQL processors.
+	DistributeSortRowCountThreshold uint64 `protobuf:"varint,146,opt,name=distribute_sort_row_count_threshold,json=distributeSortRowCountThreshold,proto3" json:"distribute_sort_row_count_threshold,omitempty"`
+	// DistributeScanRowCountThreshold is the minimum number of rows estimated to
+	// be read by the Scan operator so that we choose to distribute the plan
+	// because of this TableReader stage of DistSQL processors.
+	DistributeScanRowCountThreshold uint64 `protobuf:"varint,147,opt,name=distribute_scan_row_count_threshold,json=distributeScanRowCountThreshold,proto3" json:"distribute_scan_row_count_threshold,omitempty"`
+	// AlwaysDistributeFullScans determines whether full table scans always force
+	// the plan to be distributed, regardless of the estimated row count.
+	AlwaysDistributeFullScans bool `protobuf:"varint,148,opt,name=always_distribute_full_scans,json=alwaysDistributeFullScans,proto3" json:"always_distribute_full_scans,omitempty"`
+	// DistributeJoinRowCountThreshold is the minimum number of rows estimated to
+	// be processed from both inputs by the hash or merge join so that we choose
+	// to distribute the plan because of this joiner stage of DistSQL processors.
+	DistributeJoinRowCountThreshold uint64 `protobuf:"varint,149,opt,name=distribute_join_row_count_threshold,json=distributeJoinRowCountThreshold,proto3" json:"distribute_join_row_count_threshold,omitempty"`
+	// LegacyVarcharTyping controls the legacy behavior of allowing some invalid
+	// mix-typed comparisons with VARCHAR types. See #137837, #133037, and
+	// #132268.
+	LegacyVarcharTyping bool `protobuf:"varint,150,opt,name=legacy_varchar_typing,json=legacyVarcharTyping,proto3" json:"legacy_varchar_typing,omitempty"`
+	// AvoidFullTableScansInMutations indicates whether mutation queries that plan
+	// full table scans should be avoided.
+	AvoidFullTableScansInMutations bool `protobuf:"varint,151,opt,name=avoid_full_table_scans_in_mutations,json=avoidFullTableScansInMutations,proto3" json:"avoid_full_table_scans_in_mutations,omitempty"`
+	// CatalogDigestStalenessCheckEnabled is used to enable using the catalog
+	// digest information to do fast memo checks.
+	CatalogDigestStalenessCheckEnabled bool `protobuf:"varint,153,opt,name=catalog_digest_staleness_check_enabled,json=catalogDigestStalenessCheckEnabled,proto3" json:"catalog_digest_staleness_check_enabled,omitempty"`
+	// OptimizerPreferBoundedCardinality instructs the optimizer to prefer query
+	// plans in which every expression has a bounded cardinality over plans with
+	// one or more expressions with unbounded cardinality.
+	OptimizerPreferBoundedCardinality bool `protobuf:"varint,154,opt,name=optimizer_prefer_bounded_cardinality,json=optimizerPreferBoundedCardinality,proto3" json:"optimizer_prefer_bounded_cardinality,omitempty"`
+	// OptimizerMinRowCount sets a lower bound on row count estimates for
+	// relational expressions during query planning. A value of zero indicates no
+	// lower bound. Note that if this is set to a value greater than zero, a row
+	// count of zero can still be estimated for expressions with a cardinality of
+	// zero, e.g., for a contradictory filter.
+	OptimizerMinRowCount float64 `protobuf:"fixed64,155,opt,name=optimizer_min_row_count,json=optimizerMinRowCount,proto3" json:"optimizer_min_row_count,omitempty"`
+	// BufferedWritesEnabled controls whether the buffered writes KV transaction
+	// protocol is used for user queries on the current session. If this variable
+	// is modified in an explicit txn, then the change will be applied only to
+	// future txns on the session.
+	BufferedWritesEnabled bool `protobuf:"varint,156,opt,name=buffered_writes_enabled,json=bufferedWritesEnabled,proto3" json:"buffered_writes_enabled,omitempty"`
+	// OptimizerCheckInputMinRowCount sets a lower bound on row count estimates
+	// for the buffer scan of FK and uniqueness checks. A value of zero indicates
+	// no lower bound.
+	OptimizerCheckInputMinRowCount float64 `protobuf:"fixed64,157,opt,name=optimizer_check_input_min_row_count,json=optimizerCheckInputMinRowCount,proto3" json:"optimizer_check_input_min_row_count,omitempty"`
+	// OptimizerPlanLookupJoinsWithReverseScans enables planning for lookup joins
+	// that use reverse scans to get results in reverse index order on each
+	// lookup.
+	OptimizerPlanLookupJoinsWithReverseScans bool `protobuf:"varint,158,opt,name=optimizer_plan_lookup_joins_with_reverse_scans,json=optimizerPlanLookupJoinsWithReverseScans,proto3" json:"optimizer_plan_lookup_joins_with_reverse_scans,omitempty"`
+	// RegisterLatchWaitContentionEvents, when true, causes latch wait contention
+	// events to be registered with the *.contention_events virtual tables. It
+	// defaults to false in order to avoid registering a large number of
+	// uninformative latch wait events.
+	RegisterLatchWaitContentionEvents bool `protobuf:"varint,159,opt,name=register_latch_wait_contention_events,json=registerLatchWaitContentionEvents,proto3" json:"register_latch_wait_contention_events,omitempty"`
+	// UseCPutsOnNonUniqueIndexes, when true, indicates that CPuts should be used
+	// when writing new KVs into the non-unique indexes. It is an escape hatch in
+	// case our thinking that we don't need the CPut in such a scenario is wrong.
+	//
+	// This will have impact regardless of the buffered writes.
+	UseCPutsOnNonUniqueIndexes bool `protobuf:"varint,160,opt,name=use_cputs_on_non_unique_indexes,json=useCputsOnNonUniqueIndexes,proto3" json:"use_cputs_on_non_unique_indexes,omitempty"`
+	// BufferedWritesUseLockingOnNonUniqueIndexes, when true, indicates that
+	// locking Puts and Dels should be used when writing into the non-unique
+	// indexes.
+	//
+	// This will only have impact when BufferedWritesEnabled is set.
+	BufferedWritesUseLockingOnNonUniqueIndexes bool `protobuf:"varint,161,opt,name=buffered_writes_use_locking_on_non_unique_indexes,json=bufferedWritesUseLockingOnNonUniqueIndexes,proto3" json:"buffered_writes_use_locking_on_non_unique_indexes,omitempty"`
+	// OptimizerUseLockElisionMultipleFamilies, when true, indicates that the lock
+	// eliding optimization should be enabled for tables with multiple column
+	// families.
+	//
+	// This will only have impact when BufferedWritesEnabled is set.
+	OptimizerUseLockElisionMultipleFamilies bool `protobuf:"varint,162,opt,name=optimizer_use_lock_elision_multiple_families,json=optimizerUseLockElisionMultipleFamilies,proto3" json:"optimizer_use_lock_elision_multiple_families,omitempty"`
+	// OptimizerEnableLockElision, when false, indicates that the lock eliding
+	// optimization should be disabled for tables with any number of column
+	// families. It takes precedence over OptimizerUseLockElisionMultipleFamilies.
+	//
+	// This will only have impact when BufferedWritesEnabled is set.
+	OptimizerEnableLockElision bool `protobuf:"varint,163,opt,name=optimizer_enable_lock_elision,json=optimizerEnableLockElision,proto3" json:"optimizer_enable_lock_elision,omitempty"`
+	// OptimizerUseDeleteRangeFastPath, when true, indicates that the optimizer
+	// should try to use the delete range fast-path when possible.
+	OptimizerUseDeleteRangeFastPath bool `protobuf:"varint,164,opt,name=optimizer_use_delete_range_fast_path,json=optimizerUseDeleteRangeFastPath,proto3" json:"optimizer_use_delete_range_fast_path,omitempty"`
+	// AllowCreateTriggerFunctionWithArgvReferences, when true, allows triggers to
+	// be created with trigger functions that use the TG_ARGV parameter even
+	// though it currently doesn't have Postgres-compatible 0-based indexing
+	// behavior.
+	AllowCreateTriggerFunctionWithArgvReferences bool `protobuf:"varint,165,opt,name=allow_create_trigger_function_with_argv_references,json=allowCreateTriggerFunctionWithArgvReferences,proto3" json:"allow_create_trigger_function_with_argv_references,omitempty"`
+	// UsePre_25_2VariadicBuiltins, when true, will treat variadic builtins with a
+	// types.Any variadic argument as types.AnyElement (the pre-25.2 behavior)
+	UsePre_25_2VariadicBuiltins bool `protobuf:"varint,167,opt,name=use_pre_25_2_variadic_builtins,json=usePre252VariadicBuiltins,proto3" json:"use_pre_25_2_variadic_builtins,omitempty"`
+	// VectorSearchBeamSize controls the number of candidates examined during
+	// vector index searches. It represents the number of vector partitions that
+	// are considered at each level of the search tree. Higher values increase
+	// search accuracy but require more processing resources.
+	VectorSearchBeamSize int32 `protobuf:"varint,168,opt,name=vector_search_beam_size,json=vectorSearchBeamSize,proto3" json:"vector_search_beam_size,omitempty"`
+	// PropagateAdmissionHeaderToLeafTransactions, when true, causes leaf
+	// transactions to inherit the admission header from the root transaction.
+	PropagateAdmissionHeaderToLeafTransactions bool `protobuf:"varint,169,opt,name=propagate_admission_header_to_leaf_transactions,json=propagateAdmissionHeaderToLeafTransactions,proto3" json:"propagate_admission_header_to_leaf_transactions,omitempty"`
+	// OptimizerUseExistsFilterHoistRule, when true, causes the optimizer to apply
+	// the HoistUnboundFilterFromExistsSubquery rule to EXISTS conditions.
+	OptimizerUseExistsFilterHoistRule bool `protobuf:"varint,170,opt,name=optimizer_use_exists_filter_hoist_rule,json=optimizerUseExistsFilterHoistRule,proto3" json:"optimizer_use_exists_filter_hoist_rule,omitempty"`
+	// InitialRetryBackoffForReadCommitted controls the initial backoff
+	// duration for automatic retries of statements in explicit READ COMMITTED
+	// transactions that see a transaction retry error. 0 disables backoff.
+	InitialRetryBackoffForReadCommitted time.Duration `protobuf:"varint,171,opt,name=initial_retry_backoff_for_read_committed,json=initialRetryBackoffForReadCommitted,proto3,casttype=time.Duration" json:"initial_retry_backoff_for_read_committed,omitempty"`
+	// UseProcTxnControlExtendedProtocolFix, when true, enables the fix for
+	// PL/pgSQL transaction control statements (COMMIT, ROLLBACK) when the stored
+	// procedure is executed via a portal in the extended wire protocol.
+	UseProcTxnControlExtendedProtocolFix bool `protobuf:"varint,175,opt,name=use_proc_txn_control_extended_protocol_fix,json=useProcTxnControlExtendedProtocolFix,proto3" json:"use_proc_txn_control_extended_protocol_fix,omitempty"`
+	// DisableOptimizerRules is a list of optimizer rules that should be disabled
+	// during query optimization. The names of the rules can be found in the
+	// opt/rule_name.og.go file.
+	DisableOptimizerRules []string `protobuf:"bytes,184,rep,name=disable_optimizer_rules,json=disableOptimizerRules,proto3" json:"disable_optimizer_rules,omitempty"`
+	// UseSoftLimitForDistributeScan, if set, means that we'll use the soft limit
+	// hint - if available - when comparing against
+	// DistributeScanRowCountThreshold.
+	UseSoftLimitForDistributeScan bool `protobuf:"varint,185,opt,name=use_soft_limit_for_distribute_scan,json=useSoftLimitForDistributeScan,proto3" json:"use_soft_limit_for_distribute_scan,omitempty"`
 }
 
 func (m *LocalOnlySessionData) Reset()         { *m = LocalOnlySessionData{} }
@@ -586,6 +824,7 @@ var xxx_messageInfo_SequenceCacheEntry proto.InternalMessageInfo
 
 func init() {
 	proto.RegisterEnum("cockroach.parser.sql.sessiondatapb.ReplicationMode", ReplicationMode_name, ReplicationMode_value)
+	proto.RegisterEnum("cockroach.parser.sql.sessiondatapb.PlanCacheMode", PlanCacheMode_name, PlanCacheMode_value)
 	proto.RegisterType((*LocalOnlySessionData)(nil), "cockroach.parser.sql.sessiondatapb.LocalOnlySessionData")
 	proto.RegisterMapType((map[string]string)(nil), "cockroach.parser.sql.sessiondatapb.LocalOnlySessionData.CustomOptionsEntry")
 	proto.RegisterMapType((SequenceCache)(nil), "cockroach.parser.sql.sessiondatapb.LocalOnlySessionData.SequenceCacheEntry")
@@ -597,243 +836,356 @@ func init() {
 }
 
 var fileDescriptor_21ead158cf36da28 = []byte{
-	// 3770 bytes of a gzipped FileDescriptorProto
-	0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xac, 0x5a, 0x5b, 0x77, 0x14, 0x49,
-	0x72, 0x46, 0x03, 0xb3, 0x86, 0xe4, 0x26, 0x0a, 0x31, 0x2a, 0x24, 0x50, 0x8b, 0xeb, 0x68, 0x98,
-	0x41, 0x9a, 0x85, 0xf5, 0x2c, 0x33, 0xeb, 0xf5, 0x8e, 0xd4, 0x17, 0x68, 0x10, 0x74, 0xd3, 0x2d,
-	0x60, 0x87, 0xf1, 0x6e, 0x3a, 0x55, 0x95, 0xdd, 0x9d, 0xa8, 0xba, 0xb2, 0x94, 0x99, 0x25, 0xd4,
-	0x3c, 0xd8, 0x7f, 0xc1, 0xe7, 0xf8, 0xd9, 0xff, 0x67, 0x1f, 0xf7, 0x71, 0x9e, 0x74, 0x6c, 0xcd,
-	0x4f, 0xf0, 0x1b, 0x4f, 0x3e, 0x11, 0x99, 0x59, 0x5d, 0xad, 0xcb, 0xd8, 0xc7, 0x67, 0xdf, 0x44,
-	0xc6, 0x17, 0x91, 0x99, 0x51, 0x91, 0x11, 0x5f, 0x44, 0x43, 0x56, 0xf4, 0x76, 0xb2, 0xa2, 0xb9,
-	0xd6, 0x42, 0xa6, 0x31, 0x33, 0x2c, 0xdb, 0x5c, 0x49, 0x64, 0xc4, 0x12, 0x2a, 0xd3, 0x64, 0x44,
-	0x9d, 0x80, 0x82, 0x64, 0x39, 0x53, 0xd2, 0xc8, 0x60, 0x3e, 0x92, 0xd1, 0x96, 0x92, 0x2c, 0x1a,
-	0x2c, 0xeb, 0xed, 0x64, 0x79, 0x42, 0x75, 0x6e, 0xa6, 0x2f, 0xfb, 0x12, 0x71, 0x2b, 0xf0, 0x97,
-	0x55, 0xb9, 0xf9, 0xdf, 0xab, 0x64, 0x66, 0x1d, 0x8c, 0xb6, 0xd2, 0x64, 0xd4, 0xb5, 0x0a, 0x35,
-	0x66, 0x58, 0xf0, 0x15, 0x09, 0x34, 0xdb, 0xe1, 0xd4, 0xb0, 0xcd, 0x84, 0x6b, 0x9a, 0x29, 0xde,
-	0x13, 0xbb, 0xe1, 0xd4, 0xe2, 0xd4, 0xd2, 0x99, 0xce, 0x34, 0x48, 0x36, 0x50, 0xd0, 0xc6, 0xf5,
-	0xe0, 0x47, 0x32, 0x2f, 0x33, 0x23, 0x86, 0xe2, 0x03, 0x57, 0xb4, 0xb7, 0x45, 0x23, 0xa6, 0x23,
-	0x16, 0x73, 0x4d, 0x13, 0x31, 0x14, 0x26, 0xfc, 0x64, 0x71, 0x6a, 0xe9, 0xe4, 0xda, 0xb5, 0xfd,
-	0xbd, 0x4a, 0xd8, 0xf2, 0xb0, 0xc6, 0xb3, 0xaa, 0x03, 0xad, 0x03, 0xa6, 0x13, 0x16, 0x06, 0x1a,
-	0x5b, 0x13, 0x92, 0xe0, 0x37, 0xe4, 0x9c, 0x36, 0x43, 0x43, 0x8d, 0x18, 0x72, 0x99, 0x9b, 0xf0,
-	0x24, 0x5a, 0xbb, 0xf4, 0x71, 0xaf, 0x72, 0x1e, 0x96, 0x96, 0x6b, 0xb9, 0x62, 0x46, 0xc8, 0xb4,
-	0x73, 0x16, 0x60, 0x1b, 0x16, 0x15, 0x3c, 0x21, 0xb3, 0x22, 0x4e, 0x38, 0x15, 0x69, 0xe1, 0x2a,
-	0x6f, 0xe0, 0xd4, 0x71, 0x06, 0x66, 0x40, 0xa3, 0x99, 0x3a, 0x3f, 0x78, 0x4b, 0x94, 0xdc, 0xf2,
-	0x96, 0x8c, 0x62, 0xa9, 0x66, 0x11, 0x80, 0x0f, 0x59, 0xfd, 0xf4, 0x38, 0xab, 0x15, 0x6b, 0x75,
-	0x63, 0xac, 0x7b, 0x60, 0x83, 0x6f, 0xc8, 0x6c, 0x2a, 0x8d, 0x88, 0x38, 0x8d, 0x85, 0xce, 0x12,
-	0x06, 0x1f, 0x77, 0x87, 0x2b, 0x61, 0x46, 0xe1, 0xaf, 0x16, 0xa7, 0x96, 0xce, 0x77, 0xae, 0x58,
-	0x71, 0xcd, 0x4a, 0xbb, 0x4e, 0x18, 0x2c, 0x93, 0xcb, 0x8a, 0x4b, 0x15, 0x73, 0x45, 0xdf, 0x49,
-	0x91, 0x7a, 0x6f, 0xff, 0x1d, 0x1c, 0xa4, 0x73, 0xc9, 0x89, 0x9e, 0x82, 0xc4, 0x3a, 0xf2, 0x6b,
-	0x32, 0x13, 0xf3, 0x1e, 0xcb, 0x13, 0x43, 0xcd, 0x6e, 0x4a, 0x33, 0x25, 0x24, 0x6e, 0x72, 0x1a,
-	0x15, 0x02, 0x27, 0xdb, 0xd8, 0x4d, 0xdb, 0x4e, 0x12, 0xfc, 0x9a, 0x5c, 0x29, 0x6b, 0x28, 0xce,
-	0x62, 0x8c, 0xbe, 0xf0, 0xcc, 0xe2, 0xd4, 0xd2, 0xe9, 0xb2, 0x4a, 0x87, 0xb3, 0x18, 0x62, 0x28,
-	0x58, 0x23, 0x0b, 0x65, 0x95, 0x5c, 0x73, 0xda, 0x93, 0x49, 0x22, 0xdf, 0x73, 0x85, 0xfa, 0x3a,
-	0x24, 0xa8, 0x3b, 0x37, 0xd6, 0x7d, 0xa5, 0x79, 0xc3, 0x41, 0xc0, 0x8c, 0x0e, 0x5a, 0xe4, 0x76,
-	0xc6, 0x94, 0x11, 0x2c, 0x49, 0x46, 0xe0, 0x13, 0xa3, 0xc4, 0x66, 0x6e, 0x78, 0x4c, 0xb3, 0x84,
-	0xa5, 0x1a, 0x56, 0x20, 0xf8, 0xe2, 0xf0, 0x2c, 0x5a, 0xba, 0x51, 0x60, 0x6b, 0x63, 0x68, 0x1b,
-	0x90, 0x35, 0x07, 0x0c, 0x1e, 0x91, 0x71, 0x78, 0xe1, 0x91, 0x06, 0x42, 0x1b, 0xd9, 0x57, 0x6c,
-	0xa8, 0xc3, 0x73, 0x68, 0xe4, 0xb3, 0x42, 0xfe, 0x4a, 0xf3, 0x27, 0x85, 0x34, 0xf8, 0x9e, 0x5c,
-	0x9f, 0xd4, 0x1c, 0xe6, 0x89, 0x11, 0x34, 0x92, 0x09, 0xd5, 0x86, 0x19, 0x1d, 0x9e, 0x47, 0xf5,
-	0xab, 0x65, 0xf5, 0xe7, 0x00, 0xa9, 0xca, 0xa4, 0x0b, 0x80, 0xe0, 0x3b, 0x72, 0x15, 0x9f, 0xad,
-	0x30, 0x23, 0xea, 0x51, 0x31, 0xd5, 0x9c, 0xa9, 0x68, 0x10, 0x5e, 0x40, 0xed, 0x59, 0x0f, 0xf0,
-	0xaf, 0x23, 0xee, 0xa2, 0x38, 0xb8, 0x41, 0xce, 0x69, 0xd6, 0xe3, 0x34, 0xcf, 0x62, 0x66, 0xb8,
-	0x0e, 0x2f, 0x22, 0xfc, 0x2c, 0xac, 0xbd, 0xb2, 0x4b, 0xc1, 0x0f, 0x64, 0x1e, 0x1e, 0x27, 0x57,
-	0x34, 0x91, 0x72, 0x2b, 0xcf, 0x5c, 0x28, 0xf4, 0x24, 0x3c, 0x44, 0x1d, 0x4e, 0x83, 0xc6, 0xda,
-	0xfc, 0xfe, 0x5e, 0x65, 0xb6, 0x8d, 0xb0, 0x75, 0x44, 0x61, 0x54, 0x34, 0xa4, 0x6a, 0x3c, 0xd3,
-	0x9d, 0xd9, 0xec, 0x28, 0xc1, 0x96, 0x86, 0xf8, 0xfa, 0x20, 0xfa, 0x1f, 0x58, 0x1f, 0x6d, 0x52,
-	0x9e, 0x5a, 0xaf, 0x5f, 0xc2, 0x43, 0x5c, 0xb2, 0x22, 0xc0, 0xd7, 0xad, 0x20, 0x58, 0x25, 0xd7,
-	0x15, 0xdf, 0xce, 0x85, 0xe2, 0x94, 0xef, 0x66, 0x89, 0x88, 0x84, 0x81, 0x20, 0x1b, 0x32, 0x35,
-	0xa2, 0x5b, 0x7c, 0xa4, 0xc3, 0xc0, 0x7e, 0x79, 0x07, 0xaa, 0x3b, 0x4c, 0xdb, 0x42, 0x9e, 0xf1,
-	0x91, 0x86, 0xa7, 0xd0, 0x93, 0x2a, 0xe2, 0x14, 0x52, 0x4c, 0x26, 0x45, 0x6a, 0xa8, 0xe2, 0xda,
-	0x30, 0x65, 0xc2, 0xcb, 0xa8, 0x7c, 0x05, 0xc5, 0x5d, 0x2f, 0xed, 0x58, 0x61, 0xf0, 0x88, 0x5c,
-	0x65, 0x10, 0x41, 0x90, 0xa8, 0x32, 0xa6, 0x38, 0x65, 0x1a, 0x9c, 0x8d, 0x01, 0x13, 0xce, 0x58,
-	0x4d, 0x04, 0xb4, 0xad, 0x7c, 0x55, 0xb7, 0x32, 0x03, 0x31, 0x02, 0x97, 0x34, 0x7c, 0x98, 0xf9,
-	0x44, 0xe7, 0x2f, 0x79, 0xc5, 0x5e, 0x12, 0x44, 0x36, 0xd3, 0xf9, 0x4b, 0xb6, 0xc8, 0x6d, 0x31,
-	0x74, 0x97, 0x8b, 0x64, 0x92, 0x0f, 0x53, 0x8a, 0xf1, 0x07, 0xef, 0x5a, 0xa4, 0xfd, 0xc2, 0xc0,
-	0x67, 0x36, 0x36, 0x3d, 0xb6, 0x8a, 0xd0, 0x76, 0x09, 0xe9, 0x0d, 0xbe, 0x21, 0x5f, 0xc8, 0x1d,
-	0xae, 0x94, 0x88, 0x7d, 0x70, 0x29, 0xde, 0x87, 0xc4, 0xf2, 0x41, 0xa6, 0x9c, 0x46, 0x32, 0xed,
-	0x89, 0xb1, 0xd5, 0x10, 0xad, 0xde, 0xf6, 0x0a, 0x18, 0x69, 0x1d, 0x84, 0xbf, 0x95, 0x29, 0xaf,
-	0x22, 0xd8, 0x1b, 0xfe, 0x96, 0x5c, 0x85, 0x97, 0x82, 0x6e, 0xe9, 0xe5, 0x49, 0x62, 0xaf, 0x48,
-	0x75, 0xc4, 0x52, 0x1d, 0xce, 0xd9, 0xa8, 0xf7, 0x80, 0x46, 0x9e, 0x24, 0x78, 0xcf, 0x2e, 0x48,
-	0x83, 0xdf, 0x91, 0xb9, 0xe2, 0x92, 0x9a, 0x27, 0x3c, 0x32, 0x18, 0x50, 0x36, 0x0c, 0xc3, 0x79,
-	0x1b, 0xb4, 0x1e, 0xd1, 0x45, 0x40, 0x43, 0x2a, 0x1b, 0x92, 0xc1, 0x12, 0x99, 0x16, 0xa9, 0xe6,
-	0xca, 0xd0, 0x1e, 0xd3, 0x86, 0x66, 0xcc, 0x0c, 0xc2, 0x6b, 0xa8, 0x72, 0xc1, 0xae, 0x37, 0x98,
-	0x36, 0x6d, 0x66, 0x06, 0xc1, 0x13, 0x72, 0x83, 0x25, 0x86, 0x2b, 0xef, 0x48, 0x33, 0xca, 0x38,
-	0xed, 0xf3, 0x94, 0x2b, 0x96, 0x14, 0x57, 0xbe, 0x8e, 0xaa, 0xd7, 0x11, 0x68, 0xbd, 0xb8, 0x31,
-	0xca, 0xf8, 0x63, 0x8b, 0xf2, 0x77, 0xbd, 0x4f, 0x02, 0x3d, 0x4a, 0xa3, 0x81, 0x92, 0xa9, 0xcc,
-	0x35, 0x8d, 0xe4, 0x10, 0x32, 0xe1, 0x82, 0xfd, 0x88, 0x25, 0x49, 0x15, 0x05, 0xc1, 0x5d, 0x72,
-	0xd1, 0x9a, 0xa7, 0x9a, 0x6f, 0xa3, 0x47, 0xc2, 0x0a, 0x62, 0xcf, 0xdb, 0xe5, 0x2e, 0xdf, 0x06,
-	0x47, 0x04, 0x1b, 0xe4, 0x73, 0x87, 0xcb, 0x53, 0xb1, 0x9d, 0x73, 0xfa, 0x5e, 0x98, 0x81, 0xcc,
-	0x0d, 0x15, 0x69, 0xcc, 0x77, 0xe1, 0xe3, 0x68, 0xa3, 0x98, 0x48, 0x8d, 0x0e, 0x6f, 0xa0, 0xfe,
-	0x2d, 0x0b, 0x7f, 0x85, 0xe8, 0x37, 0x16, 0xdc, 0x04, 0x6c, 0x75, 0x0c, 0x0d, 0x7e, 0x4f, 0xe6,
-	0xb5, 0xc9, 0x37, 0x69, 0xc4, 0x0c, 0x4b, 0x64, 0xff, 0x60, 0xe8, 0xdd, 0x44, 0x4b, 0x21, 0x40,
-	0xaa, 0x16, 0x31, 0x19, 0x81, 0x2f, 0xc9, 0x1d, 0xbe, 0x9b, 0x71, 0x25, 0x86, 0x3c, 0x35, 0x2c,
-	0x81, 0xcb, 0x66, 0x98, 0x1d, 0x9d, 0x17, 0x15, 0x7f, 0xaf, 0x04, 0x64, 0x8b, 0x5b, 0x58, 0xad,
-	0x6f, 0x96, 0xc1, 0x55, 0x87, 0xb5, 0x8e, 0xec, 0x38, 0x24, 0xe4, 0x28, 0xef, 0x0f, 0xa3, 0x38,
-	0x1b, 0x52, 0xc5, 0xe1, 0xdb, 0x62, 0xfd, 0x0a, 0xef, 0xd8, 0xcf, 0xed, 0x3c, 0x83, 0xf2, 0xce,
-	0x58, 0x6c, 0xab, 0x90, 0xce, 0x13, 0xa3, 0xe9, 0x66, 0xde, 0x83, 0x44, 0xa4, 0xc5, 0x07, 0x1e,
-	0xde, 0xf5, 0x55, 0x08, 0x45, 0x6b, 0x28, 0xe9, 0x8a, 0x0f, 0x1c, 0x72, 0x71, 0xa6, 0x64, 0xc6,
-	0xfa, 0xcc, 0x40, 0x4d, 0xcd, 0x72, 0x43, 0xb1, 0x50, 0x89, 0xb4, 0x1f, 0x7e, 0x6e, 0xa3, 0xb2,
-	0x90, 0x37, 0x41, 0xdc, 0x72, 0xd2, 0xe0, 0xdf, 0xa7, 0xc8, 0xc4, 0x65, 0xb0, 0x34, 0xe8, 0xed,
-	0x04, 0x5f, 0x39, 0x3e, 0xbe, 0xa1, 0x8c, 0x79, 0xb8, 0x84, 0x85, 0xb8, 0xb1, 0xbf, 0x57, 0xa9,
-	0xd4, 0x4b, 0x68, 0x28, 0x0e, 0xdd, 0x97, 0xeb, 0x6d, 0x87, 0x7d, 0x2e, 0x63, 0xfe, 0xf1, 0x7f,
-	0x87, 0x74, 0x2a, 0xfc, 0x00, 0x40, 0x6f, 0x27, 0x65, 0x40, 0xd0, 0x20, 0xe7, 0xe1, 0x1c, 0x14,
-	0x0e, 0x82, 0xfb, 0x7f, 0x81, 0xfb, 0xdf, 0xdc, 0xdf, 0xab, 0x9c, 0x75, 0x06, 0xdd, 0x5e, 0x17,
-	0xdd, 0x3f, 0xeb, 0xbb, 0x3c, 0x42, 0xdb, 0x67, 0x41, 0xb1, 0xbb, 0x9d, 0xa0, 0x9d, 0x37, 0xe4,
-	0xaa, 0xe6, 0x4a, 0xb0, 0x84, 0xa6, 0x52, 0x0d, 0x59, 0x22, 0x3e, 0xa0, 0x7f, 0xad, 0xcd, 0x7b,
-	0x68, 0x73, 0xfe, 0xe3, 0x5e, 0x65, 0xb6, 0x8b, 0xa0, 0x17, 0x65, 0x0c, 0x1a, 0x9b, 0xd5, 0x47,
-	0x0b, 0x82, 0x16, 0x99, 0x4d, 0xf9, 0x7b, 0xaa, 0xa3, 0x01, 0x1f, 0x32, 0x1a, 0x0d, 0x58, 0xda,
-	0xe7, 0xca, 0x9a, 0xfd, 0x12, 0xcd, 0x86, 0x1f, 0xf7, 0x2a, 0x33, 0x2f, 0xf8, 0xfb, 0x2e, 0x22,
-	0xaa, 0x16, 0x80, 0x36, 0x67, 0xd2, 0x23, 0x56, 0x83, 0x7f, 0x21, 0x17, 0x34, 0xdf, 0xce, 0x79,
-	0x1a, 0x71, 0x1a, 0xb1, 0x68, 0xc0, 0xc3, 0xaf, 0x16, 0x4f, 0x2e, 0x9d, 0x7d, 0x50, 0x5b, 0xfe,
-	0x05, 0x02, 0xba, 0x7c, 0x14, 0xcd, 0x5c, 0xee, 0x3a, 0x3b, 0x55, 0x30, 0x53, 0x4f, 0x8d, 0x1a,
-	0x59, 0x06, 0x35, 0xb1, 0xde, 0x39, 0xaf, 0xcb, 0xff, 0x0c, 0xbe, 0x24, 0x97, 0xb2, 0x84, 0x45,
-	0x1c, 0xbe, 0x49, 0xf1, 0x6a, 0xee, 0x63, 0xe8, 0x4c, 0x17, 0x02, 0xff, 0x5a, 0x46, 0x24, 0xf0,
-	0x4c, 0x2d, 0xd7, 0x5c, 0x51, 0xe4, 0xbd, 0xe1, 0x32, 0x3c, 0x8d, 0xb5, 0x67, 0x1f, 0xf7, 0x2a,
-	0x8f, 0xfb, 0xc2, 0x0c, 0xf2, 0xcd, 0xe5, 0x48, 0x0e, 0x57, 0x8a, 0xe3, 0xc7, 0x9b, 0xe3, 0xbf,
-	0x57, 0xb2, 0xad, 0xfe, 0x8a, 0xe6, 0x51, 0x0e, 0x8c, 0x68, 0x05, 0x6c, 0xa4, 0x6c, 0xc8, 0x97,
-	0xbb, 0x2f, 0xd7, 0x5f, 0xb9, 0xbf, 0xdb, 0x60, 0xb2, 0x33, 0xed, 0xb6, 0x81, 0x55, 0x5c, 0x09,
-	0x56, 0xc8, 0x0c, 0xb2, 0x26, 0xf9, 0x5e, 0x53, 0x78, 0x68, 0x86, 0xa7, 0x34, 0x91, 0xfd, 0x70,
-	0xc5, 0x3e, 0x0d, 0xb3, 0x9b, 0x76, 0xe4, 0x7b, 0xfd, 0xc6, 0x4a, 0xd6, 0x65, 0xff, 0x48, 0x05,
-	0xae, 0x54, 0xf8, 0xf5, 0x51, 0x0a, 0x75, 0xa5, 0x82, 0x2f, 0xc8, 0xa5, 0x42, 0x01, 0xc9, 0x19,
-	0x98, 0xff, 0x35, 0xa2, 0x2f, 0x38, 0x34, 0x30, 0x2a, 0xb0, 0x7d, 0x08, 0x0a, 0x86, 0x1f, 0x1c,
-	0x82, 0x82, 0xd5, 0x07, 0xe4, 0x0a, 0xcb, 0x8d, 0xa4, 0x8a, 0x0f, 0xe4, 0xb0, 0x5c, 0xd3, 0x1e,
-	0xa2, 0x8f, 0x2f, 0x83, 0xb0, 0xe3, 0x64, 0xde, 0xcd, 0x37, 0xc8, 0x39, 0xa1, 0xa9, 0xce, 0x33,
-	0xae, 0xc0, 0x45, 0xe1, 0x6f, 0x2c, 0x53, 0x11, 0xba, 0xeb, 0x97, 0xe0, 0x76, 0x09, 0x53, 0x7d,
-	0x6e, 0x8b, 0x11, 0x24, 0x5d, 0x3c, 0x4d, 0xf8, 0xf7, 0x8b, 0x53, 0x4b, 0x53, 0x9d, 0x4b, 0x28,
-	0x83, 0x3a, 0x04, 0x99, 0x17, 0x8e, 0x03, 0x79, 0x52, 0xa4, 0xef, 0xa0, 0xf8, 0x28, 0x6e, 0xd4,
-	0x08, 0x4e, 0x2c, 0xd5, 0x38, 0x4f, 0x7e, 0x63, 0xf3, 0xa4, 0x85, 0x74, 0x00, 0x51, 0x47, 0x80,
-	0x3f, 0xd2, 0x3d, 0x72, 0x29, 0x85, 0x9d, 0x30, 0xbb, 0xf0, 0x98, 0x26, 0x4c, 0x9b, 0xf0, 0xb7,
-	0xa8, 0x74, 0x11, 0x04, 0x2d, 0xbb, 0xbe, 0xce, 0xb4, 0x81, 0x76, 0xc7, 0xb1, 0x4a, 0x4c, 0x26,
-	0xb4, 0x0f, 0x0f, 0x3d, 0x7c, 0x64, 0x63, 0xca, 0x49, 0xe0, 0xd5, 0x3f, 0x86, 0xf5, 0x60, 0x8b,
-	0x5c, 0x88, 0x72, 0x6d, 0xe4, 0x10, 0x09, 0x9d, 0x4c, 0x75, 0xf8, 0xed, 0xff, 0xf7, 0x01, 0x54,
-	0xd1, 0x4e, 0xcb, 0x9a, 0xc1, 0x07, 0xd0, 0x39, 0x1f, 0x95, 0xd7, 0x82, 0x35, 0x72, 0xdd, 0x56,
-	0x1b, 0xc5, 0xa1, 0xac, 0x71, 0x30, 0x07, 0x82, 0xc2, 0x0f, 0xdf, 0xe1, 0x29, 0xe7, 0x11, 0xd4,
-	0x99, 0xc4, 0x78, 0x57, 0x7c, 0x4e, 0x2e, 0xb2, 0x1d, 0x29, 0x62, 0x97, 0xa1, 0x21, 0xd5, 0xfe,
-	0xce, 0x56, 0x64, 0x5c, 0x5e, 0xf3, 0xab, 0xf0, 0xe9, 0xa3, 0x01, 0x8f, 0xb6, 0x68, 0x2f, 0x4f,
-	0x6d, 0x9b, 0xb3, 0x29, 0x63, 0xc1, 0x75, 0xf8, 0x0f, 0xf6, 0xd3, 0xa3, 0xb0, 0xe1, 0x64, 0x6b,
-	0x28, 0x0a, 0xea, 0x64, 0x31, 0x92, 0x90, 0x00, 0x81, 0x3a, 0x60, 0x85, 0xa4, 0xbe, 0x03, 0x40,
-	0x9a, 0x0c, 0xd5, 0xe0, 0xf7, 0xf6, 0x8c, 0x80, 0x43, 0x86, 0x01, 0xa5, 0xb1, 0x66, 0x41, 0x40,
-	0x94, 0xa1, 0x2e, 0xb4, 0x27, 0x1b, 0x87, 0xed, 0xdc, 0x51, 0xe6, 0x1e, 0xd5, 0x5c, 0xed, 0x88,
-	0x88, 0x87, 0xff, 0xb8, 0x38, 0xb5, 0xf4, 0xe9, 0xda, 0xb9, 0x8f, 0x7b, 0x95, 0xd3, 0x2f, 0x65,
-	0x77, 0x9d, 0xef, 0xf0, 0xa4, 0xdc, 0x46, 0xbc, 0xb4, 0x1a, 0xad, 0x5e, 0xd7, 0xe2, 0x21, 0xe0,
-	0x80, 0x03, 0xea, 0x2c, 0x11, 0xf6, 0x74, 0xae, 0x41, 0xfa, 0x03, 0xd8, 0xe9, 0x5c, 0x92, 0x99,
-	0xe9, 0x82, 0x08, 0x0e, 0x54, 0x34, 0x48, 0xbe, 0x0c, 0x42, 0xd4, 0x3a, 0x22, 0xa6, 0xc3, 0xef,
-	0x6d, 0xb7, 0xe3, 0x2a, 0x20, 0x88, 0x2c, 0xe7, 0xd2, 0xc1, 0x9f, 0xc9, 0xfd, 0x82, 0xbc, 0x59,
-	0x2a, 0xe3, 0x09, 0xaf, 0x23, 0x71, 0xd0, 0x7e, 0x96, 0x6c, 0x85, 0xab, 0x68, 0xea, 0x73, 0xaf,
-	0xb4, 0x0a, 0x3a, 0x8e, 0x00, 0x5b, 0x9b, 0xcd, 0xb4, 0xb4, 0x41, 0xc0, 0xc9, 0xd7, 0xee, 0x44,
-	0x05, 0x1f, 0x2b, 0xf7, 0xa0, 0x40, 0xca, 0x36, 0x99, 0x89, 0x06, 0xd8, 0x8c, 0x60, 0xde, 0xd3,
-	0xe1, 0x1a, 0x6e, 0xf1, 0xa5, 0xd5, 0x6b, 0x3a, 0xb5, 0x52, 0xf7, 0xd9, 0x90, 0x6a, 0x0d, 0x74,
-	0xba, 0x85, 0x4a, 0xf0, 0x27, 0x72, 0x1f, 0xca, 0x5c, 0x64, 0x28, 0x4b, 0x63, 0x2a, 0xfa, 0xa9,
-	0x54, 0x9c, 0xa6, 0xd2, 0xd0, 0x1d, 0xa1, 0x05, 0xec, 0x6e, 0xa9, 0x85, 0x86, 0xeb, 0x44, 0x32,
-	0x1b, 0x85, 0x55, 0xdc, 0xe3, 0xae, 0x55, 0x5a, 0x4d, 0xe3, 0x26, 0xaa, 0xbc, 0x90, 0xe6, 0xb5,
-	0x55, 0xb0, 0xfc, 0x42, 0x37, 0xd3, 0xaa, 0xcc, 0x46, 0x41, 0x9d, 0x54, 0x90, 0xd9, 0x66, 0x09,
-	0x87, 0xba, 0x23, 0x7a, 0x8e, 0x3b, 0x68, 0xf8, 0xba, 0xc8, 0x7e, 0xc2, 0x1a, 0x1a, 0xbc, 0xe6,
-	0x61, 0xcf, 0xcb, 0xa8, 0x56, 0x0f, 0x09, 0x50, 0xd0, 0x27, 0x0f, 0xf4, 0x00, 0x39, 0x7e, 0xd1,
-	0x53, 0x94, 0x28, 0x18, 0x95, 0xe9, 0x51, 0x47, 0x0e, 0xeb, 0xd6, 0x1d, 0xa0, 0x39, 0xee, 0x34,
-	0xc6, 0x74, 0xac, 0x95, 0x1e, 0x3a, 0x35, 0x34, 0x32, 0x86, 0x6b, 0x03, 0xa9, 0x6f, 0xdc, 0xfc,
-	0x29, 0x96, 0xc6, 0x72, 0x48, 0x35, 0xe7, 0x71, 0xd8, 0xc0, 0xbc, 0x39, 0xe7, 0x40, 0xc5, 0x4c,
-	0xa3, 0x83, 0x90, 0x2e, 0xe7, 0x71, 0x40, 0xc9, 0xfd, 0x3c, 0x2d, 0x0e, 0xc7, 0x63, 0x9a, 0x4a,
-	0x70, 0xdd, 0x0e, 0x3e, 0x33, 0x47, 0x1f, 0x31, 0x24, 0xfd, 0x2b, 0x7e, 0x8c, 0xc7, 0x5c, 0x9a,
-	0x50, 0x7a, 0x21, 0xd3, 0xaa, 0x53, 0x41, 0x12, 0x09, 0x91, 0xea, 0x9f, 0xf4, 0x73, 0x72, 0xeb,
-	0xf0, 0x19, 0xf1, 0x1d, 0x66, 0x5c, 0x99, 0x5c, 0x6d, 0x5a, 0xf2, 0xf6, 0x04, 0x93, 0xeb, 0xe2,
-	0xc1, 0x93, 0x56, 0xa5, 0x36, 0xed, 0x12, 0x2e, 0x78, 0x4b, 0xee, 0x1d, 0x36, 0xe7, 0x53, 0xa2,
-	0xca, 0x21, 0x2f, 0x2a, 0xb9, 0xc9, 0x36, 0x05, 0x3c, 0xb1, 0xb0, 0x89, 0x56, 0xef, 0x1e, 0xb4,
-	0xea, 0xfa, 0xed, 0x4e, 0x9e, 0x40, 0x4d, 0xf4, 0x68, 0xa0, 0xf9, 0x93, 0x3d, 0x74, 0xf9, 0x33,
-	0xa1, 0x2b, 0xb8, 0x0e, 0x9f, 0x5a, 0x9a, 0x5f, 0xee, 0xa3, 0xc7, 0x1f, 0xa6, 0x69, 0x41, 0xc1,
-	0x43, 0xf2, 0x19, 0x84, 0xdf, 0xb8, 0xb1, 0x28, 0xdc, 0xf7, 0xcc, 0xe5, 0x27, 0x99, 0x8d, 0x7c,
-	0x7b, 0xe1, 0x3d, 0xf5, 0x23, 0xf9, 0xd2, 0x5f, 0x64, 0x20, 0x81, 0xa9, 0x65, 0x4a, 0x42, 0xc9,
-	0x70, 0xcf, 0x13, 0x7b, 0x5b, 0x4c, 0x0c, 0xd6, 0x63, 0xeb, 0x36, 0xb4, 0x9d, 0xca, 0x13, 0xd0,
-	0x68, 0x17, 0x0a, 0xcd, 0x14, 0x1a, 0xde, 0xf5, 0x02, 0x1d, 0xfc, 0x96, 0x84, 0xf6, 0x44, 0x4a,
-	0x0e, 0x29, 0x33, 0x72, 0x28, 0xa2, 0xe2, 0x4c, 0xcf, 0x6d, 0xdf, 0x89, 0x67, 0x52, 0x72, 0xb8,
-	0x8a, 0x52, 0x7f, 0xaa, 0x65, 0x72, 0x99, 0xa7, 0xb6, 0xd7, 0x1d, 0xc8, 0x21, 0xf7, 0xf9, 0xe1,
-	0x85, 0x6d, 0x59, 0x9c, 0xe8, 0x89, 0x1c, 0x72, 0x97, 0x09, 0xbe, 0x21, 0xb3, 0x93, 0x4e, 0xec,
-	0x49, 0xc5, 0x23, 0x06, 0x65, 0xaa, 0x65, 0xf7, 0x29, 0xbb, 0xae, 0xe1, 0x85, 0xd0, 0xc2, 0xec,
-	0x30, 0x25, 0x6c, 0x0e, 0x49, 0xb9, 0x4f, 0xab, 0xa5, 0x61, 0x41, 0x71, 0xde, 0xb6, 0x6d, 0x61,
-	0x3c, 0xbc, 0x59, 0xa0, 0xc7, 0xa3, 0x01, 0x7f, 0xfa, 0x35, 0x72, 0xb9, 0x9c, 0x87, 0xfc, 0x0c,
-	0xec, 0xe5, 0x71, 0x33, 0xb0, 0xa0, 0x84, 0xf6, 0x63, 0xaf, 0x7f, 0x25, 0x57, 0xf4, 0x48, 0x1b,
-	0x3e, 0xa4, 0x22, 0xe6, 0xa9, 0x81, 0x53, 0x59, 0x72, 0xd6, 0xf9, 0xdb, 0x93, 0xb3, 0xcb, 0x76,
-	0xa7, 0xa6, 0xdb, 0xc8, 0xf2, 0xb3, 0xb7, 0x64, 0x2e, 0xe6, 0x3a, 0x52, 0x22, 0x33, 0x52, 0xd1,
-	0x1d, 0x96, 0x88, 0xb8, 0x44, 0xb9, 0xbb, 0x76, 0x68, 0xf9, 0x71, 0xaf, 0x12, 0xd6, 0x0a, 0xd4,
-	0xeb, 0x02, 0x84, 0xfc, 0x38, 0x8c, 0x8f, 0x91, 0x04, 0x2f, 0xc8, 0xed, 0x89, 0x56, 0x65, 0xc0,
-	0xf4, 0x80, 0xf6, 0x95, 0x3c, 0xe8, 0xf3, 0x0d, 0xf4, 0xf9, 0x62, 0x19, 0xfb, 0x84, 0xe9, 0xc1,
-	0x63, 0x40, 0x96, 0x1d, 0x5e, 0x27, 0x15, 0xdb, 0xc9, 0x4b, 0x15, 0x8b, 0x14, 0xbb, 0x3e, 0xd7,
-	0xec, 0xf5, 0xb8, 0x02, 0x6a, 0xac, 0xc3, 0x57, 0x36, 0x85, 0x22, 0xac, 0x65, 0x51, 0xbe, 0xcd,
-	0xf3, 0x98, 0xe0, 0x35, 0x59, 0x9a, 0x8c, 0x22, 0x31, 0xcc, 0x94, 0xdc, 0xe1, 0x31, 0xbc, 0xf5,
-	0x77, 0xbe, 0xe6, 0xdb, 0xc9, 0xd6, 0x6b, 0x37, 0x6b, 0x28, 0x85, 0x55, 0xd3, 0xa1, 0x6b, 0x63,
-	0xb0, 0x1d, 0x72, 0x09, 0xf2, 0x70, 0xd2, 0x2e, 0x3e, 0xa8, 0xa2, 0xb1, 0xc3, 0x42, 0x65, 0x5b,
-	0x4b, 0xf8, 0x97, 0xf5, 0xc3, 0xe6, 0x28, 0xfc, 0x23, 0x6e, 0xf1, 0x55, 0x79, 0x0b, 0x7c, 0x5b,
-	0xbe, 0xe5, 0x6b, 0x48, 0xd5, 0xf5, 0x5a, 0xe8, 0x92, 0xb5, 0x51, 0xf0, 0x2d, 0xb9, 0x3a, 0x7e,
-	0x71, 0x40, 0x0c, 0x45, 0xa9, 0x77, 0xfe, 0xc1, 0x36, 0x90, 0xfe, 0xc9, 0x75, 0xac, 0xd8, 0x3b,
-	0xf1, 0x35, 0x59, 0x8a, 0x79, 0x94, 0x30, 0xc5, 0x69, 0x94, 0x2b, 0x8d, 0x67, 0x72, 0x35, 0xd0,
-	0x87, 0x70, 0x61, 0xe9, 0xad, 0xbd, 0xbd, 0xc3, 0x57, 0x11, 0x5e, 0x54, 0x4c, 0x17, 0xc2, 0xde,
-	0xee, 0x80, 0x3c, 0x38, 0xc6, 0xab, 0x96, 0x7b, 0x94, 0x7d, 0x0b, 0x9e, 0xc0, 0x11, 0x5d, 0xf8,
-	0xe3, 0xe1, 0xcb, 0x7b, 0xff, 0x22, 0x2f, 0x29, 0x39, 0xb9, 0x21, 0xed, 0x1c, 0x37, 0x68, 0x91,
-	0x3b, 0x47, 0x51, 0x62, 0xac, 0x2d, 0x43, 0xf0, 0xb8, 0x3f, 0xfe, 0x3f, 0xd9, 0xb8, 0x3a, 0x44,
-	0x8e, 0x5b, 0xa9, 0x1d, 0x81, 0xf8, 0xa3, 0xff, 0x40, 0xee, 0x1d, 0x91, 0x86, 0x0e, 0x8c, 0x6c,
-	0x0b, 0xab, 0x7f, 0x42, 0xab, 0x77, 0x0e, 0x65, 0xa7, 0x89, 0xf1, 0x6d, 0x29, 0x64, 0xc7, 0x5e,
-	0x61, 0xc9, 0x7b, 0x36, 0xd2, 0x07, 0x67, 0xaf, 0x7f, 0xb6, 0x21, 0x5b, 0xc0, 0x56, 0x11, 0x35,
-	0x39, 0x81, 0x7d, 0x4a, 0x6e, 0x3a, 0x0a, 0x14, 0x29, 0xce, 0x0c, 0xb7, 0xd1, 0x49, 0x73, 0x8d,
-	0x9d, 0xc9, 0xae, 0x51, 0x7c, 0xc8, 0x75, 0x48, 0xd1, 0xd2, 0x82, 0x45, 0x56, 0x11, 0x88, 0x91,
-	0xf9, 0x0a, 0x60, 0x75, 0x87, 0x0a, 0xde, 0x91, 0x87, 0xf6, 0x15, 0x29, 0x09, 0x54, 0x84, 0x0f,
-	0x37, 0xb9, 0xd2, 0x03, 0x91, 0x69, 0x6a, 0xa4, 0xeb, 0x8c, 0x69, 0x9c, 0x63, 0xc4, 0x96, 0x12,
-	0x56, 0xf8, 0xcf, 0x68, 0xfc, 0x3e, 0xaa, 0x76, 0x64, 0xc2, 0x9f, 0x8f, 0x15, 0x37, 0xa4, 0xed,
-	0x8c, 0x6b, 0xa8, 0x55, 0x62, 0x59, 0x41, 0x95, 0x2c, 0xb8, 0x61, 0x64, 0x5c, 0x62, 0x67, 0xb6,
-	0x61, 0xb6, 0xa4, 0x98, 0x21, 0x8b, 0x98, 0xf7, 0xa8, 0x31, 0x1f, 0xc3, 0x36, 0x17, 0x49, 0xf1,
-	0x17, 0x64, 0xda, 0x3e, 0x1b, 0xae, 0x8a, 0x8f, 0xb0, 0x69, 0x5b, 0x18, 0xbf, 0xee, 0xdd, 0xfd,
-	0x07, 0x72, 0xcd, 0x97, 0xb9, 0x58, 0xc9, 0x8c, 0xee, 0x08, 0x65, 0x72, 0x48, 0x14, 0x49, 0xae,
-	0x0d, 0x57, 0x61, 0x64, 0x07, 0xd5, 0x0e, 0x53, 0x53, 0x32, 0x7b, 0x6d, 0x11, 0x55, 0x0b, 0x98,
-	0x60, 0x69, 0x70, 0x87, 0x1d, 0x4e, 0x33, 0xa9, 0x0c, 0x4b, 0xc6, 0xdf, 0x3f, 0x9e, 0x64, 0x69,
-	0xab, 0x88, 0x6a, 0x5b, 0x90, 0x3f, 0xc7, 0x23, 0x12, 0xe6, 0xe9, 0xa6, 0xcc, 0xd3, 0x98, 0xc7,
-	0x34, 0x63, 0x8a, 0x25, 0x09, 0x4f, 0xdc, 0xd4, 0x91, 0xdb, 0xe7, 0x59, 0xc8, 0xdb, 0x4e, 0x6c,
-	0xa7, 0x8e, 0x3d, 0xf2, 0xf5, 0x38, 0x60, 0x6c, 0xa9, 0x06, 0x3a, 0xa4, 0x14, 0x4f, 0x98, 0xe1,
-	0x31, 0x2d, 0x8a, 0x97, 0xce, 0x37, 0xb7, 0x73, 0x0e, 0x2f, 0x3b, 0xec, 0x1d, 0x78, 0x44, 0x58,
-	0xaf, 0x5f, 0x95, 0xb4, 0xea, 0x4e, 0xa9, 0x5b, 0xe8, 0xc0, 0x45, 0x0f, 0x73, 0x1d, 0xf7, 0xac,
-	0x32, 0x96, 0x8a, 0x48, 0x87, 0x7d, 0x7b, 0xd1, 0x83, 0x04, 0xa7, 0x89, 0xa0, 0x36, 0x62, 0x82,
-	0x1d, 0xf2, 0xed, 0x31, 0xaf, 0xfe, 0xe0, 0x44, 0xae, 0x27, 0x80, 0xe6, 0x6b, 0x0a, 0x49, 0x6d,
-	0xc7, 0xb2, 0x8c, 0x01, 0x6e, 0xf0, 0xf0, 0xa8, 0xc7, 0x3f, 0x39, 0xa3, 0x6b, 0x58, 0xdd, 0x5a,
-	0xa1, 0x0a, 0x6d, 0x71, 0xb9, 0x51, 0x12, 0x5a, 0x26, 0xb6, 0x6c, 0x25, 0xd0, 0x11, 0x85, 0x02,
-	0xa3, 0x2a, 0x1c, 0xf7, 0x45, 0x4d, 0x0f, 0xc0, 0x8e, 0x29, 0x78, 0x43, 0xa6, 0x4b, 0xd3, 0x3d,
-	0x5b, 0xeb, 0xde, 0x2d, 0x4e, 0x2d, 0x5d, 0x78, 0xf0, 0xd5, 0x2f, 0xb6, 0xaf, 0xa5, 0x99, 0x1f,
-	0xd6, 0xbe, 0x8b, 0x6a, 0x72, 0x01, 0x98, 0xc6, 0x31, 0xfe, 0xb0, 0x15, 0x0f, 0x4a, 0x42, 0x6a,
-	0x6f, 0xbf, 0x65, 0x99, 0xc6, 0x51, 0xb7, 0xc7, 0xa2, 0x37, 0x86, 0x06, 0xa6, 0x34, 0x6f, 0xef,
-	0x6d, 0xd1, 0x44, 0x46, 0x5b, 0x45, 0x41, 0xc1, 0x81, 0x97, 0xf8, 0x80, 0x0d, 0x44, 0x82, 0x3f,
-	0x74, 0xdc, 0xde, 0xdf, 0xab, 0x2c, 0xfa, 0x9e, 0xa7, 0xf1, 0x6c, 0xdd, 0xa2, 0xa1, 0x8c, 0x94,
-	0xb0, 0x9d, 0x45, 0x6f, 0xb1, 0xb1, 0x75, 0x34, 0x22, 0x78, 0x4c, 0x16, 0xe3, 0x5c, 0xe1, 0x63,
-	0x3a, 0x76, 0xc7, 0xa1, 0x65, 0xac, 0x0e, 0x77, 0x8c, 0xa1, 0x3a, 0xa9, 0xe8, 0x01, 0xe6, 0x80,
-	0x63, 0xed, 0x64, 0x36, 0xd6, 0x2c, 0xec, 0x18, 0x33, 0x6b, 0x64, 0x61, 0xc8, 0x76, 0x8b, 0x72,
-	0x07, 0x36, 0x70, 0x88, 0x63, 0xb3, 0xbe, 0xe1, 0x71, 0x98, 0x62, 0x53, 0x3b, 0x37, 0x64, 0xbb,
-	0xae, 0xe8, 0x35, 0x24, 0xa6, 0xe3, 0xaa, 0x47, 0x04, 0x4f, 0xc8, 0x8c, 0x36, 0x4a, 0x44, 0x86,
-	0xc6, 0x71, 0xe2, 0xb8, 0x2a, 0x90, 0x79, 0x89, 0x9e, 0xfb, 0x6c, 0x7f, 0xaf, 0x12, 0x74, 0x51,
-	0x5e, 0xab, 0xad, 0xaf, 0x7a, 0x69, 0x27, 0xb0, 0x3a, 0xb5, 0x38, 0x29, 0xd6, 0x20, 0xd5, 0xe4,
-	0x29, 0xfe, 0x30, 0xa5, 0xb9, 0x31, 0xb6, 0xa1, 0x31, 0x5c, 0xc1, 0x0d, 0xa1, 0x29, 0x0b, 0xb7,
-	0x71, 0xf0, 0x7c, 0xd5, 0x62, 0xba, 0x16, 0xd2, 0xf4, 0x88, 0x67, 0x7c, 0x14, 0xbc, 0x24, 0x77,
-	0x0f, 0xd0, 0x05, 0x50, 0x95, 0xd9, 0x61, 0xe7, 0x28, 0xfb, 0x33, 0xca, 0x04, 0x43, 0x90, 0xd1,
-	0x56, 0x2b, 0x3b, 0xe8, 0xa1, 0x75, 0x72, 0x6b, 0xd2, 0x24, 0x84, 0x93, 0x80, 0x1c, 0x34, 0x26,
-	0x21, 0x62, 0x37, 0xd4, 0x68, 0xaf, 0x52, 0xb6, 0xd7, 0x76, 0xc0, 0x82, 0x74, 0x88, 0xdd, 0xa0,
-	0x46, 0x16, 0x7c, 0x32, 0xb5, 0x65, 0xa1, 0xc7, 0x79, 0x3c, 0x31, 0x15, 0x37, 0xf6, 0xab, 0x39,
-	0x54, 0xb5, 0x00, 0x95, 0x47, 0xe3, 0x4f, 0xc9, 0x3c, 0x52, 0x95, 0x63, 0xe6, 0x19, 0xf9, 0x11,
-	0xf3, 0x8c, 0x59, 0x50, 0x38, 0x6a, 0x98, 0xb1, 0x4a, 0xae, 0xa3, 0x2d, 0x9c, 0xd8, 0xd3, 0x4c,
-	0x64, 0x3c, 0x11, 0x13, 0x3f, 0x38, 0xed, 0xd8, 0x1f, 0xd7, 0x00, 0xf4, 0x06, 0x30, 0xed, 0x02,
-	0xe2, 0x33, 0xf3, 0x77, 0x04, 0xa5, 0x34, 0xcd, 0xc7, 0xc4, 0x29, 0xe3, 0x6e, 0x82, 0x10, 0xee,
-	0x62, 0x00, 0x21, 0x75, 0x7a, 0x91, 0x7b, 0xe6, 0xd4, 0xe6, 0x76, 0x56, 0x30, 0xb7, 0x4d, 0x82,
-	0xc3, 0xb3, 0xda, 0x60, 0x9a, 0x9c, 0x84, 0xef, 0x3d, 0x85, 0xbf, 0x52, 0xc3, 0x9f, 0x41, 0x9d,
-	0x7c, 0xba, 0xc3, 0x92, 0x9c, 0xe3, 0x6f, 0xfe, 0x67, 0x1f, 0xac, 0xfc, 0x62, 0x4a, 0x39, 0x6c,
-	0xb1, 0x63, 0xb5, 0xbf, 0xfb, 0xe4, 0xd1, 0xd4, 0xdc, 0xf7, 0x24, 0x38, 0x3c, 0x1d, 0x2b, 0x6f,
-	0x79, 0xc6, 0x6e, 0x39, 0x53, 0xde, 0xf2, 0x4c, 0xc9, 0xc2, 0xd3, 0x53, 0xa7, 0x67, 0xa7, 0xc3,
-	0xa7, 0xa7, 0x4e, 0x5f, 0x9d, 0x9e, 0x7b, 0x7a, 0xea, 0xf4, 0xe2, 0xf4, 0x8d, 0xa7, 0xa7, 0x4e,
-	0xdf, 0x9e, 0xbe, 0x73, 0xf3, 0x3f, 0xa6, 0x8e, 0xbc, 0xcd, 0x1d, 0x72, 0x01, 0xab, 0x73, 0x4c,
-	0x77, 0xb8, 0x82, 0x63, 0xba, 0x8b, 0x9d, 0xb7, 0xab, 0xaf, 0xed, 0x62, 0x70, 0x8b, 0x9c, 0x8f,
-	0x72, 0xa5, 0x80, 0x34, 0x8e, 0xf7, 0x3d, 0xd9, 0x39, 0xe7, 0x16, 0x5f, 0xc3, 0x5a, 0x70, 0x8d,
-	0x9c, 0x11, 0x69, 0xa4, 0xb0, 0x9e, 0xdb, 0xff, 0xb1, 0xd0, 0x19, 0x2f, 0x04, 0xd7, 0x09, 0x81,
-	0x8f, 0x80, 0xea, 0xda, 0xfe, 0x7f, 0x84, 0xce, 0x99, 0x34, 0x1f, 0xa2, 0xae, 0xbe, 0x37, 0x24,
-	0x17, 0x0f, 0x64, 0xdb, 0xe0, 0x3a, 0xb9, 0xda, 0xa9, 0xb7, 0xd7, 0x9b, 0xd5, 0xd5, 0x8d, 0x66,
-	0xeb, 0x05, 0x7d, 0xde, 0xaa, 0xd5, 0x69, 0xad, 0xd9, 0x5d, 0x5d, 0x5b, 0xaf, 0xd7, 0xa6, 0x4f,
-	0x04, 0xd7, 0x48, 0x78, 0x48, 0x5c, 0x7f, 0x61, 0xa5, 0x53, 0x47, 0x2b, 0xaf, 0x6e, 0xac, 0xae,
-	0xad, 0x76, 0xeb, 0xd3, 0x9f, 0xac, 0xfd, 0xf1, 0x2f, 0xff, 0xb5, 0x70, 0xe2, 0x2f, 0xfb, 0x0b,
-	0x53, 0x7f, 0xdd, 0x5f, 0x98, 0xfa, 0x69, 0x7f, 0x61, 0xea, 0x3f, 0xf7, 0x17, 0xa6, 0xfe, 0xed,
-	0xe7, 0x85, 0x13, 0x7f, 0xfd, 0x79, 0xe1, 0xc4, 0x4f, 0x3f, 0x2f, 0x9c, 0x78, 0xfb, 0xcd, 0xff,
-	0xad, 0x0f, 0x3b, 0xf8, 0xff, 0x55, 0x36, 0x7f, 0x85, 0x0d, 0xdd, 0xc3, 0xff, 0x09, 0x00, 0x00,
-	0xff, 0xff, 0xee, 0x80, 0x86, 0x04, 0xcb, 0x22, 0x00, 0x00,
+	// 5576 bytes of a gzipped FileDescriptorProto
+	0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x9c, 0x7b, 0xdb, 0x7b, 0x1c, 0xc7,
+	0x71, 0x2f, 0x57, 0xa2, 0x75, 0xa8, 0xa6, 0x28, 0x82, 0x43, 0x50, 0x18, 0x82, 0x24, 0x16, 0xa4,
+	0x48, 0x09, 0xa2, 0x44, 0x40, 0x06, 0xad, 0xab, 0x8f, 0x8f, 0x85, 0x5d, 0x00, 0x22, 0x48, 0x90,
+	0x58, 0xee, 0x82, 0xa4, 0x25, 0x1f, 0xbb, 0x3d, 0x98, 0xe9, 0xdd, 0x6d, 0x61, 0x76, 0x7a, 0xd0,
+	0xdd, 0x03, 0x62, 0x99, 0xc4, 0xb9, 0xd9, 0x89, 0xa3, 0xdc, 0x9c, 0x38, 0x37, 0x27, 0x51, 0x6e,
+	0x76, 0x12, 0x27, 0x79, 0xc8, 0x6b, 0xf2, 0x1f, 0xf8, 0xd1, 0x8f, 0xfe, 0xf2, 0x80, 0x2f, 0x81,
+	0xff, 0x0b, 0x3d, 0xe5, 0xab, 0xaa, 0x9e, 0xd9, 0xd9, 0xc5, 0x42, 0xce, 0x97, 0x37, 0x60, 0xea,
+	0x57, 0xd5, 0x3d, 0x3d, 0xd5, 0x55, 0xbf, 0xaa, 0xee, 0x65, 0x0b, 0x66, 0x27, 0x5e, 0x30, 0xc2,
+	0x18, 0xa9, 0x92, 0x28, 0xb0, 0x41, 0xba, 0xb5, 0x10, 0xab, 0x30, 0x88, 0xb9, 0x4a, 0xe2, 0x3e,
+	0x77, 0x02, 0x0e, 0x92, 0xf9, 0x54, 0x2b, 0xab, 0xbc, 0x0b, 0xa1, 0x0a, 0xb7, 0xb5, 0x0a, 0xc2,
+	0xee, 0xbc, 0xd9, 0x89, 0xe7, 0x87, 0x54, 0xa7, 0x27, 0x3b, 0xaa, 0xa3, 0x10, 0xb7, 0x00, 0x7f,
+	0x91, 0xca, 0xb4, 0x9f, 0x59, 0x19, 0x2f, 0x74, 0xe3, 0x70, 0xc1, 0xca, 0x9e, 0x30, 0x36, 0xe8,
+	0xa5, 0x24, 0xb9, 0xf2, 0x1f, 0x21, 0x9b, 0x5c, 0x87, 0xe1, 0x36, 0x92, 0xb8, 0xdf, 0x22, 0x53,
+	0xcb, 0x81, 0x0d, 0xbc, 0xd7, 0x98, 0x67, 0x82, 0x5d, 0xc1, 0x6d, 0xb0, 0x15, 0x0b, 0xc3, 0x53,
+	0x2d, 0xda, 0x72, 0xcf, 0xaf, 0xcc, 0x56, 0xe6, 0x9e, 0x6d, 0x4e, 0x80, 0x64, 0x13, 0x05, 0x0d,
+	0x7c, 0xee, 0x7d, 0x95, 0x5d, 0x50, 0xa9, 0x95, 0x3d, 0xf9, 0x44, 0x68, 0xde, 0xde, 0xe6, 0x61,
+	0x60, 0xc2, 0x20, 0x12, 0x86, 0xc7, 0xb2, 0x27, 0xad, 0xff, 0xd4, 0x6c, 0x65, 0xee, 0xe9, 0xda,
+	0xc5, 0x83, 0xfd, 0xaa, 0xbf, 0x91, 0xc3, 0x56, 0xef, 0xd4, 0x1d, 0x68, 0x1d, 0x30, 0x4d, 0xbf,
+	0x30, 0xb0, 0xba, 0x3d, 0x24, 0xf1, 0xbe, 0xc0, 0x9e, 0x33, 0xb6, 0x67, 0x39, 0xcc, 0x5d, 0x65,
+	0xd6, 0x7f, 0x1a, 0xad, 0x9d, 0xf9, 0x74, 0xbf, 0x7a, 0x0a, 0x1e, 0xcd, 0x2f, 0x67, 0x3a, 0xb0,
+	0x52, 0x25, 0xcd, 0x93, 0x00, 0xdb, 0x24, 0x94, 0x77, 0x8b, 0x4d, 0xc9, 0x28, 0x16, 0x5c, 0x26,
+	0xc5, 0x22, 0xe6, 0x06, 0x8e, 0x1f, 0x65, 0x60, 0x12, 0x34, 0xd6, 0x12, 0xb7, 0x0e, 0xb9, 0x25,
+	0xce, 0x5e, 0xcc, 0x2d, 0x59, 0x1d, 0x24, 0x26, 0x08, 0x01, 0x7c, 0xc8, 0xea, 0xe7, 0x8e, 0xb2,
+	0x5a, 0x25, 0xab, 0x9b, 0x03, 0xdd, 0x91, 0x01, 0xde, 0x64, 0x53, 0x89, 0xb2, 0x32, 0x14, 0x3c,
+	0x92, 0x26, 0x8d, 0x03, 0xf8, 0xec, 0xbb, 0x42, 0x4b, 0xdb, 0xf7, 0x9f, 0x99, 0xad, 0xcc, 0x9d,
+	0x6a, 0x9e, 0x23, 0xf1, 0x32, 0x49, 0x5b, 0x4e, 0xe8, 0xcd, 0xb3, 0xb3, 0x5a, 0x28, 0x1d, 0x09,
+	0xcd, 0x3f, 0x52, 0x32, 0xc9, 0x57, 0xfb, 0xff, 0xc0, 0x44, 0x9a, 0x67, 0x9c, 0xe8, 0x36, 0x48,
+	0x68, 0x21, 0x5f, 0x67, 0x93, 0x91, 0x68, 0x07, 0x59, 0x6c, 0xb9, 0xdd, 0x4b, 0x78, 0xaa, 0xa5,
+	0xc2, 0x41, 0x4e, 0xa0, 0x82, 0xe7, 0x64, 0x9b, 0x7b, 0x49, 0xc3, 0x49, 0xbc, 0xcf, 0xb3, 0x73,
+	0x65, 0x0d, 0x2d, 0x82, 0x08, 0xfd, 0xd2, 0x7f, 0x76, 0xb6, 0x32, 0x77, 0xa2, 0xac, 0xd2, 0x14,
+	0x41, 0x04, 0x3e, 0xe4, 0xd5, 0xd8, 0x4c, 0x59, 0x25, 0x33, 0x82, 0xb7, 0x55, 0x1c, 0xab, 0xc7,
+	0x42, 0xa3, 0xbe, 0xf1, 0x19, 0xea, 0x4e, 0x0f, 0x74, 0x1f, 0x18, 0xb1, 0xea, 0x20, 0x60, 0xc6,
+	0x78, 0x1b, 0xec, 0x6a, 0x1a, 0x68, 0x2b, 0x83, 0x38, 0xee, 0xc3, 0x9a, 0x58, 0x2d, 0xb7, 0x32,
+	0x2b, 0x22, 0x9e, 0xc6, 0x41, 0x62, 0xe0, 0x09, 0x38, 0x5f, 0xe4, 0x9f, 0x44, 0x4b, 0x97, 0x0b,
+	0xec, 0xf2, 0x00, 0xda, 0x00, 0xe4, 0xb2, 0x03, 0x7a, 0x6f, 0xb3, 0x81, 0x7b, 0xe1, 0x94, 0xba,
+	0xd2, 0x58, 0xd5, 0xd1, 0x41, 0xcf, 0xf8, 0xcf, 0xa1, 0x91, 0x17, 0x0a, 0xf9, 0x03, 0x23, 0x6e,
+	0x15, 0x52, 0xef, 0x3d, 0x76, 0x69, 0x58, 0xb3, 0x97, 0xc5, 0x56, 0xf2, 0x50, 0xc5, 0xdc, 0xd8,
+	0xc0, 0x1a, 0xff, 0x14, 0xaa, 0x9f, 0x2f, 0xab, 0xdf, 0x05, 0x48, 0x5d, 0xc5, 0x2d, 0x00, 0x78,
+	0xef, 0xb2, 0xf3, 0xb8, 0xa1, 0xa5, 0xed, 0xf3, 0x1c, 0x15, 0x71, 0x23, 0x02, 0x1d, 0x76, 0xfd,
+	0xe7, 0x51, 0x7b, 0x2a, 0x07, 0xe4, 0xbb, 0x23, 0x6a, 0xa1, 0xd8, 0xbb, 0xcc, 0x9e, 0x33, 0x41,
+	0x5b, 0xf0, 0x2c, 0x8d, 0x02, 0x2b, 0x8c, 0x7f, 0x1a, 0xe1, 0x27, 0xe1, 0xd9, 0x03, 0x7a, 0xe4,
+	0x7d, 0xc0, 0x2e, 0xc0, 0xe6, 0x14, 0x9a, 0xc7, 0x4a, 0x6d, 0x67, 0xa9, 0x73, 0x85, 0xb6, 0x82,
+	0x8d, 0x68, 0xfc, 0x09, 0xd0, 0xa8, 0x5d, 0x38, 0xd8, 0xaf, 0x4e, 0x35, 0x10, 0xb6, 0x8e, 0x28,
+	0xf4, 0x8a, 0x55, 0xa5, 0x57, 0xef, 0x98, 0xe6, 0x54, 0x3a, 0x4e, 0xb0, 0x6d, 0xc0, 0xbf, 0x9e,
+	0xc8, 0xce, 0x93, 0xa0, 0x83, 0x36, 0xb9, 0x48, 0x68, 0xd5, 0xcf, 0xe0, 0x24, 0xce, 0x90, 0x08,
+	0xf0, 0x2b, 0x24, 0xf0, 0x96, 0xd8, 0x25, 0x2d, 0x76, 0x32, 0xa9, 0x05, 0x17, 0x7b, 0x69, 0x2c,
+	0x43, 0x69, 0xc1, 0xc9, 0x7a, 0x81, 0xee, 0xf3, 0x6d, 0xd1, 0x37, 0xbe, 0x47, 0x5f, 0xde, 0x81,
+	0x56, 0x1c, 0xa6, 0x41, 0x90, 0x3b, 0xa2, 0x6f, 0x60, 0x2b, 0xb4, 0x95, 0x0e, 0x05, 0x87, 0x10,
+	0x93, 0x2a, 0x99, 0x58, 0xae, 0x21, 0x60, 0x69, 0xeb, 0x9f, 0x45, 0xe5, 0x73, 0x28, 0x6e, 0xe5,
+	0xd2, 0x26, 0x09, 0xbd, 0xb7, 0xd9, 0xf9, 0x00, 0x3c, 0x08, 0x02, 0x55, 0x1a, 0x68, 0xc1, 0x03,
+	0x03, 0x8b, 0x8d, 0x0e, 0xe3, 0x4f, 0x92, 0x26, 0x02, 0x1a, 0x24, 0x5f, 0x32, 0x1b, 0xa9, 0x05,
+	0x1f, 0x81, 0x97, 0xb4, 0xa2, 0x97, 0xe6, 0x81, 0x2e, 0x7f, 0xc9, 0x73, 0xf4, 0x92, 0x20, 0xa2,
+	0x48, 0x97, 0xbf, 0xe4, 0x06, 0xbb, 0x2a, 0x7b, 0xee, 0xe5, 0x42, 0x15, 0x67, 0xbd, 0x84, 0xa3,
+	0xff, 0xc1, 0xbe, 0x96, 0x49, 0xa7, 0x30, 0xf0, 0x02, 0xf9, 0x66, 0x8e, 0xad, 0x23, 0xb4, 0x51,
+	0x42, 0xe6, 0x06, 0x1f, 0xb1, 0x57, 0xd4, 0xae, 0xd0, 0x5a, 0x46, 0xb9, 0x73, 0x69, 0xd1, 0x81,
+	0xc0, 0xf2, 0x44, 0x25, 0x82, 0x87, 0x2a, 0x69, 0xcb, 0x81, 0x55, 0x1f, 0xad, 0x5e, 0xcd, 0x15,
+	0xd0, 0xd3, 0x9a, 0x08, 0xff, 0x50, 0x25, 0xa2, 0x8e, 0xe0, 0xdc, 0xf0, 0x3b, 0xec, 0x3c, 0xec,
+	0x14, 0x5c, 0x96, 0x76, 0x16, 0xc7, 0xf4, 0x8a, 0xdc, 0x84, 0x41, 0x62, 0xfc, 0x69, 0xf2, 0xfa,
+	0x1c, 0xb0, 0x9a, 0xc5, 0x31, 0xbe, 0x67, 0x0b, 0xa4, 0xde, 0x17, 0xd9, 0x74, 0xf1, 0x92, 0x46,
+	0xc4, 0x22, 0xb4, 0xe8, 0x50, 0xe4, 0x86, 0xfe, 0x05, 0x72, 0xda, 0x1c, 0xd1, 0x42, 0xc0, 0xaa,
+	0xd2, 0xe4, 0x92, 0xde, 0x1c, 0x9b, 0x90, 0x89, 0x11, 0xda, 0xf2, 0x76, 0x60, 0x2c, 0x4f, 0x03,
+	0xdb, 0xf5, 0x2f, 0xa2, 0xca, 0xf3, 0xf4, 0x7c, 0x35, 0x30, 0xb6, 0x11, 0xd8, 0xae, 0x77, 0x8b,
+	0x5d, 0x0e, 0x62, 0x2b, 0x74, 0xbe, 0x90, 0xb6, 0x9f, 0x0a, 0xde, 0x11, 0x89, 0xd0, 0x41, 0x5c,
+	0xbc, 0xf2, 0x25, 0x54, 0xbd, 0x84, 0x40, 0x5a, 0xc5, 0xcd, 0x7e, 0x2a, 0xde, 0x27, 0x54, 0xfe,
+	0xae, 0x37, 0x98, 0x67, 0xfa, 0x49, 0xd8, 0xd5, 0x2a, 0x51, 0x99, 0xe1, 0xa1, 0xea, 0x41, 0x24,
+	0x9c, 0xa1, 0x8f, 0x58, 0x92, 0xd4, 0x51, 0xe0, 0xbd, 0xc4, 0x4e, 0x93, 0x79, 0x6e, 0xc4, 0x0e,
+	0xae, 0x88, 0x5f, 0x45, 0xec, 0x29, 0x7a, 0xdc, 0x12, 0x3b, 0xb0, 0x10, 0xde, 0x26, 0x7b, 0xd9,
+	0xe1, 0xb2, 0x44, 0xee, 0x64, 0x82, 0x3f, 0x96, 0xb6, 0xab, 0x32, 0xcb, 0x65, 0x12, 0x89, 0x3d,
+	0xf8, 0x38, 0xc6, 0xea, 0x40, 0x26, 0xd6, 0xf8, 0x97, 0x51, 0xff, 0x45, 0x82, 0x3f, 0x40, 0xf4,
+	0x23, 0x02, 0xaf, 0x01, 0xb6, 0x3e, 0x80, 0x7a, 0x5f, 0x62, 0x17, 0x8c, 0xcd, 0xb6, 0x78, 0x18,
+	0xd8, 0x20, 0x56, 0x9d, 0x51, 0xd7, 0xbb, 0x82, 0x96, 0x7c, 0x80, 0xd4, 0x09, 0x31, 0xec, 0x81,
+	0xf7, 0xd9, 0x35, 0xb1, 0x97, 0x0a, 0x2d, 0x7b, 0x22, 0xb1, 0x41, 0x0c, 0x2f, 0x9b, 0x62, 0x74,
+	0x74, 0xab, 0xa8, 0xc5, 0x63, 0x2d, 0x21, 0x5a, 0xbc, 0x88, 0xd9, 0xfa, 0x4a, 0x19, 0x5c, 0x77,
+	0x58, 0x5a, 0xc8, 0xa6, 0x43, 0x42, 0x8c, 0xca, 0xd7, 0xc3, 0x6a, 0x11, 0xf4, 0xb8, 0x16, 0xf0,
+	0x6d, 0x31, 0x7f, 0xf9, 0xd7, 0xe8, 0x73, 0xbb, 0x95, 0x41, 0x79, 0x73, 0x20, 0xa6, 0x2c, 0x64,
+	0xb2, 0xd8, 0x1a, 0xbe, 0x95, 0xb5, 0x21, 0x10, 0x19, 0xf9, 0x44, 0xf8, 0x2f, 0xe5, 0x59, 0x08,
+	0x45, 0x35, 0x94, 0xb4, 0xe4, 0x13, 0x01, 0xb1, 0x38, 0xd5, 0x2a, 0x0d, 0x3a, 0x81, 0x85, 0x9c,
+	0x9a, 0x66, 0x96, 0x63, 0xa2, 0x92, 0x49, 0xc7, 0x7f, 0x99, 0xbc, 0xb2, 0x90, 0xaf, 0x81, 0x78,
+	0xc3, 0x49, 0xbd, 0xef, 0x55, 0xd8, 0xd0, 0xcb, 0x60, 0x6a, 0x30, 0x3b, 0x31, 0xee, 0x72, 0xdc,
+	0x7c, 0x3d, 0x15, 0x09, 0x7f, 0x0e, 0x13, 0xf1, 0xea, 0xc1, 0x7e, 0xb5, 0xba, 0x52, 0x42, 0x43,
+	0x72, 0x68, 0xdd, 0x5f, 0x6f, 0x38, 0xec, 0x5d, 0x15, 0x89, 0x4f, 0x7f, 0x3e, 0xa4, 0x59, 0x15,
+	0x23, 0x00, 0xb3, 0x13, 0x97, 0x01, 0xde, 0x2a, 0x3b, 0x05, 0xf3, 0xe0, 0x30, 0x11, 0x1c, 0xff,
+	0x15, 0x1c, 0xff, 0xca, 0xc1, 0x7e, 0xf5, 0xa4, 0x33, 0xe8, 0xc6, 0x3a, 0xed, 0xfe, 0x5d, 0xd9,
+	0x13, 0x21, 0xda, 0x3e, 0x09, 0x8a, 0xad, 0x9d, 0x18, 0xed, 0x3c, 0x62, 0xe7, 0x8d, 0xd0, 0x32,
+	0x88, 0x79, 0xa2, 0x74, 0x2f, 0x88, 0xe5, 0x13, 0x5c, 0x5f, 0xb2, 0x79, 0x1d, 0x6d, 0x5e, 0xf8,
+	0x74, 0xbf, 0x3a, 0xd5, 0x42, 0xd0, 0xbd, 0x32, 0x06, 0x8d, 0x4d, 0x99, 0xf1, 0x02, 0x6f, 0x83,
+	0x4d, 0x25, 0xe2, 0x31, 0x37, 0x61, 0x57, 0xf4, 0x02, 0x1e, 0x76, 0x83, 0xa4, 0x23, 0x34, 0x99,
+	0x7d, 0x15, 0xcd, 0xfa, 0x9f, 0xee, 0x57, 0x27, 0xef, 0x89, 0xc7, 0x2d, 0x44, 0xd4, 0x09, 0x80,
+	0x36, 0x27, 0x93, 0x31, 0x4f, 0xbd, 0x6f, 0xb2, 0xe7, 0x8d, 0xd8, 0xc9, 0x44, 0x12, 0x0a, 0x1e,
+	0x06, 0x61, 0x57, 0xf8, 0xaf, 0xcd, 0x3e, 0x3d, 0x77, 0x72, 0x71, 0x79, 0xfe, 0x33, 0xa8, 0xe9,
+	0xfc, 0x38, 0x9a, 0x39, 0xdf, 0x72, 0x76, 0xea, 0x60, 0x66, 0x25, 0xb1, 0xba, 0x4f, 0x0c, 0x6a,
+	0xe8, 0x79, 0xf3, 0x94, 0x29, 0xff, 0xeb, 0xbd, 0xca, 0xce, 0xa4, 0x71, 0x10, 0x0a, 0xf8, 0x26,
+	0xc5, 0xae, 0xb9, 0x81, 0xae, 0x33, 0x51, 0x08, 0xf2, 0xdd, 0xd2, 0x67, 0x5e, 0xce, 0xd4, 0x32,
+	0x23, 0x34, 0x47, 0xde, 0xeb, 0xcf, 0xc3, 0xd6, 0xa8, 0xdd, 0xf9, 0x74, 0xbf, 0xfa, 0x7e, 0x47,
+	0xda, 0x6e, 0xb6, 0x35, 0x1f, 0xaa, 0xde, 0x42, 0x31, 0xfd, 0x68, 0x6b, 0xf0, 0xf7, 0x42, 0xba,
+	0xdd, 0x59, 0x30, 0x22, 0xcc, 0x80, 0x11, 0x2d, 0x80, 0x8d, 0x24, 0xe8, 0x89, 0xf9, 0xd6, 0xfd,
+	0xf5, 0x07, 0xee, 0xef, 0x06, 0x98, 0x6c, 0x4e, 0xb8, 0x61, 0xe0, 0x29, 0x3e, 0xf1, 0x16, 0xd8,
+	0x24, 0xb2, 0x26, 0xf5, 0xd8, 0x70, 0xd8, 0x68, 0x56, 0x24, 0x3c, 0x56, 0x1d, 0x7f, 0x81, 0xb6,
+	0x86, 0xdd, 0x4b, 0x9a, 0xea, 0xb1, 0x79, 0x44, 0x92, 0x75, 0xd5, 0x19, 0xab, 0x20, 0xb4, 0xf6,
+	0x5f, 0x1f, 0xa7, 0xb0, 0xa2, 0xb5, 0xf7, 0x0a, 0x3b, 0x53, 0x28, 0x20, 0x39, 0x03, 0xf3, 0x9f,
+	0x47, 0xf4, 0xf3, 0x0e, 0x0d, 0x8c, 0x0a, 0x6c, 0x1f, 0x82, 0x82, 0xe1, 0xc5, 0x43, 0x50, 0xb0,
+	0xba, 0xc8, 0xce, 0x05, 0x99, 0x55, 0x5c, 0x8b, 0xae, 0xea, 0x95, 0x73, 0xda, 0x4d, 0x5c, 0xe3,
+	0xb3, 0x20, 0x6c, 0x3a, 0x59, 0xbe, 0xcc, 0x97, 0xd9, 0x73, 0xd2, 0x70, 0x93, 0xa5, 0x42, 0xc3,
+	0x12, 0xf9, 0x5f, 0x20, 0xa6, 0x22, 0x4d, 0x2b, 0x7f, 0x04, 0x6f, 0x17, 0x07, 0xba, 0x23, 0x28,
+	0x19, 0x41, 0xd0, 0xc5, 0xd9, 0xf8, 0x6f, 0xcc, 0x56, 0xe6, 0x2a, 0xcd, 0x33, 0x28, 0x83, 0x3c,
+	0x04, 0x91, 0x17, 0xa6, 0x03, 0x71, 0x52, 0x26, 0x1f, 0x41, 0xf2, 0xd1, 0xc2, 0xea, 0x3e, 0xcc,
+	0x58, 0xe9, 0x41, 0x9c, 0x7c, 0x93, 0xe2, 0x24, 0x41, 0x9a, 0x80, 0x58, 0x41, 0x40, 0x3e, 0xa5,
+	0xeb, 0xec, 0x4c, 0x02, 0x23, 0x61, 0x74, 0x11, 0x11, 0x8f, 0x03, 0x63, 0xfd, 0xb7, 0x50, 0xe9,
+	0x34, 0x08, 0x36, 0xe8, 0xf9, 0x7a, 0x60, 0x2c, 0x94, 0x3b, 0x8e, 0x55, 0x62, 0x30, 0xe1, 0x1d,
+	0xd8, 0xe8, 0xfe, 0xdb, 0xe4, 0x53, 0x4e, 0x02, 0xbb, 0xfe, 0x7d, 0x78, 0xee, 0x6d, 0xb3, 0xe7,
+	0xc3, 0xcc, 0x58, 0xd5, 0x43, 0x42, 0xa7, 0x12, 0xe3, 0xbf, 0xf3, 0xbf, 0xdd, 0x00, 0x75, 0xb4,
+	0xb3, 0x41, 0x66, 0x70, 0x03, 0x34, 0x4f, 0x85, 0xe5, 0x67, 0x5e, 0x8d, 0x5d, 0xa2, 0x6c, 0xa3,
+	0x05, 0xa4, 0x35, 0x01, 0xe6, 0x40, 0x50, 0xac, 0xc3, 0xbb, 0x38, 0xcb, 0x0b, 0x08, 0x6a, 0x0e,
+	0x63, 0xf2, 0xa5, 0x78, 0x99, 0x9d, 0x0e, 0x76, 0x95, 0x8c, 0x5c, 0x84, 0x86, 0x50, 0xfb, 0x45,
+	0xca, 0xc8, 0xf8, 0xb8, 0x96, 0x3f, 0x85, 0x4f, 0x1f, 0x76, 0x45, 0xb8, 0xcd, 0xdb, 0x59, 0x42,
+	0x65, 0xce, 0x96, 0x8a, 0xa4, 0x30, 0xfe, 0xff, 0xa5, 0x4f, 0x8f, 0xc2, 0x55, 0x27, 0xab, 0xa1,
+	0xc8, 0x5b, 0x61, 0xb3, 0xa1, 0x82, 0x00, 0x08, 0xd4, 0x01, 0x33, 0x24, 0xcf, 0x2b, 0x00, 0xa4,
+	0xc9, 0x90, 0x0d, 0xbe, 0x44, 0x73, 0x04, 0x1c, 0x32, 0x0c, 0x48, 0x8d, 0xcb, 0x04, 0x02, 0xa2,
+	0x0c, 0x79, 0xa1, 0x31, 0x5c, 0x38, 0xec, 0x64, 0x8e, 0x32, 0xb7, 0xb9, 0x11, 0x7a, 0x57, 0x86,
+	0xc2, 0xff, 0x7f, 0xb3, 0x95, 0xb9, 0xcf, 0xd5, 0x9e, 0xfb, 0x74, 0xbf, 0x7a, 0xe2, 0xbe, 0x6a,
+	0xad, 0x8b, 0x5d, 0x11, 0x97, 0xcb, 0x88, 0xfb, 0xa4, 0xb1, 0xd1, 0x6e, 0x11, 0x1e, 0x1c, 0x0e,
+	0x38, 0xa0, 0x49, 0x63, 0x49, 0xb3, 0x73, 0x05, 0xd2, 0x97, 0xc1, 0x4e, 0xf3, 0x8c, 0x4a, 0x6d,
+	0x0b, 0x44, 0x30, 0xa1, 0xa2, 0x40, 0xca, 0xd3, 0x20, 0x78, 0xad, 0x23, 0x62, 0xc6, 0x7f, 0x8f,
+	0xaa, 0x1d, 0x97, 0x01, 0x41, 0x44, 0x9c, 0xcb, 0x78, 0x5f, 0x67, 0x37, 0x0a, 0xf2, 0x46, 0x54,
+	0x26, 0x27, 0xbc, 0x8e, 0xc4, 0x41, 0xf9, 0x59, 0xb2, 0xe5, 0x2f, 0xa1, 0xa9, 0x97, 0x73, 0xa5,
+	0x25, 0xd0, 0x71, 0x04, 0x98, 0x6c, 0xae, 0x25, 0xa5, 0x01, 0x3c, 0xc1, 0x5e, 0x77, 0x33, 0x2a,
+	0xf8, 0x58, 0xb9, 0x06, 0x05, 0x52, 0xb6, 0x15, 0xd8, 0xb0, 0x8b, 0xc5, 0x08, 0xc6, 0x3d, 0xe3,
+	0xd7, 0x70, 0x88, 0x57, 0x49, 0x6f, 0xcd, 0xa9, 0x95, 0xaa, 0xcf, 0x55, 0xa5, 0x6b, 0xa0, 0xd3,
+	0x2a, 0x54, 0xbc, 0xaf, 0xb1, 0x1b, 0x90, 0xe6, 0x42, 0xcb, 0x83, 0x24, 0xe2, 0xb2, 0x93, 0x28,
+	0x2d, 0x78, 0xa2, 0x2c, 0xdf, 0x95, 0x46, 0xc2, 0xe8, 0x44, 0x2d, 0x0c, 0xbc, 0x4e, 0xa8, 0xd2,
+	0xbe, 0x5f, 0xc7, 0x31, 0x5e, 0x22, 0xa5, 0xa5, 0x24, 0x5a, 0x43, 0x95, 0x7b, 0xca, 0x3e, 0x24,
+	0x05, 0xe2, 0x17, 0x66, 0x2d, 0xa9, 0xab, 0xb4, 0xef, 0xad, 0xb0, 0x2a, 0x32, 0xdb, 0x34, 0x16,
+	0x90, 0x77, 0x64, 0xdb, 0x71, 0x07, 0x03, 0x5f, 0x17, 0xd9, 0x8f, 0xbf, 0x8c, 0x06, 0x2f, 0xe6,
+	0xb0, 0xbb, 0x65, 0xd4, 0x46, 0x1b, 0x09, 0x90, 0xd7, 0x61, 0x8b, 0xa6, 0x8b, 0x1c, 0xbf, 0xa8,
+	0x29, 0x4a, 0x14, 0x8c, 0xab, 0x64, 0xdc, 0x94, 0xfd, 0x15, 0x5a, 0x0e, 0xd0, 0x1c, 0x54, 0x1a,
+	0x03, 0x3a, 0xb6, 0x91, 0x1c, 0x9a, 0x35, 0x14, 0x32, 0x56, 0x18, 0x0b, 0xa1, 0x6f, 0x50, 0xfc,
+	0xe9, 0x20, 0x89, 0x54, 0x8f, 0x1b, 0x21, 0x22, 0x7f, 0x15, 0xe3, 0xe6, 0xb4, 0x03, 0x15, 0x3d,
+	0x8d, 0x26, 0x42, 0x5a, 0x42, 0x44, 0x1e, 0x67, 0x37, 0xb2, 0xa4, 0x98, 0x9c, 0x88, 0x78, 0xa2,
+	0x60, 0xe9, 0x76, 0x71, 0x9b, 0x39, 0xfa, 0x88, 0x2e, 0x99, 0xef, 0xe2, 0xf7, 0x71, 0x9a, 0x73,
+	0x43, 0x4a, 0xf7, 0x54, 0x52, 0x77, 0x2a, 0x48, 0x22, 0xc1, 0x53, 0xf3, 0x2d, 0x7d, 0x97, 0xbd,
+	0x78, 0x78, 0x8e, 0xb8, 0x0f, 0x53, 0xa1, 0x6d, 0xa6, 0xb7, 0x88, 0xbc, 0xdd, 0xc2, 0xe0, 0x3a,
+	0x3b, 0x3a, 0xd3, 0xba, 0x32, 0xb6, 0x51, 0xc2, 0x79, 0x1f, 0xb2, 0xeb, 0x87, 0xcd, 0xe5, 0x21,
+	0x51, 0x67, 0x10, 0x17, 0xb5, 0xda, 0x0a, 0xb6, 0x24, 0x6c, 0x31, 0x7f, 0x0d, 0xad, 0xbe, 0x34,
+	0x6a, 0xd5, 0xd5, 0xdb, 0xcd, 0x2c, 0x86, 0x9c, 0x98, 0xa3, 0x81, 0xe6, 0x0f, 0xd7, 0xd0, 0xe5,
+	0xcf, 0x84, 0x4b, 0x21, 0x8c, 0x7f, 0x9b, 0x68, 0x7e, 0xb9, 0x8e, 0x1e, 0x7c, 0x98, 0x35, 0x02,
+	0x79, 0x37, 0xd9, 0x0b, 0xe0, 0x7e, 0x83, 0xc2, 0xa2, 0x58, 0xbe, 0x3b, 0x2e, 0x3e, 0xa9, 0xb4,
+	0x9f, 0x97, 0x17, 0xf9, 0x4a, 0x7d, 0x95, 0xbd, 0x9a, 0xbf, 0x48, 0x57, 0x01, 0x53, 0x4b, 0xb5,
+	0x82, 0x94, 0xe1, 0xb6, 0x27, 0xd6, 0xb6, 0x18, 0x18, 0x68, 0xc5, 0xd6, 0xc9, 0xb5, 0x9d, 0xca,
+	0x2d, 0xd0, 0x68, 0x14, 0x0a, 0x6b, 0x09, 0x14, 0xbc, 0xeb, 0x05, 0xda, 0x7b, 0x8b, 0xf9, 0x34,
+	0x23, 0xad, 0x7a, 0x3c, 0xb0, 0xaa, 0x27, 0xc3, 0x62, 0x4e, 0x77, 0xa9, 0xee, 0xc4, 0x39, 0x69,
+	0xd5, 0x5b, 0x42, 0x69, 0x3e, 0xab, 0x79, 0x76, 0x56, 0x24, 0x54, 0xeb, 0x76, 0x55, 0x4f, 0xe4,
+	0xf1, 0xe1, 0x1e, 0x95, 0x2c, 0x4e, 0x74, 0x4b, 0xf5, 0x84, 0x8b, 0x04, 0x6f, 0xb2, 0xa9, 0xe1,
+	0x45, 0x6c, 0x2b, 0x2d, 0xc2, 0x00, 0xd2, 0xd4, 0x06, 0x8d, 0x53, 0x5e, 0xba, 0xd5, 0x5c, 0x08,
+	0x25, 0xcc, 0x6e, 0xa0, 0x25, 0xc5, 0x90, 0x44, 0xe4, 0x61, 0xb5, 0xd4, 0x2c, 0x28, 0xe6, 0xdb,
+	0xa0, 0x12, 0x26, 0x87, 0xaf, 0x15, 0xe8, 0x41, 0x6b, 0x20, 0x9f, 0x7d, 0x8d, 0x9d, 0x2d, 0xc7,
+	0xa1, 0xbc, 0x07, 0x76, 0xff, 0xa8, 0x1e, 0x98, 0x57, 0x42, 0xe7, 0x6d, 0xaf, 0x45, 0x76, 0xce,
+	0xf4, 0x8d, 0x15, 0x3d, 0x2e, 0x23, 0x91, 0x58, 0x98, 0x15, 0x91, 0xb3, 0x26, 0xd6, 0x2d, 0x67,
+	0x49, 0xb8, 0xe6, 0x64, 0x44, 0xa9, 0x3e, 0x64, 0xd3, 0x91, 0x30, 0xa1, 0x96, 0xa9, 0x55, 0x9a,
+	0xef, 0x06, 0xb1, 0x8c, 0x4a, 0x2c, 0xb9, 0x45, 0x7d, 0xc6, 0x4f, 0xf7, 0xab, 0xfe, 0x72, 0x81,
+	0x7a, 0x58, 0x80, 0x90, 0xd2, 0xfa, 0xd1, 0x11, 0x12, 0xef, 0x1e, 0xbb, 0x3a, 0x54, 0x5d, 0x74,
+	0x03, 0xd3, 0xe5, 0x1d, 0xad, 0x46, 0x97, 0x69, 0x13, 0x97, 0x69, 0xb6, 0x8c, 0xbd, 0x15, 0x98,
+	0xee, 0xfb, 0x80, 0x2c, 0xaf, 0xd1, 0x0a, 0xab, 0x52, 0xf1, 0xad, 0x74, 0x24, 0x13, 0x2c, 0xd4,
+	0x5c, 0x7d, 0xd6, 0x16, 0x1a, 0xd8, 0xac, 0xf1, 0x1f, 0x50, 0xd4, 0x43, 0xd8, 0x06, 0xa1, 0xf2,
+	0xca, 0x2c, 0xc7, 0x78, 0x0f, 0xd9, 0xdc, 0xf0, 0x87, 0x97, 0xbd, 0x54, 0xab, 0x5d, 0x11, 0xc1,
+	0xf6, 0xfc, 0x28, 0x4f, 0xd3, 0xd4, 0x8c, 0x7a, 0xe8, 0xda, 0x03, 0x25, 0x4f, 0x58, 0x73, 0xe8,
+	0xe5, 0x01, 0x98, 0xfa, 0x52, 0x92, 0xdd, 0x1c, 0xb6, 0x8b, 0x7b, 0xa0, 0xa8, 0xc5, 0x30, 0xb7,
+	0x50, 0x35, 0x08, 0xff, 0xd1, 0x3a, 0x6c, 0xf5, 0xfd, 0xaf, 0xe0, 0x10, 0xaf, 0x95, 0x87, 0xc0,
+	0xed, 0x90, 0x57, 0x69, 0xab, 0x4a, 0xb7, 0x72, 0x2d, 0x5c, 0x92, 0x5a, 0xdf, 0x7b, 0x87, 0x9d,
+	0x1f, 0x6c, 0x12, 0xe0, 0x72, 0xb2, 0x54, 0xee, 0x7e, 0x40, 0x35, 0x5f, 0xbe, 0x4b, 0x9a, 0x24,
+	0xce, 0x17, 0xf1, 0x21, 0x9b, 0x8b, 0x44, 0x18, 0x07, 0x5a, 0xf0, 0x30, 0xd3, 0x06, 0xe7, 0xe4,
+	0xd2, 0x56, 0xee, 0x75, 0x85, 0xa5, 0x0f, 0xe9, 0xed, 0x1d, 0xbe, 0x8e, 0xf0, 0x22, 0xc9, 0x39,
+	0xaf, 0xcb, 0xed, 0x76, 0xd9, 0xe2, 0x11, 0xab, 0x4a, 0x74, 0xa1, 0xbc, 0xb6, 0xb0, 0x12, 0xd8,
+	0x55, 0xf3, 0xbf, 0x7a, 0xf8, 0xe5, 0xf3, 0xf5, 0x45, 0x2a, 0x51, 0x5a, 0xe4, 0x55, 0x45, 0xad,
+	0x57, 0x6f, 0x83, 0x5d, 0x1b, 0xc7, 0x62, 0x31, 0x1d, 0xf4, 0x60, 0xc5, 0xf3, 0xe9, 0xff, 0x7f,
+	0xf2, 0xab, 0x43, 0x7c, 0x76, 0x23, 0xa1, 0xae, 0x45, 0x3e, 0xf5, 0x0f, 0xd8, 0xf5, 0x31, 0x91,
+	0x63, 0xa4, 0xcb, 0x5a, 0x58, 0xfd, 0x1a, 0x5a, 0xbd, 0x76, 0x28, 0xa0, 0x0c, 0x75, 0x5c, 0x4b,
+	0x2e, 0x3b, 0x58, 0x95, 0x20, 0x7e, 0x1c, 0xf4, 0xcd, 0x68, 0xbb, 0xf4, 0xeb, 0xe4, 0xb2, 0x05,
+	0x6c, 0x09, 0x51, 0xc3, 0x4d, 0xd3, 0xdb, 0xec, 0x8a, 0x63, 0x2d, 0xa1, 0x16, 0x50, 0xe6, 0xa3,
+	0x77, 0xf2, 0xcc, 0x60, 0x31, 0xb1, 0x67, 0xb5, 0xe8, 0x09, 0xe3, 0x73, 0xb4, 0x34, 0x43, 0xc8,
+	0x3a, 0x02, 0xd1, 0x33, 0x1f, 0x00, 0x6c, 0xc5, 0xa1, 0xbc, 0x8f, 0xd8, 0x4d, 0xda, 0x45, 0x5a,
+	0x01, 0x7b, 0x10, 0xbd, 0x2d, 0xa1, 0x4d, 0x57, 0xa6, 0x86, 0x5b, 0xe5, 0x8a, 0x59, 0x1e, 0x65,
+	0xe8, 0xb1, 0xa5, 0x18, 0xe3, 0x7f, 0x03, 0x8d, 0xdf, 0x40, 0xd5, 0xa6, 0x8a, 0xc5, 0xdd, 0x81,
+	0xe2, 0xa6, 0xa2, 0x62, 0x76, 0x19, 0xb5, 0x4a, 0xc4, 0xc8, 0xab, 0xb3, 0x19, 0xd7, 0x3f, 0x8c,
+	0x4a, 0x84, 0x8a, 0x6a, 0x5c, 0xe2, 0xb1, 0x01, 0x26, 0xfe, 0x0b, 0x39, 0x6a, 0x40, 0xa1, 0xb0,
+	0x32, 0x45, 0x1e, 0x5b, 0x26, 0x3b, 0x60, 0x77, 0x57, 0xf0, 0x54, 0x69, 0x1b, 0xc4, 0x83, 0x6f,
+	0x12, 0x0d, 0x93, 0x9d, 0x25, 0x44, 0x35, 0x08, 0x94, 0x7f, 0x8a, 0xb7, 0x99, 0x9f, 0x25, 0x5b,
+	0x2a, 0x4b, 0x22, 0x11, 0xf1, 0x34, 0xd0, 0x41, 0x1c, 0x8b, 0xd8, 0x35, 0xef, 0x04, 0x6d, 0x99,
+	0x42, 0xde, 0x70, 0x62, 0x6a, 0xde, 0xb5, 0xd9, 0xeb, 0x83, 0x8f, 0x48, 0x19, 0x0f, 0x58, 0x85,
+	0xd6, 0x22, 0x0e, 0xac, 0x88, 0x78, 0x91, 0x03, 0x4c, 0xb6, 0xb5, 0x93, 0x09, 0xd8, 0x6d, 0x7e,
+	0x7b, 0xc4, 0xb1, 0x31, 0xed, 0x3d, 0x28, 0x69, 0xad, 0x38, 0xa5, 0x56, 0xa1, 0x03, 0x2f, 0x7a,
+	0x98, 0x32, 0x38, 0x57, 0x4f, 0x83, 0x44, 0x86, 0xc6, 0xef, 0xd0, 0x8b, 0x8e, 0xf2, 0x84, 0x35,
+	0x04, 0x35, 0x10, 0xe3, 0xed, 0xb2, 0x77, 0x8e, 0xd8, 0x89, 0xa3, 0x8d, 0xad, 0xb6, 0x04, 0xb6,
+	0x6c, 0x38, 0x04, 0x9a, 0x5d, 0x4a, 0xd6, 0x5d, 0x1c, 0xe0, 0xe6, 0xb8, 0x0d, 0x39, 0xdc, 0xea,
+	0x5a, 0x25, 0xdd, 0xe5, 0x42, 0x15, 0xaa, 0xcb, 0x72, 0xbd, 0x21, 0x8d, 0x8a, 0x29, 0x95, 0xc4,
+	0x50, 0x58, 0xf8, 0x12, 0xbf, 0xb4, 0x3f, 0x28, 0x2f, 0xd6, 0x72, 0x00, 0x16, 0x1e, 0xde, 0x23,
+	0x36, 0x51, 0x6a, 0x92, 0x51, 0xfe, 0xf9, 0x68, 0xb6, 0x32, 0xf7, 0xfc, 0xe2, 0x6b, 0x9f, 0x59,
+	0x05, 0x96, 0x5a, 0x67, 0x98, 0x8f, 0x4e, 0xeb, 0xe1, 0x07, 0x90, 0xb0, 0x8f, 0x58, 0x0f, 0xca,
+	0x42, 0x10, 0xa6, 0x13, 0x7a, 0xfb, 0x6d, 0x4a, 0xd8, 0xe3, 0xde, 0x1e, 0x13, 0xd1, 0x00, 0xea,
+	0xd9, 0x52, 0xdb, 0xba, 0xbd, 0xcd, 0x63, 0x15, 0x6e, 0x17, 0x41, 0x1e, 0xfb, 0x46, 0xf2, 0x09,
+	0xf2, 0xf0, 0x18, 0xcf, 0x0b, 0xae, 0x1e, 0xec, 0x57, 0x67, 0xf3, 0xd2, 0x61, 0xf5, 0xce, 0x3a,
+	0xa1, 0x21, 0xb4, 0x97, 0xb0, 0xcd, 0xd9, 0xdc, 0xe2, 0xea, 0xf6, 0x78, 0x84, 0xf7, 0x3e, 0x9b,
+	0x8d, 0x32, 0x8d, 0x91, 0xe0, 0xc8, 0x11, 0x7b, 0x44, 0xfc, 0x1c, 0xee, 0x08, 0x43, 0x2b, 0xac,
+	0x6a, 0xba, 0xb8, 0x2f, 0x8f, 0xb4, 0x93, 0x92, 0xaf, 0x11, 0xec, 0x08, 0x33, 0x35, 0x36, 0xd3,
+	0x0b, 0xf6, 0x8a, 0x14, 0x04, 0x36, 0xb0, 0x17, 0x42, 0x91, 0xd8, 0x8a, 0xc8, 0x4f, 0xb0, 0x36,
+	0x9c, 0xee, 0x05, 0x7b, 0x2e, 0x11, 0xad, 0x2a, 0x0c, 0x91, 0xf5, 0x1c, 0xe1, 0xdd, 0x62, 0x93,
+	0xc6, 0x6a, 0x19, 0x5a, 0x1e, 0x45, 0xb1, 0xa3, 0x7c, 0xc0, 0x89, 0x15, 0xae, 0xdc, 0x0b, 0x07,
+	0xfb, 0x55, 0xaf, 0x85, 0xf2, 0xe5, 0xe5, 0xf5, 0xa5, 0x5c, 0xda, 0xf4, 0x48, 0x67, 0x39, 0x8a,
+	0x8b, 0x67, 0xde, 0x97, 0xd9, 0xc5, 0x2c, 0xc1, 0xf3, 0x1d, 0x23, 0xac, 0xa5, 0xba, 0xc0, 0x0a,
+	0x0d, 0x6f, 0x08, 0xb5, 0x8d, 0xbf, 0x83, 0x3c, 0xe8, 0x3c, 0x61, 0x5a, 0x04, 0x59, 0xcb, 0x11,
+	0x77, 0x44, 0xdf, 0xbb, 0xcf, 0x5e, 0x1a, 0x49, 0xe1, 0xa0, 0xaa, 0xd2, 0xc3, 0x8b, 0xa3, 0xe9,
+	0x34, 0x62, 0x28, 0x6b, 0xab, 0x70, 0x7b, 0x23, 0x1d, 0x5d, 0xa1, 0x75, 0xf6, 0xe2, 0xb0, 0x49,
+	0x70, 0x27, 0x09, 0x31, 0x68, 0x40, 0x0c, 0xe4, 0x9e, 0x6f, 0xd0, 0x5e, 0xb5, 0x6c, 0xaf, 0xe1,
+	0x80, 0x05, 0x11, 0x90, 0x7b, 0xde, 0x32, 0x9b, 0xc9, 0xa9, 0x37, 0x85, 0xea, 0xb6, 0x10, 0xd1,
+	0x50, 0x73, 0xd9, 0xd2, 0x57, 0x73, 0xa8, 0x7a, 0x01, 0x2a, 0x77, 0x98, 0x6f, 0xb3, 0x0b, 0x48,
+	0x1f, 0x8e, 0x68, 0x0b, 0x64, 0x63, 0xda, 0x02, 0x53, 0xa0, 0x30, 0xae, 0x27, 0xb0, 0xc4, 0x2e,
+	0xa1, 0x2d, 0x6c, 0x7c, 0xf3, 0x54, 0xa6, 0x22, 0x96, 0x43, 0xe7, 0x36, 0xbb, 0x74, 0x46, 0x05,
+	0xa0, 0x47, 0x80, 0x69, 0x14, 0x90, 0xd2, 0x31, 0xd7, 0x60, 0x89, 0x7a, 0x42, 0x77, 0x84, 0x3b,
+	0x73, 0xcb, 0x4d, 0x3c, 0x26, 0x13, 0x05, 0xe8, 0x2e, 0x60, 0x90, 0x0c, 0xe4, 0x26, 0xde, 0x65,
+	0x38, 0x00, 0x4f, 0xb2, 0x01, 0x1f, 0x4a, 0x85, 0xab, 0xe5, 0xfd, 0x3d, 0xf4, 0x41, 0x64, 0x44,
+	0xf7, 0xb2, 0x9c, 0x10, 0x35, 0x04, 0x55, 0xed, 0xde, 0x1d, 0xea, 0xce, 0x39, 0xf2, 0xb0, 0x25,
+	0xa0, 0x0e, 0x00, 0x57, 0xf4, 0xfb, 0xe8, 0x80, 0x53, 0x07, 0xfb, 0xd5, 0xb3, 0x4b, 0x99, 0x55,
+	0xe4, 0xb1, 0x35, 0x94, 0x2f, 0x2f, 0xaf, 0x53, 0xdb, 0x2e, 0x2c, 0x3f, 0x8c, 0x62, 0xef, 0x0d,
+	0x36, 0x15, 0xc6, 0xca, 0xe4, 0xe4, 0xca, 0xf0, 0xc0, 0xe6, 0x87, 0x27, 0x4f, 0xf0, 0x2d, 0x26,
+	0x51, 0x4c, 0x5c, 0xca, 0x2c, 0x59, 0x77, 0x7e, 0xb2, 0xc1, 0xa6, 0xd2, 0x38, 0xed, 0x98, 0x9d,
+	0x18, 0x7d, 0xc4, 0xed, 0x07, 0x99, 0x58, 0xe5, 0xff, 0x02, 0xce, 0xc2, 0x3f, 0xd8, 0xaf, 0x4e,
+	0x36, 0xd6, 0xd3, 0x0e, 0xb5, 0x49, 0x69, 0x43, 0xac, 0x25, 0x56, 0x35, 0x27, 0x9d, 0xe2, 0xd0,
+	0x53, 0xa8, 0xd1, 0x86, 0xdd, 0x6e, 0x57, 0x6a, 0x9b, 0x8d, 0x39, 0xdc, 0x20, 0x9e, 0xfb, 0x8b,
+	0x54, 0xa3, 0x95, 0xdd, 0xef, 0x21, 0x29, 0x0c, 0x47, 0x7d, 0x62, 0xba, 0xdf, 0x60, 0x37, 0x86,
+	0x8d, 0x5b, 0x2d, 0x81, 0xa8, 0x70, 0x23, 0x7b, 0x32, 0x0e, 0x74, 0xe9, 0x64, 0x96, 0x9c, 0xf2,
+	0x97, 0xd0, 0xfc, 0x2b, 0x65, 0xf3, 0x9b, 0xa4, 0xd2, 0x2a, 0x34, 0x36, 0x4a, 0x0a, 0x5e, 0x8f,
+	0xbd, 0x71, 0x34, 0x47, 0xb7, 0x32, 0x09, 0xb1, 0x3b, 0x41, 0x04, 0xbb, 0x2b, 0x13, 0x8b, 0x85,
+	0xba, 0x4c, 0x3a, 0xfe, 0x37, 0x71, 0xa4, 0xf9, 0x23, 0x08, 0x3b, 0x6a, 0x6e, 0x50, 0xb9, 0x79,
+	0x4b, 0x26, 0xb6, 0x4e, 0x5a, 0x9e, 0x3a, 0x72, 0xb8, 0x31, 0x6f, 0x46, 0xe7, 0x77, 0x72, 0x17,
+	0x62, 0xd4, 0x2f, 0xe3, 0x70, 0xaf, 0x8f, 0x1b, 0xee, 0xd0, 0x0b, 0xb6, 0x06, 0x7a, 0xde, 0x87,
+	0xec, 0xfa, 0x11, 0x03, 0x96, 0x0f, 0x88, 0xf3, 0x97, 0xfa, 0x95, 0x0a, 0x71, 0xce, 0x71, 0xc3,
+	0x7c, 0x58, 0x9c, 0x1a, 0xe7, 0x2f, 0x93, 0xb1, 0xb7, 0x8f, 0xb0, 0x5d, 0x1c, 0xb5, 0xe3, 0x87,
+	0x1f, 0x4c, 0x87, 0x03, 0x9d, 0xe8, 0x05, 0x56, 0xf8, 0xbf, 0x4a, 0x23, 0x2d, 0x8e, 0x1b, 0x29,
+	0x3f, 0x85, 0x07, 0x37, 0x18, 0xe8, 0xae, 0x38, 0x55, 0xef, 0x71, 0x99, 0x76, 0xa0, 0x86, 0x6b,
+	0xb1, 0x51, 0x3e, 0xc7, 0x36, 0xe6, 0x11, 0x4e, 0x68, 0xfc, 0x5f, 0xab, 0x8c, 0xf0, 0x0e, 0x08,
+	0x7e, 0xae, 0xd7, 0x86, 0xfa, 0x8f, 0xa4, 0xed, 0x8e, 0xf5, 0x48, 0xe3, 0x35, 0xd8, 0xb5, 0xd2,
+	0xc0, 0x99, 0xe9, 0x72, 0xd5, 0x6e, 0x1b, 0x41, 0xdb, 0xc7, 0x75, 0x86, 0x60, 0x39, 0xfd, 0x6f,
+	0xd1, 0x20, 0xb3, 0x83, 0x41, 0x32, 0xd3, 0xdd, 0x40, 0x2c, 0xec, 0x19, 0xec, 0x89, 0xc0, 0x42,
+	0x7a, 0x2d, 0x76, 0x1a, 0x9b, 0xd6, 0xc4, 0x53, 0x91, 0x89, 0x7c, 0xbb, 0x82, 0x54, 0xe4, 0xfa,
+	0x67, 0x52, 0x91, 0x46, 0x1c, 0x24, 0xc8, 0x5b, 0x91, 0x88, 0x9c, 0x4a, 0xcb, 0xff, 0x7a, 0x0f,
+	0x46, 0x69, 0x48, 0xaa, 0xe2, 0x7e, 0x4f, 0xe9, 0xb4, 0x2b, 0x43, 0xe4, 0xa3, 0x3d, 0x61, 0x85,
+	0xc6, 0x64, 0xf0, 0x1b, 0x95, 0xc3, 0x3c, 0xa4, 0x31, 0x40, 0x37, 0x72, 0x30, 0x64, 0x84, 0x3e,
+	0x7b, 0x49, 0x69, 0xd9, 0x91, 0x09, 0x97, 0x11, 0xa6, 0xa9, 0x58, 0x75, 0x64, 0x18, 0xc4, 0x78,
+	0xc3, 0x69, 0x28, 0x33, 0xfc, 0x26, 0x58, 0x3d, 0x55, 0xbb, 0x76, 0xb0, 0x5f, 0xbd, 0xbc, 0x81,
+	0x2a, 0x6b, 0xcb, 0xab, 0x4a, 0xaf, 0x13, 0x7e, 0x39, 0xb0, 0x41, 0x29, 0x47, 0x34, 0x2f, 0x93,
+	0xd5, 0xb5, 0xe8, 0x48, 0x88, 0xf7, 0x35, 0xf6, 0xda, 0xcf, 0xaf, 0x4a, 0xf8, 0x96, 0x52, 0x31,
+	0x17, 0x49, 0xd6, 0xf3, 0xbf, 0x53, 0x71, 0x4d, 0xce, 0xcf, 0x2c, 0x50, 0x6a, 0x4a, 0xc5, 0x2b,
+	0x49, 0xd6, 0x3b, 0xbc, 0x60, 0x98, 0x1a, 0x22, 0xee, 0x6e, 0xa7, 0xe0, 0x68, 0xb0, 0xa5, 0x43,
+	0xe3, 0xff, 0xd6, 0x98, 0x05, 0xc3, 0x24, 0x11, 0x35, 0x08, 0xdc, 0x2a, 0xb0, 0xde, 0xdd, 0xd1,
+	0x84, 0x1c, 0xaa, 0x24, 0xc2, 0x3b, 0x04, 0x41, 0xec, 0xd8, 0x3d, 0x7c, 0x83, 0x8f, 0x2b, 0x87,
+	0x33, 0x72, 0x7d, 0x80, 0x44, 0x3e, 0x0f, 0xeb, 0x1f, 0xb2, 0x85, 0x11, 0xef, 0xa3, 0xa8, 0x84,
+	0xce, 0xe7, 0x1a, 0x63, 0x8e, 0x68, 0x43, 0x11, 0x14, 0x06, 0x89, 0xff, 0xdb, 0x95, 0x91, 0x70,
+	0x08, 0x7e, 0x88, 0x31, 0x09, 0xdc, 0xd0, 0xf5, 0xc6, 0x56, 0x9d, 0x0a, 0x1e, 0x9b, 0x7f, 0xbb,
+	0xc2, 0x6e, 0xb8, 0xaf, 0x5c, 0x5c, 0x38, 0xfb, 0xec, 0x8f, 0xfd, 0x3b, 0x30, 0xc6, 0xc9, 0xc5,
+	0x4b, 0x25, 0x7f, 0xcd, 0xac, 0x8c, 0xe7, 0xbb, 0x71, 0x38, 0xbf, 0x99, 0x9b, 0xa8, 0x1d, 0xff,
+	0xf1, 0x7e, 0xf5, 0x58, 0x73, 0x8e, 0x4c, 0x17, 0x8f, 0x8f, 0xfe, 0xe2, 0x21, 0x9b, 0xd9, 0xea,
+	0xa7, 0x81, 0x31, 0x3c, 0x0d, 0x89, 0xe9, 0x09, 0x5d, 0x9c, 0xba, 0x07, 0xca, 0x58, 0xff, 0x77,
+	0xf1, 0xdd, 0x6a, 0x33, 0x07, 0xfb, 0xd5, 0xe9, 0x1a, 0x42, 0x1b, 0xf5, 0x66, 0x13, 0x81, 0xee,
+	0xec, 0x7d, 0x69, 0xa3, 0xb5, 0xd9, 0x9c, 0x26, 0x33, 0x8d, 0x50, 0x0f, 0xcb, 0x94, 0xb1, 0xde,
+	0x23, 0x36, 0xe7, 0x58, 0x1c, 0xd5, 0xa9, 0x10, 0x82, 0x3b, 0x50, 0xa6, 0x60, 0xa7, 0xbb, 0x0f,
+	0xce, 0x95, 0x5f, 0x87, 0xf3, 0x7f, 0x8f, 0x96, 0xf2, 0x2a, 0x29, 0x2c, 0x01, 0x7e, 0xd3, 0xc1,
+	0xef, 0xe6, 0xe8, 0xfc, 0xf2, 0x9b, 0xb7, 0xc1, 0xae, 0xe6, 0xe4, 0x69, 0x57, 0x84, 0x3c, 0x4b,
+	0x20, 0x2e, 0x89, 0xa0, 0x83, 0xef, 0x90, 0x84, 0x22, 0xa6, 0x72, 0xc4, 0xff, 0x7d, 0x17, 0x27,
+	0x1c, 0xf8, 0xa1, 0x08, 0x1f, 0x00, 0x74, 0x05, 0x90, 0xf5, 0x12, 0xd0, 0xbb, 0xc9, 0xce, 0x69,
+	0x01, 0x89, 0x1e, 0x6f, 0x14, 0x8a, 0xd4, 0xba, 0x8f, 0xef, 0x7f, 0xb7, 0x82, 0xc5, 0xce, 0xd9,
+	0x42, 0xba, 0x0c, 0x42, 0x3a, 0x13, 0xd9, 0x64, 0x2f, 0x0f, 0x6e, 0x60, 0x15, 0x6d, 0x20, 0xae,
+	0xd5, 0x63, 0x1e, 0xaa, 0x2c, 0xb1, 0xdc, 0x76, 0xb5, 0x30, 0x5d, 0x15, 0x47, 0xfe, 0x1f, 0x80,
+	0x99, 0xe3, 0xcd, 0x2b, 0x03, 0xbc, 0x6b, 0x00, 0x35, 0xd5, 0xe3, 0x3a, 0x60, 0x37, 0x73, 0x28,
+	0x78, 0x75, 0xc9, 0xaa, 0x51, 0xda, 0x8e, 0xb5, 0xf8, 0x87, 0x64, 0xb1, 0x3a, 0xc0, 0xb6, 0x94,
+	0xb6, 0x3f, 0xd7, 0x9c, 0x3b, 0x5a, 0x3c, 0x64, 0xee, 0x7b, 0x87, 0xcd, 0xd1, 0x59, 0xe3, 0x88,
+	0xb9, 0xf7, 0xd8, 0x45, 0xd7, 0xfc, 0x28, 0x59, 0x2d, 0x4e, 0x2d, 0x8d, 0xff, 0x47, 0xb4, 0xe2,
+	0xe7, 0x09, 0x34, 0xb8, 0x75, 0x96, 0x9f, 0x5e, 0x9a, 0x91, 0x09, 0x61, 0x76, 0x1c, 0x37, 0xa1,
+	0x3f, 0x3e, 0x34, 0x21, 0x08, 0xe8, 0x87, 0x27, 0x74, 0x93, 0x9d, 0x8b, 0x45, 0x27, 0x08, 0xfb,
+	0x7c, 0x37, 0xd0, 0x61, 0x37, 0xd0, 0xdc, 0xf6, 0x53, 0x48, 0xb5, 0x7f, 0x42, 0x33, 0x39, 0x4b,
+	0xd2, 0x87, 0x24, 0xdc, 0x44, 0x19, 0x50, 0x79, 0x3a, 0xf4, 0x1b, 0xbd, 0xfc, 0xc3, 0x65, 0xc2,
+	0x7b, 0x19, 0x35, 0xb0, 0x8d, 0xff, 0xa7, 0x64, 0x62, 0x06, 0xb1, 0xc3, 0xf7, 0x80, 0xd6, 0x92,
+	0xbb, 0x39, 0xcc, 0x6b, 0xb1, 0x97, 0xf2, 0x9d, 0x13, 0xc9, 0x8e, 0x30, 0x16, 0x02, 0x5a, 0x2c,
+	0x12, 0x61, 0x0c, 0xa7, 0x23, 0xc3, 0x9c, 0xfe, 0x7e, 0x9f, 0x0c, 0x5e, 0x71, 0xf0, 0x65, 0x44,
+	0xb7, 0x72, 0x70, 0x1d, 0xb0, 0x39, 0x0f, 0x6e, 0xb0, 0xab, 0xe5, 0x24, 0x8c, 0xd7, 0xd8, 0xf2,
+	0x9e, 0x47, 0x18, 0x50, 0x43, 0x14, 0x78, 0xcb, 0x9f, 0x57, 0x46, 0xea, 0x17, 0xba, 0xcb, 0x56,
+	0x23, 0x68, 0x7d, 0x80, 0x1c, 0x6e, 0x93, 0xf7, 0xca, 0xcb, 0xee, 0xff, 0x45, 0x05, 0x4f, 0x2d,
+	0x26, 0x07, 0xbc, 0x7c, 0xb0, 0xd4, 0xde, 0x5b, 0x6c, 0x8a, 0xce, 0x46, 0x45, 0x44, 0xb5, 0xc1,
+	0x80, 0xce, 0xff, 0x25, 0x0d, 0x7e, 0x2e, 0x97, 0x63, 0x59, 0x50, 0x50, 0xf9, 0xa1, 0x82, 0x89,
+	0x16, 0x82, 0x2e, 0xb5, 0x0c, 0x0f, 0xfe, 0x09, 0x0d, 0x3e, 0x53, 0x60, 0x71, 0x1d, 0xf0, 0x7e,
+	0x4b, 0x79, 0x1a, 0x01, 0x9b, 0x2f, 0x2d, 0x08, 0x24, 0xf5, 0xa1, 0x5b, 0x7d, 0xc8, 0x4a, 0xb4,
+	0xd8, 0x15, 0xda, 0xe4, 0x17, 0xb9, 0xfe, 0x8a, 0x66, 0x37, 0xe8, 0x11, 0x43, 0x56, 0x2f, 0xdd,
+	0xe5, 0x03, 0x26, 0xd2, 0x24, 0x0d, 0x72, 0xcd, 0xfb, 0xec, 0x9a, 0x16, 0x1d, 0x69, 0x20, 0x7b,
+	0xc7, 0x78, 0x76, 0xf8, 0x38, 0xc0, 0xbb, 0x6c, 0x89, 0x15, 0x09, 0x72, 0x1f, 0xb1, 0x8b, 0xe7,
+	0x88, 0x7f, 0xed, 0x16, 0x3d, 0x47, 0xaf, 0x03, 0xf8, 0x51, 0x20, 0x6d, 0xbd, 0x80, 0xae, 0x20,
+	0xd2, 0x8b, 0x58, 0x15, 0x33, 0x53, 0x9a, 0x59, 0x43, 0xc7, 0x70, 0x49, 0x7e, 0x61, 0x2a, 0x3f,
+	0xde, 0xf9, 0x9b, 0x52, 0xa0, 0x85, 0xd4, 0xd4, 0xc8, 0xac, 0xd9, 0x48, 0xee, 0xa9, 0x84, 0xae,
+	0x4a, 0xb9, 0x03, 0x9e, 0xe6, 0x74, 0x66, 0x44, 0x3d, 0x1d, 0x2b, 0xf3, 0xda, 0xec, 0xf3, 0xa3,
+	0x9f, 0x28, 0xaf, 0x79, 0xb1, 0x07, 0x35, 0x76, 0xdc, 0xbf, 0xa5, 0x97, 0xb8, 0x3e, 0xfc, 0xf1,
+	0x5c, 0xf9, 0x2b, 0x93, 0xce, 0x98, 0x71, 0xbe, 0xce, 0x5e, 0x1b, 0x53, 0x55, 0x8b, 0x58, 0x62,
+	0xdc, 0x2c, 0x7a, 0x7b, 0xed, 0xa0, 0x27, 0x63, 0x29, 0x8c, 0xff, 0x77, 0x15, 0x77, 0xa6, 0x3b,
+	0x52, 0x5c, 0xaf, 0x90, 0xc6, 0x5d, 0xa7, 0xb0, 0xea, 0xf0, 0x5e, 0xad, 0x5c, 0x3f, 0x3a, 0x46,
+	0x52, 0x1e, 0xc2, 0xff, 0x41, 0x65, 0xa4, 0x80, 0x24, 0x5f, 0x2b, 0xd9, 0xf4, 0xee, 0x95, 0x37,
+	0x0e, 0xcc, 0x31, 0x12, 0xb1, 0xb0, 0x82, 0x6b, 0xec, 0x87, 0x0e, 0xee, 0xdd, 0xfd, 0x70, 0x0c,
+	0x2d, 0x58, 0x46, 0x68, 0x13, 0x90, 0xc5, 0x4d, 0x3c, 0xc9, 0x16, 0x29, 0x7b, 0x39, 0x6a, 0xe4,
+	0x92, 0xd8, 0xe0, 0x1a, 0x00, 0x7a, 0x5e, 0xa0, 0x3b, 0xbb, 0xe5, 0xe3, 0x8b, 0xbf, 0x27, 0xeb,
+	0xaf, 0xa1, 0x2a, 0x11, 0x24, 0x97, 0xce, 0xf2, 0x2b, 0x02, 0xe0, 0x7d, 0x4b, 0xba, 0xb3, 0x5b,
+	0x3a, 0xcf, 0xa8, 0xb1, 0x19, 0xea, 0x2b, 0x08, 0xbe, 0xf8, 0x06, 0x5f, 0xe4, 0x78, 0xdc, 0x14,
+	0xc9, 0x90, 0x6f, 0x65, 0x32, 0xb6, 0x32, 0x31, 0xfe, 0x3f, 0xba, 0xf0, 0x9a, 0x19, 0xd1, 0xd0,
+	0x62, 0xf1, 0x8d, 0xc5, 0x87, 0x0e, 0x52, 0x73, 0x08, 0xd8, 0xe5, 0xbb, 0x22, 0xb4, 0xd8, 0xe5,
+	0x80, 0x98, 0xc7, 0xb7, 0x04, 0x16, 0x3d, 0x4f, 0x84, 0xff, 0xa3, 0x0a, 0x56, 0xcf, 0x93, 0x24,
+	0xa7, 0x7b, 0xb4, 0x35, 0x01, 0x85, 0xcd, 0x13, 0xe1, 0x45, 0x6c, 0x61, 0x70, 0xf7, 0x2c, 0x88,
+	0x7a, 0x92, 0x2e, 0x06, 0x75, 0x89, 0x19, 0x58, 0xc5, 0x63, 0x11, 0xb4, 0xcb, 0x7d, 0x64, 0xe3,
+	0xff, 0x93, 0x73, 0xa0, 0x42, 0x6f, 0x29, 0x57, 0xbb, 0x85, 0x5a, 0x9b, 0x6a, 0x5d, 0x04, 0xed,
+	0x52, 0x17, 0xd9, 0x78, 0xcd, 0xd1, 0xb6, 0x8c, 0xd8, 0x93, 0xc6, 0x1a, 0x47, 0xab, 0x1c, 0x69,
+	0xd3, 0x59, 0x2c, 0xfc, 0x7f, 0xae, 0x1c, 0xee, 0xcb, 0xac, 0x20, 0x98, 0xf8, 0x14, 0xd2, 0xb6,
+	0x66, 0x16, 0x0b, 0x4f, 0xb2, 0x39, 0x99, 0x48, 0x24, 0x92, 0x74, 0x8c, 0xb0, 0x15, 0x84, 0xdb,
+	0xaa, 0xdd, 0x1e, 0xd7, 0xc3, 0xfa, 0x97, 0xca, 0x51, 0xc7, 0x70, 0x2f, 0x3a, 0x1b, 0x78, 0xba,
+	0x50, 0x23, 0x0b, 0x87, 0x1a, 0x5c, 0x1f, 0xb0, 0xeb, 0xae, 0xf1, 0x13, 0x62, 0xcb, 0x05, 0x22,
+	0x83, 0x06, 0x52, 0xbc, 0x67, 0x05, 0x75, 0xa3, 0xb5, 0xb2, 0x2a, 0x54, 0x31, 0x12, 0xcf, 0x7f,
+	0xcd, 0x29, 0x0d, 0x76, 0x80, 0xc2, 0xcd, 0xbd, 0xa4, 0x4e, 0xf8, 0x15, 0x07, 0x6f, 0x38, 0x34,
+	0xb0, 0xcf, 0xb7, 0xd8, 0x54, 0x4e, 0x69, 0x4a, 0x07, 0xeb, 0x59, 0x2c, 0x8c, 0xff, 0x6f, 0x95,
+	0xd9, 0xa7, 0xe7, 0x9e, 0x6d, 0x9e, 0x73, 0xf2, 0xc1, 0x99, 0x3a, 0x48, 0xbd, 0xdb, 0xec, 0x0a,
+	0x36, 0x1a, 0x54, 0xdb, 0x3a, 0xc2, 0x0a, 0xef, 0x3d, 0x92, 0xf3, 0xfd, 0x7f, 0xa7, 0xb9, 0x5c,
+	0xca, 0x8c, 0x68, 0xa9, 0xb6, 0x45, 0x02, 0xb3, 0xaa, 0xf4, 0xf2, 0x50, 0xba, 0x9f, 0xde, 0x61,
+	0xde, 0xe1, 0x6b, 0x67, 0xde, 0x04, 0x7b, 0x7a, 0x5b, 0xf4, 0xf1, 0x17, 0x0e, 0xa7, 0x9a, 0xf0,
+	0xa7, 0xb7, 0xc2, 0x3e, 0xb7, 0x1b, 0xc4, 0x99, 0xc0, 0x9f, 0x2f, 0x9c, 0x5c, 0x5c, 0xf8, 0xcc,
+	0x5a, 0xea, 0xb0, 0xc5, 0x26, 0x69, 0xbf, 0xfb, 0xd4, 0xdb, 0x95, 0xe9, 0xf7, 0x98, 0x77, 0xf8,
+	0xa2, 0x4f, 0x79, 0xc8, 0x67, 0x69, 0xc8, 0xc9, 0xf2, 0x90, 0xcf, 0x96, 0x2c, 0xdc, 0x3e, 0x7e,
+	0x62, 0x6a, 0xc2, 0xbf, 0x7d, 0xfc, 0xc4, 0xf9, 0x89, 0xe9, 0xdb, 0xc7, 0x4f, 0xcc, 0x4e, 0x5c,
+	0xbe, 0x7d, 0xfc, 0xc4, 0xd5, 0x89, 0x6b, 0xb7, 0x8f, 0x9f, 0xd8, 0x9a, 0x08, 0x6f, 0x1f, 0x3f,
+	0x11, 0x4e, 0x44, 0xb7, 0x9f, 0x39, 0xf1, 0xeb, 0x95, 0x89, 0x6f, 0x55, 0x6e, 0x3f, 0x73, 0xe2,
+	0xcf, 0x2a, 0x13, 0xdf, 0xaf, 0x5c, 0xf9, 0xa4, 0x32, 0xf6, 0x4d, 0xaf, 0xb1, 0xe7, 0xb1, 0x52,
+	0x8c, 0x38, 0x64, 0x05, 0x08, 0x38, 0xf4, 0xd2, 0xa7, 0xe8, 0xe9, 0x43, 0x7a, 0xe8, 0xbd, 0xc8,
+	0x4e, 0x85, 0x99, 0xd6, 0x22, 0xb1, 0x7c, 0x30, 0xa7, 0xa7, 0x9b, 0xcf, 0xb9, 0x87, 0x0f, 0xe1,
+	0x99, 0x77, 0x91, 0x3d, 0x2b, 0x93, 0x50, 0xe3, 0x19, 0x08, 0xfd, 0x30, 0xa3, 0x39, 0x78, 0xe0,
+	0x5d, 0x62, 0x2c, 0xc9, 0x7a, 0xa4, 0x6e, 0xe8, 0x67, 0x17, 0xcd, 0x67, 0x93, 0xac, 0x87, 0xba,
+	0xe6, 0x7a, 0x8f, 0x9d, 0x1e, 0xe9, 0x86, 0x7b, 0x97, 0xd8, 0xf9, 0xe6, 0x4a, 0x63, 0x7d, 0xad,
+	0xbe, 0xb4, 0xb9, 0xb6, 0x71, 0x8f, 0xdf, 0xdd, 0x58, 0x5e, 0xe1, 0xcb, 0x6b, 0xad, 0xa5, 0xda,
+	0xfa, 0xca, 0xf2, 0xc4, 0x31, 0xef, 0x22, 0xf3, 0x0f, 0x89, 0x57, 0xee, 0x91, 0xb4, 0x32, 0x5e,
+	0x79, 0x69, 0x73, 0xa9, 0xb6, 0xd4, 0x5a, 0x99, 0x78, 0xea, 0xfa, 0x3f, 0x54, 0xd8, 0xa9, 0xa1,
+	0x92, 0xd7, 0xbb, 0xc9, 0xce, 0xd0, 0x39, 0x9a, 0xbb, 0xcd, 0x05, 0x09, 0x77, 0xe2, 0xd8, 0xf4,
+	0xc5, 0x8f, 0x3f, 0x99, 0xf5, 0x87, 0x90, 0xab, 0x80, 0xa2, 0x2f, 0xe8, 0xbd, 0xc1, 0x3c, 0x52,
+	0xc2, 0x8b, 0xca, 0x50, 0x0c, 0x83, 0x56, 0x65, 0xfa, 0xd2, 0xc7, 0x9f, 0xcc, 0x9e, 0x3f, 0xac,
+	0xf5, 0x3e, 0xa1, 0xbc, 0x2a, 0x3b, 0x1e, 0x64, 0x56, 0x4d, 0x3c, 0x35, 0x7d, 0xee, 0xe3, 0x4f,
+	0x66, 0xcf, 0x0c, 0x01, 0x97, 0x32, 0xab, 0xa6, 0x4f, 0x7c, 0xe7, 0x07, 0x33, 0xc7, 0x7e, 0xf4,
+	0xc3, 0x99, 0x63, 0xb5, 0xaf, 0xfc, 0xf8, 0xbf, 0x66, 0x8e, 0xfd, 0xf8, 0x60, 0xa6, 0xf2, 0x93,
+	0x83, 0x99, 0xca, 0x4f, 0x0f, 0x66, 0x2a, 0xff, 0x79, 0x30, 0x53, 0xf9, 0xee, 0xcf, 0x66, 0x8e,
+	0xfd, 0xe4, 0x67, 0x33, 0xc7, 0x7e, 0xfa, 0xb3, 0x99, 0x63, 0x1f, 0xbe, 0xf9, 0x3f, 0xbb, 0xb4,
+	0x38, 0xfa, 0xcb, 0xa2, 0xad, 0x67, 0x70, 0xeb, 0xde, 0xfc, 0xef, 0x00, 0x00, 0x00, 0xff, 0xff,
+	0x5d, 0x54, 0x6a, 0xb8, 0x75, 0x34, 0x00, 0x00,
 }
 
 func (m *LocalOnlySessionData) Marshal() (dAtA []byte, err error) {
@@ -856,1437 +1208,1983 @@ func (m *LocalOnlySessionData) MarshalToSizedBuffer(dAtA []byte) (int, error) {
 	_ = i
 	var l int
 	_ = l
-	if m.CopyNumRetriesPerBatch != 0 {
-		i = encodeVarintLocalOnlySessionData(dAtA, i, uint64(m.CopyNumRetriesPerBatch))
-		i--
-		dAtA[i] = 0x7
-		i--
-		dAtA[i] = 0xc0
-	}
-	if m.CopyWritePipeliningEnabled {
+	if m.UseSoftLimitForDistributeScan {
 		i--
-		if m.CopyWritePipeliningEnabled {
+		if m.UseSoftLimitForDistributeScan {
 			dAtA[i] = 1
 		} else {
 			dAtA[i] = 0
 		}
 		i--
-		dAtA[i] = 0x7
+		dAtA[i] = 0xb
 		i--
-		dAtA[i] = 0xb0
+		dAtA[i] = 0xc8
 	}
-	if m.CopyTxnQualityOfService != 0 {
-		i = encodeVarintLocalOnlySessionData(dAtA, i, uint64(m.CopyTxnQualityOfService))
-		i--
-		dAtA[i] = 0x7
-		i--
-		dAtA[i] = 0xa8
+	if len(m.DisableOptimizerRules) > 0 {
+		for iNdEx := len(m.DisableOptimizerRules) - 1; iNdEx >= 0; iNdEx-- {
+			i -= len(m.DisableOptimizerRules[iNdEx])
+			copy(dAtA[i:], m.DisableOptimizerRules[iNdEx])
+			i = encodeVarintLocalOnlySessionData(dAtA, i, uint64(len(m.DisableOptimizerRules[iNdEx])))
+			i--
+			dAtA[i] = 0xb
+			i--
+			dAtA[i] = 0xc2
+		}
 	}
-	if m.DisableChangefeedReplication {
+	if m.UseProcTxnControlExtendedProtocolFix {
 		i--
-		if m.DisableChangefeedReplication {
+		if m.UseProcTxnControlExtendedProtocolFix {
 			dAtA[i] = 1
 		} else {
 			dAtA[i] = 0
 		}
 		i--
-		dAtA[i] = 0x7
+		dAtA[i] = 0xa
 		i--
-		dAtA[i] = 0xa0
+		dAtA[i] = 0xf8
 	}
-	if m.OptimizerUseProvidedOrderingFix {
+	if m.InitialRetryBackoffForReadCommitted != 0 {
+		i = encodeVarintLocalOnlySessionData(dAtA, i, uint64(m.InitialRetryBackoffForReadCommitted))
 		i--
-		if m.OptimizerUseProvidedOrderingFix {
+		dAtA[i] = 0xa
+		i--
+		dAtA[i] = 0xd8
+	}
+	if m.OptimizerUseExistsFilterHoistRule {
+		i--
+		if m.OptimizerUseExistsFilterHoistRule {
 			dAtA[i] = 1
 		} else {
 			dAtA[i] = 0
 		}
 		i--
-		dAtA[i] = 0x7
+		dAtA[i] = 0xa
 		i--
-		dAtA[i] = 0x98
+		dAtA[i] = 0xd0
 	}
-	if m.OptimizerUseLockOpForSerializable {
+	if m.PropagateAdmissionHeaderToLeafTransactions {
 		i--
-		if m.OptimizerUseLockOpForSerializable {
+		if m.PropagateAdmissionHeaderToLeafTransactions {
 			dAtA[i] = 1
 		} else {
 			dAtA[i] = 0
 		}
 		i--
-		dAtA[i] = 0x7
+		dAtA[i] = 0xa
 		i--
-		dAtA[i] = 0x90
+		dAtA[i] = 0xc8
 	}
-	if len(m.UnsafeSettingInterlockKey) > 0 {
-		i -= len(m.UnsafeSettingInterlockKey)
-		copy(dAtA[i:], m.UnsafeSettingInterlockKey)
-		i = encodeVarintLocalOnlySessionData(dAtA, i, uint64(len(m.UnsafeSettingInterlockKey)))
+	if m.VectorSearchBeamSize != 0 {
+		i = encodeVarintLocalOnlySessionData(dAtA, i, uint64(m.VectorSearchBeamSize))
 		i--
-		dAtA[i] = 0x7
+		dAtA[i] = 0xa
 		i--
-		dAtA[i] = 0x8a
+		dAtA[i] = 0xc0
 	}
-	if m.SharedLockingForSerializable {
+	if m.UsePre_25_2VariadicBuiltins {
 		i--
-		if m.SharedLockingForSerializable {
+		if m.UsePre_25_2VariadicBuiltins {
 			dAtA[i] = 1
 		} else {
 			dAtA[i] = 0
 		}
 		i--
-		dAtA[i] = 0x7
+		dAtA[i] = 0xa
 		i--
-		dAtA[i] = 0x80
+		dAtA[i] = 0xb8
 	}
-	if m.StrictDDLAtomicity {
+	if m.AllowCreateTriggerFunctionWithArgvReferences {
 		i--
-		if m.StrictDDLAtomicity {
+		if m.AllowCreateTriggerFunctionWithArgvReferences {
 			dAtA[i] = 1
 		} else {
 			dAtA[i] = 0
 		}
 		i--
-		dAtA[i] = 0x6
+		dAtA[i] = 0xa
 		i--
-		dAtA[i] = 0xf8
+		dAtA[i] = 0xa8
 	}
-	if m.MaxRetriesForReadCommitted != 0 {
-		i = encodeVarintLocalOnlySessionData(dAtA, i, uint64(m.MaxRetriesForReadCommitted))
+	if m.OptimizerUseDeleteRangeFastPath {
 		i--
-		dAtA[i] = 0x6
+		if m.OptimizerUseDeleteRangeFastPath {
+			dAtA[i] = 1
+		} else {
+			dAtA[i] = 0
+		}
 		i--
-		dAtA[i] = 0xf0
+		dAtA[i] = 0xa
+		i--
+		dAtA[i] = 0xa0
 	}
-	if m.DurableLockingForSerializable {
+	if m.OptimizerEnableLockElision {
 		i--
-		if m.DurableLockingForSerializable {
+		if m.OptimizerEnableLockElision {
 			dAtA[i] = 1
 		} else {
 			dAtA[i] = 0
 		}
 		i--
-		dAtA[i] = 0x6
+		dAtA[i] = 0xa
 		i--
-		dAtA[i] = 0xe8
+		dAtA[i] = 0x98
 	}
-	if m.ImplicitFKLockingForSerializable {
+	if m.OptimizerUseLockElisionMultipleFamilies {
 		i--
-		if m.ImplicitFKLockingForSerializable {
+		if m.OptimizerUseLockElisionMultipleFamilies {
 			dAtA[i] = 1
 		} else {
 			dAtA[i] = 0
 		}
 		i--
-		dAtA[i] = 0x6
+		dAtA[i] = 0xa
 		i--
-		dAtA[i] = 0xe0
+		dAtA[i] = 0x90
 	}
-	if m.OptimizerUseImprovedJoinElimination {
+	if m.BufferedWritesUseLockingOnNonUniqueIndexes {
 		i--
-		if m.OptimizerUseImprovedJoinElimination {
+		if m.BufferedWritesUseLockingOnNonUniqueIndexes {
 			dAtA[i] = 1
 		} else {
 			dAtA[i] = 0
 		}
 		i--
-		dAtA[i] = 0x6
+		dAtA[i] = 0xa
 		i--
-		dAtA[i] = 0xd8
+		dAtA[i] = 0x88
 	}
-	if m.ReplicationMode != 0 {
-		i = encodeVarintLocalOnlySessionData(dAtA, i, uint64(m.ReplicationMode))
-		i--
-		dAtA[i] = 0x6
+	if m.UseCPutsOnNonUniqueIndexes {
 		i--
-		dAtA[i] = 0xd0
-	}
-	if m.DefaultTxnIsolationLevel != 0 {
-		i = encodeVarintLocalOnlySessionData(dAtA, i, uint64(m.DefaultTxnIsolationLevel))
+		if m.UseCPutsOnNonUniqueIndexes {
+			dAtA[i] = 1
+		} else {
+			dAtA[i] = 0
+		}
 		i--
-		dAtA[i] = 0x6
+		dAtA[i] = 0xa
 		i--
-		dAtA[i] = 0xc8
+		dAtA[i] = 0x80
 	}
-	if m.OptimizerUseImprovedComputedColumnFiltersDerivation {
+	if m.RegisterLatchWaitContentionEvents {
 		i--
-		if m.OptimizerUseImprovedComputedColumnFiltersDerivation {
+		if m.RegisterLatchWaitContentionEvents {
 			dAtA[i] = 1
 		} else {
 			dAtA[i] = 0
 		}
 		i--
-		dAtA[i] = 0x6
+		dAtA[i] = 0x9
 		i--
-		dAtA[i] = 0xc0
+		dAtA[i] = 0xf8
 	}
-	if m.TestingOptimizerInjectPanics {
+	if m.OptimizerPlanLookupJoinsWithReverseScans {
 		i--
-		if m.TestingOptimizerInjectPanics {
+		if m.OptimizerPlanLookupJoinsWithReverseScans {
 			dAtA[i] = 1
 		} else {
 			dAtA[i] = 0
 		}
 		i--
-		dAtA[i] = 0x6
+		dAtA[i] = 0x9
 		i--
-		dAtA[i] = 0xb8
+		dAtA[i] = 0xf0
 	}
-	if m.OptimizerHoistUncorrelatedEqualitySubqueries {
+	if m.OptimizerCheckInputMinRowCount != 0 {
+		i -= 8
+		encoding_binary.LittleEndian.PutUint64(dAtA[i:], uint64(math.Float64bits(float64(m.OptimizerCheckInputMinRowCount))))
 		i--
-		if m.OptimizerHoistUncorrelatedEqualitySubqueries {
+		dAtA[i] = 0x9
+		i--
+		dAtA[i] = 0xe9
+	}
+	if m.BufferedWritesEnabled {
+		i--
+		if m.BufferedWritesEnabled {
 			dAtA[i] = 1
 		} else {
 			dAtA[i] = 0
 		}
 		i--
-		dAtA[i] = 0x6
+		dAtA[i] = 0x9
 		i--
-		dAtA[i] = 0xb0
+		dAtA[i] = 0xe0
 	}
-	if m.UnboundedParallelScans {
+	if m.OptimizerMinRowCount != 0 {
+		i -= 8
+		encoding_binary.LittleEndian.PutUint64(dAtA[i:], uint64(math.Float64bits(float64(m.OptimizerMinRowCount))))
 		i--
-		if m.UnboundedParallelScans {
+		dAtA[i] = 0x9
+		i--
+		dAtA[i] = 0xd9
+	}
+	if m.OptimizerPreferBoundedCardinality {
+		i--
+		if m.OptimizerPreferBoundedCardinality {
 			dAtA[i] = 1
 		} else {
 			dAtA[i] = 0
 		}
 		i--
-		dAtA[i] = 0x6
+		dAtA[i] = 0x9
 		i--
-		dAtA[i] = 0xa8
+		dAtA[i] = 0xd0
 	}
-	if m.MultipleActivePortalsEnabled {
+	if m.CatalogDigestStalenessCheckEnabled {
 		i--
-		if m.MultipleActivePortalsEnabled {
+		if m.CatalogDigestStalenessCheckEnabled {
 			dAtA[i] = 1
 		} else {
 			dAtA[i] = 0
 		}
 		i--
-		dAtA[i] = 0x6
+		dAtA[i] = 0x9
 		i--
-		dAtA[i] = 0xa0
+		dAtA[i] = 0xc8
 	}
-	if m.DisableDropVirtualCluster {
+	if m.AvoidFullTableScansInMutations {
 		i--
-		if m.DisableDropVirtualCluster {
+		if m.AvoidFullTableScansInMutations {
 			dAtA[i] = 1
 		} else {
 			dAtA[i] = 0
 		}
 		i--
-		dAtA[i] = 0x6
+		dAtA[i] = 0x9
 		i--
-		dAtA[i] = 0x98
+		dAtA[i] = 0xb8
 	}
-	if m.StreamerEnabled {
+	if m.LegacyVarcharTyping {
 		i--
-		if m.StreamerEnabled {
+		if m.LegacyVarcharTyping {
 			dAtA[i] = 1
 		} else {
 			dAtA[i] = 0
 		}
 		i--
-		dAtA[i] = 0x6
+		dAtA[i] = 0x9
 		i--
-		dAtA[i] = 0x90
+		dAtA[i] = 0xb0
 	}
-	if m.PreparedStatementsCacheSize != 0 {
-		i = encodeVarintLocalOnlySessionData(dAtA, i, uint64(m.PreparedStatementsCacheSize))
+	if m.DistributeJoinRowCountThreshold != 0 {
+		i = encodeVarintLocalOnlySessionData(dAtA, i, uint64(m.DistributeJoinRowCountThreshold))
 		i--
-		dAtA[i] = 0x6
+		dAtA[i] = 0x9
 		i--
-		dAtA[i] = 0x88
+		dAtA[i] = 0xa8
 	}
-	if m.AllowRoleMembershipsToChangeDuringTransaction {
+	if m.AlwaysDistributeFullScans {
 		i--
-		if m.AllowRoleMembershipsToChangeDuringTransaction {
+		if m.AlwaysDistributeFullScans {
 			dAtA[i] = 1
 		} else {
 			dAtA[i] = 0
 		}
 		i--
-		dAtA[i] = 0x6
+		dAtA[i] = 0x9
+		i--
+		dAtA[i] = 0xa0
+	}
+	if m.DistributeScanRowCountThreshold != 0 {
+		i = encodeVarintLocalOnlySessionData(dAtA, i, uint64(m.DistributeScanRowCountThreshold))
+		i--
+		dAtA[i] = 0x9
+		i--
+		dAtA[i] = 0x98
+	}
+	if m.DistributeSortRowCountThreshold != 0 {
+		i = encodeVarintLocalOnlySessionData(dAtA, i, uint64(m.DistributeSortRowCountThreshold))
+		i--
+		dAtA[i] = 0x9
+		i--
+		dAtA[i] = 0x90
+	}
+	if m.DistributeGroupByRowCountThreshold != 0 {
+		i = encodeVarintLocalOnlySessionData(dAtA, i, uint64(m.DistributeGroupByRowCountThreshold))
+		i--
+		dAtA[i] = 0x9
+		i--
+		dAtA[i] = 0x88
+	}
+	if m.RecursionDepthLimit != 0 {
+		i = encodeVarintLocalOnlySessionData(dAtA, i, uint64(m.RecursionDepthLimit))
+		i--
+		dAtA[i] = 0x9
 		i--
 		dAtA[i] = 0x80
 	}
-	if m.EnableCreateStatsUsingExtremes {
+	if m.DisableVecUnionEagerCancellation {
 		i--
-		if m.EnableCreateStatsUsingExtremes {
+		if m.DisableVecUnionEagerCancellation {
 			dAtA[i] = 1
 		} else {
 			dAtA[i] = 0
 		}
 		i--
-		dAtA[i] = 0x5
+		dAtA[i] = 0x8
 		i--
 		dAtA[i] = 0xf8
 	}
-	if m.OptimizerAlwaysUseHistograms {
+	if m.UnsafeAllowTriggersModifyingCascades {
 		i--
-		if m.OptimizerAlwaysUseHistograms {
+		if m.UnsafeAllowTriggersModifyingCascades {
 			dAtA[i] = 1
 		} else {
 			dAtA[i] = 0
 		}
 		i--
-		dAtA[i] = 0x5
+		dAtA[i] = 0x8
 		i--
 		dAtA[i] = 0xf0
 	}
-	if m.EnforceHomeRegionFollowerReadsEnabled {
+	if m.BypassPCRReaderCatalogAOST {
 		i--
-		if m.EnforceHomeRegionFollowerReadsEnabled {
+		if m.BypassPCRReaderCatalogAOST {
 			dAtA[i] = 1
 		} else {
 			dAtA[i] = 0
 		}
 		i--
-		dAtA[i] = 0x5
+		dAtA[i] = 0x8
 		i--
 		dAtA[i] = 0xe8
 	}
-	if m.InjectRetryErrorsOnCommitEnabled {
-		i--
-		if m.InjectRetryErrorsOnCommitEnabled {
-			dAtA[i] = 1
-		} else {
-			dAtA[i] = 0
+	{
+		size, err := m.OriginTimestampForLogicalDataReplication.MarshalToSizedBuffer(dAtA[:i])
+		if err != nil {
+			return 0, err
 		}
-		i--
-		dAtA[i] = 0x5
-		i--
-		dAtA[i] = 0xe0
+		i -= size
+		i = encodeVarintLocalOnlySessionData(dAtA, i, uint64(size))
 	}
-	if m.OptimizerUseImprovedSplitDisjunctionForJoins {
+	i--
+	dAtA[i] = 0x8
+	i--
+	dAtA[i] = 0xe2
+	if m.OptimizerPushLimitIntoProjectFilteredScan {
 		i--
-		if m.OptimizerUseImprovedSplitDisjunctionForJoins {
+		if m.OptimizerPushLimitIntoProjectFilteredScan {
 			dAtA[i] = 1
 		} else {
 			dAtA[i] = 0
 		}
 		i--
-		dAtA[i] = 0x5
+		dAtA[i] = 0x8
 		i--
 		dAtA[i] = 0xd8
 	}
-	if m.DeclareCursorStatementTimeoutEnabled {
+	if m.OptimizerUseConditionalHoistFix {
 		i--
-		if m.DeclareCursorStatementTimeoutEnabled {
+		if m.OptimizerUseConditionalHoistFix {
 			dAtA[i] = 1
 		} else {
 			dAtA[i] = 0
 		}
 		i--
-		dAtA[i] = 0x5
+		dAtA[i] = 0x8
 		i--
 		dAtA[i] = 0xd0
 	}
-	if m.CopyFromRetriesEnabled {
+	if m.OptimizerUseMergedPartialStatistics {
 		i--
-		if m.CopyFromRetriesEnabled {
+		if m.OptimizerUseMergedPartialStatistics {
 			dAtA[i] = 1
 		} else {
 			dAtA[i] = 0
 		}
 		i--
-		dAtA[i] = 0x5
+		dAtA[i] = 0x8
 		i--
 		dAtA[i] = 0xc8
 	}
-	if m.OptimizerUseLimitOrderingForStreamingGroupBy {
+	if m.EnableCreateStatsUsingExtremesBoolEnum {
 		i--
-		if m.OptimizerUseLimitOrderingForStreamingGroupBy {
+		if m.EnableCreateStatsUsingExtremesBoolEnum {
 			dAtA[i] = 1
 		} else {
 			dAtA[i] = 0
 		}
 		i--
-		dAtA[i] = 0x5
+		dAtA[i] = 0x8
 		i--
 		dAtA[i] = 0xc0
 	}
-	if m.OptimizerUseImprovedDisjunctionStats {
+	if m.OriginIDForLogicalDataReplication != 0 {
+		i = encodeVarintLocalOnlySessionData(dAtA, i, uint64(m.OriginIDForLogicalDataReplication))
 		i--
-		if m.OptimizerUseImprovedDisjunctionStats {
+		dAtA[i] = 0x8
+		i--
+		dAtA[i] = 0xb8
+	}
+	if m.OptimizerUsePolymorphicParameterFix {
+		i--
+		if m.OptimizerUsePolymorphicParameterFix {
 			dAtA[i] = 1
 		} else {
 			dAtA[i] = 0
 		}
 		i--
-		dAtA[i] = 0x5
+		dAtA[i] = 0x8
 		i--
 		dAtA[i] = 0xb0
 	}
-	if m.AllowOrdinalColumnReferences {
+	if m.PlanCacheMode != 0 {
+		i = encodeVarintLocalOnlySessionData(dAtA, i, uint64(m.PlanCacheMode))
 		i--
-		if m.AllowOrdinalColumnReferences {
+		dAtA[i] = 0x8
+		i--
+		dAtA[i] = 0xa8
+	}
+	if m.OptimizerPushOffsetIntoIndexJoin {
+		i--
+		if m.OptimizerPushOffsetIntoIndexJoin {
 			dAtA[i] = 1
 		} else {
 			dAtA[i] = 0
 		}
 		i--
-		dAtA[i] = 0x5
+		dAtA[i] = 0x8
 		i--
-		dAtA[i] = 0xa8
+		dAtA[i] = 0xa0
 	}
-	if m.ExperimentalHashGroupJoinEnabled {
+	if m.OptimizerProveImplicationWithVirtualComputedColumns {
 		i--
-		if m.ExperimentalHashGroupJoinEnabled {
+		if m.OptimizerProveImplicationWithVirtualComputedColumns {
 			dAtA[i] = 1
 		} else {
 			dAtA[i] = 0
 		}
 		i--
-		dAtA[i] = 0x5
+		dAtA[i] = 0x8
 		i--
-		dAtA[i] = 0xa0
+		dAtA[i] = 0x90
 	}
-	if m.DescriptorValidationMode != 0 {
-		i = encodeVarintLocalOnlySessionData(dAtA, i, uint64(m.DescriptorValidationMode))
-		i--
-		dAtA[i] = 0x5
+	if m.OptimizerUseImprovedMultiColumnSelectivityEstimate {
 		i--
-		dAtA[i] = 0x98
-	}
-	if len(m.SystemIdentityProto) > 0 {
-		i -= len(m.SystemIdentityProto)
-		copy(dAtA[i:], m.SystemIdentityProto)
-		i = encodeVarintLocalOnlySessionData(dAtA, i, uint64(len(m.SystemIdentityProto)))
-		i--
-		dAtA[i] = 0x5
-		i--
-		dAtA[i] = 0x92
-	}
-	if m.TransactionTimeout != 0 {
-		i = encodeVarintLocalOnlySessionData(dAtA, i, uint64(m.TransactionTimeout))
+		if m.OptimizerUseImprovedMultiColumnSelectivityEstimate {
+			dAtA[i] = 1
+		} else {
+			dAtA[i] = 0
+		}
 		i--
-		dAtA[i] = 0x5
+		dAtA[i] = 0x8
 		i--
 		dAtA[i] = 0x88
 	}
-	if m.VariableInequalityLookupJoinEnabled {
+	if m.OptimizerUseImprovedZigzagJoinCosting {
 		i--
-		if m.VariableInequalityLookupJoinEnabled {
+		if m.OptimizerUseImprovedZigzagJoinCosting {
 			dAtA[i] = 1
 		} else {
 			dAtA[i] = 0
 		}
 		i--
-		dAtA[i] = 0x5
+		dAtA[i] = 0x8
 		i--
 		dAtA[i] = 0x80
 	}
-	if m.OptimizerUseForecasts {
+	if m.OptimizerUseImprovedTrigramSimilaritySelectivity {
 		i--
-		if m.OptimizerUseForecasts {
+		if m.OptimizerUseImprovedTrigramSimilaritySelectivity {
 			dAtA[i] = 1
 		} else {
 			dAtA[i] = 0
 		}
 		i--
-		dAtA[i] = 0x4
+		dAtA[i] = 0x7
 		i--
 		dAtA[i] = 0xf8
 	}
-	if m.EnforceHomeRegion {
+	if m.OptimizerUseImprovedDistinctOnLimitHintCosting {
 		i--
-		if m.EnforceHomeRegion {
+		if m.OptimizerUseImprovedDistinctOnLimitHintCosting {
 			dAtA[i] = 1
 		} else {
 			dAtA[i] = 0
 		}
 		i--
-		dAtA[i] = 0x4
+		dAtA[i] = 0x7
 		i--
 		dAtA[i] = 0xf0
 	}
-	if m.CopyFromAtomicEnabled {
+	if m.OptimizerUseTrigramSimilarityOptimization {
 		i--
-		if m.CopyFromAtomicEnabled {
+		if m.OptimizerUseTrigramSimilarityOptimization {
 			dAtA[i] = 1
 		} else {
 			dAtA[i] = 0
 		}
 		i--
-		dAtA[i] = 0x4
+		dAtA[i] = 0x7
 		i--
 		dAtA[i] = 0xe8
 	}
-	if m.DisableHoistProjectionInJoinLimitation {
+	if m.OptimizerUseVirtualComputedColumnStats {
 		i--
-		if m.DisableHoistProjectionInJoinLimitation {
+		if m.OptimizerUseVirtualComputedColumnStats {
 			dAtA[i] = 1
 		} else {
 			dAtA[i] = 0
 		}
 		i--
-		dAtA[i] = 0x4
+		dAtA[i] = 0x7
 		i--
 		dAtA[i] = 0xe0
 	}
-	if m.CopyFastPathEnabled {
+	if m.PLpgSQLUseStrictInto {
 		i--
-		if m.CopyFastPathEnabled {
+		if m.PLpgSQLUseStrictInto {
 			dAtA[i] = 1
 		} else {
 			dAtA[i] = 0
 		}
 		i--
-		dAtA[i] = 0x4
+		dAtA[i] = 0x7
 		i--
 		dAtA[i] = 0xd8
 	}
-	if m.OptimizerUseNotVisibleIndexes {
+	if m.CloseCursorsAtCommit {
 		i--
-		if m.OptimizerUseNotVisibleIndexes {
+		if m.CloseCursorsAtCommit {
 			dAtA[i] = 1
 		} else {
 			dAtA[i] = 0
 		}
 		i--
-		dAtA[i] = 0x4
+		dAtA[i] = 0x7
 		i--
 		dAtA[i] = 0xd0
 	}
-	if m.TestingOptimizerDisableRuleProbability != 0 {
-		i -= 8
-		encoding_binary.LittleEndian.PutUint64(dAtA[i:], uint64(math.Float64bits(float64(m.TestingOptimizerDisableRuleProbability))))
+	if m.AutoCommitBeforeDDL {
 		i--
-		dAtA[i] = 0x4
+		if m.AutoCommitBeforeDDL {
+			dAtA[i] = 1
+		} else {
+			dAtA[i] = 0
+		}
 		i--
-		dAtA[i] = 0xc9
+		dAtA[i] = 0x7
+		i--
+		dAtA[i] = 0xc8
 	}
-	if m.TestingOptimizerCostPerturbation != 0 {
-		i -= 8
-		encoding_binary.LittleEndian.PutUint64(dAtA[i:], uint64(math.Float64bits(float64(m.TestingOptimizerCostPerturbation))))
+	if m.CopyNumRetriesPerBatch != 0 {
+		i = encodeVarintLocalOnlySessionData(dAtA, i, uint64(m.CopyNumRetriesPerBatch))
 		i--
-		dAtA[i] = 0x4
+		dAtA[i] = 0x7
 		i--
-		dAtA[i] = 0xc1
+		dAtA[i] = 0xc0
 	}
-	if m.UnconstrainedNonCoveringIndexScanEnabled {
+	if m.OptimizerMergeJoinsEnabled {
 		i--
-		if m.UnconstrainedNonCoveringIndexScanEnabled {
+		if m.OptimizerMergeJoinsEnabled {
 			dAtA[i] = 1
 		} else {
 			dAtA[i] = 0
 		}
 		i--
-		dAtA[i] = 0x4
+		dAtA[i] = 0x7
 		i--
 		dAtA[i] = 0xb8
 	}
-	if m.TestingOptimizerRandomSeed != 0 {
-		i = encodeVarintLocalOnlySessionData(dAtA, i, uint64(m.TestingOptimizerRandomSeed))
-		i--
-		dAtA[i] = 0x4
-		i--
-		dAtA[i] = 0xb0
-	}
-	if m.ShowPrimaryKeyConstraintOnNotVisibleColumns {
+	if m.CopyWritePipeliningEnabled {
 		i--
-		if m.ShowPrimaryKeyConstraintOnNotVisibleColumns {
+		if m.CopyWritePipeliningEnabled {
 			dAtA[i] = 1
 		} else {
 			dAtA[i] = 0
 		}
 		i--
-		dAtA[i] = 0x4
+		dAtA[i] = 0x7
+		i--
+		dAtA[i] = 0xb0
+	}
+	if m.CopyTxnQualityOfService != 0 {
+		i = encodeVarintLocalOnlySessionData(dAtA, i, uint64(m.CopyTxnQualityOfService))
+		i--
+		dAtA[i] = 0x7
 		i--
 		dAtA[i] = 0xa8
 	}
-	if m.MultipleModificationsOfTable {
+	if m.DisableChangefeedReplication {
 		i--
-		if m.MultipleModificationsOfTable {
+		if m.DisableChangefeedReplication {
 			dAtA[i] = 1
 		} else {
 			dAtA[i] = 0
 		}
 		i--
-		dAtA[i] = 0x4
+		dAtA[i] = 0x7
 		i--
 		dAtA[i] = 0xa0
 	}
-	if m.ExpectAndIgnoreNotVisibleColumnsInCopy {
+	if m.OptimizerUseProvidedOrderingFix {
 		i--
-		if m.ExpectAndIgnoreNotVisibleColumnsInCopy {
+		if m.OptimizerUseProvidedOrderingFix {
 			dAtA[i] = 1
 		} else {
 			dAtA[i] = 0
 		}
 		i--
-		dAtA[i] = 0x4
+		dAtA[i] = 0x7
 		i--
 		dAtA[i] = 0x98
 	}
-	if m.EnableImplicitTransactionForBatchStatements {
+	if m.OptimizerUseLockOpForSerializable {
 		i--
-		if m.EnableImplicitTransactionForBatchStatements {
+		if m.OptimizerUseLockOpForSerializable {
 			dAtA[i] = 1
 		} else {
 			dAtA[i] = 0
 		}
 		i--
-		dAtA[i] = 0x4
+		dAtA[i] = 0x7
 		i--
 		dAtA[i] = 0x90
 	}
-	if m.OverrideAlterPrimaryRegionInSuperRegion {
+	if len(m.UnsafeSettingInterlockKey) > 0 {
+		i -= len(m.UnsafeSettingInterlockKey)
+		copy(dAtA[i:], m.UnsafeSettingInterlockKey)
+		i = encodeVarintLocalOnlySessionData(dAtA, i, uint64(len(m.UnsafeSettingInterlockKey)))
 		i--
-		if m.OverrideAlterPrimaryRegionInSuperRegion {
+		dAtA[i] = 0x7
+		i--
+		dAtA[i] = 0x8a
+	}
+	if m.SharedLockingForSerializable {
+		i--
+		if m.SharedLockingForSerializable {
 			dAtA[i] = 1
 		} else {
 			dAtA[i] = 0
 		}
 		i--
-		dAtA[i] = 0x4
+		dAtA[i] = 0x7
 		i--
-		dAtA[i] = 0x88
+		dAtA[i] = 0x80
 	}
-	if m.EnableSuperRegions {
+	if m.StrictDDLAtomicity {
 		i--
-		if m.EnableSuperRegions {
+		if m.StrictDDLAtomicity {
 			dAtA[i] = 1
 		} else {
 			dAtA[i] = 0
 		}
 		i--
-		dAtA[i] = 0x4
-		i--
-		dAtA[i] = 0x80
-	}
-	if m.OptSplitScanLimit != 0 {
-		i = encodeVarintLocalOnlySessionData(dAtA, i, uint64(m.OptSplitScanLimit))
-		i--
-		dAtA[i] = 0x3
+		dAtA[i] = 0x6
 		i--
 		dAtA[i] = 0xf8
 	}
-	if m.DefaultTxnQualityOfService != 0 {
-		i = encodeVarintLocalOnlySessionData(dAtA, i, uint64(m.DefaultTxnQualityOfService))
+	if m.MaxRetriesForReadCommitted != 0 {
+		i = encodeVarintLocalOnlySessionData(dAtA, i, uint64(m.MaxRetriesForReadCommitted))
 		i--
-		dAtA[i] = 0x3
+		dAtA[i] = 0x6
 		i--
 		dAtA[i] = 0xf0
 	}
-	if m.CostScansWithDefaultColSize {
+	if m.DurableLockingForSerializable {
 		i--
-		if m.CostScansWithDefaultColSize {
+		if m.DurableLockingForSerializable {
 			dAtA[i] = 1
 		} else {
 			dAtA[i] = 0
 		}
 		i--
-		dAtA[i] = 0x3
+		dAtA[i] = 0x6
 		i--
 		dAtA[i] = 0xe8
 	}
-	if m.CheckFunctionBodies {
+	if m.ImplicitFKLockingForSerializable {
 		i--
-		if m.CheckFunctionBodies {
+		if m.ImplicitFKLockingForSerializable {
 			dAtA[i] = 1
 		} else {
 			dAtA[i] = 0
 		}
 		i--
-		dAtA[i] = 0x3
+		dAtA[i] = 0x6
 		i--
 		dAtA[i] = 0xe0
 	}
-	if m.AvoidBuffering {
+	if m.OptimizerUseImprovedJoinElimination {
 		i--
-		if m.AvoidBuffering {
+		if m.OptimizerUseImprovedJoinElimination {
 			dAtA[i] = 1
 		} else {
 			dAtA[i] = 0
 		}
 		i--
-		dAtA[i] = 0x3
+		dAtA[i] = 0x6
 		i--
 		dAtA[i] = 0xd8
 	}
-	if m.IndexRecommendationsEnabled {
-		i--
-		if m.IndexRecommendationsEnabled {
-			dAtA[i] = 1
-		} else {
-			dAtA[i] = 0
-		}
+	if m.ReplicationMode != 0 {
+		i = encodeVarintLocalOnlySessionData(dAtA, i, uint64(m.ReplicationMode))
 		i--
-		dAtA[i] = 0x3
+		dAtA[i] = 0x6
 		i--
 		dAtA[i] = 0xd0
 	}
-	if len(m.CustomOptions) > 0 {
-		keysForCustomOptions := make([]string, 0, len(m.CustomOptions))
-		for k := range m.CustomOptions {
-			keysForCustomOptions = append(keysForCustomOptions, string(k))
-		}
-		github_com_gogo_protobuf_sortkeys.Strings(keysForCustomOptions)
-		for iNdEx := len(keysForCustomOptions) - 1; iNdEx >= 0; iNdEx-- {
-			v := m.CustomOptions[string(keysForCustomOptions[iNdEx])]
-			baseI := i
-			i -= len(v)
-			copy(dAtA[i:], v)
-			i = encodeVarintLocalOnlySessionData(dAtA, i, uint64(len(v)))
-			i--
-			dAtA[i] = 0x12
-			i -= len(keysForCustomOptions[iNdEx])
-			copy(dAtA[i:], keysForCustomOptions[iNdEx])
-			i = encodeVarintLocalOnlySessionData(dAtA, i, uint64(len(keysForCustomOptions[iNdEx])))
-			i--
-			dAtA[i] = 0xa
-			i = encodeVarintLocalOnlySessionData(dAtA, i, uint64(baseI-i))
-			i--
-			dAtA[i] = 0x3
-			i--
-			dAtA[i] = 0xca
-		}
+	if m.DefaultTxnIsolationLevel != 0 {
+		i = encodeVarintLocalOnlySessionData(dAtA, i, uint64(m.DefaultTxnIsolationLevel))
+		i--
+		dAtA[i] = 0x6
+		i--
+		dAtA[i] = 0xc8
 	}
-	if m.DisablePlanGists {
+	if m.OptimizerUseImprovedComputedColumnFiltersDerivation {
 		i--
-		if m.DisablePlanGists {
+		if m.OptimizerUseImprovedComputedColumnFiltersDerivation {
 			dAtA[i] = 1
 		} else {
 			dAtA[i] = 0
 		}
 		i--
-		dAtA[i] = 0x3
+		dAtA[i] = 0x6
 		i--
 		dAtA[i] = 0xc0
 	}
-	if m.NullOrderedLast {
+	if m.TestingOptimizerInjectPanics {
 		i--
-		if m.NullOrderedLast {
+		if m.TestingOptimizerInjectPanics {
 			dAtA[i] = 1
 		} else {
 			dAtA[i] = 0
 		}
 		i--
-		dAtA[i] = 0x3
+		dAtA[i] = 0x6
 		i--
 		dAtA[i] = 0xb8
 	}
-	if m.InjectRetryErrorsEnabled {
+	if m.OptimizerHoistUncorrelatedEqualitySubqueries {
 		i--
-		if m.InjectRetryErrorsEnabled {
+		if m.OptimizerHoistUncorrelatedEqualitySubqueries {
 			dAtA[i] = 1
 		} else {
 			dAtA[i] = 0
 		}
 		i--
-		dAtA[i] = 0x3
+		dAtA[i] = 0x6
 		i--
 		dAtA[i] = 0xb0
 	}
-	if m.LargeFullScanRows != 0 {
-		i -= 8
-		encoding_binary.LittleEndian.PutUint64(dAtA[i:], uint64(math.Float64bits(float64(m.LargeFullScanRows))))
-		i--
-		dAtA[i] = 0x3
-		i--
-		dAtA[i] = 0xa9
-	}
-	if m.IsSuperuser {
+	if m.UnboundedParallelScans {
 		i--
-		if m.IsSuperuser {
+		if m.UnboundedParallelScans {
 			dAtA[i] = 1
 		} else {
 			dAtA[i] = 0
 		}
 		i--
-		dAtA[i] = 0x3
+		dAtA[i] = 0x6
 		i--
-		dAtA[i] = 0xa0
+		dAtA[i] = 0xa8
 	}
-	if m.AutoRehomingEnabled {
+	if m.MultipleActivePortalsEnabled {
 		i--
-		if m.AutoRehomingEnabled {
+		if m.MultipleActivePortalsEnabled {
 			dAtA[i] = 1
 		} else {
 			dAtA[i] = 0
 		}
 		i--
-		dAtA[i] = 0x3
+		dAtA[i] = 0x6
 		i--
-		dAtA[i] = 0x98
+		dAtA[i] = 0xa0
 	}
-	if m.TxnRowsReadErr != 0 {
-		i = encodeVarintLocalOnlySessionData(dAtA, i, uint64(m.TxnRowsReadErr))
+	if m.PreparedStatementsCacheSize != 0 {
+		i = encodeVarintLocalOnlySessionData(dAtA, i, uint64(m.PreparedStatementsCacheSize))
 		i--
-		dAtA[i] = 0x3
+		dAtA[i] = 0x6
 		i--
-		dAtA[i] = 0x90
+		dAtA[i] = 0x88
 	}
-	if m.TxnRowsReadLog != 0 {
-		i = encodeVarintLocalOnlySessionData(dAtA, i, uint64(m.TxnRowsReadLog))
-		i--
-		dAtA[i] = 0x3
+	if m.AllowRoleMembershipsToChangeDuringTransaction {
 		i--
-		dAtA[i] = 0x88
-	}
-	if m.TxnRowsWrittenErr != 0 {
-		i = encodeVarintLocalOnlySessionData(dAtA, i, uint64(m.TxnRowsWrittenErr))
+		if m.AllowRoleMembershipsToChangeDuringTransaction {
+			dAtA[i] = 1
+		} else {
+			dAtA[i] = 0
+		}
 		i--
-		dAtA[i] = 0x3
+		dAtA[i] = 0x6
 		i--
 		dAtA[i] = 0x80
 	}
-	if m.TxnRowsWrittenLog != 0 {
-		i = encodeVarintLocalOnlySessionData(dAtA, i, uint64(m.TxnRowsWrittenLog))
+	if m.EnableCreateStatsUsingExtremes {
 		i--
-		dAtA[i] = 0x2
+		if m.EnableCreateStatsUsingExtremes {
+			dAtA[i] = 1
+		} else {
+			dAtA[i] = 0
+		}
+		i--
+		dAtA[i] = 0x5
 		i--
 		dAtA[i] = 0xf8
 	}
-	if len(m.SessionUserProto) > 0 {
-		i -= len(m.SessionUserProto)
-		copy(dAtA[i:], m.SessionUserProto)
-		i = encodeVarintLocalOnlySessionData(dAtA, i, uint64(len(m.SessionUserProto)))
+	if m.OptimizerAlwaysUseHistograms {
 		i--
-		dAtA[i] = 0x2
+		if m.OptimizerAlwaysUseHistograms {
+			dAtA[i] = 1
+		} else {
+			dAtA[i] = 0
+		}
 		i--
-		dAtA[i] = 0xf2
+		dAtA[i] = 0x5
+		i--
+		dAtA[i] = 0xf0
 	}
-	if m.PlacementEnabled {
+	if m.EnforceHomeRegionFollowerReadsEnabled {
 		i--
-		if m.PlacementEnabled {
+		if m.EnforceHomeRegionFollowerReadsEnabled {
 			dAtA[i] = 1
 		} else {
 			dAtA[i] = 0
 		}
 		i--
-		dAtA[i] = 0x2
+		dAtA[i] = 0x5
 		i--
 		dAtA[i] = 0xe8
 	}
-	if len(m.SequenceCache) > 0 {
-		keysForSequenceCache := make([]uint32, 0, len(m.SequenceCache))
-		for k := range m.SequenceCache {
-			keysForSequenceCache = append(keysForSequenceCache, uint32(k))
-		}
-		github_com_gogo_protobuf_sortkeys.Uint32s(keysForSequenceCache)
-		for iNdEx := len(keysForSequenceCache) - 1; iNdEx >= 0; iNdEx-- {
-			v := m.SequenceCache[uint32(keysForSequenceCache[iNdEx])]
-			baseI := i
-			if v != nil {
-				{
-					size, err := v.MarshalToSizedBuffer(dAtA[:i])
-					if err != nil {
-						return 0, err
-					}
-					i -= size
-					i = encodeVarintLocalOnlySessionData(dAtA, i, uint64(size))
-				}
-				i--
-				dAtA[i] = 0x12
-			}
-			i = encodeVarintLocalOnlySessionData(dAtA, i, uint64(keysForSequenceCache[iNdEx]))
-			i--
-			dAtA[i] = 0x8
-			i = encodeVarintLocalOnlySessionData(dAtA, i, uint64(baseI-i))
-			i--
-			dAtA[i] = 0x2
-			i--
-			dAtA[i] = 0xe2
+	if m.InjectRetryErrorsOnCommitEnabled {
+		i--
+		if m.InjectRetryErrorsOnCommitEnabled {
+			dAtA[i] = 1
+		} else {
+			dAtA[i] = 0
 		}
+		i--
+		dAtA[i] = 0x5
+		i--
+		dAtA[i] = 0xe0
 	}
-	if m.NewSchemaChangerMode != 0 {
-		i = encodeVarintLocalOnlySessionData(dAtA, i, uint64(m.NewSchemaChangerMode))
+	if m.OptimizerUseImprovedSplitDisjunctionForJoins {
 		i--
-		dAtA[i] = 0x2
+		if m.OptimizerUseImprovedSplitDisjunctionForJoins {
+			dAtA[i] = 1
+		} else {
+			dAtA[i] = 0
+		}
+		i--
+		dAtA[i] = 0x5
 		i--
 		dAtA[i] = 0xd8
 	}
-	if m.SerialNormalizationMode != 0 {
-		i = encodeVarintLocalOnlySessionData(dAtA, i, uint64(m.SerialNormalizationMode))
+	if m.DeclareCursorStatementTimeoutEnabled {
 		i--
-		dAtA[i] = 0x2
+		if m.DeclareCursorStatementTimeoutEnabled {
+			dAtA[i] = 1
+		} else {
+			dAtA[i] = 0
+		}
+		i--
+		dAtA[i] = 0x5
 		i--
 		dAtA[i] = 0xd0
 	}
-	if m.DistSQLMode != 0 {
-		i = encodeVarintLocalOnlySessionData(dAtA, i, uint64(m.DistSQLMode))
+	if m.CopyFromRetriesEnabled {
 		i--
-		dAtA[i] = 0x2
+		if m.CopyFromRetriesEnabled {
+			dAtA[i] = 1
+		} else {
+			dAtA[i] = 0
+		}
+		i--
+		dAtA[i] = 0x5
 		i--
 		dAtA[i] = 0xc8
 	}
-	if m.ExperimentalDistSQLPlanningMode != 0 {
-		i = encodeVarintLocalOnlySessionData(dAtA, i, uint64(m.ExperimentalDistSQLPlanningMode))
+	if m.OptimizerUseLimitOrderingForStreamingGroupBy {
 		i--
-		dAtA[i] = 0x2
+		if m.OptimizerUseLimitOrderingForStreamingGroupBy {
+			dAtA[i] = 1
+		} else {
+			dAtA[i] = 0
+		}
+		i--
+		dAtA[i] = 0x5
 		i--
 		dAtA[i] = 0xc0
 	}
-	if m.PropagateInputOrdering {
+	if m.OptimizerUseImprovedDisjunctionStats {
 		i--
-		if m.PropagateInputOrdering {
+		if m.OptimizerUseImprovedDisjunctionStats {
 			dAtA[i] = 1
 		} else {
 			dAtA[i] = 0
 		}
 		i--
-		dAtA[i] = 0x2
-		i--
-		dAtA[i] = 0xb8
-	}
-	if m.ResultsBufferSize != 0 {
-		i = encodeVarintLocalOnlySessionData(dAtA, i, uint64(m.ResultsBufferSize))
-		i--
-		dAtA[i] = 0x2
+		dAtA[i] = 0x5
 		i--
 		dAtA[i] = 0xb0
 	}
-	if m.EnableStreamReplication {
+	if m.AllowOrdinalColumnReferences {
 		i--
-		if m.EnableStreamReplication {
+		if m.AllowOrdinalColumnReferences {
 			dAtA[i] = 1
 		} else {
 			dAtA[i] = 0
 		}
 		i--
-		dAtA[i] = 0x2
+		dAtA[i] = 0x5
 		i--
 		dAtA[i] = 0xa8
 	}
-	if len(m.ExperimentalComputedColumnRewrites) > 0 {
-		i -= len(m.ExperimentalComputedColumnRewrites)
-		copy(dAtA[i:], m.ExperimentalComputedColumnRewrites)
-		i = encodeVarintLocalOnlySessionData(dAtA, i, uint64(len(m.ExperimentalComputedColumnRewrites)))
-		i--
-		dAtA[i] = 0x2
-		i--
-		dAtA[i] = 0x9a
-	}
-	if m.StubCatalogTablesEnabled {
+	if m.ExperimentalHashGroupJoinEnabled {
 		i--
-		if m.StubCatalogTablesEnabled {
+		if m.ExperimentalHashGroupJoinEnabled {
 			dAtA[i] = 1
 		} else {
 			dAtA[i] = 0
 		}
 		i--
-		dAtA[i] = 0x2
+		dAtA[i] = 0x5
 		i--
-		dAtA[i] = 0x90
+		dAtA[i] = 0xa0
 	}
-	if m.EnableUniqueWithoutIndexConstraints {
+	if m.DescriptorValidationMode != 0 {
+		i = encodeVarintLocalOnlySessionData(dAtA, i, uint64(m.DescriptorValidationMode))
 		i--
-		if m.EnableUniqueWithoutIndexConstraints {
+		dAtA[i] = 0x5
+		i--
+		dAtA[i] = 0x98
+	}
+	if len(m.SystemIdentityProto) > 0 {
+		i -= len(m.SystemIdentityProto)
+		copy(dAtA[i:], m.SystemIdentityProto)
+		i = encodeVarintLocalOnlySessionData(dAtA, i, uint64(len(m.SystemIdentityProto)))
+		i--
+		dAtA[i] = 0x5
+		i--
+		dAtA[i] = 0x92
+	}
+	if m.TransactionTimeout != 0 {
+		i = encodeVarintLocalOnlySessionData(dAtA, i, uint64(m.TransactionTimeout))
+		i--
+		dAtA[i] = 0x5
+		i--
+		dAtA[i] = 0x88
+	}
+	if m.VariableInequalityLookupJoinEnabled {
+		i--
+		if m.VariableInequalityLookupJoinEnabled {
 			dAtA[i] = 1
 		} else {
 			dAtA[i] = 0
 		}
 		i--
-		dAtA[i] = 0x2
+		dAtA[i] = 0x5
 		i--
-		dAtA[i] = 0x88
+		dAtA[i] = 0x80
 	}
-	if m.EnableSeqScan {
+	if m.OptimizerUseForecasts {
 		i--
-		if m.EnableSeqScan {
+		if m.OptimizerUseForecasts {
 			dAtA[i] = 1
 		} else {
 			dAtA[i] = 0
 		}
 		i--
-		dAtA[i] = 0x1
+		dAtA[i] = 0x4
 		i--
 		dAtA[i] = 0xf8
 	}
-	if m.SynchronousCommit {
+	if m.EnforceHomeRegion {
 		i--
-		if m.SynchronousCommit {
+		if m.EnforceHomeRegion {
 			dAtA[i] = 1
 		} else {
 			dAtA[i] = 0
 		}
 		i--
-		dAtA[i] = 0x1
+		dAtA[i] = 0x4
 		i--
 		dAtA[i] = 0xf0
 	}
-	if m.AlterColumnTypeGeneralEnabled {
+	if m.CopyFromAtomicEnabled {
 		i--
-		if m.AlterColumnTypeGeneralEnabled {
+		if m.CopyFromAtomicEnabled {
 			dAtA[i] = 1
 		} else {
 			dAtA[i] = 0
 		}
 		i--
-		dAtA[i] = 0x1
+		dAtA[i] = 0x4
 		i--
 		dAtA[i] = 0xe8
 	}
-	if m.InsertFastPath {
+	if m.DisableHoistProjectionInJoinLimitation {
 		i--
-		if m.InsertFastPath {
+		if m.DisableHoistProjectionInJoinLimitation {
 			dAtA[i] = 1
 		} else {
 			dAtA[i] = 0
 		}
 		i--
-		dAtA[i] = 0x1
+		dAtA[i] = 0x4
 		i--
 		dAtA[i] = 0xe0
 	}
-	if m.ImplicitSelectForUpdate {
+	if m.CopyFastPathEnabled {
 		i--
-		if m.ImplicitSelectForUpdate {
+		if m.CopyFastPathEnabled {
 			dAtA[i] = 1
 		} else {
 			dAtA[i] = 0
 		}
 		i--
-		dAtA[i] = 0x1
+		dAtA[i] = 0x4
 		i--
 		dAtA[i] = 0xd8
 	}
-	if m.DisallowFullTableScans {
+	if m.OptimizerUseNotVisibleIndexes {
 		i--
-		if m.DisallowFullTableScans {
+		if m.OptimizerUseNotVisibleIndexes {
 			dAtA[i] = 1
 		} else {
 			dAtA[i] = 0
 		}
 		i--
-		dAtA[i] = 0x1
+		dAtA[i] = 0x4
 		i--
 		dAtA[i] = 0xd0
 	}
-	if m.OverrideMultiRegionZoneConfigEnabled {
+	if m.TestingOptimizerDisableRuleProbability != 0 {
+		i -= 8
+		encoding_binary.LittleEndian.PutUint64(dAtA[i:], uint64(math.Float64bits(float64(m.TestingOptimizerDisableRuleProbability))))
 		i--
-		if m.OverrideMultiRegionZoneConfigEnabled {
+		dAtA[i] = 0x4
+		i--
+		dAtA[i] = 0xc9
+	}
+	if m.TestingOptimizerCostPerturbation != 0 {
+		i -= 8
+		encoding_binary.LittleEndian.PutUint64(dAtA[i:], uint64(math.Float64bits(float64(m.TestingOptimizerCostPerturbation))))
+		i--
+		dAtA[i] = 0x4
+		i--
+		dAtA[i] = 0xc1
+	}
+	if m.UnconstrainedNonCoveringIndexScanEnabled {
+		i--
+		if m.UnconstrainedNonCoveringIndexScanEnabled {
 			dAtA[i] = 1
 		} else {
 			dAtA[i] = 0
 		}
 		i--
-		dAtA[i] = 0x1
+		dAtA[i] = 0x4
 		i--
-		dAtA[i] = 0xc0
+		dAtA[i] = 0xb8
 	}
-	if m.ImplicitColumnPartitioningEnabled {
-		i--
-		if m.ImplicitColumnPartitioningEnabled {
-			dAtA[i] = 1
-		} else {
-			dAtA[i] = 0
-		}
+	if m.TestingOptimizerRandomSeed != 0 {
+		i = encodeVarintLocalOnlySessionData(dAtA, i, uint64(m.TestingOptimizerRandomSeed))
 		i--
-		dAtA[i] = 0x1
+		dAtA[i] = 0x4
 		i--
 		dAtA[i] = 0xb0
 	}
-	if m.TempTablesEnabled {
+	if m.ShowPrimaryKeyConstraintOnNotVisibleColumns {
 		i--
-		if m.TempTablesEnabled {
+		if m.ShowPrimaryKeyConstraintOnNotVisibleColumns {
 			dAtA[i] = 1
 		} else {
 			dAtA[i] = 0
 		}
 		i--
-		dAtA[i] = 0x1
+		dAtA[i] = 0x4
 		i--
 		dAtA[i] = 0xa8
 	}
-	if m.AllowPrepareAsOptPlan {
+	if m.MultipleModificationsOfTable {
 		i--
-		if m.AllowPrepareAsOptPlan {
+		if m.MultipleModificationsOfTable {
 			dAtA[i] = 1
 		} else {
 			dAtA[i] = 0
 		}
 		i--
-		dAtA[i] = 0x1
+		dAtA[i] = 0x4
 		i--
 		dAtA[i] = 0xa0
 	}
-	if m.ForceSavepointRestart {
+	if m.ExpectAndIgnoreNotVisibleColumnsInCopy {
 		i--
-		if m.ForceSavepointRestart {
+		if m.ExpectAndIgnoreNotVisibleColumnsInCopy {
 			dAtA[i] = 1
 		} else {
 			dAtA[i] = 0
 		}
 		i--
-		dAtA[i] = 0x1
+		dAtA[i] = 0x4
 		i--
 		dAtA[i] = 0x98
 	}
-	if m.RequireExplicitPrimaryKeys {
+	if m.EnableImplicitTransactionForBatchStatements {
 		i--
-		if m.RequireExplicitPrimaryKeys {
+		if m.EnableImplicitTransactionForBatchStatements {
 			dAtA[i] = 1
 		} else {
 			dAtA[i] = 0
 		}
 		i--
-		dAtA[i] = 0x1
+		dAtA[i] = 0x4
 		i--
 		dAtA[i] = 0x90
 	}
-	if m.ZigzagJoinEnabled {
+	if m.OverrideAlterPrimaryRegionInSuperRegion {
 		i--
-		if m.ZigzagJoinEnabled {
+		if m.OverrideAlterPrimaryRegionInSuperRegion {
 			dAtA[i] = 1
 		} else {
 			dAtA[i] = 0
 		}
 		i--
-		dAtA[i] = 0x1
+		dAtA[i] = 0x4
 		i--
 		dAtA[i] = 0x88
 	}
-	if m.PreferLookupJoinsForFKs {
+	if m.EnableSuperRegions {
 		i--
-		if m.PreferLookupJoinsForFKs {
+		if m.EnableSuperRegions {
 			dAtA[i] = 1
 		} else {
 			dAtA[i] = 0
 		}
 		i--
-		dAtA[i] = 0x1
+		dAtA[i] = 0x4
 		i--
 		dAtA[i] = 0x80
 	}
-	if m.SafeUpdates {
+	if m.OptSplitScanLimit != 0 {
+		i = encodeVarintLocalOnlySessionData(dAtA, i, uint64(m.OptSplitScanLimit))
 		i--
-		if m.SafeUpdates {
+		dAtA[i] = 0x3
+		i--
+		dAtA[i] = 0xf8
+	}
+	if m.DefaultTxnQualityOfService != 0 {
+		i = encodeVarintLocalOnlySessionData(dAtA, i, uint64(m.DefaultTxnQualityOfService))
+		i--
+		dAtA[i] = 0x3
+		i--
+		dAtA[i] = 0xf0
+	}
+	if m.CostScansWithDefaultColSize {
+		i--
+		if m.CostScansWithDefaultColSize {
 			dAtA[i] = 1
 		} else {
 			dAtA[i] = 0
 		}
 		i--
-		dAtA[i] = 0x78
+		dAtA[i] = 0x3
+		i--
+		dAtA[i] = 0xe8
 	}
-	if m.LocalityOptimizedSearch {
+	if m.CheckFunctionBodies {
 		i--
-		if m.LocalityOptimizedSearch {
+		if m.CheckFunctionBodies {
 			dAtA[i] = 1
 		} else {
 			dAtA[i] = 0
 		}
 		i--
-		dAtA[i] = 0x70
+		dAtA[i] = 0x3
+		i--
+		dAtA[i] = 0xe0
 	}
-	if m.OptimizerUseMultiColStats {
+	if m.AvoidBuffering {
 		i--
-		if m.OptimizerUseMultiColStats {
+		if m.AvoidBuffering {
 			dAtA[i] = 1
 		} else {
 			dAtA[i] = 0
 		}
 		i--
-		dAtA[i] = 0x68
+		dAtA[i] = 0x3
+		i--
+		dAtA[i] = 0xd8
 	}
-	if m.OptimizerUseHistograms {
+	if m.IndexRecommendationsEnabled {
 		i--
-		if m.OptimizerUseHistograms {
+		if m.IndexRecommendationsEnabled {
 			dAtA[i] = 1
 		} else {
 			dAtA[i] = 0
 		}
 		i--
-		dAtA[i] = 0x60
+		dAtA[i] = 0x3
+		i--
+		dAtA[i] = 0xd0
 	}
-	if m.PartiallyDistributedPlansDisabled {
+	if len(m.CustomOptions) > 0 {
+		keysForCustomOptions := make([]string, 0, len(m.CustomOptions))
+		for k := range m.CustomOptions {
+			keysForCustomOptions = append(keysForCustomOptions, string(k))
+		}
+		github_com_gogo_protobuf_sortkeys.Strings(keysForCustomOptions)
+		for iNdEx := len(keysForCustomOptions) - 1; iNdEx >= 0; iNdEx-- {
+			v := m.CustomOptions[string(keysForCustomOptions[iNdEx])]
+			baseI := i
+			i -= len(v)
+			copy(dAtA[i:], v)
+			i = encodeVarintLocalOnlySessionData(dAtA, i, uint64(len(v)))
+			i--
+			dAtA[i] = 0x12
+			i -= len(keysForCustomOptions[iNdEx])
+			copy(dAtA[i:], keysForCustomOptions[iNdEx])
+			i = encodeVarintLocalOnlySessionData(dAtA, i, uint64(len(keysForCustomOptions[iNdEx])))
+			i--
+			dAtA[i] = 0xa
+			i = encodeVarintLocalOnlySessionData(dAtA, i, uint64(baseI-i))
+			i--
+			dAtA[i] = 0x3
+			i--
+			dAtA[i] = 0xca
+		}
+	}
+	if m.DisablePlanGists {
 		i--
-		if m.PartiallyDistributedPlansDisabled {
+		if m.DisablePlanGists {
 			dAtA[i] = 1
 		} else {
 			dAtA[i] = 0
 		}
 		i--
-		dAtA[i] = 0x58
+		dAtA[i] = 0x3
+		i--
+		dAtA[i] = 0xc0
 	}
-	if m.DefaultTxnUseFollowerReads {
+	if m.NullOrderedLast {
 		i--
-		if m.DefaultTxnUseFollowerReads {
+		if m.NullOrderedLast {
 			dAtA[i] = 1
 		} else {
 			dAtA[i] = 0
 		}
 		i--
-		dAtA[i] = 0x50
+		dAtA[i] = 0x3
+		i--
+		dAtA[i] = 0xb8
 	}
-	if m.DefaultTxnReadOnly {
+	if m.InjectRetryErrorsEnabled {
 		i--
-		if m.DefaultTxnReadOnly {
+		if m.InjectRetryErrorsEnabled {
 			dAtA[i] = 1
 		} else {
 			dAtA[i] = 0
 		}
 		i--
-		dAtA[i] = 0x48
-	}
-	if m.DefaultTxnPriority != 0 {
-		i = encodeVarintLocalOnlySessionData(dAtA, i, uint64(m.DefaultTxnPriority))
+		dAtA[i] = 0x3
 		i--
-		dAtA[i] = 0x40
+		dAtA[i] = 0xb0
 	}
-	if m.ReorderJoinsLimit != 0 {
-		i = encodeVarintLocalOnlySessionData(dAtA, i, uint64(m.ReorderJoinsLimit))
+	if m.LargeFullScanRows != 0 {
+		i -= 8
+		encoding_binary.LittleEndian.PutUint64(dAtA[i:], uint64(math.Float64bits(float64(m.LargeFullScanRows))))
 		i--
-		dAtA[i] = 0x38
-	}
-	if m.NoticeDisplaySeverity != 0 {
-		i = encodeVarintLocalOnlySessionData(dAtA, i, uint64(m.NoticeDisplaySeverity))
+		dAtA[i] = 0x3
 		i--
-		dAtA[i] = 0x30
+		dAtA[i] = 0xa9
 	}
-	if m.IdleInTransactionSessionTimeout != 0 {
-		i = encodeVarintLocalOnlySessionData(dAtA, i, uint64(m.IdleInTransactionSessionTimeout))
+	if m.IsSuperuser {
 		i--
-		dAtA[i] = 0x28
-	}
-	if m.IdleInSessionTimeout != 0 {
-		i = encodeVarintLocalOnlySessionData(dAtA, i, uint64(m.IdleInSessionTimeout))
+		if m.IsSuperuser {
+			dAtA[i] = 1
+		} else {
+			dAtA[i] = 0
+		}
 		i--
-		dAtA[i] = 0x20
-	}
-	if m.StmtTimeout != 0 {
-		i = encodeVarintLocalOnlySessionData(dAtA, i, uint64(m.StmtTimeout))
+		dAtA[i] = 0x3
 		i--
-		dAtA[i] = 0x18
+		dAtA[i] = 0xa0
 	}
-	if m.OptimizerFKCascadesLimit != 0 {
-		i = encodeVarintLocalOnlySessionData(dAtA, i, uint64(m.OptimizerFKCascadesLimit))
+	if m.AutoRehomingEnabled {
 		i--
-		dAtA[i] = 0x10
-	}
-	if len(m.SaveTablesPrefix) > 0 {
-		i -= len(m.SaveTablesPrefix)
-		copy(dAtA[i:], m.SaveTablesPrefix)
-		i = encodeVarintLocalOnlySessionData(dAtA, i, uint64(len(m.SaveTablesPrefix)))
+		if m.AutoRehomingEnabled {
+			dAtA[i] = 1
+		} else {
+			dAtA[i] = 0
+		}
 		i--
-		dAtA[i] = 0xa
-	}
-	return len(dAtA) - i, nil
-}
-
-func (m *SequenceCacheEntry) Marshal() (dAtA []byte, err error) {
-	size := m.Size()
-	dAtA = make([]byte, size)
-	n, err := m.MarshalToSizedBuffer(dAtA[:size])
-	if err != nil {
-		return nil, err
+		dAtA[i] = 0x3
+		i--
+		dAtA[i] = 0x98
 	}
-	return dAtA[:n], nil
-}
-
-func (m *SequenceCacheEntry) MarshalTo(dAtA []byte) (int, error) {
-	size := m.Size()
-	return m.MarshalToSizedBuffer(dAtA[:size])
-}
-
-func (m *SequenceCacheEntry) MarshalToSizedBuffer(dAtA []byte) (int, error) {
-	i := len(dAtA)
-	_ = i
-	var l int
-	_ = l
-	if m.NumValues != 0 {
-		i = encodeVarintLocalOnlySessionData(dAtA, i, uint64(m.NumValues))
+	if m.TxnRowsReadErr != 0 {
+		i = encodeVarintLocalOnlySessionData(dAtA, i, uint64(m.TxnRowsReadErr))
 		i--
-		dAtA[i] = 0x20
+		dAtA[i] = 0x3
+		i--
+		dAtA[i] = 0x90
 	}
-	if m.Increment != 0 {
-		i = encodeVarintLocalOnlySessionData(dAtA, i, uint64(m.Increment))
+	if m.TxnRowsReadLog != 0 {
+		i = encodeVarintLocalOnlySessionData(dAtA, i, uint64(m.TxnRowsReadLog))
 		i--
-		dAtA[i] = 0x18
+		dAtA[i] = 0x3
+		i--
+		dAtA[i] = 0x88
 	}
-	if m.CurrentValue != 0 {
-		i = encodeVarintLocalOnlySessionData(dAtA, i, uint64(m.CurrentValue))
+	if m.TxnRowsWrittenErr != 0 {
+		i = encodeVarintLocalOnlySessionData(dAtA, i, uint64(m.TxnRowsWrittenErr))
 		i--
-		dAtA[i] = 0x10
+		dAtA[i] = 0x3
+		i--
+		dAtA[i] = 0x80
 	}
-	if m.CachedVersion != 0 {
-		i = encodeVarintLocalOnlySessionData(dAtA, i, uint64(m.CachedVersion))
+	if m.TxnRowsWrittenLog != 0 {
+		i = encodeVarintLocalOnlySessionData(dAtA, i, uint64(m.TxnRowsWrittenLog))
 		i--
-		dAtA[i] = 0x8
+		dAtA[i] = 0x2
+		i--
+		dAtA[i] = 0xf8
 	}
-	return len(dAtA) - i, nil
-}
-
-func encodeVarintLocalOnlySessionData(dAtA []byte, offset int, v uint64) int {
-	offset -= sovLocalOnlySessionData(v)
-	base := offset
-	for v >= 1<<7 {
-		dAtA[offset] = uint8(v&0x7f | 0x80)
-		v >>= 7
-		offset++
-	}
-	dAtA[offset] = uint8(v)
-	return base
-}
-func (m *LocalOnlySessionData) Size() (n int) {
-	if m == nil {
-		return 0
-	}
-	var l int
-	_ = l
-	l = len(m.SaveTablesPrefix)
-	if l > 0 {
-		n += 1 + l + sovLocalOnlySessionData(uint64(l))
-	}
-	if m.OptimizerFKCascadesLimit != 0 {
-		n += 1 + sovLocalOnlySessionData(uint64(m.OptimizerFKCascadesLimit))
-	}
-	if m.StmtTimeout != 0 {
-		n += 1 + sovLocalOnlySessionData(uint64(m.StmtTimeout))
-	}
-	if m.IdleInSessionTimeout != 0 {
-		n += 1 + sovLocalOnlySessionData(uint64(m.IdleInSessionTimeout))
-	}
-	if m.IdleInTransactionSessionTimeout != 0 {
-		n += 1 + sovLocalOnlySessionData(uint64(m.IdleInTransactionSessionTimeout))
-	}
-	if m.NoticeDisplaySeverity != 0 {
-		n += 1 + sovLocalOnlySessionData(uint64(m.NoticeDisplaySeverity))
+	if len(m.SessionUserProto) > 0 {
+		i -= len(m.SessionUserProto)
+		copy(dAtA[i:], m.SessionUserProto)
+		i = encodeVarintLocalOnlySessionData(dAtA, i, uint64(len(m.SessionUserProto)))
+		i--
+		dAtA[i] = 0x2
+		i--
+		dAtA[i] = 0xf2
 	}
-	if m.ReorderJoinsLimit != 0 {
-		n += 1 + sovLocalOnlySessionData(uint64(m.ReorderJoinsLimit))
+	if m.PlacementEnabled {
+		i--
+		if m.PlacementEnabled {
+			dAtA[i] = 1
+		} else {
+			dAtA[i] = 0
+		}
+		i--
+		dAtA[i] = 0x2
+		i--
+		dAtA[i] = 0xe8
 	}
-	if m.DefaultTxnPriority != 0 {
-		n += 1 + sovLocalOnlySessionData(uint64(m.DefaultTxnPriority))
+	if len(m.SequenceCache) > 0 {
+		keysForSequenceCache := make([]uint32, 0, len(m.SequenceCache))
+		for k := range m.SequenceCache {
+			keysForSequenceCache = append(keysForSequenceCache, uint32(k))
+		}
+		github_com_gogo_protobuf_sortkeys.Uint32s(keysForSequenceCache)
+		for iNdEx := len(keysForSequenceCache) - 1; iNdEx >= 0; iNdEx-- {
+			v := m.SequenceCache[uint32(keysForSequenceCache[iNdEx])]
+			baseI := i
+			if v != nil {
+				{
+					size, err := v.MarshalToSizedBuffer(dAtA[:i])
+					if err != nil {
+						return 0, err
+					}
+					i -= size
+					i = encodeVarintLocalOnlySessionData(dAtA, i, uint64(size))
+				}
+				i--
+				dAtA[i] = 0x12
+			}
+			i = encodeVarintLocalOnlySessionData(dAtA, i, uint64(keysForSequenceCache[iNdEx]))
+			i--
+			dAtA[i] = 0x8
+			i = encodeVarintLocalOnlySessionData(dAtA, i, uint64(baseI-i))
+			i--
+			dAtA[i] = 0x2
+			i--
+			dAtA[i] = 0xe2
+		}
 	}
-	if m.DefaultTxnReadOnly {
-		n += 2
+	if m.NewSchemaChangerMode != 0 {
+		i = encodeVarintLocalOnlySessionData(dAtA, i, uint64(m.NewSchemaChangerMode))
+		i--
+		dAtA[i] = 0x2
+		i--
+		dAtA[i] = 0xd8
 	}
-	if m.DefaultTxnUseFollowerReads {
-		n += 2
+	if m.SerialNormalizationMode != 0 {
+		i = encodeVarintLocalOnlySessionData(dAtA, i, uint64(m.SerialNormalizationMode))
+		i--
+		dAtA[i] = 0x2
+		i--
+		dAtA[i] = 0xd0
 	}
-	if m.PartiallyDistributedPlansDisabled {
-		n += 2
+	if m.DistSQLMode != 0 {
+		i = encodeVarintLocalOnlySessionData(dAtA, i, uint64(m.DistSQLMode))
+		i--
+		dAtA[i] = 0x2
+		i--
+		dAtA[i] = 0xc8
 	}
-	if m.OptimizerUseHistograms {
-		n += 2
+	if m.ExperimentalDistSQLPlanningMode != 0 {
+		i = encodeVarintLocalOnlySessionData(dAtA, i, uint64(m.ExperimentalDistSQLPlanningMode))
+		i--
+		dAtA[i] = 0x2
+		i--
+		dAtA[i] = 0xc0
 	}
-	if m.OptimizerUseMultiColStats {
-		n += 2
+	if m.PropagateInputOrdering {
+		i--
+		if m.PropagateInputOrdering {
+			dAtA[i] = 1
+		} else {
+			dAtA[i] = 0
+		}
+		i--
+		dAtA[i] = 0x2
+		i--
+		dAtA[i] = 0xb8
 	}
-	if m.LocalityOptimizedSearch {
-		n += 2
+	if m.ResultsBufferSize != 0 {
+		i = encodeVarintLocalOnlySessionData(dAtA, i, uint64(m.ResultsBufferSize))
+		i--
+		dAtA[i] = 0x2
+		i--
+		dAtA[i] = 0xb0
 	}
-	if m.SafeUpdates {
-		n += 2
+	if m.EnableStreamReplication {
+		i--
+		if m.EnableStreamReplication {
+			dAtA[i] = 1
+		} else {
+			dAtA[i] = 0
+		}
+		i--
+		dAtA[i] = 0x2
+		i--
+		dAtA[i] = 0xa8
 	}
-	if m.PreferLookupJoinsForFKs {
-		n += 3
+	if len(m.ExperimentalComputedColumnRewrites) > 0 {
+		i -= len(m.ExperimentalComputedColumnRewrites)
+		copy(dAtA[i:], m.ExperimentalComputedColumnRewrites)
+		i = encodeVarintLocalOnlySessionData(dAtA, i, uint64(len(m.ExperimentalComputedColumnRewrites)))
+		i--
+		dAtA[i] = 0x2
+		i--
+		dAtA[i] = 0x9a
 	}
-	if m.ZigzagJoinEnabled {
-		n += 3
+	if m.StubCatalogTablesEnabled {
+		i--
+		if m.StubCatalogTablesEnabled {
+			dAtA[i] = 1
+		} else {
+			dAtA[i] = 0
+		}
+		i--
+		dAtA[i] = 0x2
+		i--
+		dAtA[i] = 0x90
 	}
-	if m.RequireExplicitPrimaryKeys {
-		n += 3
+	if m.EnableUniqueWithoutIndexConstraints {
+		i--
+		if m.EnableUniqueWithoutIndexConstraints {
+			dAtA[i] = 1
+		} else {
+			dAtA[i] = 0
+		}
+		i--
+		dAtA[i] = 0x2
+		i--
+		dAtA[i] = 0x88
 	}
-	if m.ForceSavepointRestart {
-		n += 3
+	if m.EnableSeqScan {
+		i--
+		if m.EnableSeqScan {
+			dAtA[i] = 1
+		} else {
+			dAtA[i] = 0
+		}
+		i--
+		dAtA[i] = 0x1
+		i--
+		dAtA[i] = 0xf8
 	}
-	if m.AllowPrepareAsOptPlan {
-		n += 3
+	if m.SynchronousCommit {
+		i--
+		if m.SynchronousCommit {
+			dAtA[i] = 1
+		} else {
+			dAtA[i] = 0
+		}
+		i--
+		dAtA[i] = 0x1
+		i--
+		dAtA[i] = 0xf0
 	}
-	if m.TempTablesEnabled {
-		n += 3
+	if m.AlterColumnTypeGeneralEnabled {
+		i--
+		if m.AlterColumnTypeGeneralEnabled {
+			dAtA[i] = 1
+		} else {
+			dAtA[i] = 0
+		}
+		i--
+		dAtA[i] = 0x1
+		i--
+		dAtA[i] = 0xe8
 	}
-	if m.ImplicitColumnPartitioningEnabled {
-		n += 3
+	if m.InsertFastPath {
+		i--
+		if m.InsertFastPath {
+			dAtA[i] = 1
+		} else {
+			dAtA[i] = 0
+		}
+		i--
+		dAtA[i] = 0x1
+		i--
+		dAtA[i] = 0xe0
 	}
-	if m.OverrideMultiRegionZoneConfigEnabled {
-		n += 3
+	if m.ImplicitSelectForUpdate {
+		i--
+		if m.ImplicitSelectForUpdate {
+			dAtA[i] = 1
+		} else {
+			dAtA[i] = 0
+		}
+		i--
+		dAtA[i] = 0x1
+		i--
+		dAtA[i] = 0xd8
 	}
 	if m.DisallowFullTableScans {
-		n += 3
-	}
-	if m.ImplicitSelectForUpdate {
-		n += 3
-	}
-	if m.InsertFastPath {
-		n += 3
+		i--
+		if m.DisallowFullTableScans {
+			dAtA[i] = 1
+		} else {
+			dAtA[i] = 0
+		}
+		i--
+		dAtA[i] = 0x1
+		i--
+		dAtA[i] = 0xd0
 	}
-	if m.AlterColumnTypeGeneralEnabled {
-		n += 3
+	if m.OverrideMultiRegionZoneConfigEnabled {
+		i--
+		if m.OverrideMultiRegionZoneConfigEnabled {
+			dAtA[i] = 1
+		} else {
+			dAtA[i] = 0
+		}
+		i--
+		dAtA[i] = 0x1
+		i--
+		dAtA[i] = 0xc0
 	}
-	if m.SynchronousCommit {
-		n += 3
+	if m.ImplicitColumnPartitioningEnabled {
+		i--
+		if m.ImplicitColumnPartitioningEnabled {
+			dAtA[i] = 1
+		} else {
+			dAtA[i] = 0
+		}
+		i--
+		dAtA[i] = 0x1
+		i--
+		dAtA[i] = 0xb0
 	}
-	if m.EnableSeqScan {
-		n += 3
+	if m.TempTablesEnabled {
+		i--
+		if m.TempTablesEnabled {
+			dAtA[i] = 1
+		} else {
+			dAtA[i] = 0
+		}
+		i--
+		dAtA[i] = 0x1
+		i--
+		dAtA[i] = 0xa8
 	}
-	if m.EnableUniqueWithoutIndexConstraints {
-		n += 3
+	if m.AllowPrepareAsOptPlan {
+		i--
+		if m.AllowPrepareAsOptPlan {
+			dAtA[i] = 1
+		} else {
+			dAtA[i] = 0
+		}
+		i--
+		dAtA[i] = 0x1
+		i--
+		dAtA[i] = 0xa0
 	}
-	if m.StubCatalogTablesEnabled {
-		n += 3
+	if m.ForceSavepointRestart {
+		i--
+		if m.ForceSavepointRestart {
+			dAtA[i] = 1
+		} else {
+			dAtA[i] = 0
+		}
+		i--
+		dAtA[i] = 0x1
+		i--
+		dAtA[i] = 0x98
 	}
-	l = len(m.ExperimentalComputedColumnRewrites)
-	if l > 0 {
-		n += 2 + l + sovLocalOnlySessionData(uint64(l))
+	if m.RequireExplicitPrimaryKeys {
+		i--
+		if m.RequireExplicitPrimaryKeys {
+			dAtA[i] = 1
+		} else {
+			dAtA[i] = 0
+		}
+		i--
+		dAtA[i] = 0x1
+		i--
+		dAtA[i] = 0x90
 	}
-	if m.EnableStreamReplication {
-		n += 3
+	if m.ZigzagJoinEnabled {
+		i--
+		if m.ZigzagJoinEnabled {
+			dAtA[i] = 1
+		} else {
+			dAtA[i] = 0
+		}
+		i--
+		dAtA[i] = 0x1
+		i--
+		dAtA[i] = 0x88
 	}
-	if m.ResultsBufferSize != 0 {
-		n += 2 + sovLocalOnlySessionData(uint64(m.ResultsBufferSize))
+	if m.PreferLookupJoinsForFKs {
+		i--
+		if m.PreferLookupJoinsForFKs {
+			dAtA[i] = 1
+		} else {
+			dAtA[i] = 0
+		}
+		i--
+		dAtA[i] = 0x1
+		i--
+		dAtA[i] = 0x80
 	}
-	if m.PropagateInputOrdering {
-		n += 3
+	if m.SafeUpdates {
+		i--
+		if m.SafeUpdates {
+			dAtA[i] = 1
+		} else {
+			dAtA[i] = 0
+		}
+		i--
+		dAtA[i] = 0x78
 	}
-	if m.ExperimentalDistSQLPlanningMode != 0 {
-		n += 2 + sovLocalOnlySessionData(uint64(m.ExperimentalDistSQLPlanningMode))
+	if m.LocalityOptimizedSearch {
+		i--
+		if m.LocalityOptimizedSearch {
+			dAtA[i] = 1
+		} else {
+			dAtA[i] = 0
+		}
+		i--
+		dAtA[i] = 0x70
 	}
-	if m.DistSQLMode != 0 {
-		n += 2 + sovLocalOnlySessionData(uint64(m.DistSQLMode))
+	if m.OptimizerUseMultiColStats {
+		i--
+		if m.OptimizerUseMultiColStats {
+			dAtA[i] = 1
+		} else {
+			dAtA[i] = 0
+		}
+		i--
+		dAtA[i] = 0x68
 	}
-	if m.SerialNormalizationMode != 0 {
-		n += 2 + sovLocalOnlySessionData(uint64(m.SerialNormalizationMode))
+	if m.OptimizerUseHistograms {
+		i--
+		if m.OptimizerUseHistograms {
+			dAtA[i] = 1
+		} else {
+			dAtA[i] = 0
+		}
+		i--
+		dAtA[i] = 0x60
 	}
-	if m.NewSchemaChangerMode != 0 {
-		n += 2 + sovLocalOnlySessionData(uint64(m.NewSchemaChangerMode))
+	if m.PartiallyDistributedPlansDisabled {
+		i--
+		if m.PartiallyDistributedPlansDisabled {
+			dAtA[i] = 1
+		} else {
+			dAtA[i] = 0
+		}
+		i--
+		dAtA[i] = 0x58
 	}
-	if len(m.SequenceCache) > 0 {
-		for k, v := range m.SequenceCache {
-			_ = k
-			_ = v
-			l = 0
-			if v != nil {
-				l = v.Size()
-				l += 1 + sovLocalOnlySessionData(uint64(l))
-			}
-			mapEntrySize := 1 + sovLocalOnlySessionData(uint64(k)) + l
-			n += mapEntrySize + 2 + sovLocalOnlySessionData(uint64(mapEntrySize))
+	if m.DefaultTxnUseFollowerReads {
+		i--
+		if m.DefaultTxnUseFollowerReads {
+			dAtA[i] = 1
+		} else {
+			dAtA[i] = 0
 		}
+		i--
+		dAtA[i] = 0x50
 	}
-	if m.PlacementEnabled {
-		n += 3
+	if m.DefaultTxnReadOnly {
+		i--
+		if m.DefaultTxnReadOnly {
+			dAtA[i] = 1
+		} else {
+			dAtA[i] = 0
+		}
+		i--
+		dAtA[i] = 0x48
 	}
-	l = len(m.SessionUserProto)
-	if l > 0 {
-		n += 2 + l + sovLocalOnlySessionData(uint64(l))
+	if m.DefaultTxnPriority != 0 {
+		i = encodeVarintLocalOnlySessionData(dAtA, i, uint64(m.DefaultTxnPriority))
+		i--
+		dAtA[i] = 0x40
 	}
-	if m.TxnRowsWrittenLog != 0 {
-		n += 2 + sovLocalOnlySessionData(uint64(m.TxnRowsWrittenLog))
+	if m.ReorderJoinsLimit != 0 {
+		i = encodeVarintLocalOnlySessionData(dAtA, i, uint64(m.ReorderJoinsLimit))
+		i--
+		dAtA[i] = 0x38
 	}
-	if m.TxnRowsWrittenErr != 0 {
-		n += 2 + sovLocalOnlySessionData(uint64(m.TxnRowsWrittenErr))
+	if m.NoticeDisplaySeverity != 0 {
+		i = encodeVarintLocalOnlySessionData(dAtA, i, uint64(m.NoticeDisplaySeverity))
+		i--
+		dAtA[i] = 0x30
 	}
-	if m.TxnRowsReadLog != 0 {
-		n += 2 + sovLocalOnlySessionData(uint64(m.TxnRowsReadLog))
+	if m.IdleInTransactionSessionTimeout != 0 {
+		i = encodeVarintLocalOnlySessionData(dAtA, i, uint64(m.IdleInTransactionSessionTimeout))
+		i--
+		dAtA[i] = 0x28
 	}
-	if m.TxnRowsReadErr != 0 {
-		n += 2 + sovLocalOnlySessionData(uint64(m.TxnRowsReadErr))
+	if m.IdleInSessionTimeout != 0 {
+		i = encodeVarintLocalOnlySessionData(dAtA, i, uint64(m.IdleInSessionTimeout))
+		i--
+		dAtA[i] = 0x20
 	}
-	if m.AutoRehomingEnabled {
-		n += 3
+	if m.StmtTimeout != 0 {
+		i = encodeVarintLocalOnlySessionData(dAtA, i, uint64(m.StmtTimeout))
+		i--
+		dAtA[i] = 0x18
 	}
-	if m.IsSuperuser {
-		n += 3
+	if m.OptimizerFKCascadesLimit != 0 {
+		i = encodeVarintLocalOnlySessionData(dAtA, i, uint64(m.OptimizerFKCascadesLimit))
+		i--
+		dAtA[i] = 0x10
 	}
-	if m.LargeFullScanRows != 0 {
-		n += 10
+	if len(m.SaveTablesPrefix) > 0 {
+		i -= len(m.SaveTablesPrefix)
+		copy(dAtA[i:], m.SaveTablesPrefix)
+		i = encodeVarintLocalOnlySessionData(dAtA, i, uint64(len(m.SaveTablesPrefix)))
+		i--
+		dAtA[i] = 0xa
+	}
+	return len(dAtA) - i, nil
+}
+
+func (m *SequenceCacheEntry) Marshal() (dAtA []byte, err error) {
+	size := m.Size()
+	dAtA = make([]byte, size)
+	n, err := m.MarshalToSizedBuffer(dAtA[:size])
+	if err != nil {
+		return nil, err
+	}
+	return dAtA[:n], nil
+}
+
+func (m *SequenceCacheEntry) MarshalTo(dAtA []byte) (int, error) {
+	size := m.Size()
+	return m.MarshalToSizedBuffer(dAtA[:size])
+}
+
+func (m *SequenceCacheEntry) MarshalToSizedBuffer(dAtA []byte) (int, error) {
+	i := len(dAtA)
+	_ = i
+	var l int
+	_ = l
+	if m.NumValues != 0 {
+		i = encodeVarintLocalOnlySessionData(dAtA, i, uint64(m.NumValues))
+		i--
+		dAtA[i] = 0x20
+	}
+	if m.Increment != 0 {
+		i = encodeVarintLocalOnlySessionData(dAtA, i, uint64(m.Increment))
+		i--
+		dAtA[i] = 0x18
+	}
+	if m.CurrentValue != 0 {
+		i = encodeVarintLocalOnlySessionData(dAtA, i, uint64(m.CurrentValue))
+		i--
+		dAtA[i] = 0x10
+	}
+	if m.CachedVersion != 0 {
+		i = encodeVarintLocalOnlySessionData(dAtA, i, uint64(m.CachedVersion))
+		i--
+		dAtA[i] = 0x8
+	}
+	return len(dAtA) - i, nil
+}
+
+func encodeVarintLocalOnlySessionData(dAtA []byte, offset int, v uint64) int {
+	offset -= sovLocalOnlySessionData(v)
+	base := offset
+	for v >= 1<<7 {
+		dAtA[offset] = uint8(v&0x7f | 0x80)
+		v >>= 7
+		offset++
+	}
+	dAtA[offset] = uint8(v)
+	return base
+}
+func (m *LocalOnlySessionData) Size() (n int) {
+	if m == nil {
+		return 0
+	}
+	var l int
+	_ = l
+	l = len(m.SaveTablesPrefix)
+	if l > 0 {
+		n += 1 + l + sovLocalOnlySessionData(uint64(l))
+	}
+	if m.OptimizerFKCascadesLimit != 0 {
+		n += 1 + sovLocalOnlySessionData(uint64(m.OptimizerFKCascadesLimit))
+	}
+	if m.StmtTimeout != 0 {
+		n += 1 + sovLocalOnlySessionData(uint64(m.StmtTimeout))
+	}
+	if m.IdleInSessionTimeout != 0 {
+		n += 1 + sovLocalOnlySessionData(uint64(m.IdleInSessionTimeout))
+	}
+	if m.IdleInTransactionSessionTimeout != 0 {
+		n += 1 + sovLocalOnlySessionData(uint64(m.IdleInTransactionSessionTimeout))
+	}
+	if m.NoticeDisplaySeverity != 0 {
+		n += 1 + sovLocalOnlySessionData(uint64(m.NoticeDisplaySeverity))
+	}
+	if m.ReorderJoinsLimit != 0 {
+		n += 1 + sovLocalOnlySessionData(uint64(m.ReorderJoinsLimit))
+	}
+	if m.DefaultTxnPriority != 0 {
+		n += 1 + sovLocalOnlySessionData(uint64(m.DefaultTxnPriority))
+	}
+	if m.DefaultTxnReadOnly {
+		n += 2
+	}
+	if m.DefaultTxnUseFollowerReads {
+		n += 2
+	}
+	if m.PartiallyDistributedPlansDisabled {
+		n += 2
+	}
+	if m.OptimizerUseHistograms {
+		n += 2
+	}
+	if m.OptimizerUseMultiColStats {
+		n += 2
+	}
+	if m.LocalityOptimizedSearch {
+		n += 2
+	}
+	if m.SafeUpdates {
+		n += 2
+	}
+	if m.PreferLookupJoinsForFKs {
+		n += 3
+	}
+	if m.ZigzagJoinEnabled {
+		n += 3
+	}
+	if m.RequireExplicitPrimaryKeys {
+		n += 3
+	}
+	if m.ForceSavepointRestart {
+		n += 3
+	}
+	if m.AllowPrepareAsOptPlan {
+		n += 3
+	}
+	if m.TempTablesEnabled {
+		n += 3
+	}
+	if m.ImplicitColumnPartitioningEnabled {
+		n += 3
+	}
+	if m.OverrideMultiRegionZoneConfigEnabled {
+		n += 3
+	}
+	if m.DisallowFullTableScans {
+		n += 3
+	}
+	if m.ImplicitSelectForUpdate {
+		n += 3
+	}
+	if m.InsertFastPath {
+		n += 3
+	}
+	if m.AlterColumnTypeGeneralEnabled {
+		n += 3
+	}
+	if m.SynchronousCommit {
+		n += 3
+	}
+	if m.EnableSeqScan {
+		n += 3
+	}
+	if m.EnableUniqueWithoutIndexConstraints {
+		n += 3
+	}
+	if m.StubCatalogTablesEnabled {
+		n += 3
+	}
+	l = len(m.ExperimentalComputedColumnRewrites)
+	if l > 0 {
+		n += 2 + l + sovLocalOnlySessionData(uint64(l))
+	}
+	if m.EnableStreamReplication {
+		n += 3
+	}
+	if m.ResultsBufferSize != 0 {
+		n += 2 + sovLocalOnlySessionData(uint64(m.ResultsBufferSize))
+	}
+	if m.PropagateInputOrdering {
+		n += 3
+	}
+	if m.ExperimentalDistSQLPlanningMode != 0 {
+		n += 2 + sovLocalOnlySessionData(uint64(m.ExperimentalDistSQLPlanningMode))
+	}
+	if m.DistSQLMode != 0 {
+		n += 2 + sovLocalOnlySessionData(uint64(m.DistSQLMode))
+	}
+	if m.SerialNormalizationMode != 0 {
+		n += 2 + sovLocalOnlySessionData(uint64(m.SerialNormalizationMode))
+	}
+	if m.NewSchemaChangerMode != 0 {
+		n += 2 + sovLocalOnlySessionData(uint64(m.NewSchemaChangerMode))
+	}
+	if len(m.SequenceCache) > 0 {
+		for k, v := range m.SequenceCache {
+			_ = k
+			_ = v
+			l = 0
+			if v != nil {
+				l = v.Size()
+				l += 1 + sovLocalOnlySessionData(uint64(l))
+			}
+			mapEntrySize := 1 + sovLocalOnlySessionData(uint64(k)) + l
+			n += mapEntrySize + 2 + sovLocalOnlySessionData(uint64(mapEntrySize))
+		}
+	}
+	if m.PlacementEnabled {
+		n += 3
+	}
+	l = len(m.SessionUserProto)
+	if l > 0 {
+		n += 2 + l + sovLocalOnlySessionData(uint64(l))
+	}
+	if m.TxnRowsWrittenLog != 0 {
+		n += 2 + sovLocalOnlySessionData(uint64(m.TxnRowsWrittenLog))
+	}
+	if m.TxnRowsWrittenErr != 0 {
+		n += 2 + sovLocalOnlySessionData(uint64(m.TxnRowsWrittenErr))
+	}
+	if m.TxnRowsReadLog != 0 {
+		n += 2 + sovLocalOnlySessionData(uint64(m.TxnRowsReadLog))
+	}
+	if m.TxnRowsReadErr != 0 {
+		n += 2 + sovLocalOnlySessionData(uint64(m.TxnRowsReadErr))
+	}
+	if m.AutoRehomingEnabled {
+		n += 3
+	}
+	if m.IsSuperuser {
+		n += 3
+	}
+	if m.LargeFullScanRows != 0 {
+		n += 10
 	}
 	if m.InjectRetryErrorsEnabled {
 		n += 3
@@ -2423,12 +3321,6 @@ func (m *LocalOnlySessionData) Size() (n int) {
 	if m.PreparedStatementsCacheSize != 0 {
 		n += 2 + sovLocalOnlySessionData(uint64(m.PreparedStatementsCacheSize))
 	}
-	if m.StreamerEnabled {
-		n += 3
-	}
-	if m.DisableDropVirtualCluster {
-		n += 3
-	}
 	if m.MultipleActivePortalsEnabled {
 		n += 3
 	}
@@ -2487,37 +3379,195 @@ func (m *LocalOnlySessionData) Size() (n int) {
 	if m.CopyWritePipeliningEnabled {
 		n += 3
 	}
+	if m.OptimizerMergeJoinsEnabled {
+		n += 3
+	}
 	if m.CopyNumRetriesPerBatch != 0 {
 		n += 2 + sovLocalOnlySessionData(uint64(m.CopyNumRetriesPerBatch))
 	}
-	return n
-}
-
-func (m *SequenceCacheEntry) Size() (n int) {
-	if m == nil {
-		return 0
+	if m.AutoCommitBeforeDDL {
+		n += 3
 	}
-	var l int
-	_ = l
-	if m.CachedVersion != 0 {
-		n += 1 + sovLocalOnlySessionData(uint64(m.CachedVersion))
+	if m.CloseCursorsAtCommit {
+		n += 3
 	}
-	if m.CurrentValue != 0 {
-		n += 1 + sovLocalOnlySessionData(uint64(m.CurrentValue))
+	if m.PLpgSQLUseStrictInto {
+		n += 3
 	}
-	if m.Increment != 0 {
-		n += 1 + sovLocalOnlySessionData(uint64(m.Increment))
+	if m.OptimizerUseVirtualComputedColumnStats {
+		n += 3
 	}
-	if m.NumValues != 0 {
-		n += 1 + sovLocalOnlySessionData(uint64(m.NumValues))
+	if m.OptimizerUseTrigramSimilarityOptimization {
+		n += 3
 	}
-	return n
-}
-
-func sovLocalOnlySessionData(x uint64) (n int) {
-	return (math_bits.Len64(x|1) + 6) / 7
-}
-func sozLocalOnlySessionData(x uint64) (n int) {
+	if m.OptimizerUseImprovedDistinctOnLimitHintCosting {
+		n += 3
+	}
+	if m.OptimizerUseImprovedTrigramSimilaritySelectivity {
+		n += 3
+	}
+	if m.OptimizerUseImprovedZigzagJoinCosting {
+		n += 3
+	}
+	if m.OptimizerUseImprovedMultiColumnSelectivityEstimate {
+		n += 3
+	}
+	if m.OptimizerProveImplicationWithVirtualComputedColumns {
+		n += 3
+	}
+	if m.OptimizerPushOffsetIntoIndexJoin {
+		n += 3
+	}
+	if m.PlanCacheMode != 0 {
+		n += 2 + sovLocalOnlySessionData(uint64(m.PlanCacheMode))
+	}
+	if m.OptimizerUsePolymorphicParameterFix {
+		n += 3
+	}
+	if m.OriginIDForLogicalDataReplication != 0 {
+		n += 2 + sovLocalOnlySessionData(uint64(m.OriginIDForLogicalDataReplication))
+	}
+	if m.EnableCreateStatsUsingExtremesBoolEnum {
+		n += 3
+	}
+	if m.OptimizerUseMergedPartialStatistics {
+		n += 3
+	}
+	if m.OptimizerUseConditionalHoistFix {
+		n += 3
+	}
+	if m.OptimizerPushLimitIntoProjectFilteredScan {
+		n += 3
+	}
+	l = m.OriginTimestampForLogicalDataReplication.Size()
+	n += 2 + l + sovLocalOnlySessionData(uint64(l))
+	if m.BypassPCRReaderCatalogAOST {
+		n += 3
+	}
+	if m.UnsafeAllowTriggersModifyingCascades {
+		n += 3
+	}
+	if m.DisableVecUnionEagerCancellation {
+		n += 3
+	}
+	if m.RecursionDepthLimit != 0 {
+		n += 2 + sovLocalOnlySessionData(uint64(m.RecursionDepthLimit))
+	}
+	if m.DistributeGroupByRowCountThreshold != 0 {
+		n += 2 + sovLocalOnlySessionData(uint64(m.DistributeGroupByRowCountThreshold))
+	}
+	if m.DistributeSortRowCountThreshold != 0 {
+		n += 2 + sovLocalOnlySessionData(uint64(m.DistributeSortRowCountThreshold))
+	}
+	if m.DistributeScanRowCountThreshold != 0 {
+		n += 2 + sovLocalOnlySessionData(uint64(m.DistributeScanRowCountThreshold))
+	}
+	if m.AlwaysDistributeFullScans {
+		n += 3
+	}
+	if m.DistributeJoinRowCountThreshold != 0 {
+		n += 2 + sovLocalOnlySessionData(uint64(m.DistributeJoinRowCountThreshold))
+	}
+	if m.LegacyVarcharTyping {
+		n += 3
+	}
+	if m.AvoidFullTableScansInMutations {
+		n += 3
+	}
+	if m.CatalogDigestStalenessCheckEnabled {
+		n += 3
+	}
+	if m.OptimizerPreferBoundedCardinality {
+		n += 3
+	}
+	if m.OptimizerMinRowCount != 0 {
+		n += 10
+	}
+	if m.BufferedWritesEnabled {
+		n += 3
+	}
+	if m.OptimizerCheckInputMinRowCount != 0 {
+		n += 10
+	}
+	if m.OptimizerPlanLookupJoinsWithReverseScans {
+		n += 3
+	}
+	if m.RegisterLatchWaitContentionEvents {
+		n += 3
+	}
+	if m.UseCPutsOnNonUniqueIndexes {
+		n += 3
+	}
+	if m.BufferedWritesUseLockingOnNonUniqueIndexes {
+		n += 3
+	}
+	if m.OptimizerUseLockElisionMultipleFamilies {
+		n += 3
+	}
+	if m.OptimizerEnableLockElision {
+		n += 3
+	}
+	if m.OptimizerUseDeleteRangeFastPath {
+		n += 3
+	}
+	if m.AllowCreateTriggerFunctionWithArgvReferences {
+		n += 3
+	}
+	if m.UsePre_25_2VariadicBuiltins {
+		n += 3
+	}
+	if m.VectorSearchBeamSize != 0 {
+		n += 2 + sovLocalOnlySessionData(uint64(m.VectorSearchBeamSize))
+	}
+	if m.PropagateAdmissionHeaderToLeafTransactions {
+		n += 3
+	}
+	if m.OptimizerUseExistsFilterHoistRule {
+		n += 3
+	}
+	if m.InitialRetryBackoffForReadCommitted != 0 {
+		n += 2 + sovLocalOnlySessionData(uint64(m.InitialRetryBackoffForReadCommitted))
+	}
+	if m.UseProcTxnControlExtendedProtocolFix {
+		n += 3
+	}
+	if len(m.DisableOptimizerRules) > 0 {
+		for _, s := range m.DisableOptimizerRules {
+			l = len(s)
+			n += 2 + l + sovLocalOnlySessionData(uint64(l))
+		}
+	}
+	if m.UseSoftLimitForDistributeScan {
+		n += 3
+	}
+	return n
+}
+
+func (m *SequenceCacheEntry) Size() (n int) {
+	if m == nil {
+		return 0
+	}
+	var l int
+	_ = l
+	if m.CachedVersion != 0 {
+		n += 1 + sovLocalOnlySessionData(uint64(m.CachedVersion))
+	}
+	if m.CurrentValue != 0 {
+		n += 1 + sovLocalOnlySessionData(uint64(m.CurrentValue))
+	}
+	if m.Increment != 0 {
+		n += 1 + sovLocalOnlySessionData(uint64(m.Increment))
+	}
+	if m.NumValues != 0 {
+		n += 1 + sovLocalOnlySessionData(uint64(m.NumValues))
+	}
+	return n
+}
+
+func sovLocalOnlySessionData(x uint64) (n int) {
+	return int((uint32(math_bits.Len64(x|1)+6) * 37) >> 8)
+}
+func sozLocalOnlySessionData(x uint64) (n int) {
 	return sovLocalOnlySessionData(uint64((x << 1) ^ uint64((int64(x) >> 63))))
 }
 func (m *LocalOnlySessionData) Unmarshal(dAtA []byte) error {
@@ -2530,30 +3580,1046 @@ func (m *LocalOnlySessionData) Unmarshal(dAtA []byte) error {
 			if shift >= 64 {
 				return ErrIntOverflowLocalOnlySessionData
 			}
-			if iNdEx >= l {
-				return io.ErrUnexpectedEOF
+			if iNdEx >= l {
+				return io.ErrUnexpectedEOF
+			}
+			b := dAtA[iNdEx]
+			iNdEx++
+			wire |= uint64(b&0x7F) << shift
+			if b < 0x80 {
+				break
+			}
+		}
+		fieldNum := int32(wire >> 3)
+		wireType := int(wire & 0x7)
+		if wireType == 4 {
+			return fmt.Errorf("proto: LocalOnlySessionData: wiretype end group for non-group")
+		}
+		if fieldNum <= 0 {
+			return fmt.Errorf("proto: LocalOnlySessionData: illegal tag %d (wire type %d)", fieldNum, wire)
+		}
+		switch fieldNum {
+		case 1:
+			if wireType != 2 {
+				return fmt.Errorf("proto: wrong wireType = %d for field SaveTablesPrefix", wireType)
+			}
+			var stringLen uint64
+			for shift := uint(0); ; shift += 7 {
+				if shift >= 64 {
+					return ErrIntOverflowLocalOnlySessionData
+				}
+				if iNdEx >= l {
+					return io.ErrUnexpectedEOF
+				}
+				b := dAtA[iNdEx]
+				iNdEx++
+				stringLen |= uint64(b&0x7F) << shift
+				if b < 0x80 {
+					break
+				}
+			}
+			intStringLen := int(stringLen)
+			if intStringLen < 0 {
+				return ErrInvalidLengthLocalOnlySessionData
+			}
+			postIndex := iNdEx + intStringLen
+			if postIndex < 0 {
+				return ErrInvalidLengthLocalOnlySessionData
+			}
+			if postIndex > l {
+				return io.ErrUnexpectedEOF
+			}
+			m.SaveTablesPrefix = string(dAtA[iNdEx:postIndex])
+			iNdEx = postIndex
+		case 2:
+			if wireType != 0 {
+				return fmt.Errorf("proto: wrong wireType = %d for field OptimizerFKCascadesLimit", wireType)
+			}
+			m.OptimizerFKCascadesLimit = 0
+			for shift := uint(0); ; shift += 7 {
+				if shift >= 64 {
+					return ErrIntOverflowLocalOnlySessionData
+				}
+				if iNdEx >= l {
+					return io.ErrUnexpectedEOF
+				}
+				b := dAtA[iNdEx]
+				iNdEx++
+				m.OptimizerFKCascadesLimit |= int64(b&0x7F) << shift
+				if b < 0x80 {
+					break
+				}
+			}
+		case 3:
+			if wireType != 0 {
+				return fmt.Errorf("proto: wrong wireType = %d for field StmtTimeout", wireType)
+			}
+			m.StmtTimeout = 0
+			for shift := uint(0); ; shift += 7 {
+				if shift >= 64 {
+					return ErrIntOverflowLocalOnlySessionData
+				}
+				if iNdEx >= l {
+					return io.ErrUnexpectedEOF
+				}
+				b := dAtA[iNdEx]
+				iNdEx++
+				m.StmtTimeout |= time.Duration(b&0x7F) << shift
+				if b < 0x80 {
+					break
+				}
+			}
+		case 4:
+			if wireType != 0 {
+				return fmt.Errorf("proto: wrong wireType = %d for field IdleInSessionTimeout", wireType)
+			}
+			m.IdleInSessionTimeout = 0
+			for shift := uint(0); ; shift += 7 {
+				if shift >= 64 {
+					return ErrIntOverflowLocalOnlySessionData
+				}
+				if iNdEx >= l {
+					return io.ErrUnexpectedEOF
+				}
+				b := dAtA[iNdEx]
+				iNdEx++
+				m.IdleInSessionTimeout |= time.Duration(b&0x7F) << shift
+				if b < 0x80 {
+					break
+				}
+			}
+		case 5:
+			if wireType != 0 {
+				return fmt.Errorf("proto: wrong wireType = %d for field IdleInTransactionSessionTimeout", wireType)
+			}
+			m.IdleInTransactionSessionTimeout = 0
+			for shift := uint(0); ; shift += 7 {
+				if shift >= 64 {
+					return ErrIntOverflowLocalOnlySessionData
+				}
+				if iNdEx >= l {
+					return io.ErrUnexpectedEOF
+				}
+				b := dAtA[iNdEx]
+				iNdEx++
+				m.IdleInTransactionSessionTimeout |= time.Duration(b&0x7F) << shift
+				if b < 0x80 {
+					break
+				}
+			}
+		case 6:
+			if wireType != 0 {
+				return fmt.Errorf("proto: wrong wireType = %d for field NoticeDisplaySeverity", wireType)
+			}
+			m.NoticeDisplaySeverity = 0
+			for shift := uint(0); ; shift += 7 {
+				if shift >= 64 {
+					return ErrIntOverflowLocalOnlySessionData
+				}
+				if iNdEx >= l {
+					return io.ErrUnexpectedEOF
+				}
+				b := dAtA[iNdEx]
+				iNdEx++
+				m.NoticeDisplaySeverity |= uint32(b&0x7F) << shift
+				if b < 0x80 {
+					break
+				}
+			}
+		case 7:
+			if wireType != 0 {
+				return fmt.Errorf("proto: wrong wireType = %d for field ReorderJoinsLimit", wireType)
+			}
+			m.ReorderJoinsLimit = 0
+			for shift := uint(0); ; shift += 7 {
+				if shift >= 64 {
+					return ErrIntOverflowLocalOnlySessionData
+				}
+				if iNdEx >= l {
+					return io.ErrUnexpectedEOF
+				}
+				b := dAtA[iNdEx]
+				iNdEx++
+				m.ReorderJoinsLimit |= int64(b&0x7F) << shift
+				if b < 0x80 {
+					break
+				}
+			}
+		case 8:
+			if wireType != 0 {
+				return fmt.Errorf("proto: wrong wireType = %d for field DefaultTxnPriority", wireType)
+			}
+			m.DefaultTxnPriority = 0
+			for shift := uint(0); ; shift += 7 {
+				if shift >= 64 {
+					return ErrIntOverflowLocalOnlySessionData
+				}
+				if iNdEx >= l {
+					return io.ErrUnexpectedEOF
+				}
+				b := dAtA[iNdEx]
+				iNdEx++
+				m.DefaultTxnPriority |= int64(b&0x7F) << shift
+				if b < 0x80 {
+					break
+				}
+			}
+		case 9:
+			if wireType != 0 {
+				return fmt.Errorf("proto: wrong wireType = %d for field DefaultTxnReadOnly", wireType)
+			}
+			var v int
+			for shift := uint(0); ; shift += 7 {
+				if shift >= 64 {
+					return ErrIntOverflowLocalOnlySessionData
+				}
+				if iNdEx >= l {
+					return io.ErrUnexpectedEOF
+				}
+				b := dAtA[iNdEx]
+				iNdEx++
+				v |= int(b&0x7F) << shift
+				if b < 0x80 {
+					break
+				}
+			}
+			m.DefaultTxnReadOnly = bool(v != 0)
+		case 10:
+			if wireType != 0 {
+				return fmt.Errorf("proto: wrong wireType = %d for field DefaultTxnUseFollowerReads", wireType)
+			}
+			var v int
+			for shift := uint(0); ; shift += 7 {
+				if shift >= 64 {
+					return ErrIntOverflowLocalOnlySessionData
+				}
+				if iNdEx >= l {
+					return io.ErrUnexpectedEOF
+				}
+				b := dAtA[iNdEx]
+				iNdEx++
+				v |= int(b&0x7F) << shift
+				if b < 0x80 {
+					break
+				}
+			}
+			m.DefaultTxnUseFollowerReads = bool(v != 0)
+		case 11:
+			if wireType != 0 {
+				return fmt.Errorf("proto: wrong wireType = %d for field PartiallyDistributedPlansDisabled", wireType)
+			}
+			var v int
+			for shift := uint(0); ; shift += 7 {
+				if shift >= 64 {
+					return ErrIntOverflowLocalOnlySessionData
+				}
+				if iNdEx >= l {
+					return io.ErrUnexpectedEOF
+				}
+				b := dAtA[iNdEx]
+				iNdEx++
+				v |= int(b&0x7F) << shift
+				if b < 0x80 {
+					break
+				}
+			}
+			m.PartiallyDistributedPlansDisabled = bool(v != 0)
+		case 12:
+			if wireType != 0 {
+				return fmt.Errorf("proto: wrong wireType = %d for field OptimizerUseHistograms", wireType)
+			}
+			var v int
+			for shift := uint(0); ; shift += 7 {
+				if shift >= 64 {
+					return ErrIntOverflowLocalOnlySessionData
+				}
+				if iNdEx >= l {
+					return io.ErrUnexpectedEOF
+				}
+				b := dAtA[iNdEx]
+				iNdEx++
+				v |= int(b&0x7F) << shift
+				if b < 0x80 {
+					break
+				}
+			}
+			m.OptimizerUseHistograms = bool(v != 0)
+		case 13:
+			if wireType != 0 {
+				return fmt.Errorf("proto: wrong wireType = %d for field OptimizerUseMultiColStats", wireType)
+			}
+			var v int
+			for shift := uint(0); ; shift += 7 {
+				if shift >= 64 {
+					return ErrIntOverflowLocalOnlySessionData
+				}
+				if iNdEx >= l {
+					return io.ErrUnexpectedEOF
+				}
+				b := dAtA[iNdEx]
+				iNdEx++
+				v |= int(b&0x7F) << shift
+				if b < 0x80 {
+					break
+				}
+			}
+			m.OptimizerUseMultiColStats = bool(v != 0)
+		case 14:
+			if wireType != 0 {
+				return fmt.Errorf("proto: wrong wireType = %d for field LocalityOptimizedSearch", wireType)
+			}
+			var v int
+			for shift := uint(0); ; shift += 7 {
+				if shift >= 64 {
+					return ErrIntOverflowLocalOnlySessionData
+				}
+				if iNdEx >= l {
+					return io.ErrUnexpectedEOF
+				}
+				b := dAtA[iNdEx]
+				iNdEx++
+				v |= int(b&0x7F) << shift
+				if b < 0x80 {
+					break
+				}
+			}
+			m.LocalityOptimizedSearch = bool(v != 0)
+		case 15:
+			if wireType != 0 {
+				return fmt.Errorf("proto: wrong wireType = %d for field SafeUpdates", wireType)
+			}
+			var v int
+			for shift := uint(0); ; shift += 7 {
+				if shift >= 64 {
+					return ErrIntOverflowLocalOnlySessionData
+				}
+				if iNdEx >= l {
+					return io.ErrUnexpectedEOF
+				}
+				b := dAtA[iNdEx]
+				iNdEx++
+				v |= int(b&0x7F) << shift
+				if b < 0x80 {
+					break
+				}
+			}
+			m.SafeUpdates = bool(v != 0)
+		case 16:
+			if wireType != 0 {
+				return fmt.Errorf("proto: wrong wireType = %d for field PreferLookupJoinsForFKs", wireType)
+			}
+			var v int
+			for shift := uint(0); ; shift += 7 {
+				if shift >= 64 {
+					return ErrIntOverflowLocalOnlySessionData
+				}
+				if iNdEx >= l {
+					return io.ErrUnexpectedEOF
+				}
+				b := dAtA[iNdEx]
+				iNdEx++
+				v |= int(b&0x7F) << shift
+				if b < 0x80 {
+					break
+				}
+			}
+			m.PreferLookupJoinsForFKs = bool(v != 0)
+		case 17:
+			if wireType != 0 {
+				return fmt.Errorf("proto: wrong wireType = %d for field ZigzagJoinEnabled", wireType)
+			}
+			var v int
+			for shift := uint(0); ; shift += 7 {
+				if shift >= 64 {
+					return ErrIntOverflowLocalOnlySessionData
+				}
+				if iNdEx >= l {
+					return io.ErrUnexpectedEOF
+				}
+				b := dAtA[iNdEx]
+				iNdEx++
+				v |= int(b&0x7F) << shift
+				if b < 0x80 {
+					break
+				}
+			}
+			m.ZigzagJoinEnabled = bool(v != 0)
+		case 18:
+			if wireType != 0 {
+				return fmt.Errorf("proto: wrong wireType = %d for field RequireExplicitPrimaryKeys", wireType)
+			}
+			var v int
+			for shift := uint(0); ; shift += 7 {
+				if shift >= 64 {
+					return ErrIntOverflowLocalOnlySessionData
+				}
+				if iNdEx >= l {
+					return io.ErrUnexpectedEOF
+				}
+				b := dAtA[iNdEx]
+				iNdEx++
+				v |= int(b&0x7F) << shift
+				if b < 0x80 {
+					break
+				}
+			}
+			m.RequireExplicitPrimaryKeys = bool(v != 0)
+		case 19:
+			if wireType != 0 {
+				return fmt.Errorf("proto: wrong wireType = %d for field ForceSavepointRestart", wireType)
+			}
+			var v int
+			for shift := uint(0); ; shift += 7 {
+				if shift >= 64 {
+					return ErrIntOverflowLocalOnlySessionData
+				}
+				if iNdEx >= l {
+					return io.ErrUnexpectedEOF
+				}
+				b := dAtA[iNdEx]
+				iNdEx++
+				v |= int(b&0x7F) << shift
+				if b < 0x80 {
+					break
+				}
+			}
+			m.ForceSavepointRestart = bool(v != 0)
+		case 20:
+			if wireType != 0 {
+				return fmt.Errorf("proto: wrong wireType = %d for field AllowPrepareAsOptPlan", wireType)
+			}
+			var v int
+			for shift := uint(0); ; shift += 7 {
+				if shift >= 64 {
+					return ErrIntOverflowLocalOnlySessionData
+				}
+				if iNdEx >= l {
+					return io.ErrUnexpectedEOF
+				}
+				b := dAtA[iNdEx]
+				iNdEx++
+				v |= int(b&0x7F) << shift
+				if b < 0x80 {
+					break
+				}
+			}
+			m.AllowPrepareAsOptPlan = bool(v != 0)
+		case 21:
+			if wireType != 0 {
+				return fmt.Errorf("proto: wrong wireType = %d for field TempTablesEnabled", wireType)
+			}
+			var v int
+			for shift := uint(0); ; shift += 7 {
+				if shift >= 64 {
+					return ErrIntOverflowLocalOnlySessionData
+				}
+				if iNdEx >= l {
+					return io.ErrUnexpectedEOF
+				}
+				b := dAtA[iNdEx]
+				iNdEx++
+				v |= int(b&0x7F) << shift
+				if b < 0x80 {
+					break
+				}
+			}
+			m.TempTablesEnabled = bool(v != 0)
+		case 22:
+			if wireType != 0 {
+				return fmt.Errorf("proto: wrong wireType = %d for field ImplicitColumnPartitioningEnabled", wireType)
+			}
+			var v int
+			for shift := uint(0); ; shift += 7 {
+				if shift >= 64 {
+					return ErrIntOverflowLocalOnlySessionData
+				}
+				if iNdEx >= l {
+					return io.ErrUnexpectedEOF
+				}
+				b := dAtA[iNdEx]
+				iNdEx++
+				v |= int(b&0x7F) << shift
+				if b < 0x80 {
+					break
+				}
+			}
+			m.ImplicitColumnPartitioningEnabled = bool(v != 0)
+		case 24:
+			if wireType != 0 {
+				return fmt.Errorf("proto: wrong wireType = %d for field OverrideMultiRegionZoneConfigEnabled", wireType)
+			}
+			var v int
+			for shift := uint(0); ; shift += 7 {
+				if shift >= 64 {
+					return ErrIntOverflowLocalOnlySessionData
+				}
+				if iNdEx >= l {
+					return io.ErrUnexpectedEOF
+				}
+				b := dAtA[iNdEx]
+				iNdEx++
+				v |= int(b&0x7F) << shift
+				if b < 0x80 {
+					break
+				}
+			}
+			m.OverrideMultiRegionZoneConfigEnabled = bool(v != 0)
+		case 26:
+			if wireType != 0 {
+				return fmt.Errorf("proto: wrong wireType = %d for field DisallowFullTableScans", wireType)
+			}
+			var v int
+			for shift := uint(0); ; shift += 7 {
+				if shift >= 64 {
+					return ErrIntOverflowLocalOnlySessionData
+				}
+				if iNdEx >= l {
+					return io.ErrUnexpectedEOF
+				}
+				b := dAtA[iNdEx]
+				iNdEx++
+				v |= int(b&0x7F) << shift
+				if b < 0x80 {
+					break
+				}
+			}
+			m.DisallowFullTableScans = bool(v != 0)
+		case 27:
+			if wireType != 0 {
+				return fmt.Errorf("proto: wrong wireType = %d for field ImplicitSelectForUpdate", wireType)
+			}
+			var v int
+			for shift := uint(0); ; shift += 7 {
+				if shift >= 64 {
+					return ErrIntOverflowLocalOnlySessionData
+				}
+				if iNdEx >= l {
+					return io.ErrUnexpectedEOF
+				}
+				b := dAtA[iNdEx]
+				iNdEx++
+				v |= int(b&0x7F) << shift
+				if b < 0x80 {
+					break
+				}
+			}
+			m.ImplicitSelectForUpdate = bool(v != 0)
+		case 28:
+			if wireType != 0 {
+				return fmt.Errorf("proto: wrong wireType = %d for field InsertFastPath", wireType)
+			}
+			var v int
+			for shift := uint(0); ; shift += 7 {
+				if shift >= 64 {
+					return ErrIntOverflowLocalOnlySessionData
+				}
+				if iNdEx >= l {
+					return io.ErrUnexpectedEOF
+				}
+				b := dAtA[iNdEx]
+				iNdEx++
+				v |= int(b&0x7F) << shift
+				if b < 0x80 {
+					break
+				}
+			}
+			m.InsertFastPath = bool(v != 0)
+		case 29:
+			if wireType != 0 {
+				return fmt.Errorf("proto: wrong wireType = %d for field AlterColumnTypeGeneralEnabled", wireType)
+			}
+			var v int
+			for shift := uint(0); ; shift += 7 {
+				if shift >= 64 {
+					return ErrIntOverflowLocalOnlySessionData
+				}
+				if iNdEx >= l {
+					return io.ErrUnexpectedEOF
+				}
+				b := dAtA[iNdEx]
+				iNdEx++
+				v |= int(b&0x7F) << shift
+				if b < 0x80 {
+					break
+				}
+			}
+			m.AlterColumnTypeGeneralEnabled = bool(v != 0)
+		case 30:
+			if wireType != 0 {
+				return fmt.Errorf("proto: wrong wireType = %d for field SynchronousCommit", wireType)
+			}
+			var v int
+			for shift := uint(0); ; shift += 7 {
+				if shift >= 64 {
+					return ErrIntOverflowLocalOnlySessionData
+				}
+				if iNdEx >= l {
+					return io.ErrUnexpectedEOF
+				}
+				b := dAtA[iNdEx]
+				iNdEx++
+				v |= int(b&0x7F) << shift
+				if b < 0x80 {
+					break
+				}
+			}
+			m.SynchronousCommit = bool(v != 0)
+		case 31:
+			if wireType != 0 {
+				return fmt.Errorf("proto: wrong wireType = %d for field EnableSeqScan", wireType)
+			}
+			var v int
+			for shift := uint(0); ; shift += 7 {
+				if shift >= 64 {
+					return ErrIntOverflowLocalOnlySessionData
+				}
+				if iNdEx >= l {
+					return io.ErrUnexpectedEOF
+				}
+				b := dAtA[iNdEx]
+				iNdEx++
+				v |= int(b&0x7F) << shift
+				if b < 0x80 {
+					break
+				}
+			}
+			m.EnableSeqScan = bool(v != 0)
+		case 33:
+			if wireType != 0 {
+				return fmt.Errorf("proto: wrong wireType = %d for field EnableUniqueWithoutIndexConstraints", wireType)
+			}
+			var v int
+			for shift := uint(0); ; shift += 7 {
+				if shift >= 64 {
+					return ErrIntOverflowLocalOnlySessionData
+				}
+				if iNdEx >= l {
+					return io.ErrUnexpectedEOF
+				}
+				b := dAtA[iNdEx]
+				iNdEx++
+				v |= int(b&0x7F) << shift
+				if b < 0x80 {
+					break
+				}
+			}
+			m.EnableUniqueWithoutIndexConstraints = bool(v != 0)
+		case 34:
+			if wireType != 0 {
+				return fmt.Errorf("proto: wrong wireType = %d for field StubCatalogTablesEnabled", wireType)
+			}
+			var v int
+			for shift := uint(0); ; shift += 7 {
+				if shift >= 64 {
+					return ErrIntOverflowLocalOnlySessionData
+				}
+				if iNdEx >= l {
+					return io.ErrUnexpectedEOF
+				}
+				b := dAtA[iNdEx]
+				iNdEx++
+				v |= int(b&0x7F) << shift
+				if b < 0x80 {
+					break
+				}
+			}
+			m.StubCatalogTablesEnabled = bool(v != 0)
+		case 35:
+			if wireType != 2 {
+				return fmt.Errorf("proto: wrong wireType = %d for field ExperimentalComputedColumnRewrites", wireType)
+			}
+			var stringLen uint64
+			for shift := uint(0); ; shift += 7 {
+				if shift >= 64 {
+					return ErrIntOverflowLocalOnlySessionData
+				}
+				if iNdEx >= l {
+					return io.ErrUnexpectedEOF
+				}
+				b := dAtA[iNdEx]
+				iNdEx++
+				stringLen |= uint64(b&0x7F) << shift
+				if b < 0x80 {
+					break
+				}
+			}
+			intStringLen := int(stringLen)
+			if intStringLen < 0 {
+				return ErrInvalidLengthLocalOnlySessionData
+			}
+			postIndex := iNdEx + intStringLen
+			if postIndex < 0 {
+				return ErrInvalidLengthLocalOnlySessionData
+			}
+			if postIndex > l {
+				return io.ErrUnexpectedEOF
+			}
+			m.ExperimentalComputedColumnRewrites = string(dAtA[iNdEx:postIndex])
+			iNdEx = postIndex
+		case 37:
+			if wireType != 0 {
+				return fmt.Errorf("proto: wrong wireType = %d for field EnableStreamReplication", wireType)
+			}
+			var v int
+			for shift := uint(0); ; shift += 7 {
+				if shift >= 64 {
+					return ErrIntOverflowLocalOnlySessionData
+				}
+				if iNdEx >= l {
+					return io.ErrUnexpectedEOF
+				}
+				b := dAtA[iNdEx]
+				iNdEx++
+				v |= int(b&0x7F) << shift
+				if b < 0x80 {
+					break
+				}
+			}
+			m.EnableStreamReplication = bool(v != 0)
+		case 38:
+			if wireType != 0 {
+				return fmt.Errorf("proto: wrong wireType = %d for field ResultsBufferSize", wireType)
+			}
+			m.ResultsBufferSize = 0
+			for shift := uint(0); ; shift += 7 {
+				if shift >= 64 {
+					return ErrIntOverflowLocalOnlySessionData
+				}
+				if iNdEx >= l {
+					return io.ErrUnexpectedEOF
+				}
+				b := dAtA[iNdEx]
+				iNdEx++
+				m.ResultsBufferSize |= int64(b&0x7F) << shift
+				if b < 0x80 {
+					break
+				}
+			}
+		case 39:
+			if wireType != 0 {
+				return fmt.Errorf("proto: wrong wireType = %d for field PropagateInputOrdering", wireType)
+			}
+			var v int
+			for shift := uint(0); ; shift += 7 {
+				if shift >= 64 {
+					return ErrIntOverflowLocalOnlySessionData
+				}
+				if iNdEx >= l {
+					return io.ErrUnexpectedEOF
+				}
+				b := dAtA[iNdEx]
+				iNdEx++
+				v |= int(b&0x7F) << shift
+				if b < 0x80 {
+					break
+				}
+			}
+			m.PropagateInputOrdering = bool(v != 0)
+		case 40:
+			if wireType != 0 {
+				return fmt.Errorf("proto: wrong wireType = %d for field ExperimentalDistSQLPlanningMode", wireType)
+			}
+			m.ExperimentalDistSQLPlanningMode = 0
+			for shift := uint(0); ; shift += 7 {
+				if shift >= 64 {
+					return ErrIntOverflowLocalOnlySessionData
+				}
+				if iNdEx >= l {
+					return io.ErrUnexpectedEOF
+				}
+				b := dAtA[iNdEx]
+				iNdEx++
+				m.ExperimentalDistSQLPlanningMode |= ExperimentalDistSQLPlanningMode(b&0x7F) << shift
+				if b < 0x80 {
+					break
+				}
+			}
+		case 41:
+			if wireType != 0 {
+				return fmt.Errorf("proto: wrong wireType = %d for field DistSQLMode", wireType)
+			}
+			m.DistSQLMode = 0
+			for shift := uint(0); ; shift += 7 {
+				if shift >= 64 {
+					return ErrIntOverflowLocalOnlySessionData
+				}
+				if iNdEx >= l {
+					return io.ErrUnexpectedEOF
+				}
+				b := dAtA[iNdEx]
+				iNdEx++
+				m.DistSQLMode |= DistSQLExecMode(b&0x7F) << shift
+				if b < 0x80 {
+					break
+				}
+			}
+		case 42:
+			if wireType != 0 {
+				return fmt.Errorf("proto: wrong wireType = %d for field SerialNormalizationMode", wireType)
+			}
+			m.SerialNormalizationMode = 0
+			for shift := uint(0); ; shift += 7 {
+				if shift >= 64 {
+					return ErrIntOverflowLocalOnlySessionData
+				}
+				if iNdEx >= l {
+					return io.ErrUnexpectedEOF
+				}
+				b := dAtA[iNdEx]
+				iNdEx++
+				m.SerialNormalizationMode |= SerialNormalizationMode(b&0x7F) << shift
+				if b < 0x80 {
+					break
+				}
+			}
+		case 43:
+			if wireType != 0 {
+				return fmt.Errorf("proto: wrong wireType = %d for field NewSchemaChangerMode", wireType)
+			}
+			m.NewSchemaChangerMode = 0
+			for shift := uint(0); ; shift += 7 {
+				if shift >= 64 {
+					return ErrIntOverflowLocalOnlySessionData
+				}
+				if iNdEx >= l {
+					return io.ErrUnexpectedEOF
+				}
+				b := dAtA[iNdEx]
+				iNdEx++
+				m.NewSchemaChangerMode |= NewSchemaChangerMode(b&0x7F) << shift
+				if b < 0x80 {
+					break
+				}
+			}
+		case 44:
+			if wireType != 2 {
+				return fmt.Errorf("proto: wrong wireType = %d for field SequenceCache", wireType)
+			}
+			var msglen int
+			for shift := uint(0); ; shift += 7 {
+				if shift >= 64 {
+					return ErrIntOverflowLocalOnlySessionData
+				}
+				if iNdEx >= l {
+					return io.ErrUnexpectedEOF
+				}
+				b := dAtA[iNdEx]
+				iNdEx++
+				msglen |= int(b&0x7F) << shift
+				if b < 0x80 {
+					break
+				}
+			}
+			if msglen < 0 {
+				return ErrInvalidLengthLocalOnlySessionData
+			}
+			postIndex := iNdEx + msglen
+			if postIndex < 0 {
+				return ErrInvalidLengthLocalOnlySessionData
+			}
+			if postIndex > l {
+				return io.ErrUnexpectedEOF
+			}
+			if m.SequenceCache == nil {
+				m.SequenceCache = make(SequenceCache)
+			}
+			var mapkey uint32
+			var mapvalue *SequenceCacheEntry
+			for iNdEx < postIndex {
+				entryPreIndex := iNdEx
+				var wire uint64
+				for shift := uint(0); ; shift += 7 {
+					if shift >= 64 {
+						return ErrIntOverflowLocalOnlySessionData
+					}
+					if iNdEx >= l {
+						return io.ErrUnexpectedEOF
+					}
+					b := dAtA[iNdEx]
+					iNdEx++
+					wire |= uint64(b&0x7F) << shift
+					if b < 0x80 {
+						break
+					}
+				}
+				fieldNum := int32(wire >> 3)
+				if fieldNum == 1 {
+					for shift := uint(0); ; shift += 7 {
+						if shift >= 64 {
+							return ErrIntOverflowLocalOnlySessionData
+						}
+						if iNdEx >= l {
+							return io.ErrUnexpectedEOF
+						}
+						b := dAtA[iNdEx]
+						iNdEx++
+						mapkey |= uint32(b&0x7F) << shift
+						if b < 0x80 {
+							break
+						}
+					}
+				} else if fieldNum == 2 {
+					var mapmsglen int
+					for shift := uint(0); ; shift += 7 {
+						if shift >= 64 {
+							return ErrIntOverflowLocalOnlySessionData
+						}
+						if iNdEx >= l {
+							return io.ErrUnexpectedEOF
+						}
+						b := dAtA[iNdEx]
+						iNdEx++
+						mapmsglen |= int(b&0x7F) << shift
+						if b < 0x80 {
+							break
+						}
+					}
+					if mapmsglen < 0 {
+						return ErrInvalidLengthLocalOnlySessionData
+					}
+					postmsgIndex := iNdEx + mapmsglen
+					if postmsgIndex < 0 {
+						return ErrInvalidLengthLocalOnlySessionData
+					}
+					if postmsgIndex > l {
+						return io.ErrUnexpectedEOF
+					}
+					mapvalue = &SequenceCacheEntry{}
+					if err := mapvalue.Unmarshal(dAtA[iNdEx:postmsgIndex]); err != nil {
+						return err
+					}
+					iNdEx = postmsgIndex
+				} else {
+					iNdEx = entryPreIndex
+					skippy, err := skipLocalOnlySessionData(dAtA[iNdEx:])
+					if err != nil {
+						return err
+					}
+					if (skippy < 0) || (iNdEx+skippy) < 0 {
+						return ErrInvalidLengthLocalOnlySessionData
+					}
+					if (iNdEx + skippy) > postIndex {
+						return io.ErrUnexpectedEOF
+					}
+					iNdEx += skippy
+				}
+			}
+			m.SequenceCache[mapkey] = mapvalue
+			iNdEx = postIndex
+		case 45:
+			if wireType != 0 {
+				return fmt.Errorf("proto: wrong wireType = %d for field PlacementEnabled", wireType)
+			}
+			var v int
+			for shift := uint(0); ; shift += 7 {
+				if shift >= 64 {
+					return ErrIntOverflowLocalOnlySessionData
+				}
+				if iNdEx >= l {
+					return io.ErrUnexpectedEOF
+				}
+				b := dAtA[iNdEx]
+				iNdEx++
+				v |= int(b&0x7F) << shift
+				if b < 0x80 {
+					break
+				}
+			}
+			m.PlacementEnabled = bool(v != 0)
+		case 46:
+			if wireType != 2 {
+				return fmt.Errorf("proto: wrong wireType = %d for field SessionUserProto", wireType)
+			}
+			var stringLen uint64
+			for shift := uint(0); ; shift += 7 {
+				if shift >= 64 {
+					return ErrIntOverflowLocalOnlySessionData
+				}
+				if iNdEx >= l {
+					return io.ErrUnexpectedEOF
+				}
+				b := dAtA[iNdEx]
+				iNdEx++
+				stringLen |= uint64(b&0x7F) << shift
+				if b < 0x80 {
+					break
+				}
+			}
+			intStringLen := int(stringLen)
+			if intStringLen < 0 {
+				return ErrInvalidLengthLocalOnlySessionData
+			}
+			postIndex := iNdEx + intStringLen
+			if postIndex < 0 {
+				return ErrInvalidLengthLocalOnlySessionData
+			}
+			if postIndex > l {
+				return io.ErrUnexpectedEOF
+			}
+			m.SessionUserProto = github_com_cockroachdb_cockroach_pkg_security_username.SQLUsernameProto(dAtA[iNdEx:postIndex])
+			iNdEx = postIndex
+		case 47:
+			if wireType != 0 {
+				return fmt.Errorf("proto: wrong wireType = %d for field TxnRowsWrittenLog", wireType)
+			}
+			m.TxnRowsWrittenLog = 0
+			for shift := uint(0); ; shift += 7 {
+				if shift >= 64 {
+					return ErrIntOverflowLocalOnlySessionData
+				}
+				if iNdEx >= l {
+					return io.ErrUnexpectedEOF
+				}
+				b := dAtA[iNdEx]
+				iNdEx++
+				m.TxnRowsWrittenLog |= int64(b&0x7F) << shift
+				if b < 0x80 {
+					break
+				}
+			}
+		case 48:
+			if wireType != 0 {
+				return fmt.Errorf("proto: wrong wireType = %d for field TxnRowsWrittenErr", wireType)
+			}
+			m.TxnRowsWrittenErr = 0
+			for shift := uint(0); ; shift += 7 {
+				if shift >= 64 {
+					return ErrIntOverflowLocalOnlySessionData
+				}
+				if iNdEx >= l {
+					return io.ErrUnexpectedEOF
+				}
+				b := dAtA[iNdEx]
+				iNdEx++
+				m.TxnRowsWrittenErr |= int64(b&0x7F) << shift
+				if b < 0x80 {
+					break
+				}
+			}
+		case 49:
+			if wireType != 0 {
+				return fmt.Errorf("proto: wrong wireType = %d for field TxnRowsReadLog", wireType)
 			}
-			b := dAtA[iNdEx]
-			iNdEx++
-			wire |= uint64(b&0x7F) << shift
-			if b < 0x80 {
-				break
+			m.TxnRowsReadLog = 0
+			for shift := uint(0); ; shift += 7 {
+				if shift >= 64 {
+					return ErrIntOverflowLocalOnlySessionData
+				}
+				if iNdEx >= l {
+					return io.ErrUnexpectedEOF
+				}
+				b := dAtA[iNdEx]
+				iNdEx++
+				m.TxnRowsReadLog |= int64(b&0x7F) << shift
+				if b < 0x80 {
+					break
+				}
 			}
-		}
-		fieldNum := int32(wire >> 3)
-		wireType := int(wire & 0x7)
-		if wireType == 4 {
-			return fmt.Errorf("proto: LocalOnlySessionData: wiretype end group for non-group")
-		}
-		if fieldNum <= 0 {
-			return fmt.Errorf("proto: LocalOnlySessionData: illegal tag %d (wire type %d)", fieldNum, wire)
-		}
-		switch fieldNum {
-		case 1:
-			if wireType != 2 {
-				return fmt.Errorf("proto: wrong wireType = %d for field SaveTablesPrefix", wireType)
+		case 50:
+			if wireType != 0 {
+				return fmt.Errorf("proto: wrong wireType = %d for field TxnRowsReadErr", wireType)
 			}
-			var stringLen uint64
+			m.TxnRowsReadErr = 0
 			for shift := uint(0); ; shift += 7 {
 				if shift >= 64 {
 					return ErrIntOverflowLocalOnlySessionData
@@ -2563,29 +4629,67 @@ func (m *LocalOnlySessionData) Unmarshal(dAtA []byte) error {
 				}
 				b := dAtA[iNdEx]
 				iNdEx++
-				stringLen |= uint64(b&0x7F) << shift
+				m.TxnRowsReadErr |= int64(b&0x7F) << shift
 				if b < 0x80 {
 					break
 				}
 			}
-			intStringLen := int(stringLen)
-			if intStringLen < 0 {
-				return ErrInvalidLengthLocalOnlySessionData
+		case 51:
+			if wireType != 0 {
+				return fmt.Errorf("proto: wrong wireType = %d for field AutoRehomingEnabled", wireType)
 			}
-			postIndex := iNdEx + intStringLen
-			if postIndex < 0 {
-				return ErrInvalidLengthLocalOnlySessionData
+			var v int
+			for shift := uint(0); ; shift += 7 {
+				if shift >= 64 {
+					return ErrIntOverflowLocalOnlySessionData
+				}
+				if iNdEx >= l {
+					return io.ErrUnexpectedEOF
+				}
+				b := dAtA[iNdEx]
+				iNdEx++
+				v |= int(b&0x7F) << shift
+				if b < 0x80 {
+					break
+				}
 			}
-			if postIndex > l {
+			m.AutoRehomingEnabled = bool(v != 0)
+		case 52:
+			if wireType != 0 {
+				return fmt.Errorf("proto: wrong wireType = %d for field IsSuperuser", wireType)
+			}
+			var v int
+			for shift := uint(0); ; shift += 7 {
+				if shift >= 64 {
+					return ErrIntOverflowLocalOnlySessionData
+				}
+				if iNdEx >= l {
+					return io.ErrUnexpectedEOF
+				}
+				b := dAtA[iNdEx]
+				iNdEx++
+				v |= int(b&0x7F) << shift
+				if b < 0x80 {
+					break
+				}
+			}
+			m.IsSuperuser = bool(v != 0)
+		case 53:
+			if wireType != 1 {
+				return fmt.Errorf("proto: wrong wireType = %d for field LargeFullScanRows", wireType)
+			}
+			var v uint64
+			if (iNdEx + 8) > l {
 				return io.ErrUnexpectedEOF
 			}
-			m.SaveTablesPrefix = string(dAtA[iNdEx:postIndex])
-			iNdEx = postIndex
-		case 2:
+			v = uint64(encoding_binary.LittleEndian.Uint64(dAtA[iNdEx:]))
+			iNdEx += 8
+			m.LargeFullScanRows = float64(math.Float64frombits(v))
+		case 54:
 			if wireType != 0 {
-				return fmt.Errorf("proto: wrong wireType = %d for field OptimizerFKCascadesLimit", wireType)
+				return fmt.Errorf("proto: wrong wireType = %d for field InjectRetryErrorsEnabled", wireType)
 			}
-			m.OptimizerFKCascadesLimit = 0
+			var v int
 			for shift := uint(0); ; shift += 7 {
 				if shift >= 64 {
 					return ErrIntOverflowLocalOnlySessionData
@@ -2595,16 +4699,17 @@ func (m *LocalOnlySessionData) Unmarshal(dAtA []byte) error {
 				}
 				b := dAtA[iNdEx]
 				iNdEx++
-				m.OptimizerFKCascadesLimit |= int64(b&0x7F) << shift
+				v |= int(b&0x7F) << shift
 				if b < 0x80 {
 					break
 				}
 			}
-		case 3:
+			m.InjectRetryErrorsEnabled = bool(v != 0)
+		case 55:
 			if wireType != 0 {
-				return fmt.Errorf("proto: wrong wireType = %d for field StmtTimeout", wireType)
+				return fmt.Errorf("proto: wrong wireType = %d for field NullOrderedLast", wireType)
 			}
-			m.StmtTimeout = 0
+			var v int
 			for shift := uint(0); ; shift += 7 {
 				if shift >= 64 {
 					return ErrIntOverflowLocalOnlySessionData
@@ -2614,16 +4719,17 @@ func (m *LocalOnlySessionData) Unmarshal(dAtA []byte) error {
 				}
 				b := dAtA[iNdEx]
 				iNdEx++
-				m.StmtTimeout |= time.Duration(b&0x7F) << shift
+				v |= int(b&0x7F) << shift
 				if b < 0x80 {
 					break
 				}
 			}
-		case 4:
+			m.NullOrderedLast = bool(v != 0)
+		case 56:
 			if wireType != 0 {
-				return fmt.Errorf("proto: wrong wireType = %d for field IdleInSessionTimeout", wireType)
+				return fmt.Errorf("proto: wrong wireType = %d for field DisablePlanGists", wireType)
 			}
-			m.IdleInSessionTimeout = 0
+			var v int
 			for shift := uint(0); ; shift += 7 {
 				if shift >= 64 {
 					return ErrIntOverflowLocalOnlySessionData
@@ -2633,16 +4739,17 @@ func (m *LocalOnlySessionData) Unmarshal(dAtA []byte) error {
 				}
 				b := dAtA[iNdEx]
 				iNdEx++
-				m.IdleInSessionTimeout |= time.Duration(b&0x7F) << shift
+				v |= int(b&0x7F) << shift
 				if b < 0x80 {
 					break
 				}
 			}
-		case 5:
-			if wireType != 0 {
-				return fmt.Errorf("proto: wrong wireType = %d for field IdleInTransactionSessionTimeout", wireType)
+			m.DisablePlanGists = bool(v != 0)
+		case 57:
+			if wireType != 2 {
+				return fmt.Errorf("proto: wrong wireType = %d for field CustomOptions", wireType)
 			}
-			m.IdleInTransactionSessionTimeout = 0
+			var msglen int
 			for shift := uint(0); ; shift += 7 {
 				if shift >= 64 {
 					return ErrIntOverflowLocalOnlySessionData
@@ -2652,16 +4759,124 @@ func (m *LocalOnlySessionData) Unmarshal(dAtA []byte) error {
 				}
 				b := dAtA[iNdEx]
 				iNdEx++
-				m.IdleInTransactionSessionTimeout |= time.Duration(b&0x7F) << shift
+				msglen |= int(b&0x7F) << shift
 				if b < 0x80 {
 					break
 				}
 			}
-		case 6:
+			if msglen < 0 {
+				return ErrInvalidLengthLocalOnlySessionData
+			}
+			postIndex := iNdEx + msglen
+			if postIndex < 0 {
+				return ErrInvalidLengthLocalOnlySessionData
+			}
+			if postIndex > l {
+				return io.ErrUnexpectedEOF
+			}
+			if m.CustomOptions == nil {
+				m.CustomOptions = make(map[string]string)
+			}
+			var mapkey string
+			var mapvalue string
+			for iNdEx < postIndex {
+				entryPreIndex := iNdEx
+				var wire uint64
+				for shift := uint(0); ; shift += 7 {
+					if shift >= 64 {
+						return ErrIntOverflowLocalOnlySessionData
+					}
+					if iNdEx >= l {
+						return io.ErrUnexpectedEOF
+					}
+					b := dAtA[iNdEx]
+					iNdEx++
+					wire |= uint64(b&0x7F) << shift
+					if b < 0x80 {
+						break
+					}
+				}
+				fieldNum := int32(wire >> 3)
+				if fieldNum == 1 {
+					var stringLenmapkey uint64
+					for shift := uint(0); ; shift += 7 {
+						if shift >= 64 {
+							return ErrIntOverflowLocalOnlySessionData
+						}
+						if iNdEx >= l {
+							return io.ErrUnexpectedEOF
+						}
+						b := dAtA[iNdEx]
+						iNdEx++
+						stringLenmapkey |= uint64(b&0x7F) << shift
+						if b < 0x80 {
+							break
+						}
+					}
+					intStringLenmapkey := int(stringLenmapkey)
+					if intStringLenmapkey < 0 {
+						return ErrInvalidLengthLocalOnlySessionData
+					}
+					postStringIndexmapkey := iNdEx + intStringLenmapkey
+					if postStringIndexmapkey < 0 {
+						return ErrInvalidLengthLocalOnlySessionData
+					}
+					if postStringIndexmapkey > l {
+						return io.ErrUnexpectedEOF
+					}
+					mapkey = string(dAtA[iNdEx:postStringIndexmapkey])
+					iNdEx = postStringIndexmapkey
+				} else if fieldNum == 2 {
+					var stringLenmapvalue uint64
+					for shift := uint(0); ; shift += 7 {
+						if shift >= 64 {
+							return ErrIntOverflowLocalOnlySessionData
+						}
+						if iNdEx >= l {
+							return io.ErrUnexpectedEOF
+						}
+						b := dAtA[iNdEx]
+						iNdEx++
+						stringLenmapvalue |= uint64(b&0x7F) << shift
+						if b < 0x80 {
+							break
+						}
+					}
+					intStringLenmapvalue := int(stringLenmapvalue)
+					if intStringLenmapvalue < 0 {
+						return ErrInvalidLengthLocalOnlySessionData
+					}
+					postStringIndexmapvalue := iNdEx + intStringLenmapvalue
+					if postStringIndexmapvalue < 0 {
+						return ErrInvalidLengthLocalOnlySessionData
+					}
+					if postStringIndexmapvalue > l {
+						return io.ErrUnexpectedEOF
+					}
+					mapvalue = string(dAtA[iNdEx:postStringIndexmapvalue])
+					iNdEx = postStringIndexmapvalue
+				} else {
+					iNdEx = entryPreIndex
+					skippy, err := skipLocalOnlySessionData(dAtA[iNdEx:])
+					if err != nil {
+						return err
+					}
+					if (skippy < 0) || (iNdEx+skippy) < 0 {
+						return ErrInvalidLengthLocalOnlySessionData
+					}
+					if (iNdEx + skippy) > postIndex {
+						return io.ErrUnexpectedEOF
+					}
+					iNdEx += skippy
+				}
+			}
+			m.CustomOptions[mapkey] = mapvalue
+			iNdEx = postIndex
+		case 58:
 			if wireType != 0 {
-				return fmt.Errorf("proto: wrong wireType = %d for field NoticeDisplaySeverity", wireType)
+				return fmt.Errorf("proto: wrong wireType = %d for field IndexRecommendationsEnabled", wireType)
 			}
-			m.NoticeDisplaySeverity = 0
+			var v int
 			for shift := uint(0); ; shift += 7 {
 				if shift >= 64 {
 					return ErrIntOverflowLocalOnlySessionData
@@ -2671,16 +4886,17 @@ func (m *LocalOnlySessionData) Unmarshal(dAtA []byte) error {
 				}
 				b := dAtA[iNdEx]
 				iNdEx++
-				m.NoticeDisplaySeverity |= uint32(b&0x7F) << shift
+				v |= int(b&0x7F) << shift
 				if b < 0x80 {
 					break
 				}
 			}
-		case 7:
+			m.IndexRecommendationsEnabled = bool(v != 0)
+		case 59:
 			if wireType != 0 {
-				return fmt.Errorf("proto: wrong wireType = %d for field ReorderJoinsLimit", wireType)
+				return fmt.Errorf("proto: wrong wireType = %d for field AvoidBuffering", wireType)
 			}
-			m.ReorderJoinsLimit = 0
+			var v int
 			for shift := uint(0); ; shift += 7 {
 				if shift >= 64 {
 					return ErrIntOverflowLocalOnlySessionData
@@ -2690,16 +4906,17 @@ func (m *LocalOnlySessionData) Unmarshal(dAtA []byte) error {
 				}
 				b := dAtA[iNdEx]
 				iNdEx++
-				m.ReorderJoinsLimit |= int64(b&0x7F) << shift
+				v |= int(b&0x7F) << shift
 				if b < 0x80 {
 					break
 				}
 			}
-		case 8:
+			m.AvoidBuffering = bool(v != 0)
+		case 60:
 			if wireType != 0 {
-				return fmt.Errorf("proto: wrong wireType = %d for field DefaultTxnPriority", wireType)
+				return fmt.Errorf("proto: wrong wireType = %d for field CheckFunctionBodies", wireType)
 			}
-			m.DefaultTxnPriority = 0
+			var v int
 			for shift := uint(0); ; shift += 7 {
 				if shift >= 64 {
 					return ErrIntOverflowLocalOnlySessionData
@@ -2709,14 +4926,15 @@ func (m *LocalOnlySessionData) Unmarshal(dAtA []byte) error {
 				}
 				b := dAtA[iNdEx]
 				iNdEx++
-				m.DefaultTxnPriority |= int64(b&0x7F) << shift
+				v |= int(b&0x7F) << shift
 				if b < 0x80 {
 					break
 				}
 			}
-		case 9:
+			m.CheckFunctionBodies = bool(v != 0)
+		case 61:
 			if wireType != 0 {
-				return fmt.Errorf("proto: wrong wireType = %d for field DefaultTxnReadOnly", wireType)
+				return fmt.Errorf("proto: wrong wireType = %d for field CostScansWithDefaultColSize", wireType)
 			}
 			var v int
 			for shift := uint(0); ; shift += 7 {
@@ -2733,12 +4951,12 @@ func (m *LocalOnlySessionData) Unmarshal(dAtA []byte) error {
 					break
 				}
 			}
-			m.DefaultTxnReadOnly = bool(v != 0)
-		case 10:
+			m.CostScansWithDefaultColSize = bool(v != 0)
+		case 62:
 			if wireType != 0 {
-				return fmt.Errorf("proto: wrong wireType = %d for field DefaultTxnUseFollowerReads", wireType)
+				return fmt.Errorf("proto: wrong wireType = %d for field DefaultTxnQualityOfService", wireType)
 			}
-			var v int
+			m.DefaultTxnQualityOfService = 0
 			for shift := uint(0); ; shift += 7 {
 				if shift >= 64 {
 					return ErrIntOverflowLocalOnlySessionData
@@ -2748,17 +4966,16 @@ func (m *LocalOnlySessionData) Unmarshal(dAtA []byte) error {
 				}
 				b := dAtA[iNdEx]
 				iNdEx++
-				v |= int(b&0x7F) << shift
+				m.DefaultTxnQualityOfService |= QoSLevel(b&0x7F) << shift
 				if b < 0x80 {
 					break
 				}
 			}
-			m.DefaultTxnUseFollowerReads = bool(v != 0)
-		case 11:
+		case 63:
 			if wireType != 0 {
-				return fmt.Errorf("proto: wrong wireType = %d for field PartiallyDistributedPlansDisabled", wireType)
+				return fmt.Errorf("proto: wrong wireType = %d for field OptSplitScanLimit", wireType)
 			}
-			var v int
+			m.OptSplitScanLimit = 0
 			for shift := uint(0); ; shift += 7 {
 				if shift >= 64 {
 					return ErrIntOverflowLocalOnlySessionData
@@ -2768,15 +4985,14 @@ func (m *LocalOnlySessionData) Unmarshal(dAtA []byte) error {
 				}
 				b := dAtA[iNdEx]
 				iNdEx++
-				v |= int(b&0x7F) << shift
+				m.OptSplitScanLimit |= int32(b&0x7F) << shift
 				if b < 0x80 {
 					break
 				}
 			}
-			m.PartiallyDistributedPlansDisabled = bool(v != 0)
-		case 12:
+		case 64:
 			if wireType != 0 {
-				return fmt.Errorf("proto: wrong wireType = %d for field OptimizerUseHistograms", wireType)
+				return fmt.Errorf("proto: wrong wireType = %d for field EnableSuperRegions", wireType)
 			}
 			var v int
 			for shift := uint(0); ; shift += 7 {
@@ -2793,10 +5009,10 @@ func (m *LocalOnlySessionData) Unmarshal(dAtA []byte) error {
 					break
 				}
 			}
-			m.OptimizerUseHistograms = bool(v != 0)
-		case 13:
+			m.EnableSuperRegions = bool(v != 0)
+		case 65:
 			if wireType != 0 {
-				return fmt.Errorf("proto: wrong wireType = %d for field OptimizerUseMultiColStats", wireType)
+				return fmt.Errorf("proto: wrong wireType = %d for field OverrideAlterPrimaryRegionInSuperRegion", wireType)
 			}
 			var v int
 			for shift := uint(0); ; shift += 7 {
@@ -2813,10 +5029,10 @@ func (m *LocalOnlySessionData) Unmarshal(dAtA []byte) error {
 					break
 				}
 			}
-			m.OptimizerUseMultiColStats = bool(v != 0)
-		case 14:
+			m.OverrideAlterPrimaryRegionInSuperRegion = bool(v != 0)
+		case 66:
 			if wireType != 0 {
-				return fmt.Errorf("proto: wrong wireType = %d for field LocalityOptimizedSearch", wireType)
+				return fmt.Errorf("proto: wrong wireType = %d for field EnableImplicitTransactionForBatchStatements", wireType)
 			}
 			var v int
 			for shift := uint(0); ; shift += 7 {
@@ -2833,10 +5049,10 @@ func (m *LocalOnlySessionData) Unmarshal(dAtA []byte) error {
 					break
 				}
 			}
-			m.LocalityOptimizedSearch = bool(v != 0)
-		case 15:
+			m.EnableImplicitTransactionForBatchStatements = bool(v != 0)
+		case 67:
 			if wireType != 0 {
-				return fmt.Errorf("proto: wrong wireType = %d for field SafeUpdates", wireType)
+				return fmt.Errorf("proto: wrong wireType = %d for field ExpectAndIgnoreNotVisibleColumnsInCopy", wireType)
 			}
 			var v int
 			for shift := uint(0); ; shift += 7 {
@@ -2853,10 +5069,10 @@ func (m *LocalOnlySessionData) Unmarshal(dAtA []byte) error {
 					break
 				}
 			}
-			m.SafeUpdates = bool(v != 0)
-		case 16:
+			m.ExpectAndIgnoreNotVisibleColumnsInCopy = bool(v != 0)
+		case 68:
 			if wireType != 0 {
-				return fmt.Errorf("proto: wrong wireType = %d for field PreferLookupJoinsForFKs", wireType)
+				return fmt.Errorf("proto: wrong wireType = %d for field MultipleModificationsOfTable", wireType)
 			}
 			var v int
 			for shift := uint(0); ; shift += 7 {
@@ -2873,10 +5089,10 @@ func (m *LocalOnlySessionData) Unmarshal(dAtA []byte) error {
 					break
 				}
 			}
-			m.PreferLookupJoinsForFKs = bool(v != 0)
-		case 17:
+			m.MultipleModificationsOfTable = bool(v != 0)
+		case 69:
 			if wireType != 0 {
-				return fmt.Errorf("proto: wrong wireType = %d for field ZigzagJoinEnabled", wireType)
+				return fmt.Errorf("proto: wrong wireType = %d for field ShowPrimaryKeyConstraintOnNotVisibleColumns", wireType)
 			}
 			var v int
 			for shift := uint(0); ; shift += 7 {
@@ -2893,12 +5109,12 @@ func (m *LocalOnlySessionData) Unmarshal(dAtA []byte) error {
 					break
 				}
 			}
-			m.ZigzagJoinEnabled = bool(v != 0)
-		case 18:
+			m.ShowPrimaryKeyConstraintOnNotVisibleColumns = bool(v != 0)
+		case 70:
 			if wireType != 0 {
-				return fmt.Errorf("proto: wrong wireType = %d for field RequireExplicitPrimaryKeys", wireType)
+				return fmt.Errorf("proto: wrong wireType = %d for field TestingOptimizerRandomSeed", wireType)
 			}
-			var v int
+			m.TestingOptimizerRandomSeed = 0
 			for shift := uint(0); ; shift += 7 {
 				if shift >= 64 {
 					return ErrIntOverflowLocalOnlySessionData
@@ -2908,15 +5124,14 @@ func (m *LocalOnlySessionData) Unmarshal(dAtA []byte) error {
 				}
 				b := dAtA[iNdEx]
 				iNdEx++
-				v |= int(b&0x7F) << shift
+				m.TestingOptimizerRandomSeed |= int64(b&0x7F) << shift
 				if b < 0x80 {
 					break
 				}
 			}
-			m.RequireExplicitPrimaryKeys = bool(v != 0)
-		case 19:
+		case 71:
 			if wireType != 0 {
-				return fmt.Errorf("proto: wrong wireType = %d for field ForceSavepointRestart", wireType)
+				return fmt.Errorf("proto: wrong wireType = %d for field UnconstrainedNonCoveringIndexScanEnabled", wireType)
 			}
 			var v int
 			for shift := uint(0); ; shift += 7 {
@@ -2933,10 +5148,32 @@ func (m *LocalOnlySessionData) Unmarshal(dAtA []byte) error {
 					break
 				}
 			}
-			m.ForceSavepointRestart = bool(v != 0)
-		case 20:
+			m.UnconstrainedNonCoveringIndexScanEnabled = bool(v != 0)
+		case 72:
+			if wireType != 1 {
+				return fmt.Errorf("proto: wrong wireType = %d for field TestingOptimizerCostPerturbation", wireType)
+			}
+			var v uint64
+			if (iNdEx + 8) > l {
+				return io.ErrUnexpectedEOF
+			}
+			v = uint64(encoding_binary.LittleEndian.Uint64(dAtA[iNdEx:]))
+			iNdEx += 8
+			m.TestingOptimizerCostPerturbation = float64(math.Float64frombits(v))
+		case 73:
+			if wireType != 1 {
+				return fmt.Errorf("proto: wrong wireType = %d for field TestingOptimizerDisableRuleProbability", wireType)
+			}
+			var v uint64
+			if (iNdEx + 8) > l {
+				return io.ErrUnexpectedEOF
+			}
+			v = uint64(encoding_binary.LittleEndian.Uint64(dAtA[iNdEx:]))
+			iNdEx += 8
+			m.TestingOptimizerDisableRuleProbability = float64(math.Float64frombits(v))
+		case 74:
 			if wireType != 0 {
-				return fmt.Errorf("proto: wrong wireType = %d for field AllowPrepareAsOptPlan", wireType)
+				return fmt.Errorf("proto: wrong wireType = %d for field OptimizerUseNotVisibleIndexes", wireType)
 			}
 			var v int
 			for shift := uint(0); ; shift += 7 {
@@ -2953,10 +5190,10 @@ func (m *LocalOnlySessionData) Unmarshal(dAtA []byte) error {
 					break
 				}
 			}
-			m.AllowPrepareAsOptPlan = bool(v != 0)
-		case 21:
+			m.OptimizerUseNotVisibleIndexes = bool(v != 0)
+		case 75:
 			if wireType != 0 {
-				return fmt.Errorf("proto: wrong wireType = %d for field TempTablesEnabled", wireType)
+				return fmt.Errorf("proto: wrong wireType = %d for field CopyFastPathEnabled", wireType)
 			}
 			var v int
 			for shift := uint(0); ; shift += 7 {
@@ -2973,10 +5210,10 @@ func (m *LocalOnlySessionData) Unmarshal(dAtA []byte) error {
 					break
 				}
 			}
-			m.TempTablesEnabled = bool(v != 0)
-		case 22:
+			m.CopyFastPathEnabled = bool(v != 0)
+		case 76:
 			if wireType != 0 {
-				return fmt.Errorf("proto: wrong wireType = %d for field ImplicitColumnPartitioningEnabled", wireType)
+				return fmt.Errorf("proto: wrong wireType = %d for field DisableHoistProjectionInJoinLimitation", wireType)
 			}
 			var v int
 			for shift := uint(0); ; shift += 7 {
@@ -2993,10 +5230,10 @@ func (m *LocalOnlySessionData) Unmarshal(dAtA []byte) error {
 					break
 				}
 			}
-			m.ImplicitColumnPartitioningEnabled = bool(v != 0)
-		case 24:
+			m.DisableHoistProjectionInJoinLimitation = bool(v != 0)
+		case 77:
 			if wireType != 0 {
-				return fmt.Errorf("proto: wrong wireType = %d for field OverrideMultiRegionZoneConfigEnabled", wireType)
+				return fmt.Errorf("proto: wrong wireType = %d for field CopyFromAtomicEnabled", wireType)
 			}
 			var v int
 			for shift := uint(0); ; shift += 7 {
@@ -3013,10 +5250,10 @@ func (m *LocalOnlySessionData) Unmarshal(dAtA []byte) error {
 					break
 				}
 			}
-			m.OverrideMultiRegionZoneConfigEnabled = bool(v != 0)
-		case 26:
+			m.CopyFromAtomicEnabled = bool(v != 0)
+		case 78:
 			if wireType != 0 {
-				return fmt.Errorf("proto: wrong wireType = %d for field DisallowFullTableScans", wireType)
+				return fmt.Errorf("proto: wrong wireType = %d for field EnforceHomeRegion", wireType)
 			}
 			var v int
 			for shift := uint(0); ; shift += 7 {
@@ -3033,10 +5270,10 @@ func (m *LocalOnlySessionData) Unmarshal(dAtA []byte) error {
 					break
 				}
 			}
-			m.DisallowFullTableScans = bool(v != 0)
-		case 27:
+			m.EnforceHomeRegion = bool(v != 0)
+		case 79:
 			if wireType != 0 {
-				return fmt.Errorf("proto: wrong wireType = %d for field ImplicitSelectForUpdate", wireType)
+				return fmt.Errorf("proto: wrong wireType = %d for field OptimizerUseForecasts", wireType)
 			}
 			var v int
 			for shift := uint(0); ; shift += 7 {
@@ -3053,10 +5290,10 @@ func (m *LocalOnlySessionData) Unmarshal(dAtA []byte) error {
 					break
 				}
 			}
-			m.ImplicitSelectForUpdate = bool(v != 0)
-		case 28:
+			m.OptimizerUseForecasts = bool(v != 0)
+		case 80:
 			if wireType != 0 {
-				return fmt.Errorf("proto: wrong wireType = %d for field InsertFastPath", wireType)
+				return fmt.Errorf("proto: wrong wireType = %d for field VariableInequalityLookupJoinEnabled", wireType)
 			}
 			var v int
 			for shift := uint(0); ; shift += 7 {
@@ -3073,12 +5310,12 @@ func (m *LocalOnlySessionData) Unmarshal(dAtA []byte) error {
 					break
 				}
 			}
-			m.InsertFastPath = bool(v != 0)
-		case 29:
+			m.VariableInequalityLookupJoinEnabled = bool(v != 0)
+		case 81:
 			if wireType != 0 {
-				return fmt.Errorf("proto: wrong wireType = %d for field AlterColumnTypeGeneralEnabled", wireType)
+				return fmt.Errorf("proto: wrong wireType = %d for field TransactionTimeout", wireType)
 			}
-			var v int
+			m.TransactionTimeout = 0
 			for shift := uint(0); ; shift += 7 {
 				if shift >= 64 {
 					return ErrIntOverflowLocalOnlySessionData
@@ -3088,17 +5325,16 @@ func (m *LocalOnlySessionData) Unmarshal(dAtA []byte) error {
 				}
 				b := dAtA[iNdEx]
 				iNdEx++
-				v |= int(b&0x7F) << shift
+				m.TransactionTimeout |= time.Duration(b&0x7F) << shift
 				if b < 0x80 {
 					break
 				}
 			}
-			m.AlterColumnTypeGeneralEnabled = bool(v != 0)
-		case 30:
-			if wireType != 0 {
-				return fmt.Errorf("proto: wrong wireType = %d for field SynchronousCommit", wireType)
+		case 82:
+			if wireType != 2 {
+				return fmt.Errorf("proto: wrong wireType = %d for field SystemIdentityProto", wireType)
 			}
-			var v int
+			var stringLen uint64
 			for shift := uint(0); ; shift += 7 {
 				if shift >= 64 {
 					return ErrIntOverflowLocalOnlySessionData
@@ -3108,17 +5344,29 @@ func (m *LocalOnlySessionData) Unmarshal(dAtA []byte) error {
 				}
 				b := dAtA[iNdEx]
 				iNdEx++
-				v |= int(b&0x7F) << shift
+				stringLen |= uint64(b&0x7F) << shift
 				if b < 0x80 {
 					break
 				}
 			}
-			m.SynchronousCommit = bool(v != 0)
-		case 31:
+			intStringLen := int(stringLen)
+			if intStringLen < 0 {
+				return ErrInvalidLengthLocalOnlySessionData
+			}
+			postIndex := iNdEx + intStringLen
+			if postIndex < 0 {
+				return ErrInvalidLengthLocalOnlySessionData
+			}
+			if postIndex > l {
+				return io.ErrUnexpectedEOF
+			}
+			m.SystemIdentityProto = string(dAtA[iNdEx:postIndex])
+			iNdEx = postIndex
+		case 83:
 			if wireType != 0 {
-				return fmt.Errorf("proto: wrong wireType = %d for field EnableSeqScan", wireType)
+				return fmt.Errorf("proto: wrong wireType = %d for field DescriptorValidationMode", wireType)
 			}
-			var v int
+			m.DescriptorValidationMode = 0
 			for shift := uint(0); ; shift += 7 {
 				if shift >= 64 {
 					return ErrIntOverflowLocalOnlySessionData
@@ -3128,15 +5376,14 @@ func (m *LocalOnlySessionData) Unmarshal(dAtA []byte) error {
 				}
 				b := dAtA[iNdEx]
 				iNdEx++
-				v |= int(b&0x7F) << shift
+				m.DescriptorValidationMode |= DescriptorValidationMode(b&0x7F) << shift
 				if b < 0x80 {
 					break
 				}
 			}
-			m.EnableSeqScan = bool(v != 0)
-		case 33:
+		case 84:
 			if wireType != 0 {
-				return fmt.Errorf("proto: wrong wireType = %d for field EnableUniqueWithoutIndexConstraints", wireType)
+				return fmt.Errorf("proto: wrong wireType = %d for field ExperimentalHashGroupJoinEnabled", wireType)
 			}
 			var v int
 			for shift := uint(0); ; shift += 7 {
@@ -3153,10 +5400,10 @@ func (m *LocalOnlySessionData) Unmarshal(dAtA []byte) error {
 					break
 				}
 			}
-			m.EnableUniqueWithoutIndexConstraints = bool(v != 0)
-		case 34:
+			m.ExperimentalHashGroupJoinEnabled = bool(v != 0)
+		case 85:
 			if wireType != 0 {
-				return fmt.Errorf("proto: wrong wireType = %d for field StubCatalogTablesEnabled", wireType)
+				return fmt.Errorf("proto: wrong wireType = %d for field AllowOrdinalColumnReferences", wireType)
 			}
 			var v int
 			for shift := uint(0); ; shift += 7 {
@@ -3173,12 +5420,12 @@ func (m *LocalOnlySessionData) Unmarshal(dAtA []byte) error {
 					break
 				}
 			}
-			m.StubCatalogTablesEnabled = bool(v != 0)
-		case 35:
-			if wireType != 2 {
-				return fmt.Errorf("proto: wrong wireType = %d for field ExperimentalComputedColumnRewrites", wireType)
+			m.AllowOrdinalColumnReferences = bool(v != 0)
+		case 86:
+			if wireType != 0 {
+				return fmt.Errorf("proto: wrong wireType = %d for field OptimizerUseImprovedDisjunctionStats", wireType)
 			}
-			var stringLen uint64
+			var v int
 			for shift := uint(0); ; shift += 7 {
 				if shift >= 64 {
 					return ErrIntOverflowLocalOnlySessionData
@@ -3188,27 +5435,15 @@ func (m *LocalOnlySessionData) Unmarshal(dAtA []byte) error {
 				}
 				b := dAtA[iNdEx]
 				iNdEx++
-				stringLen |= uint64(b&0x7F) << shift
+				v |= int(b&0x7F) << shift
 				if b < 0x80 {
 					break
 				}
 			}
-			intStringLen := int(stringLen)
-			if intStringLen < 0 {
-				return ErrInvalidLengthLocalOnlySessionData
-			}
-			postIndex := iNdEx + intStringLen
-			if postIndex < 0 {
-				return ErrInvalidLengthLocalOnlySessionData
-			}
-			if postIndex > l {
-				return io.ErrUnexpectedEOF
-			}
-			m.ExperimentalComputedColumnRewrites = string(dAtA[iNdEx:postIndex])
-			iNdEx = postIndex
-		case 37:
+			m.OptimizerUseImprovedDisjunctionStats = bool(v != 0)
+		case 88:
 			if wireType != 0 {
-				return fmt.Errorf("proto: wrong wireType = %d for field EnableStreamReplication", wireType)
+				return fmt.Errorf("proto: wrong wireType = %d for field OptimizerUseLimitOrderingForStreamingGroupBy", wireType)
 			}
 			var v int
 			for shift := uint(0); ; shift += 7 {
@@ -3225,12 +5460,12 @@ func (m *LocalOnlySessionData) Unmarshal(dAtA []byte) error {
 					break
 				}
 			}
-			m.EnableStreamReplication = bool(v != 0)
-		case 38:
+			m.OptimizerUseLimitOrderingForStreamingGroupBy = bool(v != 0)
+		case 89:
 			if wireType != 0 {
-				return fmt.Errorf("proto: wrong wireType = %d for field ResultsBufferSize", wireType)
+				return fmt.Errorf("proto: wrong wireType = %d for field CopyFromRetriesEnabled", wireType)
 			}
-			m.ResultsBufferSize = 0
+			var v int
 			for shift := uint(0); ; shift += 7 {
 				if shift >= 64 {
 					return ErrIntOverflowLocalOnlySessionData
@@ -3240,14 +5475,15 @@ func (m *LocalOnlySessionData) Unmarshal(dAtA []byte) error {
 				}
 				b := dAtA[iNdEx]
 				iNdEx++
-				m.ResultsBufferSize |= int64(b&0x7F) << shift
+				v |= int(b&0x7F) << shift
 				if b < 0x80 {
 					break
 				}
 			}
-		case 39:
+			m.CopyFromRetriesEnabled = bool(v != 0)
+		case 90:
 			if wireType != 0 {
-				return fmt.Errorf("proto: wrong wireType = %d for field PropagateInputOrdering", wireType)
+				return fmt.Errorf("proto: wrong wireType = %d for field DeclareCursorStatementTimeoutEnabled", wireType)
 			}
 			var v int
 			for shift := uint(0); ; shift += 7 {
@@ -3264,12 +5500,12 @@ func (m *LocalOnlySessionData) Unmarshal(dAtA []byte) error {
 					break
 				}
 			}
-			m.PropagateInputOrdering = bool(v != 0)
-		case 40:
+			m.DeclareCursorStatementTimeoutEnabled = bool(v != 0)
+		case 91:
 			if wireType != 0 {
-				return fmt.Errorf("proto: wrong wireType = %d for field ExperimentalDistSQLPlanningMode", wireType)
+				return fmt.Errorf("proto: wrong wireType = %d for field OptimizerUseImprovedSplitDisjunctionForJoins", wireType)
 			}
-			m.ExperimentalDistSQLPlanningMode = 0
+			var v int
 			for shift := uint(0); ; shift += 7 {
 				if shift >= 64 {
 					return ErrIntOverflowLocalOnlySessionData
@@ -3279,16 +5515,17 @@ func (m *LocalOnlySessionData) Unmarshal(dAtA []byte) error {
 				}
 				b := dAtA[iNdEx]
 				iNdEx++
-				m.ExperimentalDistSQLPlanningMode |= ExperimentalDistSQLPlanningMode(b&0x7F) << shift
+				v |= int(b&0x7F) << shift
 				if b < 0x80 {
 					break
 				}
 			}
-		case 41:
+			m.OptimizerUseImprovedSplitDisjunctionForJoins = bool(v != 0)
+		case 92:
 			if wireType != 0 {
-				return fmt.Errorf("proto: wrong wireType = %d for field DistSQLMode", wireType)
+				return fmt.Errorf("proto: wrong wireType = %d for field InjectRetryErrorsOnCommitEnabled", wireType)
 			}
-			m.DistSQLMode = 0
+			var v int
 			for shift := uint(0); ; shift += 7 {
 				if shift >= 64 {
 					return ErrIntOverflowLocalOnlySessionData
@@ -3298,16 +5535,17 @@ func (m *LocalOnlySessionData) Unmarshal(dAtA []byte) error {
 				}
 				b := dAtA[iNdEx]
 				iNdEx++
-				m.DistSQLMode |= DistSQLExecMode(b&0x7F) << shift
+				v |= int(b&0x7F) << shift
 				if b < 0x80 {
 					break
 				}
 			}
-		case 42:
+			m.InjectRetryErrorsOnCommitEnabled = bool(v != 0)
+		case 93:
 			if wireType != 0 {
-				return fmt.Errorf("proto: wrong wireType = %d for field SerialNormalizationMode", wireType)
+				return fmt.Errorf("proto: wrong wireType = %d for field EnforceHomeRegionFollowerReadsEnabled", wireType)
 			}
-			m.SerialNormalizationMode = 0
+			var v int
 			for shift := uint(0); ; shift += 7 {
 				if shift >= 64 {
 					return ErrIntOverflowLocalOnlySessionData
@@ -3317,16 +5555,17 @@ func (m *LocalOnlySessionData) Unmarshal(dAtA []byte) error {
 				}
 				b := dAtA[iNdEx]
 				iNdEx++
-				m.SerialNormalizationMode |= SerialNormalizationMode(b&0x7F) << shift
+				v |= int(b&0x7F) << shift
 				if b < 0x80 {
 					break
 				}
 			}
-		case 43:
+			m.EnforceHomeRegionFollowerReadsEnabled = bool(v != 0)
+		case 94:
 			if wireType != 0 {
-				return fmt.Errorf("proto: wrong wireType = %d for field NewSchemaChangerMode", wireType)
+				return fmt.Errorf("proto: wrong wireType = %d for field OptimizerAlwaysUseHistograms", wireType)
 			}
-			m.NewSchemaChangerMode = 0
+			var v int
 			for shift := uint(0); ; shift += 7 {
 				if shift >= 64 {
 					return ErrIntOverflowLocalOnlySessionData
@@ -3336,16 +5575,17 @@ func (m *LocalOnlySessionData) Unmarshal(dAtA []byte) error {
 				}
 				b := dAtA[iNdEx]
 				iNdEx++
-				m.NewSchemaChangerMode |= NewSchemaChangerMode(b&0x7F) << shift
+				v |= int(b&0x7F) << shift
 				if b < 0x80 {
 					break
 				}
 			}
-		case 44:
-			if wireType != 2 {
-				return fmt.Errorf("proto: wrong wireType = %d for field SequenceCache", wireType)
+			m.OptimizerAlwaysUseHistograms = bool(v != 0)
+		case 95:
+			if wireType != 0 {
+				return fmt.Errorf("proto: wrong wireType = %d for field EnableCreateStatsUsingExtremes", wireType)
 			}
-			var msglen int
+			var v int
 			for shift := uint(0); ; shift += 7 {
 				if shift >= 64 {
 					return ErrIntOverflowLocalOnlySessionData
@@ -3355,110 +5595,15 @@ func (m *LocalOnlySessionData) Unmarshal(dAtA []byte) error {
 				}
 				b := dAtA[iNdEx]
 				iNdEx++
-				msglen |= int(b&0x7F) << shift
+				v |= int(b&0x7F) << shift
 				if b < 0x80 {
 					break
 				}
 			}
-			if msglen < 0 {
-				return ErrInvalidLengthLocalOnlySessionData
-			}
-			postIndex := iNdEx + msglen
-			if postIndex < 0 {
-				return ErrInvalidLengthLocalOnlySessionData
-			}
-			if postIndex > l {
-				return io.ErrUnexpectedEOF
-			}
-			if m.SequenceCache == nil {
-				m.SequenceCache = make(SequenceCache)
-			}
-			var mapkey uint32
-			var mapvalue *SequenceCacheEntry
-			for iNdEx < postIndex {
-				entryPreIndex := iNdEx
-				var wire uint64
-				for shift := uint(0); ; shift += 7 {
-					if shift >= 64 {
-						return ErrIntOverflowLocalOnlySessionData
-					}
-					if iNdEx >= l {
-						return io.ErrUnexpectedEOF
-					}
-					b := dAtA[iNdEx]
-					iNdEx++
-					wire |= uint64(b&0x7F) << shift
-					if b < 0x80 {
-						break
-					}
-				}
-				fieldNum := int32(wire >> 3)
-				if fieldNum == 1 {
-					for shift := uint(0); ; shift += 7 {
-						if shift >= 64 {
-							return ErrIntOverflowLocalOnlySessionData
-						}
-						if iNdEx >= l {
-							return io.ErrUnexpectedEOF
-						}
-						b := dAtA[iNdEx]
-						iNdEx++
-						mapkey |= uint32(b&0x7F) << shift
-						if b < 0x80 {
-							break
-						}
-					}
-				} else if fieldNum == 2 {
-					var mapmsglen int
-					for shift := uint(0); ; shift += 7 {
-						if shift >= 64 {
-							return ErrIntOverflowLocalOnlySessionData
-						}
-						if iNdEx >= l {
-							return io.ErrUnexpectedEOF
-						}
-						b := dAtA[iNdEx]
-						iNdEx++
-						mapmsglen |= int(b&0x7F) << shift
-						if b < 0x80 {
-							break
-						}
-					}
-					if mapmsglen < 0 {
-						return ErrInvalidLengthLocalOnlySessionData
-					}
-					postmsgIndex := iNdEx + mapmsglen
-					if postmsgIndex < 0 {
-						return ErrInvalidLengthLocalOnlySessionData
-					}
-					if postmsgIndex > l {
-						return io.ErrUnexpectedEOF
-					}
-					mapvalue = &SequenceCacheEntry{}
-					if err := mapvalue.Unmarshal(dAtA[iNdEx:postmsgIndex]); err != nil {
-						return err
-					}
-					iNdEx = postmsgIndex
-				} else {
-					iNdEx = entryPreIndex
-					skippy, err := skipLocalOnlySessionData(dAtA[iNdEx:])
-					if err != nil {
-						return err
-					}
-					if (skippy < 0) || (iNdEx+skippy) < 0 {
-						return ErrInvalidLengthLocalOnlySessionData
-					}
-					if (iNdEx + skippy) > postIndex {
-						return io.ErrUnexpectedEOF
-					}
-					iNdEx += skippy
-				}
-			}
-			m.SequenceCache[mapkey] = mapvalue
-			iNdEx = postIndex
-		case 45:
+			m.EnableCreateStatsUsingExtremes = bool(v != 0)
+		case 96:
 			if wireType != 0 {
-				return fmt.Errorf("proto: wrong wireType = %d for field PlacementEnabled", wireType)
+				return fmt.Errorf("proto: wrong wireType = %d for field AllowRoleMembershipsToChangeDuringTransaction", wireType)
 			}
 			var v int
 			for shift := uint(0); ; shift += 7 {
@@ -3475,12 +5620,12 @@ func (m *LocalOnlySessionData) Unmarshal(dAtA []byte) error {
 					break
 				}
 			}
-			m.PlacementEnabled = bool(v != 0)
-		case 46:
-			if wireType != 2 {
-				return fmt.Errorf("proto: wrong wireType = %d for field SessionUserProto", wireType)
+			m.AllowRoleMembershipsToChangeDuringTransaction = bool(v != 0)
+		case 97:
+			if wireType != 0 {
+				return fmt.Errorf("proto: wrong wireType = %d for field PreparedStatementsCacheSize", wireType)
 			}
-			var stringLen uint64
+			m.PreparedStatementsCacheSize = 0
 			for shift := uint(0); ; shift += 7 {
 				if shift >= 64 {
 					return ErrIntOverflowLocalOnlySessionData
@@ -3490,29 +5635,16 @@ func (m *LocalOnlySessionData) Unmarshal(dAtA []byte) error {
 				}
 				b := dAtA[iNdEx]
 				iNdEx++
-				stringLen |= uint64(b&0x7F) << shift
+				m.PreparedStatementsCacheSize |= int64(b&0x7F) << shift
 				if b < 0x80 {
 					break
 				}
 			}
-			intStringLen := int(stringLen)
-			if intStringLen < 0 {
-				return ErrInvalidLengthLocalOnlySessionData
-			}
-			postIndex := iNdEx + intStringLen
-			if postIndex < 0 {
-				return ErrInvalidLengthLocalOnlySessionData
-			}
-			if postIndex > l {
-				return io.ErrUnexpectedEOF
-			}
-			m.SessionUserProto = github_com_cockroachdb_cockroach_pkg_security_username.SQLUsernameProto(dAtA[iNdEx:postIndex])
-			iNdEx = postIndex
-		case 47:
+		case 100:
 			if wireType != 0 {
-				return fmt.Errorf("proto: wrong wireType = %d for field TxnRowsWrittenLog", wireType)
+				return fmt.Errorf("proto: wrong wireType = %d for field MultipleActivePortalsEnabled", wireType)
 			}
-			m.TxnRowsWrittenLog = 0
+			var v int
 			for shift := uint(0); ; shift += 7 {
 				if shift >= 64 {
 					return ErrIntOverflowLocalOnlySessionData
@@ -3522,16 +5654,17 @@ func (m *LocalOnlySessionData) Unmarshal(dAtA []byte) error {
 				}
 				b := dAtA[iNdEx]
 				iNdEx++
-				m.TxnRowsWrittenLog |= int64(b&0x7F) << shift
+				v |= int(b&0x7F) << shift
 				if b < 0x80 {
 					break
 				}
 			}
-		case 48:
+			m.MultipleActivePortalsEnabled = bool(v != 0)
+		case 101:
 			if wireType != 0 {
-				return fmt.Errorf("proto: wrong wireType = %d for field TxnRowsWrittenErr", wireType)
+				return fmt.Errorf("proto: wrong wireType = %d for field UnboundedParallelScans", wireType)
 			}
-			m.TxnRowsWrittenErr = 0
+			var v int
 			for shift := uint(0); ; shift += 7 {
 				if shift >= 64 {
 					return ErrIntOverflowLocalOnlySessionData
@@ -3541,16 +5674,17 @@ func (m *LocalOnlySessionData) Unmarshal(dAtA []byte) error {
 				}
 				b := dAtA[iNdEx]
 				iNdEx++
-				m.TxnRowsWrittenErr |= int64(b&0x7F) << shift
+				v |= int(b&0x7F) << shift
 				if b < 0x80 {
 					break
 				}
 			}
-		case 49:
+			m.UnboundedParallelScans = bool(v != 0)
+		case 102:
 			if wireType != 0 {
-				return fmt.Errorf("proto: wrong wireType = %d for field TxnRowsReadLog", wireType)
+				return fmt.Errorf("proto: wrong wireType = %d for field OptimizerHoistUncorrelatedEqualitySubqueries", wireType)
 			}
-			m.TxnRowsReadLog = 0
+			var v int
 			for shift := uint(0); ; shift += 7 {
 				if shift >= 64 {
 					return ErrIntOverflowLocalOnlySessionData
@@ -3560,16 +5694,17 @@ func (m *LocalOnlySessionData) Unmarshal(dAtA []byte) error {
 				}
 				b := dAtA[iNdEx]
 				iNdEx++
-				m.TxnRowsReadLog |= int64(b&0x7F) << shift
+				v |= int(b&0x7F) << shift
 				if b < 0x80 {
 					break
 				}
 			}
-		case 50:
+			m.OptimizerHoistUncorrelatedEqualitySubqueries = bool(v != 0)
+		case 103:
 			if wireType != 0 {
-				return fmt.Errorf("proto: wrong wireType = %d for field TxnRowsReadErr", wireType)
+				return fmt.Errorf("proto: wrong wireType = %d for field TestingOptimizerInjectPanics", wireType)
 			}
-			m.TxnRowsReadErr = 0
+			var v int
 			for shift := uint(0); ; shift += 7 {
 				if shift >= 64 {
 					return ErrIntOverflowLocalOnlySessionData
@@ -3579,14 +5714,15 @@ func (m *LocalOnlySessionData) Unmarshal(dAtA []byte) error {
 				}
 				b := dAtA[iNdEx]
 				iNdEx++
-				m.TxnRowsReadErr |= int64(b&0x7F) << shift
+				v |= int(b&0x7F) << shift
 				if b < 0x80 {
 					break
 				}
 			}
-		case 51:
+			m.TestingOptimizerInjectPanics = bool(v != 0)
+		case 104:
 			if wireType != 0 {
-				return fmt.Errorf("proto: wrong wireType = %d for field AutoRehomingEnabled", wireType)
+				return fmt.Errorf("proto: wrong wireType = %d for field OptimizerUseImprovedComputedColumnFiltersDerivation", wireType)
 			}
 			var v int
 			for shift := uint(0); ; shift += 7 {
@@ -3603,12 +5739,12 @@ func (m *LocalOnlySessionData) Unmarshal(dAtA []byte) error {
 					break
 				}
 			}
-			m.AutoRehomingEnabled = bool(v != 0)
-		case 52:
+			m.OptimizerUseImprovedComputedColumnFiltersDerivation = bool(v != 0)
+		case 105:
 			if wireType != 0 {
-				return fmt.Errorf("proto: wrong wireType = %d for field IsSuperuser", wireType)
+				return fmt.Errorf("proto: wrong wireType = %d for field DefaultTxnIsolationLevel", wireType)
 			}
-			var v int
+			m.DefaultTxnIsolationLevel = 0
 			for shift := uint(0); ; shift += 7 {
 				if shift >= 64 {
 					return ErrIntOverflowLocalOnlySessionData
@@ -3618,28 +5754,16 @@ func (m *LocalOnlySessionData) Unmarshal(dAtA []byte) error {
 				}
 				b := dAtA[iNdEx]
 				iNdEx++
-				v |= int(b&0x7F) << shift
+				m.DefaultTxnIsolationLevel |= int64(b&0x7F) << shift
 				if b < 0x80 {
 					break
 				}
 			}
-			m.IsSuperuser = bool(v != 0)
-		case 53:
-			if wireType != 1 {
-				return fmt.Errorf("proto: wrong wireType = %d for field LargeFullScanRows", wireType)
-			}
-			var v uint64
-			if (iNdEx + 8) > l {
-				return io.ErrUnexpectedEOF
-			}
-			v = uint64(encoding_binary.LittleEndian.Uint64(dAtA[iNdEx:]))
-			iNdEx += 8
-			m.LargeFullScanRows = float64(math.Float64frombits(v))
-		case 54:
+		case 106:
 			if wireType != 0 {
-				return fmt.Errorf("proto: wrong wireType = %d for field InjectRetryErrorsEnabled", wireType)
+				return fmt.Errorf("proto: wrong wireType = %d for field ReplicationMode", wireType)
 			}
-			var v int
+			m.ReplicationMode = 0
 			for shift := uint(0); ; shift += 7 {
 				if shift >= 64 {
 					return ErrIntOverflowLocalOnlySessionData
@@ -3649,15 +5773,14 @@ func (m *LocalOnlySessionData) Unmarshal(dAtA []byte) error {
 				}
 				b := dAtA[iNdEx]
 				iNdEx++
-				v |= int(b&0x7F) << shift
+				m.ReplicationMode |= ReplicationMode(b&0x7F) << shift
 				if b < 0x80 {
 					break
 				}
 			}
-			m.InjectRetryErrorsEnabled = bool(v != 0)
-		case 55:
+		case 107:
 			if wireType != 0 {
-				return fmt.Errorf("proto: wrong wireType = %d for field NullOrderedLast", wireType)
+				return fmt.Errorf("proto: wrong wireType = %d for field OptimizerUseImprovedJoinElimination", wireType)
 			}
 			var v int
 			for shift := uint(0); ; shift += 7 {
@@ -3674,10 +5797,10 @@ func (m *LocalOnlySessionData) Unmarshal(dAtA []byte) error {
 					break
 				}
 			}
-			m.NullOrderedLast = bool(v != 0)
-		case 56:
+			m.OptimizerUseImprovedJoinElimination = bool(v != 0)
+		case 108:
 			if wireType != 0 {
-				return fmt.Errorf("proto: wrong wireType = %d for field DisablePlanGists", wireType)
+				return fmt.Errorf("proto: wrong wireType = %d for field ImplicitFKLockingForSerializable", wireType)
 			}
 			var v int
 			for shift := uint(0); ; shift += 7 {
@@ -3694,12 +5817,12 @@ func (m *LocalOnlySessionData) Unmarshal(dAtA []byte) error {
 					break
 				}
 			}
-			m.DisablePlanGists = bool(v != 0)
-		case 57:
-			if wireType != 2 {
-				return fmt.Errorf("proto: wrong wireType = %d for field CustomOptions", wireType)
+			m.ImplicitFKLockingForSerializable = bool(v != 0)
+		case 109:
+			if wireType != 0 {
+				return fmt.Errorf("proto: wrong wireType = %d for field DurableLockingForSerializable", wireType)
 			}
-			var msglen int
+			var v int
 			for shift := uint(0); ; shift += 7 {
 				if shift >= 64 {
 					return ErrIntOverflowLocalOnlySessionData
@@ -3709,124 +5832,17 @@ func (m *LocalOnlySessionData) Unmarshal(dAtA []byte) error {
 				}
 				b := dAtA[iNdEx]
 				iNdEx++
-				msglen |= int(b&0x7F) << shift
+				v |= int(b&0x7F) << shift
 				if b < 0x80 {
 					break
 				}
 			}
-			if msglen < 0 {
-				return ErrInvalidLengthLocalOnlySessionData
-			}
-			postIndex := iNdEx + msglen
-			if postIndex < 0 {
-				return ErrInvalidLengthLocalOnlySessionData
-			}
-			if postIndex > l {
-				return io.ErrUnexpectedEOF
-			}
-			if m.CustomOptions == nil {
-				m.CustomOptions = make(map[string]string)
-			}
-			var mapkey string
-			var mapvalue string
-			for iNdEx < postIndex {
-				entryPreIndex := iNdEx
-				var wire uint64
-				for shift := uint(0); ; shift += 7 {
-					if shift >= 64 {
-						return ErrIntOverflowLocalOnlySessionData
-					}
-					if iNdEx >= l {
-						return io.ErrUnexpectedEOF
-					}
-					b := dAtA[iNdEx]
-					iNdEx++
-					wire |= uint64(b&0x7F) << shift
-					if b < 0x80 {
-						break
-					}
-				}
-				fieldNum := int32(wire >> 3)
-				if fieldNum == 1 {
-					var stringLenmapkey uint64
-					for shift := uint(0); ; shift += 7 {
-						if shift >= 64 {
-							return ErrIntOverflowLocalOnlySessionData
-						}
-						if iNdEx >= l {
-							return io.ErrUnexpectedEOF
-						}
-						b := dAtA[iNdEx]
-						iNdEx++
-						stringLenmapkey |= uint64(b&0x7F) << shift
-						if b < 0x80 {
-							break
-						}
-					}
-					intStringLenmapkey := int(stringLenmapkey)
-					if intStringLenmapkey < 0 {
-						return ErrInvalidLengthLocalOnlySessionData
-					}
-					postStringIndexmapkey := iNdEx + intStringLenmapkey
-					if postStringIndexmapkey < 0 {
-						return ErrInvalidLengthLocalOnlySessionData
-					}
-					if postStringIndexmapkey > l {
-						return io.ErrUnexpectedEOF
-					}
-					mapkey = string(dAtA[iNdEx:postStringIndexmapkey])
-					iNdEx = postStringIndexmapkey
-				} else if fieldNum == 2 {
-					var stringLenmapvalue uint64
-					for shift := uint(0); ; shift += 7 {
-						if shift >= 64 {
-							return ErrIntOverflowLocalOnlySessionData
-						}
-						if iNdEx >= l {
-							return io.ErrUnexpectedEOF
-						}
-						b := dAtA[iNdEx]
-						iNdEx++
-						stringLenmapvalue |= uint64(b&0x7F) << shift
-						if b < 0x80 {
-							break
-						}
-					}
-					intStringLenmapvalue := int(stringLenmapvalue)
-					if intStringLenmapvalue < 0 {
-						return ErrInvalidLengthLocalOnlySessionData
-					}
-					postStringIndexmapvalue := iNdEx + intStringLenmapvalue
-					if postStringIndexmapvalue < 0 {
-						return ErrInvalidLengthLocalOnlySessionData
-					}
-					if postStringIndexmapvalue > l {
-						return io.ErrUnexpectedEOF
-					}
-					mapvalue = string(dAtA[iNdEx:postStringIndexmapvalue])
-					iNdEx = postStringIndexmapvalue
-				} else {
-					iNdEx = entryPreIndex
-					skippy, err := skipLocalOnlySessionData(dAtA[iNdEx:])
-					if err != nil {
-						return err
-					}
-					if (skippy < 0) || (iNdEx+skippy) < 0 {
-						return ErrInvalidLengthLocalOnlySessionData
-					}
-					if (iNdEx + skippy) > postIndex {
-						return io.ErrUnexpectedEOF
-					}
-					iNdEx += skippy
-				}
-			}
-			m.CustomOptions[mapkey] = mapvalue
-			iNdEx = postIndex
-		case 58:
+			m.DurableLockingForSerializable = bool(v != 0)
+		case 110:
 			if wireType != 0 {
-				return fmt.Errorf("proto: wrong wireType = %d for field IndexRecommendationsEnabled", wireType)
+				return fmt.Errorf("proto: wrong wireType = %d for field MaxRetriesForReadCommitted", wireType)
 			}
-			var v int
+			m.MaxRetriesForReadCommitted = 0
 			for shift := uint(0); ; shift += 7 {
 				if shift >= 64 {
 					return ErrIntOverflowLocalOnlySessionData
@@ -3836,15 +5852,14 @@ func (m *LocalOnlySessionData) Unmarshal(dAtA []byte) error {
 				}
 				b := dAtA[iNdEx]
 				iNdEx++
-				v |= int(b&0x7F) << shift
+				m.MaxRetriesForReadCommitted |= int32(b&0x7F) << shift
 				if b < 0x80 {
 					break
 				}
 			}
-			m.IndexRecommendationsEnabled = bool(v != 0)
-		case 59:
+		case 111:
 			if wireType != 0 {
-				return fmt.Errorf("proto: wrong wireType = %d for field AvoidBuffering", wireType)
+				return fmt.Errorf("proto: wrong wireType = %d for field StrictDDLAtomicity", wireType)
 			}
 			var v int
 			for shift := uint(0); ; shift += 7 {
@@ -3861,10 +5876,10 @@ func (m *LocalOnlySessionData) Unmarshal(dAtA []byte) error {
 					break
 				}
 			}
-			m.AvoidBuffering = bool(v != 0)
-		case 60:
+			m.StrictDDLAtomicity = bool(v != 0)
+		case 112:
 			if wireType != 0 {
-				return fmt.Errorf("proto: wrong wireType = %d for field CheckFunctionBodies", wireType)
+				return fmt.Errorf("proto: wrong wireType = %d for field SharedLockingForSerializable", wireType)
 			}
 			var v int
 			for shift := uint(0); ; shift += 7 {
@@ -3881,12 +5896,12 @@ func (m *LocalOnlySessionData) Unmarshal(dAtA []byte) error {
 					break
 				}
 			}
-			m.CheckFunctionBodies = bool(v != 0)
-		case 61:
-			if wireType != 0 {
-				return fmt.Errorf("proto: wrong wireType = %d for field CostScansWithDefaultColSize", wireType)
+			m.SharedLockingForSerializable = bool(v != 0)
+		case 113:
+			if wireType != 2 {
+				return fmt.Errorf("proto: wrong wireType = %d for field UnsafeSettingInterlockKey", wireType)
 			}
-			var v int
+			var stringLen uint64
 			for shift := uint(0); ; shift += 7 {
 				if shift >= 64 {
 					return ErrIntOverflowLocalOnlySessionData
@@ -3896,17 +5911,29 @@ func (m *LocalOnlySessionData) Unmarshal(dAtA []byte) error {
 				}
 				b := dAtA[iNdEx]
 				iNdEx++
-				v |= int(b&0x7F) << shift
+				stringLen |= uint64(b&0x7F) << shift
 				if b < 0x80 {
 					break
 				}
 			}
-			m.CostScansWithDefaultColSize = bool(v != 0)
-		case 62:
+			intStringLen := int(stringLen)
+			if intStringLen < 0 {
+				return ErrInvalidLengthLocalOnlySessionData
+			}
+			postIndex := iNdEx + intStringLen
+			if postIndex < 0 {
+				return ErrInvalidLengthLocalOnlySessionData
+			}
+			if postIndex > l {
+				return io.ErrUnexpectedEOF
+			}
+			m.UnsafeSettingInterlockKey = string(dAtA[iNdEx:postIndex])
+			iNdEx = postIndex
+		case 114:
 			if wireType != 0 {
-				return fmt.Errorf("proto: wrong wireType = %d for field DefaultTxnQualityOfService", wireType)
+				return fmt.Errorf("proto: wrong wireType = %d for field OptimizerUseLockOpForSerializable", wireType)
 			}
-			m.DefaultTxnQualityOfService = 0
+			var v int
 			for shift := uint(0); ; shift += 7 {
 				if shift >= 64 {
 					return ErrIntOverflowLocalOnlySessionData
@@ -3916,16 +5943,17 @@ func (m *LocalOnlySessionData) Unmarshal(dAtA []byte) error {
 				}
 				b := dAtA[iNdEx]
 				iNdEx++
-				m.DefaultTxnQualityOfService |= QoSLevel(b&0x7F) << shift
+				v |= int(b&0x7F) << shift
 				if b < 0x80 {
 					break
 				}
 			}
-		case 63:
+			m.OptimizerUseLockOpForSerializable = bool(v != 0)
+		case 115:
 			if wireType != 0 {
-				return fmt.Errorf("proto: wrong wireType = %d for field OptSplitScanLimit", wireType)
+				return fmt.Errorf("proto: wrong wireType = %d for field OptimizerUseProvidedOrderingFix", wireType)
 			}
-			m.OptSplitScanLimit = 0
+			var v int
 			for shift := uint(0); ; shift += 7 {
 				if shift >= 64 {
 					return ErrIntOverflowLocalOnlySessionData
@@ -3935,14 +5963,15 @@ func (m *LocalOnlySessionData) Unmarshal(dAtA []byte) error {
 				}
 				b := dAtA[iNdEx]
 				iNdEx++
-				m.OptSplitScanLimit |= int32(b&0x7F) << shift
+				v |= int(b&0x7F) << shift
 				if b < 0x80 {
 					break
 				}
 			}
-		case 64:
+			m.OptimizerUseProvidedOrderingFix = bool(v != 0)
+		case 116:
 			if wireType != 0 {
-				return fmt.Errorf("proto: wrong wireType = %d for field EnableSuperRegions", wireType)
+				return fmt.Errorf("proto: wrong wireType = %d for field DisableChangefeedReplication", wireType)
 			}
 			var v int
 			for shift := uint(0); ; shift += 7 {
@@ -3959,12 +5988,12 @@ func (m *LocalOnlySessionData) Unmarshal(dAtA []byte) error {
 					break
 				}
 			}
-			m.EnableSuperRegions = bool(v != 0)
-		case 65:
+			m.DisableChangefeedReplication = bool(v != 0)
+		case 117:
 			if wireType != 0 {
-				return fmt.Errorf("proto: wrong wireType = %d for field OverrideAlterPrimaryRegionInSuperRegion", wireType)
+				return fmt.Errorf("proto: wrong wireType = %d for field CopyTxnQualityOfService", wireType)
 			}
-			var v int
+			m.CopyTxnQualityOfService = 0
 			for shift := uint(0); ; shift += 7 {
 				if shift >= 64 {
 					return ErrIntOverflowLocalOnlySessionData
@@ -3974,15 +6003,14 @@ func (m *LocalOnlySessionData) Unmarshal(dAtA []byte) error {
 				}
 				b := dAtA[iNdEx]
 				iNdEx++
-				v |= int(b&0x7F) << shift
+				m.CopyTxnQualityOfService |= QoSLevel(b&0x7F) << shift
 				if b < 0x80 {
 					break
 				}
 			}
-			m.OverrideAlterPrimaryRegionInSuperRegion = bool(v != 0)
-		case 66:
+		case 118:
 			if wireType != 0 {
-				return fmt.Errorf("proto: wrong wireType = %d for field EnableImplicitTransactionForBatchStatements", wireType)
+				return fmt.Errorf("proto: wrong wireType = %d for field CopyWritePipeliningEnabled", wireType)
 			}
 			var v int
 			for shift := uint(0); ; shift += 7 {
@@ -3999,10 +6027,10 @@ func (m *LocalOnlySessionData) Unmarshal(dAtA []byte) error {
 					break
 				}
 			}
-			m.EnableImplicitTransactionForBatchStatements = bool(v != 0)
-		case 67:
+			m.CopyWritePipeliningEnabled = bool(v != 0)
+		case 119:
 			if wireType != 0 {
-				return fmt.Errorf("proto: wrong wireType = %d for field ExpectAndIgnoreNotVisibleColumnsInCopy", wireType)
+				return fmt.Errorf("proto: wrong wireType = %d for field OptimizerMergeJoinsEnabled", wireType)
 			}
 			var v int
 			for shift := uint(0); ; shift += 7 {
@@ -4019,12 +6047,12 @@ func (m *LocalOnlySessionData) Unmarshal(dAtA []byte) error {
 					break
 				}
 			}
-			m.ExpectAndIgnoreNotVisibleColumnsInCopy = bool(v != 0)
-		case 68:
+			m.OptimizerMergeJoinsEnabled = bool(v != 0)
+		case 120:
 			if wireType != 0 {
-				return fmt.Errorf("proto: wrong wireType = %d for field MultipleModificationsOfTable", wireType)
+				return fmt.Errorf("proto: wrong wireType = %d for field CopyNumRetriesPerBatch", wireType)
 			}
-			var v int
+			m.CopyNumRetriesPerBatch = 0
 			for shift := uint(0); ; shift += 7 {
 				if shift >= 64 {
 					return ErrIntOverflowLocalOnlySessionData
@@ -4034,15 +6062,14 @@ func (m *LocalOnlySessionData) Unmarshal(dAtA []byte) error {
 				}
 				b := dAtA[iNdEx]
 				iNdEx++
-				v |= int(b&0x7F) << shift
+				m.CopyNumRetriesPerBatch |= int32(b&0x7F) << shift
 				if b < 0x80 {
 					break
 				}
 			}
-			m.MultipleModificationsOfTable = bool(v != 0)
-		case 69:
+		case 121:
 			if wireType != 0 {
-				return fmt.Errorf("proto: wrong wireType = %d for field ShowPrimaryKeyConstraintOnNotVisibleColumns", wireType)
+				return fmt.Errorf("proto: wrong wireType = %d for field AutoCommitBeforeDDL", wireType)
 			}
 			var v int
 			for shift := uint(0); ; shift += 7 {
@@ -4059,12 +6086,12 @@ func (m *LocalOnlySessionData) Unmarshal(dAtA []byte) error {
 					break
 				}
 			}
-			m.ShowPrimaryKeyConstraintOnNotVisibleColumns = bool(v != 0)
-		case 70:
+			m.AutoCommitBeforeDDL = bool(v != 0)
+		case 122:
 			if wireType != 0 {
-				return fmt.Errorf("proto: wrong wireType = %d for field TestingOptimizerRandomSeed", wireType)
+				return fmt.Errorf("proto: wrong wireType = %d for field CloseCursorsAtCommit", wireType)
 			}
-			m.TestingOptimizerRandomSeed = 0
+			var v int
 			for shift := uint(0); ; shift += 7 {
 				if shift >= 64 {
 					return ErrIntOverflowLocalOnlySessionData
@@ -4074,14 +6101,15 @@ func (m *LocalOnlySessionData) Unmarshal(dAtA []byte) error {
 				}
 				b := dAtA[iNdEx]
 				iNdEx++
-				m.TestingOptimizerRandomSeed |= int64(b&0x7F) << shift
+				v |= int(b&0x7F) << shift
 				if b < 0x80 {
 					break
 				}
 			}
-		case 71:
+			m.CloseCursorsAtCommit = bool(v != 0)
+		case 123:
 			if wireType != 0 {
-				return fmt.Errorf("proto: wrong wireType = %d for field UnconstrainedNonCoveringIndexScanEnabled", wireType)
+				return fmt.Errorf("proto: wrong wireType = %d for field PLpgSQLUseStrictInto", wireType)
 			}
 			var v int
 			for shift := uint(0); ; shift += 7 {
@@ -4098,32 +6126,10 @@ func (m *LocalOnlySessionData) Unmarshal(dAtA []byte) error {
 					break
 				}
 			}
-			m.UnconstrainedNonCoveringIndexScanEnabled = bool(v != 0)
-		case 72:
-			if wireType != 1 {
-				return fmt.Errorf("proto: wrong wireType = %d for field TestingOptimizerCostPerturbation", wireType)
-			}
-			var v uint64
-			if (iNdEx + 8) > l {
-				return io.ErrUnexpectedEOF
-			}
-			v = uint64(encoding_binary.LittleEndian.Uint64(dAtA[iNdEx:]))
-			iNdEx += 8
-			m.TestingOptimizerCostPerturbation = float64(math.Float64frombits(v))
-		case 73:
-			if wireType != 1 {
-				return fmt.Errorf("proto: wrong wireType = %d for field TestingOptimizerDisableRuleProbability", wireType)
-			}
-			var v uint64
-			if (iNdEx + 8) > l {
-				return io.ErrUnexpectedEOF
-			}
-			v = uint64(encoding_binary.LittleEndian.Uint64(dAtA[iNdEx:]))
-			iNdEx += 8
-			m.TestingOptimizerDisableRuleProbability = float64(math.Float64frombits(v))
-		case 74:
+			m.PLpgSQLUseStrictInto = bool(v != 0)
+		case 124:
 			if wireType != 0 {
-				return fmt.Errorf("proto: wrong wireType = %d for field OptimizerUseNotVisibleIndexes", wireType)
+				return fmt.Errorf("proto: wrong wireType = %d for field OptimizerUseVirtualComputedColumnStats", wireType)
 			}
 			var v int
 			for shift := uint(0); ; shift += 7 {
@@ -4140,10 +6146,10 @@ func (m *LocalOnlySessionData) Unmarshal(dAtA []byte) error {
 					break
 				}
 			}
-			m.OptimizerUseNotVisibleIndexes = bool(v != 0)
-		case 75:
+			m.OptimizerUseVirtualComputedColumnStats = bool(v != 0)
+		case 125:
 			if wireType != 0 {
-				return fmt.Errorf("proto: wrong wireType = %d for field CopyFastPathEnabled", wireType)
+				return fmt.Errorf("proto: wrong wireType = %d for field OptimizerUseTrigramSimilarityOptimization", wireType)
 			}
 			var v int
 			for shift := uint(0); ; shift += 7 {
@@ -4160,10 +6166,10 @@ func (m *LocalOnlySessionData) Unmarshal(dAtA []byte) error {
 					break
 				}
 			}
-			m.CopyFastPathEnabled = bool(v != 0)
-		case 76:
+			m.OptimizerUseTrigramSimilarityOptimization = bool(v != 0)
+		case 126:
 			if wireType != 0 {
-				return fmt.Errorf("proto: wrong wireType = %d for field DisableHoistProjectionInJoinLimitation", wireType)
+				return fmt.Errorf("proto: wrong wireType = %d for field OptimizerUseImprovedDistinctOnLimitHintCosting", wireType)
 			}
 			var v int
 			for shift := uint(0); ; shift += 7 {
@@ -4180,10 +6186,10 @@ func (m *LocalOnlySessionData) Unmarshal(dAtA []byte) error {
 					break
 				}
 			}
-			m.DisableHoistProjectionInJoinLimitation = bool(v != 0)
-		case 77:
+			m.OptimizerUseImprovedDistinctOnLimitHintCosting = bool(v != 0)
+		case 127:
 			if wireType != 0 {
-				return fmt.Errorf("proto: wrong wireType = %d for field CopyFromAtomicEnabled", wireType)
+				return fmt.Errorf("proto: wrong wireType = %d for field OptimizerUseImprovedTrigramSimilaritySelectivity", wireType)
 			}
 			var v int
 			for shift := uint(0); ; shift += 7 {
@@ -4200,10 +6206,10 @@ func (m *LocalOnlySessionData) Unmarshal(dAtA []byte) error {
 					break
 				}
 			}
-			m.CopyFromAtomicEnabled = bool(v != 0)
-		case 78:
+			m.OptimizerUseImprovedTrigramSimilaritySelectivity = bool(v != 0)
+		case 128:
 			if wireType != 0 {
-				return fmt.Errorf("proto: wrong wireType = %d for field EnforceHomeRegion", wireType)
+				return fmt.Errorf("proto: wrong wireType = %d for field OptimizerUseImprovedZigzagJoinCosting", wireType)
 			}
 			var v int
 			for shift := uint(0); ; shift += 7 {
@@ -4220,10 +6226,10 @@ func (m *LocalOnlySessionData) Unmarshal(dAtA []byte) error {
 					break
 				}
 			}
-			m.EnforceHomeRegion = bool(v != 0)
-		case 79:
+			m.OptimizerUseImprovedZigzagJoinCosting = bool(v != 0)
+		case 129:
 			if wireType != 0 {
-				return fmt.Errorf("proto: wrong wireType = %d for field OptimizerUseForecasts", wireType)
+				return fmt.Errorf("proto: wrong wireType = %d for field OptimizerUseImprovedMultiColumnSelectivityEstimate", wireType)
 			}
 			var v int
 			for shift := uint(0); ; shift += 7 {
@@ -4240,10 +6246,10 @@ func (m *LocalOnlySessionData) Unmarshal(dAtA []byte) error {
 					break
 				}
 			}
-			m.OptimizerUseForecasts = bool(v != 0)
-		case 80:
+			m.OptimizerUseImprovedMultiColumnSelectivityEstimate = bool(v != 0)
+		case 130:
 			if wireType != 0 {
-				return fmt.Errorf("proto: wrong wireType = %d for field VariableInequalityLookupJoinEnabled", wireType)
+				return fmt.Errorf("proto: wrong wireType = %d for field OptimizerProveImplicationWithVirtualComputedColumns", wireType)
 			}
 			var v int
 			for shift := uint(0); ; shift += 7 {
@@ -4260,12 +6266,12 @@ func (m *LocalOnlySessionData) Unmarshal(dAtA []byte) error {
 					break
 				}
 			}
-			m.VariableInequalityLookupJoinEnabled = bool(v != 0)
-		case 81:
+			m.OptimizerProveImplicationWithVirtualComputedColumns = bool(v != 0)
+		case 132:
 			if wireType != 0 {
-				return fmt.Errorf("proto: wrong wireType = %d for field TransactionTimeout", wireType)
+				return fmt.Errorf("proto: wrong wireType = %d for field OptimizerPushOffsetIntoIndexJoin", wireType)
 			}
-			m.TransactionTimeout = 0
+			var v int
 			for shift := uint(0); ; shift += 7 {
 				if shift >= 64 {
 					return ErrIntOverflowLocalOnlySessionData
@@ -4275,16 +6281,17 @@ func (m *LocalOnlySessionData) Unmarshal(dAtA []byte) error {
 				}
 				b := dAtA[iNdEx]
 				iNdEx++
-				m.TransactionTimeout |= time.Duration(b&0x7F) << shift
+				v |= int(b&0x7F) << shift
 				if b < 0x80 {
 					break
 				}
 			}
-		case 82:
-			if wireType != 2 {
-				return fmt.Errorf("proto: wrong wireType = %d for field SystemIdentityProto", wireType)
+			m.OptimizerPushOffsetIntoIndexJoin = bool(v != 0)
+		case 133:
+			if wireType != 0 {
+				return fmt.Errorf("proto: wrong wireType = %d for field PlanCacheMode", wireType)
 			}
-			var stringLen uint64
+			m.PlanCacheMode = 0
 			for shift := uint(0); ; shift += 7 {
 				if shift >= 64 {
 					return ErrIntOverflowLocalOnlySessionData
@@ -4294,29 +6301,16 @@ func (m *LocalOnlySessionData) Unmarshal(dAtA []byte) error {
 				}
 				b := dAtA[iNdEx]
 				iNdEx++
-				stringLen |= uint64(b&0x7F) << shift
+				m.PlanCacheMode |= PlanCacheMode(b&0x7F) << shift
 				if b < 0x80 {
 					break
 				}
 			}
-			intStringLen := int(stringLen)
-			if intStringLen < 0 {
-				return ErrInvalidLengthLocalOnlySessionData
-			}
-			postIndex := iNdEx + intStringLen
-			if postIndex < 0 {
-				return ErrInvalidLengthLocalOnlySessionData
-			}
-			if postIndex > l {
-				return io.ErrUnexpectedEOF
-			}
-			m.SystemIdentityProto = github_com_cockroachdb_cockroach_pkg_security_username.SQLUsernameProto(dAtA[iNdEx:postIndex])
-			iNdEx = postIndex
-		case 83:
+		case 134:
 			if wireType != 0 {
-				return fmt.Errorf("proto: wrong wireType = %d for field DescriptorValidationMode", wireType)
+				return fmt.Errorf("proto: wrong wireType = %d for field OptimizerUsePolymorphicParameterFix", wireType)
 			}
-			m.DescriptorValidationMode = 0
+			var v int
 			for shift := uint(0); ; shift += 7 {
 				if shift >= 64 {
 					return ErrIntOverflowLocalOnlySessionData
@@ -4326,16 +6320,17 @@ func (m *LocalOnlySessionData) Unmarshal(dAtA []byte) error {
 				}
 				b := dAtA[iNdEx]
 				iNdEx++
-				m.DescriptorValidationMode |= DescriptorValidationMode(b&0x7F) << shift
+				v |= int(b&0x7F) << shift
 				if b < 0x80 {
 					break
 				}
 			}
-		case 84:
+			m.OptimizerUsePolymorphicParameterFix = bool(v != 0)
+		case 135:
 			if wireType != 0 {
-				return fmt.Errorf("proto: wrong wireType = %d for field ExperimentalHashGroupJoinEnabled", wireType)
+				return fmt.Errorf("proto: wrong wireType = %d for field OriginIDForLogicalDataReplication", wireType)
 			}
-			var v int
+			m.OriginIDForLogicalDataReplication = 0
 			for shift := uint(0); ; shift += 7 {
 				if shift >= 64 {
 					return ErrIntOverflowLocalOnlySessionData
@@ -4345,15 +6340,14 @@ func (m *LocalOnlySessionData) Unmarshal(dAtA []byte) error {
 				}
 				b := dAtA[iNdEx]
 				iNdEx++
-				v |= int(b&0x7F) << shift
+				m.OriginIDForLogicalDataReplication |= uint32(b&0x7F) << shift
 				if b < 0x80 {
 					break
 				}
 			}
-			m.ExperimentalHashGroupJoinEnabled = bool(v != 0)
-		case 85:
+		case 136:
 			if wireType != 0 {
-				return fmt.Errorf("proto: wrong wireType = %d for field AllowOrdinalColumnReferences", wireType)
+				return fmt.Errorf("proto: wrong wireType = %d for field EnableCreateStatsUsingExtremesBoolEnum", wireType)
 			}
 			var v int
 			for shift := uint(0); ; shift += 7 {
@@ -4370,10 +6364,10 @@ func (m *LocalOnlySessionData) Unmarshal(dAtA []byte) error {
 					break
 				}
 			}
-			m.AllowOrdinalColumnReferences = bool(v != 0)
-		case 86:
+			m.EnableCreateStatsUsingExtremesBoolEnum = bool(v != 0)
+		case 137:
 			if wireType != 0 {
-				return fmt.Errorf("proto: wrong wireType = %d for field OptimizerUseImprovedDisjunctionStats", wireType)
+				return fmt.Errorf("proto: wrong wireType = %d for field OptimizerUseMergedPartialStatistics", wireType)
 			}
 			var v int
 			for shift := uint(0); ; shift += 7 {
@@ -4390,10 +6384,10 @@ func (m *LocalOnlySessionData) Unmarshal(dAtA []byte) error {
 					break
 				}
 			}
-			m.OptimizerUseImprovedDisjunctionStats = bool(v != 0)
-		case 88:
+			m.OptimizerUseMergedPartialStatistics = bool(v != 0)
+		case 138:
 			if wireType != 0 {
-				return fmt.Errorf("proto: wrong wireType = %d for field OptimizerUseLimitOrderingForStreamingGroupBy", wireType)
+				return fmt.Errorf("proto: wrong wireType = %d for field OptimizerUseConditionalHoistFix", wireType)
 			}
 			var v int
 			for shift := uint(0); ; shift += 7 {
@@ -4410,10 +6404,10 @@ func (m *LocalOnlySessionData) Unmarshal(dAtA []byte) error {
 					break
 				}
 			}
-			m.OptimizerUseLimitOrderingForStreamingGroupBy = bool(v != 0)
-		case 89:
+			m.OptimizerUseConditionalHoistFix = bool(v != 0)
+		case 139:
 			if wireType != 0 {
-				return fmt.Errorf("proto: wrong wireType = %d for field CopyFromRetriesEnabled", wireType)
+				return fmt.Errorf("proto: wrong wireType = %d for field OptimizerPushLimitIntoProjectFilteredScan", wireType)
 			}
 			var v int
 			for shift := uint(0); ; shift += 7 {
@@ -4430,12 +6424,12 @@ func (m *LocalOnlySessionData) Unmarshal(dAtA []byte) error {
 					break
 				}
 			}
-			m.CopyFromRetriesEnabled = bool(v != 0)
-		case 90:
-			if wireType != 0 {
-				return fmt.Errorf("proto: wrong wireType = %d for field DeclareCursorStatementTimeoutEnabled", wireType)
+			m.OptimizerPushLimitIntoProjectFilteredScan = bool(v != 0)
+		case 140:
+			if wireType != 2 {
+				return fmt.Errorf("proto: wrong wireType = %d for field OriginTimestampForLogicalDataReplication", wireType)
 			}
-			var v int
+			var msglen int
 			for shift := uint(0); ; shift += 7 {
 				if shift >= 64 {
 					return ErrIntOverflowLocalOnlySessionData
@@ -4445,15 +6439,28 @@ func (m *LocalOnlySessionData) Unmarshal(dAtA []byte) error {
 				}
 				b := dAtA[iNdEx]
 				iNdEx++
-				v |= int(b&0x7F) << shift
+				msglen |= int(b&0x7F) << shift
 				if b < 0x80 {
 					break
 				}
 			}
-			m.DeclareCursorStatementTimeoutEnabled = bool(v != 0)
-		case 91:
+			if msglen < 0 {
+				return ErrInvalidLengthLocalOnlySessionData
+			}
+			postIndex := iNdEx + msglen
+			if postIndex < 0 {
+				return ErrInvalidLengthLocalOnlySessionData
+			}
+			if postIndex > l {
+				return io.ErrUnexpectedEOF
+			}
+			if err := m.OriginTimestampForLogicalDataReplication.Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
+				return err
+			}
+			iNdEx = postIndex
+		case 141:
 			if wireType != 0 {
-				return fmt.Errorf("proto: wrong wireType = %d for field OptimizerUseImprovedSplitDisjunctionForJoins", wireType)
+				return fmt.Errorf("proto: wrong wireType = %d for field BypassPCRReaderCatalogAOST", wireType)
 			}
 			var v int
 			for shift := uint(0); ; shift += 7 {
@@ -4470,10 +6477,10 @@ func (m *LocalOnlySessionData) Unmarshal(dAtA []byte) error {
 					break
 				}
 			}
-			m.OptimizerUseImprovedSplitDisjunctionForJoins = bool(v != 0)
-		case 92:
+			m.BypassPCRReaderCatalogAOST = bool(v != 0)
+		case 142:
 			if wireType != 0 {
-				return fmt.Errorf("proto: wrong wireType = %d for field InjectRetryErrorsOnCommitEnabled", wireType)
+				return fmt.Errorf("proto: wrong wireType = %d for field UnsafeAllowTriggersModifyingCascades", wireType)
 			}
 			var v int
 			for shift := uint(0); ; shift += 7 {
@@ -4490,10 +6497,10 @@ func (m *LocalOnlySessionData) Unmarshal(dAtA []byte) error {
 					break
 				}
 			}
-			m.InjectRetryErrorsOnCommitEnabled = bool(v != 0)
-		case 93:
+			m.UnsafeAllowTriggersModifyingCascades = bool(v != 0)
+		case 143:
 			if wireType != 0 {
-				return fmt.Errorf("proto: wrong wireType = %d for field EnforceHomeRegionFollowerReadsEnabled", wireType)
+				return fmt.Errorf("proto: wrong wireType = %d for field DisableVecUnionEagerCancellation", wireType)
 			}
 			var v int
 			for shift := uint(0); ; shift += 7 {
@@ -4510,12 +6517,12 @@ func (m *LocalOnlySessionData) Unmarshal(dAtA []byte) error {
 					break
 				}
 			}
-			m.EnforceHomeRegionFollowerReadsEnabled = bool(v != 0)
-		case 94:
+			m.DisableVecUnionEagerCancellation = bool(v != 0)
+		case 144:
 			if wireType != 0 {
-				return fmt.Errorf("proto: wrong wireType = %d for field OptimizerAlwaysUseHistograms", wireType)
+				return fmt.Errorf("proto: wrong wireType = %d for field RecursionDepthLimit", wireType)
 			}
-			var v int
+			m.RecursionDepthLimit = 0
 			for shift := uint(0); ; shift += 7 {
 				if shift >= 64 {
 					return ErrIntOverflowLocalOnlySessionData
@@ -4525,17 +6532,16 @@ func (m *LocalOnlySessionData) Unmarshal(dAtA []byte) error {
 				}
 				b := dAtA[iNdEx]
 				iNdEx++
-				v |= int(b&0x7F) << shift
+				m.RecursionDepthLimit |= int64(b&0x7F) << shift
 				if b < 0x80 {
 					break
 				}
 			}
-			m.OptimizerAlwaysUseHistograms = bool(v != 0)
-		case 95:
+		case 145:
 			if wireType != 0 {
-				return fmt.Errorf("proto: wrong wireType = %d for field EnableCreateStatsUsingExtremes", wireType)
+				return fmt.Errorf("proto: wrong wireType = %d for field DistributeGroupByRowCountThreshold", wireType)
 			}
-			var v int
+			m.DistributeGroupByRowCountThreshold = 0
 			for shift := uint(0); ; shift += 7 {
 				if shift >= 64 {
 					return ErrIntOverflowLocalOnlySessionData
@@ -4545,17 +6551,16 @@ func (m *LocalOnlySessionData) Unmarshal(dAtA []byte) error {
 				}
 				b := dAtA[iNdEx]
 				iNdEx++
-				v |= int(b&0x7F) << shift
+				m.DistributeGroupByRowCountThreshold |= uint64(b&0x7F) << shift
 				if b < 0x80 {
 					break
 				}
 			}
-			m.EnableCreateStatsUsingExtremes = bool(v != 0)
-		case 96:
+		case 146:
 			if wireType != 0 {
-				return fmt.Errorf("proto: wrong wireType = %d for field AllowRoleMembershipsToChangeDuringTransaction", wireType)
+				return fmt.Errorf("proto: wrong wireType = %d for field DistributeSortRowCountThreshold", wireType)
 			}
-			var v int
+			m.DistributeSortRowCountThreshold = 0
 			for shift := uint(0); ; shift += 7 {
 				if shift >= 64 {
 					return ErrIntOverflowLocalOnlySessionData
@@ -4565,17 +6570,16 @@ func (m *LocalOnlySessionData) Unmarshal(dAtA []byte) error {
 				}
 				b := dAtA[iNdEx]
 				iNdEx++
-				v |= int(b&0x7F) << shift
+				m.DistributeSortRowCountThreshold |= uint64(b&0x7F) << shift
 				if b < 0x80 {
 					break
 				}
 			}
-			m.AllowRoleMembershipsToChangeDuringTransaction = bool(v != 0)
-		case 97:
+		case 147:
 			if wireType != 0 {
-				return fmt.Errorf("proto: wrong wireType = %d for field PreparedStatementsCacheSize", wireType)
+				return fmt.Errorf("proto: wrong wireType = %d for field DistributeScanRowCountThreshold", wireType)
 			}
-			m.PreparedStatementsCacheSize = 0
+			m.DistributeScanRowCountThreshold = 0
 			for shift := uint(0); ; shift += 7 {
 				if shift >= 64 {
 					return ErrIntOverflowLocalOnlySessionData
@@ -4585,14 +6589,14 @@ func (m *LocalOnlySessionData) Unmarshal(dAtA []byte) error {
 				}
 				b := dAtA[iNdEx]
 				iNdEx++
-				m.PreparedStatementsCacheSize |= int64(b&0x7F) << shift
+				m.DistributeScanRowCountThreshold |= uint64(b&0x7F) << shift
 				if b < 0x80 {
 					break
 				}
 			}
-		case 98:
+		case 148:
 			if wireType != 0 {
-				return fmt.Errorf("proto: wrong wireType = %d for field StreamerEnabled", wireType)
+				return fmt.Errorf("proto: wrong wireType = %d for field AlwaysDistributeFullScans", wireType)
 			}
 			var v int
 			for shift := uint(0); ; shift += 7 {
@@ -4609,12 +6613,12 @@ func (m *LocalOnlySessionData) Unmarshal(dAtA []byte) error {
 					break
 				}
 			}
-			m.StreamerEnabled = bool(v != 0)
-		case 99:
+			m.AlwaysDistributeFullScans = bool(v != 0)
+		case 149:
 			if wireType != 0 {
-				return fmt.Errorf("proto: wrong wireType = %d for field DisableDropVirtualCluster", wireType)
+				return fmt.Errorf("proto: wrong wireType = %d for field DistributeJoinRowCountThreshold", wireType)
 			}
-			var v int
+			m.DistributeJoinRowCountThreshold = 0
 			for shift := uint(0); ; shift += 7 {
 				if shift >= 64 {
 					return ErrIntOverflowLocalOnlySessionData
@@ -4624,15 +6628,14 @@ func (m *LocalOnlySessionData) Unmarshal(dAtA []byte) error {
 				}
 				b := dAtA[iNdEx]
 				iNdEx++
-				v |= int(b&0x7F) << shift
+				m.DistributeJoinRowCountThreshold |= uint64(b&0x7F) << shift
 				if b < 0x80 {
 					break
 				}
 			}
-			m.DisableDropVirtualCluster = bool(v != 0)
-		case 100:
+		case 150:
 			if wireType != 0 {
-				return fmt.Errorf("proto: wrong wireType = %d for field MultipleActivePortalsEnabled", wireType)
+				return fmt.Errorf("proto: wrong wireType = %d for field LegacyVarcharTyping", wireType)
 			}
 			var v int
 			for shift := uint(0); ; shift += 7 {
@@ -4649,10 +6652,10 @@ func (m *LocalOnlySessionData) Unmarshal(dAtA []byte) error {
 					break
 				}
 			}
-			m.MultipleActivePortalsEnabled = bool(v != 0)
-		case 101:
+			m.LegacyVarcharTyping = bool(v != 0)
+		case 151:
 			if wireType != 0 {
-				return fmt.Errorf("proto: wrong wireType = %d for field UnboundedParallelScans", wireType)
+				return fmt.Errorf("proto: wrong wireType = %d for field AvoidFullTableScansInMutations", wireType)
 			}
 			var v int
 			for shift := uint(0); ; shift += 7 {
@@ -4669,10 +6672,10 @@ func (m *LocalOnlySessionData) Unmarshal(dAtA []byte) error {
 					break
 				}
 			}
-			m.UnboundedParallelScans = bool(v != 0)
-		case 102:
+			m.AvoidFullTableScansInMutations = bool(v != 0)
+		case 153:
 			if wireType != 0 {
-				return fmt.Errorf("proto: wrong wireType = %d for field OptimizerHoistUncorrelatedEqualitySubqueries", wireType)
+				return fmt.Errorf("proto: wrong wireType = %d for field CatalogDigestStalenessCheckEnabled", wireType)
 			}
 			var v int
 			for shift := uint(0); ; shift += 7 {
@@ -4689,10 +6692,10 @@ func (m *LocalOnlySessionData) Unmarshal(dAtA []byte) error {
 					break
 				}
 			}
-			m.OptimizerHoistUncorrelatedEqualitySubqueries = bool(v != 0)
-		case 103:
+			m.CatalogDigestStalenessCheckEnabled = bool(v != 0)
+		case 154:
 			if wireType != 0 {
-				return fmt.Errorf("proto: wrong wireType = %d for field TestingOptimizerInjectPanics", wireType)
+				return fmt.Errorf("proto: wrong wireType = %d for field OptimizerPreferBoundedCardinality", wireType)
 			}
 			var v int
 			for shift := uint(0); ; shift += 7 {
@@ -4709,10 +6712,21 @@ func (m *LocalOnlySessionData) Unmarshal(dAtA []byte) error {
 					break
 				}
 			}
-			m.TestingOptimizerInjectPanics = bool(v != 0)
-		case 104:
+			m.OptimizerPreferBoundedCardinality = bool(v != 0)
+		case 155:
+			if wireType != 1 {
+				return fmt.Errorf("proto: wrong wireType = %d for field OptimizerMinRowCount", wireType)
+			}
+			var v uint64
+			if (iNdEx + 8) > l {
+				return io.ErrUnexpectedEOF
+			}
+			v = uint64(encoding_binary.LittleEndian.Uint64(dAtA[iNdEx:]))
+			iNdEx += 8
+			m.OptimizerMinRowCount = float64(math.Float64frombits(v))
+		case 156:
 			if wireType != 0 {
-				return fmt.Errorf("proto: wrong wireType = %d for field OptimizerUseImprovedComputedColumnFiltersDerivation", wireType)
+				return fmt.Errorf("proto: wrong wireType = %d for field BufferedWritesEnabled", wireType)
 			}
 			var v int
 			for shift := uint(0); ; shift += 7 {
@@ -4729,12 +6743,23 @@ func (m *LocalOnlySessionData) Unmarshal(dAtA []byte) error {
 					break
 				}
 			}
-			m.OptimizerUseImprovedComputedColumnFiltersDerivation = bool(v != 0)
-		case 105:
+			m.BufferedWritesEnabled = bool(v != 0)
+		case 157:
+			if wireType != 1 {
+				return fmt.Errorf("proto: wrong wireType = %d for field OptimizerCheckInputMinRowCount", wireType)
+			}
+			var v uint64
+			if (iNdEx + 8) > l {
+				return io.ErrUnexpectedEOF
+			}
+			v = uint64(encoding_binary.LittleEndian.Uint64(dAtA[iNdEx:]))
+			iNdEx += 8
+			m.OptimizerCheckInputMinRowCount = float64(math.Float64frombits(v))
+		case 158:
 			if wireType != 0 {
-				return fmt.Errorf("proto: wrong wireType = %d for field DefaultTxnIsolationLevel", wireType)
+				return fmt.Errorf("proto: wrong wireType = %d for field OptimizerPlanLookupJoinsWithReverseScans", wireType)
 			}
-			m.DefaultTxnIsolationLevel = 0
+			var v int
 			for shift := uint(0); ; shift += 7 {
 				if shift >= 64 {
 					return ErrIntOverflowLocalOnlySessionData
@@ -4744,16 +6769,17 @@ func (m *LocalOnlySessionData) Unmarshal(dAtA []byte) error {
 				}
 				b := dAtA[iNdEx]
 				iNdEx++
-				m.DefaultTxnIsolationLevel |= int64(b&0x7F) << shift
+				v |= int(b&0x7F) << shift
 				if b < 0x80 {
 					break
 				}
 			}
-		case 106:
+			m.OptimizerPlanLookupJoinsWithReverseScans = bool(v != 0)
+		case 159:
 			if wireType != 0 {
-				return fmt.Errorf("proto: wrong wireType = %d for field ReplicationMode", wireType)
+				return fmt.Errorf("proto: wrong wireType = %d for field RegisterLatchWaitContentionEvents", wireType)
 			}
-			m.ReplicationMode = 0
+			var v int
 			for shift := uint(0); ; shift += 7 {
 				if shift >= 64 {
 					return ErrIntOverflowLocalOnlySessionData
@@ -4763,14 +6789,15 @@ func (m *LocalOnlySessionData) Unmarshal(dAtA []byte) error {
 				}
 				b := dAtA[iNdEx]
 				iNdEx++
-				m.ReplicationMode |= ReplicationMode(b&0x7F) << shift
+				v |= int(b&0x7F) << shift
 				if b < 0x80 {
 					break
 				}
 			}
-		case 107:
+			m.RegisterLatchWaitContentionEvents = bool(v != 0)
+		case 160:
 			if wireType != 0 {
-				return fmt.Errorf("proto: wrong wireType = %d for field OptimizerUseImprovedJoinElimination", wireType)
+				return fmt.Errorf("proto: wrong wireType = %d for field UseCPutsOnNonUniqueIndexes", wireType)
 			}
 			var v int
 			for shift := uint(0); ; shift += 7 {
@@ -4787,10 +6814,10 @@ func (m *LocalOnlySessionData) Unmarshal(dAtA []byte) error {
 					break
 				}
 			}
-			m.OptimizerUseImprovedJoinElimination = bool(v != 0)
-		case 108:
+			m.UseCPutsOnNonUniqueIndexes = bool(v != 0)
+		case 161:
 			if wireType != 0 {
-				return fmt.Errorf("proto: wrong wireType = %d for field ImplicitFKLockingForSerializable", wireType)
+				return fmt.Errorf("proto: wrong wireType = %d for field BufferedWritesUseLockingOnNonUniqueIndexes", wireType)
 			}
 			var v int
 			for shift := uint(0); ; shift += 7 {
@@ -4807,10 +6834,10 @@ func (m *LocalOnlySessionData) Unmarshal(dAtA []byte) error {
 					break
 				}
 			}
-			m.ImplicitFKLockingForSerializable = bool(v != 0)
-		case 109:
+			m.BufferedWritesUseLockingOnNonUniqueIndexes = bool(v != 0)
+		case 162:
 			if wireType != 0 {
-				return fmt.Errorf("proto: wrong wireType = %d for field DurableLockingForSerializable", wireType)
+				return fmt.Errorf("proto: wrong wireType = %d for field OptimizerUseLockElisionMultipleFamilies", wireType)
 			}
 			var v int
 			for shift := uint(0); ; shift += 7 {
@@ -4827,12 +6854,12 @@ func (m *LocalOnlySessionData) Unmarshal(dAtA []byte) error {
 					break
 				}
 			}
-			m.DurableLockingForSerializable = bool(v != 0)
-		case 110:
+			m.OptimizerUseLockElisionMultipleFamilies = bool(v != 0)
+		case 163:
 			if wireType != 0 {
-				return fmt.Errorf("proto: wrong wireType = %d for field MaxRetriesForReadCommitted", wireType)
+				return fmt.Errorf("proto: wrong wireType = %d for field OptimizerEnableLockElision", wireType)
 			}
-			m.MaxRetriesForReadCommitted = 0
+			var v int
 			for shift := uint(0); ; shift += 7 {
 				if shift >= 64 {
 					return ErrIntOverflowLocalOnlySessionData
@@ -4842,14 +6869,15 @@ func (m *LocalOnlySessionData) Unmarshal(dAtA []byte) error {
 				}
 				b := dAtA[iNdEx]
 				iNdEx++
-				m.MaxRetriesForReadCommitted |= int32(b&0x7F) << shift
+				v |= int(b&0x7F) << shift
 				if b < 0x80 {
 					break
 				}
 			}
-		case 111:
+			m.OptimizerEnableLockElision = bool(v != 0)
+		case 164:
 			if wireType != 0 {
-				return fmt.Errorf("proto: wrong wireType = %d for field StrictDDLAtomicity", wireType)
+				return fmt.Errorf("proto: wrong wireType = %d for field OptimizerUseDeleteRangeFastPath", wireType)
 			}
 			var v int
 			for shift := uint(0); ; shift += 7 {
@@ -4866,10 +6894,10 @@ func (m *LocalOnlySessionData) Unmarshal(dAtA []byte) error {
 					break
 				}
 			}
-			m.StrictDDLAtomicity = bool(v != 0)
-		case 112:
+			m.OptimizerUseDeleteRangeFastPath = bool(v != 0)
+		case 165:
 			if wireType != 0 {
-				return fmt.Errorf("proto: wrong wireType = %d for field SharedLockingForSerializable", wireType)
+				return fmt.Errorf("proto: wrong wireType = %d for field AllowCreateTriggerFunctionWithArgvReferences", wireType)
 			}
 			var v int
 			for shift := uint(0); ; shift += 7 {
@@ -4886,12 +6914,12 @@ func (m *LocalOnlySessionData) Unmarshal(dAtA []byte) error {
 					break
 				}
 			}
-			m.SharedLockingForSerializable = bool(v != 0)
-		case 113:
-			if wireType != 2 {
-				return fmt.Errorf("proto: wrong wireType = %d for field UnsafeSettingInterlockKey", wireType)
+			m.AllowCreateTriggerFunctionWithArgvReferences = bool(v != 0)
+		case 167:
+			if wireType != 0 {
+				return fmt.Errorf("proto: wrong wireType = %d for field UsePre_25_2VariadicBuiltins", wireType)
 			}
-			var stringLen uint64
+			var v int
 			for shift := uint(0); ; shift += 7 {
 				if shift >= 64 {
 					return ErrIntOverflowLocalOnlySessionData
@@ -4901,29 +6929,17 @@ func (m *LocalOnlySessionData) Unmarshal(dAtA []byte) error {
 				}
 				b := dAtA[iNdEx]
 				iNdEx++
-				stringLen |= uint64(b&0x7F) << shift
+				v |= int(b&0x7F) << shift
 				if b < 0x80 {
 					break
 				}
 			}
-			intStringLen := int(stringLen)
-			if intStringLen < 0 {
-				return ErrInvalidLengthLocalOnlySessionData
-			}
-			postIndex := iNdEx + intStringLen
-			if postIndex < 0 {
-				return ErrInvalidLengthLocalOnlySessionData
-			}
-			if postIndex > l {
-				return io.ErrUnexpectedEOF
-			}
-			m.UnsafeSettingInterlockKey = string(dAtA[iNdEx:postIndex])
-			iNdEx = postIndex
-		case 114:
+			m.UsePre_25_2VariadicBuiltins = bool(v != 0)
+		case 168:
 			if wireType != 0 {
-				return fmt.Errorf("proto: wrong wireType = %d for field OptimizerUseLockOpForSerializable", wireType)
+				return fmt.Errorf("proto: wrong wireType = %d for field VectorSearchBeamSize", wireType)
 			}
-			var v int
+			m.VectorSearchBeamSize = 0
 			for shift := uint(0); ; shift += 7 {
 				if shift >= 64 {
 					return ErrIntOverflowLocalOnlySessionData
@@ -4933,15 +6949,14 @@ func (m *LocalOnlySessionData) Unmarshal(dAtA []byte) error {
 				}
 				b := dAtA[iNdEx]
 				iNdEx++
-				v |= int(b&0x7F) << shift
+				m.VectorSearchBeamSize |= int32(b&0x7F) << shift
 				if b < 0x80 {
 					break
 				}
 			}
-			m.OptimizerUseLockOpForSerializable = bool(v != 0)
-		case 115:
+		case 169:
 			if wireType != 0 {
-				return fmt.Errorf("proto: wrong wireType = %d for field OptimizerUseProvidedOrderingFix", wireType)
+				return fmt.Errorf("proto: wrong wireType = %d for field PropagateAdmissionHeaderToLeafTransactions", wireType)
 			}
 			var v int
 			for shift := uint(0); ; shift += 7 {
@@ -4958,10 +6973,10 @@ func (m *LocalOnlySessionData) Unmarshal(dAtA []byte) error {
 					break
 				}
 			}
-			m.OptimizerUseProvidedOrderingFix = bool(v != 0)
-		case 116:
+			m.PropagateAdmissionHeaderToLeafTransactions = bool(v != 0)
+		case 170:
 			if wireType != 0 {
-				return fmt.Errorf("proto: wrong wireType = %d for field DisableChangefeedReplication", wireType)
+				return fmt.Errorf("proto: wrong wireType = %d for field OptimizerUseExistsFilterHoistRule", wireType)
 			}
 			var v int
 			for shift := uint(0); ; shift += 7 {
@@ -4978,12 +6993,12 @@ func (m *LocalOnlySessionData) Unmarshal(dAtA []byte) error {
 					break
 				}
 			}
-			m.DisableChangefeedReplication = bool(v != 0)
-		case 117:
+			m.OptimizerUseExistsFilterHoistRule = bool(v != 0)
+		case 171:
 			if wireType != 0 {
-				return fmt.Errorf("proto: wrong wireType = %d for field CopyTxnQualityOfService", wireType)
+				return fmt.Errorf("proto: wrong wireType = %d for field InitialRetryBackoffForReadCommitted", wireType)
 			}
-			m.CopyTxnQualityOfService = 0
+			m.InitialRetryBackoffForReadCommitted = 0
 			for shift := uint(0); ; shift += 7 {
 				if shift >= 64 {
 					return ErrIntOverflowLocalOnlySessionData
@@ -4993,14 +7008,14 @@ func (m *LocalOnlySessionData) Unmarshal(dAtA []byte) error {
 				}
 				b := dAtA[iNdEx]
 				iNdEx++
-				m.CopyTxnQualityOfService |= QoSLevel(b&0x7F) << shift
+				m.InitialRetryBackoffForReadCommitted |= time.Duration(b&0x7F) << shift
 				if b < 0x80 {
 					break
 				}
 			}
-		case 118:
+		case 175:
 			if wireType != 0 {
-				return fmt.Errorf("proto: wrong wireType = %d for field CopyWritePipeliningEnabled", wireType)
+				return fmt.Errorf("proto: wrong wireType = %d for field UseProcTxnControlExtendedProtocolFix", wireType)
 			}
 			var v int
 			for shift := uint(0); ; shift += 7 {
@@ -5017,12 +7032,44 @@ func (m *LocalOnlySessionData) Unmarshal(dAtA []byte) error {
 					break
 				}
 			}
-			m.CopyWritePipeliningEnabled = bool(v != 0)
-		case 120:
+			m.UseProcTxnControlExtendedProtocolFix = bool(v != 0)
+		case 184:
+			if wireType != 2 {
+				return fmt.Errorf("proto: wrong wireType = %d for field DisableOptimizerRules", wireType)
+			}
+			var stringLen uint64
+			for shift := uint(0); ; shift += 7 {
+				if shift >= 64 {
+					return ErrIntOverflowLocalOnlySessionData
+				}
+				if iNdEx >= l {
+					return io.ErrUnexpectedEOF
+				}
+				b := dAtA[iNdEx]
+				iNdEx++
+				stringLen |= uint64(b&0x7F) << shift
+				if b < 0x80 {
+					break
+				}
+			}
+			intStringLen := int(stringLen)
+			if intStringLen < 0 {
+				return ErrInvalidLengthLocalOnlySessionData
+			}
+			postIndex := iNdEx + intStringLen
+			if postIndex < 0 {
+				return ErrInvalidLengthLocalOnlySessionData
+			}
+			if postIndex > l {
+				return io.ErrUnexpectedEOF
+			}
+			m.DisableOptimizerRules = append(m.DisableOptimizerRules, string(dAtA[iNdEx:postIndex]))
+			iNdEx = postIndex
+		case 185:
 			if wireType != 0 {
-				return fmt.Errorf("proto: wrong wireType = %d for field CopyNumRetriesPerBatch", wireType)
+				return fmt.Errorf("proto: wrong wireType = %d for field UseSoftLimitForDistributeScan", wireType)
 			}
-			m.CopyNumRetriesPerBatch = 0
+			var v int
 			for shift := uint(0); ; shift += 7 {
 				if shift >= 64 {
 					return ErrIntOverflowLocalOnlySessionData
@@ -5032,11 +7079,12 @@ func (m *LocalOnlySessionData) Unmarshal(dAtA []byte) error {
 				}
 				b := dAtA[iNdEx]
 				iNdEx++
-				m.CopyNumRetriesPerBatch |= int32(b&0x7F) << shift
+				v |= int(b&0x7F) << shift
 				if b < 0x80 {
 					break
 				}
 			}
+			m.UseSoftLimitForDistributeScan = bool(v != 0)
 		default:
 			iNdEx = preIndex
 			skippy, err := skipLocalOnlySessionData(dAtA[iNdEx:])
diff --git a/pkg/sql/sessiondatapb/local_only_session_data.proto b/pkg/sql/sessiondatapb/local_only_session_data.proto
index 5d801b3..3ef129c 100644
--- a/pkg/sql/sessiondatapb/local_only_session_data.proto
+++ b/pkg/sql/sessiondatapb/local_only_session_data.proto
@@ -1,18 +1,14 @@
 // Copyright 2021 The Cockroach Authors.
 //
-// Use of this software is governed by the Business Source License
-// included in the file licenses/BSL.txt.
-//
-// As of the Change Date specified in that file, in accordance with
-// the Business Source License, use of this software will be governed
-// by the Apache License, Version 2.0, included in the file
-// licenses/APL.txt.
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
 
 syntax = "proto3";
 package cockroach.sql.sessiondatapb;
 option go_package = "github.com/cockroachdb/cockroach/pkg/sql/sessiondatapb";
 
 import "gogoproto/gogo.proto";
+import "util/hlc/timestamp.proto";
 
 // LocalOnlySessionData contains the serializable components of session
 // parameters that only influence execution on the gateway nodes.
@@ -305,7 +301,7 @@ message LocalOnlySessionData {
   int64 transaction_timeout = 81 [(gogoproto.casttype) = "time.Duration"];
   // SystemIdentityProto is the original name of the client presented to pgwire
   // before it was mapped to a SQL identifier.
-  string system_identity_proto = 82 [(gogoproto.casttype) = "github.com/cockroachdb/cockroach/pkg/security/username.SQLUsernameProto"];
+  string system_identity_proto = 82;
   // DescriptorValidationMode indicates whether to validate the descriptors at
   // read and write time, at read time only, or never.
   int64 descriptor_validation_mode = 83 [(gogoproto.casttype) = "DescriptorValidationMode"];
@@ -367,11 +363,8 @@ message LocalOnlySessionData {
   // Execution of these deallocated prepared statements will fail until they are
   // prepared again.
   int64 prepared_statements_cache_size = 97;
-  // StreamerEnabled controls whether the Streamer API can be used.
-  bool streamer_enabled = 98;
-  // DisableDropVirtualCluster causes errors when the client
-  // attempts to drop virtual clusters or tenant records.
-  bool disable_drop_virtual_cluster = 99;
+  reserved 98;
+  reserved 99;
   // MultipleActivePortalEnabled determines if the pgwire portal execution
   // for certain queries can be paused. If true, portals with read-only SELECT
   // query without sub/post queries can be executed in interleaving manner, but
@@ -464,7 +457,8 @@ message LocalOnlySessionData {
   // fixes a bug that incorrectly truncated the provided ordering (see #113072).
   bool optimizer_use_provided_ordering_fix = 115;
   // DisableChangefeedReplication, when true, disables changefeed events from
-  // being emitted for changes to data made in a session.
+  // being emitted for changes to data made in a session. This will apply only
+  // to new txns created in the session.
   bool disable_changefeed_replication = 116;
   // CopyTxnQualityOfService indicates the default QoSLevel/WorkPriority of the
   // transactions used to evaluate COPY commands.
@@ -472,9 +466,227 @@ message LocalOnlySessionData {
   // CopyWritePipeliningEnabled indicates whether the write pipelining is
   // enabled for implicit txns used by COPY.
   bool copy_write_pipelining_enabled = 118;
+  // OptimizerMergeJoinsEnabled, when true, instructs the optimizer to explore
+  // query plans with merge joins. When false, the optimizer does not attempt
+  // to plan merge joins.
+  bool optimizer_merge_joins_enabled = 119;
   // CopyNumRetriesPerBatch determines the number of times a single batch of
   // rows can be retried for non-atomic COPY.
   int32 copy_num_retries_per_batch = 120;
+  // AutoCommitBeforeDDL will cause any DDL statement received during a
+  // multi-statement transaction to make the transaction auto-commit before
+  // executing the DDL statement. After the auto-commit, any other statements
+  // that are in the transaction block will instead be executed in their own
+  // implicit transaction.
+  bool autocommit_before_ddl = 121 [(gogoproto.customname) = "AutoCommitBeforeDDL"];
+  // CloseCursorsAtCommit determines whether cursors remain open after their
+  // parent transaction closes. This is useful for oracle compatibility.
+  bool close_cursors_at_commit = 122;
+  // PLpgSQLUseStrictInto causes PL/pgSQL "SELECT ... INTO" and "RETURNING INTO"
+  // syntax to always behave as if they were specified with the STRICT option,
+  // which throws a runtime error when the SQL statement doesn't return exactly
+  // one row. This is useful for oracle compatibility.
+  bool plpgsql_use_strict_into = 123 [(gogoproto.customname) = "PLpgSQLUseStrictInto"];
+  // OptimizerUseVirtualComputedColumnStats indicates whether we should use
+  // statistics on virtual computed columns for cardinality estimation in the
+  // optimizer.
+  bool optimizer_use_virtual_computed_column_stats = 124;
+  // OptimizerUseTrigramSimilarityOptimization indicates whether the optimizer
+  // should generate improved plans for queries with trigram similarity filters.
+  bool optimizer_use_trigram_similarity_optimization = 125;
+  // OptimizerUseImprovedDistinctOnLimitHintCosting indicates whether the
+  // optimizer should use an improved costing estimate for DistinctOn operators
+  // with limit hints.
+  bool optimizer_use_improved_distinct_on_limit_hint_costing = 126;
+  // OptimizerUseImprovedTrigramSimilaritySelectivity indicates whether the
+  // optimizer should use an improved selectivitiy estimate for trigram
+  // similarity filters.
+  bool optimizer_use_improved_trigram_similarity_selectivity = 127;
+  // OptimizerUseImprovedZigzagJoinCosting, when true, indicates that the
+  // optimizer should use improved logic in the cost model for zigzag joins.
+  bool optimizer_use_improved_zigzag_join_costing = 128;
+  // OptimizerUseImprovedMultiColumnSelectivityEstimate, when true, indicates
+  // that the optimizer should use an improved selectivity estimate for
+  // multi-column predicates.
+  bool optimizer_use_improved_multi_column_selectivity_estimate = 129;
+  // OptimizerProveImplicationWithVirtualComputedColumns, when true, indicates
+  // that the optimizer should use virtual computed columns to prove partial
+  // index implication.
+  bool optimizer_prove_implication_with_virtual_computed_columns = 130;
+  reserved 131;
+  // OptimizerPushOffsetIntoIndexJoin, when true, indicates that the optimizer
+  // should push offset expressions into index joins.
+  bool optimizer_push_offset_into_index_join = 132;
+  // PlanCacheMode indicates the method that the optimizer should use to choose
+  // between a custom and generic query plan.
+  PlanCacheMode plan_cache_mode = 133;
+  // OptimizerUsePolymorphicParameterFix, when true, causes the optimizer to
+  // validate a routine's polymorphic parameters during overload resolution
+  // and type-checking.
+  bool optimizer_use_polymorphic_parameter_fix = 134;
+  // OriginIDForLogicalDataReplication is an identifier for the cluster that
+  // originally wrote the data that are being written in this session. An
+  // originID of 0 (the default) identifies a local write, 1 identifies a remote
+  // write of unspecified origin, and 2+ are reserved to identify remote writes
+  // from specific clusters.
+  uint32 origin_id_for_logical_data_replication = 135 [(gogoproto.customname) = "OriginIDForLogicalDataReplication"];
+  // EnableCreateStatsUsingExtremesBoolEnum, when true, allows the use of CREATE
+  // STATISTICS .. USING EXTREMES on bool and enum columns.
+  bool enable_create_stats_using_extremes_bool_enum = 136;
+  // OptimizerUseMergedPartialStatistics indicates whether we should use
+  // statistics merged from partial and full statistics for cardinality
+  // estimation in the optimizer.
+  bool optimizer_use_merged_partial_statistics = 137;
+  // OptimizerUseConditionalHoistFix, when true, prevents the optimizer from
+  // hoisting a volatile expression that is conditionally executed by a CASE,
+  // COALESCE, or IFERR expression.
+  bool optimizer_use_conditional_hoist_fix = 138;
+  // OptimizerPushLimitIntoProjectFilteredScan, when true, indicates that the
+  // optimizer should push limit expressions into projects of filtered scans.
+  bool optimizer_push_limit_into_project_filtered_scan = 139;
+  // OriginTimestampForLogicalDataReplication is the mvcc timestamp the data
+  // written in this session were originally written with before being
+  // replicated via Logical Data Replication.
+  util.hlc.Timestamp origin_timestamp_for_logical_data_replication = 140 [(gogoproto.nullable) = false];
+  // BypassPCRReaderCatalogAOST disables the AOST used by all user queries on
+  // the PCR reader catalog.
+  bool bypass_pcr_reader_catalog_aost = 141  [(gogoproto.customname) = "BypassPCRReaderCatalogAOST"];
+  // UnsafeAllowTriggersModifyingCascades, when true, allows row-level BEFORE
+  // triggers to modify or filter rows that are being updated or deleted as
+  // part of a cascading foreign key action. This is unsafe because it can
+  // lead to constraint violations.
+  bool unsafe_allow_triggers_modifying_cascades = 142;
+  // DisableVecUnionEagerCancellation disables the eager cancellation that is
+  // performed by the vectorized engine when transitioning into the draining
+  // state in some cases.
+  bool disable_vec_union_eager_cancellation = 143;
+  // RecursionDepthLimit is the maximum depth that nested trigger-function calls
+  // can reach.
+  int64 recursion_depth_limit = 144;
+  // DistributeGroupByRowCountThreshold is the minimum number of rows estimated
+  // to be processed by the GroupBy operator so that we choose to distribute the
+  // plan because of this aggregator stage of DistSQL processors.
+  uint64 distribute_group_by_row_count_threshold = 145;
+  // DistributeSortRowCountThreshold is the minimum number of rows estimated
+  // to be processed by the Sort operator so that we choose to distribute the
+  // plan because of this sorter stage of DistSQL processors.
+  uint64 distribute_sort_row_count_threshold = 146;
+  // DistributeScanRowCountThreshold is the minimum number of rows estimated to
+  // be read by the Scan operator so that we choose to distribute the plan
+  // because of this TableReader stage of DistSQL processors.
+  uint64 distribute_scan_row_count_threshold = 147;
+  // AlwaysDistributeFullScans determines whether full table scans always force
+  // the plan to be distributed, regardless of the estimated row count.
+  bool always_distribute_full_scans = 148;
+  // DistributeJoinRowCountThreshold is the minimum number of rows estimated to
+  // be processed from both inputs by the hash or merge join so that we choose
+  // to distribute the plan because of this joiner stage of DistSQL processors.
+  uint64 distribute_join_row_count_threshold = 149;
+  // LegacyVarcharTyping controls the legacy behavior of allowing some invalid
+  // mix-typed comparisons with VARCHAR types. See #137837, #133037, and
+  // #132268.
+  bool legacy_varchar_typing = 150;
+  // AvoidFullTableScansInMutations indicates whether mutation queries that plan
+  // full table scans should be avoided.
+  bool avoid_full_table_scans_in_mutations = 151;
+  reserved 152;
+  // CatalogDigestStalenessCheckEnabled is used to enable using the catalog
+  // digest information to do fast memo checks.
+  bool catalog_digest_staleness_check_enabled = 153;
+  // OptimizerPreferBoundedCardinality instructs the optimizer to prefer query
+  // plans in which every expression has a bounded cardinality over plans with
+  // one or more expressions with unbounded cardinality.
+  bool optimizer_prefer_bounded_cardinality = 154;
+  // OptimizerMinRowCount sets a lower bound on row count estimates for
+  // relational expressions during query planning. A value of zero indicates no
+  // lower bound. Note that if this is set to a value greater than zero, a row
+  // count of zero can still be estimated for expressions with a cardinality of
+  // zero, e.g., for a contradictory filter.
+  double optimizer_min_row_count = 155;
+  // BufferedWritesEnabled controls whether the buffered writes KV transaction
+  // protocol is used for user queries on the current session. If this variable
+  // is modified in an explicit txn, then the change will be applied only to
+  // future txns on the session.
+  bool buffered_writes_enabled = 156;
+  // OptimizerCheckInputMinRowCount sets a lower bound on row count estimates
+  // for the buffer scan of FK and uniqueness checks. A value of zero indicates
+  // no lower bound.
+  double optimizer_check_input_min_row_count = 157;
+  // OptimizerPlanLookupJoinsWithReverseScans enables planning for lookup joins
+  // that use reverse scans to get results in reverse index order on each
+  // lookup.
+  bool optimizer_plan_lookup_joins_with_reverse_scans = 158;
+  // RegisterLatchWaitContentionEvents, when true, causes latch wait contention
+  // events to be registered with the *.contention_events virtual tables. It
+  // defaults to false in order to avoid registering a large number of
+  // uninformative latch wait events.
+  bool register_latch_wait_contention_events = 159;
+  // UseCPutsOnNonUniqueIndexes, when true, indicates that CPuts should be used
+  // when writing new KVs into the non-unique indexes. It is an escape hatch in
+  // case our thinking that we don't need the CPut in such a scenario is wrong.
+  //
+  // This will have impact regardless of the buffered writes.
+  bool use_cputs_on_non_unique_indexes = 160 [(gogoproto.customname) = "UseCPutsOnNonUniqueIndexes"];
+  // BufferedWritesUseLockingOnNonUniqueIndexes, when true, indicates that
+  // locking Puts and Dels should be used when writing into the non-unique
+  // indexes.
+  //
+  // This will only have impact when BufferedWritesEnabled is set.
+  bool buffered_writes_use_locking_on_non_unique_indexes = 161;
+  // OptimizerUseLockElisionMultipleFamilies, when true, indicates that the lock
+  // eliding optimization should be enabled for tables with multiple column
+  // families.
+  //
+  // This will only have impact when BufferedWritesEnabled is set.
+  bool optimizer_use_lock_elision_multiple_families = 162;
+  // OptimizerEnableLockElision, when false, indicates that the lock eliding
+  // optimization should be disabled for tables with any number of column
+  // families. It takes precedence over OptimizerUseLockElisionMultipleFamilies.
+  //
+  // This will only have impact when BufferedWritesEnabled is set.
+  bool optimizer_enable_lock_elision = 163;
+  // OptimizerUseDeleteRangeFastPath, when true, indicates that the optimizer
+  // should try to use the delete range fast-path when possible.
+  bool optimizer_use_delete_range_fast_path = 164;
+  // AllowCreateTriggerFunctionWithArgvReferences, when true, allows triggers to
+  // be created with trigger functions that use the TG_ARGV parameter even
+  // though it currently doesn't have Postgres-compatible 0-based indexing
+  // behavior.
+  bool allow_create_trigger_function_with_argv_references = 165;
+
+  // Not backported (yet)
+  // bool create_table_with_schema_locked = 166;
+
+  // UsePre_25_2VariadicBuiltins, when true, will treat variadic builtins with a
+  // types.Any variadic argument as types.AnyElement (the pre-25.2 behavior)
+  bool use_pre_25_2_variadic_builtins = 167;
+  // VectorSearchBeamSize controls the number of candidates examined during
+  // vector index searches. It represents the number of vector partitions that
+  // are considered at each level of the search tree. Higher values increase
+  // search accuracy but require more processing resources.
+  int32 vector_search_beam_size = 168;
+  // PropagateAdmissionHeaderToLeafTransactions, when true, causes leaf
+  // transactions to inherit the admission header from the root transaction.
+  bool propagate_admission_header_to_leaf_transactions = 169;
+  // OptimizerUseExistsFilterHoistRule, when true, causes the optimizer to apply
+  // the HoistUnboundFilterFromExistsSubquery rule to EXISTS conditions.
+  bool optimizer_use_exists_filter_hoist_rule = 170;
+  // InitialRetryBackoffForReadCommitted controls the initial backoff
+  // duration for automatic retries of statements in explicit READ COMMITTED
+  // transactions that see a transaction retry error. 0 disables backoff.
+  int64 initial_retry_backoff_for_read_committed = 171 [(gogoproto.casttype) = "time.Duration"];
+  // UseProcTxnControlExtendedProtocolFix, when true, enables the fix for
+  // PL/pgSQL transaction control statements (COMMIT, ROLLBACK) when the stored
+  // procedure is executed via a portal in the extended wire protocol.
+  bool use_proc_txn_control_extended_protocol_fix = 175;
+  // DisableOptimizerRules is a list of optimizer rules that should be disabled
+  // during query optimization. The names of the rules can be found in the
+  // opt/rule_name.og.go file.
+  repeated string disable_optimizer_rules = 184;
+  // UseSoftLimitForDistributeScan, if set, means that we'll use the soft limit
+  // hint - if available - when comparing against
+  // DistributeScanRowCountThreshold.
+  bool use_soft_limit_for_distribute_scan = 185;
 
   ///////////////////////////////////////////////////////////////////////////
   // WARNING: consider whether a session parameter you're adding needs to  //
@@ -491,6 +703,23 @@ enum ReplicationMode {
   REPLICATION_MODE_DATABASE = 2;
 }
 
+// PlanCacheMode controls the optimizer's decision to use a custom or generic
+// query plan.
+enum PlanCacheMode {
+  option (gogoproto.goproto_enum_prefix) = false;
+  option (gogoproto.goproto_enum_stringer) = false;
+
+  // PlanCacheModeForceCustom forces the optimizer to use a custom query plan.
+  force_custom_plan = 0 [(gogoproto.enumvalue_customname) = "PlanCacheModeForceCustom"];
+
+  // PlanCacheModeForceCustom forces the optimizer to use a generic query plan.
+  force_generic_plan = 1 [(gogoproto.enumvalue_customname) = "PlanCacheModeForceGeneric"];
+
+  // PlanCacheModeAuto allows the optimizer to automatically choose between a
+  // custom and generic query plan.
+  auto = 2 [(gogoproto.enumvalue_customname) = "PlanCacheModeAuto"];
+}
+
 // SequenceCacheEntry is an entry in a SequenceCache.
 message SequenceCacheEntry {
   // CachedVersion stores the descpb.DescriptorVersion that cached values are associated with.
diff --git a/pkg/sql/sessiondatapb/sequence_cache.go b/pkg/sql/sessiondatapb/sequence_cache.go
index 71bfddc..a9a33f4 100644
--- a/pkg/sql/sessiondatapb/sequence_cache.go
+++ b/pkg/sql/sessiondatapb/sequence_cache.go
@@ -1,12 +1,7 @@
 // Copyright 2020 The Cockroach Authors.
 //
-// Use of this software is governed by the Business Source License
-// included in the file licenses/BSL.txt.
-//
-// As of the Change Date specified in that file, in accordance with
-// the Business Source License, use of this software will be governed
-// by the Apache License, Version 2.0, included in the file
-// licenses/APL.txt.
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
 
 package sessiondatapb
 
diff --git a/pkg/sql/sessiondatapb/sequence_cache_node.go b/pkg/sql/sessiondatapb/sequence_cache_node.go
new file mode 100644
index 0000000..5261c91
--- /dev/null
+++ b/pkg/sql/sessiondatapb/sequence_cache_node.go
@@ -0,0 +1,82 @@
+// Copyright 2024 The Cockroach Authors.
+//
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
+
+package sessiondatapb
+
+import (
+	"github.com/cockroachdb/cockroachdb-parser/pkg/sql/sem/catid"
+	"github.com/cockroachdb/cockroachdb-parser/pkg/util/syncutil"
+)
+
+// SequenceCacheNodeEntry embeds the existing SequenceCacheEntry struct that
+// session-level sequence caching currently utilizes, and also includes a mutex.
+type SequenceCacheNodeEntry struct {
+	entry SequenceCacheEntry
+	mu    syncutil.Mutex
+}
+
+// SequenceCacheNode stores sequence values at a per-node level
+// The cache stores sequence values that have already been created in KV
+// and are available to be given out as sequence numbers. Values for sequences
+// are keyed by the descpb.ID of each sequence. These IDs are represented as
+// uint32 to prevent an import cycle with the descpb package.
+type SequenceCacheNode struct {
+	cache map[catid.DescID]*SequenceCacheNodeEntry
+	mu    syncutil.RWMutex
+}
+
+// NewSequenceCacheNode initializes a new SequenceCacheNode.
+func NewSequenceCacheNode() *SequenceCacheNode {
+	return &SequenceCacheNode{
+		cache: map[catid.DescID]*SequenceCacheNodeEntry{},
+	}
+}
+
+// NextValue fetches the next value in the sequence cache. If the values in the cache have all been
+// given out or if the descriptor version has changed, then fetchNextValues() is used to repopulate the cache.
+func (sc *SequenceCacheNode) NextValue(
+	seqID catid.DescID, clientVersion uint32, fetchNextValues func() (int64, int64, int64, error),
+) (int64, error) {
+	sc.mu.RLock()
+	cacheEntry, found := sc.cache[seqID]
+	sc.mu.RUnlock()
+
+	createSequenceCacheNodeEntry := func() {
+		sc.mu.Lock()
+		defer sc.mu.Unlock()
+		// There is a hazard that multiple threads could add the entry, so check if it exists again with the writer lock
+		cacheEntry, found = sc.cache[seqID]
+		if !found {
+			cacheEntry = &SequenceCacheNodeEntry{}
+			sc.cache[seqID] = cacheEntry
+		}
+	}
+	// Create entry for this sequence ID if there are no existing entries.
+	if !found {
+		createSequenceCacheNodeEntry()
+	}
+	cacheEntry.mu.Lock()
+	defer cacheEntry.mu.Unlock()
+
+	if cacheEntry.entry.NumValues > 0 && cacheEntry.entry.CachedVersion == clientVersion {
+		cacheEntry.entry.CurrentValue += cacheEntry.entry.Increment
+		cacheEntry.entry.NumValues--
+		return cacheEntry.entry.CurrentValue - cacheEntry.entry.Increment, nil
+	}
+
+	currentValue, increment, numValues, err := fetchNextValues()
+	if err != nil {
+		return 0, err
+	}
+
+	// One value must be returned, and the rest of the values are stored.
+	val := currentValue
+	cacheEntry.entry.CurrentValue = currentValue + increment
+	cacheEntry.entry.Increment = increment
+	cacheEntry.entry.NumValues = numValues - 1
+	cacheEntry.entry.CachedVersion = clientVersion
+	return val, nil
+
+}
diff --git a/pkg/sql/sessiondatapb/session_data.go b/pkg/sql/sessiondatapb/session_data.go
index 906b8b5..4bdf248 100644
--- a/pkg/sql/sessiondatapb/session_data.go
+++ b/pkg/sql/sessiondatapb/session_data.go
@@ -1,12 +1,7 @@
 // Copyright 2020 The Cockroach Authors.
 //
-// Use of this software is governed by the Business Source License
-// included in the file licenses/BSL.txt.
-//
-// As of the Change Date specified in that file, in accordance with
-// the Business Source License, use of this software will be governed
-// by the Apache License, Version 2.0, included in the file
-// licenses/APL.txt.
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
 
 package sessiondatapb
 
@@ -55,7 +50,7 @@ func (c DataConversionConfig) GetFloatPrec(typ *types.T) int {
 }
 
 func (m VectorizeExecMode) String() string {
-	if m == VectorizeUnset {
+	if m == VectorizeUnset || m == DeprecatedVectorize201Auto {
 		m = VectorizeOn
 	}
 	name, ok := VectorizeExecMode_name[int32(m)]
@@ -77,9 +72,31 @@ func VectorizeExecModeFromString(val string) (VectorizeExecMode, bool) {
 	if m == VectorizeUnset {
 		return 0, false
 	}
+	if m == DeprecatedVectorize201Auto {
+		m = VectorizeOn
+	}
 	return m, true
 }
 
+func (m PlanCacheMode) String() string {
+	name, ok := PlanCacheMode_name[int32(m)]
+	if !ok {
+		return fmt.Sprintf("invalid (%d)", m)
+	}
+	return name
+}
+
+// PlanCacheModeFromString converts a string into a PlanCacheMode. False is
+// returned if the conversion was unsuccessful.
+func PlanCacheModeFromString(val string) (PlanCacheMode, bool) {
+	lowerVal := strings.ToLower(val)
+	m, ok := PlanCacheMode_value[lowerVal]
+	if !ok {
+		return 0, false
+	}
+	return PlanCacheMode(m), true
+}
+
 // User retrieves the current user.
 func (s *SessionData) User() username.SQLUsername {
 	return s.UserProto.Decode()
@@ -87,6 +104,6 @@ func (s *SessionData) User() username.SQLUsername {
 
 // SystemIdentity retrieves the session's system identity.
 // (Identity presented by the client prior to identity mapping.)
-func (s *LocalOnlySessionData) SystemIdentity() username.SQLUsername {
-	return s.SystemIdentityProto.Decode()
+func (s *LocalOnlySessionData) SystemIdentity() string {
+	return s.SystemIdentityProto
 }
diff --git a/pkg/sql/sessiondatapb/session_data.pb.go b/pkg/sql/sessiondatapb/session_data.pb.go
index 78cb4b8..e407c05 100644
--- a/pkg/sql/sessiondatapb/session_data.pb.go
+++ b/pkg/sql/sessiondatapb/session_data.pb.go
@@ -32,7 +32,7 @@ var _ = time.Kitchen
 // proto package needs to be updated.
 const _ = proto.GoGoProtoPackageIsVersion3 // please upgrade the proto package
 
-// VectorizeExecMode controls if an when the Executor executes queries using
+// VectorizeExecMode controls if and when the Executor executes queries using
 // the columnar execution engine.
 type VectorizeExecMode int32
 
@@ -41,6 +41,10 @@ const (
 	// the first enum value as zero is required by proto3. This is mapped to
 	// VectorizeOn.
 	VectorizeUnset VectorizeExecMode = 0
+	// DeprecatedVectorized201Auto is only possible for clusters that have been
+	// upgraded from v21.1 or older and had the old setting of "201auto" which
+	// was mapped to "on" in v21.1. It is now an alias for "on".
+	DeprecatedVectorize201Auto VectorizeExecMode = 1
 	// VectorizeOn means that any supported queries will be run using the
 	// columnar execution.
 	VectorizeOn VectorizeExecMode = 2
@@ -53,6 +57,7 @@ const (
 
 var VectorizeExecMode_name = map[int32]string{
 	0: "unset",
+	1: "deprecated201auto",
 	2: "on",
 	3: "experimental_always",
 	4: "off",
@@ -60,6 +65,7 @@ var VectorizeExecMode_name = map[int32]string{
 
 var VectorizeExecMode_value = map[string]int32{
 	"unset":               0,
+	"deprecated201auto":   1,
 	"on":                  2,
 	"experimental_always": 3,
 	"off":                 4,
@@ -190,6 +196,11 @@ type SessionData struct {
 	// could be adopted by any node in the cluster (not necessarily the gateway)
 	// and so we will need this information available on all nodes.
 	DistsqlPlanGatewayBias int64 `protobuf:"varint,31,opt,name=distsql_plan_gateway_bias,json=distsqlPlanGatewayBias,proto3" json:"distsql_plan_gateway_bias,omitempty"`
+	// StreamerEnabled controls whether the Streamer API can be used.
+	StreamerEnabled bool `protobuf:"varint,32,opt,name=streamer_enabled,json=streamerEnabled,proto3" json:"streamer_enabled,omitempty"`
+	// DeadlockTimeout specifies the amount of time before pushing the lock holder
+	// for deadlock detection.
+	DeadlockTimeout time.Duration `protobuf:"bytes,33,opt,name=deadlock_timeout,json=deadlockTimeout,proto3,stdduration" json:"deadlock_timeout"`
 }
 
 func (m *SessionData) Reset()         { *m = SessionData{} }
@@ -351,102 +362,106 @@ func init() {
 }
 
 var fileDescriptor_9fa1c5a4e61eec38 = []byte{
-	// 1509 bytes of a gzipped FileDescriptorProto
-	0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x8c, 0x56, 0x41, 0x73, 0x1b, 0xb7,
-	0x15, 0xd6, 0x9a, 0x92, 0x4b, 0x42, 0x16, 0x45, 0x43, 0x8a, 0xbd, 0xa6, 0x65, 0x92, 0x51, 0x92,
-	0x96, 0x51, 0x5b, 0xb2, 0x76, 0x67, 0x3a, 0xed, 0x74, 0xa6, 0xd3, 0xd0, 0x92, 0x52, 0xda, 0x96,
-	0xe5, 0x2e, 0xad, 0x34, 0xcd, 0x21, 0x18, 0x70, 0xf7, 0x91, 0x84, 0x85, 0x05, 0x48, 0x00, 0x6b,
-	0x8b, 0xfe, 0x05, 0x1d, 0x9f, 0x7a, 0xec, 0x45, 0xa7, 0xf6, 0xd0, 0x63, 0xff, 0x43, 0x67, 0x3a,
-	0xbe, 0x74, 0x26, 0xc7, 0x9c, 0xdc, 0x56, 0xfe, 0x17, 0x3d, 0x75, 0x80, 0x5d, 0x2e, 0x29, 0xc5,
-	0x55, 0x72, 0xe2, 0x02, 0xef, 0xfb, 0xbe, 0xf7, 0xf8, 0x1e, 0x1e, 0xf0, 0xd0, 0x87, 0x7a, 0xc2,
-	0xdb, 0x1a, 0xb4, 0x66, 0x52, 0x44, 0xd4, 0xd0, 0x71, 0x7f, 0xb6, 0x22, 0x76, 0xd9, 0x1a, 0x2b,
-	0x69, 0x24, 0xbe, 0x1d, 0xca, 0xf0, 0x58, 0x49, 0x1a, 0x8e, 0x5a, 0x7a, 0xc2, 0x5b, 0xe7, 0xf0,
-	0xd5, 0x4d, 0x2b, 0xc1, 0xe1, 0xa4, 0x0d, 0x22, 0x94, 0x11, 0xa4, 0x94, 0xea, 0x56, 0x62, 0x18,
-	0x6f, 0x47, 0x89, 0xa2, 0x86, 0x49, 0x91, 0x7f, 0x64, 0xd6, 0xf7, 0x9d, 0xd5, 0xb0, 0x18, 0xdc,
-	0xc7, 0x78, 0x18, 0x51, 0x03, 0xd9, 0x4f, 0x06, 0xd9, 0x1c, 0xca, 0xa1, 0x74, 0x9f, 0x6d, 0xfb,
-	0x95, 0xed, 0xd6, 0x86, 0x52, 0x0e, 0x39, 0xb4, 0xdd, 0xaa, 0x9f, 0x0c, 0x2e, 0x08, 0x6f, 0xff,
-	0x63, 0x1d, 0xad, 0xf6, 0xd2, 0xf0, 0x76, 0xa9, 0xa1, 0xb8, 0x8a, 0x8a, 0x36, 0xcc, 0x3e, 0xd5,
-	0xe0, 0x7b, 0x0d, 0xaf, 0x59, 0x0a, 0xf2, 0x35, 0xfe, 0x18, 0x55, 0xe8, 0x78, 0xcc, 0x59, 0xe8,
-	0x04, 0x88, 0xa0, 0x31, 0xf8, 0x57, 0x1c, 0x66, 0x7d, 0x61, 0xff, 0x31, 0x8d, 0x01, 0x3f, 0x43,
-	0x28, 0xd1, 0xa0, 0x88, 0x73, 0xe2, 0x17, 0x2c, 0xa8, 0xf3, 0xf0, 0xbf, 0x6f, 0xea, 0x9f, 0x0e,
-	0x99, 0x19, 0x25, 0xfd, 0x56, 0x28, 0xe3, 0x76, 0x9e, 0xa3, 0xa8, 0x3f, 0xff, 0x6e, 0x8f, 0x8f,
-	0x87, 0x6d, 0x0d, 0x61, 0xa2, 0x98, 0x99, 0xb6, 0xad, 0x86, 0x75, 0xd3, 0xea, 0xfd, 0xf6, 0xd1,
-	0x51, 0xf6, 0xfd, 0xc4, 0x4a, 0x06, 0x25, 0x6b, 0x72, 0x9f, 0x38, 0x46, 0x37, 0x6c, 0x88, 0x24,
-	0x94, 0xe2, 0x39, 0x28, 0x57, 0x8a, 0x50, 0x8a, 0x01, 0x1b, 0xfa, 0xcb, 0x0d, 0xaf, 0xb9, 0x7a,
-	0xef, 0x6e, 0xeb, 0x92, 0x6a, 0xb4, 0xec, 0xbf, 0xbe, 0x9f, 0x33, 0xef, 0x3b, 0x62, 0x67, 0xf9,
-	0xf5, 0x9b, 0xfa, 0x52, 0xb0, 0x19, 0xbd, 0xc3, 0x86, 0x8f, 0x50, 0xf9, 0x39, 0x84, 0x46, 0x2a,
-	0xf6, 0x12, 0x48, 0x2c, 0x23, 0xf0, 0x57, 0x1a, 0x5e, 0xb3, 0x7c, 0xaf, 0x75, 0xa9, 0x9b, 0xcf,
-	0x66, 0x94, 0xbd, 0x13, 0x08, 0x0f, 0x64, 0x04, 0xc1, 0x5a, 0xae, 0x62, 0x97, 0x78, 0x0f, 0xd5,
-	0x0d, 0x68, 0xc3, 0xc4, 0x90, 0xcc, 0xe5, 0x99, 0x78, 0x06, 0xa1, 0x21, 0x63, 0x2a, 0x58, 0xa8,
-	0xfd, 0xab, 0x0d, 0xaf, 0x59, 0x0c, 0xb6, 0x32, 0x58, 0xae, 0xd8, 0x75, 0xa0, 0x27, 0x0e, 0x83,
-	0x9b, 0xa8, 0x12, 0xc1, 0x80, 0x26, 0xdc, 0x10, 0x26, 0x0c, 0xd1, 0xec, 0x25, 0xf8, 0xdf, 0x6b,
-	0x78, 0xcd, 0x95, 0xa0, 0x9c, 0xed, 0x77, 0x85, 0xe9, 0xb1, 0x97, 0x60, 0x2b, 0xcd, 0x65, 0x5a,
-	0x32, 0xbf, 0x98, 0x56, 0x7a, 0xb6, 0xc6, 0x75, 0xb4, 0xaa, 0x81, 0xaa, 0x70, 0x44, 0xc6, 0xd4,
-	0x8c, 0xfc, 0x52, 0xa3, 0xd0, 0x2c, 0x05, 0x28, 0xdd, 0x7a, 0x42, 0xcd, 0x08, 0xdf, 0x43, 0xef,
-	0x19, 0x88, 0xc7, 0x52, 0x51, 0x35, 0x25, 0x3a, 0x1c, 0x41, 0x4c, 0xd3, 0xf3, 0x80, 0x9c, 0xd2,
-	0x46, 0x6e, 0xec, 0x39, 0x9b, 0x3b, 0x13, 0x07, 0xa8, 0xa4, 0x61, 0x42, 0xb4, 0xa1, 0x06, 0xfc,
-	0x55, 0x57, 0x9a, 0x9d, 0x4b, 0x73, 0xd6, 0x83, 0x49, 0x02, 0x22, 0x84, 0x9e, 0x65, 0x64, 0x35,
-	0x29, 0x6a, 0x98, 0xb8, 0x35, 0xde, 0x46, 0xd7, 0x7e, 0x27, 0xd5, 0xf1, 0x01, 0xc4, 0x8f, 0x58,
-	0xcc, 0x8c, 0x7f, 0xad, 0xe1, 0x35, 0x0b, 0xc1, 0xb9, 0x3d, 0xbc, 0x8f, 0xae, 0x71, 0x19, 0x1e,
-	0x13, 0xdb, 0x38, 0x32, 0x31, 0xfe, 0xba, 0xf3, 0x7a, 0xab, 0x95, 0x36, 0x45, 0x6b, 0xd6, 0x14,
-	0xad, 0xdd, 0xac, 0x29, 0x3a, 0x45, 0xeb, 0xe4, 0x4f, 0xff, 0xaa, 0x7b, 0xc1, 0xaa, 0x25, 0x3e,
-	0x4d, 0x79, 0x36, 0x57, 0x4c, 0x18, 0x7b, 0xfe, 0xb8, 0x5f, 0x71, 0x55, 0xc8, 0xd7, 0xf8, 0x57,
-	0x68, 0x4b, 0x0a, 0x92, 0x8c, 0x6d, 0x2b, 0x12, 0x05, 0x23, 0x19, 0x03, 0x51, 0xf2, 0x05, 0x01,
-	0x41, 0xfb, 0x1c, 0x22, 0xff, 0xba, 0xc3, 0xfb, 0x52, 0x1c, 0x39, 0x48, 0xe0, 0x10, 0x81, 0x7c,
-	0xb1, 0x97, 0xda, 0xf1, 0x11, 0x6a, 0x3e, 0x93, 0x4c, 0x10, 0x05, 0x34, 0x02, 0x45, 0xa4, 0x8a,
-	0x40, 0xd9, 0x53, 0xa0, 0x8d, 0xa2, 0x06, 0x86, 0x53, 0xd2, 0xa7, 0x26, 0x1c, 0xa5, 0x95, 0xc4,
-	0xee, 0x3f, 0x7e, 0x60, 0xf1, 0x81, 0x83, 0x1f, 0x66, 0xe8, 0x5e, 0x06, 0xee, 0x58, 0xac, 0x2b,
-	0xef, 0xef, 0xd1, 0xce, 0x98, 0x2a, 0xca, 0x39, 0x70, 0x77, 0x50, 0x13, 0x6e, 0x18, 0x39, 0x86,
-	0x29, 0xe1, 0x52, 0x1e, 0x27, 0x63, 0x62, 0x35, 0x74, 0x1e, 0xe4, 0x86, 0x0b, 0xf2, 0xa3, 0x05,
-	0xc6, 0x81, 0x25, 0x3c, 0x84, 0xe9, 0x23, 0x07, 0x7f, 0x60, 0xd1, 0xb3, 0x88, 0x7f, 0x8d, 0xb6,
-	0x8c, 0x62, 0x43, 0x45, 0x63, 0xa2, 0x59, 0xcc, 0x38, 0xb5, 0xbd, 0x4a, 0xcc, 0x48, 0x81, 0x1e,
-	0x49, 0x1e, 0xf9, 0x9b, 0x0d, 0xaf, 0xe9, 0x05, 0xd5, 0x0c, 0xd3, 0xcb, 0x21, 0x4f, 0x67, 0x08,
-	0x7c, 0x17, 0x6d, 0x1a, 0x25, 0x93, 0x3e, 0xb7, 0x6b, 0xe9, 0x0e, 0xbd, 0xeb, 0xa4, 0xf7, 0x5c,
-	0x18, 0x1b, 0x17, 0x6c, 0xae, 0x3f, 0xbe, 0x40, 0x3f, 0x5c, 0x4c, 0x93, 0x90, 0x97, 0x67, 0xea,
-	0x86, 0xcb, 0xd4, 0x47, 0xf3, 0x4c, 0x3d, 0x96, 0xff, 0x3f, 0x57, 0x9f, 0xa3, 0x9d, 0x45, 0x6d,
-	0x26, 0x22, 0x38, 0x71, 0x09, 0x7a, 0xa7, 0xf4, 0x4d, 0x27, 0xfd, 0xe1, 0x5c, 0xba, 0x6b, 0xf1,
-	0x36, 0x43, 0xdf, 0x54, 0xee, 0xa0, 0xda, 0x79, 0x35, 0xa0, 0x31, 0xa8, 0x45, 0x35, 0xdf, 0xa9,
-	0x55, 0xd9, 0x82, 0x86, 0xc3, 0xcc, 0x35, 0x3e, 0x41, 0x77, 0x22, 0xa6, 0xec, 0x3d, 0x10, 0x4a,
-	0x9e, 0xc4, 0x82, 0x2a, 0xa2, 0x43, 0xba, 0x50, 0xbc, 0x5b, 0x2e, 0x6b, 0xd5, 0x14, 0x74, 0x3f,
-	0xc3, 0xf4, 0x2c, 0x64, 0x56, 0xb1, 0x5f, 0xa2, 0xea, 0xec, 0x56, 0x30, 0x70, 0x62, 0x48, 0xd6,
-	0xdc, 0xd9, 0x35, 0x59, 0x75, 0x3d, 0x7b, 0x33, 0x43, 0x3c, 0x85, 0x13, 0xd3, 0x73, 0xf6, 0xec,
-	0xc2, 0xeb, 0xa2, 0xf7, 0xf3, 0xc0, 0x29, 0x7f, 0x41, 0xa7, 0x9a, 0xc4, 0x94, 0x09, 0x43, 0x99,
-	0xc8, 0x6b, 0xe0, 0xdf, 0x76, 0x31, 0xd4, 0x66, 0xc0, 0x4f, 0x1c, 0xee, 0x20, 0x83, 0xcd, 0x32,
-	0x8f, 0xbf, 0x44, 0x3f, 0xce, 0xa5, 0x66, 0x6c, 0x02, 0x74, 0x08, 0x8a, 0xc4, 0x10, 0x4b, 0x35,
-	0x25, 0x89, 0xa6, 0x43, 0x20, 0x03, 0x45, 0x43, 0x77, 0x31, 0x6d, 0xb9, 0xa3, 0xf4, 0x83, 0x19,
-	0xa9, 0x9b, 0x4a, 0xed, 0x59, 0xc6, 0x81, 0x23, 0x1c, 0x59, 0xfc, 0x7e, 0x06, 0xc7, 0x80, 0xee,
-	0xe6, 0xfa, 0x32, 0x31, 0x44, 0x0e, 0xbe, 0x83, 0x8f, 0x3b, 0xce, 0xc7, 0xce, 0x8c, 0x78, 0x98,
-	0x98, 0xc3, 0xc1, 0xe5, 0x6e, 0x1e, 0xa2, 0x0f, 0x72, 0x37, 0x23, 0xa0, 0x91, 0xf5, 0xc3, 0x99,
-	0x00, 0x22, 0x05, 0x9f, 0xce, 0x85, 0x6b, 0x4e, 0x38, 0xcf, 0xc9, 0x6f, 0x80, 0x46, 0x87, 0x83,
-	0x47, 0x4c, 0xc0, 0xa1, 0xe0, 0xd3, 0x5c, 0xec, 0x17, 0xe8, 0x56, 0xc4, 0xb4, 0xd1, 0x13, 0x4e,
-	0xc6, 0x9c, 0x0a, 0x32, 0xa4, 0x06, 0x5e, 0xd0, 0x29, 0xe9, 0x33, 0xaa, 0xfd, 0xba, 0x3b, 0x1d,
-	0x37, 0x32, 0xc0, 0x13, 0x4e, 0xc5, 0xa7, 0xa9, 0xb9, 0xc3, 0xa8, 0x7e, 0xb0, 0x5c, 0x5c, 0xab,
-	0x94, 0x1f, 0x2c, 0x17, 0xcb, 0x95, 0xf5, 0xed, 0xbf, 0x5f, 0x41, 0x9b, 0xef, 0x7a, 0xcb, 0xf0,
-	0x97, 0x68, 0xa3, 0x3f, 0x35, 0x60, 0x8f, 0x8b, 0x1d, 0x37, 0xc8, 0x40, 0xaa, 0x98, 0x1a, 0xf7,
-	0xb8, 0x7f, 0xdb, 0xa3, 0xd5, 0xb1, 0xbc, 0x3d, 0x47, 0xdb, 0x77, 0xac, 0xe0, 0x7a, 0xff, 0xe2,
-	0x16, 0xfe, 0x11, 0xc2, 0x70, 0x62, 0x14, 0x25, 0x03, 0x2e, 0xa9, 0x21, 0x11, 0x1b, 0x32, 0xa3,
-	0xdd, 0x5c, 0xb0, 0x12, 0x54, 0x9c, 0x65, 0xdf, 0x1a, 0x76, 0xdd, 0x3e, 0x3e, 0x40, 0x65, 0x77,
-	0x73, 0x3e, 0xa7, 0x9c, 0x68, 0x33, 0xe5, 0xe0, 0x86, 0x83, 0xf2, 0xbd, 0xef, 0x2f, 0x04, 0x62,
-	0x47, 0x9c, 0x56, 0x3e, 0xa7, 0x74, 0x33, 0x78, 0xcf, 0xa2, 0x83, 0x35, 0xb6, 0xb8, 0xc4, 0x8f,
-	0x11, 0x72, 0xf7, 0x6e, 0x2a, 0x95, 0xbe, 0xf7, 0x1f, 0x5f, 0x94, 0x9a, 0x8d, 0x4d, 0xad, 0x6c,
-	0x5e, 0xda, 0xa5, 0x06, 0x1c, 0x3d, 0x7b, 0x53, 0x4a, 0xd1, 0x6c, 0x63, 0xfb, 0x9f, 0x1e, 0x5a,
-	0x3b, 0xf7, 0xec, 0xe0, 0x0e, 0x5a, 0xd6, 0x30, 0xd1, 0xbe, 0xd7, 0x28, 0x34, 0x57, 0xbf, 0x25,
-	0x5f, 0xe7, 0x98, 0x76, 0x15, 0x38, 0x2e, 0xfe, 0x09, 0xda, 0xe4, 0x54, 0xdb, 0xb6, 0x9b, 0x10,
-	0x26, 0x42, 0x05, 0x31, 0x08, 0x03, 0x91, 0x4b, 0xd2, 0x5a, 0x80, 0xad, 0xad, 0x07, 0x93, 0xee,
-	0xdc, 0x52, 0xdd, 0x47, 0x85, 0x1e, 0x4c, 0x70, 0x03, 0x5d, 0x75, 0x9c, 0xc8, 0x95, 0x6b, 0xad,
-	0x53, 0x3a, 0x7b, 0x53, 0x5f, 0xb1, 0xd0, 0xdd, 0x60, 0x45, 0xc3, 0xa4, 0x1b, 0xe1, 0x3b, 0x08,
-	0x71, 0x6a, 0x27, 0x02, 0xf2, 0x9c, 0x72, 0x27, 0x58, 0x08, 0x4a, 0xe9, 0xce, 0x67, 0x94, 0xef,
-	0xfc, 0xcd, 0x43, 0xd7, 0xbf, 0x31, 0x7a, 0xe0, 0x3b, 0x68, 0x25, 0x11, 0x1a, 0x4c, 0x65, 0xa9,
-	0x8a, 0x5f, 0x9d, 0x36, 0xca, 0x39, 0xe2, 0xc8, 0xee, 0xe2, 0x9b, 0xe8, 0x8a, 0x14, 0x95, 0x2b,
-	0xd5, 0xf5, 0x57, 0xa7, 0x8d, 0xd5, 0xdc, 0x76, 0x28, 0xf0, 0xcf, 0xd1, 0x06, 0x9c, 0x8c, 0x41,
-	0x31, 0x1b, 0x25, 0xe5, 0xd9, 0x6d, 0x50, 0x29, 0x54, 0xeb, 0xaf, 0x4e, 0x1b, 0xb7, 0x17, 0xfc,
-	0xcc, 0x31, 0xe9, 0x45, 0x80, 0x6f, 0xa1, 0x82, 0x1c, 0x0c, 0x2a, 0xcb, 0xd5, 0xca, 0xab, 0xd3,
-	0xc6, 0xb5, 0xb9, 0xe6, 0x60, 0x50, 0x2d, 0xfe, 0xe1, 0xcf, 0xb5, 0xa5, 0xbf, 0xfe, 0xa5, 0xb6,
-	0xb4, 0xbd, 0x5c, 0xf4, 0x2a, 0x5e, 0xe7, 0xf3, 0xd7, 0xff, 0xa9, 0x2d, 0xbd, 0x3e, 0xab, 0x79,
-	0x5f, 0x9d, 0xd5, 0xbc, 0xaf, 0xcf, 0x6a, 0xde, 0xbf, 0xcf, 0x6a, 0xde, 0x1f, 0xdf, 0xd6, 0x96,
-	0xbe, 0x7a, 0x5b, 0x5b, 0xfa, 0xfa, 0x6d, 0x6d, 0xe9, 0x8b, 0x9f, 0x7d, 0xb7, 0x21, 0xf2, 0xe2,
-	0xa0, 0xde, 0xbf, 0xea, 0xde, 0xfb, 0x9f, 0xfe, 0x2f, 0x00, 0x00, 0xff, 0xff, 0x49, 0x61, 0x24,
-	0xe2, 0xc4, 0x0b, 0x00, 0x00,
+	// 1569 bytes of a gzipped FileDescriptorProto
+	0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x8c, 0x57, 0x4f, 0x53, 0x1b, 0xc9,
+	0x15, 0x67, 0x0c, 0x38, 0xd0, 0x18, 0x90, 0x1b, 0xd6, 0x1e, 0xcb, 0x58, 0xc8, 0xde, 0xdd, 0x44,
+	0x4b, 0x12, 0xc9, 0x90, 0x4a, 0x2a, 0xa9, 0x54, 0xa5, 0x62, 0x19, 0xd8, 0xc8, 0x36, 0xc6, 0x19,
+	0x99, 0xcd, 0x66, 0x0f, 0xdb, 0xd5, 0x9a, 0x79, 0x92, 0xda, 0xf4, 0x74, 0x4b, 0xdd, 0x3d, 0x06,
+	0xf9, 0x13, 0xa4, 0x38, 0xe5, 0x98, 0x0b, 0xa7, 0xe4, 0x90, 0xaf, 0x91, 0xca, 0xc5, 0x97, 0x54,
+	0xed, 0x71, 0x4f, 0x4e, 0x16, 0x7f, 0x8b, 0x9c, 0x52, 0xdd, 0xf3, 0x47, 0x82, 0x75, 0xb0, 0x4f,
+	0x74, 0xf7, 0xfb, 0xfd, 0x7e, 0xfd, 0xf4, 0x5e, 0xbf, 0x37, 0x0f, 0xf4, 0x89, 0x1e, 0xf2, 0x86,
+	0x06, 0xad, 0x99, 0x14, 0x11, 0x35, 0x74, 0xd0, 0xc9, 0x77, 0xc4, 0x6e, 0xeb, 0x03, 0x25, 0x8d,
+	0xc4, 0xb7, 0x43, 0x19, 0x1e, 0x2a, 0x49, 0xc3, 0x7e, 0x5d, 0x0f, 0x79, 0xfd, 0x1c, 0xbe, 0xbc,
+	0x6a, 0x25, 0x38, 0x1c, 0x37, 0x40, 0x84, 0x32, 0x82, 0x94, 0x52, 0x5e, 0x4b, 0x0c, 0xe3, 0x8d,
+	0x28, 0x51, 0xd4, 0x30, 0x29, 0x8a, 0x45, 0x66, 0xbd, 0xeb, 0xac, 0x86, 0xc5, 0xe0, 0x16, 0x83,
+	0x5e, 0x44, 0x0d, 0x64, 0x7f, 0x32, 0xc8, 0x6a, 0x4f, 0xf6, 0xa4, 0x5b, 0x36, 0xec, 0x2a, 0x3b,
+	0xad, 0xf4, 0xa4, 0xec, 0x71, 0x68, 0xb8, 0x5d, 0x27, 0xe9, 0x5e, 0x10, 0xbe, 0xf7, 0x8f, 0x12,
+	0x5a, 0x68, 0xa7, 0xee, 0x6d, 0x53, 0x43, 0x71, 0x19, 0xcd, 0x59, 0x37, 0x3b, 0x54, 0x83, 0xef,
+	0x55, 0xbd, 0xda, 0x7c, 0x50, 0xec, 0xf1, 0x67, 0xa8, 0x44, 0x07, 0x03, 0xce, 0x42, 0x27, 0x40,
+	0x04, 0x8d, 0xc1, 0xbf, 0xe2, 0x30, 0xcb, 0x13, 0xe7, 0x4f, 0x69, 0x0c, 0xf8, 0x05, 0x42, 0x89,
+	0x06, 0x45, 0xdc, 0x25, 0xfe, 0xb4, 0x05, 0x35, 0x1f, 0xff, 0xf7, 0xcd, 0xfa, 0xe7, 0x3d, 0x66,
+	0xfa, 0x49, 0xa7, 0x1e, 0xca, 0xb8, 0x51, 0xc4, 0x28, 0xea, 0x8c, 0xd7, 0x8d, 0xc1, 0x61, 0xaf,
+	0xa1, 0x21, 0x4c, 0x14, 0x33, 0xa3, 0x86, 0xd5, 0xb0, 0xd7, 0xd4, 0xdb, 0xbf, 0x7f, 0x72, 0x90,
+	0xad, 0x9f, 0x59, 0xc9, 0x60, 0xde, 0x9a, 0xdc, 0x12, 0xc7, 0xe8, 0x86, 0x75, 0x91, 0x84, 0x52,
+	0xbc, 0x04, 0xe5, 0x52, 0x11, 0x4a, 0xd1, 0x65, 0x3d, 0x7f, 0xa6, 0xea, 0xd5, 0x16, 0xb6, 0x36,
+	0xeb, 0x97, 0x64, 0xa3, 0x6e, 0x7f, 0xf5, 0xc3, 0x82, 0xf9, 0xd0, 0x11, 0x9b, 0x33, 0xaf, 0xdf,
+	0xac, 0x4f, 0x05, 0xab, 0xd1, 0x3b, 0x6c, 0xf8, 0x00, 0x2d, 0xbd, 0x84, 0xd0, 0x48, 0xc5, 0x5e,
+	0x01, 0x89, 0x65, 0x04, 0xfe, 0x6c, 0xd5, 0xab, 0x2d, 0x6d, 0xd5, 0x2f, 0xbd, 0xe6, 0x8b, 0x9c,
+	0xb2, 0x73, 0x0c, 0xe1, 0x9e, 0x8c, 0x20, 0x58, 0x2c, 0x54, 0xec, 0x16, 0xef, 0xa0, 0x75, 0x03,
+	0xda, 0x30, 0xd1, 0x23, 0x63, 0x79, 0x26, 0x5e, 0x40, 0x68, 0xc8, 0x80, 0x0a, 0x16, 0x6a, 0xff,
+	0x6a, 0xd5, 0xab, 0xcd, 0x05, 0x6b, 0x19, 0xac, 0x50, 0x6c, 0x39, 0xd0, 0x33, 0x87, 0xc1, 0x35,
+	0x54, 0x8a, 0xa0, 0x4b, 0x13, 0x6e, 0x08, 0x13, 0x86, 0x68, 0xf6, 0x0a, 0xfc, 0x1f, 0x54, 0xbd,
+	0xda, 0x6c, 0xb0, 0x94, 0x9d, 0xb7, 0x84, 0x69, 0xb3, 0x57, 0x60, 0x33, 0xcd, 0x65, 0x9a, 0x32,
+	0x7f, 0x2e, 0xcd, 0x74, 0xbe, 0xc7, 0xeb, 0x68, 0x41, 0x03, 0x55, 0x61, 0x9f, 0x0c, 0xa8, 0xe9,
+	0xfb, 0xf3, 0xd5, 0xe9, 0xda, 0x7c, 0x80, 0xd2, 0xa3, 0x67, 0xd4, 0xf4, 0xf1, 0x16, 0xfa, 0xc8,
+	0x40, 0x3c, 0x90, 0x8a, 0xaa, 0x11, 0xd1, 0x61, 0x1f, 0x62, 0x9a, 0xbe, 0x07, 0xe4, 0x94, 0x56,
+	0x0a, 0x63, 0xdb, 0xd9, 0xdc, 0x9b, 0xd8, 0x43, 0xf3, 0x1a, 0x86, 0x44, 0x1b, 0x6a, 0xc0, 0x5f,
+	0x70, 0xa9, 0xd9, 0xb8, 0x34, 0x66, 0x6d, 0x18, 0x26, 0x20, 0x42, 0x68, 0x5b, 0x46, 0x96, 0x93,
+	0x39, 0x0d, 0x43, 0xb7, 0xc7, 0xf7, 0xd0, 0xb5, 0x3f, 0x48, 0x75, 0xb8, 0x07, 0xf1, 0x13, 0x16,
+	0x33, 0xe3, 0x5f, 0xab, 0x7a, 0xb5, 0xe9, 0xe0, 0xdc, 0x19, 0xde, 0x45, 0xd7, 0xb8, 0x0c, 0x0f,
+	0x89, 0x2d, 0x1c, 0x99, 0x18, 0x7f, 0xd9, 0xdd, 0x7a, 0xab, 0x9e, 0x16, 0x45, 0x3d, 0x2f, 0x8a,
+	0xfa, 0x76, 0x56, 0x14, 0xcd, 0x39, 0x7b, 0xc9, 0x5f, 0xfe, 0xbd, 0xee, 0x05, 0x0b, 0x96, 0xf8,
+	0x3c, 0xe5, 0xd9, 0x58, 0x31, 0x61, 0xec, 0xfb, 0xe3, 0x7e, 0xc9, 0x65, 0xa1, 0xd8, 0xe3, 0xdf,
+	0xa0, 0x35, 0x29, 0x48, 0x32, 0xb0, 0xa5, 0x48, 0x14, 0xf4, 0x65, 0x0c, 0x44, 0xc9, 0x23, 0x02,
+	0x82, 0x76, 0x38, 0x44, 0xfe, 0x75, 0x87, 0xf7, 0xa5, 0x38, 0x70, 0x90, 0xc0, 0x21, 0x02, 0x79,
+	0xb4, 0x93, 0xda, 0xf1, 0x01, 0xaa, 0xbd, 0x90, 0x4c, 0x10, 0x05, 0x34, 0x02, 0x45, 0xa4, 0x8a,
+	0x40, 0xd9, 0x57, 0xa0, 0x8d, 0xa2, 0x06, 0x7a, 0x23, 0xd2, 0xa1, 0x26, 0xec, 0xa7, 0x99, 0xc4,
+	0xee, 0x37, 0x7e, 0x6c, 0xf1, 0x81, 0x83, 0xef, 0x67, 0xe8, 0x76, 0x06, 0x6e, 0x5a, 0xac, 0x4b,
+	0xef, 0x1f, 0xd1, 0xc6, 0x80, 0x2a, 0xca, 0x39, 0x70, 0xf7, 0x50, 0x13, 0x6e, 0x18, 0x39, 0x84,
+	0x11, 0xe1, 0x52, 0x1e, 0x26, 0x03, 0x62, 0x35, 0x74, 0xe1, 0xe4, 0x8a, 0x73, 0xf2, 0xd3, 0x09,
+	0xc6, 0x9e, 0x25, 0x3c, 0x86, 0xd1, 0x13, 0x07, 0x7f, 0x64, 0xd1, 0xb9, 0xc7, 0xbf, 0x45, 0x6b,
+	0x46, 0xb1, 0x9e, 0xa2, 0x31, 0xd1, 0x2c, 0x66, 0x9c, 0xda, 0x5a, 0x25, 0xa6, 0xaf, 0x40, 0xf7,
+	0x25, 0x8f, 0xfc, 0xd5, 0xaa, 0x57, 0xf3, 0x82, 0x72, 0x86, 0x69, 0x17, 0x90, 0xe7, 0x39, 0x02,
+	0x6f, 0xa2, 0x55, 0xa3, 0x64, 0xd2, 0xe1, 0x76, 0x2f, 0xdd, 0xa3, 0x77, 0x95, 0xf4, 0x91, 0x73,
+	0x63, 0xe5, 0x82, 0xcd, 0xd5, 0xc7, 0x57, 0xe8, 0xc7, 0x93, 0x61, 0x12, 0xf2, 0xf2, 0x48, 0xdd,
+	0x70, 0x91, 0xfa, 0x74, 0x1c, 0xa9, 0xa7, 0xf2, 0xff, 0xc7, 0xea, 0x4b, 0xb4, 0x31, 0xa9, 0xcd,
+	0x44, 0x04, 0xc7, 0x2e, 0x40, 0xef, 0x94, 0xbe, 0xe9, 0xa4, 0x3f, 0x19, 0x4b, 0xb7, 0x2c, 0xde,
+	0x46, 0xe8, 0xfb, 0xca, 0x4d, 0x54, 0x39, 0xaf, 0x06, 0x34, 0x06, 0x35, 0xa9, 0xe6, 0x3b, 0xb5,
+	0x32, 0x9b, 0xd0, 0x70, 0x98, 0xb1, 0xc6, 0x03, 0x74, 0x27, 0x62, 0xca, 0xf6, 0x81, 0x50, 0xf2,
+	0x24, 0x16, 0x54, 0x11, 0x1d, 0xd2, 0x89, 0xe4, 0xdd, 0x72, 0x51, 0x2b, 0xa7, 0xa0, 0x87, 0x19,
+	0xa6, 0x6d, 0x21, 0x79, 0xc6, 0x7e, 0x8d, 0xca, 0x79, 0x57, 0x30, 0x70, 0x6c, 0x48, 0x56, 0xdc,
+	0x59, 0x9b, 0x2c, 0xbb, 0x9a, 0xbd, 0x99, 0x21, 0x9e, 0xc3, 0xb1, 0x69, 0x3b, 0x7b, 0xd6, 0xf0,
+	0x5a, 0xe8, 0x6e, 0xe1, 0x38, 0xe5, 0x47, 0x74, 0xa4, 0x49, 0x4c, 0x99, 0x30, 0x94, 0x89, 0x22,
+	0x07, 0xfe, 0x6d, 0xe7, 0x43, 0x25, 0x07, 0x3e, 0x70, 0xb8, 0xbd, 0x0c, 0x96, 0x47, 0x1e, 0x7f,
+	0x8d, 0x7e, 0x5a, 0x48, 0xe5, 0x6c, 0x02, 0xb4, 0x07, 0x8a, 0xc4, 0x10, 0x4b, 0x35, 0x22, 0x89,
+	0xa6, 0x3d, 0x20, 0x5d, 0x45, 0x43, 0xd7, 0x98, 0xd6, 0xdc, 0x53, 0xfa, 0x51, 0x4e, 0x6a, 0xa5,
+	0x52, 0x3b, 0x96, 0xb1, 0xe7, 0x08, 0x07, 0x16, 0xbf, 0x9b, 0xc1, 0x31, 0xa0, 0xcd, 0x42, 0x5f,
+	0x26, 0x86, 0xc8, 0xee, 0x07, 0xdc, 0x71, 0xc7, 0xdd, 0xb1, 0x91, 0x13, 0xf7, 0x13, 0xb3, 0xdf,
+	0xbd, 0xfc, 0x9a, 0xc7, 0xe8, 0xe3, 0xe2, 0x9a, 0x3e, 0xd0, 0xc8, 0xde, 0xc3, 0x99, 0x00, 0x22,
+	0x05, 0x1f, 0x8d, 0x85, 0x2b, 0x4e, 0xb8, 0x88, 0xc9, 0xef, 0x80, 0x46, 0xfb, 0xdd, 0x27, 0x4c,
+	0xc0, 0xbe, 0xe0, 0xa3, 0x42, 0xec, 0x57, 0xe8, 0x56, 0xc4, 0xb4, 0xd1, 0x43, 0x4e, 0x06, 0x9c,
+	0x0a, 0xd2, 0xa3, 0x06, 0x8e, 0xe8, 0x88, 0x74, 0x18, 0xd5, 0xfe, 0xba, 0x7b, 0x1d, 0x37, 0x32,
+	0xc0, 0x33, 0x4e, 0xc5, 0xe7, 0xa9, 0xb9, 0xc9, 0xa8, 0xb6, 0x1f, 0xe4, 0xc2, 0x8f, 0xfc, 0x31,
+	0x54, 0x5d, 0x22, 0x96, 0xf3, 0xf3, 0xfc, 0x05, 0x3c, 0xb5, 0xdf, 0x05, 0x1a, 0x9d, 0xeb, 0x86,
+	0x77, 0x3f, 0xbc, 0x1b, 0x2e, 0xe7, 0xe4, 0xac, 0x23, 0x3e, 0x9a, 0x99, 0x5b, 0x2c, 0x2d, 0x3d,
+	0x9a, 0x99, 0x5b, 0x2a, 0x2d, 0xdf, 0xfb, 0xe7, 0x15, 0xb4, 0xfa, 0xae, 0xcf, 0x28, 0xfe, 0x1a,
+	0xad, 0x74, 0x46, 0x06, 0xec, 0x4b, 0xb5, 0x93, 0x0e, 0xe9, 0x4a, 0x15, 0x53, 0xe3, 0xe6, 0x8a,
+	0xf7, 0x7d, 0x2f, 0x9b, 0x96, 0xb7, 0xe3, 0x68, 0xbb, 0x8e, 0x15, 0x5c, 0xef, 0x5c, 0x3c, 0xc2,
+	0x3f, 0x41, 0x18, 0x8e, 0x8d, 0xa2, 0xa4, 0xcb, 0x25, 0x35, 0x24, 0x62, 0x3d, 0x66, 0xb4, 0x1b,
+	0x49, 0x66, 0x83, 0x92, 0xb3, 0xec, 0x5a, 0xc3, 0xb6, 0x3b, 0xc7, 0x7b, 0x68, 0xc9, 0x35, 0xed,
+	0x97, 0x94, 0x13, 0x6d, 0x46, 0x1c, 0xdc, 0x5c, 0xb2, 0xb4, 0xf5, 0xc3, 0x09, 0x47, 0xec, 0x74,
+	0x55, 0x2f, 0x46, 0xa4, 0x56, 0x06, 0x6f, 0x5b, 0x74, 0xb0, 0xc8, 0x26, 0xb7, 0xf8, 0x29, 0x42,
+	0xae, 0xe5, 0xa7, 0x52, 0xe9, 0xa8, 0xf1, 0xd9, 0x45, 0xa9, 0x7c, 0x62, 0xab, 0x67, 0xa3, 0xda,
+	0x36, 0x35, 0xe0, 0xe8, 0xd9, 0xe7, 0x6c, 0x3e, 0xca, 0x0f, 0xee, 0xfd, 0xcb, 0x43, 0x8b, 0xe7,
+	0xbe, 0x78, 0xb8, 0x89, 0x66, 0x34, 0x0c, 0xb5, 0xef, 0x55, 0xa7, 0x6b, 0x0b, 0xef, 0x89, 0xd7,
+	0x39, 0xa6, 0xdd, 0x05, 0x8e, 0x8b, 0xef, 0xa3, 0x55, 0x4e, 0xb5, 0xad, 0xf8, 0x21, 0x61, 0x22,
+	0x54, 0x10, 0x83, 0x30, 0x10, 0xb9, 0x20, 0x2d, 0x06, 0xd8, 0xda, 0xda, 0x30, 0x6c, 0x8d, 0x2d,
+	0xe5, 0x5d, 0x34, 0xdd, 0x86, 0x21, 0xae, 0xa2, 0xab, 0x8e, 0x13, 0xb9, 0x74, 0x2d, 0x36, 0xe7,
+	0xcf, 0xde, 0xac, 0xcf, 0x5a, 0xe8, 0x76, 0x30, 0xab, 0x61, 0xd8, 0x8a, 0xf0, 0x1d, 0x84, 0x38,
+	0xb5, 0xc3, 0x08, 0x79, 0x49, 0xb9, 0x13, 0x9c, 0x0e, 0xe6, 0xd3, 0x93, 0x2f, 0x28, 0xdf, 0xf8,
+	0xce, 0x43, 0xd7, 0xbf, 0x37, 0xf5, 0xe0, 0x3b, 0x68, 0x36, 0x11, 0x1a, 0x4c, 0x69, 0xaa, 0x8c,
+	0x4f, 0x4e, 0xab, 0x4b, 0x05, 0xe2, 0xc0, 0x9e, 0xe2, 0x9f, 0xa3, 0xeb, 0x11, 0x0c, 0x14, 0x84,
+	0xd4, 0x40, 0xb4, 0x75, 0x7f, 0x93, 0x26, 0x46, 0x96, 0xbc, 0x72, 0xe5, 0xe4, 0xb4, 0x5a, 0xde,
+	0x2e, 0x0c, 0x05, 0x69, 0xeb, 0xfe, 0xe6, 0x83, 0xc4, 0x48, 0x7c, 0x13, 0x5d, 0x91, 0xa2, 0x74,
+	0xa5, 0xbc, 0x7c, 0x72, 0x5a, 0x5d, 0x28, 0xac, 0xfb, 0x02, 0xff, 0x12, 0xad, 0xc0, 0xf1, 0x00,
+	0x14, 0xb3, 0x3f, 0x8e, 0xf2, 0xac, 0x7f, 0x95, 0xa6, 0xcb, 0xeb, 0x27, 0xa7, 0xd5, 0xdb, 0x13,
+	0xee, 0x8d, 0x31, 0x69, 0xeb, 0xc2, 0xb7, 0xd0, 0xb4, 0xec, 0x76, 0x4b, 0x33, 0xe5, 0xd2, 0xc9,
+	0x69, 0xf5, 0xda, 0x58, 0xb3, 0xdb, 0x2d, 0xcf, 0xfd, 0xe9, 0xaf, 0x95, 0xa9, 0xbf, 0xff, 0xad,
+	0x32, 0xd5, 0xfc, 0xf2, 0xf5, 0x77, 0x95, 0xa9, 0xd7, 0x67, 0x15, 0xef, 0x9b, 0xb3, 0x8a, 0xf7,
+	0xed, 0x59, 0xc5, 0xfb, 0xcf, 0x59, 0xc5, 0xfb, 0xf3, 0xdb, 0xca, 0xd4, 0x37, 0x6f, 0x2b, 0x53,
+	0xdf, 0xbe, 0xad, 0x4c, 0x7d, 0xf5, 0x8b, 0x0f, 0x1b, 0x78, 0x2f, 0xfe, 0x53, 0xd1, 0xb9, 0xea,
+	0xaa, 0xf1, 0x67, 0xff, 0x0b, 0x00, 0x00, 0xff, 0xff, 0x32, 0x89, 0x1f, 0xb5, 0x70, 0x0c, 0x00,
+	0x00,
 }
 
 func (m *SessionData) Marshal() (dAtA []byte, err error) {
@@ -469,6 +484,30 @@ func (m *SessionData) MarshalToSizedBuffer(dAtA []byte) (int, error) {
 	_ = i
 	var l int
 	_ = l
+	if m.DeadlockTimeout != 0 {
+		n1, err1 := github_com_gogo_protobuf_types.StdDurationMarshalTo(m.DeadlockTimeout, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdDuration(m.DeadlockTimeout):])
+		if err1 != nil {
+			return 0, err1
+		}
+		i -= n1
+		i = encodeVarintSessionData(dAtA, i, uint64(n1))
+		i--
+		dAtA[i] = 0x2
+		i--
+		dAtA[i] = 0x8a
+	}
+	if m.StreamerEnabled {
+		i--
+		if m.StreamerEnabled {
+			dAtA[i] = 1
+		} else {
+			dAtA[i] = 0
+		}
+		i--
+		dAtA[i] = 0x2
+		i--
+		dAtA[i] = 0x80
+	}
 	if m.DistsqlPlanGatewayBias != 0 {
 		i = encodeVarintSessionData(dAtA, i, uint64(m.DistsqlPlanGatewayBias))
 		i--
@@ -617,14 +656,16 @@ func (m *SessionData) MarshalToSizedBuffer(dAtA []byte) (int, error) {
 		i--
 		dAtA[i] = 0x80
 	}
-	n1, err1 := github_com_gogo_protobuf_types.StdDurationMarshalTo(m.LockTimeout, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdDuration(m.LockTimeout):])
-	if err1 != nil {
-		return 0, err1
+	if m.LockTimeout != 0 {
+		n2, err2 := github_com_gogo_protobuf_types.StdDurationMarshalTo(m.LockTimeout, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdDuration(m.LockTimeout):])
+		if err2 != nil {
+			return 0, err2
+		}
+		i -= n2
+		i = encodeVarintSessionData(dAtA, i, uint64(n2))
+		i--
+		dAtA[i] = 0x7a
 	}
-	i -= n1
-	i = encodeVarintSessionData(dAtA, i, uint64(n1))
-	i--
-	dAtA[i] = 0x7a
 	if m.WorkMemLimit != 0 {
 		i = encodeVarintSessionData(dAtA, i, uint64(m.WorkMemLimit))
 		i--
@@ -899,8 +940,10 @@ func (m *SessionData) Size() (n int) {
 	if m.WorkMemLimit != 0 {
 		n += 1 + sovSessionData(uint64(m.WorkMemLimit))
 	}
-	l = github_com_gogo_protobuf_types.SizeOfStdDuration(m.LockTimeout)
-	n += 1 + l + sovSessionData(uint64(l))
+	if m.LockTimeout != 0 {
+		l = github_com_gogo_protobuf_types.SizeOfStdDuration(m.LockTimeout)
+		n += 1 + l + sovSessionData(uint64(l))
+	}
 	if m.Internal {
 		n += 3
 	}
@@ -950,6 +993,13 @@ func (m *SessionData) Size() (n int) {
 	if m.DistsqlPlanGatewayBias != 0 {
 		n += 2 + sovSessionData(uint64(m.DistsqlPlanGatewayBias))
 	}
+	if m.StreamerEnabled {
+		n += 3
+	}
+	if m.DeadlockTimeout != 0 {
+		l = github_com_gogo_protobuf_types.SizeOfStdDuration(m.DeadlockTimeout)
+		n += 2 + l + sovSessionData(uint64(l))
+	}
 	return n
 }
 
@@ -1007,7 +1057,7 @@ func (m *SequenceState_Seq) Size() (n int) {
 }
 
 func sovSessionData(x uint64) (n int) {
-	return (math_bits.Len64(x|1) + 6) / 7
+	return int((uint32(math_bits.Len64(x|1)+6) * 37) >> 8)
 }
 func sozSessionData(x uint64) (n int) {
 	return sovSessionData(uint64((x << 1) ^ uint64((int64(x) >> 63))))
@@ -1700,6 +1750,59 @@ func (m *SessionData) Unmarshal(dAtA []byte) error {
 					break
 				}
 			}
+		case 32:
+			if wireType != 0 {
+				return fmt.Errorf("proto: wrong wireType = %d for field StreamerEnabled", wireType)
+			}
+			var v int
+			for shift := uint(0); ; shift += 7 {
+				if shift >= 64 {
+					return ErrIntOverflowSessionData
+				}
+				if iNdEx >= l {
+					return io.ErrUnexpectedEOF
+				}
+				b := dAtA[iNdEx]
+				iNdEx++
+				v |= int(b&0x7F) << shift
+				if b < 0x80 {
+					break
+				}
+			}
+			m.StreamerEnabled = bool(v != 0)
+		case 33:
+			if wireType != 2 {
+				return fmt.Errorf("proto: wrong wireType = %d for field DeadlockTimeout", wireType)
+			}
+			var msglen int
+			for shift := uint(0); ; shift += 7 {
+				if shift >= 64 {
+					return ErrIntOverflowSessionData
+				}
+				if iNdEx >= l {
+					return io.ErrUnexpectedEOF
+				}
+				b := dAtA[iNdEx]
+				iNdEx++
+				msglen |= int(b&0x7F) << shift
+				if b < 0x80 {
+					break
+				}
+			}
+			if msglen < 0 {
+				return ErrInvalidLengthSessionData
+			}
+			postIndex := iNdEx + msglen
+			if postIndex < 0 {
+				return ErrInvalidLengthSessionData
+			}
+			if postIndex > l {
+				return io.ErrUnexpectedEOF
+			}
+			if err := github_com_gogo_protobuf_types.StdDurationUnmarshal(&m.DeadlockTimeout, dAtA[iNdEx:postIndex]); err != nil {
+				return err
+			}
+			iNdEx = postIndex
 		default:
 			iNdEx = preIndex
 			skippy, err := skipSessionData(dAtA[iNdEx:])
diff --git a/pkg/sql/sessiondatapb/session_data.proto b/pkg/sql/sessiondatapb/session_data.proto
index 61b86a9..6c90e9d 100644
--- a/pkg/sql/sessiondatapb/session_data.proto
+++ b/pkg/sql/sessiondatapb/session_data.proto
@@ -1,12 +1,7 @@
 // Copyright 2020 The Cockroach Authors.
 //
-// Use of this software is governed by the Business Source License
-// included in the file licenses/BSL.txt.
-//
-// As of the Change Date specified in that file, in accordance with
-// the Business Source License, use of this software will be governed
-// by the Apache License, Version 2.0, included in the file
-// licenses/APL.txt.
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
 
 syntax = "proto3";
 package cockroach.sql.sessiondatapb;
@@ -142,6 +137,12 @@ message SessionData {
   // could be adopted by any node in the cluster (not necessarily the gateway)
   // and so we will need this information available on all nodes.
   int64 distsql_plan_gateway_bias = 31;
+  // StreamerEnabled controls whether the Streamer API can be used.
+  bool streamer_enabled = 32;
+  // DeadlockTimeout specifies the amount of time before pushing the lock holder
+  // for deadlock detection.
+  google.protobuf.Duration deadlock_timeout = 33 [(gogoproto.nullable) = false,
+    (gogoproto.stdduration) = true];
 }
 
 // DataConversionConfig contains the parameters that influence the output
@@ -160,7 +161,7 @@ message DataConversionConfig {
   util.timeutil.pgdate.DateStyle date_style = 4 [(gogoproto.nullable) = false];
 }
 
-// VectorizeExecMode controls if an when the Executor executes queries using
+// VectorizeExecMode controls if and when the Executor executes queries using
 // the columnar execution engine.
 enum VectorizeExecMode {
   option (gogoproto.goproto_enum_prefix) = false;
@@ -170,7 +171,10 @@ enum VectorizeExecMode {
   // the first enum value as zero is required by proto3. This is mapped to
   // VectorizeOn.
   unset = 0 [(gogoproto.enumvalue_customname) = "VectorizeUnset"];
-  reserved 1;
+  // DeprecatedVectorized201Auto is only possible for clusters that have been
+  // upgraded from v21.1 or older and had the old setting of "201auto" which
+  // was mapped to "on" in v21.1. It is now an alias for "on".
+  deprecated201auto = 1 [(gogoproto.enumvalue_customname) = "DeprecatedVectorize201Auto"];
   // VectorizeOn means that any supported queries will be run using the
   // columnar execution.
   on = 2 [(gogoproto.enumvalue_customname) = "VectorizeOn"];
diff --git a/pkg/sql/sessiondatapb/session_migration.pb.go b/pkg/sql/sessiondatapb/session_migration.pb.go
index 3640db8..79217fe 100644
--- a/pkg/sql/sessiondatapb/session_migration.pb.go
+++ b/pkg/sql/sessiondatapb/session_migration.pb.go
@@ -11,6 +11,7 @@ import (
 	io "io"
 	math "math"
 	math_bits "math/bits"
+	slices "slices"
 )
 
 // Reference imports to suppress errors if they are not otherwise used.
@@ -221,20 +222,29 @@ func (m *MigratableSession_PreparedStatement) MarshalToSizedBuffer(dAtA []byte)
 		dAtA[i] = 0x1a
 	}
 	if len(m.PlaceholderTypeHints) > 0 {
-		dAtA4 := make([]byte, len(m.PlaceholderTypeHints)*10)
-		var j3 int
-		for _, num := range m.PlaceholderTypeHints {
-			for num >= 1<<7 {
-				dAtA4[j3] = uint8(uint64(num)&0x7f | 0x80)
-				num >>= 7
+		l := 0
+		for _, e := range m.PlaceholderTypeHints {
+			l += sovSessionMigration(uint64(e))
+		}
+		i -= l
+		if l == len(m.PlaceholderTypeHints) {
+			dest := dAtA[i : i+len(m.PlaceholderTypeHints)]
+			for k, num := range m.PlaceholderTypeHints {
+				dest[k] = uint8(num)
+			}
+		} else {
+			j3 := i
+			for _, num := range m.PlaceholderTypeHints {
+				for num >= 1<<7 {
+					dAtA[j3] = uint8(uint64(num)&0x7f | 0x80)
+					num >>= 7
+					j3++
+				}
+				dAtA[j3] = uint8(num)
 				j3++
 			}
-			dAtA4[j3] = uint8(num)
-			j3++
 		}
-		i -= j3
-		copy(dAtA[i:], dAtA4[:j3])
-		i = encodeVarintSessionMigration(dAtA, i, uint64(j3))
+		i = encodeVarintSessionMigration(dAtA, i, uint64(uint64(l)))
 		i--
 		dAtA[i] = 0x12
 	}
@@ -303,7 +313,7 @@ func (m *MigratableSession_PreparedStatement) Size() (n int) {
 }
 
 func sovSessionMigration(x uint64) (n int) {
-	return (math_bits.Len64(x|1) + 6) / 7
+	return int((uint32(math_bits.Len64(x|1)+6) * 37) >> 8)
 }
 func sozSessionMigration(x uint64) (n int) {
 	return sovSessionMigration(uint64((x << 1) ^ uint64((int64(x) >> 63))))
@@ -571,8 +581,12 @@ func (m *MigratableSession_PreparedStatement) Unmarshal(dAtA []byte) error {
 					}
 				}
 				elementCount = count
-				if elementCount != 0 && len(m.PlaceholderTypeHints) == 0 {
-					m.PlaceholderTypeHints = make([]github_com_lib_pq_oid.Oid, 0, elementCount)
+				if elementCount != 0 {
+					if m.PlaceholderTypeHints == nil {
+						m.PlaceholderTypeHints = make([]github_com_lib_pq_oid.Oid, 0, elementCount)
+					} else {
+						m.PlaceholderTypeHints = slices.Grow(m.PlaceholderTypeHints, elementCount)
+					}
 				}
 				for iNdEx < postIndex {
 					var v github_com_lib_pq_oid.Oid
diff --git a/pkg/sql/sessiondatapb/session_migration.proto b/pkg/sql/sessiondatapb/session_migration.proto
index b454737..87dc72f 100644
--- a/pkg/sql/sessiondatapb/session_migration.proto
+++ b/pkg/sql/sessiondatapb/session_migration.proto
@@ -1,12 +1,7 @@
 // Copyright 2021 The Cockroach Authors.
 //
-// Use of this software is governed by the Business Source License
-// included in the file licenses/BSL.txt.
-//
-// As of the Change Date specified in that file, in accordance with
-// the Business Source License, use of this software will be governed
-// by the Apache License, Version 2.0, included in the file
-// licenses/APL.txt.
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
 
 syntax = "proto3";
 package cockroach.sql.sessiondatapb;
diff --git a/pkg/sql/sessiondatapb/session_revival_token.pb.go b/pkg/sql/sessiondatapb/session_revival_token.pb.go
index 026e672..39f221d 100644
--- a/pkg/sql/sessiondatapb/session_revival_token.pb.go
+++ b/pkg/sql/sessiondatapb/session_revival_token.pb.go
@@ -288,7 +288,7 @@ func (m *SessionRevivalToken_Payload) Size() (n int) {
 }
 
 func sovSessionRevivalToken(x uint64) (n int) {
-	return (math_bits.Len64(x|1) + 6) / 7
+	return int((uint32(math_bits.Len64(x|1)+6) * 37) >> 8)
 }
 func sozSessionRevivalToken(x uint64) (n int) {
 	return sovSessionRevivalToken(uint64((x << 1) ^ uint64((int64(x) >> 63))))
diff --git a/pkg/sql/sessiondatapb/session_revival_token.proto b/pkg/sql/sessiondatapb/session_revival_token.proto
index 0a7d2ef..8721ef4 100644
--- a/pkg/sql/sessiondatapb/session_revival_token.proto
+++ b/pkg/sql/sessiondatapb/session_revival_token.proto
@@ -1,12 +1,7 @@
 // Copyright 2022 The Cockroach Authors.
 //
-// Use of this software is governed by the Business Source License
-// included in the file licenses/BSL.txt.
-//
-// As of the Change Date specified in that file, in accordance with
-// the Business Source License, use of this software will be governed
-// by the Apache License, Version 2.0, included in the file
-// licenses/APL.txt.
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
 
 syntax = "proto3";
 package cockroach.sql.sessiondatapb;
diff --git a/pkg/sql/types/alias.go b/pkg/sql/types/alias.go
index a4d507f..d8e0b5a 100644
--- a/pkg/sql/types/alias.go
+++ b/pkg/sql/types/alias.go
@@ -1,12 +1,7 @@
 // Copyright 2020 The Cockroach Authors.
 //
-// Use of this software is governed by the Business Source License
-// included in the file licenses/BSL.txt.
-//
-// As of the Change Date specified in that file, in accordance with
-// the Business Source License, use of this software will be governed
-// by the Apache License, Version 2.0, included in the file
-// licenses/APL.txt.
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
 
 package types
 
diff --git a/pkg/sql/types/oid.go b/pkg/sql/types/oid.go
index e360db9..e73b403 100644
--- a/pkg/sql/types/oid.go
+++ b/pkg/sql/types/oid.go
@@ -1,12 +1,7 @@
 // Copyright 2017 The Cockroach Authors.
 //
-// Use of this software is governed by the Business Source License
-// included in the file licenses/BSL.txt.
-//
-// As of the Change Date specified in that file, in accordance with
-// the Business Source License, use of this software will be governed
-// by the Apache License, Version 2.0, included in the file
-// licenses/APL.txt.
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
 
 package types
 
@@ -59,10 +54,11 @@ var (
 // instead of a method so that other packages can iterate over the map directly.
 // Note that additional elements for the array Oid types are added in init().
 var OidToType = map[oid.Oid]*T{
-	oid.T_anyelement: Any,
+	oid.T_anyelement: AnyElement,
+	oid.T_any:        Any,
 	oid.T_bit:        typeBit,
 	oid.T_bool:       Bool,
-	oid.T_bpchar:     typeBpChar,
+	oid.T_bpchar:     BPChar,
 	oid.T_bytea:      Bytes,
 	oid.T_char:       QChar,
 	oid.T_date:       Date,
@@ -97,6 +93,7 @@ var OidToType = map[oid.Oid]*T{
 	oid.T_timetz:       TimeTZ,
 	oid.T_timestamp:    Timestamp,
 	oid.T_timestamptz:  TimestampTZ,
+	oid.T_trigger:      Trigger,
 	oid.T_tsquery:      TSQuery,
 	oid.T_tsvector:     TSVector,
 	oid.T_unknown:      Unknown,
@@ -108,6 +105,8 @@ var OidToType = map[oid.Oid]*T{
 	oidext.T_geometry:  Geometry,
 	oidext.T_geography: Geography,
 	oidext.T_box2d:     Box2D,
+	oidext.T_pgvector:  PGVector,
+	oidext.T_jsonpath:  Jsonpath,
 }
 
 // oidToArrayOid maps scalar type Oids to their corresponding array type Oid.
@@ -155,6 +154,8 @@ var oidToArrayOid = map[oid.Oid]oid.Oid{
 	oidext.T_geometry:  oidext.T__geometry,
 	oidext.T_geography: oidext.T__geography,
 	oidext.T_box2d:     oidext.T__box2d,
+	oidext.T_pgvector:  oidext.T__pgvector,
+	oidext.T_jsonpath:  oidext.T__jsonpath,
 }
 
 // familyToOid maps each type family to a default OID value that is used when
@@ -191,6 +192,8 @@ var familyToOid = map[Family]oid.Oid{
 	GeometryFamily:  oidext.T_geometry,
 	GeographyFamily: oidext.T_geography,
 	Box2DFamily:     oidext.T_box2d,
+	PGVectorFamily:  oidext.T_pgvector,
+	JsonpathFamily:  oidext.T_jsonpath,
 }
 
 // ArrayOids is a set of all oids which correspond to an array type.
diff --git a/pkg/sql/types/testutils.go b/pkg/sql/types/testutils.go
index c73da08..ab9d271 100644
--- a/pkg/sql/types/testutils.go
+++ b/pkg/sql/types/testutils.go
@@ -1,12 +1,7 @@
 // Copyright 2021 The Cockroach Authors.
 //
-// Use of this software is governed by the Business Source License
-// included in the file licenses/BSL.txt.
-//
-// As of the Change Date specified in that file, in accordance with
-// the Business Source License, use of this software will be governed
-// by the Apache License, Version 2.0, included in the file
-// licenses/APL.txt.
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
 
 package types
 
diff --git a/pkg/sql/types/types.go b/pkg/sql/types/types.go
index f22825e..bf02abe 100644
--- a/pkg/sql/types/types.go
+++ b/pkg/sql/types/types.go
@@ -1,12 +1,7 @@
 // Copyright 2015 The Cockroach Authors.
 //
-// Use of this software is governed by the Business Source License
-// included in the file licenses/BSL.txt.
-//
-// As of the Change Date specified in that file, in accordance with
-// the Business Source License, use of this software will be governed
-// by the Apache License, Version 2.0, included in the file
-// licenses/APL.txt.
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
 
 package types
 
@@ -14,7 +9,6 @@ import (
 	"bytes"
 	"fmt"
 	"regexp"
-	"runtime/debug"
 	"strings"
 
 	"github.com/cockroachdb/cockroachdb-parser/pkg/geo/geopb"
@@ -23,6 +17,7 @@ import (
 	"github.com/cockroachdb/cockroachdb-parser/pkg/sql/pgwire/pgcode"
 	"github.com/cockroachdb/cockroachdb-parser/pkg/sql/pgwire/pgerror"
 	"github.com/cockroachdb/cockroachdb-parser/pkg/sql/sem/catid"
+	"github.com/cockroachdb/cockroachdb-parser/pkg/util/debugutil"
 	"github.com/cockroachdb/cockroachdb-parser/pkg/util/errorutil/unimplemented"
 	"github.com/cockroachdb/cockroachdb-parser/pkg/util/protoutil"
 	"github.com/cockroachdb/errors"
@@ -91,6 +86,7 @@ import (
 // | TIMETZ            | TIMETZ         | T_timetz      | 0         | 0     |
 // | JSON              | JSONB          | T_json        | 0         | 0     |
 // | JSONB             | JSONB          | T_jsonb       | 0         | 0     |
+// | JSONPATH          | JSONPATH       | T_jsonpath    | 0         | 0     |
 // |                   |                |               |           |       |
 // | BYTES             | BYTES          | T_bytea       | 0         | 0     |
 // |                   |                |               |           |       |
@@ -100,6 +96,7 @@ import (
 // | VARCHAR(N)        | STRING         | T_varchar     | 0         | N     |
 // | CHAR              | STRING         | T_bpchar      | 0         | 1     |
 // | CHAR(N)           | STRING         | T_bpchar      | 0         | N     |
+// | BPCHAR            | STRING         | T_bpchar      | 0         | 0     |
 // | "char"            | STRING         | T_char        | 0         | 0     |
 // | NAME              | STRING         | T_name        | 0         | 0     |
 // |                   |                |               |           |       |
@@ -119,6 +116,7 @@ import (
 // | FLOAT4            | FLOAT          | T_float4      | 0         | 0     |
 // |                   |                |               |           |       |
 // | BIT               | BIT            | T_bit         | 0         | 1     |
+// | BIT(0)            | BIT            | T_bit         | 0         | 0     |
 // | BIT(N)            | BIT            | T_bit         | 0         | N     |
 // | VARBIT            | BIT            | T_varbit      | 0         | 0     |
 // | VARBIT(N)         | BIT            | T_varbit      | 0         | N     |
@@ -186,6 +184,26 @@ type T struct {
 	TypeMeta UserDefinedTypeMetadata
 }
 
+// CopyForHydrate returns a copy of the type that can be safely hydrated.
+// Recursive type references (as for tuples or arrays) are copied, but other
+// pointer fields are not deeply copied.
+//
+// Copy should be kept in alignment with the struct fields.
+func (t *T) CopyForHydrate() *T {
+	newT := *t
+	if t.InternalType.TupleContents != nil {
+		newTupleContents := make([]*T, len(t.InternalType.TupleContents))
+		for i := range t.InternalType.TupleContents {
+			newTupleContents[i] = t.InternalType.TupleContents[i].CopyForHydrate()
+		}
+		newT.InternalType.TupleContents = newTupleContents
+	}
+	if t.InternalType.ArrayContents != nil {
+		newT.InternalType.ArrayContents = t.InternalType.ArrayContents.CopyForHydrate()
+	}
+	return &newT
+}
+
 // UserDefinedTypeMetadata contains metadata needed for runtime
 // operations on user defined types. The metadata must be read only.
 type UserDefinedTypeMetadata struct {
@@ -247,8 +265,8 @@ func (u UserDefinedTypeName) Basename() string {
 }
 
 // FQName returns the fully qualified name.
-func (u UserDefinedTypeName) FQName() string {
-	return FormatTypeName(u)
+func (u UserDefinedTypeName) FQName(explicitCatalog bool) string {
+	return FormatTypeName(u, explicitCatalog)
 }
 
 // Convenience list of pre-constructed types. Caller code can use any of these
@@ -305,6 +323,14 @@ var (
 	String = &T{InternalType: InternalType{
 		Family: StringFamily, Oid: oid.T_text, Locale: &emptyLocale}}
 
+	// BPChar is a CHAR type with an unspecified width. "BP" stands for
+	// "blank padded".
+	//
+	// It is reported as BPCHAR in SHOW CREATE and "character" in introspection
+	// for compatibility with PostgreSQL.
+	BPChar = &T{InternalType: InternalType{
+		Family: StringFamily, Oid: oid.T_bpchar, Locale: &emptyLocale}}
+
 	// VarChar is equivalent to String, but has a differing OID (T_varchar),
 	// which makes it show up differently when displayed. It is reported as
 	// VARCHAR in SHOW CREATE and "character varying" in introspection for
@@ -467,6 +493,15 @@ var (
 		},
 	}
 
+	// PGVector is the type representing a PGVector object.
+	PGVector = &T{
+		InternalType: InternalType{
+			Family: PGVectorFamily,
+			Oid:    oidext.T_pgvector,
+			Locale: &emptyLocale,
+		},
+	}
+
 	// Void is the type representing void.
 	Void = &T{
 		InternalType: InternalType{
@@ -507,6 +542,15 @@ var (
 		},
 	}
 
+	// Jsonpath is the jsonpath type which represents a jsonpath query.
+	Jsonpath = &T{
+		InternalType: InternalType{
+			Family: JsonpathFamily,
+			Oid:    oidext.T_jsonpath,
+			Locale: &emptyLocale,
+		},
+	}
+
 	// RefCursor is the type for a variable representing the name of a cursor in a
 	// PLpgSQL routine. The underlying value is a string.
 	RefCursor = &T{
@@ -546,21 +590,25 @@ var (
 		TimeTZ,
 		Jsonb,
 		VarBit,
+		// TODO(normanchenn): consider including jsonpath here.
 	}
 
-	// Any is a special type used only during static analysis as a wildcard type
+	Any = &T{InternalType: InternalType{
+		Family: AnyFamily, Oid: oid.T_any, Locale: &emptyLocale}}
+
+	// AnyElement is a special type used only during static analysis as a wildcard type
 	// that matches any other type, including scalar, array, and tuple types.
 	// Execution-time values should never have this type. As an example of its
 	// use, many SQL builtin functions allow an input value to be of any type,
 	// and so use this type in their static definitions.
-	Any = &T{InternalType: InternalType{
+	AnyElement = &T{InternalType: InternalType{
 		Family: AnyFamily, Oid: oid.T_anyelement, Locale: &emptyLocale}}
 
 	// AnyArray is a special type used only during static analysis as a wildcard
 	// type that matches an array having elements of any (uniform) type (including
 	// nested array types). Execution-time values should never have this type.
 	AnyArray = &T{InternalType: InternalType{
-		Family: ArrayFamily, ArrayContents: Any, Oid: oid.T_anyarray, Locale: &emptyLocale}}
+		Family: ArrayFamily, ArrayContents: AnyElement, Oid: oid.T_anyarray, Locale: &emptyLocale}}
 
 	// AnyEnum is a special type only used during static analysis as a wildcard
 	// type that matches an possible enum value. Execution-time values should
@@ -572,7 +620,7 @@ var (
 	// type that matches a tuple with any number of fields of any type (including
 	// tuple types). Execution-time values should never have this type.
 	AnyTuple = &T{InternalType: InternalType{
-		Family: TupleFamily, TupleContents: []*T{Any}, Oid: oid.T_record, Locale: &emptyLocale}}
+		Family: TupleFamily, TupleContents: []*T{AnyElement}, Oid: oid.T_record, Locale: &emptyLocale}}
 
 	// AnyTupleArray is a special type used only during static analysis as a wildcard
 	// type that matches an array of tuples with any number of fields of any type (including
@@ -591,6 +639,11 @@ var (
 	EmptyTuple = &T{InternalType: InternalType{
 		Family: TupleFamily, Oid: oid.T_record, Locale: &emptyLocale}}
 
+	// Trigger is a special type used for trigger functions, which return a row of
+	// their target table.
+	Trigger = &T{InternalType: InternalType{
+		Family: TriggerFamily, Oid: oid.T_trigger, Locale: &emptyLocale}}
+
 	// StringArray is the type of an array value having String-typed elements.
 	StringArray = &T{InternalType: InternalType{
 		Family: ArrayFamily, ArrayContents: String, Oid: oid.T__text, Locale: &emptyLocale}}
@@ -627,6 +680,10 @@ var (
 	PGLSNArray = &T{InternalType: InternalType{
 		Family: ArrayFamily, ArrayContents: PGLSN, Oid: oid.T__pg_lsn, Locale: &emptyLocale}}
 
+	// PGVectorArray is the type of an array value having PGVector-typed elements.
+	PGVectorArray = &T{InternalType: InternalType{
+		Family: ArrayFamily, ArrayContents: PGVector, Oid: oidext.T__pgvector, Locale: &emptyLocale}}
+
 	// RefCursorArray is the type of an array value having REFCURSOR-typed elements.
 	RefCursorArray = &T{InternalType: InternalType{
 		Family: ArrayFamily, ArrayContents: RefCursor, Oid: oid.T__refcursor, Locale: &emptyLocale}}
@@ -678,25 +735,24 @@ var (
 	// by Postgres in system tables. Int2vectors are 0-indexed, unlike normal arrays.
 	Int2Vector = &T{InternalType: InternalType{
 		Family: ArrayFamily, Oid: oid.T_int2vector, ArrayContents: Int2, Locale: &emptyLocale}}
+
+	// JsonpathArray is the type of an array value having Jsonpath-typed elements.
+	JsonpathArray = &T{
+		InternalType: InternalType{
+			Family: ArrayFamily, ArrayContents: Jsonpath, Oid: oidext.T__jsonpath, Locale: &emptyLocale,
+		},
+	}
 )
 
 // Unexported wrapper types.
 var (
-	// typeBit is the SQL BIT type. It is not exported to avoid confusion with
-	// the VarBit type, and confusion over whether its default Width is
-	// unspecified or is 1. More commonly used instead is the VarBit type.
+	// typeBit is the SQL BIT type with an unspecified width. It is not exported
+	// to avoid confusion with the VarBit type, and confusion over whether its
+	// default Width is unspecified or is 1. More commonly used instead is the
+	// VarBit type.
 	typeBit = &T{InternalType: InternalType{
 		Family: BitFamily, Oid: oid.T_bit, Locale: &emptyLocale}}
 
-	// typeBpChar is a CHAR type with an unspecified width. "bp" stands for
-	// "blank padded". It is not exported to avoid confusion with QChar, as well
-	// as confusion over CHAR's default width of 1.
-	//
-	// It is reported as CHAR in SHOW CREATE and "character" in introspection for
-	// compatibility with PostgreSQL.
-	typeBpChar = &T{InternalType: InternalType{
-		Family: StringFamily, Oid: oid.T_bpchar, Locale: &emptyLocale}}
-
 	// typeQChar is a "char" type with an unspecified width. It is not exported
 	// to avoid confusion with QChar. The "char" type should always have a width
 	// of one. A "char" type with an unspecified width is only used when the
@@ -904,7 +960,7 @@ func MakeVarChar(width int32) *T {
 // the given max # characters (0 = unspecified number).
 func MakeChar(width int32) *T {
 	if width == 0 {
-		return typeBpChar
+		return BPChar
 	}
 	if width < 0 {
 		panic(errors.AssertionFailedf("width %d cannot be negative", width))
@@ -936,6 +992,21 @@ func MakeCollatedString(strType *T, locale string) *T {
 	panic(errors.AssertionFailedf("cannot apply collation to non-string type: %s", strType))
 }
 
+// MakeCollatedType is like MakeCollatedString but also handles NULL and arrays
+// of string types that need to become arrays of collated string types.
+//
+// UNKNOWN  => STRING COLLATE EN
+// []STRING => []STRING COLLATE EN
+func MakeCollatedType(typ *T, locale string) *T {
+	if typ.Family() == ArrayFamily {
+		return MakeArray(MakeCollatedType(typ.ArrayContents(), locale))
+	}
+	if typ.Family() == UnknownFamily {
+		return MakeCollatedType(String, locale)
+	}
+	return MakeCollatedString(typ, locale)
+}
+
 // MakeDecimal constructs a new instance of a DECIMAL type (oid = T_numeric)
 // that has at most "precision" # of decimal digits (0 = unspecified number of
 // digits) and at most "scale" # of decimal digits after the decimal point
@@ -1157,9 +1228,11 @@ func MakeEnum(typeOID, arrayTypeOID oid.Oid) *T {
 // MakeArray constructs a new instance of an ArrayFamily type with the given
 // element type (which may itself be an ArrayFamily type).
 func MakeArray(typ *T) *T {
-	// Do not make an array of type unknown[]. Follow Postgres' behavior and
-	// convert this to type string[].
-	if typ.Family() == UnknownFamily {
+	// Do not make an array of type unknown[]. Follow Postgres' behavior and convert
+	// this to type string[]. Likewise, Any does not have an array type, so treat it
+	// as an array of strings.
+	if typ.Family() == UnknownFamily ||
+		(typ.Family() == AnyFamily && typ.Oid() == oid.T_any) {
 		typ = String
 	}
 	arr := &T{InternalType: InternalType{
@@ -1198,6 +1271,17 @@ func MakeLabeledTuple(contents []*T, labels []string) *T {
 	}}
 }
 
+// MakePGVector constructs a new instance of a VECTOR type (pg_vector) that has
+// the given number of dimensions.
+func MakePGVector(dims int32) *T {
+	return &T{InternalType: InternalType{
+		Family: PGVectorFamily,
+		Oid:    oidext.T_pgvector,
+		Width:  dims,
+		Locale: &emptyLocale,
+	}}
+}
+
 // NewCompositeType constructs a new instance of a TupleFamily type with the
 // given field types and labels, and the given user-defined type OIDs.
 func NewCompositeType(typeOID, arrayTypeOID oid.Oid, contents []*T, labels []string) *T {
@@ -1274,6 +1358,7 @@ func (t *T) Locale() string {
 //	STRING        : max # of characters
 //	COLLATEDSTRING: max # of characters
 //	BIT           : max # of bits
+//	VECTOR        : # of dimensions
 //
 // Width is always 0 for other types.
 func (t *T) Width() int32 {
@@ -1324,7 +1409,7 @@ func (t *T) TypeModifier() int32 {
 			// var header size.
 			return width + 4
 		}
-	case BitFamily:
+	case BitFamily, PGVectorFamily:
 		if width := t.Width(); width != 0 {
 			return width
 		}
@@ -1374,6 +1459,9 @@ func (t *T) WithoutTypeModifiers() *T {
 		if !changed {
 			return t
 		}
+		if l := t.TupleLabels(); l != nil {
+			return MakeLabeledTuple(newContents, l)
+		}
 		return MakeTuple(newContents)
 	case EnumFamily:
 		// Enums have no type modifiers.
@@ -1487,12 +1575,14 @@ var familyNames = map[Family]redact.SafeString{
 	JsonFamily:           "jsonb",
 	OidFamily:            "oid",
 	PGLSNFamily:          "pg_lsn",
+	PGVectorFamily:       "vector",
 	RefCursorFamily:      "refcursor",
 	StringFamily:         "string",
 	TimeFamily:           "time",
 	TimestampFamily:      "timestamp",
 	TimestampTZFamily:    "timestamptz",
 	TimeTZFamily:         "timetz",
+	TriggerFamily:        "trigger",
 	TSQueryFamily:        "tsquery",
 	TSVectorFamily:       "tsvector",
 	TupleFamily:          "tuple",
@@ -1500,6 +1590,7 @@ var familyNames = map[Family]redact.SafeString{
 	UuidFamily:           "uuid",
 	VoidFamily:           "void",
 	EncodedKeyFamily:     "encodedkey",
+	JsonpathFamily:       "jsonpath",
 }
 
 // Name returns a user-friendly word indicating the family type.
@@ -1523,7 +1614,12 @@ func (f Family) Name() redact.SafeString {
 func (t *T) Name() string {
 	switch fam := t.Family(); fam {
 	case AnyFamily:
-		return "anyelement"
+		switch t.Oid() {
+		case oid.T_any:
+			return "any"
+		default:
+			return "anyelement"
+		}
 
 	case ArrayFamily:
 		switch t.Oid() {
@@ -1531,6 +1627,8 @@ func (t *T) Name() string {
 			return "oidvector"
 		case oid.T_int2vector:
 			return "int2vector"
+		case oid.T_anyarray:
+			return "anyarray"
 		}
 		return t.ArrayContents().Name() + "[]"
 
@@ -1570,6 +1668,9 @@ func (t *T) Name() string {
 		case oid.T_text:
 			return "string"
 		case oid.T_bpchar:
+			if t.Width() == 0 {
+				return "bpchar"
+			}
 			return "char"
 		case oid.T_char:
 			// Yes, that's the name. The ways of PostgreSQL are inscrutable.
@@ -1668,6 +1769,8 @@ func (t *T) SQLStandardNameWithTypmod(haveTypmod bool, typmod int) string {
 			return "oidvector"
 		case oid.T_int2vector:
 			return "int2vector"
+		case oid.T_anyarray:
+			return "anyarray"
 		}
 		// If we have a typemod specified then pass it down when
 		// formatting the array type.
@@ -1743,6 +1846,8 @@ func (t *T) SQLStandardNameWithTypmod(haveTypmod bool, typmod int) string {
 	case JsonFamily:
 		// Only binary JSON is currently supported.
 		return "jsonb"
+	case JsonpathFamily:
+		return "jsonpath"
 	case OidFamily:
 		switch t.Oid() {
 		case oid.T_oid:
@@ -1764,6 +1869,8 @@ func (t *T) SQLStandardNameWithTypmod(haveTypmod bool, typmod int) string {
 		}
 	case PGLSNFamily:
 		return "pg_lsn"
+	case PGVectorFamily:
+		return "vector"
 	case RefCursorFamily:
 		return "refcursor"
 	case StringFamily, CollatedStringFamily:
@@ -1823,6 +1930,8 @@ func (t *T) SQLStandardNameWithTypmod(haveTypmod bool, typmod int) string {
 			return "timestamp with time zone"
 		}
 		return fmt.Sprintf("timestamp(%d) with time zone", typmod)
+	case TriggerFamily:
+		return "trigger"
 	case TSQueryFamily:
 		return "tsquery"
 	case TSVectorFamily:
@@ -1869,17 +1978,27 @@ func (t *T) InformationSchemaName() string {
 func (t *T) SQLString() string {
 	switch t.Family() {
 	case BitFamily:
-		o := t.Oid()
-		typName := "BIT"
-		if o == oid.T_varbit {
-			typName = "VARBIT"
-		}
-		// BIT(1) pretty-prints as just BIT.
-		if (o != oid.T_varbit && t.Width() > 1) ||
-			(o == oid.T_varbit && t.Width() > 0) {
-			typName = fmt.Sprintf("%s(%d)", typName, t.Width())
+		switch t.Oid() {
+		case oid.T_bit:
+			typName := "BIT"
+			// BIT(1) pretty-prints as just BIT.
+			// BIT(0) represents a BIT type with unspecified length. This is a
+			// divergence from Postgres which does not allow this type and has
+			// no way to represent it in SQL. It is required in order for it to
+			// be correctly serialized into SQL and evaluated during distributed
+			// query execution. VARBIT cannot be used because it has a different
+			// OID.
+			if t.Width() != 1 {
+				typName = fmt.Sprintf("%s(%d)", typName, t.Width())
+			}
+			return typName
+		default:
+			typName := "VARBIT"
+			if t.Width() > 0 {
+				typName = fmt.Sprintf("%s(%d)", typName, t.Width())
+			}
+			return typName
 		}
-		return typName
 	case IntFamily:
 		switch t.Width() {
 		case 16:
@@ -1912,6 +2031,8 @@ func (t *T) SQLString() string {
 	case JsonFamily:
 		// Only binary JSON is currently supported.
 		return "JSONB"
+	case JsonpathFamily:
+		return "JSONPATH"
 	case TimestampFamily, TimestampTZFamily, TimeFamily, TimeTZFamily:
 		if t.InternalType.Precision > 0 || t.InternalType.TimePrecisionIsSet {
 			return fmt.Sprintf("%s(%d)", strings.ToUpper(t.Name()), t.Precision())
@@ -1967,11 +2088,57 @@ func (t *T) SQLString() string {
 		if t.TypeMeta.Name == nil {
 			return fmt.Sprintf("@%d", t.Oid())
 		}
-		return t.TypeMeta.Name.FQName()
+		// Do not include the catalog name. We do not allow a table to reference
+		// a type in another database, so it will always be for the current database.
+		// Removing the catalog name makes the output more portable for other
+		// databases when this function is called to produce DDL like in SHOW
+		// CREATE.
+		return t.TypeMeta.Name.FQName(false /* explicitCatalog */)
+	case TupleFamily:
+		if t.UserDefined() {
+			// We do not expect to be in a situation where we want to format a
+			// user-defined type to a string and do not have the TypeMeta hydrated,
+			// but there have been bugs in the past, and returning a less informative
+			// string is better than a nil-pointer panic.
+			if t.TypeMeta.Name == nil {
+				return fmt.Sprintf("@%d", t.Oid())
+			}
+			// Do not include the catalog name. We do not allow a table to reference
+			// a type in another database, so it will always be for the current database.
+			// Removing the catalog name makes the output more portable for other
+			// databases when this function is called to produce DDL like in SHOW
+			// CREATE.
+			return t.TypeMeta.Name.FQName(false /* explicitCatalog */)
+		}
+		return strings.ToUpper(t.Name())
+	case PGVectorFamily:
+		if t.Width() == 0 {
+			return "VECTOR"
+		}
+		return fmt.Sprintf("VECTOR(%d)", t.Width())
 	}
 	return strings.ToUpper(t.Name())
 }
 
+// SQLStringFullyQualified is a wrapper for SQLString() for when we need the
+// type name to be a fully-qualified 3-part name.
+func (t *T) SQLStringFullyQualified() string {
+	if t.UserDefined() {
+		switch t.Family() {
+		case ArrayFamily:
+			return t.ArrayContents().SQLStringFullyQualified() + "[]"
+		default:
+			if t.TypeMeta.Name != nil {
+				// Include the catalog in the type name. This is necessary to properly
+				// resolve the type, as some code paths require the database name to
+				// correctly distinguish cross-database references.
+				return t.TypeMeta.Name.FQName(true /* explicitCatalog */)
+			}
+		}
+	}
+	return t.SQLString()
+}
+
 // SQLStringForError returns a version of SQLString that will preserve safe
 // information during redaction. It is suitable for usage in error messages.
 func (t *T) SQLStringForError() redact.RedactableString {
@@ -2002,7 +2169,7 @@ func (t *T) SQLStringForError() redact.RedactableString {
 		IntervalFamily, StringFamily, BytesFamily, TimestampTZFamily, CollatedStringFamily, OidFamily,
 		UnknownFamily, UuidFamily, INetFamily, TimeFamily, JsonFamily, TimeTZFamily, BitFamily,
 		GeometryFamily, GeographyFamily, Box2DFamily, VoidFamily, EncodedKeyFamily, TSQueryFamily,
-		TSVectorFamily, AnyFamily, PGLSNFamily, RefCursorFamily:
+		TSVectorFamily, AnyFamily, PGLSNFamily, PGVectorFamily, RefCursorFamily:
 		// These types do not contain other types, and do not require redaction.
 		return redact.Sprint(redact.SafeString(t.SQLString()))
 	}
@@ -2014,7 +2181,7 @@ func (t *T) SQLStringForError() redact.RedactableString {
 // type name. The logic for proper formatting lives in the tree package.
 var FormatTypeName = fallbackFormatTypeName
 
-func fallbackFormatTypeName(UserDefinedTypeName) string {
+func fallbackFormatTypeName(UserDefinedTypeName, bool) string {
 	return "formatting logic has not been injected from tree"
 }
 
@@ -2026,7 +2193,7 @@ func fallbackFormatTypeName(UserDefinedTypeName) string {
 // other attributes of equivalent types, such as width, precision, and oid, can
 // be different.
 //
-// Wildcard types (e.g. Any, AnyArray, AnyTuple, etc) have special equivalence
+// Wildcard types (e.g. AnyElement, AnyArray, AnyTuple, etc) have special equivalence
 // behavior. AnyFamily types match any other type, including other AnyFamily
 // types. And a wildcard collation (empty string) matches any other collation.
 func (t *T) Equivalent(other *T) bool {
@@ -2136,6 +2303,38 @@ func (t *T) Equal(other *T) bool {
 	return t.Identical(other)
 }
 
+// IsWildcardType returns true if the type is only used as a wildcard during
+// static analysis, and cannot be used during execution.
+func (t *T) IsWildcardType() bool {
+	for _, wildcard := range []*T{
+		Any, AnyElement, AnyArray, AnyCollatedString, AnyEnum, AnyEnumArray, AnyTuple, AnyTupleArray,
+	} {
+		// Note that pointer comparison is insufficient since we might have
+		// deserialized t from disk.
+		if t.Identical(wildcard) {
+			return true
+		}
+	}
+	return false
+}
+
+// IsPolymorphicType returns true if the type can be used as the parameter or
+// return-type of a polymorphic function. Note that this does not include RECORD
+// (AnyTuple) or RECORD[].
+func (t *T) IsPolymorphicType() bool {
+	for _, poly := range []*T{AnyElement, AnyArray, AnyEnum, AnyEnumArray} {
+		if t.Identical(poly) {
+			return true
+		}
+	}
+	return false
+}
+
+// IsPseudoType returns true if the type is a pseudotype.
+func (t *T) IsPseudoType() bool {
+	return t.Identical(Trigger) || t.IsPolymorphicType()
+}
+
 // Size returns the size, in bytes, of this type once it has been marshaled to
 // a byte buffer. This is typically called to determine the size of the buffer
 // that needs to be allocated before calling Marshal.
@@ -2673,6 +2872,8 @@ func (t *T) IsNumeric() bool {
 	}
 }
 
+var EnumValueNotFound = errors.New("could not find enum value")
+
 // EnumGetIdxOfPhysical returns the index within the TypeMeta's slice of
 // enum physical representations that matches the input byte slice.
 func (t *T) EnumGetIdxOfPhysical(phys []byte) (int, error) {
@@ -2685,16 +2886,19 @@ func (t *T) EnumGetIdxOfPhysical(phys []byte) (int, error) {
 			return i, nil
 		}
 	}
-	err := errors.Newf(
+	err := errors.Wrapf(EnumValueNotFound,
 		"could not find %v in enum %q representation %s %s",
 		phys,
-		t.TypeMeta.Name.FQName(),
+		t.TypeMeta.Name.FQName(true /* explicitCatalog */),
 		t.TypeMeta.EnumData.debugString(),
-		debug.Stack(),
+		debugutil.Stack(),
 	)
 	return 0, err
 }
 
+// EnumValueNotYetPublicError enum value is not public yet.
+var EnumValueNotYetPublicError = pgerror.New(pgcode.InvalidParameterValue, "enum value is not yet public")
+
 // EnumGetIdxOfLogical returns the index within the TypeMeta's slice of
 // enum logical representations that matches the input string.
 func (t *T) EnumGetIdxOfLogical(logical string) (int, error) {
@@ -2707,7 +2911,7 @@ func (t *T) EnumGetIdxOfLogical(logical string) (int, error) {
 			// written until all nodes in the cluster are able to decode the
 			// physical representation.
 			if t.TypeMeta.EnumData.IsMemberReadOnly[i] {
-				return 0, errors.Newf("enum value %q is not yet public", logical)
+				return 0, errors.WithMessagef(EnumValueNotYetPublicError, "cannot use enum value %q", logical)
 			}
 			return i, nil
 		}
@@ -2742,6 +2946,8 @@ func IsValidArrayElementType(t *T) (valid bool, issueNum int) {
 		return false, 90886
 	case TSVectorFamily:
 		return false, 90886
+	case PGVectorFamily:
+		return false, 121432
 	default:
 		return true, 0
 	}
@@ -2798,13 +3004,6 @@ func IsWildcardTupleType(t *T) bool {
 	return len(t.TupleContents()) == 1 && t.TupleContents()[0].Family() == AnyFamily
 }
 
-// IsRecordType returns true if this is a RECORD type. This should only be used
-// when processing UDFs. A record differs from AnyTuple in that the tuple
-// contents may contain types other than Any.
-func IsRecordType(typ *T) bool {
-	return typ.Family() == TupleFamily && typ.Oid() == oid.T_record
-}
-
 // collatedStringTypeSQL returns the string representation of a COLLATEDSTRING
 // or []COLLATEDSTRING type. This is tricky in the case of an array of collated
 // string, since brackets must precede the COLLATE identifier:
@@ -2831,6 +3030,9 @@ func (t *T) stringTypeSQL() string {
 	case oid.T_varchar:
 		typName = "VARCHAR"
 	case oid.T_bpchar:
+		if t.Width() == 0 {
+			return "BPCHAR"
+		}
 		typName = "CHAR"
 	case oid.T_char:
 		// Yes, that's the name. The ways of PostgreSQL are inscrutable.
@@ -2993,6 +3195,11 @@ func (t *T) Delimiter() string {
 	switch t.Family() {
 	case Geometry.Family(), Geography.Family():
 		return ":"
+	case ArrayFamily:
+		if t.Oid() == oidext.T__geometry || t.Oid() == oidext.T__geography {
+			return ":"
+		}
+		return ","
 	default:
 		return ","
 	}
diff --git a/pkg/sql/types/types.pb.go b/pkg/sql/types/types.pb.go
index f5a49b7..ee4ca50 100644
--- a/pkg/sql/types/types.pb.go
+++ b/pkg/sql/types/types.pb.go
@@ -13,6 +13,7 @@ import (
 	io "io"
 	math "math"
 	math_bits "math/bits"
+	slices "slices"
 )
 
 // Reference imports to suppress errors if they are not otherwise used.
@@ -378,6 +379,19 @@ const (
 	//   Canonical: types.RefCursor
 	//   Oid      : T_refcursor
 	RefCursorFamily Family = 31
+	// PGVectorFamily is a type family for the vector type, which is the
+	// type representing pgvector vectors.
+	PGVectorFamily Family = 32
+	// TriggerFamily is a type family for the trigger type, which is the return
+	// type for trigger functions.
+	//   Canonical: types.Trigger
+	//   Oid      : T_trigger
+	TriggerFamily Family = 33
+	// JsonpathFamily is a type family for the jsonpath type, which is the type
+	// representing JSON path expressions.
+	//  Canonical: types.Jsonpath
+	//  Oid: T_jsonpath
+	JsonpathFamily Family = 34
 	// AnyFamily is a special type family used during static analysis as a
 	// wildcard type that matches any other type, including scalar, array, and
 	// tuple types. Execution-time values should never have this type. As an
@@ -422,6 +436,9 @@ var Family_name = map[int32]string{
 	29:  "TSVectorFamily",
 	30:  "PGLSNFamily",
 	31:  "RefCursorFamily",
+	32:  "PGVectorFamily",
+	33:  "TriggerFamily",
+	34:  "JsonpathFamily",
 	100: "AnyFamily",
 }
 
@@ -457,6 +474,9 @@ var Family_value = map[string]int32{
 	"TSVectorFamily":       29,
 	"PGLSNFamily":          30,
 	"RefCursorFamily":      31,
+	"PGVectorFamily":       32,
+	"TriggerFamily":        33,
+	"JsonpathFamily":       34,
 	"AnyFamily":            100,
 }
 
@@ -800,81 +820,83 @@ func init() {
 func init() { proto.RegisterFile("sql/types/types.proto", fileDescriptor_bc7f16796a7f6725) }
 
 var fileDescriptor_bc7f16796a7f6725 = []byte{
-	// 1184 bytes of a gzipped FileDescriptorProto
-	0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x9c, 0x56, 0xcf, 0x8f, 0xdb, 0x44,
-	0x14, 0xb6, 0x37, 0x3f, 0x36, 0x99, 0xfc, 0x58, 0x77, 0xba, 0x69, 0xdd, 0x05, 0xe2, 0x34, 0x02,
-	0x11, 0x2a, 0x91, 0x88, 0x72, 0x40, 0xaa, 0x84, 0xd0, 0x66, 0x93, 0xa6, 0x29, 0xbb, 0xc9, 0xe2,
-	0x38, 0x85, 0xf6, 0x12, 0x39, 0xf1, 0x24, 0x3b, 0xaa, 0xed, 0x49, 0xed, 0x49, 0xcb, 0x1e, 0xe1,
-	0xd4, 0x63, 0x8f, 0x1c, 0xbb, 0xe2, 0xc0, 0xbf, 0xb2, 0xbd, 0xf5, 0xc0, 0xa1, 0xe2, 0x10, 0x41,
-	0x56, 0xdc, 0x39, 0x73, 0x42, 0x33, 0x1e, 0x3b, 0x5e, 0xd4, 0x2d, 0x2b, 0x2e, 0x91, 0xdf, 0x37,
-	0xef, 0x7d, 0xef, 0x7b, 0x6f, 0x9e, 0x9f, 0x03, 0x4a, 0xfe, 0x13, 0xbb, 0x41, 0x8f, 0xe7, 0xc8,
-	0x0f, 0x7e, 0xeb, 0x73, 0x8f, 0x50, 0x02, 0xaf, 0x4f, 0xc8, 0xe4, 0xb1, 0x47, 0xcc, 0xc9, 0x51,
-	0xdd, 0x7f, 0x62, 0xd7, 0x7d, 0xe4, 0xd4, 0xf9, 0xf1, 0xce, 0xf6, 0x8c, 0xcc, 0x08, 0xf7, 0x69,
-	0xb0, 0xa7, 0xc0, 0x7d, 0xa7, 0x34, 0x43, 0xa4, 0x31, 0x43, 0x64, 0x3e, 0x0e, 0x7e, 0x03, 0xb8,
-	0xfa, 0xab, 0x0c, 0x4a, 0x5d, 0x97, 0x22, 0xef, 0xa9, 0x69, 0xb7, 0x16, 0x9e, 0x49, 0x31, 0x71,
-	0xef, 0x62, 0x64, 0x5b, 0xf0, 0x3b, 0x50, 0xb0, 0x04, 0x30, 0x62, 0xc4, 0xaa, 0x5c, 0x91, 0x6b,
-	0xc5, 0xdb, 0x9f, 0xd6, 0x2f, 0xc8, 0x5b, 0xff, 0x37, 0x8d, 0x71, 0x3c, 0x47, 0xcd, 0xe4, 0xe9,
-	0x52, 0x93, 0xf4, 0xbc, 0x15, 0xc3, 0xa0, 0x09, 0xe0, 0xd4, 0x23, 0xce, 0xe8, 0x3c, 0xfd, 0xc6,
-	0xff, 0xa7, 0x57, 0x18, 0x5d, 0x1c, 0xaf, 0xfe, 0x22, 0x83, 0x5c, 0x07, 0x91, 0x03, 0x44, 0x4d,
-	0xcb, 0xa4, 0x26, 0xfc, 0x16, 0x24, 0x7d, 0x0f, 0x5b, 0xbc, 0x86, 0x54, 0x73, 0x8f, 0x45, 0xad,
-	0x96, 0x5a, 0x72, 0xa0, 0x77, 0x5b, 0x7f, 0x2f, 0xb5, 0xcf, 0x67, 0x98, 0x1e, 0x2d, 0xc6, 0xf5,
-	0x09, 0x71, 0x1a, 0x51, 0x7a, 0x6b, 0xbc, 0x7e, 0x6e, 0xcc, 0x1f, 0xcf, 0x1a, 0x51, 0x03, 0xeb,
-	0x2c, 0x4c, 0xe7, 0x84, 0xf0, 0x2b, 0x00, 0xfc, 0x23, 0x73, 0x8e, 0xe2, 0x35, 0xec, 0xc4, 0x6a,
-	0x10, 0x01, 0xcc, 0x25, 0x26, 0x38, 0xeb, 0x87, 0x40, 0xf5, 0x47, 0x19, 0xdc, 0x3c, 0x44, 0x9e,
-	0x8f, 0x7d, 0x8a, 0x5c, 0x3a, 0xf4, 0x91, 0xd7, 0x42, 0x53, 0xec, 0x22, 0x8b, 0x9d, 0xc6, 0xf4,
-	0x17, 0x4d, 0xcf, 0x33, 0x8f, 0x79, 0x9a, 0x11, 0xc1, 0x16, 0x4f, 0x55, 0x68, 0x7e, 0xc6, 0xe8,
-	0x7e, 0x5b, 0x6a, 0x37, 0x62, 0x15, 0xd8, 0x78, 0xdc, 0x98, 0x3f, 0x69, 0x10, 0x6c, 0xd5, 0xfb,
-	0xd8, 0x5a, 0x2d, 0xb5, 0xfc, 0x2e, 0x0b, 0x65, 0x7c, 0xfd, 0x6e, 0x4b, 0xcf, 0x9b, 0x91, 0x85,
-	0xad, 0xfb, 0xc9, 0x8c, 0xac, 0x6c, 0x54, 0x09, 0x90, 0x0d, 0x78, 0x08, 0x0a, 0x98, 0xf5, 0xd8,
-	0x35, 0xed, 0xf5, 0x85, 0xe7, 0x6e, 0x7f, 0xf4, 0xee, 0x1b, 0x71, 0x4d, 0x3b, 0x7e, 0xd1, 0x38,
-	0x86, 0xdd, 0x51, 0x9f, 0xbf, 0xd4, 0xa4, 0x9f, 0x5e, 0x6a, 0xd2, 0xf3, 0x13, 0x4d, 0x7a, 0x71,
-	0xa2, 0x49, 0x2f, 0x4f, 0x34, 0xe9, 0xaf, 0x13, 0x4d, 0xaa, 0xfe, 0xb0, 0x09, 0xf2, 0xf1, 0x70,
-	0xf8, 0x25, 0x48, 0x4f, 0x4d, 0x07, 0xdb, 0xc7, 0x62, 0xcc, 0xb4, 0x0b, 0xb3, 0xde, 0xe5, 0x6e,
-	0x22, 0x9f, 0x08, 0x82, 0x3b, 0x20, 0xf5, 0x0c, 0x5b, 0xf4, 0x88, 0xb7, 0x25, 0x25, 0x0e, 0x03,
-	0x08, 0x56, 0x41, 0x76, 0xee, 0xa1, 0x09, 0xf6, 0x31, 0x71, 0xd5, 0x44, 0xec, 0x7c, 0x0d, 0xc3,
-	0x4f, 0x80, 0x12, 0xf4, 0xd7, 0xc2, 0x0e, 0x72, 0x19, 0xe4, 0xab, 0xc9, 0x4a, 0xa2, 0x96, 0xd2,
-	0xb7, 0x38, 0xde, 0x8a, 0x60, 0x78, 0x0d, 0xa4, 0x6d, 0x32, 0x31, 0x6d, 0xa4, 0xa6, 0x2a, 0x72,
-	0x2d, 0xab, 0x0b, 0x0b, 0x7e, 0x0c, 0xf2, 0x4f, 0xb1, 0x8f, 0xc7, 0xb6, 0x98, 0x85, 0x74, 0x2c,
-	0x53, 0x4e, 0x9c, 0xf0, 0x52, 0x3b, 0x20, 0xe0, 0x1c, 0x21, 0x1b, 0x39, 0x81, 0xef, 0xe6, 0xa5,
-	0x6a, 0xd6, 0x0b, 0x3c, 0xae, 0x6d, 0x23, 0x87, 0x13, 0xed, 0x82, 0x22, 0x5d, 0xcc, 0x6d, 0x34,
-	0x9a, 0x10, 0x97, 0x0d, 0x8f, 0xaf, 0x66, 0x2a, 0x89, 0x5a, 0xee, 0xdc, 0xfc, 0x9d, 0xe7, 0x31,
-	0xf4, 0x02, 0x8f, 0xd8, 0x13, 0x01, 0xf0, 0x26, 0xc8, 0x07, 0x14, 0xb6, 0x39, 0x46, 0xb6, 0xaf,
-	0x66, 0x2b, 0x89, 0x5a, 0x56, 0xcf, 0x71, 0x6c, 0x9f, 0x43, 0xf0, 0x0e, 0x48, 0xb0, 0x79, 0x03,
-	0x7c, 0xde, 0x6a, 0x97, 0x99, 0xb7, 0x44, 0x1f, 0x5b, 0x3a, 0x0b, 0x62, 0x0a, 0x83, 0x52, 0x23,
-	0x85, 0x39, 0x3e, 0x53, 0xef, 0x54, 0xc8, 0x23, 0x22, 0x85, 0x5f, 0x80, 0x12, 0xc5, 0x0e, 0x1a,
-	0x45, 0x77, 0x35, 0xc2, 0xfe, 0xc8, 0x47, 0x54, 0xcd, 0x57, 0xe4, 0x5a, 0x46, 0xf4, 0x17, 0x32,
-	0x97, 0xc3, 0xd0, 0xa3, 0xeb, 0x0f, 0x10, 0x85, 0x53, 0x70, 0x1d, 0x8b, 0x95, 0xb1, 0xde, 0x34,
-	0x53, 0xb6, 0xda, 0xd4, 0x02, 0x17, 0x51, 0xbf, 0xf4, 0xaa, 0xe1, 0x0b, 0x51, 0x2f, 0xe1, 0xb7,
-	0xee, 0xc9, 0x0e, 0xc8, 0xcf, 0x10, 0x19, 0x39, 0xe2, 0x55, 0x55, 0x8b, 0x9c, 0xfc, 0xc3, 0x0b,
-	0xc9, 0x63, 0x6b, 0x49, 0xcf, 0xcd, 0x62, 0x3b, 0xca, 0x05, 0xf9, 0x85, 0x45, 0xd7, 0x44, 0x5b,
-	0x9c, 0xe8, 0xce, 0x85, 0x44, 0xff, 0xb9, 0x35, 0x9a, 0x5b, 0xab, 0xa5, 0x96, 0x1b, 0xb6, 0x8c,
-	0x75, 0xbe, 0x85, 0x45, 0x43, 0xe3, 0xd6, 0x9f, 0x49, 0x90, 0x0e, 0x06, 0x0b, 0x16, 0x01, 0x68,
-	0x12, 0x62, 0x07, 0x96, 0x22, 0xc1, 0x02, 0xc8, 0x76, 0x5d, 0x2a, 0x4c, 0x19, 0x6e, 0x81, 0xdc,
-	0x5d, 0x9b, 0x98, 0x21, 0xb0, 0x01, 0xaf, 0x80, 0x42, 0x0b, 0x4d, 0xb0, 0x63, 0x86, 0x21, 0x09,
-	0x46, 0xd1, 0x32, 0x29, 0x12, 0x76, 0x12, 0x5e, 0x05, 0x5b, 0x06, 0x76, 0x90, 0x4f, 0x4d, 0x67,
-	0x2e, 0xc0, 0x14, 0x84, 0xa0, 0x18, 0xf6, 0x56, 0x60, 0x69, 0xa8, 0x80, 0xfc, 0x80, 0x7a, 0xd8,
-	0x9d, 0x09, 0x64, 0x93, 0xa5, 0x6b, 0x1e, 0x53, 0xe4, 0x0b, 0x20, 0x03, 0x4b, 0xe0, 0x4a, 0xc4,
-	0x65, 0x3c, 0x12, 0x70, 0x16, 0xaa, 0x60, 0x7b, 0x8f, 0xd8, 0xb6, 0x49, 0x91, 0x75, 0x8e, 0x01,
-	0x30, 0xfd, 0x7d, 0x6c, 0x09, 0x33, 0xcf, 0xe4, 0x0e, 0xdd, 0xc7, 0x2e, 0x79, 0xe6, 0x0a, 0xa8,
-	0xc0, 0xe4, 0x0e, 0x17, 0x91, 0x4b, 0x91, 0xe5, 0xe4, 0x5b, 0x52, 0x00, 0x5b, 0xcc, 0xa1, 0xdb,
-	0x43, 0x61, 0xc9, 0x0a, 0xb3, 0x99, 0x06, 0x61, 0x5f, 0x61, 0xf6, 0x7d, 0x9f, 0x84, 0x84, 0x90,
-	0x95, 0xc1, 0xce, 0x23, 0x79, 0x57, 0x19, 0xa5, 0xc1, 0xde, 0x23, 0x01, 0x6c, 0x33, 0x55, 0x4d,
-	0x1c, 0x32, 0x96, 0x58, 0x33, 0x3a, 0x88, 0x38, 0x88, 0x7a, 0x61, 0xd6, 0x6b, 0xac, 0x6b, 0x1d,
-	0x44, 0x66, 0x9e, 0x39, 0x3f, 0x0a, 0xc1, 0xeb, 0x2c, 0x55, 0xdb, 0x5d, 0x38, 0xc2, 0x56, 0x79,
-	0x7f, 0xc8, 0xf7, 0xb7, 0x5b, 0x02, 0xb8, 0xc1, 0x1c, 0x1e, 0x90, 0xa8, 0x98, 0x1d, 0xb8, 0x0d,
-	0x94, 0xb6, 0x3b, 0x21, 0x16, 0xb2, 0xbe, 0x46, 0x21, 0xcd, 0x7b, 0xac, 0x0b, 0xc6, 0xe0, 0x9b,
-	0x05, 0x8a, 0xd2, 0xbd, 0xcf, 0x24, 0x18, 0x83, 0x07, 0x68, 0x42, 0x89, 0x27, 0xb0, 0x0f, 0x18,
-	0xfb, 0x61, 0x67, 0x7f, 0xd0, 0x13, 0x40, 0x99, 0x69, 0xd2, 0xd1, 0x74, 0x6f, 0xe1, 0xf9, 0x91,
-	0x97, 0xc6, 0x6a, 0xd9, 0x75, 0x43, 0x22, 0x6b, 0x27, 0xf9, 0xfc, 0xe7, 0xb2, 0x54, 0x4d, 0x66,
-	0x72, 0x4a, 0xae, 0x9a, 0xce, 0x9c, 0xca, 0xca, 0xa9, 0x5c, 0x4d, 0x67, 0x5e, 0xc9, 0xca, 0x2b,
-	0xf9, 0x96, 0x07, 0xb6, 0xdf, 0xf6, 0xed, 0x86, 0x59, 0x90, 0x1a, 0xf6, 0x06, 0x6d, 0x43, 0x91,
-	0x60, 0x06, 0x24, 0x1f, 0xb6, 0x77, 0x75, 0x45, 0x66, 0xe0, 0x41, 0xbf, 0x67, 0xdc, 0x53, 0x36,
-	0xe0, 0x26, 0x48, 0xb4, 0x76, 0x1f, 0x2a, 0x09, 0x76, 0x7a, 0xaf, 0x3f, 0xd4, 0x95, 0x24, 0x04,
-	0x20, 0x7d, 0xd0, 0xed, 0x0d, 0x8d, 0xb6, 0x92, 0x62, 0xcf, 0x83, 0xf6, 0x5e, 0xbf, 0xd7, 0x52,
-	0xd2, 0x4c, 0xf3, 0x41, 0x77, 0x7f, 0xbf, 0x2b, 0x80, 0xcd, 0xe6, 0xe1, 0xe9, 0x1f, 0x65, 0xe9,
-	0x74, 0x55, 0x96, 0x5f, 0xaf, 0xca, 0xf2, 0x9b, 0x55, 0x59, 0xfe, 0x7d, 0x55, 0x96, 0x5f, 0x9c,
-	0x95, 0xa5, 0xd7, 0x67, 0x65, 0xe9, 0xcd, 0x59, 0x59, 0x7a, 0x54, 0xbf, 0xd4, 0x37, 0x3f, 0xfa,
-	0xeb, 0xf5, 0x4f, 0x00, 0x00, 0x00, 0xff, 0xff, 0xed, 0x5f, 0xa0, 0x90, 0x86, 0x09, 0x00, 0x00,
+	// 1209 bytes of a gzipped FileDescriptorProto
+	0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x9c, 0x56, 0x4d, 0x6f, 0xdb, 0x46,
+	0x13, 0x26, 0xad, 0x0f, 0x4b, 0xab, 0x0f, 0x33, 0x1b, 0x2b, 0x51, 0xfc, 0xbe, 0x15, 0x15, 0xa1,
+	0x45, 0xd5, 0x00, 0x95, 0xd0, 0xf4, 0x50, 0x20, 0x40, 0x51, 0x58, 0x96, 0xa2, 0x28, 0xb5, 0x2d,
+	0x97, 0x92, 0xd2, 0x26, 0x17, 0x81, 0x16, 0xd7, 0xf2, 0x22, 0x24, 0x57, 0x21, 0x57, 0x49, 0x7d,
+	0x6c, 0x4f, 0x39, 0xe6, 0xd8, 0xa3, 0x8d, 0x1e, 0xfa, 0x57, 0x9c, 0x5b, 0x0e, 0x3d, 0x04, 0x3d,
+	0x18, 0xad, 0xfc, 0x07, 0x7a, 0xee, 0xa9, 0x98, 0xe5, 0x92, 0xa2, 0x8b, 0x38, 0x35, 0x7a, 0x11,
+	0x38, 0xcf, 0xce, 0x3c, 0xf3, 0xcc, 0xec, 0x70, 0x44, 0x54, 0xf2, 0x9f, 0xd9, 0x4d, 0x7e, 0x34,
+	0x23, 0x7e, 0xf0, 0xdb, 0x98, 0x79, 0x8c, 0x33, 0x7c, 0x73, 0xc2, 0x26, 0x4f, 0x3d, 0x66, 0x4e,
+	0x0e, 0x1b, 0xfe, 0x33, 0xbb, 0xe1, 0x13, 0xa7, 0x21, 0x8e, 0x37, 0xd6, 0xa7, 0x6c, 0xca, 0x84,
+	0x4f, 0x13, 0x9e, 0x02, 0xf7, 0x8d, 0xd2, 0x94, 0xb0, 0xe6, 0x94, 0xb0, 0xd9, 0x7e, 0xf0, 0x1b,
+	0xc0, 0xb5, 0x5f, 0x55, 0x54, 0xea, 0xb9, 0x9c, 0x78, 0xcf, 0x4d, 0xbb, 0x3d, 0xf7, 0x4c, 0x4e,
+	0x99, 0x7b, 0x9f, 0x12, 0xdb, 0xc2, 0xdf, 0xa1, 0x82, 0x25, 0x81, 0x31, 0x10, 0x97, 0xd5, 0xaa,
+	0x5a, 0x2f, 0xde, 0xfd, 0xb4, 0x71, 0x49, 0xde, 0xc6, 0x3f, 0x69, 0x86, 0x47, 0x33, 0xd2, 0x4a,
+	0x9e, 0x9e, 0xe9, 0x8a, 0x91, 0xb7, 0x62, 0x18, 0x36, 0x11, 0x3e, 0xf0, 0x98, 0x33, 0xbe, 0x48,
+	0xbf, 0xf2, 0xdf, 0xe9, 0x35, 0xa0, 0x8b, 0xe3, 0xb5, 0x5f, 0x54, 0x94, 0xeb, 0x12, 0xb6, 0x43,
+	0xb8, 0x69, 0x99, 0xdc, 0xc4, 0xdf, 0xa2, 0xa4, 0xef, 0x51, 0x4b, 0xd4, 0x90, 0x6a, 0x6d, 0x41,
+	0xd4, 0xe2, 0x4c, 0x4f, 0x0e, 0x8c, 0x5e, 0xfb, 0xaf, 0x33, 0xfd, 0xf3, 0x29, 0xe5, 0x87, 0xf3,
+	0xfd, 0xc6, 0x84, 0x39, 0xcd, 0x28, 0xbd, 0xb5, 0xbf, 0x7c, 0x6e, 0xce, 0x9e, 0x4e, 0x9b, 0x51,
+	0x03, 0x1b, 0x10, 0x66, 0x08, 0x42, 0xfc, 0x15, 0x42, 0xfe, 0xa1, 0x39, 0x23, 0xf1, 0x1a, 0x36,
+	0x62, 0x35, 0xc8, 0x00, 0x70, 0x89, 0x09, 0xce, 0xfa, 0x21, 0x50, 0xfb, 0x51, 0x45, 0xb7, 0xf7,
+	0x88, 0xe7, 0x53, 0x9f, 0x13, 0x97, 0x8f, 0x7c, 0xe2, 0xb5, 0xc9, 0x01, 0x75, 0x89, 0x05, 0xa7,
+	0x31, 0xfd, 0x45, 0xd3, 0xf3, 0xcc, 0x23, 0x91, 0x66, 0xcc, 0xa8, 0x25, 0x52, 0x15, 0x5a, 0x9f,
+	0x01, 0xdd, 0x6f, 0x67, 0xfa, 0xad, 0x58, 0x05, 0x36, 0xdd, 0x6f, 0xce, 0x9e, 0x35, 0x19, 0xb5,
+	0x1a, 0x7d, 0x6a, 0x2d, 0xce, 0xf4, 0xfc, 0x26, 0x84, 0x02, 0x5f, 0xbf, 0xd7, 0x36, 0xf2, 0x66,
+	0x64, 0x51, 0xeb, 0x61, 0x32, 0xa3, 0x6a, 0x2b, 0x35, 0x86, 0xd4, 0x21, 0xde, 0x43, 0x05, 0x0a,
+	0x3d, 0x76, 0x4d, 0x7b, 0x79, 0xe1, 0xb9, 0xbb, 0x1f, 0xbd, 0xff, 0x46, 0x5c, 0xd3, 0x8e, 0x5f,
+	0x34, 0x8d, 0x61, 0xf7, 0xca, 0x2f, 0x8f, 0x75, 0xe5, 0xa7, 0x63, 0x5d, 0x79, 0x79, 0xa2, 0x2b,
+	0xaf, 0x4e, 0x74, 0xe5, 0xf8, 0x44, 0x57, 0xfe, 0x3c, 0xd1, 0x95, 0xda, 0x0f, 0xab, 0x28, 0x1f,
+	0x0f, 0xc7, 0x5f, 0xa2, 0xf4, 0x81, 0xe9, 0x50, 0xfb, 0x48, 0x8e, 0x99, 0x7e, 0x69, 0xd6, 0xfb,
+	0xc2, 0x4d, 0xe6, 0x93, 0x41, 0x78, 0x03, 0xa5, 0x5e, 0x50, 0x8b, 0x1f, 0x8a, 0xb6, 0xa4, 0xe4,
+	0x61, 0x00, 0xe1, 0x1a, 0xca, 0xce, 0x3c, 0x32, 0xa1, 0x3e, 0x65, 0x6e, 0x39, 0x11, 0x3b, 0x5f,
+	0xc2, 0xf8, 0x13, 0xa4, 0x05, 0xfd, 0xb5, 0xa8, 0x43, 0x5c, 0x80, 0xfc, 0x72, 0xb2, 0x9a, 0xa8,
+	0xa7, 0x8c, 0x35, 0x81, 0xb7, 0x23, 0x18, 0xdf, 0x40, 0x69, 0x9b, 0x4d, 0x4c, 0x9b, 0x94, 0x53,
+	0x55, 0xb5, 0x9e, 0x35, 0xa4, 0x85, 0x3f, 0x46, 0xf9, 0xe7, 0xd4, 0xa7, 0xfb, 0xb6, 0x9c, 0x85,
+	0x74, 0x2c, 0x53, 0x4e, 0x9e, 0x88, 0x52, 0xbb, 0x28, 0xe0, 0x1c, 0x13, 0x9b, 0x38, 0x81, 0xef,
+	0xea, 0x95, 0x6a, 0x36, 0x0a, 0x22, 0xae, 0x63, 0x13, 0x47, 0x10, 0x6d, 0xa2, 0x22, 0x9f, 0xcf,
+	0x6c, 0x32, 0x9e, 0x30, 0x17, 0x86, 0xc7, 0x2f, 0x67, 0xaa, 0x89, 0x7a, 0xee, 0xc2, 0xfc, 0x5d,
+	0xe4, 0x19, 0x1a, 0x05, 0x11, 0xb1, 0x25, 0x03, 0xf0, 0x6d, 0x94, 0x0f, 0x28, 0x6c, 0x73, 0x9f,
+	0xd8, 0x7e, 0x39, 0x5b, 0x4d, 0xd4, 0xb3, 0x46, 0x4e, 0x60, 0xdb, 0x02, 0xc2, 0xf7, 0x50, 0x02,
+	0xe6, 0x0d, 0x89, 0x79, 0xab, 0x5f, 0x65, 0xde, 0x12, 0x7d, 0x6a, 0x19, 0x10, 0x04, 0x0a, 0x83,
+	0x52, 0x23, 0x85, 0x39, 0x31, 0x53, 0xef, 0x55, 0x28, 0x22, 0x22, 0x85, 0x5f, 0xa0, 0x12, 0xa7,
+	0x0e, 0x19, 0x47, 0x77, 0x35, 0xa6, 0xfe, 0xd8, 0x27, 0xbc, 0x9c, 0xaf, 0xaa, 0xf5, 0x8c, 0xec,
+	0x2f, 0x06, 0x97, 0xbd, 0xd0, 0xa3, 0xe7, 0x0f, 0x08, 0xc7, 0x07, 0xe8, 0x26, 0x95, 0x2b, 0x63,
+	0xb9, 0x69, 0x0e, 0x60, 0xb5, 0x95, 0x0b, 0x42, 0x44, 0xe3, 0xca, 0xab, 0x46, 0x2c, 0x44, 0xa3,
+	0x44, 0xdf, 0xb9, 0x27, 0xbb, 0x28, 0x3f, 0x25, 0x6c, 0xec, 0xc8, 0x57, 0xb5, 0x5c, 0x14, 0xe4,
+	0x1f, 0x5e, 0x4a, 0x1e, 0x5b, 0x4b, 0x46, 0x6e, 0x1a, 0xdb, 0x51, 0x2e, 0xca, 0xcf, 0x2d, 0xbe,
+	0x24, 0x5a, 0x13, 0x44, 0xf7, 0x2e, 0x25, 0xfa, 0xd7, 0xad, 0xd1, 0x5a, 0x5b, 0x9c, 0xe9, 0xb9,
+	0x51, 0x7b, 0xb8, 0xcc, 0x37, 0xb7, 0x78, 0x68, 0xdc, 0x39, 0x4e, 0xa1, 0x74, 0x30, 0x58, 0xb8,
+	0x88, 0x50, 0x8b, 0x31, 0x3b, 0xb0, 0x34, 0x05, 0x17, 0x50, 0xb6, 0xe7, 0x72, 0x69, 0xaa, 0x78,
+	0x0d, 0xe5, 0xee, 0xdb, 0xcc, 0x0c, 0x81, 0x15, 0x7c, 0x0d, 0x15, 0xda, 0x64, 0x42, 0x1d, 0x33,
+	0x0c, 0x49, 0x00, 0x45, 0xdb, 0xe4, 0x44, 0xda, 0x49, 0x7c, 0x1d, 0xad, 0x0d, 0xa9, 0x43, 0x7c,
+	0x6e, 0x3a, 0x33, 0x09, 0xa6, 0x30, 0x46, 0xc5, 0xb0, 0xb7, 0x12, 0x4b, 0x63, 0x0d, 0xe5, 0x07,
+	0xdc, 0xa3, 0xee, 0x54, 0x22, 0xab, 0x90, 0xae, 0x75, 0xc4, 0x89, 0x2f, 0x81, 0x0c, 0x2e, 0xa1,
+	0x6b, 0x11, 0xd7, 0xf0, 0x89, 0x84, 0xb3, 0xb8, 0x8c, 0xd6, 0xb7, 0x98, 0x6d, 0x9b, 0x9c, 0x58,
+	0x17, 0x18, 0x10, 0xe8, 0xef, 0x53, 0x4b, 0x9a, 0x79, 0x90, 0x3b, 0x72, 0x9f, 0xba, 0xec, 0x85,
+	0x2b, 0xa1, 0x02, 0xc8, 0x1d, 0xcd, 0x23, 0x97, 0x22, 0xe4, 0x14, 0x5b, 0x52, 0x02, 0x6b, 0xe0,
+	0xd0, 0xdb, 0x25, 0x61, 0xc9, 0x1a, 0xd8, 0xa0, 0x41, 0xda, 0xd7, 0xc0, 0x7e, 0xe8, 0xb3, 0x90,
+	0x10, 0x43, 0x19, 0x70, 0x1e, 0xc9, 0xbb, 0x0e, 0x94, 0x43, 0x78, 0x8f, 0x24, 0xb0, 0x0e, 0xaa,
+	0x5a, 0x34, 0x64, 0x2c, 0x41, 0x33, 0xba, 0x84, 0x39, 0x84, 0x7b, 0x61, 0xd6, 0x1b, 0xd0, 0xb5,
+	0x2e, 0x61, 0x53, 0xcf, 0x9c, 0x1d, 0x86, 0xe0, 0x4d, 0x48, 0xd5, 0x71, 0xe7, 0x8e, 0xb4, 0xcb,
+	0xa2, 0x3f, 0xec, 0xfb, 0xbb, 0x6d, 0x09, 0xdc, 0x02, 0x87, 0x47, 0x2c, 0x2a, 0x66, 0x03, 0xaf,
+	0x23, 0xad, 0xe3, 0x4e, 0x98, 0x45, 0xac, 0xaf, 0x49, 0x48, 0xf3, 0x3f, 0xe8, 0xc2, 0x70, 0xf0,
+	0xcd, 0x9c, 0x44, 0xe9, 0xfe, 0x0f, 0x12, 0x86, 0x83, 0x47, 0x64, 0xc2, 0x99, 0x27, 0xb1, 0x0f,
+	0x80, 0x7d, 0xaf, 0xbb, 0x3d, 0xd8, 0x95, 0x40, 0x05, 0x34, 0x19, 0xe4, 0x60, 0x6b, 0xee, 0xf9,
+	0x91, 0x97, 0x0e, 0x91, 0x7b, 0xdd, 0x0b, 0x91, 0x55, 0x91, 0xc0, 0xa3, 0xd3, 0x29, 0x09, 0xa1,
+	0xdb, 0xe0, 0x06, 0x5d, 0x9a, 0x99, 0xfc, 0x50, 0x62, 0x35, 0x68, 0xc3, 0xa6, 0x1b, 0x6a, 0xb0,
+	0x36, 0x92, 0x2f, 0x7f, 0xae, 0x28, 0xb5, 0x64, 0x26, 0xa7, 0xe5, 0x6a, 0xe9, 0xcc, 0xa9, 0xaa,
+	0x9d, 0xaa, 0xb5, 0x74, 0xe6, 0xb5, 0xaa, 0xbd, 0x56, 0xef, 0x78, 0x68, 0xfd, 0x5d, 0x7f, 0xfb,
+	0x38, 0x8b, 0x52, 0xa3, 0xdd, 0x41, 0x67, 0xa8, 0x29, 0x38, 0x83, 0x92, 0x8f, 0x3b, 0x9b, 0x86,
+	0xa6, 0x02, 0xb8, 0xd3, 0xdf, 0x1d, 0x3e, 0xd0, 0x56, 0xf0, 0x2a, 0x4a, 0xb4, 0x37, 0x1f, 0x6b,
+	0x09, 0x38, 0x7d, 0xd0, 0x1f, 0x19, 0x5a, 0x12, 0x23, 0x94, 0xde, 0xe9, 0xed, 0x8e, 0x86, 0x1d,
+	0x2d, 0x05, 0xcf, 0x83, 0xce, 0x56, 0x7f, 0xb7, 0xad, 0xa5, 0xa1, 0xdc, 0x9d, 0xde, 0xf6, 0x76,
+	0x4f, 0x02, 0xab, 0xad, 0xbd, 0xd3, 0x3f, 0x2a, 0xca, 0xe9, 0xa2, 0xa2, 0xbe, 0x59, 0x54, 0xd4,
+	0xb7, 0x8b, 0x8a, 0xfa, 0xfb, 0xa2, 0xa2, 0xbe, 0x3a, 0xaf, 0x28, 0x6f, 0xce, 0x2b, 0xca, 0xdb,
+	0xf3, 0x8a, 0xf2, 0xa4, 0x71, 0xa5, 0xcf, 0x85, 0xe8, 0xab, 0xed, 0xef, 0x00, 0x00, 0x00, 0xff,
+	0xff, 0x47, 0xde, 0x1c, 0xc2, 0xc1, 0x09, 0x00, 0x00,
 }
 
 func (m *IntervalDurationField) Marshal() (dAtA []byte, err error) {
@@ -1196,7 +1218,7 @@ func (m *InternalType) Size() (n int) {
 }
 
 func sovTypes(x uint64) (n int) {
-	return (math_bits.Len64(x|1) + 6) / 7
+	return int((uint32(math_bits.Len64(x|1)+6) * 37) >> 8)
 }
 func sozTypes(x uint64) (n int) {
 	return sovTypes(uint64((x << 1) ^ uint64((int64(x) >> 63))))
@@ -1584,8 +1606,12 @@ func (m *InternalType) Unmarshal(dAtA []byte) error {
 					}
 				}
 				elementCount = count
-				if elementCount != 0 && len(m.ArrayDimensions) == 0 {
-					m.ArrayDimensions = make([]int32, 0, elementCount)
+				if elementCount != 0 {
+					if m.ArrayDimensions == nil {
+						m.ArrayDimensions = make([]int32, 0, elementCount)
+					} else {
+						m.ArrayDimensions = slices.Grow(m.ArrayDimensions, elementCount)
+					}
 				}
 				for iNdEx < postIndex {
 					var v int32
diff --git a/pkg/sql/types/types.proto b/pkg/sql/types/types.proto
index 84ab3a0..93fe700 100644
--- a/pkg/sql/types/types.proto
+++ b/pkg/sql/types/types.proto
@@ -1,12 +1,7 @@
 // Copyright 2015 The Cockroach Authors.
 //
-// Use of this software is governed by the Business Source License
-// included in the file licenses/BSL.txt.
-//
-// As of the Change Date specified in that file, in accordance with
-// the Business Source License, use of this software will be governed
-// by the Apache License, Version 2.0, included in the file
-// licenses/APL.txt.
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
 
 // Cannot be proto3 because we use nullable primitives.
 syntax = "proto2";
@@ -402,6 +397,22 @@ enum Family {
     //   Oid      : T_refcursor
     RefCursorFamily = 31;
 
+    // PGVectorFamily is a type family for the vector type, which is the
+    // type representing pgvector vectors.
+    PGVectorFamily = 32;
+
+    // TriggerFamily is a type family for the trigger type, which is the return
+    // type for trigger functions.
+    //   Canonical: types.Trigger
+    //   Oid      : T_trigger
+    TriggerFamily = 33;
+
+    // JsonpathFamily is a type family for the jsonpath type, which is the type
+    // representing JSON path expressions.
+    //  Canonical: types.Jsonpath
+    //  Oid: T_jsonpath
+    JsonpathFamily = 34;
+
     // AnyFamily is a special type family used during static analysis as a
     // wildcard type that matches any other type, including scalar, array, and
     // tuple types. Execution-time values should never have this type. As an
diff --git a/pkg/sql/types/types_jsonpb.go b/pkg/sql/types/types_jsonpb.go
index 27926b4..6486ae5 100644
--- a/pkg/sql/types/types_jsonpb.go
+++ b/pkg/sql/types/types_jsonpb.go
@@ -1,12 +1,7 @@
 // Copyright 2015 The Cockroach Authors.
 //
-// Use of this software is governed by the Business Source License
-// included in the file licenses/BSL.txt.
-//
-// As of the Change Date specified in that file, in accordance with
-// the Business Source License, use of this software will be governed
-// by the Apache License, Version 2.0, included in the file
-// licenses/APL.txt.
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
 
 package types
 
diff --git a/pkg/util/admission/admissionpb/admission_stats.pb.go b/pkg/util/admission/admissionpb/admission_stats.pb.go
index d20932f..4d1d6e2 100644
--- a/pkg/util/admission/admissionpb/admission_stats.pb.go
+++ b/pkg/util/admission/admissionpb/admission_stats.pb.go
@@ -28,19 +28,22 @@ const _ = proto.GoGoProtoPackageIsVersion3 // please upgrade the proto package
 // AdmissionWorkQueueStats is recorded for work items waiting in the admission
 // work queue.
 type AdmissionWorkQueueStats struct {
-	// Duration spent waiting.
+	// WaitDurationNanos is the time spent waiting.
 	WaitDurationNanos time.Duration `protobuf:"varint,1,opt,name=wait_duration_nanos,json=waitDurationNanos,proto3,casttype=time.Duration" json:"wait_duration_nanos,omitempty"`
-	// String representation of admission queue kind.
+	// QueueKind is the string name of the admission queue kind.
 	QueueKind string `protobuf:"bytes,2,opt,name=queue_kind,json=queueKind,proto3" json:"queue_kind,omitempty"`
-	// Set to true if deadline was exceeded.
-	DeadlineExceeded bool `protobuf:"varint,3,opt,name=deadline_exceeded,json=deadlineExceeded,proto3" json:"deadline_exceeded,omitempty"`
-	// String representation of work priority.
-	WorkPriority string `protobuf:"bytes,4,opt,name=work_priority,json=workPriority,proto3" json:"work_priority,omitempty"`
+	// DeadlineExceededCount counts the number of times -- usually zero or one
+	// unless the stats are an aggregate -- that the deadline was exceeded while
+	// waiting in the queue.
+	DeadlineExceededCount int32 `protobuf:"varint,5,opt,name=deadline_exceeded_count,json=deadlineExceededCount,proto3" json:"deadline_exceeded_count,omitempty"`
+	// WorkPriority is the integer representation of work priority, or if the
+	// AdmissionWorkQueueStats represents an aggregation of stats, the minimum of
+	// the priorities across the aggregated stats.
+	WorkPriority int32 `protobuf:"varint,6,opt,name=work_priority,json=workPriority,proto3" json:"work_priority,omitempty"`
 }
 
-func (m *AdmissionWorkQueueStats) Reset()         { *m = AdmissionWorkQueueStats{} }
-func (m *AdmissionWorkQueueStats) String() string { return proto.CompactTextString(m) }
-func (*AdmissionWorkQueueStats) ProtoMessage()    {}
+func (m *AdmissionWorkQueueStats) Reset()      { *m = AdmissionWorkQueueStats{} }
+func (*AdmissionWorkQueueStats) ProtoMessage() {}
 func (*AdmissionWorkQueueStats) Descriptor() ([]byte, []int) {
 	return fileDescriptor_695e7752d0aa7c6e, []int{0}
 }
@@ -76,27 +79,29 @@ func init() {
 }
 
 var fileDescriptor_695e7752d0aa7c6e = []byte{
-	// 313 bytes of a gzipped FileDescriptorProto
-	0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x74, 0x91, 0xc1, 0x4a, 0xf3, 0x40,
-	0x14, 0x85, 0x33, 0x7f, 0x7f, 0xc4, 0x0e, 0x16, 0x6c, 0x14, 0x0c, 0x82, 0x63, 0x51, 0x17, 0x05,
-	0x61, 0x22, 0xf8, 0x00, 0xd2, 0xa2, 0x2b, 0x41, 0xb4, 0x2e, 0x04, 0x37, 0x61, 0x92, 0x19, 0xd2,
-	0x21, 0xed, 0xdc, 0x38, 0x99, 0x50, 0x7d, 0x0b, 0x1f, 0xab, 0x1b, 0xa1, 0xcb, 0xae, 0x44, 0xd3,
-	0xb7, 0x70, 0x25, 0x13, 0x93, 0xc6, 0x8d, 0xbb, 0x33, 0xe7, 0x9e, 0xef, 0x0c, 0xdc, 0x8b, 0xcf,
-	0x72, 0x23, 0x27, 0x3e, 0xe3, 0x53, 0x99, 0x65, 0x12, 0x54, 0xa3, 0xd2, 0xb0, 0xd1, 0x41, 0x66,
-	0x98, 0xc9, 0x68, 0xaa, 0xc1, 0x80, 0x7b, 0x12, 0x41, 0x94, 0x68, 0x60, 0xd1, 0x98, 0x5a, 0x96,
-	0xae, 0x53, 0xf4, 0x17, 0xbb, 0xbf, 0x1b, 0x43, 0x0c, 0x25, 0xe0, 0x5b, 0xf5, 0xc3, 0x1e, 0xbd,
-	0x21, 0xbc, 0x37, 0xa8, 0x53, 0x0f, 0xa0, 0x93, 0xbb, 0x5c, 0xe4, 0xe2, 0xde, 0xb6, 0xbb, 0x03,
-	0xbc, 0x33, 0x63, 0xd2, 0x04, 0x3c, 0xd7, 0xcc, 0xd8, 0x4f, 0x15, 0x53, 0x90, 0x79, 0xa8, 0x87,
-	0xfa, 0xad, 0x61, 0xf7, 0xeb, 0xfd, 0xb0, 0x63, 0xe4, 0x54, 0xd0, 0xcb, 0x6a, 0x3c, 0xea, 0xda,
-	0x74, 0xfd, 0xba, 0xb1, 0x59, 0xf7, 0x00, 0xe3, 0x27, 0x5b, 0x18, 0x24, 0x52, 0x71, 0xef, 0x5f,
-	0x0f, 0xf5, 0xdb, 0xa3, 0x76, 0xe9, 0x5c, 0x4b, 0xc5, 0xdd, 0x53, 0xdc, 0xe5, 0x82, 0xf1, 0x89,
-	0x54, 0x22, 0x10, 0xcf, 0x91, 0x10, 0x5c, 0x70, 0xaf, 0xd5, 0x43, 0xfd, 0xcd, 0xd1, 0x76, 0x3d,
-	0xb8, 0xaa, 0x7c, 0xf7, 0x18, 0x77, 0x66, 0xa0, 0x93, 0x20, 0xd5, 0x12, 0xb4, 0x34, 0x2f, 0xde,
-	0xff, 0xb2, 0x6e, 0xcb, 0x9a, 0xb7, 0x95, 0x37, 0x64, 0xf3, 0x4f, 0xe2, 0xcc, 0x0b, 0x82, 0x16,
-	0x05, 0x41, 0xcb, 0x82, 0xa0, 0x8f, 0x82, 0xa0, 0xd7, 0x15, 0x71, 0x16, 0x2b, 0xe2, 0x2c, 0x57,
-	0xc4, 0x79, 0xbc, 0x88, 0xa5, 0x19, 0xe7, 0x21, 0x8d, 0x60, 0xea, 0xaf, 0x17, 0xc7, 0xc3, 0x46,
-	0xfb, 0x69, 0x12, 0xfb, 0x7f, 0x1f, 0x21, 0xdc, 0x28, 0x37, 0x77, 0xfe, 0x1d, 0x00, 0x00, 0xff,
-	0xff, 0x8f, 0x5e, 0x5b, 0x8e, 0xa9, 0x01, 0x00, 0x00,
+	// 340 bytes of a gzipped FileDescriptorProto
+	0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x74, 0x91, 0x3f, 0x4b, 0xc3, 0x40,
+	0x18, 0xc6, 0x73, 0x36, 0x2d, 0xed, 0x61, 0xa1, 0x8d, 0x4a, 0x83, 0xe0, 0xb5, 0xa8, 0x43, 0xa7,
+	0x44, 0x10, 0x1c, 0x5c, 0xa4, 0x55, 0x97, 0x0a, 0xa2, 0x75, 0x10, 0x5c, 0xc2, 0x25, 0x77, 0xa4,
+	0x47, 0xda, 0xbb, 0x78, 0xb9, 0x50, 0xfd, 0x16, 0x8e, 0x8e, 0x7e, 0x9c, 0x8e, 0x1d, 0x3b, 0x89,
+	0xa6, 0x9b, 0x1f, 0xc1, 0x49, 0x2e, 0xf6, 0x8f, 0x8b, 0xdb, 0x73, 0xcf, 0xf3, 0x7b, 0xde, 0x83,
+	0xf7, 0x85, 0x47, 0xa9, 0x62, 0x43, 0x17, 0x93, 0x11, 0x4b, 0x12, 0x26, 0xf8, 0x5a, 0xc5, 0xfe,
+	0x5a, 0x7b, 0x89, 0xc2, 0x2a, 0x71, 0x62, 0x29, 0x94, 0xb0, 0x0e, 0x03, 0x11, 0x44, 0x52, 0xe0,
+	0x60, 0xe0, 0xe8, 0xae, 0xb3, 0xa2, 0x9c, 0x3f, 0xdd, 0xdd, 0xed, 0x50, 0x84, 0x22, 0x2f, 0xb8,
+	0x5a, 0xfd, 0x76, 0xf7, 0xbf, 0x00, 0x6c, 0x74, 0x96, 0xd4, 0xbd, 0x90, 0xd1, 0x6d, 0x4a, 0x53,
+	0x7a, 0xa7, 0xa7, 0x5b, 0x1d, 0xb8, 0x35, 0xc6, 0x4c, 0x79, 0x24, 0x95, 0x58, 0xe9, 0x4f, 0x39,
+	0xe6, 0x22, 0xb1, 0x41, 0x0b, 0xb4, 0x0b, 0xdd, 0xfa, 0xf7, 0x7b, 0xb3, 0xaa, 0xd8, 0x88, 0x3a,
+	0x17, 0x8b, 0xb8, 0x5f, 0xd7, 0xf4, 0xf2, 0x75, 0xad, 0x59, 0x6b, 0x0f, 0xc2, 0x47, 0x3d, 0xd0,
+	0x8b, 0x18, 0x27, 0xf6, 0x46, 0x0b, 0xb4, 0x2b, 0xfd, 0x4a, 0xee, 0x5c, 0x31, 0x4e, 0xac, 0x13,
+	0xd8, 0x20, 0x14, 0x93, 0x21, 0xe3, 0xd4, 0xa3, 0x4f, 0x01, 0xa5, 0x84, 0x12, 0x2f, 0x10, 0x29,
+	0x57, 0x76, 0xb1, 0x05, 0xda, 0xc5, 0xfe, 0xce, 0x32, 0xbe, 0x5c, 0xa4, 0xe7, 0x3a, 0xb4, 0x0e,
+	0x60, 0x75, 0x2c, 0x64, 0xe4, 0xc5, 0x92, 0x09, 0xc9, 0xd4, 0xb3, 0x5d, 0xca, 0xe9, 0x4d, 0x6d,
+	0xde, 0x2c, 0xbc, 0x53, 0xf3, 0xf5, 0xad, 0x69, 0xf4, 0xcc, 0x72, 0xa1, 0x66, 0xf6, 0xcc, 0xb2,
+	0x59, 0x2b, 0x76, 0xf1, 0xe4, 0x13, 0x19, 0x93, 0x0c, 0x81, 0x69, 0x86, 0xc0, 0x2c, 0x43, 0xe0,
+	0x23, 0x43, 0xe0, 0x65, 0x8e, 0x8c, 0xe9, 0x1c, 0x19, 0xb3, 0x39, 0x32, 0x1e, 0xce, 0x42, 0xa6,
+	0x06, 0xa9, 0xef, 0x04, 0x62, 0xe4, 0xae, 0xb6, 0x4a, 0xfc, 0xb5, 0x76, 0xe3, 0x28, 0x74, 0xff,
+	0xbf, 0x90, 0x5f, 0xca, 0xd7, 0x7a, 0xfc, 0x13, 0x00, 0x00, 0xff, 0xff, 0x5f, 0xd1, 0x36, 0x12,
+	0xc6, 0x01, 0x00, 0x00,
 }
 
 func (m *AdmissionWorkQueueStats) Marshal() (dAtA []byte, err error) {
@@ -119,22 +124,15 @@ func (m *AdmissionWorkQueueStats) MarshalToSizedBuffer(dAtA []byte) (int, error)
 	_ = i
 	var l int
 	_ = l
-	if len(m.WorkPriority) > 0 {
-		i -= len(m.WorkPriority)
-		copy(dAtA[i:], m.WorkPriority)
-		i = encodeVarintAdmissionStats(dAtA, i, uint64(len(m.WorkPriority)))
+	if m.WorkPriority != 0 {
+		i = encodeVarintAdmissionStats(dAtA, i, uint64(m.WorkPriority))
 		i--
-		dAtA[i] = 0x22
+		dAtA[i] = 0x30
 	}
-	if m.DeadlineExceeded {
+	if m.DeadlineExceededCount != 0 {
+		i = encodeVarintAdmissionStats(dAtA, i, uint64(m.DeadlineExceededCount))
 		i--
-		if m.DeadlineExceeded {
-			dAtA[i] = 1
-		} else {
-			dAtA[i] = 0
-		}
-		i--
-		dAtA[i] = 0x18
+		dAtA[i] = 0x28
 	}
 	if len(m.QueueKind) > 0 {
 		i -= len(m.QueueKind)
@@ -175,18 +173,17 @@ func (m *AdmissionWorkQueueStats) Size() (n int) {
 	if l > 0 {
 		n += 1 + l + sovAdmissionStats(uint64(l))
 	}
-	if m.DeadlineExceeded {
-		n += 2
+	if m.DeadlineExceededCount != 0 {
+		n += 1 + sovAdmissionStats(uint64(m.DeadlineExceededCount))
 	}
-	l = len(m.WorkPriority)
-	if l > 0 {
-		n += 1 + l + sovAdmissionStats(uint64(l))
+	if m.WorkPriority != 0 {
+		n += 1 + sovAdmissionStats(uint64(m.WorkPriority))
 	}
 	return n
 }
 
 func sovAdmissionStats(x uint64) (n int) {
-	return (math_bits.Len64(x|1) + 6) / 7
+	return int((uint32(math_bits.Len64(x|1)+6) * 37) >> 8)
 }
 func sozAdmissionStats(x uint64) (n int) {
 	return sovAdmissionStats(uint64((x << 1) ^ uint64((int64(x) >> 63))))
@@ -271,11 +268,11 @@ func (m *AdmissionWorkQueueStats) Unmarshal(dAtA []byte) error {
 			}
 			m.QueueKind = string(dAtA[iNdEx:postIndex])
 			iNdEx = postIndex
-		case 3:
+		case 5:
 			if wireType != 0 {
-				return fmt.Errorf("proto: wrong wireType = %d for field DeadlineExceeded", wireType)
+				return fmt.Errorf("proto: wrong wireType = %d for field DeadlineExceededCount", wireType)
 			}
-			var v int
+			m.DeadlineExceededCount = 0
 			for shift := uint(0); ; shift += 7 {
 				if shift >= 64 {
 					return ErrIntOverflowAdmissionStats
@@ -285,17 +282,16 @@ func (m *AdmissionWorkQueueStats) Unmarshal(dAtA []byte) error {
 				}
 				b := dAtA[iNdEx]
 				iNdEx++
-				v |= int(b&0x7F) << shift
+				m.DeadlineExceededCount |= int32(b&0x7F) << shift
 				if b < 0x80 {
 					break
 				}
 			}
-			m.DeadlineExceeded = bool(v != 0)
-		case 4:
-			if wireType != 2 {
+		case 6:
+			if wireType != 0 {
 				return fmt.Errorf("proto: wrong wireType = %d for field WorkPriority", wireType)
 			}
-			var stringLen uint64
+			m.WorkPriority = 0
 			for shift := uint(0); ; shift += 7 {
 				if shift >= 64 {
 					return ErrIntOverflowAdmissionStats
@@ -305,24 +301,11 @@ func (m *AdmissionWorkQueueStats) Unmarshal(dAtA []byte) error {
 				}
 				b := dAtA[iNdEx]
 				iNdEx++
-				stringLen |= uint64(b&0x7F) << shift
+				m.WorkPriority |= int32(b&0x7F) << shift
 				if b < 0x80 {
 					break
 				}
 			}
-			intStringLen := int(stringLen)
-			if intStringLen < 0 {
-				return ErrInvalidLengthAdmissionStats
-			}
-			postIndex := iNdEx + intStringLen
-			if postIndex < 0 {
-				return ErrInvalidLengthAdmissionStats
-			}
-			if postIndex > l {
-				return io.ErrUnexpectedEOF
-			}
-			m.WorkPriority = string(dAtA[iNdEx:postIndex])
-			iNdEx = postIndex
 		default:
 			iNdEx = preIndex
 			skippy, err := skipAdmissionStats(dAtA[iNdEx:])
diff --git a/pkg/util/admission/admissionpb/admission_stats.proto b/pkg/util/admission/admissionpb/admission_stats.proto
index 3f48df2..99cbc0f 100644
--- a/pkg/util/admission/admissionpb/admission_stats.proto
+++ b/pkg/util/admission/admissionpb/admission_stats.proto
@@ -1,12 +1,7 @@
 // Copyright 2023 The Cockroach Authors.
 //
-// Use of this software is governed by the Business Source License
-// included in the file licenses/BSL.txt.
-//
-// As of the Change Date specified in that file, in accordance with
-// the Business Source License, use of this software will be governed
-// by the Apache License, Version 2.0, included in the file
-// licenses/APL.txt.
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
 
 syntax = "proto3";
 package cockroach.util.admission.admissionpb;
@@ -17,12 +12,27 @@ import "gogoproto/gogo.proto";
 // AdmissionWorkQueueStats is recorded for work items waiting in the admission
 // work queue.
 message AdmissionWorkQueueStats {
-  // Duration spent waiting.
+  option (gogoproto.goproto_stringer) = false;
+
+  // WaitDurationNanos is the time spent waiting.
   int64 wait_duration_nanos = 1 [(gogoproto.casttype) = "time.Duration"];
-  // String representation of admission queue kind.
+
+  // QueueKind is the string name of the admission queue kind.
   string queue_kind = 2;
-  // Set to true if deadline was exceeded.
-  bool deadline_exceeded = 3;
-  // String representation of work priority.
-  string work_priority = 4;
+
+  reserved 3;
+
+  // DeadlineExceededCount counts the number of times -- usually zero or one
+  // unless the stats are an aggregate -- that the deadline was exceeded while
+  // waiting in the queue.
+  int32 deadline_exceeded_count = 5;
+
+  reserved 4;
+  // WorkPriority is the integer representation of work priority, or if the
+  // AdmissionWorkQueueStats represents an aggregation of stats, the minimum of
+  // the priorities across the aggregated stats.
+  int32 work_priority = 6;
+
+  // TODO(dt): consider adding map <string, AdmissionWorkQueueStats> agg = 7 to
+  // aggregate events from separate queues separately when rolling up events.
 }
diff --git a/pkg/util/admission/admissionpb/admissionpb.go b/pkg/util/admission/admissionpb/admissionpb.go
index 53d7f01..2a549d6 100644
--- a/pkg/util/admission/admissionpb/admissionpb.go
+++ b/pkg/util/admission/admissionpb/admissionpb.go
@@ -1,20 +1,20 @@
 // Copyright 2022 The Cockroach Authors.
 //
-// Use of this software is governed by the Business Source License
-// included in the file licenses/BSL.txt.
-//
-// As of the Change Date specified in that file, in accordance with
-// the Business Source License, use of this software will be governed
-// by the Apache License, Version 2.0, included in the file
-// licenses/APL.txt.
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
 
 package admissionpb
 
 import (
+	"fmt"
 	"math"
 
+	"github.com/cockroachdb/cockroachdb-parser/pkg/util/humanizeutil"
+	"github.com/cockroachdb/cockroachdb-parser/pkg/util/tracing"
 	"github.com/cockroachdb/errors"
 	"github.com/cockroachdb/redact"
+	"github.com/gogo/protobuf/proto"
+	"go.opentelemetry.io/otel/attribute"
 )
 
 // WorkPriority represents the priority of work. In an WorkQueue, it is only
@@ -27,8 +27,8 @@ type WorkPriority int8
 const (
 	// LowPri is low priority work.
 	LowPri WorkPriority = math.MinInt8
-	// TTLLowPri is low priority work from TTL internal submissions.
-	TTLLowPri WorkPriority = -100
+	// BulkLowPri is low priority work from internal bulk submissions.
+	BulkLowPri WorkPriority = -100
 	// UserLowPri is low priority work from user submissions (SQL).
 	UserLowPri WorkPriority = -50
 	// BulkNormalPri is bulk priority work from bulk jobs, which could be run due
@@ -57,7 +57,7 @@ func (w WorkPriority) String() string {
 // SafeFormat implements the redact.SafeFormatter interface.
 func (w WorkPriority) SafeFormat(p redact.SafePrinter, verb rune) {
 	if s, ok := WorkPriorityDict[w]; ok {
-		p.Print(s)
+		p.SafeString(redact.SafeString(s))
 		return
 	}
 	p.Printf("custom-pri=%d", int8(w))
@@ -67,7 +67,7 @@ func (w WorkPriority) SafeFormat(p redact.SafePrinter, verb rune) {
 // name is used as the suffix on exported work queue metrics.
 var WorkPriorityDict = map[WorkPriority]string{
 	LowPri:           "low-pri",
-	TTLLowPri:        "ttl-low-pri",
+	BulkLowPri:       "bulk-low-pri",
 	UserLowPri:       "user-low-pri",
 	BulkNormalPri:    "bulk-normal-pri",
 	NormalPri:        "normal-pri",
@@ -104,7 +104,7 @@ func init() {
 
 	orderedPris := []WorkPriority{
 		LowPri,
-		TTLLowPri,
+		BulkLowPri,
 		UserLowPri,
 		BulkNormalPri,
 		NormalPri,
@@ -189,6 +189,37 @@ const (
 	NumWorkClasses
 )
 
+// StoreWorkType represents the type of work,
+type StoreWorkType int8
+
+const (
+	// RegularStoreWorkType is for type of store-specific work that corresponds to
+	// RegularWorkClass.
+	RegularStoreWorkType StoreWorkType = iota
+	// SnapshotIngestStoreWorkType is for snapshot work type. It is classified as
+	// ElasticWorkClass, but is prioritized higher than other work of that class.
+	SnapshotIngestStoreWorkType = 1
+	// ElasticStoreWorkType is for store-specific work that corresponds to
+	// ElasticWorkClass, excluding SnapshotIngestStoreWorkType.
+	ElasticStoreWorkType = 2
+	// NumStoreWorkTypes is the number of store work types.
+	NumStoreWorkTypes = 3
+)
+
+// WorkClassFromStoreWorkType translates StoreWorkType to a WorkClass
+func WorkClassFromStoreWorkType(workType StoreWorkType) WorkClass {
+	var class WorkClass
+	switch workType {
+	case RegularStoreWorkType:
+		class = RegularWorkClass
+	case ElasticStoreWorkType:
+		class = ElasticWorkClass
+	case SnapshotIngestStoreWorkType:
+		class = ElasticWorkClass
+	}
+	return class
+}
+
 // WorkClassFromPri translates a WorkPriority to its given WorkClass.
 func WorkClassFromPri(pri WorkPriority) WorkClass {
 	class := RegularWorkClass
@@ -206,17 +237,100 @@ func (w WorkClass) String() string {
 func (w WorkClass) SafeFormat(p redact.SafePrinter, verb rune) {
 	switch w {
 	case RegularWorkClass:
-		p.Printf("regular")
+		p.SafeString("regular")
 	case ElasticWorkClass:
-		p.Printf("elastic")
+		p.SafeString("elastic")
 	default:
-		p.Printf("<unknown-class>")
+		p.SafeString("<unknown-class>")
+	}
+}
+
+var _ tracing.AggregatorEvent = &AdmissionWorkQueueStats{}
+
+// Identity implements the tracing.AggregatorEvent interface.
+func (s *AdmissionWorkQueueStats) Identity() tracing.AggregatorEvent {
+	return &AdmissionWorkQueueStats{WorkPriority: int32(HighPri)}
+}
+
+// Combine implements the tracing.AggregatorEvent interface.
+func (s *AdmissionWorkQueueStats) Combine(other tracing.AggregatorEvent) {
+	otherStats, ok := other.(*AdmissionWorkQueueStats)
+	if !ok {
+		panic(errors.Newf("`other` is not of type AdmissionWorkQueueStats: %T", other))
+	}
+	s.WaitDurationNanos += otherStats.WaitDurationNanos
+	s.DeadlineExceededCount += otherStats.DeadlineExceededCount
+	s.WorkPriority = min(s.WorkPriority, otherStats.WorkPriority)
+
+	if s.QueueKind == "" {
+		s.QueueKind = otherStats.QueueKind
+	} else if s.QueueKind != otherStats.QueueKind {
+		s.QueueKind = "multiple-queues"
+		// TODO(dt): consider adding a map of queue kinds to counts, e.g.:
+		/*
+			if s.Agg == nil {
+				s.Agg = make(map[string]*AdmissionWorkQueueStats)
+				s.Agg[otherStats.QueueKind] = otherStats
+			} else if perQueue, ok := s.Agg[otherStats.QueueKind]; !ok {
+				s.Agg[otherStats.QueueKind] = otherStats
+			} else {
+				perQueue.Combine(otherStats)
+			}
+		*/
+	}
+}
+
+// ProtoName implements the tracing.AggregatorEvent interface.
+func (s *AdmissionWorkQueueStats) ProtoName() string {
+	return proto.MessageName(s)
+}
+
+func (s *AdmissionWorkQueueStats) ToText() []byte {
+	return []byte(s.String())
+}
+
+func (s *AdmissionWorkQueueStats) String() string {
+	return fmt.Sprintf("queue (%s/%s) wait: %s",
+		redact.SafeString(s.QueueKind),
+		WorkPriority(s.WorkPriority),
+		humanizeutil.Duration(s.WaitDurationNanos),
+	)
+
+	// TODO(dt): consider supporting a map over multiple queues when aggregating
+	// into a single stat, e.g. treat the above as a fast-path if the map is nil
+	// but otherwise do something like this:
+	/*
+		var b strings.Builder
+		fmt.Fprintf(&b, "queue (%s/%s) wait: %s (",
+			redact.SafeString(s.QueueKind),
+			WorkPriority(s.WorkPriority),
+			humanizeutil.Duration(s.WaitDurationNanos),
+		)
+
+		for _, v := range s.Agg {
+			fmt.Fprintf(&b, "%s[%s]: %s;",
+				redact.SafeString(v.QueueKind),
+				WorkPriority(s.WorkPriority),
+				humanizeutil.Duration(v.WaitDurationNanos),
+			)
+		}
+		b.WriteString(")")
+		return b.String()
+	*/
+}
+
+// Render implements the AggregatorEvent interface.
+func (s *AdmissionWorkQueueStats) Render() []attribute.KeyValue {
+	return []attribute.KeyValue{
+		{Key: "queue_wait", Value: attribute.StringValue(string(humanizeutil.Duration(s.WaitDurationNanos)))},
+		{Key: "queue_kind", Value: attribute.StringValue(s.QueueKind)},
+		{Key: "queue_priority", Value: attribute.StringValue(WorkPriority(s.WorkPriority).String())},
 	}
 }
 
 // Prevent the linter from emitting unused warnings.
 var _ = LowPri
-var _ = TTLLowPri
+var _ = BulkLowPri
 var _ = UserLowPri
 var _ = NormalPri
 var _ = UserHighPri
diff --git a/pkg/util/admission/admissionpb/doc.go b/pkg/util/admission/admissionpb/doc.go
index 6355418..33c8ca5 100644
--- a/pkg/util/admission/admissionpb/doc.go
+++ b/pkg/util/admission/admissionpb/doc.go
@@ -1,12 +1,7 @@
 // Copyright 2022 The Cockroach Authors.
 //
-// Use of this software is governed by the Business Source License
-// included in the file licenses/BSL.txt.
-//
-// As of the Change Date specified in that file, in accordance with
-// the Business Source License, use of this software will be governed
-// by the Apache License, Version 2.0, included in the file
-// licenses/APL.txt.
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
 
 // Package admissionpb contains the base types for the admission package.
 // This is to prevent excess dependencies to util/log on sessiondatapb.
diff --git a/pkg/util/admission/admissionpb/io_threshold.go b/pkg/util/admission/admissionpb/io_threshold.go
index 5e7c503..05f3983 100644
--- a/pkg/util/admission/admissionpb/io_threshold.go
+++ b/pkg/util/admission/admissionpb/io_threshold.go
@@ -1,12 +1,7 @@
 // Copyright 2022 The Cockroach Authors.
 //
-// Use of this software is governed by the Business Source License
-// included in the file licenses/BSL.txt.
-//
-// As of the Change Date specified in that file, in accordance with
-// the Business Source License, use of this software will be governed
-// by the Apache License, Version 2.0, included in the file
-// licenses/APL.txt.
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
 
 package admissionpb
 
@@ -19,17 +14,24 @@ import (
 
 // Score returns, as the second return value, whether IO admission control is
 // considering the Store overloaded wrt compaction of L0. The first return
-// value is a 1-normalized float (i.e. 1.0 is the threshold at which the
-// second value flips to true).
+// value is a 1-normalized float, where 1.0 represents severe overload, and
+// therefore 1.0 is the threshold at which the second value flips to true.
+// Admission control currently trys to maintain a store around a score
+// threshold of 0.5 for regular work and lower than 0.25 for elastic work. NB:
+// this is an incomplete representation of the signals considered by admission
+// control -- admission control additionally considers disk and flush
+// throughput bottlenecks.
 //
 // The zero value returns (0, false). Use of the nil pointer is not allowed.
 //
-// TODO(sumeer): consider whether we need to enhance this to incorporate
-// overloading via flush bandwidth. I suspect we can get away without
-// incorporating flush bandwidth since typically chronic overload will be due
-// to compactions falling behind (though that may change if we increase the
-// max number of compactions). And we will need to incorporate overload due to
-// disk bandwidth bottleneck.
+// NOTE: Future updates to the scoring function should be version gated as the
+// threshold is gossiped and used to determine lease/replica placement via the
+// allocator.
+//
+// IOThreshold has various parameters that can evolve over time. The source of
+// truth for an IOThreshold struct is admission.ioLoadListener, and is
+// propagated elsewhere using the admission.IOThresholdConsumer interface. No
+// other production code should create one from scratch.
 func (iot *IOThreshold) Score() (float64, bool) {
 	// iot.L0NumFilesThreshold and iot.L0NumSubLevelsThreshold are initialized to
 	// 0 by default, and there appears to be a period of time before we update
diff --git a/pkg/util/admission/admissionpb/io_threshold.pb.go b/pkg/util/admission/admissionpb/io_threshold.pb.go
index a6b9941..2797db4 100644
--- a/pkg/util/admission/admissionpb/io_threshold.pb.go
+++ b/pkg/util/admission/admissionpb/io_threshold.pb.go
@@ -187,7 +187,7 @@ func (m *IOThreshold) Size() (n int) {
 }
 
 func sovIoThreshold(x uint64) (n int) {
-	return (math_bits.Len64(x|1) + 6) / 7
+	return int((uint32(math_bits.Len64(x|1)+6) * 37) >> 8)
 }
 func sozIoThreshold(x uint64) (n int) {
 	return sovIoThreshold(uint64((x << 1) ^ uint64((int64(x) >> 63))))
diff --git a/pkg/util/admission/admissionpb/io_threshold.proto b/pkg/util/admission/admissionpb/io_threshold.proto
index 53a23f3..944b9f4 100644
--- a/pkg/util/admission/admissionpb/io_threshold.proto
+++ b/pkg/util/admission/admissionpb/io_threshold.proto
@@ -1,12 +1,7 @@
 // Copyright 2022 The Cockroach Authors.
 //
-// Use of this software is governed by the Business Source License
-// included in the file licenses/BSL.txt.
-//
-// As of the Change Date specified in that file, in accordance with
-// the Business Source License, use of this software will be governed
-// by the Apache License, Version 2.0, included in the file
-// licenses/APL.txt.
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
 
 syntax = "proto3";
 package cockroach.util.admission.admissionpb;
diff --git a/pkg/util/allstacks/allstacks.go b/pkg/util/allstacks/allstacks.go
new file mode 100644
index 0000000..ebbfc6a
--- /dev/null
+++ b/pkg/util/allstacks/allstacks.go
@@ -0,0 +1,37 @@
+// Copyright 2023 The Cockroach Authors.
+//
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
+
+package allstacks
+
+import (
+	"runtime"
+
+	"github.com/cockroachdb/cockroachdb-parser/pkg/util/debugutil"
+)
+
+// Get returns all stacks, except if that takes more than 512mb of memory, in
+// which case it returns only 512mb worth of stacks (clipping the last stack
+// if necessary).
+func Get() debugutil.SafeStack {
+	return GetWithBuf(nil)
+}
+
+// GetWithBuf is like Get, but tries to use the provided slice first, allocating
+// a new, larger, slice only if necessary.
+func GetWithBuf(buf []byte) debugutil.SafeStack {
+	buf = buf[:cap(buf)]
+	// We don't know how big the traces are, so grow a few times if they don't
+	// fit. Start large, though.
+	for n := 1 << 20; /* 1mb */ n <= (1 << 29); /* 512mb */ n *= 2 {
+		if len(buf) < n {
+			buf = make([]byte, n)
+		}
+		nbytes := runtime.Stack(buf, true /* all */)
+		if nbytes < len(buf) {
+			return buf[:nbytes]
+		}
+	}
+	return buf // returning full 512MB slice
+}
diff --git a/pkg/util/arith/arith.go b/pkg/util/arith/arith.go
index 82488d7..66fd82c 100644
--- a/pkg/util/arith/arith.go
+++ b/pkg/util/arith/arith.go
@@ -1,12 +1,7 @@
 // Copyright 2018 The Cockroach Authors.
 //
-// Use of this software is governed by the Business Source License
-// included in the file licenses/BSL.txt.
-//
-// As of the Change Date specified in that file, in accordance with
-// the Business Source License, use of this software will be governed
-// by the Apache License, Version 2.0, included in the file
-// licenses/APL.txt.
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
 
 package arith
 
diff --git a/pkg/util/base64/base64.go b/pkg/util/base64/base64.go
new file mode 100644
index 0000000..76d4029
--- /dev/null
+++ b/pkg/util/base64/base64.go
@@ -0,0 +1,84 @@
+// Copyright 2025 The Cockroach Authors.
+//
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
+
+package base64
+
+import (
+	"bytes"
+	"encoding/base64"
+)
+
+// Encoder is a streaming encoder for base64 strings. It must be initialized
+// with Init.
+//
+// The code has been adapted from the standard library encoder that is returned
+// by base64.NewEncoder. The main differences are that Init allows for an
+// Encoder value to be initialized directly and that it writes to an internal
+// strings.Builder instead of an io.Writer. Both allow streaming encoding
+// without extra allocations. Writes to a strings.Builder never fail, so error
+// handling has been removed for simplification.
+type Encoder struct {
+	enc  *base64.Encoding
+	sb   bytes.Buffer
+	buf  [3]byte    // buffered data waiting to be encoded
+	nbuf int8       // number of bytes in buf
+	out  [1024]byte // output buffer
+}
+
+// Init initializes an Encoder with the given base64.Encoding.
+func (e *Encoder) Init(enc *base64.Encoding) {
+	*e = Encoder{
+		enc: enc,
+	}
+}
+
+// Write encodes p in an internal buffer.
+func (e *Encoder) Write(p []byte) {
+	// Leading fringe.
+	if e.nbuf > 0 {
+		var i int
+		for i = 0; i < len(p) && e.nbuf < 3; i++ {
+			e.buf[e.nbuf] = p[i]
+			e.nbuf++
+		}
+		p = p[i:]
+		if e.nbuf < 3 {
+			return
+		}
+		e.enc.Encode(e.out[:], e.buf[:])
+		_, _ = e.sb.Write(e.out[:4])
+		e.nbuf = 0
+	}
+
+	// Large interior chunks.
+	for len(p) >= 3 {
+		nn := len(e.out) / 4 * 3
+		if nn > len(p) {
+			nn = len(p)
+			nn -= nn % 3
+		}
+		e.enc.Encode(e.out[:], p[:nn])
+		_, _ = e.sb.Write(e.out[0 : nn/3*4])
+		p = p[nn:]
+	}
+
+	// Trailing fringe.
+	copy(e.buf[:], p)
+	e.nbuf = int8(len(p))
+}
+
+// String flushes any pending output from the encoder and returns the encoded
+// string. The Encoder is reset to its initial state so it can be reused.
+func (e *Encoder) String() (s string) {
+	// If there's anything left in the buffer, flush it out.
+	if e.nbuf > 0 {
+		e.enc.Encode(e.out[:], e.buf[:e.nbuf])
+		_, _ = e.sb.Write(e.out[:e.enc.EncodedLen(int(e.nbuf))])
+		e.nbuf = 0
+	}
+	s = e.sb.String()
+	e.Init(e.enc)
+	return s
+}
diff --git a/pkg/util/bitarray/bitarray.go b/pkg/util/bitarray/bitarray.go
index 274135f..9ec2f50 100644
--- a/pkg/util/bitarray/bitarray.go
+++ b/pkg/util/bitarray/bitarray.go
@@ -1,12 +1,7 @@
 // Copyright 2018 The Cockroach Authors.
 //
-// Use of this software is governed by the Business Source License
-// included in the file licenses/BSL.txt.
-//
-// As of the Change Date specified in that file, in accordance with
-// the Business Source License, use of this software will be governed
-// by the Apache License, Version 2.0, included in the file
-// licenses/APL.txt.
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
 
 package bitarray
 
@@ -587,8 +582,7 @@ func Next(d BitArray) BitArray {
 func (d BitArray) GetBitAtIndex(index int) (int, error) {
 	// Check whether index asked is inside BitArray.
 	if index < 0 || uint(index) >= d.BitLen() {
-		err := fmt.Errorf("GetBitAtIndex: bit index %d out of valid range (0..%d)", index, int(d.BitLen())-1)
-		return 0, pgerror.WithCandidateCode(err, pgcode.ArraySubscript)
+		return 0, pgerror.Newf(pgcode.ArraySubscript, "bit index %d out of valid range (0..%d)", index, int(d.BitLen())-1)
 	}
 	// To extract bit at the given index, we have to determine the
 	// position within words array, i.e. index/numBitsPerWord after
@@ -604,8 +598,7 @@ func (d BitArray) SetBitAtIndex(index, toSet int) (BitArray, error) {
 	res := d.Clone()
 	// Check whether index asked is inside BitArray.
 	if index < 0 || uint(index) >= res.BitLen() {
-		err := fmt.Errorf("SetBitAtIndex: bit index %d out of valid range (0..%d)", index, int(res.BitLen())-1)
-		return BitArray{}, pgerror.WithCandidateCode(err, pgcode.ArraySubscript)
+		return BitArray{}, pgerror.Newf(pgcode.ArraySubscript, "bit index %d out of valid range (0..%d)", index, int(res.BitLen())-1)
 	}
 	// To update bit at the given index, we have to determine the
 	// position within words array, i.e. index/numBitsPerWord after
diff --git a/pkg/util/buildutil/crdb_test_off.go b/pkg/util/buildutil/crdb_test_off.go
index 777c902..0d058ff 100644
--- a/pkg/util/buildutil/crdb_test_off.go
+++ b/pkg/util/buildutil/crdb_test_off.go
@@ -1,15 +1,9 @@
 // Copyright 2020 The Cockroach Authors.
 //
-// Use of this software is governed by the Business Source License
-// included in the file licenses/BSL.txt.
-//
-// As of the Change Date specified in that file, in accordance with
-// the Business Source License, use of this software will be governed
-// by the Apache License, Version 2.0, included in the file
-// licenses/APL.txt.
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
 
 //go:build !crdb_test || crdb_test_off
-// +build !crdb_test crdb_test_off
 
 // Package buildutil provides a constant CrdbTestBuild.
 package buildutil
diff --git a/pkg/util/buildutil/crdb_test_on.go b/pkg/util/buildutil/crdb_test_on.go
index 7f9bd62..87fe7aa 100644
--- a/pkg/util/buildutil/crdb_test_on.go
+++ b/pkg/util/buildutil/crdb_test_on.go
@@ -1,15 +1,9 @@
 // Copyright 2020 The Cockroach Authors.
 //
-// Use of this software is governed by the Business Source License
-// included in the file licenses/BSL.txt.
-//
-// As of the Change Date specified in that file, in accordance with
-// the Business Source License, use of this software will be governed
-// by the Apache License, Version 2.0, included in the file
-// licenses/APL.txt.
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
 
 //go:build crdb_test && !crdb_test_off
-// +build crdb_test,!crdb_test_off
 
 // Package buildutil provides a constant CrdbTestBuild.
 package buildutil
diff --git a/pkg/util/cache/cache.go b/pkg/util/cache/cache.go
index e5ec6b4..e156edc 100644
--- a/pkg/util/cache/cache.go
+++ b/pkg/util/cache/cache.go
@@ -1,12 +1,7 @@
 // Copyright 2014 The Cockroach Authors.
 //
-// Use of this software is governed by the Business Source License
-// included in the file licenses/BSL.txt.
-//
-// As of the Change Date specified in that file, in accordance with
-// the Business Source License, use of this software will be governed
-// by the Apache License, Version 2.0, included in the file
-// licenses/APL.txt.
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
 //
 // This code is based on: https://github.com/golang/groupcache/
 
diff --git a/pkg/util/collatedstring/collatedstring.go b/pkg/util/collatedstring/collatedstring.go
index 9c9a31c..a6a99e1 100644
--- a/pkg/util/collatedstring/collatedstring.go
+++ b/pkg/util/collatedstring/collatedstring.go
@@ -1,12 +1,7 @@
 // Copyright 2023 The Cockroach Authors.
 //
-// Use of this software is governed by the Business Source License
-// included in the file licenses/BSL.txt.
-//
-// As of the Change Date specified in that file, in accordance with
-// the Business Source License, use of this software will be governed
-// by the Apache License, Version 2.0, included in the file
-// licenses/APL.txt.
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
 
 package collatedstring
 
diff --git a/pkg/util/constants.go b/pkg/util/constants.go
deleted file mode 100644
index 4e2e8b4..0000000
--- a/pkg/util/constants.go
+++ /dev/null
@@ -1,191 +0,0 @@
-// Copyright 2020 The Cockroach Authors.
-//
-// Use of this software is governed by the Business Source License
-// included in the file licenses/BSL.txt.
-//
-// As of the Change Date specified in that file, in accordance with
-// the Business Source License, use of this software will be governed
-// by the Apache License, Version 2.0, included in the file
-// licenses/APL.txt.
-
-package util
-
-import (
-	"fmt"
-	"math/rand"
-	"os"
-
-	"github.com/cockroachdb/cockroachdb-parser/pkg/build/bazel"
-	"github.com/cockroachdb/cockroachdb-parser/pkg/util/buildutil"
-	"github.com/cockroachdb/cockroachdb-parser/pkg/util/randutil"
-	"github.com/cockroachdb/cockroachdb-parser/pkg/util/syncutil"
-)
-
-// IsMetamorphicBuild returns whether this build is metamorphic. By build being
-// "metamorphic" we mean that some magic constants in the codebase might get
-// initialized to non-default value.
-// A build will become metamorphic with metamorphicBuildProbability probability
-// if 'crdb_test' build flag is specified (this is the case for all test
-// targets).
-func IsMetamorphicBuild() bool {
-	return metamorphicBuild
-}
-
-var metamorphicBuild bool
-
-const (
-	metamorphicBuildProbability = 0.8
-	metamorphicValueProbability = 0.75
-	metamorphicBoolProbability  = 0.5
-)
-
-// ConstantWithMetamorphicTestValue should be used to initialize "magic
-// constants" that should be varied during test scenarios to check for bugs at
-// boundary conditions. When metamorphicBuild is true, the test value will be
-// used with metamorphicValueProbability probability. In all other cases, the
-// production ("default") value will be used.
-// The constant must be a "metamorphic variable": changing it cannot affect the
-// output of any SQL DMLs. It can only affect the way in which the data is
-// retrieved or processed, because otherwise the main test corpus would fail if
-// this flag were enabled.
-//
-// An example of a "magic constant" that behaves this way is a batch size. Batch
-// sizes tend to present testing problems, because often the logic that deals
-// with what to do when a batch is finished is less likely to be exercised by
-// simple unit tests that don't use enough data to fill up a batch.
-//
-// For example, instead of writing:
-//
-// const batchSize = 64
-//
-// you should write:
-//
-// var batchSize = util.ConstantWithMetamorphicTestValue("batch-size", 64, 1)
-//
-// This will often give your code a batch size of 1 in the crdb_test build
-// configuration, increasing the amount of exercise the edge conditions get.
-//
-// The given name is used for logging.
-func ConstantWithMetamorphicTestValue(name string, defaultValue, metamorphicValue int) int {
-	if metamorphicBuild {
-		rng.Lock()
-		defer rng.Unlock()
-		if rng.r.Float64() < metamorphicValueProbability {
-			logMetamorphicValue(name, metamorphicValue)
-			return metamorphicValue
-		}
-	}
-	return defaultValue
-}
-
-// rng is initialized to a rand.Rand if crdbTestBuild is enabled.
-var rng struct {
-	r *rand.Rand
-	syncutil.Mutex
-}
-
-// DisableMetamorphicEnvVar can be used to disable metamorphic tests for
-// sub-processes. If it exists and is set to something truthy as defined by
-// strconv.ParseBool then metamorphic testing will not be enabled.
-const DisableMetamorphicEnvVar = "COCKROACH_INTERNAL_DISABLE_METAMORPHIC_TESTING"
-
-// Returns true iff the current process is eligible to enable metamorphic
-// variables. When run under Bazel, checking if we are in the Go test wrapper
-// ensures that metamorphic variables are not initialized and logged twice
-// from both the wrapper and the main test process, as both will perform
-// initialization of the test module and its dependencies.
-func metamorphicEligible() bool {
-	if !buildutil.CrdbTestBuild {
-		return false
-	}
-
-	if bazel.InTestWrapper() {
-		return false
-	}
-
-	return true
-}
-
-func init() {
-	if metamorphicEligible() {
-		if !disableMetamorphicTesting {
-			rng.r, _ = randutil.NewTestRand()
-			metamorphicBuild = rng.r.Float64() < metamorphicBuildProbability
-		}
-	}
-}
-
-// ConstantWithMetamorphicTestRange is like ConstantWithMetamorphicTestValue
-// except instead of returning a single metamorphic test value, it returns a
-// random test value in the semi-open range [min, max).
-//
-// The given name is used for logging.
-func ConstantWithMetamorphicTestRange(name string, defaultValue, min, max int) int {
-	if metamorphicBuild {
-		rng.Lock()
-		defer rng.Unlock()
-		if rng.r.Float64() < metamorphicValueProbability {
-			ret := min
-			if max > min {
-				ret = int(rng.r.Int31())%(max-min) + min
-			}
-			logMetamorphicValue(name, ret)
-			return ret
-		}
-	}
-	return defaultValue
-}
-
-// ConstantWithMetamorphicTestBool is like ConstantWithMetamorphicTestValue except
-// it returns the non-default value half of the time (if running a metamorphic build).
-//
-// The given name is used for logging.
-func ConstantWithMetamorphicTestBool(name string, defaultValue bool) bool {
-	return constantWithMetamorphicTestBoolInternal(name, defaultValue, true /* doLog */)
-}
-
-func constantWithMetamorphicTestBoolInternal(name string, defaultValue bool, doLog bool) bool {
-	if metamorphicBuild {
-		rng.Lock()
-		defer rng.Unlock()
-		if rng.r.Float64() < metamorphicBoolProbability {
-			ret := !defaultValue
-			if doLog {
-				logMetamorphicValue(name, ret)
-			}
-			return ret
-		}
-	}
-	return defaultValue
-}
-
-// ConstantWithMetamorphicTestBoolWithoutLogging is like ConstantWithMetamorphicTestBool
-// except it does not log the value. This is necessary to work around this issue:
-// https://github.com/cockroachdb/cockroachdb-parser/issues/106667
-// TODO(test-eng): Remove this variant when the issue above is addressed.
-func ConstantWithMetamorphicTestBoolWithoutLogging(name string, defaultValue bool) bool {
-	return constantWithMetamorphicTestBoolInternal(name, defaultValue, false /* doLog */)
-}
-
-// ConstantWithMetamorphicTestChoice is like ConstantWithMetamorphicTestValue except
-// it returns a random choice (equally weighted) of the given values. The default
-// value is included in the random choice.
-//
-// The given name is used for logging.
-func ConstantWithMetamorphicTestChoice(
-	name string, defaultValue interface{}, otherValues ...interface{},
-) interface{} {
-	if metamorphicBuild {
-		values := append([]interface{}{defaultValue}, otherValues...)
-		rng.Lock()
-		defer rng.Unlock()
-		value := values[rng.r.Int63n(int64(len(values)))]
-		logMetamorphicValue(name, value)
-		return value
-	}
-	return defaultValue
-}
-
-func logMetamorphicValue(name string, value interface{}) {
-	fmt.Fprintf(os.Stderr, "initialized metamorphic constant %q with value %v\n", name, value)
-}
diff --git a/pkg/util/constants_metamorphic_disable.go b/pkg/util/constants_metamorphic_disable.go
deleted file mode 100644
index 64c53d2..0000000
--- a/pkg/util/constants_metamorphic_disable.go
+++ /dev/null
@@ -1,18 +0,0 @@
-// Copyright 2022 The Cockroach Authors.
-//
-// Use of this software is governed by the Business Source License
-// included in the file licenses/BSL.txt.
-//
-// As of the Change Date specified in that file, in accordance with
-// the Business Source License, use of this software will be governed
-// by the Apache License, Version 2.0, included in the file
-// licenses/APL.txt.
-
-//go:build metamorphic_disable
-// +build metamorphic_disable
-
-package util
-
-// DisableMetamorphicTesting can be used to disable metamorphic tests. If it
-// is set to true then metamorphic testing will not be enabled.
-var disableMetamorphicTesting = true
diff --git a/pkg/util/ctxutil/canceler_1_20.go b/pkg/util/ctxutil/canceler_1_20.go
new file mode 100644
index 0000000..77e9c2e
--- /dev/null
+++ b/pkg/util/ctxutil/canceler_1_20.go
@@ -0,0 +1,46 @@
+// Copyright 2023 The Cockroach Authors.
+//
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
+
+//go:build go1.20 && !go1.21
+
+package ctxutil
+
+import (
+	"context"
+	_ "unsafe"
+)
+
+// propagateCancel arranges for f to be invoked when parent completes.
+func propagateCancel(parent context.Context, f WhenDoneFunc) {
+	child := whenDone{Context: parent, notify: f}
+	context_propagateCancel(parent, &child)
+}
+
+// A canceler is a context type that can be canceled directly. The
+// implementations are *cancelCtx and *timerCtx.
+// This interface definition is applicable to go1.20 or higher
+type canceler interface {
+	cancel(removeFromParent bool, err, cause error)
+	Done() <-chan struct{}
+}
+
+// whenDone is an adopter that implements canceler interface.
+type whenDone struct {
+	context.Context
+	notify WhenDoneFunc
+}
+
+func (c *whenDone) cancel(removeFromParent bool, err, cause error) {
+	if removeFromParent {
+		context_removeChild(c.Context, c)
+	}
+	c.notify()
+}
+
+//go:linkname context_removeChild context.removeChild
+func context_removeChild(parent context.Context, child canceler)
+
+//go:linkname context_propagateCancel context.propagateCancel
+func context_propagateCancel(parent context.Context, child canceler)
diff --git a/pkg/util/ctxutil/canceler_1_21.go b/pkg/util/ctxutil/canceler_1_21.go
new file mode 100644
index 0000000..540cdd7
--- /dev/null
+++ b/pkg/util/ctxutil/canceler_1_21.go
@@ -0,0 +1,27 @@
+// Copyright 2023 The Cockroach Authors.
+//
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
+
+//go:build go1.21 && !bazel
+
+package ctxutil
+
+import "context"
+
+// Linkage definition for go1.21 or higher built outside ./dev toolchain --
+// that is, a toolchain that did not apply cockroach runtime patches.
+
+// Since this code was built outside ./dev (i.e. "!bazel" tag defined),
+// we cannot use patched context implementation.
+// Instead, fallback to spinning up goroutine to detect parent cancellation.
+func propagateCancel(parent context.Context, notify WhenDoneFunc) {
+	done := parent.Done()
+	if done == nil {
+		panic("unexpected non-cancelable context")
+	}
+	go func() {
+		<-done
+		notify()
+	}()
+}
diff --git a/pkg/util/ctxutil/canceler_1_21_bazel.go b/pkg/util/ctxutil/canceler_1_21_bazel.go
new file mode 100644
index 0000000..18b8895
--- /dev/null
+++ b/pkg/util/ctxutil/canceler_1_21_bazel.go
@@ -0,0 +1,27 @@
+// Copyright 2023 The Cockroach Authors.
+//
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
+
+//go:build go1.21 && bazel
+
+package ctxutil
+
+import (
+	"context"
+
+	"github.com/cockroachdb/errors"
+)
+
+// Linkage definition for go1.21 or higher built with ./dev toolchain --
+// that is, a toolchain that applies cockroach runtime patches.
+
+// propagateCancel invokes notify when parent context completes.
+// Since this code was built with ./dev, use patched context.Context to access
+// needed functionality.
+func propagateCancel(parent context.Context, notify WhenDoneFunc) {
+	if !context.PropagateCancel(parent, notify) {
+		// This shouldn't happen since WhenDone checks to make sure parent is cancellable.
+		panic(errors.Newf("parent context expected to be cancellable, found %T", parent))
+	}
+}
diff --git a/pkg/util/ctxutil/context.go b/pkg/util/ctxutil/context.go
new file mode 100644
index 0000000..3461c95
--- /dev/null
+++ b/pkg/util/ctxutil/context.go
@@ -0,0 +1,9 @@
+// Copyright 2023 The Cockroach Authors.
+//
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
+
+package ctxutil
+
+// WhenDoneFunc is the callback invoked by context when it becomes done.
+type WhenDoneFunc func()
diff --git a/pkg/util/ctxutil/context_linkname.go b/pkg/util/ctxutil/context_linkname.go
new file mode 100644
index 0000000..79fba95
--- /dev/null
+++ b/pkg/util/ctxutil/context_linkname.go
@@ -0,0 +1,82 @@
+// Copyright 2025 The Cockroach Authors.
+//
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
+//
+// This file includes an implementation of WhenDone for builds using our Go
+// fork, or versions of Go prior to 1.23. These Go versions will permit the use
+// of go:linkname on the object context.cancelCtxKey.
+//
+//go:build bazel || (gc && !go1.23)
+
+package ctxutil
+
+import (
+	"context"
+	"fmt"
+	_ "unsafe" // Must import unsafe to enable linkname.
+
+	"github.com/cockroachdb/cockroachdb-parser/pkg/util/buildutil"
+)
+
+// WhenDone arranges for the specified function to be invoked when
+// parent context becomes done and returns true.
+// If the context is non-cancellable (i.e. `Done() == nil`), returns false and
+// never calls the function.
+// If the parent context is derived from context.WithCancel or
+// context.WithTimeout/Deadline, then no additional goroutines are created.
+// Otherwise, a goroutine is spun up by context.Context to detect
+// parent cancellation.
+//
+// Please be careful when using this function on the parent context
+// that may already be done.  In particular, be mindful of the dangers of
+// the done function acquiring locks:
+//
+//	func bad(ctx context.Context) {
+//	   var l syncutil.Mutex
+//	   l.Lock()
+//	   defer l.Unlock()
+//	   ctxutil.WhenDone(ctx, func() {
+//	     l.Lock() // <-- Deadlock if ctx is already done.
+//	   })
+//	   return
+//	}
+func WhenDone(parent context.Context, done WhenDoneFunc) bool {
+	if parent.Done() == nil {
+		return false
+	}
+
+	// All contexts that complete (ctx.Done() != nil) used in cockroach should
+	// support direct cancellation detection, since they should be derived from
+	// one of the standard context.Context.
+	// But, be safe and loudly fail tests in case somebody introduces strange
+	// context implementation.
+	if buildutil.CrdbTestBuild && !CanDirectlyDetectCancellation(parent) {
+		panic(fmt.Sprintf("expected context that supports direct cancellation detection, found %T", parent))
+	}
+
+	propagateCancel(parent, done)
+	return true
+}
+
+// CanDirectlyDetectCancellation checks to make sure that the parent
+// context can be used to detect parent cancellation without the need
+// to spin up goroutine.
+// That would mean that the parent context is derived from
+// context.WithCancel or context.WithTimeout/Deadline.
+// Even if parent is not derived from one of the above contexts (i.e. it
+// is a custom implementation), WhenDone function can still be used; it just
+// means that there will be an additional goroutine spun up.  As such,
+// this function is meant to be used in test environment only.
+func CanDirectlyDetectCancellation(parent context.Context) bool {
+	// context.parentCancelCtx would have been preferred mechanism to check
+	// if the cancellation can be propagated; alas, this function returns
+	// an unexported *cancelCtx, which we do not have access to.
+	// So, instead try to do what that method essentially does by
+	// getting access to internal cancelCtxKey.
+	cancellable, ok := parent.Value(&context_cancelCtxKey).(context.Context)
+	return ok && cancellable.Done() == parent.Done()
+}
+
+//go:linkname context_cancelCtxKey context.cancelCtxKey
+var context_cancelCtxKey int
diff --git a/pkg/util/ctxutil/context_no_linkname.go b/pkg/util/ctxutil/context_no_linkname.go
new file mode 100644
index 0000000..50c2500
--- /dev/null
+++ b/pkg/util/ctxutil/context_no_linkname.go
@@ -0,0 +1,27 @@
+// Copyright 2025 The Cockroach Authors.
+//
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
+//
+// This file includes an implementation of WhenDone for builds after Go 1.23
+// that do not use our Go fork.
+//
+//go:build !bazel && gc && go1.23
+
+package ctxutil
+
+import "context"
+
+// WhenDone arranges for the specified function to be invoked when
+// parent context becomes done and returns true.
+// See context_bazel.go for the full documentation on this function.
+// This version does the same but is missing an assertion that requires the
+// patched Go runtime to work properly.
+func WhenDone(parent context.Context, done WhenDoneFunc) bool {
+	if parent.Done() == nil {
+		return false
+	}
+
+	propagateCancel(parent, done)
+	return true
+}
diff --git a/pkg/util/ctxutil/doc.go b/pkg/util/ctxutil/doc.go
new file mode 100644
index 0000000..a78768e
--- /dev/null
+++ b/pkg/util/ctxutil/doc.go
@@ -0,0 +1,38 @@
+// Copyright 2023 The Cockroach Authors.
+//
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
+
+package ctxutil
+
+/*
+
+This package provides context utilities that require some "black magic" to
+access internals of context.Context implementation.
+
+In particular, this package provides WhenDone function:
+
+// WhenDone arranges for the specified function to be invoked when
+// parent context becomes done and returns true.
+func WhenDone(parent context.Context, done WhenDoneFunc) bool {...}
+
+
+Obviously, one can detect when parent is done and simply invoke the function
+when that happens using simple goroutine:
+go func() {
+  select {
+    <-parent.Done()
+    invokeCallback()
+}()
+
+However, doing so requires spinning up goroutines.  Goroutines are very cheap,
+but not 0 cost.  Certain performance critical code should avoid adding additional
+goroutines if it can be helped (every goroutine adds just a bit of load on go scheduler,
+and when the goroutine is created, it has to run; create enough of these goroutines,
+and scheduler will experience high latency).
+
+Hence, the "black magic" in this package.
+
+Currently, there are condition compilation available for go1.19, go1.20, and go1.21.
+Once switch to go1.21 completes, earlier version hacks may be removed.
+*/
diff --git a/pkg/util/ctxutil/fast_value.go b/pkg/util/ctxutil/fast_value.go
new file mode 100644
index 0000000..c6217a1
--- /dev/null
+++ b/pkg/util/ctxutil/fast_value.go
@@ -0,0 +1,249 @@
+// Copyright 2024 The Cockroach Authors.
+//
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
+
+package ctxutil
+
+import (
+	"context"
+	"sync/atomic"
+
+	"github.com/cockroachdb/cockroachdb-parser/pkg/util/buildutil"
+	"github.com/cockroachdb/logtags"
+)
+
+// FastValueKey is a key that can be used to get and set a fast value. Keys must
+// be initialized using RegisterFastValueKey().
+type FastValueKey uint8
+
+// MaxFastValues is the number of FastValueKeys that can be registered.
+//
+// To register new values, this constant will need to be increased (which could
+// cause a regression in performance).
+const MaxFastValues = 8
+
+// FastValue retrieves the value for the given key.
+func FastValue(ctx context.Context, key FastValueKey) any {
+	// This case is not necessary, but it should improve the fast path a bit.
+	if c, ok := ctx.(*fastValuesCtx); ok {
+		return c.values[key]
+	}
+	if v := ctx.Value(fastValuesAncestorKey{}); v != nil {
+		return v.(*fastValuesCtx).values[key]
+	}
+	return nil
+}
+
+// WithFastValue creates a new context with a new value for the given key. It
+// overrides any existing value for that same key.
+//
+// The given value will be returned by FastValue(ctx, key). The key must have
+// been generated using RegisterFastValueKey().
+//
+// This is a more efficient alternative to using context.WithValue() and
+// Context.Value().
+func WithFastValue(parent context.Context, key FastValueKey, val any) context.Context {
+	ancestor, parent := findFastValuesCtxAncestor(parent)
+	ctx := newFastValuesCtx(ancestor, parent)
+	ctx.values[key] = val
+	return ctx
+}
+
+// WithFastValues starts the process of creating a new context that sets a
+// number of fast values. The returned builder can be used to set values and
+// construct the context; it also provides efficient access to the current
+// values in the parent context.
+//
+// Sample usage:
+//
+//	b := WithFastValues(ctx)
+//	b.Set(key1, val1)
+//	b.Set(key2, val2)
+//	ctx = b.Finish()
+func WithFastValues(parent context.Context) FastValuesBuilder {
+	ancestor, parent := findFastValuesCtxAncestor(parent)
+	return FastValuesBuilder{
+		ctx: newFastValuesCtx(ancestor, parent),
+	}
+}
+
+// WithFastValuesPrealloc is like WithFastValues, but preallocates multiple
+// contexts that can later be reused on subsequent WithFastValue(s) calls to
+// save on allocations.
+func WithFastValuesPrealloc(parent context.Context) FastValuesBuilder {
+	ancestor, parent := findFastValuesCtxAncestor(parent)
+	container := &fastValuesContainer{}
+	container.used.Store(1)
+	ctx := &container.buf[0]
+	ctx.init(parent, container, ancestor)
+	return FastValuesBuilder{
+		ctx: ctx,
+	}
+}
+
+// FastValuesBuilder contains multiple values; used for WithFastValues.
+type FastValuesBuilder struct {
+	ctx *fastValuesCtx
+}
+
+// Get gets the value for the key in the context being built. If this key was
+// set before, it returns the last value passed to Set(); otherwise it returns
+// the value in the context that was passed to WithFastValues().
+func (b *FastValuesBuilder) Get(key FastValueKey) any {
+	return b.ctx.values[key]
+}
+
+// Set sets the value for the key in the context being built.
+func (b *FastValuesBuilder) Set(key FastValueKey, val any) {
+	b.ctx.values[key] = val
+}
+
+// Finish constructs the context with the values set by Set().
+//
+// The FastValuesBuilder must not be used again.
+func (b *FastValuesBuilder) Finish() context.Context {
+	if buildutil.CrdbTestBuild && b.ctx == nil {
+		panic("invalid use of FastValuesBuilder")
+	}
+	ctx := b.ctx
+	b.ctx = nil
+	return ctx
+}
+
+// RegisterFastValueKey creates a key that can be used with WithFastValue(). This
+// is intended to be called from global initialization code.
+//
+// Only MaxFastValues calls to RegisterFastValueKey are allowed for the lifetime
+// of the binary; only a handful of very frequent in-context values should use
+// this infrastructure.
+func RegisterFastValueKey() FastValueKey {
+	n := numFastValues.Add(1)
+	if n > MaxFastValues {
+		panic("too many fast values registered")
+	}
+	return FastValueKey(n - 1)
+}
+
+var numFastValues atomic.Uint32
+
+type fastValuesCtx struct {
+	context.Context
+	values [MaxFastValues]any
+	// container is set if this node was allocated using a fastValuesContainer
+	// that had more space. The container can be used to allocate new descendant
+	// nodes.
+	container *fastValuesContainer
+}
+
+func (ctx *fastValuesCtx) init(
+	parent context.Context, container *fastValuesContainer, ancestor *fastValuesCtx,
+) {
+	ctx.Context = parent
+	if ancestor != nil {
+		// Because we want the new node to be able to produce values for all fast
+		// keys, we need to copy all fast values from the parent context (i.e. the
+		// closest fastValuesCtx ancestor).
+		ctx.values = ancestor.values
+	}
+	ctx.container = container
+}
+
+// fastValuesAncestorKey is used to retrieve the closest fastValuesCtx ancestor.
+type fastValuesAncestorKey struct{}
+
+// Value is part of the context.Context interface.
+func (ctx *fastValuesCtx) Value(key any) any {
+	if _, ok := key.(fastValuesAncestorKey); ok {
+		return ctx
+	}
+	return ctx.Context.Value(key)
+}
+
+// newFastValuesCtx returns a new context with the given parent and the values
+// from the ancestor.
+//
+// If the ancestor has an associated container that has free slots, it is used
+// to avoid a new allocation.
+func newFastValuesCtx(ancestor *fastValuesCtx, parent context.Context) *fastValuesCtx {
+	var ctx *fastValuesCtx
+	var container *fastValuesContainer
+	if ancestor != nil && ancestor.container != nil {
+		// Try to use the container.
+		var more bool
+		ctx, more = ancestor.container.get()
+		if more {
+			container = ancestor.container
+		} else if ctx == nil {
+			ctx = &fastValuesCtx{}
+		}
+	} else {
+		ctx = &fastValuesCtx{}
+	}
+	ctx.init(parent, container, ancestor)
+	return ctx
+}
+
+// findFastValuesCtxAncestor returns the closest fastValuesCtx ancestor of the
+// given parent context.
+//
+// The returned newParent is the same with parent except when parent is a
+// fastValueCtx, in which case newParent is that parent's parent. This is used
+// to avoid unnecessarily stacking fastValueCtx nodes.
+func findFastValuesCtxAncestor(
+	parent context.Context,
+) (_ *fastValuesCtx, newParent context.Context) {
+	if p, ok := parent.(*fastValuesCtx); ok {
+		return p, p.Context
+	}
+	if v := parent.Value(fastValuesAncestorKey{}); v != nil {
+		return v.(*fastValuesCtx), parent
+	}
+	return nil, parent
+}
+
+const fastValuesContainerSize = 3
+
+// fastValuesContainer is used when we expect successive WithFastValue(s) calls.
+// We allocate a multi-object container for the first call and then use it as
+// needed.
+type fastValuesContainer struct {
+	used atomic.Int32
+	buf  [fastValuesContainerSize]fastValuesCtx
+}
+
+// get returns a new fastValueCtx from the container, and whether there are
+// still available slots in the container. If the container is used, returns nil
+// and false.
+func (c *fastValuesContainer) get() (_ *fastValuesCtx, more bool) {
+	for {
+		u := c.used.Load()
+		if u >= fastValuesContainerSize {
+			return nil, false
+		}
+		if c.used.CompareAndSwap(u, u+1) {
+			return &c.buf[u], u+1 < fastValuesContainerSize
+		}
+	}
+}
+
+func init() {
+	// Set up log tags to use fast values.
+	logtags.OverrideContextFuncs(LogTagsFromContext, WithLogTags)
+}
+
+var LogTagsKey = RegisterFastValueKey()
+
+// LogTagsFromContext returns the log tags from the context, if any.
+func LogTagsFromContext(ctx context.Context) *logtags.Buffer {
+	if v := FastValue(ctx, LogTagsKey); v != nil {
+		return v.(*logtags.Buffer)
+	}
+	return nil
+}
+
+// WithLogTags returns a context with the given tags. Used as the
+// implementation for logtags.WithTags.
+func WithLogTags(ctx context.Context, tags *logtags.Buffer) context.Context {
+	return WithFastValue(ctx, LogTagsKey, tags)
+}
diff --git a/pkg/util/debugutil/debugutil.go b/pkg/util/debugutil/debugutil.go
new file mode 100644
index 0000000..446868c
--- /dev/null
+++ b/pkg/util/debugutil/debugutil.go
@@ -0,0 +1,37 @@
+// Copyright 2023 The Cockroach Authors.
+//
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
+
+package debugutil
+
+import (
+	"runtime/debug"
+	"sync/atomic"
+)
+
+// IsLaunchedByDebugger returns true in cases where the delve debugger
+// was used to launch the cockroach process.
+func IsLaunchedByDebugger() bool {
+	return isLaunchedByDebugger.Load()
+}
+
+var isLaunchedByDebugger atomic.Bool
+
+// SafeStack is an alias for []byte that handles redaction. Use this type
+// instead of []byte when you are sure that the stack trace does not contain
+// sensitive information.
+type SafeStack []byte
+
+func (s SafeStack) SafeValue() {}
+
+// Stack wraps the output of debug.Stack() with redact.Safe() to avoid
+// unnecessary redaction.
+//
+// WARNING: Calling this function grabs system-level locks and could cause high
+// system CPU usage resulting in the Go runtime to lock up if called too
+// frequently, even if called only in error-handling pathways. Use sporadically
+// and only when necessary.
+func Stack() SafeStack {
+	return debug.Stack()
+}
diff --git a/pkg/util/unique/unique.go b/pkg/util/deduplicate/deduplicate.go
similarity index 78%
rename from pkg/util/unique/unique.go
rename to pkg/util/deduplicate/deduplicate.go
index 589ac13..2a7bf6e 100644
--- a/pkg/util/unique/unique.go
+++ b/pkg/util/deduplicate/deduplicate.go
@@ -1,14 +1,9 @@
 // Copyright 2020 The Cockroach Authors.
 //
-// Use of this software is governed by the Business Source License
-// included in the file licenses/BSL.txt.
-//
-// As of the Change Date specified in that file, in accordance with
-// the Business Source License, use of this software will be governed
-// by the Apache License, Version 2.0, included in the file
-// licenses/APL.txt.
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
 
-package unique
+package deduplicate
 
 import (
 	"bytes"
@@ -16,10 +11,10 @@ import (
 	"sort"
 )
 
-// UniquifyByteSlices takes as input a slice of slices of bytes, and
-// deduplicates them using a sort and unique. The output will not contain any
-// duplicates but it will be sorted.
-func UniquifyByteSlices(slices [][]byte) [][]byte {
+// ByteSlices takes as input a slice of slices of bytes, and deduplicates them
+// using a sort and unique. The output will not contain any duplicates but it
+// will be sorted.
+func ByteSlices(slices [][]byte) [][]byte {
 	if len(slices) == 0 {
 		return slices
 	}
@@ -42,9 +37,10 @@ func UniquifyByteSlices(slices [][]byte) [][]byte {
 	return slices
 }
 
-// UniquifyAcrossSlices removes elements from both slices that are duplicated
-// across both of the slices. For example, inputs [1,2,3], [2,3,4] would remove
-// 2 and 3 from both lists.
+// AcrossSlices removes elements from both slices that are duplicated across
+// both of the slices. For example, inputs [1,2,3], [2,3,4] would remove 2 and 3
+// from both lists.
+//
 // It assumes that both slices are pre-sorted using the same comparison metric
 // as cmpFunc provides, and also already free of duplicates internally. It
 // returns the slices, which will have also been sorted as a side effect.
@@ -56,7 +52,7 @@ func UniquifyByteSlices(slices [][]byte) [][]byte {
 // The function returns the new lengths of both input slices, whose elements
 // will have been mutated, but whose lengths must be set the new lengths by
 // the caller.
-func UniquifyAcrossSlices(
+func AcrossSlices(
 	left interface{},
 	right interface{},
 	cmpFunc func(l, r int) int,
diff --git a/pkg/util/duration/duration.go b/pkg/util/duration/duration.go
index 00c6a61..7ff6f17 100644
--- a/pkg/util/duration/duration.go
+++ b/pkg/util/duration/duration.go
@@ -1,12 +1,7 @@
 // Copyright 2016 The Cockroach Authors.
 //
-// Use of this software is governed by the Business Source License
-// included in the file licenses/BSL.txt.
-//
-// As of the Change Date specified in that file, in accordance with
-// the Business Source License, use of this software will be governed
-// by the Apache License, Version 2.0, included in the file
-// licenses/APL.txt.
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
 
 package duration
 
@@ -24,6 +19,7 @@ import (
 	"github.com/cockroachdb/cockroachdb-parser/pkg/sql/pgwire/pgerror"
 	"github.com/cockroachdb/cockroachdb-parser/pkg/sql/types"
 	"github.com/cockroachdb/cockroachdb-parser/pkg/util/arith"
+	"github.com/cockroachdb/cockroachdb-parser/pkg/util/timeutil/pgdate"
 	"github.com/cockroachdb/errors"
 )
 
@@ -736,6 +732,11 @@ func Decode(sortNanos int64, months int64, days int64) (Duration, error) {
 
 // Add returns the time t+d, using a configurable mode.
 func Add(t time.Time, d Duration) time.Time {
+	if t == pgdate.TimeInfinity || t == pgdate.TimeNegativeInfinity {
+		// "infinity"/"-infinity" add/subtract any duration results in itself.
+		return t
+	}
+
 	// Fast path adding units < 1 day.
 	// Avoiding AddDate(0,0,0) is required to prevent changing times
 	// on DST boundaries.
@@ -820,6 +821,16 @@ func (d Duration) Div(x int64) Duration {
 
 // MulFloat returns a Duration representing a time length of d*x.
 func (d Duration) MulFloat(x float64) Duration {
+	// Have a couple of special cases to avoid rounding errors with very large
+	// intervals.
+	// TODO(#26932): once we correctly error out on intervals out of range, this
+	// could be removed.
+	switch x {
+	case 1:
+		return d
+	case -1:
+		return MakeDuration(-d.nanos, -d.Days, -d.Months)
+	}
 	monthInt, monthFrac := math.Modf(float64(d.Months) * x)
 	dayInt, dayFrac := math.Modf((float64(d.Days) * x) + (monthFrac * DaysPerMonth))
 
@@ -832,6 +843,16 @@ func (d Duration) MulFloat(x float64) Duration {
 
 // DivFloat returns a Duration representing a time length of d/x.
 func (d Duration) DivFloat(x float64) Duration {
+	// Have a couple of special cases to avoid rounding errors with very large
+	// intervals.
+	// TODO(#26932): once we correctly error out on intervals out of range, this
+	// could be removed.
+	switch x {
+	case 1:
+		return d
+	case -1:
+		return MakeDuration(-d.nanos, -d.Days, -d.Months)
+	}
 	// In order to keep it compatible with PostgreSQL, we use the same logic.
 	// Refer to https://github.com/postgres/postgres/blob/e56bce5d43789cce95d099554ae9593ada92b3b7/src/backend/utils/adt/timestamp.c#L3266-L3304.
 	month := int32(float64(d.Months) / x)
diff --git a/pkg/util/duration/duration.proto b/pkg/util/duration/duration.proto
index 3d41068..efc0c80 100644
--- a/pkg/util/duration/duration.proto
+++ b/pkg/util/duration/duration.proto
@@ -1,12 +1,7 @@
 // Copyright 2021 The Cockroach Authors.
 //
-// Use of this software is governed by the Business Source License
-// included in the file licenses/BSL.txt.
-//
-// As of the Change Date specified in that file, in accordance with
-// the Business Source License, use of this software will be governed
-// by the Apache License, Version 2.0, included in the file
-// licenses/APL.txt.
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
 
 syntax = "proto3";
 package cockroach.util.duration;
diff --git a/pkg/util/duration/parse.go b/pkg/util/duration/parse.go
index b2c9394..017da5c 100644
--- a/pkg/util/duration/parse.go
+++ b/pkg/util/duration/parse.go
@@ -1,12 +1,7 @@
 // Copyright 2016 The Cockroach Authors.
 //
-// Use of this software is governed by the Business Source License
-// included in the file licenses/BSL.txt.
-//
-// As of the Change Date specified in that file, in accordance with
-// the Business Source License, use of this software will be governed
-// by the Apache License, Version 2.0, included in the file
-// licenses/APL.txt.
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
 
 package duration
 
diff --git a/pkg/util/encoding/complement_fast.go b/pkg/util/encoding/complement_fast.go
index afe0de0..095edc0 100644
--- a/pkg/util/encoding/complement_fast.go
+++ b/pkg/util/encoding/complement_fast.go
@@ -1,15 +1,9 @@
 // Copyright 2015 The Cockroach Authors.
 //
-// Use of this software is governed by the Business Source License
-// included in the file licenses/BSL.txt.
-//
-// As of the Change Date specified in that file, in accordance with
-// the Business Source License, use of this software will be governed
-// by the Apache License, Version 2.0, included in the file
-// licenses/APL.txt.
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
 
 //go:build 386 || amd64
-// +build 386 amd64
 
 package encoding
 
diff --git a/pkg/util/encoding/complement_safe.go b/pkg/util/encoding/complement_safe.go
index d9cc023..90a026f 100644
--- a/pkg/util/encoding/complement_safe.go
+++ b/pkg/util/encoding/complement_safe.go
@@ -1,15 +1,9 @@
 // Copyright 2015 The Cockroach Authors.
 //
-// Use of this software is governed by the Business Source License
-// included in the file licenses/BSL.txt.
-//
-// As of the Change Date specified in that file, in accordance with
-// the Business Source License, use of this software will be governed
-// by the Apache License, Version 2.0, included in the file
-// licenses/APL.txt.
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
 
 //go:build !386 && !amd64
-// +build !386,!amd64
 
 package encoding
 
diff --git a/pkg/util/encoding/decimal.go b/pkg/util/encoding/decimal.go
index 8ce5184..1c4dbc9 100644
--- a/pkg/util/encoding/decimal.go
+++ b/pkg/util/encoding/decimal.go
@@ -1,12 +1,7 @@
 // Copyright 2016 The Cockroach Authors.
 //
-// Use of this software is governed by the Business Source License
-// included in the file licenses/BSL.txt.
-//
-// As of the Change Date specified in that file, in accordance with
-// the Business Source License, use of this software will be governed
-// by the Apache License, Version 2.0, included in the file
-// licenses/APL.txt.
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
 //
 // An ordered key encoding scheme for arbitrary-precision fixed-point
 // numeric values based on sqlite4's key encoding:
diff --git a/pkg/util/encoding/encoding.go b/pkg/util/encoding/encoding.go
index a76151d..60177d1 100644
--- a/pkg/util/encoding/encoding.go
+++ b/pkg/util/encoding/encoding.go
@@ -1,12 +1,7 @@
 // Copyright 2014 The Cockroach Authors.
 //
-// Use of this software is governed by the Business Source License
-// included in the file licenses/BSL.txt.
-//
-// As of the Change Date specified in that file, in accordance with
-// the Business Source License, use of this software will be governed
-// by the Apache License, Version 2.0, included in the file
-// licenses/APL.txt.
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
 
 // Package encoding exposes some utilities for encoding data as bytes.
 package encoding
@@ -898,6 +893,16 @@ func prettyPrintInvertedIndexKey(b []byte) (string, []byte, error) {
 			outBytes = outBytes + strconv.Quote(UnsafeConvertBytesToString(tempB[:i])) + "/"
 		case escapedJSONArray:
 			outBytes = outBytes + "Arr/"
+			if i+2 >= len(tempB) {
+				// The key ends in an escaped JSON array byte, which is used in
+				// spans to scan over non-empty arrays.
+				return outBytes, nil, nil
+			}
+		case escaped00:
+			if i+2 >= len(tempB) {
+				// The key ends in an escaped NULL byte.
+				return outBytes, nil, nil
+			}
 		default:
 			return "", nil, errors.Errorf("malformed escape in buffer %#x", b)
 
@@ -1780,6 +1785,7 @@ const (
 	// Special case
 	JsonEmptyArray     Type = 42
 	JsonEmptyArrayDesc Type = 43
+	PGVector           Type = 44
 )
 
 // typMap maps an encoded type byte to a decoded Type. It's got 256 slots, one
@@ -2547,8 +2553,8 @@ const NoColumnID uint32 = 0
 // methods.
 //
 // The prefix uses varints to encode a column id and type, packing them into a
-// single byte when they're small (colID < 8 and typ < 15). This works by
-// shifting the colID "left" by 4 and putting any type less than 15 in the low
+// single byte when they're small (colIDDelta < 8 and typ < 15). This works by
+// shifting the colIDDelta "left" by 4 and putting any type less than 15 in the low
 // bytes. The result is uvarint encoded and fits in one byte if the original
 // column id fit in 3 bits. If it doesn't fit in one byte, the most significant
 // bits spill to the "left", leaving the type bits always at the very "right".
@@ -2559,45 +2565,45 @@ const NoColumnID uint32 = 0
 //
 // Together, this means the everything but the last byte of the first uvarint
 // can be dropped if the column id isn't needed.
-func EncodeValueTag(appendTo []byte, colID uint32, typ Type) []byte {
+func EncodeValueTag(appendTo []byte, colIDDelta uint32, typ Type) []byte {
 	if typ >= SentinelType {
-		appendTo = EncodeNonsortingUvarint(appendTo, uint64(colID)<<4|uint64(SentinelType))
+		appendTo = EncodeNonsortingUvarint(appendTo, uint64(colIDDelta)<<4|uint64(SentinelType))
 		return EncodeNonsortingUvarint(appendTo, uint64(typ))
 	}
-	if colID == NoColumnID {
+	if colIDDelta == NoColumnID {
 		// TODO(dan): EncodeValueTag is not inlined by the compiler. Copying this
 		// special case into one of the EncodeFooValue functions speeds it up by
 		// ~4ns.
 		return append(appendTo, byte(typ))
 	}
-	return EncodeNonsortingUvarint(appendTo, uint64(colID)<<4|uint64(typ))
+	return EncodeNonsortingUvarint(appendTo, uint64(colIDDelta)<<4|uint64(typ))
 }
 
 // EncodeNullValue encodes a null value, appends it to the supplied buffer, and
 // returns the final buffer.
-func EncodeNullValue(appendTo []byte, colID uint32) []byte {
-	return EncodeValueTag(appendTo, colID, Null)
+func EncodeNullValue(appendTo []byte, colIDDelta uint32) []byte {
+	return EncodeValueTag(appendTo, colIDDelta, Null)
 }
 
 // EncodeNotNullValue encodes a not null value, appends it to the supplied
 // buffer, and returns the final buffer.
-func EncodeNotNullValue(appendTo []byte, colID uint32) []byte {
-	return EncodeValueTag(appendTo, colID, NotNull)
+func EncodeNotNullValue(appendTo []byte, colIDDelta uint32) []byte {
+	return EncodeValueTag(appendTo, colIDDelta, NotNull)
 }
 
 // EncodeBoolValue encodes a bool value, appends it to the supplied buffer, and
 // returns the final buffer.
-func EncodeBoolValue(appendTo []byte, colID uint32, b bool) []byte {
+func EncodeBoolValue(appendTo []byte, colIDDelta uint32, b bool) []byte {
 	if b {
-		return EncodeValueTag(appendTo, colID, True)
+		return EncodeValueTag(appendTo, colIDDelta, True)
 	}
-	return EncodeValueTag(appendTo, colID, False)
+	return EncodeValueTag(appendTo, colIDDelta, False)
 }
 
 // EncodeIntValue encodes an int value with its value tag, appends it to the
 // supplied buffer, and returns the final buffer.
-func EncodeIntValue(appendTo []byte, colID uint32, i int64) []byte {
-	appendTo = EncodeValueTag(appendTo, colID, Int)
+func EncodeIntValue(appendTo []byte, colIDDelta uint32, i int64) []byte {
+	appendTo = EncodeValueTag(appendTo, colIDDelta, Int)
 	return EncodeUntaggedIntValue(appendTo, i)
 }
 
@@ -2611,8 +2617,8 @@ const floatValueEncodedLength = uint64AscendingEncodedLength
 
 // EncodeFloatValue encodes a float value with its value tag, appends it to the
 // supplied buffer, and returns the final buffer.
-func EncodeFloatValue(appendTo []byte, colID uint32, f float64) []byte {
-	appendTo = EncodeValueTag(appendTo, colID, Float)
+func EncodeFloatValue(appendTo []byte, colIDDelta uint32, f float64) []byte {
+	appendTo = EncodeValueTag(appendTo, colIDDelta, Float)
 	return EncodeUntaggedFloatValue(appendTo, f)
 }
 
@@ -2622,10 +2628,16 @@ func EncodeUntaggedFloatValue(appendTo []byte, f float64) []byte {
 	return EncodeUint64Ascending(appendTo, math.Float64bits(f))
 }
 
+// EncodeUntaggedFloat32Value encodes a float32 value, appends it to the supplied buffer,
+// and returns the final buffer.
+func EncodeUntaggedFloat32Value(appendTo []byte, f float32) []byte {
+	return EncodeUint32Ascending(appendTo, math.Float32bits(f))
+}
+
 // EncodeBytesValue encodes a byte array value with its value tag, appends it to
 // the supplied buffer, and returns the final buffer.
-func EncodeBytesValue(appendTo []byte, colID uint32, data []byte) []byte {
-	appendTo = EncodeValueTag(appendTo, colID, Bytes)
+func EncodeBytesValue(appendTo []byte, colIDDelta uint32, data []byte) []byte {
+	appendTo = EncodeValueTag(appendTo, colIDDelta, Bytes)
 	return EncodeUntaggedBytesValue(appendTo, data)
 }
 
@@ -2638,15 +2650,15 @@ func EncodeUntaggedBytesValue(appendTo []byte, data []byte) []byte {
 
 // EncodeArrayValue encodes a byte array value with its value tag, appends it to
 // the supplied buffer, and returns the final buffer.
-func EncodeArrayValue(appendTo []byte, colID uint32, data []byte) []byte {
-	appendTo = EncodeValueTag(appendTo, colID, Array)
+func EncodeArrayValue(appendTo []byte, colIDDelta uint32, data []byte) []byte {
+	appendTo = EncodeValueTag(appendTo, colIDDelta, Array)
 	return EncodeUntaggedBytesValue(appendTo, data)
 }
 
 // EncodeTimeValue encodes a time.Time value with its value tag, appends it to
 // the supplied buffer, and returns the final buffer.
-func EncodeTimeValue(appendTo []byte, colID uint32, t time.Time) []byte {
-	appendTo = EncodeValueTag(appendTo, colID, Time)
+func EncodeTimeValue(appendTo []byte, colIDDelta uint32, t time.Time) []byte {
+	appendTo = EncodeValueTag(appendTo, colIDDelta, Time)
 	return EncodeUntaggedTimeValue(appendTo, t)
 }
 
@@ -2659,8 +2671,8 @@ func EncodeUntaggedTimeValue(appendTo []byte, t time.Time) []byte {
 
 // EncodeTimeTZValue encodes a timetz.TimeTZ value with its value tag, appends it to
 // the supplied buffer, and returns the final buffer.
-func EncodeTimeTZValue(appendTo []byte, colID uint32, t timetz.TimeTZ) []byte {
-	appendTo = EncodeValueTag(appendTo, colID, TimeTZ)
+func EncodeTimeTZValue(appendTo []byte, colIDDelta uint32, t timetz.TimeTZ) []byte {
+	appendTo = EncodeValueTag(appendTo, colIDDelta, TimeTZ)
 	return EncodeUntaggedTimeTZValue(appendTo, t)
 }
 
@@ -2673,14 +2685,14 @@ func EncodeUntaggedTimeTZValue(appendTo []byte, t timetz.TimeTZ) []byte {
 
 // EncodeVoidValue encodes a void with its value tag, appends it to
 // the supplied buffer and returns the final buffer.
-func EncodeVoidValue(appendTo []byte, colID uint32) []byte {
-	return EncodeValueTag(appendTo, colID, Void)
+func EncodeVoidValue(appendTo []byte, colIDDelta uint32) []byte {
+	return EncodeValueTag(appendTo, colIDDelta, Void)
 }
 
 // EncodeBox2DValue encodes a geopb.BoundingBox with its value tag, appends it to
 // the supplied buffer and returns the final buffer.
-func EncodeBox2DValue(appendTo []byte, colID uint32, b geopb.BoundingBox) ([]byte, error) {
-	appendTo = EncodeValueTag(appendTo, colID, Box2D)
+func EncodeBox2DValue(appendTo []byte, colIDDelta uint32, b geopb.BoundingBox) ([]byte, error) {
+	appendTo = EncodeValueTag(appendTo, colIDDelta, Box2D)
 	return EncodeUntaggedBox2DValue(appendTo, b)
 }
 
@@ -2696,8 +2708,8 @@ func EncodeUntaggedBox2DValue(appendTo []byte, b geopb.BoundingBox) ([]byte, err
 
 // EncodeGeoValue encodes a geopb.SpatialObject value with its value tag, appends it to
 // the supplied buffer, and returns the final buffer.
-func EncodeGeoValue(appendTo []byte, colID uint32, so *geopb.SpatialObject) ([]byte, error) {
-	appendTo = EncodeValueTag(appendTo, colID, Geo)
+func EncodeGeoValue(appendTo []byte, colIDDelta uint32, so *geopb.SpatialObject) ([]byte, error) {
+	appendTo = EncodeValueTag(appendTo, colIDDelta, Geo)
 	return EncodeUntaggedGeoValue(appendTo, so)
 }
 
@@ -2713,8 +2725,8 @@ func EncodeUntaggedGeoValue(appendTo []byte, so *geopb.SpatialObject) ([]byte, e
 
 // EncodeDecimalValue encodes an apd.Decimal value with its value tag, appends
 // it to the supplied buffer, and returns the final buffer.
-func EncodeDecimalValue(appendTo []byte, colID uint32, d *apd.Decimal) []byte {
-	appendTo = EncodeValueTag(appendTo, colID, Decimal)
+func EncodeDecimalValue(appendTo []byte, colIDDelta uint32, d *apd.Decimal) []byte {
+	appendTo = EncodeValueTag(appendTo, colIDDelta, Decimal)
 	return EncodeUntaggedDecimalValue(appendTo, d)
 }
 
@@ -2737,8 +2749,8 @@ func EncodeUntaggedDecimalValue(appendTo []byte, d *apd.Decimal) []byte {
 
 // EncodeDurationValue encodes a duration.Duration value with its value tag,
 // appends it to the supplied buffer, and returns the final buffer.
-func EncodeDurationValue(appendTo []byte, colID uint32, d duration.Duration) []byte {
-	appendTo = EncodeValueTag(appendTo, colID, Duration)
+func EncodeDurationValue(appendTo []byte, colIDDelta uint32, d duration.Duration) []byte {
+	appendTo = EncodeValueTag(appendTo, colIDDelta, Duration)
 	return EncodeUntaggedDurationValue(appendTo, d)
 }
 
@@ -2752,8 +2764,8 @@ func EncodeUntaggedDurationValue(appendTo []byte, d duration.Duration) []byte {
 
 // EncodeBitArrayValue encodes a bit array value with its value tag,
 // appends it to the supplied buffer, and returns the final buffer.
-func EncodeBitArrayValue(appendTo []byte, colID uint32, d bitarray.BitArray) []byte {
-	appendTo = EncodeValueTag(appendTo, colID, BitArray)
+func EncodeBitArrayValue(appendTo []byte, colIDDelta uint32, d bitarray.BitArray) []byte {
+	appendTo = EncodeValueTag(appendTo, colIDDelta, BitArray)
 	return EncodeUntaggedBitArrayValue(appendTo, d)
 }
 
@@ -2772,8 +2784,8 @@ func EncodeUntaggedBitArrayValue(appendTo []byte, d bitarray.BitArray) []byte {
 
 // EncodeUUIDValue encodes a uuid.UUID value with its value tag, appends it to
 // the supplied buffer, and returns the final buffer.
-func EncodeUUIDValue(appendTo []byte, colID uint32, u uuid.UUID) []byte {
-	appendTo = EncodeValueTag(appendTo, colID, UUID)
+func EncodeUUIDValue(appendTo []byte, colIDDelta uint32, u uuid.UUID) []byte {
+	appendTo = EncodeValueTag(appendTo, colIDDelta, UUID)
 	return EncodeUntaggedUUIDValue(appendTo, u)
 }
 
@@ -2785,8 +2797,8 @@ func EncodeUntaggedUUIDValue(appendTo []byte, u uuid.UUID) []byte {
 
 // EncodeIPAddrValue encodes a ipaddr.IPAddr value with its value tag, appends
 // it to the supplied buffer, and returns the final buffer.
-func EncodeIPAddrValue(appendTo []byte, colID uint32, u ipaddr.IPAddr) []byte {
-	appendTo = EncodeValueTag(appendTo, colID, IPAddr)
+func EncodeIPAddrValue(appendTo []byte, colIDDelta uint32, u ipaddr.IPAddr) []byte {
+	appendTo = EncodeValueTag(appendTo, colIDDelta, IPAddr)
 	return EncodeUntaggedIPAddrValue(appendTo, u)
 }
 
@@ -2799,24 +2811,32 @@ func EncodeUntaggedIPAddrValue(appendTo []byte, u ipaddr.IPAddr) []byte {
 // EncodeJSONValue encodes an already-byte-encoded JSON value with no value tag
 // but with a length prefix, appends it to the supplied buffer, and returns the
 // final buffer.
-func EncodeJSONValue(appendTo []byte, colID uint32, data []byte) []byte {
-	appendTo = EncodeValueTag(appendTo, colID, JSON)
+func EncodeJSONValue(appendTo []byte, colIDDelta uint32, data []byte) []byte {
+	appendTo = EncodeValueTag(appendTo, colIDDelta, JSON)
 	return EncodeUntaggedBytesValue(appendTo, data)
 }
 
 // EncodeTSQueryValue encodes an already-byte-encoded TSQuery value with no
 // value tag but with a length prefix, appends it to the supplied buffer, and
 // returns the final buffer.
-func EncodeTSQueryValue(appendTo []byte, colID uint32, data []byte) []byte {
-	appendTo = EncodeValueTag(appendTo, colID, TSQuery)
+func EncodeTSQueryValue(appendTo []byte, colIDDelta uint32, data []byte) []byte {
+	appendTo = EncodeValueTag(appendTo, colIDDelta, TSQuery)
 	return EncodeUntaggedBytesValue(appendTo, data)
 }
 
 // EncodeTSVectorValue encodes an already-byte-encoded TSVector value with no
 // value tag but with a length prefix, appends it to the supplied buffer, and
 // returns the final buffer.
-func EncodeTSVectorValue(appendTo []byte, colID uint32, data []byte) []byte {
-	appendTo = EncodeValueTag(appendTo, colID, TSVector)
+func EncodeTSVectorValue(appendTo []byte, colIDDelta uint32, data []byte) []byte {
+	appendTo = EncodeValueTag(appendTo, colIDDelta, TSVector)
+	return EncodeUntaggedBytesValue(appendTo, data)
+}
+
+// EncodePGVectorValue encodes an already-byte-encoded PGVector value with no
+// value tag but with a length prefix, appends it to the supplied buffer, and
+// returns the final buffer.
+func EncodePGVectorValue(appendTo []byte, colIDDelta uint32, data []byte) []byte {
+	appendTo = EncodeValueTag(appendTo, colIDDelta, PGVector)
 	return EncodeUntaggedBytesValue(appendTo, data)
 }
 
@@ -2828,12 +2848,12 @@ func EncodeTSVectorValue(appendTo []byte, colID uint32, data []byte) []byte {
 // PeekValueLength and each of the DecodeFooValue methods will still work as
 // expected with `b[typeOffset:]`. (Except, obviously, the column id is no
 // longer encoded so if this suffix is passed back to DecodeValueTag, the
-// returned colID should be discarded.)
+// returned colIDDelta should be discarded.)
 //
 // Concretely:
 //
 //	b := ...
-//	typeOffset, _, colID, typ, err := DecodeValueTag(b)
+//	typeOffset, _, colIDDelta, typ, err := DecodeValueTag(b)
 //	_, _, _, typ, err := DecodeValueTag(b[typeOffset:])
 //
 // will return the same typ and err and
@@ -2843,7 +2863,9 @@ func EncodeTSVectorValue(appendTo []byte, colID uint32, data []byte) []byte {
 //
 // will return the same thing. PeekValueLength works as expected with either of
 // `b` or `b[typeOffset:]`.
-func DecodeValueTag(b []byte) (typeOffset int, dataOffset int, colID uint32, typ Type, err error) {
+func DecodeValueTag(
+	b []byte,
+) (typeOffset int, dataOffset int, colIDDelta uint32, typ Type, err error) {
 	// TODO(dan): This can be made faster by special casing the single byte
 	// version and skipping the column id extraction when it's not needed.
 	if len(b) == 0 {
@@ -2855,7 +2877,7 @@ func DecodeValueTag(b []byte) (typeOffset int, dataOffset int, colID uint32, typ
 	if err != nil {
 		return 0, 0, 0, Unknown, err
 	}
-	colID = uint32(tag >> 4)
+	colIDDelta = uint32(tag >> 4)
 
 	typ = Type(tag & 0xf)
 	typeOffset = n - 1
@@ -2868,7 +2890,7 @@ func DecodeValueTag(b []byte) (typeOffset int, dataOffset int, colID uint32, typ
 		typ = Type(tag)
 		dataOffset += n
 	}
-	return typeOffset, dataOffset, colID, typ, nil
+	return typeOffset, dataOffset, colIDDelta, typ, nil
 }
 
 // DecodeBoolValue decodes a value encoded by EncodeBoolValue.
@@ -2922,6 +2944,16 @@ func DecodeUntaggedFloatValue(b []byte) (remaining []byte, f float64, err error)
 	return b, math.Float64frombits(i), err
 }
 
+// DecodeUntaggedFloat32Value decodes a value encoded by EncodeUntaggedFloat32Value.
+func DecodeUntaggedFloat32Value(b []byte) (remaining []byte, f float32, err error) {
+	if len(b) < 4 {
+		return b, 0, fmt.Errorf("float32 value should be exactly 4 bytes: %d", len(b))
+	}
+	var i uint32
+	b, i, err = DecodeUint32Ascending(b)
+	return b, math.Float32frombits(i), err
+}
+
 // DecodeBytesValue decodes a value encoded by EncodeBytesValue.
 func DecodeBytesValue(b []byte) (remaining []byte, data []byte, err error) {
 	b, err = decodeValueTypeAssert(b, Bytes)
@@ -3132,6 +3164,9 @@ func DecodeUUIDValue(b []byte) (remaining []byte, u uuid.UUID, err error) {
 
 // DecodeUntaggedUUIDValue decodes a value encoded by EncodeUntaggedUUIDValue.
 func DecodeUntaggedUUIDValue(b []byte) (remaining []byte, u uuid.UUID, err error) {
+	if len(b) < uuidValueEncodedLength {
+		return b, uuid.UUID{}, errors.Errorf("invalid uuid length of %d", len(b))
+	}
 	u, err = uuid.FromBytes(b[:uuidValueEncodedLength])
 	if err != nil {
 		return b, uuid.UUID{}, err
@@ -3208,7 +3243,7 @@ func PeekValueLengthWithOffsetsAndType(b []byte, dataOffset int, typ Type) (leng
 		return dataOffset + n, err
 	case Float:
 		return dataOffset + floatValueEncodedLength, nil
-	case Bytes, Array, JSON, Geo, TSVector, TSQuery:
+	case Bytes, Array, JSON, Geo, TSVector, TSQuery, PGVector:
 		_, n, i, err := DecodeNonsortingUvarint(b)
 		return dataOffset + n + int(i), err
 	case Box2D:
@@ -3272,6 +3307,26 @@ func isValidAndPrintableRune(r rune) bool {
 	return r != utf8.RuneError && unicode.IsPrint(r)
 }
 
+// PrettyPrintJSONValueEncoded returns a string representation of the encoded
+// JSON object. It is injected from util/json to avoid an import cycle.
+var PrettyPrintJSONValueEncoded func([]byte) (string, error)
+
+var prettyPrintJSONValueEncodedNilErr = errors.New("PrettyPrintJSONValueEncoded is not injected")
+
+// PrettyPrintArrayValueEncoded returns a string representation of the encoded
+// array object if possible. It is injected from rowenc/valueside to avoid an
+// import cycle.
+var PrettyPrintArrayValueEncoded func([]byte) (string, error)
+
+var prettyPrintArrayValueEncodedNilErr = errors.New("PrettyPrintArrayValueEncoded is not injected")
+
+// PrettyPrintTupleValueEncoded returns a string representation of the encoded
+// tuple object if possible. It is injected from rowenc/valueside to avoid an
+// import cycle.
+var PrettyPrintTupleValueEncoded func([]byte) ([]byte, string, error)
+
+var prettyPrintTupleValueEncodedNilErr = errors.New("PrettyPrintTupleValueEncoded is not injected")
+
 // PrettyPrintValueEncoded returns a string representation of the first
 // decodable value in the provided byte slice, along with the remaining byte
 // slice after decoding.
@@ -3367,6 +3422,40 @@ func PrettyPrintValueEncoded(b []byte) ([]byte, string, error) {
 			return b, "", err
 		}
 		return b, ipAddr.String(), nil
+	case JSON:
+		b = b[dataOffset:]
+		var data []byte
+		b, data, err = DecodeUntaggedBytesValue(b)
+		if err != nil {
+			return b, "", err
+		}
+		if PrettyPrintJSONValueEncoded == nil {
+			return b, "", prettyPrintJSONValueEncodedNilErr
+		}
+		var s string
+		s, err = PrettyPrintJSONValueEncoded(data)
+		return b, s, err
+	case Array:
+		b = b[dataOffset:]
+		var data []byte
+		b, data, err = DecodeUntaggedBytesValue(b)
+		if err != nil {
+			return b, "", err
+		}
+		if PrettyPrintArrayValueEncoded == nil {
+			return b, "", prettyPrintArrayValueEncodedNilErr
+		}
+		var s string
+		s, err = PrettyPrintArrayValueEncoded(data)
+		return b, s, err
+	case Tuple:
+		b = b[dataOffset:]
+		if PrettyPrintTupleValueEncoded == nil {
+			return b, "", prettyPrintTupleValueEncodedNilErr
+		}
+		var s string
+		b, s, err = PrettyPrintTupleValueEncoded(b)
+		return b, s, err
 	default:
 		return b, "", errors.Errorf("unknown type %s", typ)
 	}
@@ -3719,3 +3808,19 @@ func BytesPrevish(b []byte, length int) []byte {
 	copy(buf[bLen:], bytes.Repeat([]byte{0xff}, length-bLen))
 	return buf
 }
+
+// unsafeWrapper is implementation of SafeFormatter. This is used to mark
+// arguments as unsafe for redaction. This would make sure that redact.Unsafe() is implementing SafeFormatter interface
+// without affecting invocations.
+// TODO(aa-joshi): This is a temporary solution to mark arguments as unsafe. We should move/update this into cockroachdb/redact package.
+type unsafeWrapper struct {
+	a any
+}
+
+func (uw unsafeWrapper) SafeFormat(w redact.SafePrinter, _ rune) {
+	w.Print(redact.Unsafe(uw.a))
+}
+
+func Unsafe(args any) any {
+	return unsafeWrapper{a: args}
+}
diff --git a/pkg/util/encoding/encodingtype/encoding_type.go b/pkg/util/encoding/encodingtype/encoding_type.go
index 88bb14c..6c581f5 100644
--- a/pkg/util/encoding/encodingtype/encoding_type.go
+++ b/pkg/util/encoding/encodingtype/encoding_type.go
@@ -1,12 +1,7 @@
 // Copyright 2020 The Cockroach Authors.
 //
-// Use of this software is governed by the Business Source License
-// included in the file licenses/BSL.txt.
-//
-// As of the Change Date specified in that file, in accordance with
-// the Business Source License, use of this software will be governed
-// by the Apache License, Version 2.0, included in the file
-// licenses/APL.txt.
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
 
 package encodingtype
 
diff --git a/pkg/util/encoding/float.go b/pkg/util/encoding/float.go
index 4a3f409..2bc9516 100644
--- a/pkg/util/encoding/float.go
+++ b/pkg/util/encoding/float.go
@@ -1,12 +1,7 @@
 // Copyright 2014 The Cockroach Authors.
 //
-// Use of this software is governed by the Business Source License
-// included in the file licenses/BSL.txt.
-//
-// As of the Change Date specified in that file, in accordance with
-// the Business Source License, use of this software will be governed
-// by the Apache License, Version 2.0, included in the file
-// licenses/APL.txt.
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
 
 package encoding
 
diff --git a/pkg/util/encoding/type_string.go b/pkg/util/encoding/type_string.go
index a6eaee2..25f87f5 100644
--- a/pkg/util/encoding/type_string.go
+++ b/pkg/util/encoding/type_string.go
@@ -1,3 +1,8 @@
+// Copyright 2023 The Cockroach Authors.
+//
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
+
 // Code generated by "stringer"; DO NOT EDIT.
 
 package encoding
@@ -53,6 +58,7 @@ func _() {
 	_ = x[JSONObjectDesc-41]
 	_ = x[JsonEmptyArray-42]
 	_ = x[JsonEmptyArrayDesc-43]
+	_ = x[PGVector-44]
 }
 
 func (i Type) String() string {
@@ -145,6 +151,8 @@ func (i Type) String() string {
 		return "JsonEmptyArray"
 	case JsonEmptyArrayDesc:
 		return "JsonEmptyArrayDesc"
+	case PGVector:
+		return "PGVector"
 	default:
 		return "Type(" + strconv.FormatInt(int64(i), 10) + ")"
 	}
diff --git a/pkg/util/envutil/env.go b/pkg/util/envutil/env.go
index bfcd93c..e0df4d7 100644
--- a/pkg/util/envutil/env.go
+++ b/pkg/util/envutil/env.go
@@ -1,12 +1,7 @@
 // Copyright 2016 The Cockroach Authors.
 //
-// Use of this software is governed by the Business Source License
-// included in the file licenses/BSL.txt.
-//
-// As of the Change Date specified in that file, in accordance with
-// the Business Source License, use of this software will be governed
-// by the Apache License, Version 2.0, included in the file
-// licenses/APL.txt.
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
 
 package envutil
 
@@ -169,7 +164,7 @@ func GetEnvVarsUsed() (result []redact.RedactableString) {
 		_, crdbVar := envVarRegistry.cache[string(varName)]
 		_, safeVar := safeVarRegistry[varName]
 		if crdbVar || safeVar {
-			result = append(result, redact.Sprintf("%s=%s", varName, redact.Safe(allVarsValues[varName])))
+			result = append(result, redact.Sprintf("%s=%s", varName, redact.SafeString(allVarsValues[varName])))
 		} else if _, reportable := valueReportableUnsafeVarRegistry[varName]; reportable {
 			result = append(result, redact.Sprintf("%s=%s", varName, allVarsValues[varName]))
 		} else if _, reportable := nameReportableUnsafeVarRegistry[varName]; reportable {
@@ -192,9 +187,14 @@ var safeVarRegistry = map[redact.SafeString]struct{}{
 	"GOMAXPROCS":  {},
 	"GOTRACEBACK": {},
 	"GOMEMLIMIT":  {},
+	// Jemalloc configuration override.
+	"MALLOC_CONF": {},
 	// gRPC.
 	"GRPC_GO_LOG_SEVERITY_LEVEL":  {},
 	"GRPC_GO_LOG_VERBOSITY_LEVEL": {},
+	// general
+	"LANG": {},
+	"TERM": {},
 }
 
 // valueReportableUnsafeVarRegistry is the list of variables where we can
diff --git a/pkg/util/errorutil/catch.go b/pkg/util/errorutil/catch.go
index 69ec07c..538f6a9 100644
--- a/pkg/util/errorutil/catch.go
+++ b/pkg/util/errorutil/catch.go
@@ -1,12 +1,7 @@
 // Copyright 2019 The Cockroach Authors.
 //
-// Use of this software is governed by the Business Source License
-// included in the file licenses/BSL.txt.
-//
-// As of the Change Date specified in that file, in accordance with
-// the Business Source License, use of this software will be governed
-// by the Apache License, Version 2.0, included in the file
-// licenses/APL.txt.
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
 
 package errorutil
 
diff --git a/pkg/util/errorutil/error.go b/pkg/util/errorutil/error.go
index c172ae8..6265111 100644
--- a/pkg/util/errorutil/error.go
+++ b/pkg/util/errorutil/error.go
@@ -1,12 +1,7 @@
 // Copyright 2017 The Cockroach Authors.
 //
-// Use of this software is governed by the Business Source License
-// included in the file licenses/BSL.txt.
-//
-// As of the Change Date specified in that file, in accordance with
-// the Business Source License, use of this software will be governed
-// by the Apache License, Version 2.0, included in the file
-// licenses/APL.txt.
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
 
 package errorutil
 
diff --git a/pkg/util/errorutil/sentinel.go b/pkg/util/errorutil/sentinel.go
index 4b46814..f3a8601 100644
--- a/pkg/util/errorutil/sentinel.go
+++ b/pkg/util/errorutil/sentinel.go
@@ -1,12 +1,7 @@
 // Copyright 2023 The Cockroach Authors.
 //
-// Use of this software is governed by the Business Source License
-// included in the file licenses/BSL.txt.
-//
-// As of the Change Date specified in that file, in accordance with
-// the Business Source License, use of this software will be governed
-// by the Apache License, Version 2.0, included in the file
-// licenses/APL.txt.
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
 
 package errorutil
 
diff --git a/pkg/util/errorutil/tenant.go b/pkg/util/errorutil/tenant.go
index 4bfe507..ab1c495 100644
--- a/pkg/util/errorutil/tenant.go
+++ b/pkg/util/errorutil/tenant.go
@@ -1,12 +1,7 @@
 // Copyright 2020 The Cockroach Authors.
 //
-// Use of this software is governed by the Business Source License
-// included in the file licenses/BSL.txt.
-//
-// As of the Change Date specified in that file, in accordance with
-// the Business Source License, use of this software will be governed
-// by the Apache License, Version 2.0, included in the file
-// licenses/APL.txt.
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
 
 package errorutil
 
diff --git a/pkg/util/errorutil/tenant_deprecated_wrapper.go b/pkg/util/errorutil/tenant_deprecated_wrapper.go
index a1eedbe..e514781 100644
--- a/pkg/util/errorutil/tenant_deprecated_wrapper.go
+++ b/pkg/util/errorutil/tenant_deprecated_wrapper.go
@@ -1,12 +1,7 @@
 // Copyright 2020 The Cockroach Authors.
 //
-// Use of this software is governed by the Business Source License
-// included in the file licenses/BSL.txt.
-//
-// As of the Change Date specified in that file, in accordance with
-// the Business Source License, use of this software will be governed
-// by the Apache License, Version 2.0, included in the file
-// licenses/APL.txt.
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
 
 package errorutil
 
diff --git a/pkg/util/errorutil/unimplemented/unimplemented.go b/pkg/util/errorutil/unimplemented/unimplemented.go
index 95ade43..3310945 100644
--- a/pkg/util/errorutil/unimplemented/unimplemented.go
+++ b/pkg/util/errorutil/unimplemented/unimplemented.go
@@ -1,12 +1,7 @@
 // Copyright 2019 The Cockroach Authors.
 //
-// Use of this software is governed by the Business Source License
-// included in the file licenses/BSL.txt.
-//
-// As of the Change Date specified in that file, in accordance with
-// the Business Source License, use of this software will be governed
-// by the Apache License, Version 2.0, included in the file
-// licenses/APL.txt.
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
 
 package unimplemented
 
diff --git a/pkg/util/every_n.go b/pkg/util/every_n.go
index 3cf9485..b38595e 100644
--- a/pkg/util/every_n.go
+++ b/pkg/util/every_n.go
@@ -1,12 +1,7 @@
 // Copyright 2017 The Cockroach Authors.
 //
-// Use of this software is governed by the Business Source License
-// included in the file licenses/BSL.txt.
-//
-// As of the Change Date specified in that file, in accordance with
-// the Business Source License, use of this software will be governed
-// by the Apache License, Version 2.0, included in the file
-// licenses/APL.txt.
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
 
 package util
 
diff --git a/pkg/util/fast_int_map.go b/pkg/util/fast_int_map.go
index ebe4239..a0d89f9 100644
--- a/pkg/util/fast_int_map.go
+++ b/pkg/util/fast_int_map.go
@@ -1,22 +1,16 @@
 // Copyright 2018 The Cockroach Authors.
 //
-// Use of this software is governed by the Business Source License
-// included in the file licenses/BSL.txt.
-//
-// As of the Change Date specified in that file, in accordance with
-// the Business Source License, use of this software will be governed
-// by the Apache License, Version 2.0, included in the file
-// licenses/APL.txt.
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
 
 package util
 
 import (
 	"bytes"
 	"fmt"
+	"math"
 	"math/bits"
 	"sort"
-
-	"github.com/cockroachdb/cockroachdb-parser/pkg/util/intsets"
 )
 
 // FastIntMap is a replacement for map[int]int which is more efficient when both
@@ -136,7 +130,7 @@ func (m FastIntMap) MaxKey() (_ int, ok bool) {
 	if len(m.large) == 0 {
 		return 0, false
 	}
-	max := intsets.MinInt
+	max := math.MinInt
 	for k := range m.large {
 		if max < k {
 			max = k
@@ -173,7 +167,7 @@ func (m FastIntMap) MaxValue() (_ int, ok bool) {
 	if len(m.large) == 0 {
 		return 0, false
 	}
-	max := intsets.MinInt
+	max := math.MinInt
 	for _, v := range m.large {
 		if max < v {
 			max = v
diff --git a/pkg/util/grunning/disabled.go b/pkg/util/grunning/disabled.go
index f175eb2..0f96254 100644
--- a/pkg/util/grunning/disabled.go
+++ b/pkg/util/grunning/disabled.go
@@ -1,20 +1,14 @@
 // Copyright 2022 The Cockroach Authors.
 //
-// Use of this software is governed by the Business Source License
-// included in the file licenses/BSL.txt.
-//
-// As of the Change Date specified in that file, in accordance with
-// the Business Source License, use of this software will be governed
-// by the Apache License, Version 2.0, included in the file
-// licenses/APL.txt.
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
 
-// See grunning.Supported() for an explanation behind this build tag.
+// See grunning.Supported for an explanation behind this build tag.
 //
-//go:build (linux && s390x) || !bazel
-// +build linux,s390x !bazel
+//go:build !bazel
 
 package grunning
 
-func grunningnanos() int64 { return 0 }
+const supported = false
 
-func supported() bool { return false }
+func grunningnanos() int64 { return 0 }
diff --git a/pkg/util/grunning/enabled.go b/pkg/util/grunning/enabled.go
index f8cd1b5..99a9ca9 100644
--- a/pkg/util/grunning/enabled.go
+++ b/pkg/util/grunning/enabled.go
@@ -1,27 +1,19 @@
 // Copyright 2022 The Cockroach Authors.
 //
-// Use of this software is governed by the Business Source License
-// included in the file licenses/BSL.txt.
-//
-// As of the Change Date specified in that file, in accordance with
-// the Business Source License, use of this software will be governed
-// by the Apache License, Version 2.0, included in the file
-// licenses/APL.txt.
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
 
-// See grunning.Supported() for an explanation behind this build tag.
+// See grunning.Supported for an explanation behind this build tag.
 //
-//go:build !((linux && s390x) || !bazel)
-// +build !linux !s390x
-// +build bazel
+//go:build bazel
 
 package grunning
 
-import _ "unsafe" // for go:linkname
+import "runtime"
 
-// grunningnanos returns the running time observed by the current goroutine by
-// linking to a private symbol in the (patched) runtime package.
-//
-//go:linkname grunningnanos runtime.grunningnanos
-func grunningnanos() int64
+const supported = true
 
-func supported() bool { return true }
+// grunningnanos returns the running time observed by the current goroutine.
+func grunningnanos() int64 {
+	return runtime.Grunningnanos()
+}
diff --git a/pkg/util/grunning/grunning.go b/pkg/util/grunning/grunning.go
index 8d65874..47558a7 100644
--- a/pkg/util/grunning/grunning.go
+++ b/pkg/util/grunning/grunning.go
@@ -1,12 +1,7 @@
 // Copyright 2022 The Cockroach Authors.
 //
-// Use of this software is governed by the Business Source License
-// included in the file licenses/BSL.txt.
-//
-// As of the Change Date specified in that file, in accordance with
-// the Business Source License, use of this software will be governed
-// by the Apache License, Version 2.0, included in the file
-// licenses/APL.txt.
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
 
 // Package grunning is a library that's able to retrieve on-CPU running time for
 // individual goroutines. It relies on using a patched Go and provides a
@@ -16,6 +11,11 @@ package grunning
 
 import "time"
 
+// Supported is true iff per-goroutine running time is available in this build.
+// We use a patched Go runtime for all platforms officially supported for CRDB
+// when built using Bazel.
+const Supported = supported
+
 // Time returns the time spent by the current goroutine in the running state.
 func Time() time.Duration {
 	return time.Duration(grunningnanos())
@@ -47,10 +47,3 @@ func Elapsed(start, end time.Duration) time.Duration {
 	}
 	return time.Duration(diff)
 }
-
-// Supported returns true iff per-goroutine running time is available in this
-// build. We use a patched Go runtime for all platforms officially supported for
-// CRDB when built using Bazel.
-func Supported() bool {
-	return supported()
-}
diff --git a/pkg/util/hash.go b/pkg/util/hash.go
index b216163..ddbedfa 100644
--- a/pkg/util/hash.go
+++ b/pkg/util/hash.go
@@ -1,12 +1,7 @@
 // Copyright 2017 The Cockroach Authors.
 //
-// Use of this software is governed by the Business Source License
-// included in the file licenses/BSL.txt.
-//
-// As of the Change Date specified in that file, in accordance with
-// the Business Source License, use of this software will be governed
-// by the Apache License, Version 2.0, included in the file
-// licenses/APL.txt.
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
 
 package util
 
diff --git a/pkg/util/hlc/doc.go b/pkg/util/hlc/doc.go
new file mode 100644
index 0000000..e9d31a4
--- /dev/null
+++ b/pkg/util/hlc/doc.go
@@ -0,0 +1,325 @@
+// Copyright 2021 The Cockroach Authors.
+//
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
+
+/*
+Package hlc implements the Hybrid Logical Clock outlined in "Logical Physical
+Clocks and Consistent Snapshots in Globally Distributed Databases", available
+online at http://www.cse.buffalo.edu/tech-reports/2014-04.pdf.
+
+Each node within a CockroachDB cluster maintains a hybrid logical clock (HLC),
+which provides timestamps that are a combination of physical and logical time.
+Physical time is based on a node’s coarsely-synchronized system clock, and
+logical time is based on Lamport’s clocks.
+
+Hybrid-logical clocks provide a few important properties:
+
+# Causality tracking
+
+HLCs provide causality tracking through a combination of a physical and logical
+(to break ties) component upon each inter-node exchange. Nodes attach HLC
+timestamps to each message that they send and use HLC timestamps from each
+message that they receive to update their local clock.
+
+There are currently three channels through which HLC timestamps are passed
+between nodes in a cluster:
+
+  - Store Liveness (bidirectional): stores attach clock readings to all messages.
+    Whenever a store receives a messages, it forwards its clock to the clock
+    reading included in the message.
+
+    Ref: (storeliveness.MessageBatch).Timestamp.
+
+  - Raft (unidirectional): proposers of Raft commands (i.e. leaseholders) attach
+    clock readings to some of these command (e.g. lease transfers, range merges),
+    which are later consumed by followers when commands are applied to their Raft
+    state machine.
+
+    Ref: (roachpb.Lease).Start.
+    Ref: (roachpb.MergeTrigger).FreezeStart.
+
+  - BatchRequest API (bidirectional): clients and servers of the KV BatchRequest
+    API will attach HLC clock readings on requests and responses (successes and
+    errors).
+
+    Ref: (kvpb.Header).Timestamp.
+    Ref: (kvpb.BatchResponse_Header).Now.
+    Ref: (kvpb.Error).Now.
+
+  - DistSQL flows (unidirectional): leaves of a DistSQL flow will pass clock
+    readings back to the root of the flow. Currently, this only takes place on
+    errors, and relates to the "Transaction retry errors" interaction detailed
+    below.
+
+    Ref: (kvpb.Error).Now.
+
+Capturing causal relationships between events on different nodes is critical for
+enforcing invariants within CockroachDB. What follows is an enumeration of each
+of the interactions in which causality passing through an HLC is necessary for
+correctness. It is intended to be exhaustive.
+
+For context, recall CockroachDB's transactional model: we guarantee
+serializability (transactions appear to be executed in _some_ serial order), and
+linearizability (transactions appear to execute in real-time order) for
+transactions that have overlapping read/write sets. Notably, we are not strictly
+serializable, so transactions with disjoint read/write sets can appear to
+execute in any order to a concurrent third observer that has overlapping
+read/write sets with both transactions (deemed a "causal reverse").
+
+The linearizability guarantee is important to note as two sequential (in real
+time) transactions via two different gateway nodes can be assigned timestamps
+in reverse order (the second gateway's clock may be behind), but must still see
+results according to real-time order if they access overlapping keys (e.g. B
+must see A's write). Also keep in mind that an intent's local timestamp
+signifies when the intent itself was written, but the final value will be
+resolved to the transaction's commit timestamp, which may be later than the
+local timestamp. Since the commit status and timestamp are non-local
+properties, a range may contain committed values (as unresolved intents) that
+turn out to exist in the future of the local HLC when the intent gets resolved.
+
+  - Cooperative lease transfers (Raft channel). During a cooperative lease
+    transfer from one replica of a range to another, the outgoing leaseholder
+    revokes its lease before its expiration time and consults its clock to
+    determine the start time of the next lease. It then proposes this new lease
+    through Raft (see the raft channel above). Upon application of this Raft
+    entry, the incoming leaseholder forwards its HLC to the start time of the
+    lease, ensuring that its clock is >= the new lease's start time.
+
+    The invariant that a leaseholder's clock is always >= its lease's start time
+    is used in a few places. First, it ensures that the leaseholder's clock
+    always leads the local_timestamp of any value in its keyspace written by a
+    prior leaseholder on its range, which is an important property for the
+    correctness of observed timestamps. Second, it ensures that the leaseholder
+    immediately views itself as the leaseholder. Third, it ensures that if the
+    new leaseholder was to transfer the lease away at some point in the future,
+    this later lease's start time could be pulled from the local clock and be
+    guaranteed to receive an even greater starting timestamp.
+
+  - Range merges (Raft + BatchRequest channels). During a merge of two ranges,
+    the right-hand side of the merge passes a "frozen timestamp" clock reading
+    from the right-hand side leaseholder, through the merge transaction
+    coordinator, all the way to the left-hand side's leaseholder. This timestamp
+    is captured after the right-hand side has been subsumed and has stopped
+    serving KV traffic. When the left-hand side's leaseholder applies the range
+    merge and officially takes control of the combined range, it forwards its HLC
+    to this frozen timestamp. Like the previous interaction, this one is also
+    necessary to ensure that the leaseholder of the joint range has a clock that
+    leads the local_timestamp of any value in its keyspace, even one written
+    originally on the right-hand side range.
+
+  - Observed timestamps (Raft + BatchRequest channels). During the lifetime of a
+    transaction, its coordinator issues BatchRequests to other nodes in the
+    cluster. Each time a given transaction visits a node for the first time, it
+    captures an observation from the node's HLC. Separately, when a leaseholder
+    on a given node serves a write, it assigns the write a local_timestamp from
+    its node's HLC clock. This local_timestamp is retained even if an intent is
+    moved to a higher timestamp if it is asynchronously resolved. As a result,
+    these "observed timestamps" captured during the lifetime of a transaction can
+    be used to make a claim about values that could not have been written yet at
+    the time that the transaction first visited the node, and by extension, at
+    the time that the transaction began. This allows the transaction to avoid
+    uncertainty restarts in some circumstances.
+
+    A variant of this same mechanism applies to non-transactional requests that
+    defer their timestamp allocation to the leaseholder of their (single) range.
+    These requests do not collect observed timestamps directly, but they do
+    establish an uncertainty interval immediately upon receipt by their target
+    leaseholder, using a clock reading from the leaseholder's local HLC as the
+    local limit and this clock reading + the cluster's maximum clock skew as the
+    global limit. This limit can be used to make claims about values that could
+    not have been written yet at the time that the non-transaction request first
+    reached the leaseholder node.
+
+    For more, see pkg/kv/kvserver/uncertainty/doc.go.
+
+  - Transaction retry errors (BatchRequest and DistSQL channels).
+    TODO(nvanbenschoten/andreimatei): is this a real case where passing a remote
+    clock signal through the local clock is necessary? The DistSQL channel and
+    its introduction in 72fa944 seem to imply that it is, but I don't really see
+    it, because we don't use the local clock to determine which timestamp to
+    restart the transaction at. Maybe we were just concerned about a transaction
+    restarting at a timestamp above the local clock back then because we had yet
+    to separate the "clock timestamp" domain from the "transaction timestamp"
+    domain.
+
+  - Store Liveness Support Disjointness (Store Liveness channel). One of the key
+    Store Liveness properties, the Support Disjointness Invariant, states that
+    no two support intervals with different epochs should overlap. This helps
+    establish the Lease Disjointness Invariant at the leasing layer. To be able
+    to guarantee the Support Disjointness Invariant, Store Liveness ensures that
+    a store does not request support for a new epoch before it considers the
+    previous epoch's support as expired according to its own clock. This needs
+    to happen in at least two cases:
+
+    (1) When a store restarts and increments its own epoch, it waits out any
+    previously requested support, as described in (storeliveness.RequesterMeta).
+    MaxRequested. This case does not need clock propagation.
+
+    (2) When a store learns that a supporter has withdrawn support for an
+    epoch, it needs to forward its clock to the supporter's clock to ensure
+    that any future support at a higher epoch does not overlap with the
+    previous one. For an example, see (storeliveness.MessageBatch).Timestamp.
+
+    Even though Store Liveness needs clock readings only on HeartbeatResponse
+    messages, they are included on all messages, which has the added benefit of
+    helping stores' clocks stay more closely synchronized, so they can provide
+    and withdraw support in a timely manner.
+
+# Strict monotonicity
+
+HLCs, as implemented by CockroachDB, provide strict monotonicity within and
+across restarts on a single node. Within a continuous process, providing this
+property is trivial. Across restarts, this property is enforced by waiting out
+the maximum clock offset upon process startup before serving any requests in
+ensureClockMonotonicity.
+
+The cluster setting server.clock.persist_upper_bound_interval also provides
+additional protection here by persisting the wall time of the clock
+periodically, although this protection is disabled by default.
+
+Strictly monotonic timestamp allocation ensures that two causally dependent
+transactions originating from the same node are given timestamps that reflect
+their ordering in real time. However, this itself is not a crucial guarantee,
+as CockroachDB does not and can not assume that causally dependent operations
+originate from the same node.
+
+Strictly monotonic timestamp allocation underpins the causality tracking uses
+detailed above.
+
+# Self-stabilization
+
+HLCs provide self-stabilization in the presence of isolated transient clock skew
+fluctuations. As stated above, a node forwards its HLC upon its receipt of a
+network message. The effect of this is that given sufficient intra-cluster
+communication, HLCs across nodes tend to converge and stabilize even if their
+individual physical clocks diverge. This provides no strong guarantees but can
+mask clock synchronization errors in practice.
+
+# Bounded skew
+
+HLCs within a CockroachDB deployment are configured with a maximum allowable
+offset between their physical time component and that of other HLCs in the
+cluster. This is referred to as the MaxOffset. The configuration is static and
+must be identically configured on all nodes in a cluster, which is enforced by
+the HeartbeatService.
+
+The notion of a maximum clock skew at all times between all HLCs in a cluster is
+a foundational assumption used in different parts of the system. What follows is
+an enumeration of the interactions that assume a bounded clock skew, along with
+a discussion for each about the consequences of that assumption being broken and
+the maximum clock skew between two nodes in the cluster exceeding the configured
+limit.
+
+  - Transaction uncertainty intervals. The single-key linearizability property is
+    satisfied in CockroachDB by tracking an uncertainty interval for each
+    transaction, within which the real-time ordering between two transactions is
+    indeterminate. Upon its creation, a transaction is given a provisional commit
+    timestamp commit_ts from the transaction coordinator’s local HLC and an
+    uncertainty interval of [commit_ts, commit_ts + max_offset].
+
+    When a transaction encounters a value on a key at a timestamp below its
+    provisional commit timestamp, it trivially observes the value during reads
+    and overwrites the value at a higher timestamp during writes. This alone
+    would satisfy single-key linearizability if transactions had access to a
+    perfectly synchronized global clock.
+
+    Without global synchronization, the uncertainty interval is needed because it
+    is possible for a transaction to receive a provisional commit timestamp up to
+    the cluster’s max_offset earlier than a transaction that causally preceded
+    this new transaction in real time. When a transaction encounters a value on a
+    key at a timestamp above its provisional commit timestamp but within its
+    uncertainty interval, it performs an uncertainty restart, moving its
+    provisional commit timestamp above the uncertain value but keeping the upper
+    bound of its uncertainty interval fixed.
+
+    This corresponds to treating all values in a transaction’s uncertainty window
+    as past writes. As a result, the operations on each key performed by
+    transactions take place in an order consistent with the real time ordering of
+    those transactions.
+
+    HAZARD: If the maximum clock offset is exceeded, it is possible for a
+    transaction to serve a stale read that violates single-key linearizability.
+    For example, it is possible for a transaction A to write to a key and commit
+    at a timestamp t1, then for its client to hear about the commit. The client
+    may then initiate a second transaction B on a different gateway that has a
+    slow clock. If this slow clock is more than max_offset from other clocks in
+    the system, it is possible for transaction B's uncertainty interval not to
+    extend up to t1 and therefore for a read of the key that transaction A wrote
+    to be missed. Notably, this is a violation of consistency (linearizability)
+    but not of isolation (serializability) — transaction isolation has no clock
+    dependence.
+
+  - Non-cooperative lease transfers. In the happy case, range leases move from
+    replica to replica using a coordinated handoff. However, in the unhappy case
+    where a leaseholder crashes or otherwise becomes unresponsive, other replicas
+    are able to attempt to acquire a new lease for the range as soon as they
+    observe the old lease expire. In this case, the max_offset plays a role in
+    ensuring that two replicas do not both consider themselves the leaseholder
+    for a range at the same (wallclock) time. This is ensured by designating a
+    "stasis" period equal in size to the max_offset at the end of each lease,
+    immediately before its expiration, as unusable. By preventing a lease from
+    being used within this stasis period, two replicas will never think that they
+    hold a valid lease at the same time, even if the outgoing leaseholder has a
+    slow clock and the incoming leaseholder has a fast clock (within bounds). For
+    more, see LeaseState_UNUSABLE.
+
+    Note however that it is easy to overstate the salient point here if one is
+    not careful. Lease start and end times operate in the MVCC time domain, and
+    any two leases are always guaranteed to cover disjoint intervals of MVCC
+    time. Leases entitle their holder to serve reads at any MVCC time below their
+    expiration and to serve writes at any MVCC time at or after their start time
+    and below their expiration. Additionally, the lease sequence is attached to
+    all writes and checked during Raft application, so a stale leaseholder is
+    unable to perform a write after it has been replaced (in "consensus time").
+    This combines to mean that even if two replicas believed that they hold the
+    lease for a range at the same time, they can not perform operations that
+    would be incompatible with one another (e.g. two conflicting writes). Again,
+    transaction isolation has no clock dependence.
+
+    HAZARD: If the maximum clock offset is exceeded, it is possible for two
+    replicas to both consider themselves leaseholders at the same time. This can
+    not lead to stale reads for transactional requests, because a transaction
+    with an uncertainty interval that extends past a lease's expiration will not
+    be able to use that lease to perform a read (which is enforced by a stasis
+    period immediately before its expiration). However, because some
+    non-transactional requests receive their timestamp on the server and do not
+    carry an uncertainty interval, they would be susceptible to stale reads
+    during this period. This is equivalent to the hazard for operations that do
+    use uncertainty intervals, but the mechanics differ slightly.
+
+  - "Linearizable" transactions. By default, transactions in CockroachDB provide
+    single-key linearizability and guarantee that as long as clock skew remains
+    below the configured bounds, transactions will not serve stale reads.
+    However, by default, transactions do not provide strict serializability, as
+    they are susceptible to the "causal reverse" anomaly.
+
+    However, CockroachDB does supports a stricter model of consistency through
+    its COCKROACH_EXPERIMENTAL_LINEARIZABLE environment variable. When in
+    "linearizable" mode (also known as "strict serializable" mode), all writing
+    transactions (but not read-only transactions) must wait ("commit-wait") an
+    additional max_offset after committing to ensure that their commit timestamp
+    is below the current HLC clock time of any other node in the system. In doing
+    so, all causally dependent transactions are guaranteed to start with higher
+    timestamps, regardless of the gateway they use. This ensures that all
+    causally dependent transactions commit with higher timestamps, even if their
+    read and writes sets do not conflict with the original transaction's. This
+    prevents the "causal reverse" anomaly which can be observed by a third,
+    concurrent transaction.
+
+    HAZARD: If the maximum clock offset is exceeded, it is possible that even
+    after a transaction commit-waits for the full max_offset, a causally
+    dependent transaction that evaluates on a different gateway node receives and
+    commits with an earlier timestamp. This resuscitates the possibility of the
+    causal reverse anomaly, along with the possibility for stale reads, as
+    detailed above.
+
+    HAZARD: This mode of operation is completely untested.
+
+To reduce the likelihood of stale reads, nodes periodically measure their
+clock’s offset from other nodes. If any node exceeds the configured maximum
+offset by more than 80% compared to a majority of other nodes, the node in the
+minority self-terminates. This best-effort validation is done in
+(rpc.RemoteClockMonitor).VerifyClockOffset.
+*/
+package hlc
diff --git a/pkg/util/hlc/hlc.go b/pkg/util/hlc/hlc.go
new file mode 100644
index 0000000..27e5765
--- /dev/null
+++ b/pkg/util/hlc/hlc.go
@@ -0,0 +1,695 @@
+// Copyright 2014 The Cockroach Authors.
+//
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
+
+package hlc
+
+import (
+	"context"
+	"fmt"
+	"sync/atomic"
+	"time"
+
+	"github.com/cockroachdb/apd/v3"
+	"github.com/cockroachdb/cockroachdb-parser/pkg/sql/pgwire/pgcode"
+	"github.com/cockroachdb/cockroachdb-parser/pkg/sql/pgwire/pgerror"
+	"github.com/cockroachdb/cockroachdb-parser/pkg/util/syncutil"
+	"github.com/cockroachdb/cockroachdb-parser/pkg/util/timeutil"
+	"github.com/cockroachdb/cockroachdb-parser/pkg/util/tracing"
+	"github.com/cockroachdb/errors"
+	"github.com/cockroachdb/redact"
+)
+
+// TODO(Tobias): Figure out if it would make sense to save some
+// history of the physical clock and react if it jumps backwards
+// repeatedly. This is expected during NTP updates, but may
+// indicate a broken clock in some cases.
+
+// Clock is a hybrid logical clock. Objects of this
+// type model causality while maintaining a relation
+// to physical time. Roughly speaking, timestamps
+// consist of the largest wall clock time among all
+// events, and a logical clock that ticks whenever
+// an event happens in the future of the local physical
+// clock.
+// The data structure is thread safe and thus can safely
+// be shared by multiple goroutines.
+type Clock struct {
+	// wallClock is used to read the current clock.
+	wallClock WallClock
+
+	// maxOffset is the maximal clock skew between any two nodes in the cluster,
+	// as promised by the operator. See MaxOffset().
+	//
+	// TODO(kv): make this dynamic in the distant future, see
+	// https://github.com/cockroachdb/cockroachdb-parser/issues/75564
+	maxOffset time.Duration
+
+	// toleratedOffset is the tolerated clock skew with other cluster nodes,
+	// beyond which the node will self-terminate. See ToleratedOffset().
+	toleratedOffset time.Duration
+
+	// logger is used when forward or backwards jumps are
+	// detected.
+	logger Logger
+
+	// lastPhysicalTime reports the last measured physical time. This
+	// is used to detect clock jumps. The field is accessed atomically.
+	// This field isn't part of the mutex below to prevent
+	// a second mutex acquisition in Now()
+	lastPhysicalTime int64
+
+	// monotonicityErrorsCount indicate how often this clock was
+	// observed to jump backwards. The field is accessed atomically.
+	monotonicityErrorsCount int32
+
+	// forwardClockJumpCheckEnabled specifies whether to panic on forward
+	// clock jumps. If set to 1, then jumps will cause panic. If set to 0,
+	// the check is disabled. The field is accessed atomically.
+	forwardClockJumpCheckEnabled int32
+
+	mu struct {
+		syncutil.Mutex
+
+		// timestamp is the current HLC time. The timestamp.WallTime field must
+		// be updated atomically, even though it is protected by a mutex - this
+		// enables a fast path for reading the wall time without grabbing the
+		// lock.
+		timestamp ClockTimestamp
+
+		// isMonitoringForwardClockJumps is a flag to ensure that only one jump monitoring
+		// goroutine is running per clock
+		isMonitoringForwardClockJumps bool
+
+		// WallTimeUpperBound is an upper bound to the HLC which has been
+		// successfully persisted.
+		// The wall time used by the HLC will always be lesser than this timestamp.
+		// If the physical time is greater than this value, it will cause a panic
+		// If this is set to 0, this validation is skipped
+		wallTimeUpperBound int64
+	}
+}
+
+// WallClock models a physical clock. This is a sub-interface of
+// timeutil.TimeSource.
+type WallClock interface {
+	// Now returns the current time.
+	Now() time.Time
+}
+
+// Logger is used by Clock when clock anamolies are detected.
+type Logger interface {
+	// Warningf is used when the Clock detects non-fatal
+	// conditions.
+	Warningf(ctx context.Context, format string, args ...interface{})
+	// Fatalf is used when forwardClockJump detection is enabled
+	// and the Clock detects a fatal forward clock jump.
+	//
+	// Production implementations of Fatalf should halt the
+	// process in manner appropriate to the caller.
+	Fatalf(ctx context.Context, format string, args ...interface{})
+}
+
+// panicFataler is a Logger that panics when Fatal is called.
+type panicLogger struct{}
+
+var PanicLogger Logger = &panicLogger{}
+
+func (*panicLogger) Warningf(context.Context, string, ...interface{}) {}
+func (*panicLogger) Fatalf(_ context.Context, format string, args ...interface{}) {
+	panic(fmt.Sprintf(format, args...))
+}
+
+// HybridManualClock is a convenience type to facilitate
+// creating a hybrid logical clock whose physical clock
+// ticks with the wall clock, but that can be moved arbitrarily
+// into the future or paused.
+//
+// ManualClock implements WallClock, so it can be used with
+// NewClock(NewHybridManualClock(),...).
+//
+// HybridManualClock is thread safe.
+type HybridManualClock struct {
+	mu struct {
+		syncutil.RWMutex
+		// nanos, if not 0, is the amount of time the clock was manually incremented
+		// by; it is added to physicalClock.
+		nanos int64
+		// nanosAtPause records the timestamp of the physical clock when it gets
+		// paused. 0 means that the clock is not paused.
+		nanosAtPause int64
+	}
+}
+
+// NewHybridManualClock returns a new instance, initialized with
+// specified timestamp.
+func NewHybridManualClock() *HybridManualClock {
+	return &HybridManualClock{}
+}
+
+var _ WallClock = &HybridManualClock{}
+
+// Now implements the WallClock interface.
+func (m *HybridManualClock) Now() time.Time {
+	return timeutil.Unix(0, m.UnixNano())
+}
+
+// UnixNano returns the underlying hybrid manual clock's timestamp.
+func (m *HybridManualClock) UnixNano() int64 {
+	m.mu.RLock()
+	nanosAtPause := m.mu.nanosAtPause
+	nanos := m.mu.nanos
+	m.mu.RUnlock()
+	if nanosAtPause > 0 {
+		return nanos + nanosAtPause
+	}
+	return nanos + timeutil.Now().UnixNano()
+}
+
+// Increment increments the hybrid manual clock's timestamp.
+func (m *HybridManualClock) Increment(nanos int64) {
+	m.mu.Lock()
+	m.mu.nanos += nanos
+	m.mu.Unlock()
+}
+
+// Forward sets the wall time to the supplied timestamp if this moves the clock
+// forward in time. Note that this takes an absolute timestamp (i.e. a wall
+// clock timestamp), not a delta.
+func (m *HybridManualClock) Forward(tsNanos int64) {
+	m.mu.Lock()
+	defer m.mu.Unlock()
+	now := timeutil.Now().UnixNano()
+	if tsNanos < now {
+		return
+	}
+	aheadNanos := tsNanos - now
+	if aheadNanos > m.mu.nanos {
+		m.mu.nanos = aheadNanos
+	}
+}
+
+// Pause pauses the hybrid manual clock; the passage of time no longer causes
+// the clock to tick. Increment can still be used, though.
+func (m *HybridManualClock) Pause() {
+	m.mu.Lock()
+	m.mu.nanosAtPause = timeutil.Now().UnixNano()
+	m.mu.Unlock()
+}
+
+// Resume resumes the hybrid manual clock; the passage of time continues to
+// cause clock to tick.
+func (m *HybridManualClock) Resume() {
+	m.mu.Lock()
+	m.mu.nanosAtPause = 0
+	m.mu.Unlock()
+}
+
+// NewClockWithSystemTimeSource creates a Clock that reads the system time. This
+// is equivalent to NewClock(timeutil.SystemTimeSource, maxOffset, toleratedOffset).
+func NewClockWithSystemTimeSource(maxOffset, toleratedOffset time.Duration, logger Logger) *Clock {
+	return NewClock(timeutil.DefaultTimeSource{}, maxOffset, toleratedOffset, logger)
+}
+
+// NewClockForTesting creates a new Clock for tests that don't care about clock
+// offsets, disabling offset checks. A nil wallClock uses the system clock source.
+func NewClockForTesting(wallClock WallClock) *Clock {
+	if wallClock == nil {
+		wallClock = timeutil.DefaultTimeSource{}
+	}
+	return NewClock(wallClock, 0 /* maxOffset */, 0 /* toleratedOffset */, PanicLogger)
+}
+
+// NewClock returns a Clock configured to use a specified time source. Use
+// NewClockWithSystemTimeSource to use the system clock.
+//
+// maxOffset specifies the max clock offset between cluster nodes, used for
+// linearizability and lease guarantees. toleratedOffset specifies the tolerated
+// clock offset between cluster nodes as measured by RPC heartbeats, terminating
+// the node via RemoteClockMonitor if violated. A value of 0 will disable the
+// corresponding check. See Clock.MaxOffset() and Clock.ToleratedOffset() for
+// details.
+func NewClock(wallClock WallClock, maxOffset, toleratedOffset time.Duration, logger Logger) *Clock {
+	return &Clock{
+		wallClock:       wallClock,
+		maxOffset:       maxOffset,
+		toleratedOffset: toleratedOffset,
+		logger:          logger,
+	}
+}
+
+// WallClock returns the c's time source.
+func (c *Clock) WallClock() WallClock {
+	return c.wallClock
+}
+
+// UnixNano returns the local machine's physical nanosecond
+// unix epoch timestamp as a convenience to create a HLC via
+// c := hlc.NewClockWithSystemTimeSource( ... /* maxOffset */).
+func UnixNano() int64 {
+	return timeutil.Now().UnixNano()
+}
+
+// toleratedForwardClockJump is the tolerated forward jump. Jumps greater
+// than the returned value will cause if panic if forward clock jump check is
+// enabled
+func (c *Clock) toleratedForwardClockJump() time.Duration {
+	return c.maxOffset / 2
+}
+
+// StartMonitoringForwardClockJumps starts a goroutine to update the clock's
+// forwardClockJumpCheckEnabled based on the values pushed in
+// forwardClockJumpCheckEnabledCh.
+//
+// This also keeps lastPhysicalTime up to date to avoid spurious jump errors.
+//
+// A nil channel or a value of false pushed in forwardClockJumpCheckEnabledCh
+// disables checking clock jumps between two successive reads of the physical
+// clock.
+//
+// This should only be called once per clock, and will return an error if called
+// more than once
+//
+// tickerFn is used to create a new ticker
+//
+// tickCallback is called whenever maxForwardClockJumpCh or a ticker tick is
+// processed
+func (c *Clock) StartMonitoringForwardClockJumps(
+	ctx context.Context,
+	forwardClockJumpCheckEnabledCh <-chan bool,
+	tickerFn func(d time.Duration) *time.Ticker,
+	tickCallback func(),
+) error {
+	alreadyMonitoring := c.setMonitoringClockJump()
+	if alreadyMonitoring {
+		return errors.New("clock jumps are already being monitored")
+	}
+
+	ctx, sp := tracing.ForkSpan(ctx, "clock monitor")
+	go func() {
+		defer sp.Finish()
+		// Create a ticker object which can be used in selects.
+		// This ticker is turned on / off based on forwardClockJumpCheckEnabledCh
+		ticker := tickerFn(time.Hour)
+		ticker.Stop()
+		refreshPhysicalClockItvl := c.toleratedForwardClockJump() / 2
+		for {
+			select {
+			case forwardClockJumpEnabled, ok := <-forwardClockJumpCheckEnabledCh:
+				ticker.Stop()
+				if !ok {
+					return
+				}
+				if forwardClockJumpEnabled {
+					// Forward jump check is enabled. Start the ticker
+					ticker = tickerFn(refreshPhysicalClockItvl)
+
+					// Fetch the clock once before we start enforcing forward
+					// jumps. Otherwise the gap between the previous call to
+					// Now() and the time of the first tick would look like a
+					// forward jump.
+					c.getPhysicalClockAndCheck(ctx)
+				}
+				c.setForwardJumpCheckEnabled(forwardClockJumpEnabled)
+			case <-ticker.C:
+				c.getPhysicalClockAndCheck(ctx)
+			}
+
+			if tickCallback != nil {
+				tickCallback()
+			}
+		}
+	}()
+
+	return nil
+}
+
+// MaxOffset returns the maximal clock offset to any node in the cluster as
+// specified by the operator. This is used by the cluster to safely hand off
+// leases and enforce single-key linearizability.
+//
+// A known consequence of clocks drifting apart by more than MaxOffset is the
+// possibility of stale reads. At an architectural level CockroachDB *should*
+// still be serializable in this case, but this has not been conclusively
+// verified and should be taken as conjecture.
+func (c *Clock) MaxOffset() time.Duration {
+	return c.maxOffset
+}
+
+// ToleratedOffset returns the tolerated clock offset with other nodes in the
+// cluster before self-terminating, as measured via RPC heartbeats. A
+// ToleratedOffset of zero disables this mechanism, i.e. behaves like an
+// infinite tolerated offset.
+//
+// Typically, ToleratedOffset is a slightly smaller than MaxOffset (to avoid
+// correctness issues should the actual offset regress further) but it can be
+// configured to be more lenient, instead taking the risk of a correctness
+// issues over a period of unavailability. The latter is appealing in particular
+// when clocks are very tightly synchronized and thus the MaxOffset is
+// configured to a very small value for performance, where RPC latency spikes
+// may cause spurious restarts.
+func (c *Clock) ToleratedOffset() time.Duration {
+	return c.toleratedOffset
+}
+
+// getPhysicalClockAndCheck reads the physical time as nanos since epoch. It
+// also checks for backwards and forwards jumps, as configured.
+func (c *Clock) getPhysicalClockAndCheck(ctx context.Context) int64 {
+	oldTime := atomic.LoadInt64(&c.lastPhysicalTime)
+	newTime := c.wallClock.Now().UnixNano()
+	lastPhysTime := oldTime
+	// Try to update c.lastPhysicalTime. When multiple updaters race, we want the
+	// highest clock reading to win, so keep retrying while we interleave with
+	// updaters with lower clock readings; bail if we interleave with a higher
+	// clock reading.
+	for {
+		if atomic.CompareAndSwapInt64(&c.lastPhysicalTime, lastPhysTime, newTime) {
+			break
+		}
+		lastPhysTime = atomic.LoadInt64(&c.lastPhysicalTime)
+		if lastPhysTime >= newTime {
+			// Someone else updated to a later time than ours.
+			break
+		}
+		// Someone else did an update to an earlier time than what we got in newTime.
+		// So try one more time to update.
+	}
+	c.checkPhysicalClock(ctx, oldTime, newTime)
+	return newTime
+}
+
+// checkPhysicalClock checks for time jumps.
+// oldTime is the lastPhysicalTime before the call to get a new time.
+// newTime is the result of the call to get a new time.
+func (c *Clock) checkPhysicalClock(ctx context.Context, oldTime, newTime int64) {
+	if oldTime == 0 {
+		return
+	}
+
+	interval := oldTime - newTime
+	if interval > int64(c.maxOffset/10) {
+		atomic.AddInt32(&c.monotonicityErrorsCount, 1)
+		c.logger.Warningf(ctx, "backward time jump detected (%f seconds)", float64(-interval)/1e9)
+	}
+
+	if atomic.LoadInt32(&c.forwardClockJumpCheckEnabled) != 0 {
+		toleratedForwardClockJump := c.toleratedForwardClockJump()
+		if int64(toleratedForwardClockJump) <= -interval {
+			c.logger.Fatalf(
+				ctx,
+				"detected forward time jump of %f seconds is not allowed with tolerance of %f seconds",
+				redact.Safe(float64(-interval)/1e9),
+				redact.Safe(float64(toleratedForwardClockJump)/1e9),
+			)
+		}
+	}
+}
+
+// Now returns a timestamp associated with an event from the local
+// machine that may be sent to other members of the distributed network.
+func (c *Clock) Now() Timestamp {
+	return c.NowAsClockTimestamp().ToTimestamp()
+}
+
+// NowAsClockTimestamp is like Now, but returns a ClockTimestamp instead
+// of a raw Timestamp.
+//
+// This is the counterpart of Update, which is passed a ClockTimestamp
+// received from another member of the distributed network. As such,
+// callers that intend to use the returned timestamp to update a peer's
+// HLC clock should use this method.
+func (c *Clock) NowAsClockTimestamp() ClockTimestamp {
+	physicalClock := c.getPhysicalClockAndCheck(context.TODO())
+	c.mu.Lock()
+	defer c.mu.Unlock()
+	if c.mu.timestamp.WallTime >= physicalClock {
+		// The wall time is ahead, so the logical clock ticks.
+		c.mu.timestamp.Logical++
+	} else {
+		// Use the physical clock, and reset the logical one.
+		atomic.StoreInt64(&c.mu.timestamp.WallTime, physicalClock)
+		c.mu.timestamp.Logical = 0
+	}
+
+	c.enforceWallTimeWithinBoundLocked()
+	return c.mu.timestamp
+}
+
+// enforceWallTimeWithinBoundLocked panics if the clock's wall time is greater
+// than the upper bound. The caller of this function must be holding the lock.
+func (c *Clock) enforceWallTimeWithinBoundLocked() {
+	// WallTime should not cross the upper bound (if WallTimeUpperBound is set)
+	if c.mu.wallTimeUpperBound != 0 && c.mu.timestamp.WallTime > c.mu.wallTimeUpperBound {
+		c.logger.Fatalf(
+			context.TODO(),
+			"wall time %d is not allowed to be greater than upper bound of %d.",
+			redact.Safe(c.mu.timestamp.WallTime),
+			redact.Safe(c.mu.wallTimeUpperBound),
+		)
+	}
+}
+
+// PhysicalNow returns the local wall time.
+//
+// Note that, contrary to Now(), PhysicalNow does not take into consideration
+// higher clock signals received through Update(). If you want to take them into
+// consideration, use c.Now().GoTime().
+func (c *Clock) PhysicalNow() int64 {
+	return c.wallClock.Now().UnixNano()
+}
+
+// PhysicalTime returns a time.Time struct using the local wall time.
+func (c *Clock) PhysicalTime() time.Time { return c.wallClock.Now() }
+
+// Update takes a hybrid timestamp, usually originating from an event
+// received from another member of a distributed system. The clock is
+// updated to reflect the later of the two. The update does not check
+// the maximum clock offset. To receive an error response instead of forcing the
+// update in case the remote timestamp is too far into the future, use
+// UpdateAndCheckMaxOffset() instead.
+func (c *Clock) Update(rt ClockTimestamp) {
+
+	// Fast path to avoid grabbing the mutex if the remote time is behind. This
+	// requires c.mu.timestamp.WallTime to be written atomically, even though
+	// the writer has to hold the mutex lock as well.
+	if rt.WallTime < atomic.LoadInt64(&c.mu.timestamp.WallTime) {
+		return
+	}
+
+	c.mu.Lock()
+	defer c.mu.Unlock()
+
+	// There is nothing to do if the remote wall time is behind ours. We just keep ours.
+	if rt.WallTime > c.mu.timestamp.WallTime {
+		// The remote clock is ahead of ours, and we update
+		// our own logical clock with theirs.
+		atomic.StoreInt64(&c.mu.timestamp.WallTime, rt.WallTime)
+		c.mu.timestamp.Logical = rt.Logical
+	} else if rt.WallTime == c.mu.timestamp.WallTime {
+		// Both wall times are equal, and the larger logical
+		// clock is used for the update.
+		if rt.Logical > c.mu.timestamp.Logical {
+			c.mu.timestamp.Logical = rt.Logical
+		}
+	}
+
+	c.enforceWallTimeWithinBoundLocked()
+}
+
+// NB: don't change the string here; this will cause cross-version issues
+// since this singleton is used as a marker.
+var errUntrustworthyRemoteWallTimeErr = errors.New("remote wall time is too far ahead to be trustworthy")
+
+// IsUntrustworthyRemoteWallTimeError returns true if the error came resulted
+// from a call to Clock.UpdateAndCheckMaxOffset due to the passed ClockTimestamp
+// being too far in the future.
+func IsUntrustworthyRemoteWallTimeError(err error) bool {
+	return errors.Is(err, errUntrustworthyRemoteWallTimeErr)
+}
+
+// UpdateAndCheckMaxOffset is like Update, but also takes the wall time into account and
+// returns an error in the event that the supplied remote timestamp exceeds
+// the wall clock time by more than the maximum clock offset.
+//
+// If an error is returned, it will be detectable with
+// IsUntrustworthyRemoteWallTimeError.
+func (c *Clock) UpdateAndCheckMaxOffset(ctx context.Context, rt ClockTimestamp) error {
+	physicalClock := c.getPhysicalClockAndCheck(ctx)
+
+	offset := time.Duration(rt.WallTime - physicalClock)
+	if c.maxOffset > 0 && offset > c.maxOffset {
+		return errors.Mark(
+			errors.Errorf("remote wall time is too far ahead (%s) to be trustworthy", offset),
+			errUntrustworthyRemoteWallTimeErr,
+		)
+	}
+
+	if physicalClock > rt.WallTime {
+		c.Update(ClockTimestamp{WallTime: physicalClock})
+	} else {
+		c.Update(rt)
+	}
+
+	return nil
+}
+
+// setForwardJumpCheckEnabled atomically sets forwardClockJumpCheckEnabled
+func (c *Clock) setForwardJumpCheckEnabled(forwardJumpCheckEnabled bool) {
+	if forwardJumpCheckEnabled {
+		atomic.StoreInt32(&c.forwardClockJumpCheckEnabled, 1)
+	} else {
+		atomic.StoreInt32(&c.forwardClockJumpCheckEnabled, 0)
+	}
+}
+
+// setMonitoringClockJump atomically sets isMonitoringForwardClockJumps to true and
+// returns the old value. This is used to ensure that only one monitoring
+// goroutine is launched
+func (c *Clock) setMonitoringClockJump() bool {
+	c.mu.Lock()
+	defer c.mu.Unlock()
+	isMonitoring := c.mu.isMonitoringForwardClockJumps
+	c.mu.isMonitoringForwardClockJumps = true
+	return isMonitoring
+}
+
+// RefreshHLCUpperBound persists the HLC upper bound and updates the in memory
+// value if the persist succeeds. delta is used to compute the upper bound.
+func (c *Clock) RefreshHLCUpperBound(persistFn func(int64) error, delta int64) error {
+	if delta < 0 {
+		return errors.Errorf("HLC upper bound delta %d should be positive", delta)
+	}
+	return c.persistHLCUpperBound(persistFn, c.Now().WallTime+delta)
+}
+
+// ResetHLCUpperBound persists a value of 0 as the HLC upper bound which
+// disables upper bound validation
+func (c *Clock) ResetHLCUpperBound(persistFn func(int64) error) error {
+	return c.persistHLCUpperBound(persistFn, 0 /* hlcUpperBound */)
+}
+
+// RefreshHLCUpperBound persists the HLC upper bound and updates the in memory
+// value if the persist succeeds
+func (c *Clock) persistHLCUpperBound(persistFn func(int64) error, hlcUpperBound int64) error {
+	if err := persistFn(hlcUpperBound); err != nil {
+		return err
+	}
+
+	c.mu.Lock()
+	defer c.mu.Unlock()
+	c.mu.wallTimeUpperBound = hlcUpperBound
+	return nil
+}
+
+// WallTimeUpperBound returns the in memory value of upper bound to wall time
+func (c *Clock) WallTimeUpperBound() int64 {
+	c.mu.Lock()
+	defer c.mu.Unlock()
+	return c.mu.wallTimeUpperBound
+}
+
+// SleepUntil sleeps until the HLC reaches or exceeds the given timestamp. This
+// typically results in sleeping for the duration between the given timestamp's
+// nanosecond WallTime and the Clock's current WallTime time, but may result in
+// sleeping for longer or shorter, depending on the HLC clock's relation to its
+// physical time source (it may lead it) and whether it advances more rapidly
+// due to updates from other nodes.
+//
+// If the provided context is canceled, the method will return the cancellation
+// error immediately. If an error is returned, no guarantee is made that the HLC
+// will have reached the specified timestamp.
+func (c *Clock) SleepUntil(ctx context.Context, t Timestamp) error {
+	// Don't busy loop if the HLC clock is out ahead of the system's
+	// physical clock.
+	const minSleep = 25 * time.Microsecond
+	// Refresh every second in case there was a clock jump.
+	const maxSleep = 1 * time.Second
+	for {
+		if err := ctx.Err(); err != nil {
+			return err
+		}
+		now := c.Now()
+		if t.LessEq(now) {
+			return nil
+		}
+		d := now.GoTime().Sub(t.GoTime())
+		if d < minSleep {
+			d = minSleep
+		} else if d > maxSleep {
+			d = maxSleep
+		}
+		// If we're going to sleep for at least 1ms, listen for context
+		// cancellation. Otherwise, don't bother with the select and the
+		// more expensive use of time.After.
+		if d < 1*time.Millisecond {
+			time.Sleep(d)
+		} else {
+			select {
+			case <-time.After(d):
+			case <-ctx.Done():
+				return ctx.Err()
+			}
+		}
+	}
+}
+
+// DecimalToHLC performs the conversion from an inputted DECIMAL datum for an
+// AS OF SYSTEM TIME query to an HLC timestamp.
+func DecimalToHLC(d *apd.Decimal) (Timestamp, error) {
+	if d.Negative {
+		return Timestamp{}, pgerror.Newf(pgcode.Syntax, "cannot be negative")
+	}
+	var integral, fractional apd.Decimal
+	d.Modf(&integral, &fractional)
+	timestamp, err := integral.Int64()
+	if err != nil {
+		return Timestamp{}, pgerror.Wrapf(err, pgcode.Syntax, "converting timestamp to integer") // should never happen
+	}
+	if fractional.IsZero() {
+		// there is no logical portion to this clock
+		return Timestamp{WallTime: timestamp}, nil
+	}
+
+	var logical apd.Decimal
+	multiplier := apd.New(1, 10)
+	condition, err := apd.BaseContext.Mul(&logical, &fractional, multiplier)
+	if err != nil {
+		return Timestamp{}, pgerror.Wrapf(err, pgcode.Syntax, "determining value of logical clock")
+	}
+	if _, err := condition.GoError(apd.DefaultTraps); err != nil {
+		return Timestamp{}, pgerror.Wrapf(err, pgcode.Syntax, "determining value of logical clock")
+	}
+
+	counter, err := logical.Int64()
+	if err != nil {
+		return Timestamp{}, pgerror.Newf(pgcode.Syntax, "logical part has too many digits")
+	}
+	if counter > 1<<31 {
+		return Timestamp{}, pgerror.Newf(pgcode.Syntax, "logical clock too large: %d", counter)
+	}
+	return Timestamp{
+		WallTime: timestamp,
+		Logical:  int32(counter),
+	}, nil
+}
+
+// ParseHLC parses a string representation of an `hlc.Timestamp`.
+// This differs from hlc.ParseTimestamp in that it parses the decimal
+// serialization of an hlc timestamp as opposed to the string serialization
+// performed by hlc.Timestamp.String().
+//
+// This function is used to parse:
+//
+//	1580361670629466905.0000000001
+//
+// hlc.ParseTimestamp() would be used to parse:
+//
+//	1580361670.629466905,1
+func ParseHLC(s string) (Timestamp, error) {
+	dec, _, err := apd.NewFromString(s)
+	if err != nil {
+		return Timestamp{}, err
+	}
+	return DecimalToHLC(dec)
+}
diff --git a/pkg/util/hlc/legacy_timestamp.pb.go b/pkg/util/hlc/legacy_timestamp.pb.go
new file mode 100644
index 0000000..357968a
--- /dev/null
+++ b/pkg/util/hlc/legacy_timestamp.pb.go
@@ -0,0 +1,435 @@
+// Code generated by protoc-gen-gogo. DO NOT EDIT.
+// source: util/hlc/legacy_timestamp.proto
+
+package hlc
+
+import (
+	fmt "fmt"
+	_ "github.com/gogo/protobuf/gogoproto"
+	proto "github.com/gogo/protobuf/proto"
+	io "io"
+	math "math"
+	math_bits "math/bits"
+)
+
+// Reference imports to suppress errors if they are not otherwise used.
+var _ = proto.Marshal
+var _ = fmt.Errorf
+var _ = math.Inf
+
+// This is a compile-time assertion to ensure that this generated file
+// is compatible with the proto package it is being compiled against.
+// A compilation error at this line likely means your copy of the
+// proto package needs to be updated.
+const _ = proto.GoGoProtoPackageIsVersion3 // please upgrade the proto package
+
+// LegacyTimestamp is convertible to hlc.Timestamp, but uses the
+// legacy encoding as it is encoded "below raft".
+type LegacyTimestamp struct {
+	// Holds a wall time, typically a unix epoch time expressed in
+	// nanoseconds.
+	WallTime int64 `protobuf:"varint,1,opt,name=wall_time,json=wallTime" json:"wall_time"`
+	// The logical component captures causality for events whose wall
+	// times are equal. It is effectively bounded by (maximum clock
+	// skew)/(minimal ns between events) and nearly impossible to
+	// overflow.
+	Logical int32 `protobuf:"varint,2,opt,name=logical" json:"logical"`
+}
+
+func (m *LegacyTimestamp) Reset()      { *m = LegacyTimestamp{} }
+func (*LegacyTimestamp) ProtoMessage() {}
+func (*LegacyTimestamp) Descriptor() ([]byte, []int) {
+	return fileDescriptor_3bf5feed19a38215, []int{0}
+}
+func (m *LegacyTimestamp) XXX_Unmarshal(b []byte) error {
+	return m.Unmarshal(b)
+}
+func (m *LegacyTimestamp) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+	b = b[:cap(b)]
+	n, err := m.MarshalToSizedBuffer(b)
+	if err != nil {
+		return nil, err
+	}
+	return b[:n], nil
+}
+func (m *LegacyTimestamp) XXX_Merge(src proto.Message) {
+	xxx_messageInfo_LegacyTimestamp.Merge(m, src)
+}
+func (m *LegacyTimestamp) XXX_Size() int {
+	return m.Size()
+}
+func (m *LegacyTimestamp) XXX_DiscardUnknown() {
+	xxx_messageInfo_LegacyTimestamp.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_LegacyTimestamp proto.InternalMessageInfo
+
+func init() {
+	proto.RegisterType((*LegacyTimestamp)(nil), "cockroach.parser.util.hlc.LegacyTimestamp")
+}
+
+func init() { proto.RegisterFile("util/hlc/legacy_timestamp.proto", fileDescriptor_3bf5feed19a38215) }
+
+var fileDescriptor_3bf5feed19a38215 = []byte{
+	// 230 bytes of a gzipped FileDescriptorProto
+	0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0x92, 0x2f, 0x2d, 0xc9, 0xcc,
+	0xd1, 0xcf, 0xc8, 0x49, 0xd6, 0xcf, 0x49, 0x4d, 0x4f, 0x4c, 0xae, 0x8c, 0x2f, 0xc9, 0xcc, 0x4d,
+	0x2d, 0x2e, 0x49, 0xcc, 0x2d, 0xd0, 0x2b, 0x28, 0xca, 0x2f, 0xc9, 0x17, 0x12, 0x4a, 0xce, 0x4f,
+	0xce, 0x2e, 0xca, 0x4f, 0x4c, 0xce, 0xd0, 0x03, 0x29, 0xd5, 0xcb, 0xc8, 0x49, 0x96, 0x12, 0x49,
+	0xcf, 0x4f, 0xcf, 0x07, 0x4b, 0xeb, 0x83, 0x58, 0x10, 0x95, 0x4a, 0x19, 0x5c, 0xfc, 0x3e, 0x60,
+	0x33, 0x42, 0x60, 0x46, 0x08, 0x29, 0x72, 0x71, 0x96, 0x27, 0xe6, 0xe4, 0x80, 0x0d, 0x95, 0x60,
+	0x54, 0x60, 0xd4, 0x60, 0x76, 0x62, 0x39, 0x71, 0x4f, 0x9e, 0x21, 0x88, 0x03, 0x24, 0x0c, 0x52,
+	0x27, 0x24, 0xc7, 0xc5, 0x9e, 0x93, 0x9f, 0x9e, 0x99, 0x9c, 0x98, 0x23, 0xc1, 0xa4, 0xc0, 0xa8,
+	0xc1, 0x0a, 0x55, 0x00, 0x13, 0xb4, 0xe2, 0x99, 0xb1, 0x40, 0x9e, 0x61, 0xc7, 0x02, 0x79, 0xc6,
+	0x17, 0x0b, 0xe4, 0x19, 0xbd, 0x58, 0x38, 0x98, 0x05, 0x58, 0x9c, 0xfc, 0x4f, 0x3c, 0x94, 0x63,
+	0x38, 0xf1, 0x48, 0x8e, 0xf1, 0xc2, 0x23, 0x39, 0xc6, 0x1b, 0x8f, 0xe4, 0x18, 0x1f, 0x3c, 0x92,
+	0x63, 0x9c, 0xf0, 0x58, 0x8e, 0xe1, 0xc2, 0x63, 0x39, 0x86, 0x1b, 0x8f, 0xe5, 0x18, 0xa2, 0x74,
+	0xd3, 0x33, 0x4b, 0x32, 0x4a, 0x93, 0xf4, 0x92, 0xf3, 0x73, 0xf5, 0xe1, 0x1e, 0x48, 0x49, 0x42,
+	0xb0, 0xf5, 0x0b, 0xb2, 0xd3, 0xf5, 0x61, 0x7e, 0x07, 0x04, 0x00, 0x00, 0xff, 0xff, 0x5b, 0x3c,
+	0x22, 0xdd, 0x06, 0x01, 0x00, 0x00,
+}
+
+func (this *LegacyTimestamp) Equal(that interface{}) bool {
+	if that == nil {
+		return this == nil
+	}
+
+	that1, ok := that.(*LegacyTimestamp)
+	if !ok {
+		that2, ok := that.(LegacyTimestamp)
+		if ok {
+			that1 = &that2
+		} else {
+			return false
+		}
+	}
+	if that1 == nil {
+		return this == nil
+	} else if this == nil {
+		return false
+	}
+	if this.WallTime != that1.WallTime {
+		return false
+	}
+	if this.Logical != that1.Logical {
+		return false
+	}
+	return true
+}
+func (m *LegacyTimestamp) Marshal() (dAtA []byte, err error) {
+	size := m.Size()
+	dAtA = make([]byte, size)
+	n, err := m.MarshalToSizedBuffer(dAtA[:size])
+	if err != nil {
+		return nil, err
+	}
+	return dAtA[:n], nil
+}
+
+func (m *LegacyTimestamp) MarshalTo(dAtA []byte) (int, error) {
+	size := m.Size()
+	return m.MarshalToSizedBuffer(dAtA[:size])
+}
+
+func (m *LegacyTimestamp) MarshalToSizedBuffer(dAtA []byte) (int, error) {
+	i := len(dAtA)
+	_ = i
+	var l int
+	_ = l
+	i = encodeVarintLegacyTimestamp(dAtA, i, uint64(m.Logical))
+	i--
+	dAtA[i] = 0x10
+	i = encodeVarintLegacyTimestamp(dAtA, i, uint64(m.WallTime))
+	i--
+	dAtA[i] = 0x8
+	return len(dAtA) - i, nil
+}
+
+func encodeVarintLegacyTimestamp(dAtA []byte, offset int, v uint64) int {
+	offset -= sovLegacyTimestamp(v)
+	base := offset
+	for v >= 1<<7 {
+		dAtA[offset] = uint8(v&0x7f | 0x80)
+		v >>= 7
+		offset++
+	}
+	dAtA[offset] = uint8(v)
+	return base
+}
+func NewPopulatedLegacyTimestamp(r randyLegacyTimestamp, easy bool) *LegacyTimestamp {
+	this := &LegacyTimestamp{}
+	this.WallTime = int64(r.Int63())
+	if r.Intn(2) == 0 {
+		this.WallTime *= -1
+	}
+	this.Logical = int32(r.Int31())
+	if r.Intn(2) == 0 {
+		this.Logical *= -1
+	}
+	if !easy && r.Intn(10) != 0 {
+	}
+	return this
+}
+
+type randyLegacyTimestamp interface {
+	Float32() float32
+	Float64() float64
+	Int63() int64
+	Int31() int32
+	Uint32() uint32
+	Intn(n int) int
+}
+
+func randUTF8RuneLegacyTimestamp(r randyLegacyTimestamp) rune {
+	ru := r.Intn(62)
+	if ru < 10 {
+		return rune(ru + 48)
+	} else if ru < 36 {
+		return rune(ru + 55)
+	}
+	return rune(ru + 61)
+}
+func randStringLegacyTimestamp(r randyLegacyTimestamp) string {
+	v1 := r.Intn(100)
+	tmps := make([]rune, v1)
+	for i := 0; i < v1; i++ {
+		tmps[i] = randUTF8RuneLegacyTimestamp(r)
+	}
+	return string(tmps)
+}
+func randUnrecognizedLegacyTimestamp(r randyLegacyTimestamp, maxFieldNumber int) (dAtA []byte) {
+	l := r.Intn(5)
+	for i := 0; i < l; i++ {
+		wire := r.Intn(4)
+		if wire == 3 {
+			wire = 5
+		}
+		fieldNumber := maxFieldNumber + r.Intn(100)
+		dAtA = randFieldLegacyTimestamp(dAtA, r, fieldNumber, wire)
+	}
+	return dAtA
+}
+func randFieldLegacyTimestamp(dAtA []byte, r randyLegacyTimestamp, fieldNumber int, wire int) []byte {
+	key := uint32(fieldNumber)<<3 | uint32(wire)
+	switch wire {
+	case 0:
+		dAtA = encodeVarintPopulateLegacyTimestamp(dAtA, uint64(key))
+		v2 := r.Int63()
+		if r.Intn(2) == 0 {
+			v2 *= -1
+		}
+		dAtA = encodeVarintPopulateLegacyTimestamp(dAtA, uint64(v2))
+	case 1:
+		dAtA = encodeVarintPopulateLegacyTimestamp(dAtA, uint64(key))
+		dAtA = append(dAtA, byte(r.Intn(256)), byte(r.Intn(256)), byte(r.Intn(256)), byte(r.Intn(256)), byte(r.Intn(256)), byte(r.Intn(256)), byte(r.Intn(256)), byte(r.Intn(256)))
+	case 2:
+		dAtA = encodeVarintPopulateLegacyTimestamp(dAtA, uint64(key))
+		ll := r.Intn(100)
+		dAtA = encodeVarintPopulateLegacyTimestamp(dAtA, uint64(ll))
+		for j := 0; j < ll; j++ {
+			dAtA = append(dAtA, byte(r.Intn(256)))
+		}
+	default:
+		dAtA = encodeVarintPopulateLegacyTimestamp(dAtA, uint64(key))
+		dAtA = append(dAtA, byte(r.Intn(256)), byte(r.Intn(256)), byte(r.Intn(256)), byte(r.Intn(256)))
+	}
+	return dAtA
+}
+func encodeVarintPopulateLegacyTimestamp(dAtA []byte, v uint64) []byte {
+	for v >= 1<<7 {
+		dAtA = append(dAtA, uint8(uint64(v)&0x7f|0x80))
+		v >>= 7
+	}
+	dAtA = append(dAtA, uint8(v))
+	return dAtA
+}
+func (m *LegacyTimestamp) Size() (n int) {
+	if m == nil {
+		return 0
+	}
+	var l int
+	_ = l
+	n += 1 + sovLegacyTimestamp(uint64(m.WallTime))
+	n += 1 + sovLegacyTimestamp(uint64(m.Logical))
+	return n
+}
+
+func sovLegacyTimestamp(x uint64) (n int) {
+	return int((uint32(math_bits.Len64(x|1)+6) * 37) >> 8)
+}
+func sozLegacyTimestamp(x uint64) (n int) {
+	return sovLegacyTimestamp(uint64((x << 1) ^ uint64((int64(x) >> 63))))
+}
+func (m *LegacyTimestamp) Unmarshal(dAtA []byte) error {
+	l := len(dAtA)
+	iNdEx := 0
+	for iNdEx < l {
+		preIndex := iNdEx
+		var wire uint64
+		for shift := uint(0); ; shift += 7 {
+			if shift >= 64 {
+				return ErrIntOverflowLegacyTimestamp
+			}
+			if iNdEx >= l {
+				return io.ErrUnexpectedEOF
+			}
+			b := dAtA[iNdEx]
+			iNdEx++
+			wire |= uint64(b&0x7F) << shift
+			if b < 0x80 {
+				break
+			}
+		}
+		fieldNum := int32(wire >> 3)
+		wireType := int(wire & 0x7)
+		if wireType == 4 {
+			return fmt.Errorf("proto: LegacyTimestamp: wiretype end group for non-group")
+		}
+		if fieldNum <= 0 {
+			return fmt.Errorf("proto: LegacyTimestamp: illegal tag %d (wire type %d)", fieldNum, wire)
+		}
+		switch fieldNum {
+		case 1:
+			if wireType != 0 {
+				return fmt.Errorf("proto: wrong wireType = %d for field WallTime", wireType)
+			}
+			m.WallTime = 0
+			for shift := uint(0); ; shift += 7 {
+				if shift >= 64 {
+					return ErrIntOverflowLegacyTimestamp
+				}
+				if iNdEx >= l {
+					return io.ErrUnexpectedEOF
+				}
+				b := dAtA[iNdEx]
+				iNdEx++
+				m.WallTime |= int64(b&0x7F) << shift
+				if b < 0x80 {
+					break
+				}
+			}
+		case 2:
+			if wireType != 0 {
+				return fmt.Errorf("proto: wrong wireType = %d for field Logical", wireType)
+			}
+			m.Logical = 0
+			for shift := uint(0); ; shift += 7 {
+				if shift >= 64 {
+					return ErrIntOverflowLegacyTimestamp
+				}
+				if iNdEx >= l {
+					return io.ErrUnexpectedEOF
+				}
+				b := dAtA[iNdEx]
+				iNdEx++
+				m.Logical |= int32(b&0x7F) << shift
+				if b < 0x80 {
+					break
+				}
+			}
+		default:
+			iNdEx = preIndex
+			skippy, err := skipLegacyTimestamp(dAtA[iNdEx:])
+			if err != nil {
+				return err
+			}
+			if (skippy < 0) || (iNdEx+skippy) < 0 {
+				return ErrInvalidLengthLegacyTimestamp
+			}
+			if (iNdEx + skippy) > l {
+				return io.ErrUnexpectedEOF
+			}
+			iNdEx += skippy
+		}
+	}
+
+	if iNdEx > l {
+		return io.ErrUnexpectedEOF
+	}
+	return nil
+}
+func skipLegacyTimestamp(dAtA []byte) (n int, err error) {
+	l := len(dAtA)
+	iNdEx := 0
+	depth := 0
+	for iNdEx < l {
+		var wire uint64
+		for shift := uint(0); ; shift += 7 {
+			if shift >= 64 {
+				return 0, ErrIntOverflowLegacyTimestamp
+			}
+			if iNdEx >= l {
+				return 0, io.ErrUnexpectedEOF
+			}
+			b := dAtA[iNdEx]
+			iNdEx++
+			wire |= (uint64(b) & 0x7F) << shift
+			if b < 0x80 {
+				break
+			}
+		}
+		wireType := int(wire & 0x7)
+		switch wireType {
+		case 0:
+			for shift := uint(0); ; shift += 7 {
+				if shift >= 64 {
+					return 0, ErrIntOverflowLegacyTimestamp
+				}
+				if iNdEx >= l {
+					return 0, io.ErrUnexpectedEOF
+				}
+				iNdEx++
+				if dAtA[iNdEx-1] < 0x80 {
+					break
+				}
+			}
+		case 1:
+			iNdEx += 8
+		case 2:
+			var length int
+			for shift := uint(0); ; shift += 7 {
+				if shift >= 64 {
+					return 0, ErrIntOverflowLegacyTimestamp
+				}
+				if iNdEx >= l {
+					return 0, io.ErrUnexpectedEOF
+				}
+				b := dAtA[iNdEx]
+				iNdEx++
+				length |= (int(b) & 0x7F) << shift
+				if b < 0x80 {
+					break
+				}
+			}
+			if length < 0 {
+				return 0, ErrInvalidLengthLegacyTimestamp
+			}
+			iNdEx += length
+		case 3:
+			depth++
+		case 4:
+			if depth == 0 {
+				return 0, ErrUnexpectedEndOfGroupLegacyTimestamp
+			}
+			depth--
+		case 5:
+			iNdEx += 4
+		default:
+			return 0, fmt.Errorf("proto: illegal wireType %d", wireType)
+		}
+		if iNdEx < 0 {
+			return 0, ErrInvalidLengthLegacyTimestamp
+		}
+		if depth == 0 {
+			return iNdEx, nil
+		}
+	}
+	return 0, io.ErrUnexpectedEOF
+}
+
+var (
+	ErrInvalidLengthLegacyTimestamp        = fmt.Errorf("proto: negative length found during unmarshaling")
+	ErrIntOverflowLegacyTimestamp          = fmt.Errorf("proto: integer overflow")
+	ErrUnexpectedEndOfGroupLegacyTimestamp = fmt.Errorf("proto: unexpected end of group")
+)
+
diff --git a/pkg/util/hlc/legacy_timestamp.proto b/pkg/util/hlc/legacy_timestamp.proto
new file mode 100644
index 0000000..c2450ac
--- /dev/null
+++ b/pkg/util/hlc/legacy_timestamp.proto
@@ -0,0 +1,29 @@
+// Copyright 2017 The Cockroach Authors.
+//
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
+
+syntax = "proto2";
+package cockroach.util.hlc;
+option go_package = "github.com/cockroachdb/cockroach/pkg/util/hlc";
+
+import "gogoproto/gogo.proto";
+
+// LegacyTimestamp is convertible to hlc.Timestamp, but uses the
+// legacy encoding as it is encoded "below raft".
+message LegacyTimestamp {
+  option (gogoproto.equal) = true;
+
+  option (gogoproto.goproto_stringer) = false;
+  option (gogoproto.populate) = true;
+
+  // Holds a wall time, typically a unix epoch time expressed in
+  // nanoseconds.
+  optional int64 wall_time = 1 [(gogoproto.nullable) = false];
+  // The logical component captures causality for events whose wall
+  // times are equal. It is effectively bounded by (maximum clock
+  // skew)/(minimal ns between events) and nearly impossible to
+  // overflow.
+  optional int32 logical = 2 [(gogoproto.nullable) = false];
+  reserved 3;
+}
diff --git a/pkg/util/hlc/timestamp.go b/pkg/util/hlc/timestamp.go
new file mode 100644
index 0000000..aed82ab
--- /dev/null
+++ b/pkg/util/hlc/timestamp.go
@@ -0,0 +1,414 @@
+// Copyright 2014 The Cockroach Authors.
+//
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
+
+package hlc
+
+import (
+	"fmt"
+	"math"
+	"regexp"
+	"strconv"
+	"time"
+	"unsafe"
+
+	"github.com/cockroachdb/cockroachdb-parser/pkg/util/timeutil"
+	"github.com/cockroachdb/errors"
+)
+
+// Timestamp constant values.
+var (
+	// MaxTimestamp is the max value allowed for Timestamp.
+	MaxTimestamp = Timestamp{WallTime: math.MaxInt64, Logical: math.MaxInt32}
+	// MinTimestamp is the min value allowed for Timestamp.
+	MinTimestamp = Timestamp{WallTime: 0, Logical: 1}
+	// MaxClockTimestamp is the max value allowed for ClockTimestamp.
+	MaxClockTimestamp = ClockTimestamp{WallTime: math.MaxInt64, Logical: math.MaxInt32}
+	// MinClockTimestamp is the min value allowed for ClockTimestamp.
+	MinClockTimestamp = ClockTimestamp{WallTime: 0, Logical: 1}
+)
+
+// EqOrdering returns whether the receiver sorts equally to the parameter.
+//
+// This method is split from tests of structural equality (Equal and the equals
+// operator) because it does not consider differences in flags and only
+// considers whether the walltime and logical time differ between the
+// timestamps.
+//
+// TODO(nvanbenschoten): remove this method and its uses. It's now equivalent to
+// a direct struct comparison.
+func (t Timestamp) EqOrdering(s Timestamp) bool {
+	return t.WallTime == s.WallTime && t.Logical == s.Logical
+}
+
+// Less returns whether the receiver is less than the parameter.
+func (t Timestamp) Less(s Timestamp) bool {
+	return t.WallTime < s.WallTime || (t.WallTime == s.WallTime && t.Logical < s.Logical)
+}
+
+// LessEq returns whether the receiver is less than or equal to the parameter.
+func (t Timestamp) LessEq(s Timestamp) bool {
+	return t.WallTime < s.WallTime || (t.WallTime == s.WallTime && t.Logical <= s.Logical)
+}
+
+// After returns whether the provided timestamp is after our timestamp.
+// This matches the behavior of time.After.
+func (t Timestamp) After(s Timestamp) bool {
+	return !t.LessEq(s)
+}
+
+// Compare returns -1 if this timestamp is lesser than the given timestamp, 1 if
+// it is greater, and 0 if they are equal.
+func (t Timestamp) Compare(s Timestamp) int {
+	if t.WallTime > s.WallTime {
+		return 1
+	} else if t.WallTime < s.WallTime {
+		return -1
+	} else if t.Logical > s.Logical {
+		return 1
+	} else if t.Logical < s.Logical {
+		return -1
+	} else {
+		return 0
+	}
+}
+
+// String implements the fmt.Stringer interface.
+// Outputs: seconds.nanos,logical
+func (t Timestamp) String() string {
+	// The following code was originally written as
+	//   fmt.Sprintf("%d.%09d,%d", t.WallTime/1e9, t.WallTime%1e9, t.Logical).
+	// The main problem with the original code was that it would put
+	// a negative sign in the middle (after the decimal point) if
+	// the value happened to be negative.
+	buf := make([]byte, 0, 21)
+
+	w := t.WallTime
+	if w == 0 {
+		buf = append(buf, '0', ',')
+	} else {
+		if w < 0 {
+			w = -w
+			buf = append(buf, '-')
+		}
+
+		s, ns := uint64(w/1e9), uint64(w%1e9)
+		buf = strconv.AppendUint(buf, s, 10)
+
+		prev := len(buf)
+		buf = append(buf, '.', '0', '0', '0', '0', '0', '0', '0', '0', '0', ',')
+		// The following lines expand to:
+		// 		for i := 0; i < 9; i++ {
+		// 			buf[len(buf)-2-i] = byte('0' + ns%10)
+		// 			ns = ns / 10
+		// 		}
+		zeroBuf := buf[prev+1 : len(buf)-1]
+		zeroBuf[8] = byte('0' + ns%10)
+		ns = ns / 10
+		zeroBuf[7] = byte('0' + ns%10)
+		ns = ns / 10
+		zeroBuf[6] = byte('0' + ns%10)
+		ns = ns / 10
+		zeroBuf[5] = byte('0' + ns%10)
+		ns = ns / 10
+		zeroBuf[4] = byte('0' + ns%10)
+		ns = ns / 10
+		zeroBuf[3] = byte('0' + ns%10)
+		ns = ns / 10
+		zeroBuf[2] = byte('0' + ns%10)
+		ns = ns / 10
+		zeroBuf[1] = byte('0' + ns%10)
+		ns = ns / 10
+		zeroBuf[0] = byte('0' + ns%10)
+	}
+	buf = strconv.AppendInt(buf, int64(t.Logical), 10)
+	return *(*string)(unsafe.Pointer(&buf))
+}
+
+// SafeValue implements the redact.SafeValue interface.
+func (Timestamp) SafeValue() {}
+
+var (
+	timestampRegexp = regexp.MustCompile(
+		`^(?P<sign>-)?(?P<secs>\d{1,19})(?:\.(?P<nanos>\d{1,20}))?(?:,(?P<logical>-?\d{1,10}))?$`)
+	signSubexp    = 1
+	secsSubexp    = 2
+	nanosSubexp   = 3
+	logicalSubexp = 4
+)
+
+// ParseTimestamp attempts to parse the string generated from
+// Timestamp.String().
+func ParseTimestamp(str string) (_ Timestamp, err error) {
+	matches := timestampRegexp.FindStringSubmatch(str)
+	if matches == nil {
+		return Timestamp{}, errors.Errorf("failed to parse %q as Timestamp", str)
+	}
+	defer func() {
+		if err != nil {
+			err = errors.Wrapf(err, "failed to parse %q as Timestamp", str)
+		}
+	}()
+	seconds, err := strconv.ParseInt(matches[secsSubexp], 10, 64)
+	if err != nil {
+		return Timestamp{}, err
+	}
+	var nanos int64
+	if nanosMatch := matches[nanosSubexp]; nanosMatch != "" {
+		nanos, err = strconv.ParseInt(nanosMatch, 10, 64)
+		if err != nil {
+			return Timestamp{}, err
+		}
+	}
+	wallTime := seconds*time.Second.Nanoseconds() + nanos
+	if matches[signSubexp] == "-" {
+		wallTime *= -1
+	}
+	var logical int64
+	if logicalMatch := matches[logicalSubexp]; logicalMatch != "" {
+		logical, err = strconv.ParseInt(logicalMatch, 10, 32)
+		if err != nil {
+			return Timestamp{}, err
+		}
+	}
+	t := Timestamp{
+		WallTime: wallTime,
+		Logical:  int32(logical),
+	}
+	return t, nil
+}
+
+// AsOfSystemTime returns a string to be used in an AS OF SYSTEM TIME query.
+func (t Timestamp) AsOfSystemTime() string {
+	return fmt.Sprintf("%d.%010d", t.WallTime, t.Logical)
+}
+
+// IsEmpty returns true if t is an empty Timestamp.
+// gcassert:inline
+func (t Timestamp) IsEmpty() bool {
+	// TODO(radu): consider making timestamps with zero wall time and non-zero
+	// logical time illegal. Then we can check just the wall time.
+	return t == Timestamp{}
+}
+
+// IsSet returns true if t is not an empty Timestamp.
+// gcassert:inline
+func (t Timestamp) IsSet() bool {
+	return !t.IsEmpty()
+}
+
+// AddDuration adds a given duration to this Timestamp. Normally if you want to
+// bump your clock to the higher of two timestamps, use Forward, however this
+// method is here to create a hlc.Timestamp in the future (or past).
+func (t Timestamp) AddDuration(duration time.Duration) Timestamp {
+	return t.Add(duration.Nanoseconds(), 0)
+}
+
+// Add returns a timestamp with the WallTime and Logical components increased.
+// wallTime is expressed in nanos.
+func (t Timestamp) Add(wallTime int64, logical int32) Timestamp {
+	return Timestamp{
+		WallTime: t.WallTime + wallTime,
+		Logical:  t.Logical + logical,
+	}
+}
+
+// Clone return a new timestamp that has the same contents as the receiver.
+func (t Timestamp) Clone() *Timestamp {
+	return &t
+}
+
+// Next returns the timestamp with the next later timestamp.
+func (t Timestamp) Next() Timestamp {
+	if t.Logical == math.MaxInt32 {
+		if t.WallTime == math.MaxInt64 {
+			panic("cannot take the next value to a max timestamp")
+		}
+		return Timestamp{
+			WallTime: t.WallTime + 1,
+		}
+	}
+	return Timestamp{
+		WallTime: t.WallTime,
+		Logical:  t.Logical + 1,
+	}
+}
+
+// Prev returns the next earliest timestamp.
+func (t Timestamp) Prev() Timestamp {
+	if t.Logical > 0 {
+		return Timestamp{
+			WallTime: t.WallTime,
+			Logical:  t.Logical - 1,
+		}
+	} else if t.WallTime > 0 {
+		return Timestamp{
+			WallTime: t.WallTime - 1,
+			Logical:  math.MaxInt32,
+		}
+	}
+	panic("cannot take the previous value to a zero timestamp")
+}
+
+// FloorPrev returns a timestamp earlier than the current timestamp. If it
+// can subtract a logical tick without wrapping around, it does so. Otherwise
+// it subtracts a nanosecond from the walltime.
+func (t Timestamp) FloorPrev() Timestamp {
+	if t.Logical > 0 {
+		return Timestamp{
+			WallTime: t.WallTime,
+			Logical:  t.Logical - 1,
+		}
+	} else if t.WallTime > 0 {
+		return Timestamp{
+			WallTime: t.WallTime - 1,
+			Logical:  0,
+		}
+	}
+	panic("cannot take the previous value to a zero timestamp")
+}
+
+// WallNext adds 1 to the WallTime and resets Logical.
+func (t Timestamp) WallNext() Timestamp {
+	return Timestamp{
+		WallTime: t.WallTime + 1,
+		Logical:  0,
+	}
+}
+
+// WallPrev subtracts 1 from the WallTime and resets Logical.
+func (t Timestamp) WallPrev() Timestamp {
+	return Timestamp{
+		WallTime: t.WallTime - 1,
+		Logical:  0,
+	}
+}
+
+// Forward replaces the receiver with the argument, if that moves it forwards in
+// time. Returns true if the timestamp was adjusted to a larger time and false
+// otherwise.
+func (t *Timestamp) Forward(s Timestamp) bool {
+	if t.Less(s) {
+		*t = s
+		return true
+	}
+	return false
+}
+
+// Backward replaces the receiver with the argument, if that moves it backwards
+// in time.
+func (t *Timestamp) Backward(s Timestamp) {
+	if s.Less(*t) {
+		*t = s
+	}
+}
+
+// GoTime converts the timestamp to a time.Time.
+func (t Timestamp) GoTime() time.Time {
+	return timeutil.Unix(0, t.WallTime)
+}
+
+// ToLegacyTimestamp converts a Timestamp to a LegacyTimestamp.
+func (t Timestamp) ToLegacyTimestamp() LegacyTimestamp { return LegacyTimestamp(t) }
+
+// ToTimestamp converts a LegacyTimestamp to a Timestamp.
+func (t LegacyTimestamp) ToTimestamp() Timestamp { return Timestamp(t) }
+
+// Less returns whether the receiver is less than the parameter.
+func (t LegacyTimestamp) Less(s LegacyTimestamp) bool {
+	return t.ToTimestamp().Less(s.ToTimestamp())
+}
+
+// String implements the fmt.Stringer interface.
+func (t LegacyTimestamp) String() string {
+	return t.ToTimestamp().String()
+}
+
+// SafeValue implements the redact.SafeValue interface.
+func (LegacyTimestamp) SafeValue() {}
+
+// ClockTimestamp is a Timestamp with the added capability of being able to
+// update a peer's HLC clock. It possesses this capability because the clock
+// timestamp itself is guaranteed to have come from an HLC clock somewhere in
+// the system. As such, a clock timestamp is a promise that some node in the
+// system has a clock with a reading equal to or above its value.
+type ClockTimestamp Timestamp
+
+// UnsafeToClockTimestamp converts a Timestamp to a ClockTimestamp, regardless
+// of whether the timestamp actually came from a clock. The method should only
+// be used in tests.
+func (t Timestamp) UnsafeToClockTimestamp() ClockTimestamp { return ClockTimestamp(t) }
+
+// ToTimestamp upcasts a ClockTimestamp into a Timestamp.
+func (t ClockTimestamp) ToTimestamp() Timestamp { return Timestamp(t) }
+
+// Less returns whether the receiver is less than the parameter.
+func (t ClockTimestamp) Less(s ClockTimestamp) bool { return Timestamp(t).Less(Timestamp(s)) }
+
+// LessEq returns whether the receiver is less than or equal to the parameter.
+func (t ClockTimestamp) LessEq(s ClockTimestamp) bool { return Timestamp(t).LessEq(Timestamp(s)) }
+
+// Ignore unused warnings.
+var _ = ClockTimestamp.LessEq
+
+// String implements the fmt.Stringer interface.
+func (t ClockTimestamp) String() string { return t.ToTimestamp().String() }
+
+// SafeValue implements the redact.SafeValue interface.
+func (t ClockTimestamp) SafeValue() {}
+
+// IsEmpty returns true if t is an empty ClockTimestamp.
+func (t ClockTimestamp) IsEmpty() bool { return Timestamp(t).IsEmpty() }
+
+// Forward is like Timestamp.Forward, but for ClockTimestamps.
+func (t *ClockTimestamp) Forward(s ClockTimestamp) bool { return (*Timestamp)(t).Forward(Timestamp(s)) }
+
+// Backward is like Timestamp.Backward, but for ClockTimestamps.
+func (t *ClockTimestamp) Backward(s ClockTimestamp) { (*Timestamp)(t).Backward(Timestamp(s)) }
+
+// BackwardWithTimestamp is like Backward, but with a Timestamp parameter.
+func (t *ClockTimestamp) BackwardWithTimestamp(s Timestamp) { (*Timestamp)(t).Backward(s) }
+
+// Reset implements the protoutil.Message interface.
+func (t *ClockTimestamp) Reset() { (*Timestamp)(t).Reset() }
+
+// ProtoMessage implements the protoutil.Message interface.
+func (t *ClockTimestamp) ProtoMessage() {}
+
+// MarshalTo implements the protoutil.Message interface.
+func (t *ClockTimestamp) MarshalTo(data []byte) (int, error) { return (*Timestamp)(t).MarshalTo(data) }
+
+// MarshalToSizedBuffer implements the protoutil.Message interface.
+func (t *ClockTimestamp) MarshalToSizedBuffer(data []byte) (int, error) {
+	return (*Timestamp)(t).MarshalToSizedBuffer(data)
+}
+
+// Unmarshal implements the protoutil.Message interface.
+func (t *ClockTimestamp) Unmarshal(data []byte) error { return (*Timestamp)(t).Unmarshal(data) }
+
+// Size implements the protoutil.Message interface.
+func (t *ClockTimestamp) Size() int { return (*Timestamp)(t).Size() }
+
+// Equal is needed for the gogoproto.equal option.
+func (t *ClockTimestamp) Equal(that interface{}) bool {
+	switch v := that.(type) {
+	case nil:
+		return t == nil
+	case ClockTimestamp:
+		return (*Timestamp)(t).Equal((Timestamp)(v))
+	case *ClockTimestamp:
+		return (*Timestamp)(t).Equal((*Timestamp)(v))
+	default:
+		return false
+	}
+}
+
+// NewPopulatedClockTimestamp is needed for the gogoproto.populate option.
+func NewPopulatedClockTimestamp(r randyTimestamp, easy bool) *ClockTimestamp {
+	return (*ClockTimestamp)(NewPopulatedTimestamp(r, easy))
+}
+
+// Ignore unused warnings. The function is called, but by generated functions
+// that themselves are unused.
+var _ = NewPopulatedClockTimestamp
diff --git a/pkg/util/hlc/timestamp.pb.go b/pkg/util/hlc/timestamp.pb.go
new file mode 100644
index 0000000..d140295
--- /dev/null
+++ b/pkg/util/hlc/timestamp.pb.go
@@ -0,0 +1,440 @@
+// Code generated by protoc-gen-gogo. DO NOT EDIT.
+// source: util/hlc/timestamp.proto
+
+package hlc
+
+import (
+	fmt "fmt"
+	_ "github.com/gogo/protobuf/gogoproto"
+	proto "github.com/gogo/protobuf/proto"
+	io "io"
+	math "math"
+	math_bits "math/bits"
+)
+
+// Reference imports to suppress errors if they are not otherwise used.
+var _ = proto.Marshal
+var _ = fmt.Errorf
+var _ = math.Inf
+
+// This is a compile-time assertion to ensure that this generated file
+// is compatible with the proto package it is being compiled against.
+// A compilation error at this line likely means your copy of the
+// proto package needs to be updated.
+const _ = proto.GoGoProtoPackageIsVersion3 // please upgrade the proto package
+
+// Timestamp represents a state of the hybrid logical clock.
+type Timestamp struct {
+	// Holds a wall time, typically a unix epoch time expressed in
+	// nanoseconds.
+	WallTime int64 `protobuf:"varint,1,opt,name=wall_time,json=wallTime,proto3" json:"wall_time,omitempty"`
+	// The logical component captures causality for events whose wall times
+	// are equal. It is effectively bounded by (maximum clock skew)/(minimal
+	// ns between events) and nearly impossible to overflow.
+	Logical int32 `protobuf:"varint,2,opt,name=logical,proto3" json:"logical,omitempty"`
+}
+
+func (m *Timestamp) Reset()      { *m = Timestamp{} }
+func (*Timestamp) ProtoMessage() {}
+func (*Timestamp) Descriptor() ([]byte, []int) {
+	return fileDescriptor_7f15827ff64414ad, []int{0}
+}
+func (m *Timestamp) XXX_Unmarshal(b []byte) error {
+	return m.Unmarshal(b)
+}
+func (m *Timestamp) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+	b = b[:cap(b)]
+	n, err := m.MarshalToSizedBuffer(b)
+	if err != nil {
+		return nil, err
+	}
+	return b[:n], nil
+}
+func (m *Timestamp) XXX_Merge(src proto.Message) {
+	xxx_messageInfo_Timestamp.Merge(m, src)
+}
+func (m *Timestamp) XXX_Size() int {
+	return m.Size()
+}
+func (m *Timestamp) XXX_DiscardUnknown() {
+	xxx_messageInfo_Timestamp.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_Timestamp proto.InternalMessageInfo
+
+func init() {
+	proto.RegisterType((*Timestamp)(nil), "cockroach.parser.util.hlc.Timestamp")
+}
+
+func init() { proto.RegisterFile("util/hlc/timestamp.proto", fileDescriptor_7f15827ff64414ad) }
+
+var fileDescriptor_7f15827ff64414ad = []byte{
+	// 219 bytes of a gzipped FileDescriptorProto
+	0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0x92, 0x28, 0x2d, 0xc9, 0xcc,
+	0xd1, 0xcf, 0xc8, 0x49, 0xd6, 0x2f, 0xc9, 0xcc, 0x4d, 0x2d, 0x2e, 0x49, 0xcc, 0x2d, 0xd0, 0x2b,
+	0x28, 0xca, 0x2f, 0xc9, 0x17, 0x12, 0x4a, 0xce, 0x4f, 0xce, 0x2e, 0xca, 0x4f, 0x4c, 0xce, 0xd0,
+	0x03, 0xa9, 0xd1, 0xcb, 0xc8, 0x49, 0x96, 0x12, 0x49, 0xcf, 0x4f, 0xcf, 0x07, 0x4b, 0xeb, 0x83,
+	0x58, 0x10, 0x95, 0x4a, 0x61, 0x5c, 0x9c, 0x21, 0x30, 0xcd, 0x42, 0xd2, 0x5c, 0x9c, 0xe5, 0x89,
+	0x39, 0x39, 0xf1, 0x20, 0xe3, 0x24, 0x18, 0x15, 0x18, 0x35, 0x98, 0x83, 0x38, 0x40, 0x02, 0x20,
+	0x15, 0x42, 0x12, 0x5c, 0xec, 0x39, 0xf9, 0xe9, 0x99, 0xc9, 0x89, 0x39, 0x12, 0x4c, 0x0a, 0x8c,
+	0x1a, 0xac, 0x41, 0x30, 0xae, 0x15, 0xcf, 0x8c, 0x05, 0xf2, 0x0c, 0x3b, 0x16, 0xc8, 0x33, 0xbe,
+	0x58, 0x20, 0xcf, 0xe8, 0xc5, 0xc2, 0xc1, 0x2c, 0xc0, 0xe2, 0xe4, 0x7f, 0xe2, 0xa1, 0x1c, 0xc3,
+	0x89, 0x47, 0x72, 0x8c, 0x17, 0x1e, 0xc9, 0x31, 0xde, 0x78, 0x24, 0xc7, 0xf8, 0xe0, 0x91, 0x1c,
+	0xe3, 0x84, 0xc7, 0x72, 0x0c, 0x17, 0x1e, 0xcb, 0x31, 0xdc, 0x78, 0x2c, 0xc7, 0x10, 0xa5, 0x9b,
+	0x9e, 0x59, 0x92, 0x51, 0x9a, 0xa4, 0x97, 0x9c, 0x9f, 0xab, 0x0f, 0x77, 0x6e, 0x4a, 0x12, 0x82,
+	0xad, 0x5f, 0x90, 0x9d, 0xae, 0x0f, 0xf3, 0x62, 0x12, 0x1b, 0xd8, 0xbd, 0xc6, 0x80, 0x00, 0x00,
+	0x00, 0xff, 0xff, 0xca, 0x29, 0x24, 0x71, 0xf5, 0x00, 0x00, 0x00,
+}
+
+func (this *Timestamp) Equal(that interface{}) bool {
+	if that == nil {
+		return this == nil
+	}
+
+	that1, ok := that.(*Timestamp)
+	if !ok {
+		that2, ok := that.(Timestamp)
+		if ok {
+			that1 = &that2
+		} else {
+			return false
+		}
+	}
+	if that1 == nil {
+		return this == nil
+	} else if this == nil {
+		return false
+	}
+	if this.WallTime != that1.WallTime {
+		return false
+	}
+	if this.Logical != that1.Logical {
+		return false
+	}
+	return true
+}
+func (m *Timestamp) Marshal() (dAtA []byte, err error) {
+	size := m.Size()
+	dAtA = make([]byte, size)
+	n, err := m.MarshalToSizedBuffer(dAtA[:size])
+	if err != nil {
+		return nil, err
+	}
+	return dAtA[:n], nil
+}
+
+func (m *Timestamp) MarshalTo(dAtA []byte) (int, error) {
+	size := m.Size()
+	return m.MarshalToSizedBuffer(dAtA[:size])
+}
+
+func (m *Timestamp) MarshalToSizedBuffer(dAtA []byte) (int, error) {
+	i := len(dAtA)
+	_ = i
+	var l int
+	_ = l
+	if m.Logical != 0 {
+		i = encodeVarintTimestamp(dAtA, i, uint64(m.Logical))
+		i--
+		dAtA[i] = 0x10
+	}
+	if m.WallTime != 0 {
+		i = encodeVarintTimestamp(dAtA, i, uint64(m.WallTime))
+		i--
+		dAtA[i] = 0x8
+	}
+	return len(dAtA) - i, nil
+}
+
+func encodeVarintTimestamp(dAtA []byte, offset int, v uint64) int {
+	offset -= sovTimestamp(v)
+	base := offset
+	for v >= 1<<7 {
+		dAtA[offset] = uint8(v&0x7f | 0x80)
+		v >>= 7
+		offset++
+	}
+	dAtA[offset] = uint8(v)
+	return base
+}
+func NewPopulatedTimestamp(r randyTimestamp, easy bool) *Timestamp {
+	this := &Timestamp{}
+	this.WallTime = int64(r.Int63())
+	if r.Intn(2) == 0 {
+		this.WallTime *= -1
+	}
+	this.Logical = int32(r.Int31())
+	if r.Intn(2) == 0 {
+		this.Logical *= -1
+	}
+	if !easy && r.Intn(10) != 0 {
+	}
+	return this
+}
+
+type randyTimestamp interface {
+	Float32() float32
+	Float64() float64
+	Int63() int64
+	Int31() int32
+	Uint32() uint32
+	Intn(n int) int
+}
+
+func randUTF8RuneTimestamp(r randyTimestamp) rune {
+	ru := r.Intn(62)
+	if ru < 10 {
+		return rune(ru + 48)
+	} else if ru < 36 {
+		return rune(ru + 55)
+	}
+	return rune(ru + 61)
+}
+func randStringTimestamp(r randyTimestamp) string {
+	v1 := r.Intn(100)
+	tmps := make([]rune, v1)
+	for i := 0; i < v1; i++ {
+		tmps[i] = randUTF8RuneTimestamp(r)
+	}
+	return string(tmps)
+}
+func randUnrecognizedTimestamp(r randyTimestamp, maxFieldNumber int) (dAtA []byte) {
+	l := r.Intn(5)
+	for i := 0; i < l; i++ {
+		wire := r.Intn(4)
+		if wire == 3 {
+			wire = 5
+		}
+		fieldNumber := maxFieldNumber + r.Intn(100)
+		dAtA = randFieldTimestamp(dAtA, r, fieldNumber, wire)
+	}
+	return dAtA
+}
+func randFieldTimestamp(dAtA []byte, r randyTimestamp, fieldNumber int, wire int) []byte {
+	key := uint32(fieldNumber)<<3 | uint32(wire)
+	switch wire {
+	case 0:
+		dAtA = encodeVarintPopulateTimestamp(dAtA, uint64(key))
+		v2 := r.Int63()
+		if r.Intn(2) == 0 {
+			v2 *= -1
+		}
+		dAtA = encodeVarintPopulateTimestamp(dAtA, uint64(v2))
+	case 1:
+		dAtA = encodeVarintPopulateTimestamp(dAtA, uint64(key))
+		dAtA = append(dAtA, byte(r.Intn(256)), byte(r.Intn(256)), byte(r.Intn(256)), byte(r.Intn(256)), byte(r.Intn(256)), byte(r.Intn(256)), byte(r.Intn(256)), byte(r.Intn(256)))
+	case 2:
+		dAtA = encodeVarintPopulateTimestamp(dAtA, uint64(key))
+		ll := r.Intn(100)
+		dAtA = encodeVarintPopulateTimestamp(dAtA, uint64(ll))
+		for j := 0; j < ll; j++ {
+			dAtA = append(dAtA, byte(r.Intn(256)))
+		}
+	default:
+		dAtA = encodeVarintPopulateTimestamp(dAtA, uint64(key))
+		dAtA = append(dAtA, byte(r.Intn(256)), byte(r.Intn(256)), byte(r.Intn(256)), byte(r.Intn(256)))
+	}
+	return dAtA
+}
+func encodeVarintPopulateTimestamp(dAtA []byte, v uint64) []byte {
+	for v >= 1<<7 {
+		dAtA = append(dAtA, uint8(uint64(v)&0x7f|0x80))
+		v >>= 7
+	}
+	dAtA = append(dAtA, uint8(v))
+	return dAtA
+}
+func (m *Timestamp) Size() (n int) {
+	if m == nil {
+		return 0
+	}
+	var l int
+	_ = l
+	if m.WallTime != 0 {
+		n += 1 + sovTimestamp(uint64(m.WallTime))
+	}
+	if m.Logical != 0 {
+		n += 1 + sovTimestamp(uint64(m.Logical))
+	}
+	return n
+}
+
+func sovTimestamp(x uint64) (n int) {
+	return int((uint32(math_bits.Len64(x|1)+6) * 37) >> 8)
+}
+func sozTimestamp(x uint64) (n int) {
+	return sovTimestamp(uint64((x << 1) ^ uint64((int64(x) >> 63))))
+}
+func (m *Timestamp) Unmarshal(dAtA []byte) error {
+	l := len(dAtA)
+	iNdEx := 0
+	for iNdEx < l {
+		preIndex := iNdEx
+		var wire uint64
+		for shift := uint(0); ; shift += 7 {
+			if shift >= 64 {
+				return ErrIntOverflowTimestamp
+			}
+			if iNdEx >= l {
+				return io.ErrUnexpectedEOF
+			}
+			b := dAtA[iNdEx]
+			iNdEx++
+			wire |= uint64(b&0x7F) << shift
+			if b < 0x80 {
+				break
+			}
+		}
+		fieldNum := int32(wire >> 3)
+		wireType := int(wire & 0x7)
+		if wireType == 4 {
+			return fmt.Errorf("proto: Timestamp: wiretype end group for non-group")
+		}
+		if fieldNum <= 0 {
+			return fmt.Errorf("proto: Timestamp: illegal tag %d (wire type %d)", fieldNum, wire)
+		}
+		switch fieldNum {
+		case 1:
+			if wireType != 0 {
+				return fmt.Errorf("proto: wrong wireType = %d for field WallTime", wireType)
+			}
+			m.WallTime = 0
+			for shift := uint(0); ; shift += 7 {
+				if shift >= 64 {
+					return ErrIntOverflowTimestamp
+				}
+				if iNdEx >= l {
+					return io.ErrUnexpectedEOF
+				}
+				b := dAtA[iNdEx]
+				iNdEx++
+				m.WallTime |= int64(b&0x7F) << shift
+				if b < 0x80 {
+					break
+				}
+			}
+		case 2:
+			if wireType != 0 {
+				return fmt.Errorf("proto: wrong wireType = %d for field Logical", wireType)
+			}
+			m.Logical = 0
+			for shift := uint(0); ; shift += 7 {
+				if shift >= 64 {
+					return ErrIntOverflowTimestamp
+				}
+				if iNdEx >= l {
+					return io.ErrUnexpectedEOF
+				}
+				b := dAtA[iNdEx]
+				iNdEx++
+				m.Logical |= int32(b&0x7F) << shift
+				if b < 0x80 {
+					break
+				}
+			}
+		default:
+			iNdEx = preIndex
+			skippy, err := skipTimestamp(dAtA[iNdEx:])
+			if err != nil {
+				return err
+			}
+			if (skippy < 0) || (iNdEx+skippy) < 0 {
+				return ErrInvalidLengthTimestamp
+			}
+			if (iNdEx + skippy) > l {
+				return io.ErrUnexpectedEOF
+			}
+			iNdEx += skippy
+		}
+	}
+
+	if iNdEx > l {
+		return io.ErrUnexpectedEOF
+	}
+	return nil
+}
+func skipTimestamp(dAtA []byte) (n int, err error) {
+	l := len(dAtA)
+	iNdEx := 0
+	depth := 0
+	for iNdEx < l {
+		var wire uint64
+		for shift := uint(0); ; shift += 7 {
+			if shift >= 64 {
+				return 0, ErrIntOverflowTimestamp
+			}
+			if iNdEx >= l {
+				return 0, io.ErrUnexpectedEOF
+			}
+			b := dAtA[iNdEx]
+			iNdEx++
+			wire |= (uint64(b) & 0x7F) << shift
+			if b < 0x80 {
+				break
+			}
+		}
+		wireType := int(wire & 0x7)
+		switch wireType {
+		case 0:
+			for shift := uint(0); ; shift += 7 {
+				if shift >= 64 {
+					return 0, ErrIntOverflowTimestamp
+				}
+				if iNdEx >= l {
+					return 0, io.ErrUnexpectedEOF
+				}
+				iNdEx++
+				if dAtA[iNdEx-1] < 0x80 {
+					break
+				}
+			}
+		case 1:
+			iNdEx += 8
+		case 2:
+			var length int
+			for shift := uint(0); ; shift += 7 {
+				if shift >= 64 {
+					return 0, ErrIntOverflowTimestamp
+				}
+				if iNdEx >= l {
+					return 0, io.ErrUnexpectedEOF
+				}
+				b := dAtA[iNdEx]
+				iNdEx++
+				length |= (int(b) & 0x7F) << shift
+				if b < 0x80 {
+					break
+				}
+			}
+			if length < 0 {
+				return 0, ErrInvalidLengthTimestamp
+			}
+			iNdEx += length
+		case 3:
+			depth++
+		case 4:
+			if depth == 0 {
+				return 0, ErrUnexpectedEndOfGroupTimestamp
+			}
+			depth--
+		case 5:
+			iNdEx += 4
+		default:
+			return 0, fmt.Errorf("proto: illegal wireType %d", wireType)
+		}
+		if iNdEx < 0 {
+			return 0, ErrInvalidLengthTimestamp
+		}
+		if depth == 0 {
+			return iNdEx, nil
+		}
+	}
+	return 0, io.ErrUnexpectedEOF
+}
+
+var (
+	ErrInvalidLengthTimestamp        = fmt.Errorf("proto: negative length found during unmarshaling")
+	ErrIntOverflowTimestamp          = fmt.Errorf("proto: integer overflow")
+	ErrUnexpectedEndOfGroupTimestamp = fmt.Errorf("proto: unexpected end of group")
+)
+
diff --git a/pkg/util/hlc/timestamp.proto b/pkg/util/hlc/timestamp.proto
new file mode 100644
index 0000000..8b265ac
--- /dev/null
+++ b/pkg/util/hlc/timestamp.proto
@@ -0,0 +1,27 @@
+// Copyright 2014 The Cockroach Authors.
+//
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
+
+syntax = "proto3";
+package cockroach.util.hlc;
+option go_package = "github.com/cockroachdb/cockroach/pkg/util/hlc";
+
+import "gogoproto/gogo.proto";
+
+// Timestamp represents a state of the hybrid logical clock.
+message Timestamp {
+  option (gogoproto.equal) = true;
+
+  option (gogoproto.goproto_stringer) = false;
+  option (gogoproto.populate) = true;
+
+  // Holds a wall time, typically a unix epoch time expressed in
+  // nanoseconds.
+  int64 wall_time = 1;
+  // The logical component captures causality for events whose wall times
+  // are equal. It is effectively bounded by (maximum clock skew)/(minimal
+  // ns between events) and nearly impossible to overflow.
+  int32 logical = 2;
+  reserved 3;
+}
diff --git a/pkg/util/humanizeutil/count.go b/pkg/util/humanizeutil/count.go
index 6d115f2..d785215 100644
--- a/pkg/util/humanizeutil/count.go
+++ b/pkg/util/humanizeutil/count.go
@@ -1,16 +1,13 @@
 // Copyright 2020 The Cockroach Authors.
 //
-// Use of this software is governed by the Business Source License
-// included in the file licenses/BSL.txt.
-//
-// As of the Change Date specified in that file, in accordance with
-// the Business Source License, use of this software will be governed
-// by the Apache License, Version 2.0, included in the file
-// licenses/APL.txt.
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
 
 package humanizeutil
 
 import (
+	"math"
+
 	"github.com/cockroachdb/redact"
 	"github.com/dustin/go-humanize"
 )
@@ -18,5 +15,15 @@ import (
 // Count formats a unitless integer value like a row count. It uses separating
 // commas for large values (e.g. "1,000,000").
 func Count(val uint64) redact.SafeString {
+	if val > math.MaxInt64 {
+		val = math.MaxInt64
+	}
 	return redact.SafeString(humanize.Comma(int64(val)))
 }
+
+func Countf(val float64) redact.SafeString {
+	if val > math.MaxInt64 {
+		val = math.MaxInt64
+	}
+	return redact.SafeString(humanize.Commaf(val))
+}
diff --git a/pkg/util/humanizeutil/duration.go b/pkg/util/humanizeutil/duration.go
index 897c1a3..0220c14 100644
--- a/pkg/util/humanizeutil/duration.go
+++ b/pkg/util/humanizeutil/duration.go
@@ -1,12 +1,7 @@
 // Copyright 2020 The Cockroach Authors.
 //
-// Use of this software is governed by the Business Source License
-// included in the file licenses/BSL.txt.
-//
-// As of the Change Date specified in that file, in accordance with
-// the Business Source License, use of this software will be governed
-// by the Apache License, Version 2.0, included in the file
-// licenses/APL.txt.
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
 
 package humanizeutil
 
diff --git a/pkg/util/humanizeutil/humanize.go b/pkg/util/humanizeutil/humanize.go
index 2f2e041..19c64bc 100644
--- a/pkg/util/humanizeutil/humanize.go
+++ b/pkg/util/humanizeutil/humanize.go
@@ -1,12 +1,7 @@
 // Copyright 2016 The Cockroach Authors.
 //
-// Use of this software is governed by the Business Source License
-// included in the file licenses/BSL.txt.
-//
-// As of the Change Date specified in that file, in accordance with
-// the Business Source License, use of this software will be governed
-// by the Apache License, Version 2.0, included in the file
-// licenses/APL.txt.
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
 
 package humanizeutil
 
diff --git a/pkg/util/interval/btree_based_interval.go b/pkg/util/interval/btree_based_interval.go
index 8c3f6f2..7d0335e 100644
--- a/pkg/util/interval/btree_based_interval.go
+++ b/pkg/util/interval/btree_based_interval.go
@@ -1,12 +1,7 @@
 // Copyright 2016 The Cockroach Authors.
 //
-// Use of this software is governed by the Business Source License
-// included in the file licenses/BSL.txt.
-//
-// As of the Change Date specified in that file, in accordance with
-// the Business Source License, use of this software will be governed
-// by the Apache License, Version 2.0, included in the file
-// licenses/APL.txt.
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
 //
 // This code is based on: https://github.com/google/btree.
 
diff --git a/pkg/util/interval/bu23.go b/pkg/util/interval/bu23.go
index 120d518..977f35d 100644
--- a/pkg/util/interval/bu23.go
+++ b/pkg/util/interval/bu23.go
@@ -1,21 +1,15 @@
 // Copyright 2019 The Cockroach Authors.
 //
-// Use of this software is governed by the Business Source License
-// included in the file licenses/BSL.txt.
-//
-// As of the Change Date specified in that file, in accordance with
-// the Business Source License, use of this software will be governed
-// by the Apache License, Version 2.0, included in the file
-// licenses/APL.txt.
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
 
 // Copyright ©2014 The bíogo Authors. All rights reserved.
 // Use of this source code is governed by a BSD-style
-// license that can be found in licenses/BSD-biogo.txt.
+// license that can be found in licenses/BSD3-biogo.store.llrb.txt.
 
 // This code originated in the github.com/biogo/store/interval package.
 
 //go:build !td234
-// +build !td234
 
 package interval
 
diff --git a/pkg/util/interval/interval.go b/pkg/util/interval/interval.go
index 27d73c5..45fd8df 100644
--- a/pkg/util/interval/interval.go
+++ b/pkg/util/interval/interval.go
@@ -1,19 +1,14 @@
 // Copyright ©2012 The bíogo Authors. All rights reserved.
 // Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
+// license that can be found in licenses/BSD3-biogo.store.llrb.txt.
 
 // Portions of this file are additionally subject to the following
 // license and copyright.
 //
 // Copyright 2016 The Cockroach Authors.
 //
-// Use of this software is governed by the Business Source License
-// included in the file licenses/BSL.txt.
-//
-// As of the Change Date specified in that file, in accordance with
-// the Business Source License, use of this software will be governed
-// by the Apache License, Version 2.0, included in the file
-// licenses/APL.txt.
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
 
 // This code originated in the github.com/biogo/store/interval package.
 
diff --git a/pkg/util/interval/llrb_based_interval.go b/pkg/util/interval/llrb_based_interval.go
index fc8007f..59373b5 100644
--- a/pkg/util/interval/llrb_based_interval.go
+++ b/pkg/util/interval/llrb_based_interval.go
@@ -1,19 +1,14 @@
 // Copyright ©2012 The bíogo Authors. All rights reserved.
 // Use of this source code is governed by a BSD-style
-// license that can be found in licenses/BSD-biogo.txt.
+// license that can be found in licenses/BSD3-biogo.store.llrb.txt.
 
 // Portions of this file are additionally subject to the following
 // license and copyright.
 //
 // Copyright 2016 The Cockroach Authors.
 //
-// Use of this software is governed by the Business Source License
-// included in the file licenses/BSL.txt.
-//
-// As of the Change Date specified in that file, in accordance with
-// the Business Source License, use of this software will be governed
-// by the Apache License, Version 2.0, included in the file
-// licenses/APL.txt.
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
 
 // This code originated in the github.com/biogo/store/interval package.
 
diff --git a/pkg/util/interval/range_group.go b/pkg/util/interval/range_group.go
index 4e8d5f2..b95d111 100644
--- a/pkg/util/interval/range_group.go
+++ b/pkg/util/interval/range_group.go
@@ -1,12 +1,7 @@
 // Copyright 2016 The Cockroach Authors.
 //
-// Use of this software is governed by the Business Source License
-// included in the file licenses/BSL.txt.
-//
-// As of the Change Date specified in that file, in accordance with
-// the Business Source License, use of this software will be governed
-// by the Apache License, Version 2.0, included in the file
-// licenses/APL.txt.
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
 
 package interval
 
diff --git a/pkg/util/interval/td234.go b/pkg/util/interval/td234.go
index 978e74a..1ec81b2 100644
--- a/pkg/util/interval/td234.go
+++ b/pkg/util/interval/td234.go
@@ -1,21 +1,15 @@
 // Copyright 2019 The Cockroach Authors.
 //
-// Use of this software is governed by the Business Source License
-// included in the file licenses/BSL.txt.
-//
-// As of the Change Date specified in that file, in accordance with
-// the Business Source License, use of this software will be governed
-// by the Apache License, Version 2.0, included in the file
-// licenses/APL.txt.
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
 
 // Copyright ©2014 The bíogo Authors. All rights reserved.
 // Use of this source code is governed by a BSD-style
-// license that can be found in licenses/BSD-biogo.txt.
+// license that can be found in licenses/BSD3-biogo.store.llrb.txt.
 
 // This code originated in the github.com/biogo/store/interval package.
 
 //go:build td234
-// +build td234
 
 package interval
 
diff --git a/pkg/util/intsets/bitmap.go b/pkg/util/intsets/bitmap.go
index 0cd12f4..988c032 100644
--- a/pkg/util/intsets/bitmap.go
+++ b/pkg/util/intsets/bitmap.go
@@ -1,12 +1,7 @@
 // Copyright 2022 The Cockroach Authors.
 //
-// Use of this software is governed by the Business Source License
-// included in the file licenses/BSL.txt.
-//
-// As of the Change Date specified in that file, in accordance with
-// the Business Source License, use of this software will be governed
-// by the Apache License, Version 2.0, included in the file
-// licenses/APL.txt.
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
 
 package intsets
 
diff --git a/pkg/util/intsets/fast.go b/pkg/util/intsets/fast.go
index 6081642..de01a84 100644
--- a/pkg/util/intsets/fast.go
+++ b/pkg/util/intsets/fast.go
@@ -1,15 +1,9 @@
 // Copyright 2017 The Cockroach Authors.
 //
-// Use of this software is governed by the Business Source License
-// included in the file licenses/BSL.txt.
-//
-// As of the Change Date specified in that file, in accordance with
-// the Business Source License, use of this software will be governed
-// by the Apache License, Version 2.0, included in the file
-// licenses/APL.txt.
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
 
 //go:build !fast_int_set_small && !fast_int_set_large
-// +build !fast_int_set_small,!fast_int_set_large
 
 package intsets
 
@@ -19,6 +13,8 @@ import (
 	"io"
 	"math/bits"
 
+	"github.com/cockroachdb/cockroachdb-parser/pkg/util"
+	"github.com/cockroachdb/cockroachdb-parser/pkg/util/base64"
 	"github.com/cockroachdb/errors"
 )
 
@@ -306,29 +302,55 @@ func (s Fast) SubsetOf(rhs Fast) bool {
 //
 // If the set has only elements in the range [0, 63], we encode a 0 followed by
 // a 64-bit bitmap. Otherwise, we encode a length followed by each element.
+func (s *Fast) Encode(buf *bytes.Buffer) error {
+	return s.encodeImpl(buf, nil, nil)
+}
+
+// EncodeBase64 is similar to Encode. It writes the encoded set to enc. It also
+// adds each pre-base64-encoded byte to hash.
+//
+// Closures or interfaces could be used to merge both methods into one, but they
+// are intentionally avoided to prevent extra allocations of temporary buffers
+// used during encoding.
 //
 // WARNING: this is used by plan gists, so if this encoding changes,
 // explain.gistVersion needs to be bumped.
-func (s *Fast) Encode(buf *bytes.Buffer) error {
+func (s *Fast) EncodeBase64(enc *base64.Encoder, hash *util.FNV64) error {
+	return s.encodeImpl(nil, enc, hash)
+}
+
+func (s *Fast) encodeImpl(buf *bytes.Buffer, enc *base64.Encoder, hash *util.FNV64) error {
 	if s.large != nil && s.large.Min() < 0 {
 		return errors.AssertionFailedf("Encode used with negative elements")
 	}
 
+	write := func(b []byte) {
+		if buf != nil {
+			buf.Write(b)
+		} else {
+			enc.Write(b)
+			for i := range b {
+				hash.Add(uint64(b[i]))
+			}
+		}
+	}
+
 	// This slice should stay on stack. We only need enough bytes to encode a 0
 	// and then an arbitrary 64-bit integer.
 	//gcassert:noescape
 	tmp := make([]byte, binary.MaxVarintLen64+1)
 
+	var n int
 	if s.small.hi == 0 && s.fitsInSmall() {
-		n := binary.PutUvarint(tmp, 0)
+		n = binary.PutUvarint(tmp, 0)
 		n += binary.PutUvarint(tmp[n:], s.small.lo)
-		buf.Write(tmp[:n])
+		write(tmp[:n])
 	} else {
-		n := binary.PutUvarint(tmp, uint64(s.Len()))
-		buf.Write(tmp[:n])
+		n = binary.PutUvarint(tmp, uint64(s.Len()))
+		write(tmp[:n])
 		for i, ok := s.Next(0); ok; i, ok = s.Next(i + 1) {
 			n := binary.PutUvarint(tmp, uint64(i))
-			buf.Write(tmp[:n])
+			write(tmp[:n])
 		}
 	}
 	return nil
diff --git a/pkg/util/intsets/fast_large.go b/pkg/util/intsets/fast_large.go
index 456f4ef..a008ef0 100644
--- a/pkg/util/intsets/fast_large.go
+++ b/pkg/util/intsets/fast_large.go
@@ -1,15 +1,9 @@
 // Copyright 2020 The Cockroach Authors.
 //
-// Use of this software is governed by the Business Source License
-// included in the file licenses/BSL.txt.
-//
-// As of the Change Date specified in that file, in accordance with
-// the Business Source License, use of this software will be governed
-// by the Apache License, Version 2.0, included in the file
-// licenses/APL.txt.
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
 
 //go:build fast_int_set_large
-// +build fast_int_set_large
 
 package intsets
 
diff --git a/pkg/util/intsets/fast_small.go b/pkg/util/intsets/fast_small.go
index 8cc1e69..9571cfb 100644
--- a/pkg/util/intsets/fast_small.go
+++ b/pkg/util/intsets/fast_small.go
@@ -1,15 +1,9 @@
 // Copyright 2020 The Cockroach Authors.
 //
-// Use of this software is governed by the Business Source License
-// included in the file licenses/BSL.txt.
-//
-// As of the Change Date specified in that file, in accordance with
-// the Business Source License, use of this software will be governed
-// by the Apache License, Version 2.0, included in the file
-// licenses/APL.txt.
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
 
 //go:build fast_int_set_small
-// +build fast_int_set_small
 
 package intsets
 
diff --git a/pkg/util/intsets/fast_str.go b/pkg/util/intsets/fast_str.go
index 479061a..c218053 100644
--- a/pkg/util/intsets/fast_str.go
+++ b/pkg/util/intsets/fast_str.go
@@ -1,12 +1,7 @@
 // Copyright 2020 The Cockroach Authors.
 //
-// Use of this software is governed by the Business Source License
-// included in the file licenses/BSL.txt.
-//
-// As of the Change Date specified in that file, in accordance with
-// the Business Source License, use of this software will be governed
-// by the Apache License, Version 2.0, included in the file
-// licenses/APL.txt.
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
 
 package intsets
 
diff --git a/pkg/util/intsets/fast_testonly.go b/pkg/util/intsets/fast_testonly.go
index ee47f45..47a807b 100644
--- a/pkg/util/intsets/fast_testonly.go
+++ b/pkg/util/intsets/fast_testonly.go
@@ -1,15 +1,9 @@
 // Copyright 2020 The Cockroach Authors.
 //
-// Use of this software is governed by the Business Source License
-// included in the file licenses/BSL.txt.
-//
-// As of the Change Date specified in that file, in accordance with
-// the Business Source License, use of this software will be governed
-// by the Apache License, Version 2.0, included in the file
-// licenses/APL.txt.
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
 
 //go:build fast_int_set_small || fast_int_set_large
-// +build fast_int_set_small fast_int_set_large
 
 // This file implements two variants of Fast used for testing which always
 // behaves like in either the "small" or "large" case (depending on
@@ -23,6 +17,8 @@ import (
 	"encoding/binary"
 	"io"
 
+	"github.com/cockroachdb/cockroachdb-parser/pkg/util"
+	"github.com/cockroachdb/cockroachdb-parser/pkg/util/base64"
 	"github.com/cockroachdb/errors"
 )
 
@@ -224,10 +220,24 @@ func (s Fast) SubsetOf(rhs Fast) bool {
 //
 // If the set has only elements in the range [0, 63], we encode a 0 followed by
 // a 64-bit bitmap. Otherwise, we encode a length followed by each element.
+func (s *Fast) Encode(buf *bytes.Buffer) error {
+	return s.encodeImpl(buf, nil, nil)
+}
+
+// EncodeBase64 is similar to Encode. It writes the encoded set to enc. It also
+// adds each pre-base64-encoded byte to hash.
+//
+// Closures or interfaces could be used to merge both methods into one, but they
+// are intentionally avoided to prevent extra allocations of temporary buffers
+// used during encoding.
 //
 // WARNING: this is used by plan gists, so if this encoding changes,
 // explain.gistVersion needs to be bumped.
-func (s *Fast) Encode(buf *bytes.Buffer) error {
+func (s *Fast) EncodeBase64(enc *base64.Encoder, hash *util.FNV64) error {
+	return s.encodeImpl(nil, enc, hash)
+}
+
+func (s *Fast) encodeImpl(buf *bytes.Buffer, enc *base64.Encoder, hash *util.FNV64) error {
 	if s.s != nil && s.s.Min() < 0 {
 		return errors.AssertionFailedf("Encode used with negative elements")
 	}
@@ -237,6 +247,17 @@ func (s *Fast) Encode(buf *bytes.Buffer) error {
 	//gcassert:noescape
 	tmp := make([]byte, binary.MaxVarintLen64+1)
 
+	write := func(b []byte) {
+		if buf != nil {
+			buf.Write(b)
+		} else {
+			enc.Write(b)
+			for i := range b {
+				hash.Add(uint64(b[i]))
+			}
+		}
+	}
+
 	max := MinInt
 	s.ForEach(func(i int) {
 		if i > max {
@@ -251,13 +272,13 @@ func (s *Fast) Encode(buf *bytes.Buffer) error {
 			bitmap |= (1 << uint64(i))
 		}
 		n += binary.PutUvarint(tmp[n:], bitmap)
-		buf.Write(tmp[:n])
+		write(tmp[:n])
 	} else {
 		n := binary.PutUvarint(tmp, uint64(s.Len()))
-		buf.Write(tmp[:n])
+		write(tmp[:n])
 		for i, ok := s.Next(0); ok; i, ok = s.Next(i + 1) {
 			n := binary.PutUvarint(tmp, uint64(i))
-			buf.Write(tmp[:n])
+			write(tmp[:n])
 		}
 	}
 	return nil
diff --git a/pkg/util/intsets/oracle.go b/pkg/util/intsets/oracle.go
index 62fdb45..cb136c0 100644
--- a/pkg/util/intsets/oracle.go
+++ b/pkg/util/intsets/oracle.go
@@ -1,12 +1,7 @@
 // Copyright 2022 The Cockroach Authors.
 //
-// Use of this software is governed by the Business Source License
-// included in the file licenses/BSL.txt.
-//
-// As of the Change Date specified in that file, in accordance with
-// the Business Source License, use of this software will be governed
-// by the Apache License, Version 2.0, included in the file
-// licenses/APL.txt.
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
 
 package intsets
 
diff --git a/pkg/util/intsets/sparse.go b/pkg/util/intsets/sparse.go
index d0280f7..4710498 100644
--- a/pkg/util/intsets/sparse.go
+++ b/pkg/util/intsets/sparse.go
@@ -1,12 +1,7 @@
 // Copyright 2022 The Cockroach Authors.
 //
-// Use of this software is governed by the Business Source License
-// included in the file licenses/BSL.txt.
-//
-// As of the Change Date specified in that file, in accordance with
-// the Business Source License, use of this software will be governed
-// by the Apache License, Version 2.0, included in the file
-// licenses/APL.txt.
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
 
 package intsets
 
diff --git a/pkg/util/ipaddr/ip.go b/pkg/util/ipaddr/ip.go
index 340acc0..7d0800c 100644
--- a/pkg/util/ipaddr/ip.go
+++ b/pkg/util/ipaddr/ip.go
@@ -1,12 +1,7 @@
 // Copyright 2021 The Cockroach Authors.
 //
-// Use of this software is governed by the Business Source License
-// included in the file licenses/BSL.txt.
-//
-// As of the Change Date specified in that file, in accordance with
-// the Business Source License, use of this software will be governed
-// by the Apache License, Version 2.0, included in the file
-// licenses/APL.txt.
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
 
 // Copyright 2009 The Go Authors. All rights reserved.
 // Use of this source code is governed by a BSD-style
diff --git a/pkg/util/ipaddr/ipaddr.go b/pkg/util/ipaddr/ipaddr.go
index 60795d5..b098fbb 100644
--- a/pkg/util/ipaddr/ipaddr.go
+++ b/pkg/util/ipaddr/ipaddr.go
@@ -1,12 +1,7 @@
 // Copyright 2017 The Cockroach Authors.
 //
-// Use of this software is governed by the Business Source License
-// included in the file licenses/BSL.txt.
-//
-// As of the Change Date specified in that file, in accordance with
-// the Business Source License, use of this software will be governed
-// by the Apache License, Version 2.0, included in the file
-// licenses/APL.txt.
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
 
 package ipaddr
 
diff --git a/pkg/util/iterutil/iterutil.go b/pkg/util/iterutil/iterutil.go
index 3936fe2..6d400d6 100644
--- a/pkg/util/iterutil/iterutil.go
+++ b/pkg/util/iterutil/iterutil.go
@@ -1,16 +1,15 @@
 // Copyright 2020 The Cockroach Authors.
 //
-// Use of this software is governed by the Business Source License
-// included in the file licenses/BSL.txt.
-//
-// As of the Change Date specified in that file, in accordance with
-// the Business Source License, use of this software will be governed
-// by the Apache License, Version 2.0, included in the file
-// licenses/APL.txt.
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
 
 package iterutil
 
-import "github.com/cockroachdb/errors"
+import (
+	"iter"
+
+	"github.com/cockroachdb/errors"
+)
 
 var errStopIteration = errors.New("stop iteration")
 
@@ -41,3 +40,41 @@ func Map(err error) error {
 	}
 	return err
 }
+
+// Enumerate takes an iter.Seq and returns an iter.Seq2 where the first value
+// is an int counter.
+func Enumerate[E any](seq iter.Seq[E]) iter.Seq2[int, E] {
+	return func(yield func(int, E) bool) {
+		var i int
+		for v := range seq {
+			if !yield(i, v) {
+				return
+			}
+			i++
+		}
+	}
+}
+
+// Keys takes an iter.Seq2 and returns an iter.Seq that iterates over the
+// first value in each pair of values.
+func Keys[K, V any](seq iter.Seq2[K, V]) iter.Seq[K] {
+	return func(yield func(K) bool) {
+		for k := range seq {
+			if !yield(k) {
+				return
+			}
+		}
+	}
+}
+
+// MinFunc returns the minimum element in seq, using cmp to compare elements.
+// If seq has no values, the zero value is returned.
+func MinFunc[E any](seq iter.Seq[E], cmp func(E, E) int) E {
+	var m E
+	for i, v := range Enumerate(seq) {
+		if i == 0 || cmp(v, m) < 0 {
+			m = v
+		}
+	}
+	return m
+}
diff --git a/pkg/util/json/config.go b/pkg/util/json/config.go
index 461ce40..7bb4a50 100644
--- a/pkg/util/json/config.go
+++ b/pkg/util/json/config.go
@@ -1,17 +1,12 @@
 // Copyright 2022 The Cockroach Authors.
 //
-// Use of this software is governed by the Business Source License
-// included in the file licenses/BSL.txt.
-//
-// As of the Change Date specified in that file, in accordance with
-// the Business Source License, use of this software will be governed
-// by the Apache License, Version 2.0, included in the file
-// licenses/APL.txt.
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
 
 package json
 
 import (
-	"github.com/cockroachdb/cockroachdb-parser/pkg/util"
+	"github.com/cockroachdb/cockroachdb-parser/pkg/util/metamorphic"
 	"github.com/cockroachdb/errors"
 )
 
@@ -67,9 +62,9 @@ const (
 
 // default configuration for parsing JSON.
 var parseJSONDefaultConfig = func() (cfg parseConfig) {
-	cfg.impl = util.ConstantWithMetamorphicTestChoice(
+	cfg.impl = metamorphic.ConstantWithTestChoice(
 		"parse-json-impl", useFastJSONParser, useStdGoJSON,
-	).(parseJSONImplType)
+	)
 	return cfg
 }()
 
diff --git a/pkg/util/json/contains.go b/pkg/util/json/contains.go
index 4d7abde..5ff00aa 100644
--- a/pkg/util/json/contains.go
+++ b/pkg/util/json/contains.go
@@ -1,12 +1,7 @@
 // Copyright 2017 The Cockroach Authors.
 //
-// Use of this software is governed by the Business Source License
-// included in the file licenses/BSL.txt.
-//
-// As of the Change Date specified in that file, in accordance with
-// the Business Source License, use of this software will be governed
-// by the Apache License, Version 2.0, included in the file
-// licenses/APL.txt.
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
 
 package json
 
diff --git a/pkg/util/json/contains_testers.go b/pkg/util/json/contains_testers.go
index ec2ac65..ad93f53 100644
--- a/pkg/util/json/contains_testers.go
+++ b/pkg/util/json/contains_testers.go
@@ -1,12 +1,7 @@
 // Copyright 2017 The Cockroach Authors.
 //
-// Use of this software is governed by the Business Source License
-// included in the file licenses/BSL.txt.
-//
-// As of the Change Date specified in that file, in accordance with
-// the Business Source License, use of this software will be governed
-// by the Apache License, Version 2.0, included in the file
-// licenses/APL.txt.
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
 
 // This file contains (ha!) helpers to test @>.
 
diff --git a/pkg/util/json/encode.go b/pkg/util/json/encode.go
index 1d9df80..878ca02 100644
--- a/pkg/util/json/encode.go
+++ b/pkg/util/json/encode.go
@@ -1,12 +1,7 @@
 // Copyright 2017 The Cockroach Authors.
 //
-// Use of this software is governed by the Business Source License
-// included in the file licenses/BSL.txt.
-//
-// As of the Change Date specified in that file, in accordance with
-// the Business Source License, use of this software will be governed
-// by the Apache License, Version 2.0, included in the file
-// licenses/APL.txt.
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
 
 package json
 
@@ -262,17 +257,14 @@ func decodeJSONObject(containerHeader uint32, b []byte) ([]byte, JSON, error) {
 	result := make(jsonObject, length)
 	// Decode the keys.
 	for i := 0; i < length; i++ {
-		var nextJSON JSON
-		b, nextJSON, err = decodeJSONValue(keyJEntries[i], b)
-		if err != nil {
-			return b, nil, err
-		}
-		if key, ok := nextJSON.(jsonString); ok {
-			result[i].k = key
-		} else {
+		e := keyJEntries[i]
+		if e.typCode != stringTag {
 			return b, nil, errors.AssertionFailedf(
-				"key encoded as non-string: %T", nextJSON)
+				"key encoded as non-string: %d", errors.Safe(e.typCode))
 		}
+		// Inline string decoding from decodeJSONValue. This avoids the cost to pass
+		// through a JSON interface.
+		b, result[i].k = b[e.length:], jsonString(b[:e.length])
 	}
 
 	// Decode the values.
@@ -287,10 +279,10 @@ func decodeJSONObject(containerHeader uint32, b []byte) ([]byte, JSON, error) {
 	return b, result, nil
 }
 
-func decodeJSONNumber(b []byte) ([]byte, JSON, error) {
+func decodeJSONNumber(b []byte) ([]byte, jsonNumber, error) {
 	b, d, err := encoding.DecodeUntaggedDecimalValue(b)
 	if err != nil {
-		return b, nil, err
+		return b, jsonNumber{}, err
 	}
 	return b, jsonNumber(d), nil
 }
diff --git a/pkg/util/json/encoded.go b/pkg/util/json/encoded.go
index 8782366..88e3d1b 100644
--- a/pkg/util/json/encoded.go
+++ b/pkg/util/json/encoded.go
@@ -1,18 +1,12 @@
 // Copyright 2017 The Cockroach Authors.
 //
-// Use of this software is governed by the Business Source License
-// included in the file licenses/BSL.txt.
-//
-// As of the Change Date specified in that file, in accordance with
-// the Business Source License, use of this software will be governed
-// by the Apache License, Version 2.0, included in the file
-// licenses/APL.txt.
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
 
 package json
 
 import (
 	"bytes"
-	"fmt"
 	"sort"
 	"strconv"
 	"unsafe"
@@ -595,17 +589,6 @@ func (j *jsonEncoded) AsArray() ([]JSON, bool) {
 	return decoded.AsArray()
 }
 
-func (j *jsonEncoded) AreKeysSorted() bool {
-	if dec := j.alreadyDecoded(); dec != nil {
-		return dec.AreKeysSorted()
-	}
-	decoded, err := j.decode()
-	if err != nil {
-		return false
-	}
-	return decoded.AreKeysSorted()
-}
-
 func (j *jsonEncoded) Compare(other JSON) (_ int, err error) {
 	if other == nil {
 		return -1, nil
@@ -697,15 +680,6 @@ func (j *jsonEncoded) FetchValKeyOrIdx(key string) (JSON, error) {
 	return nil, nil
 }
 
-func (j *jsonEncoded) Format(buf *bytes.Buffer) {
-	decoded, err := j.decode()
-	if err != nil {
-		fmt.Fprintf(buf, `<corrupt JSON data: %s>`, err.Error())
-	} else {
-		decoded.Format(buf)
-	}
-}
-
 // RemoveIndex implements the JSON interface.
 func (j *jsonEncoded) RemoveIndex(idx int) (JSON, bool, error) {
 	decoded, err := j.shallowDecode()
@@ -823,12 +797,12 @@ func (j *jsonEncoded) numInvertedIndexEntries() (int, error) {
 	return decoded.numInvertedIndexEntries()
 }
 
-func (j *jsonEncoded) allPaths() ([]JSON, error) {
+func (j *jsonEncoded) allPathsWithDepth(depth int) ([]JSON, error) {
 	decoded, err := j.decode()
 	if err != nil {
 		return nil, err
 	}
-	return decoded.allPaths()
+	return decoded.allPathsWithDepth(depth)
 }
 
 // HasContainerLeaf implements the JSON interface.
diff --git a/pkg/util/json/encoded_format.go b/pkg/util/json/encoded_format.go
new file mode 100644
index 0000000..63a6aef
--- /dev/null
+++ b/pkg/util/json/encoded_format.go
@@ -0,0 +1,221 @@
+// Copyright 2024 The Cockroach Authors.
+//
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
+
+package json
+
+import (
+	"bytes"
+	"fmt"
+
+	"github.com/cockroachdb/cockroachdb-parser/pkg/util/encoding"
+	"github.com/cockroachdb/errors"
+)
+
+func (j *jsonEncoded) Format(buf *bytes.Buffer) {
+	// We don't know exactly how big the JSON string will be when decoded and
+	// formatted, but we can make a reasonable guess based on the size of the
+	// encoded data. This can avoid some buffer reallocations in the common case.
+	buf.Grow(len(j.value))
+	preLen := buf.Len()
+	err := j.format(buf)
+	if err != nil {
+		buf.Truncate(preLen)
+		fmt.Fprintf(buf, `<corrupt JSON data: %s>`, err.Error())
+	}
+}
+
+func (j *jsonEncoded) format(buf *bytes.Buffer) error {
+	switch j.typ {
+	case NumberJSONType:
+		_, d, err := decodeJSONNumber(j.value)
+		if err != nil {
+			return err
+		}
+		d.Format(buf)
+	case StringJSONType:
+		s := unsafeJSONString(j.value)
+		s.Format(buf)
+	case TrueJSONType:
+		TrueJSONValue.Format(buf)
+	case FalseJSONType:
+		FalseJSONValue.Format(buf)
+	case NullJSONType:
+		NullJSONValue.Format(buf)
+	default:
+		_, err := formatEncodedJSON(buf, j.value)
+		if err != nil {
+			return err
+		}
+	}
+	return nil
+}
+
+func formatEncodedJSON(buf *bytes.Buffer, b []byte) ([]byte, error) {
+	b, containerHeader, err := encoding.DecodeUint32Ascending(b)
+	if err != nil {
+		return nil, err
+	}
+	switch containerHeader & containerHeaderTypeMask {
+	case scalarContainerTag:
+		var entry jEntry
+		var err error
+		b, entry, err = decodeJEntry(b, 0)
+		if err != nil {
+			return nil, err
+		}
+		return formatEncodedJSONValue(buf, entry, b)
+	case arrayContainerTag:
+		return formatEncodedJSONArray(buf, containerHeader, b)
+	case objectContainerTag:
+		return formatEncodedJSONObject(buf, containerHeader, b)
+	default:
+		return nil, errors.AssertionFailedf(
+			"error decoding JSON value, header: %x", errors.Safe(containerHeader))
+	}
+}
+
+func formatEncodedJSONArray(buf *bytes.Buffer, containerHeader uint32, b []byte) ([]byte, error) {
+	length := int(containerHeader & containerHeaderLenMask)
+
+	// There are `length` JEntries in the array.
+	entOff, valOff := uint32(0), uint32(0)
+	entB, valB := b, b
+	// Skip past the JEntries to find the first value, permitting parallel
+	// iteration through the JEntries and values below.
+	var err error
+	for i := 0; i < length; i++ {
+		// Decode and ignore.
+		var ent jEntry
+		valB, ent, err = decodeJEntry(valB, valOff)
+		if err != nil {
+			return nil, err
+		}
+		valOff += ent.length
+	}
+
+	buf.WriteByte('[')
+	for i := 0; i < length; i++ {
+		if i != 0 {
+			buf.WriteString(", ")
+		}
+		var ent jEntry
+		var err error
+		entB, ent, err = decodeJEntry(entB, entOff)
+		if err != nil {
+			return nil, err
+		}
+		entOff += ent.length
+		valB, err = formatEncodedJSONValue(buf, ent, valB)
+		if err != nil {
+			return nil, err
+		}
+	}
+	buf.WriteByte(']')
+	return valB, nil
+}
+
+func formatEncodedJSONObject(buf *bytes.Buffer, containerHeader uint32, b []byte) ([]byte, error) {
+	length := int(containerHeader & containerHeaderLenMask)
+
+	// There are `length` key JEntries and then `length` value JEntries in the
+	// object.
+	keyOff, valOff := uint32(0), uint32(0)
+	keyEntB, valEntB := b, b
+	// Skip past the key JEntries to find the first value JEntry, permitting
+	// parallel iteration through the key JEntries, value JEntries, keys, and
+	// values below.
+	var err error
+	for i := 0; i < length; i++ {
+		// Decode (and ignore) key JEntry.
+		var keyEnt jEntry
+		valEntB, keyEnt, err = decodeJEntry(valEntB, valOff)
+		if err != nil {
+			return nil, err
+		}
+		if keyEnt.typCode != stringTag {
+			return nil, errors.AssertionFailedf(
+				"key encoded as non-string: %d", errors.Safe(keyEnt.typCode))
+		}
+		valOff += keyEnt.length
+	}
+	// Skip past the value JEntries to find the first key.
+	valEntsSize := jEntrySize * length
+	if len(valEntB) < valEntsSize {
+		return nil, errors.AssertionFailedf("insufficient data to skip JSON object value JEntries")
+	}
+	keyB := valEntB[valEntsSize:]
+	// Skip past the keys to find the first value.
+	if len(keyB) < int(valOff) {
+		return nil, errors.AssertionFailedf("insufficient data to skip JSON object keys")
+	}
+	valB := keyB[valOff:]
+
+	// Iterate through the keys and values in parallel, formatting them.
+	buf.WriteByte('{')
+	for i := 0; i < length; i++ {
+		if i != 0 {
+			buf.WriteString(", ")
+		}
+		// Decode key JEntry i.
+		var keyEnt jEntry
+		keyEntB, keyEnt, err = decodeJEntry(keyEntB, keyOff)
+		if err != nil {
+			return nil, err
+		}
+		keyOff += keyEnt.length
+		// Decode value JEntry i.
+		var valEnt jEntry
+		valEntB, valEnt, err = decodeJEntry(valEntB, valOff)
+		if err != nil {
+			return nil, err
+		}
+		valOff += valEnt.length
+		// Decode and format key i.
+		keyS := unsafeJSONString(keyB[:keyEnt.length])
+		keyS.Format(buf)
+		keyB = keyB[keyEnt.length:]
+		buf.WriteString(": ")
+		// Decode and format value i.
+		valB, err = formatEncodedJSONValue(buf, valEnt, valB)
+		if err != nil {
+			return nil, err
+		}
+	}
+	buf.WriteByte('}')
+	return valB, nil
+}
+
+func formatEncodedJSONValue(buf *bytes.Buffer, e jEntry, b []byte) ([]byte, error) {
+	switch e.typCode {
+	case trueTag:
+		TrueJSONValue.Format(buf)
+	case falseTag:
+		FalseJSONValue.Format(buf)
+	case nullTag:
+		NullJSONValue.Format(buf)
+	case stringTag:
+		s := unsafeJSONString(b[:e.length])
+		s.Format(buf)
+		b = b[e.length:]
+	case numberTag:
+		var d jsonNumber
+		var err error
+		b, d, err = decodeJSONNumber(b)
+		if err != nil {
+			return nil, err
+		}
+		d.Format(buf)
+	case containerTag:
+		return formatEncodedJSON(buf, b)
+	default:
+		return nil, errors.AssertionFailedf(
+			"error decoding JSON value, unexpected type code: %d", errors.Safe(e.typCode))
+	}
+	return b, nil
+}
+
+func unsafeJSONString(b []byte) jsonString {
+	return jsonString(encoding.UnsafeConvertBytesToString(b))
+}
diff --git a/pkg/util/json/fuzz.go b/pkg/util/json/fuzz.go
index bd34a62..3e4d4ec 100644
--- a/pkg/util/json/fuzz.go
+++ b/pkg/util/json/fuzz.go
@@ -1,15 +1,9 @@
 // Copyright 2019 The Cockroach Authors.
 //
-// Use of this software is governed by the Business Source License
-// included in the file licenses/BSL.txt.
-//
-// As of the Change Date specified in that file, in accordance with
-// the Business Source License, use of this software will be governed
-// by the Apache License, Version 2.0, included in the file
-// licenses/APL.txt.
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
 
 //go:build gofuzz
-// +build gofuzz
 
 package json
 
diff --git a/pkg/util/json/iterator.go b/pkg/util/json/iterator.go
index c661661..a19ec2f 100644
--- a/pkg/util/json/iterator.go
+++ b/pkg/util/json/iterator.go
@@ -1,12 +1,7 @@
 // Copyright 2017 The Cockroach Authors.
 //
-// Use of this software is governed by the Business Source License
-// included in the file licenses/BSL.txt.
-//
-// As of the Change Date specified in that file, in accordance with
-// the Business Source License, use of this software will be governed
-// by the Apache License, Version 2.0, included in the file
-// licenses/APL.txt.
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
 
 package json
 
diff --git a/pkg/util/json/jentry.go b/pkg/util/json/jentry.go
index 0cb8598..db9629e 100644
--- a/pkg/util/json/jentry.go
+++ b/pkg/util/json/jentry.go
@@ -1,12 +1,7 @@
 // Copyright 2017 The Cockroach Authors.
 //
-// Use of this software is governed by the Business Source License
-// included in the file licenses/BSL.txt.
-//
-// As of the Change Date specified in that file, in accordance with
-// the Business Source License, use of this software will be governed
-// by the Apache License, Version 2.0, included in the file
-// licenses/APL.txt.
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
 
 package json
 
@@ -23,6 +18,8 @@ const jEntryIsOffFlag = 0x80000000
 const jEntryTypeMask = 0x70000000
 const jEntryOffLenMask = 0x0FFFFFFF
 
+const jEntrySize = 4
+
 // jEntry is a header for a particular JSON value. See the JSONB encoding RFC
 // for an explanation of its purpose and format:
 // https://github.com/cockroachdb/cockroachdb-parser/blob/master/docs/RFCS/20171005_jsonb_encoding.md
diff --git a/pkg/util/json/json.go b/pkg/util/json/json.go
index b78f0b5..51d1e9c 100644
--- a/pkg/util/json/json.go
+++ b/pkg/util/json/json.go
@@ -1,12 +1,7 @@
 // Copyright 2017 The Cockroach Authors.
 //
-// Use of this software is governed by the Business Source License
-// included in the file licenses/BSL.txt.
-//
-// As of the Change Date specified in that file, in accordance with
-// the Business Source License, use of this software will be governed
-// by the Apache License, Version 2.0, included in the file
-// licenses/APL.txt.
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
 
 package json
 
@@ -15,8 +10,10 @@ import (
 	"encoding/json"
 	"fmt"
 	"io"
+	"maps"
 	"math/big"
 	"reflect"
+	"slices"
 	"sort"
 	"strconv"
 	"strings"
@@ -24,16 +21,14 @@ import (
 	"unsafe"
 
 	"github.com/cockroachdb/apd/v3"
-	"github.com/cockroachdb/cockroachdb-parser/pkg/geo"
-	"github.com/cockroachdb/cockroachdb-parser/pkg/geo/geopb"
 	"github.com/cockroachdb/cockroachdb-parser/pkg/keysbase"
 	"github.com/cockroachdb/cockroachdb-parser/pkg/sql/inverted"
 	"github.com/cockroachdb/cockroachdb-parser/pkg/sql/pgwire/pgcode"
 	"github.com/cockroachdb/cockroachdb-parser/pkg/sql/pgwire/pgerror"
 	"github.com/cockroachdb/cockroachdb-parser/pkg/util/buildutil"
+	"github.com/cockroachdb/cockroachdb-parser/pkg/util/deduplicate"
 	"github.com/cockroachdb/cockroachdb-parser/pkg/util/encoding"
 	"github.com/cockroachdb/cockroachdb-parser/pkg/util/intsets"
-	uniq "github.com/cockroachdb/cockroachdb-parser/pkg/util/unique"
 	"github.com/cockroachdb/errors"
 )
 
@@ -143,10 +138,12 @@ type JSON interface {
 	// produced if this JSON gets included in an inverted index.
 	numInvertedIndexEntries() (int, error)
 
-	// allPaths returns a slice of new JSON documents, each a path to a leaf
-	// through the receiver. Note that leaves include the empty object and array
-	// in addition to scalars.
-	allPaths() ([]JSON, error)
+	// allPathsWithDepth returns a slice of new JSON documents, each a path
+	// through the receiver. The depth parameter specifies the maximum depth of
+	// the paths to return. If the depth is negative, all paths of any depth are
+	// returned. If the depth is 0, the receiver itself is returned. Note that
+	// leaves include the empty object and array in addition to scalars.
+	allPathsWithDepth(depth int) ([]JSON, error)
 
 	// FetchValKey implements the `->` operator for strings, returning nil if the
 	// key is not found.
@@ -192,11 +189,6 @@ type JSON interface {
 	// and a boolean indicating if this JSON value is a array type.
 	AsArray() ([]JSON, bool)
 
-	// AreKeysSorted returns if the keys in a JSON Object are sorted by
-	// increasing order. It returns false if the underlying JSON value
-	// is not a JSON object.
-	AreKeysSorted() bool
-
 	// Exists implements the `?` operator: does the string exist as a top-level
 	// key within the JSON value?
 	//
@@ -246,6 +238,8 @@ type JSON interface {
 	HasContainerLeaf() (bool, error)
 }
 
+var EmptyJSONValue = NewObjectBuilder(0).Build()
+
 type jsonTrue struct{}
 
 // TrueJSONValue is JSON `true`
@@ -468,6 +462,78 @@ func (b *FixedKeysObjectBuilder) Build() (JSON, error) {
 	return jsonObject(append([]jsonKeyValuePair(nil), b.pairs...)), nil
 }
 
+// PartialObject is a JSON object builder that builds an object using a set of
+// fixed key-values (supplied at construction) and a set of keys which are
+// settable when building the final JSON object.
+type PartialObject struct {
+	basePairs      []jsonKeyValuePair
+	keyOrd         map[string]int
+	allowedNewKeys map[string]struct{}
+}
+
+// NewPartialObject creates a PartialObject with the specified base key-value
+// pairs, and allows for setting the values of newKeys when building the final
+// JSON object.
+func NewPartialObject(base map[string]JSON, newKeys []string) (*PartialObject, error) {
+	// Check that newKeys are unique and disjoint from base keys.
+	newKeySet := make(map[string]struct{}, len(newKeys))
+	for _, k := range newKeys {
+		if _, ok := newKeySet[k]; ok {
+			return nil, errors.AssertionFailedf("expected unique keys, found %v", newKeys)
+		}
+		if _, ok := base[k]; ok {
+			return nil, errors.AssertionFailedf("expected new keys to be disjoint from base keys, found %v in both", k)
+		}
+		newKeySet[k] = struct{}{}
+	}
+
+	keys := slices.Collect(maps.Keys(base))
+	keys = append(keys, newKeys...)
+	sort.Strings(keys)
+
+	pairs := make([]jsonKeyValuePair, 0, len(base))
+	keyOrd := make(map[string]int, len(keys))
+
+	for i, k := range keys {
+		keyOrd[k] = i
+		if _, ok := base[k]; !ok {
+			continue
+		}
+		pairs = append(pairs, jsonKeyValuePair{k: jsonString(k), v: base[k]})
+	}
+
+	return &PartialObject{basePairs: pairs, keyOrd: keyOrd, allowedNewKeys: newKeySet}, nil
+}
+
+// NewObject creates a new JSON object with the specified new key-values. The
+// keys of newData must be exactly the same as the newKeys supplied to the
+// constructor.
+func (po *PartialObject) NewObject(newData map[string]JSON) (JSON, error) {
+	if len(newData) != len(po.allowedNewKeys) {
+		return nil, errors.AssertionFailedf(
+			"expected all %d keys to be updated, %d updated",
+			len(po.allowedNewKeys), len(newData))
+	}
+
+	pairs := make([]jsonKeyValuePair, len(po.basePairs)+len(newData))
+
+	for _, p := range po.basePairs {
+		pairs[po.keyOrd[string(p.k)]] = p
+	}
+
+	for k, v := range newData {
+		if _, ok := po.allowedNewKeys[k]; !ok {
+			return nil, errors.AssertionFailedf("unknown new key %s", k)
+		}
+		if _, ok := po.keyOrd[k]; !ok {
+			return nil, errors.AssertionFailedf("unknown key %s", k)
+		}
+		pairs[po.keyOrd[k]] = jsonKeyValuePair{k: jsonString(k), v: v}
+	}
+
+	return jsonObject(pairs), nil
+}
+
 // pairSorter sorts and uniqueifies JSON pairs. In order to keep
 // the last one for pairs with the same key while sort.Sort is
 // not stable, pairSorter uses []int orders to maintain order and
@@ -784,6 +850,7 @@ const hexAlphabet = "0123456789abcdef"
 // encodeJSONString writes a string literal to buf as a JSON string.
 // Cribbed from https://github.com/golang/go/blob/7badae85f20f1bce4cc344f9202447618d45d414/src/encoding/json/encode.go.
 func encodeJSONString(buf *bytes.Buffer, s string) {
+	buf.Grow(len(s) + 2)
 	buf.WriteByte('"')
 	start := 0
 	for i := 0; i < len(s); {
@@ -927,38 +994,6 @@ func (j jsonNumber) AsArray() ([]JSON, bool) {
 	return nil, false
 }
 
-func (j jsonNull) AreKeysSorted() bool {
-	return false
-}
-
-func (j jsonString) AreKeysSorted() bool {
-	return false
-}
-
-func (j jsonFalse) AreKeysSorted() bool {
-	return false
-}
-
-func (j jsonTrue) AreKeysSorted() bool {
-	return false
-}
-
-func (j jsonNumber) AreKeysSorted() bool {
-	return false
-}
-
-func (j jsonArray) AreKeysSorted() bool {
-	return false
-}
-
-func (j jsonObject) AreKeysSorted() bool {
-	keys := make([]string, 0, j.Len())
-	for _, a := range j {
-		keys = append(keys, a.k.String())
-	}
-	return sort.StringsAreSorted(keys)
-}
-
 // parseJSONGoStd parses json using encoding/json library.
 // TODO(yevgeniy): Remove this code once we get more confidence in lexer implementation.
 func parseJSONGoStd(s string, _ parseConfig) (JSON, error) {
@@ -1010,6 +1045,19 @@ func ParseJSON(s string, opts ...ParseOption) (JSON, error) {
 	return cfg.parseJSON(s)
 }
 
+func init() {
+	encoding.PrettyPrintJSONValueEncoded = func(b []byte) (string, error) {
+		rem, j, err := DecodeJSON(b)
+		if err != nil {
+			return "", err
+		}
+		if len(rem) != 0 {
+			return "", errors.Newf("unexpected remainder after decoding JSON: %v", rem)
+		}
+		return j.String(), nil
+	}
+}
+
 // EncodeInvertedIndexKeys takes in a key prefix and returns a slice of inverted index keys,
 // one per unique path through the receiver.
 func EncodeInvertedIndexKeys(b []byte, json JSON) ([][]byte, error) {
@@ -1229,7 +1277,7 @@ func (j jsonArray) encodeInvertedIndexKeys(b []byte) ([][]byte, error) {
 	// to emit duplicate keys from this method, as it's more expensive to
 	// deduplicate keys via KV (which will actually write the keys) than to do
 	// it now (just an in-memory sort and distinct).
-	outKeys = uniq.UniquifyByteSlices(outKeys)
+	outKeys = deduplicate.ByteSlices(outKeys)
 	return outKeys, nil
 }
 
@@ -1747,36 +1795,51 @@ func (j jsonObject) numInvertedIndexEntries() (int, error) {
 // through the input. Note that leaves include the empty object and array
 // in addition to scalars.
 func AllPaths(j JSON) ([]JSON, error) {
-	return j.allPaths()
+	return j.allPathsWithDepth(-1)
 }
 
-func (j jsonNull) allPaths() ([]JSON, error) {
+// AllPathsWithDepth returns a slice of new JSON documents, each a path
+// through the receiver. The depth parameter specifies the maximum depth of
+// the paths to return. If the depth is negative, all paths of any depth are
+// returned. If the depth is 0, the receiver itself is returned. Note that
+// leaves include the empty object and array in addition to scalars.
+func AllPathsWithDepth(j JSON, depth int) ([]JSON, error) {
+	return j.allPathsWithDepth(depth)
+}
+
+func (j jsonNull) allPathsWithDepth(depth int) ([]JSON, error) {
 	return []JSON{j}, nil
 }
 
-func (j jsonTrue) allPaths() ([]JSON, error) {
+func (j jsonTrue) allPathsWithDepth(depth int) ([]JSON, error) {
 	return []JSON{j}, nil
 }
 
-func (j jsonFalse) allPaths() ([]JSON, error) {
+func (j jsonFalse) allPathsWithDepth(depth int) ([]JSON, error) {
 	return []JSON{j}, nil
 }
 
-func (j jsonString) allPaths() ([]JSON, error) {
+func (j jsonString) allPathsWithDepth(depth int) ([]JSON, error) {
 	return []JSON{j}, nil
 }
 
-func (j jsonNumber) allPaths() ([]JSON, error) {
+func (j jsonNumber) allPathsWithDepth(depth int) ([]JSON, error) {
 	return []JSON{j}, nil
 }
 
-func (j jsonArray) allPaths() ([]JSON, error) {
-	if len(j) == 0 {
+func (j jsonArray) allPathsWithDepth(depth int) ([]JSON, error) {
+	if len(j) == 0 || depth == 0 {
 		return []JSON{j}, nil
 	}
 	ret := make([]JSON, 0, len(j))
 	for i := range j {
-		paths, err := j[i].allPaths()
+		var paths []JSON
+		var err error
+		if depth > 0 {
+			paths, err = j[i].allPathsWithDepth(depth - 1)
+		} else {
+			paths, err = j[i].allPathsWithDepth(depth)
+		}
 		if err != nil {
 			return nil, err
 		}
@@ -1787,13 +1850,19 @@ func (j jsonArray) allPaths() ([]JSON, error) {
 	return ret, nil
 }
 
-func (j jsonObject) allPaths() ([]JSON, error) {
-	if len(j) == 0 {
+func (j jsonObject) allPathsWithDepth(depth int) ([]JSON, error) {
+	if len(j) == 0 || depth == 0 {
 		return []JSON{j}, nil
 	}
 	ret := make([]JSON, 0, len(j))
 	for i := range j {
-		paths, err := j[i].v.allPaths()
+		var paths []JSON
+		var err error
+		if depth > 0 {
+			paths, err = j[i].v.allPathsWithDepth(depth - 1)
+		} else {
+			paths, err = j[i].v.allPathsWithDepth(depth)
+		}
 		if err != nil {
 			return nil, err
 		}
@@ -1804,15 +1873,6 @@ func (j jsonObject) allPaths() ([]JSON, error) {
 	return ret, nil
 }
 
-// FromSpatialObject transforms a SpatialObject into the json.JSON type.
-func FromSpatialObject(so geopb.SpatialObject, numDecimalDigits int) (JSON, error) {
-	j, err := geo.SpatialObjectToGeoJSON(so, numDecimalDigits, geo.SpatialObjectToGeoJSONFlagZero)
-	if err != nil {
-		return nil, err
-	}
-	return ParseJSON(string(j))
-}
-
 // FromDecimal returns a JSON value given a apd.Decimal.
 func FromDecimal(v apd.Decimal) JSON {
 	return jsonNumber(v)
@@ -2033,7 +2093,11 @@ func (j jsonObject) EncodeForwardIndex(buf []byte, dir encoding.Direction) ([]by
 	buf = encoding.EncodeJSONValueLength(buf, dir, int64(len(j)))
 
 	if buildutil.CrdbTestBuild {
-		if ordered := j.AreKeysSorted(); !ordered {
+		keys := make([]string, 0, j.Len())
+		for _, a := range j {
+			keys = append(keys, string(a.k))
+		}
+		if !sort.StringsAreSorted(keys) {
 			return nil, errors.AssertionFailedf("unexpectedly unordered keys in jsonObject %s", j)
 		}
 	}
diff --git a/pkg/util/json/parser.go b/pkg/util/json/parser.go
index 3192d9a..33fb428 100644
--- a/pkg/util/json/parser.go
+++ b/pkg/util/json/parser.go
@@ -1,12 +1,7 @@
 // Copyright 2022 The Cockroach Authors.
 //
-// Use of this software is governed by the Business Source License
-// included in the file licenses/BSL.txt.
-//
-// As of the Change Date specified in that file, in accordance with
-// the Business Source License, use of this software will be governed
-// by the Apache License, Version 2.0, included in the file
-// licenses/APL.txt.
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
 
 package json
 
@@ -14,7 +9,6 @@ import (
 	"bytes"
 	"encoding/json"
 	"io"
-	"reflect"
 	"strings"
 	"unsafe"
 
@@ -331,7 +325,6 @@ func decodeErrorContext(err error, s string, pos int) error {
 // This unsafe mechanism is safe to use here because, ultimately, every
 // JSON object produced from those bytes will copy those bytes anyway
 // (i.e. jsonString([]byte)).
-// See https://groups.google.com/g/golang-nuts/c/Zsfk-VMd_fU/m/O1ru4fO-BgAJ
 func unsafeGetBytes(s string) ([]byte, error) {
 	const maxStrLen = 1 << 30 // Really, can't see us supporting input JSONs that big.
 	if len(s) > maxStrLen {
@@ -340,7 +333,6 @@ func unsafeGetBytes(s string) ([]byte, error) {
 	if len(s) == 0 {
 		return nil, nil
 	}
-	//lint:ignore SA1019 StringHeader is deprecated, but no clear replacement
-	p := unsafe.Pointer((*reflect.StringHeader)(unsafe.Pointer(&s)).Data)
-	return (*[maxStrLen]byte)(p)[:len(s):len(s)], nil
+
+	return unsafe.Slice(unsafe.StringData(s), len(s)), nil
 }
diff --git a/pkg/util/json/random.go b/pkg/util/json/random.go
index 0345543..03fdb45 100644
--- a/pkg/util/json/random.go
+++ b/pkg/util/json/random.go
@@ -1,12 +1,7 @@
 // Copyright 2017 The Cockroach Authors.
 //
-// Use of this software is governed by the Business Source License
-// included in the file licenses/BSL.txt.
-//
-// As of the Change Date specified in that file, in accordance with
-// the Business Source License, use of this software will be governed
-// by the Apache License, Version 2.0, included in the file
-// licenses/APL.txt.
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
 
 package json
 
@@ -306,7 +301,7 @@ func (j *errJSON) Format(buf *bytes.Buffer) {
 		t.Format(buf)
 		if j.injectErr() {
 			// Drop terminating quote.
-			buf.Truncate(1)
+			buf.Truncate(buf.Len() - 1)
 		}
 	case jsonNumber:
 		if j.injectErr() {
diff --git a/pkg/util/json/tables.go b/pkg/util/json/tables.go
index 9e536ce..79db1aa 100644
--- a/pkg/util/json/tables.go
+++ b/pkg/util/json/tables.go
@@ -1,12 +1,7 @@
 // Copyright 2019 The Cockroach Authors.
 //
-// Use of this software is governed by the Business Source License
-// included in the file licenses/BSL.txt.
-//
-// As of the Change Date specified in that file, in accordance with
-// the Business Source License, use of this software will be governed
-// by the Apache License, Version 2.0, included in the file
-// licenses/APL.txt.
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
 
 // Copyright 2016 The Go Authors. All rights reserved.
 // Use of this source code is governed by a BSD-style
diff --git a/pkg/util/json/tokenizer/buffer.go b/pkg/util/json/tokenizer/buffer.go
index b61829b..ba466f9 100644
--- a/pkg/util/json/tokenizer/buffer.go
+++ b/pkg/util/json/tokenizer/buffer.go
@@ -1,12 +1,7 @@
 // Copyright 2022 The Cockroach Authors.
 //
-// Use of this software is governed by the Business Source License
-// included in the file licenses/BSL.txt.
-//
-// As of the Change Date specified in that file, in accordance with
-// the Business Source License, use of this software will be governed
-// by the Apache License, Version 2.0, included in the file
-// licenses/APL.txt.
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
 
 package tokenizer
 
diff --git a/pkg/util/json/tokenizer/decoder.go b/pkg/util/json/tokenizer/decoder.go
index a97634b..ea428f0 100644
--- a/pkg/util/json/tokenizer/decoder.go
+++ b/pkg/util/json/tokenizer/decoder.go
@@ -1,12 +1,7 @@
 // Copyright 2022 The Cockroach Authors.
 //
-// Use of this software is governed by the Business Source License
-// included in the file licenses/BSL.txt.
-//
-// As of the Change Date specified in that file, in accordance with
-// the Business Source License, use of this software will be governed
-// by the Apache License, Version 2.0, included in the file
-// licenses/APL.txt.
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
 
 // This is a fork of pkg/json package.
 
diff --git a/pkg/util/json/tokenizer/scanner.go b/pkg/util/json/tokenizer/scanner.go
index 83c0a87..14a9d30 100644
--- a/pkg/util/json/tokenizer/scanner.go
+++ b/pkg/util/json/tokenizer/scanner.go
@@ -1,12 +1,7 @@
 // Copyright 2022 The Cockroach Authors.
 //
-// Use of this software is governed by the Business Source License
-// included in the file licenses/BSL.txt.
-//
-// As of the Change Date specified in that file, in accordance with
-// the Business Source License, use of this software will be governed
-// by the Apache License, Version 2.0, included in the file
-// licenses/APL.txt.
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
 
 // This is a fork of pkg/json package.
 
diff --git a/pkg/util/jsonbytes/jsonbytes.go b/pkg/util/jsonbytes/jsonbytes.go
index c978b2c..5f46011 100644
--- a/pkg/util/jsonbytes/jsonbytes.go
+++ b/pkg/util/jsonbytes/jsonbytes.go
@@ -1,12 +1,7 @@
 // Copyright 2020 The Cockroach Authors.
 //
-// Use of this software is governed by the Business Source License
-// included in the file licenses/BSL.txt.
-//
-// As of the Change Date specified in that file, in accordance with
-// the Business Source License, use of this software will be governed
-// by the Apache License, Version 2.0, included in the file
-// licenses/APL.txt.
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
 
 package jsonbytes
 
diff --git a/pkg/util/jsonpath/jsonpath.go b/pkg/util/jsonpath/jsonpath.go
new file mode 100644
index 0000000..e11be39
--- /dev/null
+++ b/pkg/util/jsonpath/jsonpath.go
@@ -0,0 +1,28 @@
+// Copyright 2025 The Cockroach Authors.
+//
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
+
+package jsonpath
+
+import "strings"
+
+type Jsonpath struct {
+	Strict bool
+	Path   Path
+}
+
+func (j Jsonpath) String() string {
+	var sb strings.Builder
+	if j.Strict {
+		sb.WriteString("strict ")
+	}
+	j.Path.ToString(&sb, false /* inKey */, true /* printBrackets */)
+	return sb.String()
+}
+
+// Validate walks the Jsonpath AST. It returns an error if the AST is invalid
+// (last not in array subscripts, @ in root expressions).
+func (j Jsonpath) Validate() error {
+	return j.Path.Validate(0 /* nestingLevel */, false /* insideArraySubscript */)
+}
diff --git a/pkg/util/jsonpath/method.go b/pkg/util/jsonpath/method.go
new file mode 100644
index 0000000..62ab71e
--- /dev/null
+++ b/pkg/util/jsonpath/method.go
@@ -0,0 +1,51 @@
+// Copyright 2025 The Cockroach Authors.
+//
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
+
+package jsonpath
+
+import (
+	"fmt"
+	"strings"
+
+	"github.com/cockroachdb/errors"
+)
+
+type MethodType int
+
+const (
+	InvalidMethod MethodType = iota
+	SizeMethod
+	TypeMethod
+	AbsMethod
+	FloorMethod
+	CeilingMethod
+)
+
+var MethodTypeStrings = [...]string{
+	SizeMethod:    "size",
+	TypeMethod:    "type",
+	AbsMethod:     "abs",
+	FloorMethod:   "floor",
+	CeilingMethod: "ceiling",
+}
+
+type Method struct {
+	Type MethodType
+}
+
+var _ Path = Method{}
+
+func (m Method) ToString(sb *strings.Builder, _, _ bool) {
+	switch m.Type {
+	case SizeMethod, TypeMethod, AbsMethod, FloorMethod, CeilingMethod:
+		sb.WriteString(fmt.Sprintf(".%s()", MethodTypeStrings[m.Type]))
+	default:
+		panic(errors.AssertionFailedf("unhandled method type: %d", m.Type))
+	}
+}
+
+func (m Method) Validate(nestingLevel int, insideArraySubscript bool) error {
+	return nil
+}
diff --git a/pkg/util/jsonpath/operation.go b/pkg/util/jsonpath/operation.go
new file mode 100644
index 0000000..b4f2f23
--- /dev/null
+++ b/pkg/util/jsonpath/operation.go
@@ -0,0 +1,149 @@
+// Copyright 2025 The Cockroach Authors.
+//
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
+
+package jsonpath
+
+import (
+	"strings"
+
+	"github.com/cockroachdb/errors"
+)
+
+type OperationType int
+
+const (
+	OpInvalid OperationType = iota
+	OpCompEqual
+	OpCompNotEqual
+	OpCompLess
+	OpCompLessEqual
+	OpCompGreater
+	OpCompGreaterEqual
+	OpLogicalAnd
+	OpLogicalOr
+	OpLogicalNot
+	OpAdd
+	OpSub
+	OpMult
+	OpDiv
+	OpMod
+	OpLikeRegex
+	OpPlus
+	OpMinus
+	OpExists
+	OpIsUnknown
+	OpStartsWith
+)
+
+var OperationTypeStrings = [...]string{
+	OpCompEqual:        "==",
+	OpCompNotEqual:     "!=",
+	OpCompLess:         "<",
+	OpCompLessEqual:    "<=",
+	OpCompGreater:      ">",
+	OpCompGreaterEqual: ">=",
+	OpLogicalAnd:       "&&",
+	OpLogicalOr:        "||",
+	OpLogicalNot:       "!",
+	OpAdd:              "+",
+	OpSub:              "-",
+	OpMult:             "*",
+	OpDiv:              "/",
+	OpMod:              "%",
+	OpLikeRegex:        "like_regex",
+	OpPlus:             "+",
+	OpMinus:            "-",
+	OpExists:           "exists",
+	OpIsUnknown:        "is unknown",
+	OpStartsWith:       "starts with",
+}
+
+type Operation struct {
+	Type  OperationType
+	Left  Path
+	Right Path
+}
+
+var _ Path = Operation{}
+
+func (o Operation) ToString(sb *strings.Builder, _, printBrackets bool) {
+	switch o.Type {
+	case OpCompEqual, OpCompNotEqual, OpCompLess, OpCompLessEqual,
+		OpCompGreater, OpCompGreaterEqual, OpLogicalAnd, OpLogicalOr, OpAdd,
+		OpSub, OpMult, OpDiv, OpMod, OpStartsWith, OpLikeRegex:
+		if printBrackets {
+			sb.WriteString("(")
+			defer sb.WriteString(")")
+		}
+		o.Left.ToString(sb, false /* inKey */, opPriority(o.Left) <= opPriority(o))
+		sb.WriteString(" ")
+		sb.WriteString(OperationTypeStrings[o.Type])
+		sb.WriteString(" ")
+		o.Right.ToString(sb, false /* inKey */, opPriority(o.Right) <= opPriority(o))
+		return
+	case OpLogicalNot:
+		sb.WriteString("!(")
+		o.Left.ToString(sb, false /* inKey */, false /* printBrackets */)
+		sb.WriteString(")")
+		return
+	case OpPlus, OpMinus:
+		if printBrackets {
+			sb.WriteString("(")
+			defer sb.WriteString(")")
+		}
+		sb.WriteString(OperationTypeStrings[o.Type])
+		o.Left.ToString(sb, false /* inKey */, opPriority(o.Left) <= opPriority(o))
+		return
+	case OpExists:
+		sb.WriteString("exists (")
+		o.Left.ToString(sb, false /* inKey */, false /* printBrackets */)
+		sb.WriteString(")")
+		return
+	case OpIsUnknown:
+		sb.WriteString("(")
+		o.Left.ToString(sb, false /* inKey */, false /* printBrackets */)
+		sb.WriteString(") is unknown")
+		return
+	default:
+		panic(errors.AssertionFailedf("unhandled operation type: %d", o.Type))
+	}
+}
+
+func (o Operation) Validate(nestingLevel int, insideArraySubscript bool) error {
+	if err := o.Left.Validate(nestingLevel, insideArraySubscript); err != nil {
+		return err
+	}
+	if o.Right != nil {
+		if err := o.Right.Validate(nestingLevel, insideArraySubscript); err != nil {
+			return err
+		}
+	}
+	return nil
+}
+
+func opPriority(path Path) int {
+	switch path := path.(type) {
+	case Operation:
+		switch path.Type {
+		case OpLogicalOr:
+			return 0
+		case OpLogicalAnd:
+			return 1
+		case OpCompEqual, OpCompNotEqual, OpCompLess, OpCompLessEqual,
+			OpCompGreater, OpCompGreaterEqual, OpStartsWith:
+			return 2
+		case OpAdd, OpSub:
+			return 3
+		case OpMult, OpDiv, OpMod:
+			return 4
+		case OpPlus, OpMinus:
+			return 5
+		default:
+			return 6
+		}
+	default:
+		return 6
+	}
+}
diff --git a/pkg/util/jsonpath/parser/.gitignore b/pkg/util/jsonpath/parser/.gitignore
new file mode 100644
index 0000000..ce0ba7b
--- /dev/null
+++ b/pkg/util/jsonpath/parser/.gitignore
@@ -0,0 +1 @@
+jsonpath.go
diff --git a/pkg/util/jsonpath/parser/jsonpath.go b/pkg/util/jsonpath/parser/jsonpath.go
new file mode 100644
index 0000000..bf5d5a3
--- /dev/null
+++ b/pkg/util/jsonpath/parser/jsonpath.go
@@ -0,0 +1,1524 @@
+// Code generated by goyacc -p jsonpath -o bazel-out/darwin_arm64-fastbuild/bin/pkg/util/jsonpath/parser/jsonpath.go jsonpath-gen.y. DO NOT EDIT.
+
+//line jsonpath-gen.y:2
+package parser
+
+import __yyfmt__ "fmt"
+
+//line jsonpath-gen.y:2
+
+import (
+	"strconv"
+
+	"github.com/cockroachdb/cockroachdb-parser/pkg/sql/pgwire/pgcode"
+	"github.com/cockroachdb/cockroachdb-parser/pkg/sql/pgwire/pgerror"
+	"github.com/cockroachdb/cockroachdb-parser/pkg/sql/scanner"
+	"github.com/cockroachdb/cockroachdb-parser/pkg/sql/sem/tree"
+	"github.com/cockroachdb/cockroachdb-parser/pkg/util/json"
+	"github.com/cockroachdb/cockroachdb-parser/pkg/util/jsonpath"
+)
+
+//line jsonpath-gen.y:18
+
+func setErr(jsonpathlex jsonpathLexer, err error) int {
+	jsonpathlex.(*lexer).setErr(err)
+	return 1
+}
+
+func unimplemented(jsonpathlex jsonpathLexer, feature string) int {
+	jsonpathlex.(*lexer).Unimplemented(feature)
+	return 1
+}
+
+var _ scanner.ScanSymType = &jsonpathSymType{}
+
+func (s *jsonpathSymType) jsonpathScanSymType() {}
+
+func (s *jsonpathSymType) ID() int32 {
+	return s.id
+}
+
+func (s *jsonpathSymType) SetID(id int32) {
+	s.id = id
+}
+
+func (s *jsonpathSymType) Pos() int32 {
+	return s.pos
+}
+
+func (s *jsonpathSymType) SetPos(pos int32) {
+	s.pos = pos
+}
+
+func (s *jsonpathSymType) Str() string {
+	return s.str
+}
+
+func (s *jsonpathSymType) SetStr(str string) {
+	s.str = str
+}
+
+func (s *jsonpathSymType) UnionVal() interface{} {
+	return s.union.val
+}
+
+func (s *jsonpathSymType) SetUnionVal(val interface{}) {
+	s.union.val = val
+}
+
+type jsonpathSymUnion struct {
+	val interface{}
+}
+
+func (u *jsonpathSymUnion) jsonpath() jsonpath.Jsonpath {
+	return u.val.(jsonpath.Jsonpath)
+}
+
+func (u *jsonpathSymUnion) path() jsonpath.Path {
+	return u.val.(jsonpath.Path)
+}
+
+func (u *jsonpathSymUnion) paths() jsonpath.Paths {
+	return u.val.(jsonpath.Paths)
+}
+
+func (u *jsonpathSymUnion) pathArr() []jsonpath.Path {
+	return u.val.([]jsonpath.Path)
+}
+
+func (u *jsonpathSymUnion) bool() bool {
+	return u.val.(bool)
+}
+
+func (u *jsonpathSymUnion) numVal() *tree.NumVal {
+	return u.val.(*tree.NumVal)
+}
+
+func (u *jsonpathSymUnion) arrayList() jsonpath.ArrayList {
+	return u.val.(jsonpath.ArrayList)
+}
+
+func (u *jsonpathSymUnion) operationType() jsonpath.OperationType {
+	return u.val.(jsonpath.OperationType)
+}
+
+//line jsonpath-gen.y:112
+
+func binaryOp(op jsonpath.OperationType, left jsonpath.Path, right jsonpath.Path) jsonpath.Operation {
+	return jsonpath.Operation{
+		Type:  op,
+		Left:  left,
+		Right: right,
+	}
+}
+
+func unaryOp(op jsonpath.OperationType, left jsonpath.Path) jsonpath.Path {
+	if scalar, ok := maybeNormalizeUnaryOp(op, left); ok {
+		return scalar
+	}
+	return jsonpath.Operation{
+		Type:  op,
+		Left:  left,
+		Right: nil,
+	}
+}
+
+func maybeNormalizeUnaryOp(op jsonpath.OperationType, expr jsonpath.Path) (jsonpath.Scalar, bool) {
+
+	if op != jsonpath.OpPlus && op != jsonpath.OpMinus {
+		return jsonpath.Scalar{}, false
+	}
+
+	scalar, ok := extractNumericScalar(expr)
+	if !ok {
+		return jsonpath.Scalar{}, false
+	}
+	if op == jsonpath.OpMinus {
+		dec, _ := scalar.Value.AsDecimal()
+		dec.Neg(dec)
+		scalar.Value = json.FromDecimal(*dec)
+	}
+	return scalar, true
+}
+
+func extractNumericScalar(expr jsonpath.Path) (jsonpath.Scalar, bool) {
+	potentialScalar := expr
+	if paths, ok := expr.(jsonpath.Paths); ok {
+		if len(paths) != 1 {
+			return jsonpath.Scalar{}, false
+		}
+		potentialScalar = paths[0]
+	}
+	scalar, ok := potentialScalar.(jsonpath.Scalar)
+	if !ok {
+		return jsonpath.Scalar{}, false
+	}
+	if scalar.Type != jsonpath.ScalarFloat && scalar.Type != jsonpath.ScalarInt {
+		return jsonpath.Scalar{}, false
+	}
+	return scalar, true
+}
+
+func regexBinaryOp(left jsonpath.Path, regex string, flags string) (jsonpath.Operation, error) {
+	goFlags, err := jsonpath.RegexFlagsToGoFlags(flags)
+	if err != nil {
+		return jsonpath.Operation{}, err
+	}
+	r := jsonpath.Regex{Regex: regex, Flags: goFlags}
+	_, err = ReCache.GetRegexpWithFlags(r, goFlags)
+	if err != nil {
+		return jsonpath.Operation{}, pgerror.Wrapf(err, pgcode.InvalidRegularExpression,
+			"invalid regular expression")
+	}
+	return binaryOp(jsonpath.OpLikeRegex, left, r), nil
+}
+
+//line jsonpath-gen.y:190
+type jsonpathSymType struct {
+	yys   int
+	id    int32
+	pos   int32
+	str   string
+	union jsonpathSymUnion
+}
+
+const IDENT = 57346
+const UIDENT = 57347
+const FCONST = 57348
+const SCONST = 57349
+const USCONST = 57350
+const BCONST = 57351
+const XCONST = 57352
+const Op = 57353
+const ICONST = 57354
+const PARAM = 57355
+const TYPECAST = 57356
+const DOT_DOT = 57357
+const COLON_EQUALS = 57358
+const EQUALS_GREATER = 57359
+const LESS_EQUALS = 57360
+const GREATER_EQUALS = 57361
+const NOT_EQUALS = 57362
+const ERROR = 57363
+const STRICT = 57364
+const LAX = 57365
+const ROOT = 57366
+const CURRENT = 57367
+const VARIABLE = 57368
+const STR = 57369
+const NULL = 57370
+const TRUE = 57371
+const FALSE = 57372
+const EQUAL = 57373
+const NOT_EQUAL = 57374
+const LESS = 57375
+const LESS_EQUAL = 57376
+const GREATER = 57377
+const GREATER_EQUAL = 57378
+const AND = 57379
+const OR = 57380
+const NOT = 57381
+const LIKE_REGEX = 57382
+const FLAG = 57383
+const TO = 57384
+const LAST = 57385
+const EXISTS = 57386
+const IS = 57387
+const UNKNOWN = 57388
+const STARTS = 57389
+const WITH = 57390
+const ANY = 57391
+const SIZE = 57392
+const TYPE = 57393
+const KEYVALUE = 57394
+const ABS = 57395
+const CEILING = 57396
+const FLOOR = 57397
+const BIGINT = 57398
+const BOOLEAN = 57399
+const DATE = 57400
+const DOUBLE = 57401
+const INTEGER = 57402
+const NUMBER = 57403
+const STRING = 57404
+const DECIMAL = 57405
+const DATETIME = 57406
+const TIME = 57407
+const TIME_TZ = 57408
+const TIMESTAMP = 57409
+const TIMESTAMP_TZ = 57410
+const UMINUS = 57411
+
+var jsonpathToknames = [...]string{
+	"$end",
+	"error",
+	"$unk",
+	"IDENT",
+	"UIDENT",
+	"FCONST",
+	"SCONST",
+	"USCONST",
+	"BCONST",
+	"XCONST",
+	"Op",
+	"ICONST",
+	"PARAM",
+	"TYPECAST",
+	"DOT_DOT",
+	"COLON_EQUALS",
+	"EQUALS_GREATER",
+	"LESS_EQUALS",
+	"GREATER_EQUALS",
+	"NOT_EQUALS",
+	"ERROR",
+	"STRICT",
+	"LAX",
+	"ROOT",
+	"CURRENT",
+	"VARIABLE",
+	"STR",
+	"NULL",
+	"TRUE",
+	"FALSE",
+	"EQUAL",
+	"NOT_EQUAL",
+	"LESS",
+	"LESS_EQUAL",
+	"GREATER",
+	"GREATER_EQUAL",
+	"AND",
+	"OR",
+	"NOT",
+	"LIKE_REGEX",
+	"FLAG",
+	"TO",
+	"LAST",
+	"EXISTS",
+	"IS",
+	"UNKNOWN",
+	"STARTS",
+	"WITH",
+	"ANY",
+	"SIZE",
+	"TYPE",
+	"KEYVALUE",
+	"ABS",
+	"CEILING",
+	"FLOOR",
+	"BIGINT",
+	"BOOLEAN",
+	"DATE",
+	"DOUBLE",
+	"INTEGER",
+	"NUMBER",
+	"STRING",
+	"DECIMAL",
+	"DATETIME",
+	"TIME",
+	"TIME_TZ",
+	"TIMESTAMP",
+	"TIMESTAMP_TZ",
+	"'+'",
+	"'-'",
+	"'*'",
+	"'/'",
+	"'%'",
+	"UMINUS",
+	"'('",
+	"')'",
+	"'.'",
+	"'?'",
+	"'['",
+	"']'",
+	"','",
+	"'{'",
+	"'}'",
+}
+
+var jsonpathStatenames = [...]string{}
+
+const jsonpathEofCode = 1
+const jsonpathErrCode = 2
+const jsonpathInitialStackSize = 16
+
+//line jsonpath-gen.y:804
+
+//line yacctab:1
+var jsonpathExca = [...]int16{
+	-1, 1,
+	1, -1,
+	-2, 0,
+	-1, 78,
+	75, 63,
+	-2, 124,
+	-1, 79,
+	75, 64,
+	-2, 134,
+	-1, 80,
+	75, 65,
+	-2, 118,
+	-1, 81,
+	75, 66,
+	-2, 104,
+	-1, 82,
+	75, 67,
+	-2, 107,
+	-1, 83,
+	75, 68,
+	-2, 115,
+	-1, 84,
+	75, 69,
+	-2, 105,
+	-1, 85,
+	75, 70,
+	-2, 106,
+	-1, 86,
+	75, 71,
+	-2, 108,
+	-1, 87,
+	75, 72,
+	-2, 111,
+	-1, 88,
+	75, 73,
+	-2, 116,
+	-1, 89,
+	75, 74,
+	-2, 123,
+	-1, 90,
+	75, 75,
+	-2, 127,
+}
+
+const jsonpathPrivate = 57344
+
+const jsonpathLast = 252
+
+var jsonpathAct = [...]uint8{
+	160, 147, 65, 154, 113, 6, 138, 177, 180, 7,
+	134, 135, 48, 50, 52, 43, 131, 168, 133, 49,
+	44, 46, 47, 139, 175, 174, 41, 42, 173, 172,
+	56, 57, 58, 59, 60, 61, 171, 35, 36, 37,
+	38, 39, 40, 167, 93, 144, 34, 130, 176, 129,
+	114, 64, 66, 33, 48, 44, 46, 47, 119, 128,
+	127, 117, 105, 101, 118, 163, 126, 94, 103, 107,
+	97, 41, 42, 125, 124, 27, 28, 29, 30, 31,
+	102, 98, 106, 100, 96, 99, 108, 104, 109, 91,
+	78, 79, 80, 81, 82, 83, 84, 85, 86, 87,
+	88, 89, 90, 71, 72, 73, 74, 75, 76, 62,
+	141, 68, 35, 36, 37, 38, 39, 40, 15, 110,
+	132, 34, 137, 22, 29, 30, 31, 55, 33, 21,
+	166, 123, 157, 158, 159, 41, 42, 161, 114, 165,
+	164, 16, 17, 20, 25, 26, 23, 24, 41, 54,
+	27, 28, 29, 30, 31, 153, 13, 115, 143, 148,
+	19, 15, 27, 28, 29, 30, 31, 63, 162, 142,
+	178, 41, 42, 170, 140, 22, 41, 42, 179, 155,
+	136, 21, 22, 122, 121, 169, 10, 11, 21, 3,
+	4, 156, 9, 16, 17, 20, 25, 26, 23, 24,
+	16, 17, 20, 25, 26, 23, 24, 27, 28, 29,
+	30, 31, 19, 12, 152, 116, 149, 150, 146, 19,
+	27, 28, 29, 30, 31, 151, 145, 53, 70, 2,
+	95, 92, 77, 32, 112, 8, 69, 120, 10, 11,
+	111, 18, 45, 67, 51, 10, 11, 14, 5, 1,
+	0, 51,
+}
+
+var jsonpathPact = [...]int16{
+	167, -1000, 117, -1000, -1000, -1000, 6, 134, -57, 117,
+	176, 176, -1000, 74, -1000, 52, -1000, -1000, -1000, -1000,
+	-1000, -1000, -1000, -1000, -1000, -1000, -1000, 176, 176, 176,
+	176, 176, 176, 61, 140, -1000, -1000, -1000, -1000, -1000,
+	-1000, 117, 117, -1000, 40, -1000, 44, 169, 81, 139,
+	-1000, 117, -1000, -1000, 117, 176, 53, 53, -1000, -1000,
+	-1000, 151, 157, 90, -1000, 6, 111, -1000, -1000, -1,
+	-1000, -2, -9, -15, -16, -26, -28, -1000, -1000, -1000,
+	-1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000,
+	-1000, -66, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000,
+	-1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000,
+	117, -62, -70, -1000, 138, -57, -22, 98, 34, 93,
+	-1000, -1000, -1000, 131, -31, 147, 128, 179, 179, 179,
+	179, 125, -11, -1000, -1000, 176, 176, -1000, -1000, 84,
+	-57, -1000, -1000, -1000, -1000, -33, -64, -1000, -1000, 173,
+	161, -40, -1000, -1000, -47, -1000, -1000, -48, -51, -52,
+	-35, -1000, -1000, -1000, -1000, 151, -1000, -1000, 147, -1000,
+	-1000, -1000, -1000, -1000, -1000, -1000, -1000, 125, -1000, -75,
+	-1000,
+}
+
+var jsonpathPgo = [...]uint8{
+	0, 249, 248, 2, 6, 247, 243, 242, 241, 4,
+	9, 213, 237, 236, 235, 234, 233, 232, 231, 230,
+	229, 228, 226, 225, 3, 0, 218, 1, 214, 179,
+}
+
+var jsonpathR1 = [...]int8{
+	0, 1, 20, 20, 20, 2, 2, 3, 3, 3,
+	3, 3, 3, 3, 3, 3, 14, 14, 14, 14,
+	5, 5, 5, 5, 4, 4, 4, 4, 4, 4,
+	4, 4, 4, 4, 4, 4, 6, 17, 7, 7,
+	15, 15, 9, 9, 10, 10, 10, 10, 10, 10,
+	10, 10, 10, 11, 11, 12, 12, 16, 16, 16,
+	16, 16, 16, 13, 13, 13, 13, 13, 13, 13,
+	13, 13, 13, 13, 13, 13, 21, 21, 21, 25,
+	25, 22, 22, 26, 26, 27, 27, 27, 23, 23,
+	28, 24, 24, 29, 8, 8, 8, 8, 8, 8,
+	8, 18, 18, 18, 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,
+}
+
+var jsonpathR2 = [...]int8{
+	0, 2, 1, 1, 0, 1, 1, 1, 3, 2,
+	2, 3, 3, 3, 3, 3, 1, 4, 4, 2,
+	1, 1, 1, 1, 2, 1, 4, 2, 4, 2,
+	5, 5, 5, 5, 5, 5, 1, 1, 3, 3,
+	1, 3, 1, 3, 1, 3, 3, 3, 2, 5,
+	4, 3, 5, 3, 4, 1, 1, 1, 1, 1,
+	1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+	1, 1, 1, 1, 1, 1, 1, 4, 6, 1,
+	1, 1, 0, 1, 3, 1, 2, 2, 1, 0,
+	1, 1, 0, 1, 1, 1, 1, 1, 1, 1,
+	1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+	1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+	1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+	1, 1, 1, 1, 1, 1, 1,
+}
+
+var jsonpathChk = [...]int16{
+	-1000, -1, -20, 22, 23, -2, -3, -10, -14, 75,
+	69, 70, -11, 39, -5, 44, 24, 25, -8, 43,
+	26, 12, 6, 29, 30, 27, 28, 69, 70, 71,
+	72, 73, -16, 47, 40, 31, 32, 33, 34, 35,
+	36, 37, 38, -4, 77, -7, 78, 79, -3, -10,
+	-3, 75, -3, -11, 75, 75, -3, -3, -3, -3,
+	-3, -3, 48, 27, -10, -3, -10, -6, 71, -13,
+	-21, 63, 64, 65, 66, 67, 68, -17, 50, 51,
+	52, 53, 54, 55, 56, 57, 58, 59, 60, 61,
+	62, 49, -18, 4, 27, -19, 44, 30, 41, 45,
+	43, 23, 40, 28, 47, 22, 42, 29, 46, 48,
+	75, 71, -15, -9, -3, 76, 76, -10, -10, -3,
+	-12, 27, 26, 41, 75, 75, 75, 75, 75, 75,
+	75, 82, -10, 80, 80, 81, 42, -4, -4, 45,
+	76, 76, 76, 27, 76, -22, -26, -27, 12, 69,
+	70, -23, -28, 27, -24, -29, 12, -24, -24, -24,
+	-25, 12, 43, 76, -9, -3, 46, 76, 81, 12,
+	12, 76, 76, 76, 76, 76, 83, 42, -27, -25,
+	83,
+}
+
+var jsonpathDef = [...]int16{
+	4, -2, 0, 2, 3, 1, 5, 6, 7, 0,
+	0, 0, 44, 0, 16, 0, 20, 21, 22, 23,
+	94, 95, 96, 97, 98, 99, 100, 0, 0, 0,
+	0, 0, 0, 0, 0, 57, 58, 59, 60, 61,
+	62, 0, 0, 19, 0, 25, 0, 0, 0, 0,
+	9, 0, 10, 48, 0, 0, 11, 12, 13, 14,
+	15, 45, 0, 51, 46, 0, 47, 24, 27, 0,
+	29, 110, 109, 128, 131, 129, 130, 36, -2, -2,
+	-2, -2, -2, -2, -2, -2, -2, -2, -2, -2,
+	-2, 76, 37, 101, 102, 103, 112, 113, 114, 117,
+	119, 120, 121, 122, 125, 126, 132, 133, 135, 136,
+	0, 0, 0, 40, 42, 8, 53, 0, 0, 0,
+	50, 55, 56, 0, 0, 82, 89, 92, 92, 92,
+	92, 0, 0, 38, 39, 0, 0, 17, 18, 0,
+	0, 53, 54, 52, 28, 0, 81, 83, 85, 0,
+	0, 0, 88, 90, 0, 91, 93, 0, 0, 0,
+	0, 79, 80, 26, 41, 43, 49, 30, 0, 86,
+	87, 31, 32, 33, 34, 35, 77, 0, 84, 0,
+	78,
+}
+
+var jsonpathTok1 = [...]int8{
+	1, 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, 73, 3, 3,
+	75, 76, 71, 69, 81, 70, 77, 72, 3, 3,
+	3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+	3, 3, 3, 78, 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, 79, 3, 80, 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, 82, 3, 83,
+}
+
+var jsonpathTok2 = [...]int8{
+	2, 3, 4, 5, 6, 7, 8, 9, 10, 11,
+	12, 13, 14, 15, 16, 17, 18, 19, 20, 21,
+	22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
+	32, 33, 34, 35, 36, 37, 38, 39, 40, 41,
+	42, 43, 44, 45, 46, 47, 48, 49, 50, 51,
+	52, 53, 54, 55, 56, 57, 58, 59, 60, 61,
+	62, 63, 64, 65, 66, 67, 68, 74,
+}
+
+var jsonpathTok3 = [...]int8{
+	0,
+}
+
+var jsonpathErrorMessages = [...]struct {
+	state int
+	token int
+	msg   string
+}{}
+
+//line yaccpar:1
+
+/*	parser for yacc output	*/
+
+var (
+	jsonpathDebug        = 0
+	jsonpathErrorVerbose = false
+)
+
+type jsonpathLexer interface {
+	Lex(lval *jsonpathSymType) int
+	Error(s string)
+}
+
+type jsonpathParser interface {
+	Parse(jsonpathLexer) int
+	Lookahead() int
+}
+
+type jsonpathParserImpl struct {
+	lval  jsonpathSymType
+	stack [jsonpathInitialStackSize]jsonpathSymType
+	char  int
+}
+
+func (p *jsonpathParserImpl) Lookahead() int {
+	return p.char
+}
+
+func jsonpathNewParser() jsonpathParser {
+	return &jsonpathParserImpl{}
+}
+
+const jsonpathFlag = -1000
+
+func jsonpathTokname(c int) string {
+	if c >= 1 && c-1 < len(jsonpathToknames) {
+		if jsonpathToknames[c-1] != "" {
+			return jsonpathToknames[c-1]
+		}
+	}
+	return __yyfmt__.Sprintf("tok-%v", c)
+}
+
+func jsonpathStatname(s int) string {
+	if s >= 0 && s < len(jsonpathStatenames) {
+		if jsonpathStatenames[s] != "" {
+			return jsonpathStatenames[s]
+		}
+	}
+	return __yyfmt__.Sprintf("state-%v", s)
+}
+
+func jsonpathErrorMessage(state, lookAhead int) string {
+	const TOKSTART = 4
+
+	if !jsonpathErrorVerbose {
+		return "syntax error"
+	}
+
+	for _, e := range jsonpathErrorMessages {
+		if e.state == state && e.token == lookAhead {
+			return "syntax error: " + e.msg
+		}
+	}
+
+	res := "syntax error: unexpected " + jsonpathTokname(lookAhead)
+
+	// To match Bison, suggest at most four expected tokens.
+	expected := make([]int, 0, 4)
+
+	// Look for shiftable tokens.
+	base := int(jsonpathPact[state])
+	for tok := TOKSTART; tok-1 < len(jsonpathToknames); tok++ {
+		if n := base + tok; n >= 0 && n < jsonpathLast && int(jsonpathChk[int(jsonpathAct[n])]) == tok {
+			if len(expected) == cap(expected) {
+				return res
+			}
+			expected = append(expected, tok)
+		}
+	}
+
+	if jsonpathDef[state] == -2 {
+		i := 0
+		for jsonpathExca[i] != -1 || int(jsonpathExca[i+1]) != state {
+			i += 2
+		}
+
+		// Look for tokens that we accept or reduce.
+		for i += 2; jsonpathExca[i] >= 0; i += 2 {
+			tok := int(jsonpathExca[i])
+			if tok < TOKSTART || jsonpathExca[i+1] == 0 {
+				continue
+			}
+			if len(expected) == cap(expected) {
+				return res
+			}
+			expected = append(expected, tok)
+		}
+
+		// If the default action is to accept or reduce, give up.
+		if jsonpathExca[i+1] != 0 {
+			return res
+		}
+	}
+
+	for i, tok := range expected {
+		if i == 0 {
+			res += ", expecting "
+		} else {
+			res += " or "
+		}
+		res += jsonpathTokname(tok)
+	}
+	return res
+}
+
+func jsonpathlex1(lex jsonpathLexer, lval *jsonpathSymType) (char, token int) {
+	token = 0
+	char = lex.Lex(lval)
+	if char <= 0 {
+		token = int(jsonpathTok1[0])
+		goto out
+	}
+	if char < len(jsonpathTok1) {
+		token = int(jsonpathTok1[char])
+		goto out
+	}
+	if char >= jsonpathPrivate {
+		if char < jsonpathPrivate+len(jsonpathTok2) {
+			token = int(jsonpathTok2[char-jsonpathPrivate])
+			goto out
+		}
+	}
+	for i := 0; i < len(jsonpathTok3); i += 2 {
+		token = int(jsonpathTok3[i+0])
+		if token == char {
+			token = int(jsonpathTok3[i+1])
+			goto out
+		}
+	}
+
+out:
+	if token == 0 {
+		token = int(jsonpathTok2[1]) /* unknown char */
+	}
+	if jsonpathDebug >= 3 {
+		__yyfmt__.Printf("lex %s(%d)\n", jsonpathTokname(token), uint(char))
+	}
+	return char, token
+}
+
+func jsonpathParse(jsonpathlex jsonpathLexer) int {
+	return jsonpathNewParser().Parse(jsonpathlex)
+}
+
+func (jsonpathrcvr *jsonpathParserImpl) Parse(jsonpathlex jsonpathLexer) int {
+	var jsonpathn int
+	var jsonpathVAL jsonpathSymType
+	var jsonpathDollar []jsonpathSymType
+	_ = jsonpathDollar // silence set and not used
+	jsonpathS := jsonpathrcvr.stack[:]
+
+	Nerrs := 0   /* number of errors */
+	Errflag := 0 /* error recovery flag */
+	jsonpathstate := 0
+	jsonpathrcvr.char = -1
+	jsonpathtoken := -1 // jsonpathrcvr.char translated into internal numbering
+	defer func() {
+		// Make sure we report no lookahead when not parsing.
+		jsonpathstate = -1
+		jsonpathrcvr.char = -1
+		jsonpathtoken = -1
+	}()
+	jsonpathp := -1
+	goto jsonpathstack
+
+ret0:
+	return 0
+
+ret1:
+	return 1
+
+jsonpathstack:
+	/* put a state and value onto the stack */
+	if jsonpathDebug >= 4 {
+		__yyfmt__.Printf("char %v in %v\n", jsonpathTokname(jsonpathtoken), jsonpathStatname(jsonpathstate))
+	}
+
+	jsonpathp++
+	if jsonpathp >= len(jsonpathS) {
+		nyys := make([]jsonpathSymType, len(jsonpathS)*2)
+		copy(nyys, jsonpathS)
+		jsonpathS = nyys
+	}
+	jsonpathS[jsonpathp] = jsonpathVAL
+	jsonpathS[jsonpathp].yys = jsonpathstate
+
+jsonpathnewstate:
+	jsonpathn = int(jsonpathPact[jsonpathstate])
+	if jsonpathn <= jsonpathFlag {
+		goto jsonpathdefault /* simple state */
+	}
+	if jsonpathrcvr.char < 0 {
+		jsonpathrcvr.char, jsonpathtoken = jsonpathlex1(jsonpathlex, &jsonpathrcvr.lval)
+	}
+	jsonpathn += jsonpathtoken
+	if jsonpathn < 0 || jsonpathn >= jsonpathLast {
+		goto jsonpathdefault
+	}
+	jsonpathn = int(jsonpathAct[jsonpathn])
+	if int(jsonpathChk[jsonpathn]) == jsonpathtoken { /* valid shift */
+		jsonpathrcvr.char = -1
+		jsonpathtoken = -1
+		jsonpathVAL = jsonpathrcvr.lval
+		jsonpathstate = jsonpathn
+		if Errflag > 0 {
+			Errflag--
+		}
+		goto jsonpathstack
+	}
+
+jsonpathdefault:
+	/* default state action */
+	jsonpathn = int(jsonpathDef[jsonpathstate])
+	if jsonpathn == -2 {
+		if jsonpathrcvr.char < 0 {
+			jsonpathrcvr.char, jsonpathtoken = jsonpathlex1(jsonpathlex, &jsonpathrcvr.lval)
+		}
+
+		/* look through exception table */
+		xi := 0
+		for {
+			if jsonpathExca[xi+0] == -1 && int(jsonpathExca[xi+1]) == jsonpathstate {
+				break
+			}
+			xi += 2
+		}
+		for xi += 2; ; xi += 2 {
+			jsonpathn = int(jsonpathExca[xi+0])
+			if jsonpathn < 0 || jsonpathn == jsonpathtoken {
+				break
+			}
+		}
+		jsonpathn = int(jsonpathExca[xi+1])
+		if jsonpathn < 0 {
+			goto ret0
+		}
+	}
+	if jsonpathn == 0 {
+		/* error ... attempt to resume parsing */
+		switch Errflag {
+		case 0: /* brand new error */
+			jsonpathlex.Error(jsonpathErrorMessage(jsonpathstate, jsonpathtoken))
+			Nerrs++
+			if jsonpathDebug >= 1 {
+				__yyfmt__.Printf("%s", jsonpathStatname(jsonpathstate))
+				__yyfmt__.Printf(" saw %s\n", jsonpathTokname(jsonpathtoken))
+			}
+			fallthrough
+
+		case 1, 2: /* incompletely recovered error ... try again */
+			Errflag = 3
+
+			/* find a state where "error" is a legal shift action */
+			for jsonpathp >= 0 {
+				jsonpathn = int(jsonpathPact[jsonpathS[jsonpathp].yys]) + jsonpathErrCode
+				if jsonpathn >= 0 && jsonpathn < jsonpathLast {
+					jsonpathstate = int(jsonpathAct[jsonpathn]) /* simulate a shift of "error" */
+					if int(jsonpathChk[jsonpathstate]) == jsonpathErrCode {
+						goto jsonpathstack
+					}
+				}
+
+				/* the current p has no shift on "error", pop stack */
+				if jsonpathDebug >= 2 {
+					__yyfmt__.Printf("error recovery pops state %d\n", jsonpathS[jsonpathp].yys)
+				}
+				jsonpathp--
+			}
+			/* there is no state on the stack with an error shift ... abort */
+			goto ret1
+
+		case 3: /* no shift yet; clobber input char */
+			if jsonpathDebug >= 2 {
+				__yyfmt__.Printf("error recovery discards %s\n", jsonpathTokname(jsonpathtoken))
+			}
+			if jsonpathtoken == jsonpathEofCode {
+				goto ret1
+			}
+			jsonpathrcvr.char = -1
+			jsonpathtoken = -1
+			goto jsonpathnewstate /* try again in the same state */
+		}
+	}
+
+	/* reduction by production jsonpathn */
+	if jsonpathDebug >= 2 {
+		__yyfmt__.Printf("reduce %v in:\n\t%v\n", jsonpathn, jsonpathStatname(jsonpathstate))
+	}
+
+	jsonpathnt := jsonpathn
+	jsonpathpt := jsonpathp
+	_ = jsonpathpt // guard against "declared and not used"
+
+	jsonpathp -= int(jsonpathR2[jsonpathn])
+	// jsonpathp is now the index of $0. Perform the default action. Iff the
+	// reduced production is ε, $1 is possibly out of range.
+	if jsonpathp+1 >= len(jsonpathS) {
+		nyys := make([]jsonpathSymType, len(jsonpathS)*2)
+		copy(nyys, jsonpathS)
+		jsonpathS = nyys
+	}
+	jsonpathVAL = jsonpathS[jsonpathp+1]
+
+	/* consult goto table to find next state */
+	jsonpathn = int(jsonpathR1[jsonpathn])
+	jsonpathg := int(jsonpathPgo[jsonpathn])
+	jsonpathj := jsonpathg + jsonpathS[jsonpathp].yys + 1
+
+	if jsonpathj >= jsonpathLast {
+		jsonpathstate = int(jsonpathAct[jsonpathg])
+	} else {
+		jsonpathstate = int(jsonpathAct[jsonpathj])
+		if int(jsonpathChk[jsonpathstate]) != -jsonpathn {
+			jsonpathstate = int(jsonpathAct[jsonpathg])
+		}
+	}
+	// dummy call; replaced with literal code
+	switch jsonpathnt {
+
+	case 1:
+		jsonpathDollar = jsonpathS[jsonpathpt-2 : jsonpathpt+1]
+//line jsonpath-gen.y:259
+		{
+			jp := jsonpath.Jsonpath{Strict: jsonpathDollar[1].union.bool(), Path: jsonpathDollar[2].union.path()}
+			jsonpathlex.(*lexer).SetJsonpath(jp)
+		}
+	case 2:
+		jsonpathDollar = jsonpathS[jsonpathpt-1 : jsonpathpt+1]
+//line jsonpath-gen.y:267
+		{
+			jsonpathVAL.union.val = true
+		}
+	case 3:
+		jsonpathDollar = jsonpathS[jsonpathpt-1 : jsonpathpt+1]
+//line jsonpath-gen.y:271
+		{
+			jsonpathVAL.union.val = false
+		}
+	case 4:
+		jsonpathDollar = jsonpathS[jsonpathpt-0 : jsonpathpt+1]
+//line jsonpath-gen.y:275
+		{
+			jsonpathVAL.union.val = false
+		}
+	case 5:
+		jsonpathDollar = jsonpathS[jsonpathpt-1 : jsonpathpt+1]
+//line jsonpath-gen.y:282
+		{
+			jsonpathVAL.union.val = jsonpathDollar[1].union.path()
+		}
+	case 6:
+		jsonpathDollar = jsonpathS[jsonpathpt-1 : jsonpathpt+1]
+//line jsonpath-gen.y:286
+		{
+			jsonpathVAL.union.val = jsonpathDollar[1].union.path()
+		}
+	case 7:
+		jsonpathDollar = jsonpathS[jsonpathpt-1 : jsonpathpt+1]
+//line jsonpath-gen.y:293
+		{
+			jsonpathVAL.union.val = jsonpath.Paths(jsonpathDollar[1].union.pathArr())
+		}
+	case 8:
+		jsonpathDollar = jsonpathS[jsonpathpt-3 : jsonpathpt+1]
+//line jsonpath-gen.y:297
+		{
+			jsonpathVAL.union.val = jsonpathDollar[2].union.path()
+		}
+	case 9:
+		jsonpathDollar = jsonpathS[jsonpathpt-2 : jsonpathpt+1]
+//line jsonpath-gen.y:301
+		{
+			jsonpathVAL.union.val = unaryOp(jsonpath.OpPlus, jsonpathDollar[2].union.path())
+		}
+	case 10:
+		jsonpathDollar = jsonpathS[jsonpathpt-2 : jsonpathpt+1]
+//line jsonpath-gen.y:305
+		{
+			jsonpathVAL.union.val = unaryOp(jsonpath.OpMinus, jsonpathDollar[2].union.path())
+		}
+	case 11:
+		jsonpathDollar = jsonpathS[jsonpathpt-3 : jsonpathpt+1]
+//line jsonpath-gen.y:309
+		{
+			jsonpathVAL.union.val = binaryOp(jsonpath.OpAdd, jsonpathDollar[1].union.path(), jsonpathDollar[3].union.path())
+		}
+	case 12:
+		jsonpathDollar = jsonpathS[jsonpathpt-3 : jsonpathpt+1]
+//line jsonpath-gen.y:313
+		{
+			jsonpathVAL.union.val = binaryOp(jsonpath.OpSub, jsonpathDollar[1].union.path(), jsonpathDollar[3].union.path())
+		}
+	case 13:
+		jsonpathDollar = jsonpathS[jsonpathpt-3 : jsonpathpt+1]
+//line jsonpath-gen.y:317
+		{
+			jsonpathVAL.union.val = binaryOp(jsonpath.OpMult, jsonpathDollar[1].union.path(), jsonpathDollar[3].union.path())
+		}
+	case 14:
+		jsonpathDollar = jsonpathS[jsonpathpt-3 : jsonpathpt+1]
+//line jsonpath-gen.y:321
+		{
+			jsonpathVAL.union.val = binaryOp(jsonpath.OpDiv, jsonpathDollar[1].union.path(), jsonpathDollar[3].union.path())
+		}
+	case 15:
+		jsonpathDollar = jsonpathS[jsonpathpt-3 : jsonpathpt+1]
+//line jsonpath-gen.y:325
+		{
+			jsonpathVAL.union.val = binaryOp(jsonpath.OpMod, jsonpathDollar[1].union.path(), jsonpathDollar[3].union.path())
+		}
+	case 16:
+		jsonpathDollar = jsonpathS[jsonpathpt-1 : jsonpathpt+1]
+//line jsonpath-gen.y:332
+		{
+			jsonpathVAL.union.val = []jsonpath.Path{jsonpathDollar[1].union.path()}
+		}
+	case 17:
+		jsonpathDollar = jsonpathS[jsonpathpt-4 : jsonpathpt+1]
+//line jsonpath-gen.y:336
+		{
+			jsonpathVAL.union.val = []jsonpath.Path{jsonpathDollar[2].union.path(), jsonpathDollar[4].union.path()}
+		}
+	case 18:
+		jsonpathDollar = jsonpathS[jsonpathpt-4 : jsonpathpt+1]
+//line jsonpath-gen.y:340
+		{
+			jsonpathVAL.union.val = []jsonpath.Path{jsonpathDollar[2].union.path(), jsonpathDollar[4].union.path()}
+		}
+	case 19:
+		jsonpathDollar = jsonpathS[jsonpathpt-2 : jsonpathpt+1]
+//line jsonpath-gen.y:344
+		{
+			jsonpathVAL.union.val = append(jsonpathDollar[1].union.pathArr(), jsonpathDollar[2].union.path())
+		}
+	case 20:
+		jsonpathDollar = jsonpathS[jsonpathpt-1 : jsonpathpt+1]
+//line jsonpath-gen.y:351
+		{
+			jsonpathVAL.union.val = jsonpath.Root{}
+		}
+	case 21:
+		jsonpathDollar = jsonpathS[jsonpathpt-1 : jsonpathpt+1]
+//line jsonpath-gen.y:355
+		{
+			jsonpathVAL.union.val = jsonpath.Current{}
+		}
+	case 22:
+		jsonpathDollar = jsonpathS[jsonpathpt-1 : jsonpathpt+1]
+//line jsonpath-gen.y:359
+		{
+			jsonpathVAL.union.val = jsonpathDollar[1].union.path()
+		}
+	case 23:
+		jsonpathDollar = jsonpathS[jsonpathpt-1 : jsonpathpt+1]
+//line jsonpath-gen.y:363
+		{
+			jsonpathVAL.union.val = jsonpath.Last{}
+		}
+	case 24:
+		jsonpathDollar = jsonpathS[jsonpathpt-2 : jsonpathpt+1]
+//line jsonpath-gen.y:370
+		{
+			jsonpathVAL.union.val = jsonpathDollar[2].union.path()
+		}
+	case 25:
+		jsonpathDollar = jsonpathS[jsonpathpt-1 : jsonpathpt+1]
+//line jsonpath-gen.y:374
+		{
+			jsonpathVAL.union.val = jsonpathDollar[1].union.path()
+		}
+	case 26:
+		jsonpathDollar = jsonpathS[jsonpathpt-4 : jsonpathpt+1]
+//line jsonpath-gen.y:378
+		{
+			jsonpathVAL.union.val = jsonpath.Filter{Condition: jsonpathDollar[3].union.path()}
+		}
+	case 27:
+		jsonpathDollar = jsonpathS[jsonpathpt-2 : jsonpathpt+1]
+//line jsonpath-gen.y:382
+		{
+			jsonpathVAL.union.val = jsonpath.AnyKey{}
+		}
+	case 28:
+		jsonpathDollar = jsonpathS[jsonpathpt-4 : jsonpathpt+1]
+//line jsonpath-gen.y:386
+		{
+			jsonpathVAL.union.val = jsonpathDollar[2].union.path()
+		}
+	case 29:
+		jsonpathDollar = jsonpathS[jsonpathpt-2 : jsonpathpt+1]
+//line jsonpath-gen.y:390
+		{
+			return unimplemented(jsonpathlex, ".**")
+		}
+	case 30:
+		jsonpathDollar = jsonpathS[jsonpathpt-5 : jsonpathpt+1]
+//line jsonpath-gen.y:394
+		{
+			return unimplemented(jsonpathlex, ".decimal()")
+		}
+	case 31:
+		jsonpathDollar = jsonpathS[jsonpathpt-5 : jsonpathpt+1]
+//line jsonpath-gen.y:398
+		{
+			return unimplemented(jsonpathlex, ".datetime()")
+		}
+	case 32:
+		jsonpathDollar = jsonpathS[jsonpathpt-5 : jsonpathpt+1]
+//line jsonpath-gen.y:402
+		{
+			return unimplemented(jsonpathlex, ".time()")
+		}
+	case 33:
+		jsonpathDollar = jsonpathS[jsonpathpt-5 : jsonpathpt+1]
+//line jsonpath-gen.y:406
+		{
+			return unimplemented(jsonpathlex, ".time_tz()")
+		}
+	case 34:
+		jsonpathDollar = jsonpathS[jsonpathpt-5 : jsonpathpt+1]
+//line jsonpath-gen.y:410
+		{
+			return unimplemented(jsonpathlex, ".timestamp()")
+		}
+	case 35:
+		jsonpathDollar = jsonpathS[jsonpathpt-5 : jsonpathpt+1]
+//line jsonpath-gen.y:414
+		{
+			return unimplemented(jsonpathlex, ".timestamp_tz()")
+		}
+	case 36:
+		jsonpathDollar = jsonpathS[jsonpathpt-1 : jsonpathpt+1]
+//line jsonpath-gen.y:421
+		{
+			jsonpathVAL.union.val = jsonpath.Key(jsonpathDollar[1].str)
+		}
+	case 37:
+		jsonpathDollar = jsonpathS[jsonpathpt-1 : jsonpathpt+1]
+//line jsonpath-gen.y:428
+		{
+			jsonpathVAL.str = jsonpathDollar[1].str
+		}
+	case 38:
+		jsonpathDollar = jsonpathS[jsonpathpt-3 : jsonpathpt+1]
+//line jsonpath-gen.y:435
+		{
+			jsonpathVAL.union.val = jsonpath.Wildcard{}
+		}
+	case 39:
+		jsonpathDollar = jsonpathS[jsonpathpt-3 : jsonpathpt+1]
+//line jsonpath-gen.y:439
+		{
+			jsonpathVAL.union.val = jsonpathDollar[2].union.path()
+		}
+	case 40:
+		jsonpathDollar = jsonpathS[jsonpathpt-1 : jsonpathpt+1]
+//line jsonpath-gen.y:446
+		{
+			jsonpathVAL.union.val = jsonpath.ArrayList{jsonpathDollar[1].union.path()}
+		}
+	case 41:
+		jsonpathDollar = jsonpathS[jsonpathpt-3 : jsonpathpt+1]
+//line jsonpath-gen.y:450
+		{
+			jsonpathVAL.union.val = append(jsonpathDollar[1].union.arrayList(), jsonpathDollar[3].union.path())
+		}
+	case 42:
+		jsonpathDollar = jsonpathS[jsonpathpt-1 : jsonpathpt+1]
+//line jsonpath-gen.y:457
+		{
+			jsonpathVAL.union.val = jsonpathDollar[1].union.path()
+		}
+	case 43:
+		jsonpathDollar = jsonpathS[jsonpathpt-3 : jsonpathpt+1]
+//line jsonpath-gen.y:461
+		{
+			jsonpathVAL.union.val = jsonpath.ArrayIndexRange{
+				Start: jsonpathDollar[1].union.path(),
+				End:   jsonpathDollar[3].union.path(),
+			}
+		}
+	case 44:
+		jsonpathDollar = jsonpathS[jsonpathpt-1 : jsonpathpt+1]
+//line jsonpath-gen.y:471
+		{
+			jsonpathVAL.union.val = jsonpathDollar[1].union.path()
+		}
+	case 45:
+		jsonpathDollar = jsonpathS[jsonpathpt-3 : jsonpathpt+1]
+//line jsonpath-gen.y:475
+		{
+			jsonpathVAL.union.val = binaryOp(jsonpathDollar[2].union.operationType(), jsonpathDollar[1].union.path(), jsonpathDollar[3].union.path())
+		}
+	case 46:
+		jsonpathDollar = jsonpathS[jsonpathpt-3 : jsonpathpt+1]
+//line jsonpath-gen.y:479
+		{
+			jsonpathVAL.union.val = binaryOp(jsonpath.OpLogicalAnd, jsonpathDollar[1].union.path(), jsonpathDollar[3].union.path())
+		}
+	case 47:
+		jsonpathDollar = jsonpathS[jsonpathpt-3 : jsonpathpt+1]
+//line jsonpath-gen.y:483
+		{
+			jsonpathVAL.union.val = binaryOp(jsonpath.OpLogicalOr, jsonpathDollar[1].union.path(), jsonpathDollar[3].union.path())
+		}
+	case 48:
+		jsonpathDollar = jsonpathS[jsonpathpt-2 : jsonpathpt+1]
+//line jsonpath-gen.y:487
+		{
+			jsonpathVAL.union.val = unaryOp(jsonpath.OpLogicalNot, jsonpathDollar[2].union.path())
+		}
+	case 49:
+		jsonpathDollar = jsonpathS[jsonpathpt-5 : jsonpathpt+1]
+//line jsonpath-gen.y:491
+		{
+			jsonpathVAL.union.val = unaryOp(jsonpath.OpIsUnknown, jsonpathDollar[2].union.path())
+		}
+	case 50:
+		jsonpathDollar = jsonpathS[jsonpathpt-4 : jsonpathpt+1]
+//line jsonpath-gen.y:495
+		{
+			jsonpathVAL.union.val = binaryOp(jsonpath.OpStartsWith, jsonpathDollar[1].union.path(), jsonpathDollar[4].union.path())
+		}
+	case 51:
+		jsonpathDollar = jsonpathS[jsonpathpt-3 : jsonpathpt+1]
+//line jsonpath-gen.y:499
+		{
+			regex, err := regexBinaryOp(jsonpathDollar[1].union.path(), jsonpathDollar[3].str, "")
+			if err != nil {
+				return setErr(jsonpathlex, err)
+			}
+			jsonpathVAL.union.val = regex
+		}
+	case 52:
+		jsonpathDollar = jsonpathS[jsonpathpt-5 : jsonpathpt+1]
+//line jsonpath-gen.y:507
+		{
+			regex, err := regexBinaryOp(jsonpathDollar[1].union.path(), jsonpathDollar[3].str, jsonpathDollar[5].str)
+			if err != nil {
+				return setErr(jsonpathlex, err)
+			}
+			jsonpathVAL.union.val = regex
+		}
+	case 53:
+		jsonpathDollar = jsonpathS[jsonpathpt-3 : jsonpathpt+1]
+//line jsonpath-gen.y:518
+		{
+			jsonpathVAL.union.val = jsonpathDollar[2].union.path()
+		}
+	case 54:
+		jsonpathDollar = jsonpathS[jsonpathpt-4 : jsonpathpt+1]
+//line jsonpath-gen.y:522
+		{
+			jsonpathVAL.union.val = unaryOp(jsonpath.OpExists, jsonpathDollar[3].union.path())
+		}
+	case 55:
+		jsonpathDollar = jsonpathS[jsonpathpt-1 : jsonpathpt+1]
+//line jsonpath-gen.y:529
+		{
+			jsonpathVAL.union.val = jsonpath.Scalar{Type: jsonpath.ScalarString, Value: json.FromString(jsonpathDollar[1].str)}
+		}
+	case 56:
+		jsonpathDollar = jsonpathS[jsonpathpt-1 : jsonpathpt+1]
+//line jsonpath-gen.y:533
+		{
+			jsonpathVAL.union.val = jsonpath.Scalar{Type: jsonpath.ScalarVariable, Variable: jsonpathDollar[1].str}
+		}
+	case 57:
+		jsonpathDollar = jsonpathS[jsonpathpt-1 : jsonpathpt+1]
+//line jsonpath-gen.y:540
+		{
+			jsonpathVAL.union.val = jsonpath.OpCompEqual
+		}
+	case 58:
+		jsonpathDollar = jsonpathS[jsonpathpt-1 : jsonpathpt+1]
+//line jsonpath-gen.y:544
+		{
+			jsonpathVAL.union.val = jsonpath.OpCompNotEqual
+		}
+	case 59:
+		jsonpathDollar = jsonpathS[jsonpathpt-1 : jsonpathpt+1]
+//line jsonpath-gen.y:548
+		{
+			jsonpathVAL.union.val = jsonpath.OpCompLess
+		}
+	case 60:
+		jsonpathDollar = jsonpathS[jsonpathpt-1 : jsonpathpt+1]
+//line jsonpath-gen.y:552
+		{
+			jsonpathVAL.union.val = jsonpath.OpCompLessEqual
+		}
+	case 61:
+		jsonpathDollar = jsonpathS[jsonpathpt-1 : jsonpathpt+1]
+//line jsonpath-gen.y:556
+		{
+			jsonpathVAL.union.val = jsonpath.OpCompGreater
+		}
+	case 62:
+		jsonpathDollar = jsonpathS[jsonpathpt-1 : jsonpathpt+1]
+//line jsonpath-gen.y:560
+		{
+			jsonpathVAL.union.val = jsonpath.OpCompGreaterEqual
+		}
+	case 63:
+		jsonpathDollar = jsonpathS[jsonpathpt-1 : jsonpathpt+1]
+//line jsonpath-gen.y:567
+		{
+			jsonpathVAL.union.val = jsonpath.Method{Type: jsonpath.SizeMethod}
+		}
+	case 64:
+		jsonpathDollar = jsonpathS[jsonpathpt-1 : jsonpathpt+1]
+//line jsonpath-gen.y:571
+		{
+			jsonpathVAL.union.val = jsonpath.Method{Type: jsonpath.TypeMethod}
+		}
+	case 65:
+		jsonpathDollar = jsonpathS[jsonpathpt-1 : jsonpathpt+1]
+//line jsonpath-gen.y:575
+		{
+			return unimplemented(jsonpathlex, ".keyvalue()")
+		}
+	case 66:
+		jsonpathDollar = jsonpathS[jsonpathpt-1 : jsonpathpt+1]
+//line jsonpath-gen.y:579
+		{
+			jsonpathVAL.union.val = jsonpath.Method{Type: jsonpath.AbsMethod}
+		}
+	case 67:
+		jsonpathDollar = jsonpathS[jsonpathpt-1 : jsonpathpt+1]
+//line jsonpath-gen.y:583
+		{
+			jsonpathVAL.union.val = jsonpath.Method{Type: jsonpath.CeilingMethod}
+		}
+	case 68:
+		jsonpathDollar = jsonpathS[jsonpathpt-1 : jsonpathpt+1]
+//line jsonpath-gen.y:587
+		{
+			jsonpathVAL.union.val = jsonpath.Method{Type: jsonpath.FloorMethod}
+		}
+	case 69:
+		jsonpathDollar = jsonpathS[jsonpathpt-1 : jsonpathpt+1]
+//line jsonpath-gen.y:591
+		{
+			return unimplemented(jsonpathlex, ".bigint()")
+		}
+	case 70:
+		jsonpathDollar = jsonpathS[jsonpathpt-1 : jsonpathpt+1]
+//line jsonpath-gen.y:595
+		{
+			return unimplemented(jsonpathlex, ".boolean()")
+		}
+	case 71:
+		jsonpathDollar = jsonpathS[jsonpathpt-1 : jsonpathpt+1]
+//line jsonpath-gen.y:599
+		{
+			return unimplemented(jsonpathlex, ".date()")
+		}
+	case 72:
+		jsonpathDollar = jsonpathS[jsonpathpt-1 : jsonpathpt+1]
+//line jsonpath-gen.y:603
+		{
+			return unimplemented(jsonpathlex, ".double()")
+		}
+	case 73:
+		jsonpathDollar = jsonpathS[jsonpathpt-1 : jsonpathpt+1]
+//line jsonpath-gen.y:607
+		{
+			return unimplemented(jsonpathlex, ".integer()")
+		}
+	case 74:
+		jsonpathDollar = jsonpathS[jsonpathpt-1 : jsonpathpt+1]
+//line jsonpath-gen.y:611
+		{
+			return unimplemented(jsonpathlex, ".number()")
+		}
+	case 75:
+		jsonpathDollar = jsonpathS[jsonpathpt-1 : jsonpathpt+1]
+//line jsonpath-gen.y:615
+		{
+			return unimplemented(jsonpathlex, ".string()")
+		}
+	case 76:
+		jsonpathDollar = jsonpathS[jsonpathpt-1 : jsonpathpt+1]
+//line jsonpath-gen.y:622
+		{
+
+		}
+	case 77:
+		jsonpathDollar = jsonpathS[jsonpathpt-4 : jsonpathpt+1]
+//line jsonpath-gen.y:626
+		{
+
+		}
+	case 78:
+		jsonpathDollar = jsonpathS[jsonpathpt-6 : jsonpathpt+1]
+//line jsonpath-gen.y:630
+		{
+
+		}
+	case 79:
+		jsonpathDollar = jsonpathS[jsonpathpt-1 : jsonpathpt+1]
+//line jsonpath-gen.y:637
+		{
+
+		}
+	case 80:
+		jsonpathDollar = jsonpathS[jsonpathpt-1 : jsonpathpt+1]
+//line jsonpath-gen.y:641
+		{
+
+		}
+	case 81:
+		jsonpathDollar = jsonpathS[jsonpathpt-1 : jsonpathpt+1]
+//line jsonpath-gen.y:648
+		{
+
+		}
+	case 82:
+		jsonpathDollar = jsonpathS[jsonpathpt-0 : jsonpathpt+1]
+//line jsonpath-gen.y:652
+		{
+
+		}
+	case 83:
+		jsonpathDollar = jsonpathS[jsonpathpt-1 : jsonpathpt+1]
+//line jsonpath-gen.y:659
+		{
+
+		}
+	case 84:
+		jsonpathDollar = jsonpathS[jsonpathpt-3 : jsonpathpt+1]
+//line jsonpath-gen.y:663
+		{
+
+		}
+	case 85:
+		jsonpathDollar = jsonpathS[jsonpathpt-1 : jsonpathpt+1]
+//line jsonpath-gen.y:670
+		{
+
+		}
+	case 86:
+		jsonpathDollar = jsonpathS[jsonpathpt-2 : jsonpathpt+1]
+//line jsonpath-gen.y:674
+		{
+
+		}
+	case 87:
+		jsonpathDollar = jsonpathS[jsonpathpt-2 : jsonpathpt+1]
+//line jsonpath-gen.y:678
+		{
+
+		}
+	case 88:
+		jsonpathDollar = jsonpathS[jsonpathpt-1 : jsonpathpt+1]
+//line jsonpath-gen.y:685
+		{
+
+		}
+	case 89:
+		jsonpathDollar = jsonpathS[jsonpathpt-0 : jsonpathpt+1]
+//line jsonpath-gen.y:689
+		{
+
+		}
+	case 90:
+		jsonpathDollar = jsonpathS[jsonpathpt-1 : jsonpathpt+1]
+//line jsonpath-gen.y:696
+		{
+
+		}
+	case 91:
+		jsonpathDollar = jsonpathS[jsonpathpt-1 : jsonpathpt+1]
+//line jsonpath-gen.y:703
+		{
+
+		}
+	case 92:
+		jsonpathDollar = jsonpathS[jsonpathpt-0 : jsonpathpt+1]
+//line jsonpath-gen.y:707
+		{
+
+		}
+	case 93:
+		jsonpathDollar = jsonpathS[jsonpathpt-1 : jsonpathpt+1]
+//line jsonpath-gen.y:714
+		{
+
+		}
+	case 94:
+		jsonpathDollar = jsonpathS[jsonpathpt-1 : jsonpathpt+1]
+//line jsonpath-gen.y:721
+		{
+			jsonpathVAL.union.val = jsonpath.Scalar{Type: jsonpath.ScalarVariable, Variable: jsonpathDollar[1].str}
+		}
+	case 95:
+		jsonpathDollar = jsonpathS[jsonpathpt-1 : jsonpathpt+1]
+//line jsonpath-gen.y:725
+		{
+			i, err := jsonpathDollar[1].union.numVal().AsInt64()
+			if err != nil {
+				return setErr(jsonpathlex, err)
+			}
+			jsonpathVAL.union.val = jsonpath.Scalar{Type: jsonpath.ScalarInt, Value: json.FromInt64(i)}
+		}
+	case 96:
+		jsonpathDollar = jsonpathS[jsonpathpt-1 : jsonpathpt+1]
+//line jsonpath-gen.y:733
+		{
+			f, err := strconv.ParseFloat(jsonpathDollar[1].str, 64)
+			if err != nil {
+				return setErr(jsonpathlex, err)
+			}
+			j, err := json.FromFloat64(f)
+			if err != nil {
+				return setErr(jsonpathlex, err)
+			}
+			jsonpathVAL.union.val = jsonpath.Scalar{Type: jsonpath.ScalarFloat, Value: j}
+		}
+	case 97:
+		jsonpathDollar = jsonpathS[jsonpathpt-1 : jsonpathpt+1]
+//line jsonpath-gen.y:745
+		{
+			jsonpathVAL.union.val = jsonpath.Scalar{Type: jsonpath.ScalarBool, Value: json.FromBool(true)}
+		}
+	case 98:
+		jsonpathDollar = jsonpathS[jsonpathpt-1 : jsonpathpt+1]
+//line jsonpath-gen.y:749
+		{
+			jsonpathVAL.union.val = jsonpath.Scalar{Type: jsonpath.ScalarBool, Value: json.FromBool(false)}
+		}
+	case 99:
+		jsonpathDollar = jsonpathS[jsonpathpt-1 : jsonpathpt+1]
+//line jsonpath-gen.y:753
+		{
+			jsonpathVAL.union.val = jsonpath.Scalar{Type: jsonpath.ScalarString, Value: json.FromString(jsonpathDollar[1].str)}
+		}
+	case 100:
+		jsonpathDollar = jsonpathS[jsonpathpt-1 : jsonpathpt+1]
+//line jsonpath-gen.y:757
+		{
+			jsonpathVAL.union.val = jsonpath.Scalar{Type: jsonpath.ScalarNull, Value: json.NullJSONValue}
+		}
+	}
+	goto jsonpathstack /* stack new state and value */
+}
diff --git a/pkg/util/jsonpath/parser/jsonpath.y b/pkg/util/jsonpath/parser/jsonpath.y
new file mode 100644
index 0000000..d7b0c16
--- /dev/null
+++ b/pkg/util/jsonpath/parser/jsonpath.y
@@ -0,0 +1,804 @@
+%{
+package parser
+
+import (
+  "strconv"
+
+  "github.com/cockroachdb/cockroach/pkg/sql/pgwire/pgcode"
+  "github.com/cockroachdb/cockroach/pkg/sql/pgwire/pgerror"
+  "github.com/cockroachdb/cockroach/pkg/sql/scanner"
+  "github.com/cockroachdb/cockroach/pkg/sql/sem/tree"
+  "github.com/cockroachdb/cockroach/pkg/util/json"
+  "github.com/cockroachdb/cockroach/pkg/util/jsonpath"
+)
+
+%}
+
+%{
+
+func setErr(jsonpathlex jsonpathLexer, err error) int {
+  jsonpathlex.(*lexer).setErr(err)
+  return 1
+}
+
+func unimplemented(jsonpathlex jsonpathLexer, feature string) int {
+  jsonpathlex.(*lexer).Unimplemented(feature)
+  return 1
+}
+
+var _ scanner.ScanSymType = &jsonpathSymType{}
+
+func (s *jsonpathSymType) jsonpathScanSymType() {}
+
+// ID implements the scanner.ScanSymType interface.
+func (s *jsonpathSymType) ID() int32 {
+  return s.id
+}
+
+// SetID implements the scanner.ScanSymType interface.
+func (s *jsonpathSymType) SetID(id int32) {
+  s.id = id
+}
+
+// Pos implements the scanner.ScanSymType interface.
+func (s *jsonpathSymType) Pos() int32 {
+  return s.pos
+}
+
+// SetPos implements the scanner.ScanSymType interface.
+func (s *jsonpathSymType) SetPos(pos int32) {
+  s.pos = pos
+}
+
+// Str implements the scanner.ScanSymType interface.
+func (s *jsonpathSymType) Str() string {
+  return s.str
+}
+
+// SetStr implements the scanner.ScanSymType interface.
+func (s *jsonpathSymType) SetStr(str string) {
+  s.str = str
+}
+
+// UnionVal implements the scanner.ScanSymType interface.
+func (s *jsonpathSymType) UnionVal() interface{} {
+  return s.union.val
+}
+
+// SetUnionVal implements the scanner.ScanSymType interface.
+func (s *jsonpathSymType) SetUnionVal(val interface{}) {
+  s.union.val = val
+}
+
+type jsonpathSymUnion struct {
+  val interface{}
+}
+
+func (u *jsonpathSymUnion) jsonpath() jsonpath.Jsonpath {
+  return u.val.(jsonpath.Jsonpath)
+}
+
+func (u *jsonpathSymUnion) path() jsonpath.Path {
+  return u.val.(jsonpath.Path)
+}
+
+func (u *jsonpathSymUnion) paths() jsonpath.Paths {
+  return u.val.(jsonpath.Paths)
+}
+
+func (u *jsonpathSymUnion) pathArr() []jsonpath.Path {
+  return u.val.([]jsonpath.Path)
+}
+
+func (u *jsonpathSymUnion) bool() bool {
+  return u.val.(bool)
+}
+
+func (u *jsonpathSymUnion) numVal() *tree.NumVal {
+  return u.val.(*tree.NumVal)
+}
+
+func (u *jsonpathSymUnion) arrayList() jsonpath.ArrayList {
+  return u.val.(jsonpath.ArrayList)
+}
+
+func (u *jsonpathSymUnion) operationType() jsonpath.OperationType {
+  return u.val.(jsonpath.OperationType)
+}
+
+%}
+
+%{
+
+func binaryOp(op jsonpath.OperationType, left jsonpath.Path, right jsonpath.Path) jsonpath.Operation {
+  return jsonpath.Operation{
+    Type:  op,
+    Left:  left,
+    Right: right,
+  }
+}
+
+func unaryOp(op jsonpath.OperationType, left jsonpath.Path) jsonpath.Path {
+  if scalar, ok := maybeNormalizeUnaryOp(op, left); ok {
+    return scalar
+  }
+  return jsonpath.Operation{
+    Type:  op,
+    Left:  left,
+    Right: nil,
+  }
+}
+
+func maybeNormalizeUnaryOp(op jsonpath.OperationType, expr jsonpath.Path) (jsonpath.Scalar, bool) {
+  // Return if not unary plus or unary minus.
+  if op != jsonpath.OpPlus && op != jsonpath.OpMinus {
+    return jsonpath.Scalar{}, false
+  }
+
+  scalar, ok := extractNumericScalar(expr)
+  if !ok {
+    return jsonpath.Scalar{}, false
+  }
+  if op == jsonpath.OpMinus {
+    dec, _ := scalar.Value.AsDecimal()
+    dec.Neg(dec)
+    scalar.Value = json.FromDecimal(*dec)
+  }
+  return scalar, true
+}
+
+// extractNumericScalar attempts to extract a numeric scalar value from a
+// jsonpath.Path. It handles two cases:
+// - Direct scalar values.
+// - Scalar values wrapped in a jsonpath.Paths object of length 1.
+// The function returns the scalar and true if the path contains a valid numeric
+// value (integer or float), otherwise returns an empty scalar and false.
+func extractNumericScalar(expr jsonpath.Path) (jsonpath.Scalar, bool) {
+  potentialScalar := expr
+  if paths, ok := expr.(jsonpath.Paths); ok {
+    if len(paths) != 1 {
+      return jsonpath.Scalar{}, false
+    }
+    potentialScalar = paths[0]
+  }
+  scalar, ok := potentialScalar.(jsonpath.Scalar)
+  if !ok {
+    return jsonpath.Scalar{}, false
+  }
+  if scalar.Type != jsonpath.ScalarFloat && scalar.Type != jsonpath.ScalarInt {
+    return jsonpath.Scalar{}, false
+  }
+  return scalar, true
+}
+
+func regexBinaryOp(left jsonpath.Path, regex string, flags string) (jsonpath.Operation, error) {
+  goFlags, err := jsonpath.RegexFlagsToGoFlags(flags)
+  if err != nil {
+    return jsonpath.Operation{}, err
+  }
+  r := jsonpath.Regex{Regex: regex, Flags: goFlags}
+  _, err = ReCache.GetRegexpWithFlags(r, goFlags)
+  if err != nil {
+    return jsonpath.Operation{}, pgerror.Wrapf(err, pgcode.InvalidRegularExpression,
+      "invalid regular expression")
+  }
+  return binaryOp(jsonpath.OpLikeRegex, left, r), nil
+}
+
+%}
+
+%union{
+  id      int32
+  pos     int32
+  str     string
+  union   jsonpathSymUnion
+}
+
+/*
+ * Basic non-keyword token types.  These are hard-wired into the core lexer.
+ * They must be listed first so that their numeric codes do not depend on
+ * the set of keywords.  Keep this list in sync with backend/parser/gram.y!
+ *
+ * Some of these are not directly referenced in this file, but they must be
+ * here anyway.
+ */
+%token <str> IDENT UIDENT FCONST SCONST USCONST BCONST XCONST Op
+%token <*tree.NumVal> ICONST PARAM
+%token <str> TYPECAST DOT_DOT COLON_EQUALS EQUALS_GREATER
+%token <str> LESS_EQUALS GREATER_EQUALS NOT_EQUALS
+%token <str> ERROR
+
+%token <str> STRICT LAX
+%token <str> ROOT CURRENT
+%token <str> VARIABLE STR NULL
+%token <str> TRUE FALSE
+%token <str> EQUAL NOT_EQUAL LESS LESS_EQUAL GREATER GREATER_EQUAL
+%token <str> AND OR NOT
+%token <str> LIKE_REGEX FLAG
+%token <str> TO LAST
+%token <str> EXISTS IS UNKNOWN STARTS WITH
+%token <str> ANY
+%token <str> SIZE TYPE KEYVALUE
+%token <str> ABS CEILING FLOOR
+%token <str> BIGINT BOOLEAN DATE DOUBLE INTEGER NUMBER STRING
+%token <str> DECIMAL DATETIME TIME TIME_TZ TIMESTAMP TIMESTAMP_TZ
+
+%type <jsonpath.Jsonpath> jsonpath
+%type <jsonpath.Path> expr_or_predicate
+%type <jsonpath.Path> expr
+%type <jsonpath.Path> accessor_op
+%type <jsonpath.Path> path_primary
+%type <jsonpath.Path> key
+%type <jsonpath.Path> array_accessor
+%type <jsonpath.Path> scalar_value
+%type <jsonpath.Path> index_elem
+%type <jsonpath.Path> predicate
+%type <jsonpath.Path> delimited_predicate
+%type <jsonpath.Path> starts_with_initial
+%type <jsonpath.Path> method
+%type <[]jsonpath.Path> accessor_expr
+%type <[]jsonpath.Path> index_list
+%type <jsonpath.OperationType> comp_op
+%type <str> key_name
+%type <str> any_identifier
+%type <str> unreserved_keyword
+%type <bool> mode
+
+%left OR
+%left AND
+%right NOT
+
+%left '+' '-'
+%left '*' '/' '%'
+%left UMINUS
+
+%%
+
+jsonpath:
+  mode expr_or_predicate
+  {
+    jp := jsonpath.Jsonpath{Strict: $1.bool(), Path: $2.path()}
+    jsonpathlex.(*lexer).SetJsonpath(jp)
+  }
+;
+
+mode:
+  STRICT
+  {
+    $$.val = true
+  }
+| LAX
+  {
+    $$.val = false
+  }
+| /* empty */
+  {
+    $$.val = false
+  }
+;
+
+expr_or_predicate:
+  expr
+  {
+    $$.val = $1.path()
+  }
+| predicate
+  {
+    $$.val = $1.path()
+  }
+;
+
+expr:
+  accessor_expr
+  {
+    $$.val = jsonpath.Paths($1.pathArr())
+  }
+| '(' expr ')'
+  {
+    $$.val = $2.path()
+  }
+| '+' expr %prec UMINUS
+  {
+    $$.val = unaryOp(jsonpath.OpPlus, $2.path())
+  }
+| '-' expr %prec UMINUS
+  {
+    $$.val = unaryOp(jsonpath.OpMinus, $2.path())
+  }
+| expr '+' expr
+  {
+    $$.val = binaryOp(jsonpath.OpAdd, $1.path(), $3.path())
+  }
+| expr '-' expr
+  {
+    $$.val = binaryOp(jsonpath.OpSub, $1.path(), $3.path())
+  }
+| expr '*' expr
+  {
+    $$.val = binaryOp(jsonpath.OpMult, $1.path(), $3.path())
+  }
+| expr '/' expr
+  {
+    $$.val = binaryOp(jsonpath.OpDiv, $1.path(), $3.path())
+  }
+| expr '%' expr
+  {
+    $$.val = binaryOp(jsonpath.OpMod, $1.path(), $3.path())
+  }
+;
+
+accessor_expr:
+  path_primary
+  {
+    $$.val = []jsonpath.Path{$1.path()}
+  }
+| '(' expr ')' accessor_op
+  {
+    $$.val = []jsonpath.Path{$2.path(), $4.path()}
+  }
+| '(' predicate ')' accessor_op
+  {
+    $$.val = []jsonpath.Path{$2.path(), $4.path()}
+  }
+| accessor_expr accessor_op
+  {
+    $$.val = append($1.pathArr(), $2.path())
+  }
+;
+
+path_primary:
+  ROOT
+  {
+    $$.val = jsonpath.Root{}
+  }
+| CURRENT
+  {
+    $$.val = jsonpath.Current{}
+  }
+| scalar_value
+  {
+    $$.val = $1.path()
+  }
+| LAST
+  {
+    $$.val = jsonpath.Last{}
+  }
+;
+
+accessor_op:
+  '.' key
+  {
+    $$.val = $2.path()
+  }
+| array_accessor
+  {
+    $$.val = $1.path()
+  }
+| '?' '(' predicate ')'
+  {
+    $$.val = jsonpath.Filter{Condition: $3.path()}
+  }
+| '.' '*'
+  {
+    $$.val = jsonpath.AnyKey{}
+  }
+| '.' method '(' ')'
+  {
+    $$.val = $2.path()
+  }
+| '.' any_path
+  {
+    return unimplemented(jsonpathlex, ".**")
+  }
+| '.' DECIMAL '(' opt_csv_list ')'
+  {
+    return unimplemented(jsonpathlex, ".decimal()")
+  }
+| '.' DATETIME '(' opt_datetime_template ')'
+  {
+    return unimplemented(jsonpathlex, ".datetime()")
+  }
+| '.' TIME '(' opt_datetime_precision ')'
+  {
+    return unimplemented(jsonpathlex, ".time()")
+  }
+| '.' TIME_TZ '(' opt_datetime_precision ')'
+  {
+    return unimplemented(jsonpathlex, ".time_tz()")
+  }
+| '.' TIMESTAMP '(' opt_datetime_precision ')'
+  {
+    return unimplemented(jsonpathlex, ".timestamp()")
+  }
+| '.' TIMESTAMP_TZ '(' opt_datetime_precision ')'
+  {
+    return unimplemented(jsonpathlex, ".timestamp_tz()")
+  }
+;
+
+key:
+  key_name
+  {
+    $$.val = jsonpath.Key($1)
+  }
+;
+
+key_name:
+  any_identifier
+  {
+    $$ = $1
+  }
+;
+
+array_accessor:
+  '[' '*' ']'
+  {
+    $$.val = jsonpath.Wildcard{}
+  }
+| '[' index_list ']'
+  {
+    $$.val = $2.path()
+  }
+;
+
+index_list:
+  index_elem
+  {
+    $$.val = jsonpath.ArrayList{$1.path()}
+  }
+| index_list ',' index_elem
+  {
+    $$.val = append($1.arrayList(), $3.path())
+  }
+;
+
+index_elem:
+  expr
+  {
+    $$.val = $1.path()
+  }
+| expr TO expr
+  {
+    $$.val = jsonpath.ArrayIndexRange{
+      Start: $1.path(),
+      End: $3.path(),
+    }
+  }
+;
+
+predicate:
+  delimited_predicate
+  {
+    $$.val = $1.path()
+  }
+| expr comp_op expr
+  {
+    $$.val = binaryOp($2.operationType(), $1.path(), $3.path())
+  }
+| predicate AND predicate
+  {
+    $$.val = binaryOp(jsonpath.OpLogicalAnd, $1.path(), $3.path())
+  }
+| predicate OR predicate
+  {
+    $$.val = binaryOp(jsonpath.OpLogicalOr, $1.path(), $3.path())
+  }
+| NOT delimited_predicate
+  {
+    $$.val = unaryOp(jsonpath.OpLogicalNot, $2.path())
+  }
+| '(' predicate ')' IS UNKNOWN
+  {
+    $$.val = unaryOp(jsonpath.OpIsUnknown, $2.path())
+  }
+| expr STARTS WITH starts_with_initial
+  {
+    $$.val = binaryOp(jsonpath.OpStartsWith, $1.path(), $4.path())
+  }
+| expr LIKE_REGEX STR
+  {
+    regex, err := regexBinaryOp($1.path(), $3, "")
+    if err != nil {
+      return setErr(jsonpathlex, err)
+    }
+    $$.val = regex
+  }
+| expr LIKE_REGEX STR FLAG STR
+  {
+    regex, err := regexBinaryOp($1.path(), $3, $5)
+    if err != nil {
+      return setErr(jsonpathlex, err)
+    }
+    $$.val = regex
+  }
+;
+
+delimited_predicate:
+  '(' predicate ')'
+  {
+    $$.val = $2.path()
+  }
+| EXISTS '(' expr ')'
+  {
+    $$.val = unaryOp(jsonpath.OpExists, $3.path())
+  }
+;
+
+starts_with_initial:
+  STR
+  {
+    $$.val = jsonpath.Scalar{Type: jsonpath.ScalarString, Value: json.FromString($1)}
+  }
+| VARIABLE
+  {
+    $$.val = jsonpath.Scalar{Type: jsonpath.ScalarVariable, Variable: $1}
+  }
+;
+
+comp_op:
+  EQUAL
+  {
+    $$.val = jsonpath.OpCompEqual
+  }
+| NOT_EQUAL
+  {
+    $$.val = jsonpath.OpCompNotEqual
+  }
+| LESS
+  {
+    $$.val = jsonpath.OpCompLess
+  }
+| LESS_EQUAL
+  {
+    $$.val = jsonpath.OpCompLessEqual
+  }
+| GREATER
+  {
+    $$.val = jsonpath.OpCompGreater
+  }
+| GREATER_EQUAL
+  {
+    $$.val = jsonpath.OpCompGreaterEqual
+  }
+;
+
+method:
+  SIZE
+  {
+    $$.val = jsonpath.Method{Type: jsonpath.SizeMethod}
+  }
+| TYPE
+  {
+    $$.val = jsonpath.Method{Type: jsonpath.TypeMethod}
+  }
+| KEYVALUE
+  {
+    return unimplemented(jsonpathlex, ".keyvalue()")
+  }
+| ABS
+  {
+    $$.val = jsonpath.Method{Type: jsonpath.AbsMethod}
+  }
+| CEILING
+  {
+    $$.val = jsonpath.Method{Type: jsonpath.CeilingMethod}
+  }
+| FLOOR
+  {
+    $$.val = jsonpath.Method{Type: jsonpath.FloorMethod}
+  }
+| BIGINT
+  {
+    return unimplemented(jsonpathlex, ".bigint()")
+  }
+| BOOLEAN
+  {
+    return unimplemented(jsonpathlex, ".boolean()")
+  }
+| DATE
+  {
+    return unimplemented(jsonpathlex, ".date()")
+  }
+| DOUBLE
+  {
+    return unimplemented(jsonpathlex, ".double()")
+  }
+| INTEGER
+  {
+    return unimplemented(jsonpathlex, ".integer()")
+  }
+| NUMBER
+  {
+    return unimplemented(jsonpathlex, ".number()")
+  }
+| STRING
+  {
+    return unimplemented(jsonpathlex, ".string()")
+  }
+;
+
+any_path:
+  ANY
+  {
+    // Unimplemented from .**.
+  }
+| ANY '{' any_level '}'
+  {
+    // Unimplemented from .**.
+  }
+| ANY '{' any_level TO any_level '}'
+  {
+    // Unimplemented from .**.
+  }
+;
+
+any_level:
+  ICONST
+  {
+    // Unimplemented from .**.
+  }
+| LAST
+  {
+    // Unimplemented from .**.
+  }
+;
+
+opt_csv_list:
+  csv_list
+  {
+    // Unimplemented from .decimal().
+  }
+| /* empty */
+  {
+    // Unimplemented from .decimal().
+  }
+;
+
+csv_list:
+  csv_elem
+  {
+    // Unimplemented from .decimal().
+  }
+| csv_list ',' csv_elem
+  {
+    // Unimplemented from .decimal().
+  }
+;
+
+csv_elem:
+  ICONST
+  {
+    // Unimplemented from .decimal().
+  }
+| '+' ICONST %prec UMINUS
+  {
+    // Unimplemented from .decimal().
+  }
+| '-' ICONST %prec UMINUS
+  {
+    // Unimplemented from .decimal().
+  }
+;
+
+opt_datetime_template:
+  datetime_template
+  {
+    // Unimplemented from .datetime().
+  }
+| /* empty */
+  {
+    // Unimplemented from .datetime().
+  }
+;
+
+datetime_template:
+  STR
+  {
+    // Unimplemented from .datetime().
+  }
+;
+
+opt_datetime_precision:
+  datetime_precision
+  {
+    // Unimplemented from .time(), time_tz(), .timestamp(), .timestamp_tz().
+  }
+| /* empty */
+  {
+    // Unimplemented from .time(), time_tz(), .timestamp(), .timestamp_tz().
+  }
+;
+
+datetime_precision:
+  ICONST
+  {
+    // Unimplemented from .time(), time_tz(), .timestamp(), .timestamp_tz().
+  }
+;
+
+scalar_value:
+  VARIABLE
+  {
+    $$.val = jsonpath.Scalar{Type: jsonpath.ScalarVariable, Variable: $1}
+  }
+| ICONST
+  {
+    i, err := $1.numVal().AsInt64()
+    if err != nil {
+      return setErr(jsonpathlex, err)
+    }
+    $$.val = jsonpath.Scalar{Type: jsonpath.ScalarInt, Value: json.FromInt64(i)}
+  }
+| FCONST
+  {
+    f, err := strconv.ParseFloat($1, 64)
+    if err != nil {
+      return setErr(jsonpathlex, err)
+    }
+    j, err := json.FromFloat64(f)
+    if err != nil {
+      return setErr(jsonpathlex, err)
+    }
+    $$.val = jsonpath.Scalar{Type: jsonpath.ScalarFloat, Value: j}
+  }
+| TRUE
+  {
+    $$.val = jsonpath.Scalar{Type: jsonpath.ScalarBool, Value: json.FromBool(true)}
+  }
+| FALSE
+  {
+    $$.val = jsonpath.Scalar{Type: jsonpath.ScalarBool, Value: json.FromBool(false)}
+  }
+| STR
+  {
+    $$.val = jsonpath.Scalar{Type: jsonpath.ScalarString, Value: json.FromString($1)}
+  }
+| NULL
+  {
+    $$.val = jsonpath.Scalar{Type: jsonpath.ScalarNull, Value: json.NullJSONValue}
+  }
+;
+
+any_identifier:
+  IDENT
+| STR
+| unreserved_keyword
+;
+
+unreserved_keyword:
+  ABS
+| BIGINT
+| BOOLEAN
+| CEILING
+| DATE
+| DATETIME
+| DECIMAL
+| DOUBLE
+| EXISTS
+| FALSE
+| FLAG
+| FLOOR
+| INTEGER
+| IS
+| KEYVALUE
+| LAST
+| LAX
+| LIKE_REGEX
+| NULL
+| NUMBER
+| SIZE
+| STARTS
+| STRICT
+| STRING
+| TIME
+| TIMESTAMP
+| TIMESTAMP_TZ
+| TIME_TZ
+| TO
+| TRUE
+| TYPE
+| UNKNOWN
+| WITH
+;
+
+%%
diff --git a/pkg/util/jsonpath/parser/lexbase/.gitignore b/pkg/util/jsonpath/parser/lexbase/.gitignore
new file mode 100644
index 0000000..1b383d0
--- /dev/null
+++ b/pkg/util/jsonpath/parser/lexbase/.gitignore
@@ -0,0 +1,2 @@
+keywords.go
+tokens.go
diff --git a/pkg/util/jsonpath/parser/lexbase/keywords.go b/pkg/util/jsonpath/parser/lexbase/keywords.go
new file mode 100644
index 0000000..b29c620
--- /dev/null
+++ b/pkg/util/jsonpath/parser/lexbase/keywords.go
@@ -0,0 +1,122 @@
+// Code generated by pkg/sql/lexbase/allkeywords. DO NOT EDIT.
+
+package lexbase
+
+var KeywordsCategories = map[string]string{
+"abs": "U",
+"bigint": "U",
+"boolean": "U",
+"ceiling": "U",
+"date": "U",
+"datetime": "U",
+"decimal": "U",
+"double": "U",
+"exists": "U",
+"false": "U",
+"flag": "U",
+"floor": "U",
+"integer": "U",
+"is": "U",
+"keyvalue": "U",
+"last": "U",
+"lax": "U",
+"like_regex": "U",
+"null": "U",
+"number": "U",
+"size": "U",
+"starts": "U",
+"strict": "U",
+"string": "U",
+"time": "U",
+"timestamp": "U",
+"timestamp_tz": "U",
+"time_tz": "U",
+"to": "U",
+"true": "U",
+"type": "U",
+"unknown": "U",
+"with": "U",
+}
+
+// KeywordNames contains all keywords sorted, so that pg_get_keywords returns
+// deterministic results.
+var KeywordNames = []string{
+"abs",
+"bigint",
+"boolean",
+"ceiling",
+"date",
+"datetime",
+"decimal",
+"double",
+"exists",
+"false",
+"flag",
+"floor",
+"integer",
+"is",
+"keyvalue",
+"last",
+"lax",
+"like_regex",
+"null",
+"number",
+"size",
+"starts",
+"strict",
+"string",
+"time",
+"timestamp",
+"timestamp_tz",
+"time_tz",
+"to",
+"true",
+"type",
+"unknown",
+"with",
+}
+
+// GetKeywordID returns the lex id of the SQL keyword k or IDENT if k is
+// not a keyword.
+func GetKeywordID(k string) int32 {
+	// The previous implementation generated a map that did a string ->
+	// id lookup. Various ideas were benchmarked and the implementation below
+	// was the fastest of those, between 3% and 10% faster (at parsing, so the
+	// scanning speedup is even more) than the map implementation.
+	switch k {
+	case "abs": return ABS
+	case "bigint": return BIGINT
+	case "boolean": return BOOLEAN
+	case "ceiling": return CEILING
+	case "date": return DATE
+	case "datetime": return DATETIME
+	case "decimal": return DECIMAL
+	case "double": return DOUBLE
+	case "exists": return EXISTS
+	case "false": return FALSE
+	case "flag": return FLAG
+	case "floor": return FLOOR
+	case "integer": return INTEGER
+	case "is": return IS
+	case "keyvalue": return KEYVALUE
+	case "last": return LAST
+	case "lax": return LAX
+	case "like_regex": return LIKE_REGEX
+	case "null": return NULL
+	case "number": return NUMBER
+	case "size": return SIZE
+	case "starts": return STARTS
+	case "strict": return STRICT
+	case "string": return STRING
+	case "time": return TIME
+	case "timestamp": return TIMESTAMP
+	case "timestamp_tz": return TIMESTAMP_TZ
+	case "time_tz": return TIME_TZ
+	case "to": return TO
+	case "true": return TRUE
+	case "type": return TYPE
+	case "unknown": return UNKNOWN
+	case "with": return WITH
+	default: return IDENT
+	}
+}
diff --git a/pkg/util/jsonpath/parser/lexbase/tokens.go b/pkg/util/jsonpath/parser/lexbase/tokens.go
new file mode 100644
index 0000000..ecea4e8
--- /dev/null
+++ b/pkg/util/jsonpath/parser/lexbase/tokens.go
@@ -0,0 +1,70 @@
+// Code generated by make. DO NOT EDIT.
+// GENERATED FILE DO NOT EDIT
+
+package lexbase
+
+const IDENT = 57346
+const UIDENT = 57347
+const FCONST = 57348
+const SCONST = 57349
+const USCONST = 57350
+const BCONST = 57351
+const XCONST = 57352
+const ICONST = 57354
+const PARAM = 57355
+const TYPECAST = 57356
+const DOT_DOT = 57357
+const COLON_EQUALS = 57358
+const EQUALS_GREATER = 57359
+const LESS_EQUALS = 57360
+const GREATER_EQUALS = 57361
+const NOT_EQUALS = 57362
+const ERROR = 57363
+const STRICT = 57364
+const LAX = 57365
+const ROOT = 57366
+const CURRENT = 57367
+const VARIABLE = 57368
+const STR = 57369
+const NULL = 57370
+const TRUE = 57371
+const FALSE = 57372
+const EQUAL = 57373
+const NOT_EQUAL = 57374
+const LESS = 57375
+const LESS_EQUAL = 57376
+const GREATER = 57377
+const GREATER_EQUAL = 57378
+const AND = 57379
+const OR = 57380
+const NOT = 57381
+const LIKE_REGEX = 57382
+const FLAG = 57383
+const TO = 57384
+const LAST = 57385
+const EXISTS = 57386
+const IS = 57387
+const UNKNOWN = 57388
+const STARTS = 57389
+const WITH = 57390
+const ANY = 57391
+const SIZE = 57392
+const TYPE = 57393
+const KEYVALUE = 57394
+const ABS = 57395
+const CEILING = 57396
+const FLOOR = 57397
+const BIGINT = 57398
+const BOOLEAN = 57399
+const DATE = 57400
+const DOUBLE = 57401
+const INTEGER = 57402
+const NUMBER = 57403
+const STRING = 57404
+const DECIMAL = 57405
+const DATETIME = 57406
+const TIME = 57407
+const TIME_TZ = 57408
+const TIMESTAMP = 57409
+const TIMESTAMP_TZ = 57410
+const UMINUS = 57411
diff --git a/pkg/util/jsonpath/parser/lexbase/utils.go b/pkg/util/jsonpath/parser/lexbase/utils.go
new file mode 100644
index 0000000..2649446
--- /dev/null
+++ b/pkg/util/jsonpath/parser/lexbase/utils.go
@@ -0,0 +1,6 @@
+// Copyright 2025 The Cockroach Authors.
+//
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
+
+package lexbase
diff --git a/pkg/util/jsonpath/parser/lexer.go b/pkg/util/jsonpath/parser/lexer.go
new file mode 100644
index 0000000..d290560
--- /dev/null
+++ b/pkg/util/jsonpath/parser/lexer.go
@@ -0,0 +1,109 @@
+// Copyright 2025 The Cockroach Authors.
+//
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
+
+package parser
+
+import (
+	"strings"
+
+	"github.com/cockroachdb/cockroachdb-parser/pkg/sql/parser"
+	"github.com/cockroachdb/cockroachdb-parser/pkg/sql/pgwire/pgcode"
+	"github.com/cockroachdb/cockroachdb-parser/pkg/sql/pgwire/pgerror"
+	"github.com/cockroachdb/cockroachdb-parser/pkg/sql/sem/tree"
+	unimp "github.com/cockroachdb/cockroachdb-parser/pkg/util/errorutil/unimplemented"
+	"github.com/cockroachdb/cockroachdb-parser/pkg/util/jsonpath"
+	"github.com/cockroachdb/errors"
+)
+
+type lexer struct {
+	in string
+	// tokens contains tokens generated by the scanner.
+	tokens []jsonpathSymType
+
+	// lastPos is the position into the tokens slice of the last
+	// token returned by Lex().
+	lastPos int
+
+	expr *jsonpath.Jsonpath
+
+	lastError error
+
+	parser jsonpathParser
+}
+
+func (l *lexer) init(sql string, tokens []jsonpathSymType, p jsonpathParser) {
+	l.in = sql
+	l.tokens = tokens
+	l.lastPos = -1
+	l.expr = nil
+	l.lastError = nil
+	l.parser = p
+}
+
+// cleanup is used to avoid holding on to memory unnecessarily (for the cases
+// where we reuse a scanner).
+func (l *lexer) cleanup() {
+	l.tokens = nil
+	l.expr = nil
+	l.lastError = nil
+}
+
+func (l *lexer) lastToken() jsonpathSymType {
+	if l.lastPos < 0 {
+		return jsonpathSymType{}
+	}
+
+	if l.lastPos >= len(l.tokens) {
+		return jsonpathSymType{
+			id:  0,
+			pos: int32(len(l.in)),
+			str: "EOF",
+		}
+	}
+	return l.tokens[l.lastPos]
+}
+
+// Lex implements the jsonpathLexer interface.
+func (l *lexer) Lex(lval *jsonpathSymType) int {
+	l.lastPos++
+	if l.lastPos >= len(l.tokens) {
+		lval.id = 0
+		lval.pos = int32(len(l.in))
+		lval.str = "EOF"
+		return 0
+	}
+	*lval = l.tokens[l.lastPos]
+	return int(lval.id)
+}
+
+// Error implements the jsonpathLexer interface.
+func (l *lexer) Error(s string) {
+	s = strings.TrimPrefix(s, "syntax error: ") // we'll add it again below.
+	err := pgerror.WithCandidateCode(errors.Newf("%s", s), pgcode.Syntax)
+	lastTok := l.lastToken()
+	l.lastError = parser.PopulateErrorDetails(lastTok.id, lastTok.str, lastTok.pos, err, l.in)
+}
+
+func (l *lexer) SetJsonpath(expr jsonpath.Jsonpath) {
+	l.expr = &expr
+}
+
+func (l *lexer) setErr(err error) {
+	err = pgerror.WithCandidateCode(err, pgcode.Syntax)
+	l.lastError = err
+	lastTok := l.lastToken()
+	l.lastError = parser.PopulateErrorDetails(lastTok.id, lastTok.str, lastTok.pos, l.lastError, l.in)
+}
+
+func (l *lexer) Unimplemented(feature string) {
+	// Link to meta-issue for unimplemented JSONPath features.
+	l.lastError = unimp.NewWithIssuef(22513, "this syntax: %s", feature)
+	lastTok := l.lastToken()
+	l.lastError = parser.PopulateErrorDetails(lastTok.id, lastTok.str, lastTok.pos, l.lastError, l.in)
+	l.lastError = &tree.UnsupportedError{
+		Err:         l.lastError,
+		FeatureName: feature,
+	}
+}
diff --git a/pkg/util/jsonpath/parser/parse.go b/pkg/util/jsonpath/parser/parse.go
new file mode 100644
index 0000000..ed975ec
--- /dev/null
+++ b/pkg/util/jsonpath/parser/parse.go
@@ -0,0 +1,115 @@
+// Copyright 2025 The Cockroach Authors.
+//
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
+
+package parser
+
+import (
+	"github.com/cockroachdb/cockroachdb-parser/pkg/sql/parser/statements"
+	"github.com/cockroachdb/cockroachdb-parser/pkg/sql/scanner"
+	"github.com/cockroachdb/cockroachdb-parser/pkg/sql/sem/tree"
+	"github.com/cockroachdb/cockroachdb-parser/pkg/util/jsonpath"
+	"github.com/cockroachdb/errors"
+)
+
+func init() {
+	tree.ValidateJSONPath = func(jsonpath string) (*jsonpath.Jsonpath, error) {
+		jp, err := Parse(jsonpath)
+		if err != nil {
+			return nil, err
+		}
+		return jp.AST, nil
+	}
+}
+
+var (
+	ReCache = tree.NewRegexpCache(64)
+)
+
+type Parser struct {
+	scanner    scanner.JSONPathScanner
+	lexer      lexer
+	parserImpl jsonpathParserImpl
+}
+
+func (p *Parser) scan() (query string, tokens []jsonpathSymType, done bool) {
+	var lval jsonpathSymType
+
+	p.scanner.Scan(&lval)
+	if lval.id == 0 {
+		return "", nil, true
+	}
+
+	startPos := lval.pos
+
+	lval.pos = 0
+	tokens = append(tokens, lval)
+	var posBeforeScan int
+	for {
+		if lval.id == ERROR {
+			return p.scanner.In()[startPos:], tokens, true
+		}
+		lval = jsonpathSymType{}
+		posBeforeScan = p.scanner.Pos()
+		p.scanner.Scan(&lval)
+		if lval.id == 0 {
+			return p.scanner.In()[startPos:posBeforeScan], tokens, (lval.id == 0)
+		}
+		lval.pos -= startPos
+		tokens = append(tokens, lval)
+	}
+}
+
+// parse parses a statement from the given scanned tokens.
+func (p *Parser) parse(
+	query string, tokens []jsonpathSymType,
+) (statements.JsonpathStatement, error) {
+	p.lexer.init(query, tokens, &p.parserImpl)
+	defer p.lexer.cleanup()
+	if p.parserImpl.Parse(&p.lexer) != 0 {
+		if p.lexer.lastError == nil {
+			// This should never happen -- there should be an error object
+			// every time Parse() returns nonzero. We're just playing safe
+			// here.
+			p.lexer.Error("syntax error")
+		}
+		err := p.lexer.lastError
+		return statements.JsonpathStatement{}, err
+	}
+	return statements.JsonpathStatement{
+		AST: p.lexer.expr,
+		SQL: query,
+	}, nil
+}
+
+func (p *Parser) Parse(jsonpath string) (statements.JsonpathStatement, error) {
+	p.scanner.Init(jsonpath)
+	defer p.scanner.Cleanup()
+
+	query, tokens, done := p.scan()
+	if !done {
+		return statements.JsonpathStatement{}, errors.AssertionFailedf("invalid jsonpath query: %s", jsonpath)
+	}
+
+	stmt, err := p.parse(query, tokens)
+	if err != nil {
+		return statements.JsonpathStatement{}, err
+	}
+	return stmt, nil
+}
+
+// Parse parses a jsonpath string and returns a jsonpath.Jsonpath object.
+func Parse(path string) (statements.JsonpathStatement, error) {
+	var p Parser
+	stmt, err := p.Parse(path)
+	if err != nil {
+		return statements.JsonpathStatement{}, err
+	}
+	// Similar to flattenJsonPathParseItem in postgres, we do a pass over the AST
+	// to perform some semantic checks.
+	if err := stmt.AST.Validate(); err != nil {
+		return statements.JsonpathStatement{}, err
+	}
+	return stmt, nil
+}
diff --git a/pkg/util/jsonpath/path.go b/pkg/util/jsonpath/path.go
new file mode 100644
index 0000000..060faeb
--- /dev/null
+++ b/pkg/util/jsonpath/path.go
@@ -0,0 +1,279 @@
+// Copyright 2025 The Cockroach Authors.
+//
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
+
+package jsonpath
+
+import (
+	"fmt"
+	"regexp/syntax"
+	"strings"
+
+	"github.com/cockroachdb/cockroachdb-parser/pkg/sql/pgwire/pgcode"
+	"github.com/cockroachdb/cockroachdb-parser/pkg/sql/pgwire/pgerror"
+)
+
+var (
+	errCurrentInRoot = pgerror.Newf(pgcode.Syntax,
+		"@ is not allowed in root expressions")
+	errLastInNonArray = pgerror.Newf(pgcode.Syntax,
+		"LAST is allowed only in array subscripts")
+	errRegexXFlag = pgerror.Newf(pgcode.FeatureNotSupported,
+		"XQuery \"x\" flag (expanded regular expressions) is not implemented")
+)
+
+type Path interface {
+	// ToString appends the string representation of the path to the given
+	// strings.Builder. This implementation matches
+	// postgres/src/backend/utils/adt/jsonpath.c:printJsonPathItem().
+	ToString(sb *strings.Builder, inKey, printBrackets bool)
+
+	// Validate returns an error if there is a semantic error in the path, and
+	// collects all variable names in a map with a strictly increasing index,
+	// indicating the order of their first appearance. Leaf nodes should generally
+	// return nil.
+	Validate(nestingLevel int, insideArraySubscript bool) error
+}
+
+type Root struct{}
+
+var _ Path = &Root{}
+
+func (r Root) ToString(sb *strings.Builder, _, _ bool) {
+	sb.WriteString("$")
+}
+
+func (r Root) Validate(nestingLevel int, insideArraySubscript bool) error {
+	return nil
+}
+
+type Key string
+
+var _ Path = Key("")
+
+func (k Key) ToString(sb *strings.Builder, inKey, _ bool) {
+	if inKey {
+		sb.WriteString(".")
+	}
+	sb.WriteString(fmt.Sprintf("%q", string(k)))
+}
+
+func (k Key) Validate(nestingLevel int, insideArraySubscript bool) error {
+	return nil
+}
+
+type Wildcard struct{}
+
+var _ Path = &Wildcard{}
+
+func (w Wildcard) ToString(sb *strings.Builder, _, _ bool) {
+	sb.WriteString("[*]")
+}
+
+func (w Wildcard) Validate(nestingLevel int, insideArraySubscript bool) error {
+	return nil
+}
+
+type Paths []Path
+
+var _ Path = &Paths{}
+
+func (p Paths) ToString(sb *strings.Builder, _, _ bool) {
+	for _, path := range p {
+		path.ToString(sb, true /* inKey */, true /* printBrackets */)
+	}
+}
+
+func (p Paths) Validate(nestingLevel int, insideArraySubscript bool) error {
+	for _, p := range p {
+		if err := p.Validate(nestingLevel, insideArraySubscript); err != nil {
+			return err
+		}
+	}
+	return nil
+}
+
+type ArrayIndexRange struct {
+	Start Path
+	End   Path
+}
+
+var _ Path = ArrayIndexRange{}
+
+func (a ArrayIndexRange) ToString(sb *strings.Builder, _, _ bool) {
+	a.Start.ToString(sb, false /* inKey */, false /* printBrackets */)
+	sb.WriteString(" to ")
+	a.End.ToString(sb, false /* inKey */, false /* printBrackets */)
+}
+
+func (a ArrayIndexRange) Validate(nestingLevel int, insideArraySubscript bool) error {
+	if err := a.Start.Validate(nestingLevel, insideArraySubscript); err != nil {
+		return err
+	}
+	if err := a.End.Validate(nestingLevel, insideArraySubscript); err != nil {
+		return err
+	}
+	return nil
+}
+
+type ArrayList []Path
+
+var _ Path = ArrayList{}
+
+func (a ArrayList) ToString(sb *strings.Builder, _, _ bool) {
+	sb.WriteString("[")
+	for i, path := range a {
+		if i > 0 {
+			sb.WriteString(",")
+		}
+		path.ToString(sb, false /* inKey */, false /* printBrackets */)
+	}
+	sb.WriteString("]")
+}
+
+func (a ArrayList) Validate(nestingLevel int, insideArraySubscript bool) error {
+	for _, p := range a {
+		if err := p.Validate(nestingLevel, true /* insideArraySubscript */); err != nil {
+			return err
+		}
+	}
+	return nil
+}
+
+type Last struct{}
+
+var _ Path = Last{}
+
+func (l Last) ToString(sb *strings.Builder, _, _ bool) {
+	sb.WriteString("last")
+}
+
+func (l Last) Validate(nestingLevel int, insideArraySubscript bool) error {
+	if !insideArraySubscript {
+		return errLastInNonArray
+	}
+	return nil
+}
+
+type Filter struct {
+	Condition Path
+}
+
+var _ Path = Filter{}
+
+func (f Filter) ToString(sb *strings.Builder, _, _ bool) {
+	sb.WriteString("?(")
+	f.Condition.ToString(sb, false /* inKey */, false /* printBrackets */)
+	sb.WriteString(")")
+}
+
+func (f Filter) Validate(nestingLevel int, insideArraySubscript bool) error {
+	return f.Condition.Validate(nestingLevel+1, insideArraySubscript)
+}
+
+type Current struct{}
+
+var _ Path = Current{}
+
+func (c Current) ToString(sb *strings.Builder, _, _ bool) {
+	sb.WriteString("@")
+}
+
+func (c Current) Validate(nestingLevel int, insideArraySubscript bool) error {
+	if nestingLevel <= 0 {
+		return errCurrentInRoot
+	}
+	return nil
+}
+
+type Regex struct {
+	Regex string
+	Flags syntax.Flags
+}
+
+var _ Path = Regex{}
+
+func (r Regex) ToString(sb *strings.Builder, _, _ bool) {
+	sb.WriteString(fmt.Sprintf("%q", r.Regex))
+	if r.Flags != syntax.Perl {
+		sb.WriteString(" flag ")
+		sb.WriteString(fmt.Sprintf("%q", flagsToString(r.Flags)))
+	}
+}
+
+func flagsToString(flags syntax.Flags) string {
+	s := ""
+	if flags&syntax.FoldCase != 0 {
+		s += "i"
+	}
+	if flags&syntax.DotNL != 0 {
+		s += "s"
+	}
+	// Check if the `OneLine` flag is not set.
+	if flags&syntax.OneLine == 0 {
+		s += "m"
+	}
+	if flags&syntax.Literal != 0 {
+		s += "q"
+	}
+	return s
+}
+
+// RegexFlagsToGoFlags converts a string of flags from `like_regex` to syntax.Flags,
+// to match the flags provided by Postgres' `like_regex` flag interface.
+//
+// The following flags are defined in Postgres:
+// - i: case-insensitive
+// - s: dot matches newline
+// - m: ^ and $ match at newlines
+// - x: ignore whitespace in pattern (this flag is defined, but not accepted)
+// - q: no special characters
+func RegexFlagsToGoFlags(flags string) (syntax.Flags, error) {
+	// syntax.Perl is the default flag for regexp.Compile.
+	goFlags := syntax.Perl
+	for _, c := range flags {
+		switch c {
+		case 'i':
+			goFlags |= syntax.FoldCase
+		case 's':
+			goFlags |= syntax.DotNL
+		case 'm':
+			// Bit clear the `OneLine` flag, since we want to match at newlines.
+			// This is turned on by default in `syntax.Perl`.
+			goFlags &^= syntax.OneLine
+		case 'x':
+			// `x` flag is not supported in Postgres.
+			return syntax.Flags(0), errRegexXFlag
+		case 'q':
+			goFlags |= syntax.Literal
+		default:
+			return syntax.Flags(0), pgerror.Newf(pgcode.Syntax, "unrecognized flag character %q in LIKE_REGEX predicate", c)
+		}
+	}
+	return goFlags, nil
+}
+
+func (r Regex) Validate(nestingLevel int, insideArraySubscript bool) error {
+	return nil
+}
+
+// Pattern implements the tree.RegexpCacheKey interface.
+func (r Regex) Pattern() (string, error) {
+	return r.Regex, nil
+}
+
+type AnyKey struct{}
+
+var _ Path = AnyKey{}
+
+func (a AnyKey) ToString(sb *strings.Builder, inKey, _ bool) {
+	if inKey {
+		sb.WriteString(".")
+	}
+	sb.WriteString("*")
+}
+
+func (a AnyKey) Validate(nestingLevel int, insideArraySubscript bool) error {
+	return nil
+}
diff --git a/pkg/util/jsonpath/scalar.go b/pkg/util/jsonpath/scalar.go
new file mode 100644
index 0000000..68dfd51
--- /dev/null
+++ b/pkg/util/jsonpath/scalar.go
@@ -0,0 +1,50 @@
+// Copyright 2025 The Cockroach Authors.
+//
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
+
+package jsonpath
+
+import (
+	"fmt"
+	"strings"
+
+	"github.com/cockroachdb/cockroachdb-parser/pkg/util/json"
+	"github.com/cockroachdb/errors"
+)
+
+type ScalarType int
+
+const (
+	ScalarInt ScalarType = iota
+	ScalarFloat
+	ScalarString
+	ScalarBool
+	ScalarNull
+	ScalarVariable
+)
+
+type Scalar struct {
+	Type     ScalarType
+	Value    json.JSON
+	Variable string
+}
+
+var _ Path = Scalar{}
+
+func (s Scalar) ToString(sb *strings.Builder, _, _ bool) {
+	switch s.Type {
+	case ScalarInt, ScalarFloat, ScalarString, ScalarBool, ScalarNull:
+		sb.WriteString(s.Value.String())
+		return
+	case ScalarVariable:
+		sb.WriteString(fmt.Sprintf("$%q", s.Variable))
+		return
+	default:
+		panic(errors.AssertionFailedf("unhandled scalar type: %d", s.Type))
+	}
+}
+
+func (s Scalar) Validate(nestingLevel int, insideArraySubscript bool) error {
+	return nil
+}
diff --git a/pkg/util/log/eventpb/eventpbgen/gen.go b/pkg/util/log/eventpb/eventpbgen/gen.go
index 0ff9948..396506e 100644
--- a/pkg/util/log/eventpb/eventpbgen/gen.go
+++ b/pkg/util/log/eventpb/eventpbgen/gen.go
@@ -1,12 +1,7 @@
 // Copyright 2020 The Cockroach Authors.
 //
-// Use of this software is governed by the Business Source License
-// included in the file licenses/BSL.txt.
-//
-// As of the Change Date specified in that file, in accordance with
-// the Business Source License, use of this software will be governed
-// by the Apache License, Version 2.0, included in the file
-// licenses/APL.txt.
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
 
 package main
 
@@ -84,6 +79,7 @@ type fieldInfo struct {
 	Inherited           bool
 	IsEnum              bool
 	AllowZeroValue      bool
+	NotNullable         bool
 }
 
 var (
@@ -380,6 +376,8 @@ func readInput(
 				return errors.Newf("unknown field definition syntax: %q", line)
 			}
 
+			notNullable := notNullableRe.MatchString(line)
+
 			// Allow zero values if the field is annotated with 'includeempty'.
 			allowZeroValue := strings.Contains(line, "includeempty")
 
@@ -389,6 +387,12 @@ func readInput(
 				typ = "timestamp"
 			case "cockroach.sql.sqlbase.Descriptor":
 				typ = "protobuf"
+			case "MVCCIteratorStats":
+				fallthrough
+			case "SampledExecStats":
+				// This is necessary so that the fields in the
+				// message doesn't get inlined.
+				typ = "nestedMessage"
 			}
 
 			if otherMsg, ok := infos[typ]; ok {
@@ -455,6 +459,7 @@ func readInput(
 					MixedRedactable:     mixed,
 					IsEnum:              isEnum,
 					AllowZeroValue:      allowZeroValue,
+					NotNullable:         notNullable,
 				}
 				curMsg.Fields = append(curMsg.Fields, fi)
 				curMsg.AllFields = append(curMsg.AllFields, fi)
@@ -486,6 +491,8 @@ var fieldDefRe = regexp.MustCompile(`\s*(?P<typ>[a-z._A-Z0-9]+)` +
 
 var reservedDefRe = regexp.MustCompile(`\s*(reserved ([1-9][0-9]*);)`)
 
+var notNullableRe = regexp.MustCompile(`\s*\(\s*gogoproto\.nullable\s*\)\s*=\s*false`)
+
 func camelToSnake(typeName string) string {
 	var res strings.Builder
 	res.WriteByte(typeName[0] + 'a' - 'A')
@@ -595,7 +602,8 @@ func (m *{{.GoType}}) AppendJSONFields(printComma bool, b redact.RedactableBytes
    if m.{{.FieldName}} {
    {{- end }}
      if printComma { b = append(b, ',')}; printComma = true
-     b = append(b, "\"{{.FieldName}}\":true"...)
+     b = append(b, "\"{{.FieldName}}\":"...)
+     b = strconv.AppendBool(b, m.{{.FieldName}})
    {{ if not .AllowZeroValue -}}
    }
    {{- end }}
@@ -659,6 +667,16 @@ func (m *{{.GoType}}) AppendJSONFields(printComma bool, b redact.RedactableBytes
      }
      b = append(b, ']')
    }
+   {{- else if eq .FieldType "array_of_uint64" -}}
+   if len(m.{{.FieldName}}) > 0 {
+     if printComma { b = append(b, ',')}; printComma = true
+     b = append(b, "\"{{.FieldName}}\":["...)
+     for i, v := range m.{{.FieldName}} {
+       if i > 0 { b = append(b, ',') }
+       b = strconv.AppendUint(b, uint64(v), 10)
+     }
+     b = append(b, ']')
+   }
    {{- else if .IsEnum }}
    {{ if not .AllowZeroValue -}}
    if m.{{.FieldName}} != 0 {
@@ -694,6 +712,18 @@ func (m *{{.GoType}}) AppendJSONFields(printComma bool, b redact.RedactableBytes
        b = append(b, []byte(str)...)
      }
    }
+   {{- else if eq .FieldType "nestedMessage"}}
+   {{ if not .NotNullable -}}
+   if m.{{.FieldName}} != nil {
+   {{- end }}
+     if printComma { b = append(b, ',')}; printComma = true
+     b = append(b, "\"{{.FieldName}}\":"...)
+     b = append(b, '{')
+     printComma, b = m.{{.FieldName}}.AppendJSONFields(false, b)
+     b = append(b, '}')
+   {{ if not .NotNullable -}}
+   }
+   {{- end }}
    {{- else}}
    {{ error  .FieldType }}
    {{- end}}
diff --git a/pkg/util/log/logpb/event.go b/pkg/util/log/logpb/event.go
index 75af663..ae989cf 100644
--- a/pkg/util/log/logpb/event.go
+++ b/pkg/util/log/logpb/event.go
@@ -1,12 +1,7 @@
 // Copyright 2022 The Cockroach Authors.
 //
-// Use of this software is governed by the Business Source License
-// included in the file licenses/BSL.txt.
-//
-// As of the Change Date specified in that file, in accordance with
-// the Business Source License, use of this software will be governed
-// by the Apache License, Version 2.0, included in the file
-// licenses/APL.txt.
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
 
 package logpb
 
diff --git a/pkg/util/log/logpb/event.pb.go b/pkg/util/log/logpb/event.pb.go
index 550ec1e..120594b 100644
--- a/pkg/util/log/logpb/event.pb.go
+++ b/pkg/util/log/logpb/event.pb.go
@@ -151,7 +151,7 @@ func (m *CommonEventDetails) Size() (n int) {
 }
 
 func sovEvent(x uint64) (n int) {
-	return (math_bits.Len64(x|1) + 6) / 7
+	return int((uint32(math_bits.Len64(x|1)+6) * 37) >> 8)
 }
 func sozEvent(x uint64) (n int) {
 	return sovEvent(uint64((x << 1) ^ uint64((int64(x) >> 63))))
diff --git a/pkg/util/log/logpb/event.proto b/pkg/util/log/logpb/event.proto
index b959756..d466f45 100644
--- a/pkg/util/log/logpb/event.proto
+++ b/pkg/util/log/logpb/event.proto
@@ -1,12 +1,7 @@
 // Copyright 2022 The Cockroach Authors.
 //
-// Use of this software is governed by the Business Source License
-// included in the file licenses/BSL.txt.
-//
-// As of the Change Date specified in that file, in accordance with
-// the Business Source License, use of this software will be governed
-// by the Apache License, Version 2.0, included in the file
-// licenses/APL.txt.
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
 
 syntax = "proto3";
 package cockroach.util.log;
diff --git a/pkg/util/log/logpb/log.pb.go b/pkg/util/log/logpb/log.pb.go
index c1d2dd8..f135460 100644
--- a/pkg/util/log/logpb/log.pb.go
+++ b/pkg/util/log/logpb/log.pb.go
@@ -873,7 +873,7 @@ func (m *FileInfo) Size() (n int) {
 }
 
 func sovLog(x uint64) (n int) {
-	return (math_bits.Len64(x|1) + 6) / 7
+	return int((uint32(math_bits.Len64(x|1)+6) * 37) >> 8)
 }
 func sozLog(x uint64) (n int) {
 	return sovLog(uint64((x << 1) ^ uint64((int64(x) >> 63))))
diff --git a/pkg/util/log/logpb/log.proto b/pkg/util/log/logpb/log.proto
index eb24341..5119516 100644
--- a/pkg/util/log/logpb/log.proto
+++ b/pkg/util/log/logpb/log.proto
@@ -1,12 +1,7 @@
 // Copyright 2016 The Cockroach Authors.
 //
-// Use of this software is governed by the Business Source License
-// included in the file licenses/BSL.txt.
-//
-// As of the Change Date specified in that file, in accordance with
-// the Business Source License, use of this software will be governed
-// by the Apache License, Version 2.0, included in the file
-// licenses/APL.txt.
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
 
 syntax = "proto3";
 package cockroach.util.log;
diff --git a/pkg/util/log/logpb/severity.go b/pkg/util/log/logpb/severity.go
index 7966d20..801c789 100644
--- a/pkg/util/log/logpb/severity.go
+++ b/pkg/util/log/logpb/severity.go
@@ -1,12 +1,7 @@
 // Copyright 2019 The Cockroach Authors.
 //
-// Use of this software is governed by the Business Source License
-// included in the file licenses/BSL.txt.
-//
-// As of the Change Date specified in that file, in accordance with
-// the Business Source License, use of this software will be governed
-// by the Apache License, Version 2.0, included in the file
-// licenses/APL.txt.
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
 
 package logpb
 
diff --git a/pkg/util/log/logpb/test_utils.go b/pkg/util/log/logpb/test_utils.go
index a3572fd..a78493c 100644
--- a/pkg/util/log/logpb/test_utils.go
+++ b/pkg/util/log/logpb/test_utils.go
@@ -1,12 +1,7 @@
 // Copyright 2022 The Cockroach Authors.
 //
-// Use of this software is governed by the Business Source License
-// included in the file licenses/BSL.txt.
-//
-// As of the Change Date specified in that file, in accordance with
-// the Business Source License, use of this software will be governed
-// by the Apache License, Version 2.0, included in the file
-// licenses/APL.txt.
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
 
 package logpb
 
diff --git a/pkg/util/metamorphic/constants.go b/pkg/util/metamorphic/constants.go
new file mode 100644
index 0000000..52fef65
--- /dev/null
+++ b/pkg/util/metamorphic/constants.go
@@ -0,0 +1,299 @@
+// Copyright 2020 The Cockroach Authors.
+//
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
+
+package metamorphic
+
+import (
+	"fmt"
+	"math/rand"
+	"os"
+	"strconv"
+	"strings"
+
+	"github.com/cockroachdb/cockroachdb-parser/pkg/build/bazel"
+	"github.com/cockroachdb/cockroachdb-parser/pkg/util/buildutil"
+	"github.com/cockroachdb/cockroachdb-parser/pkg/util/envutil"
+	"github.com/cockroachdb/cockroachdb-parser/pkg/util/metamorphic/metamorphicutil"
+	"github.com/cockroachdb/cockroachdb-parser/pkg/util/randutil"
+	"github.com/cockroachdb/cockroachdb-parser/pkg/util/syncutil"
+)
+
+// IsMetamorphicBuild returns whether this build is metamorphic. By build being
+// "metamorphic" we mean that some magic constants in the codebase might get
+// initialized to non-default value.
+// A build will become metamorphic with metamorphicutil.IsMetamorphicBuildProbability probability
+// if 'crdb_test' build flag is specified (this is the case for all test
+// targets).
+func IsMetamorphicBuild() bool {
+	return metamorphicutil.IsMetamorphicBuild
+}
+
+const (
+	IsMetamorphicBuildProbability = 0.8
+	metamorphicValueProbability   = 0.75
+	metamorphicBoolProbability    = 0.5
+)
+
+// ConstantWithTestValue should be used to initialize "magic constants" that
+// should be varied during test scenarios to check for bugs at boundary
+// conditions. When metamorphicutil.IsMetamorphicBuild is true, the test value will be used with
+// metamorphicValueProbability probability. In all other cases, the production
+// ("default") value will be used.
+// The constant must be a "metamorphic variable": changing it cannot affect the
+// output of any SQL DMLs. It can only affect the way in which the data is
+// retrieved or processed, because otherwise the main test corpus would fail if
+// this flag were enabled.
+//
+// An example of a "magic constant" that behaves this way is a batch size. Batch
+// sizes tend to present testing problems, because often the logic that deals
+// with what to do when a batch is finished is less likely to be exercised by
+// simple unit tests that don't use enough data to fill up a batch.
+//
+// For example, instead of writing:
+//
+// const batchSize = 64
+//
+// you should write:
+//
+// var batchSize = metamorphic.ConstantWithTestValue("batch-size", 64, 1)
+//
+// This will often give your code a batch size of 1 in the crdb_test build
+// configuration, increasing the amount of exercise the edge conditions get.
+//
+// The given name is used for logging.
+func ConstantWithTestValue(name string, defaultValue, metamorphicValue int) int {
+	return getConstantInternal(name,
+		defaultValue,
+		strconv.Atoi,
+		metamorphicValueProbability,
+		func(r *rand.Rand) int {
+			return metamorphicValue
+		},
+		true)
+}
+
+// ConstantWithTestRange is like ConstantWithTestValue except instead of
+// returning a single metamorphic test value, it returns a random test value in
+// the semi-open range [min, max).
+//
+// The given name is used for logging.
+func ConstantWithTestRange(name string, defaultValue, min, max int) int {
+	return getConstantInternal(name,
+		defaultValue,
+		strconv.Atoi,
+		metamorphicValueProbability,
+		func(r *rand.Rand) int {
+			ret := min
+			if max > min {
+				ret = int(r.Int31())%(max-min) + min
+			}
+			return ret
+		},
+		true)
+}
+
+// ConstantWithTestBool is like ConstantWithTestValue except it returns the
+// non-default value half of the time (if running a metamorphic build).
+//
+// The given name is used for logging.
+func ConstantWithTestBool(name string, defaultValue bool) bool {
+	return constantWithTestBoolInternal(name, defaultValue, true /* doLog */)
+}
+
+// ConstantWithTestBoolWithoutLogging is like ConstantWithTestBool except it
+// does not log the value. This is necessary to work around this issue:
+// https://github.com/cockroachdb/cockroachdb-parser/issues/106667
+// TODO(test-eng): Remove this variant when the issue above is addressed.
+func ConstantWithTestBoolWithoutLogging(name string, defaultValue bool) bool {
+	return constantWithTestBoolInternal(name, defaultValue, false /* doLog */)
+}
+
+func constantWithTestBoolInternal(name string, defaultValue bool, doLog bool) bool {
+	return getConstantInternal(name,
+		defaultValue,
+		strconv.ParseBool,
+		metamorphicBoolProbability,
+		func(*rand.Rand) bool { return !defaultValue },
+		doLog)
+}
+
+// ConstantWithTestChoice is like ConstantWithTestValue except it returns a
+// random choice (equally weighted) of the given values. The default value is
+// included in the random choice.
+//
+// The given name is used for logging.
+func ConstantWithTestChoice[T any](name string, defaultValue T, otherValues ...T) T {
+	return getConstantInternal(name,
+		defaultValue,
+		func(s string) (T, error) {
+			v, err := parseChoice[T](s)
+			return v.(T), err
+		},
+		1.0,
+		func(r *rand.Rand) T {
+			values := append([]T{defaultValue}, otherValues...)
+			return values[rng.r.Int63n(int64(len(values)))]
+		},
+		true)
+}
+
+// getConstantInternal returns a value of type T for the given name. If the name
+// has been specified as an override, the parseValue func is used to parse the
+// user-provided value. If no such override is specified, it either returns the
+// defaultValue or a value generated by generateValue()
+func getConstantInternal[T any](
+	name string,
+	defaultValue T,
+	parseValue func(string) (T, error),
+	probability float64,
+	generateValue func(r *rand.Rand) T,
+	doLog bool,
+) T {
+	overrideVal, hasOverride := valueFromOverride(name, parseValue)
+	// This is structured so that we make the same number uses of
+	// `rng.r` in the case of a metamoprhic build so that the seed
+	// value is more useful.
+	if metamorphicutil.IsMetamorphicBuild || hasOverride {
+		rng.Lock()
+		defer rng.Unlock()
+		shouldGenerate := rng.r.Float64() < probability
+		if shouldGenerate || hasOverride {
+			ret := generateValue(rng.r)
+			src := randomVal
+			if hasOverride {
+				src = override
+				ret = overrideVal
+			}
+
+			if doLog {
+				logMetamorphicValue(name, ret, src)
+			}
+			return ret
+		}
+	}
+	return defaultValue
+}
+
+// parseChoice tries to parse the given string into the type T. The returned
+// value should be safe to cast to type T.
+func parseChoice[T any](s string) (any, error) {
+	var zero T
+	switch any(zero).(type) {
+	case string:
+		return s, nil
+	case int, int16, int32, int64:
+		return strconv.Atoi(s)
+	case float32:
+		return strconv.ParseFloat(s, 32)
+	case float64:
+		return strconv.ParseFloat(s, 64)
+	case bool:
+		return strconv.ParseBool(s)
+	default:
+		panic(fmt.Sprintf("unable to parse %T", zero))
+	}
+}
+
+type metamorphicSource string
+
+const (
+	randomVal metamorphicSource = ""
+	override  metamorphicSource = " (from override)"
+)
+
+func logMetamorphicValue(name string, value interface{}, src metamorphicSource) {
+	logf("initialized metamorphic constant %q with value %v%s\n", name, value, src)
+}
+
+func logf(fmtStr string, args ...interface{}) {
+	fmt.Fprintf(os.Stderr, fmtStr, args...)
+}
+
+const (
+	// DisableMetamorphicEnvVar can be used to disable metamorphic tests for
+	// sub-processes. If it exists and is set to something truthy as defined by
+	// strconv.ParseBool then metamorphic testing will not be enabled.
+	DisableMetamorphicEnvVar = "COCKROACH_INTERNAL_DISABLE_METAMORPHIC_TESTING"
+	// MetamorphicOverridesEnvVar can be used to set metamorphic
+	// variables to specific values.
+	MetamorphicOverridesEnvVar = "COCKROACH_INTERNAL_METAMORPHIC_OVERRIDES"
+)
+
+var (
+	// overrides holds user-provided values parsed from
+	// MetamorphicOverridesEnvVar.
+	overrides = map[string]string{}
+
+	// rng is initialized to a rand.Rand if crdbTestBuild is enabled.
+	rng struct {
+		r *rand.Rand
+		syncutil.Mutex
+	}
+	// Exposed for testing.
+	rngSeed int64
+)
+
+// Returns true iff the current process is eligible to enable metamorphic
+// variables. When run under Bazel, checking if we are in the Go test wrapper
+// ensures that metamorphic variables are not initialized and logged twice
+// from both the wrapper and the main test process, as both will perform
+// initialization of the test module and its dependencies.
+func metamorphicEligible() bool {
+	if !buildutil.CrdbTestBuild {
+		return false
+	}
+
+	if bazel.InTestWrapper() {
+		return false
+	}
+
+	return true
+}
+
+// valueFromOverride retuns any user-provided override value for the given name.
+// The passed parser function is used to parse the value from a string
+// representation.
+func valueFromOverride[T any](name string, parser func(string) (T, error)) (T, bool) {
+	if v, ok := overrides[name]; ok {
+		ret, err := parser(v)
+		if err != nil {
+			panic(fmt.Sprintf("malformed value for %s: %s: %s", name, v, err.Error()))
+		}
+		return ret, true
+	} else {
+		var zero T
+		return zero, false
+	}
+}
+
+func init() {
+	if metamorphicEligible() {
+		if !disableMetamorphicTesting {
+			rng.r, rngSeed = randutil.NewPseudoRandWithGlobalSeed()
+			metamorphicutil.IsMetamorphicBuild = rng.r.Float64() < IsMetamorphicBuildProbability
+			if metamorphicutil.IsMetamorphicBuild {
+				logf("metamorphic: use COCKROACH_RANDOM_SEED=%d for reproduction\n", rngSeed)
+			} else {
+				logf("IsMetamorphicBuild==false\n")
+			}
+		}
+
+		if overrideList, ok := envutil.EnvString(MetamorphicOverridesEnvVar, 0); ok {
+			logf("metamorphic: using overrides from environment\n")
+			setOverridesFromString(overrideList)
+		}
+	}
+}
+
+func setOverridesFromString(overrideList string) {
+	overrideItems := strings.Split(overrideList, ",")
+	for _, item := range overrideItems {
+		itemParts := strings.SplitN(item, "=", 2)
+		if len(itemParts) < 2 {
+			panic(fmt.Sprintf("malformed override: %s", item))
+		}
+		overrides[itemParts[0]] = itemParts[1]
+	}
+}
diff --git a/pkg/util/metamorphic/constants_metamorphic_disable.go b/pkg/util/metamorphic/constants_metamorphic_disable.go
new file mode 100644
index 0000000..4a747ca
--- /dev/null
+++ b/pkg/util/metamorphic/constants_metamorphic_disable.go
@@ -0,0 +1,12 @@
+// Copyright 2022 The Cockroach Authors.
+//
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
+
+//go:build metamorphic_disable
+
+package metamorphic
+
+// DisableMetamorphicTesting can be used to disable metamorphic tests. If it
+// is set to true then metamorphic testing will not be enabled.
+var disableMetamorphicTesting = true
diff --git a/pkg/util/constants_metamorphic_enable.go b/pkg/util/metamorphic/constants_metamorphic_enable.go
similarity index 50%
rename from pkg/util/constants_metamorphic_enable.go
rename to pkg/util/metamorphic/constants_metamorphic_enable.go
index f9a90fc..e1c35fa 100644
--- a/pkg/util/constants_metamorphic_enable.go
+++ b/pkg/util/metamorphic/constants_metamorphic_enable.go
@@ -1,17 +1,11 @@
 // Copyright 2022 The Cockroach Authors.
 //
-// Use of this software is governed by the Business Source License
-// included in the file licenses/BSL.txt.
-//
-// As of the Change Date specified in that file, in accordance with
-// the Business Source License, use of this software will be governed
-// by the Apache License, Version 2.0, included in the file
-// licenses/APL.txt.
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
 
 //go:build !metamorphic_disable
-// +build !metamorphic_disable
 
-package util
+package metamorphic
 
 import "github.com/cockroachdb/cockroachdb-parser/pkg/util/envutil"
 
diff --git a/pkg/util/metamorphic/metamorphicutil/is_metamorphic.go b/pkg/util/metamorphic/metamorphicutil/is_metamorphic.go
new file mode 100644
index 0000000..456d8eb
--- /dev/null
+++ b/pkg/util/metamorphic/metamorphicutil/is_metamorphic.go
@@ -0,0 +1,18 @@
+// Copyright 2024 The Cockroach Authors.
+//
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
+
+package metamorphicutil
+
+// NB: init() in pkg/util/metamorphic/constants.go may set this value to true.
+// We don't put this variable in that package as we would like to have a way to
+// reliably determine which packages use metamorphic constants, and
+// `bazel query somepath(_, //pkg/util/metamorphic)` should be a good way to do
+// that. However, some packages (like pkg/testutils/skip) need to check whether
+// we're running a metamorphic build, without necessarily depending on the
+// metamorphic package.
+//
+// Generally, you should use metamorphic.IsMetaMorphicBuild() instead of checking
+// this value.
+var IsMetamorphicBuild bool
diff --git a/pkg/util/netutil/addr/addr.go b/pkg/util/netutil/addr/addr.go
index ddf7abe..666ae9d 100644
--- a/pkg/util/netutil/addr/addr.go
+++ b/pkg/util/netutil/addr/addr.go
@@ -1,12 +1,7 @@
 // Copyright 2014 The Cockroach Authors.
 //
-// Use of this software is governed by the Business Source License
-// included in the file licenses/BSL.txt.
-//
-// As of the Change Date specified in that file, in accordance with
-// the Business Source License, use of this software will be governed
-// by the Apache License, Version 2.0, included in the file
-// licenses/APL.txt.
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
 
 package addr
 
diff --git a/pkg/util/nocopy.go b/pkg/util/nocopy.go
index db0d83e..c422e49 100644
--- a/pkg/util/nocopy.go
+++ b/pkg/util/nocopy.go
@@ -1,12 +1,7 @@
 // Copyright 2016 The Cockroach Authors.
 //
-// Use of this software is governed by the Business Source License
-// included in the file licenses/BSL.txt.
-//
-// As of the Change Date specified in that file, in accordance with
-// the Business Source License, use of this software will be governed
-// by the Apache License, Version 2.0, included in the file
-// licenses/APL.txt.
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
 
 package util
 
diff --git a/pkg/util/num32/doc.go b/pkg/util/num32/doc.go
new file mode 100644
index 0000000..9546d30
--- /dev/null
+++ b/pkg/util/num32/doc.go
@@ -0,0 +1,23 @@
+// Copyright 2024 The Cockroach Authors.
+//
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
+
+/*
+Package num32 contains basic numeric functions that operate on scalar, vector,
+and matrix float32 values. Inputs and outputs deliberately use simple float
+types so that they can be used in multiple contexts. It uses the gonum library
+when possible, since it offers assembly language implementations of various
+useful primitives.
+
+Using the same convention as gonum, when a slice is being modified in place, it
+has the name dst and the function does not return a value. In addition, many of
+the functions have the same name and semantics as those in gonum.
+
+Where possible, functions in this package are written with the assumption that
+the caller prevents bad input. They will panic with assertion errors if this is
+not the case, rather than returning error values. Callers should generally have
+panic recovery logic further up the stack to gracefully handle these assertions,
+as they indicate buggy code.
+*/
+package num32
diff --git a/pkg/util/num32/mat.go b/pkg/util/num32/mat.go
new file mode 100644
index 0000000..d4c8360
--- /dev/null
+++ b/pkg/util/num32/mat.go
@@ -0,0 +1,101 @@
+// Copyright 2024 The Cockroach Authors.
+//
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
+
+package num32
+
+import (
+	"math/rand"
+
+	"github.com/cockroachdb/errors"
+	"gonum.org/v1/gonum/blas"
+	"gonum.org/v1/gonum/blas/blas32"
+	"gonum.org/v1/gonum/blas/blas64"
+	"gonum.org/v1/gonum/lapack/lapack64"
+)
+
+// MatrixTranspose indicates whether a matrix operation should operate on the
+// untransposed or transposed form of the matrix.
+type MatrixTranspose byte
+
+const (
+	NoTranspose = MatrixTranspose(blas.NoTrans)
+	Transpose   = MatrixTranspose(blas.Trans)
+)
+
+// Matrix represents an N x M matrix that stores float32 values in row-wise
+// format.
+type Matrix = blas32.General
+
+// MulMatrixByVector multiplies a matrix (or its transpose) by the "s" vector,
+// stores the result in the "dst" vector, and returns "dst". The vectors are
+// treated as column matrices:
+//
+//	matrix = rows x cols
+//	s = cols x 1
+//	dst = rows x 1 (by rules of matrix multiplication)
+//
+// Therefore, len(s) must equal matrix.Cols and len(dst) must equal matrix.Rows.
+// If Transpose is specified, then the transposed matrix is multiplied by the
+// vector. In that case, len(s) must equal matrix.Rows and len(dst) must equal
+// matrix.Cols.
+func MulMatrixByVector(
+	matrix *Matrix, s []float32, dst []float32, transpose MatrixTranspose,
+) []float32 {
+	blasInput := blas32.Vector{N: len(s), Data: s, Inc: 1}
+	blasOutput := blas32.Vector{N: len(dst), Data: dst, Inc: 1}
+	blas32.Gemv(blas.Transpose(transpose), 1, *matrix, blasInput, 0, blasOutput)
+	return dst
+}
+
+// MakeRandomOrthoMatrix returns a square N x N random orthogonal matrix. Rows
+// and columns are orthonormal vectors - they have length 1 and any two rows or
+// columns are perpendicular. Multiplying a vector by this matrix will randomly
+// transform it while preserving its relative distance and angle to any other
+// vector that's also multiplied by the same matrix.
+func MakeRandomOrthoMatrix(rng *rand.Rand, dims int) Matrix {
+	if dims <= 0 {
+		panic(errors.AssertionFailedf("matrix cannot have %d dimensions", dims))
+	}
+
+	// The BLAS library only supports float64, so do work using float64 and later
+	// convert to float32. Start by allocating working memory. Allocate "dims"
+	// memory for tau, dims * dims memory for data, and dims * dims / 2 for the
+	// working memory that QR decomposition needs.
+	mem := make([]float64, dims+dims*dims+(dims*dims+1)/2)
+	tau := mem[:dims]
+	data := mem[len(tau) : len(tau)+dims*dims]
+	work := mem[len(tau)+len(data):]
+
+	for i := range data {
+		// Draw random values from the standard normal distribution (mean = 0,
+		// stdev = 1).
+		data[i] = rng.NormFloat64()
+	}
+	matrix64 := blas64.General{
+		Rows:   dims,
+		Cols:   dims,
+		Data:   data,
+		Stride: dims,
+	}
+
+	// Compute the QR decomposition of the random matrix. "Q" is an orthogonal
+	// matrix, while "R" will just be discarded.
+	lapack64.Geqrf(matrix64, tau, work, len(work))
+
+	// Construct Q from the elementary reflectors.
+	lapack64.Orgqr(matrix64, tau, work, len(work))
+
+	// Convert to a float32 matrix.
+	matrix32 := Matrix{
+		Rows:   dims,
+		Cols:   dims,
+		Data:   make([]float32, dims*dims),
+		Stride: dims,
+	}
+	for i := range matrix64.Data {
+		matrix32.Data[i] = float32(matrix64.Data[i])
+	}
+	return matrix32
+}
diff --git a/pkg/util/num32/scalar.go b/pkg/util/num32/scalar.go
new file mode 100644
index 0000000..8088b5e
--- /dev/null
+++ b/pkg/util/num32/scalar.go
@@ -0,0 +1,39 @@
+// Copyright 2024 The Cockroach Authors.
+//
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
+
+package num32
+
+import "math"
+
+// Abs returns the absolute value of x.
+//
+// Special cases are:
+//
+//	Abs(±Inf) = +Inf
+//	Abs(NaN) = NaN
+func Abs(x float32) float32 {
+	return math.Float32frombits(math.Float32bits(x) &^ (1 << 31))
+}
+
+// Sqrt returns the square root of x.
+//
+// Special cases are:
+//
+//	Sqrt(+Inf) = +Inf
+//	Sqrt(±0) = ±0
+//	Sqrt(x < 0) = NaN
+//	Sqrt(NaN) = NaN
+func Sqrt(x float32) float32 {
+	// For now, use the float64 Sqrt operation.
+	// TODO(andyk): Consider using the SQRTSS instruction like gonum does
+	// internally.
+	return float32(math.Sqrt(float64(x)))
+}
+
+// IsNaN reports whether f is an IEEE 754 “not-a-number” value.
+func IsNaN(v float32) bool {
+	// IEEE 754 says that only NaNs satisfy f != f.
+	return v != v
+}
diff --git a/pkg/util/num32/vec.go b/pkg/util/num32/vec.go
new file mode 100644
index 0000000..abf34ee
--- /dev/null
+++ b/pkg/util/num32/vec.go
@@ -0,0 +1,241 @@
+// Copyright 2024 The Cockroach Authors.
+//
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
+
+package num32
+
+import (
+	"github.com/cockroachdb/errors"
+	"gonum.org/v1/gonum/blas/blas32"
+	"gonum.org/v1/gonum/floats/scalar"
+)
+
+// L1Distance returns the L1 norm of s - t, which is the Manhattan distance
+// between the two vectors. It panics if the argument lengths do not match.
+func L1Distance(s []float32, t []float32) float32 {
+	checkDims(s, t)
+	var distance float32
+	for i := range s {
+		diff := s[i] - t[i]
+		distance += Abs(diff)
+	}
+	return distance
+}
+
+// L2Distance returns the L2 norm of s - t, which is the Euclidean distance
+// between the two vectors. It panics if the argument lengths do not match.
+func L2Distance(s, t []float32) float32 {
+	return Sqrt(L2SquaredDistance(s, t))
+}
+
+// L2SquaredDistance returns the squared L2 norm of s - t, which is the squared
+// Euclidean distance between the two vectors. Comparing squared distance is
+// equivalent to comparing distance, but the squared distance avoids an
+// expensive square-root operation. It panics if the argument lengths do not
+// match.
+func L2SquaredDistance(s, t []float32) float32 {
+	checkDims(s, t)
+	var distance float32
+	for i := range s {
+		diff := s[i] - t[i]
+		distance += diff * diff
+	}
+	return distance
+}
+
+// Dot returns the dot product of t1 and t2, also called the inner product. It
+// panics if the argument lengths do not match.
+func Dot(s []float32, t []float32) float32 {
+	checkDims(s, t)
+	var distance float32
+	for i := range s {
+		distance += s[i] * t[i]
+	}
+	return distance
+}
+
+// Norm returns the L2 norm of t.
+func Norm(t []float32) float32 {
+	var norm float32
+	for i := range t {
+		norm += t[i] * t[i]
+	}
+	return Sqrt(norm)
+}
+
+// Max returns the maximum value in the input slice. If the slice is empty, Max
+// will panic.
+func Max(s []float32) float32 {
+	return s[MaxIdx(s)]
+}
+
+// MaxIdx returns the index of the maximum value in the input slice. If several
+// entries have the maximum value, the first such index is returned. It panics
+// if s is zero length.
+func MaxIdx(s []float32) int {
+	if len(s) == 0 {
+		panic(errors.AssertionFailedf("MaxIdx input cannot be zero"))
+	}
+
+	// Set max index to first position that's not NaN.
+	var ind int
+	var max float32
+	for i, v := range s {
+		max = v
+		ind = i
+		if !IsNaN(v) {
+			break
+		}
+	}
+
+	// Now look for larger value. Further NaN values will be ignored.
+	for i := ind + 1; i < len(s); i++ {
+		if s[i] > max {
+			max = s[i]
+			ind = i
+		}
+	}
+	return ind
+}
+
+// Min returns the minimum value in the input slice. It panics if s is zero
+// length.
+func Min(s []float32) float32 {
+	return s[MinIdx(s)]
+}
+
+// MinIdx returns the index of the minimum value in the input slice. If several
+// entries have the minimum value, the first such index is returned.
+// It panics if s is zero length.
+func MinIdx(s []float32) int {
+	if len(s) == 0 {
+		panic(errors.AssertionFailedf("MinIdx input cannot be zero"))
+	}
+
+	// Set min index to first position that's not NaN.
+	var ind int
+	var min float32
+	for i, v := range s {
+		min = v
+		ind = i
+		if !IsNaN(v) {
+			break
+		}
+	}
+
+	// Now look for smaller value. Further NaN values will be ignored.
+	for i := ind + 1; i < len(s); i++ {
+		if s[i] < min {
+			min = s[i]
+			ind = i
+		}
+	}
+	return ind
+}
+
+// Sum returns the sum of the elements of the given slice.
+func Sum(x []float32) float32 {
+	var sum float32
+	for _, v := range x {
+		sum += v
+	}
+	return sum
+}
+
+// Zero sets every element of the given slice to zero.
+//
+//gcassert:inline
+func Zero(dst []float32) {
+	clear(dst)
+}
+
+// Round sets every element of the "dst" slice to its rounded value, using
+// gonum's scalar.Round function.
+//
+// NB: Upcasting from float32 to float64 to perform the rounding can cause
+// precision issues that affect the result.
+func Round(dst []float32, prec int) {
+	for i := range dst {
+		val2 := float64(dst[i])
+		val := scalar.Round(val2, prec)
+		dst[i] = float32(val)
+	}
+}
+
+// Add adds, element-wise, the elements of s and dst, and stores the result in
+// dst. It panics if the argument lengths do not match.
+func Add(dst []float32, s []float32) {
+	// blas32.Axpy is significantly faster than Go code on amd64.
+	blas32.Axpy(
+		1,
+		blas32.Vector{N: len(s), Data: s, Inc: 1},
+		blas32.Vector{N: len(dst), Data: dst, Inc: 1})
+}
+
+// AddTo adds, element-wise, the elements of s and t and stores the result in
+// dst. It panics if the argument lengths do not match.
+func AddTo(dst []float32, s []float32, t []float32) []float32 {
+	copy(dst, s)
+	Add(dst, t)
+	return dst
+}
+
+// Sub subtracts, element-wise, the elements of s from dst. It panics if the
+// argument lengths do not match.
+func Sub(dst []float32, s []float32) {
+	// blas32.Axpy is significantly faster than Go code on amd64.
+	blas32.Axpy(
+		-1,
+		blas32.Vector{N: len(s), Data: s, Inc: 1},
+		blas32.Vector{N: len(dst), Data: dst, Inc: 1})
+}
+
+// SubTo subtracts, element-wise, the elements of t from s and stores the result
+// in dst. It panics if the argument lengths do not match.
+func SubTo(dst []float32, s []float32, t []float32) []float32 {
+	copy(dst, s)
+	Sub(dst, t)
+	return dst
+}
+
+// Mul performs element-wise multiplication between dst and s and stores the
+// value in dst. It panics if the argument lengths do not match.
+func Mul(dst []float32, s []float32) {
+	// TODO(andyk): Consider implementing this in assembly.
+	checkDims(dst, s)
+	for i, val := range s {
+		dst[i] *= val
+	}
+}
+
+// MulTo performs element-wise multiplication between s and t and stores the
+// value in dst. It panics if the argument lengths do not match.
+func MulTo(dst []float32, s []float32, t []float32) []float32 {
+	// TODO(andyk): Consider implementing this in assembly.
+	checkDims(dst, s)
+	for i, val := range s {
+		dst[i] = val * t[i]
+	}
+	return dst
+}
+
+// Scale multiplies every element in dst by the scalar c.
+func Scale(c float32, dst []float32) {
+	// blas32.Scale is significantly faster than Go code on amd64.
+	blas32.Scal(c, blas32.Vector{N: len(dst), Data: dst, Inc: 1})
+}
+
+// ScaleTo multiplies the elements in s by c and stores the result in dst. It
+// panics if the slice argument lengths do not match.
+func ScaleTo(dst []float32, c float32, s []float32) []float32 {
+	copy(dst, s)
+	Scale(c, dst)
+	return dst
+}
+
+func checkDims(v []float32, v2 []float32) {
+	if len(v) != len(v2) {
+		panic(errors.AssertionFailedf("different vector dimensions %d and %d", len(v), len(v2)))
+	}
+}
diff --git a/pkg/util/pluralize.go b/pkg/util/pluralize.go
index 068d6d8..528ba7c 100644
--- a/pkg/util/pluralize.go
+++ b/pkg/util/pluralize.go
@@ -1,17 +1,14 @@
 // Copyright 2016 The Cockroach Authors.
 //
-// Use of this software is governed by the Business Source License
-// included in the file licenses/BSL.txt.
-//
-// As of the Change Date specified in that file, in accordance with
-// the Business Source License, use of this software will be governed
-// by the Apache License, Version 2.0, included in the file
-// licenses/APL.txt.
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
 
 package util
 
+import "github.com/cockroachdb/redact"
+
 // Pluralize returns a single character 's' unless n == 1.
-func Pluralize(n int64) string {
+func Pluralize(n int64) redact.SafeString {
 	if n == 1 {
 		return ""
 	}
diff --git a/pkg/util/pretty/document.go b/pkg/util/pretty/document.go
index 62e4a79..8193353 100644
--- a/pkg/util/pretty/document.go
+++ b/pkg/util/pretty/document.go
@@ -1,12 +1,7 @@
 // Copyright 2018 The Cockroach Authors.
 //
-// Use of this software is governed by the Business Source License
-// included in the file licenses/BSL.txt.
-//
-// As of the Change Date specified in that file, in accordance with
-// the Business Source License, use of this software will be governed
-// by the Apache License, Version 2.0, included in the file
-// licenses/APL.txt.
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
 
 // Package pretty prints documents based on a target line width.
 //
diff --git a/pkg/util/pretty/pretty.go b/pkg/util/pretty/pretty.go
index aea931a..36e4181 100644
--- a/pkg/util/pretty/pretty.go
+++ b/pkg/util/pretty/pretty.go
@@ -1,12 +1,7 @@
 // Copyright 2018 The Cockroach Authors.
 //
-// Use of this software is governed by the Business Source License
-// included in the file licenses/BSL.txt.
-//
-// As of the Change Date specified in that file, in accordance with
-// the Business Source License, use of this software will be governed
-// by the Apache License, Version 2.0, included in the file
-// licenses/APL.txt.
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
 
 package pretty
 
diff --git a/pkg/util/pretty/util.go b/pkg/util/pretty/util.go
index b754eb8..0859b96 100644
--- a/pkg/util/pretty/util.go
+++ b/pkg/util/pretty/util.go
@@ -1,12 +1,7 @@
 // Copyright 2018 The Cockroach Authors.
 //
-// Use of this software is governed by the Business Source License
-// included in the file licenses/BSL.txt.
-//
-// As of the Change Date specified in that file, in accordance with
-// the Business Source License, use of this software will be governed
-// by the Apache License, Version 2.0, included in the file
-// licenses/APL.txt.
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
 
 package pretty
 
diff --git a/pkg/util/protoutil/clone.go b/pkg/util/protoutil/clone.go
index 192c33c..c0f89d7 100644
--- a/pkg/util/protoutil/clone.go
+++ b/pkg/util/protoutil/clone.go
@@ -1,12 +1,7 @@
 // Copyright 2016 The Cockroach Authors.
 //
-// Use of this software is governed by the Business Source License
-// included in the file licenses/BSL.txt.
-//
-// As of the Change Date specified in that file, in accordance with
-// the Business Source License, use of this software will be governed
-// by the Apache License, Version 2.0, included in the file
-// licenses/APL.txt.
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
 
 package protoutil
 
diff --git a/pkg/util/protoutil/clone.pb.go b/pkg/util/protoutil/clone.pb.go
index c9dc39d..fc9be17 100644
--- a/pkg/util/protoutil/clone.pb.go
+++ b/pkg/util/protoutil/clone.pb.go
@@ -155,7 +155,7 @@ func (m *RecursiveAndUncloneable) Size() (n int) {
 }
 
 func sovClone(x uint64) (n int) {
-	return (math_bits.Len64(x|1) + 6) / 7
+	return int((uint32(math_bits.Len64(x|1)+6) * 37) >> 8)
 }
 func sozClone(x uint64) (n int) {
 	return sovClone(uint64((x << 1) ^ uint64((int64(x) >> 63))))
diff --git a/pkg/util/protoutil/clone.proto b/pkg/util/protoutil/clone.proto
index 77da782..2a44cf1 100644
--- a/pkg/util/protoutil/clone.proto
+++ b/pkg/util/protoutil/clone.proto
@@ -1,12 +1,7 @@
 // Copyright 2017 The Cockroach Authors.
 //
-// Use of this software is governed by the Business Source License
-// included in the file licenses/BSL.txt.
-//
-// As of the Change Date specified in that file, in accordance with
-// the Business Source License, use of this software will be governed
-// by the Apache License, Version 2.0, included in the file
-// licenses/APL.txt.
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
 
 syntax = "proto3";
 package cockroach.util.protoutil;
diff --git a/pkg/util/protoutil/jsonpb_marshal.go b/pkg/util/protoutil/jsonpb_marshal.go
index cd02994..9a1e3ca 100644
--- a/pkg/util/protoutil/jsonpb_marshal.go
+++ b/pkg/util/protoutil/jsonpb_marshal.go
@@ -1,12 +1,7 @@
 // Copyright 2016 The Cockroach Authors.
 //
-// Use of this software is governed by the Business Source License
-// included in the file licenses/BSL.txt.
-//
-// As of the Change Date specified in that file, in accordance with
-// the Business Source License, use of this software will be governed
-// by the Apache License, Version 2.0, included in the file
-// licenses/APL.txt.
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
 
 package protoutil
 
diff --git a/pkg/util/protoutil/marshal.go b/pkg/util/protoutil/marshal.go
index a774b5e..9764353 100644
--- a/pkg/util/protoutil/marshal.go
+++ b/pkg/util/protoutil/marshal.go
@@ -1,12 +1,7 @@
 // Copyright 2016 The Cockroach Authors.
 //
-// Use of this software is governed by the Business Source License
-// included in the file licenses/BSL.txt.
-//
-// As of the Change Date specified in that file, in accordance with
-// the Business Source License, use of this software will be governed
-// by the Apache License, Version 2.0, included in the file
-// licenses/APL.txt.
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
 
 package protoutil
 
@@ -15,6 +10,7 @@ import (
 
 	"github.com/cockroachdb/cockroachdb-parser/pkg/util/buildutil"
 	"github.com/gogo/protobuf/proto"
+	gproto "google.golang.org/protobuf/proto"
 )
 
 // Message extends the proto.Message interface with the MarshalTo and Size
@@ -74,3 +70,13 @@ func Unmarshal(data []byte, pb Message) error {
 	pb.Reset()
 	return pb.Unmarshal(data)
 }
+
+// TODOMarshal is a short-term workaround for the linter in order to use the latest protobuf package
+func TODOMarshal(pb gproto.Message) ([]byte, error) {
+	return gproto.Marshal(pb)
+}
+
+// TODOUnmarshal is a short-term workaround for the linter in order to use the latest protobuf package
+func TODOUnmarshal(data []byte, pb gproto.Message) error {
+	return gproto.Unmarshal(data, pb)
+}
diff --git a/pkg/util/protoutil/marshaler.go b/pkg/util/protoutil/marshaler.go
index 6d835ae..76cf92d 100644
--- a/pkg/util/protoutil/marshaler.go
+++ b/pkg/util/protoutil/marshaler.go
@@ -1,12 +1,7 @@
 // Copyright 2016 The Cockroach Authors.
 //
-// Use of this software is governed by the Business Source License
-// included in the file licenses/BSL.txt.
-//
-// As of the Change Date specified in that file, in accordance with
-// the Business Source License, use of this software will be governed
-// by the Apache License, Version 2.0, included in the file
-// licenses/APL.txt.
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
 
 package protoutil
 
diff --git a/pkg/util/race_off.go b/pkg/util/race_off.go
index 0f19256..6b9dd75 100644
--- a/pkg/util/race_off.go
+++ b/pkg/util/race_off.go
@@ -1,15 +1,9 @@
 // Copyright 2017 The Cockroach Authors.
 //
-// Use of this software is governed by the Business Source License
-// included in the file licenses/BSL.txt.
-//
-// As of the Change Date specified in that file, in accordance with
-// the Business Source License, use of this software will be governed
-// by the Apache License, Version 2.0, included in the file
-// licenses/APL.txt.
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
 
 //go:build !race
-// +build !race
 
 package util
 
diff --git a/pkg/util/race_on.go b/pkg/util/race_on.go
index 7128b66..c2a4a5f 100644
--- a/pkg/util/race_on.go
+++ b/pkg/util/race_on.go
@@ -1,15 +1,9 @@
 // Copyright 2017 The Cockroach Authors.
 //
-// Use of this software is governed by the Business Source License
-// included in the file licenses/BSL.txt.
-//
-// As of the Change Date specified in that file, in accordance with
-// the Business Source License, use of this software will be governed
-// by the Apache License, Version 2.0, included in the file
-// licenses/APL.txt.
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
 
 //go:build race
-// +build race
 
 package util
 
diff --git a/pkg/util/randutil/rand.go b/pkg/util/randutil/rand.go
index f27514e..7b1e96a 100644
--- a/pkg/util/randutil/rand.go
+++ b/pkg/util/randutil/rand.go
@@ -1,12 +1,7 @@
 // Copyright 2014 The Cockroach Authors.
 //
-// Use of this software is governed by the Business Source License
-// included in the file licenses/BSL.txt.
-//
-// As of the Change Date specified in that file, in accordance with
-// the Business Source License, use of this software will be governed
-// by the Apache License, Version 2.0, included in the file
-// licenses/APL.txt.
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
 
 package randutil
 
@@ -104,6 +99,16 @@ func NewLockedPseudoRand() (*rand.Rand, int64) {
 	return rand.New(NewLockedSource(seed)), seed
 }
 
+// NewPseudoRandWithGlobalSeed returns an instance of math/rand.Rand, which is
+// seeded with the global seed.
+// It's _not_ intended to be called directly from a test; use NewTestRand for that.
+// Instead, this function is useful for seeding other random number generators, on which the tests
+// may depend; e.g., metamorphic constants.
+// N.B. unlike NewTestRand, this function _never_ reseeds rng.
+func NewPseudoRandWithGlobalSeed() (*rand.Rand, int64) {
+	return rand.New(rand.NewSource(globalSeed)), globalSeed
+}
+
 // NewTestRand returns an instance of math/rand.Rand seeded from rng, which is
 // seeded with the global seed. If the caller is a test with a different
 // path-qualified name than the previous caller, rng is reseeded from the global
@@ -234,7 +239,8 @@ const PrintableKeyAlphabet = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWX
 // alphanumeric chars.
 func RandString(rng *rand.Rand, length int, alphabet string) string {
 	runes := []rune(alphabet)
-	buf := &strings.Builder{}
+	var buf strings.Builder
+	buf.Grow(length)
 	for i := 0; i < length; i++ {
 		buf.WriteRune(runes[rng.Intn(len(runes))])
 	}
diff --git a/pkg/util/reflect.go b/pkg/util/reflect.go
index 12d6d61..2984782 100644
--- a/pkg/util/reflect.go
+++ b/pkg/util/reflect.go
@@ -1,12 +1,7 @@
 // Copyright 2016 The Cockroach Authors.
 //
-// Use of this software is governed by the Business Source License
-// included in the file licenses/BSL.txt.
-//
-// As of the Change Date specified in that file, in accordance with
-// the Business Source License, use of this software will be governed
-// by the Apache License, Version 2.0, included in the file
-// licenses/APL.txt.
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
 
 package util
 
diff --git a/pkg/util/ring/ring_buffer.go b/pkg/util/ring/ring_buffer.go
new file mode 100644
index 0000000..60b12b2
--- /dev/null
+++ b/pkg/util/ring/ring_buffer.go
@@ -0,0 +1,230 @@
+// Copyright 2018 The Cockroach Authors.
+//
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
+
+package ring
+
+// Buffer is a deque maintained over a ring buffer.
+//
+// The zero value is ready to use. See MakeBuffer() for initializing a Buffer
+// with pre-allocated space.
+//
+// Note: it is backed by a slice (unlike container/ring/ring_buffer.go which
+// is backed by a linked list). There is also a container/ring/buffer.go, that
+// is backed by a slice and can both grow and shrink and uses bit arithmetic.
+// We should replace this implementation with that one.
+type Buffer[T any] struct {
+	buffer []T
+	head   int // the index of the front of the buffer
+	tail   int // the index of the first position after the end of the buffer
+
+	// Indicates whether the buffer is empty. Necessary to distinguish
+	// between an empty buffer and a buffer that uses all of its capacity.
+	nonEmpty bool
+}
+
+// MakeBuffer creates a buffer.
+//
+// scratch, if not nil, represents pre-allocated space that the Buffer takes
+// ownership of. The whole backing array of the provided slice is taken over,
+// included elements and available capacity.
+func MakeBuffer[T any](scratch []T) Buffer[T] {
+	return Buffer[T]{buffer: scratch}
+}
+
+// Len returns the number of elements in the Buffer.
+func (r *Buffer[T]) Len() int {
+	if !r.nonEmpty {
+		return 0
+	}
+	if r.head < r.tail {
+		return r.tail - r.head
+	} else if r.head == r.tail {
+		return cap(r.buffer)
+	} else {
+		return cap(r.buffer) + r.tail - r.head
+	}
+}
+
+// Cap returns the capacity of the Buffer.
+func (r *Buffer[T]) Cap() int {
+	return cap(r.buffer)
+}
+
+// Get returns an element at position pos in the Buffer (zero-based).
+func (r *Buffer[T]) Get(pos int) T {
+	if !r.nonEmpty || pos < 0 || pos >= r.Len() {
+		panic("index out of bounds")
+	}
+	return r.buffer[(pos+r.head)%cap(r.buffer)]
+}
+
+// GetFirst returns an element at the front of the Buffer.
+func (r *Buffer[T]) GetFirst() T {
+	if !r.nonEmpty {
+		panic("getting first from empty ring buffer")
+	}
+	return r.buffer[r.head]
+}
+
+// GetLast returns an element at the front of the Buffer.
+func (r *Buffer[T]) GetLast() T {
+	if !r.nonEmpty {
+		panic("getting last from empty ring buffer")
+	}
+	return r.buffer[(cap(r.buffer)+r.tail-1)%cap(r.buffer)]
+}
+
+func (r *Buffer[T]) resize(n int) {
+	if n < r.Len() {
+		panic("resizing to fewer elements than current length")
+	}
+
+	if n == 0 {
+		r.Discard()
+		return
+	}
+
+	newBuffer := make([]T, n)
+	r.copyTo(newBuffer)
+	r.tail = r.Len() % cap(newBuffer)
+	r.head = 0
+	r.buffer = newBuffer
+}
+
+// copyTo copies elements from r to dst. If len(dst) < r.Len(), only the first
+// len(dst) elements are copied.
+func (r *Buffer[T]) copyTo(dst []T) {
+	if !r.nonEmpty {
+		return
+	}
+	// Copy over the contents to dst.
+	if r.head < r.tail {
+		copy(dst, r.buffer[r.head:r.tail])
+	} else {
+		tailElements := r.buffer[r.head:]
+		copy(dst, tailElements)
+		// If there's space remaining, continue.
+		if len(dst) > len(tailElements) {
+			copy(dst[cap(r.buffer)-r.head:], r.buffer[:r.tail])
+		}
+	}
+}
+
+func (r *Buffer[T]) maybeGrow() {
+	if r.Len() != cap(r.buffer) {
+		return
+	}
+	n := 2 * cap(r.buffer)
+	if n == 0 {
+		n = 1
+	}
+	r.resize(n)
+}
+
+// AddFirst add element to the front of the Buffer and doubles it's underlying
+// slice if necessary.
+func (r *Buffer[T]) AddFirst(element T) {
+	r.maybeGrow()
+	r.head = (cap(r.buffer) + r.head - 1) % cap(r.buffer)
+	r.buffer[r.head] = element
+	r.nonEmpty = true
+}
+
+// AddLast adds element to the end of the Buffer and doubles it's underlying
+// slice if necessary.
+func (r *Buffer[T]) AddLast(element T) {
+	r.maybeGrow()
+	r.buffer[r.tail] = element
+	r.tail = (r.tail + 1) % cap(r.buffer)
+	r.nonEmpty = true
+}
+
+// RemoveFirst removes a single element from the front of the Buffer.
+func (r *Buffer[T]) RemoveFirst() {
+	if r.Len() == 0 {
+		panic("removing first from empty ring buffer")
+	}
+	var zero T
+	r.buffer[r.head] = zero
+	r.head = (r.head + 1) % cap(r.buffer)
+	if r.head == r.tail {
+		r.nonEmpty = false
+	}
+}
+
+// RemoveLast removes a single element from the end of the Buffer.
+func (r *Buffer[T]) RemoveLast() {
+	if r.Len() == 0 {
+		panic("removing last from empty ring buffer")
+	}
+	lastPos := (cap(r.buffer) + r.tail - 1) % cap(r.buffer)
+	var zero T
+	r.buffer[lastPos] = zero
+	r.tail = lastPos
+	if r.tail == r.head {
+		r.nonEmpty = false
+	}
+}
+
+// Reserve reserves the provided number of elements in the Buffer. It is illegal
+// to reserve a size less than the r.Len().
+//
+// If the Buffer already has a capacity of n or larger, this is a no-op.
+func (r *Buffer[T]) Reserve(n int) {
+	if n < r.Len() {
+		panic("reserving fewer elements than current length")
+	}
+	if n > cap(r.buffer) {
+		r.resize(n)
+	}
+}
+
+// Resize changes the Buffer's storage to be of the specified size. It is
+// illegal to resize to a size less than r.Len().
+//
+// This is a more general version of Reserve: Reserve only ever grows the
+// storage, whereas Resize() can also shrink it.
+//
+// Note that, if n != r.Len(), Resize always allocates new storage, even when n
+// is less than the current capacity. This can be useful to make the storage for
+// a buffer that used to be large available for GC, but it can also be wasteful.
+func (r *Buffer[T]) Resize(n int) {
+	if n < r.Len() {
+		panic("resizing to fewer elements than current length")
+	}
+
+	if n != cap(r.buffer) {
+		r.resize(n)
+	}
+}
+
+// Reset makes Buffer treat its underlying memory as if it were empty. This
+// allows for reusing the same memory again without explicitly removing old
+// elements. Note that this does not nil out the elements, so they're not made
+// available to GC.
+//
+// See also Discard.
+func (r *Buffer[T]) Reset() {
+	r.head = 0
+	r.tail = 0
+	r.nonEmpty = false
+}
+
+// Discard is like Reset, except it also does Resize(0) to nil out the
+// underlying slice. This makes the backing storage for the slice available to
+// GC if nobody else is referencing it. This is useful if r is still referenced,
+// but *r will be reassigned.
+//
+// See also Reset and Resize.
+func (r *Buffer[T]) Discard() {
+	*r = Buffer[T]{}
+}
+
+// all a slice with returns all the elements in the buffer.
+func (r *Buffer[T]) all() []T {
+	buf := make([]T, r.Len())
+	r.copyTo(buf)
+	return buf
+}
diff --git a/pkg/util/slices.go b/pkg/util/slices.go
index faec79d..d3059ce 100644
--- a/pkg/util/slices.go
+++ b/pkg/util/slices.go
@@ -1,18 +1,13 @@
 // Copyright 2021 The Cockroach Authors.
 //
-// Use of this software is governed by the Business Source License
-// included in the file licenses/BSL.txt.
-//
-// As of the Change Date specified in that file, in accordance with
-// the Business Source License, use of this software will be governed
-// by the Apache License, Version 2.0, included in the file
-// licenses/APL.txt.
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
 
 package util
 
 import (
-	"golang.org/x/exp/constraints"
-	"golang.org/x/exp/slices"
+	"cmp"
+	"slices"
 )
 
 // CombineUnique merges two ordered slices. If both slices have unique elements
@@ -25,7 +20,7 @@ import (
 // has mostly the same elements as the other. If the two slices are large and
 // don't have many duplicates, this function should be avoided, because of the
 // usage of `copy` that can increase CPU.
-func CombineUnique[T constraints.Ordered](a, b []T) []T {
+func CombineUnique[T cmp.Ordered](a, b []T) []T {
 	// We want b to be the smaller slice, so there are fewer elements to be added.
 	if len(b) > len(a) {
 		b, a = a, b
@@ -105,3 +100,24 @@ func MapFrom[T any, K comparable, V any](collection []T, fn func(T) (K, V)) map[
 	}
 	return out
 }
+
+// InsertUnique inserts an element into an ordered slice if the element is not
+// already present while maintaining the ordering property. Possibly updated
+// slice is returned.
+func InsertUnique[T cmp.Ordered](s []T, v T) []T {
+	idx, found := slices.BinarySearch(s, v)
+	if found {
+		return s
+	}
+	return slices.Insert(s, idx, v)
+}
+
+// Reduce applies a function against an accumulator and each element of a
+// collection, reducing it to a single value.
+func Reduce[T any, U any](collection []T, fn func(acc U, el T, idx int) U, init U) U {
+	acc := init
+	for idx, el := range collection {
+		acc = fn(acc, el, idx)
+	}
+	return acc
+}
diff --git a/pkg/util/smalltrace.go b/pkg/util/smalltrace.go
index 7467bab..c019882 100644
--- a/pkg/util/smalltrace.go
+++ b/pkg/util/smalltrace.go
@@ -1,12 +1,7 @@
 // Copyright 2016 The Cockroach Authors.
 //
-// Use of this software is governed by the Business Source License
-// included in the file licenses/BSL.txt.
-//
-// As of the Change Date specified in that file, in accordance with
-// the Business Source License, use of this software will be governed
-// by the Apache License, Version 2.0, included in the file
-// licenses/APL.txt.
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
 
 package util
 
diff --git a/pkg/util/stringencoding/string_encoding.go b/pkg/util/stringencoding/string_encoding.go
index 3fe3263..afa0090 100644
--- a/pkg/util/stringencoding/string_encoding.go
+++ b/pkg/util/stringencoding/string_encoding.go
@@ -7,13 +7,8 @@
 //
 // Copyright 2017 The Cockroach Authors.
 //
-// Use of this software is governed by the Business Source License
-// included in the file licenses/BSL.txt.
-//
-// As of the Change Date specified in that file, in accordance with
-// the Business Source License, use of this software will be governed
-// by the Apache License, Version 2.0, included in the file
-// licenses/APL.txt.
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
 
 // This code was derived from https://github.com/youtube/vitess.
 
@@ -78,6 +73,7 @@ func init() {
 
 // EncodeEscapedChar is used internally to write out a character from a larger
 // string that needs to be escaped to a buffer.
+// If slashedQuoteChar is true, it will write a backslash before the quoteChar.
 func EncodeEscapedChar(
 	buf *bytes.Buffer,
 	entireString string,
@@ -85,6 +81,7 @@ func EncodeEscapedChar(
 	currentByte byte,
 	currentIdx int,
 	quoteChar byte,
+	slashedQuoteChar bool,
 ) {
 	ln := utf8.RuneLen(currentRune)
 	if currentRune == utf8.RuneError {
@@ -99,10 +96,15 @@ func EncodeEscapedChar(
 	} else if ln == 1 {
 		// For single-byte runes, do the same as encodeSQLBytes.
 		if encodedChar := EncodeMap[currentByte]; encodedChar != DontEscape {
-			buf.WriteByte('\\')
+			if slashedQuoteChar {
+				buf.WriteByte('\\')
+			}
+
 			buf.WriteByte(encodedChar)
 		} else if currentByte == quoteChar {
-			buf.WriteByte('\\')
+			if slashedQuoteChar {
+				buf.WriteByte('\\')
+			}
 			buf.WriteByte(quoteChar)
 		} else {
 			// Escape non-printable characters.
diff --git a/pkg/util/strings.go b/pkg/util/strings.go
index c890fe5..d5cc408 100644
--- a/pkg/util/strings.go
+++ b/pkg/util/strings.go
@@ -1,12 +1,7 @@
 // Copyright 2016 The Cockroach Authors.
 //
-// Use of this software is governed by the Business Source License
-// included in the file licenses/BSL.txt.
-//
-// As of the Change Date specified in that file, in accordance with
-// the Business Source License, use of this software will be governed
-// by the Apache License, Version 2.0, included in the file
-// licenses/APL.txt.
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
 
 package util
 
diff --git a/pkg/util/strutil/util.go b/pkg/util/strutil/util.go
index c548535..92bd51b 100644
--- a/pkg/util/strutil/util.go
+++ b/pkg/util/strutil/util.go
@@ -1,12 +1,7 @@
 // Copyright 2022 The Cockroach Authors.
 //
-// Use of this software is governed by the Business Source License
-// included in the file licenses/BSL.txt.
-//
-// As of the Change Date specified in that file, in accordance with
-// the Business Source License, use of this software will be governed
-// by the Apache License, Version 2.0, included in the file
-// licenses/APL.txt.
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
 
 package strutil
 
diff --git a/pkg/util/syncutil/atomic.go b/pkg/util/syncutil/atomic.go
index 419d6b7..d4c99de 100644
--- a/pkg/util/syncutil/atomic.go
+++ b/pkg/util/syncutil/atomic.go
@@ -1,12 +1,7 @@
 // Copyright 2017 The Cockroach Authors.
 //
-// Use of this software is governed by the Business Source License
-// included in the file licenses/BSL.txt.
-//
-// As of the Change Date specified in that file, in accordance with
-// the Business Source License, use of this software will be governed
-// by the Apache License, Version 2.0, included in the file
-// licenses/APL.txt.
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
 
 package syncutil
 
@@ -19,70 +14,50 @@ import (
 // but for the float64 type. If you'd like to implement additional methods,
 // consider checking out the expvar Float type for guidance:
 // https://golang.org/src/expvar/expvar.go?s=2188:2222#L69
-type AtomicFloat64 uint64
+type AtomicFloat64 struct {
+	val atomic.Uint64
+}
 
-// StoreFloat64 atomically stores a float64 value into the provided address.
-func StoreFloat64(addr *AtomicFloat64, val float64) {
-	atomic.StoreUint64((*uint64)(addr), math.Float64bits(val))
+// Store atomically stores a float64 value.
+func (f *AtomicFloat64) Store(val float64) {
+	f.val.Store(math.Float64bits(val))
 }
 
-// LoadFloat64 atomically loads tha float64 value from the provided address.
-func LoadFloat64(addr *AtomicFloat64) (val float64) {
-	return math.Float64frombits(atomic.LoadUint64((*uint64)(addr)))
+// Load atomically loads tha float64 value.
+func (f *AtomicFloat64) Load() float64 {
+	return math.Float64frombits(f.val.Load())
 }
 
-func AddFloat64(addr *AtomicFloat64, add float64) (val float64) {
+// Add atomically adds delta to the float64 value and returns the new value.
+func (f *AtomicFloat64) Add(delta float64) (new float64) {
 	for {
-		oldFloat := LoadFloat64(addr)
-		oldInt := math.Float64bits(oldFloat)
-		newFloat := oldFloat + add
+		oldInt := f.val.Load()
+		oldFloat := math.Float64frombits(oldInt)
+		newFloat := oldFloat + delta
 		newInt := math.Float64bits(newFloat)
-		if atomic.CompareAndSwapUint64((*uint64)(addr), oldInt, newInt) {
-			return
+		if f.val.CompareAndSwap(oldInt, newInt) {
+			return newFloat
 		}
 	}
 }
 
-func StoreFloat64IfHigher(addr *AtomicFloat64, new float64) (val float64) {
+// StoreIfHigher atomically stores the given value if it is higher than the
+// current value (in which case the given value is returned; otherwise the
+// existing value is returned).
+func (f *AtomicFloat64) StoreIfHigher(new float64) (val float64) {
+	newInt := math.Float64bits(new)
 	for {
-		oldFloat := LoadFloat64(addr)
+		oldInt := f.val.Load()
+		oldFloat := math.Float64frombits(oldInt)
 		if oldFloat > new {
-			return
+			return oldFloat
 		}
-		oldInt := math.Float64bits(oldFloat)
-		newInt := math.Float64bits(new)
-		if atomic.CompareAndSwapUint64((*uint64)(addr), oldInt, newInt) {
-			return
+		if f.val.CompareAndSwap(oldInt, newInt) {
+			return new
 		}
 	}
 }
 
-// AtomicBool mimics an atomic boolean.
-type AtomicBool uint32
-
-// Set atomically sets the boolean.
-func (b *AtomicBool) Set(v bool) {
-	s := uint32(0)
-	if v {
-		s = 1
-	}
-	atomic.StoreUint32((*uint32)(b), s)
-}
-
-// Get atomically gets the boolean.
-func (b *AtomicBool) Get() bool {
-	return atomic.LoadUint32((*uint32)(b)) != 0
-}
-
-// Swap atomically swaps the value.
-func (b *AtomicBool) Swap(v bool) bool {
-	wanted := uint32(0)
-	if v {
-		wanted = 1
-	}
-	return atomic.SwapUint32((*uint32)(b), wanted) != 0
-}
-
 // AtomicString gives you atomic-style APIs for string.
 type AtomicString struct {
 	s atomic.Value
diff --git a/pkg/util/syncutil/int_map.go b/pkg/util/syncutil/map.go
similarity index 57%
rename from pkg/util/syncutil/int_map.go
rename to pkg/util/syncutil/map.go
index 6fa1c54..7b31eff 100644
--- a/pkg/util/syncutil/int_map.go
+++ b/pkg/util/syncutil/map.go
@@ -1,12 +1,7 @@
 // Copyright 2019 The Cockroach Authors.
 //
-// Use of this software is governed by the Business Source License
-// included in the file licenses/BSL.txt.
-//
-// As of the Change Date specified in that file, in accordance with
-// the Business Source License, use of this software will be governed
-// by the Apache License, Version 2.0, included in the file
-// licenses/APL.txt.
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
 
 // Copyright 2016 The Go Authors. All rights reserved.
 // Use of this source code is governed by a BSD-style
@@ -21,25 +16,35 @@ import (
 	"unsafe"
 )
 
-// IntMap is a concurrent map with amortized-constant-time loads, stores, and
-// deletes.  It is safe for multiple goroutines to call a Map's methods
-// concurrently.
+// Map is like a Go map[K]*V but is safe for concurrent use by multiple
+// goroutines without additional locking or coordination.
+// Loads, stores, and deletes run in amortized constant time.
 //
-// It is optimized for use in concurrent loops with keys that are
-// stable over time, and either few steady-state stores, or stores
-// localized to one goroutine per key.
+// The Map type is specialized. Most code should use a plain Go map instead,
+// with separate locking or coordination, for better type safety and to make it
+// easier to maintain other invariants along with the map content.
 //
-// For use cases that do not share these attributes, it will likely have
-// comparable or worse performance and worse type safety than an ordinary
-// map paired with a read-write mutex.
+// The Map type is optimized for two common use cases: (1) when the entry for a
+// given key is only ever written once but read many times, as in caches that
+// only grow, or (2) when multiple goroutines read, write, and overwrite entries
+// for disjoint sets of keys. In these two cases, use of an Map may
+// significantly reduce lock contention compared to a Go map paired with a
+// separate Mutex or RWMutex.
 //
-// Nil values are not supported; to use an IntMap as a set store a
-// dummy non-nil pointer instead of nil.
+// Nil values are not supported; to use an Map as a set store a dummy non-nil
+// pointer instead of nil. The Set type is provided for this purpose.
 //
 // The zero Map is valid and empty.
 //
-// A Map must not be copied after first use.
-type IntMap struct {
+// An Map must not be copied after first use.
+//
+// In the terminology of the Go memory model, Map arranges that a write
+// operation “synchronizes before” any read operation that observes the effect
+// of the write, where read and write operations are defined as follows.
+// Load, LoadAndDelete, LoadOrStore are read operations;
+// Delete, LoadAndDelete, and Store are write operations;
+// and LoadOrStore is a write operation when it returns loaded set to false.
+type Map[K comparable, V any] struct {
 	mu Mutex
 
 	// read contains the portion of the map's contents that are safe for
@@ -51,7 +56,7 @@ type IntMap struct {
 	// Entries stored in read may be updated concurrently without mu, but updating
 	// a previously-expunged entry requires that the entry be copied to the dirty
 	// map and unexpunged with mu held.
-	read unsafe.Pointer // *readOnly
+	read atomic.Pointer[readOnly[K, V]]
 
 	// dirty contains the portion of the map's contents that require mu to be
 	// held. To ensure that the dirty map can be promoted to the read map quickly,
@@ -63,7 +68,7 @@ type IntMap struct {
 	//
 	// If the dirty map is nil, the next write to the map will initialize it by
 	// making a shallow copy of the clean map, omitting stale entries.
-	dirty map[int64]*entry
+	dirty map[K]*entry[V]
 
 	// misses counts the number of loads since the read map was last updated that
 	// needed to lock mu to determine whether the key was present.
@@ -75,20 +80,17 @@ type IntMap struct {
 }
 
 // readOnly is an immutable struct stored atomically in the Map.read field.
-type readOnly struct {
-	m       map[int64]*entry
+type readOnly[K comparable, V any] struct {
+	m       map[K]*entry[V]
 	amended bool // true if the dirty map contains some key not in m.
 }
 
-// expunged is an arbitrary pointer that marks entries which have been deleted
-// from the dirty map.
-var expunged = unsafe.Pointer(new(int))
-
 // An entry is a slot in the map corresponding to a particular key.
-type entry struct {
+type entry[V any] struct {
 	// p points to the value stored for the entry.
 	//
-	// If p == nil, the entry has been deleted and m.dirty == nil.
+	// If p == nil, the entry has been deleted, and either m.dirty == nil or
+	// m.dirty[key] is e.
 	//
 	// If p == expunged, the entry has been deleted, m.dirty != nil, and the entry
 	// is missing from m.dirty.
@@ -104,18 +106,27 @@ type entry struct {
 	// p != expunged. If p == expunged, an entry's associated value can be updated
 	// only after first setting m.dirty[key] = e so that lookups using the dirty
 	// map find the entry.
-	p unsafe.Pointer
+	p atomic.Pointer[V]
+}
+
+func newEntry[V any](v *V) *entry[V] {
+	e := &entry[V]{}
+	e.p.Store(v)
+	return e
 }
 
-func newEntry(r unsafe.Pointer) *entry {
-	return &entry{p: r}
+func (m *Map[K, V]) loadReadOnly() readOnly[K, V] {
+	if p := m.read.Load(); p != nil {
+		return *p
+	}
+	return readOnly[K, V]{}
 }
 
 // Load returns the value stored in the map for a key, or nil if no
 // value is present.
 // The ok result indicates whether value was found in the map.
-func (m *IntMap) Load(key int64) (value unsafe.Pointer, ok bool) {
-	read := m.getRead()
+func (m *Map[K, V]) Load(key K) (value *V, ok bool) {
+	read := m.loadReadOnly()
 	e, ok := read.m[key]
 	if !ok && read.amended {
 		func() {
@@ -124,7 +135,7 @@ func (m *IntMap) Load(key int64) (value unsafe.Pointer, ok bool) {
 			// Avoid reporting a spurious miss if m.dirty got promoted while we were
 			// blocked on m.mu. (If further loads of the same key will not miss, it's
 			// not worth copying the dirty map for this key.)
-			read = m.getRead()
+			read = m.loadReadOnly()
 			e, ok = read.m[key]
 			if !ok && read.amended {
 				e, ok = m.dirty[key]
@@ -141,24 +152,26 @@ func (m *IntMap) Load(key int64) (value unsafe.Pointer, ok bool) {
 	return e.load()
 }
 
-func (e *entry) load() (value unsafe.Pointer, ok bool) {
-	p := atomic.LoadPointer(&e.p)
-	if p == nil || p == expunged {
+func (e *entry[V]) load() (value *V, ok bool) {
+	p := e.p.Load()
+	if p == nil || p == e.expunged() {
 		return nil, false
 	}
 	return p, true
 }
 
 // Store sets the value for a key.
-func (m *IntMap) Store(key int64, value unsafe.Pointer) {
-	read := m.getRead()
+func (m *Map[K, V]) Store(key K, value *V) {
+	m.assertNotNil(value)
+
+	read := m.loadReadOnly()
 	if e, ok := read.m[key]; ok && e.tryStore(value) {
 		return
 	}
 
 	m.mu.Lock()
 	defer m.mu.Unlock()
-	read = m.getRead()
+	read = m.loadReadOnly()
 	if e, ok := read.m[key]; ok {
 		if e.unexpungeLocked() {
 			// The entry was previously expunged, which implies that there is a
@@ -173,29 +186,34 @@ func (m *IntMap) Store(key int64, value unsafe.Pointer) {
 			// We're adding the first new key to the dirty map.
 			// Make sure it is allocated and mark the read-only map as incomplete.
 			m.dirtyLocked()
-			atomic.StorePointer(&m.read, unsafe.Pointer(&readOnly{m: read.m, amended: true}))
+			m.read.Store(&readOnly[K, V]{m: read.m, amended: true})
 		}
 		m.dirty[key] = newEntry(value)
 	}
 }
 
+// assertNotNil asserts that a provided value to store is non-nil. Map does not
+// support nil values because nil is used to indicate that an entry has been
+// deleted. Callers should use a dummy non-nil pointer instead of nil.
+func (*Map[K, V]) assertNotNil(v *V) {
+	if v == nil {
+		panic("syncutil.Map: store with a nil value is unsupported")
+	}
+}
+
 // tryStore stores a value if the entry has not been expunged.
 //
 // If the entry is expunged, tryStore returns false and leaves the entry
 // unchanged.
-func (e *entry) tryStore(r unsafe.Pointer) bool {
-	p := atomic.LoadPointer(&e.p)
-	if p == expunged {
-		return false
-	}
+func (e *entry[V]) tryStore(v *V) bool {
 	for {
-		if atomic.CompareAndSwapPointer(&e.p, p, r) {
-			return true
-		}
-		p = atomic.LoadPointer(&e.p)
-		if p == expunged {
+		p := e.p.Load()
+		if p == e.expunged() {
 			return false
 		}
+		if e.p.CompareAndSwap(p, v) {
+			return true
+		}
 	}
 }
 
@@ -203,23 +221,25 @@ func (e *entry) tryStore(r unsafe.Pointer) bool {
 //
 // If the entry was previously expunged, it must be added to the dirty map
 // before m.mu is unlocked.
-func (e *entry) unexpungeLocked() (wasExpunged bool) {
-	return atomic.CompareAndSwapPointer(&e.p, expunged, nil)
+func (e *entry[V]) unexpungeLocked() (wasExpunged bool) {
+	return e.p.CompareAndSwap(e.expunged(), nil)
 }
 
 // storeLocked unconditionally stores a value to the entry.
 //
 // The entry must be known not to be expunged.
-func (e *entry) storeLocked(r unsafe.Pointer) {
-	atomic.StorePointer(&e.p, r)
+func (e *entry[V]) storeLocked(v *V) {
+	e.p.Store(v)
 }
 
 // LoadOrStore returns the existing value for the key if present.
 // Otherwise, it stores and returns the given value.
 // The loaded result is true if the value was loaded, false if stored.
-func (m *IntMap) LoadOrStore(key int64, value unsafe.Pointer) (actual unsafe.Pointer, loaded bool) {
+func (m *Map[K, V]) LoadOrStore(key K, value *V) (actual *V, loaded bool) {
+	m.assertNotNil(value)
+
 	// Avoid locking if it's a clean hit.
-	read := m.getRead()
+	read := m.loadReadOnly()
 	if e, ok := read.m[key]; ok {
 		actual, loaded, ok = e.tryLoadOrStore(value)
 		if ok {
@@ -229,7 +249,7 @@ func (m *IntMap) LoadOrStore(key int64, value unsafe.Pointer) (actual unsafe.Poi
 
 	m.mu.Lock()
 	defer m.mu.Unlock()
-	read = m.getRead()
+	read = m.loadReadOnly()
 	if e, ok := read.m[key]; ok {
 		if e.unexpungeLocked() {
 			m.dirty[key] = e
@@ -243,7 +263,7 @@ func (m *IntMap) LoadOrStore(key int64, value unsafe.Pointer) (actual unsafe.Poi
 			// We're adding the first new key to the dirty map.
 			// Make sure it is allocated and mark the read-only map as incomplete.
 			m.dirtyLocked()
-			atomic.StorePointer(&m.read, unsafe.Pointer(&readOnly{m: read.m, amended: true}))
+			m.read.Store(&readOnly[K, V]{m: read.m, amended: true})
 		}
 		m.dirty[key] = newEntry(value)
 		actual, loaded = value, false
@@ -257,9 +277,9 @@ func (m *IntMap) LoadOrStore(key int64, value unsafe.Pointer) (actual unsafe.Poi
 //
 // If the entry is expunged, tryLoadOrStore leaves the entry unchanged and
 // returns with ok==false.
-func (e *entry) tryLoadOrStore(r unsafe.Pointer) (actual unsafe.Pointer, loaded, ok bool) {
-	p := atomic.LoadPointer(&e.p)
-	if p == expunged {
+func (e *entry[V]) tryLoadOrStore(v *V) (actual *V, loaded, ok bool) {
+	p := e.p.Load()
+	if p == e.expunged() {
 		return nil, false, false
 	}
 	if p != nil {
@@ -267,11 +287,11 @@ func (e *entry) tryLoadOrStore(r unsafe.Pointer) (actual unsafe.Pointer, loaded,
 	}
 
 	for {
-		if atomic.CompareAndSwapPointer(&e.p, nil, r) {
-			return r, false, true
+		if e.p.CompareAndSwap(nil, v) {
+			return v, false, true
 		}
-		p = atomic.LoadPointer(&e.p)
-		if p == expunged {
+		p = e.p.Load()
+		if p == e.expunged() {
 			return nil, false, false
 		}
 		if p != nil {
@@ -280,34 +300,46 @@ func (e *entry) tryLoadOrStore(r unsafe.Pointer) (actual unsafe.Pointer, loaded,
 	}
 }
 
-// Delete deletes the value for a key.
-func (m *IntMap) Delete(key int64) {
-	read := m.getRead()
+// LoadAndDelete deletes the value for a key, returning the previous value if any.
+// The loaded result reports whether the key was present.
+func (m *Map[K, V]) LoadAndDelete(key K) (value *V, loaded bool) {
+	read := m.loadReadOnly()
 	e, ok := read.m[key]
 	if !ok && read.amended {
 		func() {
 			m.mu.Lock()
 			defer m.mu.Unlock()
-			read = m.getRead()
+			read = m.loadReadOnly()
 			e, ok = read.m[key]
 			if !ok && read.amended {
+				e, ok = m.dirty[key]
 				delete(m.dirty, key)
+				// Regardless of whether the entry was present, record a miss: this key
+				// will take the slow path until the dirty map is promoted to the read
+				// map.
+				m.missLocked()
 			}
 		}()
 	}
 	if ok {
-		e.delete()
+		return e.delete()
 	}
+	return nil, false
 }
 
-func (e *entry) delete() (hadValue bool) {
+// Delete deletes the value for a key.
+func (m *Map[K, V]) Delete(key K) {
+	m.LoadAndDelete(key)
+}
+
+func (e *entry[V]) delete() (value *V, hadValue bool) {
 	for {
-		p := atomic.LoadPointer(&e.p)
-		if p == nil || p == expunged {
-			return false
+		p := e.p.Load()
+		if p == nil || p == e.expunged() {
+			return nil, false
 		}
-		if atomic.CompareAndSwapPointer(&e.p, p, nil) {
-			return true
+		if e.p.CompareAndSwap(p, nil) {
+			return p, true
 		}
 	}
 }
@@ -317,17 +349,18 @@ func (e *entry) delete() (hadValue bool) {
 //
 // Range does not necessarily correspond to any consistent snapshot of the Map's
 // contents: no key will be visited more than once, but if the value for any key
-// is stored or deleted concurrently, Range may reflect any mapping for that key
-// from any point during the Range call.
+// is stored or deleted concurrently (including by f), Range may reflect any
+// mapping for that key from any point during the Range call. Range does not
+// block other methods on the receiver; even f itself may call any method on m.
 //
 // Range may be O(N) with the number of elements in the map even if f returns
 // false after a constant number of calls.
-func (m *IntMap) Range(f func(key int64, value unsafe.Pointer) bool) {
+func (m *Map[K, V]) Range(f func(key K, value *V) bool) {
 	// We need to be able to iterate over all of the keys that were already
 	// present at the start of the call to Range.
 	// If read.amended is false, then read.m satisfies that property without
 	// requiring us to hold m.mu for a long time.
-	read := m.getRead()
+	read := m.loadReadOnly()
 	if read.amended {
 		// m.dirty contains keys not in read.m. Fortunately, Range is already O(N)
 		// (assuming the caller does not break out early), so a call to Range
@@ -336,13 +369,13 @@ func (m *IntMap) Range(f func(key int64, value unsafe.Pointer) bool) {
 		func() {
 			m.mu.Lock()
 			defer m.mu.Unlock()
-			read = m.getRead()
+			read = m.loadReadOnly()
 			if read.amended {
 				// Don't let read escape directly, otherwise it will allocate even
 				// when read.amended is false. Instead, constrain the allocation to
 				// just this branch.
-				newRead := &readOnly{m: m.dirty}
-				atomic.StorePointer(&m.read, unsafe.Pointer(newRead))
+				newRead := &readOnly[K, V]{m: m.dirty}
+				m.read.Store(newRead)
 				read = *newRead
 				m.dirty = nil
 				m.misses = 0
@@ -361,23 +394,23 @@ func (m *IntMap) Range(f func(key int64, value unsafe.Pointer) bool) {
 	}
 }
 
-func (m *IntMap) missLocked() {
+func (m *Map[K, V]) missLocked() {
 	m.misses++
 	if m.misses < len(m.dirty) {
 		return
 	}
-	atomic.StorePointer(&m.read, unsafe.Pointer(&readOnly{m: m.dirty}))
+	m.read.Store(&readOnly[K, V]{m: m.dirty})
 	m.dirty = nil
 	m.misses = 0
 }
 
-func (m *IntMap) dirtyLocked() {
+func (m *Map[K, V]) dirtyLocked() {
 	if m.dirty != nil {
 		return
 	}
 
-	read := m.getRead()
-	m.dirty = make(map[int64]*entry, len(read.m))
+	read := m.loadReadOnly()
+	m.dirty = make(map[K]*entry[V], len(read.m))
 	for k, e := range read.m {
 		if !e.tryExpungeLocked() {
 			m.dirty[k] = e
@@ -385,21 +418,28 @@ func (m *IntMap) dirtyLocked() {
 	}
 }
 
-func (m *IntMap) getRead() readOnly {
-	read := (*readOnly)(atomic.LoadPointer(&m.read))
-	if read == nil {
-		return readOnly{}
-	}
-	return *read
+// expunged is an untyped arbitrary pointer that marks entries which have been
+// deleted from the dirty map.
+//
+// It is safe for the size of the expunged pointer to differ from the size of a
+// pointer to a V because the expunged pointer is never dereferenced. However,
+// we use a large allocation for the expunged pointer to suppress checkptr
+// assertions under race. Bump this size if you see checkptr failures.
+var expunged = unsafe.Pointer(new([1 << 14]byte /* 16KiB */))
+
+// expunged returns the typed arbitrary value that marks entries which have been
+// deleted from the dirty map.
+func (e *entry[V]) expunged() *V {
+	return (*V)(expunged)
 }
 
-func (e *entry) tryExpungeLocked() (isExpunged bool) {
-	p := atomic.LoadPointer(&e.p)
+func (e *entry[V]) tryExpungeLocked() (isExpunged bool) {
+	p := e.p.Load()
 	for p == nil {
-		if atomic.CompareAndSwapPointer(&e.p, nil, expunged) {
+		if e.p.CompareAndSwap(nil, e.expunged()) {
 			return true
 		}
-		p = atomic.LoadPointer(&e.p)
+		p = e.p.Load()
 	}
-	return p == expunged
+	return p == e.expunged()
 }
diff --git a/pkg/util/syncutil/mutex_deadlock.go b/pkg/util/syncutil/mutex_deadlock.go
index a042b94..d687325 100644
--- a/pkg/util/syncutil/mutex_deadlock.go
+++ b/pkg/util/syncutil/mutex_deadlock.go
@@ -1,15 +1,9 @@
 // Copyright 2016 The Cockroach Authors.
 //
-// Use of this software is governed by the Business Source License
-// included in the file licenses/BSL.txt.
-//
-// As of the Change Date specified in that file, in accordance with
-// the Business Source License, use of this software will be governed
-// by the Apache License, Version 2.0, included in the file
-// licenses/APL.txt.
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
 
 //go:build deadlock
-// +build deadlock
 
 package syncutil
 
@@ -57,3 +51,8 @@ func (rw *RWMutex) AssertRHeld() {
 func (rw *RWMutex) TryLock() bool {
 	return false
 }
+
+// TryRLock is a no-op for deadlock mutexes.
+func (rw *RWMutex) TryRLock() bool {
+	return false
+}
diff --git a/pkg/util/syncutil/mutex_sync.go b/pkg/util/syncutil/mutex_sync.go
index 173de0d..c431e39 100644
--- a/pkg/util/syncutil/mutex_sync.go
+++ b/pkg/util/syncutil/mutex_sync.go
@@ -1,15 +1,9 @@
 // Copyright 2016 The Cockroach Authors.
 //
-// Use of this software is governed by the Business Source License
-// included in the file licenses/BSL.txt.
-//
-// As of the Change Date specified in that file, in accordance with
-// the Business Source License, use of this software will be governed
-// by the Apache License, Version 2.0, included in the file
-// licenses/APL.txt.
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
 
 //go:build !deadlock && !race
-// +build !deadlock,!race
 
 package syncutil
 
diff --git a/pkg/util/syncutil/mutex_sync_race.go b/pkg/util/syncutil/mutex_sync_race.go
index 82ef1d7..be806ee 100644
--- a/pkg/util/syncutil/mutex_sync_race.go
+++ b/pkg/util/syncutil/mutex_sync_race.go
@@ -1,15 +1,9 @@
 // Copyright 2016 The Cockroach Authors.
 //
-// Use of this software is governed by the Business Source License
-// included in the file licenses/BSL.txt.
-//
-// As of the Change Date specified in that file, in accordance with
-// the Business Source License, use of this software will be governed
-// by the Apache License, Version 2.0, included in the file
-// licenses/APL.txt.
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
 
 //go:build !deadlock && race
-// +build !deadlock,race
 
 package syncutil
 
@@ -33,6 +27,15 @@ func (m *Mutex) Lock() {
 	atomic.StoreInt32(&m.wLocked, 1)
 }
 
+// TryLock tries to lock m and reports whether it succeeded.
+func (m *Mutex) TryLock() bool {
+	if !m.mu.TryLock() {
+		return false
+	}
+	atomic.StoreInt32(&m.wLocked, 1)
+	return true
+}
+
 // Unlock unlocks m.
 func (m *Mutex) Unlock() {
 	atomic.StoreInt32(&m.wLocked, 0)
@@ -55,33 +58,51 @@ func (m *Mutex) AssertHeld() {
 
 // An RWMutex is a reader/writer mutual exclusion lock.
 type RWMutex struct {
-	sync.RWMutex
+	mu      sync.RWMutex
 	wLocked int32 // updated atomically
 	rLocked int32 // updated atomically
 }
 
 // Lock locks rw for writing.
 func (rw *RWMutex) Lock() {
-	rw.RWMutex.Lock()
+	rw.mu.Lock()
 	atomic.StoreInt32(&rw.wLocked, 1)
 }
 
+// TryLock tries to lock rw for writing and reports whether it succeeded.
+func (rw *RWMutex) TryLock() bool {
+	if !rw.mu.TryLock() {
+		return false
+	}
+	atomic.StoreInt32(&rw.wLocked, 1)
+	return true
+}
+
 // Unlock unlocks rw for writing.
 func (rw *RWMutex) Unlock() {
 	atomic.StoreInt32(&rw.wLocked, 0)
-	rw.RWMutex.Unlock()
+	rw.mu.Unlock()
 }
 
 // RLock locks m for reading.
 func (rw *RWMutex) RLock() {
-	rw.RWMutex.RLock()
+	rw.mu.RLock()
+	atomic.AddInt32(&rw.rLocked, 1)
+}
+
+// TryRLock tries to lock rw for reading and reports whether it succeeded.
+func (rw *RWMutex) TryRLock() bool {
+	if !rw.mu.TryRLock() {
+		return false
+	}
 	atomic.AddInt32(&rw.rLocked, 1)
+	return true
 }
 
 // RUnlock undoes a single RLock call.
 func (rw *RWMutex) RUnlock() {
 	atomic.AddInt32(&rw.rLocked, -1)
-	rw.RWMutex.RUnlock()
+	rw.mu.RUnlock()
 }
 
 // RLocker returns a Locker interface that implements
diff --git a/pkg/util/syncutil/mutex_tracing.go b/pkg/util/syncutil/mutex_tracing.go
new file mode 100644
index 0000000..ddc58f2
--- /dev/null
+++ b/pkg/util/syncutil/mutex_tracing.go
@@ -0,0 +1,120 @@
+// Copyright 2023 The Cockroach Authors.
+//
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
+
+package syncutil
+
+import (
+	"context"
+	"sync"
+	"time"
+)
+
+// TracedLock is like Lock, but logs a trace event using the provided context if
+// the lock acquisition is slow.
+func (m *Mutex) TracedLock(ctx context.Context) { tracedLock(ctx, m) }
+
+// TracedLock is like Lock, but logs a trace event using the provided context if
+// the lock acquisition is slow.
+func (rw *RWMutex) TracedLock(ctx context.Context) { tracedLock(ctx, rw) }
+
+// TracedRLock is like RLock, but logs a trace event using the provided context
+// if the lock acquisition is slow.
+func (rw *RWMutex) TracedRLock(ctx context.Context) { tracedLock(ctx, rw.rTryLocker()) }
+
+// TimedLock is like Lock, but returns the time it took to acquire the lock.
+func (m *Mutex) TimedLock() time.Duration { return timedLock(m) }
+
+// TimedLock is like Lock, but returns the time it took to acquire the lock.
+func (rw *RWMutex) TimedLock() time.Duration { return timedLock(rw) }
+
+// TimedRLock is like RLock, but returns the time it took to acquire the lock.
+func (rw *RWMutex) TimedRLock() time.Duration { return timedLock(rw.rTryLocker()) }
+
+// rTryLocker returns a tryLocker interface that implements the Lock, Unlock,
+// and TryLock methods by calling rw.RLock, rw.RUnlock, and rw.TryRLock,
+// respectively.
+func (rw *RWMutex) rTryLocker() tryLocker { return (*rTryLocker)(rw) }
+
+type rTryLocker RWMutex
+
+func (r *rTryLocker) Lock()         { (*RWMutex)(r).RLock() }
+func (r *rTryLocker) Unlock()       { (*RWMutex)(r).RUnlock() }
+func (r *rTryLocker) TryLock() bool { return (*RWMutex)(r).TryRLock() }
+
+// tryLocker extends the sync.Locker interface with a TryLock method.
+type tryLocker interface {
+	sync.Locker
+	TryLock() bool
+}
+
+// tracedLock is like l.Lock, but logs a trace event using the provided context
+// if the lock acquisition is slow.
+//
+// Explanation of logic:
+//
+// The function begins with a fast-path call to TryLock. Most mutexes are
+// uncontended and TryLock amounts to a single atomic CAS. If the CAS succeeds,
+// no additional work is needed. If the CAS fails, we move on to the slow-path.
+//
+// On the slow path, we first check if expensive logging is enabled. If not, we
+// simply call Lock without checking the time. We only time the acquisition if
+// expensive logging is enabled. If we do time the acquisition and it is slow,
+// we log a warning message to the logs/trace.
+//
+// It could be a reasonable choice to switch the order of the TryLock and
+// ExpensiveLogEnabled checks. However, we expect that most mutex acquisitions
+// will be uncontended and the TryLock check is cheaper than the expensive log
+// check.
+//
+// NOTE: because of this ordering of fast-path checks, it does not make sense to
+// implement tracedLock using timedLock, though it is conceptually an extension
+// of that functionality.
+func tracedLock(ctx context.Context, l tryLocker) {
+	if enableTracedLockFastPath && l.TryLock() {
+		return // fast-path
+	}
+	const vLevel = 3
+	if !LogExpensiveLogEnabled(ctx, vLevel) {
+		l.Lock()
+		return
+	}
+	start := time.Now()
+	l.Lock()
+	if dur := time.Since(start); dur >= slowLockLogThreshold {
+		LogVEventfDepth(ctx, 2 /* depth */, vLevel, "slow mutex acquisition took %s", dur)
+	}
+}
+
+// timedLock is like l.Lock, but returns the time it took to acquire the lock.
+// Returns 0 if the lock was acquired without blocking.
+func timedLock(l tryLocker) time.Duration {
+	if enableTracedLockFastPath && l.TryLock() {
+		return 0 // fast-path
+	}
+	start := time.Now()
+	l.Lock()
+	return time.Since(start)
+}
+
+// enableTracedLockFastPath is used in tests to disable the fast-path of
+// tracedLock and timedLock.
+var enableTracedLockFastPath = true
+
+// slowLockLogThreshold is the threshold at which a mutex acquisition is
+// considered slow enough to log. It is a variable and not constant so that it
+// can be changed in tests.
+var slowLockLogThreshold = 500 * time.Microsecond
+
+// LogExpensiveLogEnabled is injected from pkg/util/log to avoid an import
+// cycle. This also allows it to be mocked out in tests.
+//
+// See log.ExpensiveLogEnabled for more details.
+var LogExpensiveLogEnabled = func(ctx context.Context, level int32) bool { return false }
+
+// LogVEventfDepth is injected from pkg/util/log to avoid an import
+// cycle. This also allows it to be mocked out in tests.
+//
+// See log.LogVEventfDepth for more details.
+var LogVEventfDepth = func(ctx context.Context, depth int, level int32, format string, args ...interface{}) {}
diff --git a/pkg/util/syncutil/set.go b/pkg/util/syncutil/set.go
new file mode 100644
index 0000000..3f3cbc3
--- /dev/null
+++ b/pkg/util/syncutil/set.go
@@ -0,0 +1,57 @@
+// Copyright 2024 The Cockroach Authors.
+//
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
+
+package syncutil
+
+// Set is like a Go map[V]struct{} but is safe for concurrent use by multiple
+// goroutines without additional locking or coordination.
+// Loads, stores, and deletes run in amortized constant time.
+//
+// See the Map type for more details.
+type Set[V comparable] struct {
+	m Map[V, struct{}]
+}
+
+// Contains returns whether the value is stored in the set.
+//
+// Both Add and Remove return whether the value previously existed in the set,
+// so Contains is typically not needed when later calling one of those methods.
+// In fact, its use in logic that later mutates the set may be racy if not
+// carefully considered, as there is no synchronization between the Contains
+// call and the subsequent Add or Remove call.
+func (s *Set[V]) Contains(value V) bool {
+	_, ok := s.m.Load(value)
+	return ok
+}
+
+// dummyValue is a placeholder value for all values in the map.
+var dummyValue = new(struct{})
+
+// Add adds the value to the set.
+//
+// Returns whether the value was added (true) or was already present (false).
+func (s *Set[V]) Add(value V) bool {
+	_, loaded := s.m.LoadOrStore(value, dummyValue)
+	return !loaded
+}
+
+// Remove removes the value from the set.
+//
+// Returns whether the value was present and removed (true) or was not present
+// and not removed (false).
+func (s *Set[V]) Remove(value V) bool {
+	_, loaded := s.m.LoadAndDelete(value)
+	return loaded
+}
+
+// Range calls f sequentially for each value present in the set.
+// If f returns false, range stops the iteration.
+//
+// See Map.Range for more details.
+func (s *Set[V]) Range(f func(value V) bool) {
+	s.m.Range(func(value V, _ *struct{}) bool {
+		return f(value)
+	})
+}
diff --git a/pkg/util/system/cache_line.go b/pkg/util/system/cache_line.go
new file mode 100644
index 0000000..b3a2d02
--- /dev/null
+++ b/pkg/util/system/cache_line.go
@@ -0,0 +1,27 @@
+// Copyright 2024 The Cockroach Authors.
+//
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
+
+package system
+
+import (
+	"unsafe"
+
+	"golang.org/x/sys/cpu"
+)
+
+// CacheLineSize is the size of a CPU cache line in bytes, or a non-zero
+// estimate if the size is unknown.
+const CacheLineSize = max(
+	int(unsafe.Sizeof(cpu.CacheLinePad{})),
+	// The size of the CacheLinePad struct is 0 on some software-abstracted
+	// platforms, like Wasm, where the cache line size of the underlying CPU is
+	// not known. In such cases, use a reasonable default value of 64 bytes.
+	//
+	// NOTE: we use max instead of an init-time comparison so that CacheLineSize
+	// can be used in const expressions. The subtraction here drives this term
+	// below 0 to be ignored by max in all cases except when the size of the
+	// CacheLinePad struct is 0.
+	64-65*int(unsafe.Sizeof(cpu.CacheLinePad{})),
+)
diff --git a/pkg/util/system/num_cpu.go b/pkg/util/system/num_cpu.go
new file mode 100644
index 0000000..97460b3
--- /dev/null
+++ b/pkg/util/system/num_cpu.go
@@ -0,0 +1,22 @@
+// Copyright 2020 The Cockroach Authors.
+//
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
+
+package system
+
+import "runtime"
+
+// NumCPU returns the number of logical CPUs usable by the current process.
+//
+// !!Note!! If you are considering using this to scale parallelism with the
+// machine size, use runtime.GOMAXPROCS(0) instead. The latter is better because
+// GOMAXPROCS is reduced with certain test runs (with the race detector); it can
+// also be reduced in containerized environments.
+//
+// The set of available CPUs is checked by querying the operating system
+// at process startup. Changes to operating system CPU allocation after
+// process startup are not reflected.
+func NumCPU() int {
+	return runtime.NumCPU()
+}
diff --git a/pkg/util/testaddr_default.go b/pkg/util/testaddr_default.go
index a06e4e7..6aac26b 100644
--- a/pkg/util/testaddr_default.go
+++ b/pkg/util/testaddr_default.go
@@ -1,15 +1,9 @@
 // Copyright 2016 The Cockroach Authors.
 //
-// Use of this software is governed by the Business Source License
-// included in the file licenses/BSL.txt.
-//
-// As of the Change Date specified in that file, in accordance with
-// the Business Source License, use of this software will be governed
-// by the Apache License, Version 2.0, included in the file
-// licenses/APL.txt.
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
 
 //go:build !linux
-// +build !linux
 
 package util
 
diff --git a/pkg/util/testaddr_random.go b/pkg/util/testaddr_random.go
index fde25a4..0139527 100644
--- a/pkg/util/testaddr_random.go
+++ b/pkg/util/testaddr_random.go
@@ -1,15 +1,9 @@
 // Copyright 2016 The Cockroach Authors.
 //
-// Use of this software is governed by the Business Source License
-// included in the file licenses/BSL.txt.
-//
-// As of the Change Date specified in that file, in accordance with
-// the Business Source License, use of this software will be governed
-// by the Apache License, Version 2.0, included in the file
-// licenses/APL.txt.
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
 
 //go:build linux
-// +build linux
 
 package util
 
diff --git a/pkg/util/timeofday/time_of_day.go b/pkg/util/timeofday/time_of_day.go
index 69fd497..af20f70 100644
--- a/pkg/util/timeofday/time_of_day.go
+++ b/pkg/util/timeofday/time_of_day.go
@@ -1,12 +1,7 @@
 // Copyright 2017 The Cockroach Authors.
 //
-// Use of this software is governed by the Business Source License
-// included in the file licenses/BSL.txt.
-//
-// As of the Change Date specified in that file, in accordance with
-// the Business Source License, use of this software will be governed
-// by the Apache License, Version 2.0, included in the file
-// licenses/APL.txt.
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
 
 package timeofday
 
@@ -34,12 +29,12 @@ const (
 	// Max is the maximum TimeOfDay value (1 second before midnight)
 	Max = Time2400
 
-	microsecondsPerSecond = 1e6
-	microsecondsPerMinute = 60 * microsecondsPerSecond
-	microsecondsPerHour   = 60 * microsecondsPerMinute
-	microsecondsPerDay    = 24 * microsecondsPerHour
-	nanosPerMicro         = 1000
-	secondsPerDay         = 24 * 60 * 60
+	microsecondsPerSecond int64 = 1e6
+	microsecondsPerMinute       = 60 * microsecondsPerSecond
+	microsecondsPerHour         = 60 * microsecondsPerMinute
+	microsecondsPerDay          = 24 * microsecondsPerHour
+	nanosPerMicro               = 1000
+	secondsPerDay               = 24 * 60 * 60
 )
 
 // New creates a TimeOfDay representing the specified time.
@@ -147,19 +142,19 @@ func (t TimeOfDay) Hour() int {
 	if t == Time2400 {
 		return 24
 	}
-	return int(int64(t)%microsecondsPerDay) / microsecondsPerHour
+	return int(int64(t) % microsecondsPerDay / microsecondsPerHour)
 }
 
 // Minute returns the minute offset within the hour specified by t, in the
 // range [0, 59].
 func (t TimeOfDay) Minute() int {
-	return int(int64(t)%microsecondsPerHour) / microsecondsPerMinute
+	return int(int64(t) % microsecondsPerHour / microsecondsPerMinute)
 }
 
 // Second returns the second offset within the minute specified by t, in the
 // range [0, 59].
 func (t TimeOfDay) Second() int {
-	return int(int64(t)%microsecondsPerMinute) / microsecondsPerSecond
+	return int(int64(t) % microsecondsPerMinute / microsecondsPerSecond)
 }
 
 // Microsecond returns the microsecond offset within the second specified by t,
diff --git a/pkg/util/timetz/timetz.go b/pkg/util/timetz/timetz.go
index c1788b6..e74d4cb 100644
--- a/pkg/util/timetz/timetz.go
+++ b/pkg/util/timetz/timetz.go
@@ -1,12 +1,7 @@
 // Copyright 2019 The Cockroach Authors.
 //
-// Use of this software is governed by the Business Source License
-// included in the file licenses/BSL.txt.
-//
-// As of the Change Date specified in that file, in accordance with
-// the Business Source License, use of this software will be governed
-// by the Apache License, Version 2.0, included in the file
-// licenses/APL.txt.
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
 
 package timetz
 
@@ -120,7 +115,7 @@ func ParseTimeTZ(
 		s = timeutil.ReplaceLibPQTimePrefix(s)
 	}
 
-	t, dependsOnContext, err := pgdate.ParseTimestamp(now, dateStyle, s)
+	t, dependsOnContext, err := pgdate.ParseTimestamp(now, dateStyle, s, nil /* h */)
 	if err != nil {
 		// Build our own error message to avoid exposing the dummy date.
 		return TimeTZ{}, false, pgerror.Newf(
diff --git a/pkg/util/timeutil/cpustopwatch.go b/pkg/util/timeutil/cpustopwatch.go
index bbd96bd..bea5677 100644
--- a/pkg/util/timeutil/cpustopwatch.go
+++ b/pkg/util/timeutil/cpustopwatch.go
@@ -1,12 +1,7 @@
 // Copyright 2022 The Cockroach Authors.
 //
-// Use of this software is governed by the Business Source License
-// included in the file licenses/BSL.txt.
-//
-// As of the Change Date specified in that file, in accordance with
-// the Business Source License, use of this software will be governed
-// by the Apache License, Version 2.0, included in the file
-// licenses/APL.txt.
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
 
 package timeutil
 
@@ -30,7 +25,7 @@ type CPUStopWatch struct {
 // NewCPUStopWatch returns a new CPUStopWatch if the grunning library is
 // supported. Otherwise, it returns nil.
 func NewCPUStopWatch() *CPUStopWatch {
-	if grunning.Supported() {
+	if grunning.Supported {
 		return &CPUStopWatch{}
 	}
 	return nil
diff --git a/pkg/util/timeutil/gen/main.go b/pkg/util/timeutil/gen/main.go
index 40ae917..ed882b0 100644
--- a/pkg/util/timeutil/gen/main.go
+++ b/pkg/util/timeutil/gen/main.go
@@ -1,12 +1,7 @@
 // Copyright 2020 The Cockroach Authors.
 //
-// Use of this software is governed by the Business Source License
-// included in the file licenses/BSL.txt.
-//
-// As of the Change Date specified in that file, in accordance with
-// the Business Source License, use of this software will be governed
-// by the Apache License, Version 2.0, included in the file
-// licenses/APL.txt.
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
 
 // This binary takes the tzdata from Go's source and extracts all
 // timezones names from them. From there, a mapping of lowercased
@@ -33,13 +28,8 @@ const header = `// Code generated by pkg/util/timeutil/gen/main.go - DO NOT EDIT
 //
 // Copyright 2020 The Cockroach Authors.
 //
-// Use of this software is governed by the Business Source License
-// included in the file licenses/BSL.txt.
-//
-// As of the Change Date specified in that file, in accordance with
-// the Business Source License, use of this software will be governed
-// by the Apache License, Version 2.0, included in the file
-// licenses/APL.txt.
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
 
 package timeutil
 
diff --git a/pkg/util/timeutil/lowercase_timezones_generated.go b/pkg/util/timeutil/lowercase_timezones_generated.go
index 1e9a55c..cff0b62 100644
--- a/pkg/util/timeutil/lowercase_timezones_generated.go
+++ b/pkg/util/timeutil/lowercase_timezones_generated.go
@@ -2,13 +2,8 @@
 //
 // Copyright 2020 The Cockroach Authors.
 //
-// Use of this software is governed by the Business Source License
-// included in the file licenses/BSL.txt.
-//
-// As of the Change Date specified in that file, in accordance with
-// the Business Source License, use of this software will be governed
-// by the Apache License, Version 2.0, included in the file
-// licenses/APL.txt.
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
 
 package timeutil
 
diff --git a/pkg/util/timeutil/manual_time.go b/pkg/util/timeutil/manual_time.go
index 3f3b9fd..7fc2ba8 100644
--- a/pkg/util/timeutil/manual_time.go
+++ b/pkg/util/timeutil/manual_time.go
@@ -1,12 +1,7 @@
 // Copyright 2020 The Cockroach Authors.
 //
-// Use of this software is governed by the Business Source License
-// included in the file licenses/BSL.txt.
-//
-// As of the Change Date specified in that file, in accordance with
-// the Business Source License, use of this software will be governed
-// by the Apache License, Version 2.0, included in the file
-// licenses/APL.txt.
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
 
 package timeutil
 
diff --git a/pkg/util/timeutil/pgdate/field_extract.go b/pkg/util/timeutil/pgdate/field_extract.go
index 2890416..e907eec 100644
--- a/pkg/util/timeutil/pgdate/field_extract.go
+++ b/pkg/util/timeutil/pgdate/field_extract.go
@@ -1,12 +1,7 @@
 // Copyright 2018 The Cockroach Authors.
 //
-// Use of this software is governed by the Business Source License
-// included in the file licenses/BSL.txt.
-//
-// As of the Change Date specified in that file, in accordance with
-// the Business Source License, use of this software will be governed
-// by the Apache License, Version 2.0, included in the file
-// licenses/APL.txt.
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
 
 package pgdate
 
@@ -81,6 +76,10 @@ type fieldExtract struct {
 	currentTimeUsed bool
 	// Tracks whether the current timestamp is of db2 format.
 	isDB2 bool
+
+	// skipErrorAnnotation, if set, indicates that we should avoid allocating
+	// objects for error annotations as much as possible.
+	skipErrorAnnotation bool
 }
 
 func (fe *fieldExtract) now() time.Time {
@@ -789,6 +788,9 @@ func (fe *fieldExtract) Set(field field, v int) error {
 
 // decorateError adds context to an error object.
 func (fe *fieldExtract) decorateError(err error) error {
+	if fe.skipErrorAnnotation {
+		return err
+	}
 	return errors.WithDetailf(err,
 		"Wanted: %v\nAlready found in input: %v", &fe.wanted, &fe.has)
 }
@@ -888,20 +890,26 @@ func (fe *fieldExtract) SafeFormat(w redact.SafePrinter, _ rune) {
 
 func (fe *fieldExtract) String() string { return redact.StringWithoutMarkers(fe) }
 
+var (
+	missingRequiredDateFieldsErr    = inputErrorf("missing required date fields")
+	missingRequiredTimeFieldsErr    = inputErrorf("missing required time fields")
+	missingRequiredFieldsInInputErr = inputErrorf("missing required fields in input")
+)
+
 // validate ensures that the data in the extract is reasonable. It also
 // performs some field fixups, such as converting two-digit years
 // to actual values and adjusting for AM/PM.
 func (fe *fieldExtract) validate() error {
 	// If we have any of the required fields, we must have all of the required fields.
 	if fe.has.HasAny(dateRequiredFields) && !fe.has.HasAll(dateRequiredFields) {
-		return fe.decorateError(inputErrorf("missing required date fields"))
+		return fe.decorateError(missingRequiredDateFieldsErr)
 	}
 
 	if (fe.isDB2 && !fe.has.HasAll(db2TimeRequiredFields)) || (fe.has.HasAny(timeRequiredFields) && !fe.has.HasAll(timeRequiredFields)) {
-		return fe.decorateError(inputErrorf("missing required time fields"))
+		return fe.decorateError(missingRequiredTimeFieldsErr)
 	}
 	if !fe.has.HasAll(fe.required) {
-		return fe.decorateError(inputErrorf("missing required fields in input"))
+		return fe.decorateError(missingRequiredFieldsInInputErr)
 	}
 
 	if year, ok := fe.Get(fieldYear); ok {
diff --git a/pkg/util/timeutil/pgdate/field_string.go b/pkg/util/timeutil/pgdate/field_string.go
index d6550ad..ca157e9 100644
--- a/pkg/util/timeutil/pgdate/field_string.go
+++ b/pkg/util/timeutil/pgdate/field_string.go
@@ -1,3 +1,8 @@
+// Copyright 2023 The Cockroach Authors.
+//
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
+
 // Code generated by "stringer"; DO NOT EDIT.
 
 package pgdate
diff --git a/pkg/util/timeutil/pgdate/fields.go b/pkg/util/timeutil/pgdate/fields.go
index 184b8d9..8c0af8f 100644
--- a/pkg/util/timeutil/pgdate/fields.go
+++ b/pkg/util/timeutil/pgdate/fields.go
@@ -1,12 +1,7 @@
 // Copyright 2018 The Cockroach Authors.
 //
-// Use of this software is governed by the Business Source License
-// included in the file licenses/BSL.txt.
-//
-// As of the Change Date specified in that file, in accordance with
-// the Business Source License, use of this software will be governed
-// by the Apache License, Version 2.0, included in the file
-// licenses/APL.txt.
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
 
 package pgdate
 
diff --git a/pkg/util/timeutil/pgdate/math.go b/pkg/util/timeutil/pgdate/math.go
index 21e9ebe..704174e 100644
--- a/pkg/util/timeutil/pgdate/math.go
+++ b/pkg/util/timeutil/pgdate/math.go
@@ -1,12 +1,7 @@
 // Copyright 2018 The Cockroach Authors.
 //
-// Use of this software is governed by the Business Source License
-// included in the file licenses/BSL.txt.
-//
-// As of the Change Date specified in that file, in accordance with
-// the Business Source License, use of this software will be governed
-// by the Apache License, Version 2.0, included in the file
-// licenses/APL.txt.
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
 
 package pgdate
 
diff --git a/pkg/util/timeutil/pgdate/parsing.go b/pkg/util/timeutil/pgdate/parsing.go
index a8cbac1..daf548e 100644
--- a/pkg/util/timeutil/pgdate/parsing.go
+++ b/pkg/util/timeutil/pgdate/parsing.go
@@ -1,12 +1,7 @@
 // Copyright 2018 The Cockroach Authors.
 //
-// Use of this software is governed by the Business Source License
-// included in the file licenses/BSL.txt.
-//
-// As of the Change Date specified in that file, in accordance with
-// the Business Source License, use of this software will be governed
-// by the Apache License, Version 2.0, included in the file
-// licenses/APL.txt.
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
 
 package pgdate
 
@@ -66,24 +61,43 @@ var (
 // https://www.postgresql.org/docs/10/static/datatype-datetime.html#DATATYPE-DATETIME-SPECIAL-TABLE
 var (
 	TimeEpoch = timeutil.Unix(0, 0)
-	// TimeInfinity represents the "highest" possible time.
-	// TODO (#41564): this should actually behave as infinity, i.e. any operator
-	// leaves this as infinity. This time should always be greater than any other time.
-	// We should probably use the next microsecond after this value, i.e. timeutil.Unix(9224318016000, 0).
-	// Postgres uses math.MaxInt64 microseconds as the infinity value.
-	// See: https://github.com/postgres/postgres/blob/42aa1f0ab321fd43cbfdd875dd9e13940b485900/src/include/datatype/timestamp.h#L107.
-	TimeInfinity = timeutil.Unix(9224318016000-1, 999999000)
-	// TimeNegativeInfinity represents the "lowest" possible time.
-	// TODO (#41564): this should actually behave as -infinity, i.e. any operator
-	// leaves this as -infinity. This time should always be less than any other time.
-	// We should probably use the next microsecond before this value, i.e. timeutil.Unix(9224318016000-1, 999999000).
-	// Postgres uses math.MinInt64 microseconds as the -infinity value.
-	// See: https://github.com/postgres/postgres/blob/42aa1f0ab321fd43cbfdd875dd9e13940b485900/src/include/datatype/timestamp.h#L107.
-	TimeNegativeInfinity = timeutil.Unix(-210866803200, 0)
+	// TimeInfinity represents the "highest" possible time. Its value is
+	// "294277-01-01 23:59:59.999999 +0000 UTC", which is 24 hours after "MaxSupportedTime"
+	// (294276-12-31 23:59:59.999999 +0000 UTC).
+	//
+	// The "date" of TimeInfinity is one day after "MaxSupportedTime", it's choiced for no
+	// particular reason.
+	//
+	// The "time" of TimeInfinity is set to "23:59:59.999999" to maintain the behavior of
+	// 'Infinity'::time as it was before PR #127141. (Prior to PR #127141, 'Infinity'::time
+	// resulted in '23:59:59.999999'.) This behavior may change in the future, see issue #129148
+	// for more details.
+	//
+	// Refer to the doc comments of the function "timeutil.Unix" for the process of
+	// deriving the arguments to construct a specific time.Time.
+	TimeInfinity = timeutil.Unix(9224318102399 /* sec */, 999999000 /* nsec */)
+	// TimeNegativeInfinity represents the "lowest" possible time. Its value is
+	// "-4714-11-23 00:00:00 +0000 UTC", which is 24 hours before "MinSupportedTime"
+	// ("-4714-11-24 00:00:00 +0000 UTC").
+	//
+	// The "date" of TimeNegativeInfinity is one day before "MinSupportedTime", it's choiced for no
+	// particular reason.
+	//
+	// The "time" of TimeNegativeInfinity is set to "00:00:00" to maintain the behavior of
+	// '-Infinity'::time as it was before PR #127141. (Prior to PR #127141, '-Infinity'::time
+	// resulted in '00:00:00'.) This behavior may change in the future, see issue #129148
+	// for more details.
+	//
+	// Refer to the doc comments of the function "timeutil.Unix" for the process of
+	// deriving the arguments to construct a specific time.Time.
+	TimeNegativeInfinity = timeutil.Unix(-210898425600 /* sec */, 0 /* nsec */)
 )
 
 type ParseHelper struct {
 	fe fieldExtract
+	// SkipErrorAnnotation, if set, indicates that we should avoid allocating
+	// objects for error annotations as much as possible.
+	SkipErrorAnnotation bool
 }
 
 // ParseDate converts a string into Date.
@@ -111,11 +125,12 @@ func ParseDate(
 		// We allow time fields to be provided since they occur after
 		// the date fields that we're really looking for and for
 		// time values like 24:00:00, would push into the next day.
-		wanted: dateTimeFields,
+		wanted:              dateTimeFields,
+		skipErrorAnnotation: h.SkipErrorAnnotation,
 	}
 
 	if err := h.fe.Extract(s); err != nil {
-		return Date{}, false, parseError(err, "date", s)
+		return Date{}, false, parseError(err, "date", &h.fe)
 	}
 	date, err := h.fe.MakeDate()
 	return date, h.fe.currentTimeUsed, err
@@ -135,23 +150,25 @@ func ParseTime(
 		h = &ParseHelper{}
 	}
 	h.fe = fieldExtract{
-		currentTime: now,
-		required:    timeRequiredFields,
-		wanted:      timeFields,
+		currentTime:         now,
+		required:            timeRequiredFields,
+		wanted:              timeFields,
+		skipErrorAnnotation: h.SkipErrorAnnotation,
 	}
 
 	if err := h.fe.Extract(s); err != nil {
 		// It's possible that the user has given us a complete
 		// timestamp string; let's try again, accepting more fields.
 		h.fe = fieldExtract{
-			currentTime: now,
-			dateStyle:   dateStyle,
-			required:    timeRequiredFields,
-			wanted:      dateTimeFields,
+			currentTime:         now,
+			dateStyle:           dateStyle,
+			required:            timeRequiredFields,
+			wanted:              dateTimeFields,
+			skipErrorAnnotation: h.SkipErrorAnnotation,
 		}
 
 		if err := h.fe.Extract(s); err != nil {
-			return TimeEpoch, false, parseError(err, "time", s)
+			return TimeEpoch, false, parseError(err, "time", &h.fe)
 		}
 	}
 	res := h.fe.MakeTime()
@@ -168,54 +185,69 @@ func ParseTime(
 //
 // The dependsOnContext return value indicates if we had to consult the given
 // `now` value (either for the time or the local timezone).
+//
+// Memory allocations can be avoided by passing ParseHelper which can be re-used
+// across calls for batch parsing purposes, otherwise it can be nil.
 func ParseTimeWithoutTimezone(
-	now time.Time, dateStyle DateStyle, s string,
+	now time.Time, dateStyle DateStyle, s string, h *ParseHelper,
 ) (_ time.Time, dependsOnContext bool, _ error) {
-	fe := fieldExtract{
-		currentTime: now,
-		required:    timeRequiredFields,
-		wanted:      timeFields,
+	if h == nil {
+		h = &ParseHelper{}
+	}
+	h.fe = fieldExtract{
+		currentTime:         now,
+		required:            timeRequiredFields,
+		wanted:              timeFields,
+		skipErrorAnnotation: h.SkipErrorAnnotation,
 	}
 
-	if err := fe.Extract(s); err != nil {
+	if err := h.fe.Extract(s); err != nil {
 		// It's possible that the user has given us a complete
 		// timestamp string; let's try again, accepting more fields.
-		fe = fieldExtract{
-			currentTime: now,
-			dateStyle:   dateStyle,
-			required:    timeRequiredFields,
-			wanted:      dateTimeFields,
+		h.fe = fieldExtract{
+			currentTime:         now,
+			dateStyle:           dateStyle,
+			required:            timeRequiredFields,
+			wanted:              dateTimeFields,
+			skipErrorAnnotation: h.SkipErrorAnnotation,
 		}
 
-		if err := fe.Extract(s); err != nil {
-			return TimeEpoch, false, parseError(err, "time", s)
+		if err := h.fe.Extract(s); err != nil {
+			return TimeEpoch, false, parseError(err, "time", &h.fe)
 		}
 	}
-	res := fe.MakeTimeWithoutTimezone()
-	return res, fe.currentTimeUsed, nil
+	res := h.fe.MakeTimeWithoutTimezone()
+	return res, h.fe.currentTimeUsed, nil
 }
 
 // ParseTimestamp converts a string into a timestamp.
 //
 // The dependsOnContext return value indicates if we had to consult the given
 // `now` value (either for the time or the local timezone).
+//
+// Memory allocations can be avoided by passing ParseHelper which can be re-used
+// across calls for batch parsing purposes, otherwise it can be nil.
 func ParseTimestamp(
-	now time.Time, dateStyle DateStyle, s string,
+	now time.Time, dateStyle DateStyle, s string, h *ParseHelper,
 ) (_ time.Time, dependsOnContext bool, _ error) {
-	fe := fieldExtract{
+	if h == nil {
+		h = &ParseHelper{}
+	}
+	h.fe = fieldExtract{
 		dateStyle:   dateStyle,
 		currentTime: now,
 		// A timestamp only actually needs a date component; the time
 		// would be midnight.
-		required: dateRequiredFields,
-		wanted:   dateTimeFields,
+		required:            dateRequiredFields,
+		wanted:              dateTimeFields,
+		skipErrorAnnotation: h.SkipErrorAnnotation,
 	}
 
-	if err := fe.Extract(s); err != nil {
-		return TimeEpoch, false, parseError(err, "timestamp", s)
+	if err := h.fe.Extract(s); err != nil {
+		return TimeEpoch, false, parseError(err, "timestamp", &h.fe)
 	}
-	res := fe.MakeTimestamp()
-	return res, fe.currentTimeUsed, nil
+	res := h.fe.MakeTimestamp()
+	return res, h.fe.currentTimeUsed, nil
 }
 
 // ParseTimestampWithoutTimezone converts a string into a timestamp, stripping
@@ -231,23 +263,30 @@ func ParseTimestamp(
 //
 // The dependsOnContext return value indicates if we had to consult the given
 // `now` value (either for the time or the local timezone).
+//
+// Memory allocations can be avoided by passing ParseHelper which can be re-used
+// across calls for batch parsing purposes, otherwise it can be nil.
 func ParseTimestampWithoutTimezone(
-	now time.Time, dateStyle DateStyle, s string,
+	now time.Time, dateStyle DateStyle, s string, h *ParseHelper,
 ) (_ time.Time, dependsOnContext bool, _ error) {
-	fe := fieldExtract{
+	if h == nil {
+		h = &ParseHelper{}
+	}
+	h.fe = fieldExtract{
 		dateStyle:   dateStyle,
 		currentTime: now,
 		// A timestamp only actually needs a date component; the time
 		// would be midnight.
-		required: dateRequiredFields,
-		wanted:   dateTimeFields,
+		required:            dateRequiredFields,
+		wanted:              dateTimeFields,
+		skipErrorAnnotation: h.SkipErrorAnnotation,
 	}
 
-	if err := fe.Extract(s); err != nil {
-		return TimeEpoch, false, parseError(err, "timestamp", s)
+	if err := h.fe.Extract(s); err != nil {
+		return TimeEpoch, false, parseError(err, "timestamp", &h.fe)
 	}
-	res := fe.MakeTimestampWithoutTimezone()
-	return res, fe.currentTimeUsed, nil
+	res := h.fe.MakeTimestampWithoutTimezone()
+	return res, h.fe.currentTimeUsed, nil
 }
 
 // badFieldPrefixError constructs an error with pg code InvalidDatetimeFormat.
@@ -273,7 +312,10 @@ func outOfRangeError(field string, val int) error {
 
 // parseError ensures that any error we return to the client will
 // be some kind of error with a pg code.
-func parseError(err error, kind string, s string) error {
+func parseError(err error, kind string, fi *fieldExtract) error {
+	if fi.skipErrorAnnotation {
+		return err
+	}
 	return pgerror.WithCandidateCode(
 		errors.Wrapf(err, "parsing as type %s", errors.Safe(kind)),
 		pgcode.InvalidDatetimeFormat)
diff --git a/pkg/util/timeutil/pgdate/pgdate.go b/pkg/util/timeutil/pgdate/pgdate.go
index fbbf28a..f7fe24a 100644
--- a/pkg/util/timeutil/pgdate/pgdate.go
+++ b/pkg/util/timeutil/pgdate/pgdate.go
@@ -1,12 +1,7 @@
 // Copyright 2018 The Cockroach Authors.
 //
-// Use of this software is governed by the Business Source License
-// included in the file licenses/BSL.txt.
-//
-// As of the Change Date specified in that file, in accordance with
-// the Business Source License, use of this software will be governed
-// by the Apache License, Version 2.0, included in the file
-// licenses/APL.txt.
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
 
 // Package pgdate contains parsing functions and types for dates and times
 // in a manner that is compatible with PostgreSQL.
diff --git a/pkg/util/timeutil/pgdate/pgdate.pb.go b/pkg/util/timeutil/pgdate/pgdate.pb.go
index f9b42b5..590caf6 100644
--- a/pkg/util/timeutil/pgdate/pgdate.pb.go
+++ b/pkg/util/timeutil/pgdate/pgdate.pb.go
@@ -209,7 +209,7 @@ func (m *DateStyle) Size() (n int) {
 }
 
 func sovPgdate(x uint64) (n int) {
-	return (math_bits.Len64(x|1) + 6) / 7
+	return int((uint32(math_bits.Len64(x|1)+6) * 37) >> 8)
 }
 func sozPgdate(x uint64) (n int) {
 	return sovPgdate(uint64((x << 1) ^ uint64((int64(x) >> 63))))
diff --git a/pkg/util/timeutil/pgdate/pgdate.proto b/pkg/util/timeutil/pgdate/pgdate.proto
index f29b37c..58145a8 100644
--- a/pkg/util/timeutil/pgdate/pgdate.proto
+++ b/pkg/util/timeutil/pgdate/pgdate.proto
@@ -1,12 +1,7 @@
 // Copyright 2021 The Cockroach Authors.
 //
-// Use of this software is governed by the Business Source License
-// included in the file licenses/BSL.txt.
-//
-// As of the Change Date specified in that file, in accordance with
-// the Business Source License, use of this software will be governed
-// by the Apache License, Version 2.0, included in the file
-// licenses/APL.txt.
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
 
 syntax = "proto3";
 package cockroach.util.timeutil.pgdate;
diff --git a/pkg/util/timeutil/pgdate/setters.go b/pkg/util/timeutil/pgdate/setters.go
index 3fc8a44..a5cab88 100644
--- a/pkg/util/timeutil/pgdate/setters.go
+++ b/pkg/util/timeutil/pgdate/setters.go
@@ -1,12 +1,7 @@
 // Copyright 2018 The Cockroach Authors.
 //
-// Use of this software is governed by the Business Source License
-// included in the file licenses/BSL.txt.
-//
-// As of the Change Date specified in that file, in accordance with
-// the Business Source License, use of this software will be governed
-// by the Apache License, Version 2.0, included in the file
-// licenses/APL.txt.
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
 
 package pgdate
 
diff --git a/pkg/util/timeutil/pgdate/zone_cache.go b/pkg/util/timeutil/pgdate/zone_cache.go
index 0c3eeaf..bb55f54 100644
--- a/pkg/util/timeutil/pgdate/zone_cache.go
+++ b/pkg/util/timeutil/pgdate/zone_cache.go
@@ -1,12 +1,7 @@
 // Copyright 2018 The Cockroach Authors.
 //
-// Use of this software is governed by the Business Source License
-// included in the file licenses/BSL.txt.
-//
-// As of the Change Date specified in that file, in accordance with
-// the Business Source License, use of this software will be governed
-// by the Apache License, Version 2.0, included in the file
-// licenses/APL.txt.
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
 
 package pgdate
 
diff --git a/pkg/util/timeutil/stopwatch.go b/pkg/util/timeutil/stopwatch.go
index 70923f2..3123bd2 100644
--- a/pkg/util/timeutil/stopwatch.go
+++ b/pkg/util/timeutil/stopwatch.go
@@ -1,12 +1,7 @@
 // Copyright 2019 The Cockroach Authors.
 //
-// Use of this software is governed by the Business Source License
-// included in the file licenses/BSL.txt.
-//
-// As of the Change Date specified in that file, in accordance with
-// the Business Source License, use of this software will be governed
-// by the Apache License, Version 2.0, included in the file
-// licenses/APL.txt.
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
 
 package timeutil
 
@@ -48,7 +43,7 @@ func NewStopWatch() *StopWatch {
 // addition to wall-clock time.
 func NewStopWatchWithCPU() *StopWatch {
 	w := newStopWatch(Now)
-	if grunning.Supported() {
+	if grunning.Supported {
 		w.mu.cpuStopWatch = &cpuStopWatch{}
 	}
 	return w
diff --git a/pkg/util/timeutil/ticker.go b/pkg/util/timeutil/ticker.go
new file mode 100644
index 0000000..c29e9d6
--- /dev/null
+++ b/pkg/util/timeutil/ticker.go
@@ -0,0 +1,142 @@
+// Copyright 2025 The Cockroach Authors.
+//
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
+
+package timeutil
+
+import (
+	"slices"
+	"time"
+
+	"github.com/cockroachdb/cockroachdb-parser/pkg/util/syncutil"
+)
+
+// BroadcastTicker is a wrapper around a time.Ticker that delivers "ticks" of a
+// clock to multiple receivers at roughly the same time. This allows a set of
+// goroutines to synchronize on the same periodic schedule.
+//
+// The interface of BroadcastTicker and the receiver handles that it hands out
+// is similar to that of time.Ticker, but not identical. In particular, ticker
+// "receivers" are created from a parent BroadcastTicker.
+//
+//	bcastTicker := NewBroadcastTicker(1 * time.Second)
+//	defer bcastTicker.Stop()
+//	for range N {
+//		go func() {
+//			ticker := bcastTicker.NewTicker()
+//			defer ticker.Stop()
+//			for range ticker.C {
+//				// Do something...
+//			}
+//		}()
+//	}
+type BroadcastTicker struct {
+	ticker *time.Ticker
+	stopC  chan struct{}
+	mu     struct {
+		syncutil.Mutex
+		chans []chan time.Time
+	}
+}
+
+// NewBroadcastTicker creates a new BroadcastTicker that broadcasts the current
+// time after each tick. The period of the ticks is specified by the duration
+// argument. The duration d must be greater than zero; if not, the function will
+// panic.
+func NewBroadcastTicker(d time.Duration) *BroadcastTicker {
+	t := &BroadcastTicker{
+		ticker: time.NewTicker(d),
+		stopC:  make(chan struct{}),
+	}
+	go t.run()
+	return t
+}
+
+func (t *BroadcastTicker) run() {
+	for {
+		select {
+		case now := <-t.ticker.C:
+			t.broadcast(now)
+		case <-t.stopC:
+			return
+		}
+	}
+}
+
+func (t *BroadcastTicker) broadcast(val time.Time) {
+	t.mu.Lock()
+	defer t.mu.Unlock()
+	for _, c := range t.mu.chans {
+		select {
+		case c <- val:
+		default:
+		}
+	}
+}
+
+// Stop turns off a broadcast ticker. After Stop, no more ticks will be sent to
+// any of the receivers, even if Reset is later called.
+//
+// NOTE: this interaction between Stop and Reset could be adjusted if needed, so
+// that a stopped ticker could be restarted with a Reset call.
+func (t *BroadcastTicker) Stop() {
+	t.ticker.Stop()
+	close(t.stopC)
+}
+
+// Reset stops a broadcast ticker and resets its period to the specified
+// duration. The next tick will be broadcast after the new period elapses. The
+// duration d must be greater than zero; if not, the function will panic.
+func (t *BroadcastTicker) Reset(d time.Duration) {
+	t.ticker.Reset(d)
+}
+
+// NewTicker creates a new receiver for the broadcast ticker. The receiver
+// contains a channel that will receive the current time after each tick.
+func (t *BroadcastTicker) NewTicker() *BroadcastTickerReceiver {
+	c, r := t.allocNewTicker()
+	t.register(c)
+	return r
+}
+
+func (t *BroadcastTicker) allocNewTicker() (chan time.Time, *BroadcastTickerReceiver) {
+	c := make(chan time.Time, 1)
+	r := &BroadcastTickerReceiver{
+		C: c,
+		t: t,
+	}
+	return c, r
+}
+
+func (t *BroadcastTicker) register(c chan time.Time) {
+	t.mu.Lock()
+	defer t.mu.Unlock()
+	t.mu.chans = append(t.mu.chans, c)
+}
+
+func (t *BroadcastTicker) registerLocked(c chan time.Time) {
+	t.mu.chans = append(t.mu.chans, c)
+}
+
+func (t *BroadcastTicker) unregister(c <-chan time.Time) {
+	t.mu.Lock()
+	defer t.mu.Unlock()
+	t.mu.chans = slices.DeleteFunc(t.mu.chans, func(ch chan time.Time) bool {
+		return ch == c
+	})
+}
+
+// BroadcastTickerReceiver is a receiver of ticks from a BroadcastTicker. It is
+// little more than a wrapper struct around a channel, but is made to look like
+// a normal time.Ticker for ease of use.
+type BroadcastTickerReceiver struct {
+	C <-chan time.Time
+	t *BroadcastTicker
+}
+
+// Stop stops the receiver from receiving ticks. The method does not stop the
+// broadcast ticker itself.
+func (r *BroadcastTickerReceiver) Stop() {
+	r.t.unregister(r.C)
+}
diff --git a/pkg/util/timeutil/time.go b/pkg/util/timeutil/time.go
index 281d6b8..94e9287 100644
--- a/pkg/util/timeutil/time.go
+++ b/pkg/util/timeutil/time.go
@@ -1,12 +1,7 @@
 // Copyright 2016 The Cockroach Authors.
 //
-// Use of this software is governed by the Business Source License
-// included in the file licenses/BSL.txt.
-//
-// As of the Change Date specified in that file, in accordance with
-// the Business Source License, use of this software will be governed
-// by the Apache License, Version 2.0, included in the file
-// licenses/APL.txt.
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
 
 package timeutil
 
@@ -112,6 +107,16 @@ func ToUnixMicros(t time.Time) int64 {
 }
 
 // Unix wraps time.Unix ensuring that the result is in UTC instead of Local.
+//
+// The process of deriving the args to construct a specific time.Time:
+//
+//	// say we want to construct timestamp "294277-01-01 23:59:59.999999 +0000 UTC"
+//	tm := time.Date(294277, 1, 1, 23, 59, 59, 999999000, time.UTC)
+//	// get the args of "timeutil.Unix"
+//	sec := tm.Unix()
+//	nsec := int64(tm.Nanosecond())
+//	// verify
+//	fmt.Println(tm == time.Unix(sec, nsec).UTC())
 func Unix(sec, nsec int64) time.Time {
 	return time.Unix(sec, nsec).UTC()
 }
diff --git a/pkg/util/timeutil/time_source.go b/pkg/util/timeutil/time_source.go
index 763a547..fb93b86 100644
--- a/pkg/util/timeutil/time_source.go
+++ b/pkg/util/timeutil/time_source.go
@@ -1,12 +1,7 @@
 // Copyright 2020 The Cockroach Authors.
 //
-// Use of this software is governed by the Business Source License
-// included in the file licenses/BSL.txt.
-//
-// As of the Change Date specified in that file, in accordance with
-// the Business Source License, use of this software will be governed
-// by the Apache License, Version 2.0, included in the file
-// licenses/APL.txt.
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
 
 package timeutil
 
@@ -27,7 +22,7 @@ type TimerI interface {
 	// Reset will set the timer to notify on Ch() after duration.
 	Reset(duration time.Duration)
 
-	// Stop must only be called one time per timer.
+	// Stop prevents the Timer from firing.
 	Stop() bool
 
 	// Ch returns the channel which will be notified when the timer reaches its
@@ -71,7 +66,7 @@ func (DefaultTimeSource) Since(t time.Time) time.Duration {
 
 // NewTimer returns a TimerI wrapping *Timer.
 func (DefaultTimeSource) NewTimer() TimerI {
-	return (*timer)(NewTimer())
+	return (*timer)(new(Timer))
 }
 
 // NewTicker creates a new ticker.
diff --git a/pkg/util/timeutil/time_zone_util.go b/pkg/util/timeutil/time_zone_util.go
index f645bd5..91bf29d 100644
--- a/pkg/util/timeutil/time_zone_util.go
+++ b/pkg/util/timeutil/time_zone_util.go
@@ -1,12 +1,7 @@
 // Copyright 2017 The Cockroach Authors.
 //
-// Use of this software is governed by the Business Source License
-// included in the file licenses/BSL.txt.
-//
-// As of the Change Date specified in that file, in accordance with
-// the Business Source License, use of this software will be governed
-// by the Apache License, Version 2.0, included in the file
-// licenses/APL.txt.
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
 
 package timeutil
 
@@ -69,25 +64,40 @@ const (
 func TimeZoneStringToLocation(
 	locStr string, std TimeZoneStringToLocationStandard,
 ) (*time.Location, error) {
-	offset, _, parsed := ParseTimeZoneOffset(locStr, std)
-	if parsed {
-		if offset < -maxUTCHourOffsetInSeconds || offset > maxUTCHourOffsetInSeconds {
-			return nil, errors.New("UTC timezone offset is out of range.")
+	// ParseTimeZoneOffset uses strconv.ParseFloat, which returns an error when
+	// parsing fails that is expensive to construct. We first check if the string
+	// contains any non-numeric characters to see if we can skip attempting to
+	// parse it as a timezone offset. `/` is also checked since that character
+	// appears in most timezone names. Since UTC is the most commonly used
+	// timezone, we also check for that explicitly to avoid calling ContainsAny if
+	// possible.
+	containsNonNumeric := strings.EqualFold(locStr, "utc") || strings.ContainsAny(locStr, "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ/")
+	if !containsNonNumeric {
+		offset, _, parsed := ParseTimeZoneOffset(locStr, std)
+		if parsed {
+			if offset < -maxUTCHourOffsetInSeconds || offset > maxUTCHourOffsetInSeconds {
+				return nil, errors.New("UTC timezone offset is out of range.")
+			}
+			return TimeZoneOffsetToLocation(offset), nil
 		}
-		return TimeZoneOffsetToLocation(offset), nil
 	}
 
-	// The time may just be a raw int value.
-	intVal, err := strconv.ParseInt(locStr, 10, 64)
-	if err == nil {
-		// Parsing an int has different behavior for POSIX and ISO8601.
-		if std == TimeZoneStringToLocationPOSIXStandard {
-			intVal *= -1
-		}
-		if intVal < -maxUTCHourOffset || intVal > maxUTCHourOffset {
-			return nil, errors.New("UTC timezone offset is out of range.")
+	// The time may just be a raw int value. Similar to the above, in order to
+	// avoid constructing an expensive error, we first check if the string
+	// contains any non-numeric characters to see if we can skip attempting to
+	// parse it as an int.
+	if !containsNonNumeric {
+		intVal, err := strconv.ParseInt(locStr, 10, 64)
+		if err == nil {
+			// Parsing an int has different behavior for POSIX and ISO8601.
+			if std == TimeZoneStringToLocationPOSIXStandard {
+				intVal *= -1
+			}
+			if intVal < -maxUTCHourOffset || intVal > maxUTCHourOffset {
+				return nil, errors.New("UTC timezone offset is out of range.")
+			}
+			return TimeZoneOffsetToLocation(int(intVal) * 60 * 60), nil
 		}
-		return TimeZoneOffsetToLocation(int(intVal) * 60 * 60), nil
 	}
 
 	locTransforms := []func(string) string{
diff --git a/pkg/util/timeutil/timeout.go b/pkg/util/timeutil/timeout.go
index 2f76930..5f618d2 100644
--- a/pkg/util/timeutil/timeout.go
+++ b/pkg/util/timeutil/timeout.go
@@ -1,12 +1,7 @@
 // Copyright 2021 The Cockroach Authors.
 //
-// Use of this software is governed by the Business Source License
-// included in the file licenses/BSL.txt.
-//
-// As of the Change Date specified in that file, in accordance with
-// the Business Source License, use of this software will be governed
-// by the Apache License, Version 2.0, included in the file
-// licenses/APL.txt.
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
 
 package timeutil
 
@@ -15,13 +10,17 @@ import (
 	"time"
 
 	"github.com/cockroachdb/errors"
+	"github.com/cockroachdb/redact"
 )
 
 // RunWithTimeout runs a function with a timeout, the same way you'd do with
 // context.WithTimeout. It improves the opaque error messages returned by
 // WithTimeout by augmenting them with the op string that is passed in.
 func RunWithTimeout(
-	ctx context.Context, op string, timeout time.Duration, fn func(ctx context.Context) error,
+	ctx context.Context,
+	op redact.RedactableString,
+	timeout time.Duration,
+	fn func(ctx context.Context) error,
 ) error {
 	ctx, cancel := context.WithTimeout(ctx, timeout) // nolint:context
 	defer cancel()
diff --git a/pkg/util/timeutil/timeout_error.go b/pkg/util/timeutil/timeout_error.go
index 48a188f..caa0fda 100644
--- a/pkg/util/timeutil/timeout_error.go
+++ b/pkg/util/timeutil/timeout_error.go
@@ -1,12 +1,7 @@
 // Copyright 2021 The Cockroach Authors.
 //
-// Use of this software is governed by the Business Source License
-// included in the file licenses/BSL.txt.
-//
-// As of the Change Date specified in that file, in accordance with
-// the Business Source License, use of this software will be governed
-// by the Apache License, Version 2.0, included in the file
-// licenses/APL.txt.
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
 
 package timeutil
 
@@ -18,6 +13,7 @@ import (
 
 	"github.com/cockroachdb/errors"
 	"github.com/cockroachdb/errors/errorspb"
+	"github.com/cockroachdb/redact"
 	"github.com/gogo/protobuf/proto"
 )
 
@@ -25,7 +21,7 @@ import (
 // an operation didn't complete within its designated timeout.
 type TimeoutError struct {
 	// The operation that timed out.
-	operation string
+	operation redact.RedactableString
 	// The configured timeout.
 	timeout time.Duration
 	// The duration of the operation. This is usually expected to be the same as
@@ -44,7 +40,7 @@ var _ errors.SafeFormatter = (*TimeoutError)(nil)
 var _ net.Error = (*TimeoutError)(nil)
 
 // Operation returns the name of the operation that timed out.
-func (t *TimeoutError) Operation() string {
+func (t *TimeoutError) Operation() redact.RedactableString {
 	return t.operation
 }
 
@@ -60,7 +56,7 @@ func (t *TimeoutError) SafeFormatError(p errors.Printer) (next error) {
 	// timeout set by RunWithTimeout. It is also possible for the operation to run
 	// for much longer than the timeout, e.g. if the callee does not check the
 	// context in a timely manner. The error message must make this clear.
-	p.Printf("operation %q timed out", t.operation)
+	p.Printf("operation \"%s\" timed out", t.operation)
 	if t.took != 0 {
 		p.Printf(" after %s", t.took.Round(time.Millisecond))
 	}
@@ -80,40 +76,37 @@ func (t *TimeoutError) Cause() error {
 }
 
 // encodeTimeoutError serializes a TimeoutError.
-// We cannot include the operation in the safe strings because
-// we currently have plenty of uses where the operation is constructed
-// from unsafe/sensitive data.
 func encodeTimeoutError(
 	_ context.Context, err error,
 ) (msgPrefix string, safe []string, details proto.Message) {
 	t := err.(*TimeoutError)
 	details = &errorspb.StringsPayload{
-		Details: []string{t.operation, t.timeout.String(), t.took.String()},
+		Details: []string{t.timeout.String(), t.took.String()},
 	}
 	msgPrefix = fmt.Sprintf("operation %q timed out after %s", t.operation, t.timeout)
-	return msgPrefix, nil, details
+	return msgPrefix, []string{string(t.operation)}, details
 }
 
 func decodeTimeoutError(
 	ctx context.Context, cause error, msgPrefix string, safeDetails []string, payload proto.Message,
 ) error {
 	m, ok := payload.(*errorspb.StringsPayload)
-	if !ok || len(m.Details) < 2 {
+	if !ok || len(m.Details) < 1 || len(safeDetails) < 1 {
 		// If this ever happens, this means some version of the library
 		// (presumably future) changed the payload type, and we're
 		// receiving this here. In this case, give up and let
 		// DecodeError use the opaque type.
 		return nil
 	}
-	op := m.Details[0]
-	timeout, decodeErr := time.ParseDuration(m.Details[1])
+	op := redact.RedactableString(safeDetails[0])
+	timeout, decodeErr := time.ParseDuration(m.Details[0])
 	if decodeErr != nil {
 		// Not encoded by our encode function. Bail out.
 		return nil //nolint:returnerrcheck
 	}
 	var took time.Duration
-	if len(m.Details) >= 3 {
-		took, decodeErr = time.ParseDuration(m.Details[2])
+	if len(m.Details) >= 2 {
+		took, decodeErr = time.ParseDuration(m.Details[1])
 		if decodeErr != nil {
 			// Not encoded by our encode function. Bail out.
 			return nil //nolint:returnerrcheck
diff --git a/pkg/util/timeutil/timer.go b/pkg/util/timeutil/timer.go
index a090cd5..f77a411 100644
--- a/pkg/util/timeutil/timer.go
+++ b/pkg/util/timeutil/timer.go
@@ -1,12 +1,7 @@
 // Copyright 2016 The Cockroach Authors.
 //
-// Use of this software is governed by the Business Source License
-// included in the file licenses/BSL.txt.
-//
-// As of the Change Date specified in that file, in accordance with
-// the Business Source License, use of this software will be governed
-// by the Apache License, Version 2.0, included in the file
-// licenses/APL.txt.
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
 
 package timeutil
 
@@ -15,11 +10,6 @@ import (
 	"time"
 )
 
-var timerPool = sync.Pool{
-	New: func() interface{} {
-		return &Timer{}
-	},
-}
 var timeTimerPool sync.Pool
 
 // The Timer type represents a single event. When the Timer expires,
@@ -48,7 +38,12 @@ var timeTimerPool sync.Pool
 //
 // Note that unlike the standard library's Timer type, this Timer will
 // not begin counting down until Reset is called for the first time, as
-// there is no constructor function.
+// there is no constructor function. The zero value for Timer is ready
+// to use.
+//
+// TODO(nvanbenschoten): follow https://github.com/golang/go/issues/37196
+// and remove this abstraction once it's no longer needed. There's some
+// recent progress in https://go-review.googlesource.com/c/go/+/568341.
 type Timer struct {
 	timer *time.Timer
 	// C is a local "copy" of timer.C that can be used in a select case before
@@ -57,9 +52,11 @@ type Timer struct {
 	Read bool
 }
 
-// NewTimer allocates a new timer.
-func NewTimer() *Timer {
-	return timerPool.Get().(*Timer)
+// AsTimerI returns the Timer as a TimerI. This is helpful
+// to write code that accepts a Timer in production and a manual
+// timer in tests.
+func (t *Timer) AsTimerI() TimerI {
+	return (*timer)(t)
 }
 
 // Reset changes the timer to expire after duration d and returns
@@ -79,9 +76,7 @@ func (t *Timer) Reset(d time.Duration) {
 		t.C = t.timer.C
 		return
 	}
-	if !t.timer.Stop() && !t.Read {
-		<-t.C
-	}
+	t.stopAndDrain()
 	t.timer.Reset(d)
 	t.Read = false
 }
@@ -90,19 +85,31 @@ func (t *Timer) Reset(d time.Duration) {
 // the timer, false if the timer has already expired, been stopped previously,
 // or had never been initialized with a call to Timer.Reset. Stop does not
 // close the channel, to prevent a read from succeeding incorrectly.
-// Note that a Timer must never be used again after calls to Stop as the timer
-// object will be put into an object pool for reuse.
 func (t *Timer) Stop() bool {
 	var res bool
 	if t.timer != nil {
-		res = t.timer.Stop()
-		if res {
-			// Only place the timer back in the pool if we successfully stopped
-			// it. Otherwise, we'd have to read from the channel if !t.Read.
-			timeTimerPool.Put(t.timer)
-		}
+		res = t.stopAndDrain()
+		timeTimerPool.Put(t.timer)
 	}
 	*t = Timer{}
-	timerPool.Put(t)
+	return res
+}
+
+// stopAndDrain stops the underlying *time.Timer and drains the channel if the
+// timer has already expired but the channel has not been read from. It returns
+// true if the call stops the timer and false if the timer has already expired.
+// t.timer must not be nil and must not have already been stopped.
+func (t *Timer) stopAndDrain() bool {
+	res := t.timer.Stop()
+	if !res && !t.Read {
+		// The timer expired, but the channel has not been read from. Drain it.
+		<-t.C
+		// Even though we did not stop the timer before it expired, the channel was
+		// never read from and we had to drain it ourselves, so we consider the stop
+		// attempt successful. For any caller consulting this return value, this is
+		// an indication that after the call to Stop, the timer channel will remain
+		// empty until the next call to Reset.
+		res = true
+	}
 	return res
 }
diff --git a/pkg/util/timeutil/timeutil.go b/pkg/util/timeutil/timeutil.go
index 07d846a..5494184 100644
--- a/pkg/util/timeutil/timeutil.go
+++ b/pkg/util/timeutil/timeutil.go
@@ -1,12 +1,7 @@
 // Copyright 2020 The Cockroach Authors.
 //
-// Use of this software is governed by the Business Source License
-// included in the file licenses/BSL.txt.
-//
-// As of the Change Date specified in that file, in accordance with
-// the Business Source License, use of this software will be governed
-// by the Apache License, Version 2.0, included in the file
-// licenses/APL.txt.
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
 
 package timeutil
 
diff --git a/pkg/util/timeutil/zoneinfo.go b/pkg/util/timeutil/zoneinfo.go
index c6a3e14..14ad1e0 100644
--- a/pkg/util/timeutil/zoneinfo.go
+++ b/pkg/util/timeutil/zoneinfo.go
@@ -1,12 +1,7 @@
 // Copyright 2016 The Cockroach Authors.
 //
-// Use of this software is governed by the Business Source License
-// included in the file licenses/BSL.txt.
-//
-// As of the Change Date specified in that file, in accordance with
-// the Business Source License, use of this software will be governed
-// by the Apache License, Version 2.0, included in the file
-// licenses/APL.txt.
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
 
 package timeutil
 
diff --git a/pkg/util/topk.go b/pkg/util/topk.go
index 07ae3d4..751ad9a 100644
--- a/pkg/util/topk.go
+++ b/pkg/util/topk.go
@@ -1,12 +1,7 @@
 // Copyright 2016 The Cockroach Authors.
 //
-// Use of this software is governed by the Business Source License
-// included in the file licenses/BSL.txt.
-//
-// As of the Change Date specified in that file, in accordance with
-// the Business Source License, use of this software will be governed
-// by the Apache License, Version 2.0, included in the file
-// licenses/APL.txt.
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
 
 package util
 
diff --git a/pkg/util/tracing/context.go b/pkg/util/tracing/context.go
new file mode 100644
index 0000000..45255be
--- /dev/null
+++ b/pkg/util/tracing/context.go
@@ -0,0 +1,68 @@
+// Copyright 2020 The Cockroach Authors.
+//
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
+
+package tracing
+
+import (
+	"context"
+
+	"github.com/cockroachdb/cockroachdb-parser/pkg/util/ctxutil"
+)
+
+var activeSpanKey = ctxutil.RegisterFastValueKey()
+
+// noCtx is a singleton that we use internally to unify code paths that only
+// optionally take a Context. The specific construction here does not matter,
+// the only thing we need is that no outside caller could ever pass this
+// context in (i.e. we can't use context.Background() and the like).
+var noCtx context.Context = &struct{ context.Context }{context.Background()}
+
+// SpanFromContext returns the *Span contained in the Context, if any.
+func SpanFromContext(ctx context.Context) *Span {
+	if v := ctxutil.FastValue(ctx, activeSpanKey); v != nil {
+		return v.(*Span)
+	}
+	return nil
+}
+
+// maybeWrapCtx returns a Context wrapping the Span, with two exceptions:
+//  1. if ctx==noCtx, it's a noop
+//  2. if ctx contains the noop Span, and sp is also the noop Span, elide
+//     allocating a new Context.
+//
+// NOTE(andrei): Our detection of Span use-after-Finish() is not reliable
+// because spans are reused through a sync.Pool; we fail to detect someone
+// holding a reference to a Span (e.g. a Context referencing the span) from
+// before reuse and then using it after span reuse. We could make the detection
+// more reliable by storing the generation number of the span in the Context
+// along with the Span and checking it every time the Span is retrieved from the
+// Context. We'd have to implement our own Context struct so that the Context
+// and the generation number can be allocated together.
+func maybeWrapCtx(ctx context.Context, sp *Span) (context.Context, *Span) {
+	if ctx == noCtx {
+		return noCtx, sp
+	}
+	// NB: Some callers want to remove a Span from a Context, and thus pass nil.
+	if sp == nil {
+		// If the context originally had the nil span, and we would now be wrapping
+		// the nil span in it again, we don't have to wrap at all and can save an
+		// allocation.
+		//
+		// Note that applying this optimization for a nontrivial ctxSp would
+		// constitute a bug: A real, non-recording span might later start recording.
+		// Besides, the caller expects to get their own span, and will .Finish() it,
+		// leading to an extra, premature call to Finish().
+		if ctxSp := SpanFromContext(ctx); ctxSp == nil {
+			return ctx, sp
+		}
+	}
+	return ctxutil.WithFastValue(ctx, activeSpanKey, sp), sp
+}
+
+// ContextWithSpan returns a Context wrapping the supplied Span.
+func ContextWithSpan(ctx context.Context, sp *Span) context.Context {
+	ctx, _ = maybeWrapCtx(ctx, sp)
+	return ctx
+}
diff --git a/pkg/util/tracing/crdbspan.go b/pkg/util/tracing/crdbspan.go
new file mode 100644
index 0000000..73fd261
--- /dev/null
+++ b/pkg/util/tracing/crdbspan.go
@@ -0,0 +1,1496 @@
+// Copyright 2021 The Cockroach Authors.
+//
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
+
+package tracing
+
+import (
+	"fmt"
+	"sort"
+	"sync"
+	"sync/atomic"
+	"time"
+
+	"github.com/cockroachdb/cockroachdb-parser/pkg/util/protoutil"
+	"github.com/cockroachdb/cockroachdb-parser/pkg/util/ring"
+	"github.com/cockroachdb/cockroachdb-parser/pkg/util/syncutil"
+	"github.com/cockroachdb/cockroachdb-parser/pkg/util/timeutil"
+	"github.com/cockroachdb/cockroachdb-parser/pkg/util/tracing/tracingpb"
+	"github.com/cockroachdb/errors"
+	"github.com/cockroachdb/logtags"
+	"github.com/cockroachdb/redact"
+	"github.com/gogo/protobuf/types"
+	"go.opentelemetry.io/otel/attribute"
+)
+
+// crdbSpan is a span for internal crdb usage. This is used to power SQL session
+// tracing.
+type crdbSpan struct {
+	// tracer is the Tracer that created this span.
+	tracer *Tracer
+	// sp is Span that this crdbSpan is part of.
+	sp *Span
+
+	traceID tracingpb.TraceID // probabilistically unique
+	spanID  tracingpb.SpanID  // probabilistically unique
+	// parentSpanID indicates the parent at the time when this span was created. 0
+	// if this span didn't have a parent. If crdbSpan.mu.parent is set,
+	// parentSpanID corresponds to it. However, if the parent finishes, or if the
+	// parent is a span from a remote node, crdbSpan.mu.parent will be nil.
+	parentSpanID tracingpb.SpanID
+	operation    string // name of operation associated with the span
+
+	startTime time.Time
+
+	// logTags are set to the log tags that were available when this Span was
+	// created, so that there's no need to eagerly copy all of those log tags
+	// into this Span's tags. If the Span's tags are actually requested, these
+	// logTags will be copied out at that point.
+	//
+	// Note that these tags have not gone through the log tag -> Span tag
+	// remapping procedure; tagName() needs to be called before exposing each
+	// tag's key to a user.
+	logTags *logtags.Buffer
+
+	// eventListeners is a list of registered EventListener's that are notified
+	// whenever a Structured event is recorded by the span and its children.
+	eventListeners []EventListener
+
+	// Locking rules:
+	// - If locking both a parent and a child, the parent must be locked first. In
+	// practice, children don't take the parent's lock.
+	// - The active spans registry's lock must be acquired before this lock.
+	mu struct {
+		syncutil.Mutex
+		crdbSpanMu
+	}
+}
+
+type childRef struct {
+	_spanRef spanRef
+	// collectRecording is set if this child's recording should be included in the
+	// parent's recording. This is usually the case, except for children created
+	// with the WithDetachedRecording() option.
+	collectRecording bool
+}
+
+func (c childRef) span() *crdbSpan {
+	return c._spanRef.i.crdb
+}
+
+type crdbSpanMu struct {
+	// goroutineID is the ID of the goroutine that created this span, or the goroutine that
+	// subsequently adopted it through Span.UpdateGoroutineIDToCurrent()).
+	goroutineID uint64
+
+	// parent is the span's local parent, if any. parent is not set if the span is
+	// a root or the parent span is remote.
+	//
+	// Note that parent is mutable; a span can start by having a parent but then,
+	// if the parent finishes before the child does (which is uncommon), the
+	// child's parent is set to nil.
+	//
+	// While parent is set, this child is holding a reference in the parent's
+	// reference counter. The parent's ref count is decremented when this child
+	// Finish()es, or otherwise when this pointer is nil'ed (i.e. on parent
+	// Finish()).
+	parent spanRef
+
+	// finished is set if finish() was called.
+	finished bool
+	// finishing is set while finish() is in the process of running. finish() has
+	// two separate critical sections, and this finishing field is used to detect
+	// when other calls have been interleaved between them.
+	finishing bool
+
+	// duration is initialized to -1 and set on Finish().
+	duration time.Duration
+
+	// openChildren maintains the list of currently-open local children. These
+	// children are part of the active spans registry only indirectly, through
+	// this parent. When the parent finishes, any child that's still open will be
+	// inserted into the registry directly.
+	//
+	// If this parent is recording at the time when a child Finish()es, and the
+	// respective childRef indicates that the child is to be included in the
+	// parent's recording, then the child's recording is collected in
+	// recording.finishedChildren.
+	//
+	// The spans are not maintained in a particular order.
+	openChildren []childRef
+
+	recording recordingState
+
+	// tags are a list of key/value pairs associated with the span through
+	// SetTag(). They will be appended to the tags in logTags when someone needs
+	// to actually observe the total set of tags that is a part of this Span.
+	tags []attribute.KeyValue
+	// lazyTags are tags whose values are only string-ified on demand. Each lazy
+	// tag is expected to implement either fmt.Stringer or LazyTag.
+	lazyTags []lazyTag
+}
+
+type lazyTag struct {
+	Key   string
+	Value interface{}
+}
+
+type recordingState struct {
+	// recordingType is the recording type of the ongoing recording, if any.
+	// Its 'load' method may be called without holding the surrounding mutex,
+	// but its 'swap' method requires the mutex.
+	recordingType atomicRecordingType
+
+	logs sizeLimitedBuffer[*tracingpb.LogRecord]
+	// structured accumulates StructuredRecord's.
+	//
+	// Note that structured events that originally belonged to child spans but
+	// bubbled up to this parent in various ways (e.g. children finished while
+	// this span was not recording verbosely, or children that were dropped from a
+	// verbose recording because of the span limit) are not part of this buffer;
+	// they're in finishedChildren.Root.StructuredRecords.
+	structured sizeLimitedBuffer[*tracingpb.StructuredRecord]
+
+	// notifyParentOnStructuredEvent is true if the span's parent has asked to be
+	// notified of every StructuredEvent recording on this span.
+	notifyParentOnStructuredEvent bool
+
+	// droppedLogs is set if the span has capped out its memory limits for logs
+	// and structured events, and had to drop some. It's used to annotate
+	// recordings with the _dropped_logs tag, when applicable.
+	//
+	// NOTE: The _dropped_logs tag applies exclusively to logs directly pertaining
+	// to this span. It does not apply to structured logs belonging to child spans
+	// that were dropped because of the limit on the number of spans in the
+	// recording. We move the structured logs from such spans into the parent if
+	// there's room. If there isn't, they are silently dropped.
+	droppedLogs bool
+
+	// finishedChildren contains the recordings of finished children (and
+	// grandchildren recursively). This includes remote child span recordings
+	// that were manually imported, as well as recordings from local children
+	// that Finish()ed.
+	//
+	// Only child spans that finished while this span was in the RecordingVerbose
+	// mode are included here. Structured events from children finished while this
+	// parent was in RecordingStructured mode are stored
+	// finishedChildren.Root.Structured.
+	//
+	// It's convenient to store finishedChildren as a Trace, even though the
+	// finishedChildren.Root will only be initialized when the span finishes
+	// (other that Root.Structured, which can accumulate events from children).
+	finishedChildren Trace
+
+	// childrenMetadata is a mapping from operation to the aggregated metadata of
+	// that operation.
+	//
+	// When a child of this span is Finish()ed, it updates the map with all the
+	// children in its Recording. childrenMetadata therefore provides a bucketed
+	// view of the various operations that are being traced as part of a span.
+	childrenMetadata map[string]tracingpb.OperationMetadata
+}
+
+// makeSizeLimitedBuffer creates a sizeLimitedBuffer.
+//
+// scratch, if not nil, represents pre-allocated space that the Buffer takes
+// ownership of. The whole backing array of the provided slice is taken over,
+// included elements and available capacity.
+func makeSizeLimitedBuffer[T any](limit int64, scratch []T) sizeLimitedBuffer[T] {
+	return sizeLimitedBuffer[T]{
+		bytesLimit: limit,
+		Buffer:     ring.MakeBuffer(scratch),
+	}
+}
+
+// sizeLimitedBuffer is a wrapper on top of ring.Buffer that keeps track of the
+// memory size of its elements.
+type sizeLimitedBuffer[T any] struct {
+	ring.Buffer[T]
+	bytesSize  int64
+	bytesLimit int64
+}
+
+// Trace represents the recording of a span and all its descendents.
+type Trace struct {
+	Root tracingpb.RecordedSpan
+	// Children are the traces of the child spans. The slice is kept sorted by
+	// child start time.
+	//
+	// Children are added via addChildren(). Once a child is added to a Trace, the
+	// Trace takes ownership; only the Trace can modify that child, since it needs
+	// to maintain the NumSpans and StructuredRecordsSizeBytes bookkeeping.
+	Children []Trace
+	// NumSpans tracks the number of spans in the recording: 1 for the root plus
+	// the size of the child traces recursively.
+	NumSpans int
+	// StructuredRecordsSizeBytes tracks the total size of structured logs in Root
+	// and all the Children, recursively.
+	StructuredRecordsSizeBytes int64
+
+	// DroppedDirectChildren maintains info about whether any direct children were
+	// omitted from Children because of recording limits.
+	//
+	// When set, DroppedDirectChildren and DroppedIndirectChildren are also
+	// reflected in corresponding tags on Root.
+	DroppedDirectChildren bool
+	// DroppedIndirectChildren maintains info about whether any indirect children
+	// were omitted from Children because of recording limits.
+	DroppedIndirectChildren bool
+}
+
+// MakeTrace constructs a Trace.
+func MakeTrace(root tracingpb.RecordedSpan) Trace {
+	return Trace{
+		Root:                       root,
+		NumSpans:                   1,
+		StructuredRecordsSizeBytes: root.StructuredRecordsSizeBytes,
+	}
+}
+
+func (t *Trace) String() string {
+	return tracingpb.Recording(t.Flatten()).String()
+}
+
+// trimSpans reduces the size of the trace to maxSpans. If t.NumSpans <= maxSpans,
+// this is a no-op. Otherwise, spans will be dropped from the trace until the
+// size is exactly maxSpans.
+//
+// Structured events from the dropped spans are moved to the first non-dropped
+// parent. Note that trimStructuredEvents() can be used to reduce the size of
+// events.
+func (t *Trace) trimSpans(maxSpans int) {
+	if t.NumSpans <= maxSpans {
+		return
+	}
+	t.trimSpansRecursive(t.NumSpans-maxSpans, true /* isRoot */)
+}
+
+func (t *Trace) trimSpansRecursive(toDrop int, isRoot bool) {
+	if toDrop <= 0 {
+		toDrop := toDrop // copy escaping to the heap
+		panic(errors.AssertionFailedf("invalid toDrop < 0: %d", toDrop))
+	}
+	if t.NumSpans <= toDrop {
+		panic(errors.AssertionFailedf("NumSpans expected to be > toDrop; NumSpans: %d, toDrop: %d", t.NumSpans, toDrop))
+	}
+
+	// Look at the spans ordered by size descendingly, so that we drop the fewest children
+	// possible.
+	childrenIdx := make([]int, len(t.Children))
+	for i := range t.Children {
+		childrenIdx[i] = i
+	}
+	sort.Slice(childrenIdx, func(i, j int) bool {
+		return t.Children[childrenIdx[i]].NumSpans >= t.Children[childrenIdx[j]].NumSpans
+	})
+	// We'll eliminate some children completely (the largest ones), and we'll
+	// recurse into the next one.
+	// Figure out how many spans we're going to drop completely (we might not have
+	// to drop any).
+	spansToDrop := 0
+	total := 0
+	recurseIdx := -1
+	for _, idx := range childrenIdx {
+		if total+t.Children[idx].NumSpans <= toDrop {
+			spansToDrop++
+			total += t.Children[idx].NumSpans
+		} else {
+			break
+		}
+	}
+	// If we need to drop some more spans, but we don't have to completely drop
+	// the next fattest child, recurse into the next child.
+	toDropFromNextChild := toDrop - total
+	if toDropFromNextChild > 0 {
+		// Note: we know that childrenIdx[spansToDrop] is not out of bounds; if
+		// toDropFromNextChild > 0, there must be at least one more child after
+		// spansToDrop.
+		recurseIdx = childrenIdx[spansToDrop]
+		if t.Children[recurseIdx].NumSpans < toDropFromNextChild {
+			panic(errors.AssertionFailedf("expected next child to have enough spans"))
+		}
+		t.Children[recurseIdx].trimSpansRecursive(toDropFromNextChild, false /* isRoot */)
+		t.NumSpans -= toDropFromNextChild
+		t.DroppedIndirectChildren = true
+		if isRoot {
+			// The original recursive root Trace `t`'s Root member is expected to have independently allocated
+			// tags structures. However, child spans are potentially share memory for tags, logs, and stats
+			// information across goroutines which are not protected by a mutex. See (*Trace).PartialClone for
+			// more details - deep copying these structures is avoided to reduce allocations.
+			//
+			// To avoid multiple goroutines racing to add tags to child spans with unprotected tags structures,
+			// we only indicate on the recursive root Trace's Root member that indirect children have been dropped.
+			t.Root.EnsureTagGroup(tracingpb.AnonymousTagGroupName).AddTag("_dropped_indirect_children", "")
+		}
+	}
+
+	if spansToDrop > 0 {
+		t.DroppedDirectChildren = true
+		if isRoot {
+			// The original recursive root Trace `t`'s Root member is expected to have independently allocated
+			// tags structures. However, child spans are potentially share memory for tags, logs, and stats
+			// information across goroutines which are not protected by a mutex. See (*Trace).PartialClone for
+			// more details - deep copying these structures is avoided to reduce allocations.
+			//
+			// To avoid multiple goroutines racing to add tags to child spans with unprotected tags structures,
+			// we only indicate on the recursive root Trace's Root member that children have been dropped.
+			t.Root.EnsureTagGroup(tracingpb.AnonymousTagGroupName).AddTag("_dropped_children", "")
+		}
+		// We're going to drop the fattest spansToDrop spans.
+		childrenToDropIdx := childrenIdx[:spansToDrop]
+
+		// Sort the indexes of the children to drop ascendingly, so that we can
+		// remove them easily while maintaining the existing order for the children
+		// that stay.
+		sort.Ints(childrenToDropIdx)
+		newChildren := make([]Trace, 0, len(t.Children)-spansToDrop)
+		j := 0 // This will iterate over childrenToDropIdx
+		for i := range t.Children {
+			if j < len(childrenToDropIdx) && i == childrenToDropIdx[j] {
+				// We need to drop this child.
+				j++
+				// Copy the structured events from the dropped child to the parent.
+				// Note that t.StructuredRecordsSizeBytes doesn't change.
+				buf := t.Children[i].appendStructuredEventsRecursively(nil /* buffer */)
+				for i := range buf {
+					t.Root.AddStructuredRecord(buf[i])
+				}
+			} else {
+				// This child is not dropped; copy it over to newChildren.
+				newChildren = append(newChildren, t.Children[i])
+			}
+		}
+		t.Children = newChildren
+		t.NumSpans -= total
+	}
+}
+
+// trimStructuredEvents drops structured records as needed in order to make the total
+// size of events in t <= maxBytes.
+//
+// The method works recursively. Events are dropped first from the spans with
+// the largest events size.
+func (t *Trace) trimStructuredEvents(maxBytes int64) int64 {
+	toDrop := t.StructuredRecordsSizeBytes - maxBytes
+	if toDrop <= 0 {
+		return 0
+	}
+
+	// Look at the spans ordered by structured size descendingly; we'll drop
+	// events from the fattest child first.
+	childrenIdx := make([]int, len(t.Children)+1)
+	for i := range t.Children {
+		childrenIdx[i] = i
+	}
+	childrenIdx[len(t.Children)] = -1 // Represent the root.
+	sort.Slice(childrenIdx, func(i, j int) bool {
+		var leftSize, rightSize int64
+		if childrenIdx[i] == -1 {
+			leftSize = t.Root.StructuredRecordsSizeBytes
+		} else {
+			leftSize = t.Children[childrenIdx[i]].StructuredRecordsSizeBytes
+		}
+		if childrenIdx[j] == -1 {
+			rightSize = t.Root.StructuredRecordsSizeBytes
+		} else {
+			rightSize = t.Children[childrenIdx[j]].StructuredRecordsSizeBytes
+		}
+		return leftSize >= rightSize
+	})
+
+	droppedTotal := int64(0)
+	for _, idx := range childrenIdx {
+		var dropped int64
+		if idx == -1 {
+			// This is the root.
+			dropped = t.Root.TrimStructured(t.Root.StructuredRecordsSizeBytes - toDrop)
+		} else {
+			child := &t.Children[idx]
+			dropped = child.trimStructuredEvents(child.StructuredRecordsSizeBytes - toDrop)
+		}
+		droppedTotal += dropped
+		toDrop -= dropped
+		if toDrop <= 0 {
+			break
+		}
+	}
+
+	t.StructuredRecordsSizeBytes -= droppedTotal
+	return droppedTotal
+}
+
+// addChildren adds child traces to t. After adding the children, the trace is
+// trimmed to maxSpans (if 0, no trimming occurs). If spans are dropped because
+// of the maxSpans limit, the structured messages from dropped spans are copied
+// into their parents. However, the total size of structured logs across t is
+// limited to maxStructuredBytes (if not zero). If records need to be dropped
+// because of this limit, they're dropped from the span with the largest size
+// first.
+//
+// The list of children is kept sorted.
+func (t *Trace) addChildren(children []Trace, maxSpans int, maxStructuredBytes int64) {
+
+	// Figure out if we'll need to re-sort the children. We won't need to do it if
+	// we're adding a single child that belongs in the last position.
+	needSort := false
+	if len(t.Children) > 0 {
+		needSort = !(len(children) == 1 &&
+			children[0].Root.StartTime.After(
+				t.Children[len(t.Children)-1].Root.StartTime))
+	}
+	for i := range children {
+		c := &children[i]
+		t.NumSpans += c.NumSpans
+		t.StructuredRecordsSizeBytes += c.StructuredRecordsSizeBytes
+		t.Children = append(t.Children, *c)
+	}
+	if needSort {
+		t.sortChildren()
+	}
+	if maxSpans > 0 {
+		t.trimSpans(maxSpans)
+	}
+	if maxStructuredBytes > 0 {
+		t.trimStructuredEvents(maxStructuredBytes)
+	}
+}
+
+// sortChildren sorts the children in the trace by start time.
+func (t *Trace) sortChildren() {
+	toSort := sortPoolTraces.Get().(*[]Trace) // avoids allocations in sort.Sort
+	*toSort = t.Children
+	sort.Slice(*toSort, func(i, j int) bool {
+		return (*toSort)[i].Root.StartTime.Before((*toSort)[j].Root.StartTime)
+	})
+	*toSort = nil
+	sortPoolTraces.Put(toSort)
+}
+
+var sortPoolTraces = sync.Pool{
+	New: func() interface{} {
+		return &[]Trace{}
+	},
+}
+
+// Empty returns true if the receiver is not initialized.
+func (t *Trace) Empty() bool {
+	return len(t.Children) == 0 && t.Root.StartTime == time.Time{}
+}
+
+func (t *Trace) appendStructuredEventsRecursively(
+	buffer []tracingpb.StructuredRecord,
+) []tracingpb.StructuredRecord {
+	buffer = append(buffer, t.Root.StructuredRecords...)
+	for i := range t.Children {
+		buffer = t.Children[i].appendStructuredEventsRecursively(buffer)
+	}
+	return buffer
+}
+
+func (t *Trace) appendSpansRecursively(buffer []tracingpb.RecordedSpan) []tracingpb.RecordedSpan {
+	buffer = append(buffer, t.Root)
+	for i := range t.Children {
+		buffer = t.Children[i].appendSpansRecursively(buffer)
+	}
+	return buffer
+}
+
+// Flatten flattens the trace into a slice of spans. The root is the first span,
+// and parents come before children. Otherwise, the spans are not sorted.
+//
+// See SortSpans() for sorting the result in order to turn it into a
+// tracingpb.Recording.
+func (t *Trace) Flatten() []tracingpb.RecordedSpan {
+	if t.Empty() {
+		return nil
+	}
+	return t.appendSpansRecursively(nil /* buffer */)
+}
+
+// ToRecording converts the Trace to a tracingpb.Recording by flattening it and
+// sorting the spans.
+func (t *Trace) ToRecording() tracingpb.Recording {
+	spans := t.Flatten()
+	// sortSpans sorts the spans by StartTime, except the first Span (the root of
+	// this recording) which stays in place.
+	toSort := sortPoolRecordings.Get().(*tracingpb.Recording) // avoids allocations in sort.Sort
+	*toSort = spans[1:]
+	sort.Sort(toSort)
+	*toSort = nil
+	sortPoolRecordings.Put(toSort)
+	return spans
+}
+
+var sortPoolRecordings = sync.Pool{
+	New: func() interface{} {
+		return &tracingpb.Recording{}
+	},
+}
+
+// PartialClone performs a deep copy of the trace. The immutable slices are not
+// copied: logs, tags and stats.
+func (t *Trace) PartialClone() Trace {
+	r := *t
+	// The structured logs need copying since the slice is mutable: new logs can
+	// be added to the source when spans are added to the trace but the trace is
+	// over the span limit. Technically, simply adding to the slice is safe if we
+	// made a shallow copy of the slice, but we're being defensive here as we
+	// might go beyond simply adding logs in the future.
+	r.Root.StructuredRecords = make([]tracingpb.StructuredRecord, len(t.Root.StructuredRecords))
+	copy(r.Root.StructuredRecords, t.Root.StructuredRecords)
+	r.Children = make([]Trace, len(t.Children))
+	for i := range t.Children {
+		r.Children[i] = t.Children[i].PartialClone()
+	}
+	return r
+}
+
+// Discard zeroes out *buf. If nobody else is referencing the backing storage
+// for the buffer, or any of the elements, then this makes the backing storage
+// is made available for GC.
+//
+// Note that Discard does not modify the backing storage (i.e. it does not nil
+// out the elements). So, if anyone still has a reference to the storage, then
+// the elements cannot be GCed.
+func (buf *sizeLimitedBuffer[T]) Discard() {
+	*buf = sizeLimitedBuffer[T]{}
+}
+
+// finish marks the span as finished. Further operations on the span are not
+// allowed. Returns false if the span was already finished.
+//
+// Calling finish() a second time is illegal, as is any use-after-finish().
+// Still, the Tracer can be configured to tolerate such uses. If the Tracer was
+// configured to not tolerate use-after-Finish, we would have crashed before
+// calling this.
+func (s *crdbSpan) finish() bool {
+	// Finishing involves the following steps:
+	// 1) Take the lock and capture a reference to the parent.
+	// 2) Operate on the parent outside of the lock.
+	// 3) Take the lock again, operate on the children under the lock, and also
+	//    capture references to the children for further operations outside of the
+	//    lock.
+	// 4) Insert the children into the active spans registry outside of the lock.
+	//
+	// We could reorder things such that the lock is only taken once, but it
+	// results in more awkward code because operating on the s' parent expects to
+	// find s' children in place, to collect their recordings.
+
+	var parent spanRef
+	var hasParent bool
+	{
+		s.mu.Lock()
+		if s.mu.finished {
+			// Already finished (or at least in the process of finish()ing). This
+			// check ensures that only one caller performs cleanup for this span. We
+			// don't want the span to be re-allocated while finish() is running.
+			s.mu.Unlock()
+			return false
+		}
+		s.mu.finished = true
+		if s.recordingType() != tracingpb.RecordingOff {
+			duration := timeutil.Since(s.startTime)
+			if duration == 0 {
+				duration = time.Nanosecond
+			}
+			s.mu.duration = duration
+		}
+
+		// If there is a parent, we'll operate on the parent below, outside the
+		// child's lock, as per the lock ordering convention between parents and
+		// children. The parent might get Finish()ed by the time we call
+		// parent.childFinished(s) on it below; that's OK because we're going to
+		// hold on taking a reference in the parent's reference counter. Notice that
+		// we move the reference out of s.mu.parent; leaving it there would not work
+		// because s.mu.parent can be released by s.parentFinished() after we drop
+		// our lock.
+		//
+		// If there is no parent, we avoid releasing and then immediately
+		// re-acquiring the lock, as a performance optimization.
+		parent = s.mu.parent.move()
+		hasParent = !parent.empty()
+		if hasParent {
+			s.mu.finishing = true
+			s.mu.Unlock()
+		}
+	}
+
+	// Operate on the parent outside the child (our current receiver) lock.
+	// childFinished() might call back into the child (`s`) and acquire the
+	// child's lock.
+	if hasParent {
+		// It's possible to race with parent.Finish(); if we lose the race, the
+		// parent will not have any record of this child. childFinished() deals with
+		// that possibility.
+		parent.Span.i.crdb.childFinished(s)
+		parent.release()
+	}
+
+	// Operate on children.
+	var children []spanRef
+	var needRegistryChange bool
+	{
+		// Re-acquire the lock if we dropped it above.
+		if hasParent {
+			s.mu.Lock()
+			s.mu.finishing = false
+		}
+
+		// If the span was not part of the registry the first time the lock was
+		// acquired, above, it never will be (because we marked it as finished). So,
+		// we'll need to remove it from the registry only if it currently does not
+		// have a parent. We'll also need to manipulate the registry if there are
+		// open children (they'll need to be added to the registry).
+		needRegistryChange = !hasParent || len(s.mu.openChildren) > 0
+
+		// Deal with the orphaned children - make them roots. We call into the
+		// children while holding the parent's lock. As per the span locking
+		// convention, that's OK (but the reverse isn't).
+		//
+		// We also shallow-copy the children for operating on them outside the lock.
+		children = make([]spanRef, len(s.mu.openChildren))
+		for i := range s.mu.openChildren {
+			c := &s.mu.openChildren[i]
+			c.span().parentFinished()
+			// Move ownership of the child reference, and also nil out the pointer to
+			// the child, making it available for GC.
+			children[i] = c._spanRef.move()
+		}
+		s.mu.openChildren = nil // The children were moved away.
+		s.mu.Unlock()
+	}
+
+	if needRegistryChange {
+		// Atomically replace s in the registry with all of its still-open children.
+		s.tracer.activeSpansRegistry.swap(s.spanID, children)
+	}
+
+	return true
+}
+
+func (s *crdbSpan) recordingType() tracingpb.RecordingType {
+	if s == nil {
+		return tracingpb.RecordingOff
+	}
+	return s.mu.recording.recordingType.load()
+}
+
+// TraceID is part of the RegistrySpan interface.
+func (s *crdbSpan) TraceID() tracingpb.TraceID {
+	return s.traceID
+}
+
+// SpanID is part of the RegistrySpan interface.
+func (s *crdbSpan) SpanID() tracingpb.SpanID {
+	return s.spanID
+}
+
+// GetRecording returns the span's recording.
+//
+// finishing indicates whether s is in the process of finishing. If it isn't,
+// the recording will include an "_unfinished" tag.
+func (s *crdbSpan) GetRecording(recType tracingpb.RecordingType, finishing bool) Trace {
+	return s.getRecordingImpl(recType, false /* includeDetachedChildren */, finishing)
+}
+
+// GetFullRecording is part of the RegistrySpan interface.
+func (s *crdbSpan) GetFullRecording(recType tracingpb.RecordingType) Trace {
+	return s.getRecordingImpl(recType, true /* includeDetachedChildren */, false /* finishing */)
+}
+
+// getRecordingImpl returns the span's recording.
+//
+// finishing indicates whether s is in the process of finishing. If it isn't,
+// the recording will include an "_unfinished" tag.
+func (s *crdbSpan) getRecordingImpl(
+	recType tracingpb.RecordingType, includeDetachedChildren bool, finishing bool,
+) Trace {
+	switch recType {
+	case tracingpb.RecordingVerbose:
+		return s.getVerboseRecording(includeDetachedChildren, finishing)
+	case tracingpb.RecordingStructured:
+		return MakeTrace(s.getStructuredRecording(includeDetachedChildren))
+	case tracingpb.RecordingOff:
+		return Trace{}
+	default:
+		panic(errors.AssertionFailedf("unreachable"))
+	}
+}
+
+// rollupChildrenMetadata combines the OperationMetadata in `from` into `to`.
+func rollupChildrenMetadata(
+	to map[string]tracingpb.OperationMetadata, from map[string]tracingpb.OperationMetadata,
+) {
+	for op, metadata := range from {
+		to[op] = to[op].Combine(metadata)
+	}
+}
+
+// getVerboseRecording returns the Span's recording, including its children.
+//
+// Each RecordedSpan in the Recording contains the ChildrenMetadata of all the
+// children, both finished and open, in the spans' subtree.
+//
+// finishing indicates whether s is in the process of finishing. If it isn't,
+// the recording will include an "_unfinished" tag.
+func (s *crdbSpan) getVerboseRecording(includeDetachedChildren bool, finishing bool) Trace {
+	if s == nil {
+		return Trace{} // noop span
+	}
+
+	var result Trace
+	var childrenMetadata map[string]tracingpb.OperationMetadata
+	func() {
+		s.mu.Lock()
+		defer s.mu.Unlock()
+
+		// Make a clone of the finished children, to avoid working on and returning
+		// a trace that aliases s.mu.recording.finishedChildren. We're going to
+		// modify the trace below, when adding open children to it, and
+		// s.mu.recording.finishedChildren will also evolve after we return the
+		// copy, so we can't allow for aliases.
+		result = s.mu.recording.finishedChildren.PartialClone()
+		// result.Root.StructuredRecords might have accumulated entries from spans
+		// that were trimmed from finishedChildren. Save them so we can re-insert
+		// them below.
+		oldEvents := result.Root.StructuredRecords
+		result.StructuredRecordsSizeBytes -= result.Root.StructuredRecordsSizeBytes
+		result.Root = s.getRecordingNoChildrenLocked(tracingpb.RecordingVerbose, finishing)
+		result.StructuredRecordsSizeBytes += result.Root.StructuredRecordsSizeBytes
+		for i := range oldEvents {
+			size := int64(oldEvents[i].Size())
+			if result.StructuredRecordsSizeBytes+size <= maxStructuredBytesPerTrace {
+				result.Root.AddStructuredRecord(oldEvents[i])
+				result.StructuredRecordsSizeBytes += size
+			}
+		}
+
+		// Copy over the OperationMetadata collected from s' finished children.
+		childrenMetadata = make(map[string]tracingpb.OperationMetadata)
+		rollupChildrenMetadata(childrenMetadata, s.mu.recording.childrenMetadata)
+
+		// We recurse on s' open children to get their verbose recordings, and to
+		// aggregate OperationMetadata from their children, both finished and open.
+		now := s.tracer.now()
+		openRecordings := make([]Trace, 0, len(s.mu.openChildren))
+		for _, openChild := range s.mu.openChildren {
+			if openChild.collectRecording || includeDetachedChildren {
+				openChildSp := openChild.span()
+				openChildRecording := openChildSp.getVerboseRecording(includeDetachedChildren, false /* finishing */)
+				openRecordings = append(openRecordings, openChildRecording)
+
+				// Record an entry for openChilds' OperationMetadata.
+				op := openChildSp.operation
+				meta := childrenMetadata[op]
+				meta.Count++
+				meta.ContainsUnfinished = true
+				meta.Duration += now.Sub(openChildSp.startTime)
+				childrenMetadata[op] = meta
+
+				// Copy over the OperationMetadata collected recursively from openChilds'
+				// children.
+				rollupChildrenMetadata(childrenMetadata, openChildRecording.Root.ChildrenMetadata)
+			}
+		}
+		result.addChildren(openRecordings, maxRecordedSpansPerTrace, maxStructuredBytesPerTrace)
+	}()
+
+	// Copy over the OperationMetadata collected from s' children into the root of
+	// the recording.
+	if len(childrenMetadata) != 0 {
+		result.Root.ChildrenMetadata = childrenMetadata
+	}
+
+	return result
+}
+
+// getStructuredRecording returns a shallow copy of the structured events in
+// this span and in all the children. The returned span will contain all
+// structured events across the receiver and all its children. The returned span
+// will also have its `childrenMetadata` populated with data for all the
+// children.
+//
+// The caller does not take ownership of the events; the event payloads must be
+// treated as immutable since they're shared with the receiver.
+func (s *crdbSpan) getStructuredRecording(includeDetachedChildren bool) tracingpb.RecordedSpan {
+	s.mu.Lock()
+	defer s.mu.Unlock()
+
+	res := s.getRecordingNoChildrenLocked(
+		tracingpb.RecordingStructured,
+		false, // finishing - since we're only asking for the structured recording, the argument doesn't matter
+	)
+
+	// Wipe the root's records. We're going to re-add them.
+	res.StructuredRecordsSizeBytes = 0
+	res.StructuredRecords = res.StructuredRecords[:0]
+	// Recursively fetch the StructuredEvents for s' and its children, both
+	// finished and open.
+	buf := s.appendStructuredEventsRecursivelyLocked(res.StructuredRecords, includeDetachedChildren)
+	for i := range buf {
+		res.AddStructuredRecord(buf[i])
+	}
+
+	// Recursively fetch the OperationMetadata for s' children, both finished and
+	// open.
+	res.ChildrenMetadata = make(map[string]tracingpb.OperationMetadata)
+	s.getChildrenMetadataRecursivelyLocked(res.ChildrenMetadata,
+		false /* includeRootMetadata */, includeDetachedChildren)
+
+	return res
+}
+
+// recordFinishedChildren adds the spans in childRecording to s' recording.
+//
+// s takes ownership of childRecording; the caller is not allowed to use them anymore.
+func (s *crdbSpan) recordFinishedChildren(childRecording Trace) {
+	if childRecording.Empty() {
+		return
+	}
+
+	// Notify the event listeners registered with s of the StructuredEvents on the
+	// children being added to s.
+	events := childRecording.appendStructuredEventsRecursively(nil)
+	for _, record := range events {
+		var d types.DynamicAny
+		if err := types.UnmarshalAny(record.Payload, &d); err != nil {
+			continue
+		}
+		s.notifyEventListeners(d.Message.(protoutil.Message))
+	}
+
+	s.mu.Lock()
+	defer s.mu.Unlock()
+	s.recordFinishedChildrenLocked(childRecording)
+}
+
+// s takes ownership of childRec; the caller is not allowed to use them
+// anymore.
+func (s *crdbSpan) recordFinishedChildrenLocked(childRec Trace) {
+	if childRec.Empty() {
+		return
+	}
+
+	// Depending on the type of recording, we either keep all the information
+	// received, or only the structured events.
+	switch s.recordingType() {
+	case tracingpb.RecordingVerbose:
+		// Change the root of the recording to be a child of this Span. This is
+		// usually already the case, except with DistSQL traces where remote
+		// processors run in spans that FollowFrom an RPC Span that we don't
+		// collect.
+		childRec.Root.ParentSpanID = s.spanID
+		s.mu.recording.finishedChildren.addChildren([]Trace{childRec}, maxRecordedSpansPerTrace, maxStructuredBytesPerTrace)
+	case tracingpb.RecordingStructured:
+		fc := &s.mu.recording.finishedChildren
+		num := len(fc.Root.StructuredRecords)
+		fc.Root.StructuredRecords = childRec.appendStructuredEventsRecursively(fc.Root.StructuredRecords)
+		// Account for the size of the structured records that were appended,
+		// breaking out of the loop if we hit the byte limit. This incorporates
+		// the byte size accounting logic from RecordedSpan.AddStructuredRecord.
+		for ; num < len(fc.Root.StructuredRecords); num++ {
+			size := int64(fc.Root.StructuredRecords[num].MemorySize())
+			if fc.StructuredRecordsSizeBytes+size > maxStructuredBytesPerTrace {
+				break
+			}
+			fc.Root.StructuredRecordsSizeBytes += size
+			fc.StructuredRecordsSizeBytes += size
+		}
+		// Trim any remaining entries if we hit the byte limit.
+		for i := num; i < len(fc.Root.StructuredRecords); i++ {
+			fc.Root.StructuredRecords[i] = tracingpb.StructuredRecord{}
+		}
+		fc.Root.StructuredRecords = fc.Root.StructuredRecords[:num]
+	case tracingpb.RecordingOff:
+		break
+	default:
+		panic(errors.AssertionFailedf("unrecognized recording mode: %v", s.recordingType()))
+	}
+
+	// Update s' ChildrenMetadata to capture all the spans in childRec.
+	//
+	// As an example where we are done finishing `child`:
+	//
+	// parent
+	//   child
+	//     grandchild
+	//
+	// `parent` will have:
+	// {child: 2s, grandchild: 1s}
+	//
+	// Record finished rootChilds' metadata.
+	s.mu.recording.childrenMetadata[childRec.Root.Operation] =
+		s.mu.recording.childrenMetadata[childRec.Root.Operation].Combine(
+			tracingpb.OperationMetadata{
+				Count:              1,
+				Duration:           childRec.Root.Duration,
+				ContainsUnfinished: false,
+			})
+
+	// Record the metadata of rootChilds' children, both finished and open.
+	//
+	// GetRecording(...) is responsible for recursively capturing the metadata for
+	// rootChilds' open and finished children.
+	rollupChildrenMetadata(s.mu.recording.childrenMetadata, childRec.Root.ChildrenMetadata)
+}
+
+func (s *crdbSpan) setTagLocked(key string, value attribute.Value) {
+	k := attribute.Key(key)
+	for i := range s.mu.tags {
+		if s.mu.tags[i].Key == k {
+			s.mu.tags[i].Value = value
+			return
+		}
+	}
+	s.mu.tags = append(s.mu.tags, attribute.KeyValue{Key: k, Value: value})
+}
+
+// setLazyTagLocked sets a tag that's only stringified if s' recording is
+// collected.
+//
+// value is expected to implement either Stringer or LazyTag.
+//
+// key is expected to not match the key of a non-lazy tag.
+func (s *crdbSpan) setLazyTagLocked(key string, value interface{}) {
+	for i := range s.mu.lazyTags {
+		if s.mu.lazyTags[i].Key == key {
+			s.mu.lazyTags[i].Value = value
+			return
+		}
+	}
+	s.mu.lazyTags = append(s.mu.lazyTags, lazyTag{Key: key, Value: value})
+}
+
+// getLazyTagLocked returns the value of the tag with the given key. If that tag
+// doesn't exist, the bool retval is false.
+func (s *crdbSpan) getLazyTagLocked(key string) (interface{}, bool) {
+	for i := range s.mu.lazyTags {
+		if s.mu.lazyTags[i].Key == key {
+			return s.mu.lazyTags[i].Value, true
+		}
+	}
+	return nil, false
+}
+
+// notifyEventListeners recursively notifies all the EventListeners registered
+// with this span and any ancestor spans in the Recording, of a StructuredEvent.
+//
+// This span is notified _before_ its ancestors.
+//
+// If any of the span's EventListeners return EventConsumed status, then the
+// ancestors are **not** notified about this Structured item.
+//
+// If s has a parent, then we notify the parent of the StructuredEvent outside
+// the child (our current receiver) lock. This is as per the lock ordering
+// convention between parents and children.
+func (s *crdbSpan) notifyEventListeners(item Structured) {
+	s.mu.Lock()
+	var unlocked bool
+	defer func() {
+		if !unlocked {
+			s.mu.Unlock()
+		}
+	}()
+
+	// Check if the span has been finished concurrently with this notify call.
+	// This can happen when the signal comes from a child span; in that case the
+	// child calls into the parent without holding the child's lock, so the call
+	// can race with parent.Finish().
+	if s.mu.finished {
+		return
+	}
+
+	// Notify s' eventListeners first, before passing the event to parent.
+	for _, listener := range s.eventListeners {
+		if listener.Notify(item) == EventConsumed {
+			return
+		}
+	}
+
+	if s.mu.recording.notifyParentOnStructuredEvent {
+		parent := s.mu.parent.Span.i.crdb
+		// Take a reference of s' parent before releasing the mutex. This ensures
+		// that if the parent were to be Finish()ed concurrently then the span does
+		// not get reused until we release the reference.
+		parentRef := makeSpanRef(s.mu.parent.Span)
+		defer parentRef.release()
+		s.mu.Unlock()
+		unlocked = true
+		parent.notifyEventListeners(item)
+	}
+}
+
+// record includes a log message in s' recording.
+func (s *crdbSpan) record(msg redact.RedactableString) {
+	if s.recordingType() != tracingpb.RecordingVerbose {
+		return
+	}
+
+	recordInternal(s, &tracingpb.LogRecord{
+		Time:    s.tracer.now(),
+		Message: msg,
+	}, &s.mu.recording.logs)
+}
+
+// recordStructured includes a structured event in s' recording.
+func (s *crdbSpan) recordStructured(item Structured) {
+	if s.recordingType() == tracingpb.RecordingOff {
+		return
+	}
+
+	p, err := types.MarshalAny(item)
+	if err != nil {
+		// An error here is an error from Marshal; these
+		// are unlikely to happen.
+		return
+	}
+
+	sr := &tracingpb.StructuredRecord{
+		Time:    s.tracer.now(),
+		Payload: p,
+	}
+	recordInternal(s, sr, &s.mu.recording.structured)
+
+	// If there are any listener's registered with this span, notify them of the
+	// Structured event being recorded.
+	s.notifyEventListeners(item)
+}
+
+// memorySizable is implemented by log records and structured events for
+// exposing their in-memory size. This size is used to put caps on the payloads
+// accumulated by a span.
+//
+// Note that, as opposed to the Size() method implemented by our
+// protoutil.Messages, MemorySize() aims to represent the memory footprint, not
+// the serialized length.
+type memorySizable interface {
+	MemorySize() int
+}
+
+func recordInternal[PL memorySizable](s *crdbSpan, payload PL, buffer *sizeLimitedBuffer[PL]) {
+	s.mu.Lock()
+	defer s.mu.Unlock()
+	size := int64(payload.MemorySize())
+	if size > buffer.bytesLimit {
+		// The incoming payload alone blows past the memory limit. Let's just
+		// drop it.
+		s.mu.recording.droppedLogs = true
+		return
+	}
+
+	buffer.bytesSize += size
+	if buffer.bytesSize > buffer.bytesLimit {
+		s.mu.recording.droppedLogs = true
+	}
+	for buffer.bytesSize > buffer.bytesLimit {
+		first := buffer.GetFirst()
+		buffer.RemoveFirst()
+		buffer.bytesSize -= int64(first.MemorySize())
+	}
+	buffer.AddLast(payload)
+}
+
+// appendStructuredEventsRecursivelyLocked appends the structured events
+// accumulated by s' and its finished and still-open children to buffer, and
+// returns the resulting slice.
+func (s *crdbSpan) appendStructuredEventsRecursivelyLocked(
+	buffer []tracingpb.StructuredRecord, includeDetachedChildren bool,
+) []tracingpb.StructuredRecord {
+	buffer = s.appendStructuredEventsLocked(buffer)
+	for _, c := range s.mu.openChildren {
+		if c.collectRecording || includeDetachedChildren {
+			sp := c.span()
+			buffer = func() []tracingpb.StructuredRecord {
+				sp.mu.Lock()
+				defer sp.mu.Unlock()
+				return sp.appendStructuredEventsRecursivelyLocked(buffer, includeDetachedChildren)
+			}()
+		}
+	}
+	return s.mu.recording.finishedChildren.appendStructuredEventsRecursively(buffer)
+}
+
+// getChildrenMetadataRecursivelyLocked populates `childrenMetadata` with
+// OperationMetadata entries for all of s' children (open and finished),
+// recursively.
+//
+// The method also populates `childrenMetadata` with an entry for the receiver
+// if `includeRootMetadata` is true.
+func (s *crdbSpan) getChildrenMetadataRecursivelyLocked(
+	childrenMetadata map[string]tracingpb.OperationMetadata,
+	includeRootMetadata, includeDetachedChildren bool,
+) {
+	if includeRootMetadata {
+		// Record an entry for s' metadata.
+		prevMetadata := childrenMetadata[s.operation]
+		prevMetadata.Count++
+		if s.mu.duration == -1 {
+			prevMetadata.Duration += timeutil.Since(s.startTime)
+			prevMetadata.ContainsUnfinished = true
+		} else {
+			prevMetadata.Duration += s.mu.duration
+		}
+		childrenMetadata[s.operation] = prevMetadata
+	}
+
+	// Copy over s' Finish()ed children metadata.
+	rollupChildrenMetadata(childrenMetadata, s.mu.recording.childrenMetadata)
+
+	// For each of s' open children, recurse to collect their metadata.
+	for _, c := range s.mu.openChildren {
+		if c.collectRecording || includeDetachedChildren {
+			sp := c.span()
+			func() {
+				sp.mu.Lock()
+				defer sp.mu.Unlock()
+				sp.getChildrenMetadataRecursivelyLocked(childrenMetadata,
+					true /*includeRootMetadata */, includeDetachedChildren)
+			}()
+		}
+	}
+}
+
+func (s *crdbSpan) appendStructuredEventsLocked(
+	buffer []tracingpb.StructuredRecord,
+) []tracingpb.StructuredRecord {
+	numEvents := s.mu.recording.structured.Len()
+	for i := 0; i < numEvents; i++ {
+		event := s.mu.recording.structured.Get(i)
+		buffer = append(buffer, *event)
+	}
+	return buffer
+}
+
+// getRecordingNoChildrenLocked returns the Span's recording without including
+// children.
+//
+// The tags are included in the result only if recordingType==RecordingVerbose.
+// This is a performance optimization as stringifying the tag values can be
+// expensive.
+//
+// finishing indicates whether s is in the process of finishing. If it isn't,
+// the recording will include an "_unfinished" tag.
+func (s *crdbSpan) getRecordingNoChildrenLocked(
+	recordingType tracingpb.RecordingType, finishing bool,
+) tracingpb.RecordedSpan {
+	rs := tracingpb.RecordedSpan{
+		TraceID:       s.traceID,
+		SpanID:        s.spanID,
+		ParentSpanID:  s.parentSpanID,
+		GoroutineID:   s.mu.goroutineID,
+		Operation:     s.operation,
+		StartTime:     s.startTime,
+		Duration:      s.mu.duration,
+		Verbose:       s.recordingType() == tracingpb.RecordingVerbose,
+		RecordingMode: s.recordingType().ToProto(),
+	}
+
+	if rs.Duration == -1 {
+		// -1 indicates an unfinished Span. For a recording it's better to put some
+		// duration in it, otherwise tools get confused. For example, we export
+		// recordings to Jaeger, and spans with a zero duration don't look nice.
+		rs.Duration = timeutil.Since(rs.StartTime)
+		rs.Finished = false
+	} else {
+		rs.Finished = true
+	}
+
+	// If the span is not verbose, optimize by avoiding the tags.
+	// This span is likely only used to carry payloads around.
+	//
+	// TODO(andrei): The optimization for avoiding the tags was done back when
+	// stringifying a {NodeID,StoreID}Container (a very common tag) was expensive.
+	// That has become cheap since, so this optimization might not be worth it any
+	// more.
+	wantTags := recordingType == tracingpb.RecordingVerbose
+	if wantTags {
+		if !finishing && !s.mu.finished {
+			rs.EnsureTagGroup(tracingpb.AnonymousTagGroupName).AddTag("_unfinished", "1")
+		}
+		if s.recordingType() == tracingpb.RecordingVerbose {
+			rs.EnsureTagGroup(tracingpb.AnonymousTagGroupName).AddTag("_verbose", "1")
+		}
+		if s.mu.recording.droppedLogs {
+			rs.EnsureTagGroup(tracingpb.AnonymousTagGroupName).AddTag("_dropped_logs", "")
+		}
+		if s.mu.recording.finishedChildren.DroppedDirectChildren {
+			rs.EnsureTagGroup(tracingpb.AnonymousTagGroupName).AddTag("_dropped_children", "")
+		}
+		if s.mu.recording.finishedChildren.DroppedIndirectChildren {
+			rs.EnsureTagGroup(tracingpb.AnonymousTagGroupName).AddTag("_dropped_indirect_children", "")
+		}
+	}
+
+	if numEvents := s.mu.recording.structured.Len(); numEvents != 0 {
+		rs.StructuredRecords = make([]tracingpb.StructuredRecord, 0, numEvents)
+		for i := 0; i < numEvents; i++ {
+			event := s.mu.recording.structured.Get(i)
+			rs.AddStructuredRecord(*event)
+		}
+	}
+
+	if wantTags {
+		if s.logTags != nil {
+			setLogTags(s.logTags.Get(), func(remappedKey string, tag *logtags.Tag) {
+				rs.EnsureTagGroup(tracingpb.AnonymousTagGroupName).AddTag(remappedKey, tag.ValueStr())
+			})
+		}
+		for _, kv := range s.mu.tags {
+			// We encode the tag values as strings.
+			rs.EnsureTagGroup(tracingpb.AnonymousTagGroupName).AddTag(string(kv.Key), kv.Value.Emit())
+		}
+		for _, tg := range s.getLazyTagGroupsLocked() {
+			if tg.Name == tracingpb.AnonymousTagGroupName {
+				for _, tag := range tg.Tags {
+					rs.EnsureTagGroup(tracingpb.AnonymousTagGroupName).AddTag(tag.Key, tag.Value)
+				}
+			} else {
+				rs.TagGroups = append(rs.TagGroups, *tg)
+			}
+		}
+
+		// Pull anonymous group to the front.
+		for i := range rs.TagGroups {
+			if rs.TagGroups[i].Name == tracingpb.AnonymousTagGroupName {
+				rs.TagGroups[0], rs.TagGroups[i] = rs.TagGroups[i], rs.TagGroups[0]
+			}
+		}
+	}
+
+	if numLogs := s.mu.recording.logs.Len(); numLogs != 0 {
+		rs.Logs = make([]tracingpb.LogRecord, numLogs)
+		for i := 0; i < numLogs; i++ {
+			lr := s.mu.recording.logs.Get(i)
+			rs.Logs[i] = *lr
+		}
+	}
+
+	return rs
+}
+
+// getLazyTagGroupsLocked returns a list of lazy tags as a slice of
+// *tracingpb.TagGroup
+func (s *crdbSpan) getLazyTagGroupsLocked() []*tracingpb.TagGroup {
+	var lazyTags []*tracingpb.TagGroup
+	addTagGroup := func(name string) *tracingpb.TagGroup {
+		lazyTags = append(lazyTags,
+			&tracingpb.TagGroup{
+				Name: name,
+			})
+		return lazyTags[len(lazyTags)-1]
+	}
+
+	addTag := func(k, v string) {
+		var tagGroup *tracingpb.TagGroup
+		for _, tg := range lazyTags {
+			if tg.Name == tracingpb.AnonymousTagGroupName {
+				tagGroup = tg
+				break
+			}
+		}
+		if tagGroup == nil {
+			tagGroup = addTagGroup(tracingpb.AnonymousTagGroupName)
+		}
+		tagGroup.Tags = append(tagGroup.Tags, tracingpb.Tag{
+			Key:   k,
+			Value: v,
+		})
+	}
+	for _, kv := range s.mu.lazyTags {
+		switch v := kv.Value.(type) {
+		case LazyTag:
+			var tagGroup *tracingpb.TagGroup
+			for _, tag := range v.Render() {
+				if tagGroup == nil {
+					// Only create the tag group if we have at least one child tag.
+					tagGroup = addTagGroup(kv.Key)
+				}
+				tagGroup.Tags = append(tagGroup.Tags,
+					tracingpb.Tag{
+						Key:   string(tag.Key),
+						Value: tag.Value.Emit(),
+					},
+				)
+			}
+		case fmt.Stringer:
+			addTag(kv.Key, v.String())
+		default:
+			addTag(kv.Key, fmt.Sprintf("<can't render %T>", kv.Value))
+		}
+	}
+	return lazyTags
+}
+
+// addChildLocked adds a child to the receiver.
+//
+// The receiver's lock must be held.
+//
+// The adding fails if the receiver has already Finish()ed. This should never
+// happen, since using a Span after Finish() is illegal. But still, we
+// defensively return false.
+func (s *crdbSpan) addChildLocked(child *Span, collectChildRec bool) bool {
+	s.mu.AssertHeld()
+
+	if s.mu.finished {
+		return false
+	}
+
+	s.mu.openChildren = append(
+		s.mu.openChildren,
+		childRef{_spanRef: makeSpanRef(child), collectRecording: collectChildRec},
+	)
+	return true
+}
+
+// childFinished is called when a child is Finish()ed. Depending on the
+// receiver's recording mode, the child is atomically removed and replaced it
+// with its recording.
+//
+// child is the child span that just finished.
+//
+// This method can be called while the parent (s) is still alive, is in the
+// process of finishing (i.e. s.finish() is in the middle section where it has
+// dropped the lock), or has completed finishing. In the first two cases, it is
+// expected that child is part of s.mu.openChildren. In the last case, this will
+// be a no-op.
+func (s *crdbSpan) childFinished(child *crdbSpan) {
+	s.mu.Lock()
+	defer s.mu.Unlock()
+
+	var childIdx int
+	found := false
+	for i, c := range s.mu.openChildren {
+		sp := c.span()
+		if sp == child {
+			childIdx = i
+			found = true
+			break
+		}
+	}
+	if !found {
+		// We haven't found the child, so the child must be calling into the parent
+		// (s) after s.finish() completed. This can happen if finishing the child
+		// races with finishing the parent (if s.finish() would have ran to
+		// completion before c.finish() was called, c wouldn't have called
+		// s.childFinished(c) because it would no longer have had a parent).
+		if !s.mu.finished {
+			panic(errors.AssertionFailedf("unexpectedly failed to find child of non-finished parent"))
+		}
+		// Since s has been finished, there's nothing more to do.
+		return
+	}
+
+	// Sanity check the situations when this method is called after s.finish() was
+	// called. Running this after s.finish() was called indicates that s.finish()
+	// and child.finish() were called concurrently - if s.finish() would have
+	// finished before child.finish() was called, the child would not have had a
+	// parent to call childFinished() on. Here, we assert that we understand the
+	// races that can happen, as this concurrency is subtle.
+	// - s.childFinished(c) can be called after s.finish() completed, in which
+	//   case `found` will be false above, and we won't get here.
+	// - s.childFinished(c) can also be called after s.finish() started, but
+	//   before s.finish() completed. s.finish() has two critical sections, and
+	//   drops its lock in between them.
+	// This is the only case where the child is found, and we explicitly assert
+	// that here.
+	if s.mu.finished {
+		if !s.mu.finishing {
+			panic(errors.AssertionFailedf("child unexpectedly calling into finished parent"))
+		}
+	}
+
+	collectChildRec := s.mu.openChildren[childIdx].collectRecording
+	// Drop the child's reference.
+	if s.mu.openChildren[childIdx]._spanRef.decRef() {
+		// We're going to use the child below, so we don't want it to be
+		// re-allocated yet. It shouldn't be re-allocated, because each span holds a
+		// reference to itself that's only dropped at the end of Span.Finish() (and
+		// the child at this point is in the middle of its Finish() call).
+		panic(errors.AssertionFailedf("span's reference count unexpectedly dropped to zero: %s", child.operation))
+	}
+
+	// Unlink the child.
+	l := len(s.mu.openChildren)
+	s.mu.openChildren[childIdx] = s.mu.openChildren[l-1]
+	s.mu.openChildren[l-1] = childRef{}
+	s.mu.openChildren = s.mu.openChildren[:l-1]
+
+	// Collect the child's recording.
+
+	if s.recordingType() == tracingpb.RecordingOff || !collectChildRec {
+		return
+	}
+
+	s.recordFinishedChildrenLocked(child.GetRecording(s.recordingType(),
+		false /* finishing - the child is already finished */))
+}
+
+// parentFinished makes s a root.
+func (s *crdbSpan) parentFinished() {
+	s.mu.Lock()
+	defer s.mu.Unlock()
+	s.mu.parent.release()
+	// Reset `notifyParentOnStructuredEvent` since s no longer has a parent.
+	s.mu.recording.notifyParentOnStructuredEvent = false
+}
+
+// visitOpenChildren calls the visitor for every open child. The receiver's lock
+// is held for the duration of the iteration, so the visitor should be quick.
+// The visitor is not allowed to hold on to children after it returns.
+func (s *crdbSpan) visitOpenChildren(visitor func(child *crdbSpan)) {
+	s.mu.Lock()
+	defer s.mu.Unlock()
+	for _, c := range s.mu.openChildren {
+		visitor(c.span())
+	}
+}
+
+// SetRecordingType is part of the RegistrySpan interface.
+func (s *crdbSpan) SetRecordingType(to tracingpb.RecordingType) {
+	s.mu.recording.recordingType.swap(to)
+
+	s.mu.Lock()
+	defer s.mu.Unlock()
+	for _, child := range s.mu.openChildren {
+		child.span().SetRecordingType(to)
+	}
+}
+
+// RecordingType is part of the RegistrySpan interface.
+func (s *crdbSpan) RecordingType() tracingpb.RecordingType {
+	return s.recordingType()
+}
+
+// withLock calls f while holding s' lock.
+func (s *crdbSpan) withLock(f func()) {
+	s.mu.Lock()
+	defer s.mu.Unlock()
+	f()
+}
+
+// wantEventNotificationsLocked returns true if the span was created
+// WithEventListeners(...) or the span has been configured to notify its parent
+// span on a StructuredEvent recording.
+func (s *crdbSpan) wantEventNotificationsLocked() bool {
+	return len(s.eventListeners) != 0 || s.mu.recording.notifyParentOnStructuredEvent
+}
+
+// setGoroutineID updates the span's goroutine ID.
+func (s *crdbSpan) setGoroutineID(gid int64) {
+	s.mu.Lock()
+	defer s.mu.Unlock()
+	s.mu.goroutineID = uint64(gid)
+}
+
+type atomicRecordingType tracingpb.RecordingType
+
+// load returns the recording type.
+func (art *atomicRecordingType) load() tracingpb.RecordingType {
+	return tracingpb.RecordingType(atomic.LoadInt32((*int32)(art)))
+}
+
+// swap stores the new recording type and returns the old one.
+func (art *atomicRecordingType) swap(recType tracingpb.RecordingType) tracingpb.RecordingType {
+	return tracingpb.RecordingType(atomic.SwapInt32((*int32)(art), int32(recType)))
+}
diff --git a/pkg/util/tracing/doc.go b/pkg/util/tracing/doc.go
new file mode 100644
index 0000000..12de42d
--- /dev/null
+++ b/pkg/util/tracing/doc.go
@@ -0,0 +1,96 @@
+// Copyright 2021 The Cockroach Authors.
+//
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
+
+// Package tracing encapsulates all tracing facilities used in CockroachDB.
+// Tracing exposes a lifetime-of-a-request view of operations, tracking it
+// through various internal components and across RPC boundaries. The concepts
+// and primitives used in this package are standard for most distributed
+// tracing libraries[1][2], but we'll capture it all here anyway.
+//
+// 1. The Data Model
+//
+//	       [Span A]  <--- (root span)
+//	           |
+//	    +------+------+
+//	    |             |
+//	[Span B]      [Span C] <--- (C is a "child of" A)
+//	    |             |
+//	[Span D]      +---+-------+
+//	              |           |
+//	          [Span E]    [Span F] >>> [Span G] <--- (G "follows from" F)
+//
+// Traces are defined implicitly by their Spans. A Trace can be thought of a
+// directed acyclic graph of Spans, where edges between Spans indicate that
+// they're causally related. An alternate (and usually the more useful)
+// rendering[3] of traces is a temporal one:
+//
+//	––|–––––––|–––––––|–––––––|–––––––|–––––––|–––––––|–––––––|–> time
+//
+//	 [Span A···················································]
+//	   [Span B··············································]
+//	      [Span D··········································]
+//	    [Span C········································]
+//	         [Span E·······]           [Span F··] [Span G··]
+//
+// The causal relation between spans can be one of two types:
+//   - Parent-child relation: Typically used when the parent span depends on the
+//     result of the child span (during an RPC call, the
+//     client-side span would be the parent of the
+//     server-side span). See [4].
+//   - Follows-from relation: Typically used when the first span does not in any
+//     way depend on the result of the second (think of a
+//     goroutine that spins off another that outlives it).
+//     Note that we still refer to the "first" and "second"
+//     span as being the "parent" and "child" respectively
+//     (they're still nodes in the DAG, just with a
+//     different kind of edge between them)[5].
+//
+// Each Span[6] is logically comprised of the following:
+// - An operation name
+// - Timing information (start timestamp, duration)
+// - A set of zero or more tags (for annotation, visible when rendering spans)
+// - References to other spans (mediated by the relations described above)
+// - Recording data[7] (structured data/messages visible when rendering spans)
+//
+// Spans are created through a Tracer. Related, Tracers also understand how to
+// serialize and deserialize[8] Spans across process boundaries (using only the
+// Span metadata[9]). We've defined handy GRPC interceptors[10] that let us do
+// this across RPC boundaries.
+//
+// The tracing package is tightly coupled with the context package. Since we
+// want the tracing infrastructure to be plumbed through the various layers in
+// the callstack, we tuck the Span object within a context.Context[11].
+//
+// Since this package is used pervasively, the implementation is very
+// performance-sensitive. It tries to avoid allocations (even
+// trying to avoid allocating Span objects[12] whenever possible), and avoids
+// doing work unless strictly necessary.
+//
+// The tracing package internally makes use of OpenTelemetry[2]. This gives us
+// the ability to configure external collectors for tracing information,
+// like Jaeger, DataDog, Lightstep or Zipkin.
+//
+// -----------------------------------------------------------------------------
+//
+// [1]: https://research.google/pubs/pub36356/
+// [2]: https://opentelemetry.io
+// [3]: `Recording.String`
+// [4]: `ChildSpan`
+// [5]: `ForkSpan`. "forking" a Span is the same as creating a new one
+//
+//	with a "follows from" relation.
+//
+// [6]: `crdbSpan`
+// [7]: `Span.SetVerbose`. To understand the specifics of what exactly is
+//
+//	captured in Span recording, when Spans have children that may be either
+//	local or remote, look towards `WithParent` and `WithDetachedRecording`.
+//
+// [8]: `Tracer.{InjectMetaInto,ExtractMetaFrom}`
+// [9]: `SpanMeta`
+// [10]: `{Client,Server}Interceptor`
+// [11]: `SpanFromContext`
+// [12]: WithForceRealSpan
+package tracing
diff --git a/pkg/util/tracing/span.go b/pkg/util/tracing/span.go
new file mode 100644
index 0000000..c85ca68
--- /dev/null
+++ b/pkg/util/tracing/span.go
@@ -0,0 +1,965 @@
+// Copyright 2017 The Cockroach Authors.
+//
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
+
+package tracing
+
+import (
+	"fmt"
+	"strings"
+	"sync/atomic"
+	"time"
+
+	"github.com/cockroachdb/cockroachdb-parser/pkg/util/debugutil"
+	"github.com/cockroachdb/cockroachdb-parser/pkg/util/protoutil"
+	"github.com/cockroachdb/cockroachdb-parser/pkg/util/tracing/tracingpb"
+	"github.com/cockroachdb/errors"
+	"github.com/cockroachdb/logtags"
+	"github.com/petermattis/goid"
+	"go.opentelemetry.io/otel/attribute"
+	"go.opentelemetry.io/otel/codes"
+	oteltrace "go.opentelemetry.io/otel/trace"
+	"golang.org/x/net/trace"
+)
+
+// Span is the tracing Span that we use in CockroachDB. Depending on the tracing
+// configuration, it can hold anywhere between zero and three destinations for
+// trace information:
+//
+// 1. external OpenTelemetry-compatible trace collector (Jaeger, Zipkin, Lightstep),
+// 2. /debug/requests endpoint (net/trace package); mostly useful for local debugging
+// 3. CRDB-internal trace span (powers SQL session tracing).
+//
+// The CockroachDB-internal Span (crdbSpan) is more complex because
+// rather than reporting to some external sink, the caller's "owner"
+// must propagate the trace data back across process boundaries towards
+// the root of the trace span tree; see WithParent
+// and WithRemoteParentFromSpanMeta, respectively.
+//
+// Additionally, the internal span type also supports turning on, stopping,
+// and restarting its data collection (see Span.StartRecording), and this is
+// used extensively in SQL session tracing.
+//
+// Span is a fairly thin wrapper around spanInner, dealing with guarding against
+// use-after-Finish and reference counting for pooling and re-allocating.
+type Span struct {
+	// helper is the allocation helper that this span is part of. Used to release
+	// back into a pool on Finish().
+	helper *spanAllocHelper
+
+	i spanInner
+
+	// finished is set on Finish(). Used to detect use-after-Finish.
+	finished int32 // atomic
+
+	// refCnt counts the references to this span held by other spans. The Span can
+	// only be re-allocated when refCnt reaches zero.
+	//
+	// The reference counting mechanism is used only internally by the tracing
+	// infrastructure. Clients using Spans do not track their references because
+	// it'd be too burdensome to require all the references to have a clearly
+	// defined life cycle, and to be explicitly released when they're no longer in
+	// use. For clients, the contract is that a span can be used until Finish().
+	//
+	// For convenience, the span itself holds a reference to itself until
+	// Finish(). This ensures that the reference count will not become zero before
+	// Finish().
+	//
+	// The reference count serves a couple of purposes:
+	// 1) Prevent re-allocation of a Span while child spans are still operating on
+	// it. In particular, this ensures that races between Finish()ing a parent and
+	// a child cannot result in the child operating on a re-allocated parent.
+	// Because of the span's lock ordering convention, a child cannot hold its
+	// lock while operating on the parent. During Finish(), the child drops its
+	// lock and informs the parent that it is Finish()ing. If the parent
+	// Finish()es at the same time, that call could erroneously conclude that the
+	// parent can be made available for re-use, even through the child goroutine
+	// has a pending call into the parent.
+	//
+	// 2) Prevent re-allocation of child spans while a Finish()ing parent is in
+	// the process of transforming the children into roots and inserting them into
+	// the active spans registry. Operating on the registry is done without
+	// holding any span's lock, so a race with a child's Finish() could result in
+	// the registry operating on a re-allocated span.
+	//
+	// 3) Prevent re-allocation of a Span in between the time that WithParent(s)
+	// captures a reference to s and the time when the parent option is used to
+	// create the child. Such an inopportune reuse of a span could only happen is
+	// the span is Finish()ed concurrently with the creation of its child, which
+	// is illegal. Still, we optionally tolerate use-after-Finishes, and this use
+	// cannot be tolerated with the reference count protection. Without this
+	// protection, the tree of spans in a trace could degenerate into a graph
+	// through the introduction of loops. A loop could lead to deadlock due to the
+	// fact that we lock multiple spans at once. The lock ordering convention is
+	// that the parent needs to be locked before the child, which ensures
+	// deadlock-freedom in the absence of loops.
+	// For example:
+	// 1. parent := tr.StartSpan()
+	// 2. parentOpt := WithParent(parent)
+	// 3. parent.Finish()
+	// 4. child := tr.StartSpan(parentOpt)
+	// If "parent" would be re-allocated as "child", then child would have itself
+	// as a parent. The use of parentOpt in step 4) after parent was finished in
+	// step 3) is a use-after-Finish of parent; it is illegal and, if detection is
+	// enabled, it might be detected as such. However, if span pooling and re-use
+	// is enabled, then the detection is not realiable (it does not catch cases
+	// where a span is re-used before a reference to it taken before the prior
+	// Finish() is used).
+	// A span having itself as a parent is just the trivial case of the problem;
+	// loops of arbitrary length are also possible. For example, for a loop of
+	// length 2:
+	// 1. Say we have span A as a parent with span B as a child (A -> B).
+	// 2. parentA := WithParent(A)
+	// 3. parentB := WithParent(B)
+	// 4. A.Finish(); B.Finish();
+	// 5. X := tr.StartSpan(parentA); Y := tr.StartSpan(parentB);
+	// If B is re-used as X, and A is re-used as Y, we get the following graph:
+	//  B<-┐
+	//  |  |
+	//  └->A
+	//
+	// We avoid these hazards by having WithParent(s) increment s' refCnt. Spans
+	// are not re-used while the creation of a child is pending. Spans can be
+	// Finish()ed while the creation of the child is pending, in which case the
+	// creation of the child will reliably detect the use-after-Finish (and turn
+	// it into a no-op if configured to tolerate such illegal uses).
+	refCnt int32 // atomic
+
+	// finishStack is set if debugUseAfterFinish is set. It represents the stack
+	// that called Finish(), in order to report it on further use.
+	finishStack debugutil.SafeStack
+}
+
+// detectUseAfterFinish() checks whether sp has already been Finish()ed. If it
+// did, the behavior depends on the Tracer's configuration: if it was configured
+// to tolerate use-after-Finish, detectUseAfterFinish returns true. If it has
+// been configured to not tolerate use-after-Finish, it crashes.
+//
+// Exported methods on Span are supposed to call this and short-circuit if true
+// is returrned.
+//
+// Note that a nil span will return true.
+func (sp *Span) detectUseAfterFinish() bool {
+	if sp == nil {
+		return true
+	}
+	alreadyFinished := atomic.LoadInt32(&sp.finished) != 0
+	// In test builds, we panic on span use after Finish. This is in preparation
+	// of span pooling, at which point use-after-Finish would become corruption.
+	if alreadyFinished && sp.i.tracer.PanicOnUseAfterFinish() {
+		var finishStack debugutil.SafeStack
+		if sp.finishStack == nil {
+			finishStack = debugutil.SafeStack("<stack not captured. Set debugUseAfterFinish>")
+		} else {
+			finishStack = sp.finishStack
+		}
+		panic(errors.AssertionFailedf("use of Span after Finish. Span: %s. Finish previously called at: %s",
+			sp.i.OperationName(), finishStack))
+	}
+
+	return alreadyFinished
+}
+
+// incRef increments sp's reference count. The span will not be re-allocated
+// before a corresponding decRef() is performed (i.e. before the count reaches
+// zero).
+//
+// Most code should not call incRef() directly, but instead use makeSpanRef().
+func (sp *Span) incRef() {
+	atomic.AddInt32(&sp.refCnt, 1)
+}
+
+// decRef decrements the span's reference count. If it reaches zero, the span is
+// made available for reuse if the Tracer was so configured.
+//
+// Returns true if the value dropped to zero.
+func (sp *Span) decRef() bool {
+	refCnt := atomic.AddInt32(&sp.refCnt, -1)
+	if refCnt < 0 {
+		panic(errors.AssertionFailedf("refCnt below 0: %s", sp))
+	}
+	// If this was the last reference, make the span available for re-use.
+	if refCnt == 0 {
+		alreadyFinished := atomic.LoadInt32(&sp.finished) != 0
+		if !alreadyFinished {
+			panic(errors.AssertionFailedf("Span reference count dropped to zero before the span was Finish()ed"))
+		}
+		if detectSpanRefLeaks {
+			sp.setFinalizer(nil)
+		}
+
+		sp.i.crdb.tracer.releaseSpanToPool(sp)
+		return true
+	}
+	return false
+}
+
+// Tracer exports the tracer this span was created using.
+func (sp *Span) Tracer() *Tracer {
+	if sp == nil {
+		return nil
+	}
+	sp.detectUseAfterFinish()
+	return sp.i.Tracer()
+}
+
+func (sp *Span) String() string {
+	return sp.OperationName()
+}
+
+// Redactable returns true if this Span's tracer is marked redactable.
+func (sp *Span) Redactable() bool {
+	if sp == nil {
+		return false
+	}
+	sp.detectUseAfterFinish()
+	return sp.Tracer().Redactable()
+}
+
+// Finish marks the Span as completed. It is illegal to use a Span after calling
+// Finish().
+//
+// Finishing a nil *Span is a noop.
+func (sp *Span) Finish() {
+	sp.finishInternal()
+}
+
+// finishInternal finishes the span.
+func (sp *Span) finishInternal() {
+	if sp == nil || sp.detectUseAfterFinish() {
+		return
+	}
+	if sp.Tracer().debugUseAfterFinish {
+		sp.finishStack = debugutil.Stack()
+	}
+	atomic.StoreInt32(&sp.finished, 1)
+	sp.i.Finish()
+	// Release the reference that the span held to itself. Unless we're racing
+	// with the finishing of the parent or one of the children, this one will be
+	// the last reference, and the span will be made available for re-allocation.
+	sp.decRef()
+}
+
+// FinishAndGetRecording finishes the span and gets a recording at the same
+// time. This is offered as a combined operation because, otherwise, the caller
+// would be forced to collect the recording before finishing and so the span
+// would appear to be unfinished in the recording (it's illegal to collect the
+// recording after the span finishes, except by using this method).
+//
+// Returns nil if the span is not currently recording (even if it had been
+// recording in the past).
+func (sp *Span) FinishAndGetRecording(recType tracingpb.RecordingType) tracingpb.Recording {
+	rec := tracingpb.Recording(nil)
+	if sp.RecordingType() != tracingpb.RecordingOff {
+		rec = sp.i.GetRecording(recType, true /* finishing */)
+	}
+	// Reach directly into sp.i to pass the finishing argument.
+	sp.finishInternal()
+	return rec
+}
+
+// FinishAndGetConfiguredRecording is like FinishAndGetRecording, except that
+// the type of recording returned is the type that the span was configured to
+// record.
+//
+// Returns nil if the span is not currently recording (even if it had been
+// recording in the past).
+func (sp *Span) FinishAndGetConfiguredRecording() tracingpb.Recording {
+	rec := tracingpb.Recording(nil)
+	recType := sp.RecordingType()
+	if recType != tracingpb.RecordingOff {
+		// Reach directly into sp.i to pass the finishing argument.
+		rec = sp.i.GetRecording(recType, true /* finishing */)
+	}
+	sp.finishInternal()
+	return rec
+}
+
+// GetRecording retrieves the current recording, if the Span has recording
+// enabled. This can be called while spans that are part of the recording are
+// still open; it can run concurrently with operations on those spans.
+//
+// Returns nil if the span is not currently recording (even if it had been
+// recording in the past).
+//
+// recType indicates the type of information to be returned: structured info or
+// structured + verbose info. The caller can ask for either regardless of the
+// current recording mode (and also regardless of past recording modes) but, of
+// course, GetRecording(RecordingVerbose) will not return verbose info if it was
+// never collected.
+//
+// As a performance optimization, GetRecording does not return tags when
+// recType == RecordingStructured. Returning tags requires expensive
+// stringification.
+//
+// A few internal tags are added to denote span properties:
+//
+//	"_unfinished":	The span was never Finish()ed.
+//	"_verbose":	The span is a verbose one.
+//	"_dropped_logs":	The span dropped events due to size limits.
+//	"_dropped_children": Some (direct) child spans were dropped because of the
+//											 trace size limit.
+//	"_dropped_indirect_children": Some indirect child spans were dropped
+//																because of the trace size limit.
+//
+// If recType is RecordingStructured, the return value will be nil if the span
+// doesn't have any structured events.
+func (sp *Span) GetRecording(recType tracingpb.RecordingType) tracingpb.Recording {
+	if sp.detectUseAfterFinish() {
+		return nil
+	}
+	if sp.RecordingType() == tracingpb.RecordingOff {
+		return nil
+	}
+	return sp.i.GetRecording(recType, false /* finishing */)
+}
+
+func (sp *Span) GetFullTraceRecording(recType tracingpb.RecordingType) Trace {
+	if sp.detectUseAfterFinish() {
+		return Trace{}
+	}
+	if sp.RecordingType() == tracingpb.RecordingOff {
+		return Trace{}
+	}
+	return sp.i.GetFullTraceRecording(recType)
+}
+
+// GetConfiguredRecording is like GetRecording, except the type of recording it
+// returns is the one that the span has been previously configured with.
+//
+// Returns nil if the span is not currently recording (even if it had been
+// recording in the past).
+func (sp *Span) GetConfiguredRecording() tracingpb.Recording {
+	if sp.detectUseAfterFinish() {
+		return nil
+	}
+	recType := sp.RecordingType()
+	if recType == tracingpb.RecordingOff {
+		return nil
+	}
+	return sp.i.GetRecording(recType, false /* finishing */)
+}
+
+// GetTraceRecording returns the span's recording as a Trace.
+//
+// See also GetRecording(), which returns a tracingpb.Recording.
+func (sp *Span) GetTraceRecording(recType tracingpb.RecordingType) Trace {
+	if sp.detectUseAfterFinish() {
+		return Trace{}
+	}
+	return sp.i.GetTraceRecording(recType, false /* finishing */)
+}
+
+// FinishAndGetTraceRecording finishes the span and returns its recording as a
+// Trace.
+//
+// See also FinishAndGetRecording(), which returns a tracingpb.Recording.
+func (sp *Span) FinishAndGetTraceRecording(recType tracingpb.RecordingType) Trace {
+	if sp.detectUseAfterFinish() {
+		return Trace{}
+	}
+	rec := sp.i.GetTraceRecording(recType, true /* finishing */)
+	sp.Finish()
+	return rec
+}
+
+// ImportRemoteRecording adds the spans in remoteRecording as children of the
+// receiver. As a result of this, the imported recording will be a part of the
+// GetRecording() output for the receiver. All the structured events from the
+// trace are passed to the receiver's event listeners.
+//
+// This function is used to import a recording from another node.
+func (sp *Span) ImportRemoteRecording(remoteRecording tracingpb.Recording) {
+	if sp.detectUseAfterFinish() {
+		return
+	}
+	// Handle recordings coming from 22.2 nodes that don't have the
+	// StructuredRecordsSizeBytes field set.
+	// TODO(andrei): remove this in 23.2.
+	for i := range remoteRecording {
+		if len(remoteRecording[i].StructuredRecords) != 0 && remoteRecording[i].StructuredRecordsSizeBytes == 0 {
+			size := int64(0)
+			for _, rec := range remoteRecording[i].StructuredRecords {
+				size += int64(rec.MemorySize())
+			}
+			remoteRecording[i].StructuredRecordsSizeBytes = size
+		}
+	}
+
+	sp.ImportTrace(treeifyRecording(remoteRecording))
+}
+
+// ImportTrace takes a trace recording and, depending on the receiver's
+// recording mode, adds it as a child to sp. All the structured events from the
+// trace are passed to the receiver's event listeners.
+//
+// ImportTrace takes ownership of trace; the caller should not use it anymore.
+// The caller can call Trace.PartialClone() to make a sufficient copy for
+// passing into ImportTrace.
+func (sp *Span) ImportTrace(trace Trace) {
+	if sp.detectUseAfterFinish() {
+		return
+	}
+	sp.i.ImportTrace(trace)
+}
+
+// Meta returns the information which needs to be propagated across process
+// boundaries in order to derive child spans from this Span. This may return an
+// Empty SpanMeta (which is a valid input to WithRemoteParentFromSpanMeta) if
+// the Span has been optimized out.
+func (sp *Span) Meta() SpanMeta {
+	if sp.detectUseAfterFinish() {
+		return SpanMeta{}
+	}
+	return sp.i.Meta()
+}
+
+// SetRecordingType sets the recording mode of the span and its children,
+// recursively. Setting it to RecordingOff disables further recording.
+// Everything recorded so far remains in memory.
+func (sp *Span) SetRecordingType(to tracingpb.RecordingType) {
+	if sp.detectUseAfterFinish() {
+		return
+	}
+	sp.i.SetRecordingType(to)
+}
+
+// RecordingType returns the range's current recording mode.
+func (sp *Span) RecordingType() tracingpb.RecordingType {
+	if sp.detectUseAfterFinish() {
+		return tracingpb.RecordingOff
+	}
+	return sp.i.RecordingType()
+}
+
+// IsVerbose returns true if the Span is verbose. See SetVerbose for details.
+func (sp *Span) IsVerbose() bool {
+	return sp.RecordingType() == tracingpb.RecordingVerbose
+}
+
+// Record provides a way to record free-form text into verbose spans. Recordings
+// may be dropped due to sizing constraints.
+//
+// TODO(tbg): make sure `msg` is lint-forced to be const.
+func (sp *Span) Record(msg string) {
+	if sp.detectUseAfterFinish() {
+		return
+	}
+	sp.i.Record(msg)
+}
+
+// Recordf is like Record, but accepts a format specifier.
+func (sp *Span) Recordf(format string, args ...interface{}) {
+	if sp.detectUseAfterFinish() {
+		return
+	}
+	sp.i.Recordf(format, args...)
+}
+
+// RecordStructured adds a Structured payload to the Span. It will be added to
+// the recording even if the Span is not verbose; however it will be discarded
+// if the underlying Span has been optimized out (i.e. is nil). Payloads may
+// also be dropped due to sizing constraints.
+//
+// RecordStructured does not take ownership of item; it marshals it into an Any
+// proto.
+func (sp *Span) RecordStructured(item Structured) {
+	if sp.detectUseAfterFinish() {
+		return
+	}
+	sp.i.RecordStructured(item)
+}
+
+// SetTag adds a tag to the span. If there is a pre-existing tag set for the
+// key, it is overwritten.
+func (sp *Span) SetTag(key string, value attribute.Value) {
+	if sp.detectUseAfterFinish() {
+		return
+	}
+	sp.i.SetTag(key, value)
+}
+
+// LazyTag is a tag value that expands into a series of key-value tags when
+// included in a recording. LazyTags can be used when it's useful to maintain a
+// single, structured tag in a Span (for example because the tag is accessed
+// through Span.GetLazyTag(key)), but that tag should render as multiple
+// key-value pairs when the Span's recording is collected. Recordings can only
+// contain string tags, for simplicity.
+type LazyTag interface {
+	// Render produces the list of key-value tags for the span's recording.
+	Render() []attribute.KeyValue
+}
+
+// SetLazyTag adds a tag to the span. The tag's value is expected to implement
+// either fmt.Stringer or LazyTag, and is only stringified using one of
+// the two on demand:
+//   - if the Span has an otel span or a net.Trace, the tag
+//     is stringified immediately and passed to the external trace (see
+//     SetLazyStatusTag if you want to avoid that).
+//   - if/when the span's recording is collected, the tag is stringified on demand.
+//     If the recording is collected multiple times, the tag is stringified
+//     multiple times (so, the tag can evolve over time). Since generally the
+//     collection of a recording can happen asynchronously, the implementation of
+//     Stringer or LazyTag should be thread-safe.
+func (sp *Span) SetLazyTag(key string, value interface{}) {
+	if sp.detectUseAfterFinish() {
+		return
+	}
+	sp.i.SetLazyTag(key, value)
+}
+
+// SetLazyTagLocked is the same as SetLazyTag but assumes that the mutex of sp
+// is being held.
+//
+// Deprecated: this method should not be used because it's introduced only to go
+// around some tech debt (#100438). Once that issue is addressed, this method
+// should be removed.
+func (sp *Span) SetLazyTagLocked(key string, value interface{}) {
+	if sp.detectUseAfterFinish() {
+		return
+	}
+	sp.i.setLazyTagLocked(key, value)
+}
+
+// GetLazyTag returns the value of the tag with the given key. If that tag doesn't
+// exist, the bool retval is false.
+func (sp *Span) GetLazyTag(key string) (interface{}, bool) {
+	if sp.detectUseAfterFinish() {
+		return attribute.Value{}, false
+	}
+	return sp.i.GetLazyTag(key)
+}
+
+// EventListener is an object that can be registered to listen for Structured
+// events recorded by the span and its children.
+type EventListener interface {
+	// Notify is invoked on every Structured event recorded by the span and its
+	// children, recursively.
+	//
+	// The caller holds the mutex of the span.
+	//
+	// Notify will not be called concurrently on the same span.
+	Notify(event Structured) EventConsumptionStatus
+}
+
+// EventConsumptionStatus describes whether the structured event has been "consumed"
+// by the EventListener.
+type EventConsumptionStatus int
+
+const (
+	// EventNotConsumed indicates that the event wasn't "consumed" by the
+	// EventListener, so other listeners as well as any ancestor spans should be
+	// notified about the event.
+	EventNotConsumed EventConsumptionStatus = iota
+	// EventConsumed indicates that the event has been "consumed" by the
+	// EventListener, so neither other listeners for the span nor the ancestor
+	// spans should be notified about it.
+	EventConsumed
+)
+
+// TraceID retrieves a span's trace ID.
+func (sp *Span) TraceID() tracingpb.TraceID {
+	if sp.detectUseAfterFinish() {
+		return 0
+	}
+	return sp.i.TraceID()
+}
+
+// SpanID retrieves a span's ID.
+func (sp *Span) SpanID() tracingpb.SpanID {
+	return sp.i.SpanID()
+}
+
+// OperationName returns the name of this span assigned when the span was
+// created.
+func (sp *Span) OperationName() string {
+	if sp == nil {
+		return "<nil>"
+	}
+	sp.detectUseAfterFinish()
+	return sp.i.crdb.operation
+}
+
+// IsSterile returns true if this span does not want to have children spans. In
+// that case, trying to create a child span will result in the would-be child
+// being a root span.
+func (sp *Span) IsSterile() bool {
+	if sp.detectUseAfterFinish() {
+		return true
+	}
+	return sp.i.sterile
+}
+
+// UpdateGoroutineIDToCurrent updates the span's goroutine ID to the current
+// goroutine. This should be called when a different goroutine takes ownership
+// of a span.
+func (sp *Span) UpdateGoroutineIDToCurrent() {
+	if sp.detectUseAfterFinish() {
+		return
+	}
+	sp.i.crdb.setGoroutineID(goid.Get())
+}
+
+// reset prepares sp for (re-)use.
+//
+// sp might be a re-allocated span that was previously used and Finish()ed. In
+// such cases, nobody should still be using a reference to the span - doing so
+// would be a use-after-Finish. The Tracer can be configured to do best-effort
+// detection of such cases (and crash), or it can be configured to tolerate
+// them. When tolerating them, in the face of buggy code, this method might be
+// called concurrently with the bugster accessing the span. This can result in
+// data races, and we don't make much of an effort to avoid them - some fields
+// in the span are not protected by a mutex; others are atomics but this method
+// doesn't always bother doing atomic operations on them. This method does take
+// the crdbSpan's lock, though. That will avoid some races.
+func (sp *Span) reset(
+	traceID tracingpb.TraceID,
+	spanID tracingpb.SpanID,
+	operation string,
+	goroutineID uint64,
+	startTime time.Time,
+	logTags *logtags.Buffer,
+	eventListeners []EventListener,
+	kind oteltrace.SpanKind,
+	otelSpan oteltrace.Span,
+	netTr trace.Trace,
+	sterile bool,
+) {
+	if sp.i.crdb == nil {
+		// We assume that spans being reset have come from the sync.Pool.
+		panic(errors.AssertionFailedf("unexpected reset of no-op Spans"))
+	}
+
+	if refCnt := sp.refCnt; refCnt != 0 {
+		// The span should not have been made available for reuse with live
+		// references.
+		panic(errors.AssertionFailedf("expected 0 refCnt but found %d: %s", refCnt, sp))
+	}
+
+	// Take a self-reference. This will be held until Finish(), ensuring that the
+	// reference count is not zero before Finish().
+	sp.incRef()
+	if detectSpanRefLeaks {
+		// Register a finalizer that, if not cleared by then, will panic at GC time
+		// indicating that some references to the span were leaked (or that the span
+		// wasn't Finish()ed, which is one way for the refCount to not reach zero).
+		// The finalizer will be cleared when the refCount reaches zero.
+		//
+		// Note that, in tests that use the TestCluster, there's also detection of
+		// non-finished spans through the active spans registry on cluster shutdown.
+		sp.setFinalizer(func(sp *Span) {
+			// If the Tracer that produced this Span was Close()d, then let's keep
+			// quiet. We've detected a Span leak nonetheless, but it's likely that the
+			// test that leaked the span has already finished. Panicking in the middle
+			// of an unrelated test would be poor UX.
+			if sp.i.Tracer().closed() {
+				return
+			}
+			panic(errors.AssertionFailedf("Span not finished or references not released; "+
+				"span: %s, finished: %t, refCnt: %d.\n"+
+				"If running multiple tests, it's possible that the leaked span came from a previous "+
+				"test. In particular, if a previous test failed, the failure might have caused some unclean "+
+				"unwind that leaked the span. If there are previous failures, consider ignoring this panic.",
+				sp, atomic.LoadInt32(&sp.finished) == 1, atomic.LoadInt32(&sp.refCnt)))
+		})
+	}
+
+	c := sp.i.crdb
+	if c == nil && otelSpan == nil && netTr == nil {
+		panic(errors.AssertionFailedf("must have at least one of crdbSpan, otelSpan, or netTr"))
+	}
+	sp.i = spanInner{
+		tracer:   sp.i.tracer,
+		crdb:     c,
+		otelSpan: otelSpan,
+		netTr:    netTr,
+		sterile:  sterile,
+	}
+
+	c.traceID = traceID
+	c.spanID = spanID
+	c.parentSpanID = 0
+	c.operation = operation
+	c.startTime = startTime
+	c.logTags = logTags
+	if len(c.eventListeners) != 0 {
+		panic(errors.AssertionFailedf("unexpected event listeners in span being reset: %v", c.eventListeners))
+	}
+	c.eventListeners = eventListeners
+	{
+		// Nobody is supposed to have a reference to the span at this point, but let's
+		// take the lock anyway to protect against buggy clients accessing the span
+		// after Finish().
+		func() {
+			c.mu.Lock()
+			defer c.mu.Unlock()
+			if len(c.mu.openChildren) != 0 {
+				panic(errors.AssertionFailedf("unexpected children in span being reset: %v", c.mu.openChildren))
+			}
+			if len(c.mu.tags) != 0 {
+				panic(errors.AssertionFailedf("unexpected tags in span being reset: %v", c.mu.tags))
+			}
+			if !c.mu.recording.finishedChildren.Empty() {
+				panic(errors.AssertionFailedf("unexpected finished children in span being reset: %v", c.mu.recording.finishedChildren))
+			}
+			if c.mu.recording.structured.Len() != 0 {
+				panic(errors.AssertionFailedf("unexpected structured recording in span being reset"))
+			}
+			if c.mu.recording.logs.Len() != 0 {
+				panic(errors.AssertionFailedf("unexpected logs in span being reset"))
+			}
+			h := sp.helper
+			c.mu.crdbSpanMu = crdbSpanMu{
+				duration:     -1, // unfinished
+				openChildren: h.childrenAlloc[:0],
+				goroutineID:  goroutineID,
+				recording: recordingState{
+					logs:             makeSizeLimitedBuffer[*tracingpb.LogRecord](maxLogBytesPerSpan, nil /* scratch */),
+					structured:       makeSizeLimitedBuffer[*tracingpb.StructuredRecord](maxStructuredBytesPerSpan, h.structuredEventsAlloc[:]),
+					childrenMetadata: h.childrenMetadataAlloc,
+					finishedChildren: MakeTrace(tracingpb.RecordedSpan{}),
+				},
+				tags: h.tagsAlloc[:0],
+			}
+
+			if kind != oteltrace.SpanKindUnspecified {
+				c.setTagLocked(SpanKindTagKey, attribute.StringValue(kind.String()))
+			}
+		}()
+	}
+
+	// We only mark the span as not finished at the end so that accesses to the
+	// span concurrent with this call are detected if the Tracer is configured to
+	// detect use-after-Finish. Similarly, we do the write atomically to prevent
+	// reorderings.
+	atomic.StoreInt32(&sp.finished, 0)
+	sp.finishStack = nil
+}
+
+// SetOtelStatus sets the status of the OpenTelemetry span (if any).
+func (sp *Span) SetOtelStatus(code codes.Code, msg string) {
+	if sp == nil || sp.i.otelSpan == nil {
+		return
+	}
+	sp.i.otelSpan.SetStatus(codes.Error, msg)
+}
+
+// spanRef represents a reference to a span. In addition to a simple *Span, a
+// spanRef prevents the referenced span from being reallocated in between the
+// time when this spanRef was created and the time when release() is called. It
+// does this by holding open a reference in the span's reference counter.
+type spanRef struct {
+	*Span
+}
+
+// makeSpanRef increments sp's reference counter and returns a spanRef which
+// will drop that reference on release().
+func makeSpanRef(sp *Span) spanRef {
+	sp.incRef()
+	return makeSpanRefRaw(sp)
+}
+
+// makeSpanRefRaw creates a spanRef for sp, but doesn't increment sp's reference
+// counter. The caller must increment the reference count separately.
+func makeSpanRefRaw(sp *Span) spanRef {
+	return spanRef{Span: sp}
+}
+
+// tryMakeSpanRef creates a spanRef for sp unless sp's reference count has
+// already reached zero (in which case sp might have been made available for
+// reuse). In case of failure, returns spanRef{}, false.
+//
+// tryMakeSpanRef avoids hazards otherwise made possible by spans being
+// Finish()ed and reused concurrently with this tryMakeSpanRef call. For
+// example, the WithParent(sp) option holds a reference to sp. We don't want
+// releasing sp to the sync.Pool for reuse to race with the creation of that
+// option in such a way that WithParent(sp) succeeds and also sp is made
+// available for reuse. That can lead to deadlock if, for example, sp ends up
+// being reallocated as its own child. If tryMakeSpanRef() succeeds, sp will not
+// be made available for reuse until this reference is release()ed.
+func tryMakeSpanRef(sp *Span) (spanRef, bool) {
+	// What comes is tricky. We want to guarantee that sp is not reused after this
+	// method returns. It can be re-used before this method is called, and it can
+	// be re-used during our loop below, but not after. More exactly, we want to
+	// "atomically" check whether sp is available for reuse and, if it isn't, make
+	// sure it doesn't become available for reuse until the would-be child is
+	// created (and beyond, for as long as the child holds a reference to the
+	// parent). We want to do this using atomics only; there's no locks to work
+	// with because the races we're concerned about are races with sp.decRef() and
+	// that method cannot take locks because it can run either under a parent's or
+	// a child's lock when operating on the parent's refCnt.
+	//
+	// The way we do it is through instituting the invariant that, once refCnt
+	// reaches 0, the only thing that increments it away from 0 is sp.reset(). In
+	// particular, WithParent(sp) does not make refCnt 0->1 transitions. This way,
+	// if a non-zero refCnt is found, then we know that the span is good to use
+	// and we can add our own reference. Once we've added our reference, this
+	// reference will keep the span good to use until we eventually release it. On
+	// the other hand, if we ever see a zero refCnt, then we can't use the span.
+
+	// Loop until we don't race on sp.refCnt.
+	for {
+		cnt := atomic.LoadInt32(&sp.refCnt)
+		if cnt == 0 {
+			// sp was Finish()ed, and it might be in the pool awaiting reallocation.
+			// It'd be unsafe to hold a reference to sp because of deadlock hazards,
+			// so we'll return an Empty option (i.e. the resulting child will be a
+			// root).
+			return spanRef{}, false
+		}
+		// Attempt to acquire a reference on sp, but only if we're not racing with anyone.
+		swapped := atomic.CompareAndSwapInt32(&sp.refCnt, cnt, cnt+1)
+		if swapped {
+			// We have a reference. The span can not be re-used while we hold the
+			// reference, so we're good to create the child.
+			break
+		} else {
+			// We raced with someone - possibly with a sp.decRef() that might have
+			// brought the refCnt to zero and made the span available for reuse. We
+			// need to restart to see if that was the case.
+			continue
+		}
+	}
+
+	ref := makeSpanRefRaw(sp)
+	return ref, true
+}
+
+func (sr *spanRef) empty() bool {
+	return sr.Span == nil
+}
+
+// release decrements the reference counter of the span that this spanRef refers
+// to. If the spanRef does not reference a span because move() has already been
+// called, or if release() has already been called, a release() call is a no-op.
+//
+// Note that release() is not thread-safe. When a spanRef is shared between
+// goroutines, the owner span is expected to serialize accesses through the
+// span's lock. Different `spanRefs` can reference the same span though, and
+// they can be used concurrently.
+//
+// Returns true if the span's refcount dropped to zero.
+func (sr *spanRef) release() bool {
+	if sr.empty() {
+		// There's no reference; nothing to do.
+		return false
+	}
+	sp := sr.Span
+	sr.Span = nil
+	return sp.decRef()
+}
+
+// move returns a new spanRef holding a reference to sr's span. sr's reference
+// is released.
+func (sr *spanRef) move() spanRef {
+	cpy := *sr
+	sr.Span = nil
+	return cpy
+}
+
+// SpanMeta is information about a Span that is not local to this
+// process. Typically, SpanMeta is populated from information
+// about a Span on the other end of an RPC, and is used to derive
+// a child span via `Tracer.StartSpan`. For local spans, SpanMeta
+// is not used, as the *Span directly can be derived from.
+//
+// SpanMeta contains the trace and span identifiers of the parent,
+// along with additional metadata. In particular, this specifies
+// whether the child should be recording, in which case the contract
+// is that the recording is to be returned to the caller when the
+// child finishes, so that the caller can inductively construct the
+// entire trace.
+type SpanMeta struct {
+	traceID tracingpb.TraceID
+	spanID  tracingpb.SpanID
+
+	// otelCtx is the OpenTelemetry span context. This is only populated when the
+	// remote Span is reporting to an external OpenTelemetry tracer. Setting this
+	// will cause child spans to also get an OpenTelemetry span.
+	otelCtx oteltrace.SpanContext
+
+	// If set, all spans derived from this context are being recorded.
+	recordingType tracingpb.RecordingType
+
+	// sterile is set if this span does not want to have children spans. In that
+	// case, trying to create a child span will result in the would-be child being
+	// a root span. This is useful for span corresponding to long-running
+	// operations that don't want to be associated with derived operations.
+	//
+	// Note that this field is unlike all the others in that it doesn't make it
+	// across the wire through a carrier. As can be seen in
+	// Tracer.InjectMetaInto(carrier), if sterile is set, then we don't propagate
+	// any info about the span in order to not have a child be created on the
+	// other side. Similarly, ExtractMetaFrom does not deserialize this field.
+	sterile bool
+}
+
+// Empty returns whether or not the SpanMeta is a zero value.
+func (sm SpanMeta) Empty() bool {
+	return sm.spanID == 0 && sm.traceID == 0
+}
+
+func (sm SpanMeta) String() string {
+	var s strings.Builder
+	s.WriteString(fmt.Sprintf("[spanID: %d, traceID: %d rec: %d", sm.spanID, sm.traceID, sm.recordingType))
+	hasOtelSpan := sm.otelCtx.IsValid()
+	if hasOtelSpan {
+		s.WriteString(" hasOtel")
+		s.WriteString(fmt.Sprintf(" trace: %d span: %d", sm.otelCtx.TraceID(), sm.otelCtx.SpanID()))
+	}
+	s.WriteRune(']')
+	return s.String()
+}
+
+// ToProto converts a SpanMeta to the *TraceInfo proto.
+func (sm SpanMeta) ToProto() *tracingpb.TraceInfo {
+	ti := &tracingpb.TraceInfo{
+		TraceID:       sm.traceID,
+		ParentSpanID:  sm.spanID,
+		RecordingMode: sm.recordingType.ToProto(),
+	}
+	if sm.otelCtx.HasTraceID() {
+		var traceID [16]byte = sm.otelCtx.TraceID()
+		var spanID [8]byte = sm.otelCtx.SpanID()
+		ti.Otel = &tracingpb.TraceInfo_OtelInfo{
+			TraceID: traceID[:],
+			SpanID:  spanID[:],
+		}
+	}
+	return ti
+}
+
+// SpanMetaFromProto converts a TraceInfo proto to SpanMeta.
+func SpanMetaFromProto(info tracingpb.TraceInfo) SpanMeta {
+	var otelCtx oteltrace.SpanContext
+	if info.Otel != nil {
+		traceID := [16]byte(info.Otel.TraceID)
+		spanID := [8]byte(info.Otel.SpanID)
+		otelCtx = otelCtx.WithRemote(true).WithTraceID(traceID).WithSpanID(spanID)
+	}
+
+	sm := SpanMeta{
+		traceID: info.TraceID,
+		spanID:  info.ParentSpanID,
+		otelCtx: otelCtx,
+		sterile: false,
+	}
+	switch info.RecordingMode {
+	case tracingpb.RecordingMode_OFF:
+		sm.recordingType = tracingpb.RecordingOff
+	case tracingpb.RecordingMode_STRUCTURED:
+		sm.recordingType = tracingpb.RecordingStructured
+	case tracingpb.RecordingMode_VERBOSE:
+		sm.recordingType = tracingpb.RecordingVerbose
+	default:
+		sm.recordingType = tracingpb.RecordingOff
+	}
+	return sm
+}
+
+// Structured is an opaque protobuf that can be attached to a trace via
+// `Span.RecordStructured`.
+type Structured interface {
+	protoutil.Message
+}
diff --git a/pkg/util/tracing/span_finalizer_race_off.go b/pkg/util/tracing/span_finalizer_race_off.go
new file mode 100644
index 0000000..1078119
--- /dev/null
+++ b/pkg/util/tracing/span_finalizer_race_off.go
@@ -0,0 +1,21 @@
+// Copyright 2022 The Cockroach Authors.
+//
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
+
+//go:build !race
+
+package tracing
+
+import "runtime"
+
+// setFinalizer registers a finalizer to run when the Span is garbage collected.
+// Passing nil clears any previously registered finalizer.
+func (sp *Span) setFinalizer(fn func(sp *Span)) {
+	if fn == nil {
+		// Avoid typed nil.
+		runtime.SetFinalizer(sp, nil)
+		return
+	}
+	runtime.SetFinalizer(sp, fn)
+}
diff --git a/pkg/util/tracing/span_finalizer_race_on.go b/pkg/util/tracing/span_finalizer_race_on.go
new file mode 100644
index 0000000..3ac78bd
--- /dev/null
+++ b/pkg/util/tracing/span_finalizer_race_on.go
@@ -0,0 +1,11 @@
+// Copyright 2022 The Cockroach Authors.
+//
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
+
+//go:build race
+
+package tracing
+
+// finalizers are expensive under race, so this is a no-op.
+func (sp *Span) setFinalizer(fn func(sp *Span)) {}
diff --git a/pkg/util/tracing/span_inner.go b/pkg/util/tracing/span_inner.go
new file mode 100644
index 0000000..9c8273f
--- /dev/null
+++ b/pkg/util/tracing/span_inner.go
@@ -0,0 +1,292 @@
+// Copyright 2021 The Cockroach Authors.
+//
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
+
+package tracing
+
+import (
+	"fmt"
+
+	"github.com/cockroachdb/cockroachdb-parser/pkg/util/timeutil"
+	"github.com/cockroachdb/cockroachdb-parser/pkg/util/tracing/tracingpb"
+	"github.com/cockroachdb/redact"
+	"go.opentelemetry.io/otel/attribute"
+	oteltrace "go.opentelemetry.io/otel/trace"
+	"golang.org/x/net/trace"
+)
+
+// spanInner contains all the span types we are recording to.
+// Note that one of crdb, otelSpan or netTr should be non-nil.
+type spanInner struct {
+	tracer *Tracer // never nil
+
+	// Internal trace Span; nil if not tracing to crdb.
+	// When not-nil, allocated together with the surrounding Span for
+	// performance.
+	crdb *crdbSpan
+	// x/net/trace.Trace instance; nil if not tracing to x/net/trace.
+	netTr trace.Trace
+	// otelSpan is the "shadow span" created for reporting to the OpenTelemetry
+	// tracer (if an otel tracer was configured).
+	otelSpan oteltrace.Span
+
+	// sterile is set if this span does not want to have children spans. In that
+	// case, trying to create a child span will result in the would-be child being
+	// a root span. This is useful for span corresponding to long-running
+	// operations that don't want to be associated with derived operations.
+	sterile bool
+}
+
+func (s *spanInner) TraceID() tracingpb.TraceID {
+	return s.crdb.TraceID()
+}
+
+func (s *spanInner) SpanID() tracingpb.SpanID {
+	return s.crdb.SpanID()
+}
+
+func (s *spanInner) isSterile() bool {
+	return s.sterile
+}
+
+func (s *spanInner) RecordingType() tracingpb.RecordingType {
+	return s.crdb.recordingType()
+}
+
+func (s *spanInner) SetRecordingType(to tracingpb.RecordingType) {
+	s.crdb.SetRecordingType(to)
+}
+
+// GetTraceRecording returns the span's recording as a Trace.
+//
+// See also GetRecording(), which returns it as a tracingpb.Recording.
+func (s *spanInner) GetTraceRecording(recType tracingpb.RecordingType, finishing bool) Trace {
+	return s.crdb.GetRecording(recType, finishing)
+}
+
+// GetFullTraceRecording returns the span's full recording, including detached
+// children, as a Trace. See GetTraceRecording and WithDetachedRecording.
+func (s *spanInner) GetFullTraceRecording(recType tracingpb.RecordingType) Trace {
+	return s.crdb.GetFullRecording(recType)
+}
+
+// GetRecording returns the span's recording.
+//
+// finishing indicates whether s is in the process of finishing. If it isn't,
+// the recording will include an "_unfinished" tag.
+func (s *spanInner) GetRecording(
+	recType tracingpb.RecordingType, finishing bool,
+) tracingpb.Recording {
+	trace := s.GetTraceRecording(recType, finishing)
+	return trace.ToRecording()
+}
+
+func (s *spanInner) ImportTrace(trace Trace) {
+	s.crdb.recordFinishedChildren(trace)
+}
+
+func treeifyRecording(rec tracingpb.Recording) Trace {
+	if len(rec) == 0 {
+		return Trace{}
+	}
+
+	byParent := make(map[tracingpb.SpanID][]*tracingpb.RecordedSpan)
+	for i := range rec {
+		s := &rec[i]
+		byParent[s.ParentSpanID] = append(byParent[s.ParentSpanID], s)
+	}
+	r := treeifyRecordingInner(rec[0], byParent)
+
+	// Include the orphans under the root.
+	orphans := rec.OrphanSpans()
+	traces := make([]Trace, len(orphans))
+	for i, sp := range orphans {
+		traces[i] = treeifyRecordingInner(sp, byParent)
+	}
+	r.addChildren(traces, 0 /* maxSpans */, 0 /* maxStructuredBytes */)
+	return r
+}
+
+func treeifyRecordingInner(
+	sp tracingpb.RecordedSpan, byParent map[tracingpb.SpanID][]*tracingpb.RecordedSpan,
+) Trace {
+	r := MakeTrace(sp)
+	children := make([]Trace, len(byParent[sp.SpanID]))
+	for i, s := range byParent[sp.SpanID] {
+		children[i] = treeifyRecordingInner(*s, byParent)
+	}
+	r.addChildren(children, 0 /* maxSpans */, 0 /* maxStructuredBytes */)
+	return r
+}
+
+func (s *spanInner) Finish() {
+	if s == nil {
+		return
+	}
+
+	if !s.crdb.finish() {
+		// Short-circuit because netTr.Finish does not tolerate double-finish.
+		return
+	}
+
+	if s.otelSpan != nil {
+		// Serialize the lazy tags.
+		s.crdb.mu.Lock()
+		defer s.crdb.mu.Unlock()
+		for _, lazyTagGroup := range s.crdb.getLazyTagGroupsLocked() {
+			for _, tag := range lazyTagGroup.Tags {
+				key := attribute.Key(tag.Key)
+				if lazyTagGroup.Name != tracingpb.AnonymousTagGroupName {
+					key = attribute.Key(fmt.Sprintf("%s-%s", lazyTagGroup.Name, tag.Key))
+				}
+				s.otelSpan.SetAttributes(attribute.KeyValue{
+					Key:   key,
+					Value: attribute.StringValue(tag.Value),
+				})
+			}
+		}
+
+		s.otelSpan.End()
+	}
+
+	if s.netTr != nil {
+		s.netTr.Finish()
+	}
+}
+
+func (s *spanInner) Meta() SpanMeta {
+	var traceID tracingpb.TraceID
+	var spanID tracingpb.SpanID
+	var recordingType tracingpb.RecordingType
+	var sterile bool
+
+	if s.crdb != nil {
+		traceID, spanID = s.crdb.traceID, s.crdb.spanID
+		recordingType = s.crdb.mu.recording.recordingType.load()
+		sterile = s.isSterile()
+	}
+
+	var otelCtx oteltrace.SpanContext
+	if s.otelSpan != nil {
+		otelCtx = s.otelSpan.SpanContext()
+	}
+
+	if traceID == 0 &&
+		spanID == 0 &&
+		!otelCtx.TraceID().IsValid() &&
+		recordingType == 0 &&
+		!sterile {
+		return SpanMeta{}
+	}
+	return SpanMeta{
+		traceID:       traceID,
+		spanID:        spanID,
+		otelCtx:       otelCtx,
+		recordingType: recordingType,
+		sterile:       sterile,
+	}
+}
+
+// OperationName returns the span's name. The name was specified at span
+// creation time.
+func (s *spanInner) OperationName() string {
+	return s.crdb.operation
+}
+
+func (s *spanInner) SetTag(key string, value attribute.Value) *spanInner {
+	if s.otelSpan != nil {
+		s.otelSpan.SetAttributes(attribute.KeyValue{
+			Key:   attribute.Key(key),
+			Value: value,
+		})
+	}
+	if s.netTr != nil {
+		s.netTr.LazyPrintf("%s:%v", key, value)
+	}
+	s.crdb.mu.Lock()
+	defer s.crdb.mu.Unlock()
+	s.crdb.setTagLocked(key, value)
+	return s
+}
+
+func (s *spanInner) SetLazyTag(key string, value interface{}) *spanInner {
+	s.crdb.mu.Lock()
+	defer s.crdb.mu.Unlock()
+	s.crdb.setLazyTagLocked(key, value)
+	return s
+}
+
+func (s *spanInner) setLazyTagLocked(key string, value interface{}) *spanInner {
+	s.crdb.setLazyTagLocked(key, value)
+	return s
+}
+
+// GetLazyTag returns the value of the tag with the given key. If that tag doesn't
+// exist, the bool retval is false.
+func (s *spanInner) GetLazyTag(key string) (interface{}, bool) {
+	s.crdb.mu.Lock()
+	defer s.crdb.mu.Unlock()
+	return s.crdb.getLazyTagLocked(key)
+}
+
+func (s *spanInner) RecordStructured(item Structured) {
+	s.crdb.recordStructured(item)
+	if s.hasVerboseSink() {
+		// Do not call .String() on the item, so that non-redactable bits
+		// in its representation are properly preserved by Recordf() in
+		// verbose recordings.
+		s.Recordf("%v", item)
+	}
+}
+
+func (s *spanInner) Record(msg string) {
+	s.Recordf("%s", msg)
+}
+
+func (s *spanInner) Recordf(format string, args ...interface{}) {
+	if !s.hasVerboseSink() {
+		return
+	}
+	var str redact.RedactableString
+	if s.Tracer().Redactable() {
+		str = redact.Sprintf(format, args...)
+	} else {
+		// `fmt.Sprintf` when called on a logEntry will use the faster
+		// `logEntry.String` method instead of `logEntry.SafeFormat`.
+		// The additional use of `redact.Sprint(...)` is necessary
+		// to wrap the result in redaction markers.
+		str = redact.Sprint(fmt.Sprintf(format, args...))
+	}
+	s.recordRedactable(format, args, str)
+}
+
+func (s *spanInner) recordRedactable(
+	format string, args []interface{}, str redact.RedactableString,
+) {
+	if s.otelSpan != nil {
+		// TODO(obs-inf): depending on the situation it may be more appropriate to
+		// redact the string here.
+		// See:
+		// https://github.com/cockroachdb/cockroachdb-parser/issues/58610#issuecomment-926093901
+		s.otelSpan.AddEvent(str.StripMarkers(), oteltrace.WithTimestamp(timeutil.Now()))
+	}
+	if s.netTr != nil {
+		s.netTr.LazyPrintf(format, args)
+	}
+	s.crdb.record(str)
+}
+
+// hasVerboseSink returns false if there is no reason to even evaluate Record
+// because the result wouldn't be used for anything.
+func (s *spanInner) hasVerboseSink() bool {
+	if s.netTr == nil && s.otelSpan == nil && s.RecordingType() != tracingpb.RecordingVerbose {
+		return false
+	}
+	return true
+}
+
+// Tracer exports the tracer this span was created using.
+func (s *spanInner) Tracer() *Tracer {
+	return s.tracer
+}
diff --git a/pkg/util/tracing/span_options.go b/pkg/util/tracing/span_options.go
new file mode 100644
index 0000000..6d498a3
--- /dev/null
+++ b/pkg/util/tracing/span_options.go
@@ -0,0 +1,496 @@
+// Copyright 2020 The Cockroach Authors.
+//
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
+
+package tracing
+
+import (
+	"github.com/cockroachdb/cockroachdb-parser/pkg/util/tracing/tracingpb"
+	"github.com/cockroachdb/errors"
+	"github.com/cockroachdb/logtags"
+	"go.opentelemetry.io/otel/attribute"
+	oteltrace "go.opentelemetry.io/otel/trace"
+)
+
+// spanReferenceType describes the relationship between a parent and a child
+// span. This is an OpenTracing concept that we've maintained back from when
+// CRDB was exporting traces to OpenTracing collectors. We no longer use
+// OpenTracing, and OpenTelemetry doesn't (yet?) have a perfectly analogous
+// concept.
+//
+// TODO(andrei): Follow
+// https://github.com/open-telemetry/opentelemetry-specification/issues/65 and
+// see how the OpenTelemetry concepts evolve.
+type spanReferenceType int
+
+const (
+	// childOfRef means that the parent span will wait for the child span's
+	// termination.
+	childOfRef spanReferenceType = iota
+	// followsFromRef means the child operation will run asynchronously with
+	// respect to the parent span.
+	followsFromRef
+)
+
+var followsFromAttribute = []attribute.KeyValue{attribute.String("follows-from", "")}
+
+// spanOptions are the options to `Tracer.StartSpan`. This struct is
+// typically not used directly. Instead, the methods mentioned on each
+// field comment below are invoked as arguments to `Tracer.StartSpan`.
+// See the SpanOption interface for a synopsis.
+type spanOptions struct {
+	// Parent, if set, indicates the parent span of the span being created with
+	// these spanOptions.
+	// If parent is set, its refCnt is assumed to have been incremented with the
+	// reference held here (see WithParent()). Thus, this `spanOptions` cannot be
+	// discarded; it must be used exactly once. StartSpan() will decrement refCnt.
+	Parent spanRef // see WithParent
+	// ParentDoesNotCollectRecording is set by WithDetachedRecording. It means
+	// that, although this span has a parent, the parent should generally not
+	// include this child's recording when the parent is asked for its own
+	// recording. Usually, a parent span includes all its children in its
+	// recording. However, sometimes that's not desired; sometimes the creator of
+	// a child span has a different plan for how the recording of that child will
+	// end up being collected and reported to where it ultimately needs to go.
+	// Still, even in these cases, a parent-child relationship is still useful
+	// (for example for the purposes of the active spans registry), so the child
+	// span cannot simply be created as a root.
+	//
+	// For example, in the case of DistSQL, each processor in a flow has its own
+	// span, as a child of the flow. The DistSQL infrastructure organizes the
+	// collection of each processor span recording independently, without relying
+	// on collecting the recording of the flow's span.
+	ParentDoesNotCollectRecording bool
+	RemoteParent                  SpanMeta               // see WithRemoteParentFromSpanMeta
+	RefType                       spanReferenceType      // see WithFollowsFrom
+	LogTags                       *logtags.Buffer        // see WithLogTags
+	Tags                          map[string]interface{} // see WithTags
+	ForceRealSpan                 bool                   // see WithForceRealSpan
+	SpanKind                      oteltrace.SpanKind     // see WithSpanKind
+	Sterile                       bool                   // see WithSterile
+	EventListeners                []EventListener        // see WithEventListeners
+
+	// recordingTypeExplicit is set if the WithRecording() option was used. In
+	// that case, spanOptions.recordingType() returns recordingTypeOpt below. If
+	// not set, recordingType() looks at the parent, subject to
+	// minRecordingTypeOpt.
+	recordingTypeExplicit bool
+	recordingTypeOpt      tracingpb.RecordingType
+	// minRecordingTypeOpt, if set, indicates the "minimum" recording type of
+	// this span (if it doesn't contradict recordingTypeOpt). If the parent has
+	// a more "verbose" recording type, than that type is used by
+	// recordingType().
+	minRecordingTypeOpt tracingpb.RecordingType
+}
+
+func (opts *spanOptions) parentTraceID() tracingpb.TraceID {
+	if !opts.Parent.empty() {
+		return opts.Parent.i.crdb.traceID
+	} else if !opts.RemoteParent.Empty() {
+		return opts.RemoteParent.traceID
+	}
+	return 0
+}
+
+func (opts *spanOptions) parentSpanID() tracingpb.SpanID {
+	if !opts.Parent.empty() {
+		return opts.Parent.i.crdb.spanID
+	} else if !opts.RemoteParent.Empty() {
+		return opts.RemoteParent.spanID
+	}
+	return 0
+}
+
+// recordingType computes the resulting recording type of the span
+// based on various settings. Please note that some of this logic is
+// partially duplicates in `Tracer.startSpanFast` which is used for
+// spans without a parent and avoids calling this method for
+// performance reasons. If you modify this method, make sure to modify
+// `startSpanFast` as well.
+func (opts *spanOptions) recordingType() tracingpb.RecordingType {
+	if opts.recordingTypeExplicit {
+		return opts.recordingTypeOpt
+	}
+
+	var recordingType tracingpb.RecordingType
+	if !opts.Parent.empty() {
+		recordingType = opts.Parent.i.crdb.recordingType()
+	} else if !opts.RemoteParent.Empty() {
+		recordingType = opts.RemoteParent.recordingType
+	}
+	if recordingType < opts.minRecordingTypeOpt {
+		recordingType = opts.minRecordingTypeOpt
+	}
+	return recordingType
+}
+
+// otelContext returns information about the OpenTelemetry parent span. If there
+// is a local parent with an otel Span, that Span is returned. If there is a
+// RemoteParent,  a SpanContext is returned. If there's no OpenTelemetry parent,
+// both return values will be Empty.
+func (opts *spanOptions) otelContext() (oteltrace.Span, oteltrace.SpanContext) {
+	if !opts.Parent.empty() && opts.Parent.i.otelSpan != nil {
+		return opts.Parent.i.otelSpan, oteltrace.SpanContext{}
+	}
+	if !opts.RemoteParent.Empty() && opts.RemoteParent.otelCtx.IsValid() {
+		return nil, opts.RemoteParent.otelCtx
+	}
+	return nil, oteltrace.SpanContext{}
+}
+
+// SpanOption is the interface satisfied by options to `Tracer.StartSpan`.
+// A synopsis of the options follows. For details, see their comments.
+//
+// - WithParent: create a child Span with a local parent.
+// - WithRemoteParentFromSpanMeta: create a child Span with a remote parent.
+// - WithFollowsFrom: hint that child may outlive parent.
+// - WithLogTags: populates the Span tags from a `logtags.Buffer`.
+// - WithCtxLogTags: like WithLogTags, but takes a `context.Context`.
+// - WithTags: adds tags to a Span on creation.
+// - WithForceRealSpan: prevents optimizations that can avoid creating a real span.
+// - WithDetachedRecording: don't include the recording in the parent.
+type SpanOption interface {
+	apply(spanOptions) spanOptions
+}
+
+type parentOption spanRef
+
+// WithParent instructs StartSpan to create a child Span from a (local) parent
+// Span.
+//
+// In case when the parent span is created with a different Tracer (generally,
+// when the parent lives in a different process), WithRemoteParentFromSpanMeta should be
+// used.
+//
+// WithParent will be a no-op (i.e. the span resulting from
+// applying this option will be a root span, just as if this option hadn't been
+// specified) in the following cases:
+//   - if `sp` is nil
+//   - if `sp` is a sterile span (i.e. a span explicitly marked as not wanting
+//     children).
+//
+// The child inherits the parent's log tags. The data collected in the
+// child trace will be retrieved automatically when the parent's data is
+// retrieved, meaning that the caller has no obligation (and in fact
+// must not) manually propagate the recording to the parent Span.
+//
+// The child will start recording if the parent is recording at the time
+// of child instantiation.
+//
+// By default, children are derived using a ChildOf relationship,
+// which corresponds to the expectation that the parent span will
+// wait for the child to Finish(). If this expectation does not hold,
+// WithFollowsFrom should be added to the StartSpan invocation.
+//
+// WithParent increments sp's reference count. As such, the resulting option
+// must be passed to StartSpan(opt). Once passed to StartSpan(opt), opt cannot
+// be reused. The child span will be responsible for ultimately doing the
+// decrement. The fact that WithParent takes a reference on sp is important to
+// avoid the possibility of deadlocks when buggy code uses a Span after Finish()
+// (which is illegal). See comments on Span.refCnt for details. By taking the
+// reference, it becomes safe (from a deadlock perspective) to call
+// WithParent(sp) concurrently with sp.Finish(). Note that calling
+// WithParent(sp) after sp was re-allocated cannot result in deadlocks
+// regardless of the reference counting.
+func WithParent(sp *Span) SpanOption {
+	if sp == nil {
+		return (parentOption)(spanRef{})
+	}
+
+	// Panic if the parent has already been finished, if configured to do so. If
+	// the parent has finished and we're configured not to panic, StartSpan() will
+	// deal with it when passed this WithParent option.
+	//
+	// Note that this check is best-effort (like all done() checks). More checking
+	// below.
+	_ = sp.detectUseAfterFinish()
+
+	// Sterile spans don't get children and its children will be a root span.
+	if sp.IsSterile() {
+		return (parentOption)(spanRef{})
+	}
+
+	ref, _ /* ok */ := tryMakeSpanRef(sp)
+	// Note that ref will be Empty if tryMakeSpanRef() failed. In that case, the
+	// resulting span will not have a parent.
+	return (parentOption)(ref)
+}
+
+func (p parentOption) apply(opts spanOptions) spanOptions {
+	opts.Parent = (spanRef)(p)
+	return opts
+}
+
+type remoteParent SpanMeta
+
+// WithRemoteParentFromSpanMeta instructs StartSpan to create a child span
+// descending from a parent described via a SpanMeta. Generally this parent span
+// lives in a different process.
+//
+// For the purposes of trace recordings, there's no mechanism ensuring that the
+// child's recording will be passed to the parent span. When that's desired, it
+// has to be done manually by calling Span.GetRecording() and propagating the
+// result to the parent by calling Span.ImportRemoteRecording().
+//
+// The canonical use case for this is around RPC boundaries, where a server
+// handling a request wants to create a child span descending from a parent on a
+// remote machine.
+//
+// node 1                         (network)          node 2
+// --------------------------------------------------------------------------
+// Span.Meta()                   ----------> sp2 := Tracer.StartSpan(WithRemoteParentFromSpanMeta(.))
+//
+//	doSomething(sp2)
+//
+// Span.ImportRemoteRecording(.) <---------- sp2.FinishAndGetRecording()
+//
+// By default, the child span is derived using a ChildOf relationship, which
+// corresponds to the expectation that the parent span will usually wait for the
+// child to Finish(). If this expectation does not hold, WithFollowsFrom should
+// be added to the StartSpan invocation.
+//
+// If you're in possession of a TraceInfo instead of a SpanMeta, prefer using
+// WithRemoteParentFromTraceInfo instead. If the TraceInfo is heap-allocated,
+// WithRemoteParentFromTraceInfo will not allocate (whereas
+// WithRemoteParentFromSpanMeta allocates).
+func WithRemoteParentFromSpanMeta(parent SpanMeta) SpanOption {
+	if parent.Empty() || parent.sterile {
+		return nil
+	}
+	return (remoteParent)(parent)
+}
+
+func (p remoteParent) apply(opts spanOptions) spanOptions {
+	opts.RemoteParent = (SpanMeta)(p)
+	return opts
+}
+
+type remoteParentFromLocalSpanOption spanRef
+
+func (r remoteParentFromLocalSpanOption) apply(opts spanOptions) spanOptions {
+	opts.RemoteParent = r.Meta()
+	sr := spanRef(r)
+	sr.release()
+	return opts
+}
+
+// WithRemoteParentFromLocalSpan is equivalent to
+// WithRemoteParentFromSpanMeta(sp.Meta()), but doesn't allocate. The span will
+// be created with parent info, but without being linked into the parent. This
+// is useful when the child needs to be created with a different Tracer than the
+// parent - e.g. when a tenant is calling into the local KV server.
+func WithRemoteParentFromLocalSpan(sp *Span) SpanOption {
+	ref, _ /* ok */ := tryMakeSpanRef(sp)
+	// Note that ref will be Empty if tryMakeSpanRef() failed. In that case, the
+	// resulting span will not have a parent.
+	return remoteParentFromLocalSpanOption(ref)
+}
+
+type remoteParentFromTraceInfoOpt tracingpb.TraceInfo
+
+var _ SpanOption = &remoteParentFromTraceInfoOpt{}
+
+// WithRemoteParentFromTraceInfo is like WithRemoteParentFromSpanMeta, except the remote
+// parent info is passed in as *TraceInfo. This is equivalent to
+// WithRemoteParentFromSpanMeta(SpanMetaFromProto(ti)), but more efficient because it
+// doesn't allocate.
+func WithRemoteParentFromTraceInfo(ti *tracingpb.TraceInfo) SpanOption {
+	return (*remoteParentFromTraceInfoOpt)(ti)
+}
+
+func (r *remoteParentFromTraceInfoOpt) apply(opts spanOptions) spanOptions {
+	opts.RemoteParent = SpanMetaFromProto(*(*tracingpb.TraceInfo)(r))
+	return opts
+}
+
+type detachedRecording struct{}
+
+var detachedRecordingSingleton = SpanOption(detachedRecording{})
+
+func (o detachedRecording) apply(opts spanOptions) spanOptions {
+	opts.ParentDoesNotCollectRecording = true
+	return opts
+}
+
+// WithDetachedRecording configures the span to not be included in the parent's
+// recording (if any) under most circumstances. Usually, a parent span includes
+// all its children in its recording. However, sometimes that's not desired;
+// sometimes the creator of a child span has a different plan for how the
+// recording of that child will end up being collected and reported to where it
+// ultimately needs to go. Still, even in these cases, a parent-child
+// relationship is still useful (for example for the purposes of the active
+// spans registry), so the child span cannot simply be created as a root.
+//
+// For example, in the case of DistSQL, each processor in a flow has its own
+// span, as a child of the flow. The DistSQL infrastructure organizes the
+// collection of each processor span recording independently, without relying
+// on collecting the recording of the flow's span.
+//
+// In the case when the parent's recording is collected through the span
+// registry, this option is ignore since, in that case, we want as much info as
+// possible.
+func WithDetachedRecording() SpanOption {
+	return detachedRecordingSingleton
+}
+
+type followsFromOpt struct{}
+
+var followsFromSingleton = SpanOption(followsFromOpt{})
+
+// WithFollowsFrom instructs StartSpan to link the child span to its parent
+// using a different kind of relationship than the regular parent-child one,
+// should a child span be created (i.e. should WithParent or
+// WithRemoteParentFromSpanMeta be supplied as well). This relationship was
+// called "follows-from" in the old OpenTracing API. This only matters if the
+// trace is sent to an OpenTelemetry tracer; CRDB itself ignores it (what
+// matters for CRDB is the WithDetachedTrace option).
+// OpenTelemetry does not have a concept of a follows-from relationship at the
+// moment; specifying this option results in the child having a Link to the
+// parent.
+// TODO(andrei): OpenTelemetry used to have a FollowsFrom relationship, but then
+// it was removed for the topic to be reconsidered more deeply. Let's keep an
+// eye on
+// https://github.com/open-telemetry/opentelemetry-specification/issues/65 and
+// see how the thinking evolves.
+//
+// A WithFollowsFrom child is expected to run asynchronously with respect to the
+// parent span (for example: asynchronous cleanup work), whereas a "regular"
+// child span is not (i.e. the parent span typically waits for the child to
+// Finish()).
+//
+// There is no penalty for getting this wrong, but it can help external trace
+// systems visualize the traces better.
+func WithFollowsFrom() SpanOption {
+	return followsFromSingleton
+}
+
+func (o followsFromOpt) apply(opts spanOptions) spanOptions {
+	opts.RefType = followsFromRef
+	return opts
+}
+
+type forceRealSpanOption struct{}
+
+var forceRealSpanSingleton = SpanOption(forceRealSpanOption{})
+
+// WithForceRealSpan forces StartSpan to create of a real Span regardless of the
+// Tracer's tracing mode.
+//
+// When tracing is disabled all spans are nil; these spans aren't
+// capable of recording, so this option should be passed to StartSpan if the
+// caller wants to be able to call SetVerbose(true) on the span later. If the
+// span should be recording from the beginning, use WithRecording() instead.
+func WithForceRealSpan() SpanOption {
+	return forceRealSpanSingleton
+}
+
+func (forceRealSpanOption) apply(opts spanOptions) spanOptions {
+	opts.ForceRealSpan = true
+	return opts
+}
+
+type recordingSpanOption struct {
+	recType tracingpb.RecordingType
+}
+
+var structuredRecordingSingleton = SpanOption(recordingSpanOption{recType: tracingpb.RecordingStructured})
+var verboseRecordingSingleton = SpanOption(recordingSpanOption{recType: tracingpb.RecordingVerbose})
+
+// WithRecording configures the span to record in the given mode.
+//
+// The recording mode can be changed later with SetVerbose().
+func WithRecording(recType tracingpb.RecordingType) SpanOption {
+	switch recType {
+	case tracingpb.RecordingStructured:
+		return structuredRecordingSingleton
+	case tracingpb.RecordingVerbose:
+		return verboseRecordingSingleton
+	case tracingpb.RecordingOff:
+		panic(errors.AssertionFailedf("invalid recording option: RecordingOff"))
+	default:
+		recCpy := recType // copy excaping to the heap
+		panic(errors.AssertionFailedf("invalid recording option: %d", recCpy))
+	}
+}
+
+func (o recordingSpanOption) apply(opts spanOptions) spanOptions {
+	opts.recordingTypeExplicit = true
+	opts.recordingTypeOpt = o.recType
+	return opts
+}
+
+// withSpanKindOption configures a span with a specific kind.
+type withSpanKindOption struct {
+	kind oteltrace.SpanKind
+}
+
+// WithSpanKind configures a span with an OpenTelemetry kind. This option only
+// matters if OpenTelemetry tracing is enabled; the CRDB tracer ignores it
+// otherwise.
+func WithSpanKind(kind oteltrace.SpanKind) SpanOption {
+	return withSpanKindOption{kind: kind}
+}
+
+func (w withSpanKindOption) apply(opts spanOptions) spanOptions {
+	opts.SpanKind = w.kind
+	return opts
+}
+
+// WithServerSpanKind is a shorthand for server spans, frequently saving
+// allocations.
+var WithServerSpanKind = WithSpanKind(oteltrace.SpanKindServer)
+
+// WithClientSpanKind is a shorthand for server spans, frequently saving
+// allocations.
+var WithClientSpanKind = WithSpanKind(oteltrace.SpanKindClient)
+
+type withSterileOption struct{}
+
+// WithSterile configures the span to not permit any child spans. The would-be
+// children of a sterile span end up being root spans.
+//
+// Since WithParent(<sterile span>) is a noop, it is allowed to create children
+// of sterile span with any Tracer. This is unlike children of any other spans,
+// which must be created with the same Tracer as the parent.
+func WithSterile() SpanOption {
+	return withSterileOption{}
+}
+
+func (w withSterileOption) apply(opts spanOptions) spanOptions {
+	opts.Sterile = true
+	return opts
+}
+
+type eventListenersOption []EventListener
+
+var _ SpanOption = eventListenersOption{}
+
+func (ev eventListenersOption) apply(opts spanOptions) spanOptions {
+	// Applying an EventListener span option implies the span has at least
+	// `RecordingStructured` recording type.
+	opts.minRecordingTypeOpt = tracingpb.RecordingStructured
+	eventListeners := ([]EventListener)(ev)
+	opts.EventListeners = eventListeners
+	return opts
+}
+
+// WithEventListeners registers eventListeners to the span. The listeners are
+// notified of Structured events recorded by the span and its children. Once the
+// span is finished, the listeners are not notified of events any more even from
+// surviving child spans.
+//
+// The listeners will also be notified of StructuredEvents recorded on remote
+// spans, when the remote recording is imported by the span or one of its
+// children. Note, the listeners will be notified of StructuredEvents in the
+// imported remote recording out of order.
+//
+// WithEventListeners implies a `RecordingStructured` recording type for the
+// span. If the recording type has been explicitly set to `RecordingVerbose` via
+// the `WithRecording(...) option, that will be respected instead.
+//
+// The caller should not mutate `eventListeners` after calling
+// WithEventListeners.
+func WithEventListeners(eventListeners ...EventListener) SpanOption {
+	return (eventListenersOption)(eventListeners)
+}
diff --git a/pkg/util/tracing/tags.go b/pkg/util/tracing/tags.go
new file mode 100644
index 0000000..2e00146
--- /dev/null
+++ b/pkg/util/tracing/tags.go
@@ -0,0 +1,55 @@
+// Copyright 2018 The Cockroach Authors.
+//
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
+
+package tracing
+
+import "github.com/cockroachdb/logtags"
+
+// LogTagsOption is a StartSpanOption that uses log tags to populate the Span tags.
+type logTagsOption logtags.Buffer
+
+var _ SpanOption = &logTagsOption{}
+
+func (lt *logTagsOption) apply(opts spanOptions) spanOptions {
+	opts.LogTags = (*logtags.Buffer)(lt)
+	return opts
+}
+
+// WithLogTags returns a SpanOption that sets the Span tags to the given log
+// tags. When applied, the returned option will apply any logtag name->Span tag
+// name remapping that has been registered via RegisterTagRemapping.
+//
+// Note that there is no need to use this option with StartSpanCtx, as that will
+// already propagate the log tags from the Context supplied to it to the Span.
+// However, if a WithLogTags option is supplied, it will be used and replaces
+// the Context-derived tags.
+func WithLogTags(tags *logtags.Buffer) SpanOption {
+	return (*logTagsOption)(tags)
+}
+
+// tagRemap is a map that records desired conversions
+var tagRemap = make(map[string]string)
+
+// RegisterTagRemapping sets the Span tag name that corresponds to the given log
+// tag name. Should be called as part of an init() function.
+func RegisterTagRemapping(logTag, spanTag string) {
+	tagRemap[logTag] = spanTag
+}
+
+// setLogTags calls the provided function for each tag pair from the provided log tags.
+// It takes into account any prior calls to RegisterTagRemapping.
+func setLogTags(logTags []logtags.Tag, setTag func(remappedKey string, value *logtags.Tag)) {
+	tagName := func(logTag string) string {
+		if v, ok := tagRemap[logTag]; ok {
+			return v
+		}
+		return logTag
+	}
+
+	for i := range logTags {
+		tag := &logTags[i]
+		setTag(tagName(tag.Key()), tag)
+	}
+}
diff --git a/pkg/util/tracing/test_utils.go b/pkg/util/tracing/test_utils.go
new file mode 100644
index 0000000..e023321
--- /dev/null
+++ b/pkg/util/tracing/test_utils.go
@@ -0,0 +1,254 @@
+// Copyright 2018 The Cockroach Authors.
+//
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
+
+package tracing
+
+import (
+	"fmt"
+	"regexp"
+	"sort"
+	"strings"
+	"time"
+
+	"github.com/cockroachdb/cockroachdb-parser/pkg/util/tracing/tracingpb"
+	"github.com/cockroachdb/errors"
+	"github.com/cockroachdb/redact"
+	"github.com/pmezard/go-difflib/difflib"
+)
+
+// FindMsgInRecording returns the index of the first Span containing msg in its
+// logs, or -1 if no Span is found.
+func FindMsgInRecording(recording tracingpb.Recording, msg string) int {
+	for i, sp := range recording {
+		if LogsContainMsg(sp, msg) {
+			return i
+		}
+	}
+	return -1
+}
+
+// LogsContainMsg returns true if a Span's logs contain the given message.
+func LogsContainMsg(sp tracingpb.RecordedSpan, msg string) bool {
+	for _, l := range sp.Logs {
+		if strings.Contains(l.Msg().StripMarkers(), msg) {
+			return true
+		}
+	}
+	return false
+}
+
+// CountLogMessages counts the messages containing msg.
+func CountLogMessages(sp tracingpb.RecordedSpan, msg string) int {
+	res := 0
+	for _, l := range sp.Logs {
+		if strings.Contains(l.Msg().StripMarkers(), msg) {
+			res++
+		}
+	}
+	return res
+}
+
+// CheckRecordedSpans checks whether a recording looks like an expected
+// one represented by a string with one line per expected span and one line per
+// expected event (i.e. log message), with a tab-indentation for child spans.
+//
+//	if err := CheckRecordedSpans(Span.GetRecording(), `
+//	    span: root
+//	        event: a
+//	        span: child
+//	            event: [ambient] b
+//	            event: c
+//	`); err != nil {
+//	  t.Fatal(err)
+//	}
+//
+// The event lines can (and generally should) omit the file:line part that they
+// might contain (depending on the level at which they were logged).
+//
+// Note: this test function is in this file because it needs to be used by
+// both tests in the tracing package and tests outside of it, and the function
+// itself depends on tracing.
+func CheckRecordedSpans(rec tracingpb.Recording, expected string) error {
+	normalize := func(rec string) string {
+		// normalize the string form of a recording for ease of comparison.
+		//
+		// 1. Strip out any leading new lines.
+		rec = strings.TrimLeft(rec, "\n")
+		// 2. Strip out trailing whitespace.
+		rec = strings.TrimRight(rec, "\n\t ")
+		// 3. Strip out file:line information from the recordings.
+		//
+		// 	 Before |  "event: util/log/trace_test.go:111 log"
+		// 	 After  |  "event: log"
+		re := regexp.MustCompile(`event: .*:[0-9]*`)
+		rec = string(re.ReplaceAll([]byte(rec), []byte("event:")))
+		// 4. Change all tabs to four spaces.
+		rec = strings.ReplaceAll(rec, "\t", "    ")
+		// 5. Compute the outermost indentation.
+		indent := strings.Repeat(" ", len(rec)-len(strings.TrimLeft(rec, " ")))
+		// 6. Outdent each line by that amount.
+		var lines []string
+		for _, line := range strings.Split(rec, "\n") {
+			lines = append(lines, strings.TrimPrefix(line, indent))
+		}
+		// 7. Stitch everything together.
+		return strings.Join(lines, "\n")
+	}
+
+	var rows []string
+	row := func(depth int, format string, args ...interface{}) {
+		rows = append(rows, strings.Repeat("    ", depth)+fmt.Sprintf(format, args...))
+	}
+
+	mapping := make(map[tracingpb.SpanID]tracingpb.SpanID) // spanID -> parentSpanID
+	for _, rs := range rec {
+		mapping[rs.SpanID] = rs.ParentSpanID
+	}
+	depth := func(spanID tracingpb.SpanID) int {
+		// Traverse up the parent links until one is not found.
+		curSpanID := spanID
+		d := 0
+		for {
+			var ok bool
+			curSpanID, ok = mapping[curSpanID]
+			if !ok {
+				break
+			}
+			d++
+		}
+		return d
+	}
+
+	for _, rs := range rec {
+		d := depth(rs.SpanID)
+		row(d, "span: %s", rs.Operation)
+		var tags []string
+		for _, tagGroup := range rs.TagGroups {
+			for _, tag := range tagGroup.Tags {
+				tags = append(tags, fmt.Sprintf("%s=%v", tag.Key, tag.Value))
+			}
+		}
+		if len(tags) > 0 {
+			sort.Strings(tags)
+			row(d, "    tags: %s", strings.Join(tags, " "))
+		}
+
+		for _, l := range rs.Logs {
+			row(d, "    event: %s", l.Msg().StripMarkers())
+		}
+	}
+
+	exp := normalize(expected)
+	got := normalize(strings.Join(rows, "\n"))
+	if got != exp {
+		diff := difflib.UnifiedDiff{
+			A:        difflib.SplitLines(exp),
+			FromFile: "exp",
+			B:        difflib.SplitLines(got),
+			ToFile:   "got",
+			Context:  4,
+		}
+		diffText, _ := difflib.GetUnifiedDiffString(diff)
+		return errors.Newf("unexpected diff:\n%s\n\nrecording:\n%s", diffText, rec.String())
+	}
+	return nil
+}
+
+// T is a subset of testing.TB.
+type T interface {
+	Fatalf(format string, args ...interface{})
+}
+
+// checkRecording checks whether a recording looks like the expected
+// one. The expected string is allowed to elide timing information, and the
+// outer-most indentation level is adjusted for when comparing.
+//
+//	checkRecording(t, sp.GetRecording(), `
+//	    === operation:root
+//	    [childrenMetadata]
+//	    event:root 1
+//	        === operation:remote child
+//	        event:remote child 1
+//	`)
+func checkRecording(t T, rec tracingpb.Recording, expected string) {
+	checkRecordingWithRedact(t, rec, expected, false)
+}
+
+func checkRecordingWithRedact(t T, rec tracingpb.Recording, expected string, redactValues bool) {
+	normalize := func(rec string) string {
+		// normalize the string form of a recording for ease of comparison.
+		//
+		// 1. Strip out any leading new lines.
+		rec = strings.TrimLeft(rec, "\n")
+		// 2. Strip out trailing newlines.
+		rec = strings.TrimRight(rec, "\n")
+		// 3. Strip out all timing information from the recordings.
+		//
+		// 	 Before |  "0.007ms      0.007ms    event:root 1"
+		// 	 After  |  "event:root 1"
+		re := regexp.MustCompile(`.*s.*s\s{4}`)
+		rec = string(re.ReplaceAll([]byte(rec), nil))
+		// 4. Strip out all the metadata from each ChildrenMetadata entry.
+		//
+		// 	 Before |  [operation: {Count:<count>, Duration:<duration>}]
+		// 	 After  |  [operation]
+		re = regexp.MustCompile(`: .*]`)
+		rec = string(re.ReplaceAll([]byte(rec), []byte("]")))
+		// 5. Change all tabs to four spaces.
+		rec = strings.ReplaceAll(rec, "\t", "    ")
+		// 6. Compute the outermost indentation.
+		indent := strings.Repeat(" ", len(rec)-len(strings.TrimLeft(rec, " ")))
+		// 7. Outdent each line by that amount.
+		var lines []string
+		for _, line := range strings.Split(rec, "\n") {
+			lines = append(lines, strings.TrimPrefix(line, indent))
+		}
+		// 8. Stitch everything together.
+		return strings.Join(lines, "\n")
+	}
+
+	sortChildrenMetadataByName := func(m map[string]tracingpb.OperationMetadata) {
+		// Sort the OperationMetadata of s' children alphabetically.
+		childrenMetadata := make([]tracingpb.OperationAndMetadata, 0, len(m))
+		for operation, metadata := range m {
+			childrenMetadata = append(childrenMetadata,
+				tracingpb.OperationAndMetadata{Operation: operation, Metadata: metadata})
+		}
+		sort.Slice(childrenMetadata, func(i, j int) bool {
+			return childrenMetadata[i].Operation < childrenMetadata[j].Operation
+		})
+
+		for i, cm := range childrenMetadata {
+			metadata := m[cm.Operation]
+			metadata.Duration = time.Duration(float64(i) * time.Second.Seconds())
+			m[cm.Operation] = metadata
+		}
+	}
+
+	// ChildrenMetadata are sorted in descending order of duration when returned.
+	// To ensure a stable sort in tests, we set the durations to sort in an
+	// alphabetical descending order.
+	for i := range rec {
+		sortChildrenMetadataByName(rec[i].ChildrenMetadata)
+	}
+
+	actual := redact.Sprint(rec)
+	if redactValues {
+		actual = actual.Redact()
+	}
+	exp := normalize(expected)
+	got := normalize(string(actual))
+	if got != exp {
+		diff := difflib.UnifiedDiff{
+			A:        difflib.SplitLines(exp),
+			FromFile: "exp",
+			B:        difflib.SplitLines(got),
+			ToFile:   "got",
+			Context:  4,
+		}
+		diffText, _ := difflib.GetUnifiedDiffString(diff)
+		t.Fatalf("unexpected diff:\n%s", redact.RedactableString(diffText))
+	}
+}
diff --git a/pkg/util/tracing/tracer.go b/pkg/util/tracing/tracer.go
new file mode 100644
index 0000000..daa59b3
--- /dev/null
+++ b/pkg/util/tracing/tracer.go
@@ -0,0 +1,1767 @@
+// Copyright 2015 The Cockroach Authors.
+//
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
+
+package tracing
+
+import (
+	"context"
+	"fmt"
+	"os"
+	"regexp"
+	"strconv"
+	"strings"
+	"sync"
+	"sync/atomic"
+	"time"
+	"unsafe"
+
+	"github.com/cockroachdb/cockroachdb-parser/pkg/settings"
+	"github.com/cockroachdb/cockroachdb-parser/pkg/util/buildutil"
+	"github.com/cockroachdb/cockroachdb-parser/pkg/util/debugutil"
+	"github.com/cockroachdb/cockroachdb-parser/pkg/util/envutil"
+	"github.com/cockroachdb/cockroachdb-parser/pkg/util/iterutil"
+	"github.com/cockroachdb/cockroachdb-parser/pkg/util/metamorphic"
+	"github.com/cockroachdb/cockroachdb-parser/pkg/util/netutil/addr"
+	"github.com/cockroachdb/cockroachdb-parser/pkg/util/randutil"
+	"github.com/cockroachdb/cockroachdb-parser/pkg/util/ring"
+	"github.com/cockroachdb/cockroachdb-parser/pkg/util/syncutil"
+	"github.com/cockroachdb/cockroachdb-parser/pkg/util/timeutil"
+	"github.com/cockroachdb/cockroachdb-parser/pkg/util/tracing/tracingpb"
+	"github.com/cockroachdb/errors"
+	"github.com/cockroachdb/logtags"
+	"github.com/petermattis/goid"
+	"go.opentelemetry.io/otel/attribute"
+	"go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc"
+	"go.opentelemetry.io/otel/exporters/zipkin"
+	"go.opentelemetry.io/otel/sdk/resource"
+	otelsdk "go.opentelemetry.io/otel/sdk/trace"
+	semconv "go.opentelemetry.io/otel/semconv/v1.4.0"
+	oteltrace "go.opentelemetry.io/otel/trace"
+	"golang.org/x/net/trace"
+	"google.golang.org/grpc/metadata"
+)
+
+const (
+
+	// maxRecordedSpansPerTrace limits the number of spans per recording, keeping
+	// recordings from getting too large.
+	maxRecordedSpansPerTrace = 1000
+	// maxRecordedBytesPerSpan limits the size of unstructured logs in a span.
+	maxLogBytesPerSpan = 256 * (1 << 10) // 256 KiB
+	// maxStructuredBytesPerSpan limits the size of structured logs in a span.
+	// This limit applies to records directly logged into the span; it does not
+	// apply to records in child span (including structured records copied from
+	// the child into the parent when the child is dropped because of the number
+	// of spans limit).
+	// See also maxStructuredBytesPerTrace.
+	maxStructuredBytesPerSpan = 10 * (1 << 10) // 10 KiB
+	// maxStructuredBytesPerTrace limits the total size of structured logs in a
+	// trace recording, across all spans. This limit is enforced at the time when
+	// a span is finished and its recording is copied to the parent, and at the
+	// time when an open span's recording is collected - which calls into all its
+	// open children. Thus, if there are multiple open spans that are part of the
+	// same trace, each one of them can temporarily have up to
+	// maxStructuredBytesPerTrace worth of messages under it. Each open span is
+	// also subject to the maxStructuredBytesPerSpan limit.
+	maxStructuredBytesPerTrace = 1 << 20 // 1 MiB
+
+	// maxSpanRegistrySize limits the number of local root spans tracked in
+	// a Tracer's registry.
+	maxSpanRegistrySize = 5000
+	// maxLogsPerSpanExternal limits the number of logs in a Span for external
+	// tracers (net/trace, OpenTelemetry); use a comfortable limit.
+	maxLogsPerSpanExternal = 1000
+	// maxSnapshots limits the number of snapshots that a Tracer will hold in
+	// memory. Beyond this limit, each new snapshot evicts the oldest one.
+	maxSnapshots          = 10
+	maxAutomaticSnapshots = 20 // TODO(dt): make this a setting
+)
+
+// These constants are used to form keys to represent tracing context
+// information in "carriers" to be transported across RPC boundaries.
+const (
+	prefixTracerState = "crdb-tracer-"
+
+	fieldNameTraceID = prefixTracerState + "traceid"
+	fieldNameSpanID  = prefixTracerState + "spanid"
+	// fieldNameRecordingType will contain the desired type of trace recording.
+	fieldNameRecordingType = "rec"
+
+	// fieldNameOtel{TraceID,SpanID} will contain the OpenTelemetry span info, hex
+	// encoded.
+	fieldNameOtelTraceID = prefixTracerState + "otel_traceid"
+	fieldNameOtelSpanID  = prefixTracerState + "otel_spanid"
+
+	SpanKindTagKey = "span.kind"
+)
+
+// TODO(davidh): Once performance issues around redaction are
+// resolved via #58610, this setting can be removed so that all traces
+// have redactability enabled.
+var enableTraceRedactable = settings.RegisterBoolSetting(
+	settings.ApplicationLevel,
+	"trace.redactable.enabled",
+	"set to true to enable finer-grainer redactability for unstructured events in traces",
+	true,
+)
+
+var enableNetTrace = settings.RegisterBoolSetting(
+	settings.ApplicationLevel,
+	"trace.debug.enable",
+	"if set, traces for recent requests can be seen at https://<ui>/debug/requests",
+	false,
+	settings.WithName("trace.debug_http_endpoint.enabled"),
+	settings.WithPublic)
+
+var openTelemetryCollector = settings.RegisterStringSetting(
+	settings.ApplicationLevel,
+	"trace.opentelemetry.collector",
+	"address of an OpenTelemetry trace collector to receive "+
+		"traces using the otel gRPC protocol, as <host>:<port>. "+
+		"If no port is specified, 4317 will be used.",
+	envutil.EnvOrDefaultString("COCKROACH_OTLP_COLLECTOR", ""),
+	settings.WithValidateString(func(_ *settings.Values, s string) error {
+		if s == "" {
+			return nil
+		}
+		_, _, err := addr.SplitHostPort(s, "4317")
+		return err
+	}),
+	settings.WithPublic,
+)
+
+// ZipkinCollector is the cluster setting that specifies the Zipkin instance
+// to send traces to, if any.
+var ZipkinCollector = settings.RegisterStringSetting(
+	settings.ApplicationLevel,
+	"trace.zipkin.collector",
+	"the address of a Zipkin instance to receive traces, as <host>:<port>. "+
+		"If no port is specified, 9411 will be used.",
+	envutil.EnvOrDefaultString("COCKROACH_ZIPKIN", ""),
+	settings.WithValidateString(func(_ *settings.Values, s string) error {
+		if s == "" {
+			return nil
+		}
+		_, _, err := addr.SplitHostPort(s, "9411")
+		return err
+	}),
+	settings.WithPublic,
+)
+
+var forceVerboseSpanRegexp = settings.RegisterStringSetting(
+	settings.ApplicationLevel,
+	"trace.span.force_verbose_regexp",
+	"a regular expression representing trace span operation names that should be "+
+		"forced into a verbose recording mode. If a span is created whose operation name matches "+
+		"the provided regular expression, the span and all of its children are forced into a verbose "+
+		"recording mode, meaning that the spans will capture all structured logs and events recorded "+
+		"during the lifetime of the span(s). NOTE: the verbose recording mode is known to cause non-trivial "+
+		"amounts of overhead. Using this setting could have a negative impact on cluster latency.",
+	"", /*defaultValue*/
+	settings.WithValidateString(func(_ *settings.Values, s string) error {
+		if s == "" {
+			return nil
+		}
+		_, err := regexp.Compile(s)
+		return err
+	}),
+	settings.WithVisibility(settings.Reserved),
+)
+
+// EnableActiveSpansRegistry controls Tracers configured as
+// WithTracingMode(TracingModeFromEnv) (which is the default). When enabled,
+// spans are allocated and registered with the active spans registry until
+// finished. When disabled, span creation is short-circuited for a small
+// performance improvement.
+var EnableActiveSpansRegistry = settings.RegisterBoolSetting(
+	settings.ApplicationLevel,
+	"trace.span_registry.enabled",
+	"if set, ongoing traces can be seen at https://<ui>/#/debug/tracez",
+	envutil.EnvOrDefaultBool("COCKROACH_REAL_SPANS", false),
+	settings.WithPublic)
+
+var periodicSnapshotInterval = settings.RegisterDurationSetting(
+	settings.ApplicationLevel,
+	"trace.snapshot.rate",
+	"if non-zero, interval at which background trace snapshots are captured",
+	0,
+	settings.NonNegativeDuration,
+	settings.WithPublic)
+
+// panicOnUseAfterFinish, if set, causes use of a span after Finish() to panic
+// if detected.
+var panicOnUseAfterFinish = buildutil.CrdbTestBuild ||
+	envutil.EnvOrDefaultBool("COCKROACH_CRASH_ON_SPAN_USE_AFTER_FINISH", false)
+
+// debugUseAfterFinish controls whether to debug uses of Span values after finishing.
+// FOR DEBUGGING ONLY. This will slow down the program.
+var debugUseAfterFinish = envutil.EnvOrDefaultBool("COCKROACH_DEBUG_SPAN_USE_AFTER_FINISH", false)
+
+// reuseSpans controls whether spans can be re-allocated after they've been
+// Finish()ed. See Tracer.spanReusePercent for details.
+//
+// Span reuse is incompatible with the deadlock detector because, with reuse,
+// the span mutexes end up being reused and locked repeatedly in random order on
+// the same goroutine. This erroneously looks like a potential deadlock to the
+// detector.
+var reuseSpans = !syncutil.DeadlockEnabled && envutil.EnvOrDefaultBool("COCKROACH_REUSE_TRACING_SPANS", true)
+
+// detectSpanRefLeaks enables the detection of Span reference leaks - i.e.
+// failures to decrement a Span's reference count. If detection is enabled, such
+// bugs will cause crashes. Otherwise, such bugs silently prevent reallocations
+// of spans, at a memory cost.
+//
+// The detection mechanism uses runtime finalizers; they're disabled under race
+// builds elsewhere.
+var detectSpanRefLeaks = buildutil.CrdbTestBuild
+
+// TracingMode specifies whether span creation is enabled or disabled by
+// default, when other conditions that don't explicitly turn tracing on don't
+// apply.
+type TracingMode int
+
+const (
+	// TracingModeFromEnv configures tracing according to enableTracingByDefault.
+	TracingModeFromEnv TracingMode = iota
+	// TracingModeOnDemand means that Spans will no be created unless there's a
+	// particular reason to create them (i.e. a span being created with
+	// WithForceRealSpan(), a net.Trace or OpenTelemetry tracers attached).
+	TracingModeOnDemand
+	// TracingModeActiveSpansRegistry means that Spans are always created.
+	// Currently-open spans are accessible through the active spans registry.
+	//
+	// If no net.Trace/OpenTelemetry tracer is attached, spans do not record
+	// events by default (i.e. do not accumulate log messages via Span.Record() or
+	// a history of finished child spans). In order for a span to record events,
+	// it must be started with the WithRecording() option).
+	TracingModeActiveSpansRegistry
+)
+
+// SpanReusePercentOpt is the option produced by WithSpanReusePercent(),
+// configuring the Tracer's span reuse policy.
+type SpanReusePercentOpt uint
+
+var _ TracerOption = SpanReusePercentOpt(0)
+
+// WithSpanReusePercent configures the Tracer span reuse ratio, overriding the
+// environmental default.
+func WithSpanReusePercent(percent uint32) TracerOption {
+	if percent > 100 {
+		panic(errors.AssertionFailedf("invalid percent: %d", percent))
+	}
+	return SpanReusePercentOpt(percent)
+}
+
+func (s SpanReusePercentOpt) apply(opt *tracerOptions) {
+	val := uint32(s)
+	opt.spanReusePercent = &val
+}
+
+// spanReusePercent controls the span reuse probability for Tracers that are not
+// explicitly configured with a reuse probability. Tests vary this away from the
+// default of 100% in order to make the use-after-Finish detection reliable (see
+// panicOnUseAfterFinish).
+var spanReusePercent = metamorphic.ConstantWithTestRange(
+	"span-reuse-rate",
+	100, /* defaultValue - always reuse spans. This turns to 0 if reuseSpans is not set. */
+	0,   /* metamorphic min */
+	101, /* metamorphic max */
+)
+
+// Tracer implements tracing requests. It supports:
+//
+//   - forwarding events to x/net/trace instances
+//
+//   - recording traces. Recorded events can be retrieved at any time.
+//
+//   - OpenTelemetry tracing. This is implemented by maintaining a "shadow"
+//     OpenTelemetry Span inside each of our spans.
+//
+// Even when tracing is disabled, we still use this Tracer (with x/net/trace and
+// lightstep disabled) because of its recording capability (verbose tracing needs
+// to work in all cases).
+//
+// Tracer is currently stateless so we could have a single instance; however,
+// this won't be the case if the cluster settings move away from using global
+// state.
+type Tracer struct {
+	// True if tracing to the debug/requests endpoint. Accessed via t.useNetTrace().
+	_useNetTrace int32 // updated atomically
+
+	// True if we would like spans created from this tracer to be marked
+	// as redactable. This will make unstructured events logged to those
+	// spans redactable.
+	// Currently, this is used to mark spans as redactable and to redact
+	// them at the network boundary from KV.
+	_redactable int32 // accessed atomically
+
+	// Pointer to an OpenTelemetry tracer used as a "shadow tracer", if any. If
+	// not nil, the respective *otel.Tracer will be used to create mirror spans
+	// for all spans that the parent Tracer creates.
+	otelTracer unsafe.Pointer
+
+	// _activeSpansRegistryEnabled controls whether spans are created and
+	// registered with activeSpansRegistry until they're Finish()ed. If not
+	// enabled, span creation is generally a no-op unless a recording span is
+	// explicitly requested.
+	_activeSpansRegistryEnabled int32 // accessed atomically
+
+	opNameRegexp atomic.Pointer[regexp.Regexp]
+
+	// activeSpans is a map that references all non-Finish'ed local root spans,
+	// i.e. those for which no WithParent(<non-nil>) option was supplied.
+	activeSpansRegistry *SpanRegistry
+	snapshotsMu         struct {
+		syncutil.Mutex
+		// snapshots stores the activeSpansRegistry snapshots taken during the
+		// Tracer's lifetime. The ring buffer will contain snapshots with contiguous
+		// IDs, from the oldest one to <oldest id> + maxSnapshots - 1.
+		snapshots     ring.Buffer[snapshotWithID]
+		autoSnapshots ring.Buffer[snapshotWithID]
+	}
+
+	testingMu               syncutil.Mutex // protects testingRecordAsyncSpans
+	testingRecordAsyncSpans bool           // see TestingRecordAsyncSpans
+
+	// panicOnUseAfterFinish configures the Tracer to crash when a Span is used
+	// after it was previously Finish()ed. Crashing is best-effort if reuseSpan is
+	// set - use-after-Finish detection doesn't work across span re-allocations.
+	panicOnUseAfterFinish bool
+	// debugUseAfterFinish configures the Tracer to collect expensive extra info
+	// to help debug use-after-Finish() bugs - stack traces will be collected and
+	// stored on every Span.Finish().
+	debugUseAfterFinish bool
+
+	// spanReusePercent controls the probability that a Finish()ed Span is made
+	// available for reuse. A value of 100 configures the Tracer to always reuse
+	// spans; a value of 0 configures it to not reuse any spans. Values in between
+	// will cause spans to be reused randomly.
+	//
+	// Span reuse works by pooling finished spans in a sync.Pool and re-allocate
+	// them in order to avoid large dynamic memory allocations. When reusing
+	// spans, buggy code that uses previously-finished spans can result in trace
+	// corruption, if the span in question has been reallocated by the time it's
+	// erroneously used.
+	//
+	// Span reuse saves dynamic memory allocations for span creation. Creating a
+	// span generally still needs to allocate the Context that the span is
+	// associated with; contexts cannot be reused because they are immutable and
+	// don't have a clear lifetime. Before span reuse was introduced, we had a way
+	// to allocate a Span and its Context at once. Compared to that, span reuse
+	// doesn't save on the absolute number of allocations, but saves on the size
+	// of these allocations: spans are large and contexts are small. This amounts
+	// to savings of around 10KB worth of heap for simple queries.
+	//
+	// When a span is reused, use-after-Finish detection (as configured by
+	// panicOnUseAfterFinish) becomes unreliable. That's why tests metamorphically
+	// set this to less than 100.
+	spanReusePercent uint32
+	// spanPool holds spanAllocHelper's. If reuseSpans is set, spans are
+	// allocated through this pool to reduce dynamic memory allocations.
+	spanPool sync.Pool
+	// spansCreated/spansAllocated counts how many spans have been created and how
+	// many have been allocated (i.e. not reused through the spanPool) since the
+	// last time TestingGetStatsAndReset() was called. These counters are only
+	// incremented if the MaintainAllocationCounters testing knob was set.
+	spansCreated, spansAllocated int32 // atomics
+
+	testing TracerTestingKnobs
+
+	// stack is populated in NewTracer and is printed in assertions related to
+	// mixing tracers.
+	stack debugutil.SafeStack
+	// closed is set on Close().
+	_closed int32 // accessed atomically
+}
+
+// SpanRegistry is a map that references all non-Finish'ed local root spans,
+// i.e. those for which no WithLocalParent(<non-nil>) option was supplied. The
+// map is keyed on the span ID, which is deterministically unique.
+//
+// In normal operation, a local root crdbSpan is inserted on creation and
+// removed on .Finish().
+//
+// The map can be introspected by `Tracer.VisitSpans`. A Span can also be
+// retrieved from its ID by `Tracer.GetActiveSpanByID`.
+type SpanRegistry struct {
+	mu struct {
+		syncutil.Mutex
+		// m stores all the currently open spans. Note that a span being present
+		// here proves that the corresponding Span.Finish() call has not yet
+		// completed (but crdbSpan.Finish() might have finished), therefor the span
+		// cannot be reused while present in the registry. At the same time, note
+		// that Span.Finish() can be called on these spans so, when using one of
+		// these spans, we need to be prepared for that use to be concurrent with
+		// the Finish() call.
+		m map[tracingpb.SpanID]*crdbSpan
+	}
+}
+
+func makeSpanRegistry() *SpanRegistry {
+	r := &SpanRegistry{}
+	r.mu.m = make(map[tracingpb.SpanID]*crdbSpan)
+	return r
+}
+
+func (r *SpanRegistry) removeSpanLocked(id tracingpb.SpanID) {
+	delete(r.mu.m, id)
+}
+
+func (r *SpanRegistry) addSpan(s *crdbSpan) {
+	r.mu.Lock()
+	defer r.mu.Unlock()
+	r.addSpanLocked(s)
+}
+
+func (r *SpanRegistry) addSpanLocked(s *crdbSpan) {
+	// Ensure that the registry does not grow unboundedly in case there is a leak.
+	// When the registry reaches max size, each new span added kicks out an
+	// arbitrary existing span. We rely on map iteration order here to make this
+	// cheap.
+	if len(r.mu.m) == maxSpanRegistrySize {
+		for k := range r.mu.m {
+			delete(r.mu.m, k)
+			break
+		}
+	}
+	r.mu.m[s.spanID] = s
+}
+
+// getSpanByID looks up a span in the registry. Returns nil if not found.
+func (r *SpanRegistry) getSpanByID(id tracingpb.SpanID) RegistrySpan {
+	r.mu.Lock()
+	defer r.mu.Unlock()
+	crdbSpan, ok := r.mu.m[id]
+	if !ok {
+		// Avoid returning a typed nil pointer.
+		return nil
+	}
+	return crdbSpan
+}
+
+// VisitRoots calls the visitor callback for every local root span in the
+// registry. Iterations stops when the visitor returns an error. If that error
+// is iterutils.StopIteration(), then VisitRoots() returns nil.
+//
+// The callback should not hold on to the span after it returns.
+func (r *SpanRegistry) VisitRoots(visitor func(span RegistrySpan) error) error {
+	// Take a snapshot of the registry and release the lock.
+	spans := r.getSpanRefs()
+
+	// Keep the spans alive while visting them below.
+	defer func() {
+		for i := range spans {
+			spans[i].release()
+		}
+	}()
+
+	for _, sp := range spans {
+		if err := visitor(sp.Span.i.crdb); err != nil {
+			return iterutil.Map(err)
+		}
+	}
+	return nil
+}
+
+// visitTrace recursively calls the visitor on sp and all its descendants.
+func visitTrace(sp *crdbSpan, visitor func(sp RegistrySpan)) {
+	visitor(sp)
+	sp.visitOpenChildren(func(child *crdbSpan) {
+		visitTrace(child, visitor)
+	})
+}
+
+// VisitSpans calls the visitor callback for every span in the
+// registry.
+//
+// The callback should not hold on to the span after it returns.
+func (r *SpanRegistry) VisitSpans(visitor func(span RegistrySpan)) {
+	// Take a snapshot of the registry and release the lock.
+	spans := r.getSpanRefs()
+
+	// Keep the spans alive while visting them below.
+	defer func() {
+		for i := range spans {
+			spans[i].release()
+		}
+	}()
+
+	for _, sp := range spans {
+		visitTrace(sp.Span.i.crdb, visitor)
+	}
+}
+
+// getSpanRefs collects references to all spans in the SpanRegistry map and
+// returns a slice of them.
+func (r *SpanRegistry) getSpanRefs() []spanRef {
+	r.mu.Lock()
+	defer r.mu.Unlock()
+	spans := make([]spanRef, 0, len(r.mu.m))
+	for _, sp := range r.mu.m {
+		spans = append(spans, makeSpanRef(sp.sp))
+	}
+	return spans
+}
+
+// testingAll returns (pointers to) all the spans in the registry, in an
+// arbitrary order. Since spans can generally finish at any point and use of a
+// finished span is not permitted, this method is only suitable for tests.
+func (r *SpanRegistry) testingAll() []*crdbSpan {
+	r.mu.Lock()
+	defer r.mu.Unlock()
+	res := make([]*crdbSpan, 0, len(r.mu.m))
+	for _, sp := range r.mu.m {
+		res = append(res, sp)
+	}
+	return res
+}
+
+// swap atomically swaps a span with its children. This is called when a parent
+// finishes for promoting its (still open) children into the registry. Before
+// removing the parent from the registry, the children are accessible in the
+// registry through that parent; if we didn't do this swap when the parent is
+// removed, the children would not be part of the registry anymore.
+//
+// The children are passed as spanRef's, so they're not going to be reallocated
+// concurrently with this call. swap takes ownership of the spanRefs, and will
+// release() them.
+func (r *SpanRegistry) swap(parentID tracingpb.SpanID, children []spanRef) {
+	func() {
+		r.mu.Lock()
+		defer r.mu.Unlock()
+		r.removeSpanLocked(parentID)
+		for _, c := range children {
+			sp := c.Span.i.crdb
+			sp.withLock(func() {
+				if !sp.mu.finished {
+					r.addSpanLocked(sp)
+				}
+			})
+		}
+	}()
+	for _, c := range children {
+		c.release()
+	}
+}
+
+// TracerTestingKnobs contains knobs for a Tracer.
+type TracerTestingKnobs struct {
+	// Clock allows the time source for spans to be controlled.
+	Clock timeutil.TimeSource
+	// UseNetTrace, if set, forces the Traces to always create spans which record
+	// to net.Trace objects.
+	UseNetTrace bool
+	// MaintainAllocationCounters, if set,  configures the Tracer to maintain
+	// counters about span creation. See Tracer.GetStatsAndReset().
+	MaintainAllocationCounters bool
+	// ReleaseSpanToPool, if set, if called just before a span is put in the
+	// sync.Pool for reuse. If the hook returns false, the span will not be put in
+	// the pool.
+	ReleaseSpanToPool func(*Span) bool
+}
+
+// Redactable returns true if the tracer is configured to emit
+// redactable logs. This value will affect the redactability of messages
+// from already open Spans.
+func (t *Tracer) Redactable() bool {
+	return atomic.LoadInt32(&t._redactable) != 0
+}
+
+// SetRedactable changes the redactability of the Tracer. This
+// affects any future trace spans created.
+func (t *Tracer) SetRedactable(to bool) {
+	var n int32
+	if to {
+		n = 1
+	}
+	atomic.StoreInt32(&t._redactable, n)
+}
+
+// SetActiveSpansRegistryEnabled controls whether spans are created and
+// registered with activeSpansRegistry.
+func (t *Tracer) SetActiveSpansRegistryEnabled(to bool) {
+	var n int32
+	if to {
+		n = 1
+	}
+	atomic.StoreInt32(&t._activeSpansRegistryEnabled, n)
+}
+
+// ActiveSpansRegistryEnabled returns true if this tracer is configured
+// to register spans with the activeSpansRegistry
+func (t *Tracer) ActiveSpansRegistryEnabled() bool {
+	return atomic.LoadInt32(&t._activeSpansRegistryEnabled) != 0
+}
+
+// NewTracer creates a Tracer with default options.
+//
+// See NewTracerWithOpt() for controlling various configuration options.
+func NewTracer() *Tracer {
+	var defaultSpanReusePercent uint32
+	if reuseSpans {
+		defaultSpanReusePercent = uint32(spanReusePercent)
+	} else {
+		defaultSpanReusePercent = 0
+	}
+
+	t := &Tracer{
+		stack:               debugutil.Stack(),
+		activeSpansRegistry: makeSpanRegistry(),
+		// These might be overridden in NewTracerWithOpt.
+		panicOnUseAfterFinish: panicOnUseAfterFinish,
+		debugUseAfterFinish:   debugUseAfterFinish,
+		spanReusePercent:      defaultSpanReusePercent,
+	}
+	t.SetActiveSpansRegistryEnabled(true)
+
+	t.spanPool = sync.Pool{
+		New: func() interface{} {
+			if t.testing.MaintainAllocationCounters {
+				atomic.AddInt32(&t.spansAllocated, 1)
+			}
+			h := new(spanAllocHelper)
+			// Read-only span fields are assigned here. The rest are initialized in Span.reset().
+			h.span.helper = h
+			sp := &h.span
+			sp.i.tracer = t
+			c := &h.crdbSpan
+			*c = crdbSpan{
+				tracer: t,
+				sp:     sp,
+			}
+			sp.i.crdb = c
+			h.childrenMetadataAlloc = make(map[string]tracingpb.OperationMetadata)
+			return h
+		},
+	}
+	return t
+}
+
+// NewTracerWithOpt creates a Tracer and configures it according to the
+// passed-in options.
+func NewTracerWithOpt(ctx context.Context, opts ...TracerOption) *Tracer {
+	var o tracerOptions
+	for _, opt := range opts {
+		opt.apply(&o)
+	}
+	t := NewTracer()
+	if o.useAfterFinishOpt != nil {
+		t.panicOnUseAfterFinish = o.useAfterFinishOpt.panicOnUseAfterFinish
+		t.debugUseAfterFinish = o.useAfterFinishOpt.debugUseAfterFinish
+	}
+	if o.spanReusePercent != nil {
+		t.spanReusePercent = *o.spanReusePercent
+	}
+	t.testing = o.knobs
+	t.SetActiveSpansRegistryEnabled(o.tracingDefault == TracingModeActiveSpansRegistry)
+	if o.sv != nil {
+		t.configure(ctx, o.sv, o.tracingDefault)
+		forceVerboseSpanRegexp.SetOnChange(o.sv, func(ctx context.Context) {
+			if err := t.setVerboseOpNameRegexp(forceVerboseSpanRegexp.Get(o.sv)); err != nil {
+				fmt.Fprintf(os.Stderr, "error compiling verbose span operation name regexp: %s\n", err)
+			}
+		})
+	}
+	return t
+}
+
+// tracerOptions groups configuration for Tracer construction.
+type tracerOptions struct {
+	sv                *settings.Values
+	knobs             TracerTestingKnobs
+	tracingDefault    TracingMode
+	useAfterFinishOpt *useAfterFinishOpt
+	// spanReusePercent, if not nil, controls the probability of span reuse. A
+	// negative value indicates that the default should come from the environment.
+	// If nil, the probability comes from the environment (test vs production).
+	spanReusePercent *uint32
+}
+
+// TracerOption is implemented by the arguments to the Tracer constructor.
+type TracerOption interface {
+	apply(opt *tracerOptions)
+}
+
+type clusterSettingsOpt struct {
+	sv *settings.Values
+}
+
+func (o clusterSettingsOpt) apply(opt *tracerOptions) {
+	opt.sv = o.sv
+}
+
+var _ TracerOption = clusterSettingsOpt{}
+
+// WithClusterSettings configures the Tracer according to the relevant cluster
+// settings. Future changes to those cluster settings will update the Tracer.
+func WithClusterSettings(sv *settings.Values) TracerOption {
+	return clusterSettingsOpt{sv: sv}
+}
+
+type knobsOpt struct {
+	knobs TracerTestingKnobs
+}
+
+func (o knobsOpt) apply(opt *tracerOptions) {
+	opt.knobs = o.knobs
+}
+
+var _ TracerOption = knobsOpt{}
+
+// WithTestingKnobs configures the Tracer with the specified knobs.
+func WithTestingKnobs(knobs TracerTestingKnobs) TracerOption {
+	return knobsOpt{knobs: knobs}
+}
+
+type tracingModeOpt TracingMode
+
+var _ TracerOption = tracingModeOpt(TracingModeFromEnv)
+
+func (o tracingModeOpt) apply(opt *tracerOptions) {
+	opt.tracingDefault = TracingMode(o)
+}
+
+// WithTracingMode configures the Tracer's tracing mode.
+func WithTracingMode(opt TracingMode) TracerOption {
+	return tracingModeOpt(opt)
+}
+
+type useAfterFinishOpt struct {
+	panicOnUseAfterFinish bool
+	debugUseAfterFinish   bool
+}
+
+var _ TracerOption = useAfterFinishOpt{}
+
+func (o useAfterFinishOpt) apply(opt *tracerOptions) {
+	opt.useAfterFinishOpt = &o
+}
+
+// WithUseAfterFinishOpt allows control over the Tracer's behavior when a Span
+// is used after it had been Finish()ed.
+//
+// panicOnUseAfterFinish configures the Tracer to panic when it detects that any
+// method on a Span is called after that Span was Finish()ed. If not set, such
+// uses are tolerated as silent no-ops.
+//
+// debugUseAfterFinish configures the Tracer to collect stack traces on every
+// Span.Finish() call. These are presented when the finished span is reused.
+// This option is expensive. It's invalid to debugUseAfterFinish if
+// panicOnUseAfterFinish is not set.
+func WithUseAfterFinishOpt(panicOnUseAfterFinish, debugUseAfterFinish bool) TracerOption {
+	if debugUseAfterFinish && !panicOnUseAfterFinish {
+		panic(errors.AssertionFailedf("it is nonsensical to set debugUseAfterFinish when panicOnUseAfterFinish is not set, " +
+			"as the collected stacks will never be used"))
+	}
+	return useAfterFinishOpt{
+		panicOnUseAfterFinish: panicOnUseAfterFinish,
+		debugUseAfterFinish:   debugUseAfterFinish,
+	}
+}
+
+func (t *Tracer) setVerboseOpNameRegexp(s string) error {
+	if s == "" {
+		t.opNameRegexp.Store(nil)
+		return nil
+	}
+	compiled, err := regexp.Compile(s)
+	if err != nil {
+		return err
+	}
+	t.opNameRegexp.Store(compiled)
+	return nil
+}
+
+// configure sets up the Tracer according to the cluster settings (and keeps
+// it updated if they change).
+func (t *Tracer) configure(ctx context.Context, sv *settings.Values, tracingDefault TracingMode) {
+	// traceProvider is captured by the function below.
+	var traceProvider *otelsdk.TracerProvider
+
+	// reconfigure will be called every time a cluster setting affecting tracing
+	// is updated.
+	reconfigure := func(ctx context.Context) {
+		otlpCollectorAddr := openTelemetryCollector.Get(sv)
+		zipkinAddr := ZipkinCollector.Get(sv)
+		enableRedactable := enableTraceRedactable.Get(sv)
+
+		switch tracingDefault {
+		case TracingModeFromEnv:
+			t.SetActiveSpansRegistryEnabled(EnableActiveSpansRegistry.Get(sv))
+		case TracingModeOnDemand:
+			t.SetActiveSpansRegistryEnabled(false)
+		case TracingModeActiveSpansRegistry:
+			t.SetActiveSpansRegistryEnabled(true)
+		default:
+			panic(errors.AssertionFailedf("unrecognized tracing option: %v", tracingDefault))
+		}
+
+		t.SetRedactable(enableRedactable)
+
+		var nt int32
+		if enableNetTrace.Get(sv) {
+			nt = 1
+		}
+		atomic.StoreInt32(&t._useNetTrace, nt)
+
+		// Return early if the OpenTelemetry tracer is disabled.
+		if otlpCollectorAddr == "" && zipkinAddr == "" {
+			if traceProvider != nil {
+				t.SetOpenTelemetryTracer(nil)
+				if err := traceProvider.Shutdown(ctx); err != nil {
+					fmt.Fprintf(os.Stderr, "error shutting down tracer: %s", err)
+				}
+			}
+			return
+		}
+
+		opts := []otelsdk.TracerProviderOption{otelsdk.WithSampler(otelsdk.AlwaysSample())}
+		resource, err := resource.New(ctx,
+			resource.WithAttributes(semconv.ServiceNameKey.String("CockroachDB")),
+		)
+		if err == nil {
+			opts = append(opts, otelsdk.WithResource(resource))
+		} else {
+			fmt.Fprintf(os.Stderr, "failed to create OpenTelemetry resource: %s\n", err)
+		}
+
+		if otlpCollectorAddr != "" {
+			spanProcessor, err := createOTLPSpanProcessor(ctx, otlpCollectorAddr)
+			if err == nil {
+				opts = append(opts, otelsdk.WithSpanProcessor(spanProcessor))
+			} else {
+				fmt.Fprintf(os.Stderr, "failed to create OTLP processor: %s", err)
+			}
+		}
+
+		if zipkinAddr != "" {
+			spanProcessor, err := createZipkinCollector(ctx, zipkinAddr)
+			if err == nil {
+				opts = append(opts, otelsdk.WithSpanProcessor(spanProcessor))
+			} else {
+				fmt.Fprintf(os.Stderr, "failed to create Zipkin processor: %s", err)
+			}
+		}
+
+		oldTP := traceProvider
+		traceProvider = otelsdk.NewTracerProvider(opts...)
+
+		// Canonical OpenTelemetry wants every module to have its own Tracer
+		// instance, with each one initialized with a different name. We're not
+		// doing that though, because our code creates all the spans through a
+		// single Tracer (the receiver of this method). So, we're creating a
+		// single Tracer here.
+		otelTracer := traceProvider.Tracer("crdb")
+		t.SetOpenTelemetryTracer(otelTracer)
+
+		// Shutdown the old tracer.
+		if oldTP != nil {
+			_ = oldTP.Shutdown(context.TODO())
+		}
+
+		// TODO(andrei): Figure out how to cleanup the tracer when the server
+		// exits. It unfortunately seems hard to plumb the Stopper to here to put
+		// a closer on it.
+	}
+
+	reconfigure(ctx)
+
+	EnableActiveSpansRegistry.SetOnChange(sv, reconfigure)
+	enableNetTrace.SetOnChange(sv, reconfigure)
+	openTelemetryCollector.SetOnChange(sv, reconfigure)
+	ZipkinCollector.SetOnChange(sv, reconfigure)
+	enableTraceRedactable.SetOnChange(sv, reconfigure)
+}
+
+func createOTLPSpanProcessor(
+	ctx context.Context, otlpCollectorAddr string,
+) (otelsdk.SpanProcessor, error) {
+	host, port, err := addr.SplitHostPort(otlpCollectorAddr, "4317")
+	if err != nil {
+		return nil, err
+	}
+
+	exporter, err := otlptracegrpc.New(
+		ctx,
+		otlptracegrpc.WithEndpoint(fmt.Sprintf("%s:%s", host, port)),
+		// TODO(andrei): Add support for secure connections to the collector.
+		otlptracegrpc.WithInsecure())
+	if err != nil {
+		return nil, err
+	}
+	spanProcessor := otelsdk.NewBatchSpanProcessor(exporter)
+	return spanProcessor, nil
+}
+
+func createZipkinCollector(ctx context.Context, zipkinAddr string) (otelsdk.SpanProcessor, error) {
+	host, port, err := addr.SplitHostPort(zipkinAddr, "9411")
+	if err != nil {
+		return nil, err
+	}
+	exporter, err := zipkin.New(fmt.Sprintf("http://%s:%s/api/v2/spans", host, port))
+	if err != nil {
+		return nil, err
+	}
+	spanProcessor := otelsdk.NewBatchSpanProcessor(exporter)
+	return spanProcessor, nil
+}
+
+// HasExternalSink returns whether the tracer is configured to report
+// to an external tracing collector.
+func (t *Tracer) HasExternalSink() bool {
+	return t.getOtelTracer() != nil || t.useNetTrace()
+}
+
+func (t *Tracer) useNetTrace() bool {
+	return t.testing.UseNetTrace || atomic.LoadInt32(&t._useNetTrace) != 0
+}
+
+// Close cleans up any resources associated with a Tracer.
+func (t *Tracer) Close() {
+	atomic.StoreInt32(&t._closed, 1)
+	// Clean up the OpenTelemetry tracer, if any.
+	t.SetOpenTelemetryTracer(nil)
+}
+
+// closed returns true if Close() has been called.
+func (t *Tracer) closed() bool {
+	return atomic.LoadInt32(&t._closed) == 1
+}
+
+// SetOpenTelemetryTracer sets the OpenTelemetry tracer to use as a "shadow
+// tracer". A nil value means that no otel tracer will be used.
+func (t *Tracer) SetOpenTelemetryTracer(tr oteltrace.Tracer) {
+	var p *oteltrace.Tracer
+	if tr == nil {
+		p = nil
+	} else {
+		p = &tr
+	}
+	atomic.StorePointer(&t.otelTracer, unsafe.Pointer(p))
+}
+
+// getOtelTracer returns the OpenTelemetry tracer to use, or nil.
+func (t *Tracer) getOtelTracer() oteltrace.Tracer {
+	p := atomic.LoadPointer(&t.otelTracer)
+	if p == nil {
+		return nil
+	}
+	return *(*oteltrace.Tracer)(p)
+}
+
+// StartSpan starts a Span. See SpanOption for details.
+func (t *Tracer) StartSpan(operationName string, os ...SpanOption) *Span {
+	_, sp := t.StartSpanCtx(noCtx, operationName, os...)
+	return sp
+}
+
+// spanAllocHelper
+type spanAllocHelper struct {
+	span     Span
+	crdbSpan crdbSpan
+	// Pre-allocated buffers for the span.
+	tagsAlloc             [3]attribute.KeyValue
+	childrenAlloc         [4]childRef
+	structuredEventsAlloc [3]*tracingpb.StructuredRecord
+	childrenMetadataAlloc map[string]tracingpb.OperationMetadata
+}
+
+// newSpan allocates a span using the Tracer's sync.Pool. A span that was
+// previously Finish()ed be returned if the Tracer is configured for Span reuse.
+// +(...) must be called on the returned span before further use.
+func (t *Tracer) newSpan(
+	traceID tracingpb.TraceID,
+	spanID tracingpb.SpanID,
+	operation string,
+	goroutineID uint64,
+	startTime time.Time,
+	logTags *logtags.Buffer,
+	eventListeners []EventListener,
+	kind oteltrace.SpanKind,
+	otelSpan oteltrace.Span,
+	netTr trace.Trace,
+	sterile bool,
+) *Span {
+	if t.testing.MaintainAllocationCounters {
+		atomic.AddInt32(&t.spansCreated, 1)
+	}
+	h := t.spanPool.Get().(*spanAllocHelper)
+	h.span.reset(
+		traceID, spanID, operation, goroutineID,
+		startTime, logTags, eventListeners, kind,
+		otelSpan, netTr, sterile)
+	return &h.span
+}
+
+// releaseSpanToPool makes sp available for re-allocation. If the Tracer was not
+// configured for span reuse, this is a no-op.
+func (t *Tracer) releaseSpanToPool(sp *Span) {
+	switch t.spanReusePercent {
+	case 0:
+		return
+	case 100:
+		break
+	default:
+		rnd := randutil.FastUint32() % 100
+		if rnd >= t.spanReusePercent {
+			return
+		}
+	}
+
+	// Nil out various slices inside the span to make them available for GC (both
+	// the backing storage for the slices and the individual elements in the
+	// slices). The backing arrays might be shared with the spanAllocHelper, in
+	// which case they can't be GCed (and we don't want them to be GC'ed either
+	// because we'll reuse them when the span is re-allocated from the pool).
+	// We'll zero-out the spanAllocHelper, though, to make all the elements
+	// available for GC.
+	c := sp.i.crdb
+	c.eventListeners = nil
+	// Nobody is supposed to have a reference to the span at this point, but let's
+	// take the lock anyway to protect against buggy clients accessing the span
+	// after Finish().
+	func() {
+		c.mu.Lock()
+		defer c.mu.Unlock()
+		c.mu.openChildren = nil
+		c.mu.recording.finishedChildren = Trace{}
+		c.mu.tags = nil
+		c.mu.lazyTags = nil
+		c.mu.recording.logs.Discard()
+		c.mu.recording.structured.Discard()
+	}()
+
+	// Zero out the spanAllocHelper buffers to make the elements inside the
+	// arrays, if any, available for GC.
+	h := sp.helper
+	h.tagsAlloc = [3]attribute.KeyValue{}
+	h.childrenAlloc = [4]childRef{}
+	h.structuredEventsAlloc = [3]*tracingpb.StructuredRecord{}
+	for op := range h.childrenMetadataAlloc {
+		delete(h.childrenMetadataAlloc, op)
+	}
+
+	release := true
+	if fn := t.testing.ReleaseSpanToPool; fn != nil {
+		release = fn(sp)
+	}
+	if release {
+		t.spanPool.Put(h)
+	}
+}
+
+// StartSpanCtx starts a Span and returns it alongside a wrapping Context
+// derived from the supplied Context. Any log tags found in the supplied
+// Context are propagated into the Span; this behavior can be modified by
+// passing WithLogTags explicitly.
+//
+// See SpanOption for other options that can be passed.
+func (t *Tracer) StartSpanCtx(
+	ctx context.Context, operationName string, os ...SpanOption,
+) (context.Context, *Span) {
+	if t == nil {
+		return ctx, nil
+	}
+	// NB: apply takes and returns a value to avoid forcing
+	// `opts` on the heap here.
+	var opts spanOptions
+	for i := range os {
+		if os[i] == nil {
+			continue
+		}
+		opts = os[i].apply(opts)
+	}
+
+	return t.startSpanFast(ctx, operationName, &opts)
+}
+
+// AlwaysTrace returns true if operations should be traced regardless of the
+// context.
+func (t *Tracer) AlwaysTrace() bool {
+	if t.ActiveSpansRegistryEnabled() {
+		return true
+	}
+	otelTracer := t.getOtelTracer()
+	return t.useNetTrace() || otelTracer != nil
+}
+
+func (t *Tracer) forceOpNameVerbose(opName string) bool {
+	if r := t.opNameRegexp.Load(); r != nil {
+		return r.MatchString(opName)
+	}
+	return false
+}
+
+// startSpanFast implements a fast path for the common case of tracing
+// being disabled on the current span and its parent. We make only the
+// checks necessary to ensure that recording is disabled and wrap the
+// context in a nil span.
+func (t *Tracer) startSpanFast(
+	ctx context.Context, opName string, opts *spanOptions,
+) (context.Context, *Span) {
+	if opts.RefType != childOfRef && opts.RefType != followsFromRef {
+		panic(errors.AssertionFailedf("unexpected RefType %v", opts.RefType))
+	}
+
+	// This is a fast path for the common case where there's no parent
+	// span. This contains duplicated logic from
+	// `(*spanOptions).recordingType()`. Specifically, we are aiming to
+	// avoid creating local copies of `opts.Parent` and
+	// `opts.RemoteParent` hence conditional logic is being inlined and
+	// checked locally. This logic should only change if
+	// `recordingType()` is being modified.
+	if opts.Parent.Span == nil && opts.RemoteParent.Empty() {
+		var recordingType tracingpb.RecordingType
+
+		if opts.recordingTypeExplicit {
+			recordingType = opts.recordingTypeOpt
+		}
+
+		if recordingType < opts.minRecordingTypeOpt {
+			recordingType = opts.minRecordingTypeOpt
+		}
+
+		shouldBeNilSpan := !(t.AlwaysTrace() || opts.ForceRealSpan || recordingType != tracingpb.RecordingOff)
+		forceVerbose := t.forceOpNameVerbose(opName)
+		if shouldBeNilSpan && !forceVerbose && !opts.Sterile {
+			return maybeWrapCtx(ctx, nil)
+		}
+	}
+	return t.startSpanGeneric(ctx, opName, opts)
+}
+
+// startSpanGeneric is the implementation of StartSpanCtx and StartSpan. In
+// the latter case, ctx == noCtx and the returned Context is the supplied one;
+// otherwise the returned Context embeds the returned Span.
+func (t *Tracer) startSpanGeneric(
+	ctx context.Context, opName string, opts *spanOptions,
+) (context.Context, *Span) {
+	if opts.RefType != childOfRef && opts.RefType != followsFromRef {
+		panic(errors.AssertionFailedf("unexpected RefType %v", opts.RefType))
+	}
+
+	if !opts.Parent.empty() {
+		// If we don't panic, opts.Parent will be moved into the child, and this
+		// release() will be a no-op.
+		defer opts.Parent.release()
+
+		if !opts.RemoteParent.Empty() {
+			panic(errors.AssertionFailedf("can't specify both Parent and RemoteParent"))
+		}
+
+		if opts.Parent.i.sterile {
+			// A sterile parent should have been optimized away by
+			// WithParent.
+			panic(errors.AssertionFailedf("invalid sterile parent"))
+		}
+		if s := opts.Parent.Tracer(); s != t {
+			// Creating a child with a different Tracer than the parent is not allowed
+			// because it would become unclear which active span registry the new span
+			// should belong to. In particular, the child could end up in the parent's
+			// registry if the parent Finish()es before the child, and then it would
+			// be leaked because Finish()ing the child would attempt to remove the
+			// span from the child tracer's registry.
+			panic(errors.AssertionFailedf(`attempting to start span with parent from different Tracer.
+parent operation: %s, tracer created at:
+
+%s
+
+child operation: %s, tracer created at:
+%s`,
+				opts.Parent.OperationName(), s.stack, opName, t.stack))
+		}
+	}
+
+	// Are we tracing everything, or have a parent, or want a real span, or were
+	// asked for a recording? Then we create a real trace span. In all other
+	// cases, a nil span will do.
+	shouldBeNilSpan := !(t.AlwaysTrace() || opts.parentTraceID() != 0 || opts.ForceRealSpan || opts.recordingType() != tracingpb.RecordingOff)
+	// Finally, we should check to see if this opName is configured to always be forced to the
+	// tracingpb.RecordingVerbose RecordingType. If it is, we'll want to create a real trace
+	// span.
+	forceVerbose := t.forceOpNameVerbose(opName)
+	if shouldBeNilSpan && !forceVerbose {
+		return maybeWrapCtx(ctx, nil)
+	}
+
+	if opts.LogTags == nil {
+		opts.LogTags = logtags.FromContext(ctx)
+	}
+
+	if opts.LogTags == nil && !opts.Parent.empty() {
+		// If no log tags are specified in the options, use the parent
+		// span's, if any. This behavior is the reason logTags are
+		// fundamentally different from tags, which are strictly per span,
+		// for better or worse.
+		opts.LogTags = opts.Parent.i.crdb.logTags
+	}
+
+	startTime := timeutil.Now()
+
+	// First, create any external spans that we may need (OpenTelemetry, net/trace).
+	// We do this early so that they are available when we construct the main Span,
+	// which makes it easier to avoid one-offs when populating the tags items for
+	// the top-level Span.
+	var otelSpan oteltrace.Span
+	if otelTr := t.getOtelTracer(); otelTr != nil {
+		parentSpan, parentContext := opts.otelContext()
+		otelSpan = makeOtelSpan(otelTr, opName, parentSpan, parentContext, opts.RefType, startTime, opts.SpanKind)
+		// If LogTags are given, pass them as tags to the otel span.
+		// Regular tags are populated later, via the top-level Span.
+		if opts.LogTags != nil {
+			setLogTags(opts.LogTags.Get(), func(remappedKey string, tag *logtags.Tag) {
+				otelSpan.SetAttributes(attribute.String(remappedKey, tag.ValueStr()))
+			})
+		}
+	}
+
+	var netTr trace.Trace
+	if t.useNetTrace() {
+		netTr = trace.New("tracing", opName)
+		netTr.SetMaxEvents(maxLogsPerSpanExternal)
+
+		// If LogTags are given, pass them as tags to the otel span.
+		// Regular tags are populated later, via the top-level Span.
+		if opts.LogTags != nil {
+			setLogTags(opts.LogTags.Get(), func(remappedKey string, tag *logtags.Tag) {
+				netTr.LazyPrintf("%s:%v", remappedKey, tag)
+			})
+		}
+	}
+
+	// Now that `ot` and `netTr` are properly set up, make the Span.
+
+	traceID := opts.parentTraceID()
+	if traceID == 0 {
+		traceID = tracingpb.TraceID(randutil.FastInt63())
+	}
+	spanID := tracingpb.SpanID(randutil.FastInt63())
+
+	s := t.newSpan(
+		traceID, spanID, opName, uint64(goid.Get()),
+		startTime, opts.LogTags, opts.EventListeners, opts.SpanKind,
+		otelSpan, netTr, opts.Sterile)
+
+	var recType tracingpb.RecordingType
+	if forceVerbose {
+		recType = tracingpb.RecordingVerbose
+	} else {
+		recType = opts.recordingType()
+	}
+	s.i.crdb.SetRecordingType(recType)
+	s.i.crdb.parentSpanID = opts.parentSpanID()
+
+	var localRoot bool
+	{
+		// If a parent is specified, link the newly created Span to the parent.
+		// While the parent is alive, the child will be part of the
+		// activeSpansRegistry indirectly through this link. If the parent is
+		// recording, it will also use this link to collect the child's recording.
+		//
+		// NB: (!opts.Parent.Empty() && opts.Parent.i.crdb == nil) is not possible at
+		// the moment, but let's not rely on that.
+		if !opts.Parent.empty() && opts.Parent.i.crdb != nil {
+
+			// Panic if the parent has already been finished, if configured to do so.
+			// If the parent has finished and we're configured not to panic,
+			// addChildLocked we'll return false below and we'll deal with it.
+			_ = opts.Parent.detectUseAfterFinish()
+
+			parent := opts.Parent.i.crdb
+			if s.i.crdb == parent {
+				panic(errors.AssertionFailedf("attempting to link a child to itself: %s", s.i.crdb.operation))
+			}
+
+			// We're going to hold the parent's lock while we link both the parent
+			// to the child and the child to the parent.
+			parent.withLock(func() {
+				added := parent.addChildLocked(s, !opts.ParentDoesNotCollectRecording)
+				if added {
+					localRoot = false
+					// We take over the reference in opts.Parent. The child will release
+					// it once when it nils out s.i.crdb.mu.parent (i.e. when either the
+					// parent of the child finish). Note that some methods on opts cannot
+					// be used from this moment on.
+					s.i.crdb.mu.parent = opts.Parent.move()
+					s.i.crdb.mu.recording.notifyParentOnStructuredEvent = parent.wantEventNotificationsLocked()
+				} else {
+					// The parent has already finished, so make this "child" a root.
+					localRoot = true
+				}
+			})
+		} else {
+			localRoot = true
+		}
+	}
+
+	// If the span is a local root, put it into the registry of active local root
+	// spans. Span.Finish will take care of removing it.
+	if localRoot {
+		t.activeSpansRegistry.addSpan(s.i.crdb)
+	}
+
+	return maybeWrapCtx(ctx, s)
+}
+
+// Carrier is what's used to capture the serialized data. Each carrier is
+// inextricably linked to a corresponding format. See serializationFormat for
+// more details.
+type Carrier interface {
+	Set(key, val string)
+	ForEach(fn func(key, val string) error) error
+}
+
+// MapCarrier is an implementation of the Carrier interface for a map of string
+// pairs.
+type MapCarrier struct {
+	Map map[string]string
+}
+
+// Set implements the Carrier interface.
+func (c MapCarrier) Set(key, val string) {
+	c.Map[key] = val
+}
+
+// ForEach implements the Carrier interface.
+func (c MapCarrier) ForEach(fn func(key, val string) error) error {
+	for k, v := range c.Map {
+		if err := fn(k, v); err != nil {
+			return err
+		}
+	}
+	return nil
+}
+
+// InjectMetaInto is used to serialize the given span metadata into the given
+// Carrier. This, alongside ExtractMetaFrom, can be used to carry span metadata
+// across process boundaries. See serializationFormat for more details.
+func (t *Tracer) InjectMetaInto(sm SpanMeta, carrier Carrier) {
+	if sm.Empty() {
+		// Fast path when tracing is disabled. ExtractMetaFrom will accept an
+		// Empty map as a noop context.
+		return
+	}
+	// If the span has been marked as not wanting children, we don't propagate any
+	// information about it through the carrier (the point of propagating span
+	// info is to create a child from it).
+	if sm.sterile {
+		return
+	}
+
+	if sm.otelCtx.TraceID().IsValid() {
+		carrier.Set(fieldNameOtelTraceID, sm.otelCtx.TraceID().String())
+		carrier.Set(fieldNameOtelSpanID, sm.otelCtx.SpanID().String())
+	}
+
+	carrier.Set(fieldNameTraceID, strconv.FormatUint(uint64(sm.traceID), 16))
+	carrier.Set(fieldNameSpanID, strconv.FormatUint(uint64(sm.spanID), 16))
+	carrier.Set(fieldNameRecordingType, sm.recordingType.ToCarrierValue())
+}
+
+var noopSpanMeta = SpanMeta{}
+
+// ExtractMetaFrom is used to deserialize a span metadata (if any) from the
+// given Carrier. This, alongside InjectMetaFrom, can be used to carry span
+// metadata across process boundaries. See serializationFormat for more details.
+func (t *Tracer) ExtractMetaFrom(carrier Carrier) (SpanMeta, error) {
+	var traceID tracingpb.TraceID
+	var spanID tracingpb.SpanID
+	var otelTraceID oteltrace.TraceID
+	var otelSpanID oteltrace.SpanID
+	var recordingTypeExplicit bool
+	var recordingType tracingpb.RecordingType
+
+	iterFn := func(k, v string) error {
+		switch k = strings.ToLower(k); k {
+		case fieldNameTraceID:
+			var err error
+			id, err := strconv.ParseUint(v, 16, 64)
+			if err != nil {
+				return errors.Errorf("invalid trace id: %s", v)
+			}
+			traceID = tracingpb.TraceID(id)
+		case fieldNameSpanID:
+			var err error
+			id, err := strconv.ParseUint(v, 16, 64)
+			if err != nil {
+				return errors.Errorf("invalid span id: %s", v)
+			}
+			spanID = tracingpb.SpanID(id)
+		case fieldNameOtelTraceID:
+			var err error
+			otelTraceID, err = oteltrace.TraceIDFromHex(v)
+			if err != nil {
+				return err
+			}
+		case fieldNameOtelSpanID:
+			var err error
+			otelSpanID, err = oteltrace.SpanIDFromHex(v)
+			if err != nil {
+				return err
+			}
+		case fieldNameRecordingType:
+			recordingTypeExplicit = true
+			recordingType = tracingpb.RecordingTypeFromCarrierValue(v)
+		}
+		return nil
+	}
+
+	// Instead of iterating through the interface type, we prefer to do so with
+	// the explicit types to avoid heap allocations.
+	switch c := carrier.(type) {
+	case MapCarrier:
+		if err := c.ForEach(iterFn); err != nil {
+			return noopSpanMeta, err
+		}
+	case MetadataCarrier:
+		if err := c.ForEach(iterFn); err != nil {
+			return noopSpanMeta, err
+		}
+	default:
+		return noopSpanMeta, errors.New("unsupported carrier")
+	}
+
+	if traceID == 0 && spanID == 0 {
+		return noopSpanMeta, nil
+	}
+
+	if !recordingTypeExplicit && recordingType == tracingpb.RecordingOff {
+		// A 21.1 node (or a 21.2 mode running in backwards-compatibility mode)
+		// that passed a TraceID but not fieldNameDeprecatedVerboseTracing wants the
+		// structured events.
+		recordingType = tracingpb.RecordingStructured
+	}
+
+	var otelCtx oteltrace.SpanContext
+	if otelTraceID.IsValid() && otelSpanID.IsValid() {
+		otelCtx = otelCtx.WithRemote(true).WithTraceID(otelTraceID).WithSpanID(otelSpanID)
+	}
+
+	return SpanMeta{
+		traceID:       traceID,
+		spanID:        spanID,
+		otelCtx:       otelCtx,
+		recordingType: recordingType,
+		// The sterile field doesn't make it across the wire. The simple fact that
+		// there was any tracing info in the carrier means that the parent span was
+		// not sterile.
+		sterile: false,
+	}, nil
+}
+
+// RegistrySpan is the interface used by clients of the active span registry.
+//
+// Note that RegistrySpans can be Finish()ed concurrently with their use, so all
+// methods must work with concurrent Finish() calls.
+type RegistrySpan interface {
+	// TraceID returns the id of the trace that this span is part of.
+	TraceID() tracingpb.TraceID
+
+	// SpanID returns the span's ID.
+	SpanID() tracingpb.SpanID
+
+	// GetFullRecording returns the recording of the trace rooted at this span.
+	//
+	// This includes the recording of child spans created with the
+	// WithDetachedRecording option. In other situations, the recording of such
+	// children is not included in the parent's recording but, in the case of the
+	// span registry, we want as much information as possible to be included.
+	GetFullRecording(recType tracingpb.RecordingType) Trace
+
+	// SetRecordingType sets the recording mode of the span and its children,
+	// recursively. Setting it to RecordingOff disables further recording.
+	// Everything recorded so far remains in memory.
+	SetRecordingType(to tracingpb.RecordingType)
+
+	// RecordingType returns the span's current recording type.
+	RecordingType() tracingpb.RecordingType
+}
+
+var _ RegistrySpan = &crdbSpan{}
+
+// GetActiveSpansRegistry returns a pointer to the registry containing all
+// in-flight on the node.
+func (t *Tracer) GetActiveSpansRegistry() *SpanRegistry {
+	return t.activeSpansRegistry
+}
+
+// GetActiveSpanByID retrieves any active root span given its ID.
+func (t *Tracer) GetActiveSpanByID(spanID tracingpb.SpanID) RegistrySpan {
+	return t.activeSpansRegistry.getSpanByID(spanID)
+}
+
+// VisitSpans calls the visitor callback for every local root span in the
+// registry. Iterations stops when the visitor returns an error. If that error
+// is iterutils.StopIteration(), then VisitSpans() returns nil.
+//
+// The callback should not hold on to the span after it returns.
+func (t *Tracer) VisitSpans(visitor func(span RegistrySpan) error) error {
+	return t.activeSpansRegistry.VisitRoots(visitor)
+}
+
+// TestingRecordAsyncSpans is a test-only helper that configures
+// the tracer to include recordings from forked/async child spans, when
+// retrieving the recording for a parent span.
+func (t *Tracer) TestingRecordAsyncSpans() {
+	t.testingMu.Lock()
+	defer t.testingMu.Unlock()
+
+	t.testingRecordAsyncSpans = true
+}
+
+// ShouldRecordAsyncSpans returns whether or not we should include recordings
+// from async child spans in the parent span. See TestingRecordAsyncSpans, this
+// mode is only used in tests.
+func (t *Tracer) ShouldRecordAsyncSpans() bool {
+	t.testingMu.Lock()
+	defer t.testingMu.Unlock()
+
+	return t.testingRecordAsyncSpans
+}
+
+// PanicOnUseAfterFinish returns true if the Tracer is configured to crash when
+// a Span is used after it was previously Finish()ed. Crashing is supposed to be
+// best-effort as, in the future, reliably detecting use-after-Finish might not
+// be possible (i.e. it's not possible if the Span is reused for a different
+// operation before the use-after-Finish occurs).
+func (t *Tracer) PanicOnUseAfterFinish() bool {
+	return t.panicOnUseAfterFinish
+}
+
+// SpanRegistry exports the registry containing all currently-open spans.
+func (t *Tracer) SpanRegistry() *SpanRegistry {
+	return t.activeSpansRegistry
+}
+
+// TestingGetStatsAndReset returns the number of spans created and allocated
+// since the previous TestingGetStatsAndReset() call. The difference
+// created-allocated indicates how many times spans have been reused through the
+// Tracer's pool.
+//
+// Panics if the MaintainAllocationCounters testing knob was not set.
+func (t *Tracer) TestingGetStatsAndReset() (int, int) {
+	if !t.testing.MaintainAllocationCounters {
+		panic(errors.AssertionFailedf("GetStatsAndReset() needs the Tracer to have been configured with MaintainAllocationCounters"))
+	}
+	created := atomic.SwapInt32(&t.spansCreated, 0)
+	allocs := atomic.SwapInt32(&t.spansAllocated, 0)
+	return int(created), int(allocs)
+}
+
+func (t *Tracer) now() time.Time {
+	if clock := t.testing.Clock; clock != nil {
+		return clock.Now()
+	}
+	return timeutil.Now()
+}
+
+// ForkSpan forks the current span, if any[1]. Forked spans "follow from" the
+// original, and are typically used to trace operations that may outlive the
+// parent (think async tasks). See the package-level documentation for more
+// details.
+//
+// The recordings from these spans will not be automatically propagated to the
+// parent span[2]. Also see `ChildSpan`, for the other kind of derived span
+// relation.
+//
+// A context wrapping the newly created span is returned, along with the span
+// itself. If non-nil, the caller is responsible for eventually Finish()ing it.
+//
+// [1]: Looking towards the provided context to see if one exists.
+// [2]: Unless configured differently by tests, see
+//
+//	TestingRecordAsyncSpans.
+func ForkSpan(ctx context.Context, opName string) (context.Context, *Span) {
+	sp := SpanFromContext(ctx)
+	if sp == nil {
+		return ctx, nil
+	}
+	opts := make([]SpanOption, 0, 3)
+	if sp.Tracer().ShouldRecordAsyncSpans() {
+		opts = append(opts, WithParent(sp))
+	} else {
+		opts = append(opts, WithParent(sp), WithDetachedRecording())
+	}
+	opts = append(opts, WithFollowsFrom())
+	return sp.Tracer().StartSpanCtx(ctx, opName, opts...)
+}
+
+// EnsureForkSpan is like ForkSpan except that, if there is no span in ctx, it
+// creates a root span.
+func EnsureForkSpan(ctx context.Context, tr *Tracer, opName string) (context.Context, *Span) {
+	sp := SpanFromContext(ctx)
+	opts := make([]SpanOption, 0, 3)
+	// If there's a span in ctx, we use it as a parent.
+	if sp != nil {
+		tr = sp.Tracer()
+		if tr.ShouldRecordAsyncSpans() {
+			opts = append(opts, WithParent(sp))
+		} else {
+			// Using auto collection here ensures that recordings from async spans
+			// also show up at the parent.
+			opts = append(opts, WithParent(sp), WithDetachedRecording())
+		}
+		opts = append(opts, WithFollowsFrom())
+	}
+	return tr.StartSpanCtx(ctx, opName, opts...)
+}
+
+// ChildSpan creates a child span of the current one, if any, via the WithParent
+// option. Recordings from child spans are automatically propagated to the
+// parent span, and the tags are inherited from the context's log tags
+// automatically. Also see `ForkSpan`, for the other kind of derived span
+// relation.
+//
+// A context wrapping the newly created span is returned, along with the span
+// itself. If non-nil, the caller is responsible for eventually Finish()ing it.
+func ChildSpan(ctx context.Context, opName string, os ...SpanOption) (context.Context, *Span) {
+	sp := SpanFromContext(ctx)
+	if sp == nil {
+		return ctx, nil
+	}
+	if len(os) == 0 {
+		return sp.Tracer().StartSpanCtx(ctx, opName, WithParent(sp))
+	}
+	os = append(os[:len(os):len(os)], WithParent(sp))
+	return sp.Tracer().StartSpanCtx(ctx, opName, os...)
+}
+
+// EnsureChildSpan looks at the supplied Context. If it contains a Span, returns
+// a child span via the WithParent option; otherwise starts a
+// new Span. In both cases, a context wrapping the Span is returned along with
+// the newly created Span.
+//
+// The caller is responsible for closing the Span (via Span.Finish).
+func EnsureChildSpan(
+	ctx context.Context, tr *Tracer, name string, os ...SpanOption,
+) (context.Context, *Span) {
+	// NB: Making the capacity dynamic, based on len(os), makes this allocate.
+	// With a fixed length, it doesn't allocate.
+	opts := make([]SpanOption, 0, 3)
+	opts = append(opts, WithParent(SpanFromContext(ctx)))
+	opts = append(opts, os...)
+	ctx, sp := tr.StartSpanCtx(ctx, name, opts...)
+	return ctx, sp
+}
+
+// ContextWithRecordingSpan returns a context with an embedded trace Span. The
+// Span is derived from the provided Tracer. The recording is collected and the
+// span is Finish()ed through the returned callback.
+//
+// The returned callback can be called multiple times.
+//
+// Note that to convert the recorded spans into text, you can use
+// Recording.String(). Tests can also use FindMsgInRecording().
+func ContextWithRecordingSpan(
+	ctx context.Context, tr *Tracer, opName string,
+) (_ context.Context, finishAndGetRecording func() tracingpb.Recording) {
+	ctx, sp := tr.StartSpanCtx(ctx, opName, WithRecording(tracingpb.RecordingVerbose))
+	var rec tracingpb.Recording
+	return ctx,
+		func() tracingpb.Recording {
+			if rec != nil {
+				return rec
+			}
+			rec = sp.FinishAndGetConfiguredRecording()
+			return rec
+		}
+}
+
+// makeOtelSpan creates an OpenTelemetry span. If either of localParent or
+// remoteParent are not Empty, the returned span will be a child of that parent.
+//
+// End() needs to be called on the returned span once the span is complete.
+func makeOtelSpan(
+	otelTr oteltrace.Tracer,
+	opName string,
+	localParent oteltrace.Span,
+	remoteParent oteltrace.SpanContext,
+	refType spanReferenceType,
+	startTime time.Time,
+	kind oteltrace.SpanKind,
+) oteltrace.Span {
+	ctx := context.Background()
+	var parentSpanContext oteltrace.SpanContext
+	if localParent != nil {
+		parentSpanContext = localParent.SpanContext()
+	} else if remoteParent.IsValid() {
+		parentSpanContext = remoteParent
+	}
+
+	opts := make([]oteltrace.SpanStartOption, 0, 3)
+	opts = append(opts, oteltrace.WithTimestamp(startTime), oteltrace.WithSpanKind(kind))
+	switch refType {
+	case childOfRef:
+		// If a parent was passed in, put it in the context. That's where Start()
+		// will take it from.
+		if parentSpanContext.IsValid() {
+			ctx = oteltrace.ContextWithSpanContext(ctx, parentSpanContext)
+		}
+
+	case followsFromRef:
+		opts = append(opts, oteltrace.WithLinks(oteltrace.Link{
+			SpanContext: parentSpanContext,
+			Attributes:  followsFromAttribute,
+		}))
+	default:
+		panic(errors.AssertionFailedf("unsupported span reference type: %v", refType))
+	}
+
+	_ /* ctx */, sp := otelTr.Start(ctx, opName, opts...)
+	return sp
+}
+
+// MetadataCarrier is an implementation of the Carrier interface for gRPC
+// metadata.
+type MetadataCarrier struct {
+	metadata.MD
+}
+
+// Set implements the Carrier interface.
+func (w MetadataCarrier) Set(key, val string) {
+	// The GRPC HPACK implementation rejects any uppercase keys here.
+	//
+	// As such, since the HTTP_HEADERS format is case-insensitive anyway, we
+	// blindly lowercase the key.
+	key = strings.ToLower(key)
+	w.MD[key] = append(w.MD[key], val)
+}
+
+// ForEach implements the Carrier interface.
+func (w MetadataCarrier) ForEach(fn func(key, val string) error) error {
+	for k, vals := range w.MD {
+		for _, v := range vals {
+			if err := fn(k, v); err != nil {
+				return err
+			}
+		}
+	}
+
+	return nil
+}
+
+// SpanInclusionFuncForClient is used as a SpanInclusionFunc for the client-side
+// of RPCs, deciding for which operations the gRPC tracing interceptor should
+// create a span.
+//
+// We use this to circumvent the interceptor's work when tracing is
+// disabled. Otherwise, the interceptor causes an increase in the
+// number of packets (even with an Empty context!).
+//
+// See #17177.
+func SpanInclusionFuncForClient(parent *Span) bool {
+	return parent != nil
+}
+
+// SpanInclusionFuncForServer is used as a SpanInclusionFunc for the server-side
+// of RPCs, deciding for which operations the gRPC tracing interceptor should
+// create a span.
+func SpanInclusionFuncForServer(t *Tracer, spanMeta SpanMeta) bool {
+	// If there is an incoming trace on the RPC (spanMeta) or the tracer is
+	// configured to always trace, return true. The second part is particularly
+	// useful for calls coming through the HTTP->RPC gateway (i.e. the AdminUI),
+	// where client is never tracing.
+	return !spanMeta.Empty() || t.AlwaysTrace()
+}
diff --git a/pkg/util/tracing/tracer_snapshots.go b/pkg/util/tracing/tracer_snapshots.go
new file mode 100644
index 0000000..e92c921
--- /dev/null
+++ b/pkg/util/tracing/tracer_snapshots.go
@@ -0,0 +1,338 @@
+// Copyright 2021 The Cockroach Authors.
+//
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
+
+package tracing
+
+import (
+	"bufio"
+	"context"
+	"strconv"
+	"strings"
+	"time"
+
+	"github.com/cockroachdb/cockroachdb-parser/pkg/settings"
+	"github.com/cockroachdb/cockroachdb-parser/pkg/util/allstacks"
+	"github.com/cockroachdb/cockroachdb-parser/pkg/util/timeutil"
+	"github.com/cockroachdb/cockroachdb-parser/pkg/util/tracing/tracingpb"
+	"github.com/cockroachdb/errors"
+	"github.com/petermattis/goid"
+)
+
+// SpansSnapshot represents a snapshot of all the open spans at a certain point
+// in time.
+type SpansSnapshot struct {
+	// CapturedAt is the time when the snapshot was collected.
+	CapturedAt time.Time
+	// Traces contains the collected traces. Each "local route" corresponds to one
+	// trace. "Detached recording" spans are included in the parent's trace.
+	Traces []tracingpb.Recording
+	// Stacks is a map from groutine ID to the goroutine's stack trace. All
+	// goroutines running at the time when this snapshot is produced are
+	// represented here. A goroutine referenced by a span's GoroutineID field will
+	// not be present if it has finished since the respective span was started.
+	Stacks map[int]string
+	// Err is set if an error was encountered when producing the snapshot. The
+	// snapshot will be incomplete in this case.
+	Err error
+}
+
+// SnapshotID identifies a spans snapshot. The ID can be used to retrieve a
+// specific snapshot from the Tracer.
+type SnapshotID int
+
+type snapshotWithID struct {
+	ID SnapshotID
+	SpansSnapshot
+}
+
+// SaveSnapshot collects a snapshot of the currently open spans (i.e. the
+// contents of the Tracer's active spans registry) saves it in-memory in the
+// Tracer. The snapshot's ID is returned; the snapshot can be retrieved
+// subsequently through t.GetSnapshot(id).
+//
+// Snapshots also include a dump of all the goroutine stack traces.
+func (t *Tracer) SaveSnapshot() SnapshotInfo {
+	return t.saveSnapshot(false)
+}
+
+// SaveAutomaticSnapshot is like SaveSnapshot but saves the snapshot created in
+// the "automatic" snapshots buffer instead of the manual snapshot buffer.
+func (t *Tracer) SaveAutomaticSnapshot() SnapshotInfo {
+	return t.saveSnapshot(true)
+}
+
+func (t *Tracer) saveSnapshot(automatic bool) SnapshotInfo {
+	snap := t.generateSnapshot()
+	t.snapshotsMu.Lock()
+	defer t.snapshotsMu.Unlock()
+
+	snapshots := &t.snapshotsMu.snapshots
+	limit := maxSnapshots
+	if automatic {
+		snapshots = &t.snapshotsMu.autoSnapshots
+		limit = maxAutomaticSnapshots
+	}
+
+	if snapshots.Len() >= limit {
+		snapshots.RemoveFirst()
+	}
+	var id SnapshotID
+	if snapshots.Len() == 0 {
+		id = 1
+	} else {
+		id = snapshots.GetLast().ID + 1
+	}
+	snapshots.AddLast(snapshotWithID{
+		ID:            id,
+		SpansSnapshot: snap,
+	})
+	return SnapshotInfo{
+		ID:         id,
+		CapturedAt: snap.CapturedAt,
+	}
+}
+
+var errSnapshotTooOld = errors.Newf(
+	"the requested snapshot is too old and has been deleted. "+
+		"Only the last %d snapshots are stored.", maxSnapshots)
+
+var errSnapshotDoesntExist = errors.New("the requested snapshot doesn't exist")
+
+// GetSnapshot returns the snapshot with the given ID. If the ID is below the
+// minimum stored snapshot, then the requested snapshot must have been
+// garbage-collected and errSnapshotTooOld is returned. If the snapshot id is
+// beyond the maximum stored ID, errSnapshotDoesntExist is returned.
+//
+// Note that SpansSpanshot has an Err field through which errors are returned.
+// In these error cases, the snapshot will be incomplete.
+func (t *Tracer) GetSnapshot(id SnapshotID) (SpansSnapshot, error) {
+	return t.getSnapshot(id, false)
+}
+
+// GetAutomaticSnapshot is a variant of GetSnapshot but for retrieving automatic
+// snapshots.
+func (t *Tracer) GetAutomaticSnapshot(id SnapshotID) (SpansSnapshot, error) {
+	return t.getSnapshot(id, true)
+}
+
+func (t *Tracer) getSnapshot(id SnapshotID, auto bool) (SpansSnapshot, error) {
+	t.snapshotsMu.Lock()
+	defer t.snapshotsMu.Unlock()
+	snapshots := &t.snapshotsMu.snapshots
+	if auto {
+		snapshots = &t.snapshotsMu.autoSnapshots
+	}
+
+	if snapshots.Len() == 0 {
+		return SpansSnapshot{}, errSnapshotDoesntExist
+	}
+	minID := snapshots.GetFirst().ID
+	if id < minID {
+		return SpansSnapshot{}, errSnapshotTooOld
+	}
+	maxID := snapshots.GetLast().ID
+	if id > maxID {
+		return SpansSnapshot{}, errSnapshotDoesntExist
+	}
+
+	return snapshots.Get(int(id - minID)).SpansSnapshot, nil
+}
+
+// SnapshotInfo represents minimal info about a stored snapshot, as returned by
+// Tracer.GetSnapshots().
+type SnapshotInfo struct {
+	ID         SnapshotID
+	CapturedAt time.Time
+}
+
+// GetSnapshots returns info on all stored span snapshots.
+func (t *Tracer) GetSnapshots() []SnapshotInfo {
+	t.snapshotsMu.Lock()
+	defer t.snapshotsMu.Unlock()
+	snapshots := &t.snapshotsMu.snapshots
+
+	res := make([]SnapshotInfo, snapshots.Len())
+	for i := 0; i < snapshots.Len(); i++ {
+		s := snapshots.Get(i)
+		res[i] = SnapshotInfo{
+			ID:         s.ID,
+			CapturedAt: s.CapturedAt,
+		}
+	}
+	return res
+}
+
+// GetAutomaticSnapshots returns info on all stored automatic span snapshots.
+func (t *Tracer) GetAutomaticSnapshots() []SnapshotInfo {
+	t.snapshotsMu.Lock()
+	defer t.snapshotsMu.Unlock()
+	autoSnapshots := &t.snapshotsMu.autoSnapshots
+
+	res := make([]SnapshotInfo, autoSnapshots.Len())
+	for i := 0; i < autoSnapshots.Len(); i++ {
+		s := autoSnapshots.Get(i)
+		res[i] = SnapshotInfo{
+			ID:         s.ID,
+			CapturedAt: s.CapturedAt,
+		}
+	}
+	return res
+}
+
+// generateSnapshot produces a snapshot of all the currently open spans and
+// all the current goroutine stacktraces.
+//
+// Note that SpansSpanshot has an Err field through which errors are returned.
+// In these error cases, the snapshot will be incomplete.
+func (t *Tracer) generateSnapshot() SpansSnapshot {
+	capturedAt := timeutil.Now()
+	// Collect the traces.
+	traces := make([]tracingpb.Recording, 0, 1000)
+	_ = t.SpanRegistry().VisitRoots(func(sp RegistrySpan) error {
+		rec := sp.GetFullRecording(tracingpb.RecordingVerbose)
+		traces = append(traces, rec.Flatten())
+		return nil
+	})
+
+	// Collect and parse the goroutine stack traces.
+	stacks := allstacks.Get()
+
+	splits := strings.Split(string(stacks), "\n\n")
+	stackMap := make(map[int]string, len(splits))
+	var parseErr error
+	for _, s := range splits {
+		// Parse the goroutine ID. The first line of each stack is expected to look like:
+		// goroutine 115 [chan receive]:
+		scanner := bufio.NewScanner(strings.NewReader(s))
+		scanner.Split(bufio.ScanWords)
+		// Skip the word "goroutine".
+		if !scanner.Scan() {
+			parseErr = errors.Errorf("unexpected end of string")
+			break
+		}
+		// Scan the goroutine ID.
+		if !scanner.Scan() {
+			parseErr = errors.Errorf("unexpected end of string")
+			break
+		}
+		goroutineID, err := strconv.Atoi(scanner.Text())
+		if err != nil {
+			panic(err)
+		}
+		stackMap[goroutineID] = s
+	}
+
+	return SpansSnapshot{
+		CapturedAt: capturedAt,
+		Traces:     traces,
+		Stacks:     stackMap,
+		Err:        parseErr,
+	}
+}
+
+// PeriodicSnapshotsLoop runs until done closes, calling SaveAutomaticSnapshot
+// if enabled at the interval set by the trace.snapshot.rate setting.
+func (t *Tracer) PeriodicSnapshotsLoop(sv *settings.Values, done <-chan struct{}) {
+	ch := make(chan struct{}, 1)
+	periodicSnapshotInterval.SetOnChange(sv, func(_ context.Context) {
+		select {
+		case ch <- struct{}{}:
+		default:
+		}
+	})
+	t.runPeriodicSnapshotsLoop(sv, ch, done, nil /* testingKnob */)
+}
+
+func (t *Tracer) runPeriodicSnapshotsLoop(
+	sv *settings.Values, settingChange, done, testingKnob <-chan struct{},
+) {
+	loop := func(rate time.Duration) (exiting bool) {
+		ticker := time.NewTicker(rate)
+		defer ticker.Stop()
+		for {
+			select {
+			case <-done:
+				return true
+			case <-ticker.C:
+				t.SaveAutomaticSnapshot()
+				if testingKnob != nil {
+					if _, ok := <-testingKnob; !ok {
+						return true
+					}
+				}
+			case <-settingChange:
+				if periodicSnapshotInterval.Get(sv) != rate {
+					return false
+				}
+			}
+		}
+	}
+
+	for {
+		if rate := periodicSnapshotInterval.Get(sv); rate != 0 {
+			if loop(rate) {
+				return // loop hit done
+			}
+		} else {
+			select {
+			case <-done:
+				return
+			case <-settingChange:
+			}
+		}
+	}
+}
+
+// MaybeRecordStackHistory records in the span found in the passed context, if
+// there is one and it is verbose or has a sink, any stacks found for the
+// current goroutine in the currently stored tracer automatic snapshots, since
+// the passed time (generally when this goroutine started processing this
+// request/op). See the "trace.snapshot.rate" setting for controlling whether
+// such automatic snapshots are available to be searched and if so at what
+// granularity.
+func (sp *Span) MaybeRecordStackHistory(since time.Time) {
+	if sp == nil || sp.RecordingType() == tracingpb.RecordingOff {
+		return
+	}
+
+	t := sp.Tracer()
+	id := int(goid.Get())
+
+	var prevStack string
+
+	t.snapshotsMu.Lock()
+	defer t.snapshotsMu.Unlock()
+	for i := 0; i < t.snapshotsMu.autoSnapshots.Len(); i++ {
+		s := t.snapshotsMu.autoSnapshots.Get(i)
+		if s.CapturedAt.Before(since) {
+			continue
+		}
+		stack, ok := s.Stacks[id]
+		if ok {
+			sp.RecordStructured(stackDelta(prevStack, stack, timeutil.Since(s.CapturedAt)))
+			prevStack = stack
+		}
+	}
+}
+
+func stackDelta(base, change string, age time.Duration) Structured {
+	if base == "" {
+		return &tracingpb.CapturedStack{Stack: change, Age: age}
+	}
+
+	var i, lines int
+	for i = range base {
+		c := base[len(base)-1-i]
+		if i > len(change) || change[len(change)-1-i] != c {
+			break
+		}
+		if c == '\n' {
+			lines++
+		}
+	}
+	return &tracingpb.CapturedStack{
+		Stack: change[:len(change)-i], SharedSuffix: int32(i), SharedLines: int32(lines),
+	}
+}
diff --git a/pkg/util/tracing/tracing_aggregator.go b/pkg/util/tracing/tracing_aggregator.go
new file mode 100644
index 0000000..d1cff24
--- /dev/null
+++ b/pkg/util/tracing/tracing_aggregator.go
@@ -0,0 +1,102 @@
+// Copyright 2022 The Cockroach Authors.
+//
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
+
+package tracing
+
+import (
+	"context"
+
+	"github.com/cockroachdb/cockroachdb-parser/pkg/util/protoutil"
+	"github.com/cockroachdb/cockroachdb-parser/pkg/util/syncutil"
+	"github.com/cockroachdb/errors"
+)
+
+// AggregatorEvent describes an event that can be aggregated and stored by the
+// TracingAggregator. A AggregatorEvent also implements the tracing.LazyTag interface
+// to render its information on the associated tracing span.
+type AggregatorEvent interface {
+	// Identity returns a AggregatorEvent that when combined with another
+	// event returns the other AggregatorEvent unchanged.
+	Identity() AggregatorEvent
+	// Combine combines two AggregatorEvents together.
+	Combine(other AggregatorEvent)
+	// ProtoName returns the fully qualified name of the underlying proto that is
+	// a AggregatorEvent.
+	ProtoName() string
+	// String returns the string representation of the AggregatorEvent.
+	String() string
+}
+
+// A TracingAggregator can be used to aggregate and render AggregatorEvents that
+// are emitted as part of its tracing spans' recording.
+type TracingAggregator struct {
+	mu struct {
+		syncutil.Mutex
+		// aggregatedEvents is a mapping from the name identifying the
+		// AggregatorEvent to the running aggregate of the
+		// AggregatorEvent.
+		aggregatedEvents map[string]AggregatorEvent
+	}
+}
+
+// ForEachAggregatedEvent executes f on each event in the TracingAggregator's
+// in-memory map.
+func (b *TracingAggregator) ForEachAggregatedEvent(f func(name string, event AggregatorEvent)) {
+	b.mu.Lock()
+	defer b.mu.Unlock()
+
+	for name, event := range b.mu.aggregatedEvents {
+		f(name, event)
+	}
+}
+
+// Notify implements the EventListener interface.
+func (b *TracingAggregator) Notify(event Structured) EventConsumptionStatus {
+	bulkEvent, ok := event.(AggregatorEvent)
+	if !ok {
+		return EventNotConsumed
+	}
+
+	b.mu.Lock()
+	defer b.mu.Unlock()
+
+	// If this is the first AggregatorEvent with this name, set it as a LazyTag on
+	// the associated tracing span.
+	eventName := bulkEvent.ProtoName()
+	if _, ok := b.mu.aggregatedEvents[bulkEvent.ProtoName()]; !ok {
+		b.mu.aggregatedEvents[eventName] = bulkEvent.Identity()
+	}
+	b.mu.aggregatedEvents[eventName].Combine(bulkEvent)
+	return EventNotConsumed
+}
+
+// AggregatorEventToBytes marshals an event into a byte slice.
+func AggregatorEventToBytes(_ context.Context, event AggregatorEvent) ([]byte, error) {
+	msg, ok := event.(protoutil.Message)
+	if !ok {
+		// This should never happen but if it does skip the aggregated event.
+		return nil, errors.Newf("event is not a protoutil.Message: %T", event)
+	}
+	data := make([]byte, msg.Size())
+	if _, err := msg.MarshalTo(data); err != nil {
+		// This should never happen but if it does skip the aggregated event.
+		return nil, errors.Newf("event is not a protoutil.Message: %T", event)
+	}
+
+	return data, nil
+}
+
+var _ EventListener = &TracingAggregator{}
+
+// TracingAggregatorForContext creates a TracingAggregator if the provided
+// context has a tracing span.
+func TracingAggregatorForContext(ctx context.Context) *TracingAggregator {
+	if SpanFromContext(ctx) == nil {
+		return nil
+	}
+	agg := &TracingAggregator{}
+	agg.mu.aggregatedEvents = make(map[string]AggregatorEvent)
+	return agg
+}
diff --git a/pkg/util/tracing/tracingpb/recorded_span.go b/pkg/util/tracing/tracingpb/recorded_span.go
new file mode 100644
index 0000000..af53e70
--- /dev/null
+++ b/pkg/util/tracing/tracingpb/recorded_span.go
@@ -0,0 +1,213 @@
+// Copyright 2019 The Cockroach Authors.
+//
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
+
+package tracingpb
+
+import (
+	"fmt"
+	"time"
+
+	"github.com/cockroachdb/cockroachdb-parser/pkg/util/humanizeutil"
+	"github.com/cockroachdb/redact"
+	types "github.com/gogo/protobuf/types"
+)
+
+const (
+	// AnonymousTagGroupName is the name of the anonymous tag group.
+	AnonymousTagGroupName = ""
+)
+
+// TraceID is a probabilistically-unique id, shared by all spans in a trace.
+type TraceID uint64
+
+func (TraceID) SafeValue() {}
+
+// SpanID is a probabilistically-unique span id.
+type SpanID uint64
+
+func (SpanID) SafeValue() {}
+
+// Recording represents a group of RecordedSpans rooted at a fixed root span, as
+// returned by GetRecording. Spans are sorted by StartTime.
+type Recording []RecordedSpan
+
+// Less implements sort.Interface.
+func (r Recording) Less(i, j int) bool {
+	return r[i].StartTime.Before(r[j].StartTime)
+}
+
+// Swap implements sort.Interface.
+func (r Recording) Swap(i, j int) {
+	r[i], r[j] = r[j], r[i]
+}
+
+// Len implements sort.Interface.
+func (r Recording) Len() int {
+	return len(r)
+}
+
+// LogMessageField is the field name used for the log message in a LogRecord.
+const LogMessageField = "event"
+
+// String implements fmt.Stringer.
+func (s *RecordedSpan) String() string {
+	return redact.Sprint(s).StripMarkers()
+}
+
+// SafeFormat implements redact.SafeFormatter.
+func (s *RecordedSpan) SafeFormat(w redact.SafePrinter, _ rune) {
+	w.Printf("=== %s (id: %d parent: %d)\n", redact.Safe(s.Operation), s.SpanID, s.ParentSpanID)
+	for _, ev := range s.Logs {
+		w.Printf("%s %s\n", redact.Safe(ev.Time.UTC().Format(time.RFC3339Nano)), ev.Msg())
+	}
+}
+
+// Structured visits the data passed to RecordStructured for the Span from which
+// the RecordedSpan was created.
+func (s *RecordedSpan) Structured(visit func(*types.Any, time.Time)) {
+	for _, sr := range s.StructuredRecords {
+		visit(sr.Payload, sr.Time)
+	}
+}
+
+// FindTagGroup returns the tag group matching the supplied name, or nil if
+// the name is not found.
+func (s *RecordedSpan) FindTagGroup(name string) *TagGroup {
+	for i := range s.TagGroups {
+		tagGroup := &s.TagGroups[i]
+		if tagGroup.Name == name {
+			return tagGroup
+		}
+	}
+	return nil
+}
+
+// EnsureTagGroup returns a reference to the tag group with the given name,
+// creating it if it doesn't exist.
+func (s *RecordedSpan) EnsureTagGroup(name string) *TagGroup {
+	if tg := s.FindTagGroup(name); tg != nil {
+		return tg
+	}
+	s.TagGroups = append(s.TagGroups, TagGroup{Name: name})
+	return &s.TagGroups[len(s.TagGroups)-1]
+}
+
+// AddStructuredRecord adds r to s' structured logs and returns r.MemorySize().
+//
+// Note that the limit on the size of a span's structured records is not
+// enforced here. If it's needed, the caller has to do it.
+func (s *RecordedSpan) AddStructuredRecord(r StructuredRecord) int64 {
+	size := int64(r.MemorySize())
+	s.StructuredRecords = append(s.StructuredRecords, r)
+	s.StructuredRecordsSizeBytes += size
+	return size
+}
+
+// TrimStructured potentially drops structured log records in order to keep the
+// structured record size <= maxSize. The prefix of the records that sum up to
+// <= maxSize is kept.
+func (s *RecordedSpan) TrimStructured(maxSize int64) int64 {
+	if s.StructuredRecordsSizeBytes <= maxSize {
+		return 0
+	}
+	size := int64(0)
+	for i := range s.StructuredRecords {
+		recordSize := int64(s.StructuredRecords[i].MemorySize())
+		if size+recordSize > maxSize {
+			// Zero-out the slice elements that are about to be trimmed, so they can
+			// be GC'ed.
+			for j := i; j < len(s.StructuredRecords); j++ {
+				s.StructuredRecords[j] = StructuredRecord{}
+			}
+			// Trim all records from i onwards.
+			s.StructuredRecords = s.StructuredRecords[:i]
+			break
+		}
+	}
+	oldSize := s.StructuredRecordsSizeBytes
+	s.StructuredRecordsSizeBytes = size
+	return oldSize - size
+}
+
+// AddTag adds a tag to the group. If a tag with the given key already exists,
+// its value is updated.
+func (tg *TagGroup) AddTag(k, v string) {
+	for i := range tg.Tags {
+		tag := &tg.Tags[i]
+		if tag.Key == k {
+			tag.Value = v
+			return
+		}
+	}
+	tg.Tags = append(tg.Tags, Tag{Key: k, Value: v})
+}
+
+// Msg extracts the message of the LogRecord, which is either in an "event" or
+// "error" field.
+func (l LogRecord) Msg() redact.RedactableString {
+	if l.Message != "" {
+		return l.Message
+	}
+	return ""
+}
+
+// MemorySize implements the sizable interface.
+func (l *LogRecord) MemorySize() int {
+	return 3*8 + // 3 words for time.Time
+		2*8 + // 2 words for StringHeader
+		len(l.Message)
+}
+
+// MemorySize implements the sizable interface.
+func (r *StructuredRecord) MemorySize() int {
+	return 3*8 + // 3 words for time.Time
+		1*8 + // 1 words for *Any
+		r.Payload.Size() // TODO(andrei): this is the encoded size, not the mem size
+}
+
+// FindTag returns the value matching the supplied key, or nil if the key is
+// not found.
+func (tg *TagGroup) FindTag(key string) (string, bool) {
+	for _, tag := range tg.Tags {
+		if tag.Key == key {
+			return tag.Value, true
+		}
+	}
+	return "", false
+}
+
+// Combine returns the sum of m and other.
+func (m OperationMetadata) Combine(other OperationMetadata) OperationMetadata {
+	m.Count += other.Count
+	m.ContainsUnfinished = m.ContainsUnfinished || other.ContainsUnfinished
+	m.Duration += other.Duration
+	return m
+}
+
+var _ redact.SafeFormatter = OperationMetadata{}
+
+func (m OperationMetadata) String() string {
+	return redact.StringWithoutMarkers(m)
+}
+
+// SafeFormat implements redact.SafeFormatter.
+func (m OperationMetadata) SafeFormat(s redact.SafePrinter, _ rune) {
+	s.Printf("{count: %d, duration %s", m.Count, humanizeutil.Duration(m.Duration))
+	if m.ContainsUnfinished {
+		s.Printf(", unfinished")
+	}
+	s.SafeRune('}')
+}
+
+func (c CapturedStack) String() string {
+	age := c.Age.Seconds()
+	if c.Stack == "" && c.SharedSuffix > 0 {
+		return fmt.Sprintf("stack as of %.1fs ago had not changed from previous stack", age)
+	}
+	if c.SharedLines > 0 {
+		return fmt.Sprintf("stack as of %.1fs ago: %s\n ...+%d lines matching previous stack", age, c.Stack, c.SharedLines)
+	}
+	return fmt.Sprintf("stack as of %.1fs ago: %s", age, c.Stack)
+}
diff --git a/pkg/util/tracing/tracingpb/recorded_span.pb.go b/pkg/util/tracing/tracingpb/recorded_span.pb.go
new file mode 100644
index 0000000..fc8f99b
--- /dev/null
+++ b/pkg/util/tracing/tracingpb/recorded_span.pb.go
@@ -0,0 +1,3410 @@
+// Code generated by protoc-gen-gogo. DO NOT EDIT.
+// source: util/tracing/tracingpb/recorded_span.proto
+
+package tracingpb
+
+import (
+	fmt "fmt"
+	github_com_cockroachdb_redact "github.com/cockroachdb/redact"
+	_ "github.com/gogo/protobuf/gogoproto"
+	proto "github.com/gogo/protobuf/proto"
+	github_com_gogo_protobuf_sortkeys "github.com/gogo/protobuf/sortkeys"
+	github_com_gogo_protobuf_types "github.com/gogo/protobuf/types"
+	types "github.com/gogo/protobuf/types"
+	io "io"
+	math "math"
+	math_bits "math/bits"
+	time "time"
+)
+
+// Reference imports to suppress errors if they are not otherwise used.
+var _ = proto.Marshal
+var _ = fmt.Errorf
+var _ = math.Inf
+var _ = time.Kitchen
+
+// This is a compile-time assertion to ensure that this generated file
+// is compatible with the proto package it is being compiled against.
+// A compilation error at this line likely means your copy of the
+// proto package needs to be updated.
+const _ = proto.GoGoProtoPackageIsVersion3 // please upgrade the proto package
+
+// LogRecord is a log message recorded in a traced span.
+type LogRecord struct {
+	// Time of the log record.
+	Time time.Time `protobuf:"bytes,1,opt,name=time,proto3,stdtime" json:"time"`
+	// The log message.
+	Message github_com_cockroachdb_redact.RedactableString `protobuf:"bytes,3,opt,name=message,proto3,customtype=github.com/cockroachdb/redact.RedactableString" json:"message"`
+}
+
+func (m *LogRecord) Reset()         { *m = LogRecord{} }
+func (m *LogRecord) String() string { return proto.CompactTextString(m) }
+func (*LogRecord) ProtoMessage()    {}
+func (*LogRecord) Descriptor() ([]byte, []int) {
+	return fileDescriptor_e9b7b35ae7ab4ca8, []int{0}
+}
+func (m *LogRecord) XXX_Unmarshal(b []byte) error {
+	return m.Unmarshal(b)
+}
+func (m *LogRecord) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+	b = b[:cap(b)]
+	n, err := m.MarshalToSizedBuffer(b)
+	if err != nil {
+		return nil, err
+	}
+	return b[:n], nil
+}
+func (m *LogRecord) XXX_Merge(src proto.Message) {
+	xxx_messageInfo_LogRecord.Merge(m, src)
+}
+func (m *LogRecord) XXX_Size() int {
+	return m.Size()
+}
+func (m *LogRecord) XXX_DiscardUnknown() {
+	xxx_messageInfo_LogRecord.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_LogRecord proto.InternalMessageInfo
+
+type LogRecord_Field struct {
+	Key   string                                         `protobuf:"bytes,1,opt,name=key,proto3" json:"key,omitempty"`
+	Value github_com_cockroachdb_redact.RedactableString `protobuf:"bytes,2,opt,name=value,proto3,customtype=github.com/cockroachdb/redact.RedactableString" json:"value"`
+}
+
+func (m *LogRecord_Field) Reset()         { *m = LogRecord_Field{} }
+func (m *LogRecord_Field) String() string { return proto.CompactTextString(m) }
+func (*LogRecord_Field) ProtoMessage()    {}
+func (*LogRecord_Field) Descriptor() ([]byte, []int) {
+	return fileDescriptor_e9b7b35ae7ab4ca8, []int{0, 0}
+}
+func (m *LogRecord_Field) XXX_Unmarshal(b []byte) error {
+	return m.Unmarshal(b)
+}
+func (m *LogRecord_Field) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+	b = b[:cap(b)]
+	n, err := m.MarshalToSizedBuffer(b)
+	if err != nil {
+		return nil, err
+	}
+	return b[:n], nil
+}
+func (m *LogRecord_Field) XXX_Merge(src proto.Message) {
+	xxx_messageInfo_LogRecord_Field.Merge(m, src)
+}
+func (m *LogRecord_Field) XXX_Size() int {
+	return m.Size()
+}
+func (m *LogRecord_Field) XXX_DiscardUnknown() {
+	xxx_messageInfo_LogRecord_Field.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_LogRecord_Field proto.InternalMessageInfo
+
+// StructuredRecord is a structured message recorded in a traced span.
+type StructuredRecord struct {
+	// Time of the structured record.
+	Time    time.Time  `protobuf:"bytes,1,opt,name=time,proto3,stdtime" json:"time"`
+	Payload *types.Any `protobuf:"bytes,2,opt,name=payload,proto3" json:"payload,omitempty"`
+}
+
+func (m *StructuredRecord) Reset()         { *m = StructuredRecord{} }
+func (m *StructuredRecord) String() string { return proto.CompactTextString(m) }
+func (*StructuredRecord) ProtoMessage()    {}
+func (*StructuredRecord) Descriptor() ([]byte, []int) {
+	return fileDescriptor_e9b7b35ae7ab4ca8, []int{1}
+}
+func (m *StructuredRecord) XXX_Unmarshal(b []byte) error {
+	return m.Unmarshal(b)
+}
+func (m *StructuredRecord) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+	b = b[:cap(b)]
+	n, err := m.MarshalToSizedBuffer(b)
+	if err != nil {
+		return nil, err
+	}
+	return b[:n], nil
+}
+func (m *StructuredRecord) XXX_Merge(src proto.Message) {
+	xxx_messageInfo_StructuredRecord.Merge(m, src)
+}
+func (m *StructuredRecord) XXX_Size() int {
+	return m.Size()
+}
+func (m *StructuredRecord) XXX_DiscardUnknown() {
+	xxx_messageInfo_StructuredRecord.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_StructuredRecord proto.InternalMessageInfo
+
+// OperationMetadata captures information corresponding to the operation that
+// a span is started with.
+type OperationMetadata struct {
+	// Duration represents the total time spent by spans tracing the operation.
+	Duration time.Duration `protobuf:"varint,1,opt,name=duration,proto3,casttype=time.Duration" json:"duration,omitempty"`
+	// Count represents the number of spans tracing the operation.
+	Count int64 `protobuf:"varint,2,opt,name=count,proto3" json:"count,omitempty"`
+	// ContainsUnfinished is true if the OperationMetadata contains information
+	// about unfinished spans tracing the operation.
+	ContainsUnfinished bool `protobuf:"varint,3,opt,name=contains_unfinished,json=containsUnfinished,proto3" json:"contains_unfinished,omitempty"`
+}
+
+func (m *OperationMetadata) Reset()      { *m = OperationMetadata{} }
+func (*OperationMetadata) ProtoMessage() {}
+func (*OperationMetadata) Descriptor() ([]byte, []int) {
+	return fileDescriptor_e9b7b35ae7ab4ca8, []int{2}
+}
+func (m *OperationMetadata) XXX_Unmarshal(b []byte) error {
+	return m.Unmarshal(b)
+}
+func (m *OperationMetadata) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+	b = b[:cap(b)]
+	n, err := m.MarshalToSizedBuffer(b)
+	if err != nil {
+		return nil, err
+	}
+	return b[:n], nil
+}
+func (m *OperationMetadata) XXX_Merge(src proto.Message) {
+	xxx_messageInfo_OperationMetadata.Merge(m, src)
+}
+func (m *OperationMetadata) XXX_Size() int {
+	return m.Size()
+}
+func (m *OperationMetadata) XXX_DiscardUnknown() {
+	xxx_messageInfo_OperationMetadata.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_OperationMetadata proto.InternalMessageInfo
+
+// RecordedSpan is the data recorded by a trace span. It
+// needs to be able to cross RPC boundaries so that the
+// complete recording of the trace can be constructed.
+type RecordedSpan struct {
+	// ID of the trace; spans that are part of the same hierarchy share
+	// the same trace ID.
+	TraceID TraceID `protobuf:"varint,1,opt,name=trace_id,json=traceId,proto3,customtype=TraceID" json:"trace_id"`
+	// ID of the span.
+	SpanID SpanID `protobuf:"varint,2,opt,name=span_id,json=spanId,proto3,customtype=SpanID" json:"span_id"`
+	// ID of the parent span.
+	ParentSpanID SpanID `protobuf:"varint,3,opt,name=parent_span_id,json=parentSpanId,proto3,customtype=SpanID" json:"parent_span_id"`
+	// Operation name.
+	Operation string `protobuf:"bytes,4,opt,name=operation,proto3" json:"operation,omitempty"`
+	// tag_groups describes tags associated with the span, potentially in a
+	// shallow structured hierarchy.
+	//
+	// A span may have at most one "anonymous" tag group, that is, a tag group
+	// without a Name. This is not enforced in the protobuf definition, but is
+	// expected in code.
+	//
+	// The tags in an anonymous group are not necessarily related, and should
+	// instead be treated as independent, top-level items. These tags are
+	// stored in a tag group for convenience.
+	TagGroups []TagGroup `protobuf:"bytes,18,rep,name=tag_groups,json=tagGroups,proto3" json:"tag_groups"`
+	// Time when the span was started.
+	StartTime time.Time `protobuf:"bytes,7,opt,name=start_time,json=startTime,proto3,stdtime" json:"start_time"`
+	// The span's duration, measured from start to Finish().
+	//
+	// A span whose recording is collected before it's finished will have the
+	// duration set as the "time of collection - start time". Such a span will
+	// have an "unfinished" tag and a `finished` boolean value of false in this
+	// recording.
+	Duration time.Duration `protobuf:"bytes,8,opt,name=duration,proto3,stdduration" json:"duration"`
+	// Events logged in the span.
+	Logs []LogRecord `protobuf:"bytes,9,rep,name=logs,proto3" json:"logs"`
+	// verbose indicates whether the span was recording in verbose mode at the
+	// time the recording was produced.
+	//
+	// This field is deprecated; it can be removed in 23.1. Use recording_mode
+	// instead.
+	Verbose bool `protobuf:"varint,16,opt,name=verbose,proto3" json:"verbose,omitempty"`
+	// recording_mode indicates the recording mode of the span at the the
+	// recording was produced.
+	RecordingMode RecordingMode `protobuf:"varint,17,opt,name=recording_mode,json=recordingMode,proto3,enum=cockroach.util.tracing.tracingpb.RecordingMode" json:"recording_mode,omitempty"`
+	// The ID of the goroutine on which the span was created.
+	GoroutineID uint64 `protobuf:"varint,12,opt,name=goroutine_id,json=goroutineId,proto3" json:"goroutine_id,omitempty"`
+	// True if the span has been Finish()ed, false otherwise.
+	Finished bool `protobuf:"varint,13,opt,name=finished,proto3" json:"finished,omitempty"`
+	// StructuredRecords contains StructuredRecord events recorded either in this
+	// span, or in children spans that have finished while our span was not
+	// recording verbosely.
+	//
+	// A StructuredRecord wraps the Payload with a RecordedAt timestamp to expose
+	// information about when this event occurred.
+	StructuredRecords []StructuredRecord `protobuf:"bytes,14,rep,name=structured_records,json=structuredRecords,proto3" json:"structured_records"`
+	// structured_records_size_bytes represents the total size of the logs in
+	// structured_records.
+	StructuredRecordsSizeBytes int64 `protobuf:"varint,20,opt,name=structured_records_size_bytes,json=structuredRecordsSizeBytes,proto3" json:"structured_records_size_bytes,omitempty"`
+	// ChildrenMetadata is a mapping from operation to the aggregated metadata of
+	// that operation.
+	//
+	// When a child of this span is Finish()ed, it updates the map with all the
+	// children in its Recording. ChildrenMetadata therefore provides a bucketed
+	// view of the various operations that are being traced as part of a span.
+	ChildrenMetadata map[string]OperationMetadata `protobuf:"bytes,19,rep,name=children_metadata,json=childrenMetadata,proto3" json:"children_metadata" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"`
+}
+
+func (m *RecordedSpan) Reset()      { *m = RecordedSpan{} }
+func (*RecordedSpan) ProtoMessage() {}
+func (*RecordedSpan) Descriptor() ([]byte, []int) {
+	return fileDescriptor_e9b7b35ae7ab4ca8, []int{3}
+}
+func (m *RecordedSpan) XXX_Unmarshal(b []byte) error {
+	return m.Unmarshal(b)
+}
+func (m *RecordedSpan) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+	b = b[:cap(b)]
+	n, err := m.MarshalToSizedBuffer(b)
+	if err != nil {
+		return nil, err
+	}
+	return b[:n], nil
+}
+func (m *RecordedSpan) XXX_Merge(src proto.Message) {
+	xxx_messageInfo_RecordedSpan.Merge(m, src)
+}
+func (m *RecordedSpan) XXX_Size() int {
+	return m.Size()
+}
+func (m *RecordedSpan) XXX_DiscardUnknown() {
+	xxx_messageInfo_RecordedSpan.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_RecordedSpan proto.InternalMessageInfo
+
+type TagGroup struct {
+	// May be empty. If so, indicates that contained Tags should be treated as
+	// top-level.
+	//
+	// If a value is instead present here, indicates that this group is a
+	// structured collection of related tags.
+	Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"`
+	Tags []Tag  `protobuf:"bytes,2,rep,name=tags,proto3" json:"tags"`
+}
+
+func (m *TagGroup) Reset()         { *m = TagGroup{} }
+func (m *TagGroup) String() string { return proto.CompactTextString(m) }
+func (*TagGroup) ProtoMessage()    {}
+func (*TagGroup) Descriptor() ([]byte, []int) {
+	return fileDescriptor_e9b7b35ae7ab4ca8, []int{4}
+}
+func (m *TagGroup) XXX_Unmarshal(b []byte) error {
+	return m.Unmarshal(b)
+}
+func (m *TagGroup) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+	b = b[:cap(b)]
+	n, err := m.MarshalToSizedBuffer(b)
+	if err != nil {
+		return nil, err
+	}
+	return b[:n], nil
+}
+func (m *TagGroup) XXX_Merge(src proto.Message) {
+	xxx_messageInfo_TagGroup.Merge(m, src)
+}
+func (m *TagGroup) XXX_Size() int {
+	return m.Size()
+}
+func (m *TagGroup) XXX_DiscardUnknown() {
+	xxx_messageInfo_TagGroup.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_TagGroup proto.InternalMessageInfo
+
+type Tag struct {
+	// key is the name of the tag. This is a safe value.
+	Key string `protobuf:"bytes,1,opt,name=key,proto3" json:"key,omitempty"`
+	// value is the value of the tag. This is NOT a safe value.
+	// It may contain PII or other sensitive information.
+	// TODO(knz): we should deprecate this field, and define
+	// a new value field with type RedactableString.
+	Value string `protobuf:"bytes,2,opt,name=value,proto3" json:"value,omitempty"`
+}
+
+func (m *Tag) Reset()         { *m = Tag{} }
+func (m *Tag) String() string { return proto.CompactTextString(m) }
+func (*Tag) ProtoMessage()    {}
+func (*Tag) Descriptor() ([]byte, []int) {
+	return fileDescriptor_e9b7b35ae7ab4ca8, []int{5}
+}
+func (m *Tag) XXX_Unmarshal(b []byte) error {
+	return m.Unmarshal(b)
+}
+func (m *Tag) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+	b = b[:cap(b)]
+	n, err := m.MarshalToSizedBuffer(b)
+	if err != nil {
+		return nil, err
+	}
+	return b[:n], nil
+}
+func (m *Tag) XXX_Merge(src proto.Message) {
+	xxx_messageInfo_Tag.Merge(m, src)
+}
+func (m *Tag) XXX_Size() int {
+	return m.Size()
+}
+func (m *Tag) XXX_DiscardUnknown() {
+	xxx_messageInfo_Tag.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_Tag proto.InternalMessageInfo
+
+// NormalizedSpan is a representation of a RecordedSpan from a trace with all
+// its children embedded, recursively. This JSON serialization of this proto is
+// used in the system.statement_diagnostics.trace column.
+//
+// See RecordedSpan for the description of the fields.
+type NormalizedSpan struct {
+	Operation string `protobuf:"bytes,1,opt,name=operation,proto3" json:"operation,omitempty"`
+	// Deprecated. Avoid new uses. Prefer tag_groups.
+	// TODO(benbardin): Deprecate the tags field for 23.1.
+	Tags              map[string]string            `protobuf:"bytes,2,rep,name=tags,proto3" json:"tags,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"`
+	TagGroups         []TagGroup                   `protobuf:"bytes,8,rep,name=tag_groups,json=tagGroups,proto3" json:"tag_groups"`
+	StartTime         time.Time                    `protobuf:"bytes,3,opt,name=start_time,json=startTime,proto3,stdtime" json:"start_time"`
+	Duration          time.Duration                `protobuf:"bytes,4,opt,name=duration,proto3,stdduration" json:"duration"`
+	Logs              []LogRecord                  `protobuf:"bytes,5,rep,name=logs,proto3" json:"logs"`
+	StructuredRecords []StructuredRecord           `protobuf:"bytes,7,rep,name=structured_records,json=structuredRecords,proto3" json:"structured_records"`
+	ChildrenMetadata  map[string]OperationMetadata `protobuf:"bytes,9,rep,name=children_metadata,json=childrenMetadata,proto3" json:"children_metadata" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"`
+	Children          []NormalizedSpan             `protobuf:"bytes,6,rep,name=children,proto3" json:"children"`
+}
+
+func (m *NormalizedSpan) Reset()         { *m = NormalizedSpan{} }
+func (m *NormalizedSpan) String() string { return proto.CompactTextString(m) }
+func (*NormalizedSpan) ProtoMessage()    {}
+func (*NormalizedSpan) Descriptor() ([]byte, []int) {
+	return fileDescriptor_e9b7b35ae7ab4ca8, []int{6}
+}
+func (m *NormalizedSpan) XXX_Unmarshal(b []byte) error {
+	return m.Unmarshal(b)
+}
+func (m *NormalizedSpan) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+	b = b[:cap(b)]
+	n, err := m.MarshalToSizedBuffer(b)
+	if err != nil {
+		return nil, err
+	}
+	return b[:n], nil
+}
+func (m *NormalizedSpan) XXX_Merge(src proto.Message) {
+	xxx_messageInfo_NormalizedSpan.Merge(m, src)
+}
+func (m *NormalizedSpan) XXX_Size() int {
+	return m.Size()
+}
+func (m *NormalizedSpan) XXX_DiscardUnknown() {
+	xxx_messageInfo_NormalizedSpan.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_NormalizedSpan proto.InternalMessageInfo
+
+type CapturedStack struct {
+	// Stack is the strack trace, or distinct prefix of the stack trace if a previous
+	// capture of this stack is also being recorded.
+	Stack string `protobuf:"bytes,1,opt,name=stack,proto3" json:"stack,omitempty"`
+	// SharedSuffix indicates the length of the elided suffix of this stack that
+	// was identical to the previous capture of this stack.
+	SharedSuffix int32 `protobuf:"varint,2,opt,name=shared_suffix,json=sharedSuffix,proto3" json:"shared_suffix,omitempty"`
+	// SharedLines indicated how many newlines were in the elided shared suffix.
+	SharedLines int32 `protobuf:"varint,3,opt,name=shared_lines,json=sharedLines,proto3" json:"shared_lines,omitempty"`
+	// Age indicates the duration prior to being recorded that this stack was captured.
+	Age time.Duration `protobuf:"varint,4,opt,name=age,proto3,casttype=time.Duration" json:"age,omitempty"`
+}
+
+func (m *CapturedStack) Reset()      { *m = CapturedStack{} }
+func (*CapturedStack) ProtoMessage() {}
+func (*CapturedStack) Descriptor() ([]byte, []int) {
+	return fileDescriptor_e9b7b35ae7ab4ca8, []int{7}
+}
+func (m *CapturedStack) XXX_Unmarshal(b []byte) error {
+	return m.Unmarshal(b)
+}
+func (m *CapturedStack) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+	b = b[:cap(b)]
+	n, err := m.MarshalToSizedBuffer(b)
+	if err != nil {
+		return nil, err
+	}
+	return b[:n], nil
+}
+func (m *CapturedStack) XXX_Merge(src proto.Message) {
+	xxx_messageInfo_CapturedStack.Merge(m, src)
+}
+func (m *CapturedStack) XXX_Size() int {
+	return m.Size()
+}
+func (m *CapturedStack) XXX_DiscardUnknown() {
+	xxx_messageInfo_CapturedStack.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_CapturedStack proto.InternalMessageInfo
+
+func init() {
+	proto.RegisterType((*LogRecord)(nil), "cockroach.parser.util.tracing.tracingpb.LogRecord")
+	proto.RegisterType((*LogRecord_Field)(nil), "cockroach.parser.util.tracing.tracingpb.LogRecord.Field")
+	proto.RegisterType((*StructuredRecord)(nil), "cockroach.parser.util.tracing.tracingpb.StructuredRecord")
+	proto.RegisterType((*OperationMetadata)(nil), "cockroach.parser.util.tracing.tracingpb.OperationMetadata")
+	proto.RegisterType((*RecordedSpan)(nil), "cockroach.parser.util.tracing.tracingpb.RecordedSpan")
+	proto.RegisterMapType((map[string]OperationMetadata)(nil), "cockroach.parser.util.tracing.tracingpb.RecordedSpan.ChildrenMetadataEntry")
+	proto.RegisterType((*TagGroup)(nil), "cockroach.parser.util.tracing.tracingpb.TagGroup")
+	proto.RegisterType((*Tag)(nil), "cockroach.parser.util.tracing.tracingpb.Tag")
+	proto.RegisterType((*NormalizedSpan)(nil), "cockroach.parser.util.tracing.tracingpb.NormalizedSpan")
+	proto.RegisterMapType((map[string]OperationMetadata)(nil), "cockroach.parser.util.tracing.tracingpb.NormalizedSpan.ChildrenMetadataEntry")
+	proto.RegisterMapType((map[string]string)(nil), "cockroach.parser.util.tracing.tracingpb.NormalizedSpan.TagsEntry")
+	proto.RegisterType((*CapturedStack)(nil), "cockroach.parser.util.tracing.tracingpb.CapturedStack")
+}
+
+func init() {
+	proto.RegisterFile("util/tracing/tracingpb/recorded_span.proto", fileDescriptor_e9b7b35ae7ab4ca8)
+}
+
+var fileDescriptor_e9b7b35ae7ab4ca8 = []byte{
+	// 1133 bytes of a gzipped FileDescriptorProto
+	0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xc4, 0x56, 0x4b, 0x6f, 0xdb, 0x46,
+	0x17, 0x15, 0x25, 0x4a, 0xa2, 0x46, 0xb2, 0x43, 0x4f, 0xfc, 0x01, 0x8c, 0xf0, 0x55, 0x72, 0x95,
+	0x16, 0x30, 0x52, 0x84, 0x6a, 0x15, 0xb4, 0x0d, 0xd2, 0x45, 0x10, 0xc5, 0x49, 0x20, 0xc1, 0x79,
+	0x80, 0x72, 0xbb, 0x28, 0x50, 0x10, 0x23, 0x72, 0x4c, 0x13, 0x96, 0x38, 0x04, 0x67, 0x98, 0x46,
+	0x46, 0xd7, 0xed, 0xb2, 0x59, 0x7a, 0xd9, 0x9f, 0xe3, 0x65, 0x96, 0x41, 0x17, 0x6e, 0x2b, 0xff,
+	0x8b, 0x6e, 0x5a, 0xcc, 0x70, 0x48, 0xdb, 0x92, 0x0c, 0xd9, 0x70, 0x80, 0xae, 0x34, 0x8f, 0x7b,
+	0xee, 0x3d, 0x73, 0x1f, 0x47, 0x04, 0x77, 0x62, 0xe6, 0x8f, 0xda, 0x2c, 0x42, 0x8e, 0x1f, 0x78,
+	0xe9, 0x6f, 0x38, 0x6c, 0x47, 0xd8, 0x21, 0x91, 0x8b, 0x5d, 0x9b, 0x86, 0x28, 0x30, 0xc3, 0x88,
+	0x30, 0x02, 0x37, 0x1c, 0xe2, 0xec, 0x47, 0x04, 0x39, 0x7b, 0x26, 0x47, 0x99, 0xd2, 0xda, 0xcc,
+	0x50, 0xf5, 0x75, 0x8f, 0x78, 0x44, 0x18, 0xb7, 0xf9, 0x2a, 0xc1, 0xd5, 0x6f, 0x79, 0x84, 0x78,
+	0x23, 0xdc, 0x16, 0xbb, 0x61, 0xbc, 0xdb, 0x46, 0xc1, 0x44, 0x5e, 0x35, 0x67, 0xaf, 0x98, 0x3f,
+	0xc6, 0x94, 0xa1, 0x71, 0x28, 0x0d, 0x1a, 0xb3, 0x06, 0x6e, 0x1c, 0x21, 0xe6, 0x13, 0xc9, 0xa9,
+	0xfe, 0xc9, 0x05, 0xfc, 0x53, 0x6e, 0xc2, 0xaa, 0xf5, 0x73, 0x1e, 0x54, 0xb6, 0x89, 0x67, 0x89,
+	0x47, 0xc1, 0xfb, 0x40, 0xe5, 0x61, 0x0c, 0x65, 0x43, 0xd9, 0xac, 0x76, 0xea, 0x66, 0x12, 0xc2,
+	0x4c, 0x43, 0x98, 0x3b, 0x29, 0x87, 0xae, 0x76, 0x74, 0xdc, 0xcc, 0xbd, 0xfd, 0xa3, 0xa9, 0x58,
+	0x02, 0x01, 0x5f, 0x81, 0xf2, 0x18, 0x53, 0x8a, 0x3c, 0x6c, 0x14, 0x36, 0x94, 0xcd, 0x4a, 0xf7,
+	0x2b, 0x6e, 0xf0, 0xfb, 0x71, 0xd3, 0xf4, 0x7c, 0xb6, 0x17, 0x0f, 0x4d, 0x87, 0x8c, 0xdb, 0x59,
+	0x96, 0x5c, 0x9e, 0x46, 0x17, 0x39, 0xcc, 0xb4, 0xc4, 0x0f, 0x1a, 0x8e, 0xf0, 0x80, 0x45, 0x7e,
+	0xe0, 0x59, 0xa9, 0x9b, 0xba, 0x07, 0x8a, 0x4f, 0x7d, 0x3c, 0x72, 0xa1, 0x0e, 0x0a, 0xfb, 0x78,
+	0x22, 0x38, 0x55, 0x2c, 0xbe, 0x84, 0xdb, 0xa0, 0xf8, 0x1a, 0x8d, 0x62, 0x6c, 0xe4, 0xaf, 0x15,
+	0x2a, 0x71, 0xd2, 0x57, 0xb5, 0xbc, 0x5e, 0x68, 0xfd, 0x04, 0xf4, 0x01, 0x8b, 0x62, 0x87, 0xc5,
+	0x11, 0x76, 0xaf, 0x9d, 0x0e, 0x13, 0x94, 0x43, 0x34, 0x19, 0x11, 0xe4, 0x0a, 0x8e, 0xd5, 0xce,
+	0xfa, 0x1c, 0xf8, 0x51, 0x30, 0xb1, 0x52, 0xa3, 0xd6, 0xaf, 0x0a, 0x58, 0x7b, 0x19, 0xe2, 0xa4,
+	0x80, 0xcf, 0x31, 0x43, 0x2e, 0x62, 0x08, 0xde, 0x05, 0x5a, 0x5a, 0x54, 0xc1, 0xa1, 0xd0, 0x5d,
+	0xfb, 0xfb, 0xb8, 0xb9, 0xc2, 0x23, 0x98, 0x5b, 0xf2, 0xc2, 0xca, 0x4c, 0xe0, 0x3a, 0x28, 0x3a,
+	0x24, 0x0e, 0x98, 0x08, 0x59, 0xb0, 0x92, 0x0d, 0x6c, 0x83, 0x9b, 0x0e, 0x09, 0x18, 0xf2, 0x03,
+	0x6a, 0xc7, 0xc1, 0xae, 0x1f, 0xf8, 0x74, 0x0f, 0xbb, 0xa2, 0x4a, 0x9a, 0x05, 0xd3, 0xab, 0x6f,
+	0xb3, 0x9b, 0x07, 0xea, 0xe1, 0x6f, 0xcd, 0x5c, 0xeb, 0x1f, 0x0d, 0xd4, 0x2c, 0xd9, 0xea, 0x83,
+	0x10, 0x05, 0xf0, 0x4b, 0xa0, 0xf1, 0xd6, 0xc1, 0xb6, 0xef, 0x0a, 0x32, 0x6a, 0xb7, 0x2e, 0xf3,
+	0x5e, 0xde, 0xe1, 0xe7, 0xbd, 0xad, 0xe9, 0xe9, 0xd2, 0x2a, 0x0b, 0xdb, 0x9e, 0x0b, 0xbf, 0x00,
+	0x65, 0x3e, 0x28, 0x1c, 0x95, 0x17, 0x28, 0x43, 0xa2, 0x4a, 0xdc, 0xab, 0x00, 0xc9, 0x95, 0x55,
+	0xe2, 0x86, 0x3d, 0x17, 0x6e, 0x81, 0xd5, 0x10, 0x45, 0x38, 0x60, 0x76, 0x8a, 0x2c, 0x08, 0x64,
+	0x63, 0x0e, 0x59, 0x7b, 0x25, 0xec, 0x24, 0xbe, 0x16, 0x9e, 0xee, 0x5c, 0xf8, 0x7f, 0x50, 0x21,
+	0x69, 0x46, 0x0d, 0x55, 0x34, 0xcf, 0xe9, 0x01, 0x7c, 0x09, 0x00, 0x43, 0x9e, 0xed, 0x45, 0x24,
+	0x0e, 0xa9, 0x01, 0x37, 0x0a, 0x9b, 0xd5, 0xce, 0x1d, 0x73, 0xd9, 0x18, 0x9b, 0x3b, 0xc8, 0x7b,
+	0xc6, 0x21, 0x5d, 0x95, 0x73, 0xb1, 0x2a, 0x4c, 0xee, 0x29, 0x7c, 0x0c, 0x00, 0x65, 0x28, 0x62,
+	0xb6, 0xe8, 0x98, 0xf2, 0x15, 0x3a, 0xa6, 0x22, 0x70, 0xfc, 0x06, 0x3e, 0x3c, 0x53, 0x70, 0x4d,
+	0xb8, 0xb8, 0x35, 0xe7, 0x22, 0x2d, 0x7c, 0xe2, 0xe1, 0x90, 0x7b, 0x38, 0x6d, 0x81, 0x27, 0x40,
+	0x1d, 0x11, 0x8f, 0x1a, 0x15, 0xf1, 0xa0, 0xcf, 0x96, 0x3f, 0x28, 0x9b, 0x7d, 0xf9, 0x22, 0x01,
+	0x87, 0x06, 0x28, 0xbf, 0xc6, 0xd1, 0x90, 0x50, 0x6c, 0xe8, 0xa2, 0x4f, 0xd2, 0x2d, 0xfc, 0x0e,
+	0xac, 0x26, 0x02, 0xe8, 0x07, 0x9e, 0x3d, 0x26, 0x2e, 0x36, 0xd6, 0x36, 0x94, 0xcd, 0xd5, 0x4e,
+	0x7b, 0x79, 0x28, 0x2b, 0xc5, 0x3d, 0x27, 0x2e, 0xb6, 0x56, 0xa2, 0xb3, 0x5b, 0xd8, 0x01, 0x35,
+	0x8f, 0x44, 0x24, 0x66, 0x7e, 0x20, 0x3a, 0xac, 0x26, 0x2a, 0x7e, 0x63, 0x7a, 0xdc, 0xac, 0x3e,
+	0x4b, 0xcf, 0x7b, 0x5b, 0x56, 0x35, 0x33, 0xea, 0xb9, 0xb0, 0x0e, 0xb4, 0xac, 0x9d, 0x57, 0x04,
+	0xcd, 0x6c, 0x0f, 0x3d, 0x00, 0x69, 0x36, 0xce, 0x76, 0x12, 0x8b, 0x1a, 0xab, 0x22, 0x2d, 0x9d,
+	0xe5, 0x5c, 0x67, 0xa5, 0x40, 0x66, 0x67, 0x8d, 0xce, 0x9c, 0x53, 0xf8, 0x08, 0x7c, 0x34, 0x1f,
+	0xc8, 0xa6, 0xfe, 0x01, 0xb6, 0x87, 0x13, 0x86, 0xa9, 0xb1, 0x2e, 0x86, 0xb1, 0x3e, 0x87, 0x1c,
+	0xf8, 0x07, 0xb8, 0xcb, 0x2d, 0xe0, 0x8f, 0x60, 0xcd, 0xd9, 0xf3, 0x47, 0x6e, 0x84, 0x03, 0x7b,
+	0x2c, 0x67, 0xdf, 0xb8, 0x29, 0xa8, 0x6e, 0x5d, 0x36, 0xad, 0xc9, 0x90, 0x9a, 0x8f, 0xa5, 0x9f,
+	0x54, 0x42, 0x9e, 0x04, 0x2c, 0x9a, 0x48, 0xf2, 0xba, 0x33, 0x73, 0x59, 0x7f, 0x03, 0xfe, 0xb7,
+	0x10, 0xb0, 0x40, 0x72, 0x7b, 0x67, 0x25, 0xb7, 0xda, 0xb9, 0xb7, 0x9c, 0xd7, 0x9c, 0x9c, 0x49,
+	0xbd, 0x7d, 0x90, 0xbf, 0xaf, 0x24, 0x1a, 0xd3, 0x57, 0xb5, 0xa2, 0x5e, 0xea, 0xab, 0x5a, 0x49,
+	0x2f, 0xf7, 0x55, 0x0d, 0xe8, 0xd5, 0xbe, 0xaa, 0x55, 0xf5, 0x5a, 0x5f, 0xd5, 0x6e, 0xe8, 0x7a,
+	0xcb, 0x06, 0x5a, 0x3a, 0x6e, 0x10, 0x02, 0x35, 0x40, 0x52, 0x89, 0x2b, 0x96, 0x58, 0xc3, 0x87,
+	0x40, 0x65, 0xc8, 0xa3, 0x46, 0x5e, 0x64, 0xea, 0xd3, 0x4b, 0x0d, 0x6f, 0xda, 0xe5, 0x1c, 0xd8,
+	0xba, 0x0b, 0x0a, 0x3b, 0xc8, 0x5b, 0xf0, 0xd8, 0xf5, 0x73, 0xff, 0x2f, 0x92, 0x77, 0xeb, 0x97,
+	0x32, 0x58, 0x7d, 0x41, 0xa2, 0x31, 0x1a, 0xf9, 0x07, 0x52, 0x13, 0xcf, 0x69, 0x8c, 0x32, 0xab,
+	0x31, 0x2f, 0xce, 0x11, 0x7c, 0xb0, 0x9c, 0xe0, 0x79, 0xef, 0x9c, 0x2f, 0x15, 0xf5, 0x48, 0xf8,
+	0xce, 0x68, 0x96, 0xf6, 0xa1, 0x35, 0xab, 0x70, 0x7d, 0xcd, 0x52, 0xaf, 0xa3, 0x59, 0xc5, 0xeb,
+	0x69, 0xd6, 0xe2, 0x89, 0x2f, 0x7f, 0xf8, 0x89, 0x9f, 0x2c, 0x1a, 0xd7, 0x44, 0x70, 0x9f, 0x5e,
+	0xb9, 0xc6, 0x57, 0x1a, 0x58, 0x68, 0x01, 0x2d, 0x3d, 0x33, 0x4a, 0x22, 0xe2, 0xe7, 0x57, 0x8d,
+	0x28, 0x7d, 0x67, 0x7e, 0xea, 0x5f, 0x83, 0x4a, 0xd6, 0x68, 0x97, 0x9d, 0x05, 0x3e, 0xc3, 0xff,
+	0x9d, 0x7a, 0xb4, 0x0e, 0x15, 0xb0, 0xf2, 0x18, 0x85, 0xa2, 0x2a, 0x03, 0x86, 0x9c, 0x7d, 0xce,
+	0x92, 0xf2, 0x85, 0x0c, 0x9a, 0x6c, 0xe0, 0x6d, 0xb0, 0x42, 0xf7, 0x10, 0x6f, 0x07, 0x1a, 0xef,
+	0xee, 0xfa, 0x6f, 0x44, 0xf8, 0xa2, 0x55, 0x4b, 0x0e, 0x07, 0xe2, 0x0c, 0x7e, 0x0c, 0xe4, 0xde,
+	0x1e, 0xf9, 0x01, 0xa6, 0x62, 0x0c, 0x8a, 0x56, 0x35, 0x39, 0xdb, 0xe6, 0x47, 0xf0, 0x36, 0x28,
+	0xf0, 0x0f, 0x5b, 0xf5, 0xa2, 0x4f, 0x30, 0x7e, 0x9b, 0x48, 0x5a, 0xf7, 0x87, 0xa3, 0xbf, 0x1a,
+	0xb9, 0xa3, 0x69, 0x43, 0x79, 0x37, 0x6d, 0x28, 0xef, 0xa7, 0x0d, 0xe5, 0xcf, 0x69, 0x43, 0x79,
+	0x7b, 0xd2, 0xc8, 0xbd, 0x3b, 0x69, 0xe4, 0xde, 0x9f, 0x34, 0x72, 0xdf, 0x7f, 0x73, 0xc1, 0x57,
+	0x6a, 0xb6, 0x6e, 0x87, 0xfb, 0x5e, 0x7b, 0xf1, 0xc7, 0xfb, 0xb0, 0x24, 0x46, 0xea, 0xde, 0xbf,
+	0x01, 0x00, 0x00, 0xff, 0xff, 0x55, 0xcb, 0x88, 0xc0, 0x9d, 0x0c, 0x00, 0x00,
+}
+
+func (m *LogRecord) Marshal() (dAtA []byte, err error) {
+	size := m.Size()
+	dAtA = make([]byte, size)
+	n, err := m.MarshalToSizedBuffer(dAtA[:size])
+	if err != nil {
+		return nil, err
+	}
+	return dAtA[:n], nil
+}
+
+func (m *LogRecord) MarshalTo(dAtA []byte) (int, error) {
+	size := m.Size()
+	return m.MarshalToSizedBuffer(dAtA[:size])
+}
+
+func (m *LogRecord) MarshalToSizedBuffer(dAtA []byte) (int, error) {
+	i := len(dAtA)
+	_ = i
+	var l int
+	_ = l
+	if len(m.Message) > 0 {
+		i -= len(m.Message)
+		copy(dAtA[i:], m.Message)
+		i = encodeVarintRecordedSpan(dAtA, i, uint64(len(m.Message)))
+		i--
+		dAtA[i] = 0x1a
+	}
+	n1, err1 := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.Time, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(m.Time):])
+	if err1 != nil {
+		return 0, err1
+	}
+	i -= n1
+	i = encodeVarintRecordedSpan(dAtA, i, uint64(n1))
+	i--
+	dAtA[i] = 0xa
+	return len(dAtA) - i, nil
+}
+
+func (m *LogRecord_Field) Marshal() (dAtA []byte, err error) {
+	size := m.Size()
+	dAtA = make([]byte, size)
+	n, err := m.MarshalToSizedBuffer(dAtA[:size])
+	if err != nil {
+		return nil, err
+	}
+	return dAtA[:n], nil
+}
+
+func (m *LogRecord_Field) MarshalTo(dAtA []byte) (int, error) {
+	size := m.Size()
+	return m.MarshalToSizedBuffer(dAtA[:size])
+}
+
+func (m *LogRecord_Field) MarshalToSizedBuffer(dAtA []byte) (int, error) {
+	i := len(dAtA)
+	_ = i
+	var l int
+	_ = l
+	if len(m.Value) > 0 {
+		i -= len(m.Value)
+		copy(dAtA[i:], m.Value)
+		i = encodeVarintRecordedSpan(dAtA, i, uint64(len(m.Value)))
+		i--
+		dAtA[i] = 0x12
+	}
+	if len(m.Key) > 0 {
+		i -= len(m.Key)
+		copy(dAtA[i:], m.Key)
+		i = encodeVarintRecordedSpan(dAtA, i, uint64(len(m.Key)))
+		i--
+		dAtA[i] = 0xa
+	}
+	return len(dAtA) - i, nil
+}
+
+func (m *StructuredRecord) Marshal() (dAtA []byte, err error) {
+	size := m.Size()
+	dAtA = make([]byte, size)
+	n, err := m.MarshalToSizedBuffer(dAtA[:size])
+	if err != nil {
+		return nil, err
+	}
+	return dAtA[:n], nil
+}
+
+func (m *StructuredRecord) MarshalTo(dAtA []byte) (int, error) {
+	size := m.Size()
+	return m.MarshalToSizedBuffer(dAtA[:size])
+}
+
+func (m *StructuredRecord) MarshalToSizedBuffer(dAtA []byte) (int, error) {
+	i := len(dAtA)
+	_ = i
+	var l int
+	_ = l
+	if m.Payload != nil {
+		{
+			size, err := m.Payload.MarshalToSizedBuffer(dAtA[:i])
+			if err != nil {
+				return 0, err
+			}
+			i -= size
+			i = encodeVarintRecordedSpan(dAtA, i, uint64(size))
+		}
+		i--
+		dAtA[i] = 0x12
+	}
+	n3, err3 := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.Time, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(m.Time):])
+	if err3 != nil {
+		return 0, err3
+	}
+	i -= n3
+	i = encodeVarintRecordedSpan(dAtA, i, uint64(n3))
+	i--
+	dAtA[i] = 0xa
+	return len(dAtA) - i, nil
+}
+
+func (m *OperationMetadata) Marshal() (dAtA []byte, err error) {
+	size := m.Size()
+	dAtA = make([]byte, size)
+	n, err := m.MarshalToSizedBuffer(dAtA[:size])
+	if err != nil {
+		return nil, err
+	}
+	return dAtA[:n], nil
+}
+
+func (m *OperationMetadata) MarshalTo(dAtA []byte) (int, error) {
+	size := m.Size()
+	return m.MarshalToSizedBuffer(dAtA[:size])
+}
+
+func (m *OperationMetadata) MarshalToSizedBuffer(dAtA []byte) (int, error) {
+	i := len(dAtA)
+	_ = i
+	var l int
+	_ = l
+	if m.ContainsUnfinished {
+		i--
+		if m.ContainsUnfinished {
+			dAtA[i] = 1
+		} else {
+			dAtA[i] = 0
+		}
+		i--
+		dAtA[i] = 0x18
+	}
+	if m.Count != 0 {
+		i = encodeVarintRecordedSpan(dAtA, i, uint64(m.Count))
+		i--
+		dAtA[i] = 0x10
+	}
+	if m.Duration != 0 {
+		i = encodeVarintRecordedSpan(dAtA, i, uint64(m.Duration))
+		i--
+		dAtA[i] = 0x8
+	}
+	return len(dAtA) - i, nil
+}
+
+func (m *RecordedSpan) Marshal() (dAtA []byte, err error) {
+	size := m.Size()
+	dAtA = make([]byte, size)
+	n, err := m.MarshalToSizedBuffer(dAtA[:size])
+	if err != nil {
+		return nil, err
+	}
+	return dAtA[:n], nil
+}
+
+func (m *RecordedSpan) MarshalTo(dAtA []byte) (int, error) {
+	size := m.Size()
+	return m.MarshalToSizedBuffer(dAtA[:size])
+}
+
+func (m *RecordedSpan) MarshalToSizedBuffer(dAtA []byte) (int, error) {
+	i := len(dAtA)
+	_ = i
+	var l int
+	_ = l
+	if m.StructuredRecordsSizeBytes != 0 {
+		i = encodeVarintRecordedSpan(dAtA, i, uint64(m.StructuredRecordsSizeBytes))
+		i--
+		dAtA[i] = 0x1
+		i--
+		dAtA[i] = 0xa0
+	}
+	if len(m.ChildrenMetadata) > 0 {
+		keysForChildrenMetadata := make([]string, 0, len(m.ChildrenMetadata))
+		for k := range m.ChildrenMetadata {
+			keysForChildrenMetadata = append(keysForChildrenMetadata, string(k))
+		}
+		github_com_gogo_protobuf_sortkeys.Strings(keysForChildrenMetadata)
+		for iNdEx := len(keysForChildrenMetadata) - 1; iNdEx >= 0; iNdEx-- {
+			v := m.ChildrenMetadata[string(keysForChildrenMetadata[iNdEx])]
+			baseI := i
+			{
+				size, err := (&v).MarshalToSizedBuffer(dAtA[:i])
+				if err != nil {
+					return 0, err
+				}
+				i -= size
+				i = encodeVarintRecordedSpan(dAtA, i, uint64(size))
+			}
+			i--
+			dAtA[i] = 0x12
+			i -= len(keysForChildrenMetadata[iNdEx])
+			copy(dAtA[i:], keysForChildrenMetadata[iNdEx])
+			i = encodeVarintRecordedSpan(dAtA, i, uint64(len(keysForChildrenMetadata[iNdEx])))
+			i--
+			dAtA[i] = 0xa
+			i = encodeVarintRecordedSpan(dAtA, i, uint64(baseI-i))
+			i--
+			dAtA[i] = 0x1
+			i--
+			dAtA[i] = 0x9a
+		}
+	}
+	if len(m.TagGroups) > 0 {
+		for iNdEx := len(m.TagGroups) - 1; iNdEx >= 0; iNdEx-- {
+			{
+				size, err := m.TagGroups[iNdEx].MarshalToSizedBuffer(dAtA[:i])
+				if err != nil {
+					return 0, err
+				}
+				i -= size
+				i = encodeVarintRecordedSpan(dAtA, i, uint64(size))
+			}
+			i--
+			dAtA[i] = 0x1
+			i--
+			dAtA[i] = 0x92
+		}
+	}
+	if m.RecordingMode != 0 {
+		i = encodeVarintRecordedSpan(dAtA, i, uint64(m.RecordingMode))
+		i--
+		dAtA[i] = 0x1
+		i--
+		dAtA[i] = 0x88
+	}
+	if m.Verbose {
+		i--
+		if m.Verbose {
+			dAtA[i] = 1
+		} else {
+			dAtA[i] = 0
+		}
+		i--
+		dAtA[i] = 0x1
+		i--
+		dAtA[i] = 0x80
+	}
+	if len(m.StructuredRecords) > 0 {
+		for iNdEx := len(m.StructuredRecords) - 1; iNdEx >= 0; iNdEx-- {
+			{
+				size, err := m.StructuredRecords[iNdEx].MarshalToSizedBuffer(dAtA[:i])
+				if err != nil {
+					return 0, err
+				}
+				i -= size
+				i = encodeVarintRecordedSpan(dAtA, i, uint64(size))
+			}
+			i--
+			dAtA[i] = 0x72
+		}
+	}
+	if m.Finished {
+		i--
+		if m.Finished {
+			dAtA[i] = 1
+		} else {
+			dAtA[i] = 0
+		}
+		i--
+		dAtA[i] = 0x68
+	}
+	if m.GoroutineID != 0 {
+		i = encodeVarintRecordedSpan(dAtA, i, uint64(m.GoroutineID))
+		i--
+		dAtA[i] = 0x60
+	}
+	if len(m.Logs) > 0 {
+		for iNdEx := len(m.Logs) - 1; iNdEx >= 0; iNdEx-- {
+			{
+				size, err := m.Logs[iNdEx].MarshalToSizedBuffer(dAtA[:i])
+				if err != nil {
+					return 0, err
+				}
+				i -= size
+				i = encodeVarintRecordedSpan(dAtA, i, uint64(size))
+			}
+			i--
+			dAtA[i] = 0x4a
+		}
+	}
+	if m.Duration != 0 {
+		n5, err5 := github_com_gogo_protobuf_types.StdDurationMarshalTo(m.Duration, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdDuration(m.Duration):])
+		if err5 != nil {
+			return 0, err5
+		}
+		i -= n5
+		i = encodeVarintRecordedSpan(dAtA, i, uint64(n5))
+		i--
+		dAtA[i] = 0x42
+	}
+	n6, err6 := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.StartTime, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(m.StartTime):])
+	if err6 != nil {
+		return 0, err6
+	}
+	i -= n6
+	i = encodeVarintRecordedSpan(dAtA, i, uint64(n6))
+	i--
+	dAtA[i] = 0x3a
+	if len(m.Operation) > 0 {
+		i -= len(m.Operation)
+		copy(dAtA[i:], m.Operation)
+		i = encodeVarintRecordedSpan(dAtA, i, uint64(len(m.Operation)))
+		i--
+		dAtA[i] = 0x22
+	}
+	if m.ParentSpanID != 0 {
+		i = encodeVarintRecordedSpan(dAtA, i, uint64(m.ParentSpanID))
+		i--
+		dAtA[i] = 0x18
+	}
+	if m.SpanID != 0 {
+		i = encodeVarintRecordedSpan(dAtA, i, uint64(m.SpanID))
+		i--
+		dAtA[i] = 0x10
+	}
+	if m.TraceID != 0 {
+		i = encodeVarintRecordedSpan(dAtA, i, uint64(m.TraceID))
+		i--
+		dAtA[i] = 0x8
+	}
+	return len(dAtA) - i, nil
+}
+
+func (m *TagGroup) Marshal() (dAtA []byte, err error) {
+	size := m.Size()
+	dAtA = make([]byte, size)
+	n, err := m.MarshalToSizedBuffer(dAtA[:size])
+	if err != nil {
+		return nil, err
+	}
+	return dAtA[:n], nil
+}
+
+func (m *TagGroup) MarshalTo(dAtA []byte) (int, error) {
+	size := m.Size()
+	return m.MarshalToSizedBuffer(dAtA[:size])
+}
+
+func (m *TagGroup) MarshalToSizedBuffer(dAtA []byte) (int, error) {
+	i := len(dAtA)
+	_ = i
+	var l int
+	_ = l
+	if len(m.Tags) > 0 {
+		for iNdEx := len(m.Tags) - 1; iNdEx >= 0; iNdEx-- {
+			{
+				size, err := m.Tags[iNdEx].MarshalToSizedBuffer(dAtA[:i])
+				if err != nil {
+					return 0, err
+				}
+				i -= size
+				i = encodeVarintRecordedSpan(dAtA, i, uint64(size))
+			}
+			i--
+			dAtA[i] = 0x12
+		}
+	}
+	if len(m.Name) > 0 {
+		i -= len(m.Name)
+		copy(dAtA[i:], m.Name)
+		i = encodeVarintRecordedSpan(dAtA, i, uint64(len(m.Name)))
+		i--
+		dAtA[i] = 0xa
+	}
+	return len(dAtA) - i, nil
+}
+
+func (m *Tag) Marshal() (dAtA []byte, err error) {
+	size := m.Size()
+	dAtA = make([]byte, size)
+	n, err := m.MarshalToSizedBuffer(dAtA[:size])
+	if err != nil {
+		return nil, err
+	}
+	return dAtA[:n], nil
+}
+
+func (m *Tag) MarshalTo(dAtA []byte) (int, error) {
+	size := m.Size()
+	return m.MarshalToSizedBuffer(dAtA[:size])
+}
+
+func (m *Tag) MarshalToSizedBuffer(dAtA []byte) (int, error) {
+	i := len(dAtA)
+	_ = i
+	var l int
+	_ = l
+	if len(m.Value) > 0 {
+		i -= len(m.Value)
+		copy(dAtA[i:], m.Value)
+		i = encodeVarintRecordedSpan(dAtA, i, uint64(len(m.Value)))
+		i--
+		dAtA[i] = 0x12
+	}
+	if len(m.Key) > 0 {
+		i -= len(m.Key)
+		copy(dAtA[i:], m.Key)
+		i = encodeVarintRecordedSpan(dAtA, i, uint64(len(m.Key)))
+		i--
+		dAtA[i] = 0xa
+	}
+	return len(dAtA) - i, nil
+}
+
+func (m *NormalizedSpan) Marshal() (dAtA []byte, err error) {
+	size := m.Size()
+	dAtA = make([]byte, size)
+	n, err := m.MarshalToSizedBuffer(dAtA[:size])
+	if err != nil {
+		return nil, err
+	}
+	return dAtA[:n], nil
+}
+
+func (m *NormalizedSpan) MarshalTo(dAtA []byte) (int, error) {
+	size := m.Size()
+	return m.MarshalToSizedBuffer(dAtA[:size])
+}
+
+func (m *NormalizedSpan) MarshalToSizedBuffer(dAtA []byte) (int, error) {
+	i := len(dAtA)
+	_ = i
+	var l int
+	_ = l
+	if len(m.ChildrenMetadata) > 0 {
+		keysForChildrenMetadata := make([]string, 0, len(m.ChildrenMetadata))
+		for k := range m.ChildrenMetadata {
+			keysForChildrenMetadata = append(keysForChildrenMetadata, string(k))
+		}
+		github_com_gogo_protobuf_sortkeys.Strings(keysForChildrenMetadata)
+		for iNdEx := len(keysForChildrenMetadata) - 1; iNdEx >= 0; iNdEx-- {
+			v := m.ChildrenMetadata[string(keysForChildrenMetadata[iNdEx])]
+			baseI := i
+			{
+				size, err := (&v).MarshalToSizedBuffer(dAtA[:i])
+				if err != nil {
+					return 0, err
+				}
+				i -= size
+				i = encodeVarintRecordedSpan(dAtA, i, uint64(size))
+			}
+			i--
+			dAtA[i] = 0x12
+			i -= len(keysForChildrenMetadata[iNdEx])
+			copy(dAtA[i:], keysForChildrenMetadata[iNdEx])
+			i = encodeVarintRecordedSpan(dAtA, i, uint64(len(keysForChildrenMetadata[iNdEx])))
+			i--
+			dAtA[i] = 0xa
+			i = encodeVarintRecordedSpan(dAtA, i, uint64(baseI-i))
+			i--
+			dAtA[i] = 0x4a
+		}
+	}
+	if len(m.TagGroups) > 0 {
+		for iNdEx := len(m.TagGroups) - 1; iNdEx >= 0; iNdEx-- {
+			{
+				size, err := m.TagGroups[iNdEx].MarshalToSizedBuffer(dAtA[:i])
+				if err != nil {
+					return 0, err
+				}
+				i -= size
+				i = encodeVarintRecordedSpan(dAtA, i, uint64(size))
+			}
+			i--
+			dAtA[i] = 0x42
+		}
+	}
+	if len(m.StructuredRecords) > 0 {
+		for iNdEx := len(m.StructuredRecords) - 1; iNdEx >= 0; iNdEx-- {
+			{
+				size, err := m.StructuredRecords[iNdEx].MarshalToSizedBuffer(dAtA[:i])
+				if err != nil {
+					return 0, err
+				}
+				i -= size
+				i = encodeVarintRecordedSpan(dAtA, i, uint64(size))
+			}
+			i--
+			dAtA[i] = 0x3a
+		}
+	}
+	if len(m.Children) > 0 {
+		for iNdEx := len(m.Children) - 1; iNdEx >= 0; iNdEx-- {
+			{
+				size, err := m.Children[iNdEx].MarshalToSizedBuffer(dAtA[:i])
+				if err != nil {
+					return 0, err
+				}
+				i -= size
+				i = encodeVarintRecordedSpan(dAtA, i, uint64(size))
+			}
+			i--
+			dAtA[i] = 0x32
+		}
+	}
+	if len(m.Logs) > 0 {
+		for iNdEx := len(m.Logs) - 1; iNdEx >= 0; iNdEx-- {
+			{
+				size, err := m.Logs[iNdEx].MarshalToSizedBuffer(dAtA[:i])
+				if err != nil {
+					return 0, err
+				}
+				i -= size
+				i = encodeVarintRecordedSpan(dAtA, i, uint64(size))
+			}
+			i--
+			dAtA[i] = 0x2a
+		}
+	}
+	if m.Duration != 0 {
+		n8, err8 := github_com_gogo_protobuf_types.StdDurationMarshalTo(m.Duration, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdDuration(m.Duration):])
+		if err8 != nil {
+			return 0, err8
+		}
+		i -= n8
+		i = encodeVarintRecordedSpan(dAtA, i, uint64(n8))
+		i--
+		dAtA[i] = 0x22
+	}
+	n9, err9 := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.StartTime, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(m.StartTime):])
+	if err9 != nil {
+		return 0, err9
+	}
+	i -= n9
+	i = encodeVarintRecordedSpan(dAtA, i, uint64(n9))
+	i--
+	dAtA[i] = 0x1a
+	if len(m.Tags) > 0 {
+		keysForTags := make([]string, 0, len(m.Tags))
+		for k := range m.Tags {
+			keysForTags = append(keysForTags, string(k))
+		}
+		github_com_gogo_protobuf_sortkeys.Strings(keysForTags)
+		for iNdEx := len(keysForTags) - 1; iNdEx >= 0; iNdEx-- {
+			v := m.Tags[string(keysForTags[iNdEx])]
+			baseI := i
+			i -= len(v)
+			copy(dAtA[i:], v)
+			i = encodeVarintRecordedSpan(dAtA, i, uint64(len(v)))
+			i--
+			dAtA[i] = 0x12
+			i -= len(keysForTags[iNdEx])
+			copy(dAtA[i:], keysForTags[iNdEx])
+			i = encodeVarintRecordedSpan(dAtA, i, uint64(len(keysForTags[iNdEx])))
+			i--
+			dAtA[i] = 0xa
+			i = encodeVarintRecordedSpan(dAtA, i, uint64(baseI-i))
+			i--
+			dAtA[i] = 0x12
+		}
+	}
+	if len(m.Operation) > 0 {
+		i -= len(m.Operation)
+		copy(dAtA[i:], m.Operation)
+		i = encodeVarintRecordedSpan(dAtA, i, uint64(len(m.Operation)))
+		i--
+		dAtA[i] = 0xa
+	}
+	return len(dAtA) - i, nil
+}
+
+func (m *CapturedStack) Marshal() (dAtA []byte, err error) {
+	size := m.Size()
+	dAtA = make([]byte, size)
+	n, err := m.MarshalToSizedBuffer(dAtA[:size])
+	if err != nil {
+		return nil, err
+	}
+	return dAtA[:n], nil
+}
+
+func (m *CapturedStack) MarshalTo(dAtA []byte) (int, error) {
+	size := m.Size()
+	return m.MarshalToSizedBuffer(dAtA[:size])
+}
+
+func (m *CapturedStack) MarshalToSizedBuffer(dAtA []byte) (int, error) {
+	i := len(dAtA)
+	_ = i
+	var l int
+	_ = l
+	if m.Age != 0 {
+		i = encodeVarintRecordedSpan(dAtA, i, uint64(m.Age))
+		i--
+		dAtA[i] = 0x20
+	}
+	if m.SharedLines != 0 {
+		i = encodeVarintRecordedSpan(dAtA, i, uint64(m.SharedLines))
+		i--
+		dAtA[i] = 0x18
+	}
+	if m.SharedSuffix != 0 {
+		i = encodeVarintRecordedSpan(dAtA, i, uint64(m.SharedSuffix))
+		i--
+		dAtA[i] = 0x10
+	}
+	if len(m.Stack) > 0 {
+		i -= len(m.Stack)
+		copy(dAtA[i:], m.Stack)
+		i = encodeVarintRecordedSpan(dAtA, i, uint64(len(m.Stack)))
+		i--
+		dAtA[i] = 0xa
+	}
+	return len(dAtA) - i, nil
+}
+
+func encodeVarintRecordedSpan(dAtA []byte, offset int, v uint64) int {
+	offset -= sovRecordedSpan(v)
+	base := offset
+	for v >= 1<<7 {
+		dAtA[offset] = uint8(v&0x7f | 0x80)
+		v >>= 7
+		offset++
+	}
+	dAtA[offset] = uint8(v)
+	return base
+}
+func (m *LogRecord) Size() (n int) {
+	if m == nil {
+		return 0
+	}
+	var l int
+	_ = l
+	l = github_com_gogo_protobuf_types.SizeOfStdTime(m.Time)
+	n += 1 + l + sovRecordedSpan(uint64(l))
+	l = len(m.Message)
+	if l > 0 {
+		n += 1 + l + sovRecordedSpan(uint64(l))
+	}
+	return n
+}
+
+func (m *LogRecord_Field) Size() (n int) {
+	if m == nil {
+		return 0
+	}
+	var l int
+	_ = l
+	l = len(m.Key)
+	if l > 0 {
+		n += 1 + l + sovRecordedSpan(uint64(l))
+	}
+	l = len(m.Value)
+	if l > 0 {
+		n += 1 + l + sovRecordedSpan(uint64(l))
+	}
+	return n
+}
+
+func (m *StructuredRecord) Size() (n int) {
+	if m == nil {
+		return 0
+	}
+	var l int
+	_ = l
+	l = github_com_gogo_protobuf_types.SizeOfStdTime(m.Time)
+	n += 1 + l + sovRecordedSpan(uint64(l))
+	if m.Payload != nil {
+		l = m.Payload.Size()
+		n += 1 + l + sovRecordedSpan(uint64(l))
+	}
+	return n
+}
+
+func (m *OperationMetadata) Size() (n int) {
+	if m == nil {
+		return 0
+	}
+	var l int
+	_ = l
+	if m.Duration != 0 {
+		n += 1 + sovRecordedSpan(uint64(m.Duration))
+	}
+	if m.Count != 0 {
+		n += 1 + sovRecordedSpan(uint64(m.Count))
+	}
+	if m.ContainsUnfinished {
+		n += 2
+	}
+	return n
+}
+
+func (m *RecordedSpan) Size() (n int) {
+	if m == nil {
+		return 0
+	}
+	var l int
+	_ = l
+	if m.TraceID != 0 {
+		n += 1 + sovRecordedSpan(uint64(m.TraceID))
+	}
+	if m.SpanID != 0 {
+		n += 1 + sovRecordedSpan(uint64(m.SpanID))
+	}
+	if m.ParentSpanID != 0 {
+		n += 1 + sovRecordedSpan(uint64(m.ParentSpanID))
+	}
+	l = len(m.Operation)
+	if l > 0 {
+		n += 1 + l + sovRecordedSpan(uint64(l))
+	}
+	l = github_com_gogo_protobuf_types.SizeOfStdTime(m.StartTime)
+	n += 1 + l + sovRecordedSpan(uint64(l))
+	if m.Duration != 0 {
+		l = github_com_gogo_protobuf_types.SizeOfStdDuration(m.Duration)
+		n += 1 + l + sovRecordedSpan(uint64(l))
+	}
+	if len(m.Logs) > 0 {
+		for _, e := range m.Logs {
+			l = e.Size()
+			n += 1 + l + sovRecordedSpan(uint64(l))
+		}
+	}
+	if m.GoroutineID != 0 {
+		n += 1 + sovRecordedSpan(uint64(m.GoroutineID))
+	}
+	if m.Finished {
+		n += 2
+	}
+	if len(m.StructuredRecords) > 0 {
+		for _, e := range m.StructuredRecords {
+			l = e.Size()
+			n += 1 + l + sovRecordedSpan(uint64(l))
+		}
+	}
+	if m.Verbose {
+		n += 3
+	}
+	if m.RecordingMode != 0 {
+		n += 2 + sovRecordedSpan(uint64(m.RecordingMode))
+	}
+	if len(m.TagGroups) > 0 {
+		for _, e := range m.TagGroups {
+			l = e.Size()
+			n += 2 + l + sovRecordedSpan(uint64(l))
+		}
+	}
+	if len(m.ChildrenMetadata) > 0 {
+		for k, v := range m.ChildrenMetadata {
+			_ = k
+			_ = v
+			l = v.Size()
+			mapEntrySize := 1 + len(k) + sovRecordedSpan(uint64(len(k))) + 1 + l + sovRecordedSpan(uint64(l))
+			n += mapEntrySize + 2 + sovRecordedSpan(uint64(mapEntrySize))
+		}
+	}
+	if m.StructuredRecordsSizeBytes != 0 {
+		n += 2 + sovRecordedSpan(uint64(m.StructuredRecordsSizeBytes))
+	}
+	return n
+}
+
+func (m *TagGroup) Size() (n int) {
+	if m == nil {
+		return 0
+	}
+	var l int
+	_ = l
+	l = len(m.Name)
+	if l > 0 {
+		n += 1 + l + sovRecordedSpan(uint64(l))
+	}
+	if len(m.Tags) > 0 {
+		for _, e := range m.Tags {
+			l = e.Size()
+			n += 1 + l + sovRecordedSpan(uint64(l))
+		}
+	}
+	return n
+}
+
+func (m *Tag) Size() (n int) {
+	if m == nil {
+		return 0
+	}
+	var l int
+	_ = l
+	l = len(m.Key)
+	if l > 0 {
+		n += 1 + l + sovRecordedSpan(uint64(l))
+	}
+	l = len(m.Value)
+	if l > 0 {
+		n += 1 + l + sovRecordedSpan(uint64(l))
+	}
+	return n
+}
+
+func (m *NormalizedSpan) Size() (n int) {
+	if m == nil {
+		return 0
+	}
+	var l int
+	_ = l
+	l = len(m.Operation)
+	if l > 0 {
+		n += 1 + l + sovRecordedSpan(uint64(l))
+	}
+	if len(m.Tags) > 0 {
+		for k, v := range m.Tags {
+			_ = k
+			_ = v
+			mapEntrySize := 1 + len(k) + sovRecordedSpan(uint64(len(k))) + 1 + len(v) + sovRecordedSpan(uint64(len(v)))
+			n += mapEntrySize + 1 + sovRecordedSpan(uint64(mapEntrySize))
+		}
+	}
+	l = github_com_gogo_protobuf_types.SizeOfStdTime(m.StartTime)
+	n += 1 + l + sovRecordedSpan(uint64(l))
+	if m.Duration != 0 {
+		l = github_com_gogo_protobuf_types.SizeOfStdDuration(m.Duration)
+		n += 1 + l + sovRecordedSpan(uint64(l))
+	}
+	if len(m.Logs) > 0 {
+		for _, e := range m.Logs {
+			l = e.Size()
+			n += 1 + l + sovRecordedSpan(uint64(l))
+		}
+	}
+	if len(m.Children) > 0 {
+		for _, e := range m.Children {
+			l = e.Size()
+			n += 1 + l + sovRecordedSpan(uint64(l))
+		}
+	}
+	if len(m.StructuredRecords) > 0 {
+		for _, e := range m.StructuredRecords {
+			l = e.Size()
+			n += 1 + l + sovRecordedSpan(uint64(l))
+		}
+	}
+	if len(m.TagGroups) > 0 {
+		for _, e := range m.TagGroups {
+			l = e.Size()
+			n += 1 + l + sovRecordedSpan(uint64(l))
+		}
+	}
+	if len(m.ChildrenMetadata) > 0 {
+		for k, v := range m.ChildrenMetadata {
+			_ = k
+			_ = v
+			l = v.Size()
+			mapEntrySize := 1 + len(k) + sovRecordedSpan(uint64(len(k))) + 1 + l + sovRecordedSpan(uint64(l))
+			n += mapEntrySize + 1 + sovRecordedSpan(uint64(mapEntrySize))
+		}
+	}
+	return n
+}
+
+func (m *CapturedStack) Size() (n int) {
+	if m == nil {
+		return 0
+	}
+	var l int
+	_ = l
+	l = len(m.Stack)
+	if l > 0 {
+		n += 1 + l + sovRecordedSpan(uint64(l))
+	}
+	if m.SharedSuffix != 0 {
+		n += 1 + sovRecordedSpan(uint64(m.SharedSuffix))
+	}
+	if m.SharedLines != 0 {
+		n += 1 + sovRecordedSpan(uint64(m.SharedLines))
+	}
+	if m.Age != 0 {
+		n += 1 + sovRecordedSpan(uint64(m.Age))
+	}
+	return n
+}
+
+func sovRecordedSpan(x uint64) (n int) {
+	return int((uint32(math_bits.Len64(x|1)+6) * 37) >> 8)
+}
+func sozRecordedSpan(x uint64) (n int) {
+	return sovRecordedSpan(uint64((x << 1) ^ uint64((int64(x) >> 63))))
+}
+func (m *LogRecord) Unmarshal(dAtA []byte) error {
+	l := len(dAtA)
+	iNdEx := 0
+	for iNdEx < l {
+		preIndex := iNdEx
+		var wire uint64
+		for shift := uint(0); ; shift += 7 {
+			if shift >= 64 {
+				return ErrIntOverflowRecordedSpan
+			}
+			if iNdEx >= l {
+				return io.ErrUnexpectedEOF
+			}
+			b := dAtA[iNdEx]
+			iNdEx++
+			wire |= uint64(b&0x7F) << shift
+			if b < 0x80 {
+				break
+			}
+		}
+		fieldNum := int32(wire >> 3)
+		wireType := int(wire & 0x7)
+		if wireType == 4 {
+			return fmt.Errorf("proto: LogRecord: wiretype end group for non-group")
+		}
+		if fieldNum <= 0 {
+			return fmt.Errorf("proto: LogRecord: illegal tag %d (wire type %d)", fieldNum, wire)
+		}
+		switch fieldNum {
+		case 1:
+			if wireType != 2 {
+				return fmt.Errorf("proto: wrong wireType = %d for field Time", wireType)
+			}
+			var msglen int
+			for shift := uint(0); ; shift += 7 {
+				if shift >= 64 {
+					return ErrIntOverflowRecordedSpan
+				}
+				if iNdEx >= l {
+					return io.ErrUnexpectedEOF
+				}
+				b := dAtA[iNdEx]
+				iNdEx++
+				msglen |= int(b&0x7F) << shift
+				if b < 0x80 {
+					break
+				}
+			}
+			if msglen < 0 {
+				return ErrInvalidLengthRecordedSpan
+			}
+			postIndex := iNdEx + msglen
+			if postIndex < 0 {
+				return ErrInvalidLengthRecordedSpan
+			}
+			if postIndex > l {
+				return io.ErrUnexpectedEOF
+			}
+			if err := github_com_gogo_protobuf_types.StdTimeUnmarshal(&m.Time, dAtA[iNdEx:postIndex]); err != nil {
+				return err
+			}
+			iNdEx = postIndex
+		case 3:
+			if wireType != 2 {
+				return fmt.Errorf("proto: wrong wireType = %d for field Message", wireType)
+			}
+			var stringLen uint64
+			for shift := uint(0); ; shift += 7 {
+				if shift >= 64 {
+					return ErrIntOverflowRecordedSpan
+				}
+				if iNdEx >= l {
+					return io.ErrUnexpectedEOF
+				}
+				b := dAtA[iNdEx]
+				iNdEx++
+				stringLen |= uint64(b&0x7F) << shift
+				if b < 0x80 {
+					break
+				}
+			}
+			intStringLen := int(stringLen)
+			if intStringLen < 0 {
+				return ErrInvalidLengthRecordedSpan
+			}
+			postIndex := iNdEx + intStringLen
+			if postIndex < 0 {
+				return ErrInvalidLengthRecordedSpan
+			}
+			if postIndex > l {
+				return io.ErrUnexpectedEOF
+			}
+			m.Message = github_com_cockroachdb_redact.RedactableString(dAtA[iNdEx:postIndex])
+			iNdEx = postIndex
+		default:
+			iNdEx = preIndex
+			skippy, err := skipRecordedSpan(dAtA[iNdEx:])
+			if err != nil {
+				return err
+			}
+			if (skippy < 0) || (iNdEx+skippy) < 0 {
+				return ErrInvalidLengthRecordedSpan
+			}
+			if (iNdEx + skippy) > l {
+				return io.ErrUnexpectedEOF
+			}
+			iNdEx += skippy
+		}
+	}
+
+	if iNdEx > l {
+		return io.ErrUnexpectedEOF
+	}
+	return nil
+}
+func (m *LogRecord_Field) Unmarshal(dAtA []byte) error {
+	l := len(dAtA)
+	iNdEx := 0
+	for iNdEx < l {
+		preIndex := iNdEx
+		var wire uint64
+		for shift := uint(0); ; shift += 7 {
+			if shift >= 64 {
+				return ErrIntOverflowRecordedSpan
+			}
+			if iNdEx >= l {
+				return io.ErrUnexpectedEOF
+			}
+			b := dAtA[iNdEx]
+			iNdEx++
+			wire |= uint64(b&0x7F) << shift
+			if b < 0x80 {
+				break
+			}
+		}
+		fieldNum := int32(wire >> 3)
+		wireType := int(wire & 0x7)
+		if wireType == 4 {
+			return fmt.Errorf("proto: Field: wiretype end group for non-group")
+		}
+		if fieldNum <= 0 {
+			return fmt.Errorf("proto: Field: illegal tag %d (wire type %d)", fieldNum, wire)
+		}
+		switch fieldNum {
+		case 1:
+			if wireType != 2 {
+				return fmt.Errorf("proto: wrong wireType = %d for field Key", wireType)
+			}
+			var stringLen uint64
+			for shift := uint(0); ; shift += 7 {
+				if shift >= 64 {
+					return ErrIntOverflowRecordedSpan
+				}
+				if iNdEx >= l {
+					return io.ErrUnexpectedEOF
+				}
+				b := dAtA[iNdEx]
+				iNdEx++
+				stringLen |= uint64(b&0x7F) << shift
+				if b < 0x80 {
+					break
+				}
+			}
+			intStringLen := int(stringLen)
+			if intStringLen < 0 {
+				return ErrInvalidLengthRecordedSpan
+			}
+			postIndex := iNdEx + intStringLen
+			if postIndex < 0 {
+				return ErrInvalidLengthRecordedSpan
+			}
+			if postIndex > l {
+				return io.ErrUnexpectedEOF
+			}
+			m.Key = string(dAtA[iNdEx:postIndex])
+			iNdEx = postIndex
+		case 2:
+			if wireType != 2 {
+				return fmt.Errorf("proto: wrong wireType = %d for field Value", wireType)
+			}
+			var stringLen uint64
+			for shift := uint(0); ; shift += 7 {
+				if shift >= 64 {
+					return ErrIntOverflowRecordedSpan
+				}
+				if iNdEx >= l {
+					return io.ErrUnexpectedEOF
+				}
+				b := dAtA[iNdEx]
+				iNdEx++
+				stringLen |= uint64(b&0x7F) << shift
+				if b < 0x80 {
+					break
+				}
+			}
+			intStringLen := int(stringLen)
+			if intStringLen < 0 {
+				return ErrInvalidLengthRecordedSpan
+			}
+			postIndex := iNdEx + intStringLen
+			if postIndex < 0 {
+				return ErrInvalidLengthRecordedSpan
+			}
+			if postIndex > l {
+				return io.ErrUnexpectedEOF
+			}
+			m.Value = github_com_cockroachdb_redact.RedactableString(dAtA[iNdEx:postIndex])
+			iNdEx = postIndex
+		default:
+			iNdEx = preIndex
+			skippy, err := skipRecordedSpan(dAtA[iNdEx:])
+			if err != nil {
+				return err
+			}
+			if (skippy < 0) || (iNdEx+skippy) < 0 {
+				return ErrInvalidLengthRecordedSpan
+			}
+			if (iNdEx + skippy) > l {
+				return io.ErrUnexpectedEOF
+			}
+			iNdEx += skippy
+		}
+	}
+
+	if iNdEx > l {
+		return io.ErrUnexpectedEOF
+	}
+	return nil
+}
+func (m *StructuredRecord) Unmarshal(dAtA []byte) error {
+	l := len(dAtA)
+	iNdEx := 0
+	for iNdEx < l {
+		preIndex := iNdEx
+		var wire uint64
+		for shift := uint(0); ; shift += 7 {
+			if shift >= 64 {
+				return ErrIntOverflowRecordedSpan
+			}
+			if iNdEx >= l {
+				return io.ErrUnexpectedEOF
+			}
+			b := dAtA[iNdEx]
+			iNdEx++
+			wire |= uint64(b&0x7F) << shift
+			if b < 0x80 {
+				break
+			}
+		}
+		fieldNum := int32(wire >> 3)
+		wireType := int(wire & 0x7)
+		if wireType == 4 {
+			return fmt.Errorf("proto: StructuredRecord: wiretype end group for non-group")
+		}
+		if fieldNum <= 0 {
+			return fmt.Errorf("proto: StructuredRecord: illegal tag %d (wire type %d)", fieldNum, wire)
+		}
+		switch fieldNum {
+		case 1:
+			if wireType != 2 {
+				return fmt.Errorf("proto: wrong wireType = %d for field Time", wireType)
+			}
+			var msglen int
+			for shift := uint(0); ; shift += 7 {
+				if shift >= 64 {
+					return ErrIntOverflowRecordedSpan
+				}
+				if iNdEx >= l {
+					return io.ErrUnexpectedEOF
+				}
+				b := dAtA[iNdEx]
+				iNdEx++
+				msglen |= int(b&0x7F) << shift
+				if b < 0x80 {
+					break
+				}
+			}
+			if msglen < 0 {
+				return ErrInvalidLengthRecordedSpan
+			}
+			postIndex := iNdEx + msglen
+			if postIndex < 0 {
+				return ErrInvalidLengthRecordedSpan
+			}
+			if postIndex > l {
+				return io.ErrUnexpectedEOF
+			}
+			if err := github_com_gogo_protobuf_types.StdTimeUnmarshal(&m.Time, dAtA[iNdEx:postIndex]); err != nil {
+				return err
+			}
+			iNdEx = postIndex
+		case 2:
+			if wireType != 2 {
+				return fmt.Errorf("proto: wrong wireType = %d for field Payload", wireType)
+			}
+			var msglen int
+			for shift := uint(0); ; shift += 7 {
+				if shift >= 64 {
+					return ErrIntOverflowRecordedSpan
+				}
+				if iNdEx >= l {
+					return io.ErrUnexpectedEOF
+				}
+				b := dAtA[iNdEx]
+				iNdEx++
+				msglen |= int(b&0x7F) << shift
+				if b < 0x80 {
+					break
+				}
+			}
+			if msglen < 0 {
+				return ErrInvalidLengthRecordedSpan
+			}
+			postIndex := iNdEx + msglen
+			if postIndex < 0 {
+				return ErrInvalidLengthRecordedSpan
+			}
+			if postIndex > l {
+				return io.ErrUnexpectedEOF
+			}
+			if m.Payload == nil {
+				m.Payload = &types.Any{}
+			}
+			if err := m.Payload.Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
+				return err
+			}
+			iNdEx = postIndex
+		default:
+			iNdEx = preIndex
+			skippy, err := skipRecordedSpan(dAtA[iNdEx:])
+			if err != nil {
+				return err
+			}
+			if (skippy < 0) || (iNdEx+skippy) < 0 {
+				return ErrInvalidLengthRecordedSpan
+			}
+			if (iNdEx + skippy) > l {
+				return io.ErrUnexpectedEOF
+			}
+			iNdEx += skippy
+		}
+	}
+
+	if iNdEx > l {
+		return io.ErrUnexpectedEOF
+	}
+	return nil
+}
+func (m *OperationMetadata) Unmarshal(dAtA []byte) error {
+	l := len(dAtA)
+	iNdEx := 0
+	for iNdEx < l {
+		preIndex := iNdEx
+		var wire uint64
+		for shift := uint(0); ; shift += 7 {
+			if shift >= 64 {
+				return ErrIntOverflowRecordedSpan
+			}
+			if iNdEx >= l {
+				return io.ErrUnexpectedEOF
+			}
+			b := dAtA[iNdEx]
+			iNdEx++
+			wire |= uint64(b&0x7F) << shift
+			if b < 0x80 {
+				break
+			}
+		}
+		fieldNum := int32(wire >> 3)
+		wireType := int(wire & 0x7)
+		if wireType == 4 {
+			return fmt.Errorf("proto: OperationMetadata: wiretype end group for non-group")
+		}
+		if fieldNum <= 0 {
+			return fmt.Errorf("proto: OperationMetadata: illegal tag %d (wire type %d)", fieldNum, wire)
+		}
+		switch fieldNum {
+		case 1:
+			if wireType != 0 {
+				return fmt.Errorf("proto: wrong wireType = %d for field Duration", wireType)
+			}
+			m.Duration = 0
+			for shift := uint(0); ; shift += 7 {
+				if shift >= 64 {
+					return ErrIntOverflowRecordedSpan
+				}
+				if iNdEx >= l {
+					return io.ErrUnexpectedEOF
+				}
+				b := dAtA[iNdEx]
+				iNdEx++
+				m.Duration |= time.Duration(b&0x7F) << shift
+				if b < 0x80 {
+					break
+				}
+			}
+		case 2:
+			if wireType != 0 {
+				return fmt.Errorf("proto: wrong wireType = %d for field Count", wireType)
+			}
+			m.Count = 0
+			for shift := uint(0); ; shift += 7 {
+				if shift >= 64 {
+					return ErrIntOverflowRecordedSpan
+				}
+				if iNdEx >= l {
+					return io.ErrUnexpectedEOF
+				}
+				b := dAtA[iNdEx]
+				iNdEx++
+				m.Count |= int64(b&0x7F) << shift
+				if b < 0x80 {
+					break
+				}
+			}
+		case 3:
+			if wireType != 0 {
+				return fmt.Errorf("proto: wrong wireType = %d for field ContainsUnfinished", wireType)
+			}
+			var v int
+			for shift := uint(0); ; shift += 7 {
+				if shift >= 64 {
+					return ErrIntOverflowRecordedSpan
+				}
+				if iNdEx >= l {
+					return io.ErrUnexpectedEOF
+				}
+				b := dAtA[iNdEx]
+				iNdEx++
+				v |= int(b&0x7F) << shift
+				if b < 0x80 {
+					break
+				}
+			}
+			m.ContainsUnfinished = bool(v != 0)
+		default:
+			iNdEx = preIndex
+			skippy, err := skipRecordedSpan(dAtA[iNdEx:])
+			if err != nil {
+				return err
+			}
+			if (skippy < 0) || (iNdEx+skippy) < 0 {
+				return ErrInvalidLengthRecordedSpan
+			}
+			if (iNdEx + skippy) > l {
+				return io.ErrUnexpectedEOF
+			}
+			iNdEx += skippy
+		}
+	}
+
+	if iNdEx > l {
+		return io.ErrUnexpectedEOF
+	}
+	return nil
+}
+func (m *RecordedSpan) Unmarshal(dAtA []byte) error {
+	l := len(dAtA)
+	iNdEx := 0
+	for iNdEx < l {
+		preIndex := iNdEx
+		var wire uint64
+		for shift := uint(0); ; shift += 7 {
+			if shift >= 64 {
+				return ErrIntOverflowRecordedSpan
+			}
+			if iNdEx >= l {
+				return io.ErrUnexpectedEOF
+			}
+			b := dAtA[iNdEx]
+			iNdEx++
+			wire |= uint64(b&0x7F) << shift
+			if b < 0x80 {
+				break
+			}
+		}
+		fieldNum := int32(wire >> 3)
+		wireType := int(wire & 0x7)
+		if wireType == 4 {
+			return fmt.Errorf("proto: RecordedSpan: wiretype end group for non-group")
+		}
+		if fieldNum <= 0 {
+			return fmt.Errorf("proto: RecordedSpan: illegal tag %d (wire type %d)", fieldNum, wire)
+		}
+		switch fieldNum {
+		case 1:
+			if wireType != 0 {
+				return fmt.Errorf("proto: wrong wireType = %d for field TraceID", wireType)
+			}
+			m.TraceID = 0
+			for shift := uint(0); ; shift += 7 {
+				if shift >= 64 {
+					return ErrIntOverflowRecordedSpan
+				}
+				if iNdEx >= l {
+					return io.ErrUnexpectedEOF
+				}
+				b := dAtA[iNdEx]
+				iNdEx++
+				m.TraceID |= TraceID(b&0x7F) << shift
+				if b < 0x80 {
+					break
+				}
+			}
+		case 2:
+			if wireType != 0 {
+				return fmt.Errorf("proto: wrong wireType = %d for field SpanID", wireType)
+			}
+			m.SpanID = 0
+			for shift := uint(0); ; shift += 7 {
+				if shift >= 64 {
+					return ErrIntOverflowRecordedSpan
+				}
+				if iNdEx >= l {
+					return io.ErrUnexpectedEOF
+				}
+				b := dAtA[iNdEx]
+				iNdEx++
+				m.SpanID |= SpanID(b&0x7F) << shift
+				if b < 0x80 {
+					break
+				}
+			}
+		case 3:
+			if wireType != 0 {
+				return fmt.Errorf("proto: wrong wireType = %d for field ParentSpanID", wireType)
+			}
+			m.ParentSpanID = 0
+			for shift := uint(0); ; shift += 7 {
+				if shift >= 64 {
+					return ErrIntOverflowRecordedSpan
+				}
+				if iNdEx >= l {
+					return io.ErrUnexpectedEOF
+				}
+				b := dAtA[iNdEx]
+				iNdEx++
+				m.ParentSpanID |= SpanID(b&0x7F) << shift
+				if b < 0x80 {
+					break
+				}
+			}
+		case 4:
+			if wireType != 2 {
+				return fmt.Errorf("proto: wrong wireType = %d for field Operation", wireType)
+			}
+			var stringLen uint64
+			for shift := uint(0); ; shift += 7 {
+				if shift >= 64 {
+					return ErrIntOverflowRecordedSpan
+				}
+				if iNdEx >= l {
+					return io.ErrUnexpectedEOF
+				}
+				b := dAtA[iNdEx]
+				iNdEx++
+				stringLen |= uint64(b&0x7F) << shift
+				if b < 0x80 {
+					break
+				}
+			}
+			intStringLen := int(stringLen)
+			if intStringLen < 0 {
+				return ErrInvalidLengthRecordedSpan
+			}
+			postIndex := iNdEx + intStringLen
+			if postIndex < 0 {
+				return ErrInvalidLengthRecordedSpan
+			}
+			if postIndex > l {
+				return io.ErrUnexpectedEOF
+			}
+			m.Operation = string(dAtA[iNdEx:postIndex])
+			iNdEx = postIndex
+		case 7:
+			if wireType != 2 {
+				return fmt.Errorf("proto: wrong wireType = %d for field StartTime", wireType)
+			}
+			var msglen int
+			for shift := uint(0); ; shift += 7 {
+				if shift >= 64 {
+					return ErrIntOverflowRecordedSpan
+				}
+				if iNdEx >= l {
+					return io.ErrUnexpectedEOF
+				}
+				b := dAtA[iNdEx]
+				iNdEx++
+				msglen |= int(b&0x7F) << shift
+				if b < 0x80 {
+					break
+				}
+			}
+			if msglen < 0 {
+				return ErrInvalidLengthRecordedSpan
+			}
+			postIndex := iNdEx + msglen
+			if postIndex < 0 {
+				return ErrInvalidLengthRecordedSpan
+			}
+			if postIndex > l {
+				return io.ErrUnexpectedEOF
+			}
+			if err := github_com_gogo_protobuf_types.StdTimeUnmarshal(&m.StartTime, dAtA[iNdEx:postIndex]); err != nil {
+				return err
+			}
+			iNdEx = postIndex
+		case 8:
+			if wireType != 2 {
+				return fmt.Errorf("proto: wrong wireType = %d for field Duration", wireType)
+			}
+			var msglen int
+			for shift := uint(0); ; shift += 7 {
+				if shift >= 64 {
+					return ErrIntOverflowRecordedSpan
+				}
+				if iNdEx >= l {
+					return io.ErrUnexpectedEOF
+				}
+				b := dAtA[iNdEx]
+				iNdEx++
+				msglen |= int(b&0x7F) << shift
+				if b < 0x80 {
+					break
+				}
+			}
+			if msglen < 0 {
+				return ErrInvalidLengthRecordedSpan
+			}
+			postIndex := iNdEx + msglen
+			if postIndex < 0 {
+				return ErrInvalidLengthRecordedSpan
+			}
+			if postIndex > l {
+				return io.ErrUnexpectedEOF
+			}
+			if err := github_com_gogo_protobuf_types.StdDurationUnmarshal(&m.Duration, dAtA[iNdEx:postIndex]); err != nil {
+				return err
+			}
+			iNdEx = postIndex
+		case 9:
+			if wireType != 2 {
+				return fmt.Errorf("proto: wrong wireType = %d for field Logs", wireType)
+			}
+			var msglen int
+			for shift := uint(0); ; shift += 7 {
+				if shift >= 64 {
+					return ErrIntOverflowRecordedSpan
+				}
+				if iNdEx >= l {
+					return io.ErrUnexpectedEOF
+				}
+				b := dAtA[iNdEx]
+				iNdEx++
+				msglen |= int(b&0x7F) << shift
+				if b < 0x80 {
+					break
+				}
+			}
+			if msglen < 0 {
+				return ErrInvalidLengthRecordedSpan
+			}
+			postIndex := iNdEx + msglen
+			if postIndex < 0 {
+				return ErrInvalidLengthRecordedSpan
+			}
+			if postIndex > l {
+				return io.ErrUnexpectedEOF
+			}
+			m.Logs = append(m.Logs, LogRecord{})
+			if err := m.Logs[len(m.Logs)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
+				return err
+			}
+			iNdEx = postIndex
+		case 12:
+			if wireType != 0 {
+				return fmt.Errorf("proto: wrong wireType = %d for field GoroutineID", wireType)
+			}
+			m.GoroutineID = 0
+			for shift := uint(0); ; shift += 7 {
+				if shift >= 64 {
+					return ErrIntOverflowRecordedSpan
+				}
+				if iNdEx >= l {
+					return io.ErrUnexpectedEOF
+				}
+				b := dAtA[iNdEx]
+				iNdEx++
+				m.GoroutineID |= uint64(b&0x7F) << shift
+				if b < 0x80 {
+					break
+				}
+			}
+		case 13:
+			if wireType != 0 {
+				return fmt.Errorf("proto: wrong wireType = %d for field Finished", wireType)
+			}
+			var v int
+			for shift := uint(0); ; shift += 7 {
+				if shift >= 64 {
+					return ErrIntOverflowRecordedSpan
+				}
+				if iNdEx >= l {
+					return io.ErrUnexpectedEOF
+				}
+				b := dAtA[iNdEx]
+				iNdEx++
+				v |= int(b&0x7F) << shift
+				if b < 0x80 {
+					break
+				}
+			}
+			m.Finished = bool(v != 0)
+		case 14:
+			if wireType != 2 {
+				return fmt.Errorf("proto: wrong wireType = %d for field StructuredRecords", wireType)
+			}
+			var msglen int
+			for shift := uint(0); ; shift += 7 {
+				if shift >= 64 {
+					return ErrIntOverflowRecordedSpan
+				}
+				if iNdEx >= l {
+					return io.ErrUnexpectedEOF
+				}
+				b := dAtA[iNdEx]
+				iNdEx++
+				msglen |= int(b&0x7F) << shift
+				if b < 0x80 {
+					break
+				}
+			}
+			if msglen < 0 {
+				return ErrInvalidLengthRecordedSpan
+			}
+			postIndex := iNdEx + msglen
+			if postIndex < 0 {
+				return ErrInvalidLengthRecordedSpan
+			}
+			if postIndex > l {
+				return io.ErrUnexpectedEOF
+			}
+			m.StructuredRecords = append(m.StructuredRecords, StructuredRecord{})
+			if err := m.StructuredRecords[len(m.StructuredRecords)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
+				return err
+			}
+			iNdEx = postIndex
+		case 16:
+			if wireType != 0 {
+				return fmt.Errorf("proto: wrong wireType = %d for field Verbose", wireType)
+			}
+			var v int
+			for shift := uint(0); ; shift += 7 {
+				if shift >= 64 {
+					return ErrIntOverflowRecordedSpan
+				}
+				if iNdEx >= l {
+					return io.ErrUnexpectedEOF
+				}
+				b := dAtA[iNdEx]
+				iNdEx++
+				v |= int(b&0x7F) << shift
+				if b < 0x80 {
+					break
+				}
+			}
+			m.Verbose = bool(v != 0)
+		case 17:
+			if wireType != 0 {
+				return fmt.Errorf("proto: wrong wireType = %d for field RecordingMode", wireType)
+			}
+			m.RecordingMode = 0
+			for shift := uint(0); ; shift += 7 {
+				if shift >= 64 {
+					return ErrIntOverflowRecordedSpan
+				}
+				if iNdEx >= l {
+					return io.ErrUnexpectedEOF
+				}
+				b := dAtA[iNdEx]
+				iNdEx++
+				m.RecordingMode |= RecordingMode(b&0x7F) << shift
+				if b < 0x80 {
+					break
+				}
+			}
+		case 18:
+			if wireType != 2 {
+				return fmt.Errorf("proto: wrong wireType = %d for field TagGroups", wireType)
+			}
+			var msglen int
+			for shift := uint(0); ; shift += 7 {
+				if shift >= 64 {
+					return ErrIntOverflowRecordedSpan
+				}
+				if iNdEx >= l {
+					return io.ErrUnexpectedEOF
+				}
+				b := dAtA[iNdEx]
+				iNdEx++
+				msglen |= int(b&0x7F) << shift
+				if b < 0x80 {
+					break
+				}
+			}
+			if msglen < 0 {
+				return ErrInvalidLengthRecordedSpan
+			}
+			postIndex := iNdEx + msglen
+			if postIndex < 0 {
+				return ErrInvalidLengthRecordedSpan
+			}
+			if postIndex > l {
+				return io.ErrUnexpectedEOF
+			}
+			m.TagGroups = append(m.TagGroups, TagGroup{})
+			if err := m.TagGroups[len(m.TagGroups)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
+				return err
+			}
+			iNdEx = postIndex
+		case 19:
+			if wireType != 2 {
+				return fmt.Errorf("proto: wrong wireType = %d for field ChildrenMetadata", wireType)
+			}
+			var msglen int
+			for shift := uint(0); ; shift += 7 {
+				if shift >= 64 {
+					return ErrIntOverflowRecordedSpan
+				}
+				if iNdEx >= l {
+					return io.ErrUnexpectedEOF
+				}
+				b := dAtA[iNdEx]
+				iNdEx++
+				msglen |= int(b&0x7F) << shift
+				if b < 0x80 {
+					break
+				}
+			}
+			if msglen < 0 {
+				return ErrInvalidLengthRecordedSpan
+			}
+			postIndex := iNdEx + msglen
+			if postIndex < 0 {
+				return ErrInvalidLengthRecordedSpan
+			}
+			if postIndex > l {
+				return io.ErrUnexpectedEOF
+			}
+			if m.ChildrenMetadata == nil {
+				m.ChildrenMetadata = make(map[string]OperationMetadata)
+			}
+			var mapkey string
+			mapvalue := &OperationMetadata{}
+			for iNdEx < postIndex {
+				entryPreIndex := iNdEx
+				var wire uint64
+				for shift := uint(0); ; shift += 7 {
+					if shift >= 64 {
+						return ErrIntOverflowRecordedSpan
+					}
+					if iNdEx >= l {
+						return io.ErrUnexpectedEOF
+					}
+					b := dAtA[iNdEx]
+					iNdEx++
+					wire |= uint64(b&0x7F) << shift
+					if b < 0x80 {
+						break
+					}
+				}
+				fieldNum := int32(wire >> 3)
+				if fieldNum == 1 {
+					var stringLenmapkey uint64
+					for shift := uint(0); ; shift += 7 {
+						if shift >= 64 {
+							return ErrIntOverflowRecordedSpan
+						}
+						if iNdEx >= l {
+							return io.ErrUnexpectedEOF
+						}
+						b := dAtA[iNdEx]
+						iNdEx++
+						stringLenmapkey |= uint64(b&0x7F) << shift
+						if b < 0x80 {
+							break
+						}
+					}
+					intStringLenmapkey := int(stringLenmapkey)
+					if intStringLenmapkey < 0 {
+						return ErrInvalidLengthRecordedSpan
+					}
+					postStringIndexmapkey := iNdEx + intStringLenmapkey
+					if postStringIndexmapkey < 0 {
+						return ErrInvalidLengthRecordedSpan
+					}
+					if postStringIndexmapkey > l {
+						return io.ErrUnexpectedEOF
+					}
+					mapkey = string(dAtA[iNdEx:postStringIndexmapkey])
+					iNdEx = postStringIndexmapkey
+				} else if fieldNum == 2 {
+					var mapmsglen int
+					for shift := uint(0); ; shift += 7 {
+						if shift >= 64 {
+							return ErrIntOverflowRecordedSpan
+						}
+						if iNdEx >= l {
+							return io.ErrUnexpectedEOF
+						}
+						b := dAtA[iNdEx]
+						iNdEx++
+						mapmsglen |= int(b&0x7F) << shift
+						if b < 0x80 {
+							break
+						}
+					}
+					if mapmsglen < 0 {
+						return ErrInvalidLengthRecordedSpan
+					}
+					postmsgIndex := iNdEx + mapmsglen
+					if postmsgIndex < 0 {
+						return ErrInvalidLengthRecordedSpan
+					}
+					if postmsgIndex > l {
+						return io.ErrUnexpectedEOF
+					}
+					mapvalue = &OperationMetadata{}
+					if err := mapvalue.Unmarshal(dAtA[iNdEx:postmsgIndex]); err != nil {
+						return err
+					}
+					iNdEx = postmsgIndex
+				} else {
+					iNdEx = entryPreIndex
+					skippy, err := skipRecordedSpan(dAtA[iNdEx:])
+					if err != nil {
+						return err
+					}
+					if (skippy < 0) || (iNdEx+skippy) < 0 {
+						return ErrInvalidLengthRecordedSpan
+					}
+					if (iNdEx + skippy) > postIndex {
+						return io.ErrUnexpectedEOF
+					}
+					iNdEx += skippy
+				}
+			}
+			m.ChildrenMetadata[mapkey] = *mapvalue
+			iNdEx = postIndex
+		case 20:
+			if wireType != 0 {
+				return fmt.Errorf("proto: wrong wireType = %d for field StructuredRecordsSizeBytes", wireType)
+			}
+			m.StructuredRecordsSizeBytes = 0
+			for shift := uint(0); ; shift += 7 {
+				if shift >= 64 {
+					return ErrIntOverflowRecordedSpan
+				}
+				if iNdEx >= l {
+					return io.ErrUnexpectedEOF
+				}
+				b := dAtA[iNdEx]
+				iNdEx++
+				m.StructuredRecordsSizeBytes |= int64(b&0x7F) << shift
+				if b < 0x80 {
+					break
+				}
+			}
+		default:
+			iNdEx = preIndex
+			skippy, err := skipRecordedSpan(dAtA[iNdEx:])
+			if err != nil {
+				return err
+			}
+			if (skippy < 0) || (iNdEx+skippy) < 0 {
+				return ErrInvalidLengthRecordedSpan
+			}
+			if (iNdEx + skippy) > l {
+				return io.ErrUnexpectedEOF
+			}
+			iNdEx += skippy
+		}
+	}
+
+	if iNdEx > l {
+		return io.ErrUnexpectedEOF
+	}
+	return nil
+}
+func (m *TagGroup) Unmarshal(dAtA []byte) error {
+	l := len(dAtA)
+	iNdEx := 0
+	for iNdEx < l {
+		preIndex := iNdEx
+		var wire uint64
+		for shift := uint(0); ; shift += 7 {
+			if shift >= 64 {
+				return ErrIntOverflowRecordedSpan
+			}
+			if iNdEx >= l {
+				return io.ErrUnexpectedEOF
+			}
+			b := dAtA[iNdEx]
+			iNdEx++
+			wire |= uint64(b&0x7F) << shift
+			if b < 0x80 {
+				break
+			}
+		}
+		fieldNum := int32(wire >> 3)
+		wireType := int(wire & 0x7)
+		if wireType == 4 {
+			return fmt.Errorf("proto: TagGroup: wiretype end group for non-group")
+		}
+		if fieldNum <= 0 {
+			return fmt.Errorf("proto: TagGroup: illegal tag %d (wire type %d)", fieldNum, wire)
+		}
+		switch fieldNum {
+		case 1:
+			if wireType != 2 {
+				return fmt.Errorf("proto: wrong wireType = %d for field Name", wireType)
+			}
+			var stringLen uint64
+			for shift := uint(0); ; shift += 7 {
+				if shift >= 64 {
+					return ErrIntOverflowRecordedSpan
+				}
+				if iNdEx >= l {
+					return io.ErrUnexpectedEOF
+				}
+				b := dAtA[iNdEx]
+				iNdEx++
+				stringLen |= uint64(b&0x7F) << shift
+				if b < 0x80 {
+					break
+				}
+			}
+			intStringLen := int(stringLen)
+			if intStringLen < 0 {
+				return ErrInvalidLengthRecordedSpan
+			}
+			postIndex := iNdEx + intStringLen
+			if postIndex < 0 {
+				return ErrInvalidLengthRecordedSpan
+			}
+			if postIndex > l {
+				return io.ErrUnexpectedEOF
+			}
+			m.Name = string(dAtA[iNdEx:postIndex])
+			iNdEx = postIndex
+		case 2:
+			if wireType != 2 {
+				return fmt.Errorf("proto: wrong wireType = %d for field Tags", wireType)
+			}
+			var msglen int
+			for shift := uint(0); ; shift += 7 {
+				if shift >= 64 {
+					return ErrIntOverflowRecordedSpan
+				}
+				if iNdEx >= l {
+					return io.ErrUnexpectedEOF
+				}
+				b := dAtA[iNdEx]
+				iNdEx++
+				msglen |= int(b&0x7F) << shift
+				if b < 0x80 {
+					break
+				}
+			}
+			if msglen < 0 {
+				return ErrInvalidLengthRecordedSpan
+			}
+			postIndex := iNdEx + msglen
+			if postIndex < 0 {
+				return ErrInvalidLengthRecordedSpan
+			}
+			if postIndex > l {
+				return io.ErrUnexpectedEOF
+			}
+			m.Tags = append(m.Tags, Tag{})
+			if err := m.Tags[len(m.Tags)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
+				return err
+			}
+			iNdEx = postIndex
+		default:
+			iNdEx = preIndex
+			skippy, err := skipRecordedSpan(dAtA[iNdEx:])
+			if err != nil {
+				return err
+			}
+			if (skippy < 0) || (iNdEx+skippy) < 0 {
+				return ErrInvalidLengthRecordedSpan
+			}
+			if (iNdEx + skippy) > l {
+				return io.ErrUnexpectedEOF
+			}
+			iNdEx += skippy
+		}
+	}
+
+	if iNdEx > l {
+		return io.ErrUnexpectedEOF
+	}
+	return nil
+}
+func (m *Tag) Unmarshal(dAtA []byte) error {
+	l := len(dAtA)
+	iNdEx := 0
+	for iNdEx < l {
+		preIndex := iNdEx
+		var wire uint64
+		for shift := uint(0); ; shift += 7 {
+			if shift >= 64 {
+				return ErrIntOverflowRecordedSpan
+			}
+			if iNdEx >= l {
+				return io.ErrUnexpectedEOF
+			}
+			b := dAtA[iNdEx]
+			iNdEx++
+			wire |= uint64(b&0x7F) << shift
+			if b < 0x80 {
+				break
+			}
+		}
+		fieldNum := int32(wire >> 3)
+		wireType := int(wire & 0x7)
+		if wireType == 4 {
+			return fmt.Errorf("proto: Tag: wiretype end group for non-group")
+		}
+		if fieldNum <= 0 {
+			return fmt.Errorf("proto: Tag: illegal tag %d (wire type %d)", fieldNum, wire)
+		}
+		switch fieldNum {
+		case 1:
+			if wireType != 2 {
+				return fmt.Errorf("proto: wrong wireType = %d for field Key", wireType)
+			}
+			var stringLen uint64
+			for shift := uint(0); ; shift += 7 {
+				if shift >= 64 {
+					return ErrIntOverflowRecordedSpan
+				}
+				if iNdEx >= l {
+					return io.ErrUnexpectedEOF
+				}
+				b := dAtA[iNdEx]
+				iNdEx++
+				stringLen |= uint64(b&0x7F) << shift
+				if b < 0x80 {
+					break
+				}
+			}
+			intStringLen := int(stringLen)
+			if intStringLen < 0 {
+				return ErrInvalidLengthRecordedSpan
+			}
+			postIndex := iNdEx + intStringLen
+			if postIndex < 0 {
+				return ErrInvalidLengthRecordedSpan
+			}
+			if postIndex > l {
+				return io.ErrUnexpectedEOF
+			}
+			m.Key = string(dAtA[iNdEx:postIndex])
+			iNdEx = postIndex
+		case 2:
+			if wireType != 2 {
+				return fmt.Errorf("proto: wrong wireType = %d for field Value", wireType)
+			}
+			var stringLen uint64
+			for shift := uint(0); ; shift += 7 {
+				if shift >= 64 {
+					return ErrIntOverflowRecordedSpan
+				}
+				if iNdEx >= l {
+					return io.ErrUnexpectedEOF
+				}
+				b := dAtA[iNdEx]
+				iNdEx++
+				stringLen |= uint64(b&0x7F) << shift
+				if b < 0x80 {
+					break
+				}
+			}
+			intStringLen := int(stringLen)
+			if intStringLen < 0 {
+				return ErrInvalidLengthRecordedSpan
+			}
+			postIndex := iNdEx + intStringLen
+			if postIndex < 0 {
+				return ErrInvalidLengthRecordedSpan
+			}
+			if postIndex > l {
+				return io.ErrUnexpectedEOF
+			}
+			m.Value = string(dAtA[iNdEx:postIndex])
+			iNdEx = postIndex
+		default:
+			iNdEx = preIndex
+			skippy, err := skipRecordedSpan(dAtA[iNdEx:])
+			if err != nil {
+				return err
+			}
+			if (skippy < 0) || (iNdEx+skippy) < 0 {
+				return ErrInvalidLengthRecordedSpan
+			}
+			if (iNdEx + skippy) > l {
+				return io.ErrUnexpectedEOF
+			}
+			iNdEx += skippy
+		}
+	}
+
+	if iNdEx > l {
+		return io.ErrUnexpectedEOF
+	}
+	return nil
+}
+func (m *NormalizedSpan) Unmarshal(dAtA []byte) error {
+	l := len(dAtA)
+	iNdEx := 0
+	for iNdEx < l {
+		preIndex := iNdEx
+		var wire uint64
+		for shift := uint(0); ; shift += 7 {
+			if shift >= 64 {
+				return ErrIntOverflowRecordedSpan
+			}
+			if iNdEx >= l {
+				return io.ErrUnexpectedEOF
+			}
+			b := dAtA[iNdEx]
+			iNdEx++
+			wire |= uint64(b&0x7F) << shift
+			if b < 0x80 {
+				break
+			}
+		}
+		fieldNum := int32(wire >> 3)
+		wireType := int(wire & 0x7)
+		if wireType == 4 {
+			return fmt.Errorf("proto: NormalizedSpan: wiretype end group for non-group")
+		}
+		if fieldNum <= 0 {
+			return fmt.Errorf("proto: NormalizedSpan: illegal tag %d (wire type %d)", fieldNum, wire)
+		}
+		switch fieldNum {
+		case 1:
+			if wireType != 2 {
+				return fmt.Errorf("proto: wrong wireType = %d for field Operation", wireType)
+			}
+			var stringLen uint64
+			for shift := uint(0); ; shift += 7 {
+				if shift >= 64 {
+					return ErrIntOverflowRecordedSpan
+				}
+				if iNdEx >= l {
+					return io.ErrUnexpectedEOF
+				}
+				b := dAtA[iNdEx]
+				iNdEx++
+				stringLen |= uint64(b&0x7F) << shift
+				if b < 0x80 {
+					break
+				}
+			}
+			intStringLen := int(stringLen)
+			if intStringLen < 0 {
+				return ErrInvalidLengthRecordedSpan
+			}
+			postIndex := iNdEx + intStringLen
+			if postIndex < 0 {
+				return ErrInvalidLengthRecordedSpan
+			}
+			if postIndex > l {
+				return io.ErrUnexpectedEOF
+			}
+			m.Operation = string(dAtA[iNdEx:postIndex])
+			iNdEx = postIndex
+		case 2:
+			if wireType != 2 {
+				return fmt.Errorf("proto: wrong wireType = %d for field Tags", wireType)
+			}
+			var msglen int
+			for shift := uint(0); ; shift += 7 {
+				if shift >= 64 {
+					return ErrIntOverflowRecordedSpan
+				}
+				if iNdEx >= l {
+					return io.ErrUnexpectedEOF
+				}
+				b := dAtA[iNdEx]
+				iNdEx++
+				msglen |= int(b&0x7F) << shift
+				if b < 0x80 {
+					break
+				}
+			}
+			if msglen < 0 {
+				return ErrInvalidLengthRecordedSpan
+			}
+			postIndex := iNdEx + msglen
+			if postIndex < 0 {
+				return ErrInvalidLengthRecordedSpan
+			}
+			if postIndex > l {
+				return io.ErrUnexpectedEOF
+			}
+			if m.Tags == nil {
+				m.Tags = make(map[string]string)
+			}
+			var mapkey string
+			var mapvalue string
+			for iNdEx < postIndex {
+				entryPreIndex := iNdEx
+				var wire uint64
+				for shift := uint(0); ; shift += 7 {
+					if shift >= 64 {
+						return ErrIntOverflowRecordedSpan
+					}
+					if iNdEx >= l {
+						return io.ErrUnexpectedEOF
+					}
+					b := dAtA[iNdEx]
+					iNdEx++
+					wire |= uint64(b&0x7F) << shift
+					if b < 0x80 {
+						break
+					}
+				}
+				fieldNum := int32(wire >> 3)
+				if fieldNum == 1 {
+					var stringLenmapkey uint64
+					for shift := uint(0); ; shift += 7 {
+						if shift >= 64 {
+							return ErrIntOverflowRecordedSpan
+						}
+						if iNdEx >= l {
+							return io.ErrUnexpectedEOF
+						}
+						b := dAtA[iNdEx]
+						iNdEx++
+						stringLenmapkey |= uint64(b&0x7F) << shift
+						if b < 0x80 {
+							break
+						}
+					}
+					intStringLenmapkey := int(stringLenmapkey)
+					if intStringLenmapkey < 0 {
+						return ErrInvalidLengthRecordedSpan
+					}
+					postStringIndexmapkey := iNdEx + intStringLenmapkey
+					if postStringIndexmapkey < 0 {
+						return ErrInvalidLengthRecordedSpan
+					}
+					if postStringIndexmapkey > l {
+						return io.ErrUnexpectedEOF
+					}
+					mapkey = string(dAtA[iNdEx:postStringIndexmapkey])
+					iNdEx = postStringIndexmapkey
+				} else if fieldNum == 2 {
+					var stringLenmapvalue uint64
+					for shift := uint(0); ; shift += 7 {
+						if shift >= 64 {
+							return ErrIntOverflowRecordedSpan
+						}
+						if iNdEx >= l {
+							return io.ErrUnexpectedEOF
+						}
+						b := dAtA[iNdEx]
+						iNdEx++
+						stringLenmapvalue |= uint64(b&0x7F) << shift
+						if b < 0x80 {
+							break
+						}
+					}
+					intStringLenmapvalue := int(stringLenmapvalue)
+					if intStringLenmapvalue < 0 {
+						return ErrInvalidLengthRecordedSpan
+					}
+					postStringIndexmapvalue := iNdEx + intStringLenmapvalue
+					if postStringIndexmapvalue < 0 {
+						return ErrInvalidLengthRecordedSpan
+					}
+					if postStringIndexmapvalue > l {
+						return io.ErrUnexpectedEOF
+					}
+					mapvalue = string(dAtA[iNdEx:postStringIndexmapvalue])
+					iNdEx = postStringIndexmapvalue
+				} else {
+					iNdEx = entryPreIndex
+					skippy, err := skipRecordedSpan(dAtA[iNdEx:])
+					if err != nil {
+						return err
+					}
+					if (skippy < 0) || (iNdEx+skippy) < 0 {
+						return ErrInvalidLengthRecordedSpan
+					}
+					if (iNdEx + skippy) > postIndex {
+						return io.ErrUnexpectedEOF
+					}
+					iNdEx += skippy
+				}
+			}
+			m.Tags[mapkey] = mapvalue
+			iNdEx = postIndex
+		case 3:
+			if wireType != 2 {
+				return fmt.Errorf("proto: wrong wireType = %d for field StartTime", wireType)
+			}
+			var msglen int
+			for shift := uint(0); ; shift += 7 {
+				if shift >= 64 {
+					return ErrIntOverflowRecordedSpan
+				}
+				if iNdEx >= l {
+					return io.ErrUnexpectedEOF
+				}
+				b := dAtA[iNdEx]
+				iNdEx++
+				msglen |= int(b&0x7F) << shift
+				if b < 0x80 {
+					break
+				}
+			}
+			if msglen < 0 {
+				return ErrInvalidLengthRecordedSpan
+			}
+			postIndex := iNdEx + msglen
+			if postIndex < 0 {
+				return ErrInvalidLengthRecordedSpan
+			}
+			if postIndex > l {
+				return io.ErrUnexpectedEOF
+			}
+			if err := github_com_gogo_protobuf_types.StdTimeUnmarshal(&m.StartTime, dAtA[iNdEx:postIndex]); err != nil {
+				return err
+			}
+			iNdEx = postIndex
+		case 4:
+			if wireType != 2 {
+				return fmt.Errorf("proto: wrong wireType = %d for field Duration", wireType)
+			}
+			var msglen int
+			for shift := uint(0); ; shift += 7 {
+				if shift >= 64 {
+					return ErrIntOverflowRecordedSpan
+				}
+				if iNdEx >= l {
+					return io.ErrUnexpectedEOF
+				}
+				b := dAtA[iNdEx]
+				iNdEx++
+				msglen |= int(b&0x7F) << shift
+				if b < 0x80 {
+					break
+				}
+			}
+			if msglen < 0 {
+				return ErrInvalidLengthRecordedSpan
+			}
+			postIndex := iNdEx + msglen
+			if postIndex < 0 {
+				return ErrInvalidLengthRecordedSpan
+			}
+			if postIndex > l {
+				return io.ErrUnexpectedEOF
+			}
+			if err := github_com_gogo_protobuf_types.StdDurationUnmarshal(&m.Duration, dAtA[iNdEx:postIndex]); err != nil {
+				return err
+			}
+			iNdEx = postIndex
+		case 5:
+			if wireType != 2 {
+				return fmt.Errorf("proto: wrong wireType = %d for field Logs", wireType)
+			}
+			var msglen int
+			for shift := uint(0); ; shift += 7 {
+				if shift >= 64 {
+					return ErrIntOverflowRecordedSpan
+				}
+				if iNdEx >= l {
+					return io.ErrUnexpectedEOF
+				}
+				b := dAtA[iNdEx]
+				iNdEx++
+				msglen |= int(b&0x7F) << shift
+				if b < 0x80 {
+					break
+				}
+			}
+			if msglen < 0 {
+				return ErrInvalidLengthRecordedSpan
+			}
+			postIndex := iNdEx + msglen
+			if postIndex < 0 {
+				return ErrInvalidLengthRecordedSpan
+			}
+			if postIndex > l {
+				return io.ErrUnexpectedEOF
+			}
+			m.Logs = append(m.Logs, LogRecord{})
+			if err := m.Logs[len(m.Logs)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
+				return err
+			}
+			iNdEx = postIndex
+		case 6:
+			if wireType != 2 {
+				return fmt.Errorf("proto: wrong wireType = %d for field Children", wireType)
+			}
+			var msglen int
+			for shift := uint(0); ; shift += 7 {
+				if shift >= 64 {
+					return ErrIntOverflowRecordedSpan
+				}
+				if iNdEx >= l {
+					return io.ErrUnexpectedEOF
+				}
+				b := dAtA[iNdEx]
+				iNdEx++
+				msglen |= int(b&0x7F) << shift
+				if b < 0x80 {
+					break
+				}
+			}
+			if msglen < 0 {
+				return ErrInvalidLengthRecordedSpan
+			}
+			postIndex := iNdEx + msglen
+			if postIndex < 0 {
+				return ErrInvalidLengthRecordedSpan
+			}
+			if postIndex > l {
+				return io.ErrUnexpectedEOF
+			}
+			m.Children = append(m.Children, NormalizedSpan{})
+			if err := m.Children[len(m.Children)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
+				return err
+			}
+			iNdEx = postIndex
+		case 7:
+			if wireType != 2 {
+				return fmt.Errorf("proto: wrong wireType = %d for field StructuredRecords", wireType)
+			}
+			var msglen int
+			for shift := uint(0); ; shift += 7 {
+				if shift >= 64 {
+					return ErrIntOverflowRecordedSpan
+				}
+				if iNdEx >= l {
+					return io.ErrUnexpectedEOF
+				}
+				b := dAtA[iNdEx]
+				iNdEx++
+				msglen |= int(b&0x7F) << shift
+				if b < 0x80 {
+					break
+				}
+			}
+			if msglen < 0 {
+				return ErrInvalidLengthRecordedSpan
+			}
+			postIndex := iNdEx + msglen
+			if postIndex < 0 {
+				return ErrInvalidLengthRecordedSpan
+			}
+			if postIndex > l {
+				return io.ErrUnexpectedEOF
+			}
+			m.StructuredRecords = append(m.StructuredRecords, StructuredRecord{})
+			if err := m.StructuredRecords[len(m.StructuredRecords)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
+				return err
+			}
+			iNdEx = postIndex
+		case 8:
+			if wireType != 2 {
+				return fmt.Errorf("proto: wrong wireType = %d for field TagGroups", wireType)
+			}
+			var msglen int
+			for shift := uint(0); ; shift += 7 {
+				if shift >= 64 {
+					return ErrIntOverflowRecordedSpan
+				}
+				if iNdEx >= l {
+					return io.ErrUnexpectedEOF
+				}
+				b := dAtA[iNdEx]
+				iNdEx++
+				msglen |= int(b&0x7F) << shift
+				if b < 0x80 {
+					break
+				}
+			}
+			if msglen < 0 {
+				return ErrInvalidLengthRecordedSpan
+			}
+			postIndex := iNdEx + msglen
+			if postIndex < 0 {
+				return ErrInvalidLengthRecordedSpan
+			}
+			if postIndex > l {
+				return io.ErrUnexpectedEOF
+			}
+			m.TagGroups = append(m.TagGroups, TagGroup{})
+			if err := m.TagGroups[len(m.TagGroups)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
+				return err
+			}
+			iNdEx = postIndex
+		case 9:
+			if wireType != 2 {
+				return fmt.Errorf("proto: wrong wireType = %d for field ChildrenMetadata", wireType)
+			}
+			var msglen int
+			for shift := uint(0); ; shift += 7 {
+				if shift >= 64 {
+					return ErrIntOverflowRecordedSpan
+				}
+				if iNdEx >= l {
+					return io.ErrUnexpectedEOF
+				}
+				b := dAtA[iNdEx]
+				iNdEx++
+				msglen |= int(b&0x7F) << shift
+				if b < 0x80 {
+					break
+				}
+			}
+			if msglen < 0 {
+				return ErrInvalidLengthRecordedSpan
+			}
+			postIndex := iNdEx + msglen
+			if postIndex < 0 {
+				return ErrInvalidLengthRecordedSpan
+			}
+			if postIndex > l {
+				return io.ErrUnexpectedEOF
+			}
+			if m.ChildrenMetadata == nil {
+				m.ChildrenMetadata = make(map[string]OperationMetadata)
+			}
+			var mapkey string
+			mapvalue := &OperationMetadata{}
+			for iNdEx < postIndex {
+				entryPreIndex := iNdEx
+				var wire uint64
+				for shift := uint(0); ; shift += 7 {
+					if shift >= 64 {
+						return ErrIntOverflowRecordedSpan
+					}
+					if iNdEx >= l {
+						return io.ErrUnexpectedEOF
+					}
+					b := dAtA[iNdEx]
+					iNdEx++
+					wire |= uint64(b&0x7F) << shift
+					if b < 0x80 {
+						break
+					}
+				}
+				fieldNum := int32(wire >> 3)
+				if fieldNum == 1 {
+					var stringLenmapkey uint64
+					for shift := uint(0); ; shift += 7 {
+						if shift >= 64 {
+							return ErrIntOverflowRecordedSpan
+						}
+						if iNdEx >= l {
+							return io.ErrUnexpectedEOF
+						}
+						b := dAtA[iNdEx]
+						iNdEx++
+						stringLenmapkey |= uint64(b&0x7F) << shift
+						if b < 0x80 {
+							break
+						}
+					}
+					intStringLenmapkey := int(stringLenmapkey)
+					if intStringLenmapkey < 0 {
+						return ErrInvalidLengthRecordedSpan
+					}
+					postStringIndexmapkey := iNdEx + intStringLenmapkey
+					if postStringIndexmapkey < 0 {
+						return ErrInvalidLengthRecordedSpan
+					}
+					if postStringIndexmapkey > l {
+						return io.ErrUnexpectedEOF
+					}
+					mapkey = string(dAtA[iNdEx:postStringIndexmapkey])
+					iNdEx = postStringIndexmapkey
+				} else if fieldNum == 2 {
+					var mapmsglen int
+					for shift := uint(0); ; shift += 7 {
+						if shift >= 64 {
+							return ErrIntOverflowRecordedSpan
+						}
+						if iNdEx >= l {
+							return io.ErrUnexpectedEOF
+						}
+						b := dAtA[iNdEx]
+						iNdEx++
+						mapmsglen |= int(b&0x7F) << shift
+						if b < 0x80 {
+							break
+						}
+					}
+					if mapmsglen < 0 {
+						return ErrInvalidLengthRecordedSpan
+					}
+					postmsgIndex := iNdEx + mapmsglen
+					if postmsgIndex < 0 {
+						return ErrInvalidLengthRecordedSpan
+					}
+					if postmsgIndex > l {
+						return io.ErrUnexpectedEOF
+					}
+					mapvalue = &OperationMetadata{}
+					if err := mapvalue.Unmarshal(dAtA[iNdEx:postmsgIndex]); err != nil {
+						return err
+					}
+					iNdEx = postmsgIndex
+				} else {
+					iNdEx = entryPreIndex
+					skippy, err := skipRecordedSpan(dAtA[iNdEx:])
+					if err != nil {
+						return err
+					}
+					if (skippy < 0) || (iNdEx+skippy) < 0 {
+						return ErrInvalidLengthRecordedSpan
+					}
+					if (iNdEx + skippy) > postIndex {
+						return io.ErrUnexpectedEOF
+					}
+					iNdEx += skippy
+				}
+			}
+			m.ChildrenMetadata[mapkey] = *mapvalue
+			iNdEx = postIndex
+		default:
+			iNdEx = preIndex
+			skippy, err := skipRecordedSpan(dAtA[iNdEx:])
+			if err != nil {
+				return err
+			}
+			if (skippy < 0) || (iNdEx+skippy) < 0 {
+				return ErrInvalidLengthRecordedSpan
+			}
+			if (iNdEx + skippy) > l {
+				return io.ErrUnexpectedEOF
+			}
+			iNdEx += skippy
+		}
+	}
+
+	if iNdEx > l {
+		return io.ErrUnexpectedEOF
+	}
+	return nil
+}
+func (m *CapturedStack) Unmarshal(dAtA []byte) error {
+	l := len(dAtA)
+	iNdEx := 0
+	for iNdEx < l {
+		preIndex := iNdEx
+		var wire uint64
+		for shift := uint(0); ; shift += 7 {
+			if shift >= 64 {
+				return ErrIntOverflowRecordedSpan
+			}
+			if iNdEx >= l {
+				return io.ErrUnexpectedEOF
+			}
+			b := dAtA[iNdEx]
+			iNdEx++
+			wire |= uint64(b&0x7F) << shift
+			if b < 0x80 {
+				break
+			}
+		}
+		fieldNum := int32(wire >> 3)
+		wireType := int(wire & 0x7)
+		if wireType == 4 {
+			return fmt.Errorf("proto: CapturedStack: wiretype end group for non-group")
+		}
+		if fieldNum <= 0 {
+			return fmt.Errorf("proto: CapturedStack: illegal tag %d (wire type %d)", fieldNum, wire)
+		}
+		switch fieldNum {
+		case 1:
+			if wireType != 2 {
+				return fmt.Errorf("proto: wrong wireType = %d for field Stack", wireType)
+			}
+			var stringLen uint64
+			for shift := uint(0); ; shift += 7 {
+				if shift >= 64 {
+					return ErrIntOverflowRecordedSpan
+				}
+				if iNdEx >= l {
+					return io.ErrUnexpectedEOF
+				}
+				b := dAtA[iNdEx]
+				iNdEx++
+				stringLen |= uint64(b&0x7F) << shift
+				if b < 0x80 {
+					break
+				}
+			}
+			intStringLen := int(stringLen)
+			if intStringLen < 0 {
+				return ErrInvalidLengthRecordedSpan
+			}
+			postIndex := iNdEx + intStringLen
+			if postIndex < 0 {
+				return ErrInvalidLengthRecordedSpan
+			}
+			if postIndex > l {
+				return io.ErrUnexpectedEOF
+			}
+			m.Stack = string(dAtA[iNdEx:postIndex])
+			iNdEx = postIndex
+		case 2:
+			if wireType != 0 {
+				return fmt.Errorf("proto: wrong wireType = %d for field SharedSuffix", wireType)
+			}
+			m.SharedSuffix = 0
+			for shift := uint(0); ; shift += 7 {
+				if shift >= 64 {
+					return ErrIntOverflowRecordedSpan
+				}
+				if iNdEx >= l {
+					return io.ErrUnexpectedEOF
+				}
+				b := dAtA[iNdEx]
+				iNdEx++
+				m.SharedSuffix |= int32(b&0x7F) << shift
+				if b < 0x80 {
+					break
+				}
+			}
+		case 3:
+			if wireType != 0 {
+				return fmt.Errorf("proto: wrong wireType = %d for field SharedLines", wireType)
+			}
+			m.SharedLines = 0
+			for shift := uint(0); ; shift += 7 {
+				if shift >= 64 {
+					return ErrIntOverflowRecordedSpan
+				}
+				if iNdEx >= l {
+					return io.ErrUnexpectedEOF
+				}
+				b := dAtA[iNdEx]
+				iNdEx++
+				m.SharedLines |= int32(b&0x7F) << shift
+				if b < 0x80 {
+					break
+				}
+			}
+		case 4:
+			if wireType != 0 {
+				return fmt.Errorf("proto: wrong wireType = %d for field Age", wireType)
+			}
+			m.Age = 0
+			for shift := uint(0); ; shift += 7 {
+				if shift >= 64 {
+					return ErrIntOverflowRecordedSpan
+				}
+				if iNdEx >= l {
+					return io.ErrUnexpectedEOF
+				}
+				b := dAtA[iNdEx]
+				iNdEx++
+				m.Age |= time.Duration(b&0x7F) << shift
+				if b < 0x80 {
+					break
+				}
+			}
+		default:
+			iNdEx = preIndex
+			skippy, err := skipRecordedSpan(dAtA[iNdEx:])
+			if err != nil {
+				return err
+			}
+			if (skippy < 0) || (iNdEx+skippy) < 0 {
+				return ErrInvalidLengthRecordedSpan
+			}
+			if (iNdEx + skippy) > l {
+				return io.ErrUnexpectedEOF
+			}
+			iNdEx += skippy
+		}
+	}
+
+	if iNdEx > l {
+		return io.ErrUnexpectedEOF
+	}
+	return nil
+}
+func skipRecordedSpan(dAtA []byte) (n int, err error) {
+	l := len(dAtA)
+	iNdEx := 0
+	depth := 0
+	for iNdEx < l {
+		var wire uint64
+		for shift := uint(0); ; shift += 7 {
+			if shift >= 64 {
+				return 0, ErrIntOverflowRecordedSpan
+			}
+			if iNdEx >= l {
+				return 0, io.ErrUnexpectedEOF
+			}
+			b := dAtA[iNdEx]
+			iNdEx++
+			wire |= (uint64(b) & 0x7F) << shift
+			if b < 0x80 {
+				break
+			}
+		}
+		wireType := int(wire & 0x7)
+		switch wireType {
+		case 0:
+			for shift := uint(0); ; shift += 7 {
+				if shift >= 64 {
+					return 0, ErrIntOverflowRecordedSpan
+				}
+				if iNdEx >= l {
+					return 0, io.ErrUnexpectedEOF
+				}
+				iNdEx++
+				if dAtA[iNdEx-1] < 0x80 {
+					break
+				}
+			}
+		case 1:
+			iNdEx += 8
+		case 2:
+			var length int
+			for shift := uint(0); ; shift += 7 {
+				if shift >= 64 {
+					return 0, ErrIntOverflowRecordedSpan
+				}
+				if iNdEx >= l {
+					return 0, io.ErrUnexpectedEOF
+				}
+				b := dAtA[iNdEx]
+				iNdEx++
+				length |= (int(b) & 0x7F) << shift
+				if b < 0x80 {
+					break
+				}
+			}
+			if length < 0 {
+				return 0, ErrInvalidLengthRecordedSpan
+			}
+			iNdEx += length
+		case 3:
+			depth++
+		case 4:
+			if depth == 0 {
+				return 0, ErrUnexpectedEndOfGroupRecordedSpan
+			}
+			depth--
+		case 5:
+			iNdEx += 4
+		default:
+			return 0, fmt.Errorf("proto: illegal wireType %d", wireType)
+		}
+		if iNdEx < 0 {
+			return 0, ErrInvalidLengthRecordedSpan
+		}
+		if depth == 0 {
+			return iNdEx, nil
+		}
+	}
+	return 0, io.ErrUnexpectedEOF
+}
+
+var (
+	ErrInvalidLengthRecordedSpan        = fmt.Errorf("proto: negative length found during unmarshaling")
+	ErrIntOverflowRecordedSpan          = fmt.Errorf("proto: integer overflow")
+	ErrUnexpectedEndOfGroupRecordedSpan = fmt.Errorf("proto: unexpected end of group")
+)
+
diff --git a/pkg/util/tracing/tracingpb/recorded_span.proto b/pkg/util/tracing/tracingpb/recorded_span.proto
new file mode 100644
index 0000000..2cb670e
--- /dev/null
+++ b/pkg/util/tracing/tracingpb/recorded_span.proto
@@ -0,0 +1,191 @@
+// Copyright 2017 The Cockroach Authors.
+//
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
+
+syntax = "proto3";
+package cockroach.util.tracing.tracingpb;
+option go_package = "github.com/cockroachdb/cockroach/pkg/util/tracing/tracingpb";
+
+import "gogoproto/gogo.proto";
+import "google/protobuf/any.proto";
+import "google/protobuf/timestamp.proto";
+import "google/protobuf/duration.proto";
+import "util/tracing/tracingpb/tracing.proto";
+
+// LogRecord is a log message recorded in a traced span.
+message LogRecord {
+  // Time of the log record.
+  google.protobuf.Timestamp time = 1 [(gogoproto.nullable) = false,
+                                     (gogoproto.stdtime) = true];
+  message Field {
+    string key = 1;
+    string value = 2 [(gogoproto.nullable) = false, (gogoproto.customtype) = "github.com/cockroachdb/redact.RedactableString"];
+  }
+  // The log message.
+  string message = 3 [(gogoproto.nullable) = false, (gogoproto.customtype) = "github.com/cockroachdb/redact.RedactableString"];
+
+  reserved 2;
+}
+
+// StructuredRecord is a structured message recorded in a traced span.
+message StructuredRecord {
+  // Time of the structured record.
+  google.protobuf.Timestamp time = 1 [(gogoproto.nullable) = false,
+                                     (gogoproto.stdtime) = true];
+  google.protobuf.Any payload = 2;
+}
+
+// OperationMetadata captures information corresponding to the operation that
+// a span is started with.
+message OperationMetadata {
+  option (gogoproto.goproto_stringer) = false;
+
+  // Duration represents the total time spent by spans tracing the operation.
+  int64 duration = 1 [(gogoproto.casttype) = "time.Duration"];
+  // Count represents the number of spans tracing the operation.
+  int64 count = 2;
+  // ContainsUnfinished is true if the OperationMetadata contains information
+  // about unfinished spans tracing the operation.
+  bool contains_unfinished = 3;
+}
+
+
+// RecordedSpan is the data recorded by a trace span. It
+// needs to be able to cross RPC boundaries so that the
+// complete recording of the trace can be constructed.
+message RecordedSpan {
+  option (gogoproto.goproto_stringer) = false;
+
+  // ID of the trace; spans that are part of the same hierarchy share
+  // the same trace ID.
+  uint64 trace_id = 1 [(gogoproto.nullable) = false, (gogoproto.customname) = "TraceID", (gogoproto.customtype) = "TraceID"];
+  // ID of the span.
+  uint64 span_id = 2 [(gogoproto.nullable) = false, (gogoproto.customname) = "SpanID", (gogoproto.customtype) = "SpanID"];
+  // ID of the parent span.
+  uint64 parent_span_id = 3 [(gogoproto.nullable) = false, (gogoproto.customname) = "ParentSpanID", (gogoproto.customtype) = "SpanID"];
+  // Operation name.
+  string operation = 4;
+
+  // tag_groups describes tags associated with the span, potentially in a
+  // shallow structured hierarchy.
+  //
+  // A span may have at most one "anonymous" tag group, that is, a tag group
+  // without a Name. This is not enforced in the protobuf definition, but is
+  // expected in code.
+  //
+  // The tags in an anonymous group are not necessarily related, and should
+  // instead be treated as independent, top-level items. These tags are
+  // stored in a tag group for convenience.
+  repeated TagGroup tag_groups = 18 [(gogoproto.nullable) = false];
+
+  // Time when the span was started.
+  google.protobuf.Timestamp start_time = 7 [(gogoproto.nullable) = false,
+                                            (gogoproto.stdtime) = true];
+  // The span's duration, measured from start to Finish().
+  //
+  // A span whose recording is collected before it's finished will have the
+  // duration set as the "time of collection - start time". Such a span will
+  // have an "unfinished" tag and a `finished` boolean value of false in this
+  // recording.
+  google.protobuf.Duration duration = 8 [(gogoproto.nullable) = false,
+                                         (gogoproto.stdduration) = true];
+
+  // Events logged in the span.
+  repeated LogRecord logs = 9 [(gogoproto.nullable) = false];
+  // verbose indicates whether the span was recording in verbose mode at the
+  // time the recording was produced.
+  //
+  // This field is deprecated; it can be removed in 23.1. Use recording_mode
+  // instead.
+  bool verbose = 16;
+  // recording_mode indicates the recording mode of the span at the the
+  // recording was produced.
+  RecordingMode recording_mode = 17;
+
+  // The ID of the goroutine on which the span was created.
+  uint64 goroutine_id = 12 [(gogoproto.customname) = "GoroutineID"];
+
+  // True if the span has been Finish()ed, false otherwise.
+  bool finished = 13;
+
+  // StructuredRecords contains StructuredRecord events recorded either in this
+  // span, or in children spans that have finished while our span was not
+  // recording verbosely.
+  //
+  // A StructuredRecord wraps the Payload with a RecordedAt timestamp to expose
+  // information about when this event occurred.
+  repeated StructuredRecord structured_records = 14 [(gogoproto.nullable) = false];
+  // structured_records_size_bytes represents the total size of the logs in
+  // structured_records.
+  int64 structured_records_size_bytes = 20;
+
+  // ChildrenMetadata is a mapping from operation to the aggregated metadata of
+  // that operation.
+  //
+  // When a child of this span is Finish()ed, it updates the map with all the
+  // children in its Recording. ChildrenMetadata therefore provides a bucketed
+  // view of the various operations that are being traced as part of a span.
+  map<string, OperationMetadata> children_metadata = 19 [(gogoproto.nullable) = false];
+
+  reserved 5,6,10,11,15;
+}
+
+message TagGroup {
+  // May be empty. If so, indicates that contained Tags should be treated as
+  // top-level.
+  //
+  // If a value is instead present here, indicates that this group is a
+  // structured collection of related tags.
+  string name = 1;
+
+  repeated Tag tags = 2 [(gogoproto.nullable) = false];
+}
+
+message Tag {
+  // key is the name of the tag. This is a safe value.
+  string key = 1;
+  // value is the value of the tag. This is NOT a safe value.
+  // It may contain PII or other sensitive information.
+  // TODO(knz): we should deprecate this field, and define
+  // a new value field with type RedactableString.
+  string value = 2;
+}
+
+// NormalizedSpan is a representation of a RecordedSpan from a trace with all
+// its children embedded, recursively. This JSON serialization of this proto is
+// used in the system.statement_diagnostics.trace column.
+//
+// See RecordedSpan for the description of the fields.
+message NormalizedSpan {
+  string operation = 1;
+
+  // Deprecated. Avoid new uses. Prefer tag_groups.
+  // TODO(benbardin): Deprecate the tags field for 23.1.
+  map<string, string> tags = 2;
+
+  repeated TagGroup tag_groups = 8 [(gogoproto.nullable) = false];
+  google.protobuf.Timestamp start_time = 3 [(gogoproto.nullable) = false,
+                                           (gogoproto.stdtime) = true];
+  google.protobuf.Duration duration = 4 [(gogoproto.nullable) = false,
+                                        (gogoproto.stdduration) = true];
+  repeated LogRecord logs = 5 [(gogoproto.nullable) = false];
+  repeated StructuredRecord structured_records = 7 [(gogoproto.nullable) = false];
+  map<string, OperationMetadata> children_metadata = 9 [(gogoproto.nullable) = false];
+  repeated NormalizedSpan children = 6 [(gogoproto.nullable) = false];
+}
+
+message CapturedStack {
+  option (gogoproto.goproto_stringer) = false;
+  // Stack is the strack trace, or distinct prefix of the stack trace if a previous
+  // capture of this stack is also being recorded.
+  string stack = 1;
+  // SharedSuffix indicates the length of the elided suffix of this stack that 
+  // was identical to the previous capture of this stack.
+  int32 shared_suffix = 2;
+  // SharedLines indicated how many newlines were in the elided shared suffix.
+  int32 shared_lines = 3;
+  // Age indicates the duration prior to being recorded that this stack was captured.
+  int64 age = 4 [(gogoproto.casttype) = "time.Duration"];
+  // NEXT ID: 5.
+}
diff --git a/pkg/util/tracing/tracingpb/recording.go b/pkg/util/tracing/tracingpb/recording.go
new file mode 100644
index 0000000..adb9156
--- /dev/null
+++ b/pkg/util/tracing/tracingpb/recording.go
@@ -0,0 +1,548 @@
+// Copyright 2020 The Cockroach Authors.
+//
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
+
+package tracingpb
+
+import (
+	"encoding/json"
+	"fmt"
+	"regexp"
+	"sort"
+	"strconv"
+	"time"
+
+	"github.com/cockroachdb/cockroachdb-parser/pkg/util/protoutil"
+	"github.com/cockroachdb/errors"
+	"github.com/cockroachdb/redact"
+	"github.com/gogo/protobuf/jsonpb"
+	"github.com/gogo/protobuf/proto"
+	"github.com/gogo/protobuf/types"
+	jaegerjson "github.com/jaegertracing/jaeger/model/json"
+)
+
+// RecordingType is the type of recording that a Span might be performing.
+type RecordingType int32
+
+const (
+	// RecordingOff means that the Span discards events passed in.
+	RecordingOff RecordingType = iota
+
+	// RecordingStructured means that the Span discards events passed in through
+	// Recordf(), but collects events passed in through RecordStructured(), as
+	// well as information about child spans (their name, start and stop time).
+	RecordingStructured
+
+	// RecordingVerbose means that the Span collects events passed in through
+	// Recordf() in its recording.
+	RecordingVerbose
+)
+
+// ToCarrierValue encodes the RecordingType to be propagated through a carrier.
+func (t RecordingType) ToCarrierValue() string {
+	switch t {
+	case RecordingOff:
+		return "n"
+	case RecordingStructured:
+		return "s"
+	case RecordingVerbose:
+		return "v"
+	default:
+		panic(fmt.Sprintf("invalid RecordingType: %d", t))
+	}
+}
+
+// ToProto converts t to the corresponding proto enum.
+func (t RecordingType) ToProto() RecordingMode {
+	switch t {
+	case RecordingOff:
+		return RecordingMode_OFF
+	case RecordingStructured:
+		return RecordingMode_STRUCTURED
+	case RecordingVerbose:
+		return RecordingMode_VERBOSE
+	default:
+		panic(fmt.Sprintf("invalid RecordingType: %d", t))
+	}
+}
+
+// RecordingTypeFromProto converts from the proto values to the corresponding enum.
+func RecordingTypeFromProto(val RecordingMode) RecordingType {
+	switch val {
+	case RecordingMode_OFF:
+		return RecordingOff
+	case RecordingMode_STRUCTURED:
+		return RecordingStructured
+	case RecordingMode_VERBOSE:
+		return RecordingVerbose
+	default:
+		panic(fmt.Sprintf("invalid RecordingType: %d", val))
+	}
+}
+
+// RecordingTypeFromCarrierValue decodes a recording type carried by a carrier.
+func RecordingTypeFromCarrierValue(val string) RecordingType {
+	switch val {
+	case "v":
+		return RecordingVerbose
+	case "s":
+		return RecordingStructured
+	case "n":
+		return RecordingOff
+	default:
+		// Unrecognized.
+		return RecordingOff
+	}
+}
+
+type traceLogData struct {
+	logRecord
+	depth int
+	// timeSincePrev represents the duration since the previous log line (previous in the
+	// set of log lines that this is part of). This is always computed relative to a log line
+	// from the same Span, except for start of Span in which case the duration is computed relative
+	// to the last log in the parent occurring before this start. For example:
+	// start Span A
+	// log 1           // duration relative to "start Span A"
+	//   start Span B  // duration relative to "log 1"
+	//   log 2  			 // duration relative to "start Span B"
+	// log 3  				 // duration relative to "log 1"
+	timeSincePrev time.Duration
+}
+
+type logRecord struct {
+	Timestamp time.Time
+	Msg       redact.RedactableString
+}
+
+// String formats the given spans for human consumption, showing the
+// relationship using nesting and times as both relative to the previous event
+// and cumulative.
+//
+// Child spans are inserted into the parent at the point of the child's
+// StartTime; see the diagram on generateSessionTraceVTable() for the ordering
+// of messages.
+//
+// Each log line show the time since the beginning of the trace
+// and since the previous log line. Span starts are shown with special "===
+// <operation>" lines. For a Span start, the time since the relative log line
+// can be negative when the Span start follows a message from the parent that
+// was generated after the child Span started (or even after the child
+// finished).
+//
+// TODO(andrei): this should be unified with
+// SessionTracing.generateSessionTraceVTable().
+func (r Recording) String() string {
+	return redact.Sprint(r).StripMarkers()
+}
+
+// SafeFormat implements the redact.SafeFormatter interface.
+func (r Recording) SafeFormat(w redact.SafePrinter, _ rune) {
+	if len(r) == 0 {
+		w.SafeString("<empty recording>")
+		return
+	}
+
+	start := r[0].StartTime
+	writeLogs := func(logs []traceLogData) {
+		for _, entry := range logs {
+			w.Printf("% 10.3fms % 10.3fms",
+				1000*entry.Timestamp.Sub(start).Seconds(),
+				1000*entry.timeSincePrev.Seconds())
+			for i := 0; i < entry.depth+1; i++ {
+				w.SafeString("    ")
+			}
+			w.Printf("%s\n", entry.Msg)
+		}
+	}
+
+	logs := r.visitSpan(r[0], 0 /* depth */)
+	writeLogs(logs)
+
+	// Check if there's any orphan spans (spans for which the parent is missing).
+	// This shouldn't happen, but we're protecting against incomplete traces. For
+	// example, ingesting of remote spans through DistSQL is complex. Orphan spans
+	// would not be reflected in the output string at all without this.
+	orphans := r.OrphanSpans()
+	if len(orphans) > 0 {
+		// This shouldn't happen.
+		w.SafeString("orphan spans (trace is missing spans):\n")
+		for _, o := range orphans {
+			logs := r.visitSpan(o, 0 /* depth */)
+			writeLogs(logs)
+		}
+	}
+}
+
+// OrphanSpans returns the spans with parents missing from the recording.
+func (r Recording) OrphanSpans() []RecordedSpan {
+	spanIDs := make(map[SpanID]struct{})
+	for _, sp := range r {
+		spanIDs[sp.SpanID] = struct{}{}
+	}
+
+	var orphans []RecordedSpan
+	for i, sp := range r {
+		if i == 0 {
+			// The first Span can be a root Span. Note that any other root Span will
+			// be considered an orphan.
+			continue
+		}
+		if _, ok := spanIDs[sp.ParentSpanID]; !ok {
+			orphans = append(orphans, sp)
+		}
+	}
+	return orphans
+}
+
+// FindLogMessage returns the first log message in the recording that matches
+// the given regexp. The bool return value is true if such a message is found.
+//
+// This method strips the redaction markers from all the log messages, which is
+// pretty inefficient.
+func (r Recording) FindLogMessage(pattern string) (string, bool) {
+	re := regexp.MustCompile(pattern)
+	for _, sp := range r {
+		for _, l := range sp.Logs {
+			msg := l.Msg().StripMarkers()
+			if re.MatchString(msg) {
+				return msg, true
+			}
+		}
+	}
+	return "", false
+}
+
+// FindSpan returns the Span with the given operation. The bool retval is false
+// if the Span is not found.
+func (r Recording) FindSpan(operation string) (RecordedSpan, bool) {
+	for _, sp := range r {
+		if sp.Operation == operation {
+			return sp, true
+		}
+	}
+	return RecordedSpan{}, false
+}
+
+// OperationAndMetadata contains information about a tracing span operation and
+// its corresponding metadata.
+type OperationAndMetadata struct {
+	Operation string
+	Metadata  OperationMetadata
+}
+
+// visitSpan returns the log messages for sp, and all of sp's children.
+//
+// All messages from a Span are kept together. Sibling spans are ordered within
+// the parent in their start order.
+func (r Recording) visitSpan(sp RecordedSpan, depth int) []traceLogData {
+	ownLogs := make([]traceLogData, 0, len(sp.Logs)+1)
+
+	conv := func(msg redact.RedactableString, timestamp time.Time, ref time.Time) traceLogData {
+		var timeSincePrev time.Duration
+		if ref != (time.Time{}) {
+			timeSincePrev = timestamp.Sub(ref)
+		}
+		return traceLogData{
+			logRecord: logRecord{
+				Timestamp: timestamp,
+				Msg:       msg,
+			},
+			depth:         depth,
+			timeSincePrev: timeSincePrev,
+		}
+	}
+
+	// Add a log line representing the start of the Span.
+	var sb redact.StringBuilder
+	sb.SafeString("=== operation:")
+	sb.SafeString(redact.SafeString(sp.Operation))
+
+	for _, tg := range sp.TagGroups {
+		var prefix redact.RedactableString
+		if tg.Name != AnonymousTagGroupName {
+			prefix = redact.Sprint("%s-", redact.SafeString(tg.Name))
+		}
+		for _, tag := range tg.Tags {
+			sb.Printf(" %s%s:%s", prefix, redact.SafeString(tag.Key), tag.Value)
+		}
+	}
+
+	ownLogs = append(ownLogs, conv(
+		sb.RedactableString(),
+		sp.StartTime,
+		// ref - this entries timeSincePrev will be computed when we merge it into the parent
+		time.Time{}))
+
+	// Sort the OperationMetadata of s' children in descending order of duration.
+	childrenMetadata := make([]OperationAndMetadata, 0, len(sp.ChildrenMetadata))
+	for operation, metadata := range sp.ChildrenMetadata {
+		childrenMetadata = append(childrenMetadata,
+			OperationAndMetadata{operation, metadata})
+	}
+	sort.Slice(childrenMetadata, func(i, j int) bool {
+		return childrenMetadata[i].Metadata.Duration > childrenMetadata[j].Metadata.Duration
+	})
+	for _, c := range childrenMetadata {
+		var sb redact.StringBuilder
+		sb.Printf("[%s: %s]", redact.SafeString(c.Operation), c.Metadata)
+		ownLogs = append(ownLogs, conv(sb.RedactableString(), sp.StartTime, time.Time{}))
+	}
+
+	for _, l := range sp.Logs {
+		lastLog := ownLogs[len(ownLogs)-1]
+		var sb redact.StringBuilder
+		sb.Printf("event:%s", l.Msg())
+		ownLogs = append(ownLogs, conv(sb.RedactableString(), l.Time, lastLog.Timestamp))
+	}
+
+	// If the span was verbose at the time when the structured event was recorded,
+	// then the Structured events will also have been stringified and included in
+	// the Logs above. We conservatively serialize the structured events again
+	// here, for the case when the span had not been verbose at the time.
+	sp.Structured(func(sr *types.Any, t time.Time) {
+		str, err := MessageToJSONString(sr, false /* emitDefaults */)
+		if err != nil {
+			return
+		}
+		lastLog := ownLogs[len(ownLogs)-1]
+		var sb redact.StringBuilder
+		sb.SafeString("structured:")
+		_, _ = sb.WriteString(str)
+		ownLogs = append(ownLogs, conv(sb.RedactableString(), t, lastLog.Timestamp))
+	})
+
+	childSpans := make([][]traceLogData, 0)
+	for _, osp := range r {
+		if osp.ParentSpanID != sp.SpanID {
+			continue
+		}
+		childSpans = append(childSpans, r.visitSpan(osp, depth+1))
+	}
+
+	// Merge ownLogs with childSpans.
+	mergedLogs := make([]traceLogData, 0, len(ownLogs))
+	timeMax := time.Date(2200, 0, 0, 0, 0, 0, 0, time.UTC)
+	i, j := 0, 0
+	var lastTimestamp time.Time
+	for i < len(ownLogs) || j < len(childSpans) {
+		if len(mergedLogs) > 0 {
+			lastTimestamp = mergedLogs[len(mergedLogs)-1].Timestamp
+		}
+		nextLog, nextChild := timeMax, timeMax
+		if i < len(ownLogs) {
+			nextLog = ownLogs[i].Timestamp
+		}
+		if j < len(childSpans) {
+			nextChild = childSpans[j][0].Timestamp
+		}
+		if nextLog.After(nextChild) {
+			// Fill in timeSincePrev for the first one of the child's entries.
+			if lastTimestamp != (time.Time{}) {
+				childSpans[j][0].timeSincePrev = childSpans[j][0].Timestamp.Sub(lastTimestamp)
+			}
+			mergedLogs = append(mergedLogs, childSpans[j]...)
+			lastTimestamp = childSpans[j][0].Timestamp
+			j++
+		} else {
+			mergedLogs = append(mergedLogs, ownLogs[i])
+			lastTimestamp = ownLogs[i].Timestamp
+			i++
+		}
+	}
+
+	return mergedLogs
+}
+
+// ToJaegerJSON returns the trace as a JSON that can be imported into Jaeger for
+// visualization.
+//
+// The format is described here: https://github.com/jaegertracing/jaeger-ui/issues/381#issuecomment-494150826
+//
+// The statement is passed in so it can be included in the trace.
+func (r Recording) ToJaegerJSON(stmt, comment, nodeStr string) (string, error) {
+	if len(r) == 0 {
+		return "", nil
+	}
+
+	cpy := make(Recording, len(r))
+	copy(cpy, r)
+	r = cpy
+
+	tagGroupsCopy := make([]TagGroup, len(r[0].TagGroups))
+	var anonymousTagGroup *TagGroup
+	for i, tg := range r[0].TagGroups {
+		tagGroupsCopy[i] = tg
+		if tagGroupsCopy[i].Name == "" {
+			anonymousTagGroup = &tagGroupsCopy[i]
+		}
+	}
+	if anonymousTagGroup == nil {
+		tagGroupsCopy = append(tagGroupsCopy, TagGroup{})
+		anonymousTagGroup = &tagGroupsCopy[len(tagGroupsCopy)-1]
+	}
+	anonymousTagGroup.Tags = append(anonymousTagGroup.Tags, Tag{
+		Key:   "statement",
+		Value: stmt,
+	})
+	r[0].TagGroups = tagGroupsCopy
+
+	toJaegerSpanID := func(spanID SpanID) jaegerjson.SpanID {
+		return jaegerjson.SpanID(strconv.FormatUint(uint64(spanID), 10))
+	}
+
+	// Each Span in Jaeger belongs to a "process" that generated it. Spans
+	// belonging to different colors are colored differently in Jaeger. We're
+	// going to map our different nodes to different processes.
+	processes := make(map[jaegerjson.ProcessID]jaegerjson.Process)
+	// getProcessID figures out what "process" a Span belongs to. It looks for an
+	// "node: <node id>" tag. The processes map is populated with an entry for every
+	// node present in the trace.
+	getProcessID := func(sp RecordedSpan) jaegerjson.ProcessID {
+		node := "unknown node"
+		for _, tagGroup := range sp.TagGroups {
+			if tagGroup.Name != "" {
+				// We know this particular tag is in the anonymous tag group, so only
+				// search for that one.
+				continue
+			}
+			for _, tag := range tagGroup.Tags {
+				if tag.Key == "node" {
+					node = fmt.Sprintf("node %s", tag.Value)
+					break
+				}
+			}
+		}
+		// If we have passed in an explicit nodeStr then use that as a processID.
+		if nodeStr != "" {
+			node = nodeStr
+		}
+		pid := jaegerjson.ProcessID(node)
+		if _, ok := processes[pid]; !ok {
+			processes[pid] = jaegerjson.Process{
+				ServiceName: node,
+				Tags:        nil,
+			}
+		}
+		return pid
+	}
+
+	var t jaegerjson.Trace
+	t.TraceID = jaegerjson.TraceID(strconv.FormatUint(uint64(r[0].TraceID), 10))
+	t.Processes = processes
+
+	for _, sp := range r {
+		var s jaegerjson.Span
+
+		s.TraceID = t.TraceID
+		s.Duration = uint64(sp.Duration.Microseconds())
+		s.StartTime = uint64(sp.StartTime.UnixNano() / 1000)
+		s.SpanID = toJaegerSpanID(sp.SpanID)
+		s.OperationName = sp.Operation
+		s.ProcessID = getProcessID(sp)
+
+		if sp.ParentSpanID != 0 {
+			s.References = []jaegerjson.Reference{{
+				RefType: jaegerjson.ChildOf,
+				TraceID: s.TraceID,
+				SpanID:  toJaegerSpanID(sp.ParentSpanID),
+			}}
+		}
+
+		if sp.GoroutineID != 0 {
+			s.Tags = append(s.Tags, jaegerjson.KeyValue{
+				Key:   "goroutine",
+				Value: sp.GoroutineID,
+				Type:  jaegerjson.Int64Type,
+			})
+		}
+		for _, tagGroup := range sp.TagGroups {
+			for _, tag := range tagGroup.Tags {
+				var prefix string
+				if tagGroup.Name != AnonymousTagGroupName {
+					prefix = fmt.Sprintf("%s-", tagGroup.Name)
+				}
+				s.Tags = append(s.Tags, jaegerjson.KeyValue{
+					Key:   fmt.Sprintf("%s%s", prefix, tag.Key),
+					Value: tag.Value,
+					Type:  "STRING",
+				})
+			}
+		}
+		for _, l := range sp.Logs {
+			jl := jaegerjson.Log{
+				Timestamp: uint64(l.Time.UnixNano() / 1000),
+				Fields: []jaegerjson.KeyValue{{
+					Key:   "event",
+					Value: l.Msg(),
+					Type:  "STRING",
+				}},
+			}
+			s.Logs = append(s.Logs, jl)
+		}
+
+		// If the span was verbose at the time when each structured event was
+		// recorded, then the respective events would have been stringified and
+		// included in the Logs above. If the span was not verbose at the time, we
+		// need to produce a string now. We don't know whether the span was verbose
+		// or not at the time each event was recorded, so we make a guess based on
+		// whether the span was verbose at the moment when the Recording was
+		// produced.
+		if !(sp.Verbose || sp.RecordingMode == RecordingMode_VERBOSE) {
+			sp.Structured(func(sr *types.Any, t time.Time) {
+				jl := jaegerjson.Log{Timestamp: uint64(t.UnixNano() / 1000)}
+				jsonStr, err := MessageToJSONString(sr, false /* emitDefaults */)
+				if err != nil {
+					return
+				}
+				jl.Fields = append(jl.Fields, jaegerjson.KeyValue{
+					Key:   "structured",
+					Value: jsonStr,
+					Type:  "STRING",
+				})
+				s.Logs = append(s.Logs, jl)
+			})
+		}
+
+		t.Spans = append(t.Spans, s)
+	}
+
+	data := TraceCollection{
+		Data: []jaegerjson.Trace{t},
+		// Add a comment that will show-up at the top of the JSON file, is someone opens the file.
+		// NOTE: This comment is scarce on newlines because they appear as \n in the
+		// generated file doing more harm than good.
+		Comment: comment,
+	}
+	json, err := json.MarshalIndent(data, "" /* prefix */, "\t" /* indent */)
+	if err != nil {
+		return "", err
+	}
+	return string(json), nil
+}
+
+// TraceCollection is the format accepted by the Jaegar upload feature, as per
+// https://github.com/jaegertracing/jaeger-ui/issues/381#issuecomment-494150826
+type TraceCollection struct {
+	// Comment is a dummy field we use to put instructions on how to load the trace.
+	Comment string             `json:"_comment"`
+	Data    []jaegerjson.Trace `json:"data"`
+}
+
+// MessageToJSONString converts a protocol message into a JSON string. The
+// emitDefaults flag dictates whether fields with zero values are rendered or
+// not.
+//
+// TODO(andrei): It'd be nice if this function dealt with redactable vs safe
+// fields, like EventPayload.AppendJSONFields does.
+func MessageToJSONString(msg protoutil.Message, emitDefaults bool) (string, error) {
+	// Convert to json.
+	jsonEncoder := jsonpb.Marshaler{EmitDefaults: emitDefaults}
+	msgJSON, err := jsonEncoder.MarshalToString(msg)
+	if err != nil {
+		return "", errors.Newf("error when converting %s to JSON string", proto.MessageName(msg))
+	}
+
+	return msgJSON, nil
+}
diff --git a/pkg/util/tracing/tracingpb/tracing.go b/pkg/util/tracing/tracingpb/tracing.go
new file mode 100644
index 0000000..75358bc
--- /dev/null
+++ b/pkg/util/tracing/tracingpb/tracing.go
@@ -0,0 +1,11 @@
+// Copyright 2021 The Cockroach Authors.
+//
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
+
+package tracingpb
+
+// Empty returns true if t does not have any tracing info in it.
+func (t *TraceInfo) Empty() bool {
+	return t == nil || t.TraceID == 0
+}
diff --git a/pkg/util/tracing/tracingpb/tracing.pb.go b/pkg/util/tracing/tracingpb/tracing.pb.go
new file mode 100644
index 0000000..aaf6955
--- /dev/null
+++ b/pkg/util/tracing/tracingpb/tracing.pb.go
@@ -0,0 +1,661 @@
+// Code generated by protoc-gen-gogo. DO NOT EDIT.
+// source: util/tracing/tracingpb/tracing.proto
+
+package tracingpb
+
+import (
+	fmt "fmt"
+	_ "github.com/gogo/protobuf/gogoproto"
+	proto "github.com/gogo/protobuf/proto"
+	io "io"
+	math "math"
+	math_bits "math/bits"
+)
+
+// Reference imports to suppress errors if they are not otherwise used.
+var _ = proto.Marshal
+var _ = fmt.Errorf
+var _ = math.Inf
+
+// This is a compile-time assertion to ensure that this generated file
+// is compatible with the proto package it is being compiled against.
+// A compilation error at this line likely means your copy of the
+// proto package needs to be updated.
+const _ = proto.GoGoProtoPackageIsVersion3 // please upgrade the proto package
+
+type RecordingMode int32
+
+const (
+	RecordingMode_OFF        RecordingMode = 0
+	RecordingMode_VERBOSE    RecordingMode = 1
+	RecordingMode_STRUCTURED RecordingMode = 2
+)
+
+var RecordingMode_name = map[int32]string{
+	0: "OFF",
+	1: "VERBOSE",
+	2: "STRUCTURED",
+}
+
+var RecordingMode_value = map[string]int32{
+	"OFF":        0,
+	"VERBOSE":    1,
+	"STRUCTURED": 2,
+}
+
+func (x RecordingMode) String() string {
+	return proto.EnumName(RecordingMode_name, int32(x))
+}
+
+func (RecordingMode) EnumDescriptor() ([]byte, []int) {
+	return fileDescriptor_26ff58dc79e6a348, []int{0}
+}
+
+// TraceInfo represents the tracing context of an operation. It is the proto
+// representation of tracing.SpanMeta. TraceInfos are passed around in RPC
+// payloads so that the server can create spans that are linked to the remote
+// parent.
+type TraceInfo struct {
+	TraceID TraceID `protobuf:"varint,1,opt,name=trace_id,json=traceId,proto3,customtype=TraceID" json:"trace_id"`
+	// ID of the parent span.
+	ParentSpanID SpanID `protobuf:"varint,2,opt,name=parent_span_id,json=parentSpanId,proto3,customtype=SpanID" json:"parent_span_id"`
+	// The type of recording, if any, that the parent span is doing. See
+	// tracing.RecordingType.
+	RecordingMode RecordingMode       `protobuf:"varint,3,opt,name=recording_mode,json=recordingMode,proto3,enum=cockroach.util.tracing.tracingpb.RecordingMode" json:"recording_mode,omitempty"`
+	Otel          *TraceInfo_OtelInfo `protobuf:"bytes,4,opt,name=otel,proto3" json:"otel,omitempty"`
+}
+
+func (m *TraceInfo) Reset()         { *m = TraceInfo{} }
+func (m *TraceInfo) String() string { return proto.CompactTextString(m) }
+func (*TraceInfo) ProtoMessage()    {}
+func (*TraceInfo) Descriptor() ([]byte, []int) {
+	return fileDescriptor_26ff58dc79e6a348, []int{0}
+}
+func (m *TraceInfo) XXX_Unmarshal(b []byte) error {
+	return m.Unmarshal(b)
+}
+func (m *TraceInfo) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+	b = b[:cap(b)]
+	n, err := m.MarshalToSizedBuffer(b)
+	if err != nil {
+		return nil, err
+	}
+	return b[:n], nil
+}
+func (m *TraceInfo) XXX_Merge(src proto.Message) {
+	xxx_messageInfo_TraceInfo.Merge(m, src)
+}
+func (m *TraceInfo) XXX_Size() int {
+	return m.Size()
+}
+func (m *TraceInfo) XXX_DiscardUnknown() {
+	xxx_messageInfo_TraceInfo.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_TraceInfo proto.InternalMessageInfo
+
+// OtelInfo contains the OpenTelemetry tracing context, if any.
+type TraceInfo_OtelInfo struct {
+	// trace_id will have exactly 16 bytes.
+	TraceID []byte `protobuf:"bytes,1,opt,name=trace_id,json=traceId,proto3" json:"trace_id,omitempty"`
+	// span_id will have exactly 8 bytes.
+	SpanID []byte `protobuf:"bytes,2,opt,name=span_id,json=spanId,proto3" json:"span_id,omitempty"`
+}
+
+func (m *TraceInfo_OtelInfo) Reset()         { *m = TraceInfo_OtelInfo{} }
+func (m *TraceInfo_OtelInfo) String() string { return proto.CompactTextString(m) }
+func (*TraceInfo_OtelInfo) ProtoMessage()    {}
+func (*TraceInfo_OtelInfo) Descriptor() ([]byte, []int) {
+	return fileDescriptor_26ff58dc79e6a348, []int{0, 0}
+}
+func (m *TraceInfo_OtelInfo) XXX_Unmarshal(b []byte) error {
+	return m.Unmarshal(b)
+}
+func (m *TraceInfo_OtelInfo) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+	b = b[:cap(b)]
+	n, err := m.MarshalToSizedBuffer(b)
+	if err != nil {
+		return nil, err
+	}
+	return b[:n], nil
+}
+func (m *TraceInfo_OtelInfo) XXX_Merge(src proto.Message) {
+	xxx_messageInfo_TraceInfo_OtelInfo.Merge(m, src)
+}
+func (m *TraceInfo_OtelInfo) XXX_Size() int {
+	return m.Size()
+}
+func (m *TraceInfo_OtelInfo) XXX_DiscardUnknown() {
+	xxx_messageInfo_TraceInfo_OtelInfo.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_TraceInfo_OtelInfo proto.InternalMessageInfo
+
+func init() {
+	proto.RegisterEnum("cockroach.parser.util.tracing.tracingpb.RecordingMode", RecordingMode_name, RecordingMode_value)
+	proto.RegisterType((*TraceInfo)(nil), "cockroach.parser.util.tracing.tracingpb.TraceInfo")
+	proto.RegisterType((*TraceInfo_OtelInfo)(nil), "cockroach.parser.util.tracing.tracingpb.TraceInfo.OtelInfo")
+}
+
+func init() {
+	proto.RegisterFile("util/tracing/tracingpb/tracing.proto", fileDescriptor_26ff58dc79e6a348)
+}
+
+var fileDescriptor_26ff58dc79e6a348 = []byte{
+	// 388 bytes of a gzipped FileDescriptorProto
+	0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x84, 0x92, 0x4f, 0x8b, 0xda, 0x40,
+	0x18, 0xc6, 0x33, 0x2a, 0xc6, 0x8e, 0x31, 0xc8, 0xd0, 0x83, 0x78, 0x18, 0x43, 0x5b, 0x8a, 0xf4,
+	0x90, 0x80, 0xad, 0xa7, 0xde, 0x52, 0x95, 0x7a, 0x28, 0x96, 0xf1, 0xcf, 0xc2, 0xc2, 0x22, 0xf9,
+	0x33, 0x1b, 0x83, 0x9a, 0x09, 0x63, 0xfc, 0x04, 0xfb, 0x05, 0xf6, 0x63, 0x79, 0xf4, 0x28, 0x7b,
+	0x90, 0xdd, 0xf8, 0x45, 0x96, 0x8c, 0x9b, 0xe8, 0x2e, 0x82, 0xa7, 0x3c, 0x6f, 0xe6, 0xf9, 0xbd,
+	0xf0, 0x3c, 0xbc, 0xf0, 0xdb, 0x3a, 0xf2, 0x17, 0x46, 0xc4, 0x2d, 0xc7, 0x0f, 0xbc, 0xf4, 0x1b,
+	0xda, 0xa9, 0xd2, 0x43, 0xce, 0x22, 0x86, 0x34, 0x87, 0x39, 0x73, 0xce, 0x2c, 0x67, 0xa6, 0x27,
+	0x7e, 0x3d, 0x7d, 0xcd, 0xfc, 0xf5, 0xcf, 0x1e, 0xf3, 0x98, 0x30, 0x1b, 0x89, 0x3a, 0x72, 0x5f,
+	0x1e, 0xf2, 0xf0, 0xd3, 0x88, 0x5b, 0x0e, 0xed, 0x07, 0xf7, 0x0c, 0xb5, 0x61, 0x29, 0x01, 0xe8,
+	0xd4, 0x77, 0x6b, 0x40, 0x03, 0xcd, 0x82, 0x59, 0xdf, 0xec, 0x1b, 0xd2, 0xd3, 0xbe, 0x21, 0x1f,
+	0x4d, 0x9d, 0xf8, 0x24, 0x89, 0x2c, 0xbc, 0x7d, 0x17, 0x75, 0xa0, 0x1a, 0x5a, 0x9c, 0x06, 0xd1,
+	0x74, 0x15, 0x5a, 0x41, 0x02, 0xe7, 0x04, 0x8c, 0xdf, 0xe0, 0xe2, 0x30, 0xb4, 0x02, 0xc1, 0x2a,
+	0xff, 0x85, 0xef, 0x38, 0x13, 0x25, 0x3c, 0x4d, 0x2e, 0x9a, 0x40, 0x95, 0x53, 0x87, 0x71, 0xd7,
+	0x0f, 0xbc, 0xe9, 0x92, 0xb9, 0xb4, 0x96, 0xd7, 0x40, 0x53, 0x6d, 0x19, 0xfa, 0xb5, 0x6c, 0x3a,
+	0x49, 0xb9, 0x7f, 0xcc, 0xa5, 0xa4, 0xc2, 0xcf, 0x47, 0xf4, 0x17, 0x16, 0x58, 0x44, 0x17, 0xb5,
+	0x82, 0x06, 0x9a, 0xe5, 0xd6, 0xaf, 0xeb, 0xdb, 0xb2, 0x3e, 0xf4, 0x41, 0x44, 0x17, 0x89, 0x20,
+	0x62, 0x43, 0xfd, 0x06, 0x96, 0xd2, 0x3f, 0xe8, 0xfb, 0x87, 0xaa, 0x14, 0xb3, 0x7c, 0xb1, 0x9b,
+	0xaf, 0x50, 0x3e, 0x2f, 0x45, 0x31, 0x61, 0x9c, 0x15, 0x42, 0x8a, 0x2b, 0x11, 0xfd, 0x47, 0x1b,
+	0x56, 0xde, 0x45, 0x40, 0x32, 0xcc, 0x0f, 0x7a, 0xbd, 0xaa, 0x84, 0xca, 0x50, 0x9e, 0x74, 0x89,
+	0x39, 0x18, 0x76, 0xab, 0x00, 0xa9, 0x10, 0x0e, 0x47, 0x64, 0xfc, 0x67, 0x34, 0x26, 0xdd, 0x4e,
+	0x35, 0x67, 0xde, 0x6d, 0x5e, 0xb0, 0xb4, 0x89, 0x31, 0xd8, 0xc6, 0x18, 0xec, 0x62, 0x0c, 0x9e,
+	0x63, 0x0c, 0x1e, 0x0f, 0x58, 0xda, 0x1e, 0xb0, 0xb4, 0x3b, 0x60, 0xe9, 0xf6, 0xb7, 0xe7, 0x47,
+	0xb3, 0xb5, 0xad, 0x3b, 0x6c, 0x69, 0x64, 0xb9, 0x5d, 0xfb, 0xa4, 0x8d, 0x70, 0xee, 0x19, 0x97,
+	0x2f, 0xcc, 0x2e, 0x8a, 0x13, 0xf9, 0xf9, 0x1a, 0x00, 0x00, 0xff, 0xff, 0xe8, 0x00, 0xf7, 0xb2,
+	0x82, 0x02, 0x00, 0x00,
+}
+
+func (m *TraceInfo) Marshal() (dAtA []byte, err error) {
+	size := m.Size()
+	dAtA = make([]byte, size)
+	n, err := m.MarshalToSizedBuffer(dAtA[:size])
+	if err != nil {
+		return nil, err
+	}
+	return dAtA[:n], nil
+}
+
+func (m *TraceInfo) MarshalTo(dAtA []byte) (int, error) {
+	size := m.Size()
+	return m.MarshalToSizedBuffer(dAtA[:size])
+}
+
+func (m *TraceInfo) MarshalToSizedBuffer(dAtA []byte) (int, error) {
+	i := len(dAtA)
+	_ = i
+	var l int
+	_ = l
+	if m.Otel != nil {
+		{
+			size, err := m.Otel.MarshalToSizedBuffer(dAtA[:i])
+			if err != nil {
+				return 0, err
+			}
+			i -= size
+			i = encodeVarintTracing(dAtA, i, uint64(size))
+		}
+		i--
+		dAtA[i] = 0x22
+	}
+	if m.RecordingMode != 0 {
+		i = encodeVarintTracing(dAtA, i, uint64(m.RecordingMode))
+		i--
+		dAtA[i] = 0x18
+	}
+	if m.ParentSpanID != 0 {
+		i = encodeVarintTracing(dAtA, i, uint64(m.ParentSpanID))
+		i--
+		dAtA[i] = 0x10
+	}
+	if m.TraceID != 0 {
+		i = encodeVarintTracing(dAtA, i, uint64(m.TraceID))
+		i--
+		dAtA[i] = 0x8
+	}
+	return len(dAtA) - i, nil
+}
+
+func (m *TraceInfo_OtelInfo) Marshal() (dAtA []byte, err error) {
+	size := m.Size()
+	dAtA = make([]byte, size)
+	n, err := m.MarshalToSizedBuffer(dAtA[:size])
+	if err != nil {
+		return nil, err
+	}
+	return dAtA[:n], nil
+}
+
+func (m *TraceInfo_OtelInfo) MarshalTo(dAtA []byte) (int, error) {
+	size := m.Size()
+	return m.MarshalToSizedBuffer(dAtA[:size])
+}
+
+func (m *TraceInfo_OtelInfo) MarshalToSizedBuffer(dAtA []byte) (int, error) {
+	i := len(dAtA)
+	_ = i
+	var l int
+	_ = l
+	if len(m.SpanID) > 0 {
+		i -= len(m.SpanID)
+		copy(dAtA[i:], m.SpanID)
+		i = encodeVarintTracing(dAtA, i, uint64(len(m.SpanID)))
+		i--
+		dAtA[i] = 0x12
+	}
+	if len(m.TraceID) > 0 {
+		i -= len(m.TraceID)
+		copy(dAtA[i:], m.TraceID)
+		i = encodeVarintTracing(dAtA, i, uint64(len(m.TraceID)))
+		i--
+		dAtA[i] = 0xa
+	}
+	return len(dAtA) - i, nil
+}
+
+func encodeVarintTracing(dAtA []byte, offset int, v uint64) int {
+	offset -= sovTracing(v)
+	base := offset
+	for v >= 1<<7 {
+		dAtA[offset] = uint8(v&0x7f | 0x80)
+		v >>= 7
+		offset++
+	}
+	dAtA[offset] = uint8(v)
+	return base
+}
+func (m *TraceInfo) Size() (n int) {
+	if m == nil {
+		return 0
+	}
+	var l int
+	_ = l
+	if m.TraceID != 0 {
+		n += 1 + sovTracing(uint64(m.TraceID))
+	}
+	if m.ParentSpanID != 0 {
+		n += 1 + sovTracing(uint64(m.ParentSpanID))
+	}
+	if m.RecordingMode != 0 {
+		n += 1 + sovTracing(uint64(m.RecordingMode))
+	}
+	if m.Otel != nil {
+		l = m.Otel.Size()
+		n += 1 + l + sovTracing(uint64(l))
+	}
+	return n
+}
+
+func (m *TraceInfo_OtelInfo) Size() (n int) {
+	if m == nil {
+		return 0
+	}
+	var l int
+	_ = l
+	l = len(m.TraceID)
+	if l > 0 {
+		n += 1 + l + sovTracing(uint64(l))
+	}
+	l = len(m.SpanID)
+	if l > 0 {
+		n += 1 + l + sovTracing(uint64(l))
+	}
+	return n
+}
+
+func sovTracing(x uint64) (n int) {
+	return int((uint32(math_bits.Len64(x|1)+6) * 37) >> 8)
+}
+func sozTracing(x uint64) (n int) {
+	return sovTracing(uint64((x << 1) ^ uint64((int64(x) >> 63))))
+}
+func (m *TraceInfo) Unmarshal(dAtA []byte) error {
+	l := len(dAtA)
+	iNdEx := 0
+	for iNdEx < l {
+		preIndex := iNdEx
+		var wire uint64
+		for shift := uint(0); ; shift += 7 {
+			if shift >= 64 {
+				return ErrIntOverflowTracing
+			}
+			if iNdEx >= l {
+				return io.ErrUnexpectedEOF
+			}
+			b := dAtA[iNdEx]
+			iNdEx++
+			wire |= uint64(b&0x7F) << shift
+			if b < 0x80 {
+				break
+			}
+		}
+		fieldNum := int32(wire >> 3)
+		wireType := int(wire & 0x7)
+		if wireType == 4 {
+			return fmt.Errorf("proto: TraceInfo: wiretype end group for non-group")
+		}
+		if fieldNum <= 0 {
+			return fmt.Errorf("proto: TraceInfo: illegal tag %d (wire type %d)", fieldNum, wire)
+		}
+		switch fieldNum {
+		case 1:
+			if wireType != 0 {
+				return fmt.Errorf("proto: wrong wireType = %d for field TraceID", wireType)
+			}
+			m.TraceID = 0
+			for shift := uint(0); ; shift += 7 {
+				if shift >= 64 {
+					return ErrIntOverflowTracing
+				}
+				if iNdEx >= l {
+					return io.ErrUnexpectedEOF
+				}
+				b := dAtA[iNdEx]
+				iNdEx++
+				m.TraceID |= TraceID(b&0x7F) << shift
+				if b < 0x80 {
+					break
+				}
+			}
+		case 2:
+			if wireType != 0 {
+				return fmt.Errorf("proto: wrong wireType = %d for field ParentSpanID", wireType)
+			}
+			m.ParentSpanID = 0
+			for shift := uint(0); ; shift += 7 {
+				if shift >= 64 {
+					return ErrIntOverflowTracing
+				}
+				if iNdEx >= l {
+					return io.ErrUnexpectedEOF
+				}
+				b := dAtA[iNdEx]
+				iNdEx++
+				m.ParentSpanID |= SpanID(b&0x7F) << shift
+				if b < 0x80 {
+					break
+				}
+			}
+		case 3:
+			if wireType != 0 {
+				return fmt.Errorf("proto: wrong wireType = %d for field RecordingMode", wireType)
+			}
+			m.RecordingMode = 0
+			for shift := uint(0); ; shift += 7 {
+				if shift >= 64 {
+					return ErrIntOverflowTracing
+				}
+				if iNdEx >= l {
+					return io.ErrUnexpectedEOF
+				}
+				b := dAtA[iNdEx]
+				iNdEx++
+				m.RecordingMode |= RecordingMode(b&0x7F) << shift
+				if b < 0x80 {
+					break
+				}
+			}
+		case 4:
+			if wireType != 2 {
+				return fmt.Errorf("proto: wrong wireType = %d for field Otel", wireType)
+			}
+			var msglen int
+			for shift := uint(0); ; shift += 7 {
+				if shift >= 64 {
+					return ErrIntOverflowTracing
+				}
+				if iNdEx >= l {
+					return io.ErrUnexpectedEOF
+				}
+				b := dAtA[iNdEx]
+				iNdEx++
+				msglen |= int(b&0x7F) << shift
+				if b < 0x80 {
+					break
+				}
+			}
+			if msglen < 0 {
+				return ErrInvalidLengthTracing
+			}
+			postIndex := iNdEx + msglen
+			if postIndex < 0 {
+				return ErrInvalidLengthTracing
+			}
+			if postIndex > l {
+				return io.ErrUnexpectedEOF
+			}
+			if m.Otel == nil {
+				m.Otel = &TraceInfo_OtelInfo{}
+			}
+			if err := m.Otel.Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
+				return err
+			}
+			iNdEx = postIndex
+		default:
+			iNdEx = preIndex
+			skippy, err := skipTracing(dAtA[iNdEx:])
+			if err != nil {
+				return err
+			}
+			if (skippy < 0) || (iNdEx+skippy) < 0 {
+				return ErrInvalidLengthTracing
+			}
+			if (iNdEx + skippy) > l {
+				return io.ErrUnexpectedEOF
+			}
+			iNdEx += skippy
+		}
+	}
+
+	if iNdEx > l {
+		return io.ErrUnexpectedEOF
+	}
+	return nil
+}
+func (m *TraceInfo_OtelInfo) Unmarshal(dAtA []byte) error {
+	l := len(dAtA)
+	iNdEx := 0
+	for iNdEx < l {
+		preIndex := iNdEx
+		var wire uint64
+		for shift := uint(0); ; shift += 7 {
+			if shift >= 64 {
+				return ErrIntOverflowTracing
+			}
+			if iNdEx >= l {
+				return io.ErrUnexpectedEOF
+			}
+			b := dAtA[iNdEx]
+			iNdEx++
+			wire |= uint64(b&0x7F) << shift
+			if b < 0x80 {
+				break
+			}
+		}
+		fieldNum := int32(wire >> 3)
+		wireType := int(wire & 0x7)
+		if wireType == 4 {
+			return fmt.Errorf("proto: OtelInfo: wiretype end group for non-group")
+		}
+		if fieldNum <= 0 {
+			return fmt.Errorf("proto: OtelInfo: illegal tag %d (wire type %d)", fieldNum, wire)
+		}
+		switch fieldNum {
+		case 1:
+			if wireType != 2 {
+				return fmt.Errorf("proto: wrong wireType = %d for field TraceID", wireType)
+			}
+			var byteLen int
+			for shift := uint(0); ; shift += 7 {
+				if shift >= 64 {
+					return ErrIntOverflowTracing
+				}
+				if iNdEx >= l {
+					return io.ErrUnexpectedEOF
+				}
+				b := dAtA[iNdEx]
+				iNdEx++
+				byteLen |= int(b&0x7F) << shift
+				if b < 0x80 {
+					break
+				}
+			}
+			if byteLen < 0 {
+				return ErrInvalidLengthTracing
+			}
+			postIndex := iNdEx + byteLen
+			if postIndex < 0 {
+				return ErrInvalidLengthTracing
+			}
+			if postIndex > l {
+				return io.ErrUnexpectedEOF
+			}
+			m.TraceID = append(m.TraceID[:0], dAtA[iNdEx:postIndex]...)
+			if m.TraceID == nil {
+				m.TraceID = []byte{}
+			}
+			iNdEx = postIndex
+		case 2:
+			if wireType != 2 {
+				return fmt.Errorf("proto: wrong wireType = %d for field SpanID", wireType)
+			}
+			var byteLen int
+			for shift := uint(0); ; shift += 7 {
+				if shift >= 64 {
+					return ErrIntOverflowTracing
+				}
+				if iNdEx >= l {
+					return io.ErrUnexpectedEOF
+				}
+				b := dAtA[iNdEx]
+				iNdEx++
+				byteLen |= int(b&0x7F) << shift
+				if b < 0x80 {
+					break
+				}
+			}
+			if byteLen < 0 {
+				return ErrInvalidLengthTracing
+			}
+			postIndex := iNdEx + byteLen
+			if postIndex < 0 {
+				return ErrInvalidLengthTracing
+			}
+			if postIndex > l {
+				return io.ErrUnexpectedEOF
+			}
+			m.SpanID = append(m.SpanID[:0], dAtA[iNdEx:postIndex]...)
+			if m.SpanID == nil {
+				m.SpanID = []byte{}
+			}
+			iNdEx = postIndex
+		default:
+			iNdEx = preIndex
+			skippy, err := skipTracing(dAtA[iNdEx:])
+			if err != nil {
+				return err
+			}
+			if (skippy < 0) || (iNdEx+skippy) < 0 {
+				return ErrInvalidLengthTracing
+			}
+			if (iNdEx + skippy) > l {
+				return io.ErrUnexpectedEOF
+			}
+			iNdEx += skippy
+		}
+	}
+
+	if iNdEx > l {
+		return io.ErrUnexpectedEOF
+	}
+	return nil
+}
+func skipTracing(dAtA []byte) (n int, err error) {
+	l := len(dAtA)
+	iNdEx := 0
+	depth := 0
+	for iNdEx < l {
+		var wire uint64
+		for shift := uint(0); ; shift += 7 {
+			if shift >= 64 {
+				return 0, ErrIntOverflowTracing
+			}
+			if iNdEx >= l {
+				return 0, io.ErrUnexpectedEOF
+			}
+			b := dAtA[iNdEx]
+			iNdEx++
+			wire |= (uint64(b) & 0x7F) << shift
+			if b < 0x80 {
+				break
+			}
+		}
+		wireType := int(wire & 0x7)
+		switch wireType {
+		case 0:
+			for shift := uint(0); ; shift += 7 {
+				if shift >= 64 {
+					return 0, ErrIntOverflowTracing
+				}
+				if iNdEx >= l {
+					return 0, io.ErrUnexpectedEOF
+				}
+				iNdEx++
+				if dAtA[iNdEx-1] < 0x80 {
+					break
+				}
+			}
+		case 1:
+			iNdEx += 8
+		case 2:
+			var length int
+			for shift := uint(0); ; shift += 7 {
+				if shift >= 64 {
+					return 0, ErrIntOverflowTracing
+				}
+				if iNdEx >= l {
+					return 0, io.ErrUnexpectedEOF
+				}
+				b := dAtA[iNdEx]
+				iNdEx++
+				length |= (int(b) & 0x7F) << shift
+				if b < 0x80 {
+					break
+				}
+			}
+			if length < 0 {
+				return 0, ErrInvalidLengthTracing
+			}
+			iNdEx += length
+		case 3:
+			depth++
+		case 4:
+			if depth == 0 {
+				return 0, ErrUnexpectedEndOfGroupTracing
+			}
+			depth--
+		case 5:
+			iNdEx += 4
+		default:
+			return 0, fmt.Errorf("proto: illegal wireType %d", wireType)
+		}
+		if iNdEx < 0 {
+			return 0, ErrInvalidLengthTracing
+		}
+		if depth == 0 {
+			return iNdEx, nil
+		}
+	}
+	return 0, io.ErrUnexpectedEOF
+}
+
+var (
+	ErrInvalidLengthTracing        = fmt.Errorf("proto: negative length found during unmarshaling")
+	ErrIntOverflowTracing          = fmt.Errorf("proto: integer overflow")
+	ErrUnexpectedEndOfGroupTracing = fmt.Errorf("proto: unexpected end of group")
+)
+
diff --git a/pkg/util/tracing/tracingpb/tracing.proto b/pkg/util/tracing/tracingpb/tracing.proto
new file mode 100644
index 0000000..455fd44
--- /dev/null
+++ b/pkg/util/tracing/tracingpb/tracing.proto
@@ -0,0 +1,42 @@
+// Copyright 2021 The Cockroach Authors.
+//
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
+
+syntax = "proto3";
+package cockroach.util.tracing.tracingpb;
+option go_package = "github.com/cockroachdb/cockroach/pkg/util/tracing/tracingpb";
+
+import "gogoproto/gogo.proto";
+
+
+enum RecordingMode {
+  OFF = 0;
+  VERBOSE = 1;
+  STRUCTURED = 2;
+}
+
+// TraceInfo represents the tracing context of an operation. It is the proto
+// representation of tracing.SpanMeta. TraceInfos are passed around in RPC
+// payloads so that the server can create spans that are linked to the remote
+// parent.
+message TraceInfo {
+  uint64 trace_id = 1 [(gogoproto.nullable) = false, (gogoproto.customname) = "TraceID", (gogoproto.customtype) = "TraceID"];
+  // ID of the parent span.
+  uint64 parent_span_id = 2 [(gogoproto.nullable) = false, (gogoproto.customname) = "ParentSpanID", (gogoproto.customtype) = "SpanID"];
+
+  // The type of recording, if any, that the parent span is doing. See
+  // tracing.RecordingType.
+  RecordingMode recording_mode = 3;
+
+  // OtelInfo contains the OpenTelemetry tracing context, if any.
+  message OtelInfo {
+    // trace_id will have exactly 16 bytes.
+    bytes trace_id = 1 [(gogoproto.customname) = "TraceID"];
+    // span_id will have exactly 8 bytes.
+    bytes span_id = 2 [(gogoproto.customname) = "SpanID"];
+  }
+
+  OtelInfo otel = 4;
+}
+
diff --git a/pkg/util/tracing/utils.go b/pkg/util/tracing/utils.go
new file mode 100644
index 0000000..0672800
--- /dev/null
+++ b/pkg/util/tracing/utils.go
@@ -0,0 +1,58 @@
+// Copyright 2021 The Cockroach Authors.
+//
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
+
+package tracing
+
+import (
+	"github.com/cockroachdb/cockroachdb-parser/pkg/util/tracing/tracingpb"
+	"github.com/cockroachdb/redact"
+	"github.com/gogo/protobuf/jsonpb"
+)
+
+// TraceToJSON returns the string representation of the trace in JSON format.
+//
+// TraceToJSON assumes that the first span in the recording contains all the
+// other spans.
+func TraceToJSON(trace tracingpb.Recording) (string, error) {
+	root := normalizeSpan(trace[0], trace)
+	marshaller := jsonpb.Marshaler{
+		Indent: "\t",
+	}
+	str, err := marshaller.MarshalToString(&root)
+	if err != nil {
+		return "", err
+	}
+	return str, nil
+}
+
+func normalizeSpan(s tracingpb.RecordedSpan, trace tracingpb.Recording) tracingpb.NormalizedSpan {
+	var n tracingpb.NormalizedSpan
+	n.Operation = s.Operation
+	n.StartTime = s.StartTime
+	n.Duration = s.Duration
+	n.TagGroups = s.TagGroups
+	n.Logs = s.Logs
+	n.StructuredRecords = s.StructuredRecords
+	n.ChildrenMetadata = s.ChildrenMetadata
+
+	for _, ss := range trace {
+		if ss.ParentSpanID != s.SpanID {
+			continue
+		}
+		n.Children = append(n.Children, normalizeSpan(ss, trace))
+	}
+	return n
+}
+
+// RedactAndTruncateError redacts the error and truncates the string
+// representation of the error to a fixed length.
+func RedactAndTruncateError(err error) string {
+	maxErrLength := 250
+	redactedErr := string(redact.Sprintf("%v", err))
+	if len(redactedErr) < maxErrLength {
+		maxErrLength = len(redactedErr)
+	}
+	return redactedErr[:maxErrLength]
+}
diff --git a/pkg/util/treeprinter/tree_printer.go b/pkg/util/treeprinter/tree_printer.go
index c2218fa..0e44889 100644
--- a/pkg/util/treeprinter/tree_printer.go
+++ b/pkg/util/treeprinter/tree_printer.go
@@ -1,12 +1,7 @@
 // Copyright 2017 The Cockroach Authors.
 //
-// Use of this software is governed by the Business Source License
-// included in the file licenses/BSL.txt.
-//
-// As of the Change Date specified in that file, in accordance with
-// the Business Source License, use of this software will be governed
-// by the Apache License, Version 2.0, included in the file
-// licenses/APL.txt.
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
 
 package treeprinter
 
diff --git a/pkg/util/tsearch/config.go b/pkg/util/tsearch/config.go
index d9b1875..235ee1d 100644
--- a/pkg/util/tsearch/config.go
+++ b/pkg/util/tsearch/config.go
@@ -1,12 +1,7 @@
 // Copyright 2022 The Cockroach Authors.
 //
-// Use of this software is governed by the Business Source License
-// included in the file licenses/BSL.txt.
-//
-// As of the Change Date specified in that file, in accordance with
-// the Business Source License, use of this software will be governed
-// by the Apache License, Version 2.0, included in the file
-// licenses/APL.txt.
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
 
 package tsearch
 
diff --git a/pkg/util/tsearch/encoding.go b/pkg/util/tsearch/encoding.go
index b18a7a1..781222b 100644
--- a/pkg/util/tsearch/encoding.go
+++ b/pkg/util/tsearch/encoding.go
@@ -1,12 +1,7 @@
 // Copyright 2022 The Cockroach Authors.
 //
-// Use of this software is governed by the Business Source License
-// included in the file licenses/BSL.txt.
-//
-// As of the Change Date specified in that file, in accordance with
-// the Business Source License, use of this software will be governed
-// by the Apache License, Version 2.0, included in the file
-// licenses/APL.txt.
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
 
 package tsearch
 
diff --git a/pkg/util/tsearch/eval.go b/pkg/util/tsearch/eval.go
index cf65a8c..8bb236b 100644
--- a/pkg/util/tsearch/eval.go
+++ b/pkg/util/tsearch/eval.go
@@ -1,12 +1,7 @@
 // Copyright 2022 The Cockroach Authors.
 //
-// Use of this software is governed by the Business Source License
-// included in the file licenses/BSL.txt.
-//
-// As of the Change Date specified in that file, in accordance with
-// the Business Source License, use of this software will be governed
-// by the Apache License, Version 2.0, included in the file
-// licenses/APL.txt.
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
 
 package tsearch
 
@@ -173,9 +168,9 @@ func (e *tsEvaluator) evalFollowedBy(
 		if lExhausted && rExhausted {
 			break
 		}
-		var lPos, rPos int
+		var lPos, rPos int64
 		if !lExhausted {
-			lPos = int(lPositions.positions[lIdx].position) + lOffset
+			lPos = int64(lPositions.positions[lIdx].position) + int64(lOffset)
 		} else {
 			// Quit unless we're outputting all of the RHS, which we will if we have
 			// a negative match on the LHS.
@@ -185,7 +180,7 @@ func (e *tsEvaluator) evalFollowedBy(
 			lPos = math.MaxInt64
 		}
 		if !rExhausted {
-			rPos = int(rPositions.positions[rIdx].position) + rOffset
+			rPos = int64(rPositions.positions[rIdx].position) + int64(rOffset)
 		} else {
 			// Quit unless we're outputting all of the LHS, which we will if we have
 			// a negative match on the RHS.
diff --git a/pkg/util/tsearch/lex.go b/pkg/util/tsearch/lex.go
index c2759e1..cbabdfe 100644
--- a/pkg/util/tsearch/lex.go
+++ b/pkg/util/tsearch/lex.go
@@ -1,12 +1,7 @@
 // Copyright 2022 The Cockroach Authors.
 //
-// Use of this software is governed by the Business Source License
-// included in the file licenses/BSL.txt.
-//
-// As of the Change Date specified in that file, in accordance with
-// the Business Source License, use of this software will be governed
-// by the Apache License, Version 2.0, included in the file
-// licenses/APL.txt.
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
 
 package tsearch
 
diff --git a/pkg/util/tsearch/random.go b/pkg/util/tsearch/random.go
index 9fc8124..8cd849c 100644
--- a/pkg/util/tsearch/random.go
+++ b/pkg/util/tsearch/random.go
@@ -1,12 +1,7 @@
 // Copyright 2022 The Cockroach Authors.
 //
-// Use of this software is governed by the Business Source License
-// included in the file licenses/BSL.txt.
-//
-// As of the Change Date specified in that file, in accordance with
-// the Business Source License, use of this software will be governed
-// by the Apache License, Version 2.0, included in the file
-// licenses/APL.txt.
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
 
 package tsearch
 
diff --git a/pkg/util/tsearch/rank.go b/pkg/util/tsearch/rank.go
index 757f736..242501e 100644
--- a/pkg/util/tsearch/rank.go
+++ b/pkg/util/tsearch/rank.go
@@ -1,12 +1,7 @@
 // Copyright 2023 The Cockroach Authors.
 //
-// Use of this software is governed by the Business Source License
-// included in the file licenses/BSL.txt.
-//
-// As of the Change Date specified in that file, in accordance with
-// the Business Source License, use of this software will be governed
-// by the Apache License, Version 2.0, included in the file
-// licenses/APL.txt.
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
 
 package tsearch
 
diff --git a/pkg/util/tsearch/snowball.go b/pkg/util/tsearch/snowball.go
index ca33884..11f2992 100644
--- a/pkg/util/tsearch/snowball.go
+++ b/pkg/util/tsearch/snowball.go
@@ -1,12 +1,7 @@
 // Copyright 2022 The Cockroach Authors.
 //
-// Use of this software is governed by the Business Source License
-// included in the file licenses/BSL.txt.
-//
-// As of the Change Date specified in that file, in accordance with
-// the Business Source License, use of this software will be governed
-// by the Apache License, Version 2.0, included in the file
-// licenses/APL.txt.
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
 
 package tsearch
 
diff --git a/pkg/util/tsearch/stopwords.go b/pkg/util/tsearch/stopwords.go
index f481f19..88b9852 100644
--- a/pkg/util/tsearch/stopwords.go
+++ b/pkg/util/tsearch/stopwords.go
@@ -1,12 +1,7 @@
 // Copyright 2022 The Cockroach Authors.
 //
-// Use of this software is governed by the Business Source License
-// included in the file licenses/BSL.txt.
-//
-// As of the Change Date specified in that file, in accordance with
-// the Business Source License, use of this software will be governed
-// by the Apache License, Version 2.0, included in the file
-// licenses/APL.txt.
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
 
 package tsearch
 
diff --git a/pkg/util/tsearch/tsquery.go b/pkg/util/tsearch/tsquery.go
index a2fca59..e86fdb3 100644
--- a/pkg/util/tsearch/tsquery.go
+++ b/pkg/util/tsearch/tsquery.go
@@ -1,12 +1,7 @@
 // Copyright 2022 The Cockroach Authors.
 //
-// Use of this software is governed by the Business Source License
-// included in the file licenses/BSL.txt.
-//
-// As of the Change Date specified in that file, in accordance with
-// the Business Source License, use of this software will be governed
-// by the Apache License, Version 2.0, included in the file
-// licenses/APL.txt.
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
 
 package tsearch
 
diff --git a/pkg/util/tsearch/tsvector.go b/pkg/util/tsearch/tsvector.go
index e5b598f..787f29e 100644
--- a/pkg/util/tsearch/tsvector.go
+++ b/pkg/util/tsearch/tsvector.go
@@ -1,12 +1,7 @@
 // Copyright 2022 The Cockroach Authors.
 //
-// Use of this software is governed by the Business Source License
-// included in the file licenses/BSL.txt.
-//
-// As of the Change Date specified in that file, in accordance with
-// the Business Source License, use of this software will be governed
-// by the Apache License, Version 2.0, included in the file
-// licenses/APL.txt.
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
 
 package tsearch
 
diff --git a/pkg/util/uint128/uint128.go b/pkg/util/uint128/uint128.go
index 86fff00..3cde26e 100644
--- a/pkg/util/uint128/uint128.go
+++ b/pkg/util/uint128/uint128.go
@@ -1,12 +1,7 @@
 // Copyright 2017 The Cockroach Authors.
 //
-// Use of this software is governed by the Business Source License
-// included in the file licenses/BSL.txt.
-//
-// As of the Change Date specified in that file, in accordance with
-// the Business Source License, use of this software will be governed
-// by the Apache License, Version 2.0, included in the file
-// licenses/APL.txt.
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
 
 package uint128
 
diff --git a/pkg/util/unresolved_addr.go b/pkg/util/unresolved_addr.go
index 07ec5ce..268067c 100644
--- a/pkg/util/unresolved_addr.go
+++ b/pkg/util/unresolved_addr.go
@@ -1,12 +1,7 @@
 // Copyright 2015 The Cockroach Authors.
 //
-// Use of this software is governed by the Business Source License
-// included in the file licenses/BSL.txt.
-//
-// As of the Change Date specified in that file, in accordance with
-// the Business Source License, use of this software will be governed
-// by the Apache License, Version 2.0, included in the file
-// licenses/APL.txt.
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
 
 package util
 
diff --git a/pkg/util/unresolved_addr.pb.go b/pkg/util/unresolved_addr.pb.go
index 6f29f58..2d0ca9b 100644
--- a/pkg/util/unresolved_addr.pb.go
+++ b/pkg/util/unresolved_addr.pb.go
@@ -166,7 +166,7 @@ func (m *UnresolvedAddr) Size() (n int) {
 }
 
 func sovUnresolvedAddr(x uint64) (n int) {
-	return (math_bits.Len64(x|1) + 6) / 7
+	return int((uint32(math_bits.Len64(x|1)+6) * 37) >> 8)
 }
 func sozUnresolvedAddr(x uint64) (n int) {
 	return sovUnresolvedAddr(uint64((x << 1) ^ uint64((int64(x) >> 63))))
diff --git a/pkg/util/unresolved_addr.proto b/pkg/util/unresolved_addr.proto
index 059dd76..28c0013 100644
--- a/pkg/util/unresolved_addr.proto
+++ b/pkg/util/unresolved_addr.proto
@@ -1,12 +1,7 @@
 // Copyright 2015 The Cockroach Authors.
 //
-// Use of this software is governed by the Business Source License
-// included in the file licenses/BSL.txt.
-//
-// As of the Change Date specified in that file, in accordance with
-// the Business Source License, use of this software will be governed
-// by the Apache License, Version 2.0, included in the file
-// licenses/APL.txt.
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
 
 syntax = "proto2";
 package cockroach.util;
diff --git a/pkg/util/uuid/codec.go b/pkg/util/uuid/codec.go
index 2aeae27..ce7d392 100644
--- a/pkg/util/uuid/codec.go
+++ b/pkg/util/uuid/codec.go
@@ -1,12 +1,7 @@
 // Copyright 2019 The Cockroach Authors.
 //
-// Use of this software is governed by the Business Source License
-// included in the file licenses/BSL.txt.
-//
-// As of the Change Date specified in that file, in accordance with
-// the Business Source License, use of this software will be governed
-// by the Apache License, Version 2.0, included in the file
-// licenses/APL.txt.
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
 
 // Copyright (C) 2013-2018 by Maxim Bublis <b@codemonkey.ru>
 // Use of this source code is governed by a MIT-style
diff --git a/pkg/util/uuid/fuzz.go b/pkg/util/uuid/fuzz.go
index 5777372..6677b57 100644
--- a/pkg/util/uuid/fuzz.go
+++ b/pkg/util/uuid/fuzz.go
@@ -1,12 +1,7 @@
 // Copyright 2019 The Cockroach Authors.
 //
-// Use of this software is governed by the Business Source License
-// included in the file licenses/BSL.txt.
-//
-// As of the Change Date specified in that file, in accordance with
-// the Business Source License, use of this software will be governed
-// by the Apache License, Version 2.0, included in the file
-// licenses/APL.txt.
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
 
 // Copyright (c) 2018 Andrei Tudor Călin <mail@acln.ro>
 // Use of this source code is governed by a MIT-style
@@ -15,7 +10,6 @@
 // This code originated in github.com/gofrs/uuid.
 
 //go:build gofuzz
-// +build gofuzz
 
 package uuid
 
diff --git a/pkg/util/uuid/generator.go b/pkg/util/uuid/generator.go
index 11bb2ca..5efb356 100644
--- a/pkg/util/uuid/generator.go
+++ b/pkg/util/uuid/generator.go
@@ -1,12 +1,7 @@
 // Copyright 2019 The Cockroach Authors.
 //
-// Use of this software is governed by the Business Source License
-// included in the file licenses/BSL.txt.
-//
-// As of the Change Date specified in that file, in accordance with
-// the Business Source License, use of this software will be governed
-// by the Apache License, Version 2.0, included in the file
-// licenses/APL.txt.
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
 
 // Copyright (C) 2013-2018 by Maxim Bublis <b@codemonkey.ru>
 // Use of this source code is governed by a MIT-style
@@ -18,12 +13,11 @@ package uuid
 
 import (
 	"crypto/md5"
-	crypto_rand "crypto/rand"
 	"crypto/sha1"
 	"encoding/binary"
 	"fmt"
 	"hash"
-	"io"
+	math_rand "math/rand/v2"
 	"net"
 	"sync"
 	"time"
@@ -42,7 +36,9 @@ type epochFunc func() time.Time
 type HWAddrFunc func() (net.HardwareAddr, error)
 
 // DefaultGenerator is the default UUID Generator used by this package.
-// It uses crypto/rand as the source of entropy.
+// It uses math/rand as the source of entropy, which is backed by the
+// cryptographically random ChaCha8 algorithm.
+// See https://go.dev/blog/chacha8rand.
 var DefaultGenerator Generator = NewGen()
 
 // NewV1 returns a UUID based on the current timestamp and MAC address.
@@ -56,7 +52,7 @@ func NewV3(ns UUID, name string) UUID {
 }
 
 // NewV4 returns a randomly generated UUID.
-func NewV4() (UUID, error) {
+func NewV4() UUID {
 	return DefaultGenerator.NewV4()
 }
 
@@ -70,7 +66,7 @@ type Generator interface {
 	NewV1() (UUID, error)
 	// NewV2(domain byte) (UUID, error) // CRL: Removed support for V2.
 	NewV3(ns UUID, name string) UUID
-	NewV4() (UUID, error)
+	NewV4() UUID
 	NewV5(ns UUID, name string) UUID
 }
 
@@ -90,7 +86,9 @@ type Gen struct {
 	hardwareAddrOnce  sync.Once
 	storageMutex      syncutil.Mutex
 
-	rand io.Reader
+	// randUint64 is the function used to generate random uint64 values. The
+	// function is stored directly to avoid the overhead of interface dispatch.
+	randUint64 func() uint64
 
 	epochFunc     epochFunc
 	hwAddrFunc    HWAddrFunc
@@ -109,11 +107,11 @@ func NewGen() *Gen {
 	return NewGenWithHWAF(defaultHWAddrFunc)
 }
 
-// NewGenWithReader returns a new instance of gen which uses r as its source of
-// randomness.
-func NewGenWithReader(r io.Reader) *Gen {
+// NewGenWithRand returns a new instance of gen which uses randUint64 as its
+// source of randomness.
+func NewGenWithRand(randUint64 func() uint64) *Gen {
 	g := NewGen()
-	g.rand = r
+	g.randUint64 = randUint64
 	return g
 }
 
@@ -132,7 +130,10 @@ func NewGenWithHWAF(hwaf HWAddrFunc) *Gen {
 	return &Gen{
 		epochFunc:  time.Now,
 		hwAddrFunc: hwaf,
-		rand:       crypto_rand.Reader,
+		// "math/rand".Uint64 is safe for concurrent use. As of go1.22, the
+		// math/rand (and math/rand/v2) package uses a cryptographically secure RNG.
+		// See https://go.dev/blog/randv2 and https://go.dev/blog/chacha8rand.
+		randUint64: math_rand.Uint64,
 	}
 }
 
@@ -140,10 +141,7 @@ func NewGenWithHWAF(hwaf HWAddrFunc) *Gen {
 func (g *Gen) NewV1() (UUID, error) {
 	u := UUID{}
 
-	timeNow, clockSeq, err := g.getClockSequence()
-	if err != nil {
-		return Nil, err
-	}
+	timeNow, clockSeq := g.getClockSequence()
 	binary.BigEndian.PutUint32(u[0:], uint32(timeNow))
 	binary.BigEndian.PutUint16(u[4:], uint16(timeNow>>32))
 	binary.BigEndian.PutUint16(u[6:], uint16(timeNow>>48))
@@ -171,25 +169,14 @@ func (g *Gen) NewV3(ns UUID, name string) UUID {
 }
 
 // NewV4 returns a randomly generated UUID.
-func (g *Gen) NewV4() (UUID, error) {
+func (g *Gen) NewV4() UUID {
 	u := UUID{}
-	if r, ok := g.rand.(mathRandReader); ok {
-		if n, err := r.Read(u[:]); n != len(u) {
-			panic("math/rand.Read always returns len(p)")
-		} else if err != nil {
-			panic("math/rand.Read always returns a nil error")
-		}
-	} else {
-		willEscape := UUID{}
-		if _, err := io.ReadFull(g.rand, willEscape[:]); err != nil {
-			return Nil, err
-		}
-		u = willEscape
-	}
+	binary.BigEndian.PutUint64(u[:Size/2], g.randUint64())
+	binary.BigEndian.PutUint64(u[Size/2:], g.randUint64())
 	u.SetVersion(V4)
 	u.SetVariant(VariantRFC4122)
 
-	return u, nil
+	return u
 }
 
 // NewV5 returns a UUID based on SHA-1 hash of the namespace UUID and name.
@@ -202,18 +189,12 @@ func (g *Gen) NewV5(ns UUID, name string) UUID {
 }
 
 // Returns the epoch and clock sequence.
-func (g *Gen) getClockSequence() (uint64, uint16, error) {
-	var err error
+func (g *Gen) getClockSequence() (uint64, uint16) {
 	g.clockSequenceOnce.Do(func() {
-		buf := make([]byte, 2)
-		if _, err = io.ReadFull(g.rand, buf); err != nil {
-			return
-		}
+		buf := make([]byte, 8)
+		binary.BigEndian.PutUint64(buf[:], g.randUint64())
 		g.clockSequence = binary.BigEndian.Uint16(buf)
 	})
-	if err != nil {
-		return 0, 0, err
-	}
 
 	g.storageMutex.Lock()
 	defer g.storageMutex.Unlock()
@@ -226,7 +207,7 @@ func (g *Gen) getClockSequence() (uint64, uint16, error) {
 	}
 	g.lastTime = timeNow
 
-	return timeNow, g.clockSequence, nil
+	return timeNow, g.clockSequence
 }
 
 // Returns the hardware address.
@@ -239,11 +220,13 @@ func (g *Gen) getHardwareAddr() ([]byte, error) {
 			return
 		}
 
-		// Initialize hardwareAddr randomly in case
-		// of real network interfaces absence.
-		if _, err = io.ReadFull(g.rand, g.hardwareAddr[:]); err != nil {
-			return
+		// Initialize hardwareAddr randomly in case of real network interfaces
+		// absence.
+		hwAddr, err = RandomHardwareAddrFunc()
+		if err != nil {
+			panic("RandomHardwareAddrFunc does not return an error")
 		}
+		copy(g.hardwareAddr[:], hwAddr)
 		// Set multicast bit as recommended by RFC-4122
 		g.hardwareAddr[0] |= 0x01
 	})
@@ -288,14 +271,13 @@ func defaultHWAddrFunc() (net.HardwareAddr, error) {
 }
 
 // RandomHardwareAddrFunc returns a random hardware address, with the multicast
-// and local-admin bits set as per the IEEE802 spec.
+// and local-admin bits set as per the IEEE802 spec. This function never
+// returns an error, but the signature has to match the HWAddrFunc type.
 func RandomHardwareAddrFunc() (net.HardwareAddr, error) {
-	var err error
-	var hardwareAddr = make(net.HardwareAddr, 6)
-	if _, err = io.ReadFull(crypto_rand.Reader, hardwareAddr[:]); err != nil {
-		return []byte{}, err
-	}
+	var hardwareAddr = make([]byte, 8)
+	binary.BigEndian.PutUint64(hardwareAddr, math_rand.Uint64())
 	// Set multicast bit and local-admin bit to match Postgres.
 	hardwareAddr[0] |= 0x03
-	return hardwareAddr, nil
+	// Discard the last 2 bytes.
+	return hardwareAddr[:6], nil
 }
diff --git a/pkg/util/uuid/sql.go b/pkg/util/uuid/sql.go
index 1041473..3a19a63 100644
--- a/pkg/util/uuid/sql.go
+++ b/pkg/util/uuid/sql.go
@@ -1,12 +1,7 @@
 // Copyright 2019 The Cockroach Authors.
 //
-// Use of this software is governed by the Business Source License
-// included in the file licenses/BSL.txt.
-//
-// As of the Change Date specified in that file, in accordance with
-// the Business Source License, use of this software will be governed
-// by the Apache License, Version 2.0, included in the file
-// licenses/APL.txt.
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
 
 // Copyright (C) 2013-2018 by Maxim Bublis <b@codemonkey.ru>
 // Use of this source code is governed by a MIT-style
diff --git a/pkg/util/uuid/uuid.go b/pkg/util/uuid/uuid.go
index f52a2de..7dc9972 100644
--- a/pkg/util/uuid/uuid.go
+++ b/pkg/util/uuid/uuid.go
@@ -1,12 +1,7 @@
 // Copyright 2019 The Cockroach Authors.
 //
-// Use of this software is governed by the Business Source License
-// included in the file licenses/BSL.txt.
-//
-// As of the Change Date specified in that file, in accordance with
-// the Business Source License, use of this software will be governed
-// by the Apache License, Version 2.0, included in the file
-// licenses/APL.txt.
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
 
 // Copyright (C) 2013-2018 by Maxim Bublis <b@codemonkey.ru>
 // Use of this source code is governed by a MIT-style
@@ -26,6 +21,7 @@ import (
 	"github.com/cockroachdb/cockroachdb-parser/pkg/util/timeutil"
 	"github.com/cockroachdb/cockroachdb-parser/pkg/util/uint128"
 	"github.com/cockroachdb/errors"
+	"github.com/cockroachdb/redact"
 )
 
 // Size of a UUID in bytes.
@@ -38,6 +34,11 @@ const RFC4122StrSize = 36
 // encoding of a UUID.
 type Bytes []byte
 
+var _ redact.SafeValue = Bytes{}
+
+// SafeValue implements the redact.SafeValue interface.
+func (b Bytes) SafeValue() {}
+
 // GetUUID constructs a UUID from the bytes. If the data is not valid, a zero
 // value will be returned.
 func (b Bytes) GetUUID() UUID { return FromBytesOrNil(b) }
@@ -50,6 +51,11 @@ func (b Bytes) String() string {
 // UUID is an array type to represent the value of a UUID, as defined in RFC-4122.
 type UUID [Size]byte
 
+var _ redact.SafeValue = UUID{}
+
+// SafeValue implements the redact.SafeValue interface.
+func (u UUID) SafeValue() {}
+
 // UUID versions.
 const (
 	_  byte = iota
@@ -73,6 +79,11 @@ const (
 // UUIDs since they don't have an embedded timestamp.
 type Timestamp uint64
 
+var _ redact.SafeValue = Timestamp(0)
+
+// SafeValue implements the redact.SafeValue interface.
+func (t Timestamp) SafeValue() {}
+
 const _100nsPerSecond = 10000000
 
 // Time returns the UTC time.Time representation of a Timestamp
diff --git a/pkg/util/uuid/uuid_wrapper.go b/pkg/util/uuid/uuid_wrapper.go
index f6bcb33..e9f9e75 100644
--- a/pkg/util/uuid/uuid_wrapper.go
+++ b/pkg/util/uuid/uuid_wrapper.go
@@ -1,28 +1,60 @@
 // Copyright 2016 The Cockroach Authors.
 //
-// Use of this software is governed by the Business Source License
-// included in the file licenses/BSL.txt.
-//
-// As of the Change Date specified in that file, in accordance with
-// the Business Source License, use of this software will be governed
-// by the Apache License, Version 2.0, included in the file
-// licenses/APL.txt.
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
 
 package uuid
 
 import (
 	"encoding/binary"
+	"encoding/hex"
 	"encoding/json"
 	"fmt"
-	math_rand "math/rand"
 
 	"github.com/cockroachdb/cockroachdb-parser/pkg/util/uint128"
 	"github.com/cockroachdb/errors"
+	"github.com/cockroachdb/redact"
+)
+
+const (
+	shortSize    = 4
+	shortStrSize = 8
 )
 
-// Short returns the first eight characters of the output of String().
-func (u UUID) Short() string {
-	return u.String()[:8]
+// Short is an abbreviated version of a UUID containing the first four bytes.
+type Short struct {
+	b [shortSize]byte
+}
+
+var _ redact.SafeValue = Short{}
+
+// SafeValue implements the redact.SafeValue interface.
+func (s Short) SafeValue() {}
+
+// String returns the 8-character hexidecimal representation of the abbreviated
+// UUID.
+func (s Short) String() string {
+	var b [shortStrSize]byte
+	hex.Encode(b[:], s.b[:])
+	return string(b[:])
+}
+
+// ToInt32 returns an int32 representation of the abbreviated UUID.
+func (s Short) ToInt32() int32 {
+	return int32(binary.BigEndian.Uint32(s.b[:]))
+}
+
+// FromInt32 sets the abbreviated UUID from an int32.
+func (s *Short) FromInt32(i int32) {
+	binary.BigEndian.PutUint32(s.b[:], uint32(i))
+}
+
+// Short returns an abbreviated version of the UUID containing the first four
+// bytes.
+func (u UUID) Short() Short {
+	return Short{
+		b: [shortSize]byte(u[0:shortSize]),
+	}
 }
 
 // ShortStringer implements fmt.Stringer to output Short() on String().
@@ -30,7 +62,7 @@ type ShortStringer UUID
 
 // String is part of fmt.Stringer.
 func (s ShortStringer) String() string {
-	return UUID(s).Short()
+	return UUID(s).Short().String()
 }
 
 var _ fmt.Stringer = ShortStringer{}
@@ -94,35 +126,11 @@ func (u *UUID) UnmarshalJSON(data []byte) error {
 	return err
 }
 
-// MakeV4 calls Must(NewV4)
+// MakeV4 calls NewV4.
 func MakeV4() UUID {
-	return Must(NewV4())
+	return NewV4()
 }
 
-// FastMakeV4 generates a UUID using a fast but not cryptographically secure
-// source of randomness.
-func FastMakeV4() UUID {
-	u, err := fastGen.NewV4()
-	if err != nil {
-		panic(errors.Wrap(err, "should never happen with math/rand.Rand"))
-	}
-	return u
-}
-
-// mathRandReader is an io.Reader that calls through to "math/rand".Read
-// which is safe for concurrent use.
-type mathRandReader struct{}
-
-func (r mathRandReader) Read(p []byte) (n int, err error) {
-	// https://github.com/cockroachdb/cockroachdb-parser/issues/110597 tracks this
-	// deprecated usage.
-	//lint:ignore SA1019 deprecated
-	return math_rand.Read(p)
-}
-
-// fastGen is a non-cryptographically secure Generator.
-var fastGen = NewGenWithReader(mathRandReader{})
-
 // NewPopulatedUUID returns a populated UUID.
 func NewPopulatedUUID(r interface {
 	Uint32() uint32
diff --git a/pkg/util/vector/vector.go b/pkg/util/vector/vector.go
new file mode 100644
index 0000000..b34a2f7
--- /dev/null
+++ b/pkg/util/vector/vector.go
@@ -0,0 +1,297 @@
+// Copyright 2024 The Cockroach Authors.
+//
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
+
+package vector
+
+import (
+	"math"
+	"math/rand"
+	"slices"
+	"strconv"
+	"strings"
+
+	"github.com/cockroachdb/cockroachdb-parser/pkg/sql/pgwire/pgcode"
+	"github.com/cockroachdb/cockroachdb-parser/pkg/sql/pgwire/pgerror"
+	"github.com/cockroachdb/cockroachdb-parser/pkg/util/encoding"
+	"github.com/cockroachdb/cockroachdb-parser/pkg/util/num32"
+)
+
+// MaxDim is the maximum number of dimensions a vector can have.
+const MaxDim = 16000
+
+// T is the type of a PGVector-like vector.
+type T []float32
+
+// ParseVector parses the Postgres string representation of a vector.
+func ParseVector(input string) (T, error) {
+	input = strings.TrimSpace(input)
+	if !strings.HasPrefix(input, "[") || !strings.HasSuffix(input, "]") {
+		return T{}, pgerror.Newf(pgcode.InvalidTextRepresentation,
+			"malformed vector literal: Vector contents must start with \"[\" and"+
+				" end with \"]\"")
+	}
+
+	input = strings.TrimPrefix(input, "[")
+	input = strings.TrimSuffix(input, "]")
+	parts := strings.Split(input, ",")
+
+	if len(parts) > MaxDim {
+		return T{}, pgerror.Newf(pgcode.ProgramLimitExceeded, "vector cannot have more than %d dimensions", MaxDim)
+	}
+
+	vector := make([]float32, len(parts))
+	for i, part := range parts {
+		part = strings.TrimSpace(part)
+		if part == "" {
+			return T{}, pgerror.New(pgcode.InvalidTextRepresentation, "invalid input syntax for type vector: empty string")
+		}
+
+		val, err := strconv.ParseFloat(part, 32)
+		if err != nil {
+			return T{}, pgerror.Newf(pgcode.InvalidTextRepresentation, "invalid input syntax for type vector: %s", part)
+		}
+
+		if math.IsInf(val, 0) {
+			return T{}, pgerror.New(pgcode.DataException, "infinite value not allowed in vector")
+		}
+		if math.IsNaN(val) {
+			return T{}, pgerror.New(pgcode.DataException, "NaN not allowed in vector")
+		}
+		vector[i] = float32(val)
+	}
+
+	return vector, nil
+}
+
+// AsSet returns this vector a set of one vector.
+func (v T) AsSet() Set {
+	return Set{
+		Dims:  len(v),
+		Count: 1,
+		Data:  slices.Clip(v),
+	}
+}
+
+// String implements the fmt.Stringer interface.
+func (v T) String() string {
+	var sb strings.Builder
+	// Pre-grow by a reasonable amount to avoid multiple allocations.
+	sb.Grow(len(v)*8 + 2)
+	sb.WriteString("[")
+	for i, v := range v {
+		if i > 0 {
+			sb.WriteString(",")
+		}
+		sb.WriteString(strconv.FormatFloat(float64(v), 'g', -1, 32))
+	}
+	sb.WriteString("]")
+	return sb.String()
+}
+
+// Size returns the size of the vector in bytes.
+func (v T) Size() uintptr {
+	return 24 + uintptr(cap(v))*4
+}
+
+// Compare returns -1 if v < v2, 1 if v > v2, and 0 if v == v2.
+func (v T) Compare(v2 T) (int, error) {
+	n := min(len(v), len(v2))
+	for i := 0; i < n; i++ {
+		if v[i] < v2[i] {
+			return -1, nil
+		} else if v[i] > v2[i] {
+			return 1, nil
+		}
+	}
+	if len(v) < len(v2) {
+		return -1, nil
+	} else if len(v) > len(v2) {
+		return 1, nil
+	}
+	return 0, nil
+}
+
+// Encode encodes the vector as a byte array suitable for storing in KV.
+func Encode(appendTo []byte, t T) ([]byte, error) {
+	appendTo = encoding.EncodeUint32Ascending(appendTo, uint32(len(t)))
+	for i := range t {
+		appendTo = encoding.EncodeUntaggedFloat32Value(appendTo, t[i])
+	}
+	return appendTo, nil
+}
+
+// Decode decodes the byte array into a vector and returns any remaining bytes.
+func Decode(b []byte) (remaining []byte, ret T, err error) {
+	var n uint32
+	b, n, err = encoding.DecodeUint32Ascending(b)
+	if err != nil {
+		return nil, nil, err
+	}
+	ret = make(T, n)
+	for i := range ret {
+		b, ret[i], err = encoding.DecodeUntaggedFloat32Value(b)
+		if err != nil {
+			return nil, nil, err
+		}
+	}
+	return b, ret, nil
+}
+
+// L1Distance returns the L1 (Manhattan) distance between t and t2.
+func L1Distance(t T, t2 T) (float64, error) {
+	if err := checkDims(t, t2); err != nil {
+		return 0, err
+	}
+	return float64(num32.L1Distance(t, t2)), nil
+}
+
+// L2Distance returns the Euclidean distance between t and t2.
+func L2Distance(t T, t2 T) (float64, error) {
+	if err := checkDims(t, t2); err != nil {
+		return 0, err
+	}
+	// TODO(queries): check for overflow and validate intermediate result if needed.
+	// NOTE: This does not use the num32.L2Distance function because it needs to
+	// return a float64 value.
+	return math.Sqrt(float64(num32.L2SquaredDistance(t, t2))), nil
+}
+
+// CosDistance returns the cosine distance between t and t2. This represents the
+// similarity between the two vectors, ranging from 0 (most similar) to 2 (least
+// similar). Only the angle between the vectors matters; the norms (magnitudes)
+// are irrelevant.
+func CosDistance(t T, t2 T) (float64, error) {
+	if err := checkDims(t, t2); err != nil {
+		return 0, err
+	}
+
+	// Compute the cosine of the angle between the two vectors as their dot
+	// product divided by the product of their norms:
+	//      t·t2
+	//  -----------
+	//  ||t|| ||t2||
+	var dot, normA, normB float32
+	for i := range t {
+		dot += t[i] * t2[i]
+		normA += t[i] * t[i]
+		normB += t2[i] * t2[i]
+	}
+
+	// Use sqrt(a * b) over sqrt(a) * sqrt(b) to compute norms.
+	similarity := float64(dot) / math.Sqrt(float64(normA)*float64(normB))
+
+	// Cosine distance = 1 - cosine similarity. Ensure that similarity always
+	// stays within [-1, 1] despite any floating point arithmetic error.
+	if similarity > 1 {
+		similarity = 1
+	} else if similarity < -1 {
+		similarity = -1
+	}
+	return 1 - similarity, nil
+}
+
+// InnerProduct returns the inner product of t1 and t2.
+func InnerProduct(t T, t2 T) (float64, error) {
+	if err := checkDims(t, t2); err != nil {
+		return 0, err
+	}
+	return float64(num32.Dot(t, t2)), nil
+}
+
+// NegInnerProduct returns the negative inner product of t1 and t2.
+func NegInnerProduct(t T, t2 T) (float64, error) {
+	p, err := InnerProduct(t, t2)
+	return -p, err
+}
+
+// Norm returns the L2 norm of t.
+func Norm(t T) float64 {
+	var norm float64
+	for i := range t {
+		norm += float64(t[i]) * float64(t[i])
+	}
+	// TODO(queries): check for overflow and validate intermediate result if needed.
+	// NOTE: This does not use the num32.Norm function because it needs to return
+	// a float64 value.
+	return math.Sqrt(norm)
+}
+
+// Add returns t+t2, pointwise.
+func Add(t T, t2 T) (T, error) {
+	if err := checkDims(t, t2); err != nil {
+		return nil, err
+	}
+	ret := make(T, len(t))
+	for i := range t {
+		ret[i] = t[i] + t2[i]
+	}
+	for i := range ret {
+		if math.IsInf(float64(ret[i]), 0) {
+			return nil, pgerror.New(pgcode.NumericValueOutOfRange, "value out of range: overflow")
+		}
+	}
+	return ret, nil
+}
+
+// Minus returns t-t2, pointwise.
+func Minus(t T, t2 T) (T, error) {
+	if err := checkDims(t, t2); err != nil {
+		return nil, err
+	}
+	ret := make(T, len(t))
+	for i := range t {
+		ret[i] = t[i] - t2[i]
+	}
+	for i := range ret {
+		if math.IsInf(float64(ret[i]), 0) {
+			return nil, pgerror.New(pgcode.NumericValueOutOfRange, "value out of range: overflow")
+		}
+	}
+	return ret, nil
+}
+
+// Mult returns t*t2, pointwise.
+func Mult(t T, t2 T) (T, error) {
+	if err := checkDims(t, t2); err != nil {
+		return nil, err
+	}
+	ret := make(T, len(t))
+	for i := range t {
+		ret[i] = t[i] * t2[i]
+	}
+	for i := range ret {
+		if math.IsInf(float64(ret[i]), 0) {
+			return nil, pgerror.New(pgcode.NumericValueOutOfRange, "value out of range: overflow")
+		}
+		if ret[i] == 0 && !(t[i] == 0 || t2[i] == 0) {
+			return nil, pgerror.New(pgcode.NumericValueOutOfRange, "value out of range: underflow")
+		}
+	}
+	return ret, nil
+}
+
+// Random returns a random vector with the number of dimensions in [1, maxDim]
+// range.
+func Random(rng *rand.Rand, maxDim int) T {
+	n := 1 + rng.Intn(maxDim)
+	v := make(T, n)
+	for i := range v {
+		for {
+			v[i] = math.Float32frombits(rng.Uint32())
+			if math.IsNaN(float64(v[i])) || math.IsInf(float64(v[i]), 0) {
+				continue
+			}
+			break
+		}
+	}
+	return v
+}
+
+func checkDims(t T, t2 T) error {
+	if len(t) != len(t2) {
+		return pgerror.Newf(pgcode.DataException, "different vector dimensions %d and %d", len(t), len(t2))
+	}
+	return nil
+}
diff --git a/pkg/util/vector/vector.pb.go b/pkg/util/vector/vector.pb.go
new file mode 100644
index 0000000..b27495c
--- /dev/null
+++ b/pkg/util/vector/vector.pb.go
@@ -0,0 +1,403 @@
+// Code generated by protoc-gen-gogo. DO NOT EDIT.
+// source: util/vector/vector.proto
+
+package vector
+
+import (
+	encoding_binary "encoding/binary"
+	fmt "fmt"
+	_ "github.com/gogo/protobuf/gogoproto"
+	proto "github.com/gogo/protobuf/proto"
+	io "io"
+	math "math"
+	math_bits "math/bits"
+	slices "slices"
+)
+
+// Reference imports to suppress errors if they are not otherwise used.
+var _ = proto.Marshal
+var _ = fmt.Errorf
+var _ = math.Inf
+
+// This is a compile-time assertion to ensure that this generated file
+// is compatible with the proto package it is being compiled against.
+// A compilation error at this line likely means your copy of the
+// proto package needs to be updated.
+const _ = proto.GoGoProtoPackageIsVersion3 // please upgrade the proto package
+
+// Set is a set of float32 vectors of equal dimension. Vectors in the set are
+// stored contiguously in a slice, in row-wise order. They are assumed to be
+// unordered; some methods do not preserve ordering.
+type Set struct {
+	// Dims is the number of dimensions of each vector in the set.
+	Dims int `protobuf:"varint,1,opt,name=dims,proto3,casttype=int" json:"dims,omitempty"`
+	// Count is the number of vectors in the set.
+	Count int `protobuf:"varint,2,opt,name=count,proto3,casttype=int" json:"count,omitempty"`
+	// Data is a float32 slice that contains all vectors, laid out contiguously in
+	// row-wise order in memory.
+	// NB: Avoid using this field directly, instead preferring to use the At
+	// function to access individual vectors.
+	Data []float32 `protobuf:"fixed32,3,rep,packed,name=data,proto3" json:"data,omitempty"`
+}
+
+func (m *Set) Reset()         { *m = Set{} }
+func (m *Set) String() string { return proto.CompactTextString(m) }
+func (*Set) ProtoMessage()    {}
+func (*Set) Descriptor() ([]byte, []int) {
+	return fileDescriptor_c8d9d2e19ddd5019, []int{0}
+}
+func (m *Set) XXX_Unmarshal(b []byte) error {
+	return m.Unmarshal(b)
+}
+func (m *Set) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+	b = b[:cap(b)]
+	n, err := m.MarshalToSizedBuffer(b)
+	if err != nil {
+		return nil, err
+	}
+	return b[:n], nil
+}
+func (m *Set) XXX_Merge(src proto.Message) {
+	xxx_messageInfo_Set.Merge(m, src)
+}
+func (m *Set) XXX_Size() int {
+	return m.Size()
+}
+func (m *Set) XXX_DiscardUnknown() {
+	xxx_messageInfo_Set.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_Set proto.InternalMessageInfo
+
+func init() {
+	proto.RegisterType((*Set)(nil), "cockroach.parser.util.vector.Set")
+}
+
+func init() { proto.RegisterFile("util/vector/vector.proto", fileDescriptor_c8d9d2e19ddd5019) }
+
+var fileDescriptor_c8d9d2e19ddd5019 = []byte{
+	// 207 bytes of a gzipped FileDescriptorProto
+	0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0x92, 0x28, 0x2d, 0xc9, 0xcc,
+	0xd1, 0x2f, 0x4b, 0x4d, 0x2e, 0xc9, 0x2f, 0x82, 0x52, 0x7a, 0x05, 0x45, 0xf9, 0x25, 0xf9, 0x42,
+	0xa2, 0xc9, 0xf9, 0xc9, 0xd9, 0x45, 0xf9, 0x89, 0xc9, 0x19, 0x7a, 0x20, 0x35, 0x7a, 0x10, 0x49,
+	0x29, 0x91, 0xf4, 0xfc, 0xf4, 0x7c, 0xb0, 0x0a, 0x7d, 0x10, 0x0b, 0xa2, 0x58, 0x29, 0x94, 0x8b,
+	0x39, 0x38, 0xb5, 0x44, 0x48, 0x9a, 0x8b, 0x25, 0x25, 0x33, 0xb7, 0x58, 0x82, 0x51, 0x81, 0x51,
+	0x83, 0xd9, 0x89, 0xfd, 0xd7, 0x3d, 0x79, 0xe6, 0xcc, 0xbc, 0x92, 0x20, 0xb0, 0xa0, 0x90, 0x2c,
+	0x17, 0x6b, 0x72, 0x7e, 0x69, 0x5e, 0x89, 0x04, 0x13, 0xaa, 0x2c, 0x44, 0x54, 0x48, 0x88, 0x8b,
+	0x25, 0x25, 0xb1, 0x24, 0x51, 0x82, 0x59, 0x81, 0x59, 0x83, 0x29, 0x08, 0xcc, 0x76, 0x0a, 0x3a,
+	0xf1, 0x50, 0x8e, 0xe1, 0xc4, 0x23, 0x39, 0xc6, 0x0b, 0x8f, 0xe4, 0x18, 0x6f, 0x3c, 0x92, 0x63,
+	0x7c, 0xf0, 0x48, 0x8e, 0x71, 0xc2, 0x63, 0x39, 0x86, 0x0b, 0x8f, 0xe5, 0x18, 0x6e, 0x3c, 0x96,
+	0x63, 0x88, 0x32, 0x48, 0xcf, 0x2c, 0xc9, 0x28, 0x4d, 0xd2, 0x4b, 0xce, 0xcf, 0xd5, 0x87, 0x3b,
+	0x38, 0x25, 0x09, 0xc1, 0xd6, 0x2f, 0xc8, 0x4e, 0xd7, 0x47, 0xf2, 0x64, 0x12, 0x1b, 0xd8, 0xc5,
+	0xc6, 0x80, 0x00, 0x00, 0x00, 0xff, 0xff, 0x59, 0x42, 0xc9, 0xfe, 0xfa, 0x00, 0x00, 0x00,
+}
+
+func (m *Set) Marshal() (dAtA []byte, err error) {
+	size := m.Size()
+	dAtA = make([]byte, size)
+	n, err := m.MarshalToSizedBuffer(dAtA[:size])
+	if err != nil {
+		return nil, err
+	}
+	return dAtA[:n], nil
+}
+
+func (m *Set) MarshalTo(dAtA []byte) (int, error) {
+	size := m.Size()
+	return m.MarshalToSizedBuffer(dAtA[:size])
+}
+
+func (m *Set) MarshalToSizedBuffer(dAtA []byte) (int, error) {
+	i := len(dAtA)
+	_ = i
+	var l int
+	_ = l
+	if len(m.Data) > 0 {
+		for iNdEx := len(m.Data) - 1; iNdEx >= 0; iNdEx-- {
+			f1 := math.Float32bits(float32(m.Data[iNdEx]))
+			i -= 4
+			encoding_binary.LittleEndian.PutUint32(dAtA[i:], uint32(f1))
+		}
+		i = encodeVarintVector(dAtA, i, uint64(len(m.Data)*4))
+		i--
+		dAtA[i] = 0x1a
+	}
+	if m.Count != 0 {
+		i = encodeVarintVector(dAtA, i, uint64(m.Count))
+		i--
+		dAtA[i] = 0x10
+	}
+	if m.Dims != 0 {
+		i = encodeVarintVector(dAtA, i, uint64(m.Dims))
+		i--
+		dAtA[i] = 0x8
+	}
+	return len(dAtA) - i, nil
+}
+
+func encodeVarintVector(dAtA []byte, offset int, v uint64) int {
+	offset -= sovVector(v)
+	base := offset
+	for v >= 1<<7 {
+		dAtA[offset] = uint8(v&0x7f | 0x80)
+		v >>= 7
+		offset++
+	}
+	dAtA[offset] = uint8(v)
+	return base
+}
+func (m *Set) Size() (n int) {
+	if m == nil {
+		return 0
+	}
+	var l int
+	_ = l
+	if m.Dims != 0 {
+		n += 1 + sovVector(uint64(m.Dims))
+	}
+	if m.Count != 0 {
+		n += 1 + sovVector(uint64(m.Count))
+	}
+	if len(m.Data) > 0 {
+		n += 1 + sovVector(uint64(len(m.Data)*4)) + len(m.Data)*4
+	}
+	return n
+}
+
+func sovVector(x uint64) (n int) {
+	return int((uint32(math_bits.Len64(x|1)+6) * 37) >> 8)
+}
+func sozVector(x uint64) (n int) {
+	return sovVector(uint64((x << 1) ^ uint64((int64(x) >> 63))))
+}
+func (m *Set) Unmarshal(dAtA []byte) error {
+	l := len(dAtA)
+	iNdEx := 0
+	for iNdEx < l {
+		preIndex := iNdEx
+		var wire uint64
+		for shift := uint(0); ; shift += 7 {
+			if shift >= 64 {
+				return ErrIntOverflowVector
+			}
+			if iNdEx >= l {
+				return io.ErrUnexpectedEOF
+			}
+			b := dAtA[iNdEx]
+			iNdEx++
+			wire |= uint64(b&0x7F) << shift
+			if b < 0x80 {
+				break
+			}
+		}
+		fieldNum := int32(wire >> 3)
+		wireType := int(wire & 0x7)
+		if wireType == 4 {
+			return fmt.Errorf("proto: Set: wiretype end group for non-group")
+		}
+		if fieldNum <= 0 {
+			return fmt.Errorf("proto: Set: illegal tag %d (wire type %d)", fieldNum, wire)
+		}
+		switch fieldNum {
+		case 1:
+			if wireType != 0 {
+				return fmt.Errorf("proto: wrong wireType = %d for field Dims", wireType)
+			}
+			m.Dims = 0
+			for shift := uint(0); ; shift += 7 {
+				if shift >= 64 {
+					return ErrIntOverflowVector
+				}
+				if iNdEx >= l {
+					return io.ErrUnexpectedEOF
+				}
+				b := dAtA[iNdEx]
+				iNdEx++
+				m.Dims |= int(b&0x7F) << shift
+				if b < 0x80 {
+					break
+				}
+			}
+		case 2:
+			if wireType != 0 {
+				return fmt.Errorf("proto: wrong wireType = %d for field Count", wireType)
+			}
+			m.Count = 0
+			for shift := uint(0); ; shift += 7 {
+				if shift >= 64 {
+					return ErrIntOverflowVector
+				}
+				if iNdEx >= l {
+					return io.ErrUnexpectedEOF
+				}
+				b := dAtA[iNdEx]
+				iNdEx++
+				m.Count |= int(b&0x7F) << shift
+				if b < 0x80 {
+					break
+				}
+			}
+		case 3:
+			if wireType == 5 {
+				var v uint32
+				if (iNdEx + 4) > l {
+					return io.ErrUnexpectedEOF
+				}
+				v = uint32(encoding_binary.LittleEndian.Uint32(dAtA[iNdEx:]))
+				iNdEx += 4
+				v2 := float32(math.Float32frombits(v))
+				m.Data = append(m.Data, v2)
+			} else if wireType == 2 {
+				var packedLen int
+				for shift := uint(0); ; shift += 7 {
+					if shift >= 64 {
+						return ErrIntOverflowVector
+					}
+					if iNdEx >= l {
+						return io.ErrUnexpectedEOF
+					}
+					b := dAtA[iNdEx]
+					iNdEx++
+					packedLen |= int(b&0x7F) << shift
+					if b < 0x80 {
+						break
+					}
+				}
+				if packedLen < 0 {
+					return ErrInvalidLengthVector
+				}
+				postIndex := iNdEx + packedLen
+				if postIndex < 0 {
+					return ErrInvalidLengthVector
+				}
+				if postIndex > l {
+					return io.ErrUnexpectedEOF
+				}
+				var elementCount int
+				elementCount = packedLen / 4
+				if elementCount != 0 {
+					if m.Data == nil {
+						m.Data = make([]float32, 0, elementCount)
+					} else {
+						m.Data = slices.Grow(m.Data, elementCount)
+					}
+				}
+				for iNdEx < postIndex {
+					var v uint32
+					if (iNdEx + 4) > l {
+						return io.ErrUnexpectedEOF
+					}
+					v = uint32(encoding_binary.LittleEndian.Uint32(dAtA[iNdEx:]))
+					iNdEx += 4
+					v2 := float32(math.Float32frombits(v))
+					m.Data = append(m.Data, v2)
+				}
+			} else {
+				return fmt.Errorf("proto: wrong wireType = %d for field Data", wireType)
+			}
+		default:
+			iNdEx = preIndex
+			skippy, err := skipVector(dAtA[iNdEx:])
+			if err != nil {
+				return err
+			}
+			if (skippy < 0) || (iNdEx+skippy) < 0 {
+				return ErrInvalidLengthVector
+			}
+			if (iNdEx + skippy) > l {
+				return io.ErrUnexpectedEOF
+			}
+			iNdEx += skippy
+		}
+	}
+
+	if iNdEx > l {
+		return io.ErrUnexpectedEOF
+	}
+	return nil
+}
+func skipVector(dAtA []byte) (n int, err error) {
+	l := len(dAtA)
+	iNdEx := 0
+	depth := 0
+	for iNdEx < l {
+		var wire uint64
+		for shift := uint(0); ; shift += 7 {
+			if shift >= 64 {
+				return 0, ErrIntOverflowVector
+			}
+			if iNdEx >= l {
+				return 0, io.ErrUnexpectedEOF
+			}
+			b := dAtA[iNdEx]
+			iNdEx++
+			wire |= (uint64(b) & 0x7F) << shift
+			if b < 0x80 {
+				break
+			}
+		}
+		wireType := int(wire & 0x7)
+		switch wireType {
+		case 0:
+			for shift := uint(0); ; shift += 7 {
+				if shift >= 64 {
+					return 0, ErrIntOverflowVector
+				}
+				if iNdEx >= l {
+					return 0, io.ErrUnexpectedEOF
+				}
+				iNdEx++
+				if dAtA[iNdEx-1] < 0x80 {
+					break
+				}
+			}
+		case 1:
+			iNdEx += 8
+		case 2:
+			var length int
+			for shift := uint(0); ; shift += 7 {
+				if shift >= 64 {
+					return 0, ErrIntOverflowVector
+				}
+				if iNdEx >= l {
+					return 0, io.ErrUnexpectedEOF
+				}
+				b := dAtA[iNdEx]
+				iNdEx++
+				length |= (int(b) & 0x7F) << shift
+				if b < 0x80 {
+					break
+				}
+			}
+			if length < 0 {
+				return 0, ErrInvalidLengthVector
+			}
+			iNdEx += length
+		case 3:
+			depth++
+		case 4:
+			if depth == 0 {
+				return 0, ErrUnexpectedEndOfGroupVector
+			}
+			depth--
+		case 5:
+			iNdEx += 4
+		default:
+			return 0, fmt.Errorf("proto: illegal wireType %d", wireType)
+		}
+		if iNdEx < 0 {
+			return 0, ErrInvalidLengthVector
+		}
+		if depth == 0 {
+			return iNdEx, nil
+		}
+	}
+	return 0, io.ErrUnexpectedEOF
+}
+
+var (
+	ErrInvalidLengthVector        = fmt.Errorf("proto: negative length found during unmarshaling")
+	ErrIntOverflowVector          = fmt.Errorf("proto: integer overflow")
+	ErrUnexpectedEndOfGroupVector = fmt.Errorf("proto: unexpected end of group")
+)
+
diff --git a/pkg/util/vector/vector.proto b/pkg/util/vector/vector.proto
new file mode 100644
index 0000000..06ffdd8
--- /dev/null
+++ b/pkg/util/vector/vector.proto
@@ -0,0 +1,27 @@
+// Copyright 2024 The Cockroach Authors.
+//
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
+
+syntax = "proto3";
+package cockroach.util.vector;
+option go_package = "github.com/cockroachdb/cockroach/pkg/util/vector";
+
+import "gogoproto/gogo.proto";
+
+option (gogoproto.goproto_getters_all) = false;
+
+// Set is a set of float32 vectors of equal dimension. Vectors in the set are
+// stored contiguously in a slice, in row-wise order. They are assumed to be
+// unordered; some methods do not preserve ordering.
+message Set {
+  // Dims is the number of dimensions of each vector in the set.
+  int64 dims = 1 [(gogoproto.casttype) = "int"];
+  // Count is the number of vectors in the set.
+  int64 count = 2 [(gogoproto.casttype) = "int"];
+  // Data is a float32 slice that contains all vectors, laid out contiguously in
+  // row-wise order in memory.
+  // NB: Avoid using this field directly, instead preferring to use the At
+  // function to access individual vectors.
+  repeated float data = 3;
+}
diff --git a/pkg/util/vector/vector_set.go b/pkg/util/vector/vector_set.go
new file mode 100644
index 0000000..78d8918
--- /dev/null
+++ b/pkg/util/vector/vector_set.go
@@ -0,0 +1,228 @@
+// Copyright 2024 The Cockroach Authors.
+//
+// Use of this software is governed by the CockroachDB Software License
+// included in the /LICENSE file.
+
+package vector
+
+import (
+	"slices"
+
+	"github.com/cockroachdb/cockroachdb-parser/pkg/util/buildutil"
+	"github.com/cockroachdb/cockroachdb-parser/pkg/util/num32"
+	"github.com/cockroachdb/errors"
+)
+
+// MakeSet constructs a new empty vector set with the given number of
+// dimensions. New vectors can be added via the Add or AddSet methods.
+func MakeSet(dims int) Set {
+	return Set{Dims: dims}
+}
+
+// MakeSetFromRawData constructs a new vector set from a raw slice of vectors.
+// The vectors in the slice have the given number of dimensions and are laid out
+// contiguously in row-wise order.
+// NB: The data slice is directly used rather than copied; do not use it outside
+// the context of this vector set after this point.
+func MakeSetFromRawData(data []float32, dims int) Set {
+	if len(data)%dims != 0 {
+		panic(errors.AssertionFailedf(
+			"data length %d is not a multiple of %d dimensions", len(data), dims))
+	}
+	return Set{
+		Dims:  dims,
+		Count: len(data) / dims,
+		Data:  data,
+	}
+}
+
+// Clone performs a deep copy of the vector set. Changes to the original or
+// clone will not affect the other.
+func (vs *Set) Clone() Set {
+	return Set{
+		Dims:  vs.Dims,
+		Count: vs.Count,
+		Data:  slices.Clone(vs.Data),
+	}
+}
+
+// AsMatrix returns this set as a matrix, to be used with the num32 package.
+// NB: The underlying float32 slice is shared by the resulting matrix, so any
+// changes will affect both the vector set and matrix.
+func (vs *Set) AsMatrix() num32.Matrix {
+	return num32.Matrix{
+		Rows:   vs.Count,
+		Cols:   vs.Dims,
+		Stride: vs.Dims,
+		Data:   vs.Data,
+	}
+}
+
+// At returns the vector at the given offset in the set. The returned vector is
+// intended for transient use, since mutations to the vector set can invalidate
+// the reference.
+//
+//gcassert:inline
+func (vs *Set) At(offset int) T {
+	start := offset * vs.Dims
+	end := start + vs.Dims
+	return vs.Data[start:end:end]
+}
+
+// SplitAt divides the vector set into two subsets at the given offset. This
+// vector set is updated to contain only the vectors before the split point, and
+// the returned set contains only the vectors on or after the split point.
+func (vs *Set) SplitAt(offset int) Set {
+	if offset > vs.Count {
+		panic(errors.AssertionFailedf(
+			"split point %d cannot be greater than set size %d", offset, vs.Count))
+	}
+
+	split := offset * vs.Dims
+	other := Set{
+		Dims:  vs.Dims,
+		Count: vs.Count - offset,
+		Data:  vs.Data[split:],
+	}
+
+	// Specify capacity of the slice so that it's safe to add vectors to this
+	// set without impacting the returned set.
+	vs.Data = vs.Data[:split:split]
+	vs.Count = offset
+	return other
+}
+
+// Slice returns a vector set that contains a subset of "count" vectors,
+// starting at the given offset.
+//
+// NOTE: Slice returns a set that references the same memory as this set.
+// Modifications to one set may be visible in the other set, so callers should
+// typically ensure that both sets are immutable after calling Slice.
+func (vs *Set) Slice(offset, count int) Set {
+	if offset > vs.Count {
+		panic(errors.AssertionFailedf(
+			"slice start %d cannot be greater than set size %d", offset, vs.Count))
+	}
+	if offset+count > vs.Count {
+		panic(errors.AssertionFailedf(
+			"slice end %d cannot be greater than set size %d", offset+count, vs.Count))
+	}
+
+	start := offset * vs.Dims
+	end := (offset + count) * vs.Dims
+	return Set{
+		Dims:  vs.Dims,
+		Count: count,
+		Data:  vs.Data[start:end:end],
+	}
+}
+
+// Add appends a new vector to the set.
+func (vs *Set) Add(v T) {
+	if vs.Dims != len(v) {
+		panic(errors.AssertionFailedf(
+			"cannot add vector with %d dimensions to a set with %d dimensions", len(v), vs.Dims))
+	}
+	vs.Data = append(vs.Data, v...)
+	vs.Count++
+}
+
+// AddSet appends all vectors from the given set to this set.
+func (vs *Set) AddSet(vectors Set) {
+	if vs.Dims != vectors.Dims {
+		panic(errors.AssertionFailedf(
+			"cannot add vector set with %d dimensions to a set with %d dimensions",
+			vectors.Dims, vs.Dims))
+	}
+	vs.Data = append(vs.Data, vectors.Data...)
+	vs.Count += vectors.Count
+}
+
+// AddUndefined adds the given number of vectors to this set. The vectors should
+// be set to defined values before use.
+func (vs *Set) AddUndefined(count int) {
+	vs.Data = slices.Grow(vs.Data, count*vs.Dims)
+	vs.Count += count
+	vs.Data = vs.Data[:vs.Count*vs.Dims]
+	if buildutil.CrdbTestBuild {
+		// Write non-zero values to undefined memory.
+		for i := len(vs.Data) - count*vs.Dims; i < len(vs.Data); i++ {
+			vs.Data[i] = 0xBADF00D
+		}
+	}
+}
+
+// Clear empties the set so that it has zero vectors.
+func (vs *Set) Clear() {
+	if buildutil.CrdbTestBuild {
+		// Write non-zero values to cleared memory.
+		for i := 0; i < len(vs.Data); i++ {
+			vs.Data[i] = 0xBADF00D
+		}
+	}
+	vs.Data = vs.Data[:0]
+	vs.Count = 0
+}
+
+// ReplaceWithLast removes the vector at the given offset from the set,
+// replacing it with the last vector in the set. The modified set has one less
+// element and the last vector's position changes.
+func (vs *Set) ReplaceWithLast(offset int) {
+	targetStart := offset * vs.Dims
+	sourceEnd := len(vs.Data)
+	copy(vs.Data[targetStart:targetStart+vs.Dims], vs.Data[sourceEnd-vs.Dims:sourceEnd])
+	if buildutil.CrdbTestBuild {
+		// Write non-zero values to undefined memory.
+		for i := sourceEnd - vs.Dims; i < sourceEnd; i++ {
+			vs.Data[i] = 0xBADF00D
+		}
+	}
+	vs.Data = vs.Data[:sourceEnd-vs.Dims]
+	vs.Count--
+}
+
+// EnsureCapacity grows the underlying data slice if needed to ensure the
+// requested capacity. This is useful to prevent unnecessary resizing when it's
+// known up-front how big the vector set will need to get.
+func (vs *Set) EnsureCapacity(capacity int) {
+	if vs.Count < capacity {
+		vs.Data = slices.Grow(vs.Data, (capacity-vs.Count)*vs.Dims)
+	}
+}
+
+// Centroid calculates the mean of each dimension across all vectors in the set
+// and writes the resulting averages to the provided centroid slice. The slice
+// must be pre-allocated by the caller, with its length set to the number of
+// dimensions (Dims field) of the vectors in the set.
+func (vs *Set) Centroid(centroid T) T {
+	if len(centroid) != vs.Dims {
+		panic(errors.AssertionFailedf(
+			"centroid dims %d cannot differ from vector set dims %d", len(centroid), vs.Dims))
+	}
+
+	if vs.Count == 0 {
+		// Return vector of zeros.
+		num32.Zero(centroid)
+		return centroid
+	}
+
+	data := vs.Data
+	copy(centroid, data)
+	data = data[vs.Dims:]
+	for len(data) > 0 {
+		num32.Add(centroid, data[:vs.Dims])
+		data = data[vs.Dims:]
+	}
+	num32.Scale(1/float32(vs.Count), centroid)
+	return centroid
+}
+
+// Equal returns true if this set is equal to the other set. Two sets are equal
+// if they have the same number of dimensions, the same number of vectors, and
+// the same values in the same order.
+func (vs *Set) Equal(other *Set) bool {
+	if vs.Dims != other.Dims || vs.Count != other.Count {
+		return false
+	}
+	return slices.Equal(vs.Data, other.Data)
+}
diff --git a/pkg/util/version/version.go b/pkg/util/version/version.go
deleted file mode 100644
index f34c403..0000000
--- a/pkg/util/version/version.go
+++ /dev/null
@@ -1,237 +0,0 @@
-// Copyright 2018 The Cockroach Authors.
-//
-// Use of this software is governed by the Business Source License
-// included in the file licenses/BSL.txt.
-//
-// As of the Change Date specified in that file, in accordance with
-// the Business Source License, use of this software will be governed
-// by the Apache License, Version 2.0, included in the file
-// licenses/APL.txt.
-
-package version
-
-import (
-	"fmt"
-	"regexp"
-	"strconv"
-	"strings"
-
-	"github.com/cockroachdb/errors"
-)
-
-// Version represents a semantic version; see
-// https://semver.org/spec/v2.0.0.html.
-type Version struct {
-	major      int32
-	minor      int32
-	patch      int32
-	preRelease string
-	metadata   string
-}
-
-// Major returns the major (first) version number.
-func (v *Version) Major() int {
-	return int(v.major)
-}
-
-// Minor returns the minor (second) version number.
-func (v *Version) Minor() int {
-	return int(v.minor)
-}
-
-// Patch returns the patch (third) version number.
-func (v *Version) Patch() int {
-	return int(v.patch)
-}
-
-// PreRelease returns the pre-release version (if present).
-func (v *Version) PreRelease() string {
-	return v.preRelease
-}
-
-// Metadata returns the metadata (if present).
-func (v *Version) Metadata() string {
-	return v.metadata
-}
-
-// String returns the string representation, in the format:
-//
-//	"v1.2.3-beta+md"
-func (v Version) String() string {
-	var b strings.Builder
-	fmt.Fprintf(&b, "v%d.%d.%d", v.major, v.minor, v.patch)
-	if v.preRelease != "" {
-		fmt.Fprintf(&b, "-%s", v.preRelease)
-	}
-	if v.metadata != "" {
-		fmt.Fprintf(&b, "+%s", v.metadata)
-	}
-	return b.String()
-}
-
-// versionRE is the regexp that is used to verify that a version string is
-// of the form "vMAJOR.MINOR.PATCH[-PRERELEASE][+METADATA]". This
-// conforms to https://semver.org/spec/v2.0.0.html
-var versionRE = regexp.MustCompile(
-	`^v(0|[1-9][0-9]*)\.(0|[1-9][0-9]*)\.(0|[1-9][0-9]*)(-[0-9A-Za-z-.]+)?(\+[0-9A-Za-z-.]+|)?$`,
-	// ^major           ^minor           ^patch         ^preRelease       ^metadata
-)
-
-// numericRE is the regexp used to check if an identifier is numeric.
-var numericRE = regexp.MustCompile(`^(0|[1-9][0-9]*)$`)
-
-// Parse creates a version from a string. The string must be a valid semantic
-// version (as per https://semver.org/spec/v2.0.0.html) in the format:
-//
-//	"vMINOR.MAJOR.PATCH[-PRERELEASE][+METADATA]".
-//
-// MINOR, MAJOR, and PATCH are numeric values (without any leading 0s).
-// PRERELEASE and METADATA can contain ASCII characters and digits, hyphens and
-// dots.
-func Parse(str string) (*Version, error) {
-	if !versionRE.MatchString(str) {
-		return nil, errors.Errorf("invalid version string '%s'", str)
-	}
-
-	var v Version
-	r := strings.NewReader(str)
-	// Read the major.minor.patch part.
-	_, err := fmt.Fscanf(r, "v%d.%d.%d", &v.major, &v.minor, &v.patch)
-	if err != nil {
-		panic(fmt.Sprintf("invalid version '%s' passed the regex: %s", str, err))
-	}
-	remaining := str[len(str)-r.Len():]
-	// Read the pre-release, if present.
-	if len(remaining) > 0 && remaining[0] == '-' {
-		p := strings.IndexRune(remaining, '+')
-		if p == -1 {
-			p = len(remaining)
-		}
-		v.preRelease = remaining[1:p]
-		remaining = remaining[p:]
-	}
-	// Read the metadata, if present.
-	if len(remaining) > 0 {
-		if remaining[0] != '+' {
-			panic(fmt.Sprintf("invalid version '%s' passed the regex", str))
-		}
-		v.metadata = remaining[1:]
-	}
-	return &v, nil
-}
-
-// MustParse is like Parse but panics on any error. Recommended as an
-// initializer for global values.
-func MustParse(str string) *Version {
-	v, err := Parse(str)
-	if err != nil {
-		panic(err)
-	}
-	return v
-}
-
-func cmpVal(a, b int32) int {
-	if a > b {
-		return +1
-	}
-	if a < b {
-		return -1
-	}
-	return 0
-}
-
-// Compare returns -1, 0, or +1 indicating the relative ordering of versions.
-func (v *Version) Compare(w *Version) int {
-	if v := cmpVal(v.major, w.major); v != 0 {
-		return v
-	}
-	if v := cmpVal(v.minor, w.minor); v != 0 {
-		return v
-	}
-	if v := cmpVal(v.patch, w.patch); v != 0 {
-		return v
-	}
-	if v.preRelease != w.preRelease {
-		if v.preRelease == "" && w.preRelease != "" {
-			// 1.0.0 is greater than 1.0.0-alpha.
-			return 1
-		}
-		if v.preRelease != "" && w.preRelease == "" {
-			// 1.0.0-alpha is less than 1.0.0.
-			return -1
-		}
-
-		// Quoting from https://semver.org/spec/v2.0.0.html:
-		//   Precedence for two pre-release versions with the same major, minor, and
-		//   patch version MUST be determined by comparing each dot separated
-		//   identifier from left to right until a difference is found as follows:
-		//    (1) Identifiers consisting of only digits are compared numerically.
-		//    (2) identifiers with letters or hyphens are compared lexically in ASCII
-		//        sort order.
-		//    (3) Numeric identifiers always have lower precedence than non-numeric
-		//        identifiers.
-		//    (4) A larger set of pre-release fields has a higher precedence than a
-		//        smaller set, if all of the preceding identifiers are equal.
-		//
-		vs := strings.Split(v.preRelease, ".")
-		ws := strings.Split(w.preRelease, ".")
-		for ; len(vs) > 0 && len(ws) > 0; vs, ws = vs[1:], ws[1:] {
-			vStr, wStr := vs[0], ws[0]
-			if vStr == wStr {
-				continue
-			}
-			vNumeric := numericRE.MatchString(vStr)
-			wNumeric := numericRE.MatchString(wStr)
-			switch {
-			case vNumeric && wNumeric:
-				// Case 1.
-				vVal, err := strconv.Atoi(vStr)
-				if err != nil {
-					panic(err)
-				}
-				wVal, err := strconv.Atoi(wStr)
-				if err != nil {
-					panic(err)
-				}
-				if vVal == wVal {
-					panic("different strings yield the same numbers")
-				}
-				if vVal < wVal {
-					return -1
-				}
-				return 1
-
-			case vNumeric:
-				// Case 3.
-				return -1
-
-			case wNumeric:
-				// Case 3.
-				return 1
-
-			default:
-				// Case 2.
-				if vStr < wStr {
-					return -1
-				}
-				return 1
-			}
-		}
-
-		if len(vs) > 0 {
-			// Case 4.
-			return +1
-		}
-		if len(ws) > 0 {
-			// Case 4.
-			return -1
-		}
-	}
-
-	return 0
-}
-
-// AtLeast returns true if v >= w.
-func (v *Version) AtLeast(w *Version) bool {
-	return v.Compare(w) >= 0
-}
diff --git a/snapshot.sh b/snapshot.sh
index 0fd70ba..32c9069 100755
--- a/snapshot.sh
+++ b/snapshot.sh
@@ -10,6 +10,7 @@ COCKROACHDB_LOC=$GOPATH/src/github.com/cockroachdb/cockroach
 
 echo "Generating files in-line using dev build short"
 cd $COCKROACHDB_LOC
+./dev gen
 ./dev gen parser
 ./dev gen protobuf
 
@@ -34,8 +35,19 @@ echo "removing excess files, fixing up file paths"
 cd $LOC
 # replace compiler function to avoid conflicts.
 sed -i.bak -e 's/compilerVersion/compilerVersionParser/g' pkg/build/*.go
-# temporarily copy embedded data over
+# copy all geo subdirectories with embedded data and required functionality
 cp -R $COCKROACHDB_LOC/pkg/geo/geoprojbase/data $LOC/pkg/geo/geoprojbase/data
+cp -R $COCKROACHDB_LOC/pkg/geo/geoprojbase/embeddedproj $LOC/pkg/geo/geoprojbase/embeddedproj
+# ensure all geo subdirectories needed for geometry parsing/creation are included
+echo "Ensuring all geo dependencies are copied..."
+for geo_subdir in geodist geogen geogfn geographiclib geoindex geomfn geoproj geos geosegmentize geotest geotransform twkb; do
+  if [ -d "$COCKROACHDB_LOC/pkg/geo/$geo_subdir" ] && [ ! -d "$LOC/pkg/geo/$geo_subdir" ]; then
+    echo "Copying additional geo dependency: $geo_subdir"
+    cp -R "$COCKROACHDB_LOC/pkg/geo/$geo_subdir" "$LOC/pkg/geo/$geo_subdir"
+  fi
+done
+# copy the proj_api.h file
+cp $COCKROACHDB_LOC/c-deps/proj/src/proj_api.h $LOC/pkg/geo/geoproj/proj_api.h
 # delete gitignores
 rm pkg/sql/lexbase/.gitignore pkg/sql/parser/.gitignore
 rm pkg/sql/plpgsql/parser/.gitignore pkg/sql/plpgsql/parser/lexbase/.gitignore
@@ -63,5 +75,5 @@ done
 
 echo "Cleaning up go and testing everything works"
 go mod tidy
-echo "v0.0.0" > pkg/build/version.txt
+echo "v1.2.3" > pkg/build/version.txt
 go test .
diff --git a/version b/version
index bd9a08a..b422f81 100644
--- a/version
+++ b/version
@@ -1 +1 @@
-c0325904870a4aa399d59906b4e8eb9e58eebadd
+a119dceff4befb7135e0d0981e8c8a24a2f6c16c
