├── .gitignore ├── LICENSE ├── README.md ├── five ├── main.go ├── mnist.go ├── mnist.py ├── read.go ├── testdata ├── mat_diag.txt ├── mat_proj.txt └── mat_valid.txt └── valid.txt /.gitignore: -------------------------------------------------------------------------------- 1 | .idea 2 | MNIST_data 3 | testdata -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Apache License 2 | Version 2.0, January 2004 3 | http://www.apache.org/licenses/ 4 | 5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 6 | 7 | 1. Definitions. 8 | 9 | "License" shall mean the terms and conditions for use, reproduction, 10 | and distribution as defined by Sections 1 through 9 of this document. 11 | 12 | "Licensor" shall mean the copyright owner or entity authorized by 13 | the copyright owner that is granting the License. 14 | 15 | "Legal Entity" shall mean the union of the acting entity and all 16 | other entities that control, are controlled by, or are under common 17 | control with that entity. For the purposes of this definition, 18 | "control" means (i) the power, direct or indirect, to cause the 19 | direction or management of such entity, whether by contract or 20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 21 | outstanding shares, or (iii) beneficial ownership of such entity. 22 | 23 | "You" (or "Your") shall mean an individual or Legal Entity 24 | exercising permissions granted by this License. 25 | 26 | "Source" form shall mean the preferred form for making modifications, 27 | including but not limited to software source code, documentation 28 | source, and configuration files. 29 | 30 | "Object" form shall mean any form resulting from mechanical 31 | transformation or translation of a Source form, including but 32 | not limited to compiled object code, generated documentation, 33 | and conversions to other media types. 34 | 35 | "Work" shall mean the work of authorship, whether in Source or 36 | Object form, made available under the License, as indicated by a 37 | copyright notice that is included in or attached to the work 38 | (an example is provided in the Appendix below). 39 | 40 | "Derivative Works" shall mean any work, whether in Source or Object 41 | form, that is based on (or derived from) the Work and for which the 42 | editorial revisions, annotations, elaborations, or other modifications 43 | represent, as a whole, an original work of authorship. For the purposes 44 | of this License, Derivative Works shall not include works that remain 45 | separable from, or merely link (or bind by name) to the interfaces of, 46 | the Work and Derivative Works thereof. 47 | 48 | "Contribution" shall mean any work of authorship, including 49 | the original version of the Work and any modifications or additions 50 | to that Work or Derivative Works thereof, that is intentionally 51 | submitted to Licensor for inclusion in the Work by the copyright owner 52 | or by an individual or Legal Entity authorized to submit on behalf of 53 | the copyright owner. For the purposes of this definition, "submitted" 54 | means any form of electronic, verbal, or written communication sent 55 | to the Licensor or its representatives, including but not limited to 56 | communication on electronic mailing lists, source code control systems, 57 | and issue tracking systems that are managed by, or on behalf of, the 58 | Licensor for the purpose of discussing and improving the Work, but 59 | excluding communication that is conspicuously marked or otherwise 60 | designated in writing by the copyright owner as "Not a Contribution." 61 | 62 | "Contributor" shall mean Licensor and any individual or Legal Entity 63 | on behalf of whom a Contribution has been received by Licensor and 64 | subsequently incorporated within the Work. 65 | 66 | 2. Grant of Copyright License. Subject to the terms and conditions of 67 | this License, each Contributor hereby grants to You a perpetual, 68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 69 | copyright license to reproduce, prepare Derivative Works of, 70 | publicly display, publicly perform, sublicense, and distribute the 71 | Work and such Derivative Works in Source or Object form. 72 | 73 | 3. Grant of Patent License. Subject to the terms and conditions of 74 | this License, each Contributor hereby grants to You a perpetual, 75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 76 | (except as stated in this section) patent license to make, have made, 77 | use, offer to sell, sell, import, and otherwise transfer the Work, 78 | where such license applies only to those patent claims licensable 79 | by such Contributor that are necessarily infringed by their 80 | Contribution(s) alone or by combination of their Contribution(s) 81 | with the Work to which such Contribution(s) was submitted. If You 82 | institute patent litigation against any entity (including a 83 | cross-claim or counterclaim in a lawsuit) alleging that the Work 84 | or a Contribution incorporated within the Work constitutes direct 85 | or contributory patent infringement, then any patent licenses 86 | granted to You under this License for that Work shall terminate 87 | as of the date such litigation is filed. 88 | 89 | 4. Redistribution. You may reproduce and distribute copies of the 90 | Work or Derivative Works thereof in any medium, with or without 91 | modifications, and in Source or Object form, provided that You 92 | meet the following conditions: 93 | 94 | (a) You must give any other recipients of the Work or 95 | Derivative Works a copy of this License; and 96 | 97 | (b) You must cause any modified files to carry prominent notices 98 | stating that You changed the files; and 99 | 100 | (c) You must retain, in the Source form of any Derivative Works 101 | that You distribute, all copyright, patent, trademark, and 102 | attribution notices from the Source form of the Work, 103 | excluding those notices that do not pertain to any part of 104 | the Derivative Works; and 105 | 106 | (d) If the Work includes a "NOTICE" text file as part of its 107 | distribution, then any Derivative Works that You distribute must 108 | include a readable copy of the attribution notices contained 109 | within such NOTICE file, excluding those notices that do not 110 | pertain to any part of the Derivative Works, in at least one 111 | of the following places: within a NOTICE text file distributed 112 | as part of the Derivative Works; within the Source form or 113 | documentation, if provided along with the Derivative Works; or, 114 | within a display generated by the Derivative Works, if and 115 | wherever such third-party notices normally appear. The contents 116 | of the NOTICE file are for informational purposes only and 117 | do not modify the License. You may add Your own attribution 118 | notices within Derivative Works that You distribute, alongside 119 | or as an addendum to the NOTICE text from the Work, provided 120 | that such additional attribution notices cannot be construed 121 | as modifying the License. 122 | 123 | You may add Your own copyright statement to Your modifications and 124 | may provide additional or different license terms and conditions 125 | for use, reproduction, or distribution of Your modifications, or 126 | for any such Derivative Works as a whole, provided Your use, 127 | reproduction, and distribution of the Work otherwise complies with 128 | the conditions stated in this License. 129 | 130 | 5. Submission of Contributions. Unless You explicitly state otherwise, 131 | any Contribution intentionally submitted for inclusion in the Work 132 | by You to the Licensor shall be under the terms and conditions of 133 | this License, without any additional terms or conditions. 134 | Notwithstanding the above, nothing herein shall supersede or modify 135 | the terms of any separate license agreement you may have executed 136 | with Licensor regarding such Contributions. 137 | 138 | 6. Trademarks. This License does not grant permission to use the trade 139 | names, trademarks, service marks, or product names of the Licensor, 140 | except as required for reasonable and customary use in describing the 141 | origin of the Work and reproducing the content of the NOTICE file. 142 | 143 | 7. Disclaimer of Warranty. Unless required by applicable law or 144 | agreed to in writing, Licensor provides the Work (and each 145 | Contributor provides its Contributions) on an "AS IS" BASIS, 146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 147 | implied, including, without limitation, any warranties or conditions 148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 149 | PARTICULAR PURPOSE. You are solely responsible for determining the 150 | appropriateness of using or redistributing the Work and assume any 151 | risks associated with Your exercise of permissions under this License. 152 | 153 | 8. Limitation of Liability. In no event and under no legal theory, 154 | whether in tort (including negligence), contract, or otherwise, 155 | unless required by applicable law (such as deliberate and grossly 156 | negligent acts) or agreed to in writing, shall any Contributor be 157 | liable to You for damages, including any direct, indirect, special, 158 | incidental, or consequential damages of any character arising as a 159 | result of this License or out of the use or inability to use the 160 | Work (including but not limited to damages for loss of goodwill, 161 | work stoppage, computer failure or malfunction, or any and all 162 | other commercial damages or losses), even if such Contributor 163 | has been advised of the possibility of such damages. 164 | 165 | 9. Accepting Warranty or Additional Liability. While redistributing 166 | the Work or Derivative Works thereof, You may choose to offer, 167 | and charge a fee for, acceptance of support, warranty, indemnity, 168 | or other liability obligations and/or rights consistent with this 169 | License. However, in accepting such obligations, You may act only 170 | on Your own behalf and on Your sole responsibility, not on behalf 171 | of any other Contributor, and only if You agree to indemnify, 172 | defend, and hold each Contributor harmless for any liability 173 | incurred by, or claims asserted against, such Contributor by reason 174 | of your accepting any such warranty or additional liability. 175 | 176 | END OF TERMS AND CONDITIONS 177 | 178 | APPENDIX: How to apply the Apache License to your work. 179 | 180 | To apply the Apache License to your work, attach the following 181 | boilerplate notice, with the fields enclosed by brackets "{}" 182 | replaced with your own identifying information. (Don't include 183 | the brackets!) The text should be enclosed in the appropriate 184 | comment syntax for the file format. We also recommend that a 185 | file or class name and description of purpose be included on the 186 | same "printed page" as the copyright notice for easier 187 | identification within third-party archives. 188 | 189 | Copyright {yyyy} {name of copyright owner} 190 | 191 | Licensed under the Apache License, Version 2.0 (the "License"); 192 | you may not use this file except in compliance with the License. 193 | You may obtain a copy of the License at 194 | 195 | http://www.apache.org/licenses/LICENSE-2.0 196 | 197 | Unless required by applicable law or agreed to in writing, software 198 | distributed under the License is distributed on an "AS IS" BASIS, 199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 200 | See the License for the specific language governing permissions and 201 | limitations under the License. -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Evaluating a machine learning function with functional encryption - example 2 | 3 | This repository demonstrates how the [SGP](https://eprint.iacr.org/2018/206.pdf) functional encryption (FE) 4 | scheme for evaluation of quadratic multi-variate polynomials can be used 5 | to evaluate a machine learning function on encrypted data. 6 | 7 | Specifically, the test data shipped with this repository provides all that 8 | we need to predict which number is hiding behind the image image of a handwritten 9 | digit encoded as a matrix of grayscale levels saved in `testdata/mat_valid.txt` 10 | also seen below: 11 | 12 | ``` 13 | 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 14 | 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 15 | 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 16 | 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 17 | 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 18 | 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 2 0 1 3 2 1 0 0 0 0 19 | 0 0 0 0 0 0 0 0 0 0 1 1 2 2 2 2 2 2 2 2 2 2 2 0 0 0 0 0 20 | 0 0 0 0 0 0 0 0 2 2 2 2 2 2 2 2 2 2 1 0 0 0 0 0 0 0 0 0 21 | 0 0 0 0 0 0 0 0 2 2 2 2 2 2 2 2 2 2 0 0 0 0 0 0 0 0 0 0 22 | 0 0 0 0 0 0 0 0 0 1 1 2 2 2 0 0 0 1 0 0 0 0 0 0 0 0 0 0 23 | 0 0 0 0 0 0 0 0 0 0 0 1 2 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 24 | 0 0 0 0 0 0 0 0 0 0 0 1 2 2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 25 | 0 0 0 0 0 0 0 0 0 0 0 0 2 2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 26 | 0 0 0 0 0 0 0 0 0 0 0 0 0 2 2 1 1 0 0 0 0 0 0 0 0 0 0 0 27 | 0 0 0 0 0 0 0 0 0 0 0 0 0 0 2 2 2 1 0 0 0 0 0 0 0 0 0 0 28 | 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 2 2 2 1 0 0 0 0 0 0 0 0 0 29 | 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 2 2 2 0 0 0 0 0 0 0 0 30 | 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 2 2 2 0 0 0 0 0 0 0 0 31 | 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 2 2 2 2 0 0 0 0 0 0 0 0 32 | 0 0 0 0 0 0 0 0 0 0 0 0 0 1 2 2 2 2 2 2 0 0 0 0 0 0 0 0 33 | 0 0 0 0 0 0 0 0 0 0 0 1 2 2 2 2 2 2 0 0 0 0 0 0 0 0 0 0 34 | 0 0 0 0 0 0 0 0 0 0 2 2 2 2 2 2 0 0 0 0 0 0 0 0 0 0 0 0 35 | 0 0 0 0 0 0 0 2 2 2 2 2 2 2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 36 | 0 0 0 0 0 2 2 2 2 2 2 2 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 37 | 0 0 0 0 1 2 2 2 2 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 38 | 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 39 | 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 40 | 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 41 | ``` 42 | 43 | However, the goal of this example is to demonstrate that a 44 | party can encrypt the input data, while another party can learn something 45 | from the encrypted data (e.g. which number is represented on the image) 46 | without actually knowing exactly what the image was. 47 | 48 | 49 | The example uses an implementation of the scheme from the 50 | [GoFE library](https://github.com/fentec-project/gofe). 51 | 52 | ### Input data 53 | The example assumes that we learned a function for recognizing numbers from 54 | images of hand-written digits using TensorFlow, and saved the parameters to files 55 | `mat_diag.txt` and `mat_proj.txt`, which we put in the `testdata` folder. 56 | * mat_valid.txt holds a vector that needs to be encrypted 57 | * mat_proj.txt holds the first set of parameters of the function deciding which digit is the image 58 | * mat_diag.txt holds the second set of parameters of the function deciding which digit is the image 59 | 60 | We used a Python script `mnist.py` to train the model. Feel free to continue with the 61 | section [How to run the example](#how-to-run-the-example) if you wish to run the 62 | example without re-running the training script. 63 | 64 | #### Generating training data 65 | If you wish to re-train the model (and generate new input data for the example), 66 | you will need to: 67 | 68 | 1. Install the dependencies: 69 | ````bash 70 | $ pip install tensorflow numpy 71 | ```` 72 | 2. Navigate to the root of this repository and run the 73 | python training script: 74 | ````bash 75 | $ cd $GOPATH/src/github.com/fentec-project/neural-network-on-encrypted-data 76 | $ python mnist.py 77 | ```` 78 | 79 | ## How to run the example 80 | 1. Build the example by running: 81 | ````bash 82 | $ go get github.com/fentec-project/neural-network-on-encrypted-data 83 | ```` 84 | 2. This will produce the `neural-network-on-encrypted-data` executable in your `$GOPATH/bin`. 85 | If you have `$GOPATH/bin` in your `PATH` environment variable, you 86 | will be able to run the example by running command `neural-network-on-encrypted-data` from the 87 | root of this repository. 88 | 89 | Otherwise just call: 90 | ```bash 91 | $ $GOPATH/bin/neural-network-on-encrypted-data 92 | ``` 93 | The example will output the predicted number behind the image 94 | (encoded as a matrix in `testdata/mat_valid.txt`): 95 | ````bash 96 | prediction vector: [-99073763 -149651697 -114628671 83732640 -387336224 130856071 -302672454 -126041027 -121102209 -111101930] 97 | the model predicts that the number is 5 98 | ```` 99 | -------------------------------------------------------------------------------- /five: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fentec-project/neural-network-on-encrypted-data/f47c73d7383489cd763b714cb9d55092c64bf9d7/five -------------------------------------------------------------------------------- /main.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2018 XLAB d.o.o 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | package main 18 | 19 | import ( 20 | "math/big" 21 | "github.com/pkg/errors" 22 | quad "github.com/fentec-project/gofe/quadratic" 23 | "fmt" 24 | ) 25 | 26 | // This is a demonstration of how the SGP FE scheme for evaluation of 27 | // quadratic multivariate polynomials can be used 28 | // to evaluate a machine learning function on encrypted data. 29 | // 30 | // First, we assume that we learned a function for recognizing numbers 31 | // from images using TensorFlow, and saved the parameters to files 32 | // mat_valid.txt, mat_diag.txt and mat_proj.txt, which we put in the 33 | // testdata folder. 34 | func main() { 35 | // Read input matrices. 36 | // Matrices were exported from tensor flow. 37 | // We determine parameters like the number of vectors, vector space, 38 | // number of classes to be predicted and the number of examples, from the 39 | // input matrices. 40 | 41 | // Projection matrix - our data. 42 | // Contains nVecs vectors projected onto vector space of size vecSize. 43 | proj, err := readMatFromFile("testdata/mat_proj.txt") 44 | if err != nil { 45 | panic(errors.Wrap(err, "error reading projection matrix")) 46 | } 47 | nVecs := proj.Rows() 48 | vecSize := proj.Cols() 49 | 50 | // Diagonal matrix 51 | // number of rows of this matrix represents the number of classes. 52 | // The function will predict one of these classes. 53 | diag, err := readMatFromFile("testdata/mat_diag.txt") 54 | if err != nil { 55 | panic(errors.Wrap(err, "error reading diagonal matrix")) 56 | } 57 | nClasses := diag.Rows() 58 | if diag.Cols() != nVecs { 59 | panic(fmt.Sprintf("diagonal matrix must have %d columns", nVecs)) 60 | } 61 | 62 | // Valid matrix 63 | // number of rows of this matrix represents the number of examples. 64 | valid, err := readMatFromFile("testdata/mat_valid.txt") 65 | if err != nil { 66 | panic(errors.Wrap(err, "error reading valid matrix")) 67 | } 68 | if valid.Cols() != vecSize { 69 | panic(fmt.Sprintf("valid matrix must have %d columns", vecSize)) 70 | } 71 | 72 | // We know that all the values in the matrices are in the 73 | // interval [-bound, bound]. 74 | bound := big.NewInt(100) 75 | 76 | // q is an instance of the FE scheme for quadratic multi-variate 77 | // polynomials constructed by Sans, Gay, Pointcheval (SGP) 78 | q := quad.NewSGP(vecSize, bound) 79 | 80 | // we generate a master secret key that we will need for encryption 81 | // of our data. 82 | fmt.Println("Generating master secret key...") 83 | msk, err := q.GenerateMasterKey() 84 | if err != nil { 85 | panic(errors.Wrap(err, "error when generating master keys")) 86 | } 87 | 88 | // First, we encrypt the data from mat_valid.txt 89 | // with our master secret key. 90 | // x = first row of matrix valid 91 | // y = also the first row of matrix valid 92 | fmt.Println("Encrypting...") 93 | c, err := q.Encrypt(valid[0], valid[0], msk) 94 | if err != nil { 95 | panic(errors.Wrap(err, "error when encrypting")) 96 | } 97 | 98 | // Then, we manipulate the encryption to be the encryption of the 99 | // projected data. 100 | // Note that this can also be done without knowing the secret key. 101 | fmt.Println("Manipulating encryption...") 102 | projC := projectEncryption(c, proj) 103 | 104 | fmt.Println("Manipulating secret key...") 105 | projSecKey := projectSecKey(msk, proj) 106 | 107 | // We create a new (projected) scheme instance for decrypting 108 | newBound := big.NewInt(1500000000) 109 | fmt.Println("Creating new (projected) scheme instance for decrypting...") 110 | qProj := quad.NewSGP(nVecs, newBound) 111 | 112 | res := make([]*big.Int, nClasses) 113 | maxValue := new(big.Int).Set(newBound) 114 | maxValue = maxValue.Neg(maxValue) 115 | 116 | fmt.Println("Predicting...") 117 | predictedNum := 0 // the predicted number 118 | for i := 0; i < nClasses; i++ { 119 | // We construct a diagonal matrix D that has the elements in the 120 | // current row of matrix diag on the diagonal. 121 | D := diagMat(diag[i]) 122 | 123 | // We derive a feKey for obtaining the prediction from the encryption. 124 | // We will use this feKey for decrypting the final result, 125 | // e.g. x^T * D * y. 126 | feKey, err := qProj.DeriveKey(projSecKey, D) 127 | if err != nil { 128 | panic(errors.Wrap(err, "error when deriving FE key")) 129 | } 130 | 131 | // We decrypt the encryption with the derived key feKey. 132 | // The result of decryption holds the value of x^T * D * y, 133 | // which in our case predicts the number from the handwritten 134 | // image. 135 | dec, err := qProj.Decrypt(projC, feKey, D) 136 | if err != nil { 137 | panic(errors.Wrap(err, "error when decrypting")) 138 | } 139 | res[i] = dec 140 | if dec.Cmp(maxValue) > 0 { 141 | maxValue.Set(dec) 142 | predictedNum = i 143 | } 144 | } 145 | 146 | fmt.Println("Prediction vector:", res) 147 | fmt.Println("The model predicts that the number on the image is", predictedNum) 148 | } 149 | -------------------------------------------------------------------------------- /mnist.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2018 XLAB d.o.o 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | package main 18 | 19 | import ( 20 | "math/big" 21 | 22 | "github.com/fentec-project/gofe/data" 23 | quad "github.com/fentec-project/gofe/quadratic" 24 | ) 25 | 26 | // innerProdEncryption accepts the encryption c of (x, y) 27 | // and vectors u, v. It manipulates the encryption in order 28 | // to obtain the encryption of (x*u, y*v). 29 | func innerProdEncryption(c *quad.SGPCipher, u, v data.Vector) *quad.SGPCipher { 30 | zeros := make(data.Vector, 2) 31 | zeros[0] = big.NewInt(0) 32 | zeros[1] = big.NewInt(0) 33 | 34 | firstG1 := zeros.MulG1() 35 | secondG2 := zeros.MulG2() 36 | 37 | for i := 0; i < len(c.AMulG1); i++ { 38 | ui := make(data.Vector, 2) 39 | ui[0] = u[i] 40 | ui[1] = u[i] 41 | tmpG1 := ui.MulVecG1(c.AMulG1[i]) 42 | firstG1 = firstG1.Add(tmpG1) 43 | 44 | vi := make(data.Vector, 2) 45 | vi[0] = v[i] 46 | vi[1] = v[i] 47 | tmpG2 := vi.MulVecG2(c.BMulG2[i]) 48 | secondG2 = secondG2.Add(tmpG2) 49 | } 50 | 51 | first := make([]data.VectorG1, 1) 52 | first[0] = firstG1 53 | second := make([]data.VectorG2, 1) 54 | second[0] = secondG2 55 | 56 | return quad.NewSGPCipher(c.G1MulGamma, first, second) 57 | } 58 | 59 | // projectEncryption accepts the encryption c of (x, y) 60 | // and projection matrix P. It manipulates the encryption 61 | // in order to obtain an encryption of (P*x, P*y). 62 | func projectEncryption(c *quad.SGPCipher, P data.Matrix) *quad.SGPCipher { 63 | n := len(P) // number of vectors in the P matrix 64 | aMulG1 := make([]data.VectorG1, n) 65 | bMulG2 := make([]data.VectorG2, n) 66 | 67 | for i := 0; i < n; i++ { 68 | innerC := innerProdEncryption(c, P[i], P[i]) 69 | aMulG1[i] = innerC.AMulG1[0] 70 | bMulG2[i] = innerC.BMulG2[0] 71 | } 72 | 73 | return quad.NewSGPCipher(c.G1MulGamma, aMulG1, bMulG2) 74 | } 75 | 76 | // innerProdSecKey accepts the secret key msk that was used for 77 | // encryption of (x, y), and vectors u, v. 78 | // It manipulates the provided master secret key in order to obtain 79 | // a secret key for encryption of (x*u, y*v). 80 | // Secret key is manipulated with the inner (dot) product operation. 81 | func innerProdSecKey(msk *quad.SGPSecKey, u, v data.Vector) *quad.SGPSecKey { 82 | s := make(data.Vector, 1) 83 | s[0], _ = msk.S.Dot(u) 84 | 85 | t := make(data.Vector, 1) 86 | t[0], _ = msk.T.Dot(v) 87 | 88 | return quad.NewSGPSecKey(s, t) 89 | } 90 | 91 | // projectSecKey accepts the secret key msk that was used for 92 | // encryption of (x, y), and the projection matrix P. 93 | // It manipulates the provided master secret key in order to obtain 94 | // a secret key for encryption of (P*x, P*y). 95 | func projectSecKey(msk *quad.SGPSecKey, P data.Matrix) *quad.SGPSecKey { 96 | n := len(P) // number of vectors in the P matrix 97 | s := make(data.Vector, n) 98 | t := make(data.Vector, n) 99 | 100 | for i := 0; i < n; i++ { 101 | secKeyInner := innerProdSecKey(msk, P[i], P[i]) 102 | s[i] = secKeyInner.S[0] 103 | t[i] = secKeyInner.T[0] 104 | } 105 | 106 | return quad.NewSGPSecKey(s, t) 107 | } 108 | 109 | // diagMat takes a vector v and returns a diagonal matrix 110 | // with elements of v on the diagonal. 111 | func diagMat(v data.Vector) data.Matrix { 112 | l := len(v) 113 | mat := make(data.Matrix, l) 114 | 115 | for j, vi := range v { 116 | vec := make(data.Vector, l) 117 | for i := 0; i < l; i++ { 118 | vec[i] = big.NewInt(0) 119 | if i == j { 120 | vec[i].Set(vi) 121 | } 122 | } 123 | mat[j] = vec 124 | } 125 | 126 | return mat 127 | } 128 | -------------------------------------------------------------------------------- /mnist.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2018 XLAB d.o.o 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | # imports 16 | import tensorflow as tf 17 | import numpy as np 18 | 19 | img_h = img_w = 28 # MNIST images are 28x28 20 | img_size_flat = img_h * img_w + 1 # 28x28 + 1=785, the total number of pixels plus bias 21 | n_classes = 10 # Number of classes, one class per digit 22 | disc_data = 3 23 | disc_value = 80 24 | 25 | 26 | def load_data(mode='train'): 27 | """ 28 | Function to (download and) load the MNIST data 29 | :param mode: train or test 30 | :return: images and the corresponding labels 31 | """ 32 | from tensorflow.examples.tutorials.mnist import input_data 33 | mnist = input_data.read_data_sets("MNIST_data/", one_hot=True) 34 | if mode == 'train': 35 | x_train, y_train, x_valid, y_valid = mnist.train.images, mnist.train.labels, \ 36 | mnist.validation.images, mnist.validation.labels 37 | return x_train, y_train, x_valid, y_valid 38 | elif mode == 'test': 39 | x_test, y_test = mnist.test.images, mnist.test.labels 40 | return x_test, y_test 41 | 42 | 43 | def randomize(x, y): 44 | """ Randomizes the order of data samples and their corresponding labels""" 45 | permutation = np.random.permutation(y.shape[0]) 46 | shuffled_x = x[permutation, :] 47 | shuffled_y = y[permutation] 48 | return shuffled_x, shuffled_y 49 | 50 | 51 | def get_next_batch(x, y, start, end): 52 | x_batch = x[start:end] 53 | y_batch = y[start:end] 54 | return x_batch, y_batch 55 | 56 | 57 | def discretize_data(d, size): 58 | max_value = np.amax(np.abs(d)) 59 | res = np.floor((d / max_value) * size) / size 60 | return res 61 | 62 | def add_ones(d): 63 | ones = np.ones((d.shape[0], 1)) 64 | return np.concatenate([ones, d], axis=1) 65 | 66 | 67 | # Load MNIST data 68 | x_train, y_train, x_valid, y_valid = load_data(mode='train') 69 | 70 | x_train = add_ones(discretize_data(x_train, disc_data)) 71 | x_valid = add_ones(discretize_data(x_valid, disc_data)) 72 | 73 | 74 | print("Size of:") 75 | print("- Training-set:\t\t{}".format(len(y_train))) 76 | print("- Validation-set:\t{}".format(len(y_valid))) 77 | 78 | 79 | print('x_train:\t{}'.format(x_train.shape)) 80 | print('y_train:\t{}'.format(y_train.shape)) 81 | print('x_train:\t{}'.format(x_valid.shape)) 82 | print('y_valid:\t{}'.format(y_valid.shape)) 83 | 84 | # Hyper-parameters 85 | epochs = 10 # Total number of training epochs 86 | batch_size = 100 # Training batch size 87 | display_freq = 100 # Frequency of displaying the training results 88 | learning_rate = 0.001 # The optimization initial learning rate 89 | 90 | h1 = 20 # The first hidden layer is a projection to h1 dimensions 91 | 92 | # weight and bais wrappers 93 | def weight_variable(name, shape): 94 | """ 95 | Create a weight variable with appropriate initialization 96 | :param name: weight name 97 | :param shape: weight shape 98 | :return: initialized weight variable 99 | """ 100 | initer = tf.truncated_normal_initializer(stddev=0.01) 101 | return tf.get_variable('W_' + name, 102 | dtype=tf.float32, 103 | shape=shape, 104 | initializer=initer) 105 | 106 | 107 | 108 | # Create the graph for the linear model 109 | # Placeholders for inputs (x) and outputs(y) 110 | x = tf.placeholder(tf.float32, shape=[None, img_size_flat], name='X') 111 | y = tf.placeholder(tf.float32, shape=[None, n_classes], name='Y') 112 | 113 | 114 | P = weight_variable('projection', shape=[img_size_flat, h1]) 115 | fc1 = tf.matmul(x, P) 116 | 117 | x2 = tf.square(fc1) 118 | 119 | D = weight_variable('output', shape=[h1, n_classes]) 120 | output_logits = tf.matmul(x2, D) 121 | 122 | # Network predictions 123 | cls_prediction = tf.argmax(output_logits, axis=1, name='predictions') 124 | 125 | # Define the loss function, optimizer, and accuracy 126 | loss = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits(labels=y, logits=output_logits), name='loss') 127 | optimizer = tf.train.AdamOptimizer(learning_rate=learning_rate, name='Adam-op').minimize(loss) 128 | correct_prediction = tf.equal(tf.argmax(output_logits, 1), tf.argmax(y, 1), name='correct_pred') 129 | accuracy = tf.reduce_mean(tf.cast(correct_prediction, tf.float32), name='accuracy') 130 | 131 | # Create the op for initializing all variables 132 | init = tf.global_variables_initializer() 133 | 134 | sess = tf.InteractiveSession() 135 | sess.run(init) 136 | global_step = 0 137 | # Number of training iterations in each epoch 138 | num_tr_iter = int(len(y_train) / batch_size) 139 | for epoch in range(epochs): 140 | print('Training epoch: {}'.format(epoch + 1)) 141 | x_train, y_train = randomize(x_train, y_train) 142 | for iteration in range(num_tr_iter): 143 | global_step += 1 144 | start = iteration * batch_size 145 | end = (iteration + 1) * batch_size 146 | x_batch, y_batch = get_next_batch(x_train, y_train, start, end) 147 | 148 | # Run optimization op (backprop) 149 | feed_dict_batch = {x: x_batch, y: y_batch} 150 | sess.run(optimizer, feed_dict=feed_dict_batch) 151 | 152 | if iteration % display_freq == 0: 153 | # Calculate and display the batch loss and accuracy 154 | loss_batch, acc_batch = sess.run([loss, accuracy], 155 | feed_dict=feed_dict_batch) 156 | 157 | print("iter {0:3d}:\t Loss={1:.2f},\tTraining Accuracy={2:.01%}". 158 | format(iteration, loss_batch, acc_batch)) 159 | 160 | # Run validation after every epoch 161 | feed_dict_valid = {x: x_valid[:5000], y: y_valid[:5000]} 162 | Pr, Di, loss_valid, acc_valid = sess.run([P, D, loss, accuracy], feed_dict=feed_dict_valid) 163 | print('---------------------------------------------------------') 164 | print("Epoch: {0}, validation loss: {1:.2f}, validation accuracy: {2:.01%}". 165 | format(epoch + 1, loss_valid, acc_valid)) 166 | print('---------------------------------------------------------') 167 | # print(Di) 168 | 169 | 170 | Pr = discretize_data(Pr, disc_value) 171 | Di = discretize_data(Di, disc_value) 172 | predict = np.matmul(np.square(np.matmul(x_valid, Pr)), Di) 173 | correct = np.equal(np.argmax(predict, 1), np.argmax(y_valid, 1)) 174 | final_acc = np.mean(correct) 175 | print('-----------------------------------------------------------------') 176 | print('-----------------------------------------------------------------') 177 | print('-----------------------------------------------------------------') 178 | print("The final accuracy of validation set after discretization: {0:.01%}". 179 | format(final_acc)) 180 | print('-----------------------------------------------------------------') 181 | print('-----------------------------------------------------------------') 182 | print('-----------------------------------------------------------------') 183 | 184 | 185 | def matrix_to_txt(Mat, name): 186 | w = open(name + '.txt', 'w') 187 | for i in range(Mat.shape[0]): 188 | row = [str(x) for x in Mat[i, :]] 189 | w.write(' '.join(row) + '\n') 190 | w.close() 191 | 192 | 193 | Pr = Pr * disc_value 194 | Pr = Pr.astype(int) 195 | Di = Di * disc_value 196 | Di = Di.astype(int) 197 | valid1 = np.floor(x_valid[:1] * disc_data + 0.5) 198 | valid1 = valid1.astype(int) 199 | 200 | matrix_to_txt(np.transpose(Pr), 'testdata/mat_proj') 201 | matrix_to_txt(np.transpose(Di), 'testdata/mat_diag') 202 | matrix_to_txt(valid1, 'testdata/mat_valid') -------------------------------------------------------------------------------- /read.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2018 XLAB d.o.o 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | package main 18 | 19 | import ( 20 | "bufio" 21 | "math/big" 22 | "os" 23 | "strings" 24 | 25 | "github.com/pkg/errors" 26 | "github.com/fentec-project/gofe/data" 27 | ) 28 | 29 | // readMatFromFile reads matrix elements from the provided file 30 | // and gives a matrix 31 | func readMatFromFile(path string) (data.Matrix, error) { 32 | file, err := os.Open(path) 33 | if err != nil { 34 | return nil, errors.Wrap(err, "error reading matrix from file") 35 | } 36 | 37 | scanner := bufio.NewScanner(file) 38 | vecs := make([]data.Vector, 0) 39 | 40 | for scanner.Scan() { 41 | line := scanner.Text() 42 | numbers := strings.Split(line, " ") 43 | v := make(data.Vector, len(numbers)) 44 | for i, n := range numbers { 45 | v[i], _ = new(big.Int).SetString(n, 10) 46 | } 47 | vecs = append(vecs, v) 48 | } 49 | 50 | return data.NewMatrix(vecs) 51 | } 52 | -------------------------------------------------------------------------------- /testdata/mat_diag.txt: -------------------------------------------------------------------------------- 1 | 21 -17 -46 -25 1 -2 -38 12 7 14 -23 -8 -12 8 21 -1 6 27 5 -29 2 | 27 41 9 -45 5 13 13 2 -39 -22 11 -44 -17 6 -8 -16 -10 -40 -27 52 3 | 18 27 5 1 17 -59 -1 30 -8 -3 -1 -1 -28 -40 32 35 -32 0 -6 9 4 | -48 5 29 2 15 -27 -20 13 13 -20 -32 -14 29 -10 20 8 12 -1 -25 -8 5 | 28 -21 -1 5 22 -5 -4 -80 -7 -38 44 22 -20 25 -71 -23 -21 -17 -31 6 6 | -15 -36 20 -9 -5 41 -13 -6 -14 24 0 -9 37 -35 -38 -9 23 -25 25 -15 7 | -5 0 -32 -31 -60 6 -57 -28 -27 19 -2 28 -22 15 -29 19 -13 25 32 23 8 | 31 -7 -32 15 6 -11 31 25 -19 -50 -24 -6 -22 9 21 25 37 -42 -44 -35 9 | -17 0 7 -20 -48 -8 13 -11 31 4 9 17 -19 -4 -12 -42 -23 -21 9 -23 10 | -11 -40 -21 33 16 19 9 -32 13 12 -6 -33 10 20 -4 -79 -11 14 -33 -39 11 | -------------------------------------------------------------------------------- /testdata/mat_proj.txt: -------------------------------------------------------------------------------- 1 | 41 0 0 -1 -1 0 1 -1 0 0 1 -2 0 5 13 13 0 1 1 0 -1 0 -1 -1 1 -1 -1 0 -1 -1 -2 0 1 0 0 -22 -24 -21 -17 -4 17 13 11 12 -22 -15 -10 -20 -32 -25 14 5 -13 1 0 0 -1 0 0 -1 0 -4 0 -11 -13 -35 -5 -22 -15 -12 -8 -17 -39 -36 -26 -7 -4 -18 -1 -1 -17 14 18 0 -1 0 -1 0 -14 -23 -14 -15 -20 0 -11 -14 -10 -7 -5 -16 6 1 6 -5 -17 -13 -1 -3 -12 11 18 4 -1 -1 1 -5 11 -9 -14 -12 0 -11 -5 -9 5 -3 7 10 15 -2 10 20 4 4 7 8 7 5 16 7 0 -2 -1 -4 -18 -14 2 11 -1 -4 5 11 11 0 6 5 -2 -2 5 6 6 2 -1 1 -7 -7 -6 -7 13 -1 0 34 4 1 19 2 3 5 -4 9 9 5 6 2 -3 -11 1 0 2 7 2 1 -5 -19 -17 -23 -14 1 -28 40 25 4 -1 24 19 4 9 9 22 9 12 -1 -8 -2 4 12 9 0 1 6 14 0 -5 -7 4 -1 21 32 9 -11 2 5 2 12 17 16 16 13 -2 3 2 16 9 9 11 12 0 -7 18 21 -4 -15 -13 14 19 10 -2 -7 14 -2 3 -7 7 14 16 15 9 -9 -14 4 22 20 22 13 4 1 11 12 -1 -12 -14 15 9 34 5 23 17 3 2 -9 2 9 26 19 -2 -18 -22 -5 22 33 21 16 14 15 -3 4 12 -20 8 11 16 17 -8 -5 -1 12 10 -14 -7 10 20 17 -10 -40 -57 -34 8 18 18 12 8 2 3 2 4 4 -4 10 16 3 -5 -14 -9 7 1 0 -4 9 16 8 -10 -48 -60 -31 8 11 4 3 -9 9 -3 8 -17 -11 -26 -2 6 31 -13 -1 -4 0 14 4 5 13 14 6 -25 -39 -46 -20 1 -4 -1 -11 -7 8 5 1 0 -5 11 16 -16 29 -15 7 17 -2 21 4 9 9 2 -12 -24 -34 -36 -21 -3 -7 -2 -6 3 5 20 14 13 43 0 -2 -17 -14 -8 16 16 -2 10 -2 7 14 -4 -24 -26 -37 -22 -11 6 5 1 0 11 15 13 34 -6 42 21 -1 -22 -26 -3 13 8 7 19 8 4 -4 -4 -24 -43 -21 5 16 23 14 12 12 20 6 2 6 11 39 29 -2 -3 5 -7 10 13 14 4 12 8 -1 -9 -31 -34 -2 23 14 31 21 15 13 10 18 -7 15 32 16 6 1 -1 -19 -11 2 13 3 13 16 10 6 -10 -28 -21 5 17 27 18 19 16 9 18 17 6 9 7 -2 14 1 14 -23 -15 20 7 15 14 6 1 3 -7 -16 -16 9 15 20 22 13 7 9 7 10 -13 3 1 6 -1 -1 10 22 4 19 20 11 5 1 0 1 -4 -1 -1 -3 2 6 6 1 9 -9 0 11 7 -10 -23 -10 -1 -1 -5 16 15 10 3 -1 -1 0 3 4 5 -5 -6 -4 -1 4 0 2 0 2 1 13 4 5 0 20 1 -1 -1 10 -3 -6 4 9 6 19 14 3 9 4 3 -7 -1 -12 -2 -12 -5 -12 4 6 -15 12 7 -14 -1 -2 -2 -31 -23 -13 -6 7 9 6 21 23 13 9 -2 3 -4 -8 0 -22 -12 -13 -8 -25 -33 0 14 -16 0 -2 -1 5 -14 -3 5 -4 -1 24 21 5 7 4 2 3 2 -5 11 -10 -17 -26 -4 -37 -26 10 -5 9 1 0 -1 -1 12 3 -17 -12 -7 7 10 -17 -15 -8 -9 -10 1 19 -3 -15 -13 -23 6 -4 -39 -15 -10 7 0 -1 -1 -2 -1 -10 -22 -17 -12 -1 3 -6 -10 1 -9 -7 4 12 -3 -6 -1 -21 -17 13 16 0 0 0 0 0 0 0 0 8 19 31 -4 -3 11 -8 -8 -5 29 1 7 14 32 29 -11 -5 -13 13 -1 -2 1 0 -1 2 | -21 -2 1 0 -1 -1 0 0 -1 -1 -1 0 -1 5 2 -13 -2 -1 -2 1 -1 1 0 1 0 0 0 -2 0 -1 -1 -1 -1 -1 -2 -9 -8 -13 -13 -5 6 0 -1 -16 -17 -32 -31 -3 3 3 -6 -13 -6 1 -2 -1 0 0 0 1 1 -8 -2 -7 -15 2 0 -26 -27 -27 -38 -25 -40 -30 -12 6 1 12 13 2 -21 -15 -16 -1 -1 -1 0 -1 -7 -12 -5 7 2 -3 -14 -2 -16 -18 -16 -10 -21 -30 -2 16 -2 15 12 16 0 -10 11 2 0 -1 0 -15 9 15 -3 -24 -13 -25 -24 -17 -12 -13 -15 -17 -16 -24 -12 -5 -30 -11 9 14 28 39 12 -4 -2 -1 -1 -2 -8 -15 -2 -12 -13 1 9 8 18 9 1 -9 -13 -19 -21 -19 -11 -12 -6 0 5 16 25 9 15 -1 0 27 -5 1 4 2 6 10 10 8 15 11 5 -2 -4 -15 -9 -9 0 6 8 1 2 20 -3 14 17 -1 -23 12 -5 -20 0 -6 1 6 10 10 17 5 4 2 1 -9 -11 -6 0 7 7 3 16 27 21 22 16 -2 -10 7 -6 -28 6 4 -1 14 7 0 3 1 3 3 -5 -12 -26 -8 -7 10 8 1 26 42 21 8 -10 -9 -6 -1 -10 -18 -5 -1 -8 -6 -4 0 -2 2 8 4 -19 -25 -16 -11 -3 5 4 1 14 30 0 -16 -5 -10 -4 -3 -7 -2 -8 -12 -11 -2 4 -3 -6 14 8 -2 -18 -17 -20 -10 -15 -4 -4 3 10 28 -3 0 -10 4 -5 6 -3 -13 5 -1 4 5 3 4 7 22 6 -10 -16 -4 -4 -9 -15 -11 -2 5 13 15 -3 18 -11 4 -5 13 3 -1 14 12 14 12 -1 12 21 2 1 -20 -9 -3 -6 -3 -7 3 0 16 14 -2 10 6 -25 1 -2 -7 14 29 20 18 31 13 18 29 14 1 -13 -22 -11 -5 -8 -3 11 5 8 8 4 0 -13 -19 -20 16 -16 -2 -2 19 27 17 28 18 20 16 -3 -13 -20 -30 -7 -4 1 8 11 19 10 2 4 -13 -4 -48 -1 -2 -15 -23 1 24 4 2 21 12 12 1 -17 -27 -35 -36 -9 -1 16 17 12 29 23 16 16 -1 -14 -12 -22 0 -19 -10 6 15 2 7 3 7 -14 -24 -29 -26 -37 -20 7 14 19 16 17 33 14 11 1 -12 -24 -12 -20 -1 -11 0 0 3 13 8 0 -12 -16 -31 -23 -22 -27 -9 13 14 18 14 8 21 17 7 2 -12 -38 -17 -28 0 -4 11 -8 -2 5 11 -3 -5 -15 -7 -6 -12 -13 3 16 10 0 -1 -2 3 -3 -12 -19 -23 -51 -6 -8 1 6 3 -17 -7 11 13 -5 -7 -17 -10 -7 -1 -13 6 6 -6 -10 -12 -12 -13 -14 -19 -35 -23 -50 -23 5 -1 16 -6 -32 -14 24 -4 -15 -8 -4 -7 -8 -15 0 1 -4 -10 -14 -23 -23 -15 -19 -21 -39 -28 -27 -24 1 0 -14 -21 -39 -20 -4 -7 -5 -13 3 -9 -6 -4 -8 -11 -6 -15 -17 -30 -30 -20 -21 -25 -35 -42 -1 -32 -1 0 0 -11 -18 -18 -43 -21 -9 -7 -9 -2 -4 -7 -10 -11 -10 -7 -12 -23 -20 -28 -15 -10 -11 -27 -15 10 1 -1 0 -28 -13 -2 -17 -5 0 -4 -10 -3 -17 -22 -23 -10 -13 -8 -8 -9 -14 -10 -16 -14 -13 -21 -9 -16 0 -1 0 -13 20 27 3 1 17 18 2 -1 -2 -15 -4 -9 5 -4 -1 4 -1 -3 -14 -3 3 -32 -14 -9 -1 -2 1 -2 20 24 27 13 32 18 17 32 23 13 10 10 12 14 4 25 19 13 33 34 12 3 4 -10 0 0 -2 0 -2 14 17 14 4 4 16 9 14 59 57 45 32 28 10 9 17 36 25 33 -13 -1 -1 -1 -1 1 1 0 0 -12 -10 -8 -6 -11 15 -3 19 15 10 41 32 15 13 22 7 25 9 31 -1 0 1 0 -1 3 | 12 -2 0 0 -2 -1 -1 -1 0 -1 0 1 -1 -13 -10 9 -1 0 0 0 0 0 -1 0 0 1 0 0 0 1 0 -2 -1 0 -1 -19 -17 0 1 -28 -31 -39 -32 -3 -23 -6 -8 -24 -28 -29 -16 6 -9 -1 -1 -2 -2 -2 -1 -2 -1 -14 -1 -8 -29 -20 -1 10 6 -5 0 -12 -4 11 -2 -5 0 -3 -8 -13 -24 11 13 -1 0 0 0 0 -14 -18 11 -8 8 13 18 27 31 34 10 20 25 16 14 16 14 21 2 -8 -14 -8 29 -7 1 -1 1 15 -18 6 1 36 18 20 24 36 35 36 28 24 24 31 21 21 14 13 -3 -4 -13 8 13 23 0 -1 0 -8 30 10 3 8 15 -4 8 12 9 13 9 7 10 22 21 12 20 18 7 13 -12 -4 3 17 -11 -2 -2 3 0 -7 6 7 2 3 10 8 4 7 7 2 0 1 -4 0 3 0 -5 3 8 17 11 36 15 0 23 -21 -23 22 24 12 6 16 0 3 -5 -2 -7 3 -2 -6 -7 -10 0 -5 0 -5 -5 2 24 31 18 -1 -11 -5 9 20 15 10 9 -6 -4 0 5 3 5 -1 -4 -5 4 7 7 6 2 15 11 8 40 59 27 -19 -10 8 7 22 10 12 8 6 -8 -7 -6 1 3 3 3 8 -1 11 16 6 10 23 10 24 62 33 -5 -20 -4 -13 31 14 13 1 5 -5 -15 -7 -5 5 11 5 4 3 2 4 13 7 0 -5 9 0 36 35 7 -15 -27 -8 29 25 -3 -18 -18 -14 -9 -10 5 16 12 5 5 -2 -2 10 7 -10 -25 -26 -26 -4 22 34 7 -13 -20 -21 8 -8 -12 -16 -16 -16 -6 5 11 21 13 17 9 -2 -8 3 2 -11 -19 -47 -35 -28 -14 23 -9 0 -11 -22 3 -28 -29 -25 -21 -9 -4 -8 6 17 22 20 2 -7 2 0 0 -5 -24 -38 -36 -20 -10 14 8 11 13 -18 10 -29 -35 -15 -24 -13 -9 -12 -8 1 10 26 6 -5 0 -3 -10 -15 -21 -21 -23 -4 -5 19 -1 1 15 31 3 -22 -17 -3 -31 -21 -24 -28 -20 2 13 18 9 1 -13 -4 2 -4 -13 -4 -3 5 19 26 20 -1 19 35 32 19 -2 -13 -29 -30 -24 -21 -32 -3 19 12 -4 -4 -2 7 14 1 10 16 11 26 37 25 21 -1 0 17 35 27 -5 2 -7 -10 -17 -32 -33 -14 -2 1 2 11 13 7 14 8 20 8 12 1 5 7 -7 -2 0 14 39 29 27 19 1 -3 -9 -14 -14 -11 4 5 15 23 17 9 14 14 8 15 11 12 14 -7 16 0 -8 13 30 22 26 13 11 12 16 12 2 1 16 13 18 23 21 15 6 3 10 16 24 14 17 17 1 1 -16 -3 19 16 4 17 17 16 20 16 18 5 7 10 20 22 24 20 0 14 16 15 22 9 11 10 0 0 8 8 8 12 1 12 15 13 9 15 17 16 16 21 19 7 14 15 10 15 10 14 7 12 24 -6 0 0 -1 7 1 8 5 -3 5 0 -3 5 13 12 7 7 12 9 15 17 15 15 -5 11 20 11 14 15 -1 0 -1 24 34 14 12 -4 -6 11 5 2 5 3 10 4 10 11 17 14 8 27 -4 13 24 10 5 6 1 0 0 -2 27 -9 -12 6 0 -2 5 1 2 11 9 22 6 17 6 8 5 -7 10 17 -5 15 -5 5 -1 -2 1 -2 -18 -20 -29 -7 -5 1 6 7 7 22 30 20 14 7 3 3 12 -8 -12 -2 15 20 -9 6 -1 0 0 -1 -1 -16 -15 -13 -12 -19 -21 -16 -14 -37 -37 -43 -17 -8 -8 -7 -8 -29 -9 -3 -12 0 0 0 1 -1 0 0 -1 0 -2 -9 -12 -15 -21 -37 -6 -4 -9 -53 -34 -36 -48 -34 -20 -22 -11 -2 -2 0 -1 -1 0 4 | 35 -1 -1 0 1 1 -1 1 0 -2 -2 -2 0 -13 -10 10 0 0 -1 0 1 -1 0 -1 0 1 1 -2 -1 -2 -1 -1 -2 -1 -1 -15 -17 -9 -3 -22 -31 -38 -44 11 -27 -19 -23 -20 -25 -30 -22 -18 -12 0 -2 0 1 0 -1 -2 -1 -9 0 -9 -24 -19 -14 -26 -30 -49 -46 -44 -19 -10 0 -24 -28 -35 -34 -29 -29 8 12 -2 0 -1 0 -1 -12 -16 -12 -22 -19 -21 -22 -23 -23 -46 -71 -63 -49 -18 -15 -7 -12 -14 -11 -14 -16 -8 19 4 1 0 -1 -12 12 -7 -4 8 -14 -18 -34 -39 -28 -34 -36 -35 -31 -27 -8 2 -8 -7 -19 -13 -5 17 8 1 -1 0 -1 -7 1 -4 11 4 -6 14 11 0 11 5 5 -6 -12 -5 -4 -6 -5 -1 -16 -17 -19 -9 -5 -14 -3 -1 -2 5 20 17 -4 3 13 8 14 2 5 15 12 20 21 15 19 13 5 -1 1 -17 -8 -11 -13 8 -2 1 -18 38 36 -9 -18 -2 -7 -3 3 -1 12 17 24 24 21 18 10 4 2 7 11 1 -4 -9 1 14 5 0 7 27 0 -13 -14 -1 -11 6 0 4 11 5 6 19 16 5 -5 2 5 1 9 -6 -2 13 7 -7 -20 11 10 -1 -9 -8 9 8 -3 -1 10 11 10 18 10 8 7 -3 5 9 7 3 -1 -6 -11 -19 -35 -10 12 13 3 8 -12 -17 16 18 4 3 17 10 9 8 -14 -12 -20 -2 1 8 11 10 -2 0 -11 -25 -4 -27 -10 6 18 11 -12 -4 9 16 6 17 14 7 2 -3 -11 -11 -7 4 6 15 20 21 8 2 -20 -33 -13 -9 -7 9 9 19 0 24 6 13 7 13 4 5 -9 -31 -26 -7 -1 3 7 12 19 20 15 8 -3 -39 -11 16 -21 -1 10 18 0 33 5 8 10 10 -4 -2 -12 -14 -7 4 0 12 12 9 10 14 10 -5 -24 -27 7 16 12 -14 1 6 13 20 2 16 11 5 -3 0 -4 -2 1 2 10 12 13 21 21 23 0 0 -28 -25 -4 28 -1 -1 -1 -10 16 10 3 13 8 11 3 3 -2 -7 1 -2 4 8 23 17 19 13 5 -3 -22 -6 -18 26 19 1 -7 -10 -6 6 11 18 13 17 9 4 6 8 1 -2 8 13 33 22 9 11 1 1 -25 -21 4 37 22 -1 -2 -14 -16 -9 7 11 12 20 11 11 12 11 6 3 18 15 23 15 -3 -1 0 -13 -31 -22 19 19 -21 -1 -1 -8 1 -3 3 10 13 5 -5 5 8 -6 12 12 16 19 18 13 10 1 -1 -12 -25 -20 9 22 17 0 3 -12 1 5 -5 -3 0 -3 -18 -14 -9 -8 0 9 12 6 6 3 7 -6 8 -12 -9 -15 16 18 -6 0 -18 3 7 1 7 -10 -13 -10 -15 -25 -19 -21 -3 -2 -4 7 -1 -6 -5 -6 -7 -9 3 8 19 -5 1 -2 3 8 -5 -3 5 -8 -22 -16 -6 -15 -11 -4 -8 -11 -11 1 -6 -16 -18 -12 -3 -9 5 30 -5 -19 -2 -1 -1 0 2 -12 -18 -19 -15 -10 -14 -2 -2 8 -6 -8 -15 -7 -17 -18 -14 -2 -5 6 2 17 13 -5 -2 -1 -2 -17 -6 -15 -24 -12 -11 -13 -10 -2 2 3 -11 -8 -16 -10 -11 -6 -2 -1 14 9 17 18 4 -14 1 -2 -2 9 -7 4 4 -10 3 2 0 -1 -1 -8 -15 -8 1 0 5 -2 -3 15 20 18 23 -1 17 6 -1 0 -1 1 12 21 25 3 2 -3 0 3 8 8 10 23 8 7 -1 3 -1 26 25 4 -9 -21 16 8 -1 0 0 -1 -2 20 26 16 17 22 33 34 20 29 43 55 37 46 22 19 26 27 36 23 -1 -2 -1 0 1 -1 0 -2 -2 -11 -13 -10 18 16 22 34 13 14 12 60 42 38 37 31 26 30 16 32 -2 -1 0 -1 -2 5 | -21 -2 -2 -1 0 1 0 -2 0 -1 0 -1 1 11 9 -13 -1 1 -1 1 -2 1 0 -1 -1 0 0 -1 -1 -1 0 0 0 0 -1 12 12 7 1 17 16 20 23 10 23 12 16 19 24 27 19 16 10 -1 0 -1 1 -2 0 -2 1 11 1 3 16 9 13 5 -7 15 9 25 1 -1 1 26 30 40 35 28 26 9 5 -1 -2 -1 1 0 8 12 8 14 19 9 5 -11 -19 7 23 15 15 9 11 6 8 13 27 17 30 40 11 13 -2 -2 -1 -12 8 2 3 -6 13 21 20 9 1 2 3 9 9 -3 4 3 8 7 17 17 37 18 7 -5 -1 -2 0 8 -14 1 -8 -7 1 5 1 2 -10 0 5 -3 -5 -3 2 2 20 17 5 1 18 15 9 36 17 0 -1 -13 -10 2 -26 -18 -10 -4 -4 -7 -2 4 -6 -12 -1 0 -3 -2 17 17 2 -6 -3 5 19 -18 2 0 -22 -3 -6 -19 -36 -17 5 0 3 2 0 6 -5 -6 4 -7 -11 2 -1 6 4 -3 5 2 10 -20 -20 1 7 -24 -16 -16 -9 3 16 6 3 8 -1 8 2 6 -3 -5 -14 -9 7 9 11 7 -1 2 -15 1 22 13 4 -20 -12 5 4 12 22 15 6 3 10 -3 1 12 -12 -28 -17 -14 -2 7 17 -1 1 6 34 13 31 12 0 -11 -30 30 13 16 29 23 16 12 12 -5 8 15 -18 -31 -29 -15 -1 7 21 9 12 4 1 32 12 6 4 9 -14 21 24 25 23 18 12 5 -5 -9 3 5 -25 -30 -28 -23 -6 6 21 25 30 7 1 10 11 4 6 0 2 22 25 10 14 2 -6 -13 -6 -17 -5 -10 -20 -21 -17 -13 -4 9 18 14 15 -2 -19 -27 -9 0 3 10 8 -2 15 -1 -16 -19 -15 -15 -22 -20 -8 -13 -7 -12 -15 -10 9 15 6 18 18 -16 -45 -32 -23 5 -11 9 -36 -28 -4 -17 -30 -24 -27 -14 -11 -12 -3 -6 -10 -23 -30 -8 13 -1 14 3 1 -26 -23 -36 -1 0 -14 -6 -36 -28 -36 -14 -15 -25 -24 -19 -17 -12 -4 -10 -21 -34 -33 -3 15 8 -5 -17 -29 -25 -19 -46 -20 0 -19 -33 -39 -22 -29 -12 -8 -14 -15 -15 -18 -24 -16 -16 -29 -22 -19 -6 1 -3 -24 -15 -27 -23 -23 -40 -21 -1 -4 -33 -30 -21 -13 3 5 3 9 0 -5 -7 -12 -20 -34 -16 -7 3 15 3 -10 -7 -9 6 -3 -25 8 1 -2 -24 -39 -13 -3 1 12 14 20 10 11 13 -7 -13 -13 -11 7 15 18 12 -6 4 -4 6 -4 4 2 1 17 -23 -59 -8 5 8 19 16 24 19 11 20 4 1 1 0 12 22 29 13 -5 6 0 7 -13 -15 3 0 1 -17 -43 -8 18 11 29 19 4 13 0 12 5 5 9 1 9 10 12 6 -1 6 8 3 -4 -14 -2 0 -10 -22 -24 5 2 16 25 5 -3 1 0 4 7 16 8 11 15 4 7 9 4 18 10 0 1 17 1 -1 -2 -22 -19 5 4 7 0 -3 5 1 5 13 12 11 10 12 5 9 0 2 17 1 18 5 6 0 -1 1 0 -24 -40 1 -11 -16 -23 -16 -1 -4 5 9 9 9 15 14 2 -4 4 13 -6 6 -2 10 1 -19 -1 -1 -2 -2 -32 -39 -15 -20 -32 -20 -21 -17 0 8 6 6 15 12 -10 1 13 -2 -17 -11 -17 17 -20 -9 1 -1 0 0 7 -29 -41 -29 -25 -21 -26 -14 0 -1 -1 -5 15 -3 5 -1 12 6 1 -5 29 29 -17 -11 -1 -1 -1 -1 1 -17 -23 -20 6 5 15 8 13 11 17 -2 -5 -14 -2 6 4 10 -16 18 9 -1 0 -1 -2 -1 0 -1 1 8 8 10 -2 11 9 31 14 12 30 11 7 -1 27 8 0 -18 -8 -19 -1 -1 0 0 1 6 | -53 0 0 0 0 0 0 -1 -1 -2 -2 -2 -1 17 16 -8 -2 0 -2 -1 -1 -1 0 -2 -2 -1 -2 -1 0 -2 0 1 -1 -1 -1 11 7 14 16 32 24 18 26 3 -14 17 6 -7 -17 -16 -11 -7 17 -2 0 0 0 0 -1 -1 0 -7 -2 -7 -1 23 17 24 29 35 33 37 26 24 49 22 -11 20 16 9 0 21 16 -2 0 -1 -1 0 3 14 5 12 13 23 46 45 36 17 22 25 19 31 28 23 12 1 15 -14 14 23 -17 7 1 -1 -1 -13 -1 -1 1 -5 8 7 24 23 22 15 6 15 13 18 8 3 4 12 4 9 -10 4 -3 -3 -1 -1 -2 -1 -18 -12 12 20 5 25 33 28 19 9 1 -3 3 11 4 10 8 7 11 10 -1 -10 4 -11 8 1 -2 -4 -18 -5 13 1 19 19 27 21 16 15 12 3 2 10 3 -2 6 -9 3 -9 -4 -15 -7 -28 -18 -1 25 15 -12 -16 -5 6 23 24 28 16 4 -6 2 4 9 -2 -1 1 10 0 -14 -13 -18 -13 -13 -24 -22 -2 20 23 -1 -30 5 13 11 26 32 16 15 0 -11 -8 0 -8 -12 -5 -8 -11 -21 -10 -11 -34 -28 -24 -4 17 19 34 9 -4 10 15 23 21 33 24 8 -1 -13 -16 -14 -16 -16 -14 -17 -8 -21 -16 -24 -61 -36 -10 7 15 14 27 7 8 14 24 18 28 22 16 -9 -9 -19 -19 -22 -10 -9 -8 -8 0 -12 -22 -43 -61 -61 -22 -1 12 19 6 -17 9 11 21 22 28 30 11 1 -9 -17 -15 -6 0 12 2 10 14 -2 -2 -38 -51 -41 -30 -6 9 12 -9 -3 6 11 18 7 19 9 2 -11 -21 -20 -25 -13 9 15 15 14 17 16 33 36 12 -23 -23 -21 -2 3 16 7 5 13 2 -3 -7 -12 -5 -9 -15 -21 -33 -17 6 4 15 -7 6 16 33 46 46 13 11 4 -10 -8 -2 -7 22 9 2 2 5 -12 -9 -7 -9 -19 -29 -17 -2 5 13 4 -8 11 32 31 20 15 11 0 -1 -7 -11 1 13 9 -7 -7 -3 2 -7 2 -14 -15 -20 -9 -5 -2 -1 3 -5 16 15 19 30 36 31 6 1 6 -1 9 -10 -6 -5 13 14 9 1 -8 -3 -19 -14 1 -4 3 0 11 6 18 16 13 27 42 26 -6 1 -7 9 6 -17 -6 -3 -6 8 -1 -6 10 3 -15 -21 -12 -3 2 0 21 12 15 10 9 26 17 14 -15 1 0 -11 18 -1 3 2 -10 -11 -7 9 -2 -10 -14 -19 -9 -4 -10 14 27 11 21 11 12 24 -8 -26 -16 0 21 3 47 18 2 -9 2 5 9 8 -2 -15 -26 -21 -5 -12 7 10 11 14 12 12 5 17 -1 -13 -9 -1 -19 -6 48 32 -1 -9 7 -3 11 -2 -10 -15 -11 -14 -8 -2 2 10 10 14 12 19 11 13 24 -15 0 -1 13 10 11 13 11 -2 1 3 -1 -3 2 -12 -9 -10 0 2 8 9 16 12 23 18 7 27 35 20 -2 0 0 0 -2 6 7 1 -3 -3 -7 -6 -6 -10 -11 -8 1 1 1 11 22 7 23 9 12 14 9 10 -1 1 -1 23 34 7 8 -5 1 -2 -14 -7 -12 -21 -6 -4 0 -1 5 13 13 16 13 7 5 12 2 -17 1 0 -1 -3 28 27 34 38 18 -1 -10 -8 -7 -13 -8 -7 -4 10 -4 -6 5 27 21 15 10 -10 10 5 -1 -2 0 -1 -1 29 34 59 33 17 16 19 11 9 3 11 12 0 -11 1 26 18 31 22 33 31 18 5 -2 0 1 -1 0 -12 -10 15 22 25 11 25 2 -15 3 -1 -11 -39 -31 16 33 20 17 13 16 -1 0 0 0 0 -1 1 1 8 13 13 -7 0 -3 -3 -12 -13 -4 -44 -25 -12 8 -11 14 4 14 -2 -1 0 1 -2 1 7 | 43 0 -1 -1 0 1 -1 0 0 -2 0 0 -2 -1 0 1 0 0 -1 -1 0 0 -1 1 -1 0 0 0 0 0 -1 -1 1 1 0 -12 -11 -5 -7 -23 -29 -26 -34 13 -18 -24 -25 -20 -27 -29 -22 -20 -12 -1 0 -2 -1 0 0 -2 0 -15 1 -9 -18 -25 -39 -31 -33 -41 -11 -47 -27 -14 -42 -21 -30 -41 -46 -33 -27 12 14 -1 -1 -1 -1 -1 -4 -22 -33 -28 -37 -58 -47 -68 -64 -63 -49 -50 -39 -19 -22 -17 -21 -9 -8 1 2 -2 30 -10 1 0 1 14 8 -23 -21 -1 -46 -42 -32 -16 -23 -12 -12 -5 -7 -3 -10 -16 -4 2 7 -1 12 3 23 28 0 0 -1 -4 -14 -17 16 13 -16 -9 -4 -12 17 13 19 2 4 -5 -9 -9 -11 -5 2 3 -14 10 26 10 -15 -2 -1 -6 20 19 13 10 4 1 4 2 19 16 6 10 10 9 10 8 16 17 13 -7 1 4 20 5 12 0 -23 18 37 2 -9 6 5 3 16 19 10 13 5 0 8 19 17 24 14 21 24 12 12 5 -1 2 0 0 22 10 16 7 11 22 21 17 5 12 7 4 5 9 10 11 10 21 11 1 7 4 24 10 9 16 13 12 18 0 11 15 14 24 12 9 10 4 9 10 11 14 5 -3 6 4 -2 -1 0 9 -1 4 27 34 19 15 10 17 -9 16 19 20 6 15 13 11 11 10 5 20 8 2 -5 -2 0 -8 8 11 3 12 12 16 7 11 22 22 -4 29 15 10 17 13 14 17 23 11 8 21 10 8 5 -3 4 2 1 10 15 25 14 8 6 11 16 24 23 41 13 4 11 12 6 3 -1 -11 -12 9 7 9 8 -2 0 5 16 15 14 14 9 4 16 0 8 28 19 17 -4 -1 2 1 -3 -9 -9 -18 -9 11 17 16 11 -5 -6 10 5 2 4 -9 -8 -10 -2 -15 -5 26 7 5 -6 -1 -16 -14 -15 -1 -1 -6 7 23 22 16 14 -5 11 -5 -4 4 8 -9 -14 -5 0 1 -16 9 7 -9 -30 -18 -13 -19 -7 -5 -7 -4 16 28 21 13 14 4 -9 -3 -4 6 4 -27 -50 -20 3 -2 -13 -13 -3 -28 -27 -19 -17 -14 -2 -4 -6 9 11 23 21 19 9 -3 -13 -14 -16 -4 -14 -26 -50 -20 15 0 6 -21 -15 -52 -27 -24 -23 -20 -3 -9 3 7 15 18 12 8 -6 -7 -12 -11 -9 -15 -9 -5 -17 1 -21 -2 -2 2 -25 -58 -26 -20 -17 -11 1 1 7 0 9 11 -3 -3 -5 -6 -14 -15 -19 -9 -25 -11 -4 19 13 0 16 -39 -48 -42 -34 -15 -8 -4 6 7 -7 -2 7 2 -4 -8 -9 -16 -2 -12 -22 -19 -13 0 0 2 -7 -1 -17 -18 -47 -43 -32 -15 -9 2 -11 2 -1 2 3 -4 5 -3 -4 -14 -10 -14 -17 -6 -6 1 8 5 -1 -1 -19 -17 -25 -18 -7 3 -2 3 6 9 -1 -1 -4 6 3 1 -1 -4 -6 -4 2 -25 -11 -9 -14 -24 0 -1 -1 -32 -24 4 6 11 3 8 11 9 0 6 4 18 10 0 1 -2 -16 -10 -4 -15 3 -10 1 8 0 0 -1 -23 -44 1 1 2 5 2 3 1 -1 9 10 9 8 10 -3 -8 -2 -20 -8 -9 6 3 -2 12 1 -1 -1 8 -24 5 26 6 8 13 0 3 9 6 0 -6 11 -12 -18 -5 13 7 -12 -21 -14 -27 1 -9 1 -2 -1 0 18 20 6 -2 -1 -1 -4 -1 10 4 8 18 13 6 8 11 7 7 4 -11 -12 -18 -8 -8 -1 -1 0 1 -1 -1 -8 -3 13 17 23 12 11 10 32 29 17 14 9 24 25 29 22 24 11 1 0 0 0 -1 0 -1 -1 13 20 17 22 24 18 36 4 3 22 38 18 13 51 25 19 13 -6 14 -2 -1 0 -1 -2 8 | -4 -1 -1 0 0 0 0 -1 -1 1 1 -1 -1 -14 -18 -8 1 0 1 1 -1 0 -2 -1 -1 -2 0 0 -1 -2 -1 -1 0 1 0 -6 -8 -11 -7 11 16 11 13 -13 2 -17 -16 6 4 -6 -6 2 -8 0 -1 0 -2 -1 -1 -1 0 8 -1 0 2 -10 -18 -16 -17 -3 7 -18 11 32 21 16 27 12 0 -3 -7 -8 -9 -2 0 0 0 2 -8 10 3 14 14 -16 -22 4 -15 -14 -5 11 22 27 36 28 20 9 13 7 -15 -12 -14 0 -1 -1 0 -9 -7 5 7 -10 -15 -24 -24 -16 -29 -20 -17 -2 3 12 25 10 10 7 9 10 4 14 -5 -16 -1 0 0 3 -7 -20 9 -1 -15 -24 -20 -20 -16 -10 -17 -17 -4 -12 -8 1 0 9 16 3 12 -4 -40 -14 12 1 -1 11 -17 -15 -17 -23 -20 -28 -29 -28 -14 -16 -15 -28 -29 -27 -12 -15 0 1 1 10 10 13 -4 2 1 -1 -24 -35 -33 -27 -19 -21 -19 -23 -19 -20 -25 -24 -33 -31 -36 -35 -26 -18 -4 -2 -8 0 21 25 34 2 3 0 -26 -19 -6 -38 -12 -1 -10 -20 -15 -20 -22 -28 -31 -45 -34 -33 -23 -17 -12 -7 -3 -11 5 25 24 -15 -10 -14 -20 -16 -2 -16 -20 2 -13 -13 -27 -13 -10 -20 -23 -24 -18 -17 -24 -13 -8 -2 6 -5 1 32 -7 -27 -17 -12 -9 -31 -8 3 -9 -9 0 -5 3 8 9 21 -2 1 11 -4 -11 -14 -5 -4 2 11 3 11 -11 3 -4 -5 -1 13 5 9 9 -1 8 11 14 28 18 31 34 35 31 11 -3 -5 -8 -5 6 5 18 16 7 4 -1 -3 5 6 13 17 28 17 25 24 26 37 42 35 45 27 8 1 -4 -5 -3 0 -7 12 32 22 0 19 -6 -1 3 -14 15 32 29 20 26 20 14 22 27 32 17 2 9 2 -1 0 8 5 -4 11 31 23 11 16 4 -2 0 -19 1 8 18 13 14 21 15 11 9 8 1 -7 -7 7 -4 -2 -1 8 9 18 19 4 -3 -19 -2 1 -2 -19 -1 -12 4 6 4 11 12 4 3 5 -12 -5 -9 4 -1 2 5 15 4 2 9 -20 -1 1 -21 -1 0 -14 2 15 2 3 3 6 7 1 -5 -10 -16 -5 2 -1 -1 14 13 11 -2 -7 -8 -21 -23 -1 -23 -2 4 -13 -2 -2 5 7 15 10 -4 -3 -9 -12 -8 -2 5 4 2 16 8 15 14 2 2 -23 -42 -16 -12 -2 0 5 -19 -1 5 8 11 14 -2 -6 -12 -12 -6 6 2 2 -1 5 5 14 19 -2 -7 -9 -28 -34 -25 1 0 20 -28 -6 4 10 7 0 -6 -15 -16 -9 -5 -3 -4 -2 -6 8 1 -4 1 1 -13 -7 -29 -28 -13 0 -8 -15 -36 -14 -2 -6 -9 -4 -10 -14 -8 -13 -16 -12 -15 2 3 6 -9 -12 -12 -9 -28 -13 -12 2 -1 -1 -6 -20 -29 -5 13 10 3 3 -6 -8 -14 -18 -23 -23 -12 -11 -11 -15 -19 -10 -6 -25 -29 -28 -19 -26 -1 -1 0 -16 -7 10 -15 -18 -6 0 -2 -5 -16 -14 -14 -16 -15 -14 -4 -13 -12 -5 -10 -22 -13 -36 -19 4 -1 0 0 -18 8 6 -3 -12 -13 -9 -13 -9 -20 -16 -18 -11 -14 -11 -7 -8 -10 -12 -18 -21 -23 -25 -13 -3 0 1 -1 -12 12 -15 -23 -6 5 -8 -10 -3 -5 -22 -18 -21 -12 -13 -13 -8 -3 -6 -26 -4 5 -34 -4 -11 -1 1 -1 0 -14 -29 11 4 -6 -21 -20 -1 -13 -9 -3 -11 -20 -7 -20 3 16 7 -4 -1 -10 3 7 -9 0 -1 0 -2 0 16 20 17 -18 -26 -15 -12 -11 -7 -8 -22 -22 -12 -3 -17 -9 10 0 24 -12 0 -1 0 0 -1 1 1 0 -13 -17 -23 -38 -33 -7 -32 -1 -2 -36 -15 -20 -4 -46 -11 -14 20 11 27 0 0 -1 0 -1 9 | 16 -1 1 0 0 1 -1 0 -1 0 0 -1 -1 11 11 4 0 -1 0 -1 0 -1 -1 0 -1 -2 -1 -1 0 0 1 -1 -1 -1 -1 16 15 9 2 30 -2 -2 -9 -13 -8 -19 -7 21 27 27 22 15 10 -1 0 -1 -1 1 -1 0 -2 15 0 12 22 16 11 13 8 13 19 19 38 35 32 23 40 46 40 38 31 -11 -15 -2 1 1 0 -1 10 18 -10 12 4 -5 2 -7 -11 -3 -6 -15 -10 -4 -6 0 26 -2 8 12 -3 -6 -22 9 -1 0 -2 15 10 -13 -9 -4 -2 -18 -21 -25 -17 -26 -13 -15 -12 -12 -2 3 15 8 16 7 17 -7 -13 -22 0 0 -1 4 -17 -16 -1 0 -12 -6 -5 -6 -29 -22 -28 -20 -17 -14 -6 -3 -5 2 9 17 38 16 -35 -16 6 0 -2 -9 2 8 4 -6 3 -1 -14 -2 -13 -10 -22 -22 -20 -18 -18 -8 -8 -8 -1 -1 3 10 -20 8 19 -1 -24 17 18 -10 -18 -8 9 0 -6 -7 2 -11 -21 -18 -31 -22 -10 -11 -5 -2 -4 -1 -11 -16 -7 17 6 -1 18 1 -13 -13 -2 -5 1 -5 0 -3 -5 -11 -16 -18 -27 -30 -11 -19 -11 -5 -8 -18 -12 -25 -10 0 -18 13 13 -1 -24 4 -2 -13 12 -3 1 -5 10 4 -7 -11 -16 -15 -16 -16 -24 -20 -7 -12 -16 -12 -17 -19 12 13 6 27 -20 0 -2 -9 1 6 3 1 7 -5 0 -13 0 2 1 -18 -15 -16 -10 -14 -25 -1 10 -4 -10 10 19 22 -14 7 -2 -3 -1 -14 -2 -2 -4 -3 -16 -22 -9 -2 -12 -13 -17 -27 -8 -12 -11 -10 -13 -13 -7 6 19 7 -2 -11 -15 -11 -7 3 -3 3 -2 -6 -25 -24 -9 -4 -17 -11 -25 -21 -18 -19 -19 -23 -6 -2 15 -1 7 27 -11 -8 -1 -2 -4 -3 -4 0 -1 -11 -32 -20 -13 -6 -3 -14 -21 -11 -1 -13 -7 2 1 -7 -7 15 -14 25 7 12 12 2 6 2 1 -5 -9 -20 -31 -17 -10 0 -15 -18 -5 -5 0 6 8 4 -14 -9 -1 0 -17 -16 4 6 5 4 2 -8 -6 -3 -10 -15 -17 -18 -5 3 -4 -3 -6 -3 8 -4 0 9 0 -6 16 1 -22 -34 1 -12 -1 -5 -6 -13 -11 -13 -11 -18 -15 -8 3 0 -11 0 9 4 14 -3 -11 5 2 6 5 -1 1 -8 1 -17 -8 0 -16 -10 -17 1 -11 -10 3 4 3 -12 -7 13 -1 7 -4 -2 -17 8 25 19 -21 -1 -2 -24 5 1 -10 -23 -2 -2 -1 -2 -2 8 9 1 -7 -6 -2 4 4 4 4 -8 -4 9 23 19 -12 -1 18 -29 -4 3 -18 -13 -3 1 3 3 19 5 6 2 -4 2 -10 -4 -8 -7 -9 -9 -13 1 35 10 -14 1 -21 9 1 0 -9 -10 -13 -6 5 5 14 13 -4 3 0 3 3 0 -5 -16 -10 -3 6 10 23 17 -2 -1 -15 6 -10 -2 7 -16 -23 2 -4 11 3 7 1 7 -1 4 -6 4 0 4 3 -1 14 38 17 11 0 0 -1 -2 -15 -3 22 -6 -9 1 -3 -6 -17 -14 -8 -11 -7 -5 -1 4 12 1 -3 -8 -6 18 1 1 0 0 1 -20 -23 -6 10 6 -20 -24 -14 -13 -17 -16 -25 -9 -8 -7 -1 -7 -7 -11 -6 -9 -24 7 15 15 1 -1 -1 5 -22 -12 11 -6 -13 -12 -12 -28 -27 -34 -31 -13 -18 -23 -1 2 0 -5 12 -1 -7 33 15 9 1 -2 -1 -1 19 17 4 -10 -20 -21 -15 -30 -28 -20 -15 -22 -15 -15 -19 -8 -20 -16 9 28 9 15 -5 8 0 0 -2 -1 -1 -19 -19 -16 -21 -22 -22 -21 -23 -23 -24 -34 -10 -20 -34 -33 -14 -18 -22 3 16 0 -2 -1 -1 0 1 0 -1 12 17 26 -8 -7 -2 7 -18 -13 21 -26 -16 -5 12 0 -5 -10 -16 2 0 0 -1 0 0 10 | -9 0 1 -1 -2 -2 -1 1 0 -2 1 0 0 -10 -10 -9 1 -1 0 0 -1 -2 -2 0 -2 -1 0 -1 -1 -1 0 0 1 -2 1 -14 -13 -12 -11 -23 -29 -31 -38 11 -32 -37 -35 -20 -26 -28 -20 -17 -13 1 0 -1 1 0 -1 -1 -1 -11 -1 -7 -25 -34 -25 -24 -26 -29 2 -15 -13 -14 -29 -46 -18 -38 -31 -30 -29 8 11 0 0 -1 -1 0 -17 6 10 -11 -3 -9 -11 2 -17 -18 -35 -19 -24 -16 -26 -40 -18 -13 -24 -25 -23 -12 10 -7 0 0 1 15 10 3 12 31 16 18 9 -3 -10 -11 -3 -19 -29 -14 -23 -30 -16 -9 -11 6 3 4 4 -2 -2 1 0 -4 19 16 41 39 17 8 4 -18 -22 -16 -19 -19 -17 -10 -17 -15 -12 -6 1 11 9 1 -7 -27 -13 -2 0 -8 38 47 40 43 6 10 9 -3 -15 -14 -13 -23 -20 -19 -15 -3 4 5 16 13 13 2 -17 14 0 -1 23 0 38 27 26 23 18 5 0 -8 -12 -15 -9 -18 -18 -8 8 6 21 19 20 16 25 13 -4 18 -9 1 20 14 19 41 27 2 12 4 -7 -13 -12 -14 -9 -2 5 2 13 26 19 27 22 20 27 10 16 8 8 13 15 24 -1 34 16 2 -5 -4 -6 -19 -21 -13 3 13 25 14 14 12 18 17 21 22 6 -17 -10 17 17 13 10 27 2 14 5 -6 -1 -7 -12 -23 -16 -3 17 19 18 11 6 0 2 1 9 17 0 -22 -8 -6 1 11 19 23 23 16 2 -15 -9 -9 -9 -2 1 7 -1 -4 7 1 -9 -16 -11 -2 1 4 -30 -47 -28 -22 -1 8 14 7 6 8 1 -12 -6 1 -5 -1 -3 10 -4 -2 1 -4 -22 -14 -12 1 1 10 -22 -26 -17 0 18 -1 5 27 -5 1 4 -4 -10 0 -3 -10 -1 3 -9 -4 -5 0 -5 0 -9 -4 1 0 -2 -12 3 19 -15 -18 15 22 -2 10 6 -8 -14 0 2 -4 -6 -6 -7 -5 -9 -12 4 -5 16 -8 2 7 8 0 -9 3 1 -2 17 33 11 9 -6 -5 -9 0 -1 -1 -1 -11 -18 -6 -3 -5 0 0 6 3 1 23 13 -9 -22 23 9 1 15 38 11 15 10 9 7 6 7 -1 -21 -16 -7 -7 2 -6 1 4 4 12 10 12 11 0 -8 13 20 0 7 23 -7 22 4 -3 13 0 0 -15 -28 -23 -14 -2 3 -2 -7 0 1 6 11 15 20 1 -24 16 -23 0 1 32 11 -3 6 -10 -6 0 -4 -28 -24 -23 -3 6 -2 1 -5 -1 3 9 13 10 9 -3 -12 14 2 0 20 24 25 5 11 3 0 1 -3 -22 -22 -26 -11 -1 -6 -12 -9 -11 -6 0 7 -4 3 -10 -15 -2 -8 0 -16 -3 6 -10 -19 13 2 -2 -9 -16 -13 -23 -20 -12 -14 -8 -6 -12 -7 6 -1 -16 0 -14 -32 6 -2 1 6 -4 2 -6 6 12 1 6 -17 -12 -16 -21 -22 -24 -15 -16 -17 -8 2 0 -8 -28 -16 -28 -35 -22 -1 -1 -2 -1 -14 -9 8 20 17 8 -2 -8 -15 -20 -22 -15 -20 -16 -12 -8 2 -4 -9 -11 -28 -23 -24 -10 0 0 0 -1 1 -6 -5 23 29 10 11 3 -3 -7 -6 -12 -10 -18 -10 -2 -14 -18 -13 -36 -33 -18 -7 14 0 1 -2 11 15 22 20 35 23 20 20 19 13 4 -5 -3 -12 -20 -11 -26 -10 -22 -15 -33 -25 -30 -6 8 -1 -1 -1 1 -3 17 18 13 5 18 27 20 20 10 -5 -7 -20 -18 -26 -16 -15 -19 -23 -28 -48 -37 -14 6 1 -1 -1 1 -1 -7 -19 -23 -15 -3 -10 -16 -22 -27 -25 -27 -15 -12 -28 -23 -24 -40 -21 -11 -12 1 0 -2 -1 0 -1 -1 0 4 5 -1 12 15 -2 9 -10 -10 6 -25 -12 -9 14 3 -6 -5 -6 -3 -1 0 -1 0 0 11 | 37 1 -1 -1 0 0 0 0 0 -1 0 0 0 -4 -4 -3 -2 -1 1 -1 -1 -2 1 -1 -1 0 0 -2 0 -2 -2 1 -2 0 -1 -15 -15 -6 -5 -12 -19 -18 -28 13 -18 -23 -22 -8 -21 -22 -15 -18 -11 -1 -1 -2 0 0 -1 0 1 -6 -1 0 -18 -5 -2 -26 -15 -16 10 16 -2 -12 -8 -9 1 13 15 -3 -16 -7 -10 -2 0 0 -1 0 8 14 -11 0 -2 -20 -21 -1 1 -9 -17 -9 -10 -7 -9 -16 -13 -12 16 25 14 -1 -12 3 1 0 0 -10 -9 -5 -2 1 6 -21 -4 3 19 13 16 5 -6 -1 5 4 11 12 24 17 31 29 8 -9 1 -1 0 5 -13 -3 -3 -6 0 -4 -6 4 7 8 -5 1 1 10 17 13 15 13 8 9 11 30 28 -13 4 -2 0 -17 -23 -10 3 -14 -7 -9 -3 -5 -7 -6 -15 -20 -8 -14 0 -7 7 -3 -8 1 17 18 11 27 10 -2 -24 -4 -19 -5 3 -5 -13 -8 -10 -5 -2 -15 -12 -22 -10 -5 6 -2 1 -1 3 16 15 12 12 23 -1 1 -17 -13 -16 -12 9 -2 -6 -7 8 0 1 -9 -11 -17 -5 -8 4 1 -5 -4 1 -10 4 22 43 15 17 -12 -16 -22 -11 -31 -1 0 -6 -6 6 3 0 -9 -17 -27 -10 7 6 3 0 4 0 -11 -3 9 1 14 -23 -12 -8 -23 -14 -9 3 -4 3 8 15 7 3 -6 -25 -37 -8 -1 11 0 -2 -6 -2 -15 -7 -2 -7 -23 -11 -9 -13 -22 -21 -1 15 12 13 9 23 20 12 10 -25 -25 -11 7 2 -1 2 -9 -6 -14 -4 -15 -7 -6 1 -8 -12 -11 -6 -3 12 8 17 19 18 24 22 17 7 -21 -14 6 4 0 9 5 8 -4 -11 -14 -9 1 2 1 -5 -18 -7 8 13 17 19 22 20 25 29 27 0 -16 5 11 14 15 4 15 13 9 2 0 16 19 5 19 -17 -13 10 19 18 23 16 24 24 25 28 20 3 0 2 16 22 9 12 11 7 5 -6 4 15 -9 0 0 -15 -33 26 17 5 15 22 23 25 23 20 14 13 1 7 23 21 8 7 -7 1 4 -2 -8 19 23 27 0 -21 -1 21 3 2 17 15 17 10 7 9 15 5 5 18 25 18 11 0 3 0 -3 1 -4 25 9 5 0 -1 17 10 16 8 11 11 11 10 6 2 -3 2 6 19 20 13 8 -7 -5 -8 -6 -12 -5 10 12 -2 -1 -1 3 21 15 11 5 15 6 7 -8 -3 8 13 13 2 11 0 5 -4 -3 -2 -19 -5 13 -25 -6 1 0 -22 4 7 10 6 9 6 -4 -8 -18 -8 -11 -1 4 1 6 4 8 -5 -3 3 -9 5 -12 -13 7 -8 -1 -10 12 8 3 0 1 0 -9 -3 -7 -13 -16 -9 -6 0 6 11 15 -4 3 4 6 -7 -1 -15 12 1 -1 -3 4 -17 2 11 -5 -11 -4 9 -7 -8 -10 -4 -4 4 -6 8 3 2 0 12 6 11 10 -8 -16 1 1 1 -3 4 10 2 -2 2 0 -1 -4 -2 -2 -2 -4 -3 -4 0 4 14 9 26 0 5 7 -16 -15 1 0 -1 0 -7 -3 -9 -19 -16 -1 1 -1 1 8 3 7 3 9 6 12 15 20 38 13 8 -11 14 -7 0 1 1 -9 -23 -21 -14 -30 -15 -6 4 -7 12 -4 0 9 5 3 -2 10 5 12 4 17 4 -9 10 5 0 0 1 -1 0 0 -21 -16 -14 -16 -12 -3 -4 -14 -2 -6 3 1 -9 -9 -27 -10 -3 -5 -15 -23 7 2 -2 0 1 -1 -1 2 7 -7 -32 -21 -48 -39 -30 1 -28 -32 -23 -33 -16 -35 -50 -38 -27 -34 5 -2 0 1 -1 -1 -1 1 0 -10 -15 -9 -17 -22 -17 -38 -8 -5 -19 -39 -23 -15 -36 -32 -7 -3 9 -21 0 -2 -2 0 -1 12 | 23 -1 0 -1 -1 1 0 1 0 0 -1 0 -1 19 14 -13 -1 -1 1 -2 -2 0 1 0 -1 1 -1 0 -1 -2 -2 0 0 0 0 3 0 -3 1 25 18 16 26 11 -7 -17 -10 23 30 31 9 1 2 0 1 0 -2 -1 -2 -1 0 15 0 8 12 39 25 7 17 31 9 50 16 -1 21 20 -1 15 21 28 21 -11 -15 1 0 -1 -1 -2 12 20 6 23 23 13 19 29 31 16 13 17 20 20 13 11 -8 -12 17 14 30 16 -28 9 1 1 0 -17 -2 17 4 -10 17 18 22 22 21 18 10 11 1 8 9 4 1 3 11 3 17 18 1 -9 -2 1 -1 10 -20 16 -19 -13 25 30 13 2 -6 5 -6 5 0 9 4 -2 3 1 0 -2 17 23 30 3 17 0 -1 -15 -17 10 -3 5 15 16 12 -5 -8 1 -5 -10 -3 -19 -19 -32 -7 -9 -7 2 14 20 24 8 -18 -1 -12 16 -5 18 14 2 10 15 8 -1 -1 -5 0 -13 -11 -27 -18 -12 -10 -10 -3 11 15 19 11 13 -17 0 2 2 7 23 15 4 11 4 15 1 5 5 0 -18 -17 -22 -10 -5 -4 3 0 -1 11 7 24 13 18 -1 -3 -9 9 -2 -2 0 4 6 7 -4 -1 -5 -14 -24 -26 -16 -8 -3 6 12 15 5 4 1 13 18 -22 -1 -5 -10 -1 4 1 -5 9 11 10 4 5 -1 -4 -22 -4 -9 2 3 5 9 13 2 7 8 -21 -17 4 -2 -6 -11 -3 5 4 3 19 3 19 12 10 15 -9 -8 1 3 -2 -3 5 -5 7 6 14 14 -7 -20 8 -2 -4 -12 3 -15 4 -1 13 10 11 11 14 15 11 -6 5 9 0 -3 -3 -3 4 4 6 23 6 -28 -10 1 -2 2 -1 -20 11 13 6 8 14 15 14 9 7 2 21 12 -2 4 5 12 2 10 20 17 8 3 -10 14 -13 1 -2 -9 14 9 7 10 11 7 11 8 14 15 19 11 6 5 13 -2 4 8 11 5 19 -23 0 0 -14 -23 14 -10 0 6 14 10 9 0 10 20 22 24 21 10 12 6 10 0 1 12 4 -15 27 -1 -11 0 -17 -2 13 -11 -10 5 12 9 2 -3 8 26 27 25 25 17 12 10 10 4 8 6 13 2 23 -6 -14 0 -3 16 3 5 2 3 7 4 -3 -7 12 21 28 22 13 16 15 14 10 7 6 11 6 9 15 -3 -8 -1 -2 0 11 3 -7 -1 13 -2 -2 -6 11 36 30 15 6 9 5 2 -4 -2 4 -10 5 14 -15 -1 -2 -2 -17 1 0 -2 4 -8 2 -7 -1 2 23 20 16 14 9 0 6 -6 -12 -3 -6 -4 7 -17 -18 -2 5 -2 -13 6 10 -7 -11 -15 4 -9 4 17 11 14 15 13 11 0 -1 -4 -10 0 -2 -2 -13 -11 -25 -13 0 -1 0 1 -5 -19 -26 -25 -11 -6 9 6 18 17 21 19 20 -2 5 -15 -6 -13 -11 6 7 -20 -23 20 1 -1 -2 -8 1 -8 -24 -18 -11 -14 -1 1 14 10 10 3 6 0 -1 -16 2 -7 5 -11 -2 -22 -23 -20 0 0 -1 -3 -7 8 -19 -22 -15 0 -2 -2 5 6 3 6 3 6 -4 3 9 5 6 -4 -10 -25 -6 -17 -1 -2 -2 -8 -19 -30 -18 -16 -26 -14 -6 -8 14 8 14 20 7 15 -9 -2 -5 -8 -14 4 -17 -16 -14 -1 0 -2 0 -2 6 -23 -34 -14 -22 -26 -20 7 4 -9 -3 -10 1 6 -4 -15 -24 -23 -18 -10 -13 -10 -12 -2 0 -1 -1 0 0 -21 -7 -21 -39 -37 -63 -55 -45 -31 -56 -62 -56 -61 -31 -37 -56 -53 -46 -26 7 1 -1 -1 1 0 0 -2 -1 11 16 15 -18 -20 -24 -39 -34 -33 -24 -53 -32 -31 -26 -35 -17 -22 -15 -25 -1 1 -1 0 0 13 | 21 -1 -1 -2 -2 0 1 -2 1 -2 -2 0 -2 -2 -3 13 -1 0 -1 1 1 1 -1 0 -2 -1 -1 1 -1 0 -1 0 0 0 -2 -7 -9 -8 0 -13 9 8 6 -24 -22 -6 2 -10 3 1 3 5 -5 -1 -1 -1 0 -1 -2 0 0 -8 1 -2 -6 -13 -12 -8 -3 -11 -7 -10 -6 6 18 22 19 7 0 6 -8 -3 -2 1 -1 -2 -1 0 -4 7 14 13 15 13 1 6 2 -1 -20 -4 3 -17 -10 8 2 -1 -3 -14 -19 1 -5 -4 1 0 0 5 -8 21 2 1 7 -2 -17 -11 -4 2 -1 -4 6 -2 3 8 -4 -15 0 10 7 17 11 10 -1 0 1 -6 18 24 12 12 -3 -13 0 5 6 14 10 5 3 4 10 5 3 8 -1 13 3 15 27 17 7 -2 -2 15 -1 17 6 1 3 -3 -1 9 14 14 16 16 13 16 15 18 12 16 9 4 2 26 36 1 10 -1 25 -18 -20 -2 9 -6 3 2 3 8 9 6 7 19 17 21 24 19 21 21 11 -1 -7 7 43 17 12 0 -1 1 -1 -14 -3 -4 -2 2 6 7 5 4 8 15 18 21 14 15 6 6 0 13 -11 -4 16 30 8 -3 -2 10 -9 -2 -12 0 1 5 2 4 0 -1 -4 3 1 -13 -12 -8 -11 -10 1 2 8 -3 15 -18 2 -3 -3 -9 16 -4 -4 2 7 11 1 3 -4 -3 -15 -12 -23 -26 -24 -24 -27 -14 -19 -15 -15 -21 3 13 14 -7 -14 -22 13 5 10 2 -3 -2 3 -5 -2 -6 1 -4 -13 -17 -15 -15 -32 -25 -22 -20 -15 -25 3 26 4 -3 -9 -13 -27 9 16 7 -10 0 1 11 13 4 11 17 6 -3 -8 1 -10 -1 -4 -3 15 -22 -9 5 -12 1 -5 -20 -28 9 5 2 2 -1 2 15 12 19 25 22 7 6 4 7 2 7 6 -6 4 11 -25 -1 10 17 10 -22 -8 -3 -17 -1 -1 12 15 11 9 16 19 24 11 8 3 2 -11 0 -5 -1 0 21 -26 -36 0 -1 11 1 -6 -30 -24 -19 -17 1 5 18 27 26 21 11 4 13 9 9 0 3 2 8 17 17 -17 -12 -10 -1 15 11 0 -13 -25 -28 -36 -27 -10 2 18 21 15 7 4 6 7 14 10 -1 7 10 15 28 -42 -15 -10 0 1 -5 10 -5 -33 -29 -28 -38 -41 -24 -10 1 0 -4 2 4 8 15 1 0 8 2 16 -4 -30 -11 -17 -1 1 16 33 18 -17 -12 -30 -40 -58 -49 -48 -45 -35 -21 -3 8 11 9 5 11 14 7 6 -15 -19 -16 -2 1 -14 18 41 13 2 -9 -24 -29 -36 -44 -45 -39 -28 -19 -11 3 6 14 7 7 9 5 3 11 -2 -18 -12 -1 18 -4 31 21 2 0 -12 2 -9 -13 -9 -21 -11 -5 2 10 14 18 10 12 3 -1 -3 7 3 -12 0 0 5 -6 -1 23 7 8 16 14 3 -1 1 4 1 1 6 1 0 6 2 11 -2 -5 -17 -6 15 4 -2 -1 0 -9 -3 15 10 0 15 13 2 16 17 13 8 9 9 5 6 0 8 6 -11 1 -2 -6 -9 5 1 -1 0 15 23 22 31 25 15 16 18 33 28 17 25 18 12 1 -2 -8 -18 7 -22 -21 -13 -14 -12 0 -2 0 -2 3 29 39 32 39 36 21 24 38 23 23 22 14 1 -1 3 -13 -17 -17 -1 -16 2 -6 -8 -7 -1 1 0 0 16 22 39 41 44 49 42 37 25 33 24 13 12 8 3 3 18 17 25 32 28 29 11 -7 -2 1 -1 -1 0 24 20 26 15 6 26 33 29 23 20 24 19 20 13 16 30 42 39 29 -16 0 0 -1 1 0 0 0 0 8 -1 -7 3 -2 3 14 12 8 -7 30 17 4 -6 -22 -12 -1 -4 13 0 -1 0 -1 -1 14 | 27 0 0 0 0 0 0 -1 0 -1 0 0 -1 14 12 -8 -1 -1 1 0 0 -2 0 -1 -1 0 1 0 -1 -1 0 1 -1 0 0 -5 -6 -5 -1 17 17 17 25 3 -4 -23 -18 18 25 25 3 -12 -3 0 0 1 -2 0 -1 -2 0 9 1 2 3 -7 -4 -14 -6 14 8 -8 -8 -6 -5 0 12 25 28 16 5 -6 -10 0 -2 -1 -1 0 8 3 14 11 7 -15 -18 0 -12 -13 -18 -10 -13 -11 -1 -4 1 -5 12 9 21 10 -23 11 -1 -1 1 9 20 17 27 -2 -3 -10 -9 -5 -18 -6 -2 -4 -17 5 -2 -8 8 -1 1 14 11 -4 -16 -15 0 0 -1 7 11 -3 28 7 1 -5 -1 -7 -8 -1 -4 -5 7 -4 -8 6 7 -7 5 -2 18 10 -4 -21 13 -2 0 23 4 21 16 18 11 11 3 -1 5 2 3 -2 9 12 13 -5 2 -5 -2 -5 -3 -7 -6 4 -23 -1 -23 3 5 5 -5 -3 1 -3 11 6 3 7 8 10 17 12 13 4 1 2 -4 0 -2 -8 -19 0 -22 -1 -2 5 14 8 0 -5 5 12 16 7 3 5 8 8 17 3 5 7 -5 -10 1 -13 -30 -15 -3 -8 -17 -10 -5 -1 -8 -4 -14 0 2 3 5 3 -3 -4 -1 6 12 3 7 4 1 -3 -7 -18 -35 -37 -39 0 -5 -11 -4 -1 -15 -7 -18 -17 -8 -3 0 -9 -8 3 4 2 7 8 5 8 -1 -12 -11 -4 -37 -39 -41 -27 -6 13 12 -1 4 -5 -8 -12 -4 2 -9 10 4 19 11 18 25 24 20 8 0 9 2 -10 -32 -56 -53 -33 -10 8 8 13 1 9 -17 -5 4 -1 2 5 20 21 27 26 23 30 20 11 0 5 8 7 4 -27 -41 -31 23 1 -1 2 -4 11 -10 -9 -1 1 3 14 19 22 20 25 34 32 17 15 -1 -4 -2 -3 -17 -32 -36 -16 -18 -18 14 -4 6 -15 -10 -25 -21 0 4 10 17 20 24 24 27 32 21 6 5 -4 -4 -6 -23 -25 -17 -42 -2 -2 13 -1 6 -24 -40 -41 -24 -6 -4 10 24 17 17 25 19 20 18 5 7 -2 7 -3 -8 -37 -24 -16 -24 -1 14 9 -12 -24 -34 -25 -20 -2 -2 4 11 13 11 16 21 20 7 3 -4 2 -16 -20 -10 -20 -35 -29 -18 -1 9 2 -23 -23 -22 -34 -6 -9 -6 6 8 8 10 9 9 12 -3 3 -6 -5 -10 -18 -17 -33 -41 -12 -11 1 0 14 -8 -31 -26 -33 -23 -19 -4 -6 7 12 9 7 -2 7 -2 0 -7 -10 -12 -32 -36 -35 -28 17 3 -1 -20 12 7 -11 -12 -23 -21 -18 -13 -11 -5 2 -11 4 2 -1 -4 -5 -3 -13 -11 -26 -35 -38 -25 -13 3 0 8 6 2 -5 -20 -15 -23 -21 -18 -10 -10 -10 -9 9 1 8 -1 -4 -9 -15 -13 -25 -33 -20 -19 4 -1 0 12 -1 3 -6 12 -3 -15 -3 -7 -2 -3 1 4 -3 10 3 -3 -6 -11 -18 -13 -25 -20 -23 -22 -23 1 0 -1 -2 -4 7 -5 1 -7 -9 -3 6 1 4 8 10 6 3 3 0 -3 -7 -2 -5 0 -26 -26 13 -2 0 -1 -11 -16 -13 -7 1 9 -8 -7 1 -1 11 13 14 9 7 4 11 1 -16 -2 -12 -15 -22 -12 15 -2 -1 0 11 3 16 23 4 8 1 -5 9 11 6 1 -5 19 4 -1 -1 5 2 -17 -17 0 -34 3 -9 -1 0 -2 -1 13 15 26 1 2 2 14 14 3 1 3 10 -15 -9 -6 12 -3 -1 -2 -7 -16 -21 4 -9 -2 -2 1 0 0 19 32 20 12 15 5 3 -8 5 5 20 0 5 13 6 -7 -3 4 -17 -1 -1 1 -1 0 -1 -2 1 0 -10 -11 -12 14 -1 -4 -22 -4 0 -8 22 16 15 1 6 8 -3 -7 9 -2 -1 -1 -2 0 15 | 11 -1 0 -1 1 -2 -2 -1 1 -1 -2 -1 -1 -11 -17 -16 -1 0 1 -1 0 -1 1 1 0 -1 0 -1 -2 -1 -2 0 -1 -1 -2 -7 -9 -9 -2 -16 -20 -22 -22 10 -1 -13 -12 6 3 -5 1 -10 -2 0 -1 0 -2 -1 -2 1 1 4 0 -11 -20 1 -5 3 -21 -27 -39 -18 -20 -18 -8 -7 6 -11 -6 2 -1 1 1 -1 0 -1 0 1 12 14 4 2 1 1 -12 -6 -23 -19 -24 -25 -31 -31 -24 -7 15 21 8 13 -5 -15 18 -6 -2 -1 -2 2 -4 17 7 -2 -10 -18 -29 -33 -28 -22 -29 -33 -34 -35 -29 -22 -4 -5 11 -4 29 30 25 13 -2 -1 -2 4 -2 17 22 2 -6 -3 -2 -3 -1 -9 -18 -16 -22 -32 -26 -20 -16 -14 -9 -17 5 37 28 20 -2 -1 -2 -7 25 23 -7 8 15 18 11 2 1 -2 -1 -13 -18 -22 -27 -29 -16 -8 -14 -19 -10 23 21 42 19 1 -22 12 18 4 -2 2 4 14 9 3 -2 8 9 7 -1 -14 -20 -27 -31 -14 -12 -30 -13 -3 9 27 17 -1 2 20 -12 5 4 8 -3 2 -3 14 17 18 28 22 -2 -19 -25 -22 -30 -28 -19 -23 -20 0 22 41 13 19 -2 7 -8 13 18 9 9 14 22 28 30 31 31 28 6 -17 -11 -23 -28 -23 -13 -28 -26 7 31 35 23 15 -14 -3 2 25 34 26 37 35 38 31 27 25 32 24 13 -1 -4 -14 -18 -15 -15 -22 -18 32 29 31 8 -19 -23 -19 8 20 43 43 38 15 18 13 0 7 4 9 16 19 12 10 -14 -20 -12 -31 -15 9 4 29 -3 -11 -11 -18 3 36 48 12 6 -8 -13 -19 -19 -15 -3 12 15 16 23 20 -4 -9 -10 -25 -9 -8 11 18 9 0 -2 -5 -1 15 -4 -5 -13 -22 -24 -18 -15 -17 -8 2 5 13 24 15 -3 4 -2 -14 6 9 7 7 13 -5 -9 13 -5 -11 -24 -25 -29 -16 -14 -8 -4 -12 -10 -7 2 6 6 8 -4 3 -2 -6 27 19 4 0 0 -1 -5 -18 -8 -18 -30 -25 -11 -6 -4 5 4 4 0 -3 0 4 1 7 16 14 5 1 20 8 -1 -7 11 0 -11 3 -8 -9 -25 -10 -7 -5 -19 4 7 2 -3 3 -1 -3 -10 12 17 16 10 17 21 17 -4 3 5 0 1 2 -5 -5 -10 -10 -2 -13 -9 1 -1 9 2 7 4 -6 2 9 7 20 17 3 26 15 -2 -3 1 0 1 14 4 0 -4 -5 -11 -11 -9 -2 17 11 3 4 4 2 -1 -1 2 16 9 -3 7 -4 -6 -14 -21 -1 15 4 -1 -3 -4 -6 -17 -14 -11 4 14 4 -4 9 5 8 -4 4 8 0 7 1 0 -16 -18 -1 -14 -2 -21 -12 -18 -13 -13 -11 -20 -6 -10 1 7 0 -2 3 -2 -4 3 7 1 -1 -4 -1 -10 -14 -8 9 0 -1 -6 -22 -42 -13 1 -4 -4 -8 -7 -5 -1 8 -5 0 2 -12 -15 -1 -7 0 -11 -17 -18 -3 -24 -17 -1 1 -1 -13 -23 -1 -12 -12 -7 -15 -18 -15 -13 -4 0 0 -3 -8 -14 -14 -15 0 -11 -16 -10 -11 10 7 1 -2 0 -28 -17 0 -3 -2 -11 -17 -25 -24 -20 -5 -3 3 5 5 -12 -7 -8 5 -17 -32 -20 -2 8 1 -1 0 1 10 -1 0 15 10 3 -5 -14 -15 -13 -18 -12 -12 -4 -10 -12 -2 17 -10 -21 -24 -14 -8 -1 -3 0 -1 -1 0 -1 -4 8 13 1 2 -10 -21 -21 -7 -10 7 6 8 -6 0 11 -8 -14 -15 -16 -10 -2 -3 0 -1 0 -1 -2 2 -4 2 -1 12 6 7 21 19 23 8 5 -1 -9 -6 16 -4 -1 -3 15 0 -2 -2 0 -2 -1 -2 0 12 18 15 0 10 15 13 -5 1 12 -3 -29 -24 0 1 -14 -14 -16 -5 -2 -1 -1 -1 -1 16 | 10 -1 -1 0 0 0 0 1 -1 0 -1 0 -2 -4 -1 16 -1 0 -2 1 -2 -1 0 -2 1 -1 -1 -2 -2 1 -1 -1 -2 -1 -1 15 16 14 19 8 4 10 12 -9 9 38 37 9 24 19 15 18 9 -1 -1 0 0 0 0 1 -1 20 -2 12 27 39 43 59 57 46 12 40 28 15 29 9 -3 21 6 19 28 21 19 -1 -1 0 1 0 3 18 16 24 19 45 47 30 45 30 18 13 11 12 -1 -3 5 -1 10 -4 2 22 -5 11 1 0 -1 -15 3 -2 28 25 14 12 10 13 20 5 -9 -9 -7 -8 -9 0 6 -4 -20 -14 -11 8 -1 -25 -1 -2 -1 4 9 19 14 15 9 11 10 11 -7 1 -6 -12 -11 -1 -9 -10 -10 -6 -16 -5 6 -6 -10 9 13 -1 0 -31 -4 4 14 25 16 12 7 10 14 5 -4 -1 -6 4 -9 -6 -11 -17 -9 -12 -12 -9 4 1 0 -1 23 -4 -15 -6 11 12 12 10 4 12 17 -1 3 6 -4 -17 -5 -11 -3 -5 -12 -2 -21 -9 -7 5 -12 1 11 -34 -25 -14 -5 2 -6 -10 1 7 4 -5 -10 3 5 3 1 -10 -2 1 -11 -7 -13 -50 -22 -14 -10 -8 -5 -15 -13 -11 -7 -19 -10 2 -6 -10 -12 -11 -12 2 12 18 0 -7 -7 -10 -5 -1 -22 -23 -15 -10 14 -8 -2 -3 -32 -18 -1 -8 -16 -13 -18 -26 -35 -36 -24 -6 7 18 14 -5 -3 -11 -5 -7 -19 -23 -28 -6 -23 -5 -16 -35 -33 -16 -10 -27 -29 -20 -35 -39 -34 -39 -7 5 5 3 -9 -2 1 -1 11 4 -15 -25 -30 -40 -9 4 -16 -26 -34 -25 -34 -40 -50 -28 -43 -29 -9 17 24 16 4 -2 -10 -2 1 -1 8 -1 -12 -17 -14 -11 15 0 -8 -28 -12 -18 -23 -38 -36 -20 -13 4 17 40 28 11 2 6 -5 -2 5 2 9 9 20 23 9 12 25 5 -4 -31 0 4 1 -10 5 1 19 20 34 36 25 13 5 20 7 17 18 0 18 17 30 16 6 55 -2 -2 -2 -8 1 -8 13 10 3 -8 6 17 28 30 24 17 20 19 19 18 23 0 15 8 24 37 26 12 23 -1 1 -12 12 7 13 8 17 8 21 14 19 17 18 13 19 16 24 14 21 6 24 19 13 16 41 24 28 -1 0 0 16 8 2 27 6 17 13 14 12 4 10 14 15 18 16 20 13 6 10 15 -1 15 51 18 -11 -1 -1 -20 17 15 6 14 12 11 5 0 7 14 14 5 15 22 25 19 14 0 5 10 10 15 39 33 26 -2 17 -13 4 6 3 -1 2 0 6 4 17 13 18 20 21 23 21 7 1 -7 -3 -1 -2 -1 23 38 14 -1 -21 4 20 10 10 -11 -2 -8 1 1 1 6 7 6 9 -3 -3 1 -11 -15 -9 -7 0 -6 -2 6 -1 -2 5 11 10 -8 -5 -11 -7 -8 -13 -2 -7 -6 -3 -8 -15 -8 -9 -15 -10 -15 -5 -2 -8 -9 6 29 0 -2 0 6 1 -7 5 -12 -7 -10 -11 -10 -4 -9 -11 -15 -12 -12 -29 -21 -3 -12 -13 -18 -30 -12 -10 -10 0 0 -1 18 4 -11 1 -7 -3 -12 -12 1 4 -5 -7 -6 -7 -23 -34 -35 -24 -21 -7 -8 -19 -16 -13 16 0 -2 -1 10 -6 -19 -15 -13 -28 -16 -1 -2 -5 -1 -2 9 -5 -11 -19 -33 -34 -15 3 -10 -23 14 -1 11 -1 -1 -1 -1 19 -9 -31 -28 -20 -26 -25 -10 -10 -12 -16 -16 -7 -15 -24 -64 -55 -28 -27 -13 -2 5 -6 8 0 -1 0 -1 0 -17 -33 -28 -11 -17 -17 -9 -38 -41 -26 -25 -5 -4 0 -18 -24 -22 -13 -40 -16 -2 -1 -2 -1 -1 0 0 0 -8 -13 -21 -21 -19 -21 -4 -10 -17 -48 -47 -3 8 -10 -5 -8 -8 11 -28 -1 1 -1 0 -1 17 | -30 -1 1 -1 1 -1 1 0 -1 -1 1 0 1 -3 -1 11 0 -2 0 -1 0 -1 0 0 0 0 -2 -1 -2 -1 -1 -1 1 0 0 5 6 4 0 7 14 14 11 -7 3 4 4 7 10 10 4 9 3 0 -1 0 0 -2 0 0 -1 12 0 12 14 28 38 40 34 23 15 28 24 -7 -4 -1 -6 3 2 2 13 23 17 0 0 -1 -1 0 5 15 -3 9 1 -12 -2 -5 2 -7 -9 -28 -27 -19 -16 -8 -21 -34 -1 10 21 20 -21 7 1 -1 0 -3 -13 1 11 10 5 3 3 2 -8 -10 -11 -6 -21 -13 -16 -20 -2 -13 -16 -2 18 8 7 -7 0 -1 1 7 -22 -2 -22 -23 2 3 -4 13 13 10 7 6 -3 2 -2 -2 12 8 -1 3 9 7 8 -16 6 0 -1 -27 -26 -37 -22 -8 2 -5 14 10 3 3 2 9 13 9 12 -4 12 1 -9 -4 6 -5 1 -19 -29 -1 -22 -29 -29 -1 2 -3 -16 -2 -8 -4 -8 -5 1 -2 8 5 -2 -7 -6 -5 -5 -6 -16 -13 -12 -20 -23 1 -22 -32 -19 -7 -1 3 -3 -4 -2 -5 -10 -14 -4 -11 -8 -12 -12 -20 -9 -18 -10 -19 -23 -19 -10 -10 5 -16 -20 -24 -7 -31 -1 3 1 -2 -8 -5 -18 -17 -19 -22 -17 -18 -19 -13 -10 -14 -13 -19 -17 -20 -28 11 -19 -17 -10 -37 -10 -16 0 -1 0 -3 -10 -13 -17 -16 -31 -31 -24 -26 -19 -15 -17 -23 -16 -18 2 -21 -37 -20 -1 -12 -21 -33 -22 -7 11 4 0 -1 -8 -20 -29 -29 -26 -12 -14 -8 -18 -12 -10 -8 -3 -10 6 0 -11 -23 5 -12 -18 -16 -12 0 4 -4 -13 -12 -17 -24 -30 -17 4 1 -7 -8 -3 -9 5 -1 13 6 10 -1 -6 -21 2 0 -6 -27 -6 5 -9 -13 -22 -17 -19 -23 -15 5 22 12 16 -8 -2 -4 -2 2 -2 9 2 6 11 29 22 -17 -11 -22 -10 -1 -24 -11 -19 -17 -18 -9 2 14 23 12 9 9 3 -3 -5 -5 -11 -7 -22 -16 19 36 1 1 -8 -19 4 -17 -19 -18 -15 -6 -1 4 16 20 31 20 0 12 -3 -16 -5 -17 -19 -25 -18 -17 36 41 23 -1 -4 -21 9 -11 -12 -4 -10 -1 7 15 19 23 28 19 7 8 -3 -13 -13 -16 -15 -10 -3 -10 62 53 22 -1 -1 -1 6 -6 -2 1 1 11 15 16 11 21 28 9 7 2 -12 -13 -7 -13 -5 -3 -15 -6 27 34 12 -2 -2 -26 10 0 -5 0 7 -2 6 7 9 21 15 1 -5 -8 -16 -8 -7 -9 -2 -11 11 18 29 11 22 -1 -21 -17 -12 -3 0 1 8 -9 -5 6 5 0 -6 -15 -12 -9 -10 -6 3 1 17 14 21 1 21 28 10 -1 -12 17 11 7 5 9 13 -5 -5 3 -9 -12 -18 -13 -10 -8 -13 4 2 15 30 16 4 4 8 4 -1 0 3 19 21 29 18 11 5 8 14 2 -8 -19 -8 -9 -11 -10 2 1 8 21 24 9 15 23 -2 -17 0 1 -1 6 13 27 27 20 13 6 8 -3 0 -5 -4 -5 -10 -11 -11 9 6 22 26 -1 10 9 20 -5 -1 0 -1 4 -1 -5 0 -1 5 23 10 -12 -5 1 1 -9 -9 0 -5 9 27 26 46 35 35 11 20 -9 -1 0 -1 -15 -27 -43 -38 -23 -5 -4 8 -7 -11 -9 -15 -12 -7 -7 -11 13 15 27 22 27 12 3 14 -2 -1 0 0 -1 -22 -37 -21 -17 -22 -15 -16 -13 -21 -24 -14 -10 -11 -23 -11 -15 -9 4 -11 -15 -17 -34 12 -1 -1 0 -2 0 -2 9 20 7 -10 -14 -20 -15 -23 -12 -17 -12 -14 -17 -4 -12 -25 -6 7 -29 -11 -2 -1 -2 -1 -1 1 0 0 -11 -18 -21 2 -5 -12 -26 4 2 -28 -4 -1 -3 -40 -18 -5 -5 7 -17 -1 0 -1 -1 1 18 | 6 -1 -1 0 0 0 -2 -1 0 0 -2 0 0 -9 -7 13 1 -1 -1 -1 0 -2 0 -2 -1 -2 0 -1 0 0 1 -1 -2 0 0 -16 -14 -9 -9 -23 -35 -37 -32 13 -32 -29 -30 -21 -27 -30 -22 -17 -11 0 -1 0 0 0 0 -1 -1 -17 -2 -12 -25 -35 -14 -16 -30 -35 2 -8 -8 -3 -7 -7 -1 -16 -16 -25 -34 8 12 0 0 0 0 -2 -14 -21 -17 -23 -13 -21 -20 -12 -28 -19 -34 -21 -10 -1 4 -2 0 9 1 -4 -18 -18 26 -6 -2 -1 0 12 16 -21 -25 10 -14 -29 -25 -19 -15 -11 -10 -9 -10 -6 -8 -13 0 1 8 -3 13 26 20 20 -1 0 -2 -8 -10 -7 19 9 1 -6 0 -17 -2 -4 -7 -8 -8 -10 -5 -7 -6 -1 1 13 7 22 17 18 -13 0 0 11 6 -9 11 6 11 8 13 2 2 9 -1 -3 -3 -10 -11 -11 -1 -3 -7 -8 5 35 35 55 14 -2 7 -3 -10 -14 -2 5 5 13 -5 0 0 7 2 7 2 -4 -10 -9 -11 1 3 -7 2 11 41 49 16 -1 22 -8 13 -9 5 6 4 -13 -14 -2 10 3 7 -3 -12 -18 -3 -1 -12 -11 -8 1 14 11 58 50 20 15 13 20 2 0 -3 2 -7 -1 5 -5 12 10 -9 -10 -8 -9 -7 -12 -17 -14 -3 12 -4 1 71 46 21 15 5 1 -6 0 -3 -8 0 9 -1 -2 -2 -8 -14 -9 4 5 -5 -16 -8 -15 -5 -7 -10 0 33 41 13 6 10 11 -2 20 11 -2 0 -14 -5 -12 -9 -2 -10 7 22 19 7 1 0 -18 -18 -12 -12 1 27 35 6 -1 15 2 17 9 3 -10 -7 -9 -18 -6 -8 -1 0 16 25 19 3 4 -6 -12 -13 -17 -21 -9 26 36 1 1 4 28 -1 -15 -6 -13 -17 -13 -17 -17 5 14 14 12 15 18 8 -5 -12 -2 -19 -22 -26 -16 16 32 0 19 -7 28 22 -4 -13 -14 -19 -16 -15 5 5 1 1 4 6 14 1 -15 -11 -16 -26 -19 -16 -14 -3 22 -2 0 -9 3 17 -7 -26 -8 -16 -13 -7 2 7 5 2 -1 13 14 3 -8 -18 -15 -25 -8 -19 -22 -4 26 2 -1 -16 6 24 -2 -25 -12 -14 -14 -5 3 3 16 7 2 14 3 -6 -10 -18 -16 -18 -16 -6 -1 3 19 15 1 2 19 11 1 -15 -8 -13 -17 -13 -14 4 12 7 6 9 3 -20 -15 -19 -5 -6 -25 2 5 -13 25 -22 -2 -1 22 22 3 13 -4 -14 -19 -24 -22 -11 -1 3 3 -8 -6 -19 -15 -9 3 -3 -10 2 13 -12 12 2 0 21 2 11 13 7 3 -12 -17 -22 -30 -27 -18 -4 -4 -4 -7 -8 -4 -8 -6 -8 -6 6 4 5 5 -6 -2 -17 -5 -5 -3 -12 5 -5 -13 -22 -30 -23 -24 -16 -16 -9 -6 4 4 -5 0 0 3 11 8 8 16 -1 -1 -10 9 -13 2 8 7 0 -3 -13 -14 -20 -23 -21 -13 -7 -9 -5 2 5 12 11 -8 12 25 20 -19 0 1 -1 -8 -7 19 11 6 3 0 -11 -12 -20 -19 -29 -15 -18 -17 -7 4 3 9 5 -4 25 14 6 19 0 0 0 -28 6 38 11 1 -8 -1 -8 -13 -14 -9 -17 -12 -13 -3 -3 5 13 30 21 -2 20 18 12 14 0 1 0 18 18 15 31 16 4 2 -3 8 15 1 11 25 13 12 8 16 34 8 26 2 -25 -14 -14 0 0 0 -1 -1 21 28 -2 24 21 15 23 37 30 36 34 42 48 44 42 22 -17 0 6 -4 -14 13 -16 3 -1 0 -1 1 -1 -17 -32 -17 4 6 17 11 0 -17 0 7 9 16 20 -8 -23 -1 1 24 16 -1 -1 -2 0 1 0 -2 -1 13 24 26 -10 -7 12 -9 -14 -14 12 -7 11 19 7 1 -18 0 -16 20 1 1 1 0 -1 19 | 12 -2 0 -1 -2 -1 0 -2 -1 1 -1 0 -1 9 9 -1 -1 1 -1 -2 1 -2 0 -1 -1 0 -1 1 0 1 0 -1 0 0 0 -4 -2 5 7 10 15 24 19 -13 23 23 20 22 29 26 16 7 8 0 1 0 1 0 0 1 -1 -3 -1 -1 -9 12 7 -20 -9 0 -16 -8 -6 2 15 36 24 37 40 37 25 -12 -14 -1 -2 0 0 0 9 -13 -21 -15 -21 -23 -34 -40 -25 -21 -1 -14 -5 -6 5 23 11 20 31 26 24 9 -5 10 0 -1 0 -16 11 -25 -12 -29 -31 -45 -33 -19 -11 -17 -21 -8 4 -5 15 20 9 9 26 12 26 22 5 6 -2 1 0 2 -14 -25 -16 -30 -23 -21 -11 -6 -6 -9 -12 -1 -2 4 19 17 19 18 15 10 14 25 20 29 19 0 0 13 -16 -37 -25 -37 -17 -17 -18 -6 -4 3 -1 3 10 9 22 20 28 22 13 23 14 29 33 12 27 -2 -21 14 -22 -37 -20 -26 -30 -16 -4 1 5 -2 2 8 18 18 24 33 28 21 23 26 23 24 39 6 13 1 -8 -1 -15 -34 -25 -11 -15 -10 4 3 7 10 14 13 9 17 20 15 23 24 19 20 20 33 23 21 21 -7 -8 -21 -1 -23 -34 -15 -9 -3 1 8 18 14 17 9 -7 -3 -8 -7 -5 -1 2 1 18 43 47 -1 -14 -8 -10 -19 -11 -5 -13 -13 -5 6 16 17 20 21 13 -1 -7 -15 -21 -23 -22 -15 -2 -11 -1 18 20 23 9 -11 -12 -13 -22 2 5 9 10 -4 6 0 6 10 16 8 -9 -18 -30 -34 -28 -34 -22 -28 -14 -5 19 32 6 -10 -9 -16 11 -6 1 6 5 5 4 1 11 15 25 5 -7 -16 -20 -20 -21 -17 -15 -31 -32 -27 -4 17 -17 -2 -3 -23 20 7 4 -2 5 1 4 6 8 17 23 7 -2 -20 -15 -13 -2 -3 -17 -22 -30 -30 -21 -7 6 16 -16 -21 -3 3 -1 -5 4 -5 1 7 11 16 12 -1 -10 -14 -15 -8 -17 -6 -12 -27 -26 -19 -23 -17 0 1 -16 -29 -11 5 -3 -11 0 1 15 17 18 25 7 -7 -12 -5 -10 -4 -15 -10 -10 -29 -13 3 1 -22 -9 -1 -17 -48 -3 -10 -15 -19 -9 6 12 19 32 16 -3 -5 -8 0 -10 -12 -6 -14 -14 -8 -10 -5 -6 -13 -22 -1 -10 -30 13 -2 -11 1 -12 2 16 26 18 5 -11 -5 -1 -2 0 1 0 -4 -5 -3 -13 -13 -18 -26 15 0 -7 -44 -1 16 8 11 3 8 9 4 -8 -12 -24 -14 -3 -5 -6 -6 2 3 -3 -4 -10 -4 -30 -22 -5 1 -18 -36 -32 9 11 13 11 10 6 -1 -8 -11 -18 -16 -3 4 6 6 6 9 -3 11 3 0 -14 -9 4 -1 13 0 -19 11 25 11 16 15 14 7 1 1 -10 -8 4 1 10 8 4 12 7 21 4 -7 4 -15 -1 0 -13 2 -9 12 -3 3 16 9 20 13 16 7 1 6 10 5 8 5 7 10 6 26 13 -6 19 14 0 1 0 -9 -1 8 0 -3 10 9 13 16 19 15 15 12 16 12 15 7 10 -1 0 6 23 20 1 6 -1 -1 0 -5 1 4 7 2 4 19 18 23 22 18 16 17 12 19 11 1 10 20 -8 16 21 16 7 -16 -2 0 0 9 -10 -30 -22 -12 -1 17 22 10 25 22 27 21 15 17 0 25 24 25 4 20 4 18 -8 1 -1 0 -1 0 4 -30 -44 -20 -7 -3 1 7 13 9 17 3 21 21 29 20 23 15 12 20 32 23 -4 -2 -2 0 -1 -1 -2 7 6 -15 -26 -28 -24 -20 8 17 2 -5 -3 0 13 3 0 12 -2 8 -9 0 -1 -2 -2 0 0 0 -1 -5 -10 -8 -2 -8 -8 2 6 6 -1 -10 -8 0 -32 -17 -6 -10 5 5 -1 0 -1 0 1 20 | 31 -2 -2 -1 0 -1 -1 -1 -1 0 0 -1 -1 8 6 2 -1 1 -1 -2 -1 0 -1 -2 1 1 1 -1 0 -2 1 -2 -2 0 0 13 14 9 6 19 5 10 8 -4 27 -2 9 18 23 23 14 12 10 0 0 -1 -2 0 0 -2 1 14 -1 11 21 10 2 14 13 28 30 24 43 34 20 8 16 9 8 18 27 -7 -12 0 -1 -1 -1 0 11 6 -2 26 9 -4 7 6 0 6 20 16 7 16 14 20 25 1 12 -1 6 -2 -20 2 0 0 -1 14 -13 -10 14 15 12 9 2 4 1 5 19 10 1 3 -4 -9 -4 -20 -12 -20 -11 -19 -7 -22 -2 -1 0 11 -23 -14 2 12 1 -3 -2 13 -2 13 14 21 14 2 -5 -15 -13 -21 -28 -26 -15 -16 -10 -26 -2 0 -1 -5 -16 -9 -5 -8 -16 -22 -10 6 15 12 2 7 14 8 -11 -17 -26 -33 -21 -17 -20 -8 -10 -11 -1 0 24 -20 -16 -18 -38 -22 -18 -11 -10 4 5 6 1 19 15 -1 -10 -24 -30 -24 -19 -15 -26 -12 -25 -2 -15 0 -8 -13 -9 -39 -29 -24 -4 -16 -9 -4 0 12 20 26 12 -13 -15 -33 -25 -11 -15 -17 -29 -27 4 -18 -14 -15 -9 -18 -13 -31 -21 -14 11 -10 -18 -7 8 11 25 31 15 -22 -31 -35 -19 -9 -8 -20 -24 -32 -27 -22 -27 -18 -2 -18 -14 -27 -14 -8 0 -10 -23 -5 13 15 40 22 -1 -28 -16 -24 -17 -1 -7 -12 -14 -25 -22 -23 -14 8 -18 -17 -14 -27 -7 -6 3 -8 -7 3 11 17 23 9 -21 -17 -11 -13 1 6 8 6 -5 -22 -25 -25 -2 10 -14 -25 -30 -26 -9 -9 2 3 7 14 15 15 15 5 -11 -6 -6 -1 0 2 8 2 -1 -11 -7 -27 17 -1 -7 4 -33 -26 -10 4 0 6 7 6 4 2 0 1 -2 -1 -3 -3 -9 4 15 8 4 16 1 -16 14 9 -2 5 8 -12 -11 -1 8 9 1 -3 -13 -16 -6 12 7 4 -8 -8 -7 0 7 7 4 -1 5 -8 -1 -1 -1 2 10 -28 -2 2 4 -2 -3 -8 -7 -10 0 22 12 6 2 -6 -1 2 11 -1 -3 -3 21 -7 20 -2 10 -6 5 -3 2 3 6 0 -3 0 -1 -24 -4 31 11 3 -14 -3 4 0 14 6 3 2 20 6 -5 0 -2 8 3 -1 2 11 8 13 -4 3 -16 -18 14 31 24 1 -7 9 -1 8 13 11 7 -5 11 8 0 1 -2 -23 24 2 7 8 5 -2 -1 -13 -26 -6 12 27 26 13 14 14 6 5 18 3 11 8 16 -9 -12 0 -22 -13 -11 1 8 6 12 -2 2 -10 -11 -4 11 27 27 28 14 16 10 1 8 10 23 3 14 -3 -12 0 -6 8 -4 -9 -3 6 3 0 4 -7 -6 7 10 23 22 22 19 28 17 13 13 7 14 3 -1 17 -2 1 3 24 24 15 -1 5 -5 12 3 7 0 6 15 18 14 20 8 17 11 11 8 12 5 7 -18 5 1 -1 -2 11 3 28 15 2 -6 7 5 10 -3 -2 0 -9 6 0 2 12 7 12 -1 -13 -13 -16 2 -13 1 -2 -1 21 10 8 1 -14 -26 -14 -8 -4 5 -1 -11 -6 -7 -7 -2 -21 -10 -13 4 -2 -14 -17 5 13 0 0 -2 -12 -17 7 18 25 -8 -13 2 5 -24 -26 -35 -24 -15 -25 -3 -22 -19 -11 7 -12 2 15 22 8 0 1 -1 0 9 18 30 29 22 -16 -14 -31 -43 -32 -58 -46 -42 -80 -67 -47 -34 -6 -3 13 -7 -19 1 7 -1 0 -2 -1 -2 -6 20 1 -10 -24 -37 -23 -32 -48 -36 -34 0 -36 -9 3 14 7 7 -14 -14 0 -1 0 -1 0 0 0 -1 -2 -7 -3 -2 -12 -12 -23 -19 -15 -17 -26 -9 -1 -18 0 -8 2 3 -3 -1 -2 0 1 0 21 | -------------------------------------------------------------------------------- /testdata/mat_valid.txt: -------------------------------------------------------------------------------- 1 | 3 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 2 0 1 3 2 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 2 2 2 2 2 2 2 2 2 2 2 0 0 0 0 0 0 0 0 0 0 0 0 0 2 2 2 2 2 2 2 2 2 2 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 2 2 2 2 2 2 2 2 2 2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 2 2 2 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 2 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 2 2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 2 2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 2 2 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 2 2 2 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 2 2 2 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 2 2 2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 2 2 2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 2 2 2 2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 2 2 2 2 2 2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 2 2 2 2 2 2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 2 2 2 2 2 2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 2 2 2 2 2 2 2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 2 2 2 2 2 2 2 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 2 2 2 2 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 2 | -------------------------------------------------------------------------------- /valid.txt: -------------------------------------------------------------------------------- 1 | 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 2 | 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 3 | 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 4 | 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 5 | 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 6 | 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 2 0 1 3 2 1 0 0 0 0 7 | 0 0 0 0 0 0 0 0 0 0 1 1 2 2 2 2 2 2 2 2 2 2 2 0 0 0 0 0 8 | 0 0 0 0 0 0 0 0 2 2 2 2 2 2 2 2 2 2 1 0 0 0 0 0 0 0 0 0 9 | 0 0 0 0 0 0 0 0 2 2 2 2 2 2 2 2 2 2 0 0 0 0 0 0 0 0 0 0 10 | 0 0 0 0 0 0 0 0 0 1 1 2 2 2 0 0 0 1 0 0 0 0 0 0 0 0 0 0 11 | 0 0 0 0 0 0 0 0 0 0 0 1 2 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 12 | 0 0 0 0 0 0 0 0 0 0 0 1 2 2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 13 | 0 0 0 0 0 0 0 0 0 0 0 0 2 2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 14 | 0 0 0 0 0 0 0 0 0 0 0 0 0 2 2 1 1 0 0 0 0 0 0 0 0 0 0 0 15 | 0 0 0 0 0 0 0 0 0 0 0 0 0 0 2 2 2 1 0 0 0 0 0 0 0 0 0 0 16 | 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 2 2 2 1 0 0 0 0 0 0 0 0 0 17 | 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 2 2 2 0 0 0 0 0 0 0 0 18 | 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 2 2 2 0 0 0 0 0 0 0 0 19 | 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 2 2 2 2 0 0 0 0 0 0 0 0 20 | 0 0 0 0 0 0 0 0 0 0 0 0 0 1 2 2 2 2 2 2 0 0 0 0 0 0 0 0 21 | 0 0 0 0 0 0 0 0 0 0 0 1 2 2 2 2 2 2 0 0 0 0 0 0 0 0 0 0 22 | 0 0 0 0 0 0 0 0 0 0 2 2 2 2 2 2 0 0 0 0 0 0 0 0 0 0 0 0 23 | 0 0 0 0 0 0 0 2 2 2 2 2 2 2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 24 | 0 0 0 0 0 2 2 2 2 2 2 2 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 25 | 0 0 0 0 1 2 2 2 2 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 26 | 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 27 | 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 28 | 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 29 | 30 | --------------------------------------------------------------------------------